// Read-only user preview controls. const { hasPermission } = require('#src/rbac'); module.exports = function registerViewAsRoutes(app, deps) { const pool = deps.pool; const requirePermission = deps.requirePermission; const startViewAsUser = deps.startViewAsUser; const stopViewAsUser = deps.stopViewAsUser; const recordRequestAuditEvent = deps.recordRequestAuditEvent; app.post('/settings/users/:id/view-as', requirePermission('users.read'), requirePermission('impersonate.allow'), async function (req, res, next) { try { const actor = req.authenticatedUser || req.currentUser && req.currentUser.authenticatedUser || req.currentUser; const targetUserId = Number(req.params.id); if (!actor || !hasPermission(actor, 'impersonate.allow') || req.currentUser && req.currentUser.isViewingAs) { return res.sendStatus(403); } if (!Number.isInteger(targetUserId) || targetUserId <= 0 || targetUserId === Number(actor.id)) { return res.status(400).send('Choose another user to preview.'); } const [rows] = await pool.query('SELECT id, name, username FROM a_users WHERE id = ? LIMIT 1', [targetUserId]); if (!rows.length) { return res.sendStatus(404); } const target = rows[0]; const started = await startViewAsUser(pool, req, actor.id, targetUserId); if (!started) { return res.status(409).send('The preview could not be started. Sign in again and retry.'); } if (typeof recordRequestAuditEvent === 'function') { await recordRequestAuditEvent(pool, req, { category: 'users', eventType: 'user.view_as_started', actorUserId: actor.id, targetType: 'user', targetId: targetUserId, targetLabel: target.username, details: { expiresInMinutes: 15 } }); } res.redirect('/dashboard'); } catch (error) { next(error); } }); app.post('/settings/view-as/stop', async function (req, res, next) { try { const actor = req.authenticatedUser || req.currentUser && req.currentUser.authenticatedUser; if (!actor || !req.currentUser || !req.currentUser.isViewingAs) { return res.redirect('/dashboard'); } const target = req.currentUser; const stopped = await stopViewAsUser(pool, req, actor.id); if (!stopped) { return res.status(409).send('The preview has already ended. Refresh the page to continue.'); } if (typeof recordRequestAuditEvent === 'function') { await recordRequestAuditEvent(pool, req, { category: 'users', eventType: 'user.view_as_stopped', actorUserId: actor.id, targetType: 'user', targetId: target.id, targetLabel: target.username }); } res.redirect('/settings/users'); } catch (error) { next(error); } }); };