fix: 2x Portal-Bugs (Vertragsauswahl + Email-Sync)
Bug 1 — Support-Anfrage: ausgewaehlter Vertrag nicht erkennbar
Im Kundenportal beim Erstellen einer Support-Anfrage war der
Selected-State des Vertrags nur ein dezenter blau-grauer
Hintergrund + Border-Farbwechsel. Auf hellem Bildschirm / nicht-
perfekter Lichtsituation kaum zu sehen.
Fix: kraefigere Markierung mit linkem 4px-Akzent-Bar
(border-l-blue-600), kraefigerem Background (bg-blue-100),
Checkmark-Icon rechtsbuendig und blauer Titel-Text.
Bug 2 — Email-Sync im Portal: "Keine Berechtigung"
POST /api/stressfrei-emails/:id/sync hatte
requirePermission('customers:update') – die Portal-Kunden nicht
haben (nur customers:read fuer eigene Daten). Sie konnten ihr
eigenes Postfach nicht synchronisieren.
Fix: Perm-Middleware aus der Route raus, Mitarbeiter-Check +
Owner-Check in den Controller verlegt:
- isCustomerPortal: nur Owner-Check (canAccessStressfreiEmail)
- Mitarbeiter: muss customers:update haben
Trennung der Threat-Modelle – Portal-User darf sein Postfach
syncen, sonst aber nichts triggern; Mitarbeiter brauchen weiter
die Update-Perm.
Live-verifiziert:
- Portal-User 1 syncs eigenes Konto → Auth passiert (400 wegen
fehlender IMAP-Config in dev-DB, NICHT 403)
- Portal-User 1 syncs Customer-3-Konto → 403 "Kein Zugriff"
- Mitarbeiter ohne customers:update → weiter 403
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -260,6 +260,16 @@ export async function getContractFolderCounts(req: AuthRequest, res: Response):
|
||||
export async function syncAccount(req: AuthRequest, res: Response): Promise<void> {
|
||||
try {
|
||||
const stressfreiEmailId = parseInt(req.params.id);
|
||||
// Mitarbeiter brauchen customers:update (wie früher), Portal-Kunden
|
||||
// brauchen keine Perm – nur Eigentum am Konto (Owner-Check unten).
|
||||
// Trennung der Threat-Modelle: Portal-User dürfen IHR eigenes
|
||||
// Postfach syncen, sollen aber nicht Mitarbeiter-Updates triggern.
|
||||
const isPortal = !!req.user?.isCustomerPortal;
|
||||
const hasUpdatePerm = req.user?.permissions?.includes('customers:update') ?? false;
|
||||
if (!isPortal && !hasUpdatePerm) {
|
||||
res.status(403).json({ success: false, error: 'Keine Berechtigung' } as ApiResponse);
|
||||
return;
|
||||
}
|
||||
if (!(await canAccessStressfreiEmail(req, res, stressfreiEmailId))) return;
|
||||
const fullSync = req.query.full === 'true';
|
||||
|
||||
|
||||
@@ -236,10 +236,14 @@ router.delete(
|
||||
|
||||
// E-Mails für ein Konto synchronisieren
|
||||
// POST /api/stressfrei-emails/:id/sync?full=true
|
||||
//
|
||||
// KEIN `requirePermission('customers:update')` hier: Portal-Kunden
|
||||
// dürfen ihr EIGENES Postfach synchronisieren – sie haben aber nur
|
||||
// `customers:read`. Der Mitarbeiter-Perm-Check und der Owner-Check
|
||||
// laufen im Controller. (Pentest 2026-05-30 follow-up.)
|
||||
router.post(
|
||||
'/stressfrei-emails/:id/sync',
|
||||
authenticate,
|
||||
requirePermission('customers:update'),
|
||||
cachedEmailController.syncAccount
|
||||
);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user