fix(GRO-2299): redact googleMapsApiKey from PATCH /api/admin/settings response #195

Merged
Flea Flicker merged 1 commits from gro-2299-redact-patch-settings into dev 2026-06-09 06:52:49 +00:00
Member

GRO-2299 — Redact googleMapsApiKey from PATCH /api/admin/settings (symmetric with GRO-2294 GET fix)

LOW / defense-in-depth follow-up surfaced by the GRO-2298 security review.

Problem

redactSettings() (added in GRO-2294) was applied only to GET /api/admin/settings. The sibling PATCH handler returned the full row via .returning() without redaction, so a settings PATCH echoed the encrypted googleMapsApiKey ciphertext back to the caller.

Fix

  • src/routes/settings.ts: add a !updated guard and wrap the PATCH return in the existing redactSettings(updated) helper, so redaction is symmetric across all settings responses.
  • src/__tests__/settings.test.ts: new PATCH /settings describe block asserting the response omits googleMapsApiKey (existing-row and auto-create-then-update branches) while still returning non-secret updated fields.
  • UAT_PLAYBOOK.md §13 TC-API-13.2 updated — now asserts the PATCH response must NOT include googleMapsApiKey, mirroring TC-API-13.1.

Verification (local)

  • pnpm typecheck — clean
  • pnpm vitest run src/__tests__/settings.test.ts — 4 passed

Risk: LOW. Endpoint is requireSuperUser()-gated; value is AES-256-GCM ciphertext, not plaintext; not a regression.

Source review: GRO-2298. Parent: GRO-2294.

Co-Authored-By: Paperclip noreply@paperclip.ing

## GRO-2299 — Redact googleMapsApiKey from PATCH /api/admin/settings (symmetric with GRO-2294 GET fix) LOW / defense-in-depth follow-up surfaced by the GRO-2298 security review. ### Problem `redactSettings()` (added in GRO-2294) was applied only to **GET** `/api/admin/settings`. The sibling **PATCH** handler returned the full row via `.returning()` **without** redaction, so a settings PATCH echoed the encrypted `googleMapsApiKey` ciphertext back to the caller. ### Fix - `src/routes/settings.ts`: add a `!updated` guard and wrap the PATCH return in the existing `redactSettings(updated)` helper, so redaction is symmetric across all settings responses. - `src/__tests__/settings.test.ts`: new `PATCH /settings` describe block asserting the response omits `googleMapsApiKey` (existing-row and auto-create-then-update branches) while still returning non-secret updated fields. - **UAT_PLAYBOOK.md §13 TC-API-13.2** updated — now asserts the PATCH response must NOT include `googleMapsApiKey`, mirroring TC-API-13.1. ### Verification (local) - `pnpm typecheck` — clean - `pnpm vitest run src/__tests__/settings.test.ts` — 4 passed Risk: LOW. Endpoint is `requireSuperUser()`-gated; value is AES-256-GCM ciphertext, not plaintext; not a regression. Source review: GRO-2298. Parent: GRO-2294. Co-Authored-By: Paperclip <noreply@paperclip.ing>
Flea Flicker added 1 commit 2026-06-09 06:50:36 +00:00
fix(GRO-2299): redact googleMapsApiKey from PATCH /api/admin/settings response
CI / Test (pull_request) Successful in 24s
CI / Lint & Typecheck (pull_request) Successful in 27s
CI / Build & Push Docker Images (pull_request) Successful in 1m18s
5f01df819e
The PATCH handler returned the full businessSettings row via .returning(),
echoing the encrypted googleMapsApiKey ciphertext back to the caller. Wrap the
return in the existing redactSettings() helper (after a !updated guard) so
redaction is applied symmetrically with the GET projection (GRO-2294).

- src/routes/settings.ts: guard + redactSettings(updated) on PATCH return
- src/__tests__/settings.test.ts: assert PATCH omits googleMapsApiKey
  (existing-row and auto-create-then-update branches)
- UAT_PLAYBOOK.md §13 TC-API-13.2: assert PATCH response omits the secret

Co-Authored-By: Paperclip <noreply@paperclip.ing>
Flea Flicker merged commit b4b48f7b50 into dev 2026-06-09 06:52:49 +00:00
Sign in to join this conversation.