1import { ROLE_DEFINITIONS, isFullAccessRole, normalizeRole } from "../permissions.js?v=0.1.821"; 2 3export function cloneRoleDefinitions() { 4 return ROLE_DEFINITIONS.map((role) => ({ 5 ...role, 6 defaultPermissions: role.defaultPermissions.map((permission) => ({ ...permission })) 7 })); 8} 9 10function normalizePermission(permission) { 11 return { 12 moduleId: String(permission?.moduleId || ""), 13 action: String(permission?.action || "view"), 14 allowed: permission?.allowed !== false 15 }; 16} 17 18export function normalizeRoleDefinition(role) { 19 const roleId = normalizeRole(role?.id || role?.name); 20 const fallback = ROLE_DEFINITIONS.find((item) => item.id === roleId) || ROLE_DEFINITIONS.at(-1); 21 const defaultPermissions = isFullAccessRole({ role: roleId, active: true }) 22 ? fallback.defaultPermissions.map((permission) => ({ ...permission })) 23 : Array.isArray(role?.defaultPermissions) 24 ? role.defaultPermissions.map(normalizePermission) 25 : fallback.defaultPermissions.map((permission) => ({ ...permission })); 26 27 return { 28 id: normalizeRole(role?.id || role?.name || fallback.id), 29 name: normalizeRole(role?.name || role?.id || fallback.name), 30 label: String(role?.label || fallback.label), 31 description: String(role?.description || fallback.description), 32 defaultPermissions 33 }; 34} 35 36export function normalizeAccessUser(user) { 37 const active = user?.active === false || String(user?.status || "").toLowerCase() === "disabled" 38 ? false 39 : true; 40 41 return { 42 id: String(user?.id || ""), 43 name: String(user?.name || ""), 44 email: String(user?.email || ""), 45 phone: String(user?.phone || ""), 46 role: normalizeRole(user?.role || "readonly"), 47 department: String(user?.department || ""), 48 position: String(user?.position || ""), 49 managerId: String(user?.managerId || ""), 50 managerName: String(user?.managerName || ""), 51 active, 52 status: active ? "active" : "disabled", 53 permissions: Array.isArray(user?.permissions) ? user.permissions.map(normalizePermission) : [], 54 modules: Array.isArray(user?.modules) ? [...user.modules] : undefined, 55 allowedModules: Array.isArray(user?.allowedModules) ? [...user.allowedModules] : undefined, 56 deniedModules: Array.isArray(user?.deniedModules) ? [...user.deniedModules] : undefined, 57 createdAt: user?.createdAt || new Date().toISOString(), 58 updatedAt: user?.updatedAt || new Date().toISOString(), 59 lastLoginAt: user?.lastLoginAt || null 60 }; 61} 62 63export function defaultAccessState() { 64 return { 65 users: [], 66 roles: cloneRoleDefinitions(), 67 selectedUserId: "", 68 selectedRoleId: "ridic", 69 message: "", 70 error: "", 71 feedbackTarget: "" 72 }; 73} 74 75export function loadAccessState() { 76 return defaultAccessState(); 77} 78 79export function saveAccessState(state) { 80 return { 81 ...defaultAccessState(), 82 ...state, 83 users: Array.isArray(state.users) ? state.users.map(normalizeAccessUser) : [], 84 roles: Array.isArray(state.roles) ? state.roles.map(normalizeRoleDefinition) : cloneRoleDefinitions() 85 }; 86} 87 88function userKey(user) { 89 const email = String(user?.email || "").trim().toLowerCase(); 90 return email || String(user?.id || "").trim().toLowerCase(); 91} 92 93function userId(user) { 94 return String(user?.id || "").trim().toLowerCase(); 95} 96 97export function mergeAccessUsers(baseUsers, accessUsers) { 98 const users = new Map(); 99 const idToKey = new Map(); 100 101 function upsert(user) { 102 const normalized = normalizeAccessUser(user); 103 const key = userKey(normalized); 104 const id = userId(normalized); 105 106 if (!key && !id) { 107 return; 108 } 109 110 const existingKey = (key && users.has(key) ? key : "") || (id ? idToKey.get(id) : ""); 111 const nextUser = existingKey ? { ...users.get(existingKey), ...normalized } : normalized; 112 const nextKey = userKey(nextUser) || key || id; 113 114 if (existingKey && existingKey !== nextKey) { 115 users.delete(existingKey); 116 } 117 118 users.set(nextKey, nextUser); 119 if (id) { 120 idToKey.set(id, nextKey); 121 } 122 } 123 124 baseUsers.forEach(upsert); 125 accessUsers.forEach(upsert); 126 127 return [...users.values()].sort((a, b) => a.name.localeCompare(b.name, "cs")); 128} 129 130export function rolePermissionContext(roles) { 131 return Object.fromEntries(roles.map((role) => [ 132 role.id, 133 role.defaultPermissions.map((permission) => ({ ...permission })) 134 ])); 135} 136 137export function withAccessContext(user, accessState) { 138 if (!user) { 139 return null; 140 } 141 142 const normalizedUser = normalizeAccessUser(user); 143 const mergedUsers = mergeAccessUsers([normalizedUser], accessState.users); 144 const normalizedEmail = normalizedUser.email.trim().toLowerCase(); 145 const normalizedId = normalizedUser.id.trim().toLowerCase(); 146 const merged = mergedUsers.find((item) => ( 147 (normalizedEmail && item.email.trim().toLowerCase() === normalizedEmail) || 148 (normalizedId && item.id.trim().toLowerCase() === normalizedId) 149 )) || normalizedUser; 150 151 return { 152 ...merged, 153 rolePermissions: rolePermissionContext(accessState.roles) 154 }; 155} 156 157export function permissionMap(permissions) { 158 const map = new Map(); 159 permissions.forEach((permission) => { 160 map.set(`${permission.moduleId}:${permission.action}`, permission.allowed !== false); 161 }); 162 return map; 163} 164 165export function rolePermissionsFor(roleId, roles) { 166 const role = roles.find((item) => item.id === normalizeRole(roleId)); 167 return role ? role.defaultPermissions.map((permission) => ({ ...permission })) : []; 168} 169
170export function makePermissionsFromMatrix(moduleItems, actions, formData, prefix) { 171 const permissions = []; 172 173 moduleItems.forEach((moduleItem) => { 174 actions.forEach((action) => { 175 permissions.push({ 176 moduleId: moduleItem.id, 177 action, 178 allowed: formData.get(`${prefix}-${moduleItem.id}-${action}`) === "on" 179 }); 180 }); 181 }); 182 183 return permissions; 184}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.