const jwt = require('jsonwebtoken'); const mysql = require('mysql2/promise'); const JWT_SECRET = process.env.SSO_JWT_SECRET; let pool; function getPool() { if (!pool) { pool = mysql.createPool({ host: process.env.DB_HOST || 'mariadb', port: parseInt(process.env.DB_PORT) || 3306, user: process.env.DB_USER || 'hyungi_user', password: process.env.DB_PASSWORD, database: process.env.DB_NAME || 'hyungi', waitForConnections: true, connectionLimit: 5, queueLimit: 0 }); } return pool; } function extractToken(req) { const authHeader = req.headers['authorization']; if (authHeader && authHeader.startsWith('Bearer ')) { return authHeader.split(' ')[1]; } if (req.cookies && req.cookies.sso_token) { return req.cookies.sso_token; } return null; } function requireAuth(req, res, next) { const token = extractToken(req); if (!token) { return res.status(401).json({ success: false, error: '인증이 필요합니다' }); } try { const decoded = jwt.verify(token, JWT_SECRET); req.user = decoded; next(); } catch { return res.status(401).json({ success: false, error: '유효하지 않은 토큰입니다' }); } } function requireAdmin(req, res, next) { const token = extractToken(req); if (!token) { return res.status(401).json({ success: false, error: '인증이 필요합니다' }); } try { const decoded = jwt.verify(token, JWT_SECRET); if (!['admin', 'system'].includes((decoded.role || '').toLowerCase())) { return res.status(403).json({ success: false, error: '관리자 권한이 필요합니다' }); } req.user = decoded; next(); } catch { return res.status(401).json({ success: false, error: '유효하지 않은 토큰입니다' }); } } function requirePage(pageName) { return async (req, res, next) => { const userId = req.user.user_id || req.user.id; const role = (req.user.role || '').toLowerCase(); if (role === 'admin' || role === 'system') return next(); try { const db = getPool(); const [rows] = await db.query( 'SELECT can_access FROM user_page_permissions WHERE user_id = ? AND page_name = ?', [userId, pageName] ); if (rows.length > 0) { return rows[0].can_access ? next() : res.status(403).json({ success: false, error: '접근 권한이 없습니다' }); } const [userRows] = await db.query('SELECT department_id FROM sso_users WHERE user_id = ?', [userId]); if (userRows.length > 0 && userRows[0].department_id) { const [deptRows] = await db.query( 'SELECT can_access FROM department_page_permissions WHERE department_id = ? AND page_name = ?', [userRows[0].department_id, pageName] ); if (deptRows.length > 0) { return deptRows[0].can_access ? next() : res.status(403).json({ success: false, error: '접근 권한이 없습니다' }); } } return res.status(403).json({ success: false, error: '접근 권한이 없습니다' }); } catch (err) { console.error('Permission check error:', err); return res.status(500).json({ success: false, error: '권한 확인 실패' }); } }; } module.exports = { getPool, extractToken, requireAuth, requireAdmin, requirePage };