diff --git a/apps/studio/components/interfaces/SignIn/SignInMfaForm.tsx b/apps/studio/components/interfaces/SignIn/SignInMfaForm.tsx index 92bc0850ef8..2b437c0f802 100644 --- a/apps/studio/components/interfaces/SignIn/SignInMfaForm.tsx +++ b/apps/studio/components/interfaces/SignIn/SignInMfaForm.tsx @@ -1,5 +1,4 @@ import { zodResolver } from '@hookform/resolvers/zod' -import { SupportCategories } from '@supabase/shared-types/out/constants' import type { Factor } from '@supabase/supabase-js' import { useQueryClient } from '@tanstack/react-query' import { useAuthError } from 'common' @@ -13,7 +12,6 @@ import { FormItemLayout } from 'ui-patterns/form/FormItemLayout/FormItemLayout' import { GenericSkeletonLoader } from 'ui-patterns/ShimmeringLoader' import z from 'zod' -import { SupportLink } from '../Support/SupportLink' import { AlertError } from '@/components/ui/AlertError' import { useMfaChallengeAndVerifyMutation } from '@/data/profile/mfa-challenge-and-verify-mutation' import { useMfaListFactorsQuery } from '@/data/profile/mfa-list-factors-query' @@ -26,6 +24,8 @@ const schema = z.object({ const formId = 'sign-in-mfa-form' +const SUPPORT_EMAIL_HREF = `mailto:support@supabase.com?subject=${encodeURIComponent('Unable to sign in via MFA')}` + function getFactorDisplayName(factor: Pick | null | undefined): string { const name = factor?.friendly_name?.trim() return name && name.length > 0 ? name : 'your authenticator app' @@ -115,9 +115,7 @@ export const SignInMfaForm = ({ context = 'sign-in' }: SignInMfaFormProps) => { Back to sign in } @@ -129,7 +127,14 @@ export const SignInMfaForm = ({ context = 'sign-in' }: SignInMfaFormProps) => { <> {isLoadingFactors && } - {isErrorFactors && } + {isErrorFactors && ( + + )} {isSuccessFactors && (
@@ -235,17 +240,6 @@ export const SignInMfaForm = ({ context = 'sign-in' }: SignInMfaFormProps) => { Force sign out and clear cookies -
  • - - Reach out to us via support - -
  • diff --git a/apps/studio/hooks/misc/withAuth.tsx b/apps/studio/hooks/misc/withAuth.tsx index b480149fbf9..67d4288e971 100644 --- a/apps/studio/hooks/misc/withAuth.tsx +++ b/apps/studio/hooks/misc/withAuth.tsx @@ -17,10 +17,9 @@ export function withAuth( options: { /** * The auth level used to check the user credentials. In most cases, if the user has MFA enabled - * we want the highest level (which is 2) for all pages. For certain pages, the user should be - * able to access them even if he didn't finished his login (typed in his MFA code), for example - * the support page: We want the user to be able to submit a ticket even if he's not fully - * signed in. + * we want the highest level (which is 2) for all pages, as the platform API rejects sessions + * that haven't completed the MFA challenge. Only opt out for pages that don't read from the + * platform API and are meant to be reachable before the user has finished signing in. * @default true */ useHighestAAL: boolean @@ -43,9 +42,12 @@ export function withAuth( isPending: isAALLoading, data: aalData, isError: isErrorAAL, + isSuccess: isSuccessAAL, error: errorAAL, } = useAuthenticatorAssuranceLevelQuery() + const isAtHighestAAL = isSuccessAAL && aalData.currentLevel === aalData.nextLevel + useEffect(() => { if (isErrorAAL) { toast.error( @@ -57,19 +59,17 @@ export function withAuth( const { isError: isErrorPermissions, error: errorPermissions } = usePermissionsQuery() useEffect(() => { - if (isErrorPermissions) { + if (isErrorPermissions && isAtHighestAAL) { toast.error( `Failed to fetch permissions: ${errorPermissions?.message}. Try refreshing your browser, or reach out to us via a support ticket if the issue persists` ) } - }, [isErrorPermissions, errorPermissions]) + }, [isErrorPermissions, errorPermissions, isAtHighestAAL]) const isLoggedIn = Boolean(session) const isFinishedLoading = !isLoading && !isAALLoading - const isCorrectLevel = options.useHighestAAL - ? aalData?.currentLevel === aalData?.nextLevel - : true + const isCorrectLevel = options.useHighestAAL ? isAtHighestAAL : true const needsMfaElevation = isLoggedIn && !isCorrectLevel const redirectToSignIn = useCallback(() => { diff --git a/apps/studio/pages/support/new.tsx b/apps/studio/pages/support/new.tsx index 6dadb2a5061..9a30b6f00f1 100644 --- a/apps/studio/pages/support/new.tsx +++ b/apps/studio/pages/support/new.tsx @@ -14,4 +14,4 @@ SupportPage.getLayout = (page) => ( ) -export default withAuth(SupportPage, { useHighestAAL: false }) +export default withAuth(SupportPage)