- Added user tracking features to the projects module, including: - Database schema updates to track project creator and assignee. - API enhancements for user management and project filtering by user. - UI components for user assignment in project forms and listings. - New query functions for retrieving users and filtering projects. - Security integration with role-based access and authentication requirements. chore: Create utility scripts for database checks and project testing - Added scripts to check the structure of the projects table. - Created tests for project creation and user tracking functionality. - Implemented API tests to verify project retrieval and user assignment. fix: Update project creation and update functions to include user tracking - Modified createProject and updateProject functions to handle user IDs for creator and assignee. - Ensured that project updates reflect the correct user assignments and timestamps.
25 KiB
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.localconfigured 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.jsscript 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
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:
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:
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:
"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 (
<div className="flex justify-center items-center h-64">Loading...</div>
);
}
if (!session) {
return fallback || <div>Redirecting to login...</div>;
}
if (requiredRole && !hasPermission(session.user.role, requiredRole)) {
return fallback || <div>Access denied</div>;
}
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 formsrc/app/auth/signout/page.js- Logout confirmationsrc/app/auth/error/page.js- Error handlingsrc/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:
// 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:
// 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
- Install dependencies (NextAuth.js v5, bcryptjs, zod)
- Create environment configuration (.env.local)
- Extend database schema (users, sessions, audit_logs)
- Create initial admin user script
✅ Phase 2: Authentication - COMPLETED
- Configure NextAuth.js with credentials provider
- Create API route handlers (/api/auth/[...nextauth])
- Implement user management system
- Test login/logout functionality
✅ Phase 3: Authorization - COMPLETED
- Implement API middleware (withAuth, role hierarchy)
- Protect existing API routes (projects, contracts, tasks, notes)
- Create role-based helper functions
- Integrate session provider in app layout
🔄 Phase 4: User Interface - IN PROGRESS
- Create sign-in page with form validation
- Update navigation component with auth integration
- 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
-
Complete Auth UI (High Priority)
- Sign-out confirmation page
- Unauthorized access page
- Enhanced error handling
-
Admin User Management (High Priority)
- User listing interface
- Create/edit user forms
- Role assignment controls
-
Security Enhancements (Medium Priority)
- Input validation schemas
- Rate limiting middleware
- Comprehensive audit logging
-
Password Management (Medium Priority)
- Password reset functionality
- Password strength requirements
- Password change interface
User Tracking in Projects - NEW FEATURE ✅
📊 Project User Management Implementation
We've successfully implemented comprehensive user tracking for projects:
Database Schema Updates ✅
- created_by: Tracks who created the project (user ID)
- assigned_to: Tracks who is assigned to work on the project (user ID)
- created_at: Timestamp when project was created
- updated_at: Timestamp when project was last modified
- Indexes: Performance optimized with proper foreign key indexes
API Enhancements ✅
- Enhanced Queries: Projects now include user names and emails via JOIN operations
- User Assignment: New
/api/projects/usersendpoint for user management - Query Filters: Support for filtering projects by assigned user or creator
- User Context: Create/update operations automatically capture authenticated user ID
UI Components ✅
- Project Form: User assignment dropdown in create/edit forms
- Project Listing: "Created By" and "Assigned To" columns in project table
- User Selection: Dropdown populated with active users for assignment
New Query Functions ✅
getAllUsersForAssignment(): Get active users for assignment dropdowngetProjectsByAssignedUser(userId): Filter projects by assigneegetProjectsByCreator(userId): Filter projects by creatorupdateProjectAssignment(projectId, userId): Update project assignment
Security Integration ✅
- Authentication Required: All user operations require valid session
- Role-Based Access: User assignment respects role hierarchy
- Audit Ready: Infrastructure prepared for comprehensive user action logging
Usage Examples
Creating Projects with User Tracking
// Projects are automatically assigned to the authenticated user as creator
POST /api/projects
{
"project_name": "New Project",
"assigned_to": "user-id-here", // Optional assignment
// ... other project data
}
Filtering Projects by User
// Get projects assigned to specific user
GET /api/projects?assigned_to=user-id
// Get projects created by specific user
GET /api/projects?created_by=user-id
Updating Project Assignment
POST /api/projects/users
{
"projectId": 123,
"assignedToUserId": "new-user-id"
}
Next Enhancements
-
Dashboard Views (Recommended)
- "My Projects" dashboard showing assigned projects
- Project creation history per user
- Workload distribution reports
-
Advanced Filtering (Future)
- Multi-user assignment support
- Team-based project assignments
- Role-based project visibility
-
Notifications (Future)
- Email alerts on project assignment
- Deadline reminders for assigned users
- Status change notifications
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 endpointstest-auth-detailed.mjs- Comprehensive authentication flow testingtest-complete-auth.mjs- Full system authentication validationtest-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
Security Libraries
Best Practices
Next Steps: Choose which phase to implement first and create detailed implementation tickets for development.