"use client"; import { useState } from "react"; import { useTranslations } from "next-intl"; import { AxiosResponse } from "axios"; import moment from "moment"; import { Button } from "@app/components/ui/button"; import CopyTextBox from "@app/components/CopyTextBox"; import CopyToClipboard from "@app/components/CopyToClipboard"; import { SettingsContainer, SettingsFormCell, SettingsFormGrid, SettingsSection, SettingsSectionBody, SettingsSectionDescription, SettingsSectionHeader, SettingsSectionTitle as SectionTitle } from "@app/components/Settings"; import { createApiClient, formatAxiosError } from "@app/lib/api"; import { useEnvContext } from "@app/hooks/useEnvContext"; import { toast } from "@app/hooks/useToast"; import type { GetMyVirtualApiKeyResponse, ListMyVirtualApiKeysResponse, VirtualApiKeyWithResources } from "@server/routers/virtualApiKey/types"; import { formatVirtualApiKeyCredential, formatVirtualApiKeyPreview } from "@app/lib/virtualApiKeyFormat"; type UserVirtualApiKeysProps = { orgId: string; initialData: ListMyVirtualApiKeysResponse; }; function useRevealSecret(orgId: string, virtualApiKeyId: string) { const t = useTranslations(); const api = createApiClient(useEnvContext()); const [credential, setCredential] = useState(null); const [loading, setLoading] = useState(false); const revealSecret = () => { if (credential || loading) { return; } setLoading(true); api.get>( `/org/${orgId}/my-virtual-api-keys/${virtualApiKeyId}` ) .then((res) => { const secret = res.data.data.virtualApiKey.secret; if (secret) { setCredential( formatVirtualApiKeyCredential(virtualApiKeyId, secret) ); } else { toast({ variant: "destructive", title: t("virtualApiKeysErrorFetchSecret"), description: t( "virtualApiKeysErrorFetchSecretDescription" ) }); } }) .catch((e) => { toast({ variant: "destructive", title: t("virtualApiKeysErrorFetchSecret"), description: formatAxiosError( e, t("virtualApiKeysErrorFetchSecretDescription") ) }); }) .finally(() => { setLoading(false); }); }; return { credential, loading, revealSecret }; } function OwnedKeySecret({ orgId, virtualApiKeyId, lastChars }: { orgId: string; virtualApiKeyId: string; lastChars: string; }) { const t = useTranslations(); const preview = formatVirtualApiKeyPreview(virtualApiKeyId, lastChars); const { credential, loading, revealSecret } = useRevealSecret( orgId, virtualApiKeyId ); const displayValue = credential ?? preview; return (
{!credential ? ( ) : null}
); } function IdentityKeyCenterpiece({ orgId, virtualApiKeyId, lastChars, resourceName }: { orgId: string; virtualApiKeyId: string; lastChars: string; resourceName?: string | null; }) { const t = useTranslations(); const preview = formatVirtualApiKeyPreview(virtualApiKeyId, lastChars); const { credential, loading, revealSecret } = useRevealSecret( orgId, virtualApiKeyId ); const displayValue = credential ?? preview; const headline = resourceName ? t("myVirtualApiKeysIdentityResourceHeadline", { resourceName }) : t("myVirtualApiKeysIdentityHeadline"); const description = resourceName ? t("myVirtualApiKeysIdentityResourceDescription", { resourceName }) : t("myVirtualApiKeysIdentityDescription"); return (

{headline}

{description}

{!credential ? (
) : null}
); } function ManualKeyRow({ orgId, keyRow }: { orgId: string; keyRow: VirtualApiKeyWithResources; }) { const t = useTranslations(); return (

{keyRow.name || t("myVirtualApiKeysUnnamed")}

{keyRow.description ? (

{keyRow.description}

) : null}

{t("created")} {moment(keyRow.createdAt).format("lll")}

); } export default function UserVirtualApiKeys({ orgId, initialData }: UserVirtualApiKeysProps) { const t = useTranslations(); const resourceName = initialData.resourceName; return ( <> {initialData.manualKeys.length > 0 ? ( {t("myVirtualApiKeysManualTitle")} {resourceName ? t( "myVirtualApiKeysManualResourceDescription", { resourceName } ) : t("myVirtualApiKeysManualDescription")} {initialData.manualKeys.map((keyRow) => ( ))} ) : null} ); }