/** * 단순화된 페이지 권한 관리 시스템 * admin/user 구조에서 페이지별 접근 권한을 관리 */ class PagePermissionManager { constructor() { this.currentUser = null; this.pagePermissions = new Map(); this.defaultPages = this.initDefaultPages(); } /** * 기본 페이지 목록 초기화 */ initDefaultPages() { return { 'issues_create': { title: '부적합 등록', defaultAccess: true }, 'issues_view': { title: '부적합 조회', defaultAccess: true }, 'issues_manage': { title: '부적합 관리', defaultAccess: true }, 'issues_inbox': { title: '수신함', defaultAccess: true }, 'issues_management': { title: '관리함', defaultAccess: false }, 'issues_archive': { title: '폐기함', defaultAccess: false }, 'issues_dashboard': { title: '현황판', defaultAccess: true }, 'projects_manage': { title: '프로젝트 관리', defaultAccess: false }, 'daily_work': { title: '일일 공수', defaultAccess: false }, 'reports': { title: '보고서', defaultAccess: false }, 'users_manage': { title: '사용자 관리', defaultAccess: false } }; } /** * 사용자 설정 * @param {Object} user - 사용자 객체 */ setUser(user) { this.currentUser = user; this.loadPagePermissions(); } /** * 사용자별 페이지 권한 로드 */ async loadPagePermissions() { if (!this.currentUser) return; try { // API에서 사용자별 페이지 권한 가져오기 const apiUrl = window.API_BASE_URL || (() => { const hostname = window.location.hostname; if (hostname === 'm.hyungi.net') { return 'https://m-api.hyungi.net/api'; } return '/api'; })(); const response = await fetch(`${apiUrl}/users/${this.currentUser.id}/page-permissions`, { headers: { 'Authorization': `Bearer ${localStorage.getItem('access_token')}` } }); if (response.ok) { const pagePermissions = await response.json(); this.pagePermissions.clear(); // 기존 권한 초기화 pagePermissions.forEach(perm => { this.pagePermissions.set(perm.page_name, perm.can_access); }); console.log('페이지 권한 로드 완료:', this.pagePermissions); } else { console.warn('페이지 권한 로드 실패, 기본 권한 사용'); } } catch (error) { console.warn('페이지 권한 로드 실패, 기본 권한 사용:', error); } } /** * 페이지 접근 권한 체크 * @param {string} pageName - 체크할 페이지명 * @returns {boolean} 접근 권한 여부 */ canAccessPage(pageName) { if (!this.currentUser) return false; // admin은 모든 페이지 접근 가능 if (this.currentUser.role === 'admin') { return true; } // 개별 페이지 권한이 설정되어 있으면 우선 적용 if (this.pagePermissions.has(pageName)) { return this.pagePermissions.get(pageName); } // 기본 권한 확인 const pageConfig = this.defaultPages[pageName]; return pageConfig ? pageConfig.defaultAccess : false; } /** * UI 요소 페이지 권한 제어 * @param {string} selector - CSS 선택자 * @param {string} pageName - 필요한 페이지 권한 * @param {string} action - 'show'|'hide'|'disable'|'enable' */ controlElement(selector, pageName, action = 'show') { const elements = document.querySelectorAll(selector); const hasAccess = this.canAccessPage(pageName); elements.forEach(element => { switch (action) { case 'show': element.style.display = hasAccess ? '' : 'none'; break; case 'hide': element.style.display = hasAccess ? 'none' : ''; break; case 'disable': element.disabled = !hasAccess; if (!hasAccess) { element.classList.add('opacity-50', 'cursor-not-allowed'); } break; case 'enable': element.disabled = hasAccess; if (hasAccess) { element.classList.remove('opacity-50', 'cursor-not-allowed'); } break; } }); } /** * 메뉴 구성 생성 * @returns {Array} 페이지 권한에 따른 메뉴 구성 */ getMenuConfig() { const menuItems = [ { id: 'issues_create', title: '부적합 등록', icon: 'fas fa-plus-circle', path: '#issues/create', pageName: 'issues_create' }, { id: 'issues_view', title: '부적합 조회', icon: 'fas fa-search', path: '#issues/view', pageName: 'issues_view' }, { id: 'issues_manage', title: '부적합 관리', icon: 'fas fa-tasks', path: '#issues/manage', pageName: 'issues_manage' }, { id: 'projects_manage', title: '프로젝트 관리', icon: 'fas fa-folder-open', path: '#projects/manage', pageName: 'projects_manage' }, { id: 'daily_work', title: '일일 공수', icon: 'fas fa-calendar-check', path: '#daily-work', pageName: 'daily_work' }, { id: 'reports', title: '보고서', icon: 'fas fa-chart-bar', path: '#reports', pageName: 'reports' }, { id: 'users_manage', title: '사용자 관리', icon: 'fas fa-users-cog', path: '#users/manage', pageName: 'users_manage' } ]; // 페이지 권한에 따라 메뉴 필터링 return menuItems.filter(item => this.canAccessPage(item.pageName)); } /** * 페이지 권한 부여 * @param {number} userId - 사용자 ID * @param {string} pageName - 페이지명 * @param {boolean} canAccess - 접근 허용 여부 * @param {string} notes - 메모 */ async grantPageAccess(userId, pageName, canAccess, notes = '') { if (this.currentUser.role !== 'admin') { throw new Error('관리자만 권한을 설정할 수 있습니다.'); } try { const apiUrl = window.API_BASE_URL || (() => { const hostname = window.location.hostname; const protocol = window.location.protocol; const port = window.location.port; if ((hostname === 'localhost' || hostname === '127.0.0.1') && port) { return `${protocol}//${hostname}:${port}/api`; } if (hostname === 'm.hyungi.net') { return 'https://m-api.hyungi.net/api'; } return '/api'; })(); const response = await fetch(`${apiUrl}/page-permissions/grant`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${localStorage.getItem('access_token')}` }, body: JSON.stringify({ user_id: userId, page_name: pageName, can_access: canAccess, notes: notes }) }); if (!response.ok) { throw new Error('페이지 권한 설정 실패'); } return await response.json(); } catch (error) { console.error('페이지 권한 설정 오류:', error); throw error; } } /** * 사용자 페이지 권한 목록 조회 * @param {number} userId - 사용자 ID * @returns {Array} 페이지 권한 목록 */ async getUserPagePermissions(userId) { try { const apiUrl = window.API_BASE_URL || (() => { const hostname = window.location.hostname; const protocol = window.location.protocol; const port = window.location.port; if ((hostname === 'localhost' || hostname === '127.0.0.1') && port) { return `${protocol}//${hostname}:${port}/api`; } if (hostname === 'm.hyungi.net') { return 'https://m-api.hyungi.net/api'; } return '/api'; })(); const response = await fetch(`${apiUrl}/users/${userId}/page-permissions`, { headers: { 'Authorization': `Bearer ${localStorage.getItem('access_token')}` } }); if (!response.ok) { throw new Error('페이지 권한 목록 조회 실패'); } return await response.json(); } catch (error) { console.error('페이지 권한 목록 조회 오류:', error); throw error; } } /** * 모든 페이지 목록과 설명 가져오기 * @returns {Object} 페이지 목록 */ getAllPages() { return this.defaultPages; } } // 전역 페이지 권한 관리자 인스턴스 window.pagePermissionManager = new PagePermissionManager(); // 편의 함수들 window.canAccessPage = (pageName) => window.pagePermissionManager.canAccessPage(pageName); window.controlElement = (selector, pageName, action) => window.pagePermissionManager.controlElement(selector, pageName, action);