mirror of
https://github.com/screentinker/screentinker.git
synced 2026-05-15 07:32:23 -06:00
108 lines
3 KiB
JavaScript
108 lines
3 KiB
JavaScript
// Phase 2.1: permission helpers.
|
|
//
|
|
// Routes call these as Express middleware to gate access, or as predicate
|
|
// functions to branch within a handler. They presume resolveTenancy has
|
|
// already attached req.workspaceId / req.workspaceRole / req.orgRole /
|
|
// req.isPlatformAdmin.
|
|
//
|
|
// Layering (top wins):
|
|
// 1. req.isPlatformAdmin -> allow anything
|
|
// 2. req.orgRole in {org_owner, org_admin} -> allow read/write/admin within the org
|
|
// org_owner also has billing.write and org.delete (not exposed in 2.1)
|
|
// 3. req.workspaceRole in {workspace_admin, workspace_editor, workspace_viewer}
|
|
// gates resource access per the role's bands
|
|
|
|
'use strict';
|
|
|
|
function canRead(req) {
|
|
if (req.isPlatformAdmin) return true;
|
|
if (req.orgRole === 'org_owner' || req.orgRole === 'org_admin') return true;
|
|
return !!req.workspaceRole; // any workspace_member can read
|
|
}
|
|
|
|
function canWrite(req) {
|
|
if (req.isPlatformAdmin) return true;
|
|
if (req.orgRole === 'org_owner' || req.orgRole === 'org_admin') return true;
|
|
return req.workspaceRole === 'workspace_admin' || req.workspaceRole === 'workspace_editor';
|
|
}
|
|
|
|
function canAdmin(req) {
|
|
if (req.isPlatformAdmin) return true;
|
|
if (req.orgRole === 'org_owner' || req.orgRole === 'org_admin') return true;
|
|
return req.workspaceRole === 'workspace_admin';
|
|
}
|
|
|
|
function isOrgAdmin(req) {
|
|
if (req.isPlatformAdmin) return true;
|
|
return req.orgRole === 'org_owner' || req.orgRole === 'org_admin';
|
|
}
|
|
|
|
function isOrgOwner(req) {
|
|
if (req.isPlatformAdmin) return true;
|
|
return req.orgRole === 'org_owner';
|
|
}
|
|
|
|
// ---- middleware variants ----
|
|
|
|
function requireWorkspace(req, res, next) {
|
|
if (!req.workspaceId) {
|
|
return res.status(403).json({ error: 'No workspace context' });
|
|
}
|
|
next();
|
|
}
|
|
|
|
function requireWorkspaceRead(req, res, next) {
|
|
if (!canRead(req)) {
|
|
return res.status(403).json({ error: 'Workspace access required' });
|
|
}
|
|
next();
|
|
}
|
|
|
|
function requireWorkspaceWrite(req, res, next) {
|
|
if (!canWrite(req)) {
|
|
return res.status(403).json({ error: 'Workspace editor or admin required' });
|
|
}
|
|
next();
|
|
}
|
|
|
|
function requireWorkspaceAdmin(req, res, next) {
|
|
if (!canAdmin(req)) {
|
|
return res.status(403).json({ error: 'Workspace admin required' });
|
|
}
|
|
next();
|
|
}
|
|
|
|
function requireOrgAdmin(req, res, next) {
|
|
if (!isOrgAdmin(req)) {
|
|
return res.status(403).json({ error: 'Organization admin required' });
|
|
}
|
|
next();
|
|
}
|
|
|
|
function requireOrgOwner(req, res, next) {
|
|
if (!isOrgOwner(req)) {
|
|
return res.status(403).json({ error: 'Organization owner required' });
|
|
}
|
|
next();
|
|
}
|
|
|
|
function requirePlatformAdmin(req, res, next) {
|
|
if (!req.user || req.user.role !== 'platform_admin') {
|
|
return res.status(403).json({ error: 'Platform admin required' });
|
|
}
|
|
next();
|
|
}
|
|
|
|
module.exports = {
|
|
// boolean predicates
|
|
canRead, canWrite, canAdmin, isOrgAdmin, isOrgOwner,
|
|
// express middleware
|
|
requireWorkspace,
|
|
requireWorkspaceRead,
|
|
requireWorkspaceWrite,
|
|
requireWorkspaceAdmin,
|
|
requireOrgAdmin,
|
|
requireOrgOwner,
|
|
requirePlatformAdmin,
|
|
};
|