From 6a8836f968eaa14eae44905ecfff856da1419745 Mon Sep 17 00:00:00 2001 From: Joshen Lim Date: Wed, 20 Aug 2025 20:17:34 +0800 Subject: [PATCH] Chore/disable more sections 02 (#38058) * Add flags for policies, third party auth, and manual linking + providers in sign in page * Add flag for rate limitm page * Add UnknownInterface components * Update comment * Flip flags to true * Add flags for realtime policies and reports page * Temp * Add flag for sign in providers page * Add flag for stripe wrapper * Add flag for custom domains * Add flag for dedicated ipv4 address addon * Add empty state for realtime policies * Add empty state for reports page * Add flag for disable legacy JWT keys section * Add flag for legacy jwt keys * nit * Remove ConnectionStringMoved call out * Add flag for project settings log drains * Add flag for subscription link in project settings * Deprecate settings/auth page and redirect directly to auth page * Flip back flags --- .../interfaces/Settings/Addons/Addons.tsx | 290 +++++++++--------- .../Database/ConnectionStringMoved.tsx | 53 ---- .../layouts/JWTKeys/JWTKeysLayout.tsx | 16 +- .../ProjectSettingsLayout/SettingsLayout.tsx | 15 + .../SettingsMenu.utils.tsx | 56 +++- .../ui/ProjectSettings/DisplayApiSettings.tsx | 31 +- .../pages/project/[ref]/database/settings.tsx | 4 +- .../pages/project/[ref]/settings/addons.tsx | 2 +- .../pages/project/[ref]/settings/auth.tsx | 106 ------- .../pages/project/[ref]/settings/general.tsx | 5 +- .../project/[ref]/settings/jwt/index.tsx | 24 +- .../enabled-features/enabled-features.json | 6 + .../enabled-features.schema.json | 27 ++ 13 files changed, 290 insertions(+), 345 deletions(-) delete mode 100644 apps/studio/components/interfaces/Settings/Database/ConnectionStringMoved.tsx delete mode 100644 apps/studio/pages/project/[ref]/settings/auth.tsx diff --git a/apps/studio/components/interfaces/Settings/Addons/Addons.tsx b/apps/studio/components/interfaces/Settings/Addons/Addons.tsx index 50cba0c77a5..058c99f796b 100644 --- a/apps/studio/components/interfaces/Settings/Addons/Addons.tsx +++ b/apps/studio/components/interfaces/Settings/Addons/Addons.tsx @@ -28,6 +28,7 @@ import { useProjectSettingsV2Query } from 'data/config/project-settings-v2-query import { useOrgSubscriptionQuery } from 'data/subscriptions/org-subscription-query' import { useProjectAddonsQuery } from 'data/subscriptions/project-addons-query' import type { ProjectAddonVariantMeta } from 'data/subscriptions/types' +import { useIsFeatureEnabled } from 'hooks/misc/useIsFeatureEnabled' import { useSelectedOrganizationQuery } from 'hooks/misc/useSelectedOrganization' import { useIsOrioleDbInAws, @@ -45,13 +46,18 @@ import CustomDomainSidePanel from './CustomDomainSidePanel' import IPv4SidePanel from './IPv4SidePanel' import PITRSidePanel from './PITRSidePanel' -const Addons = () => { +export const Addons = () => { const { resolvedTheme } = useTheme() const { ref: projectRef } = useParams() const { setPanel } = useAddonsPagePanel() const isProjectActive = useIsProjectActive() const isOrioleDbInAws = useIsOrioleDbInAws() + const { projectSettingsCustomDomains, projectAddonsDedicatedIpv4Address } = useIsFeatureEnabled([ + 'project_settings:custom_domains', + 'project_addons:dedicated_ipv4_address', + ]) + const { data: selectedOrg } = useSelectedOrganizationQuery() const { data: selectedProject, isLoading: isLoadingProject } = useSelectedProjectQuery() const { data: parentProject } = useProjectByRefQuery(selectedProject?.parent_project_ref) @@ -330,80 +336,83 @@ const Addons = () => { - - - - - -
-

Dedicated IPv4 address

-
-

More information

-
- -
-

About IPv4 deprecation

- + {projectAddonsDedicatedIpv4Address && ( + <> + + + + +
+

Dedicated IPv4 address

+
+

More information

+
+ +
+

About IPv4 deprecation

+ +
+
- +
-
-
- - -
-
-
- IPv4 + + +
+
+
+ IPv4 +
+
+
+

Current option:

+

+ {ipv4 !== undefined + ? 'Dedicated IPv4 address is enabled' + : 'Dedicated IPv4 address is not enabled'} +

+ setPanel('ipv4')} + disabled={ + !isProjectActive || projectUpdateDisabled || !(canUpdateIPv4 || ipv4) + } + tooltip={{ + content: { + side: 'bottom', + text: !(canUpdateIPv4 || ipv4) + ? 'Temporarily disabled while we are migrating to IPv6, please check back later.' + : undefined, + }, + }} + > + Change dedicated IPv4 address + +
-
-
-

Current option:

-

- {ipv4 !== undefined - ? 'Dedicated IPv4 address is enabled' - : 'Dedicated IPv4 address is not enabled'} -

- setPanel('ipv4')} - disabled={ - !isProjectActive || projectUpdateDisabled || !(canUpdateIPv4 || ipv4) - } - tooltip={{ - content: { - side: 'bottom', - text: !(canUpdateIPv4 || ipv4) - ? 'Temporarily disabled while we are migrating to IPv6, please check back later.' - : undefined, - }, - }} - > - Change dedicated IPv4 address - -
-
- - - + + + + + )} @@ -528,75 +537,78 @@ const Addons = () => { - - - - - -
-

Custom domain

-
-

More information

-
- -
-

About custom domains

- + {projectSettingsCustomDomains && ( + <> + + + + +
+

Custom domain

+
+

More information

+
+ +
+

About custom domains

+ +
+
- +
-
-
- - -
-
-
- Custom Domain + + +
+
+
+ Custom Domain +
+
+
+

Current option:

+

+ {customDomain !== undefined + ? 'Custom domain is enabled' + : 'Custom domain is not enabled'} +

+ + + +
-
-
-

Current option:

-

- {customDomain !== undefined - ? 'Custom domain is enabled' - : 'Custom domain is not enabled'} -

- - - -
-
- - - + + + + + )} )} @@ -606,5 +618,3 @@ const Addons = () => { ) } - -export default Addons diff --git a/apps/studio/components/interfaces/Settings/Database/ConnectionStringMoved.tsx b/apps/studio/components/interfaces/Settings/Database/ConnectionStringMoved.tsx deleted file mode 100644 index 3852592b862..00000000000 --- a/apps/studio/components/interfaces/Settings/Database/ConnectionStringMoved.tsx +++ /dev/null @@ -1,53 +0,0 @@ -import { Button } from 'ui' -import { Plug, GitBranch, ChevronsUpDown, Pointer } from 'lucide-react' - -export const ConnectionStringMoved = () => { - return ( -
-
-

Connection string has moved

-

- You can find Project connect details by clicking 'Connect' in the top bar -

-
-
-
-
-
-
-
- - - -
- -
-
-
-
- ) -} diff --git a/apps/studio/components/layouts/JWTKeys/JWTKeysLayout.tsx b/apps/studio/components/layouts/JWTKeys/JWTKeysLayout.tsx index acebf3386e5..03ea980a382 100644 --- a/apps/studio/components/layouts/JWTKeys/JWTKeysLayout.tsx +++ b/apps/studio/components/layouts/JWTKeys/JWTKeysLayout.tsx @@ -3,16 +3,22 @@ import { ScaffoldContainer } from 'components/layouts/Scaffold' import { PropsWithChildren } from 'react' import { useParams } from 'common' +import { useIsFeatureEnabled } from 'hooks/misc/useIsFeatureEnabled' const JWTKeysLayout = ({ children }: PropsWithChildren) => { const { ref: projectRef } = useParams() + const { projectSettingsLegacyJwtKeys } = useIsFeatureEnabled(['project_settings:legacy_jwt_keys']) const navigationItems = [ - { - label: 'Legacy JWT Secret', - href: `/project/${projectRef}/settings/jwt`, - id: 'legacy-jwt-keys', - }, + ...(projectSettingsLegacyJwtKeys + ? [ + { + label: 'Legacy JWT Secret', + href: `/project/${projectRef}/settings/jwt`, + id: 'legacy-jwt-keys', + }, + ] + : []), { label: 'JWT Signing Keys', href: `/project/${projectRef}/settings/jwt/signing-keys`, diff --git a/apps/studio/components/layouts/ProjectSettingsLayout/SettingsLayout.tsx b/apps/studio/components/layouts/ProjectSettingsLayout/SettingsLayout.tsx index b3a56eb2f7b..af234cf85cd 100644 --- a/apps/studio/components/layouts/ProjectSettingsLayout/SettingsLayout.tsx +++ b/apps/studio/components/layouts/ProjectSettingsLayout/SettingsLayout.tsx @@ -38,11 +38,21 @@ const SettingsLayout = ({ title, children }: PropsWithChildren { const isProjectBuilding = project?.status === PROJECT_STATUS.COMING_UP @@ -22,6 +27,15 @@ export const generateSettingsMenu = ( const authEnabled = features?.auth ?? true const edgeFunctionsEnabled = features?.edgeFunctions ?? true const storageEnabled = features?.storage ?? true + const legacyJwtKeysEnabled = features?.legacyJwtKeys ?? true + const logDrainsEnabled = features?.logDrains ?? true + const billingEnabled = features?.billing ?? true + + const authSettingsURL = features?.authPolicies + ? `/project/${ref}/auth/policies` + : features?.authSignInProviders + ? `/project/${ref}/auth/providers` + : `/project/${ref}/auth/sessions` return [ { @@ -57,12 +71,16 @@ export const generateSettingsMenu = ( url: `/project/${ref}/settings/integrations`, items: [], }, - { - name: `Log Drains`, - key: `log-drains`, - url: `/project/${ref}/settings/log-drains`, - items: [], - }, + ...(logDrainsEnabled + ? [ + { + name: `Log Drains`, + key: `log-drains`, + url: `/project/${ref}/settings/log-drains`, + items: [], + }, + ] + : []), { name: 'Data API', key: 'api', @@ -79,7 +97,9 @@ export const generateSettingsMenu = ( { name: 'JWT Keys', key: 'jwt', - url: `/project/${ref}/settings/jwt`, + url: legacyJwtKeysEnabled + ? `/project/${ref}/settings/jwt` + : `/project/${ref}/settings/jwt/signing-keys`, items: [], label: 'NEW', }, @@ -116,8 +136,9 @@ export const generateSettingsMenu = ( { name: 'Authentication', key: 'auth', - url: isProjectBuilding ? buildingUrl : `/project/${ref}/settings/auth`, + url: authSettingsURL, items: [], + rightIcon: , }, ] : []), @@ -149,14 +170,17 @@ export const generateSettingsMenu = ( { title: 'Billing', items: [ - { - name: 'Subscription', - key: 'subscription', - url: `/org/${organization?.slug}/billing`, - items: [], - rightIcon: , - }, - + ...(billingEnabled + ? [ + { + name: 'Subscription', + key: 'subscription', + url: `/org/${organization?.slug}/billing`, + items: [], + rightIcon: , + }, + ] + : []), { name: 'Usage', key: 'usage', diff --git a/apps/studio/components/ui/ProjectSettings/DisplayApiSettings.tsx b/apps/studio/components/ui/ProjectSettings/DisplayApiSettings.tsx index 81cefd8d75a..b9f456d02b1 100644 --- a/apps/studio/components/ui/ProjectSettings/DisplayApiSettings.tsx +++ b/apps/studio/components/ui/ProjectSettings/DisplayApiSettings.tsx @@ -10,6 +10,7 @@ import Panel from 'components/ui/Panel' import { useJwtSecretUpdatingStatusQuery } from 'data/config/jwt-secret-updating-status-query' import { useProjectSettingsV2Query } from 'data/config/project-settings-v2-query' import { useAsyncCheckProjectPermissions } from 'hooks/misc/useCheckPermissions' +import { useIsFeatureEnabled } from 'hooks/misc/useIsFeatureEnabled' import { Input } from 'ui' import { getLastUsedAPIKeys, useLastUsedAPIKeysLogQuery } from './DisplayApiSettings.utils' import { ToggleLegacyApiKeysPanel } from './ToggleLegacyApiKeys' @@ -24,6 +25,9 @@ export const DisplayApiSettings = ({ showLegacyText?: boolean }) => { const { ref: projectRef } = useParams() + const { projectSettingsShowDisableLegacyApiKeys } = useIsFeatureEnabled([ + 'project_settings:show_disable_legacy_api_keys', + ]) const { data: settings, @@ -213,21 +217,22 @@ export const DisplayApiSettings = ({ )) )} - {showNotice ? ( - + + {showNotice ? ( + - ) : ( - - )} - + href="https://github.com/orgs/supabase/discussions/29260" + buttonText="Read the announcement" + /> + ) : projectSettingsShowDisableLegacyApiKeys ? ( + + ) : null} ) } diff --git a/apps/studio/pages/project/[ref]/database/settings.tsx b/apps/studio/pages/project/[ref]/database/settings.tsx index a44f04db2d4..920d10470bd 100644 --- a/apps/studio/pages/project/[ref]/database/settings.tsx +++ b/apps/studio/pages/project/[ref]/database/settings.tsx @@ -1,14 +1,13 @@ import { DiskManagementPanelForm } from 'components/interfaces/DiskManagement/DiskManagementPanelForm' import { ConnectionPooling, NetworkRestrictions } from 'components/interfaces/Settings/Database' import BannedIPs from 'components/interfaces/Settings/Database/BannedIPs' -import { ConnectionStringMoved } from 'components/interfaces/Settings/Database/ConnectionStringMoved' import { DatabaseReadOnlyAlert } from 'components/interfaces/Settings/Database/DatabaseReadOnlyAlert' import ResetDbPassword from 'components/interfaces/Settings/Database/DatabaseSettings/ResetDbPassword' import DiskSizeConfiguration from 'components/interfaces/Settings/Database/DiskSizeConfiguration' import { PoolingModesModal } from 'components/interfaces/Settings/Database/PoolingModesModal' import SSLConfiguration from 'components/interfaces/Settings/Database/SSLConfiguration' -import DefaultLayout from 'components/layouts/DefaultLayout' import DatabaseLayout from 'components/layouts/DatabaseLayout/DatabaseLayout' +import DefaultLayout from 'components/layouts/DefaultLayout' import { ScaffoldContainer, ScaffoldHeader, ScaffoldTitle } from 'components/layouts/Scaffold' import { useIsAwsCloudProvider, useIsAwsK8sCloudProvider } from 'hooks/misc/useSelectedProject' import type { NextPageWithLayout } from 'types' @@ -30,7 +29,6 @@ const ProjectSettings: NextPageWithLayout = () => {
-
diff --git a/apps/studio/pages/project/[ref]/settings/addons.tsx b/apps/studio/pages/project/[ref]/settings/addons.tsx index d9bf4b63684..c24befee049 100644 --- a/apps/studio/pages/project/[ref]/settings/addons.tsx +++ b/apps/studio/pages/project/[ref]/settings/addons.tsx @@ -1,4 +1,4 @@ -import Addons from 'components/interfaces/Settings/Addons/Addons' +import { Addons } from 'components/interfaces/Settings/Addons/Addons' import DefaultLayout from 'components/layouts/DefaultLayout' import SettingsLayout from 'components/layouts/ProjectSettingsLayout/SettingsLayout' import { diff --git a/apps/studio/pages/project/[ref]/settings/auth.tsx b/apps/studio/pages/project/[ref]/settings/auth.tsx deleted file mode 100644 index ce87957dfd9..00000000000 --- a/apps/studio/pages/project/[ref]/settings/auth.tsx +++ /dev/null @@ -1,106 +0,0 @@ -import { useParams } from 'common' -import DefaultLayout from 'components/layouts/DefaultLayout' -import SettingsLayout from 'components/layouts/ProjectSettingsLayout/SettingsLayout' -import ProductEmptyState from 'components/to-be-cleaned/ProductEmptyState' -import { ChevronRight } from 'lucide-react' -import Link from 'next/link' -import type { NextPageWithLayout } from 'types' - -const ProjectSettings: NextPageWithLayout = () => { - const { ref } = useParams() as { ref: string } - - return ( - -
-

- All settings are now under configuration within the Authentication page. -

- - General user signup - - - - Password settings in email provider - - - - User sessions - - - - Refresh tokens - - - - Bot and abuse protection - - - - SMTP settings - - - - Access token expiry - - - - Multifactor authentication - - - - Third party authentication - - - - Max request duration - - - - Max direct database connections - - -
-
- ) -} - -ProjectSettings.getLayout = (page) => ( - - {page} - -) - -export default ProjectSettings diff --git a/apps/studio/pages/project/[ref]/settings/general.tsx b/apps/studio/pages/project/[ref]/settings/general.tsx index 894cf9b36eb..11943bbd52f 100644 --- a/apps/studio/pages/project/[ref]/settings/general.tsx +++ b/apps/studio/pages/project/[ref]/settings/general.tsx @@ -20,7 +20,8 @@ const ProjectSettings: NextPageWithLayout = () => { const { data: selectedOrganization } = useSelectedOrganizationQuery() const isBranch = !!project?.parent_project_ref - const { projectsTransfer: projectTransferEnabled } = useIsFeatureEnabled(['projects:transfer']) + const { projectsTransfer: projectTransferEnabled, projectSettingsCustomDomains } = + useIsFeatureEnabled(['projects:transfer', 'project_settings:custom_domains']) const { data: subscription } = useOrgSubscriptionQuery({ orgSlug: selectedOrganization?.slug }) const hasHipaaAddon = subscriptionHasHipaaAddon(subscription) @@ -37,7 +38,7 @@ const ProjectSettings: NextPageWithLayout = () => { {/* this is only settable on compliance orgs, currently that means HIPAA orgs */} {!isBranch && hasHipaaAddon && } - + {projectSettingsCustomDomains && } {!isBranch && projectTransferEnabled && } {!isBranch && } diff --git a/apps/studio/pages/project/[ref]/settings/jwt/index.tsx b/apps/studio/pages/project/[ref]/settings/jwt/index.tsx index 07f3565d857..02364d45227 100644 --- a/apps/studio/pages/project/[ref]/settings/jwt/index.tsx +++ b/apps/studio/pages/project/[ref]/settings/jwt/index.tsx @@ -8,16 +8,22 @@ import { JwtSecretUpdateError, JwtSecretUpdateStatus } from '@supabase/shared-ty import { useQueryClient } from '@tanstack/react-query' import { useParams } from 'common' import { JWT_SECRET_UPDATE_ERROR_MESSAGES } from 'components/interfaces/JwtSecrets/jwt.constants' +import { UnknownInterface } from 'components/ui/UnknownInterface' import { useJwtSecretUpdatingStatusQuery } from 'data/config/jwt-secret-updating-status-query' import { configKeys } from 'data/config/keys' +import { useIsFeatureEnabled } from 'hooks/misc/useIsFeatureEnabled' import { useEffect, useRef } from 'react' import { toast } from 'sonner' const JWTKeysLegacyPage: NextPageWithLayout = () => { - const { ref: projectRef, source } = useParams() const client = useQueryClient() + const { ref: projectRef } = useParams() + const { projectSettingsLegacyJwtKeys } = useIsFeatureEnabled(['project_settings:legacy_jwt_keys']) - const { data } = useJwtSecretUpdatingStatusQuery({ projectRef }) + const { data } = useJwtSecretUpdatingStatusQuery( + { projectRef }, + { enabled: projectSettingsLegacyJwtKeys } + ) const jwtSecretUpdateStatus = data?.jwtSecretUpdateStatus const jwtSecretUpdateError = data?.jwtSecretUpdateError @@ -44,14 +50,20 @@ const JWTKeysLegacyPage: NextPageWithLayout = () => { previousJwtSecretUpdateStatus.current = jwtSecretUpdateStatus }, [jwtSecretUpdateStatus]) - return + if (!projectSettingsLegacyJwtKeys) { + return + } + + return ( + + + + ) } JWTKeysLegacyPage.getLayout = (page) => ( - - {page} - + {page} ) diff --git a/packages/common/enabled-features/enabled-features.json b/packages/common/enabled-features/enabled-features.json index 4c0f50f6cc2..726353ef525 100644 --- a/packages/common/enabled-features/enabled-features.json +++ b/packages/common/enabled-features/enabled-features.json @@ -46,6 +46,12 @@ "project_homepage:show_instance_size": true, "project_homepage:show_examples": true, + "project_addons:dedicated_ipv4_address": true, + "project_settings:custom_domains": true, + "project_settings:show_disable_legacy_api_keys": true, + "project_settings:legacy_jwt_keys": true, + "project_settings:log_drains": true, + "reports:all": true, "table_editor:enable_rls_toggle": true diff --git a/packages/common/enabled-features/enabled-features.schema.json b/packages/common/enabled-features/enabled-features.schema.json index 07a42fa4d0d..e6cd53fb668 100644 --- a/packages/common/enabled-features/enabled-features.schema.json +++ b/packages/common/enabled-features/enabled-features.schema.json @@ -153,6 +153,28 @@ "description": "Show all client libraries examples in the project homepage. When false, all client library examples will be hidden except the JavaScript client library." }, + "project_addons:dedicated_ipv4_address": { + "type": "boolean", + "description": "Show the dedicated IPv4 address addon" + }, + + "project_settings:custom_domains": { + "type": "boolean", + "description": "Show the custom domain configuration section + custom domain addon" + }, + "project_settings:show_disable_legacy_api_keys": { + "type": "boolean", + "description": "Show the disable legacy API keys section in project settings API Keys page" + }, + "project_settings:legacy_jwt_keys": { + "type": "boolean", + "description": "Enable the legacy JWT secret page in project settings" + }, + "project_settings:log_drains": { + "type": "boolean", + "description": "Enable the log drains page in project settings" + }, + "reports:all": { "type": "boolean", "description": "Enable the project reports page" @@ -196,6 +218,11 @@ "project_homepage:show_instance_size", "project_homepage:show_examples", "project_homepage:show_all_client_libraries", + "project_addons:dedicated_ipv4_address", + "project_settings:custom_domains", + "project_settings:show_disable_legacy_api_keys", + "project_settings:legacy_jwt_keys", + "project_settings:log_drains", "project_connection:javascript_example", "project_connection:dart_example", "reports:all",