key-details-dialog.tsx70 lines · main
1import { FileKey } from 'lucide-react'
2import { useMemo } from 'react'
3import {
4 Button,
5 DialogFooter,
6 DialogHeader,
7 DialogSection,
8 DialogSectionSeparator,
9 DialogTitle,
10 Input,
11 Label,
12 Textarea,
13} from 'ui'
14
15import CopyButton from '@/components/ui/CopyButton'
16import { JWTSigningKey } from '@/data/jwt-signing-keys/jwt-signing-keys-query'
17
18export function KeyDetailsDialog({
19 selectedKey,
20 restURL,
21 onClose,
22}: {
23 selectedKey: JWTSigningKey
24 restURL: string
25 onClose: () => void
26}) {
27 const jwksURL = useMemo(() => new URL('/auth/v1/.well-known/jwks.json', restURL), [restURL])
28 const jwks = useMemo(
29 () => JSON.stringify({ keys: [selectedKey.public_jwk] }, null, 2),
30 [selectedKey]
31 )
32
33 return (
34 <>
35 <DialogHeader>
36 <DialogTitle>Key Details</DialogTitle>
37 </DialogHeader>
38 <DialogSectionSeparator />
39 <DialogSection className="flex flex-col gap-6">
40 <div className="flex flex-col gap-2">
41 <Label htmlFor="key-id">Key ID</Label>
42 <Input id="key-id" value={selectedKey.id} readOnly />
43 </div>
44 <div className="flex flex-col gap-2">
45 <Label htmlFor="discovery-url">Discovery URL</Label>
46 <Input id="discovery-url" value={jwksURL.href} readOnly />
47 </div>
48 <div className="flex flex-col gap-2">
49 <Label htmlFor="jwk" className="flex flex-row gap-2 items-center">
50 <FileKey className="size-4 text-foreground-light" />
51 Public key set (JSON Web Key Set format)
52 </Label>
53 <div className="relative">
54 <Textarea className="font-mono text-sm pr-10" rows={8} value={jwks} readOnly />
55 <CopyButton
56 type="default"
57 iconOnly
58 text={jwks}
59 className="absolute top-2 right-2"
60 copyLabel="Copy JWKS"
61 />
62 </div>
63 </div>
64 </DialogSection>
65 <DialogFooter>
66 <Button onClick={() => onClose()}>OK</Button>
67 </DialogFooter>
68 </>
69 )
70}