Commit Graph

1 Commits

Author SHA1 Message Date
null 89d06eeb7d fix(billing): correct RevenueCat webhook auth to HMAC-SHA256 + enable export
The webhook verified an Ed25519 signature in an X-Signature header, but RevenueCat
offers no public-key signing — it sends HMAC-SHA256 in X-RevenueCat-Webhook-Signature
(t=<ts>,v1=<hex>) computed over "<ts>.<rawBody>". As written, every real event would
have 401'd and premium would never sync for the partner.

- Rewrite verification to HMAC-SHA256 with a +/-5-min timestamp replay guard and a
  constant-time compare; extract a pure verifyWebhookSignature() for unit testing.
- Rename secret REVENUECAT_SIGNING_KEY -> REVENUECAT_WEBHOOK_SECRET (it is an HMAC
  secret, not an Ed25519 key). Never deployed, so no migration.
- Uncomment the export in index.ts (deploy still gated on seeding the secret).
- Add revenueCatWebhook.test.ts: valid / tampered / wrong-secret / missing / stale.
- Reconcile Future.md + Engineering_Reference_Manual.md to the real scheme.

Verified against the live account: the entitlement identifier is now closer_premium,
so events match entitlementLogic. Build + 80 tests green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-09 03:43:59 -05:00