From 4dd39ceab70333e66bbf72a6ba78a6e7e41bf21c Mon Sep 17 00:00:00 2001 From: Hyungi Ahn Date: Tue, 31 Mar 2026 07:32:16 +0900 Subject: [PATCH] =?UTF-8?q?fix(tkfb):=20pageAccessRoutes=20=EB=A0=88?= =?UTF-8?q?=EA=B1=B0=EC=8B=9C=20users/roles=20=ED=85=8C=EC=9D=B4=EB=B8=94?= =?UTF-8?q?=20=E2=86=92=20sso=5Fusers=20=EC=A0=84=ED=99=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit users 테이블과 sso_users 테이블의 user_id가 다른 문제 해결. - 모든 사용자 조회를 sso_users로 전환 - admin 체크를 req.user.role(JWT)로 간소화 → DB 쿼리 제거 - POST/DELETE에 UPSERT 패턴 적용 - is_admin_only 참조 완전 제거 Co-Authored-By: Claude Opus 4.6 (1M context) --- .../api/routes/pageAccessRoutes.js | 130 ++++++------------ 1 file changed, 41 insertions(+), 89 deletions(-) diff --git a/system1-factory/api/routes/pageAccessRoutes.js b/system1-factory/api/routes/pageAccessRoutes.js index 10b8847..768ac7b 100644 --- a/system1-factory/api/routes/pageAccessRoutes.js +++ b/system1-factory/api/routes/pageAccessRoutes.js @@ -3,6 +3,11 @@ 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 @@ -11,7 +16,7 @@ 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, is_admin_only, display_order + SELECT id, page_key, page_name, page_path, category, description, display_order FROM pages ORDER BY display_order, page_name `); @@ -32,12 +37,9 @@ router.get('/users/:userId/page-access', requireAuth, async (req, res) => { const { userId } = req.params; const db = await getDb(); - // 사용자의 역할 확인 + // 사용자 조회 (sso_users) const [userRows] = await db.query(` - SELECT u.user_id, u.username, u.role_id, r.name as role_name - FROM users u - LEFT JOIN roles r ON u.role_id = r.id - WHERE u.user_id = ? + SELECT user_id, name, role FROM sso_users WHERE user_id = ? `, [userId]); if (userRows.length === 0) { @@ -46,10 +48,10 @@ router.get('/users/:userId/page-access', requireAuth, async (req, res) => { const user = userRows[0]; - // Admin/System Admin인 경우 모든 페이지 접근 가능 - if (user.role_name === 'Admin' || user.role_name === 'System Admin') { + // Admin인 경우 모든 페이지 접근 가능 + if (isAdminRole(user.role)) { const [allPages] = await db.query(` - SELECT id, page_key, page_name, page_path, category, is_admin_only + SELECT id, page_key, page_name, page_path, category FROM pages ORDER BY display_order, page_name `); @@ -60,9 +62,8 @@ router.get('/users/:userId/page-access', requireAuth, async (req, res) => { page_name: page.page_name, page_path: page.page_path, category: page.category, - is_admin_only: page.is_admin_only, can_access: true, - is_default: true // Admin은 기본적으로 모든 권한 보유 + is_default: true })); return res.json({ success: true, data: { user, pageAccess } }); @@ -70,9 +71,7 @@ router.get('/users/:userId/page-access', requireAuth, async (req, res) => { // 사용자의 부서 조회 const [workerRows] = await db.query(` - SELECT w.department_id FROM sso_users su - LEFT JOIN workers w ON su.user_id = w.user_id - WHERE su.user_id = ? + SELECT w.department_id FROM workers w WHERE w.user_id = ? `, [userId]); const departmentId = workerRows[0]?.department_id || 0; @@ -85,16 +84,13 @@ router.get('/users/:userId/page-access', requireAuth, async (req, res) => { p.page_name, p.page_path, p.category, - p.is_admin_only, COALESCE(upa.can_access, dpp.can_access, p.is_default_accessible, 0) as can_access, - upa.granted_at, - u2.username as granted_by_username + upa.granted_at FROM pages p LEFT JOIN user_page_access upa ON p.id = upa.page_id AND upa.user_id = ? LEFT JOIN department_page_permissions dpp ON dpp.department_id = ? AND (dpp.page_name = CONCAT('s1.', p.page_key) OR dpp.page_name = p.page_key) - LEFT JOIN users u2 ON upa.granted_by = u2.user_id ORDER BY p.display_order, p.page_name `, [userId, departmentId]); @@ -112,50 +108,29 @@ router.get('/users/:userId/page-access', requireAuth, async (req, res) => { */ router.post('/users/:userId/page-access', requireAuth, async (req, res) => { try { - const { userId } = req.params; - const { pageIds, canAccess } = req.body; - const adminUserId = req.user.user_id; // 권한을 부여하는 Admin의 user_id - - // Admin 권한 확인 - const db = await getDb(); - const [adminRows] = await db.query(` - SELECT u.role_id, r.name as role_name - FROM users u - LEFT JOIN roles r ON u.role_id = r.id - WHERE u.user_id = ? - `, [adminUserId]); - - if (adminRows.length === 0 || (adminRows[0].role_name !== 'Admin' && adminRows[0].role_name !== 'System Admin')) { + if (!isAdminRole(req.user.role)) { return res.status(403).json({ success: false, error: '권한이 없습니다. 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 users WHERE user_id = ?', [userId]); + 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, error: '사용자를 찾을 수 없습니다.' }); } // 페이지 접근 권한 업데이트 for (const pageId of pageIds) { - // 기존 권한 확인 - const [existing] = await db.query( - 'SELECT * FROM user_page_access WHERE user_id = ? AND page_id = ?', - [userId, pageId] - ); - - if (existing.length > 0) { - // 업데이트 - await db.query( - 'UPDATE user_page_access SET can_access = ?, granted_at = NOW(), granted_by = ? WHERE user_id = ? AND page_id = ?', - [canAccess ? 1 : 0, adminUserId, userId, pageId] - ); - } else { - // 삽입 - await db.query( - 'INSERT INTO user_page_access (user_id, page_id, can_access, granted_by) VALUES (?, ?, ?, ?)', - [userId, pageId, canAccess ? 1 : 0, adminUserId] - ); - } + 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: '페이지 접근 권한이 업데이트되었습니다.' }); @@ -171,23 +146,13 @@ router.post('/users/:userId/page-access', requireAuth, async (req, res) => { */ router.delete('/users/:userId/page-access/:pageId', requireAuth, async (req, res) => { try { - const { userId, pageId } = req.params; - const adminUserId = req.user.user_id; - - // Admin 권한 확인 - const db = await getDb(); - const [adminRows] = await db.query(` - SELECT u.role_id, r.name as role_name - FROM users u - LEFT JOIN roles r ON u.role_id = r.id - WHERE u.user_id = ? - `, [adminUserId]); - - if (adminRows.length === 0 || (adminRows[0].role_name !== 'Admin' && adminRows[0].role_name !== 'System Admin')) { + if (!isAdminRole(req.user.role)) { return res.status(403).json({ success: false, error: '권한이 없습니다.' }); } - // 접근 권한 삭제 + 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] @@ -206,36 +171,23 @@ router.delete('/users/:userId/page-access/:pageId', requireAuth, async (req, res */ router.get('/page-access/summary', requireAuth, async (req, res) => { try { - const adminUserId = req.user.user_id; - - // Admin 권한 확인 - const db = await getDb(); - const [adminRows] = await db.query(` - SELECT u.role_id, r.name as role_name - FROM users u - LEFT JOIN roles r ON u.role_id = r.id - WHERE u.user_id = ? - `, [adminUserId]); - - if (adminRows.length === 0 || (adminRows[0].role_name !== 'Admin' && adminRows[0].role_name !== 'System Admin')) { + if (!isAdminRole(req.user.role)) { return res.status(403).json({ success: false, error: '권한이 없습니다.' }); } - // 모든 사용자와 페이지 권한 조회 + const db = await getDb(); const [summary] = await db.query(` SELECT - u.user_id, - u.username, - u.name, - r.name as role_name, + 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 users u - LEFT JOIN roles r ON u.role_id = r.id - LEFT JOIN user_page_access upa ON u.user_id = upa.user_id AND upa.can_access = 1 - WHERE r.name NOT IN ('Admin', 'System Admin') - GROUP BY u.user_id, u.username, u.name, r.name - ORDER BY u.username + 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 });