diff --git a/frontend/src/app.js b/frontend/src/app.js index 7fa8b74..6ab0beb 100644 --- a/frontend/src/app.js +++ b/frontend/src/app.js @@ -161,36 +161,18 @@ env.addFilter('_', translateHelper); app.set('view engine', 'html'); +const { buildUserSession } = require('./middlewares/authMiddleware'); + // Helper para extraer usuario de cookie si existe app.use((req, res, next) => { const token = req.cookies.auth_token; - let user = { - name: 'System', - first_name: 'System', - email: 'admin@edu-space.com', - role: 'admin', - is_authenticated: Boolean(token), - is_admin: () => true, - has_permission: () => true, - has_role: () => true, - can_edit_reservation: () => true, - can_delete_reservation: () => true, - get_institutional_role: () => 'admin', - role_badge_display: { class: 'bg-primary text-white', icon: 'bi-shield-check', label: 'Administrador' } - }; + let user = buildUserSession({ role: 'admin', name: 'System', email: 'admin@edu-space.com' }); + user.is_authenticated = Boolean(token); + if (token) { try { const decoded = JSON.parse(Buffer.from(token.split('.')[1], 'base64').toString('utf8')); - const roleStr = (decoded.role || 'Admin').toLowerCase(); - user = { - ...user, - id: decoded.sub, - name: decoded.name || 'System', - first_name: (decoded.name || 'System').split(' ')[0], - email: decoded.email || 'admin@edu-space.com', - role: roleStr, - is_admin: () => roleStr === 'admin' || decoded.is_admin === true - }; + user = buildUserSession(decoded); } catch (e) {} } let isImpersonating = false; diff --git a/frontend/src/middlewares/authMiddleware.js b/frontend/src/middlewares/authMiddleware.js index 59a1076..a6e028c 100644 --- a/frontend/src/middlewares/authMiddleware.js +++ b/frontend/src/middlewares/authMiddleware.js @@ -1,6 +1,78 @@ const apiClient = require('../services/apiClient'); const axios = require('axios'); +const buildUserSession = (decoded) => { + const roleStr = (decoded?.role || 'Admin').toLowerCase(); + const isAdmin = roleStr === 'admin' || decoded?.is_admin === true; + const isBedelia = roleStr === 'bedelia'; + const isDocente = roleStr === 'docente' || roleStr === 'profesor'; + const isAlumno = roleStr === 'alumno' || roleStr === 'estudiante'; + const canManage = isAdmin || isBedelia; + + let badgeClass = 'bg-primary text-white'; + let badgeIcon = 'bi-shield-check'; + let badgeLabel = decoded?.role || 'Administrador'; + + if (isBedelia) { + badgeClass = 'bg-warning text-dark'; + badgeIcon = 'bi-building-gear'; + badgeLabel = 'BedelĂ­a'; + } else if (isDocente) { + badgeClass = 'bg-info text-white'; + badgeIcon = 'bi-person-video3'; + badgeLabel = 'Docente'; + } else if (isAlumno) { + badgeClass = 'bg-success text-white'; + badgeIcon = 'bi-mortarboard'; + badgeLabel = 'Alumno'; + } + + return { + id: decoded?.sub || 1, + name: decoded?.name || 'System', + first_name: (decoded?.name || 'System').split(' ')[0], + email: decoded?.email || 'admin@edu-space.com', + role: roleStr, + is_authenticated: true, + is_active: true, + is_admin: () => isAdmin, + is_bedelia: () => isBedelia, + is_docente: () => isDocente, + is_alumno: () => isAlumno, + can_manage: () => canManage, + has_role: (r) => roleStr === (r || '').toLowerCase(), + has_permission: (module, action) => { + if (isAdmin) return true; + if (isBedelia) { + if (module === 'reservations' || module === 'classrooms' || module === 'schedule') return true; + if (module === 'academic' && action === 'read') return true; + } + if (isDocente) { + if (module === 'my_subjects' || module === 'academic') return true; + if (module === 'reservations' && action === 'read') return true; + } + if (isAlumno) { + if (module === 'my_subjects' && action === 'read') return true; + } + return false; + }, + can_edit_reservation: (res) => { + if (isAdmin || isBedelia) return true; + if (isDocente && res && (res.user_id === decoded?.sub || res.user?.id === decoded?.sub)) return true; + return false; + }, + can_delete_reservation: (res) => { + return isAdmin || isBedelia; + }, + get_institutional_role: () => roleStr, + role_badge_display: { + class: badgeClass, + icon: badgeIcon, + label: badgeLabel + } + }; +}; + const requireAuth = (req, res, next) => { const token = req.cookies.auth_token; @@ -17,24 +89,7 @@ const requireAuth = (req, res, next) => { } }); - let user = { - name: 'System', - first_name: 'System', - email: 'admin@edu-space.com', - role: 'admin', - is_authenticated: true, - is_admin: () => true, - has_permission: () => true, - can_edit_reservation: () => true, - can_delete_reservation: () => true, - has_role: () => true, - get_institutional_role: () => 'admin', - role_badge_display: { - class: 'bg-primary text-white', - icon: 'bi-shield-check', - label: 'Administrador' - } - }; + let user = buildUserSession({ role: 'admin', name: 'System', email: 'admin@edu-space.com' }); try { const payloadBase64 = token.split('.')[1]; @@ -46,21 +101,7 @@ const requireAuth = (req, res, next) => { return res.redirect('/auth/login'); } - const roleStr = (decoded.role || 'Admin').toLowerCase(); - user = { - ...user, - id: decoded.sub, - name: decoded.name || 'System', - first_name: (decoded.name || 'System').split(' ')[0], - email: decoded.email || 'admin@edu-space.com', - role: roleStr, - is_admin: () => roleStr === 'admin' || decoded.is_admin === true, - role_badge_display: { - class: roleStr === 'admin' ? 'bg-primary text-white' : 'bg-info text-white', - icon: roleStr === 'admin' ? 'bi-shield-check' : 'bi-person', - label: decoded.role || 'Administrador' - } - }; + user = buildUserSession(decoded); } catch (e) { console.error('Error decoding token payload:', e.message); } @@ -101,4 +142,4 @@ const requireAuth = (req, res, next) => { next(); }; -module.exports = { requireAuth }; +module.exports = { requireAuth, buildUserSession };