feat: add multi-BU tenancy with per-user team scoping (Option B)

- Add bu_teams column to users table (migration + fresh schema)
- Create shared KNOWN_TEAMS constant and validateTeams helper
- Expose user teams in auth middleware, login, and /me responses
- Add bu_teams CRUD to user management routes with audit logging
- Make Ivanti FINDINGS_FILTERS configurable via IVANTI_BU_FILTER env var
- Add query-time team filtering to GET /findings and /findings/counts
- Update AuthContext with teams helpers and admin scope toggle
- Create AdminScopeToggle component (My Teams / All BUs)
- Scope ReportingPage findings fetch by user teams
- Scope CompliancePage team selector by user teams
- Scope ExportsPage findings exports by user teams
- Add BU teams multi-select to UserManagement create/edit forms
- Display team badges in user list table
This commit is contained in:
Jordan Ramos
2026-05-05 11:04:53 -06:00
parent af951fdc12
commit 2656df94d3
24 changed files with 999 additions and 127 deletions

View File

@@ -143,7 +143,8 @@ function createAuthRouter(db, logAudit) {
id: user.id,
username: user.username,
email: user.email,
group: user.user_group
group: user.user_group,
teams: user.bu_teams ? user.bu_teams.split(',').filter(Boolean) : []
}
});
} catch (err) {
@@ -222,7 +223,7 @@ function createAuthRouter(db, logAudit) {
try {
const session = await new Promise((resolve, reject) => {
db.get(
`SELECT s.*, u.id as user_id, u.username, u.email, u.user_group, u.is_active
`SELECT s.*, u.id as user_id, u.username, u.email, u.user_group, u.bu_teams, u.is_active
FROM sessions s
JOIN users u ON s.user_id = u.id
WHERE s.session_id = ? AND s.expires_at > datetime('now')`,
@@ -249,7 +250,8 @@ function createAuthRouter(db, logAudit) {
id: session.user_id,
username: session.username,
email: session.email,
group: session.user_group
group: session.user_group,
teams: session.bu_teams ? session.bu_teams.split(',').filter(Boolean) : []
}
});
} catch (err) {