Both could only be created and deleted. For a webhook that is actively harmful:
recreating it issues a new signing secret, so the receiver that verifies the
X-ApiCore-Signature header against the old one starts rejecting every delivery
without anyone changing it on purpose.
Backend:
- New PATCH /webhooks/:id behind a new webhooks:update permission, covering the
target URL, the event selection and the active flag - the last of which had
no way to be set after creation at all, so a misbehaving receiver could only
be deleted. The signing secret is deliberately left alone and stays out of
the audit log.
- A changed webhook URL runs through the same assertPublicWebhookUrl SSRF check
as a new one; without that the edit would have been a way around the guard
create() applies. Covered by a test.
- New PATCH /documents/:id behind a new documents:update permission, for
re-linking a document filed against the wrong record and correcting its
display name. Re-linking validates the new target with the existing
assertEntityExists; the stored file is untouched.
Frontend:
- New webhook edit dialog. The event labels and the toggle helper moved out of
the create dialog into lib/webhooks/labels.ts so both use one copy.
- Documents can be renamed from the attachment card.
Re-linking a document to a different record has no UI yet: it needs a two-step
picker (colony, then inspection) that is not worth building unprompted.
Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
Weitere vom Sicherheitsaudit gemeldete Luecken behoben, die bisher als
niedrige Prioritaet offen gelassen wurden:
- SSO-Login (Entra ID) prüft jetzt lokale MFA genauso wie der
Passwort-Login: ist mfaEnabled gesetzt, liefert /auth/sso/complete
denselben mfaRequired-Codepfad wie /auth/login, bevor Tokens
ausgestellt werden. Frontend (Login-Seite, AuthContext) zeigt in dem
Fall den bestehenden Code-Eingabe-Schritt statt die Anmeldung
stillschweigend abzuschliessen.
- Avatar- und Dokument-Uploads pruefen jetzt die tatsaechlichen
Datei-Bytes (Magic Numbers fuer PNG/JPEG/WEBP/PDF) statt nur dem
client-angegebenen MIME-Typ/data:-URL-Praefix zu vertrauen.
- Swagger-UI (/api/v1/docs) ist jetzt standardmaessig deaktiviert
(ENABLE_SWAGGER=true erforderlich), da sie zuvor das komplette
API-Schema ungeschuetzt oeffentlich preisgab.
npm-audit-Warnungen (deepmerge-ts/mysql2 unter prisma) bewusst nicht
gefixt: kein stabiles Prisma-Release loest sie bislang auf, nur eine
Release-Candidate-Hauptversion - das Risiko eines Downgrades/RC-Upgrades
der Datenbankschicht uebersteigt den Nutzen fuer eine Kette, die zur
Laufzeit ohnehin nicht erreichbar ist (nur Prisma-CLI, nur MySQL-Treiber,
dieses Projekt nutzt Postgres).
Co-Authored-By: Claude Sonnet 5 <[email protected]>