BE-API-5c: DSGVO-Consent-Guard #127

Closed
opened 2026-06-26 12:36:27 +02:00 by niboer · 0 comments
Owner

Beschreibung

DSGVO-Zustimmungsschranke pro Person (403 bei fehlendem Consent). Der Guard wird auf allen Endpunkten angewandt (ausser /health, Consent-Endpunkt selbst und i18n-Endpunkte).

Aufgaben

  • auth.ts: Neuer Hook requireConsent()
    • Prueft ob request.user.personId einen Eintrag in consents hat
    • Wenn nicht → 403 "DSGVO-Zustimmung erforderlich"
  • Wende requireConsent auf folgende Endpunkte an:
    • GET /api/v1/persons
    • GET /api/v1/persons/{person_id}
    • PUT /api/v1/persons/{person_id}
    • POST /api/v1/persons
    • GET /api/v1/persons/{person_id}/contacts
    • PUT /api/v1/persons/{person_id}/contacts
    • POST /api/v1/persons/{person_id}/archive
    • POST /api/v1/persons/{person_id}/switch-group
    • PUT /api/v1/persons/{person_id}/user-link
    • GET /api/v1/persons/{person_id}/invitations
    • GET /api/v1/persons/me
    • GET /api/v1/events
    • POST /api/v1/events
    • GET /api/v1/events/{event_id}
    • PUT /api/v1/events/{event_id}
    • DELETE /api/v1/events/{event_id}
    • POST /api/v1/events/{event_id}/publish
    • GET /api/v1/events/{event_id}/guests
    • POST /api/v1/events/{event_id}/guests
    • GET /api/v1/events/{event_id}/guests/{person_id}
    • DELETE /api/v1/events/{event_id}/guests/{person_id}
    • PUT /api/v1/events/{event_id}/guests/{person_id}/status
    • PUT /api/v1/events/{event_id}/guests/{person_id}/payment
    • GET /api/v1/events/{event_id}/guests/{person_id}/role
    • PUT /api/v1/events/{event_id}/guests/{person_id}/role
    • GET /api/v1/events/{event_id}/guests/{person_id}/form-draft
    • PUT /api/v1/events/{event_id}/guests/{person_id}/form-draft
    • PUT /api/v1/events/{event_id}/guests/{person_id}/form-final
    • PUT /api/v1/events/{event_id}/guests/{person_id}/form-override
    • GET /api/v1/events/{event_id}/form
    • PUT /api/v1/events/{event_id}/form
    • GET /api/v1/events/{event_id}/roles
    • POST /api/v1/events/{event_id}/roles
    • GET /api/v1/events/{event_id}/roles/{role_id}
    • PUT /api/v1/events/{event_id}/roles/{role_id}
    • DELETE /api/v1/events/{event_id}/roles/{role_id}
    • GET /api/v1/groups
    • POST /api/v1/groups
    • GET /api/v1/groups/{group_id}
    • PUT /api/v1/groups/{group_id}
    • DELETE /api/v1/groups/{group_id}
    • GET /api/v1/groups/{group_id}/members
    • POST /api/v1/groups/{group_id}/members
    • DELETE /api/v1/groups/{group_id}/members/{person_id}
    • POST /api/v1/groups/{group_id}/join-request
    • PUT /api/v1/groups/{group_id}/join-request/{person_id}
    • GET /api/v1/templates
    • POST /api/v1/templates
    • GET /api/v1/templates/{template_id}
    • PUT /api/v1/templates/{template_id}
    • DELETE /api/v1/templates/{template_id}
    • GET /api/v1/invoices
  • Ausgenommen: /health, PUT .../consent, GET /api/v1/i18n, GET /api/v1/i18n/{lang}
  • Tests in auth.test.ts: requireConsent-Hook (fehlender Consent → 403, vorhandener Consent → pass)
  • openapi.yaml: 403-Responses mit Consent-Hinweis ergaenzen
  • design.md: Autorisierungsmatrix (§5.1) um requireConsent-Hook ergaenzen

Abhaengigkeiten

  • Epic: #100
  • Vorgaenger: #125 (Consent-Endpunkt)

Technische Hinweise

  • Der Hook wird vor den bestehenden Auth-Hooks ausgefuehrt (erster Eintrag im preHandler-Array)
  • Consent gilt pro Person (ein Eintrag in consents reicht aus)
  • policyVersion wird aktuell nicht auf Gueltigkeit geprueft (zukunftiger Task)
## Beschreibung DSGVO-Zustimmungsschranke pro Person (403 bei fehlendem Consent). Der Guard wird auf **allen** Endpunkten angewandt (ausser `/health`, Consent-Endpunkt selbst und i18n-Endpunkte). ## Aufgaben - [ ] `auth.ts`: Neuer Hook `requireConsent()` - Prueft ob `request.user.personId` einen Eintrag in `consents` hat - Wenn nicht → 403 "DSGVO-Zustimmung erforderlich" - [ ] Wende `requireConsent` auf folgende Endpunkte an: - `GET /api/v1/persons` - `GET /api/v1/persons/{person_id}` - `PUT /api/v1/persons/{person_id}` - `POST /api/v1/persons` - `GET /api/v1/persons/{person_id}/contacts` - `PUT /api/v1/persons/{person_id}/contacts` - `POST /api/v1/persons/{person_id}/archive` - `POST /api/v1/persons/{person_id}/switch-group` - `PUT /api/v1/persons/{person_id}/user-link` - `GET /api/v1/persons/{person_id}/invitations` - `GET /api/v1/persons/me` - `GET /api/v1/events` - `POST /api/v1/events` - `GET /api/v1/events/{event_id}` - `PUT /api/v1/events/{event_id}` - `DELETE /api/v1/events/{event_id}` - `POST /api/v1/events/{event_id}/publish` - `GET /api/v1/events/{event_id}/guests` - `POST /api/v1/events/{event_id}/guests` - `GET /api/v1/events/{event_id}/guests/{person_id}` - `DELETE /api/v1/events/{event_id}/guests/{person_id}` - `PUT /api/v1/events/{event_id}/guests/{person_id}/status` - `PUT /api/v1/events/{event_id}/guests/{person_id}/payment` - `GET /api/v1/events/{event_id}/guests/{person_id}/role` - `PUT /api/v1/events/{event_id}/guests/{person_id}/role` - `GET /api/v1/events/{event_id}/guests/{person_id}/form-draft` - `PUT /api/v1/events/{event_id}/guests/{person_id}/form-draft` - `PUT /api/v1/events/{event_id}/guests/{person_id}/form-final` - `PUT /api/v1/events/{event_id}/guests/{person_id}/form-override` - `GET /api/v1/events/{event_id}/form` - `PUT /api/v1/events/{event_id}/form` - `GET /api/v1/events/{event_id}/roles` - `POST /api/v1/events/{event_id}/roles` - `GET /api/v1/events/{event_id}/roles/{role_id}` - `PUT /api/v1/events/{event_id}/roles/{role_id}` - `DELETE /api/v1/events/{event_id}/roles/{role_id}` - `GET /api/v1/groups` - `POST /api/v1/groups` - `GET /api/v1/groups/{group_id}` - `PUT /api/v1/groups/{group_id}` - `DELETE /api/v1/groups/{group_id}` - `GET /api/v1/groups/{group_id}/members` - `POST /api/v1/groups/{group_id}/members` - `DELETE /api/v1/groups/{group_id}/members/{person_id}` - `POST /api/v1/groups/{group_id}/join-request` - `PUT /api/v1/groups/{group_id}/join-request/{person_id}` - `GET /api/v1/templates` - `POST /api/v1/templates` - `GET /api/v1/templates/{template_id}` - `PUT /api/v1/templates/{template_id}` - `DELETE /api/v1/templates/{template_id}` - `GET /api/v1/invoices` - [ ] Ausgenommen: `/health`, `PUT .../consent`, `GET /api/v1/i18n`, `GET /api/v1/i18n/{lang}` - [ ] Tests in `auth.test.ts`: `requireConsent`-Hook (fehlender Consent → 403, vorhandener Consent → pass) - [ ] `openapi.yaml`: 403-Responses mit Consent-Hinweis ergaenzen - [ ] `design.md`: Autorisierungsmatrix (§5.1) um `requireConsent`-Hook ergaenzen ## Abhaengigkeiten - Epic: #100 - Vorgaenger: #125 (Consent-Endpunkt) ## Technische Hinweise - Der Hook wird **vor** den bestehenden Auth-Hooks ausgefuehrt (erster Eintrag im preHandler-Array) - Consent gilt pro Person (ein Eintrag in `consents` reicht aus) - `policyVersion` wird aktuell nicht auf Gueltigkeit geprueft (zukunftiger Task)
Sign in to join this conversation.
No description provided.