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

258 lines
7.6 KiB
Markdown

# 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
### 2. Magic Link (Passwordless)
- 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:
```typescript
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:
```typescript
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:
```tsx
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:
```typescript
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:**
```html
<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:**
```html
<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