/home/techb158/cosmic.abdallabala.com/src/security
NameSizeModeActions
accessControl.js121430666editdlrm
securityHeaders.js23410666editdlrm
tokenVault.js19670666editdlrm
Edit: /home/techb158/cosmic.abdallabala.com/src/security/accessControl.js (12143B)
const { list, findById, insert, update, audit } = require("../storage/jsonDatabase.js"); const PERMISSIONS = [ "project:read", "risk:read", "risk:write", "risk:delete", "mitigation:write", "gate:read", "gate:evaluate", "gate:review", "gate:approve", "report:export", "integration:read", "integration:write", "integration:sync", "oauth:manage", "user:read", "user:write", "audit:read", "metrics:write" ]; const ROLE_TEMPLATES = { "ROLE-ADMIN": { name: "System Admin", permissions: ["*"] }, "ROLE-PM": { name: "Project Manager", permissions: ["project:read", "risk:read", "risk:write", "mitigation:write", "gate:read", "gate:evaluate", "report:export", "integration:read", "integration:sync", "audit:read"] }, "ROLE-RISK-OWNER": { name: "Risk Owner", permissions: ["project:read", "risk:read", "risk:write", "mitigation:write", "gate:read"] }, "ROLE-AI-ENGINEER": { name: "AI Engineer / Data Scientist", permissions: ["project:read", "risk:read", "mitigation:write", "metrics:write", "gate:read", "report:export"] }, "ROLE-GOV-REVIEWER": { name: "Governance Reviewer", permissions: ["project:read", "risk:read", "gate:read", "gate:evaluate", "gate:review", "report:export", "audit:read"] }, "ROLE-LEGAL-ETHICS": { name: "Legal / Ethics Reviewer", permissions: ["project:read", "risk:read", "mitigation:write", "gate:read", "gate:review", "report:export", "audit:read"] }, "ROLE-INTEGRATION-ADMIN": { name: "Integration Admin", permissions: ["project:read", "integration:read", "integration:write", "integration:sync", "oauth:manage", "report:export", "audit:read"] }, "ROLE-VIEWER": { name: "Read-only Viewer", permissions: ["project:read", "risk:read", "gate:read", "integration:read", "report:export"] } }; function safeParsePermissions(value) { if (Array.isArray(value)) return value; if (!value) return []; try { const parsed = JSON.parse(value); return Array.isArray(parsed) ? parsed : []; } catch (_error) { return String(value).split(",").map(item => item.trim()).filter(Boolean); } } function unique(values) { return Array.from(new Set(values.filter(Boolean))); } function normalizePermissions(value) { const permissions = unique(safeParsePermissions(value)); if (permissions.includes("*")) return ["*"]; const unknown = permissions.filter(item => !PERMISSIONS.includes(item)); if (unknown.length) throw new Error(`Unknown permission(s): ${unknown.join(", ")}`); return permissions; } function toRoleView(row) { return { id: row.id, name: row.name, permissions: normalizePermissions(row.permissions_json), description: row.description || "", createdAt: row.created_at, updatedAt: row.updated_at }; } function toUserView(database, row) { const role = findById(database, "roles", row.role_id); const roleView = role ? toRoleView(role) : null; return { id: row.id, displayName: row.display_name, email: row.email, roleId: row.role_id, roleName: roleView ? roleView.name : "Unknown role", permissions: roleView ? roleView.permissions : [], active: row.active !== false, createdAt: row.created_at, updatedAt: row.updated_at }; } class AuthorizationError extends Error { constructor(message, details = {}) { super(message); this.name = "AuthorizationError"; this.status = 403; this.details = details; } } class AccessControlService { constructor(database) { this.database = database; } listPermissions() { return PERMISSIONS.slice(); } ensureDefaultRolesAndUsers(actorUserId = "USER-SYSTEM") { return this.database.transaction(db => { const roles = list(db, "roles"); Object.entries(ROLE_TEMPLATES).forEach(([id, template]) => { const existing = roles.find(role => role.id === id); const row = { id, name: template.name, permissions_json: JSON.stringify(template.permissions), description: template.description || "Built-in COSMIC AI-Risk role." }; if (existing) { update(db, "roles", id, row); } else { insert(db, "roles", row, "ROLE"); } }); const users = list(db, "users"); const defaultUsers = [ { id: "USER-SYSTEM", display_name: "System", email: "system@cosmic.local", role_id: "ROLE-ADMIN", active: true }, { id: "USER-PM", display_name: "Project Manager", email: "pm@cosmic.local", role_id: "ROLE-PM", active: true }, { id: "USER-RISK", display_name: "Risk Owner", email: "risk.owner@cosmic.local", role_id: "ROLE-RISK-OWNER", active: true }, { id: "USER-ENGINEER", display_name: "AI Engineer", email: "ai.engineer@cosmic.local", role_id: "ROLE-AI-ENGINEER", active: true }, { id: "USER-GOV", display_name: "Governance Reviewer", email: "governance@cosmic.local", role_id: "ROLE-GOV-REVIEWER", active: true }, { id: "USER-LEGAL", display_name: "Legal Ethics Reviewer", email: "legal.ethics@cosmic.local", role_id: "ROLE-LEGAL-ETHICS", active: true }, { id: "USER-INTEGRATION", display_name: "Integration Admin", email: "integration.admin@cosmic.local", role_id: "ROLE-INTEGRATION-ADMIN", active: true }, { id: "USER-VIEWER", display_name: "Read-only Viewer", email: "viewer@cosmic.local", role_id: "ROLE-VIEWER", active: true } ]; defaultUsers.forEach(user => { if (!users.find(item => item.id === user.id)) { insert(db, "users", user, "USER"); } }); audit(db, { project_id: "system", actor_user_id: actorUserId, entity_type: "AccessControl", entity_id: "defaults", action: "seed-defaults", after_json: { roleCount: Object.keys(ROLE_TEMPLATES).length, userCount: defaultUsers.length } }); return { roles: list(db, "roles").map(toRoleView), users: list(db, "users").map(user => toUserView(db, user)) }; }); } listRoles() { const db = this.database.read(); return list(db, "roles").map(toRoleView).sort((a, b) => a.name.localeCompare(b.name)); } getRole(roleId) { const db = this.database.read(); const role = findById(db, "roles", roleId); return role ? toRoleView(role) : null; } listUsers() { const db = this.database.read(); return list(db, "users").map(user => toUserView(db, user)).sort((a, b) => a.displayName.localeCompare(b.displayName)); } getUser(userId) { const db = this.database.read(); const user = findById(db, "users", userId); return user ? toUserView(db, user) : null; } createUser(payload, actorUserId = "USER-SYSTEM") { if (!payload || typeof payload !== "object") throw new Error("User payload is required"); const displayName = String(payload.displayName || payload.display_name || "").trim(); const email = String(payload.email || "").trim(); const roleId = String(payload.roleId || payload.role_id || "ROLE-VIEWER").trim(); if (!displayName) throw new Error("displayName is required"); if (!email || !email.includes("@")) throw new Error("valid email is required"); return this.database.transaction(db => { if (!findById(db, "roles", roleId)) throw new Error(`Role not found: ${roleId}`); const user = insert(db, "users", { display_name: displayName, email, role_id: roleId, active: payload.active !== false }, "USER"); audit(db, { project_id: "system", actor_user_id: actorUserId, entity_type: "User", entity_id: user.id, action: "create", after_json: user }); return toUserView(db, user); }); } updateUser(userId, payload, actorUserId = "USER-SYSTEM") { if (!payload || typeof payload !== "object") throw new Error("User patch payload is required"); return this.database.transaction(db => { const before = findById(db, "users", userId); if (!before) return null; const patch = {}; if (payload.displayName !== undefined || payload.display_name !== undefined) patch.display_name = String(payload.displayName || payload.display_name || "").trim(); if (payload.email !== undefined) patch.email = String(payload.email || "").trim(); if (payload.roleId !== undefined || payload.role_id !== undefined) { const roleId = String(payload.roleId || payload.role_id || "").trim(); if (!findById(db, "roles", roleId)) throw new Error(`Role not found: ${roleId}`); patch.role_id = roleId; } if (payload.active !== undefined) patch.active = Boolean(payload.active); const user = update(db, "users", userId, patch); audit(db, { project_id: "system", actor_user_id: actorUserId, entity_type: "User", entity_id: userId, action: "update", before_json: before, after_json: user }); return toUserView(db, user); }); } createRole(payload, actorUserId = "USER-SYSTEM") { if (!payload || typeof payload !== "object") throw new Error("Role payload is required"); const name = String(payload.name || "").trim(); if (!name) throw new Error("name is required"); const permissions = normalizePermissions(payload.permissions || payload.permissions_json || []); return this.database.transaction(db => { const role = insert(db, "roles", { name, permissions_json: JSON.stringify(permissions), description: payload.description || "Custom COSMIC AI-Risk role." }, "ROLE"); audit(db, { project_id: "system", actor_user_id: actorUserId, entity_type: "Role", entity_id: role.id, action: "create", after_json: role }); return toRoleView(role); }); } updateRole(roleId, payload, actorUserId = "USER-SYSTEM") { if (!payload || typeof payload !== "object") throw new Error("Role patch payload is required"); return this.database.transaction(db => { const before = findById(db, "roles", roleId); if (!before) return null; const patch = {}; if (payload.name !== undefined) patch.name = String(payload.name || "").trim(); if (payload.description !== undefined) patch.description = String(payload.description || "").trim(); if (payload.permissions !== undefined || payload.permissions_json !== undefined) { patch.permissions_json = JSON.stringify(normalizePermissions(payload.permissions || payload.permissions_json || [])); } const role = update(db, "roles", roleId, patch); audit(db, { project_id: "system", actor_user_id: actorUserId, entity_type: "Role", entity_id: roleId, action: "update", before_json: before, after_json: role }); return toRoleView(role); }); } hasPermission(userId, permission) { const user = this.getUser(userId || "USER-SYSTEM"); if (!user || user.active === false) return false; return user.permissions.includes("*") || user.permissions.includes(permission); } requirePermission(userId, permission, context = {}) { const user = this.getUser(userId || "USER-SYSTEM"); if (!user) throw new AuthorizationError(`Unknown actor user: ${userId}`, { permission, context }); if (user.active === false) throw new AuthorizationError(`Inactive actor user: ${userId}`, { permission, context }); if (user.permissions.includes("*") || user.permissions.includes(permission)) return user; throw new AuthorizationError(`Permission denied: ${permission}`, { actorUserId: userId, permission, role: user.roleName, context }); } getAccessSummary(userId) { const user = this.getUser(userId || "USER-SYSTEM"); if (!user) return null; return { actor: user, permissions: this.listPermissions(), roles: this.listRoles(), users: this.listUsers() }; } } module.exports = { AccessControlService, AuthorizationError, PERMISSIONS, ROLE_TEMPLATES, normalizePermissions };