Joshen/fe 2660 clean up stale feature flags enabled for 2 months part 1 (#43329)

## Context 

Just cleaning up feature flags that have been toggled on for all users
and unchanged for the past 2 months
- advisorRules
- newJwtSecrets
- isWorkOSTPAEnabled
- EnableOAuth21
- gitlessBranching
- showRefreshToast
- awsPrivateLinkIntegration
- useBedrockAssistant (Already not used)
- enableStripeSyncEngineIntegration
- ShowExplainWithAiInQueryPerformance

Doing it in 2 parts so its easier for review
This commit is contained in:
Joshen Lim authored and GitHub committed 2026-03-04 13:08:39 +08:00
1 parent 2306898f7b
commit 564f4f66ee
19 files changed
+108 -322

No files matched your search

@@ -25,13 +25,13 @@ import {
} from 'lucide-react'
import dynamic from 'next/dynamic'
import { useMemo } from 'react'
import type { CommandOptions, ICommand } from 'ui-patterns/CommandMenu'
import {
PageType,
useRegisterCommands,
useRegisterPage,
useSetCommandMenuOpen,
} from 'ui-patterns/CommandMenu'
import type { CommandOptions, ICommand } from 'ui-patterns/CommandMenu'
import { COMMAND_MENU_SECTIONS } from './CommandMenu.utils'
import {
@@ -58,7 +58,6 @@ export function useCreateCommands(options?: CommandOptions) {
setPage,
openSidebar,
snap,
authenticationOauth21,
authEnabled,
edgeFunctionsEnabled,
storageEnabled,
@@ -184,7 +183,7 @@ export function useCreateCommands(options?: CommandOptions) {
},
]
: []),
...(IS_PLATFORM && authenticationOauth21
...(IS_PLATFORM
? [
{
id: 'create-oauth-app',
@@ -207,7 +206,6 @@ export function useCreateCommands(options?: CommandOptions) {
passwordVerificationHook,
passwordVerificationHookEnabled,
beforeUserCreatedHook,
authenticationOauth21,
]
)
@@ -1,4 +1,4 @@
import { useFlag, useParams } from 'common'
import { useParams } from 'common'
import type { Hook } from 'components/interfaces/Auth/Hooks/hooks.constants'
import { HOOKS_DEFINITIONS } from 'components/interfaces/Auth/Hooks/hooks.constants'
import { extractMethod, isValidHook } from 'components/interfaces/Auth/Hooks/hooks.utils'
@@ -89,9 +89,6 @@ export function useCreateCommandsConfig() {
const { openSidebar } = useSidebarManagerSnapshot()
const snap = useAiAssistantStateSnapshot()
// Auth
const authenticationOauth21 = useFlag('EnableOAuth21')
const {
projectAuthAll: authEnabled,
projectEdgeFunctionAll: edgeFunctionsEnabled,
@@ -182,7 +179,6 @@ export function useCreateCommandsConfig() {
setPage,
openSidebar,
snap,
authenticationOauth21,
authEnabled,
edgeFunctionsEnabled,
storageEnabled,
@@ -93,8 +93,7 @@ export const useUnifiedLogsPreview = () => {
export const useIsBranching2Enabled = () => {
const { flags } = useFeaturePreviewContext()
const gitlessBranchingEnabled = useFlag('gitlessBranching')
return gitlessBranchingEnabled && flags[LOCAL_STORAGE_KEYS.UI_PREVIEW_BRANCHING_2_0]
return flags[LOCAL_STORAGE_KEYS.UI_PREVIEW_BRANCHING_2_0]
}
export const useIsPgDeltaDiffEnabled = () => {
@@ -105,8 +104,7 @@ export const useIsPgDeltaDiffEnabled = () => {
export const useIsAdvisorRulesEnabled = () => {
const { flags } = useFeaturePreviewContext()
const advisorRulesEnabled = useFlag('advisorRules')
return advisorRulesEnabled && flags[LOCAL_STORAGE_KEYS.UI_PREVIEW_ADVISOR_RULES]
return flags[LOCAL_STORAGE_KEYS.UI_PREVIEW_ADVISOR_RULES]
}
export const useIsQueueOperationsEnabled = () => {
@@ -14,8 +14,6 @@ type FeaturePreview = {
}
export const useFeaturePreviews = (): FeaturePreview[] => {
const gitlessBranchingEnabled = useFlag('gitlessBranching')
const advisorRulesEnabled = useFlag('advisorRules')
const isUnifiedLogsPreviewAvailable = useFlag('unifiedLogs')
const tableEditorNewFilterBar = useFlag('tableEditorNewFilterBar')
const pgDeltaDiffEnabled = useFlag('pgdeltaDiff')
@@ -34,7 +32,7 @@ export const useFeaturePreviews = (): FeaturePreview[] => {
key: LOCAL_STORAGE_KEYS.UI_PREVIEW_BRANCHING_2_0,
name: 'Branching via dashboard',
discussionsUrl: 'https://github.com/orgs/supabase/discussions/branching-2-0',
enabled: gitlessBranchingEnabled,
enabled: true,
isNew: false,
isPlatformOnly: true,
isDefaultOptIn: false,
@@ -43,7 +41,7 @@ export const useFeaturePreviews = (): FeaturePreview[] => {
key: LOCAL_STORAGE_KEYS.UI_PREVIEW_ADVISOR_RULES,
name: 'Disable Advisor rules',
discussionsUrl: undefined,
enabled: advisorRulesEnabled,
enabled: true,
isNew: false,
isPlatformOnly: true,
isDefaultOptIn: false,
@@ -1,7 +1,5 @@
import { ChevronDown } from 'lucide-react'
import Image from 'next/image'
import { useFlag } from 'common'
import {
Button,
cn,
@@ -12,6 +10,7 @@ import {
DropdownMenuSeparator,
DropdownMenuTrigger,
} from 'ui'
import {
getIntegrationTypeIcon,
getIntegrationTypeLabel,
@@ -52,8 +51,6 @@ export const AddIntegrationDropdown = ({
align = 'end',
onSelectIntegrationType,
}: AddIntegrationDropdownProps) => {
const isWorkOSEnabled = useFlag('isWorkOSTPAEnabled')
return (
<DropdownMenu>
<DropdownMenuTrigger asChild>
@@ -64,12 +61,9 @@ export const AddIntegrationDropdown = ({
<DropdownMenuContent align={align} className="w-56">
<DropdownMenuLabel>Select provider</DropdownMenuLabel>
<DropdownMenuSeparator />
<ProviderDropdownItem type="firebase" onSelectIntegrationType={onSelectIntegrationType} />
<ProviderDropdownItem type="clerk" onSelectIntegrationType={onSelectIntegrationType} />
{isWorkOSEnabled && (
<ProviderDropdownItem type="workos" onSelectIntegrationType={onSelectIntegrationType} />
)}
<ProviderDropdownItem type="workos" onSelectIntegrationType={onSelectIntegrationType} />
<ProviderDropdownItem type="auth0" onSelectIntegrationType={onSelectIntegrationType} />
<ProviderDropdownItem type="awsCognito" onSelectIntegrationType={onSelectIntegrationType} />
</DropdownMenuContent>
@@ -1,4 +1,3 @@
import { useFlag } from 'common'
import { useDatabaseExtensionsQuery } from 'data/database-extensions/database-extensions-query'
import { useSchemasQuery } from 'data/database/schemas-query'
import { useFDWsQuery } from 'data/fdw/fdws-query'
@@ -19,7 +18,6 @@ import {
export const useInstalledIntegrations = () => {
const { data: project } = useSelectedProjectQuery()
const { integrationsWrappers } = useIsFeatureEnabled(['integrations:wrappers'])
const stripeSyncEnabled = useFlag('enableStripeSyncEngineIntegration')
const allIntegrations = useMemo(() => {
return INTEGRATIONS.filter((integration) => {
@@ -29,15 +27,12 @@ export const useInstalledIntegrations = () => {
) {
return false
}
if (!stripeSyncEnabled && integration.id === 'stripe_sync_engine') {
return false
}
if (!IS_PLATFORM && integration.id === 'data_api') {
return false
}
return true
})
}, [integrationsWrappers, stripeSyncEnabled])
}, [integrationsWrappers])
const {
data,
@@ -1,10 +1,5 @@
import { PermissionAction } from '@supabase/shared-types/out/constants'
import { AnimatePresence } from 'framer-motion'
import { AlertCircle, RotateCw, Timer } from 'lucide-react'
import { useMemo, useState } from 'react'
import { toast } from 'sonner'
import { useFlag, useParams } from 'common'
import { useParams } from 'common'
import { TextConfirmModal } from 'components/ui/TextConfirmModalWrapper'
import { useLegacyAPIKeysStatusQuery } from 'data/api-keys/legacy-api-keys-status-query'
import { useJWTSigningKeyDeleteMutation } from 'data/jwt-signing-keys/jwt-signing-key-delete-mutation'
@@ -12,8 +7,12 @@ import { useJWTSigningKeyUpdateMutation } from 'data/jwt-signing-keys/jwt-signin
import { JWTSigningKey, useJWTSigningKeysQuery } from 'data/jwt-signing-keys/jwt-signing-keys-query'
import { useLegacyJWTSigningKeyCreateMutation } from 'data/jwt-signing-keys/legacy-jwt-signing-key-create-mutation'
import { useLegacyJWTSigningKeyQuery } from 'data/jwt-signing-keys/legacy-jwt-signing-key-query'
import { AnimatePresence } from 'framer-motion'
import { useAsyncCheckPermissions } from 'hooks/misc/useCheckPermissions'
import { useSelectedProjectQuery } from 'hooks/misc/useSelectedProject'
import { AlertCircle, RotateCw, Timer } from 'lucide-react'
import { useMemo, useState } from 'react'
import { toast } from 'sonner'
import {
AlertDialog,
AlertDialogCancel,
@@ -39,7 +38,7 @@ import {
TableRow,
} from 'ui'
import { GenericSkeletonLoader } from 'ui-patterns/ShimmeringLoader'
import { SigningKeysComingSoonBanner } from '../signing-keys-coming-soon'
import { StartUsingJwtSigningKeysBanner } from '../start-using-keys-banner'
import { ActionPanel } from './action-panel'
import { CreateKeyDialog } from './create-key-dialog'
@@ -53,8 +52,6 @@ export const JWTSecretKeysTable = () => {
const { ref: projectRef } = useParams()
const { data: project, isPending: isProjectLoading } = useSelectedProjectQuery()
const newJwtSecrets = useFlag('newJwtSecrets')
const [selectedKey, setSelectedKey] = useState<JWTSigningKey>()
const [selectedKeyToUpdate, setSelectedKeyToUpdate] = useState<string>()
const [shownDialog, setShownDialog] = useState<DialogType>()
@@ -182,10 +179,6 @@ export const JWTSecretKeysTable = () => {
return <GenericSkeletonLoader />
}
if (!newJwtSecrets) {
return <SigningKeysComingSoonBanner />
}
return (
<>
<div className="-space-y-px">
@@ -4,6 +4,20 @@ import {
JwtSecretUpdateProgress,
JwtSecretUpdateStatus,
} from '@supabase/shared-types/out/events'
import { useParams } from 'common'
import { ButtonTooltip } from 'components/ui/ButtonTooltip'
import { FormActions } from 'components/ui/Forms/FormActions'
import Panel from 'components/ui/Panel'
import { TextConfirmModal } from 'components/ui/TextConfirmModalWrapper'
import { useLegacyAPIKeysStatusQuery } from 'data/api-keys/legacy-api-keys-status-query'
import { useAuthConfigQuery } from 'data/auth/auth-config-query'
import { useAuthConfigUpdateMutation } from 'data/auth/auth-config-update-mutation'
import { useJwtSecretUpdateMutation } from 'data/config/jwt-secret-update-mutation'
import { useJwtSecretUpdatingStatusQuery } from 'data/config/jwt-secret-updating-status-query'
import { useProjectPostgrestConfigQuery } from 'data/config/project-postgrest-config-query'
import { useLegacyJWTSigningKeyQuery } from 'data/jwt-signing-keys/legacy-jwt-signing-key-query'
import { useAsyncCheckPermissions } from 'hooks/misc/useCheckPermissions'
import { uuidv4 } from 'lib/helpers'
import {
AlertCircle,
ChevronDown,
@@ -23,21 +37,6 @@ import {
import Link from 'next/link'
import { Dispatch, SetStateAction, useState } from 'react'
import { toast } from 'sonner'
import { useFlag, useParams } from 'common'
import { ButtonTooltip } from 'components/ui/ButtonTooltip'
import { FormActions } from 'components/ui/Forms/FormActions'
import Panel from 'components/ui/Panel'
import { TextConfirmModal } from 'components/ui/TextConfirmModalWrapper'
import { useLegacyAPIKeysStatusQuery } from 'data/api-keys/legacy-api-keys-status-query'
import { useAuthConfigQuery } from 'data/auth/auth-config-query'
import { useAuthConfigUpdateMutation } from 'data/auth/auth-config-update-mutation'
import { useJwtSecretUpdateMutation } from 'data/config/jwt-secret-update-mutation'
import { useJwtSecretUpdatingStatusQuery } from 'data/config/jwt-secret-updating-status-query'
import { useProjectPostgrestConfigQuery } from 'data/config/project-postgrest-config-query'
import { useLegacyJWTSigningKeyQuery } from 'data/jwt-signing-keys/legacy-jwt-signing-key-query'
import { useAsyncCheckPermissions } from 'hooks/misc/useCheckPermissions'
import { uuidv4 } from 'lib/helpers'
import {
Button,
DropdownMenu,
@@ -52,6 +51,7 @@ import {
} from 'ui'
import { Admonition } from 'ui-patterns/admonition'
import { number, object } from 'yup'
import {
JWT_SECRET_UPDATE_ERROR_MESSAGES,
JWT_SECRET_UPDATE_PROGRESS_MESSAGES,
@@ -66,8 +66,6 @@ const schema = object({
const JWTSettings = () => {
const { ref: projectRef } = useParams()
const newJwtSecrets = useFlag('newJwtSecrets')
const [customToken, setCustomToken] = useState<string>('')
const [showCustomTokenInput, setShowCustomTokenInput] = useState(false)
const [isCreatingKey, setIsCreatingKey] = useState<boolean>(false)
@@ -276,7 +274,7 @@ const JWTSettings = () => {
disabled={!canUpdateConfig || isLoadingAuthConfig}
/>
{newJwtSecrets && !legacyKey && (
{!legacyKey && (
<>
{isUpdatingJwtSecret && (
<div className="flex items-center space-x-2">
@@ -388,89 +386,6 @@ const JWTSettings = () => {
</div>
</>
)}
{!newJwtSecrets && (
<div className="space-y-3">
<div className="p-3 px-6 border rounded-md shadow-sm bg-studio">
{isUpdatingJwtSecret ? (
<div className="flex items-center space-x-2">
<Loader2 className="animate-spin" size={14} />
<p className="text-sm">
Updating JWT secret: {jwtSecretUpdateProgressMessage}
</p>
</div>
) : (
<div className="w-full space-y-2">
<div className="flex items-center justify-between w-full">
<div className="flex flex-col space-y-1">
<p className="text-sm">Generate a new JWT secret</p>
<p className="text-sm opacity-50">
A random secret will be created, or you can create your own.
</p>
</div>
<div className="flex flex-col items-end">
{isUpdatingJwtSecret ? (
<Button loading type="secondary">
Updating JWT secret...
</Button>
) : !canGenerateNewJWTSecret ? (
<ButtonTooltip
disabled
type="default"
iconRight={<ChevronDown size={14} />}
tooltip={{
content: {
side: 'bottom',
text: 'You need additional permissions to generate a new JWT secret',
},
}}
>
Generate a new secret
</ButtonTooltip>
) : (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button
type="default"
iconRight={<ChevronDown size={14} />}
>
<span>Generate a new secret</span>
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end" side="bottom">
<DropdownMenuItem
className="space-x-2"
onClick={() => setIsGeneratingKey(true)}
>
<RefreshCw size={16} />
<p>Generate a random secret</p>
</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem
className="space-x-2"
onClick={() => setIsCreatingKey(true)}
>
<PenTool size={16} />
<p>Create my own secret</p>
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
)}
</div>
</div>
</div>
)}
</div>
{isJwtSecretUpdateFailed ? (
<Admonition type="warning" title="Failed to update JWT secret">
Please try again. If the failures persist, please contact Supabase
support with the following details: <br />
Change tracking ID: {data?.changeTrackingId} <br />
Error message: {jwtSecretUpdateErrorMessage}
</Admonition>
) : null}
</div>
)}
</>
)}
</Panel.Content>
@@ -1,28 +0,0 @@
import { Github } from 'lucide-react'
import { Button } from 'ui'
import { FeatureBanner } from 'components/ui/FeatureBanner'
export const SigningKeysComingSoonBanner = () => {
return (
<FeatureBanner bgAlt className="pb-10">
<div className="flex flex-col gap-0 z-[2]">
<p className="text-sm text-foreground">JWT signing keys are coming soon</p>
<p className="text-sm text-foreground-lighter lg:max-w-sm 2xl:max-w-none">
We're rolling out JWT signing keys to better support your application needs.
</p>
<div className="mt-4">
<Button type="default" icon={<Github />}>
<a
href="https://github.com/orgs/supabase/discussions/29289"
target="_blank"
rel="noreferrer"
>
Learn more
</a>
</Button>
</div>
</div>
</FeatureBanner>
)
}
@@ -1,4 +1,3 @@
import { useFlag } from 'common'
import { SIDEBAR_KEYS } from 'components/layouts/ProjectLayout/LayoutSidebar/LayoutSidebarProvider'
import { AiAssistantDropdown } from 'components/ui/AiAssistantDropdown'
import { formatSql } from 'lib/formatSql'
@@ -40,8 +39,6 @@ export const QueryDetail = ({ selectedRow, onClickViewSuggestion, onClose }: Que
const aiSnap = useAiAssistantStateSnapshot()
const track = useTrack()
const showExplainWithAiInQueryPerformance = useFlag('ShowExplainWithAiInQueryPerformance')
useEffect(() => {
if (selectedRow !== undefined) {
const formattedQuery = formatSql(selectedRow['query'])
@@ -85,16 +82,14 @@ export const QueryDetail = ({ selectedRow, onClickViewSuggestion, onClose }: Que
<QueryPanelSection className="pt-2 border-b relative">
<div className="flex items-center justify-between mb-4">
<h4>Query pattern</h4>
{showExplainWithAiInQueryPerformance && (
<AiAssistantDropdown
label="Explain with AI"
buildPrompt={buildPromptForCopy}
onOpenAssistant={handleExplainQuery}
telemetrySource="query_performance"
size="tiny"
type="default"
/>
)}
<AiAssistantDropdown
label="Explain with AI"
buildPrompt={buildPromptForCopy}
onOpenAssistant={handleExplainQuery}
telemetrySource="query_performance"
size="tiny"
type="default"
/>
</div>
<div
className={cn(
@@ -1,13 +1,12 @@
import Link from 'next/link'
import { useFlag } from 'common'
import { SidePanelVercelProjectLinker } from 'components/interfaces/Organization/IntegrationSettings/SidePanelVercelProjectLinker'
import { ScaffoldContainer, ScaffoldDivider } from 'components/layouts/Scaffold'
import { useProjectDetailQuery } from 'data/projects/project-detail-query'
import { useIsFeatureEnabled } from 'hooks/misc/useIsFeatureEnabled'
import { useSelectedProjectQuery } from 'hooks/misc/useSelectedProject'
import { BASE_PATH } from 'lib/constants'
import { AlertDescription_Shadcn_, AlertTitle_Shadcn_, Alert_Shadcn_, WarningIcon } from 'ui'
import Link from 'next/link'
import { Alert_Shadcn_, AlertDescription_Shadcn_, AlertTitle_Shadcn_, WarningIcon } from 'ui'
import { AWSPrivateLinkSection } from './AWSPrivateLink/AWSPrivateLinkSection'
import { GitHubSection } from './GithubIntegration/GithubSection'
import { VercelSection } from './VercelIntegration/VercelSection'
@@ -29,11 +28,9 @@ const IntegrationSettings = () => {
const showVercelIntegration = useIsFeatureEnabled('integrations:vercel')
const showAWSPrivateLinkFeature = useIsFeatureEnabled('integrations:aws_private_link')
const showAWSPrivateLinkConfigCat = useFlag('awsPrivateLinkIntegration')
// PrivateLink is not available in eu-central-2 (Zurich) until Feb 2026
const isPrivateLinkUnsupportedRegion = project?.region === 'eu-central-2'
const showAWSPrivateLink =
showAWSPrivateLinkFeature && showAWSPrivateLinkConfigCat && !isPrivateLinkUnsupportedRegion
const showAWSPrivateLink = showAWSPrivateLinkFeature && !isPrivateLinkUnsupportedRegion
return (
<>
@@ -3,10 +3,7 @@ import type { Project } from 'data/projects/project-detail-query'
import { IS_PLATFORM } from 'lib/constants'
import { ArrowUpRight } from 'lucide-react'
export const generateAdvisorsMenu = (
project?: Project,
features?: { advisorRules: boolean }
): ProductMenuGroup[] => {
export const generateAdvisorsMenu = (project?: Project): ProductMenuGroup[] => {
const ref = project?.ref ?? 'default'
return [
@@ -34,7 +31,7 @@ export const generateAdvisorsMenu = (
},
],
},
...(IS_PLATFORM && features?.advisorRules
...(IS_PLATFORM
? [
{
title: 'Configuration',
@@ -1,9 +1,9 @@
import { useIsAdvisorRulesEnabled } from 'components/interfaces/App/FeaturePreview/FeaturePreviewContext'
import { SIDEBAR_KEYS } from 'components/layouts/ProjectLayout/LayoutSidebar/LayoutSidebarProvider'
import { ProductMenu } from 'components/ui/ProductMenu'
import { useSelectedProjectQuery } from 'hooks/misc/useSelectedProject'
import { useSidebarManagerSnapshot } from 'state/sidebar-manager-state'
import { Badge, Button } from 'ui'
import { FeaturePreviewSidebarPanel } from '../../ui/FeaturePreviewSidebarPanel'
import { generateAdvisorsMenu } from './AdvisorsMenu.utils'
@@ -13,7 +13,6 @@ interface AdvisorsSidebarMenuProps {
export function AdvisorsSidebarMenu({ page }: AdvisorsSidebarMenuProps) {
const { data: project } = useSelectedProjectQuery()
const advisorRules = useIsAdvisorRulesEnabled()
const { toggleSidebar } = useSidebarManagerSnapshot()
const handleOpenAdvisor = () => {
@@ -34,7 +33,7 @@ export function AdvisorsSidebarMenu({ page }: AdvisorsSidebarMenuProps) {
}
/>
<ProductMenu page={page} menu={generateAdvisorsMenu(project, { advisorRules })} />
<ProductMenu page={page} menu={generateAdvisorsMenu(project)} />
</div>
)
}
@@ -1,55 +1,23 @@
import { useParams } from 'common'
import { ProductMenu } from 'components/ui/ProductMenu'
import { useAuthConfigPrefetch } from 'data/auth/auth-config-query'
import { withAuth } from 'hooks/misc/withAuth'
import { useRouter } from 'next/router'
import { PropsWithChildren } from 'react'
import { useFlag, useParams } from 'common'
import { ProductMenu } from 'components/ui/ProductMenu'
import { useAuthConfigPrefetch } from 'data/auth/auth-config-query'
import { useIsFeatureEnabled } from 'hooks/misc/useIsFeatureEnabled'
import { withAuth } from 'hooks/misc/withAuth'
import { ProjectLayout } from '../ProjectLayout'
import { generateAuthMenu } from './AuthLayout.utils'
import { useGenerateAuthMenu } from './AuthLayout.utils'
const AuthProductMenu = () => {
const router = useRouter()
const { ref: projectRef = 'default' } = useParams()
const authenticationShowOverview = useFlag('authOverviewPage')
const authenticationOauth21 = useFlag('EnableOAuth21')
const {
authenticationSignInProviders,
authenticationRateLimits,
authenticationEmails,
authenticationMultiFactor,
authenticationAttackProtection,
authenticationPerformance,
} = useIsFeatureEnabled([
'authentication:sign_in_providers',
'authentication:rate_limits',
'authentication:emails',
'authentication:multi_factor',
'authentication:attack_protection',
'authentication:performance',
])
useAuthConfigPrefetch({ projectRef })
const page = router.pathname.split('/')[4]
return (
<ProductMenu
page={page}
menu={generateAuthMenu(projectRef, {
authenticationSignInProviders,
authenticationRateLimits,
authenticationEmails,
authenticationMultiFactor,
authenticationAttackProtection,
authenticationShowOverview,
authenticationOauth21,
authenticationPerformance,
})}
/>
)
const menu = useGenerateAuthMenu()
return <ProductMenu page={page} menu={menu} />
}
const AuthLayout = ({ children }: PropsWithChildren<{}>) => {
@@ -1,48 +1,45 @@
import { useFlag, useParams } from 'common'
import type { ProductMenuGroup } from 'components/ui/ProductMenu/ProductMenu.types'
import { IS_PLATFORM } from 'lib/constants'
export const generateAuthMenu = (
ref: string,
flags?: {
authenticationSignInProviders: boolean
authenticationRateLimits: boolean
authenticationEmails: boolean
authenticationMultiFactor: boolean
authenticationAttackProtection: boolean
authenticationShowOverview: boolean
authenticationOauth21: boolean
authenticationPerformance: boolean
}
): ProductMenuGroup[] => {
import { useIsFeatureEnabled } from '@/hooks/misc/useIsFeatureEnabled'
export const useGenerateAuthMenu = (): ProductMenuGroup[] => {
const { ref } = useParams()
const authenticationShowOverview = useFlag('authOverviewPage')
const {
authenticationSignInProviders,
authenticationRateLimits,
authenticationEmails,
authenticationMultiFactor,
authenticationAttackProtection,
authenticationShowOverview,
authenticationOauth21,
authenticationPerformance,
} = flags ?? {}
} = useIsFeatureEnabled([
'authentication:sign_in_providers',
'authentication:rate_limits',
'authentication:emails',
'authentication:multi_factor',
'authentication:attack_protection',
'authentication:performance',
])
const baseUrl = `/project/${ref}/auth`
return [
{
title: 'Manage',
items: [
...(authenticationShowOverview
? [{ name: 'Overview', key: 'overview', url: `/project/${ref}/auth/overview`, items: [] }]
: []),
{ name: 'Users', key: 'users', url: `/project/${ref}/auth/users`, items: [] },
...(authenticationOauth21
? [
{
name: 'OAuth Apps',
key: 'oauth-apps',
url: `/project/${ref}/auth/oauth-apps`,
items: [],
},
]
? [{ name: 'Overview', key: 'overview', url: `${baseUrl}/overview`, items: [] }]
: []),
{ name: 'Users', key: 'users', url: `${baseUrl}/users`, items: [] },
{
name: 'OAuth Apps',
key: 'oauth-apps',
url: `${baseUrl}/oauth-apps`,
items: [],
},
],
},
...(authenticationEmails && IS_PLATFORM
@@ -56,7 +53,7 @@ export const generateAuthMenu = (
name: 'Email',
key: 'email',
pages: ['templates', 'smtp'],
url: `/project/${ref}/auth/templates`,
url: `${baseUrl}/templates`,
items: [],
},
]
@@ -71,7 +68,7 @@ export const generateAuthMenu = (
{
name: 'Policies',
key: 'policies',
url: `/project/${ref}/auth/policies`,
url: `${baseUrl}/policies`,
items: [],
},
...(IS_PLATFORM
@@ -82,25 +79,21 @@ export const generateAuthMenu = (
name: 'Sign In / Providers',
key: 'sign-in-up',
pages: ['providers', 'third-party'],
url: `/project/${ref}/auth/providers`,
url: `${baseUrl}/providers`,
items: [],
},
]
: []),
...(authenticationOauth21
? [
{
name: 'OAuth Server',
key: 'oauth-server',
url: `/project/${ref}/auth/oauth-server`,
label: 'Beta',
},
]
: []),
{
name: 'OAuth Server',
key: 'oauth-server',
url: `${baseUrl}/oauth-server`,
label: 'Beta',
},
{
name: 'Sessions',
key: 'sessions',
url: `/project/${ref}/auth/sessions`,
url: `${baseUrl}/sessions`,
items: [],
},
...(authenticationRateLimits
@@ -108,7 +101,7 @@ export const generateAuthMenu = (
{
name: 'Rate Limits',
key: 'rate-limits',
url: `/project/${ref}/auth/rate-limits`,
url: `${baseUrl}/rate-limits`,
items: [],
},
]
@@ -118,7 +111,7 @@ export const generateAuthMenu = (
{
name: 'Multi-Factor',
key: 'mfa',
url: `/project/${ref}/auth/mfa`,
url: `${baseUrl}/mfa`,
items: [],
},
]
@@ -126,7 +119,7 @@ export const generateAuthMenu = (
{
name: 'URL Configuration',
key: 'url-configuration',
url: `/project/${ref}/auth/url-configuration`,
url: `${baseUrl}/url-configuration`,
items: [],
},
...(authenticationAttackProtection
@@ -134,7 +127,7 @@ export const generateAuthMenu = (
{
name: 'Attack Protection',
key: 'protection',
url: `/project/${ref}/auth/protection`,
url: `${baseUrl}/protection`,
items: [],
},
]
@@ -142,14 +135,14 @@ export const generateAuthMenu = (
{
name: 'Auth Hooks',
key: 'hooks',
url: `/project/${ref}/auth/hooks`,
url: `${baseUrl}/hooks`,
items: [],
label: 'Beta',
},
{
name: 'Audit Logs',
key: 'audit-logs',
url: `/project/${ref}/auth/audit-logs`,
url: `${baseUrl}/audit-logs`,
items: [],
},
...(authenticationPerformance
@@ -157,7 +150,7 @@ export const generateAuthMenu = (
{
name: 'Performance',
key: 'performance',
url: `/project/${ref}/auth/performance`,
url: `${baseUrl}/performance`,
items: [],
},
]
@@ -1,10 +1,9 @@
import { IS_PLATFORM } from 'common'
import { useDeploymentCommitQuery } from 'data/utils/deployment-commit-query'
import dayjs from 'dayjs'
import { useRouter } from 'next/router'
import { useEffect, useRef, useState } from 'react'
import { toast } from 'sonner'
import { IS_PLATFORM, useFlag } from 'common'
import { useDeploymentCommitQuery } from 'data/utils/deployment-commit-query'
import { Button, StatusIcon } from 'ui'
const DeployCheckToast = ({ id }: { id: string | number }) => {
@@ -34,8 +33,6 @@ const DeployCheckToast = ({ id }: { id: string | number }) => {
// there's a new version of Studio is available, and the user has been on the old dashboard (based on commit) for more than 24 hours.
// [Joshen] K-Dog has a suggestion here to bring down the time period here by checking commits
export function useCheckLatestDeploy() {
const showRefreshToast = useFlag('showRefreshToast')
const [currentCommitTime, setCurrentCommitTime] = useState('')
const [isToastShown, setIsToastShown] = useState(false)
@@ -59,7 +56,7 @@ export function useCheckLatestDeploy() {
}, [commit])
useEffect(() => {
if (!showRefreshToast || !commit || commit.commitTime === 'unknown') {
if (!commit || commit.commitTime === 'unknown') {
return
}
@@ -91,5 +88,5 @@ export function useCheckLatestDeploy() {
position: 'bottom-right',
})
setIsToastShown(true)
}, [commit, showRefreshToast, isToastShown, currentCommitTime])
}, [commit, isToastShown, currentCommitTime])
}
@@ -4,8 +4,6 @@ import { VERSION } from 'stripe-experiment-sync'
import { install, uninstall } from 'stripe-experiment-sync/supabase'
import { z } from 'zod'
const ENABLE_FLAG_KEY = 'enableStripeSyncEngineIntegration'
const InstallBodySchema = z.object({
projectRef: z.string().min(1),
stripeSecretKey: z.string().min(1),
@@ -1,4 +1,4 @@
import { useFlag, useParams } from 'common'
import { useParams } from 'common'
import { INTEGRATIONS } from 'components/interfaces/Integrations/Landing/Integrations.constants'
import { useInstalledIntegrations } from 'components/interfaces/Integrations/Landing/useInstalledIntegrations'
import { DefaultLayout } from 'components/layouts/DefaultLayout'
@@ -41,7 +41,6 @@ const IntegrationPage: NextPageWithLayout = () => {
const router = useRouter()
const { ref, id, pageId, childId } = useParams()
const { integrationsWrappers } = useIsFeatureEnabled(['integrations:wrappers'])
const stripeSyncEnabled = useFlag('enableStripeSyncEngineIntegration')
const { installedIntegrations: installedIntegrations, isLoading: isIntegrationsLoading } =
useInstalledIntegrations()
@@ -140,10 +139,6 @@ const IntegrationPage: NextPageWithLayout = () => {
return <UnknownInterface urlBack={`/project/${ref}/integrations`} />
}
if (id === 'stripe_sync_engine' && !stripeSyncEnabled) {
return <UnknownInterface urlBack={`/project/${ref}/integrations`} />
}
if (!integrationsWrappers && id?.endsWith('_wrapper')) {
return <UnknownInterface urlBack={`/project/${ref}/integrations`} />
}
@@ -1,7 +1,3 @@
import { Search } from 'lucide-react'
import { parseAsString, useQueryState } from 'nuqs'
import { useMemo } from 'react'
import {
IntegrationCard,
IntegrationLoadingCard,
@@ -13,6 +9,9 @@ import { AlertError } from 'components/ui/AlertError'
import { DocsButton } from 'components/ui/DocsButton'
import { NoSearchResults } from 'components/ui/NoSearchResults'
import { DOCS_URL } from 'lib/constants'
import { Search } from 'lucide-react'
import { parseAsString, useQueryState } from 'nuqs'
import { useMemo } from 'react'
import type { NextPageWithLayout } from 'types'
import { Input } from 'ui-patterns/DataInputs/Input'
import { PageContainer } from 'ui-patterns/PageContainer'
@@ -25,9 +24,8 @@ import {
PageHeaderTitle,
} from 'ui-patterns/PageHeader'
import { PageSection, PageSectionContent, PageSectionMeta } from 'ui-patterns/PageSection'
import { useFlag } from 'common'
const FEATURED_INTEGRATIONS = ['cron', 'queues'] // + either stripe_sync_engine or stripe_wrapper depending on feature flag
const FEATURED_INTEGRATIONS = ['cron', 'queues', 'stripe_sync_engine']
// Featured integration images
const FEATURED_INTEGRATION_IMAGES: Record<string, string> = {
@@ -47,16 +45,6 @@ const IntegrationsPage: NextPageWithLayout = () => {
parseAsString.withDefault('').withOptions({ clearOnDefault: true })
)
const isStripeSyncEngineEnabled = useFlag('enableStripeSyncEngineIntegration')
const featuredIntegrationIds = useMemo(() => {
if (isStripeSyncEngineEnabled) {
return FEATURED_INTEGRATIONS.concat(['stripe_sync_engine'])
} else {
return FEATURED_INTEGRATIONS.concat(['stripe_wrapper'])
}
}, [isStripeSyncEngineEnabled])
const { availableIntegrations, installedIntegrations, error, isError, isLoading, isSuccess } =
useInstalledIntegrations()
@@ -117,7 +105,7 @@ const IntegrationsPage: NextPageWithLayout = () => {
}
const featured = filteredAndSortedIntegrations.filter((i) =>
featuredIntegrationIds.includes(i.id)
FEATURED_INTEGRATIONS.includes(i.id)
)
const allIntegrations = filteredAndSortedIntegrations // Include all integrations, including featured