Skip to content

Commit

Permalink
feat(dasboard): added api ket scope in dashboard (#3560)
Browse files Browse the repository at this point in the history
Co-authored-by: Siddharth <[email protected]>
  • Loading branch information
siddhart1o1 and Siddharth authored Nov 16, 2023
1 parent afcebcd commit 43e8dcd
Show file tree
Hide file tree
Showing 8 changed files with 249 additions and 54 deletions.
4 changes: 3 additions & 1 deletion apps/dashboard/app/api-keys/server-actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ export const revokeApiKeyServerAction = async (id: string) => {

export const createApiKeyServerAction = async (_prevState: unknown, form: FormData) => {
const apiKeyName = form.get("apiKeyName")
const readOnly = form.get("apiScope") === "readOnly"

if (!apiKeyName || typeof apiKeyName !== "string") {
return {
error: true,
Expand All @@ -72,7 +74,7 @@ export const createApiKeyServerAction = async (_prevState: unknown, form: FormDa

let data
try {
data = await createApiKey(token, apiKeyName, apiKeyExpiresInDays)
data = await createApiKey(token, apiKeyName, apiKeyExpiresInDays, readOnly)
} catch (err) {
console.log("error in createApiKey ", err)
return {
Expand Down
22 changes: 14 additions & 8 deletions apps/dashboard/components/api-keys/api-card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,18 @@ import React from "react"
import { Card, Divider, Typography, Box } from "@mui/joy"

import RevokeKey from "./revoke"
import { formatDate } from "./utils"
import { formatDate, getScopeText } from "./utils"

interface ApiKey {
id: string
name: string
createdAt: number
expiresAt: number
lastUsedAt?: number | null | undefined
expired: boolean
revoked: boolean
readonly __typename: "ApiKey"
readonly id: string
readonly name: string
readonly createdAt: number
readonly revoked: boolean
readonly expired: boolean
readonly lastUsedAt?: number | null
readonly expiresAt: number
readonly readOnly: boolean
}

interface ApiKeysCardProps {
Expand Down Expand Up @@ -47,6 +49,10 @@ const ApiKeysCard: React.FC<ApiKeysCardProps> = ({
<Typography fontSize={13}>Expires At</Typography>
<Typography fontSize={13}>{formatDate(key.expiresAt)}</Typography>
</Box>
<Box sx={{ display: "flex", justifyContent: "space-between" }}>
<Typography fontSize={13}>Scope</Typography>
<Typography fontSize={13}>{getScopeText(key.readOnly)}</Typography>
</Box>
{!key.revoked && !key.expired && <RevokeKey id={key.id} />}
</Card>
))
Expand Down
14 changes: 13 additions & 1 deletion apps/dashboard/components/api-keys/create.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import {
Tooltip,
Select,
Option,
Radio,
RadioGroup,
} from "@mui/joy"

import InfoOutlined from "@mui/icons-material/InfoOutlined"
Expand Down Expand Up @@ -254,7 +256,17 @@ const ApiKeyCreate = () => {
{state.message}
</FormHelperText>
) : null}

<Box>
<Typography>Scope</Typography>
<RadioGroup defaultValue="readAndWrite" name="apiScope">
<Radio value="readAndWrite" label="Read and Write" />
<FormHelperText>
Full access: read and write account details.
</FormHelperText>
<Radio value="readOnly" label="Read Only" />
<FormHelperText>Limited access: view data only.</FormHelperText>
</RadioGroup>
</Box>
<Box
sx={{
display: "flex",
Expand Down
89 changes: 49 additions & 40 deletions apps/dashboard/components/api-keys/list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,18 @@ import Typography from "@mui/joy/Typography"
import Divider from "@mui/joy/Divider"

import RevokeKey from "./revoke"
import { formatDate } from "./utils"
import { formatDate, getScopeText } from "./utils"

interface ApiKey {
id: string
name: string
createdAt: number
expiresAt: number
lastUsedAt?: number | null
readonly __typename: "ApiKey"
readonly id: string
readonly name: string
readonly createdAt: number
readonly revoked: boolean
readonly expired: boolean
readonly lastUsedAt?: number | null
readonly expiresAt: number
readonly readOnly: boolean
}

interface ApiKeysListProps {
Expand All @@ -32,26 +36,28 @@ const ApiKeysList: React.FC<ApiKeysListProps> = ({
<thead>
<tr>
<th style={{ width: "20%" }}>Name</th>
<th style={{ width: "30%" }}>API Key ID</th>
<th style={{ width: "20%" }}>Expires At</th>
<th style={{ width: "20%" }}>Last Used</th>
<th style={{ width: "10%", textAlign: "right" }}>Action</th>
<th style={{ width: "25%" }}>API Key ID</th>
<th style={{ width: "15%" }}>Scope</th>
<th style={{ width: "15%" }}>Expires At</th>
<th style={{ width: "15%" }}>Last Used</th>
<th style={{ width: "5%", textAlign: "right" }}>Action</th>
</tr>
</thead>
<tbody>
{activeKeys.map(({ id, name, expiresAt, lastUsedAt }) => (
<tr key={id}>
<td style={{ width: "20%" }}>{name}</td>
<td style={{ width: "30%" }}>{id}</td>
<td style={{ width: "20%" }}>{formatDate(expiresAt)}</td>
<td style={{ width: "20%" }}>
{lastUsedAt ? formatDate(lastUsedAt) : "Never"}
</td>
<td style={{ width: "10%", textAlign: "right" }}>
<RevokeKey id={id} />
</td>
</tr>
))}
{activeKeys.map(({ id, name, expiresAt, lastUsedAt, readOnly }) => {
return (
<tr key={id}>
<td>{name}</td>
<td>{id}</td>
<td>{getScopeText(readOnly)}</td>
<td>{formatDate(expiresAt)}</td>
<td>{lastUsedAt ? formatDate(lastUsedAt) : "Never"}</td>
<td style={{ textAlign: "right" }}>
<RevokeKey id={id} />
</td>
</tr>
)
})}
</tbody>
</Table>
{activeKeys.length === 0 && <Typography>No active keys to display.</Typography>}
Expand All @@ -62,19 +68,21 @@ const ApiKeysList: React.FC<ApiKeysListProps> = ({
<Table aria-label="revoked keys table">
<thead>
<tr>
<th style={{ width: "25%" }}>Name</th>
<th style={{ width: "35%" }}>API Key ID</th>
<th style={{ width: "15%" }}>Created At</th>
<th style={{ width: "20%" }}>Name</th>
<th style={{ width: "25%" }}>API Key ID</th>
<th style={{ width: "15%" }}>Scope</th>
<th style={{ width: "20%" }}>Created At</th>
<th style={{ textAlign: "right", width: "15%" }}>Status</th>
</tr>
</thead>
<tbody>
{revokedKeys.map(({ id, name, createdAt }) => (
{revokedKeys.map(({ id, name, createdAt, readOnly }) => (
<tr key={id}>
<td style={{ width: "25%" }}>{name}</td>
<td style={{ width: "35%" }}>{id}</td>
<td style={{ width: "15%" }}>{formatDate(createdAt)}</td>
<td style={{ textAlign: "right", width: "15%" }}>Revoked</td>
<td>{name}</td>
<td>{id}</td>
<td>{getScopeText(readOnly)}</td>
<td>{formatDate(createdAt)}</td>
<td style={{ textAlign: "right" }}>Revoked</td>
</tr>
))}
</tbody>
Expand All @@ -83,25 +91,26 @@ const ApiKeysList: React.FC<ApiKeysListProps> = ({

<Divider />

{/* Expired Keys Section */}
<Typography fontSize={22}>Expired Keys</Typography>
<Table aria-label="expired keys table">
<thead>
<tr>
<th style={{ width: "25%" }}>Name</th>
<th style={{ width: "35%" }}>API Key ID</th>
<th style={{ width: "20%" }}>Name</th>
<th style={{ width: "25%" }}>API Key ID</th>
<th style={{ width: "15%" }}>Scope</th>
<th style={{ width: "20%" }}>Created At</th>
<th style={{ textAlign: "right", width: "15%" }}>Expires At</th>
</tr>
</thead>
<tbody>
{expiredKeys.map(({ id, name, createdAt, expiresAt }) => (
{expiredKeys.map(({ id, name, createdAt, expiresAt, readOnly }) => (
<tr key={id}>
<td style={{ width: "25%" }}>{name}</td>
<td style={{ width: "35%" }}>{id}</td>
<td style={{ width: "20%" }}>{formatDate(createdAt)}</td>
<td style={{ textAlign: "right", width: "15%" }}>
{formatDate(expiresAt)}
</td>
<td>{name}</td>
<td>{id}</td>
<td>{getScopeText(readOnly)}</td>
<td>{formatDate(createdAt)}</td>
<td style={{ textAlign: "right" }}>{formatDate(expiresAt)}</td>
</tr>
))}
</tbody>
Expand Down
4 changes: 4 additions & 0 deletions apps/dashboard/components/api-keys/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,7 @@ export const formatDate = (timestamp: number): string => {
}
return new Date(timestamp * 1000).toLocaleDateString(undefined, options)
}

export const getScopeText = (readOnly: boolean): string => {
return readOnly ? "Read Only" : "Read and Write"
}
Loading

0 comments on commit 43e8dcd

Please sign in to comment.