ca-grow-ops-manager/backend/src/utils/jwt.ts
fullsizemalt 9dc0586d67 feat: Sprint 2 Phase 1 - Auth Core Complete
 Implemented:
- Password hashing with bcrypt (salt rounds = 10)
- JWT token generation (access 15m, refresh 7d)
- Updated login endpoint to return access + refresh tokens
- Added refresh and logout endpoints
- Updated seed script with hashed passwords
- Added test users for all roles (OWNER, MANAGER, GROWER, STAFF)

📝 Files Added/Modified:
- backend/src/utils/password.ts (NEW)
- backend/src/utils/jwt.ts (NEW)
- backend/src/controllers/auth.controller.ts (UPDATED)
- backend/src/routes/auth.routes.ts (UPDATED)
- backend/prisma/seed.js (UPDATED - now hashes passwords)
- CREDENTIALS.md (UPDATED - all test users documented)

🔐 Test Users:
- admin@runfoo.run (OWNER)
- manager@runfoo.run (MANAGER)
- grower@runfoo.run (GROWER)
- staff@runfoo.run (STAFF)
All passwords: password123

⏭️ Next: Auth middleware + RBAC
2025-12-09 13:52:54 -08:00

38 lines
834 B
TypeScript

import jwt from 'jsonwebtoken';
const JWT_SECRET = process.env.JWT_SECRET || 'supersecret';
export interface TokenPayload {
userId: string;
email: string;
role: string;
}
/**
* Generate an access token (short-lived)
*/
export function generateAccessToken(payload: TokenPayload): string {
return jwt.sign(payload, JWT_SECRET, {
expiresIn: '15m',
});
}
/**
* Generate a refresh token (long-lived)
*/
export function generateRefreshToken(payload: TokenPayload): string {
return jwt.sign(payload, JWT_SECRET, {
expiresIn: '7d',
});
}
/**
* Verify and decode a token
*/
export function verifyToken(token: string): TokenPayload {
try {
return jwt.verify(token, JWT_SECRET) as TokenPayload;
} catch (error) {
throw new Error('Invalid or expired token');
}
}