mirror of
https://github.com/supabase/supabase.git
synced 2026-09-08 19:08:44 +08:00
Multigres (High Availability) projects ship with legacy API keys disabled and the management API rejects re-enabling them, so the Dashboard should not surface them at all. Hides the "Legacy anon, service_role API keys" tab, renders an empty state on the legacy page for direct URL access, and drops the "Copy anonymous API key" / "Copy service API key" commands from the command menu. Non-HA projects are unchanged. Fixes FE-4276 <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * High Availability projects now hide legacy API key navigation and commands. * Legacy API key settings display an unavailable message for High Availability projects. * Publishable and secret key options remain available where supported. * Other projects continue to provide access to supported legacy API key options. * **Bug Fixes** * Prevented unsupported legacy API key controls from appearing on High Availability projects. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Joshen Lim <joshenlimek@gmail.com>
185 lines
5.5 KiB
TypeScript
185 lines
5.5 KiB
TypeScript
import { PermissionAction } from '@supabase/shared-types/out/constants'
|
|
import { Key } from 'lucide-react'
|
|
import { useMemo } from 'react'
|
|
import { toast } from 'sonner'
|
|
import { Badge, copyToClipboard } from 'ui'
|
|
import type { ICommand } from 'ui-patterns/CommandMenu'
|
|
import {
|
|
PageType,
|
|
useRegisterCommands,
|
|
useRegisterPage,
|
|
useResetCommandMenu,
|
|
useSetCommandMenuOpen,
|
|
useSetPage,
|
|
} from 'ui-patterns/CommandMenu'
|
|
|
|
import { COMMAND_MENU_SECTIONS } from './CommandMenu.utils'
|
|
import { orderCommandSectionsByPriority } from './ordering'
|
|
import { useAPIKeys } from '@/data/api-keys/api-keys-query'
|
|
import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions'
|
|
import { useHighAvailability } from '@/hooks/misc/useHighAvailability'
|
|
import { useSelectedProjectQuery } from '@/hooks/misc/useSelectedProject'
|
|
|
|
const API_KEYS_PAGE_NAME = 'API Keys'
|
|
|
|
export function useApiKeysCommands() {
|
|
const setIsOpen = useSetCommandMenuOpen()
|
|
const resetCommandMenu = useResetCommandMenu()
|
|
const setPage = useSetPage()
|
|
|
|
const { data: project } = useSelectedProjectQuery()
|
|
const ref = project?.ref || '_'
|
|
|
|
const { can: canReadAPIKeys } = useAsyncCheckPermissions(PermissionAction.SECRETS_READ, '*')
|
|
const { isHighAvailability } = useHighAvailability()
|
|
|
|
const { data: apiKeysData } = useAPIKeys(
|
|
{ projectRef: project?.ref, reveal: true },
|
|
{ enabled: canReadAPIKeys }
|
|
)
|
|
const commands = useMemo(() => {
|
|
const {
|
|
anonKey: legacyAnonKey,
|
|
serviceKey: legacyServiceKey,
|
|
publishableKey,
|
|
allSecretKeys,
|
|
} = canReadAPIKeys ? (apiKeysData ?? {}) : {}
|
|
|
|
const anonKey = isHighAvailability ? undefined : legacyAnonKey
|
|
const serviceKey = isHighAvailability ? undefined : legacyServiceKey
|
|
|
|
return [
|
|
project &&
|
|
publishableKey && {
|
|
id: 'publishable-key',
|
|
name: `Copy publishable key`,
|
|
action: () => {
|
|
copyToClipboard(publishableKey.api_key ?? '', () => {
|
|
toast.success('Publishable key copied to clipboard')
|
|
})
|
|
setIsOpen(false)
|
|
resetCommandMenu()
|
|
},
|
|
badge: () => (
|
|
<span className="flex items-center gap-x-1">
|
|
<Badge>Project: {project?.name}</Badge>
|
|
<Badge>{publishableKey.type}</Badge>
|
|
</span>
|
|
),
|
|
icon: () => <Key />,
|
|
},
|
|
...(project && allSecretKeys
|
|
? allSecretKeys.map((key) => ({
|
|
id: key.id,
|
|
name: `Copy secret key (${key.name})`,
|
|
action: () => {
|
|
copyToClipboard(key.api_key ?? '', () => {
|
|
toast.success('Secret key copied to clipboard')
|
|
})
|
|
setIsOpen(false)
|
|
resetCommandMenu()
|
|
},
|
|
badge: () => (
|
|
<span className="flex items-center gap-x-1">
|
|
<Badge>Project: {project?.name}</Badge>
|
|
<Badge>{key.type}</Badge>
|
|
</span>
|
|
),
|
|
icon: () => <Key />,
|
|
}))
|
|
: []),
|
|
project &&
|
|
anonKey && {
|
|
id: 'anon-key',
|
|
name: `Copy anonymous API key`,
|
|
action: () => {
|
|
copyToClipboard(anonKey.api_key ?? '', () => {
|
|
toast.success('Anonymous API key copied to clipboard')
|
|
})
|
|
setIsOpen(false)
|
|
resetCommandMenu()
|
|
},
|
|
badge: () => (
|
|
<span className="flex items-center gap-x-1">
|
|
<Badge>Project: {project?.name}</Badge>
|
|
<Badge>Public</Badge>
|
|
<Badge>{anonKey.type}</Badge>
|
|
</span>
|
|
),
|
|
icon: () => <Key />,
|
|
},
|
|
project &&
|
|
serviceKey && {
|
|
id: 'service-key',
|
|
name: `Copy service API key`,
|
|
action: () => {
|
|
copyToClipboard(serviceKey.api_key ?? '', () => {
|
|
toast.success('Service key copied to clipboard')
|
|
})
|
|
setIsOpen(false)
|
|
resetCommandMenu()
|
|
},
|
|
badge: () => (
|
|
<span className="flex items-center gap-x-1">
|
|
<Badge>Project: {project?.name}</Badge>
|
|
<Badge variant="destructive">Secret</Badge>
|
|
<Badge>{serviceKey.type}</Badge>
|
|
</span>
|
|
),
|
|
icon: () => <Key />,
|
|
},
|
|
!(anonKey || serviceKey) && {
|
|
id: 'api-keys-project-settings',
|
|
name: 'See API keys in Project Settings',
|
|
route: `/project/${ref}/settings/api-keys`,
|
|
icon: () => <Key />,
|
|
},
|
|
].filter(Boolean) as ICommand[]
|
|
}, [canReadAPIKeys, apiKeysData, isHighAvailability, project, ref, resetCommandMenu, setIsOpen])
|
|
|
|
useRegisterPage(
|
|
API_KEYS_PAGE_NAME,
|
|
{
|
|
type: PageType.Commands,
|
|
sections: [
|
|
{
|
|
id: 'api-keys',
|
|
name: 'API keys',
|
|
commands,
|
|
},
|
|
],
|
|
},
|
|
{ deps: [commands], enabled: !!project && commands.length > 0 }
|
|
)
|
|
|
|
useRegisterCommands(
|
|
COMMAND_MENU_SECTIONS.ACTIONS,
|
|
[
|
|
{
|
|
id: 'api-keys',
|
|
name: 'Get API keys...',
|
|
action: () => setPage(API_KEYS_PAGE_NAME),
|
|
icon: () => <Key />,
|
|
},
|
|
],
|
|
{
|
|
enabled: !!project && commands.length > 0,
|
|
orderSection: orderCommandSectionsByPriority,
|
|
sectionMeta: { priority: 3 },
|
|
}
|
|
)
|
|
|
|
useRegisterCommands(
|
|
COMMAND_MENU_SECTIONS.NAVIGATE,
|
|
[
|
|
{
|
|
id: 'nav-api-keys',
|
|
name: 'Go to API Keys',
|
|
route: `/project/${ref}/settings/api-keys`,
|
|
icon: () => <Key />,
|
|
},
|
|
],
|
|
{ enabled: !!project }
|
|
)
|
|
}
|