import { FastifyRequest, FastifyReply } from 'fastify'; import { comparePassword } from '../utils/password'; import { generateAccessToken, generateRefreshToken, verifyToken } from '../utils/jwt'; export const login = async (request: FastifyRequest, reply: FastifyReply) => { const { email, password } = request.body as any; if (!email || !password) { return reply.code(400).send({ message: 'Email and password required' }); } const user = await request.server.prisma.user.findUnique({ where: { email } }); if (!user) { return reply.code(401).send({ message: 'Invalid credentials' }); } // Compare password with bcrypt const isValid = await comparePassword(password, user.passwordHash); if (!isValid) { return reply.code(401).send({ message: 'Invalid credentials' }); } // Generate tokens const payload = { userId: user.id, email: user.email, role: user.role }; const accessToken = generateAccessToken(payload); const refreshToken = generateRefreshToken(payload); // TODO: Store refresh token in Redis for invalidation on logout return { accessToken, refreshToken, user: { id: user.id, email: user.email, name: user.name, role: user.role } }; }; export const refresh = async (request: FastifyRequest, reply: FastifyReply) => { const { refreshToken } = request.body as any; if (!refreshToken) { return reply.code(400).send({ message: 'Refresh token required' }); } try { // Verify refresh token const payload = verifyToken(refreshToken); // TODO: Check if refresh token is in Redis (not revoked) // Generate new access token const newAccessToken = generateAccessToken({ userId: payload.userId, email: payload.email, role: payload.role }); return { accessToken: newAccessToken }; } catch (error) { return reply.code(401).send({ message: 'Invalid or expired refresh token' }); } }; export const logout = async (request: FastifyRequest, reply: FastifyReply) => { // TODO: Invalidate refresh token in Redis return { message: 'Logged out successfully' }; }; export const me = async (request: FastifyRequest, reply: FastifyReply) => { try { await request.jwtVerify(); return request.user; } catch (err) { reply.send(err); } };