This document outlines the complete authentication flows within the NextJS starter application with Better Auth v1.4+, including user registration, login, logout, password reset, social authentication, and multi-tenant organization management processes.
| Not Authenticated | C[Login/Register Flow] B --> | Authenticated | D[Application Access] C --> E[Email/Password Login] E --> I[Credentials Validation] I --> M{Validation Result} M --> | Success | D M --> | Failure | N[Error Handling] N --> C 1. User Registration FlowRegistration ProcesssequenceDiagram participant User participant RegisterForm participant API participant BetterAuth participant DB participant EmailService User->>RegisterForm: Access registration page User->>RegisterForm: Fill registration details User->>RegisterForm: Submit registration BetterAuth->>DB: Insert user record BetterAuth-->>API: Registration successful Registration Validation Flowflowchart TD A[Registration Form Submit] --> B[Client-Side Validation] B --> C{Validation Passed?} C --> | No | D[Show Field Errors] D --> A C --> | Yes | E[Send to API] E --> F[Server-Side Validation] | No | H[Return Error Response] H --> I[Display Server Errors] I --> A G --> | Yes |
J --> K[Send Verification Email]
K --> L[Create User Session]
L --> M[Redirect to Dashboard]
interface RegistrationForm {
name: string; // Required, min 2 chars
email: string; // Required, valid email
password: string; // Required, 8-128 chars
confirmPassword: string; // Must match password
organizationName?: string; // Optional, creates org if provided
acceptTerms: boolean; // Required, must be true
}- Name: 2-100 characters, alphanumeric + spaces
- Email: Valid email format, unique in database
- Password: 8-128 characters, complexity requirements
- Organization Name: Optional, 2-100 characters if provided
- Terms: Must be accepted
interface RegistrationErrors {
name?: string; // Invalid name format
email?: string; // Email already exists or invalid
password?: string; // Password too weak
confirmPassword?: string; // Passwords don't match
organizationName?: string; // Invalid organization name
acceptTerms?: string; // Terms must be accepted
server?: string; // Server-side errors
} User->>Browser: Navigate to /auth/login
Browser->>UI: Render Login Form
User->>UI: Enter credentials
UI->>UI: Client-side validation
User->>UI: Click Login button
UI->>API: POST /api/v1/auth/login
API->>API: Server-side validation
API->>BetterAuth: Authenticate user
BetterAuth->>DB: Verify credentials
DB-->>BetterAuth: User data (if valid)
alt Valid Credentials
BetterAuth->>DB: Create session
BetterAuth->>DB: Generate JWT tokens
BetterAuth-->>API: Authentication successful
API-->>UI: Return user data + tokens
UI->>UI: Update auth state
UI->>UI: Store tokens (cookies/localStorage)
UI-->>User: Redirect to dashboard
else Invalid Credentials
BetterAuth-->>API: Authentication failed
API-->>UI: Error response
UI-->>User: Show error message
end
Note over User,Middleware: Subsequent Request Authentication
User->>Browser: Navigate to protected route
Browser->>Middleware: Request with auth cookie
Middleware->>DB: Validate session
DB-->>Middleware: Session valid
Middleware-->>Browser: Allow access to protected route
interface LoginForm {
email: string; // Required, valid email
password: string; // Required
rememberMe?: boolean; // Optional, extends session
}- Session Duration: 3 days (configurable)
- Session Refresh: Automatic refresh if used within 1 day
- Token Storage: Secure HTTP-only cookies + localStorage for API calls
- Session Invalidation: Manual logout or automatic expiration
interface LoginState {
isLoading: boolean; // Form submission in progress
error?: string; // Login error message
success: boolean; // Login successful
requiresEmailVerification: boolean; // Email not verified
isBanned: boolean; // Account banned
banReason?: string; // Reason for ban
banExpires?: Date; // Ban expiration date
} User->>Browser: Navigate to /auth/login
Browser->>UI: Render Login Form
User->>UI: Click "Continue with Google"
UI->>API: GET /api/auth/signin/google
API->>BetterAuth: Initiate OAuth flow
BetterAuth->>Google: Redirect to Google OAuth
Google-->>User: Show Google consent screen
User->>Google: Authorize application
Google-->>BetterAuth: Redirect with authorization code
BetterAuth->>Google: Exchange code for tokens
Google-->>BetterAuth: Access tokens + user profile
BetterAuth->>DB: Check if user exists
alt User Exists
BetterAuth->>DB: Update last login
else New User
BetterAuth->>DB: Create new user record
BetterAuth->>DB: Create verification record (auto-verified)
end
BetterAuth->>DB: Create session
BetterAuth-->>API: Authentication successful
API-->>Browser: Redirect to dashboard
interface GoogleOAuthConfig {
clientId: string; // Google OAuth client ID
clientSecret: string; // Google OAuth client secret
redirectUri: string; // Authorized redirect URI
scope: string[]; // Requested permissions
}interface ProfileMapping {
email: string; // From Google profile
name: string; // From Google profile
image?: string; // From Google profile
emailVerified: true; // Auto-verified for OAuth
role: "USER"; // Default role for OAuth users
} Note over User,DB: After Registration
BetterAuth->>EmailService: Send verification email
EmailService-->>User: Email with verification link
User->>EmailService: Open verification email
User->>Browser: Click verification link
Browser->>API: GET /api/auth/verify-email?token=xxx
API->>BetterAuth: Process verification
BetterAuth->>DB: Find verification token
alt Valid Token
BetterAuth->>DB: Mark email as verified
BetterAuth->>DB: Delete verification token
BetterAuth-->>API: Verification successful
API-->>Browser: Redirect to login with success
else Invalid/Expired Token
BetterAuth-->>API: Verification failed
API-->>Browser: Show error page
Browser-->>User: Offer to resend verification
end
interface VerificationEmail {
to: string; // User's email address
subject: string; // "Verify your email address"
verificationUrl: string; // Unique verification link
expirationHours: number; // Token expiration (24 hours)
userName: string; // User's name for personalization
} User->>UI: Click "Resend verification"
UI->>API: POST /api/auth/resend-verification
API->>API: Validate email address
API->>DB: Check user exists and not verified
API->>BetterAuth: Generate new verification token
BetterAuth->>DB: Store verification token
BetterAuth->>EmailService: Send verification email
EmailService-->>User: New verification email
API-->>UI: Success response
UI-->>User: Show confirmation message
User->>Browser: Navigate to /auth/forgot-password
Browser->>UI: Render forgot password form
User->>UI: Enter email address
UI->>API: POST /api/v1/auth/reset
API->>DB: Check if user exists
alt User Exists
API->>BetterAuth: Generate reset token
BetterAuth->>DB: Store reset token
BetterAuth->>EmailService: Send reset email
EmailService-->>User: Password reset email
end
API-->>UI: Success response (always success for security)
UI-->>User: "Check your email" message
Note over User,EmailService: Password Reset Process
User->>EmailService: Open reset email
User->>Browser: Click reset link
Browser->>UI: Navigate to /auth/new-password?token=xxx
UI->>UI: Validate token with API
UI->>UI: Render new password form
User->>UI: Enter new password
UI->>API: POST /api/v1/auth/new-password
API->>BetterAuth: Validate token and update password
BetterAuth->>DB: Update user password
BetterAuth->>DB: Invalidate all sessions
BetterAuth->>DB: Delete reset token
BetterAuth-->>API: Password reset successful
API-->>UI: Success response
UI-->>User: Redirect to login with success message
interface PasswordResetForm {
password: string; // Required, 8-128 chars
confirmPassword: string; // Must match password
}- Expiration: 24 hours
- Single Use: Token becomes invalid after use
- Security: Cryptographically secure random tokens
- Invalidation: All sessions invalidated after password change
User->>UI: Click logout button
UI->>API: POST /api/v1/auth/logout
API->>BetterAuth: Logout request
BetterAuth->>DB: Delete session
BetterAuth->>DB: Revoke JWT tokens
BetterAuth-->>API: Logout successful
API-->>UI: Success response
UI->>UI: Clear local auth state
UI->>UI: Clear tokens from storage
UI--->User: Redirect to login page
interface LogoutOptions {
allDevices?: boolean; // Logout from all devices
redirectUrl?: string; // Custom redirect after logout
} Browser->>Middleware: Request with session cookie
Middleware->>DB: Check session exists
alt Session Exists
Middleware->>DB: Check session not expired
alt Session Valid
Middleware->>BetterAuth: Get user data
BetterAuth-->>Middleware: User information
Middleware-->>Browser: Continue to protected route
else Session Expired
Middleware->>DB: Delete expired session
Middleware-->>Browser: Redirect to login
end
else No Session
Middleware-->>Browser: Redirect to login
end
Browser->>Middleware: Request with aging session
Middleware->>DB: Check session age
alt Session age > 1 day and < 3 days
Middleware->>BetterAuth: Refresh session
BetterAuth->>DB: Update session expiration
BetterAuth->>DB: Generate new tokens
BetterAuth-->>Middleware: Refreshed session data
Middleware-->>Browser: Set new session cookies
else Session age >= 3 days
Middleware->>DB: Delete expired session
Middleware-->>Browser: Redirect to login
end
Note over User,DB: After Primary Authentication
API->>MFAService: Generate MFA challenge
MFAService-->>User: Send MFA code (SMS/Email/App)
UI->>User: Show MFA input form
User->>UI: Enter MFA code
UI->>API: Verify MFA code
API->>MFAService: Validate code
MFAService-->>API: Validation result
alt Valid Code
API->>DB: Complete authentication
API-->>UI: Success response
UI-->>User: Grant access
else Invalid Code
API-->>UI: Error response
UI-->>User: Show error + retry option
end
interface AuthErrorCodes {
INVALID_CREDENTIALS: "Email or password is incorrect";
USER_NOT_FOUND: "No account found with this email";
EMAIL_NOT_VERIFIED: "Please verify your email before logging in";
ACCOUNT_BANNED: "Your account has been banned";
WEAK_PASSWORD: "Password does not meet security requirements";
EMAIL_EXISTS: "An account with this email already exists";
INVALID_TOKEN: "Invalid or expired verification link";
RATE_LIMITED: "Too many attempts. Please try again later";
OAUTH_ERROR: "Failed to authenticate with Google";
NETWORK_ERROR: "Connection error. Please try again";
}interface UserFeedback {
success: {
type: "success";
message: string;
action?: string; // Optional action button text
actionUrl?: string; // Optional action URL
};
error: {
type: "error";
message: string;
code?: string; // Error code for logging
retryable?: boolean; // Can user retry the action
};
warning: {
type: "warning";
message: string;
dismissible?: boolean; // Can user dismiss the warning
};
info: {
type: "info";
message: string;
persistent?: boolean; // Stays visible until dismissed
};
}- Password Requirements: Minimum 8 characters, complexity rules
- Rate Limiting: Prevent brute force attacks
- Session Security: HTTP-only, secure cookies
- CSRF Protection: SameSite cookie attributes
- Token Security: JWT with RS256 signing
- Account Lockout: Temporary bans after failed attempts
- Email Privacy: Email addresses only used for authentication
- Password Security: Never stored in plain text
- Session Data: Minimal data stored in sessions
- Audit Logging: All authentication events logged
- Data Encryption: All sensitive data encrypted at rest
---
Document Version: 1.1
Last Updated: December 8, 2024
Next Review: January 31, 2025