import { Router, Response, NextFunction } from 'express'; import { authService } from '../services/authService'; import { AuthenticatedRequest, authMiddleware } from '../middleware/auth'; import { signupSchema, signinSchema, googleAuthSchema, passwordResetRequestSchema, passwordResetConfirmSchema, } from '../utils/validators'; const router = Router(); // POST /auth/signup router.post('/signup', async (req, res: Response, next: NextFunction) => { try { const { email, password, name } = signupSchema.parse(req.body); const result = await authService.signup(email, password, name); res.status(201).json(result); } catch (err) { next(err); } }); // POST /auth/signin router.post('/signin', async (req, res: Response, next: NextFunction) => { try { const { email, password } = signinSchema.parse(req.body); const result = await authService.signin(email, password); res.status(200).json(result); } catch (err: unknown) { if ( err instanceof Error && (err as { code?: string }).code === 'ACCOUNT_PENDING_DELETION' ) { const appErr = err as { code?: string; statusCode?: number; deletion_scheduled_at?: string }; res.status(403).json({ error: err.message, code: appErr.code, deletion_scheduled_at: appErr.deletion_scheduled_at, timestamp: new Date().toISOString(), }); return; } next(err); } }); // POST /auth/google router.post('/google', async (req, res: Response, next: NextFunction) => { try { const { id_token } = googleAuthSchema.parse(req.body); const result = await authService.googleAuth(id_token); const statusCode = result.is_new_user ? 201 : 200; res.status(statusCode).json(result); } catch (err: unknown) { if ( err instanceof Error && (err as { code?: string }).code === 'ACCOUNT_PENDING_DELETION' ) { const appErr = err as { code?: string; statusCode?: number; deletion_scheduled_at?: string }; res.status(403).json({ error: err.message, code: appErr.code, deletion_scheduled_at: appErr.deletion_scheduled_at, timestamp: new Date().toISOString(), }); return; } next(err); } }); // POST /auth/password-reset router.post('/password-reset', async (req, res: Response, next: NextFunction) => { try { const { email } = passwordResetRequestSchema.parse(req.body); await authService.requestPasswordReset(email); res.status(200).json({ message: 'If an account exists with this email, a reset link has been sent.', timestamp: new Date().toISOString(), }); } catch (err) { next(err); } }); // PUT /auth/password-reset router.put('/password-reset', async (req, res: Response, next: NextFunction) => { try { const { token, new_password } = passwordResetConfirmSchema.parse(req.body); await authService.confirmPasswordReset(token, new_password); res.status(200).json({ message: 'Password updated successfully.', timestamp: new Date().toISOString(), }); } catch (err) { next(err); } }); // DELETE /auth/account (protected) router.delete( '/account', authMiddleware, async (req: AuthenticatedRequest, res: Response, next: NextFunction) => { try { await authService.deleteAccount(req.userId!); res.status(204).send(); } catch (err) { next(err); } } ); // POST /auth/restore-account (protected) router.post( '/restore-account', authMiddleware, async (req: AuthenticatedRequest, res: Response, next: NextFunction) => { try { const user = await authService.restoreAccount(req.userId!); res.status(200).json({ user, message: 'Account restored successfully.', timestamp: new Date().toISOString(), }); } catch (err) { next(err); } } ); export default router;