mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-20 04:51:11 -05:00
258 lines
7.6 KiB
Markdown
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
|