import { PermissionAction } from '@supabase/shared-types/out/constants' import { JwtSecretUpdateStatus } from '@supabase/shared-types/out/events' import { AlertCircle, BookOpen, Loader2 } from 'lucide-react' import { useParams } from 'common' import Panel from 'components/ui/Panel' import { useJwtSecretUpdatingStatusQuery } from 'data/config/jwt-secret-updating-status-query' import { useProjectSettingsV2Query } from 'data/config/project-settings-v2-query' import { useCheckPermissions } from 'hooks/misc/useCheckPermissions' import { Button, Input } from 'ui' const DisplayApiSettings = ({ legacy }: { legacy?: boolean }) => { const { ref: projectRef } = useParams() const { data: settings, isError: isProjectSettingsError, isLoading: isProjectSettingsLoading, } = useProjectSettingsV2Query({ projectRef }) const { data, isError: isJwtSecretUpdateStatusError, isLoading: isJwtSecretUpdateStatusLoading, } = useJwtSecretUpdatingStatusQuery({ projectRef }) const jwtSecretUpdateStatus = data?.jwtSecretUpdateStatus const canReadAPIKeys = useCheckPermissions(PermissionAction.READ, 'service_api_keys') const isNotUpdatingJwtSecret = jwtSecretUpdateStatus === undefined || jwtSecretUpdateStatus === JwtSecretUpdateStatus.Updated const apiKeys = settings?.service_api_keys ?? [] // api keys should not be empty. However it can be populated with a delay on project creation const isApiKeysEmpty = apiKeys.length === 0 return ( <>
Project API Keys

Your API is secured behind an API gateway which requires an API Key for every request.
You can use the keys below in the Supabase client libraries.

) } > {isProjectSettingsError || isJwtSecretUpdateStatusError ? (

{isProjectSettingsError ? 'Failed to retrieve API keys' : 'Failed to update JWT secret'}

) : isApiKeysEmpty || isProjectSettingsLoading || isJwtSecretUpdateStatusLoading ? (

{isProjectSettingsLoading || isApiKeysEmpty ? 'Retrieving API keys' : 'JWT secret is being updated'}

) : ( apiKeys.map((x, i: number) => ( = 1 && 'border-t border-panel-border-interior-light [[data-theme*=dark]_&]:border-panel-border-interior-dark' } > {x.tags?.split(',').map((x, i: number) => ( {x} ))} {x.tags === 'service_role' && ( <> secret )} {x.tags === 'anon' && public} } copy={canReadAPIKeys && isNotUpdatingJwtSecret} reveal={x.tags !== 'anon' && canReadAPIKeys && isNotUpdatingJwtSecret} value={ !canReadAPIKeys ? 'You need additional permissions to view API keys' : jwtSecretUpdateStatus === JwtSecretUpdateStatus.Failed ? 'JWT secret update failed, new API key may have issues' : jwtSecretUpdateStatus === JwtSecretUpdateStatus.Updating ? 'Updating JWT secret...' : x?.api_key ?? 'You need additional permissions to view API keys' } onChange={() => {}} descriptionText={ x.tags === 'service_role' ? 'This key has the ability to bypass Row Level Security. Never share it publicly. ' + (legacy ? 'Prefer using Publishable API keys instead.' : '') : 'This key is safe to use in a browser if you have enabled Row Level Security for your tables and configured policies. ' + (legacy ? 'Prefer using Secret API keys instead.' : '') } /> )) )}
) } export default DisplayApiSettings