mirror of
https://github.com/supabase/supabase.git
synced 2026-10-17 07:09:07 +03:00
The dashboard's `sign_in` event never fires when a user completes a TOTP challenge: `SignInForm` only tracks when no MFA challenge is needed, and the /sign-in-mfa page only tracks on mount when the assurance level is already satisfied (OAuth/SSO returns). Sign-ins that go through the actual MFA form were invisible to analytics, and the login audit event was missing on the same path. **Changed:** - **MFA-challenged sign-ins now tracked**: `SignInMfaForm` fires `sign_in` (reading the same `method` query param the page mount site reads) plus the login audit event on successful TOTP verification, in the sign-in context only. The forgot-password flow stays untracked: it is a reset, not a sign-in. - **Password+MFA sign-ins report `method: email`**: `SignInForm` now passes `?method=email` when routing to /sign-in-mfa instead of falling through to `unknown`. - **Partner TOTP sign-ins carry their provider**: `SignInPartner` now passes `?method=<partner>` when routing to /sign-in-mfa, matching the raw-provider-name convention the other entry points use. - **Join caveat documented**: the `SignInEvent` doc comment now notes the event is captured server-side and races the identify call, so it is not a valid funnel join key across the auth boundary. ## Linear - fixes GROWTH-1156 <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Added sign-in method details to MFA redirects for email and partner authentication, improving sign-in flow tracking. * Added telemetry and login auditing for successful MFA sign-ins while keeping forgot-password flows untracked. * **Documentation** * Clarified sign-in event tracking coverage, including OAuth providers, server-side capture, anonymous identifiers, and the sign-in page. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
56 lines
1.6 KiB
TypeScript
56 lines
1.6 KiB
TypeScript
import { Loader2 } from 'lucide-react'
|
||
import { useRouter } from 'next/router'
|
||
import { useEffect } from 'react'
|
||
|
||
import { InlineLink } from '@/components/ui/InlineLink'
|
||
import { auth } from '@/lib/gotrue'
|
||
|
||
export const SignInPartner = () => {
|
||
const router = useRouter()
|
||
|
||
useEffect(() => {
|
||
;(async () => {
|
||
const params = new URLSearchParams(window.location.hash.substring(1))
|
||
|
||
const partner = params.get('partner')
|
||
const token = params.get('id_token')
|
||
|
||
const { data } = await auth.getSession()
|
||
|
||
if (!data.session && partner && token) {
|
||
try {
|
||
await auth.signInWithIdToken({ provider: partner, token })
|
||
} finally {
|
||
router.replace({ pathname: '/sign-in-mfa', query: { method: partner } })
|
||
}
|
||
} else {
|
||
router.replace({ pathname: '/sign-in' })
|
||
}
|
||
})()
|
||
}, [])
|
||
|
||
return (
|
||
<div className="relative mx-auto w-full flex flex-col items-center justify-center gap-y-6">
|
||
<Loader2 className="animate-spin" />
|
||
<h2 className="text-lg text-center">Signing in to Supabase Dashboard</h2>
|
||
<p className="text-xs text-foreground-lighter text-center max-w-[220px] sm:max-w-full">
|
||
By continuing, you agree to Supabase’s{' '}
|
||
<InlineLink
|
||
href="https://supabase.com/terms"
|
||
className="text-foreground-lighter hover:text-foreground"
|
||
>
|
||
Terms of Service
|
||
</InlineLink>{' '}
|
||
and{' '}
|
||
<InlineLink
|
||
href="https://supabase.com/privacy"
|
||
className="text-foreground-lighter hover:text-foreground"
|
||
>
|
||
Privacy Policy
|
||
</InlineLink>
|
||
.
|
||
</p>
|
||
</div>
|
||
)
|
||
}
|