import { PermissionAction } from '@supabase/shared-types/out/constants' import { useParams } from 'common' import dayjs from 'dayjs' import { Check, Key, Trash } from 'lucide-react' import { useState } from 'react' import { toast } from 'sonner' import { cn } from 'ui' import ConfirmationModal from 'ui-patterns/Dialogs/ConfirmationModal' import { ButtonTooltip } from '@/components/ui/ButtonTooltip' import CopyButton from '@/components/ui/CopyButton' import { useClientSecretDeleteMutation } from '@/data/oauth-secrets/client-secret-delete-mutation' import { Secret, useClientSecretsQuery } from '@/data/oauth-secrets/client-secrets-query' import { useOrganizationMembersQuery } from '@/data/organizations/organization-members-query' import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions' export interface SecretRowProps { secret: Secret appId?: string } export const SecretRow = ({ secret, appId }: SecretRowProps) => { const { slug } = useParams() const [showDeleteModal, setShowDeleteModal] = useState(false) const { can: canManageSecrets } = useAsyncCheckPermissions(PermissionAction.UPDATE, 'oauth_apps') const { data } = useClientSecretsQuery({ slug, appId }) const secrets = data?.client_secrets ?? [] const isLast = secrets.length === 1 const { data: members = [] } = useOrganizationMembersQuery({ slug }) const generatedBy = members.find((x) => x.gotrue_id === secret.created_by) const generatedByName = generatedBy?.username ?? generatedBy?.primary_email ?? secret.created_by const { mutate: deleteSecret, isPending: isDeleting } = useClientSecretDeleteMutation({ onSuccess: () => { // Show success toast and close modal after successful deletion toast.success('Successfully deleted client secret') setShowDeleteModal(false) }, }) const handleDelete = () => { if (!slug) return console.error('Slug is required') if (!appId) return console.error('App ID is required') deleteSecret({ slug, appId, secretId: secret.id }) } const isNew = secret.client_secret !== undefined return ( <>
{isNew ? secret.client_secret : `${secret.client_secret_alias}${'*'.repeat(36)}`}
{isNew && secret.client_secret && (Added {isNew ? 'now' : dayjs(secret.created_at).fromNow()} by {generatedByName}
{secret.last_used_at && (Last used {dayjs(secret.last_used_at).fromNow()}
)} {!secret.last_used_at && !isNew && (Never used
)}{isLast ? 'The last client secret cannot be deleted. Please generate a new secret before deleting this one.' : 'Are you sure you want to delete this client secret?'}