Add backend team enforcement via requireTeam() middleware

Introduce server-side team-scoped data access enforcement:

- Add TEAM_TO_IVANTI/IVANTI_TO_TEAM mapping to helpers/teams.js
- Add requireTeam() middleware to middleware/auth.js
  - Admin bypass (req.teamScope = null)
  - 403 for users with no team assignment
  - Populates req.teamScope with short and ivanti name arrays
- Ivanti findings: replace client ?teams= param with req.teamScope filtering
  on GET /, /counts, /counts/history, /fp-workflow-counts, POST /sync
  - Override and note endpoints verify finding is in team scope
- Compliance: add requireTeam() router-level, validate ?team= param against scope
  on GET /items and GET /summary
- CARD: validate teamName param on GET /teams/:teamName/assets
- Todo queue: verify findings belong to user's teams on POST /batch
- Clarify IVANTI_BU_FILTER comment (sync-level vs query-time filtering)
- Update 14 test files to include requireTeam in auth middleware mocks
This commit is contained in:
Jordan Ramos
2026-06-24 11:36:25 -06:00
parent ab66d7d813
commit a003091b6a
20 changed files with 239 additions and 81 deletions

View File

@@ -1,5 +1,6 @@
// Authentication Middleware
const pool = require('../db');
const { teamToIvanti } = require('../helpers/teams');
// Require authenticated user — no parameters needed, pool is imported directly
function requireAuth() {
@@ -66,4 +67,38 @@ function requireGroup(...allowedGroups) {
};
}
module.exports = { requireAuth, requireGroup };
// Require team assignment — enforces team-scoped data access.
// Admin group bypasses (req.teamScope = null means "no filter").
// Non-admin users without teams get 403.
// Non-admin users with teams get req.teamScope = { short: [...], ivanti: [...] }.
function requireTeam() {
return (req, res, next) => {
if (!req.user) {
return res.status(401).json({ error: 'Authentication required' });
}
// Admin bypass — full access to all teams
if (req.user.group === 'Admin') {
req.teamScope = null;
return next();
}
// No teams assigned — block access
if (!req.user.teams || req.user.teams.length === 0) {
return res.status(403).json({
error: 'No team assignment. Contact an administrator to assign BU teams to your account.',
code: 'NO_TEAM_ASSIGNMENT'
});
}
// Build scope with both naming conventions
req.teamScope = {
short: req.user.teams,
ivanti: req.user.teams.map(t => teamToIvanti(t))
};
next();
};
}
module.exports = { requireAuth, requireGroup, requireTeam };