import { Router, Request, Response } from 'express'; import { z } from 'zod'; import db from '../db'; import { hashPassword, comparePassword, generateToken, validateEmail, validatePassword, } from '../utils/auth'; const router = Router(); const registerSchema = z.object({ email: z.string().email(), password: z.string().min(8), }); const loginSchema = z.object({ email: z.string().email(), password: z.string(), }); // Register router.post('/register', async (req: Request, res: Response): Promise => { try { const { email, password } = registerSchema.parse(req.body); if (!validateEmail(email)) { res.status(400).json({ error: 'invalid_email', message: 'Invalid email format', }); return; } const passwordValidation = validatePassword(password); if (!passwordValidation.valid) { res.status(400).json({ error: 'invalid_password', message: 'Password does not meet requirements', details: passwordValidation.errors, }); return; } const existingUser = await db.users.findByEmail(email); if (existingUser) { res.status(409).json({ error: 'user_exists', message: 'User with this email already exists', }); return; } const passwordHash = await hashPassword(password); const user = await db.users.create(email, passwordHash); const token = generateToken(user); res.status(201).json({ token, user: { id: user.id, email: user.email, plan: user.plan, createdAt: user.createdAt, }, }); } catch (error) { if (error instanceof z.ZodError) { res.status(400).json({ error: 'validation_error', message: 'Invalid input', details: error.errors, }); return; } console.error('Register error:', error); res.status(500).json({ error: 'server_error', message: 'Failed to register user', }); } }); // Login router.post('/login', async (req: Request, res: Response): Promise => { try { const { email, password } = loginSchema.parse(req.body); const user = await db.users.findByEmail(email); if (!user) { res.status(401).json({ error: 'invalid_credentials', message: 'Invalid email or password', }); return; } const isValidPassword = await comparePassword(password, user.passwordHash); if (!isValidPassword) { res.status(401).json({ error: 'invalid_credentials', message: 'Invalid email or password', }); return; } await db.users.updateLastLogin(user.id); const token = generateToken(user); res.json({ token, user: { id: user.id, email: user.email, plan: user.plan, createdAt: user.createdAt, lastLoginAt: new Date(), }, }); } catch (error) { if (error instanceof z.ZodError) { res.status(400).json({ error: 'validation_error', message: 'Invalid input', details: error.errors, }); return; } console.error('Login error:', error); res.status(500).json({ error: 'server_error', message: 'Failed to login', }); } }); export default router;