Files
thrilltrack-explorer/docs/AUTHENTICATION.md
2025-10-31 14:01:45 +00:00

7.6 KiB

ThrillWiki Authentication System

Overview

ThrillWiki implements a comprehensive authentication system following Supabase best practices with multiple sign-in methods, MFA support, and advanced security features.

Supported Authentication Methods

1. Email & Password

  • Standard email/password authentication
  • Password strength validation (minimum 6 characters)
  • Email confirmation required by default
  • Password reset flow with secure email links
  • One-click email authentication
  • No password required
  • Expires after 1 hour
  • Rate limited to prevent abuse (1 request per 60 seconds)

3. Email OTP (One-Time Password)

  • 6-digit verification code sent via email
  • Alternative to Magic Links
  • Expires after 1 hour
  • Ideal for mobile apps

4. OAuth Social Login

  • Google: Full profile and email access
  • Discord: Identity and email access
  • Automatic identity linking with matching emails
  • Manual identity linking for logged-in users

Security Features

Multi-Factor Authentication (MFA/TOTP)

  • App-based authenticator (Google Authenticator, Authy, etc.)
  • Required for moderators and administrators
  • QR code enrollment with manual secret fallback
  • AAL2 (Authenticator Assurance Level 2) enforcement
  • Automatic session step-up challenges

Session Management

  • Multiple active sessions across devices
  • Session expiry monitoring with proactive refresh
  • Device and browser detection
  • IP address tracking (last 8 chars of hash for privacy)
  • Revoke individual sessions or all others

Sign Out Options

  • Global: Sign out from all devices (default)
  • Local: Sign out from current device only
  • Others: Sign out from all other devices

Identity Management

  • Link multiple OAuth providers to one account
  • Disconnect OAuth identities (with safety checks)
  • Add password backup to OAuth-only accounts
  • Prevents account orphaning (requires at least 1 auth method)
  • AAL2 required for disconnecting identities

Implementation Details

Critical Security Fixes

  1. Email Redirect URLs: All signup flows include emailRedirectTo parameter
  2. MFA Bypass Prevention: Canceling MFA prompt triggers forced sign-out
  3. Non-Dismissable MFA Modal: Cannot close MFA challenge without completing
  4. Session Monitoring: Tokens refreshed 5 minutes before expiry

Automatic Identity Linking

When a user signs in with OAuth using an email that already exists:

  • Supabase automatically links the new identity
  • Removes unconfirmed identities to prevent takeover attacks
  • Logs linking event to audit trail
  • Only works with confirmed email addresses

Manual Identity Linking

Users can manually link additional OAuth providers:

import { linkOAuthIdentity } from '@/lib/identityService';

// Link a new provider
const result = await linkOAuthIdentity('google');

Password Reset Flow

For OAuth-only accounts that want to add password:

import { addPasswordToAccount } from '@/lib/identityService';

// Triggers password setup email
const result = await addPasswordToAccount();
// User receives email with link to set password

Email OTP Implementation

For Developers

  1. Modify Supabase email template to include {{ .Token }}
  2. Use the EmailOTPInput component:
import { EmailOTPInput } from '@/components/auth/EmailOTPInput';

<EmailOTPInput
  email={userEmail}
  onVerify={async (code) => {
    const { error } = await supabase.auth.verifyOtp({
      email: userEmail,
      token: code,
      type: 'email',
    });
  }}
  onCancel={() => setShowOTP(false)}
  onResend={async () => {
    await supabase.auth.signInWithOtp({ email: userEmail });
  }}
/>

User Flows

Sign Up with Email

  1. User enters email, password, username, display name
  2. System validates email (no disposable addresses)
  3. CAPTCHA verification (if enabled)
  4. Confirmation email sent to user
  5. User clicks link → Redirected to /auth/callback
  6. Account confirmed and logged in

Sign In with MFA Enrolled

  1. User enters email and password
  2. System authenticates credentials
  3. If MFA enrolled → Shows MFA challenge
  4. User enters 6-digit TOTP code
  5. Session upgraded to AAL2
  6. User granted full access

Linking Additional Provider

  1. User navigates to Settings → Security
  2. Clicks "Connect" on desired OAuth provider
  3. Completes OAuth flow with provider
  4. Returns to ThrillWiki with linked identity
  5. Can now sign in with either method

Disconnecting Provider

  1. User navigates to Settings → Security
  2. Clicks "Disconnect" on OAuth provider
  3. System verifies:
    • Not the last identity
    • Has password backup OR another OAuth provider
    • User has AAL2 session (MFA verified if enrolled)
  4. Identity disconnected and logged to audit

Error Handling

Common Error Codes

  • email_exists: Email already registered
  • invalid_credentials: Wrong email/password
  • email_not_confirmed: Email not verified yet
  • mfa_verification_failed: Wrong TOTP code
  • identity_already_exists: Provider already linked
  • single_identity_not_deletable: Cannot remove last auth method
  • insufficient_aal: MFA verification required

User-Friendly Messages

All errors are converted to user-friendly messages:

import { handleError } from '@/lib/errorHandler';

try {
  // Auth operation
} catch (error) {
  handleError(error, { action: 'Sign In' });
  // Shows toast with friendly message
}

Configuration

Email Templates

Configure in Supabase Dashboard → Authentication → Email Templates

Magic Link Template:

<h2>Magic Link</h2>
<p>Follow this link to login:</p>
<p><a href="{{ .SiteURL }}/auth/confirm?token_hash={{ .TokenHash }}&type=email">Log In</a></p>

OTP Template:

<h2>Verification Code</h2>
<p>Your verification code is:</p>
<h1 style="font-size: 32px; letter-spacing: 8px;">{{ .Token }}</h1>
<p>This code expires in 1 hour.</p>

Redirect URLs

Configure in Supabase Dashboard → Authentication → URL Configuration:

  • Site URL: https://www.thrillwiki.com
  • Redirect URLs:
    • https://www.thrillwiki.com/auth/callback
    • http://localhost:8080/auth/callback (development)

Best Practices

For Users

  • Enable MFA for additional security
  • Link multiple providers for backup access
  • Use strong, unique passwords (if using email/password)
  • Review active sessions regularly
  • Sign out from unfamiliar devices

For Developers

  • Always include emailRedirectTo in signup calls
  • Validate emails to prevent disposable addresses
  • Never log sensitive data (passwords, tokens)
  • Use AAL2 checks for critical operations
  • Implement proper error handling with user-friendly messages
  • Test all authentication flows thoroughly

Audit Logging

All authentication events are logged:

  • Sign in/sign out
  • MFA enrollment/verification
  • Identity linking/unlinking
  • Password changes
  • Session revocations

Access logs via admin_audit_log table or Settings → Security → Sessions.

Testing Checklist

  • Sign up with email/password
  • Confirm email and log in
  • Reset password
  • Magic link sign in
  • OAuth sign in (Google)
  • OAuth sign in (Discord)
  • Enroll MFA
  • Sign in with MFA
  • Cancel MFA (should sign out)
  • Link additional OAuth provider
  • Disconnect OAuth provider
  • Add password to OAuth-only account
  • Revoke session
  • Sign out (all scopes)

Support

For issues or questions about authentication:

  • Check Supabase auth logs in dashboard
  • Review browser console for client errors
  • Check network requests in DevTools
  • Verify email template configuration
  • Confirm redirect URLs are correct