Skip to content

fix(security): keep profile saves working after Generate and billing - #70

Draft
cursor[bot] wants to merge 1 commit into
mainfrom
cursor/critical-bug-investigation-4f67
Draft

cursor[bot] wants to merge 1 commit into
mainfrom
cursor/critical-bug-investigation-4f67

Conversation

@cursor

@cursor cursor Bot commented Sep 5, 2026

Copy link
Copy Markdown

What changed

  • After Generate (PR feat(profile): persist every catalog report on Generate #68 catalog persist) or a PAYG credit debit, Admin writes extra fields onto users/{uid} (allReportsReady, toolStatus, creditBalance, etc.).
  • validUserUpdate used hasOnly(userProfileAllowedKeys()) on the merged document, so those extra keys made every later client profile save fail (birth edits, photo URLs, settings).
  • Those server-owned keys are now allowed and protected. The same keys are still forbidden on signup create so a client cannot mint creditBalance.

Why this change is safe

  • Root cause: Firestore request.resource.data after a merge includes Admin-written keys that were missing from the allow-list.
  • Scope is firestore.rules plus a unit test that parses the key lists. No app/API refactor.
  • Clients still cannot change billing or generation-status fields. Create-time constraints for trial/subscription flags are unchanged.

Verification

  • pnpm exec eslint tests/unit/firestoreUserRules.test.ts
  • pnpm test — 74 suites / 397 tests passed, including tests/unit/firestoreUserRules.test.ts
  • Playwright smoke — not applicable (rules-only; no UI/route change)

Regression prevention

  • New test fails if Generate/billing keys drop out of the allow-list or protected list, and checks that a birth-place save still passes while creditBalance / allReportsReady writes do not.
  • Existing behavior outside this scope is unchanged.

Release checklist (solo-friendly)

  • CI is green (CI / Lint + Jest, CI / Playwright smoke)
  • Ready to merge to main
  • Deploy Firestore rules after merge (firebase deploy --only firestore:rules). Repo rules do not apply until deployed.

Trigger (concrete)

  1. User clicks Generate (natal persist writes allReportsReady, pendingToolSlugs, toolStatus, lastProgressAt, mysticalProfileGeneratedAt) or a PAYG Seer/credit pack writes creditBalance / billingMode.
  2. User saves birth place, a photo URL, or settings via updateUserProfile (client SDK).
  3. Before this fix: Firestore permission-denied. Edits vanish on reload.
Open in Web View Automation 

…writes

Admin persist and credit debit add fields that hasOnly() did not allow, so every later client profile save was rejected. List those keys as allowed-and-protected, and still forbid them on signup create.

Co-authored-by: Andy Oliver Rozario <andyrozario7@gmail.com>
@vercel

vercel Bot commented Sep 5, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
future-seer Ready Ready Preview Sep 5, 2026 11:15am UTC

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant