# Sprint 2: Authentication & RBAC **Date**: 2025-12-09 **Status**: ๐ŸŸก In Progress **Duration**: 8-10 hours **Priority**: ๐Ÿ”ด Critical --- ## ๐ŸŽฏ Objective Implement secure authentication and role-based access control (RBAC) to protect all API endpoints and enforce permissions based on user roles. --- ## ๐Ÿ“‹ Current State ### What Works - โœ… Basic login endpoint exists (`/api/auth/login`) - โœ… JWT plugin registered in Fastify - โœ… User model with Role enum (OWNER, MANAGER, GROWER, STAFF) - โœ… Frontend AuthContext exists ### What's Missing - โŒ Password hashing (currently plaintext) - โŒ JWT token generation and validation - โŒ Auth middleware to protect routes - โŒ RBAC middleware for role-based permissions - โŒ Refresh token logic - โŒ Proper error handling for auth failures --- ## ๐Ÿ—๏ธ Implementation Plan ### Phase 1: Backend Auth Core (3-4 hours) #### Task 2.1: Password Hashing - [ ] Install bcrypt: `npm install bcrypt @types/bcrypt` - [ ] Create password utility functions (hash, compare) - [ ] Update seed script to hash passwords - [ ] Update login controller to compare hashed passwords #### Task 2.2: JWT Token Generation - [ ] Create JWT utility functions (generate access token, generate refresh token) - [ ] Update login endpoint to return JWT tokens - [ ] Add token expiry configuration (15min access, 7d refresh) - [ ] Store refresh tokens in Redis #### Task 2.3: Auth Middleware - [ ] Create `authenticate` middleware (verify JWT) - [ ] Add user info to request object - [ ] Handle expired tokens - [ ] Handle invalid tokens #### Task 2.4: RBAC Middleware - [ ] Create `authorize(...roles)` middleware - [ ] Check user role against allowed roles - [ ] Return 403 Forbidden if unauthorized --- ### Phase 2: Protected Routes (2-3 hours) #### Task 2.5: Apply Auth to Routes - [ ] Protect `/api/rooms` (all roles) - [ ] Protect `/api/batches` (all roles) - [ ] Protect `/api/timeclock` (all roles) - [ ] Add role restrictions where needed #### Task 2.6: Refresh Token Endpoint - [ ] Create `/api/auth/refresh` endpoint - [ ] Validate refresh token - [ ] Generate new access token - [ ] Return new tokens #### Task 2.7: Logout Endpoint - [ ] Create `/api/auth/logout` endpoint - [ ] Invalidate refresh token in Redis - [ ] Clear tokens from client --- ### Phase 3: Frontend Integration (2-3 hours) #### Task 2.8: Update AuthContext - [ ] Store tokens in localStorage - [ ] Add token refresh logic - [ ] Add automatic logout on 401 - [ ] Add token to all API requests #### Task 2.9: Update API Client - [ ] Create axios instance with interceptors - [ ] Add Authorization header to requests - [ ] Handle 401 (refresh token or logout) - [ ] Handle 403 (show permission error) #### Task 2.10: Update Login Flow - [ ] Store tokens on successful login - [ ] Redirect to dashboard - [ ] Handle login errors - [ ] Add loading states --- ### Phase 4: Testing & Polish (1-2 hours) #### Task 2.11: Manual Testing - [ ] Test login with correct credentials - [ ] Test login with wrong credentials - [ ] Test protected routes without token - [ ] Test protected routes with valid token - [ ] Test token expiry and refresh - [ ] Test logout #### Task 2.12: Add More Test Users - [ ] Create users for each role (MANAGER, GROWER, STAFF) - [ ] Update seed script - [ ] Document test credentials --- ## ๐Ÿ” Security Considerations ### Password Security - Use bcrypt with salt rounds = 10 - Never log passwords - Never return password hashes in API responses ### Token Security - Access tokens: Short-lived (15 minutes) - Refresh tokens: Longer-lived (7 days) - Store refresh tokens in httpOnly cookies (future enhancement) - Invalidate refresh tokens on logout ### RBAC Rules - **OWNER**: Full access to everything - **MANAGER**: Full access except user management - **GROWER**: Read/write batches, rooms, tasks - **STAFF**: Read-only + timeclock --- ## ๐Ÿ“Š Success Criteria - [ ] All API endpoints require authentication - [ ] Passwords are hashed with bcrypt - [ ] JWT tokens working (access + refresh) - [ ] Role-based permissions enforced - [ ] Frontend stores and uses tokens correctly - [ ] Token refresh works automatically - [ ] Logout invalidates tokens - [ ] Multiple test users available (one per role) - [ ] No security vulnerabilities (no plaintext passwords, no exposed secrets) --- ## ๐Ÿงช Testing Checklist ### Backend Tests - [ ] Login with valid credentials returns tokens - [ ] Login with invalid credentials returns 401 - [ ] Protected route without token returns 401 - [ ] Protected route with valid token returns data - [ ] Protected route with expired token returns 401 - [ ] Refresh token endpoint works - [ ] Logout invalidates refresh token - [ ] RBAC blocks unauthorized roles ### Frontend Tests - [ ] Login form submits correctly - [ ] Tokens stored in localStorage - [ ] API requests include Authorization header - [ ] 401 triggers token refresh - [ ] Logout clears tokens and redirects --- ## ๐Ÿ“ Files to Modify ### Backend - `backend/package.json` - Add bcrypt dependency - `backend/src/utils/password.ts` - New file (hash, compare) - `backend/src/utils/jwt.ts` - New file (generate, verify) - `backend/src/middleware/auth.ts` - New file (authenticate, authorize) - `backend/src/controllers/auth.controller.ts` - Update login, add refresh, logout - `backend/src/routes/*.routes.ts` - Add auth middleware - `backend/prisma/seed.js` - Hash passwords ### Frontend - `frontend/src/context/AuthContext.tsx` - Update token handling - `frontend/src/lib/api.ts` - New file (axios instance with interceptors) - `frontend/src/pages/LoginPage.tsx` - Update login flow --- ## ๐Ÿš€ Let's Begin Starting with **Task 2.1: Password Hashing**...