Files
eene_dashboard/backend/src/routes/auth.ts
EENE Dashboard 22366dde72 Initial commit - EENE Dashboard
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-29 18:07:10 +09:00

71 lines
2.0 KiB
TypeScript

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;