const express = require('express'); const router = express.Router(); const { getDb } = require('../dbPool'); const { requireAuth, requireAdmin } = require('../middlewares/auth'); // Admin 역할 확인 헬퍼 function isAdminRole(role) { return ['admin', 'system'].includes((role || '').toLowerCase()); } /** * 모든 페이지 목록 조회 * GET /api/pages */ router.get('/pages', requireAuth, async (req, res) => { try { const db = await getDb(); const [pages] = await db.query(` SELECT id, page_key, page_name, page_path, category, description, display_order FROM pages ORDER BY display_order, page_name `); res.json({ success: true, data: pages }); } catch (error) { console.error('페이지 목록 조회 오류:', error); res.status(500).json({ success: false, message: '페이지 목록을 불러오는데 실패했습니다.' }); } }); /** * 특정 사용자의 페이지 접근 권한 조회 * GET /api/users/:userId/page-access */ router.get('/users/:userId/page-access', requireAuth, async (req, res) => { try { const { userId } = req.params; const db = await getDb(); // 사용자 조회 (sso_users) const [userRows] = await db.query(` SELECT user_id, name, role FROM sso_users WHERE user_id = ? `, [userId]); if (userRows.length === 0) { return res.status(404).json({ success: false, message: '사용자를 찾을 수 없습니다.' }); } const user = userRows[0]; // Admin인 경우 모든 페이지 접근 가능 if (isAdminRole(user.role)) { const [allPages] = await db.query(` SELECT id, page_key, page_name, page_path, category FROM pages ORDER BY display_order, page_name `); const pageAccess = allPages.map(page => ({ page_id: page.id, page_key: page.page_key, page_name: page.page_name, page_path: page.page_path, category: page.category, can_access: true, is_default: true })); return res.json({ success: true, data: { user, pageAccess } }); } // 사용자의 부서 조회 const [workerRows] = await db.query(` SELECT w.department_id FROM workers w WHERE w.user_id = ? `, [userId]); const departmentId = workerRows[0]?.department_id || 0; // 일반 사용자의 페이지 접근 권한 조회 // department_page_permissions.page_name은 's1.' 접두사 사용, pages.page_key는 접두사 없음 const [pageAccess] = await db.query(` SELECT p.id as page_id, p.page_key, p.page_name, p.page_path, p.category, COALESCE(upp.can_access, dpp.can_access, p.is_default_accessible, 0) as can_access, upp.granted_at FROM pages p LEFT JOIN user_page_permissions upp ON upp.user_id = ? AND (upp.page_name COLLATE utf8mb4_general_ci = CONCAT('s1.', p.page_key) OR upp.page_name COLLATE utf8mb4_general_ci = p.page_key) LEFT JOIN department_page_permissions dpp ON dpp.department_id = ? AND (dpp.page_name COLLATE utf8mb4_general_ci = CONCAT('s1.', p.page_key) OR dpp.page_name COLLATE utf8mb4_general_ci = p.page_key) ORDER BY p.display_order, p.page_name `, [userId, departmentId]); res.json({ success: true, data: { user, pageAccess } }); } catch (error) { console.error('페이지 접근 권한 조회 오류:', error); res.status(500).json({ success: false, message: '페이지 접근 권한을 불러오는데 실패했습니다.' }); } }); /** * 사용자에게 페이지 접근 권한 부여/회수 * POST /api/users/:userId/page-access * Body: { pageIds: [1, 2, 3], canAccess: true } */ router.post('/users/:userId/page-access', requireAuth, async (req, res) => { try { if (!isAdminRole(req.user.role)) { return res.status(403).json({ success: false, message: '권한이 없습니다. Admin 계정만 사용자 권한을 관리할 수 있습니다.' }); } const { userId } = req.params; const { pageIds, canAccess } = req.body; const adminUserId = req.user.user_id; const db = await getDb(); // 사용자 존재 확인 const [userRows] = await db.query('SELECT user_id FROM sso_users WHERE user_id = ?', [userId]); if (userRows.length === 0) { return res.status(404).json({ success: false, message: '사용자를 찾을 수 없습니다.' }); } // 페이지 접근 권한 업데이트 for (const pageId of pageIds) { await db.query(` INSERT INTO user_page_access (user_id, page_id, can_access, granted_by) VALUES (?, ?, ?, ?) ON DUPLICATE KEY UPDATE can_access = ?, granted_at = NOW(), granted_by = ? `, [userId, pageId, canAccess ? 1 : 0, adminUserId, canAccess ? 1 : 0, adminUserId]); } res.json({ success: true, message: '페이지 접근 권한이 업데이트되었습니다.' }); } catch (error) { console.error('페이지 접근 권한 부여 오류:', error); res.status(500).json({ success: false, message: '페이지 접근 권한을 업데이트하는데 실패했습니다.' }); } }); /** * 특정 페이지의 접근 권한 회수 * DELETE /api/users/:userId/page-access/:pageId */ router.delete('/users/:userId/page-access/:pageId', requireAuth, async (req, res) => { try { if (!isAdminRole(req.user.role)) { return res.status(403).json({ success: false, message: '권한이 없습니다.' }); } const { userId, pageId } = req.params; const db = await getDb(); await db.query( 'DELETE FROM user_page_access WHERE user_id = ? AND page_id = ?', [userId, pageId] ); res.json({ success: true, message: '페이지 접근 권한이 회수되었습니다.' }); } catch (error) { console.error('페이지 접근 권한 회수 오류:', error); res.status(500).json({ success: false, message: '페이지 접근 권한을 회수하는데 실패했습니다.' }); } }); /** * 모든 사용자의 페이지 접근 권한 요약 조회 (Admin용) * GET /api/page-access/summary */ router.get('/page-access/summary', requireAuth, async (req, res) => { try { if (!isAdminRole(req.user.role)) { return res.status(403).json({ success: false, message: '권한이 없습니다.' }); } const db = await getDb(); const [summary] = await db.query(` SELECT su.user_id, su.name, su.role, COUNT(DISTINCT upa.page_id) as accessible_pages_count, (SELECT COUNT(*) FROM pages) as total_pages_count FROM sso_users su LEFT JOIN user_page_access upa ON su.user_id = upa.user_id AND upa.can_access = 1 WHERE su.role NOT IN ('admin', 'system') GROUP BY su.user_id, su.name, su.role ORDER BY su.name `); res.json({ success: true, data: summary }); } catch (error) { console.error('페이지 접근 권한 요약 조회 오류:', error); res.status(500).json({ success: false, message: '페이지 접근 권한 요약을 불러오는데 실패했습니다.' }); } }); module.exports = router;