mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-20 06:51:12 -05:00
feat: Implement all authentication compliance phases
This commit is contained in:
257
docs/AUTHENTICATION.md
Normal file
257
docs/AUTHENTICATION.md
Normal file
@@ -0,0 +1,257 @@
|
||||
# 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
|
||||
Reference in New Issue
Block a user