import { Router } from 'express'; import bcrypt from 'bcrypt'; import jwt from 'jsonwebtoken'; import { prisma } from '../lib/prisma'; import { authenticate } from '../middleware/auth'; import { AppError } from '../middleware/errorHandler'; const router = Router(); // POST /api/auth/login router.post('/login', async (req, res, next) => { try { const { email, password } = req.body as { email: string; password: string }; if (!email || !password) { throw new AppError(400, '이메일과 비밀번호를 입력해주세요.'); } const user = await prisma.user.findUnique({ where: { email } }); if (!user || !user.isActive) { throw new AppError(401, '이메일 또는 비밀번호가 올바르지 않습니다.'); } const isMatch = await bcrypt.compare(password, user.password); if (!isMatch) { throw new AppError(401, '이메일 또는 비밀번호가 올바르지 않습니다.'); } const token = jwt.sign( { userId: user.id, email: user.email, role: user.role }, process.env.JWT_SECRET!, { expiresIn: process.env.JWT_EXPIRES_IN || '7d' } as jwt.SignOptions, ); res.json({ token, user: { id: user.id, email: user.email, name: user.name, role: user.role, department: user.department, }, }); } catch (err) { next(err); } }); // GET /api/auth/me router.get('/me', authenticate, async (req, res, next) => { try { const user = await prisma.user.findUnique({ where: { id: req.user!.userId }, select: { id: true, email: true, name: true, role: true, department: true }, }); if (!user) throw new AppError(404, '사용자를 찾을 수 없습니다.'); res.json(user); } catch (err) { next(err); } }); // POST /api/auth/logout (클라이언트 토큰 삭제용 — 서버는 stateless) router.post('/logout', authenticate, (_req, res) => { res.json({ message: '로그아웃 되었습니다.' }); }); export default router;