mirror of
https://github.com/supabase/supabase.git
synced 2026-10-06 09:55:06 +03:00
refactor: complete replacing useAsyncCheckPermissions with V2
This commit is contained in:
1 parent
d4d84f45e7
commit
80bea0660e
59 files changed
+262
-375
No files matched your search
@@ -65,7 +65,7 @@ export const JWTSecretKeysTable = () => {
|
||||
const showApiKeysLastUsed = useFlag('showApiKeysLastUsed')
|
||||
|
||||
const { can: canReadAPIKeys, isLoading: isLoadingCanReadAPIKeys } = useAsyncCheckPermissionsV2(
|
||||
FGA_PERMISSIONS.PROJECT.API_GATEWAY_KEYS_READ
|
||||
FGA_PERMISSIONS.PROJECT.AUTH_SIGNING_KEYS_READ
|
||||
)
|
||||
const now = useRef(new Date()).current
|
||||
const {
|
||||
|
||||
@@ -86,7 +86,7 @@ export const JWTSettings = () => {
|
||||
const [isRegeneratingKey, setIsGeneratingKey] = useState<boolean>(false)
|
||||
|
||||
const { can: canReadJWTSecret } = useAsyncCheckPermissionsV2(
|
||||
FGA_PERMISSIONS.PROJECT.DATA_API_CONFIG_SECRET_READ
|
||||
FGA_PERMISSIONS.PROJECT.AUTH_SIGNING_KEYS_READ
|
||||
)
|
||||
const { can: canGenerateNewJWTSecret } = useAsyncCheckPermissionsV2(
|
||||
FGA_PERMISSIONS.PROJECT.ADMIN_WRITE
|
||||
@@ -97,7 +97,7 @@ export const JWTSettings = () => {
|
||||
const { mutateAsync: updateJwt, isPending: isSubmittingJwtSecretUpdateRequest } =
|
||||
useJwtSecretUpdateMutation()
|
||||
|
||||
const { can: canReadAPIKeys } = useAsyncCheckPermissionsV2(FGA_PERMISSIONS.PROJECT.API_GATEWAY_KEYS_READ)
|
||||
const { can: canReadAPIKeys } = useAsyncCheckPermissionsV2(FGA_PERMISSIONS.PROJECT.AUTH_SIGNING_KEYS_READ)
|
||||
const { data: legacyKey, isPending } = useLegacyJWTSigningKeyQuery(
|
||||
{ projectRef },
|
||||
{ enabled: IS_PLATFORM && canReadAPIKeys, retry: false }
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { PermissionAction } from '@supabase/shared-types/out/constants'
|
||||
import { useParams } from 'common'
|
||||
import { useRouter } from 'next/router'
|
||||
import { cn } from 'ui'
|
||||
@@ -14,9 +13,8 @@ import {
|
||||
import { ButtonTooltip } from '@/components/ui/ButtonTooltip'
|
||||
import { InlineLink } from '@/components/ui/InlineLink'
|
||||
import { useProjectSettingsV2Query } from '@/data/config/project-settings-v2-query'
|
||||
import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions'
|
||||
import { useSelectedProjectQuery } from '@/hooks/misc/useSelectedProject'
|
||||
import { DOCS_URL } from '@/lib/constants'
|
||||
import { FGA_PERMISSIONS, useAsyncCheckPermissionsV2 } from '@/hooks/misc/useCheckPermissionsV2'
|
||||
|
||||
export type LogicalBackupCliInstructionsProps = {
|
||||
enabled?: boolean
|
||||
@@ -33,15 +31,8 @@ export const LogicalBackupCliInstructions = ({
|
||||
}: LogicalBackupCliInstructionsProps) => {
|
||||
const router = useRouter()
|
||||
const { ref } = useParams()
|
||||
const { data: project } = useSelectedProjectQuery()
|
||||
const { can: canResetDbPassword } = useAsyncCheckPermissions(
|
||||
PermissionAction.UPDATE,
|
||||
'projects',
|
||||
{
|
||||
resource: {
|
||||
project_id: project?.id,
|
||||
},
|
||||
}
|
||||
const { can: canResetDbPassword } = useAsyncCheckPermissionsV2(
|
||||
FGA_PERMISSIONS.PROJECT.DATABASE_CONFIG_WRITE
|
||||
)
|
||||
|
||||
const {
|
||||
@@ -53,11 +44,11 @@ export const LogicalBackupCliInstructions = ({
|
||||
const connectionUri =
|
||||
isSuccess && settings
|
||||
? buildDirectPostgresConnectionUri({
|
||||
db_user: settings.db_user,
|
||||
db_host: settings.db_host,
|
||||
db_port: settings.db_port,
|
||||
db_name: settings.db_name,
|
||||
})
|
||||
db_user: settings.db_user,
|
||||
db_host: settings.db_host,
|
||||
db_port: settings.db_port,
|
||||
db_name: settings.db_name,
|
||||
})
|
||||
: null
|
||||
|
||||
const shellScript = connectionUri ? buildLogicalBackupShellScript(connectionUri) : ''
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { PermissionAction, SupportCategories } from '@supabase/shared-types/out/constants'
|
||||
import { SupportCategories } from '@supabase/shared-types/out/constants'
|
||||
import { useParams } from 'common'
|
||||
import { Download, MoreVertical, Trash } from 'lucide-react'
|
||||
import { useState } from 'react'
|
||||
@@ -24,8 +24,8 @@ import { DropdownMenuItemTooltip } from '@/components/ui/DropdownMenuItemTooltip
|
||||
import { InlineLink } from '@/components/ui/InlineLink'
|
||||
import { useBackupDownloadMutation } from '@/data/database/backup-download-mutation'
|
||||
import { useDownloadableBackupQuery } from '@/data/database/backup-query'
|
||||
import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions'
|
||||
import { useSelectedProjectQuery } from '@/hooks/misc/useSelectedProject'
|
||||
import { useAsyncCheckPermissionsV2, FGA_PERMISSIONS } from '@/hooks/misc/useCheckPermissionsV2'
|
||||
|
||||
export const PauseFailedState = () => {
|
||||
const { ref } = useParams()
|
||||
@@ -33,9 +33,9 @@ export const PauseFailedState = () => {
|
||||
const [visible, setVisible] = useState(false)
|
||||
const [showCliBackup, setShowCliBackup] = useState(false)
|
||||
|
||||
const { can: canDeleteProject } = useAsyncCheckPermissions(PermissionAction.UPDATE, 'projects', {
|
||||
resource: { project_id: project?.id },
|
||||
})
|
||||
const { can: canDeleteProject } = useAsyncCheckPermissionsV2(
|
||||
FGA_PERMISSIONS.PROJECT.ADMIN_WRITE
|
||||
)
|
||||
|
||||
const { data, isPending: isLoadingBackups } = useDownloadableBackupQuery({ projectRef: ref })
|
||||
const backups = data?.backups ?? []
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { PermissionAction, SupportCategories } from '@supabase/shared-types/out/constants'
|
||||
import { SupportCategories } from '@supabase/shared-types/out/constants'
|
||||
import { useParams } from 'common'
|
||||
import { Download, MoreVertical, Trash } from 'lucide-react'
|
||||
import { useState } from 'react'
|
||||
@@ -24,8 +24,8 @@ import { DropdownMenuItemTooltip } from '@/components/ui/DropdownMenuItemTooltip
|
||||
import { InlineLink } from '@/components/ui/InlineLink'
|
||||
import { useBackupDownloadMutation } from '@/data/database/backup-download-mutation'
|
||||
import { useDownloadableBackupQuery } from '@/data/database/backup-query'
|
||||
import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions'
|
||||
import { useSelectedProjectQuery } from '@/hooks/misc/useSelectedProject'
|
||||
import { useAsyncCheckPermissionsV2, FGA_PERMISSIONS } from '@/hooks/misc/useCheckPermissionsV2'
|
||||
|
||||
export const RestoreFailedState = () => {
|
||||
const { ref } = useParams()
|
||||
@@ -33,9 +33,9 @@ export const RestoreFailedState = () => {
|
||||
const [visible, setVisible] = useState(false)
|
||||
const [showCliBackup, setShowCliBackup] = useState(false)
|
||||
|
||||
const { can: canDeleteProject } = useAsyncCheckPermissions(PermissionAction.UPDATE, 'projects', {
|
||||
resource: { project_id: project?.id },
|
||||
})
|
||||
const { can: canDeleteProject } = useAsyncCheckPermissionsV2(
|
||||
FGA_PERMISSIONS.PROJECT.ADMIN_WRITE
|
||||
)
|
||||
|
||||
const { data, isPending: isLoadingBackups } = useDownloadableBackupQuery({ projectRef: ref })
|
||||
const backups = data?.backups ?? []
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { PermissionAction } from '@supabase/shared-types/out/constants'
|
||||
import { useParams } from 'common'
|
||||
import { AlertTriangle } from 'lucide-react'
|
||||
import { useRouter } from 'next/router'
|
||||
@@ -9,9 +8,9 @@ import ConfirmationModal from 'ui-patterns/Dialogs/ConfirmationModal'
|
||||
|
||||
import { useProjectDetailQuery, useSetProjectStatus } from '@/data/projects/project-detail-query'
|
||||
import { useProjectRestartMutation } from '@/data/projects/project-restart-mutation'
|
||||
import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions'
|
||||
import { useSelectedProjectQuery } from '@/hooks/misc/useSelectedProject'
|
||||
import { PROJECT_STATUS } from '@/lib/constants'
|
||||
import { useAsyncCheckPermissionsV2 } from '@/hooks/misc/useCheckPermissionsV2'
|
||||
|
||||
export const UnhealthyState = () => {
|
||||
const router = useRouter()
|
||||
@@ -20,9 +19,8 @@ export const UnhealthyState = () => {
|
||||
const { setProjectStatus } = useSetProjectStatus()
|
||||
const [showConfirm, setShowConfirm] = useState(false)
|
||||
|
||||
const { can: canRestartProject } = useAsyncCheckPermissions(
|
||||
PermissionAction.INFRA_EXECUTE,
|
||||
'reboot'
|
||||
const { can: canRestartProject } = useAsyncCheckPermissionsV2(
|
||||
'project_operations_write'
|
||||
)
|
||||
|
||||
useProjectDetailQuery(
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { PermissionAction } from '@supabase/shared-types/out/constants'
|
||||
import { LOCAL_STORAGE_KEYS, useParams } from 'common'
|
||||
import { PropsWithChildren, useEffect } from 'react'
|
||||
|
||||
@@ -8,8 +7,8 @@ import { useIsQueueOperationsEnabled } from '@/components/interfaces/Account/Pre
|
||||
import { BannerTableEditorQueueOperations } from '@/components/ui/BannerStack/Banners/BannerTableEditorQueueOperations'
|
||||
import { useBannerStack } from '@/components/ui/BannerStack/BannerStackProvider'
|
||||
import { NoPermission } from '@/components/ui/NoPermission'
|
||||
import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions'
|
||||
import { useLocalStorageQuery } from '@/hooks/misc/useLocalStorage'
|
||||
import { useAsyncCheckPermissionsV2, FGA_PERMISSIONS } from '@/hooks/misc/useCheckPermissionsV2'
|
||||
|
||||
export const TableEditorLayout = ({ children }: PropsWithChildren<{}>) => {
|
||||
const { ref } = useParams()
|
||||
@@ -21,14 +20,12 @@ export const TableEditorLayout = ({ children }: PropsWithChildren<{}>) => {
|
||||
false
|
||||
)
|
||||
|
||||
const { can: canReadTables, isSuccess: isPermissionsLoaded } = useAsyncCheckPermissions(
|
||||
PermissionAction.TENANT_SQL_ADMIN_READ,
|
||||
'tables'
|
||||
const { can: canReadTables, isSuccess: isPermissionsLoaded } = useAsyncCheckPermissionsV2(
|
||||
FGA_PERMISSIONS.PROJECT.DATABASE_READ
|
||||
)
|
||||
|
||||
const { can: canWriteTables } = useAsyncCheckPermissions(
|
||||
PermissionAction.TENANT_SQL_ADMIN_WRITE,
|
||||
'tables'
|
||||
const { can: canWriteTables } = useAsyncCheckPermissionsV2(
|
||||
FGA_PERMISSIONS.PROJECT.DATABASE_WRITE
|
||||
)
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { PermissionAction } from '@supabase/shared-types/out/constants'
|
||||
import { keepPreviousData } from '@tanstack/react-query'
|
||||
import { useParams } from 'common'
|
||||
import { Filter, Plus } from 'lucide-react'
|
||||
@@ -31,7 +30,6 @@ import { ENTITY_TYPE } from '@/data/entity-types/entity-type-constants'
|
||||
import { useEntityTypesQuery } from '@/data/entity-types/entity-types-infinite-query'
|
||||
import { useTableApiAccessQuery } from '@/data/privileges/table-api-access-query'
|
||||
import { getTableEditor, useTableEditorQuery } from '@/data/table-editor/table-editor-query'
|
||||
import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions'
|
||||
import { useLocalStorage } from '@/hooks/misc/useLocalStorage'
|
||||
import { useQuerySchemaState } from '@/hooks/misc/useSchemaQueryState'
|
||||
import { useSelectedProjectQuery } from '@/hooks/misc/useSelectedProject'
|
||||
@@ -39,6 +37,7 @@ import { useIsProtectedSchema } from '@/hooks/useProtectedSchemas'
|
||||
import { SHORTCUT_IDS } from '@/state/shortcuts/registry'
|
||||
import { useShortcut } from '@/state/shortcuts/useShortcut'
|
||||
import { useTableEditorStateSnapshot } from '@/state/table-editor'
|
||||
import { useAsyncCheckPermissionsV2, FGA_PERMISSIONS } from '@/hooks/misc/useCheckPermissionsV2'
|
||||
|
||||
type Sort = 'alphabetical' | 'grouped-alphabetical'
|
||||
|
||||
@@ -95,9 +94,8 @@ export const TableEditorMenu = () => {
|
||||
{ enabled: Boolean(selectedSchema && entityNames.length > 0) }
|
||||
)
|
||||
|
||||
const { can: canCreateTables } = useAsyncCheckPermissions(
|
||||
PermissionAction.TENANT_SQL_ADMIN_WRITE,
|
||||
'tables'
|
||||
const { can: canCreateTables } = useAsyncCheckPermissionsV2(
|
||||
FGA_PERMISSIONS.PROJECT.DATABASE_WRITE
|
||||
)
|
||||
|
||||
const { isSchemaLocked } = useIsProtectedSchema({ schema: selectedSchema })
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { PermissionAction } from '@supabase/shared-types/out/constants'
|
||||
import { useEffect } from 'react'
|
||||
import {
|
||||
Button,
|
||||
@@ -15,7 +14,7 @@ import {
|
||||
|
||||
import { AIOptInLevelSelector } from '@/components/interfaces/Organization/GeneralSettings/AIOptInLevelSelector'
|
||||
import { useAIOptInForm } from '@/hooks/forms/useAIOptInForm'
|
||||
import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions'
|
||||
import { useAsyncCheckPermissionsV2, FGA_PERMISSIONS } from '@/hooks/misc/useCheckPermissionsV2'
|
||||
|
||||
interface AIOptInModalProps {
|
||||
visible: boolean
|
||||
@@ -24,9 +23,8 @@ interface AIOptInModalProps {
|
||||
|
||||
export const AIOptInModal = ({ visible, onCancel }: AIOptInModalProps) => {
|
||||
const { form, onSubmit, isUpdating, currentOptInLevel } = useAIOptInForm(onCancel)
|
||||
const { can: canUpdateOrganization } = useAsyncCheckPermissions(
|
||||
PermissionAction.UPDATE,
|
||||
'organizations'
|
||||
const { can: canUpdateOrganization } = useAsyncCheckPermissionsV2(
|
||||
FGA_PERMISSIONS.ORGANIZATION.ADMIN_WRITE
|
||||
)
|
||||
|
||||
const onOpenChange = (open: boolean) => {
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { PermissionAction } from '@supabase/shared-types/out/constants'
|
||||
import { LOCAL_STORAGE_KEYS, useParams } from 'common'
|
||||
import { ShieldCheck, X } from 'lucide-react'
|
||||
import { useMemo, useState } from 'react'
|
||||
@@ -22,10 +21,10 @@ import { AUTO_ENABLE_RLS_EVENT_TRIGGER_SQL } from '@/components/interfaces/Datab
|
||||
import { ButtonTooltip } from '@/components/ui/ButtonTooltip'
|
||||
import { useDatabaseEventTriggerCreateMutation } from '@/data/database-event-triggers/database-event-trigger-create-mutation'
|
||||
import { useDatabaseEventTriggersQuery } from '@/data/database-event-triggers/database-event-triggers-query'
|
||||
import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions'
|
||||
import { useLocalStorageQuery } from '@/hooks/misc/useLocalStorage'
|
||||
import { useSelectedProjectQuery } from '@/hooks/misc/useSelectedProject'
|
||||
import { useTrack } from '@/lib/telemetry/track'
|
||||
import { useAsyncCheckPermissionsV2, FGA_PERMISSIONS } from '@/hooks/misc/useCheckPermissionsV2'
|
||||
|
||||
export const AutoEnableRLSNotice = ({ iconOnly }: { iconOnly?: boolean }) => {
|
||||
const { ref } = useParams()
|
||||
@@ -87,9 +86,8 @@ const CreateEnsureRLSTriggerDialog = ({ iconOnly }: { iconOnly?: boolean }) => {
|
||||
|
||||
const [open, setOpen] = useState(false)
|
||||
|
||||
const { can: canCreateTriggers } = useAsyncCheckPermissions(
|
||||
PermissionAction.TENANT_SQL_ADMIN_WRITE,
|
||||
'triggers'
|
||||
const { can: canCreateTriggers } = useAsyncCheckPermissionsV2(
|
||||
FGA_PERMISSIONS.PROJECT.DATABASE_WRITE
|
||||
)
|
||||
|
||||
const { mutate: createEventTrigger, isPending: isCreating } =
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { PermissionAction } from '@supabase/shared-types/out/constants'
|
||||
import { JwtSecretUpdateStatus } from '@supabase/shared-types/out/events'
|
||||
import { IS_PLATFORM, useFlag, useParams } from 'common'
|
||||
import { AlertCircle, Loader2 } from 'lucide-react'
|
||||
@@ -13,7 +12,7 @@ import Panel from '@/components/ui/Panel'
|
||||
import { useApiKeysLastUsedQuery } from '@/data/analytics/api-keys-last-used-query'
|
||||
import { useJwtSecretUpdatingStatusQuery } from '@/data/config/jwt-secret-updating-status-query'
|
||||
import { useProjectSettingsV2Query } from '@/data/config/project-settings-v2-query'
|
||||
import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions'
|
||||
import { useAsyncCheckPermissionsV2, FGA_PERMISSIONS } from '@/hooks/misc/useCheckPermissionsV2'
|
||||
|
||||
export const DisplayApiSettings = ({
|
||||
showTitle = true,
|
||||
@@ -38,9 +37,8 @@ export const DisplayApiSettings = ({
|
||||
} = useJwtSecretUpdatingStatusQuery({ projectRef })
|
||||
const jwtSecretUpdateStatus = data?.jwtSecretUpdateStatus
|
||||
|
||||
const { isLoading: isLoadingPermissions, can: canReadAPIKeys } = useAsyncCheckPermissions(
|
||||
PermissionAction.READ,
|
||||
'service_api_keys'
|
||||
const { isLoading: isLoadingPermissions, can: canReadAPIKeys } = useAsyncCheckPermissionsV2(
|
||||
FGA_PERMISSIONS.PROJECT.API_GATEWAY_KEYS_READ
|
||||
)
|
||||
|
||||
const isLoading = isProjectSettingsLoading || isLoadingPermissions
|
||||
@@ -207,7 +205,7 @@ export const DisplayApiSettings = ({
|
||||
? 'Updating JWT secret...'
|
||||
: (x?.api_key ?? 'You need additional permissions to view API keys')
|
||||
}
|
||||
onChange={() => {}}
|
||||
onChange={() => { }}
|
||||
/>
|
||||
</FormLayout>
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { PermissionAction } from '@supabase/shared-types/out/constants'
|
||||
import { useParams } from 'common'
|
||||
import { useState } from 'react'
|
||||
import { toast } from 'sonner'
|
||||
@@ -20,8 +19,8 @@ import { useToggleLegacyAPIKeysMutation } from '@/data/api-keys/legacy-api-key-t
|
||||
import { useLegacyAPIKeysStatusQuery } from '@/data/api-keys/legacy-api-keys-status-query'
|
||||
import { useLegacyJWTSigningKeyQuery } from '@/data/jwt-signing-keys/legacy-jwt-signing-key-query'
|
||||
import { useAuthorizedAppsQuery } from '@/data/oauth/authorized-apps-query'
|
||||
import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions'
|
||||
import { useSelectedOrganizationQuery } from '@/hooks/misc/useSelectedOrganization'
|
||||
import { useAsyncCheckPermissionsV2, FGA_PERMISSIONS } from '@/hooks/misc/useCheckPermissionsV2'
|
||||
|
||||
export const ToggleLegacyApiKeysPanel = () => {
|
||||
const { ref: projectRef } = useParams()
|
||||
@@ -30,10 +29,11 @@ export const ToggleLegacyApiKeysPanel = () => {
|
||||
const [isConfirmOpen, setIsConfirmOpen] = useState(false)
|
||||
const [isAppsWarningOpen, setIsAppsWarningOpen] = useState(false)
|
||||
|
||||
const { can: canReadAPIKeys } = useAsyncCheckPermissions(PermissionAction.SECRETS_READ, '*')
|
||||
const { can: canUpdateAPIKeys, isSuccess: isPermissionsSuccess } = useAsyncCheckPermissions(
|
||||
PermissionAction.SECRETS_WRITE,
|
||||
'*'
|
||||
const { can: canReadAPIKeys } = useAsyncCheckPermissionsV2(
|
||||
FGA_PERMISSIONS.PROJECT.AUTH_SIGNING_KEYS_READ
|
||||
)
|
||||
const { can: canUpdateAPIKeys, isSuccess: isPermissionsSuccess } = useAsyncCheckPermissionsV2(
|
||||
FGA_PERMISSIONS.PROJECT.AUTH_SIGNING_KEYS_WRITE
|
||||
)
|
||||
|
||||
const { data: legacyAPIKeysStatusData, isSuccess: isLegacyAPIKeysStatusSuccess } =
|
||||
@@ -63,25 +63,25 @@ export const ToggleLegacyApiKeysPanel = () => {
|
||||
|
||||
const appsWarning = isAuthorizedAppsError
|
||||
? {
|
||||
title: 'Check your OAuth apps before continuing',
|
||||
description: (
|
||||
<>
|
||||
Disabling legacy API keys can break apps that integrate with Supabase. Before
|
||||
continuing, check your organization's {oauthAppsLink} to ensure none of them depend on
|
||||
the legacy API keys.
|
||||
</>
|
||||
),
|
||||
}
|
||||
title: 'Check your OAuth apps before continuing',
|
||||
description: (
|
||||
<>
|
||||
Disabling legacy API keys can break apps that integrate with Supabase. Before
|
||||
continuing, check your organization's {oauthAppsLink} to ensure none of them depend on
|
||||
the legacy API keys.
|
||||
</>
|
||||
),
|
||||
}
|
||||
: {
|
||||
title: 'Apps using Supabase may break',
|
||||
description: (
|
||||
<>
|
||||
Your project uses apps that integrate with Supabase. Disabling the legacy API keys is a
|
||||
brand new feature and the apps you're using may not have added support for this yet. It
|
||||
can cause them to stop functioning. Check your {oauthAppsLink} before continuing.
|
||||
</>
|
||||
),
|
||||
}
|
||||
title: 'Apps using Supabase may break',
|
||||
description: (
|
||||
<>
|
||||
Your project uses apps that integrate with Supabase. Disabling the legacy API keys is a
|
||||
brand new feature and the apps you're using may not have added support for this yet. It
|
||||
can cause them to stop functioning. Check your {oauthAppsLink} before continuing.
|
||||
</>
|
||||
),
|
||||
}
|
||||
|
||||
if (!(isLegacyAPIKeysStatusSuccess && isPermissionsSuccess)) {
|
||||
return null
|
||||
@@ -205,32 +205,32 @@ const ToggleApiKeysModal = ({
|
||||
alert={
|
||||
isLegacyKeysEnabled
|
||||
? {
|
||||
title: 'Ensure legacy keys are no longer in use before disabling',
|
||||
description: (
|
||||
<span className="prose text-sm">
|
||||
Disabling <code>anon</code> and <code>service_role</code> keys while they are in
|
||||
use will cause downtime for your application. Ensure they are no longer in use
|
||||
before proceeding. If you have not created a publishable and at least one secret
|
||||
API key, some dashboard functionality may become unavailable.
|
||||
<br />
|
||||
<br />
|
||||
<span className="text-danger">
|
||||
This disables API keys when used in the <code>apikey</code> header. They remain
|
||||
valid as a JWT.
|
||||
</span>
|
||||
title: 'Ensure legacy keys are no longer in use before disabling',
|
||||
description: (
|
||||
<span className="prose text-sm">
|
||||
Disabling <code>anon</code> and <code>service_role</code> keys while they are in
|
||||
use will cause downtime for your application. Ensure they are no longer in use
|
||||
before proceeding. If you have not created a publishable and at least one secret
|
||||
API key, some dashboard functionality may become unavailable.
|
||||
<br />
|
||||
<br />
|
||||
<span className="text-danger">
|
||||
This disables API keys when used in the <code>apikey</code> header. They remain
|
||||
valid as a JWT.
|
||||
</span>
|
||||
),
|
||||
}
|
||||
</span>
|
||||
),
|
||||
}
|
||||
: {
|
||||
title: 'Publishable and secret keys are preferred',
|
||||
description: (
|
||||
<span className="prose text-sm">
|
||||
Re-enabling <code>anon</code> and <code>service_role</code> keys may be
|
||||
appropriate in certain cases, but using a publishable and secret key is more
|
||||
secure. We recommend against re-enabling legacy API keys.
|
||||
</span>
|
||||
),
|
||||
}
|
||||
title: 'Publishable and secret keys are preferred',
|
||||
description: (
|
||||
<span className="prose text-sm">
|
||||
Re-enabling <code>anon</code> and <code>service_role</code> keys may be
|
||||
appropriate in certain cases, but using a publishable and secret key is more
|
||||
secure. We recommend against re-enabling legacy API keys.
|
||||
</span>
|
||||
),
|
||||
}
|
||||
}
|
||||
/>
|
||||
)
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { PermissionAction } from '@supabase/shared-types/out/constants'
|
||||
import { Check, Plus } from 'lucide-react'
|
||||
import { ComponentPropsWithoutRef, forwardRef, useMemo, useState } from 'react'
|
||||
import {
|
||||
@@ -23,9 +22,9 @@ import {
|
||||
|
||||
import { RestartProjectDialog } from '@/components/interfaces/ErrorHandling/RestartProjectDialog'
|
||||
import { useSchemasQuery } from '@/data/database/schemas-query'
|
||||
import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions'
|
||||
import { useSchemasFilteredForHighAvailability } from '@/hooks/misc/useHighAvailability'
|
||||
import { useSelectedProjectQuery } from '@/hooks/misc/useSelectedProject'
|
||||
import { useAsyncCheckPermissionsV2, FGA_PERMISSIONS } from '@/hooks/misc/useCheckPermissionsV2'
|
||||
|
||||
type SchemaSelectorProps = Omit<ComponentPropsWithoutRef<'div'>, 'onSelect'> & {
|
||||
disabled?: boolean
|
||||
@@ -72,9 +71,8 @@ export const SchemaSelector = forwardRef<HTMLDivElement, SchemaSelectorProps>(
|
||||
if (!isControlled) setInternalOpen(next)
|
||||
onOpenChange?.(next)
|
||||
}
|
||||
const { can: canCreateSchemas } = useAsyncCheckPermissions(
|
||||
PermissionAction.TENANT_SQL_ADMIN_WRITE,
|
||||
'schemas'
|
||||
const { can: canCreateSchemas } = useAsyncCheckPermissionsV2(
|
||||
FGA_PERMISSIONS.PROJECT.DATABASE_WRITE
|
||||
)
|
||||
|
||||
const { data: project } = useSelectedProjectQuery()
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { PermissionAction } from '@supabase/shared-types/out/constants'
|
||||
import { useFlag, useParams } from 'common'
|
||||
import Link from 'next/link'
|
||||
import { PropsWithChildren } from 'react'
|
||||
@@ -8,9 +7,9 @@ import { ButtonTooltip } from './ButtonTooltip'
|
||||
import { RequestUpgradeToBillingOwners } from './RequestUpgradeToBillingOwners'
|
||||
import { getInfrastructurePath } from '@/components/interfaces/Settings/Infrastructure/Infrastructure.utils'
|
||||
import { SupportLink } from '@/components/interfaces/Support/SupportLink'
|
||||
import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions'
|
||||
import { useIsFeatureEnabled } from '@/hooks/misc/useIsFeatureEnabled'
|
||||
import { useSelectedOrganizationQuery } from '@/hooks/misc/useSelectedOrganization'
|
||||
import { useAsyncCheckPermissionsV2 } from '@/hooks/misc/useCheckPermissionsV2'
|
||||
|
||||
export const PLAN_REQUEST_EMPTY_PLACEHOLDER =
|
||||
'<Specify which plan to upgrade to: Pro | Team | Enterprise>'
|
||||
@@ -54,10 +53,8 @@ export const UpgradePlanButton = ({
|
||||
const projectUpdateDisabled = useFlag('disableProjectCreationAndUpdate')
|
||||
const { billingAll } = useIsFeatureEnabled(['billing:all'])
|
||||
|
||||
const { can: canUpdateSubscription } = useAsyncCheckPermissions(
|
||||
PermissionAction.BILLING_WRITE,
|
||||
'stripe.subscriptions',
|
||||
undefined,
|
||||
const { can: canUpdateSubscription } = useAsyncCheckPermissionsV2(
|
||||
'billing_write',
|
||||
{ organizationSlug: slug }
|
||||
)
|
||||
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
import { PermissionAction } from '@supabase/shared-types/out/constants'
|
||||
import { useQuery } from '@tanstack/react-query'
|
||||
|
||||
import { configKeys } from './keys'
|
||||
import type { components } from '@/data/api'
|
||||
import { get, handleError } from '@/data/fetchers'
|
||||
import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions'
|
||||
import type { ResponseError, UseCustomQueryOptions } from '@/types'
|
||||
import { useAsyncCheckPermissionsV2, FGA_PERMISSIONS } from '@/hooks/misc/useCheckPermissionsV2'
|
||||
|
||||
export type ProjectSettingsVariables = { projectRef?: string }
|
||||
|
||||
@@ -46,9 +45,8 @@ export const useProjectSettingsV2Query = <TData = ProjectSettingsData>(
|
||||
) => {
|
||||
// [Joshen] Sync with API perms checking here - shouldReturnApiKeys
|
||||
// https://github.com/supabase/platform/blob/develop/api/src/routes/platform/projects/ref/settings.controller.ts#L92
|
||||
const { can: canReadAPIKeys } = useAsyncCheckPermissions(
|
||||
PermissionAction.TENANT_SQL_ADMIN_WRITE,
|
||||
'*'
|
||||
const { can: canReadAPIKeys } = useAsyncCheckPermissionsV2(
|
||||
FGA_PERMISSIONS.PROJECT.API_GATEWAY_KEYS_READ
|
||||
)
|
||||
|
||||
return useQuery<ProjectSettingsData, ProjectSettingsError, TData>({
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
import { PermissionAction } from '@supabase/shared-types/out/constants'
|
||||
import { useQuery } from '@tanstack/react-query'
|
||||
import { IS_PLATFORM } from 'common'
|
||||
|
||||
import { organizationKeys } from './keys'
|
||||
import { get, handleError } from '@/data/fetchers'
|
||||
import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions'
|
||||
import type { ResponseError, UseCustomQueryOptions } from '@/types'
|
||||
import { useAsyncCheckPermissionsV2 } from '@/hooks/misc/useCheckPermissionsV2'
|
||||
|
||||
export type OrganizationCustomerProfileVariables = {
|
||||
slug?: string
|
||||
@@ -48,10 +47,8 @@ export const useOrganizationCustomerProfileQuery = <TData = OrganizationCustomer
|
||||
) => {
|
||||
// [Joshen] Thinking it makes sense to add this check at the RQ level - prevent
|
||||
// unnecessary requests, although this behaviour still needs handling on the UI
|
||||
const { can: canReadCustomerProfile } = useAsyncCheckPermissions(
|
||||
PermissionAction.BILLING_READ,
|
||||
'stripe.customer',
|
||||
undefined,
|
||||
const { can: canReadCustomerProfile } = useAsyncCheckPermissionsV2(
|
||||
'billing_read',
|
||||
{ organizationSlug: slug }
|
||||
)
|
||||
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
import { PermissionAction } from '@supabase/shared-types/out/constants'
|
||||
import { useQuery } from '@tanstack/react-query'
|
||||
import { components } from 'api-types'
|
||||
|
||||
import { organizationKeys } from './keys'
|
||||
import { get, handleError } from '@/data/fetchers'
|
||||
import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions'
|
||||
import type { ResponseError, UseCustomQueryOptions } from '@/types'
|
||||
import { useAsyncCheckPermissionsV2 } from '@/hooks/misc/useCheckPermissionsV2'
|
||||
|
||||
export type OrganizationPaymentMethodsVariables = { slug?: string }
|
||||
export type OrganizationPaymentMethod = components['schemas']['PaymentsResponse_Output']['data'][0]
|
||||
@@ -48,9 +47,8 @@ export const useOrganizationPaymentMethodsQuery = <TData = OrganizationPaymentMe
|
||||
TData
|
||||
> = {}
|
||||
) => {
|
||||
const { can: canReadSubscriptions } = useAsyncCheckPermissions(
|
||||
PermissionAction.BILLING_READ,
|
||||
'stripe.payment_methods'
|
||||
const { can: canReadSubscriptions } = useAsyncCheckPermissionsV2(
|
||||
'billing_read'
|
||||
)
|
||||
return useQuery<OrganizationPaymentMethodsData, OrganizationPaymentMethodsError, TData>({
|
||||
queryKey: organizationKeys.paymentMethods(slug),
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
import { PermissionAction } from '@supabase/shared-types/out/constants'
|
||||
import { useQuery } from '@tanstack/react-query'
|
||||
import { components } from 'api-types'
|
||||
|
||||
import { organizationKeys } from './keys'
|
||||
import { get, handleError } from '@/data/fetchers'
|
||||
import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions'
|
||||
import type { ResponseError, UseCustomQueryOptions } from '@/types'
|
||||
import { useAsyncCheckPermissionsV2 } from '@/hooks/misc/useCheckPermissionsV2'
|
||||
|
||||
export type OrganizationTaxIdVariables = {
|
||||
slug?: string
|
||||
@@ -36,9 +35,8 @@ export const useOrganizationTaxIdQuery = <TData = OrganizationTaxIdData>(
|
||||
...options
|
||||
}: UseCustomQueryOptions<OrganizationTaxIdData, OrganizationTaxIdError, TData> = {}
|
||||
) => {
|
||||
const { can: canReadSubscriptions } = useAsyncCheckPermissions(
|
||||
PermissionAction.BILLING_READ,
|
||||
'stripe.tax_ids'
|
||||
const { can: canReadSubscriptions } = useAsyncCheckPermissionsV2(
|
||||
'billing_read'
|
||||
)
|
||||
|
||||
return useQuery<OrganizationTaxIdData, OrganizationTaxIdError, TData>({
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import { PermissionAction } from '@supabase/shared-types/out/constants'
|
||||
|
||||
import { useS3AccessKeyCreateMutation } from './s3-access-key-create-mutation'
|
||||
import { WRAPPERS } from '@/components/interfaces/Integrations/Wrappers/Wrappers.constants'
|
||||
import {
|
||||
@@ -13,13 +11,15 @@ import {
|
||||
import { useAPIKeys } from '@/data/api-keys/api-keys-query'
|
||||
import { useProjectSettingsV2Query } from '@/data/config/project-settings-v2-query'
|
||||
import { FDWCreateVariables, useFDWCreateMutation } from '@/data/fdw/fdw-create-mutation'
|
||||
import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions'
|
||||
import { useSelectedProjectQuery } from '@/hooks/misc/useSelectedProject'
|
||||
import { useAsyncCheckPermissionsV2, FGA_PERMISSIONS } from '@/hooks/misc/useCheckPermissionsV2'
|
||||
|
||||
export const useIcebergWrapperCreateMutation = () => {
|
||||
const { data: project } = useSelectedProjectQuery()
|
||||
|
||||
const { can: canReadAPIKeys } = useAsyncCheckPermissions(PermissionAction.SECRETS_READ, '*')
|
||||
const { can: canReadAPIKeys } = useAsyncCheckPermissionsV2(
|
||||
FGA_PERMISSIONS.PROJECT.API_GATEWAY_KEYS_SECRET_READ
|
||||
)
|
||||
const { data: apiKeysData } = useAPIKeys(
|
||||
{ projectRef: project?.ref, reveal: true },
|
||||
{ enabled: canReadAPIKeys }
|
||||
@@ -33,9 +33,8 @@ export const useIcebergWrapperCreateMutation = () => {
|
||||
|
||||
const wrapperMeta = WRAPPERS.find((wrapper) => wrapper.name === 'iceberg_wrapper')
|
||||
|
||||
const { can: canCreateCredentials } = useAsyncCheckPermissions(
|
||||
PermissionAction.STORAGE_ADMIN_WRITE,
|
||||
'*'
|
||||
const { can: canCreateCredentials } = useAsyncCheckPermissionsV2(
|
||||
FGA_PERMISSIONS.PROJECT.STORAGE_CONFIG_WRITE
|
||||
)
|
||||
|
||||
const { mutateAsync: createS3AccessKey, isPending: isCreatingS3AccessKey } =
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { PermissionAction } from '@supabase/shared-types/out/constants'
|
||||
import { IS_PLATFORM } from 'common'
|
||||
|
||||
import { useLocalS3KeysQuery } from '../misc/local-s3-keys-query'
|
||||
@@ -12,9 +11,9 @@ import {
|
||||
} from '@/components/interfaces/Storage/VectorBuckets/VectorBuckets.utils'
|
||||
import { useProjectSettingsV2Query } from '@/data/config/project-settings-v2-query'
|
||||
import { FDWCreateVariables, useFDWCreateMutation } from '@/data/fdw/fdw-create-mutation'
|
||||
import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions'
|
||||
import { useDeploymentMode } from '@/hooks/misc/useDeploymentMode'
|
||||
import { useSelectedProjectQuery } from '@/hooks/misc/useSelectedProject'
|
||||
import { useAsyncCheckPermissionsV2, FGA_PERMISSIONS } from '@/hooks/misc/useCheckPermissionsV2'
|
||||
|
||||
export const useS3VectorsWrapperCreateMutation = () => {
|
||||
const { data: project } = useSelectedProjectQuery()
|
||||
@@ -39,9 +38,8 @@ export const useS3VectorsWrapperCreateMutation = () => {
|
||||
|
||||
const wrapperMeta = WRAPPERS.find((wrapper) => wrapper.name === 's3_vectors_wrapper')
|
||||
|
||||
const { can: canCreateCredentials } = useAsyncCheckPermissions(
|
||||
PermissionAction.STORAGE_ADMIN_WRITE,
|
||||
'*'
|
||||
const { can: canCreateCredentials } = useAsyncCheckPermissionsV2(
|
||||
FGA_PERMISSIONS.PROJECT.STORAGE_CONFIG_WRITE
|
||||
)
|
||||
|
||||
const { mutateAsync: createS3AccessKey, isPending: isCreatingS3AccessKey } =
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
import { PermissionAction } from '@supabase/shared-types/out/constants'
|
||||
import { useQuery } from '@tanstack/react-query'
|
||||
|
||||
import { subscriptionKeys } from './keys'
|
||||
import { get, handleError } from '@/data/fetchers'
|
||||
import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions'
|
||||
import type { ResponseError, UseCustomQueryOptions } from '@/types'
|
||||
import { useAsyncCheckPermissionsV2 } from '@/hooks/misc/useCheckPermissionsV2'
|
||||
|
||||
export type OrgBalanceVariables = {
|
||||
orgSlug?: string
|
||||
@@ -36,9 +35,8 @@ export const useOrgBalanceQuery = <TData = OrgBalanceData>(
|
||||
) => {
|
||||
// [Joshen] Thinking it makes sense to add this check at the RQ level - prevent
|
||||
// unnecessary requests, although this behaviour still needs handling on the UI
|
||||
const { can: canReadBalance } = useAsyncCheckPermissions(
|
||||
PermissionAction.BILLING_READ,
|
||||
'stripe.subscriptions'
|
||||
const { can: canReadBalance } = useAsyncCheckPermissionsV2(
|
||||
'billing_read'
|
||||
)
|
||||
|
||||
return useQuery<OrgBalanceData, OrgBalanceError, TData>({
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
import { PermissionAction } from '@supabase/shared-types/out/constants'
|
||||
import { useQuery } from '@tanstack/react-query'
|
||||
|
||||
import { subscriptionKeys } from './keys'
|
||||
import { get, handleError } from '@/data/fetchers'
|
||||
import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions'
|
||||
import { UseCustomQueryOptions } from '@/types'
|
||||
import { useAsyncCheckPermissionsV2 } from '@/hooks/misc/useCheckPermissionsV2'
|
||||
|
||||
export type OrgPlansVariables = {
|
||||
orgSlug?: string
|
||||
@@ -28,9 +27,8 @@ export const useOrgPlansQuery = <TData = OrgPlansData>(
|
||||
{ orgSlug }: OrgPlansVariables,
|
||||
{ enabled = true, ...options }: UseCustomQueryOptions<OrgPlansData, OrgPlansError, TData> = {}
|
||||
) => {
|
||||
const { can: canReadSubscriptions } = useAsyncCheckPermissions(
|
||||
PermissionAction.BILLING_READ,
|
||||
'stripe.subscriptions'
|
||||
const { can: canReadSubscriptions } = useAsyncCheckPermissionsV2(
|
||||
'billing_read'
|
||||
)
|
||||
|
||||
return useQuery<OrgPlansData, OrgPlansError, TData>({
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
import { PermissionAction } from '@supabase/shared-types/out/constants'
|
||||
import { useQuery } from '@tanstack/react-query'
|
||||
|
||||
import { subscriptionKeys } from './keys'
|
||||
import { get, handleError } from '@/data/fetchers'
|
||||
import { useCheckEntitlements } from '@/hooks/misc/useCheckEntitlements'
|
||||
import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions'
|
||||
import type { ResponseError, UseCustomQueryOptions } from '@/types'
|
||||
import { useAsyncCheckPermissionsV2 } from '@/hooks/misc/useCheckPermissionsV2'
|
||||
|
||||
export type OrgSubscriptionVariables = {
|
||||
orgSlug?: string
|
||||
@@ -40,9 +39,8 @@ export const useOrgSubscriptionQuery = <TData = OrgSubscriptionData>(
|
||||
) => {
|
||||
// [Joshen] Thinking it makes sense to add this check at the RQ level - prevent
|
||||
// unnecessary requests, although this behaviour still needs handling on the UI
|
||||
const { can: canReadSubscriptions } = useAsyncCheckPermissions(
|
||||
PermissionAction.BILLING_READ,
|
||||
'stripe.subscriptions'
|
||||
const { can: canReadSubscriptions } = useAsyncCheckPermissionsV2(
|
||||
'billing_read'
|
||||
)
|
||||
|
||||
return useQuery<OrgSubscriptionData, OrgSubscriptionError, TData>({
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { getTableRowsCountSql } from '@supabase/pg-meta'
|
||||
import { PermissionAction } from '@supabase/shared-types/out/constants'
|
||||
import { QueryClient, useQuery, useQueryClient } from '@tanstack/react-query'
|
||||
import { IS_PLATFORM, useFlag } from 'common'
|
||||
|
||||
@@ -13,10 +12,10 @@ import {
|
||||
PG_META_SCOPED_INTROSPECTION_FLAG,
|
||||
prefetchTableEditor,
|
||||
} from '@/data/table-editor/table-editor-query'
|
||||
import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions'
|
||||
import { RoleImpersonationState, wrapWithRoleImpersonation } from '@/lib/role-impersonation'
|
||||
import { isRoleImpersonationEnabled } from '@/state/role-impersonation-state'
|
||||
import { ResponseError, UseCustomQueryOptions } from '@/types'
|
||||
import { useAsyncCheckPermissionsV2, FGA_PERMISSIONS } from '@/hooks/misc/useCheckPermissionsV2'
|
||||
|
||||
export type GetTableRowsCountArgs = {
|
||||
table?: SupaTable
|
||||
@@ -112,9 +111,8 @@ export const useTableRowsCountQuery = <TData = TableRowsCountData>(
|
||||
identifier: readReplicaIdentifier,
|
||||
type,
|
||||
} = useConnectionStringForReadOps()
|
||||
const { can: canSQLAdminWrite, isLoading: isPermissionsLoading } = useAsyncCheckPermissions(
|
||||
PermissionAction.TENANT_SQL_ADMIN_WRITE,
|
||||
'tables'
|
||||
const { can: canSQLAdminWrite, isLoading: isPermissionsLoading } = useAsyncCheckPermissionsV2(
|
||||
FGA_PERMISSIONS.PROJECT.DATABASE_WRITE
|
||||
)
|
||||
const scoped = !!useFlag(PG_META_SCOPED_INTROSPECTION_FLAG)
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { zodResolver } from '@hookform/resolvers/zod'
|
||||
import { PermissionAction } from '@supabase/shared-types/out/constants'
|
||||
import { useQueryClient } from '@tanstack/react-query'
|
||||
import { LOCAL_STORAGE_KEYS } from 'common'
|
||||
import { useForm } from 'react-hook-form'
|
||||
@@ -8,12 +7,12 @@ import * as z from 'zod'
|
||||
|
||||
import { useOrganizationUpdateMutation } from '@/data/organizations/organization-update-mutation'
|
||||
import { invalidateOrganizationsQuery } from '@/data/organizations/organizations-query'
|
||||
import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions'
|
||||
import { useLocalStorageQuery } from '@/hooks/misc/useLocalStorage'
|
||||
import { getAiOptInLevel } from '@/hooks/misc/useOrgOptedIntoAi'
|
||||
import { useSelectedOrganizationQuery } from '@/hooks/misc/useSelectedOrganization'
|
||||
import { OPT_IN_TAGS } from '@/lib/constants'
|
||||
import type { ResponseError } from '@/types'
|
||||
import { useAsyncCheckPermissionsV2, FGA_PERMISSIONS } from '../misc/useCheckPermissionsV2'
|
||||
|
||||
// Shared schema definition
|
||||
export const AIOptInSchema = z.object({
|
||||
@@ -31,9 +30,8 @@ export type AIOptInFormValues = z.infer<typeof AIOptInSchema>
|
||||
export const useAIOptInForm = (onSuccessCallback?: () => void) => {
|
||||
const queryClient = useQueryClient()
|
||||
const { data: selectedOrganization } = useSelectedOrganizationQuery()
|
||||
const { can: canUpdateOrganization } = useAsyncCheckPermissions(
|
||||
PermissionAction.UPDATE,
|
||||
'organizations'
|
||||
const { can: canUpdateOrganization } = useAsyncCheckPermissionsV2(
|
||||
FGA_PERMISSIONS.ORGANIZATION.ADMIN_WRITE
|
||||
)
|
||||
|
||||
const [, setUpdatedOptInSinceMCP] = useLocalStorageQuery(
|
||||
|
||||
@@ -121,7 +121,6 @@ function useGetProjectPermissionsV2(
|
||||
}
|
||||
}
|
||||
|
||||
// Useful when you want to avoid layout changes while waiting for permissions to load
|
||||
export function useAsyncCheckPermissionsV2(
|
||||
permission: FgaPermissions | FgaPermissions[],
|
||||
overrides?: {
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { PermissionAction } from '@supabase/shared-types/out/constants'
|
||||
import { PageContainer } from 'ui-patterns/PageContainer'
|
||||
import {
|
||||
PageHeader,
|
||||
@@ -16,14 +15,13 @@ import AuthLayout from '@/components/layouts/AuthLayout/AuthLayout'
|
||||
import { DefaultLayout } from '@/components/layouts/DefaultLayout'
|
||||
import { DocsButton } from '@/components/ui/DocsButton'
|
||||
import { NoPermission } from '@/components/ui/NoPermission'
|
||||
import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions'
|
||||
import { DOCS_URL } from '@/lib/constants'
|
||||
import type { NextPageWithLayout } from '@/types'
|
||||
import { useAsyncCheckPermissionsV2, FGA_PERMISSIONS } from '@/hooks/misc/useCheckPermissionsV2'
|
||||
|
||||
const AuditLogsPage: NextPageWithLayout = () => {
|
||||
const { can: canReadAuthSettings, isSuccess: isPermissionsLoaded } = useAsyncCheckPermissions(
|
||||
PermissionAction.READ,
|
||||
'custom_config_gotrue'
|
||||
const { can: canReadAuthSettings, isSuccess: isPermissionsLoaded } = useAsyncCheckPermissionsV2(
|
||||
FGA_PERMISSIONS.PROJECT.AUTH_CONFIG_READ
|
||||
)
|
||||
|
||||
if (isPermissionsLoaded && !canReadAuthSettings) {
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { PermissionAction } from '@supabase/shared-types/out/constants'
|
||||
import { PageContainer } from 'ui-patterns/PageContainer'
|
||||
import {
|
||||
PageHeader,
|
||||
@@ -16,14 +15,13 @@ import AuthLayout from '@/components/layouts/AuthLayout/AuthLayout'
|
||||
import { DefaultLayout } from '@/components/layouts/DefaultLayout'
|
||||
import { DocsButton } from '@/components/ui/DocsButton'
|
||||
import { NoPermission } from '@/components/ui/NoPermission'
|
||||
import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions'
|
||||
import { DOCS_URL } from '@/lib/constants'
|
||||
import type { NextPageWithLayout } from '@/types'
|
||||
import { useAsyncCheckPermissionsV2, FGA_PERMISSIONS } from '@/hooks/misc/useCheckPermissionsV2'
|
||||
|
||||
const Hooks: NextPageWithLayout = () => {
|
||||
const { can: canReadAuthSettings, isSuccess: isPermissionsLoaded } = useAsyncCheckPermissions(
|
||||
PermissionAction.READ,
|
||||
'custom_config_gotrue'
|
||||
const { can: canReadAuthSettings, isSuccess: isPermissionsLoaded } = useAsyncCheckPermissionsV2(
|
||||
FGA_PERMISSIONS.PROJECT.AUTH_CONFIG_READ
|
||||
)
|
||||
|
||||
if (isPermissionsLoaded && !canReadAuthSettings) {
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { PermissionAction } from '@supabase/shared-types/out/constants'
|
||||
import { useParams } from 'common'
|
||||
import { PageContainer } from 'ui-patterns/PageContainer'
|
||||
import {
|
||||
@@ -16,17 +15,16 @@ import AuthLayout from '@/components/layouts/AuthLayout/AuthLayout'
|
||||
import { DefaultLayout } from '@/components/layouts/DefaultLayout'
|
||||
import { NoPermission } from '@/components/ui/NoPermission'
|
||||
import { UnknownInterface } from '@/components/ui/UnknownInterface'
|
||||
import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions'
|
||||
import { useIsFeatureEnabled } from '@/hooks/misc/useIsFeatureEnabled'
|
||||
import type { NextPageWithLayout } from '@/types'
|
||||
import { useAsyncCheckPermissionsV2, FGA_PERMISSIONS } from '@/hooks/misc/useCheckPermissionsV2'
|
||||
|
||||
const MfaPage: NextPageWithLayout = () => {
|
||||
const { ref } = useParams()
|
||||
const showMFA = useIsFeatureEnabled('authentication:multi_factor')
|
||||
|
||||
const { can: canReadAuthSettings, isSuccess: isPermissionsLoaded } = useAsyncCheckPermissions(
|
||||
PermissionAction.READ,
|
||||
'custom_config_gotrue'
|
||||
const { can: canReadAuthSettings, isSuccess: isPermissionsLoaded } = useAsyncCheckPermissionsV2(
|
||||
FGA_PERMISSIONS.PROJECT.AUTH_CONFIG_READ
|
||||
)
|
||||
|
||||
if (!showMFA) {
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { PermissionAction } from '@supabase/shared-types/out/constants'
|
||||
import { useParams } from 'common'
|
||||
import { PageContainer } from 'ui-patterns/PageContainer'
|
||||
import {
|
||||
@@ -16,17 +15,16 @@ import AuthLayout from '@/components/layouts/AuthLayout/AuthLayout'
|
||||
import { DefaultLayout } from '@/components/layouts/DefaultLayout'
|
||||
import { NoPermission } from '@/components/ui/NoPermission'
|
||||
import { UnknownInterface } from '@/components/ui/UnknownInterface'
|
||||
import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions'
|
||||
import { useIsFeatureEnabled } from '@/hooks/misc/useIsFeatureEnabled'
|
||||
import type { NextPageWithLayout } from '@/types'
|
||||
import { useAsyncCheckPermissionsV2, FGA_PERMISSIONS } from '@/hooks/misc/useCheckPermissionsV2'
|
||||
|
||||
const PerformancePage: NextPageWithLayout = () => {
|
||||
const { ref } = useParams()
|
||||
const showPerformance = useIsFeatureEnabled('authentication:performance')
|
||||
|
||||
const { can: canReadAuthSettings, isSuccess: isPermissionsLoaded } = useAsyncCheckPermissions(
|
||||
PermissionAction.READ,
|
||||
'custom_config_gotrue'
|
||||
const { can: canReadAuthSettings, isSuccess: isPermissionsLoaded } = useAsyncCheckPermissionsV2(
|
||||
FGA_PERMISSIONS.PROJECT.AUTH_CONFIG_READ
|
||||
)
|
||||
|
||||
if (!showPerformance) {
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { PermissionAction } from '@supabase/shared-types/out/constants'
|
||||
import { useParams } from 'common'
|
||||
import { PageContainer } from 'ui-patterns/PageContainer'
|
||||
import {
|
||||
@@ -16,17 +15,16 @@ import AuthLayout from '@/components/layouts/AuthLayout/AuthLayout'
|
||||
import { DefaultLayout } from '@/components/layouts/DefaultLayout'
|
||||
import { NoPermission } from '@/components/ui/NoPermission'
|
||||
import { UnknownInterface } from '@/components/ui/UnknownInterface'
|
||||
import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions'
|
||||
import { useIsFeatureEnabled } from '@/hooks/misc/useIsFeatureEnabled'
|
||||
import type { NextPageWithLayout } from '@/types'
|
||||
import { useAsyncCheckPermissionsV2, FGA_PERMISSIONS } from '@/hooks/misc/useCheckPermissionsV2'
|
||||
|
||||
const ProtectionPage: NextPageWithLayout = () => {
|
||||
const { ref } = useParams()
|
||||
const showAttackProtection = useIsFeatureEnabled('authentication:attack_protection')
|
||||
|
||||
const { can: canReadAuthSettings, isSuccess: isPermissionsLoaded } = useAsyncCheckPermissions(
|
||||
PermissionAction.READ,
|
||||
'custom_config_gotrue'
|
||||
const { can: canReadAuthSettings, isSuccess: isPermissionsLoaded } = useAsyncCheckPermissionsV2(
|
||||
FGA_PERMISSIONS.PROJECT.AUTH_CONFIG_READ
|
||||
)
|
||||
|
||||
if (!showAttackProtection) {
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { PermissionAction } from '@supabase/shared-types/out/constants'
|
||||
import { useParams } from 'common'
|
||||
import { PageContainer } from 'ui-patterns/PageContainer'
|
||||
import {
|
||||
@@ -18,18 +17,17 @@ import { DefaultLayout } from '@/components/layouts/DefaultLayout'
|
||||
import { DocsButton } from '@/components/ui/DocsButton'
|
||||
import { NoPermission } from '@/components/ui/NoPermission'
|
||||
import { UnknownInterface } from '@/components/ui/UnknownInterface'
|
||||
import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions'
|
||||
import { useIsFeatureEnabled } from '@/hooks/misc/useIsFeatureEnabled'
|
||||
import { DOCS_URL } from '@/lib/constants'
|
||||
import type { NextPageWithLayout } from '@/types'
|
||||
import { useAsyncCheckPermissionsV2, FGA_PERMISSIONS } from '@/hooks/misc/useCheckPermissionsV2'
|
||||
|
||||
const RateLimitsPage: NextPageWithLayout = () => {
|
||||
const { ref } = useParams()
|
||||
const showRateLimits = useIsFeatureEnabled('authentication:rate_limits')
|
||||
|
||||
const { can: canReadAuthSettings, isSuccess: isPermissionsLoaded } = useAsyncCheckPermissions(
|
||||
PermissionAction.READ,
|
||||
'custom_config_gotrue'
|
||||
const { can: canReadAuthSettings, isSuccess: isPermissionsLoaded } = useAsyncCheckPermissionsV2(
|
||||
FGA_PERMISSIONS.PROJECT.AUTH_CONFIG_READ
|
||||
)
|
||||
|
||||
if (!showRateLimits) {
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { PermissionAction } from '@supabase/shared-types/out/constants'
|
||||
import { PageContainer } from 'ui-patterns/PageContainer'
|
||||
import {
|
||||
PageHeader,
|
||||
@@ -14,13 +13,12 @@ import { SessionsAuthSettingsForm } from '@/components/interfaces/Auth/SessionsA
|
||||
import AuthLayout from '@/components/layouts/AuthLayout/AuthLayout'
|
||||
import { DefaultLayout } from '@/components/layouts/DefaultLayout'
|
||||
import { NoPermission } from '@/components/ui/NoPermission'
|
||||
import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions'
|
||||
import type { NextPageWithLayout } from '@/types'
|
||||
import { useAsyncCheckPermissionsV2, FGA_PERMISSIONS } from '@/hooks/misc/useCheckPermissionsV2'
|
||||
|
||||
const SessionsPage: NextPageWithLayout = () => {
|
||||
const { can: canReadAuthSettings, isSuccess: isPermissionsLoaded } = useAsyncCheckPermissions(
|
||||
PermissionAction.READ,
|
||||
'custom_config_gotrue'
|
||||
const { can: canReadAuthSettings, isSuccess: isPermissionsLoaded } = useAsyncCheckPermissionsV2(
|
||||
FGA_PERMISSIONS.PROJECT.AUTH_CONFIG_READ
|
||||
)
|
||||
|
||||
if (isPermissionsLoaded && !canReadAuthSettings) {
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { PermissionAction } from '@supabase/shared-types/out/constants'
|
||||
import { PageContainer } from 'ui-patterns/PageContainer'
|
||||
import { PageSection, PageSectionContent } from 'ui-patterns/PageSection'
|
||||
import { GenericSkeletonLoader } from 'ui-patterns/ShimmeringLoader'
|
||||
@@ -7,13 +6,12 @@ import { SmtpForm } from '@/components/interfaces/Auth/SmtpForm/SmtpForm'
|
||||
import { AuthEmailsLayout } from '@/components/layouts/AuthLayout/AuthEmailsLayout'
|
||||
import { DefaultLayout } from '@/components/layouts/DefaultLayout'
|
||||
import { NoPermission } from '@/components/ui/NoPermission'
|
||||
import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions'
|
||||
import type { NextPageWithLayout } from '@/types'
|
||||
import { useAsyncCheckPermissionsV2, FGA_PERMISSIONS } from '@/hooks/misc/useCheckPermissionsV2'
|
||||
|
||||
const SmtpPage: NextPageWithLayout = () => {
|
||||
const { can: canReadAuthSettings, isSuccess: isPermissionsLoaded } = useAsyncCheckPermissions(
|
||||
PermissionAction.READ,
|
||||
'custom_config_gotrue'
|
||||
const { can: canReadAuthSettings, isSuccess: isPermissionsLoaded } = useAsyncCheckPermissionsV2(
|
||||
FGA_PERMISSIONS.PROJECT.AUTH_CONFIG_READ
|
||||
)
|
||||
|
||||
if (isPermissionsLoaded && !canReadAuthSettings) {
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { zodResolver } from '@hookform/resolvers/zod'
|
||||
import { PermissionAction } from '@supabase/shared-types/out/constants'
|
||||
import { useParams } from 'common'
|
||||
import Link from 'next/link'
|
||||
import { useRouter } from 'next/router'
|
||||
@@ -59,11 +58,11 @@ import { DocsButton } from '@/components/ui/DocsButton'
|
||||
import { NoPermission } from '@/components/ui/NoPermission'
|
||||
import { useAuthConfigQuery } from '@/data/auth/auth-config-query'
|
||||
import { useAuthConfigUpdateMutation } from '@/data/auth/auth-config-update-mutation'
|
||||
import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions'
|
||||
import { useSelectedOrganizationQuery } from '@/hooks/misc/useSelectedOrganization'
|
||||
import { useSelectedProjectQuery } from '@/hooks/misc/useSelectedProject'
|
||||
import { DOCS_URL } from '@/lib/constants'
|
||||
import type { NextPageWithLayout } from '@/types'
|
||||
import { useAsyncCheckPermissionsV2, FGA_PERMISSIONS } from '@/hooks/misc/useCheckPermissionsV2'
|
||||
|
||||
const TemplatePage: NextPageWithLayout = () => {
|
||||
return <RedirectToTemplates />
|
||||
@@ -74,14 +73,12 @@ const RedirectToTemplates = () => {
|
||||
const { templateId, ref } = router.query
|
||||
const { ref: projectRef } = useParams()
|
||||
|
||||
const { can: canReadAuthSettings, isSuccess: isPermissionsLoaded } = useAsyncCheckPermissions(
|
||||
PermissionAction.READ,
|
||||
'custom_config_gotrue'
|
||||
const { can: canReadAuthSettings, isSuccess: isPermissionsLoaded } = useAsyncCheckPermissionsV2(
|
||||
FGA_PERMISSIONS.PROJECT.AUTH_CONFIG_READ
|
||||
)
|
||||
|
||||
const { can: canUpdateConfig } = useAsyncCheckPermissions(
|
||||
PermissionAction.UPDATE,
|
||||
'custom_config_gotrue'
|
||||
const { can: canUpdateConfig } = useAsyncCheckPermissionsV2(
|
||||
FGA_PERMISSIONS.PROJECT.AUTH_CONFIG_WRITE
|
||||
)
|
||||
|
||||
const { data: authConfig, isPending: isLoadingConfig } = useAuthConfigQuery({ projectRef })
|
||||
@@ -132,16 +129,16 @@ const RedirectToTemplates = () => {
|
||||
// Create form schema for security templates
|
||||
const TemplateFormSchema = templateEnabledKey
|
||||
? z.object({
|
||||
[templateEnabledKey]: z.boolean(),
|
||||
})
|
||||
[templateEnabledKey]: z.boolean(),
|
||||
})
|
||||
: z.object({})
|
||||
|
||||
const defaultValues = templateEnabledKey
|
||||
? {
|
||||
[templateEnabledKey]: authConfig
|
||||
? Boolean(authConfig[templateEnabledKey as keyof typeof authConfig])
|
||||
: false,
|
||||
}
|
||||
[templateEnabledKey]: authConfig
|
||||
? Boolean(authConfig[templateEnabledKey as keyof typeof authConfig])
|
||||
: false,
|
||||
}
|
||||
: {}
|
||||
|
||||
const templateForm = useForm<z.infer<typeof TemplateFormSchema>>({
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { PermissionAction } from '@supabase/shared-types/out/constants'
|
||||
import { PageContainer } from 'ui-patterns/PageContainer'
|
||||
import { PageSection, PageSectionContent } from 'ui-patterns/PageSection'
|
||||
import { GenericSkeletonLoader } from 'ui-patterns/ShimmeringLoader'
|
||||
@@ -7,13 +6,12 @@ import { EmailTemplates } from '@/components/interfaces/Auth/EmailTemplates/Emai
|
||||
import { AuthEmailsLayout } from '@/components/layouts/AuthLayout/AuthEmailsLayout'
|
||||
import { DefaultLayout } from '@/components/layouts/DefaultLayout'
|
||||
import { NoPermission } from '@/components/ui/NoPermission'
|
||||
import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions'
|
||||
import type { NextPageWithLayout } from '@/types'
|
||||
import { useAsyncCheckPermissionsV2, FGA_PERMISSIONS } from '@/hooks/misc/useCheckPermissionsV2'
|
||||
|
||||
const TemplatesPage: NextPageWithLayout = () => {
|
||||
const { can: canReadAuthSettings, isSuccess: isPermissionsLoaded } = useAsyncCheckPermissions(
|
||||
PermissionAction.READ,
|
||||
'custom_config_gotrue'
|
||||
const { can: canReadAuthSettings, isSuccess: isPermissionsLoaded } = useAsyncCheckPermissionsV2(
|
||||
FGA_PERMISSIONS.PROJECT.AUTH_CONFIG_READ
|
||||
)
|
||||
|
||||
if (isPermissionsLoaded && !canReadAuthSettings) {
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { PermissionAction } from '@supabase/shared-types/out/constants'
|
||||
import { useParams } from 'common'
|
||||
import { PageContainer } from 'ui-patterns/PageContainer'
|
||||
|
||||
@@ -8,15 +7,14 @@ import { AuthProvidersLayout } from '@/components/layouts/AuthLayout/AuthProvide
|
||||
import { DefaultLayout } from '@/components/layouts/DefaultLayout'
|
||||
import { NoPermission } from '@/components/ui/NoPermission'
|
||||
import { UnknownInterface } from '@/components/ui/UnknownInterface'
|
||||
import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions'
|
||||
import { useIsFeatureEnabled } from '@/hooks/misc/useIsFeatureEnabled'
|
||||
import type { NextPageWithLayout } from '@/types'
|
||||
import { useAsyncCheckPermissionsV2, FGA_PERMISSIONS } from '@/hooks/misc/useCheckPermissionsV2'
|
||||
|
||||
const ThirdPartyPage: NextPageWithLayout = () => {
|
||||
const { ref } = useParams()
|
||||
const { can: canReadAuthSettings, isSuccess: isPermissionsLoaded } = useAsyncCheckPermissions(
|
||||
PermissionAction.READ,
|
||||
'custom_config_gotrue'
|
||||
const { can: canReadAuthSettings, isSuccess: isPermissionsLoaded } = useAsyncCheckPermissionsV2(
|
||||
FGA_PERMISSIONS.PROJECT.AUTH_CONFIG_READ
|
||||
)
|
||||
|
||||
const showThirdPartyAuth = useIsFeatureEnabled('authentication:third_party_auth')
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { PermissionAction } from '@supabase/shared-types/out/constants'
|
||||
import { PageContainer } from 'ui-patterns/PageContainer'
|
||||
import {
|
||||
PageHeader,
|
||||
@@ -15,13 +14,12 @@ import SiteUrl from '@/components/interfaces/Auth/SiteUrl/SiteUrl'
|
||||
import AuthLayout from '@/components/layouts/AuthLayout/AuthLayout'
|
||||
import { DefaultLayout } from '@/components/layouts/DefaultLayout'
|
||||
import { NoPermission } from '@/components/ui/NoPermission'
|
||||
import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions'
|
||||
import type { NextPageWithLayout } from '@/types'
|
||||
import { useAsyncCheckPermissionsV2, FGA_PERMISSIONS } from '@/hooks/misc/useCheckPermissionsV2'
|
||||
|
||||
const URLConfiguration: NextPageWithLayout = () => {
|
||||
const { can: canReadAuthSettings, isSuccess: isPermissionsLoaded } = useAsyncCheckPermissions(
|
||||
PermissionAction.READ,
|
||||
'custom_config_gotrue'
|
||||
const { can: canReadAuthSettings, isSuccess: isPermissionsLoaded } = useAsyncCheckPermissionsV2(
|
||||
FGA_PERMISSIONS.PROJECT.AUTH_CONFIG_READ
|
||||
)
|
||||
|
||||
if (isPermissionsLoaded && !canReadAuthSettings) {
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { PermissionAction } from '@supabase/shared-types/out/constants'
|
||||
import { useParams } from 'common'
|
||||
import { partition } from 'lodash'
|
||||
import { MessageCircle } from 'lucide-react'
|
||||
@@ -18,13 +17,13 @@ import { DocsButton } from '@/components/ui/DocsButton'
|
||||
import { NoPermission } from '@/components/ui/NoPermission'
|
||||
import { Branch, useBranchesQuery } from '@/data/branches/branches-query'
|
||||
import { useGitHubConnectionsQuery } from '@/data/integrations/github-connections-query'
|
||||
import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions'
|
||||
import { useSelectedOrganizationQuery } from '@/hooks/misc/useSelectedOrganization'
|
||||
import { useSelectedProjectQuery } from '@/hooks/misc/useSelectedProject'
|
||||
import { DOCS_URL } from '@/lib/constants'
|
||||
import { useTrack } from '@/lib/telemetry/track'
|
||||
import { useAppStateSnapshot } from '@/state/app-state'
|
||||
import type { NextPageWithLayout } from '@/types'
|
||||
import { useAsyncCheckPermissionsV2, FGA_PERMISSIONS } from '@/hooks/misc/useCheckPermissionsV2'
|
||||
|
||||
const BranchesPage: NextPageWithLayout = () => {
|
||||
const router = useRouter()
|
||||
@@ -41,9 +40,8 @@ const BranchesPage: NextPageWithLayout = () => {
|
||||
const projectRef =
|
||||
project !== undefined ? (isBranch ? project.parent_project_ref : ref) : undefined
|
||||
|
||||
const { can: canReadBranches, isSuccess: isPermissionsLoaded } = useAsyncCheckPermissions(
|
||||
PermissionAction.READ,
|
||||
'preview_branches'
|
||||
const { can: canReadBranches, isSuccess: isPermissionsLoaded } = useAsyncCheckPermissionsV2(
|
||||
FGA_PERMISSIONS.PROJECT.BRANCHING_DEVELOPMENT_READ
|
||||
)
|
||||
|
||||
const {
|
||||
@@ -156,12 +154,8 @@ const BranchesPage: NextPageWithLayout = () => {
|
||||
// content as `children` instead of capturing it from a closure.
|
||||
export const BranchesPageWrapper = ({ children }: PropsWithChildren) => {
|
||||
const snap = useAppStateSnapshot()
|
||||
const { can: canCreateBranches } = useAsyncCheckPermissions(
|
||||
PermissionAction.CREATE,
|
||||
'preview_branches',
|
||||
{
|
||||
resource: { is_default: false },
|
||||
}
|
||||
const { can: canCreateBranches } = useAsyncCheckPermissionsV2(
|
||||
FGA_PERMISSIONS.PROJECT.BRANCHING_DEVELOPMENT_CREATE
|
||||
)
|
||||
|
||||
const primaryActions = (
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { PermissionAction } from '@supabase/shared-types/out/constants'
|
||||
import { useParams } from 'common'
|
||||
import { partition } from 'lodash'
|
||||
import { ArrowRight, GitMerge, MessageCircle, MoreVertical, Shield, X } from 'lucide-react'
|
||||
@@ -31,12 +30,12 @@ import { NoPermission } from '@/components/ui/NoPermission'
|
||||
import { useBranchUpdateMutation } from '@/data/branches/branch-update-mutation'
|
||||
import { Branch, useBranchesQuery } from '@/data/branches/branches-query'
|
||||
import { useGitHubConnectionsQuery } from '@/data/integrations/github-connections-query'
|
||||
import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions'
|
||||
import { useSelectedOrganizationQuery } from '@/hooks/misc/useSelectedOrganization'
|
||||
import { useSelectedProjectQuery } from '@/hooks/misc/useSelectedProject'
|
||||
import { DOCS_URL } from '@/lib/constants'
|
||||
import { useTrack } from '@/lib/telemetry/track'
|
||||
import type { NextPageWithLayout } from '@/types'
|
||||
import { useAsyncCheckPermissionsV2, FGA_PERMISSIONS } from '@/hooks/misc/useCheckPermissionsV2'
|
||||
|
||||
const MergeRequestsPage: NextPageWithLayout = () => {
|
||||
const router = useRouter()
|
||||
@@ -48,9 +47,8 @@ const MergeRequestsPage: NextPageWithLayout = () => {
|
||||
const projectRef =
|
||||
project !== undefined ? (isBranch ? project.parent_project_ref : ref) : undefined
|
||||
|
||||
const { can: canReadBranches, isSuccess: isPermissionsLoaded } = useAsyncCheckPermissions(
|
||||
PermissionAction.READ,
|
||||
'preview_branches'
|
||||
const { can: canReadBranches, isSuccess: isPermissionsLoaded } = useAsyncCheckPermissionsV2(
|
||||
FGA_PERMISSIONS.PROJECT.BRANCHING_DEVELOPMENT_READ
|
||||
)
|
||||
|
||||
const {
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { PermissionAction } from '@supabase/shared-types/out/constants'
|
||||
import { useParams } from 'common'
|
||||
import { AlertCircle, DatabaseBackup } from 'lucide-react'
|
||||
import { Alert, AlertDescription, AlertTitle } from 'ui'
|
||||
@@ -26,11 +25,11 @@ import { NoPermission } from '@/components/ui/NoPermission'
|
||||
import { UpgradeToPro } from '@/components/ui/UpgradeToPro'
|
||||
import { useBackupsQuery } from '@/data/database/backups-query'
|
||||
import { useCheckEntitlements } from '@/hooks/misc/useCheckEntitlements'
|
||||
import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions'
|
||||
import { useHighAvailability } from '@/hooks/misc/useHighAvailability'
|
||||
import { useIsOrioleDbInAws, useSelectedProjectQuery } from '@/hooks/misc/useSelectedProject'
|
||||
import { DOCS_URL, PROJECT_STATUS } from '@/lib/constants'
|
||||
import type { NextPageWithLayout } from '@/types'
|
||||
import { useAsyncCheckPermissionsV2, FGA_PERMISSIONS } from '@/hooks/misc/useCheckPermissionsV2'
|
||||
|
||||
const DatabasePhysicalBackups: NextPageWithLayout = () => {
|
||||
return (
|
||||
@@ -83,9 +82,8 @@ const PITR = () => {
|
||||
const isEnabled = backups?.pitr_enabled
|
||||
const isActiveHealthy = project?.status === PROJECT_STATUS.ACTIVE_HEALTHY
|
||||
|
||||
const { can: canReadPhysicalBackups, isSuccess: isPermissionsLoaded } = useAsyncCheckPermissions(
|
||||
PermissionAction.READ,
|
||||
'physical_backups'
|
||||
const { can: canReadPhysicalBackups, isSuccess: isPermissionsLoaded } = useAsyncCheckPermissionsV2(
|
||||
FGA_PERMISSIONS.PROJECT.BACKUPS_READ
|
||||
)
|
||||
|
||||
if (isPermissionsLoaded && !canReadPhysicalBackups) {
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { PermissionAction } from '@supabase/shared-types/out/constants'
|
||||
import { useParams } from 'common'
|
||||
import { DatabaseBackup, Info } from 'lucide-react'
|
||||
import { Admonition } from 'ui-patterns/Admonition'
|
||||
@@ -23,10 +22,10 @@ import { HighAvailabilityDisabledEmptyState } from '@/components/ui/HighAvailabi
|
||||
import InformationBox from '@/components/ui/InformationBox'
|
||||
import { NoPermission } from '@/components/ui/NoPermission'
|
||||
import { useBackupsQuery } from '@/data/database/backups-query'
|
||||
import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions'
|
||||
import { useIsHighAvailability, useIsOrioleDbInAws } from '@/hooks/misc/useSelectedProject'
|
||||
import { DOCS_URL } from '@/lib/constants'
|
||||
import type { NextPageWithLayout } from '@/types'
|
||||
import { useAsyncCheckPermissionsV2, FGA_PERMISSIONS } from '@/hooks/misc/useCheckPermissionsV2'
|
||||
|
||||
const DatabaseScheduledBackups: NextPageWithLayout = () => {
|
||||
return (
|
||||
@@ -67,9 +66,8 @@ const ScheduledBackups = () => {
|
||||
const isHighAvailability = useIsHighAvailability()
|
||||
const isPitrEnabled = backups?.pitr_enabled
|
||||
|
||||
const { can: canReadScheduledBackups, isSuccess: isPermissionsLoaded } = useAsyncCheckPermissions(
|
||||
PermissionAction.READ,
|
||||
'back_ups'
|
||||
const { can: canReadScheduledBackups, isSuccess: isPermissionsLoaded } = useAsyncCheckPermissionsV2(
|
||||
FGA_PERMISSIONS.PROJECT.BACKUPS_READ
|
||||
)
|
||||
|
||||
if (isOrioleDbInAws) {
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { PermissionAction } from '@supabase/shared-types/out/constants'
|
||||
import { PageContainer } from 'ui-patterns/PageContainer'
|
||||
import {
|
||||
PageHeader,
|
||||
@@ -15,14 +14,13 @@ import { DatabaseLayout } from '@/components/layouts/DatabaseLayout/DatabaseLayo
|
||||
import { DefaultLayout } from '@/components/layouts/DefaultLayout'
|
||||
import { DocsButton } from '@/components/ui/DocsButton'
|
||||
import { NoPermission } from '@/components/ui/NoPermission'
|
||||
import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions'
|
||||
import { DOCS_URL } from '@/lib/constants'
|
||||
import type { NextPageWithLayout } from '@/types'
|
||||
import { useAsyncCheckPermissionsV2, FGA_PERMISSIONS } from '@/hooks/misc/useCheckPermissionsV2'
|
||||
|
||||
const DatabaseExtensions: NextPageWithLayout = () => {
|
||||
const { can: canReadExtensions, isSuccess: isPermissionsLoaded } = useAsyncCheckPermissions(
|
||||
PermissionAction.TENANT_SQL_ADMIN_READ,
|
||||
'extensions'
|
||||
const { can: canReadExtensions, isSuccess: isPermissionsLoaded } = useAsyncCheckPermissionsV2(
|
||||
FGA_PERMISSIONS.PROJECT.DATABASE_READ
|
||||
)
|
||||
|
||||
if (isPermissionsLoaded && !canReadExtensions) {
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { PermissionAction } from '@supabase/shared-types/out/constants'
|
||||
import { PageContainer } from 'ui-patterns/PageContainer'
|
||||
import {
|
||||
PageHeader,
|
||||
@@ -14,14 +13,13 @@ import { DatabaseLayout } from '@/components/layouts/DatabaseLayout/DatabaseLayo
|
||||
import { DefaultLayout } from '@/components/layouts/DefaultLayout'
|
||||
import { DocsButton } from '@/components/ui/DocsButton'
|
||||
import { NoPermission } from '@/components/ui/NoPermission'
|
||||
import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions'
|
||||
import { DOCS_URL } from '@/lib/constants'
|
||||
import type { NextPageWithLayout } from '@/types'
|
||||
import { useAsyncCheckPermissionsV2, FGA_PERMISSIONS } from '@/hooks/misc/useCheckPermissionsV2'
|
||||
|
||||
const DatabaseFunctionsPage: NextPageWithLayout = () => {
|
||||
const { can: canReadFunctions, isSuccess: isPermissionsLoaded } = useAsyncCheckPermissions(
|
||||
PermissionAction.TENANT_SQL_ADMIN_READ,
|
||||
'functions'
|
||||
const { can: canReadFunctions, isSuccess: isPermissionsLoaded } = useAsyncCheckPermissionsV2(
|
||||
FGA_PERMISSIONS.PROJECT.DATABASE_READ
|
||||
)
|
||||
|
||||
if (isPermissionsLoaded && !canReadFunctions) {
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import type { PGTable } from '@supabase/pg-meta'
|
||||
import { ident, safeSql } from '@supabase/pg-meta'
|
||||
import { PermissionAction } from '@supabase/shared-types/out/constants'
|
||||
import { LOCAL_STORAGE_KEYS, useParams } from 'common'
|
||||
import { Search, X } from 'lucide-react'
|
||||
import { parseAsBoolean, parseAsString, useQueryState } from 'nuqs'
|
||||
@@ -42,7 +41,6 @@ import { Shortcut } from '@/components/ui/Shortcut'
|
||||
import { useProjectPostgrestConfigQuery } from '@/data/config/project-postgrest-config-query'
|
||||
import { useDatabasePoliciesQuery } from '@/data/database-policies/database-policies-query'
|
||||
import { useTablesQuery } from '@/data/tables/tables-query'
|
||||
import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions'
|
||||
import { useLocalStorageQuery } from '@/hooks/misc/useLocalStorage'
|
||||
import { useSelectedProjectQuery } from '@/hooks/misc/useSelectedProject'
|
||||
import { useIsProtectedSchema } from '@/hooks/useProtectedSchemas'
|
||||
@@ -53,6 +51,7 @@ import { SHORTCUT_IDS } from '@/state/shortcuts/registry'
|
||||
import { useShortcut } from '@/state/shortcuts/useShortcut'
|
||||
import { useSidebarManagerSnapshot } from '@/state/sidebar-manager-state'
|
||||
import type { NextPageWithLayout } from '@/types'
|
||||
import { useAsyncCheckPermissionsV2, FGA_PERMISSIONS } from '@/hooks/misc/useCheckPermissionsV2'
|
||||
|
||||
/**
|
||||
* Filter tables by table name and policy name
|
||||
@@ -182,9 +181,8 @@ const DatabasePoliciesPage: NextPageWithLayout = () => {
|
||||
)
|
||||
const exposedSchemas = getExposedSchemas(dbSchema)
|
||||
|
||||
const { can: canReadPolicies, isSuccess: isPermissionsLoaded } = useAsyncCheckPermissions(
|
||||
PermissionAction.TENANT_SQL_ADMIN_READ,
|
||||
'policies'
|
||||
const { can: canReadPolicies, isSuccess: isPermissionsLoaded } = useAsyncCheckPermissionsV2(
|
||||
FGA_PERMISSIONS.PROJECT.DATABASE_READ
|
||||
)
|
||||
|
||||
const handleSelectCreatePolicy = useCallback(
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { PermissionAction } from '@supabase/shared-types/out/constants'
|
||||
import { useParams } from 'common'
|
||||
import { PageContainer } from 'ui-patterns/PageContainer'
|
||||
import { PageSection, PageSectionContent } from 'ui-patterns/PageSection'
|
||||
@@ -11,16 +10,15 @@ import { DefaultLayout } from '@/components/layouts/DefaultLayout'
|
||||
import { PageLayout } from '@/components/layouts/PageLayout/PageLayout'
|
||||
import { NoPermission } from '@/components/ui/NoPermission'
|
||||
import { useDatabasePublicationsQuery } from '@/data/database-publications/database-publications-query'
|
||||
import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions'
|
||||
import { useSelectedProjectQuery } from '@/hooks/misc/useSelectedProject'
|
||||
import type { NextPageWithLayout } from '@/types'
|
||||
import { useAsyncCheckPermissionsV2, FGA_PERMISSIONS } from '@/hooks/misc/useCheckPermissionsV2'
|
||||
|
||||
const DatabasePublicationsContent = () => {
|
||||
const { ref, id } = useParams()
|
||||
const { data: project } = useSelectedProjectQuery()
|
||||
const { can: canViewPublications, isSuccess: isPermissionsLoaded } = useAsyncCheckPermissions(
|
||||
PermissionAction.TENANT_SQL_ADMIN_READ,
|
||||
'publications'
|
||||
const { can: canViewPublications, isSuccess: isPermissionsLoaded } = useAsyncCheckPermissionsV2(
|
||||
FGA_PERMISSIONS.PROJECT.DATABASE_READ
|
||||
)
|
||||
|
||||
const { data: publications = [], isPending } = useDatabasePublicationsQuery({
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { PermissionAction } from '@supabase/shared-types/out/constants'
|
||||
import { PageContainer } from 'ui-patterns/PageContainer'
|
||||
import { PageSection } from 'ui-patterns/PageSection'
|
||||
|
||||
@@ -8,13 +7,12 @@ import { DatabaseLayout } from '@/components/layouts/DatabaseLayout/DatabaseLayo
|
||||
import { DefaultLayout } from '@/components/layouts/DefaultLayout'
|
||||
import { PageLayout } from '@/components/layouts/PageLayout/PageLayout'
|
||||
import { NoPermission } from '@/components/ui/NoPermission'
|
||||
import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions'
|
||||
import type { NextPageWithLayout } from '@/types'
|
||||
import { useAsyncCheckPermissionsV2, FGA_PERMISSIONS } from '@/hooks/misc/useCheckPermissionsV2'
|
||||
|
||||
const DatabasePublicationsContent = () => {
|
||||
const { can: canViewPublications, isSuccess: isPermissionsLoaded } = useAsyncCheckPermissions(
|
||||
PermissionAction.TENANT_SQL_ADMIN_READ,
|
||||
'publications'
|
||||
const { can: canViewPublications, isSuccess: isPermissionsLoaded } = useAsyncCheckPermissionsV2(
|
||||
FGA_PERMISSIONS.PROJECT.DATABASE_READ
|
||||
)
|
||||
|
||||
if (isPermissionsLoaded && !canViewPublications) {
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { PermissionAction } from '@supabase/shared-types/out/constants'
|
||||
import { IS_PLATFORM, useParams } from 'common'
|
||||
import { isEqual } from 'lodash'
|
||||
import { AlertCircle, CornerDownLeft, Loader2 } from 'lucide-react'
|
||||
@@ -18,12 +17,12 @@ import { InlineLink } from '@/components/ui/InlineLink'
|
||||
import { useEdgeFunctionBodyQuery } from '@/data/edge-functions/edge-function-body-query'
|
||||
import { useEdgeFunctionQuery } from '@/data/edge-functions/edge-function-query'
|
||||
import { useEdgeFunctionDeployMutation } from '@/data/edge-functions/edge-functions-deploy-mutation'
|
||||
import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions'
|
||||
import { useSelectedOrganizationQuery } from '@/hooks/misc/useSelectedOrganization'
|
||||
import { useSelectedProjectQuery } from '@/hooks/misc/useSelectedProject'
|
||||
import { usePreventNavigationOnUnsavedChanges } from '@/hooks/ui/usePreventNavigationOnUnsavedChanges'
|
||||
import { BASE_PATH, DOCS_URL } from '@/lib/constants'
|
||||
import { useTrack } from '@/lib/telemetry/track'
|
||||
import { useAsyncCheckPermissionsV2, FGA_PERMISSIONS } from '@/hooks/misc/useCheckPermissionsV2'
|
||||
|
||||
const CodePage = () => {
|
||||
const { ref, functionSlug } = useParams()
|
||||
@@ -33,7 +32,9 @@ const CodePage = () => {
|
||||
const track = useTrack()
|
||||
const [showDeployWarning, setShowDeployWarning] = useState(false)
|
||||
|
||||
const { can: canDeployFunction } = useAsyncCheckPermissions(PermissionAction.FUNCTIONS_WRITE, '*')
|
||||
const { can: canDeployFunction } = useAsyncCheckPermissionsV2(
|
||||
FGA_PERMISSIONS.PROJECT.EDGE_FUNCTIONS_WRITE
|
||||
)
|
||||
|
||||
const { data: selectedFunction } = useEdgeFunctionQuery({
|
||||
projectRef: ref,
|
||||
@@ -68,9 +69,9 @@ const CodePage = () => {
|
||||
const initialFiles = useMemo(() => {
|
||||
return !!functionBody
|
||||
? formatFunctionBodyToFiles({
|
||||
functionBody,
|
||||
entrypointPath: selectedFunction?.entrypoint_path,
|
||||
})
|
||||
functionBody,
|
||||
entrypointPath: selectedFunction?.entrypoint_path,
|
||||
})
|
||||
: []
|
||||
}, [functionBody, selectedFunction?.entrypoint_path])
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { PermissionAction } from '@supabase/shared-types/out/constants'
|
||||
import { IS_PLATFORM, useFeatureFlags, useFlag, useParams } from 'common'
|
||||
import dayjs, { Dayjs } from 'dayjs'
|
||||
import maxBy from 'lodash/maxBy'
|
||||
@@ -24,8 +23,8 @@ import {
|
||||
} from '@/data/analytics/functions-combined-stats-query'
|
||||
import { useEdgeFunctionQuery } from '@/data/edge-functions/edge-function-query'
|
||||
import { useFillTimeseriesSorted } from '@/hooks/analytics/useFillTimeseriesSorted'
|
||||
import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions'
|
||||
import type { ChartIntervals, NextPageWithLayout } from '@/types'
|
||||
import { useAsyncCheckPermissionsV2, FGA_PERMISSIONS } from '@/hooks/misc/useCheckPermissionsV2'
|
||||
|
||||
const CHART_INTERVALS: ChartIntervals[] = [
|
||||
{
|
||||
@@ -121,9 +120,8 @@ const LegacyEdgeFunctionOverview = () => {
|
||||
endDate: endDate.toISOString(),
|
||||
})
|
||||
|
||||
const { isLoading: permissionsLoading, can: canReadFunction } = useAsyncCheckPermissions(
|
||||
PermissionAction.FUNCTIONS_READ,
|
||||
functionSlug as string
|
||||
const { isLoading: permissionsLoading, can: canReadFunction } = useAsyncCheckPermissionsV2(
|
||||
FGA_PERMISSIONS.PROJECT.EDGE_FUNCTIONS_READ
|
||||
)
|
||||
if (!canReadFunction && !permissionsLoading) {
|
||||
return <NoPermission isFullPage resourceText="access this edge function" />
|
||||
|
||||
@@ -1,18 +1,15 @@
|
||||
import { PermissionAction } from '@supabase/shared-types/out/constants'
|
||||
|
||||
import { LogsPreviewer } from '@/components/interfaces/Settings/Logs/LogsPreviewer'
|
||||
import { DefaultLayout } from '@/components/layouts/DefaultLayout'
|
||||
import LogsLayout from '@/components/layouts/LogsLayout/LogsLayout'
|
||||
import { NoPermission } from '@/components/ui/NoPermission'
|
||||
import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions'
|
||||
import { useSelectedProjectQuery } from '@/hooks/misc/useSelectedProject'
|
||||
import type { NextPageWithLayout } from '@/types'
|
||||
import { useAsyncCheckPermissionsV2, FGA_PERMISSIONS } from '@/hooks/misc/useCheckPermissionsV2'
|
||||
|
||||
const LogsPage: NextPageWithLayout = () => {
|
||||
const { data: project } = useSelectedProjectQuery()
|
||||
const { can: canReadAuthLogs } = useAsyncCheckPermissions(
|
||||
PermissionAction.ANALYTICS_READ,
|
||||
'logflare'
|
||||
const { can: canReadAuthLogs } = useAsyncCheckPermissionsV2(
|
||||
FGA_PERMISSIONS.PROJECT.ANALYTICS_LOGS_READ
|
||||
)
|
||||
|
||||
return !canReadAuthLogs ? (
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { PermissionAction } from '@supabase/shared-types/out/constants'
|
||||
import { useQueryClient } from '@tanstack/react-query'
|
||||
import { useFlag, useParams } from 'common'
|
||||
import dayjs from 'dayjs'
|
||||
@@ -40,7 +39,6 @@ import { getReportAttributesV2 } from '@/data/reports/database-charts'
|
||||
import { useDatabaseReport } from '@/data/reports/database-report-query'
|
||||
import { useProjectAddonsQuery } from '@/data/subscriptions/project-addons-query'
|
||||
import { useCheckEntitlements } from '@/hooks/misc/useCheckEntitlements'
|
||||
import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions'
|
||||
import { useRefreshHandler, useReportDateRange } from '@/hooks/misc/useReportDateRange'
|
||||
import { useSelectedOrganizationQuery } from '@/hooks/misc/useSelectedOrganization'
|
||||
import { useIsHighAvailability, useSelectedProjectQuery } from '@/hooks/misc/useSelectedProject'
|
||||
@@ -50,6 +48,7 @@ import { useDatabaseSelectorStateSnapshot } from '@/state/database-selector'
|
||||
import { SHORTCUT_IDS } from '@/state/shortcuts/registry'
|
||||
import { useShortcut } from '@/state/shortcuts/useShortcut'
|
||||
import type { NextPageWithLayout } from '@/types'
|
||||
import { useAsyncCheckPermissionsV2, FGA_PERMISSIONS } from '@/hooks/misc/useCheckPermissionsV2'
|
||||
|
||||
const DatabaseReport: NextPageWithLayout = () => {
|
||||
return (
|
||||
@@ -195,19 +194,13 @@ const DatabaseUsage = () => {
|
||||
const computeInstance = addons?.selected_addons.find((addon) => addon.type === 'compute_instance')
|
||||
const poolingOptimizations =
|
||||
POOLING_OPTIMIZATIONS[
|
||||
(computeInstance?.variant.identifier as keyof typeof POOLING_OPTIMIZATIONS) ??
|
||||
(project?.infra_compute_size === 'nano' ? 'ci_nano' : 'ci_micro')
|
||||
(computeInstance?.variant.identifier as keyof typeof POOLING_OPTIMIZATIONS) ??
|
||||
(project?.infra_compute_size === 'nano' ? 'ci_nano' : 'ci_micro')
|
||||
]
|
||||
const defaultMaxClientConn = poolingOptimizations.maxClientConn ?? 200
|
||||
|
||||
const { can: canUpdateDiskSizeConfig } = useAsyncCheckPermissions(
|
||||
PermissionAction.UPDATE,
|
||||
'projects',
|
||||
{
|
||||
resource: {
|
||||
project_id: project?.id,
|
||||
},
|
||||
}
|
||||
const { can: canUpdateDiskSizeConfig } = useAsyncCheckPermissionsV2(
|
||||
FGA_PERMISSIONS.PROJECT.INFRA_DISK_CONFIG_WRITE
|
||||
)
|
||||
|
||||
const { getEntitlementSetValues, isLoading: isEntitlementLoading } = useCheckEntitlements(
|
||||
@@ -363,8 +356,8 @@ const DatabaseUsage = () => {
|
||||
syncId="database-charts"
|
||||
showMaxValue={
|
||||
chart.id === 'client-connections' ||
|
||||
chart.id === 'client-connections-basic' ||
|
||||
chart.id === 'pgbouncer-connections'
|
||||
chart.id === 'client-connections-basic' ||
|
||||
chart.id === 'pgbouncer-connections'
|
||||
? true
|
||||
: chart.showMaxValue
|
||||
}
|
||||
@@ -432,7 +425,7 @@ const DatabaseUsage = () => {
|
||||
</div>
|
||||
|
||||
<div className="ml-auto">
|
||||
{/*
|
||||
{/*
|
||||
[Joshen] TODO: Check if this check is still relevant
|
||||
The DiskSizeConfigurationModal is old and might be obsolete
|
||||
*/}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { PermissionAction } from '@supabase/shared-types/out/constants'
|
||||
import { useFeatureFlags, useFlag, useParams } from 'common'
|
||||
import { useRouter } from 'next/router'
|
||||
import { parseAsBoolean, useQueryState } from 'nuqs'
|
||||
@@ -11,9 +10,9 @@ import { DefaultLayout } from '@/components/layouts/DefaultLayout'
|
||||
import ObservabilityLayout from '@/components/layouts/ObservabilityLayout/ObservabilityLayout'
|
||||
import ProductEmptyState from '@/components/to-be-cleaned/ProductEmptyState'
|
||||
import { useContentQuery } from '@/data/content/content-query'
|
||||
import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions'
|
||||
import { useProfile } from '@/lib/profile'
|
||||
import type { NextPageWithLayout } from '@/types'
|
||||
import { FGA_PERMISSIONS, useAsyncCheckUserContentPermissions } from '@/hooks/misc/useCheckPermissionsV2'
|
||||
|
||||
export const UserReportPage: NextPageWithLayout = () => {
|
||||
const router = useRouter()
|
||||
@@ -48,12 +47,11 @@ export const UserReportPage: NextPageWithLayout = () => {
|
||||
if (reports.length === 0) router.replace(`/project/${ref}/observability/api-overview`)
|
||||
}, [isSuccess, data, router, ref, showOverview, flagsLoaded])
|
||||
|
||||
const { can: canCreateReport } = useAsyncCheckPermissions(
|
||||
PermissionAction.CREATE,
|
||||
'user_content',
|
||||
const { can: canCreateReport } = useAsyncCheckUserContentPermissions(
|
||||
FGA_PERMISSIONS.PROJECT.SNIPPETS_WRITE,
|
||||
{
|
||||
resource: { type: 'report', owner_id: profile?.id },
|
||||
subject: { id: profile?.id },
|
||||
mode: 'create',
|
||||
type: 'report',
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { PermissionAction } from '@supabase/shared-types/out/constants'
|
||||
import { IS_PLATFORM, useParams } from 'common'
|
||||
import { useMemo } from 'react'
|
||||
import { Separator } from 'ui'
|
||||
@@ -16,15 +15,17 @@ import SettingsLayout from '@/components/layouts/ProjectSettingsLayout/SettingsL
|
||||
import { DisableInteraction } from '@/components/ui/DisableInteraction'
|
||||
import { DocsButton } from '@/components/ui/DocsButton'
|
||||
import { useAPIKeysQuery } from '@/data/api-keys/api-keys-query'
|
||||
import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions'
|
||||
import { useDeploymentMode } from '@/hooks/misc/useDeploymentMode'
|
||||
import { DOCS_URL } from '@/lib/constants'
|
||||
import type { NextPageWithLayout } from '@/types'
|
||||
import { useAsyncCheckPermissionsV2, FGA_PERMISSIONS } from '@/hooks/misc/useCheckPermissionsV2'
|
||||
|
||||
const ApiKeysNewPage: NextPageWithLayout = () => {
|
||||
const { ref: projectRef } = useParams()
|
||||
const { isCli, isSelfHosted } = useDeploymentMode()
|
||||
const { can: canReadAPIKeys } = useAsyncCheckPermissions(PermissionAction.SECRETS_READ, '*')
|
||||
const { can: canReadAPIKeys } = useAsyncCheckPermissionsV2(
|
||||
FGA_PERMISSIONS.PROJECT.API_GATEWAY_KEYS_READ
|
||||
)
|
||||
const { data: apiKeysData = [] } = useAPIKeysQuery(
|
||||
{
|
||||
projectRef,
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { PermissionAction } from '@supabase/shared-types/out/constants'
|
||||
import { IS_PLATFORM } from 'common'
|
||||
import { GenericSkeletonLoader } from 'ui-patterns/ShimmeringLoader'
|
||||
|
||||
@@ -8,16 +7,15 @@ import JWTKeysLayout from '@/components/layouts/JWTKeys/JWTKeysLayout'
|
||||
import SettingsLayout from '@/components/layouts/ProjectSettingsLayout/SettingsLayout'
|
||||
import { LocalSetupGuide } from '@/components/ui/LocalSetupGuide'
|
||||
import { NoPermission } from '@/components/ui/NoPermission'
|
||||
import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions'
|
||||
import { useDeploymentMode } from '@/hooks/misc/useDeploymentMode'
|
||||
import { DOCS_URL } from '@/lib/constants'
|
||||
import type { NextPageWithLayout } from '@/types'
|
||||
import { useAsyncCheckPermissionsV2, FGA_PERMISSIONS } from '@/hooks/misc/useCheckPermissionsV2'
|
||||
|
||||
const JWTSigningKeysPage: NextPageWithLayout = () => {
|
||||
const { isCli, isSelfHosted } = useDeploymentMode()
|
||||
const { can: canReadAPIKeys, isSuccess: isPermissionsLoaded } = useAsyncCheckPermissions(
|
||||
PermissionAction.READ,
|
||||
'auth_signing_keys'
|
||||
const { can: canReadAPIKeys, isSuccess: isPermissionsLoaded } = useAsyncCheckPermissionsV2(
|
||||
FGA_PERMISSIONS.PROJECT.AUTH_SIGNING_KEYS_READ
|
||||
)
|
||||
|
||||
if (!IS_PLATFORM) {
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { PermissionAction } from '@supabase/shared-types/out/constants'
|
||||
import { IS_PLATFORM, useParams } from 'common'
|
||||
import { ChevronDown } from 'lucide-react'
|
||||
import { cloneElement, useState, type ReactElement } from 'react'
|
||||
@@ -31,16 +30,15 @@ import {
|
||||
import { LogDrainData, useLogDrainsQuery } from '@/data/log-drains/log-drains-query'
|
||||
import { useUpdateLogDrainMutation } from '@/data/log-drains/update-log-drain-mutation'
|
||||
import { useCheckEntitlements } from '@/hooks/misc/useCheckEntitlements'
|
||||
import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions'
|
||||
import { DOCS_URL } from '@/lib/constants'
|
||||
import { useTrack } from '@/lib/telemetry/track'
|
||||
import { SHORTCUT_IDS } from '@/state/shortcuts/registry'
|
||||
import type { NextPageWithLayout } from '@/types'
|
||||
import { useAsyncCheckPermissionsV2, FGA_PERMISSIONS } from '@/hooks/misc/useCheckPermissionsV2'
|
||||
|
||||
const LogDrainsSettings: NextPageWithLayout = () => {
|
||||
const { can: canManageLogDrains, isLoading: isLoadingPermissions } = useAsyncCheckPermissions(
|
||||
PermissionAction.ANALYTICS_ADMIN_WRITE,
|
||||
'logflare'
|
||||
const { can: canManageLogDrains, isLoading: isLoadingPermissions } = useAsyncCheckPermissionsV2(
|
||||
FGA_PERMISSIONS.PROJECT.ANALYTICS_CONFIG_WRITE
|
||||
)
|
||||
|
||||
const track = useTrack()
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
import { PermissionAction } from '@supabase/shared-types/out/constants'
|
||||
import { createFileRoute, Outlet } from '@tanstack/react-router'
|
||||
|
||||
import { PageLayout } from '@/components/layouts/PageLayout/PageLayout'
|
||||
import { NoPermission } from '@/components/ui/NoPermission'
|
||||
import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions'
|
||||
import { useAsyncCheckPermissionsV2, FGA_PERMISSIONS } from '@/hooks/misc/useCheckPermissionsV2'
|
||||
|
||||
export const Route = createFileRoute('/project/$ref/database/triggers')({
|
||||
component: TriggersShell,
|
||||
@@ -14,9 +13,8 @@ export const Route = createFileRoute('/project/$ref/database/triggers')({
|
||||
|
||||
function TriggersShell() {
|
||||
const { ref } = Route.useParams()
|
||||
const { can: canReadTriggers, isSuccess: isPermissionsLoaded } = useAsyncCheckPermissions(
|
||||
PermissionAction.TENANT_SQL_ADMIN_READ,
|
||||
'triggers'
|
||||
const { can: canReadTriggers, isSuccess: isPermissionsLoaded } = useAsyncCheckPermissionsV2(
|
||||
FGA_PERMISSIONS.PROJECT.DATABASE_READ
|
||||
)
|
||||
|
||||
if (isPermissionsLoaded && !canReadTriggers) {
|
||||
|
||||
+12
-12
@@ -25,10 +25,12 @@ vi.mock('@/hooks/misc/useSelectedOrganization', () => ({
|
||||
}),
|
||||
}))
|
||||
|
||||
vi.mock('@/hooks/misc/useCheckPermissions', () => ({
|
||||
useGetPermissions: () => ({ permissions: [], organizationSlug: 'test-org' }),
|
||||
doPermissionsCheck: () => true,
|
||||
useAsyncCheckPermissions: () => ({ can: true, isSuccess: true }),
|
||||
vi.mock('@/data/permissions/permissions-query-v2', () => ({
|
||||
usePermissionsQueryV2: () => ({
|
||||
data: {
|
||||
organizations: [{ slug: 'test-org', role: 'owner', permissions: [], projects: [] }],
|
||||
},
|
||||
}),
|
||||
}))
|
||||
|
||||
vi.mock('@/hooks/misc/useIsFeatureEnabled', () => ({
|
||||
@@ -76,13 +78,14 @@ vi.mock('@/hooks/misc/useCheckEntitlements', () => ({
|
||||
useCheckEntitlements: () => ({ hasAccess: false }),
|
||||
}))
|
||||
|
||||
const { mockRolesManagementPermissions, mockIsFeatureEnabled } = vi.hoisted(() => ({
|
||||
mockRolesManagementPermissions: vi.fn(),
|
||||
const { mockGetAssignableRoleIds, mockIsFeatureEnabled } = vi.hoisted(() => ({
|
||||
mockGetAssignableRoleIds: vi.fn(),
|
||||
mockIsFeatureEnabled: vi.fn(),
|
||||
}))
|
||||
|
||||
vi.mock('@/components/interfaces/Organization/TeamSettings/TeamSettings.utils', () => ({
|
||||
useGetRolesManagementPermissions: mockRolesManagementPermissions,
|
||||
getOrgRole: () => 'owner',
|
||||
getAssignableRoleIds: mockGetAssignableRoleIds,
|
||||
}))
|
||||
|
||||
const mockInvite = vi.fn().mockResolvedValue({ succeeded: [], failed: [] })
|
||||
@@ -124,10 +127,7 @@ async function submitForm(emailValue: string) {
|
||||
describe('InviteMemberButton', () => {
|
||||
beforeEach(() => {
|
||||
mockInvite.mockResolvedValue({ succeeded: [], failed: [] })
|
||||
mockRolesManagementPermissions.mockReturnValue({
|
||||
rolesAddable: [1, 2, 3, 4],
|
||||
rolesRemovable: [1, 2, 3, 4],
|
||||
})
|
||||
mockGetAssignableRoleIds.mockReturnValue([1, 2, 3, 4])
|
||||
mockIsFeatureEnabled.mockReturnValue({ organizationMembersCreate: true })
|
||||
})
|
||||
|
||||
@@ -148,7 +148,7 @@ describe('InviteMemberButton', () => {
|
||||
|
||||
describe('when the user cannot invite members', () => {
|
||||
beforeEach(() => {
|
||||
mockRolesManagementPermissions.mockReturnValue({ rolesAddable: [], rolesRemovable: [] })
|
||||
mockGetAssignableRoleIds.mockReturnValue([])
|
||||
})
|
||||
|
||||
it('shows only the permission warning, not the shortcut tooltip', async () => {
|
||||
|
||||
@@ -23,8 +23,9 @@ vi.mock('common', async () => {
|
||||
}
|
||||
})
|
||||
|
||||
vi.mock('@/hooks/misc/useCheckPermissions', () => ({
|
||||
useAsyncCheckPermissions: mockUseAsyncCheckPermissions,
|
||||
vi.mock('@/hooks/misc/useCheckPermissionsV2', () => ({
|
||||
useAsyncCheckPermissionsV2: mockUseAsyncCheckPermissions,
|
||||
FGA_PERMISSIONS: { PROJECT: { API_GATEWAY_KEYS_READ: 'api_gateway_keys_read' } },
|
||||
}))
|
||||
|
||||
vi.mock('@/data/api-keys/api-keys-query', () => ({
|
||||
|
||||
@@ -20,8 +20,9 @@ vi.mock('common', async () => {
|
||||
}
|
||||
})
|
||||
|
||||
vi.mock('@/hooks/misc/useCheckPermissions', () => ({
|
||||
useAsyncCheckPermissions: mockUseAsyncCheckPermissions,
|
||||
vi.mock('@/hooks/misc/useCheckPermissionsV2', () => ({
|
||||
useAsyncCheckPermissionsV2: mockUseAsyncCheckPermissions,
|
||||
FGA_PERMISSIONS: { PROJECT: { AUTH_SIGNING_KEYS_READ: 'auth_signing_keys_read' } },
|
||||
}))
|
||||
|
||||
vi.mock('@/hooks/misc/useDeploymentMode', () => ({
|
||||
|
||||
Reference in new issue
Block a user