# All files / utils access.js

0% Statements 0/40
0% Branches 0/31
0% Functions 0/12
0% Lines 0/38

Press n or j to go to the next uncovered block, b, p or k for the previous block.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178

     /**
     * @deprecated 이 파일의 미들웨어 함수들은 하위 호환성을 위해 유지됩니다.
     * 새로운 코드에서는 '../middlewares/auth'를 사용하세요.
     */

    // utils/access.js - 유틸리티 함수와 레거시 호환성
    const ACCESS_LEVELS = {
      worker: 1,
      group_leader: 2,
      support_team: 3,
      admin: 4,
      system: 5
    };

    const ACCESS_LEVEL_NAMES = {
      worker: '작업자',
      group_leader: '그룹장',
      support_team: '지원팀',
      admin: '관리자',
      system: '시스템'
    };

    /**
     * 권한 레벨 비교 (유틸리티 함수)
     * @param {string} userLevel - 사용자의 권한 레벨
     * @param {string} requiredLevel - 필요한 권한 레벨
     * @returns {boolean} - 권한 여부
     */
    const hasPermission = (userLevel, requiredLevel) => {
      const userOrder = ACCESS_LEVELS[userLevel] || 0;
      const requiredOrder = ACCESS_LEVELS[requiredLevel] || 999;
      return userOrder >= requiredOrder;
    };

    /**
     * 권한 레벨을 숫자로 변환
     * @param {string} level - 권한 레벨 문자열
     * @returns {number} - 권한 레벨 숫자
     */
    const getLevelNumber = (level) => {
      return ACCESS_LEVELS[level] || 0;
    };

    /**
     * 권한 레벨을 한글명으로 변환
     * @param {string} level - 권한 레벨 문자열
     * @returns {string} - 한글 권한명
     */
    const getLevelName = (level) => {
      return ACCESS_LEVEL_NAMES[level] || '알 수 없음';
    };

    /**
     * 사용자가 특정 권한들 중 하나라도 가지고 있는지 확인
     * @param {string} userLevel - 사용자의 권한 레벨
     * @param {string[]} allowedLevels - 허용된 권한 레벨들
     * @returns {boolean} - 권한 여부
     */
    const hasAnyPermission = (userLevel, allowedLevels) => {
      return allowedLevels.some(level => hasPermission(userLevel, level));
    };

    /**
     * 모든 권한 레벨 목록 반환
     * @returns {string[]} - 권한 레벨 배열
     */
    const getAllLevels = () => {
      return Object.keys(ACCESS_LEVELS);
    };

    /**
     * 특정 권한 레벨 이상의 모든 권한 반환
     * @param {string} minLevel - 최소 권한 레벨
     * @returns {string[]} - 해당 레벨 이상의 권한들
     */
    const getLevelsAbove = (minLevel) => {
      const minOrder = ACCESS_LEVELS[minLevel] || 0;
      return Object.keys(ACCESS_LEVELS).filter(level => ACCESS_LEVELS[level] >= minOrder);
    };

    // ===== 프론트엔드용 권한 체크 함수들 =====

    /**
     * 페이지 접근 권한 체크 (프론트엔드에서 사용)
     * @param {string} userLevel - 사용자 권한
     * @param {object} pageConfig - 페이지 설정 {minLevel?, allowedRoles?, deniedRoles?}
     * @returns {boolean} - 접근 가능 여부
     */
    const canAccessPage = (userLevel, pageConfig) => {
      const { minLevel, allowedRoles, deniedRoles = [] } = pageConfig;

      // 거부 목록 체크
      if (deniedRoles.includes(userLevel)) {
        return false;
      }

      // 허용 목록 체크
      if (allowedRoles && allowedRoles.length > 0) {
        return allowedRoles.includes(userLevel);
      }

      // 최소 레벨 체크
      if (minLevel) {
        return hasPermission(userLevel, minLevel);
      }

      return true;
    };

    /**
     * CRUD 권한 체크 (프론트엔드에서 사용)
     * @param {string} userLevel - 사용자 권한
     * @param {string} table - 테이블명
     * @param {string} action - 액션 (CREATE, READ, UPDATE, DELETE)
     * @returns {boolean} - 권한 여부
     */
    const canPerformAction = (userLevel, table, action) => {
      // 기본적으로 모든 인증된 사용자에게 권한 부여
      // 특별한 제한이 필요한 경우에만 여기서 체크

      // 예시: 사용자 관리는 admin 이상만
      if (table === 'Users' && ['CREATE', 'UPDATE', 'DELETE'].includes(action)) {
        return hasPermission(userLevel, 'admin');
      }

      // 예시: 시스템 테이블은 system만
      if (table === 'SystemConfig') {
        return hasPermission(userLevel, 'system');
      }

      // 나머지는 모든 인증된 사용자에게 허용
      return userLevel && userLevel !== 'anonymous';
    };

    // ===== 레거시 호환성: 미들웨어 함수 =====

    /**
     * @deprecated 이 미들웨어는 하위 호환성을 위해 유지됩니다.
     * 새로운 코드에서는 '../middlewares/auth'의 requireRole을 사용하세요.
     *
     * @example
     * // 이전 방식 (deprecated)
     * const { requireAccess } = require('../utils/access');
     * router.get('/admin', requireAccess('admin'), handler);
     *
     * // 새로운 방식 (권장)
     * const { requireAuth, requireRole } = require('../middlewares/auth');
     * router.get('/admin', requireAuth, requireRole('admin'), handler);
     */
    const requireAccess = (...allowed) => {
      return (req, res, next) => {
        if (!req.user || !allowed.includes(req.user.access_level)) {
          return res.status(403).json({ error: '접근 권한이 없습니다' });
        }
        next();
      };
    };

    module.exports = {
      // 기본 유틸리티 함수들
      hasPermission,
      getLevelNumber,
      getLevelName,
      hasAnyPermission,
      getAllLevels,
      getLevelsAbove,

      // 프론트엔드용 함수들
      canAccessPage,
      canPerformAction,

      // 레거시 호환성 (deprecated)
      requireAccess,

      // 상수들
      ACCESS_LEVELS,
      ACCESS_LEVEL_NAMES
    };