Home / Function/ SecretRow() — supabase Function Reference

SecretRow() — supabase Function Reference

Architecture documentation for the SecretRow() function in SecretRow.tsx from the supabase codebase.

Entity Profile

Relationship Graph

Source Code

apps/studio/components/interfaces/Organization/OAuthApps/OAuthSecrets/SecretRow.tsx lines 22–133

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 (
    <>
      <div
        className={cn(
          'flex items-center justify-between p-4 border first:rounded-t last:rounded-b',
          isNew && 'bg-background-alternative'
        )}
      >
        <div className="flex flex-row gap-6 items-center">
          <Key size={16} strokeWidth={2} />
          <div className="flex flex-col gap-1">
            <div className="flex items-center gap-2">
              <div className="flex items-center gap-2">
                {isNew && <Check size={14} className="text-brand" strokeWidth={3} />}
                <p className="font-mono text-sm">
                  {isNew ? secret.client_secret : `${secret.client_secret_alias}${'*'.repeat(36)}`}
                </p>
                {isNew && secret.client_secret && (
                  <CopyButton text={secret.client_secret} type="default" iconOnly />
                )}
              </div>
            </div>
            <div className="flex flex-col gap-0">
              <p className="text-sm text-foreground-lighter">
                Added {isNew ? 'now' : dayjs(secret.created_at).fromNow()} by {generatedByName}
              </p>
              {secret.last_used_at && (
                <p className="text-sm text-foreground-lighter">
                  Last used {dayjs(secret.last_used_at).fromNow()}
                </p>
              )}
              {!secret.last_used_at && !isNew && (
                <p className="text-sm text-foreground-lighter">Never used</p>
              )}
            </div>
          </div>
        </div>
        <div className="flex items-center gap-2">
          <ButtonTooltip
            type="default"
            className="w-7"
            icon={<Trash />}
            disabled={!appId || !canManageSecrets || isLast}
            onClick={() => setShowDeleteModal(true)}
            tooltip={{
              content: {
                className: 'w-64 text-center',
                side: 'bottom',
                text: !canManageSecrets
                  ? 'You need additional permissions to delete client secrets'
                  : isLast
                    ? 'You must have at least one client secret for the OAuth application to function.'
                    : undefined,
              },
            }}
          />
        </div>
      </div>

      <ConfirmationModal
        visible={showDeleteModal}
        variant="destructive"
        title="Confirm to delete client secret"
        confirmLabel="Delete"
        confirmLabelLoading="Deleting"
        loading={isDeleting}
        onCancel={() => setShowDeleteModal(false)}
        onConfirm={handleDelete}
        disabled={isLast}
        alert={{
          title: 'This action cannot be undone',
          description: 'The client secret will be permanently removed and cannot be recovered.',
        }}
      >
        <p className="text-sm text-foreground-light">
          {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?'}
        </p>
      </ConfirmationModal>
    </>
  )
}

Subdomains

Analyze Your Own Codebase

Get architecture documentation, dependency graphs, and domain analysis for your codebase in minutes.

Try Supermodel Free