Authentication Flow
VizBoard implements a JWT-based session strategy with a 30-day expiration period. Sessions are managed server-side using NextAuth.js v5.Supported Authentication Methods
Email/Password
Traditional credentials-based authentication with bcrypt password hashing
Google OAuth
Sign in with your Google account
GitHub OAuth
Sign in with your GitHub account
User Registration
New users can sign up using email and password or through OAuth providers.Choose Registration Method
Option 1: Email/Password RegistrationFill out the registration form with:
- First Name
- Last Name
- Email address
- Password
- Convert email to lowercase for consistency
- Hash the password using bcrypt (salt rounds: 10)
- Create a full name by combining first and last names
- Store the user in the PostgreSQL database
- Redirect to the OAuth provider
- Extract profile information (name, email)
- Create a user account with
passwordset tonull - Link the OAuth account to the user
Email Validation
The system checks if the email is already registered:
- If the email exists with a password, registration is blocked
- If the email exists from OAuth only, you’re prompted to use that OAuth provider
Code Reference
The sign-up logic is implemented insrc/app/actions/auth/signUp.ts:8-41:
User Login
Existing users can log in using any method they registered with.Choose Login Method
Credentials LoginEnter your email and password. The authentication flow:
- Email is converted to lowercase
- User is fetched from database
- Password is compared using bcrypt
- If successful, a JWT token is created
- Redirects to the provider
- Validates the OAuth callback
- Creates or updates the user session
Session Creation
Upon successful authentication, NextAuth.js creates a JWT session with:
- User ID
- Name (first name + last name)
- First name and last name (stored separately)
- 30-day expiration
Login Form Implementation
The login form uses React Hook Form with Zod validation (src/components/auth/login-form.tsx:32-59):
Session Management
VizBoard uses JWT-based sessions configured insrc/lib/auth/auth.ts:48-53.
Session Configuration
Session Callbacks
NextAuth.js provides three key callbacks: 1. JWT Callback (src/lib/auth/auth.ts:174-203)
Runs when a JWT is created or updated:
src/lib/auth/auth.ts:205-215)
Exposes JWT data to the client session:
src/lib/auth/auth.ts:134-172)
Handles OAuth provider name extraction:
Protecting Routes
To protect routes, use theauth() helper function:
Example: Project Actions
All project-related actions check authentication (src/app/actions/project/crud.ts:23-26):
Database Schema
User authentication data is stored in two tables:User Table
Account Table (OAuth)
The
password field is null for users who register via OAuth. This prevents credential-based login for OAuth users.Environment Variables
Required environment variables for authentication:Best Practices
Password Security
- Passwords are hashed with bcrypt (10 rounds)
- Never store plain-text passwords
- Password field is nullable for OAuth users
Email Normalization
- All emails are converted to lowercase
- Prevents duplicate accounts with different casing
Session Security
- JWT tokens expire after 30 days
- Sessions are validated on each request
- Use
auth()helper to check authentication
OAuth Integration
- OAuth accounts link automatically by email
- Users cannot mix OAuth and credentials
- Profile data extracted from provider
Troubleshooting
”Invalid email or password” Error
- Verify the email is correct (check for typos)
- Ensure you’re using the same authentication method you registered with
- If you registered with OAuth, use that provider to log in
”Email already registered” Error
- This email is already in use
- Try logging in instead of signing up
- Use the “Forgot Password” flow if needed
OAuth Provider Not Working
- Check that environment variables are set correctly
- Verify OAuth app credentials in provider console
- Ensure redirect URIs are configured properly
Session Expires Too Quickly
- JWT sessions last 30 days by default
- Check if browser is blocking cookies
- Verify
NEXTAUTH_SECRETis set correctly
