feat(backend): Contact-Encrypt-Helper mit Regressionsschutz #323

Merged
niboer merged 1 commit from feat/contact-encrypt-helper into main 2026-07-22 16:19:27 +00:00
Owner

closes #313

Altes Verhalten

Jeder Endpunkt, der ContactData schreibt, musste encrypt() aus crypto.ts manuell importieren und jedes Feld einzeln verschluesseln (for-Loop oder einzelne Aufrufe). Ebenso wurde decrypt() in mehreren Routes fuer ContactData direkt aus crypto.ts importiert, jeweils mit eigener Nullpruefung und try/catch. Es gab keine automatische Pruefung, ob neue Dateien versehentlich wieder den direkten Weg gehen.

Neues Verhalten

  • contact-encrypt.ts — zentraler Helper encryptContactData() und encryptAddressOnly() als Gegenstueck zu contact-decrypt.ts
  • Alle Routes nutzen jetzt ausschliesslich die Helper, kein direkter encrypt/decrypt-Import aus crypto.ts mehr fuer ContactData
  • Unit-Test contact-encrypt.test.ts deckt beide Funktionen ab (symmetrisch zu contact-decrypt.test.ts)
  • ESLint-Regel project/no-direct-crypto-contactdata verhindert, dass neue Dateien encrypt/decrypt aus crypto.ts fuer ContactData importieren. Explizite Allowlist fuer legitime Nicht-ContactData-Nutzungen (invoice-XML, crypto.ts selbst, Helper). Test-Dateien komplett ausgenommen.

Begruendung

Redundanz vermeiden, einheitliche Verschluesselung erzwingen und Regression durch neue Entwickler (oder KI-Agents) automatisch abfangen.

Test-Hinweise

  • npm test (backend) laeuft gruen — 675 Tests, 37 Files
  • npm run lint (backend) laeuft gruen
  • Wer eine neue .ts-Datei in src/ anlegt und import { encrypt } from '../lib/crypto.js' schreibt, bekommt einen ESLint-Error mit eindeutiger Meldung

Checkliste

  • use:testid an neuen <button>, <a>, <form>-Elementen gesetzt? — nicht relevant
  • Korrespondierender E2E-Test in e2e/specs/ angelegt? — nicht relevant
closes #313 ### Altes Verhalten Jeder Endpunkt, der ContactData schreibt, musste `encrypt()` aus `crypto.ts` manuell importieren und jedes Feld einzeln verschluesseln (for-Loop oder einzelne Aufrufe). Ebenso wurde `decrypt()` in mehreren Routes fuer ContactData direkt aus `crypto.ts` importiert, jeweils mit eigener Nullpruefung und try/catch. Es gab keine automatische Pruefung, ob neue Dateien versehentlich wieder den direkten Weg gehen. ### Neues Verhalten - **contact-encrypt.ts** — zentraler Helper `encryptContactData()` und `encryptAddressOnly()` als Gegenstueck zu `contact-decrypt.ts` - **Alle Routes** nutzen jetzt ausschliesslich die Helper, kein direkter `encrypt`/`decrypt`-Import aus `crypto.ts` mehr fuer ContactData - **Unit-Test** `contact-encrypt.test.ts` deckt beide Funktionen ab (symmetrisch zu `contact-decrypt.test.ts`) - **ESLint-Regel** `project/no-direct-crypto-contactdata` verhindert, dass neue Dateien `encrypt`/`decrypt` aus `crypto.ts` fuer ContactData importieren. Explizite Allowlist fuer legitime Nicht-ContactData-Nutzungen (invoice-XML, crypto.ts selbst, Helper). Test-Dateien komplett ausgenommen. ### Begruendung Redundanz vermeiden, einheitliche Verschluesselung erzwingen und Regression durch neue Entwickler (oder KI-Agents) automatisch abfangen. ### Test-Hinweise - `npm test` (backend) laeuft gruen — 675 Tests, 37 Files - `npm run lint` (backend) laeuft gruen - Wer eine neue .ts-Datei in `src/` anlegt und `import { encrypt } from '../lib/crypto.js'` schreibt, bekommt einen ESLint-Error mit eindeutiger Meldung ### Checkliste - [x] `use:testid` an neuen `<button>`, `<a>`, `<form>`-Elementen gesetzt? — nicht relevant - [x] Korrespondierender E2E-Test in `e2e/specs/` angelegt? — nicht relevant
feat(backend): Contact-Encrypt-Helper mit Regressionsschutz
All checks were successful
CI Backend / lint-backend (pull_request) Successful in 1m1s
CI Frontend / lint-frontend (pull_request) Successful in 1m29s
CI Meta / conventional-commit (pull_request) Successful in 1s
E2E / e2e (pull_request) Successful in 5m20s
CI Backend / test-backend (pull_request) Successful in 4m4s
CI Frontend / test-frontend (pull_request) Successful in 2m6s
CI Backend / lint-backend (push) Successful in 1m1s
CI Meta / conventional-commit (push) Has been skipped
CI Backend / test-backend (push) Successful in 4m5s
CD / build-and-push (push) Successful in 38s
29cac89407
refs/closes #313

Aktuelles: encrypt()/decrypt() aus crypto.ts werden in allen Routes
manuell importiert und auf ContactData-Felder angewendet. Das fuehrt
zu Redundanz und fehlender Zentralisierung.

Neu:
- contact-encrypt.ts als Gegenstueck zu contact-decrypt.ts mit
  encryptContactData() und encryptAddressOnly()
- decrypt()-Import in persons.ts, export.ts und import-export.ts
  durch decryptContactData() ersetzt
- Neuer Unit-Test contact-encrypt.test.ts (symmetrisch zu
  contact-decrypt.test.ts)
- ESLint-Custom-Rule project/no-direct-crypto-contactdata als
  Regressionsschutz: verbietet encrypt/decrypt-Import aus crypto.ts
  in allen Dateien ausser einer expliziten Allowlist
  (contact-encrypt.ts, contact-decrypt.ts, invoice-generator.ts,
  crypto.ts, invoices.ts) und Test-Dateien.
- encrypt()-Import aus crypto.ts in allen Routes entfernt (nur noch
  in den beiden Helpern und invoice-generator.ts aktiv).

Wichtige Aenderung: Die encrypt-Logik in routes/contacts.ts,
routes/import-export.ts und routes/setup.ts nutzt jetzt
encryptContactData() statt einer manuellen for-Loop. Die
decrypt-Logik in routes/persons.ts, routes/export.ts und
routes/import-export.ts (Export) nutzt decryptContactData()
statt einzelner decrypt()-Aufrufe mit try/catch.
niboer merged commit 29cac89407 into main 2026-07-22 16:19:27 +00:00
niboer deleted branch feat/contact-encrypt-helper 2026-07-22 16:19:28 +00:00
Sign in to join this conversation.
No description provided.