const express = require('express'); const bcrypt = require('bcrypt'); const jwt = require('jsonwebtoken'); const { query } = require('../db'); const router = express.Router(); // JWT 시크릿 (환경변수에서 가져오거나 기본값 사용) const JWT_SECRET = process.env.JWT_SECRET || 'your-secret-key-change-this-in-production'; // 회원가입 router.post('/register', async (req, res) => { try { const { email, password, name } = req.body; // 이메일 중복 확인 const existingUser = await query('SELECT id FROM users WHERE email = $1', [email]); if (existingUser.rows.length > 0) { return res.status(400).json({ success: false, message: '이미 사용 중인 이메일입니다' }); } // 비밀번호 해시 const saltRounds = 10; const passwordHash = await bcrypt.hash(password, saltRounds); // 사용자 생성 const result = await query( 'INSERT INTO users (email, password_hash, name) VALUES ($1, $2, $3) RETURNING id, email, name, role, created_at', [email, passwordHash, name] ); const user = result.rows[0]; // JWT 토큰 생성 const token = jwt.sign( { userId: user.id, email: user.email, role: user.role }, JWT_SECRET, { expiresIn: '7d' } ); res.json({ success: true, user: { id: user.id, email: user.email, name: user.name, role: user.role, created_at: user.created_at }, token, message: '회원가입이 완료되었습니다' }); } catch (error) { console.error('Registration error:', error); res.status(500).json({ success: false, message: '회원가입 중 오류가 발생했습니다' }); } }); // 로그인 router.post('/login', async (req, res) => { try { const { email, password } = req.body; // 사용자 조회 const result = await query( 'SELECT id, email, password_hash, name, role, is_active FROM users WHERE email = $1', [email] ); if (result.rows.length === 0) { return res.status(400).json({ success: false, message: '등록되지 않은 이메일입니다' }); } const user = result.rows[0]; if (!user.is_active) { return res.status(400).json({ success: false, message: '비활성화된 계정입니다' }); } // 비밀번호 확인 const isValidPassword = await bcrypt.compare(password, user.password_hash); if (!isValidPassword) { return res.status(400).json({ success: false, message: '비밀번호가 올바르지 않습니다' }); } // 마지막 로그인 시간 업데이트 await query('UPDATE users SET last_login = CURRENT_TIMESTAMP WHERE id = $1', [user.id]); // JWT 토큰 생성 const token = jwt.sign( { userId: user.id, email: user.email, role: user.role }, JWT_SECRET, { expiresIn: '7d' } ); res.json({ success: true, user: { id: user.id, email: user.email, name: user.name, role: user.role, is_active: user.is_active }, token, message: '로그인되었습니다' }); } catch (error) { console.error('Login error:', error); res.status(500).json({ success: false, message: '로그인 중 오류가 발생했습니다' }); } }); // 토큰 검증 router.get('/verify', authenticateToken, async (req, res) => { try { const result = await query( 'SELECT id, email, name, role, is_active, last_login FROM users WHERE id = $1', [req.user.userId] ); if (result.rows.length === 0) { return res.status(404).json({ success: false, message: '사용자를 찾을 수 없습니다' }); } const user = result.rows[0]; if (!user.is_active) { return res.status(403).json({ success: false, message: '비활성화된 계정입니다' }); } res.json({ success: true, user: { id: user.id, email: user.email, name: user.name, role: user.role, is_active: user.is_active, last_login: user.last_login } }); } catch (error) { console.error('Token verification error:', error); res.status(500).json({ success: false, message: '토큰 검증 중 오류가 발생했습니다' }); } }); // JWT 토큰 인증 미들웨어 function authenticateToken(req, res, next) { const authHeader = req.headers['authorization']; const token = authHeader && authHeader.split(' ')[1]; if (!token) { return res.status(401).json({ success: false, message: '액세스 토큰이 필요합니다' }); } jwt.verify(token, JWT_SECRET, (err, user) => { if (err) { return res.status(403).json({ success: false, message: '유효하지 않은 토큰입니다' }); } req.user = user; next(); }); } // 관리자 권한 확인 미들웨어 function requireAdmin(req, res, next) { if (req.user.role !== 'admin') { return res.status(403).json({ success: false, message: '관리자 권한이 필요합니다' }); } next(); } module.exports = { router, authenticateToken, requireAdmin };