From 685505a568ca7aa2e54fe5e47329796b710ec29f Mon Sep 17 00:00:00 2001 From: "kemal.earth" <606977+kemaldotearth@users.noreply.github.com> Date: Thu, 2 Oct 2025 13:43:57 +0100 Subject: [PATCH 1/3] feat(studio): add auth overview feature flag (#39113) * feat: basic auth overview page setup Adds the route and layout for the Authentication Overview page. * feat: add feature flag for auth overview * chore: small clean up * feat: add overview page header * feat: create sections for auth overview page Adds three high level components for the sections of the Auth overview page. Can break down further later * feat: add conditional redirect for top level sidebar item This adds a redirect based on whether overview page is enabled or not. For users who dont have it enabled they go to users as default when tapping authentication. * feat: add redirect if overview is set to false * fix: add loaded context for feature flag * chore: clean up scaffolding mark up * chore: remove unused important * chore: placeholders for sections --- .../Auth/Overview/OverviewLearnMore.tsx | 15 +++++ .../Auth/Overview/OverviewMonitoring.tsx | 16 ++++++ .../Auth/Overview/OverviewUsage.tsx | 14 +++++ apps/studio/components/interfaces/Sidebar.tsx | 4 ++ .../layouts/AuthLayout/AuthLayout.tsx | 4 ++ .../layouts/AuthLayout/AuthLayout.utils.ts | 9 ++- .../NavigationBar/NavigationBar.utils.tsx | 10 +++- .../pages/project/[ref]/auth/overview.tsx | 57 +++++++++++++++++++ 8 files changed, 127 insertions(+), 2 deletions(-) create mode 100644 apps/studio/components/interfaces/Auth/Overview/OverviewLearnMore.tsx create mode 100644 apps/studio/components/interfaces/Auth/Overview/OverviewMonitoring.tsx create mode 100644 apps/studio/components/interfaces/Auth/Overview/OverviewUsage.tsx create mode 100644 apps/studio/pages/project/[ref]/auth/overview.tsx diff --git a/apps/studio/components/interfaces/Auth/Overview/OverviewLearnMore.tsx b/apps/studio/components/interfaces/Auth/Overview/OverviewLearnMore.tsx new file mode 100644 index 0000000000000..aefc6fad95ab0 --- /dev/null +++ b/apps/studio/components/interfaces/Auth/Overview/OverviewLearnMore.tsx @@ -0,0 +1,15 @@ +import { ScaffoldSection, ScaffoldSectionTitle } from 'components/layouts/Scaffold' +import { Card } from 'ui' + +export const OverviewLearnMore = () => { + return ( + + Learn more +
+ + + +
+
+ ) +} diff --git a/apps/studio/components/interfaces/Auth/Overview/OverviewMonitoring.tsx b/apps/studio/components/interfaces/Auth/Overview/OverviewMonitoring.tsx new file mode 100644 index 0000000000000..098ff90beeced --- /dev/null +++ b/apps/studio/components/interfaces/Auth/Overview/OverviewMonitoring.tsx @@ -0,0 +1,16 @@ +import { ScaffoldSectionTitle, ScaffoldSection } from 'components/layouts/Scaffold' +import { Card } from 'ui' + +export const OverviewMonitoring = () => { + return ( + + Monitoring +
+ + + + +
+
+ ) +} diff --git a/apps/studio/components/interfaces/Auth/Overview/OverviewUsage.tsx b/apps/studio/components/interfaces/Auth/Overview/OverviewUsage.tsx new file mode 100644 index 0000000000000..f0223bd5091a5 --- /dev/null +++ b/apps/studio/components/interfaces/Auth/Overview/OverviewUsage.tsx @@ -0,0 +1,14 @@ +import { ScaffoldSection, ScaffoldSectionTitle } from 'components/layouts/Scaffold' +import { Card } from 'ui' + +export const OverviewUsage = () => { + return ( + + Usage +
+ + +
+
+ ) +} diff --git a/apps/studio/components/interfaces/Sidebar.tsx b/apps/studio/components/interfaces/Sidebar.tsx index 63c0ee2600e15..72eea15c4c951 100644 --- a/apps/studio/components/interfaces/Sidebar.tsx +++ b/apps/studio/components/interfaces/Sidebar.tsx @@ -46,6 +46,7 @@ import { useIsNewStorageUIEnabled, useUnifiedLogsPreview, } from './App/FeaturePreview/FeaturePreviewContext' +import { useFlag } from 'common' export const ICON_SIZE = 32 export const ICON_STROKE_WIDTH = 1.5 @@ -244,12 +245,15 @@ const ProjectLinks = () => { 'realtime:all', ]) + const authOverviewPageEnabled = useFlag('authOverviewPage') + const toolRoutes = generateToolRoutes(ref, project) const productRoutes = generateProductRoutes(ref, project, { auth: authEnabled, edgeFunctions: edgeFunctionsEnabled, storage: storageEnabled, realtime: realtimeEnabled, + authOverviewPage: authOverviewPageEnabled, isStorageV2, }) const otherRoutes = generateOtherRoutes(ref, project, { diff --git a/apps/studio/components/layouts/AuthLayout/AuthLayout.tsx b/apps/studio/components/layouts/AuthLayout/AuthLayout.tsx index a57815f65d470..8fa1483de02ad 100644 --- a/apps/studio/components/layouts/AuthLayout/AuthLayout.tsx +++ b/apps/studio/components/layouts/AuthLayout/AuthLayout.tsx @@ -8,11 +8,14 @@ import { useIsFeatureEnabled } from 'hooks/misc/useIsFeatureEnabled' import { withAuth } from 'hooks/misc/withAuth' import ProjectLayout from '../ProjectLayout/ProjectLayout' import { generateAuthMenu } from './AuthLayout.utils' +import { useFlag } from 'common' const AuthProductMenu = () => { const router = useRouter() const { ref: projectRef = 'default' } = useParams() + const authenticationShowOverview = useFlag('authOverviewPage') + const { authenticationSignInProviders, authenticationRateLimits, @@ -42,6 +45,7 @@ const AuthProductMenu = () => { authenticationMultiFactor, authenticationAttackProtection, authenticationAdvanced, + authenticationShowOverview, })} /> ) diff --git a/apps/studio/components/layouts/AuthLayout/AuthLayout.utils.ts b/apps/studio/components/layouts/AuthLayout/AuthLayout.utils.ts index e40c51f9af4c5..67bad8717a388 100644 --- a/apps/studio/components/layouts/AuthLayout/AuthLayout.utils.ts +++ b/apps/studio/components/layouts/AuthLayout/AuthLayout.utils.ts @@ -10,6 +10,7 @@ export const generateAuthMenu = ( authenticationMultiFactor: boolean authenticationAttackProtection: boolean authenticationAdvanced: boolean + authenticationShowOverview: boolean } ): ProductMenuGroup[] => { const { @@ -19,12 +20,18 @@ export const generateAuthMenu = ( authenticationMultiFactor, authenticationAttackProtection, authenticationAdvanced, + authenticationShowOverview, } = flags ?? {} return [ { title: 'Manage', - items: [{ name: 'Users', key: 'users', url: `/project/${ref}/auth/users`, items: [] }], + items: [ + ...(authenticationShowOverview + ? [{ name: 'Overview', key: 'overview', url: `/project/${ref}/auth/overview`, items: [] }] + : []), + { name: 'Users', key: 'users', url: `/project/${ref}/auth/users`, items: [] }, + ], }, { title: 'Configuration', diff --git a/apps/studio/components/layouts/ProjectLayout/NavigationBar/NavigationBar.utils.tsx b/apps/studio/components/layouts/ProjectLayout/NavigationBar/NavigationBar.utils.tsx index 2f0b698771ca5..c3f6fc7885f99 100644 --- a/apps/studio/components/layouts/ProjectLayout/NavigationBar/NavigationBar.utils.tsx +++ b/apps/studio/components/layouts/ProjectLayout/NavigationBar/NavigationBar.utils.tsx @@ -50,6 +50,7 @@ export const generateProductRoutes = ( edgeFunctions?: boolean storage?: boolean realtime?: boolean + authOverviewPage?: boolean isStorageV2?: boolean } ): Route[] => { @@ -61,6 +62,7 @@ export const generateProductRoutes = ( const edgeFunctionsEnabled = features?.edgeFunctions ?? true const storageEnabled = features?.storage ?? true const realtimeEnabled = features?.realtime ?? true + const authOverviewPageEnabled = features?.authOverviewPage ?? false const isStorageV2 = features?.isStorageV2 ?? false const databaseMenu = generateDatabaseMenu(project) @@ -86,7 +88,13 @@ export const generateProductRoutes = ( key: 'auth', label: 'Authentication', icon: , - link: ref && (isProjectBuilding ? buildingUrl : `/project/${ref}/auth/users`), + link: + ref && + (isProjectBuilding + ? buildingUrl + : authOverviewPageEnabled + ? `/project/${ref}/auth/overview` + : `/project/${ref}/auth/users`), items: authMenu, }, ] diff --git a/apps/studio/pages/project/[ref]/auth/overview.tsx b/apps/studio/pages/project/[ref]/auth/overview.tsx new file mode 100644 index 0000000000000..6f55feeb6c7e1 --- /dev/null +++ b/apps/studio/pages/project/[ref]/auth/overview.tsx @@ -0,0 +1,57 @@ +import { NextPageWithLayout } from 'types' +import DefaultLayout from 'components/layouts/DefaultLayout' +import AuthLayout from 'components/layouts/AuthLayout/AuthLayout' +import { ScaffoldContainer, ScaffoldSection } from 'components/layouts/Scaffold' +import { PageLayout } from 'components/layouts/PageLayout/PageLayout' +import { DocsButton } from 'components/ui/DocsButton' +import { DOCS_URL } from 'lib/constants' +import { OverviewMonitoring } from 'components/interfaces/Auth/Overview/OverviewMonitoring' +import { OverviewUsage } from 'components/interfaces/Auth/Overview/OverviewUsage' +import { OverviewLearnMore } from 'components/interfaces/Auth/Overview/OverviewLearnMore' +import { useRouter } from 'next/router' +import { FeatureFlagContext, useFlag, useParams } from 'common' +import { useContext, useEffect } from 'react' + +const AuthOverview: NextPageWithLayout = () => { + const router = useRouter() + const { ref } = useParams() + const { hasLoaded } = useContext(FeatureFlagContext) + const authOverviewPageEnabled = useFlag('authOverviewPage') + + useEffect(() => { + if (hasLoaded && !authOverviewPageEnabled) { + router.replace(`/project/${ref}/auth/users`) + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [authOverviewPageEnabled, router, ref]) + + if (!authOverviewPageEnabled) { + return null + } + + return ( + +
+ + + +
+
+ ) +} + +AuthOverview.getLayout = (page) => ( + + + } + size="large" + > + {page} + + + +) + +export default AuthOverview From 7be825f373a63a2f7274d4b95597c38089c8345e Mon Sep 17 00:00:00 2001 From: Adam Mokan Date: Thu, 2 Oct 2025 06:09:32 -0700 Subject: [PATCH 2/3] Add Adam Mokan to humans.txt (#39126) adds Adam Mokan to `apps/docs/public/humans.txt` --- apps/docs/public/humans.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/docs/public/humans.txt b/apps/docs/public/humans.txt index dc97d192858f9..afe7e39f78960 100644 --- a/apps/docs/public/humans.txt +++ b/apps/docs/public/humans.txt @@ -3,6 +3,7 @@ TEAM Supabase is 100% remote. Aaron Byrne +Adam Mokan Alaister Young Alan De Los Santos Aleksi Immonen From 35cae7d4fee6c506d3687d354ab104af63ca802b Mon Sep 17 00:00:00 2001 From: Chris Chinchilla Date: Thu, 2 Oct 2025 17:52:43 +0300 Subject: [PATCH 3/3] docs: Improve explanation of how to enable physical backups (#39192) * Draft * Remove table --- apps/docs/content/guides/platform/backups.mdx | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/apps/docs/content/guides/platform/backups.mdx b/apps/docs/content/guides/platform/backups.mdx index 72ca5d5c52d72..b18781e0ec7e7 100644 --- a/apps/docs/content/guides/platform/backups.mdx +++ b/apps/docs/content/guides/platform/backups.mdx @@ -21,21 +21,19 @@ Once a project is deleted all associated data will be permanently removed, inclu Database backups can be categorized into two types: **logical** and **physical**. You can learn more about them [here](/blog/postgresql-physical-logical-backups). -As a general rule of thumb, projects will either have logical or physical backups based on plan, database size, and add-ons: + -| Plan | Database Size (0-15GB) | [Database Size (>15GB)](#backup-process-for-large-databases) | [PITR](#point-in-time-recovery) | [Read Replicas](./read-replicas#prerequisites) | -| ---------- | ---------------------- | ------------------------------------------------------------ | ------------------------------- | ---------------------------------------------- | -| Pro | logical | physical | physical | physical | -| Team | logical | physical | physical | physical | -| Enterprise | physical | physical | physical | physical | +To enable physical backups, you have three options: - +- Enable [Point-in-Time Recovery (PITR)](#point-in-time-recovery) +- [Increase your disk size](/docs/guides/platform/database-size) to greater than 15GB +- [Create a read replica](/docs/guides/platform/read-replicas) -Once a project satisfies at least one of the requirements for physical backups then logical backups will no longer be taken. However, your project may revert back to logical backups if add-ons are removed. +Once a project satisfies at least one of the requirements for physical backups then logical backups are no longer made. However, your project may revert back to logical backups if you remove add-ons. -You can confirm your project's backup type by navigating to [Database Backups > Scheduled backups](/dashboard/project/_/database/backups/scheduled) and if you can download a backup then it is logical, otherwise it is physical. +You can confirm your project's backup type by navigating to [**Database Backups > Scheduled backups**](/dashboard/project/_/database/backups/scheduled) and if you can download a backup then it is logical, otherwise it is physical. However, if your project has the Point-in-Time Recovery (PITR) add-on then the backups are physical and you can view them in [Database Backups > Point in time](/dashboard/project/_/database/backups/pitr).