# Authorization Implementation Guide ## Project Overview This document outlines the implementation strategy for adding authentication and authorization to the Project Management Panel - a Next.js 15 application with SQLite database. ## Current State Analysis (Updated: June 25, 2025) ### ✅ What We Have Implemented - **Framework**: Next.js 15 with App Router - **Database**: SQLite with better-sqlite3 - **Authentication**: NextAuth.js v5 with credentials provider - **User Management**: Complete user CRUD operations with bcrypt password hashing - **Database Schema**: Users table with roles, audit logs, sessions - **API Protection**: Middleware system with role-based access control - **Session Management**: JWT-based sessions with 30-day expiration - **Security Features**: Account lockout, failed login tracking, password validation - **UI Components**: Authentication provider, navigation with user context - **Auth Pages**: Sign-in page implemented ### ✅ What's Protected - **API Routes**: All major endpoints (projects, contracts, tasks, notes) are protected - **Role Hierarchy**: admin > project_manager > user > read_only - **Navigation**: Role-based menu items (admin sees user management) - **Session Security**: Automatic session management and validation ### 🔄 Partially Implemented - **Auth Pages**: Sign-in exists, missing sign-out and error pages - **User Interface**: Basic auth integration, could use more polish - **Admin Features**: User management backend exists, UI needs completion - **Audit Logging**: Database schema exists, not fully integrated ### ❌ Still Missing - Complete user management UI for admins - Password reset functionality - Rate limiting implementation - Enhanced input validation schemas - CSRF protection - Security headers middleware - Comprehensive error handling - Email notifications ## Recommended Implementation Strategy ### 1. Authentication Solution: NextAuth.js **Why NextAuth.js?** - ✅ Native Next.js 15 App Router support - ✅ Database session management - ✅ Built-in security features (CSRF, JWT handling) - ✅ Flexible provider system - ✅ SQLite adapter available ### 2. Role-Based Access Control (RBAC) **Proposed User Roles:** | Role | Permissions | Use Case | | ------------------- | --------------------------------------- | ----------------------- | | **Admin** | Full system access, user management | System administrators | | **Project Manager** | Manage all projects/tasks, view reports | Team leads, supervisors | | **User** | View/edit assigned projects/tasks | Regular employees | | **Read-only** | View-only access to data | Clients, stakeholders | ## Implementation Status ### ✅ Phase 1: Foundation Setup - COMPLETED #### 1.1 Dependencies - ✅ INSTALLED - NextAuth.js v5 (beta) - bcryptjs for password hashing - Zod for validation - Better-sqlite3 adapter compatibility #### 1.2 Environment Configuration - ✅ COMPLETED - `.env.local` configured with NEXTAUTH_SECRET and NEXTAUTH_URL - Database URL configuration - Development environment setup #### 1.3 Database Schema - ✅ IMPLEMENTED - Users table with roles and security features - Sessions table for NextAuth.js - Audit logs table for security tracking - Proper indexes for performance #### 1.4 Initial Admin User - ✅ COMPLETED - `scripts/create-admin.js` script available - Default admin user: admin@localhost.com / admin123456 ### ✅ Phase 2: Authentication Core - COMPLETED #### 2.1 NextAuth.js Configuration - ✅ IMPLEMENTED - **File**: `src/lib/auth.js` - Credentials provider with email/password - JWT session strategy with 30-day expiration - Account lockout after 5 failed attempts (15-minute lockout) - Password verification with bcrypt - Failed login attempt tracking - Session callbacks for role management #### 2.2 API Route Handlers - ✅ IMPLEMENTED - **File**: `src/app/api/auth/[...nextauth]/route.js` - NextAuth.js handlers properly configured #### 2.3 User Management System - ✅ IMPLEMENTED - **File**: `src/lib/userManagement.js` - Complete CRUD operations for users - Password hashing and validation - Role management functions - User lookup by ID and email ### ✅ Phase 3: Authorization Middleware - COMPLETED #### 3.1 API Protection Middleware - ✅ IMPLEMENTED - **File**: `src/lib/middleware/auth.js` - `withAuth()` function for protecting routes - Role hierarchy enforcement (admin=4, project_manager=3, user=2, read_only=1) - Helper functions: `withReadAuth`, `withUserAuth`, `withAdminAuth`, `withManagerAuth` - Proper error handling and status codes #### 3.2 Protected API Routes - ✅ IMPLEMENTED Example in `src/app/api/projects/route.js`: - GET requests require read_only access - POST requests require user access - All major API endpoints are protected #### 3.3 Session Provider - ✅ IMPLEMENTED - **File**: `src/components/auth/AuthProvider.js` - NextAuth SessionProvider wrapper - Integrated into root layout ### 🔄 Phase 4: User Interface - PARTIALLY COMPLETED #### 4.1 Authentication Pages - 🔄 PARTIAL - ✅ **Sign-in page**: `src/app/auth/signin/page.js` - Complete with form validation - ❌ **Sign-out page**: Missing - 🔄 **Error page**: `src/app/auth/error/page.js` - Basic implementation - ❌ **Unauthorized page**: Missing #### 4.2 Navigation Updates - ✅ COMPLETED - **File**: `src/components/ui/Navigation.js` - User session integration with useSession - Role-based menu items (admin sees user management) - Sign-out functionality - Conditional rendering based on auth status #### 4.3 User Management Interface - ❌ MISSING - Backend exists in userManagement.js - Admin UI for user CRUD operations needed - Role assignment interface needed ### ❌ Phase 5: Security Enhancements - NOT STARTED #### 5.1 Input Validation Schemas - ❌ MISSING - Zod schemas for API endpoints - Request validation middleware #### 5.2 Rate Limiting - ❌ MISSING - Rate limiting middleware - IP-based request tracking #### 5.3 Security Headers - ❌ MISSING - CSRF protection - Security headers middleware - Content Security Policy ```javascript import NextAuth from "next-auth"; import CredentialsProvider from "next-auth/providers/credentials"; import { BetterSQLite3Adapter } from "@auth/better-sqlite3-adapter"; import db from "./db.js"; import bcrypt from "bcryptjs"; import { z } from "zod"; const loginSchema = z.object({ email: z.string().email("Invalid email format"), password: z.string().min(6, "Password must be at least 6 characters"), }); export const { handlers, auth, signIn, signOut } = NextAuth({ adapter: BetterSQLite3Adapter(db), session: { strategy: "database", maxAge: 30 * 24 * 60 * 60, // 30 days updateAge: 24 * 60 * 60, // 24 hours }, providers: [ CredentialsProvider({ name: "credentials", credentials: { email: { label: "Email", type: "email" }, password: { label: "Password", type: "password" }, }, async authorize(credentials, req) { try { // Validate input const validatedFields = loginSchema.parse(credentials); // Check if user exists and is active const user = db .prepare( ` SELECT id, email, name, password_hash, role, is_active, failed_login_attempts, locked_until FROM users WHERE email = ? AND is_active = 1 ` ) .get(validatedFields.email); if (!user) { throw new Error("Invalid credentials"); } // Check if account is locked if (user.locked_until && new Date(user.locked_until) > new Date()) { throw new Error("Account temporarily locked"); } // Verify password const isValidPassword = await bcrypt.compare( validatedFields.password, user.password_hash ); if (!isValidPassword) { // Increment failed attempts db.prepare( ` UPDATE users SET failed_login_attempts = failed_login_attempts + 1, locked_until = CASE WHEN failed_login_attempts >= 4 THEN datetime('now', '+15 minutes') ELSE locked_until END WHERE id = ? ` ).run(user.id); throw new Error("Invalid credentials"); } // Reset failed attempts and update last login db.prepare( ` UPDATE users SET failed_login_attempts = 0, locked_until = NULL, last_login = CURRENT_TIMESTAMP WHERE id = ? ` ).run(user.id); // Log successful login logAuditEvent(user.id, "LOGIN_SUCCESS", "user", user.id, req); return { id: user.id, email: user.email, name: user.name, role: user.role, }; } catch (error) { console.error("Login error:", error); return null; } }, }), ], callbacks: { async jwt({ token, user, account }) { if (user) { token.role = user.role; token.userId = user.id; } return token; }, async session({ session, token, user }) { if (token) { session.user.id = token.userId || token.sub; session.user.role = token.role || user?.role; } return session; }, async signIn({ user, account, profile, email, credentials }) { // Additional sign-in logic if needed return true; }, }, pages: { signIn: "/auth/signin", signOut: "/auth/signout", error: "/auth/error", }, events: { async signOut({ session, token }) { if (session?.user?.id) { logAuditEvent(session.user.id, "LOGOUT", "user", session.user.id); } }, }, }); // Audit logging helper function logAuditEvent(userId, action, resourceType, resourceId, req = null) { try { db.prepare( ` INSERT INTO audit_logs (user_id, action, resource_type, resource_id, ip_address, user_agent) VALUES (?, ?, ?, ?, ?, ?) ` ).run( userId, action, resourceType, resourceId, req?.ip || "unknown", req?.headers?.["user-agent"] || "unknown" ); } catch (error) { console.error("Audit log error:", error); } } ``` #### 2.2 API Route Handlers Create `src/app/api/auth/[...nextauth]/route.js`: ```javascript import { handlers } from "@/lib/auth"; export const { GET, POST } = handlers; ``` ### Phase 3: Authorization Middleware #### 3.1 API Protection Middleware Create `src/lib/middleware/auth.js`: ```javascript import { auth } from "@/lib/auth"; import { NextResponse } from "next/server"; import { z } from "zod"; // Role hierarchy for permission checking const ROLE_HIERARCHY = { admin: 4, project_manager: 3, user: 2, read_only: 1, }; export function withAuth(handler, options = {}) { return async (req, context) => { try { const session = await auth(); // Check if user is authenticated if (!session?.user) { return NextResponse.json( { error: "Authentication required" }, { status: 401 } ); } // Check if user account is active const user = db .prepare("SELECT is_active FROM users WHERE id = ?") .get(session.user.id); if (!user?.is_active) { return NextResponse.json( { error: "Account deactivated" }, { status: 403 } ); } // Check role-based permissions if ( options.requiredRole && !hasPermission(session.user.role, options.requiredRole) ) { logAuditEvent( session.user.id, "ACCESS_DENIED", options.resource || "api", req.url ); return NextResponse.json( { error: "Insufficient permissions" }, { status: 403 } ); } // Check resource-specific permissions if (options.checkResourceAccess) { const hasAccess = await options.checkResourceAccess( session.user, context.params ); if (!hasAccess) { return NextResponse.json( { error: "Access denied to this resource" }, { status: 403 } ); } } // Validate request body if schema provided if ( options.bodySchema && (req.method === "POST" || req.method === "PUT" || req.method === "PATCH") ) { try { const body = await req.json(); options.bodySchema.parse(body); } catch (error) { return NextResponse.json( { error: "Invalid request data", details: error.errors }, { status: 400 } ); } } // Add user info to request req.user = session.user; req.session = session; // Call the original handler return await handler(req, context); } catch (error) { console.error("Auth middleware error:", error); return NextResponse.json( { error: "Internal server error" }, { status: 500 } ); } }; } export function hasPermission(userRole, requiredRole) { return ROLE_HIERARCHY[userRole] >= ROLE_HIERARCHY[requiredRole]; } // Helper for read-only operations export function withReadAuth(handler) { return withAuth(handler, { requiredRole: "read_only" }); } // Helper for user-level operations export function withUserAuth(handler) { return withAuth(handler, { requiredRole: "user" }); } // Helper for project manager operations export function withManagerAuth(handler) { return withAuth(handler, { requiredRole: "project_manager" }); } // Helper for admin operations export function withAdminAuth(handler) { return withAuth(handler, { requiredRole: "admin" }); } ``` #### 3.2 Client-Side Route Protection Create `src/components/auth/ProtectedRoute.js`: ```javascript "use client"; import { useSession } from "next-auth/react"; import { useRouter } from "next/navigation"; import { useEffect } from "react"; export function ProtectedRoute({ children, requiredRole = null, fallback = null, }) { const { data: session, status } = useSession(); const router = useRouter(); useEffect(() => { if (status === "loading") return; // Still loading if (!session) { router.push("/auth/signin"); return; } if (requiredRole && !hasPermission(session.user.role, requiredRole)) { router.push("/unauthorized"); return; } }, [session, status, router, requiredRole]); if (status === "loading") { return (
Loading...
); } if (!session) { return fallback ||
Redirecting to login...
; } if (requiredRole && !hasPermission(session.user.role, requiredRole)) { return fallback ||
Access denied
; } return children; } function hasPermission(userRole, requiredRole) { const roleHierarchy = { admin: 4, project_manager: 3, user: 2, read_only: 1, }; return roleHierarchy[userRole] >= roleHierarchy[requiredRole]; } ``` ### Phase 4: User Interface Components #### 4.1 Authentication Pages Pages to create: - `src/app/auth/signin/page.js` - Login form - `src/app/auth/signout/page.js` - Logout confirmation - `src/app/auth/error/page.js` - Error handling - `src/app/unauthorized/page.js` - Access denied page #### 4.2 Navigation Updates Update `src/components/ui/Navigation.js` to include: - Login/logout buttons - User info display - Role-based menu items #### 4.3 User Management Interface For admin users: - User listing and management - Role assignment - Account activation/deactivation ### Phase 5: Security Enhancements #### 5.1 Input Validation Schemas Create `src/lib/schemas/` with Zod schemas for all API endpoints: ```javascript // src/lib/schemas/project.js import { z } from "zod"; export const createProjectSchema = z.object({ contract_id: z.number().int().positive(), project_name: z.string().min(1).max(255), project_number: z.string().min(1).max(50), address: z.string().optional(), // ... other fields }); export const updateProjectSchema = createProjectSchema.partial(); ``` #### 5.2 Rate Limiting Implement rate limiting for sensitive endpoints: ```javascript // src/lib/middleware/rateLimit.js const attempts = new Map(); export function withRateLimit( handler, options = { maxAttempts: 5, windowMs: 15 * 60 * 1000 } ) { return async (req, context) => { const key = req.ip || "unknown"; const now = Date.now(); const window = attempts.get(key) || { count: 0, resetTime: now + options.windowMs, }; if (now > window.resetTime) { window.count = 1; window.resetTime = now + options.windowMs; } else { window.count++; } attempts.set(key, window); if (window.count > options.maxAttempts) { return NextResponse.json({ error: "Too many requests" }, { status: 429 }); } return handler(req, context); }; } ``` ## Implementation Checklist (Updated Status) ### ✅ Phase 1: Foundation - COMPLETED - [x] Install dependencies (NextAuth.js v5, bcryptjs, zod) - [x] Create environment configuration (.env.local) - [x] Extend database schema (users, sessions, audit_logs) - [x] Create initial admin user script ### ✅ Phase 2: Authentication - COMPLETED - [x] Configure NextAuth.js with credentials provider - [x] Create API route handlers (/api/auth/[...nextauth]) - [x] Implement user management system - [x] Test login/logout functionality ### ✅ Phase 3: Authorization - COMPLETED - [x] Implement API middleware (withAuth, role hierarchy) - [x] Protect existing API routes (projects, contracts, tasks, notes) - [x] Create role-based helper functions - [x] Integrate session provider in app layout ### 🔄 Phase 4: User Interface - IN PROGRESS - [x] Create sign-in page with form validation - [x] Update navigation component with auth integration - [x] Add role-based menu items - [ ] Create sign-out confirmation page - [ ] Create error handling page - [ ] Create unauthorized access page - [ ] Build admin user management interface ### ❌ Phase 5: Security Enhancements - NOT STARTED - [ ] Add input validation schemas to all endpoints - [ ] Implement rate limiting for sensitive operations - [ ] Add comprehensive audit logging - [ ] Create security headers middleware - [ ] Implement CSRF protection - [ ] Add password reset functionality ## Current Working Features ### 🔐 Authentication System - **Login/Logout**: Fully functional with NextAuth.js - **Session Management**: JWT-based with 30-day expiration - **Password Security**: bcrypt hashing with salt rounds - **Account Lockout**: 5 failed attempts = 15-minute lockout - **Role System**: 4-tier hierarchy (admin, project_manager, user, read_only) ### 🛡️ Authorization System - **API Protection**: All major endpoints require authentication - **Role-Based Access**: Different permission levels per endpoint - **Middleware**: Clean abstraction with helper functions - **Session Validation**: Automatic session verification ### 📱 User Interface - **Navigation**: Context-aware with user info and sign-out - **Auth Pages**: Professional sign-in form with error handling - **Role Integration**: Admin users see additional menu items - **Responsive**: Works across device sizes ### 🗄️ Database Security - **User Management**: Complete CRUD with proper validation - **Audit Schema**: Ready for comprehensive logging - **Indexes**: Optimized for performance - **Constraints**: Role validation and data integrity ## Next Priority Tasks 1. **Complete Auth UI** (High Priority) - Sign-out confirmation page - Unauthorized access page - Enhanced error handling 2. **Admin User Management** (High Priority) - User listing interface - Create/edit user forms - Role assignment controls 3. **Security Enhancements** (Medium Priority) - Input validation schemas - Rate limiting middleware - Comprehensive audit logging 4. **Password Management** (Medium Priority) - Password reset functionality - Password strength requirements - Password change interface ## Security Best Practices ### 1. Password Security - Minimum 8 characters - Require special characters, numbers - Hash with bcrypt (cost factor 12+) - Implement password history ### 2. Session Security - Secure cookies - Session rotation - Timeout handling - Device tracking ### 3. API Security - Input validation on all endpoints - SQL injection prevention (prepared statements) - XSS protection - CSRF tokens ### 4. Audit & Monitoring - Log all authentication events - Monitor failed login attempts - Track permission changes - Alert on suspicious activity ## Testing Status ### ✅ Completed Tests - **Authentication Flow**: Login/logout working correctly - **API Protection**: All endpoints properly secured - **Role Validation**: Permission levels enforced - **Session Management**: JWT tokens and expiration working - **Password Security**: bcrypt hashing and verification functional - **Account Lockout**: Failed attempt tracking and temporary lockout ### 🔧 Available Test Scripts - `test-auth.mjs` - Tests API route protection and auth endpoints - `test-auth-detailed.mjs` - Comprehensive authentication flow testing - `test-complete-auth.mjs` - Full system authentication validation - `test-logged-in-flow.mjs` - Authenticated user session testing ### ✅ Verified Security Features - Unauthorized API requests return 401 - Role-based access control working - Session tokens properly validated - Password attempts tracked and limited - Admin user creation and management functional ## Deployment Considerations ### 1. Environment Variables - Use strong, random secrets - Different keys per environment - Secure secret management ### 2. Database Security - Regular backups - Encryption at rest - Network security - Access logging ### 3. Application Security - HTTPS enforcement - Security headers - Content Security Policy - Regular security updates ## Migration Strategy ### 1. Development Phase - Implement on development branch - Test thoroughly with sample data - Document all changes ### 2. Staging Deployment - Deploy to staging environment - Performance testing - Security testing - User acceptance testing ### 3. Production Deployment - Database backup before migration - Gradual rollout - Monitor for issues - Rollback plan ready ## Resources and Documentation ### NextAuth.js - [Official Documentation](https://next-auth.js.org/) - [Better SQLite3 Adapter](https://authjs.dev/reference/adapter/better-sqlite3) ### Security Libraries - [Zod Validation](https://zod.dev/) - [bcryptjs](https://www.npmjs.com/package/bcryptjs) ### Best Practices - [OWASP Top 10](https://owasp.org/www-project-top-ten/) - [Next.js Security Guidelines](https://nextjs.org/docs/advanced-features/security-headers) --- **Next Steps**: Choose which phase to implement first and create detailed implementation tickets for development.