LOADING…
0%
Complete changelog

Commit

Fix purchase-security and payment logic bugs

Commit details

Commit notes

Fixes the logic bugs found in the codebase analysis:

- Guest purchase takeover (HIGH): registering an account with a guest buyer's email no longer claims their purchases. Guest purchases are only linked once the email is verified — via a new email verification flow (token table was dead schema; now wired: users.email_verified_at column, /auth/verify-email + /auth/resend-verification endpoints, verification email on signup, frontend verify page). Google OAuth emails count as verified. hasPurchasedPack only matches by email for verified accounts.

- Partial refunds (HIGH): charge.refunded webhook events for PARTIAL refunds no longer revoke the buyer's downloads and claw back the creator's full earnings; only full refunds are processed.

- Price validation (MEDIUM): pack priceCents is now a non-negative integer at the schema level, and packs/bundles must be free or cost at least Stripe's €0.50 minimum. Coupons are clamped so the remaining charge never drops below that minimum (previously a 90%-off coupon on a cheap pack produced checkouts Stripe rejects).

- Bundle webhook ordering (MEDIUM): persist the payment intent ID before completing bundle purchases, so a crash mid-webhook can't leave completed purchases that refunds can never find.

- Double-charge protection (MEDIUM): re-running checkout for the same pack/bundle reuses the existing open Stripe session instead of opening a second payable one; stale sessions are expired and their pending rows released; completed-but-unprocessed sessions block re-purchase. Failed session creation no longer leaves orphaned pending purchases.

- Download zip memory (LOW): pack downloads now stream files through the archiver with backpressure instead of buffering every file (and effectively the whole zip) in memory.

- customer.subscription.updated is now handled, keeping status/period in sync with portal-side changes without recording spurious payments.

Also makes the frontend lint gate green: formats 6 drifted files and fixes 3 pre-existing ESLint errors that were masked by the format failure.

[private session redacted]

Files changed
24
Lines added
+7,494
Lines removed
−92
This page is a permanent record of commit 70b34ffe.