Authentication Overview
The Ever Works provides a flexible, secure authentication system that supports multiple providers and authentication methods.
Authentication Architecture
The template uses a hybrid authentication approach, supporting both NextAuth.js and Supabase Auth simultaneously, allowing you to choose the best solution for your needs.
graph TB
User[User] --> Choice{Auth Method}
Choice -->|NextAuth.js| NextAuth[NextAuth.js]
Choice -->|Supabase| Supabase[Supabase Auth]
NextAuth --> OAuth1[OAuth Providers]
NextAuth --> Credentials[Email/Password]
NextAuth --> JWT1[JWT Tokens]
Supabase --> OAuth2[OAuth Providers]
Supabase --> Magic[Magic Links]
Supabase --> JWT2[JWT Tokens]
JWT1 --> Session[Session Management]
JWT2 --> Session
Session --> Protected[Protected Routes]
Supported Authentication Methods
1. OAuth Providers
NextAuth.js OAuth
- Google - Google OAuth 2.0
- GitHub - GitHub OAuth
- Facebook - Facebook Login
- Twitter/X - Twitter OAuth 2.0
- Microsoft - Microsoft OAuth 2.0
Supabase OAuth
- Google - Google OAuth 2.0
- GitHub - GitHub OAuth
- Facebook - Facebook Login
- Twitter/X - Twitter OAuth 2.0
- Discord - Discord OAuth
- Apple - Sign in with Apple
2. Email/Password Authentication
NextAuth.js Credentials
- Custom email/password authentication
- Password hashing with bcrypt
- Custom validation logic
- Database session storage
Supabase Auth
- Built-in email/password authentication
- Email verification
- Password reset functionality
- Secure password policies
3. Magic Link Authentication
Supabase Magic Links
- Passwordless authentication
- Email-based login
- Secure token generation
- Automatic account creation
Authentication Flow
OAuth Authentication Flow
sequenceDiagram
participant U as User
participant A as App
participant P as OAuth Provider
participant S as Session Store
U->>A: Click "Sign in with Provider"
A->>P: Redirect to OAuth Provider
P->>U: Show consent screen
U->>P: Grant permission
P->>A: Redirect with auth code
A->>P: Exchange code for tokens
P->>A: Return access token
A->>S: Create user session
A->>U: Redirect to app
Email/Password Flow
sequenceDiagram
participant U as User
participant A as App
participant D as Database
participant S as Session Store
U->>A: Submit email/password
A->>A: Validate credentials
A->>D: Check user exists
D->>A: Return user data
A->>A: Verify password hash
A->>S: Create session
A->>U: Return success
User Roles and Permissions
Default Roles
| Role | Description | Permissions |
|---|---|---|
| user | Regular user | Submit items, manage profile |
| moderator | Content moderator | Review submissions, moderate content |
| admin | Administrator | Full system access except user management |
| super_admin | Super administrator | Complete system control |
Permission System
// Permission definitions
export const permissions = {
// Item permissions
'items:create': ['user', 'moderator', 'admin', 'super_admin'],
'items:read': ['user', 'moderator', 'admin', 'super_admin'],
'items:update': ['moderator', 'admin', 'super_admin'],
'items:delete': ['admin', 'super_admin'],
'items:approve': ['moderator', 'admin', 'super_admin'],
// User permissions
'users:read': ['admin', 'super_admin'],
'users:update': ['admin', 'super_admin'],
'users:delete': ['super_admin'],
'users:ban': ['admin', 'super_admin'],
// System permissions
'system:configure': ['super_admin'],
'system:backup': ['admin', 'super_admin'],
'system:logs': ['admin', 'super_admin'],
} as const;
Session Management
NextAuth.js Sessions
JWT Strategy
// JWT session configuration
export const authOptions: NextAuthOptions = {
session: {
strategy: 'jwt',
maxAge: 30 * 24 * 60 * 60, // 30 days
},
jwt: {
maxAge: 30 * 24 * 60 * 60, // 30 days
},
callbacks: {
jwt: async ({ token, user }) => {
if (user) {
token.role = user.role;
token.permissions = user.permissions;
}
return token;
},
session: async ({ session, token }) => {
session.user.role = token.role;
session.user.permissions = token.permissions;
return session;
},
},
};
Database Strategy
// Database session configuration
export const authOptions: NextAuthOptions = {
session: {
strategy: 'database',
maxAge: 30 * 24 * 60 * 60, // 30 days
updateAge: 24 * 60 * 60, // 24 hours
},
adapter: DrizzleAdapter(db),
};
Supabase Sessions
// Supabase session management
export const supabaseAuth = {
session: {
persistSession: true,
autoRefreshToken: true,
detectSessionInUrl: true,
},
auth: {
flowType: 'pkce',
autoRefreshToken: true,
persistSession: true,
},
};
Security Features
Password Security
Password Requirements
- Minimum 8 characters
- At least one uppercase letter
- At least one lowercase letter
- At least one number
- At least one special character
Password Hashing
import bcrypt from 'bcryptjs';
// Hash password
const hashPassword = async (password: string): Promise<string> => {
const saltRounds = 12;
return bcrypt.hash(password, saltRounds);
};
// Verify password
const verifyPassword = async (password: string, hash: string): Promise<boolean> => {
return bcrypt.compare(password, hash);
};
Rate Limiting
// Authentication rate limiting
export const authRateLimit = {
signin: {
max: 5, // 5 attempts
windowMs: 15 * 60 * 1000, // 15 minutes
},
signup: {
max: 3, // 3 attempts
windowMs: 60 * 60 * 1000, // 1 hour
},
passwordReset: {
max: 3, // 3 attempts
windowMs: 60 * 60 * 1000, // 1 hour
},
};
CSRF Protection
// CSRF token validation
export const csrfProtection = {
enabled: true,
secret: process.env.CSRF_SECRET,
cookie: {
name: '__Host-csrf-token',
sameSite: 'strict',
secure: true,
httpOnly: true,
},
};