add features

This commit is contained in:
Matthias Hochmeister
2026-03-03 17:01:53 +01:00
parent 92b05726d4
commit 5a6fc85a75
30 changed files with 1104 additions and 198 deletions

View File

@@ -89,6 +89,28 @@ function getUserId(req: Request): string {
return req.user!.id;
}
function getUserGroups(req: Request): string[] {
return req.user?.groups ?? [];
}
/**
* Returns true if the user is authorised to write to equipment in the given
* category. Admin can write to any category. Fahrmeister can only write to
* motorised categories. Zeugmeister can only write to non-motorised categories.
*/
async function checkCategoryPermission(kategorieId: string, groups: string[]): Promise<boolean> {
if (groups.includes('dashboard_admin')) return true;
const result = await equipmentService.getCategoryById(kategorieId);
if (!result) return false; // unknown category → deny
if (result.motorisiert) {
return groups.includes('dashboard_fahrmeister');
} else {
return groups.includes('dashboard_zeugmeister');
}
}
// ── Controller ────────────────────────────────────────────────────────────────
class EquipmentController {
@@ -193,6 +215,12 @@ class EquipmentController {
});
return;
}
const groups = getUserGroups(req);
const allowed = await checkCategoryPermission(parsed.data.kategorie_id, groups);
if (!allowed) {
res.status(403).json({ success: false, message: 'Keine Berechtigung für diese Kategorie' });
return;
}
const equipment = await equipmentService.createEquipment(parsed.data, getUserId(req));
res.status(201).json({ success: true, data: equipment });
} catch (error) {
@@ -221,6 +249,25 @@ class EquipmentController {
res.status(400).json({ success: false, message: 'Kein Feld zum Aktualisieren angegeben' });
return;
}
// Determine which category to check permissions against
const groups = getUserGroups(req);
if (!groups.includes('dashboard_admin')) {
// If kategorie_id is being changed, check against the new category; otherwise fetch existing
let kategorieId = parsed.data.kategorie_id;
if (!kategorieId) {
const existing = await equipmentService.getEquipmentById(id);
if (!existing) {
res.status(404).json({ success: false, message: 'Ausrüstung nicht gefunden' });
return;
}
kategorieId = existing.kategorie_id;
}
const allowed = await checkCategoryPermission(kategorieId, groups);
if (!allowed) {
res.status(403).json({ success: false, message: 'Keine Berechtigung für diese Kategorie' });
return;
}
}
const equipment = await equipmentService.updateEquipment(id, parsed.data, getUserId(req));
if (!equipment) {
res.status(404).json({ success: false, message: 'Ausrüstung nicht gefunden' });
@@ -253,6 +300,19 @@ class EquipmentController {
});
return;
}
const groups = getUserGroups(req);
if (!groups.includes('dashboard_admin')) {
const existing = await equipmentService.getEquipmentById(id);
if (!existing) {
res.status(404).json({ success: false, message: 'Ausrüstung nicht gefunden' });
return;
}
const allowed = await checkCategoryPermission(existing.kategorie_id, groups);
if (!allowed) {
res.status(403).json({ success: false, message: 'Keine Berechtigung für diese Kategorie' });
return;
}
}
await equipmentService.updateStatus(
id, parsed.data.status, parsed.data.bemerkung, getUserId(req)
);
@@ -302,6 +362,19 @@ class EquipmentController {
});
return;
}
const groups = getUserGroups(req);
if (!groups.includes('dashboard_admin')) {
const existing = await equipmentService.getEquipmentById(id);
if (!existing) {
res.status(404).json({ success: false, message: 'Ausrüstung nicht gefunden' });
return;
}
const allowed = await checkCategoryPermission(existing.kategorie_id, groups);
if (!allowed) {
res.status(403).json({ success: false, message: 'Keine Berechtigung für diese Kategorie' });
return;
}
}
const entry = await equipmentService.addWartungslog(id, parsed.data, getUserId(req));
res.status(201).json({ success: true, data: entry });
} catch (error: any) {