Overnight Digest
Last night, 11:47pm → 7:02am · June 1, 2026 · 3 repos
fix: prevent double-refund on concurrent webhook events
The refund handler lacked idempotency protection — two simultaneous Stripe webhook events for the same charge could each trigger a full refund. Added database-level locking and a `processed_refunds` deduplication table. Also fixed missing `try/catch` that would silently swallow Stripe API errors.
refundHandler() — removed console.log that leaked PII to stdout in production. Security fix.
feat: auto-retry failed charges with exponential backoff
Implements automatic retry of failed Stripe charges with jitter-based exponential backoff (base: 1s, max: 64s, jitter ±25%). Retry logic respects Stripe's `api_version` and deduplicates via idempotency key. Includes new `retry_log` table and admin dashboard widget.
retryWithJitter() — added 4 new test cases covering timeout, max-attempts-exceeded, and Stripe API error scenarios.
feat: persist dark mode preference to localStorage + cookie fallback
User's theme preference is now stored in localStorage on first visit, with a server-set __theme cookie for SSR. On subsequent server-rendered page loads, the correct theme flashes before JS runs — eliminating the white-flash-on-refresh bug. Preference sync runs on account switch.
clearThemeCookie() on sign-out.
chore: upgrade dependencies — nodemailer 6.9, axios 1.6, pg 8.11
Routine dependency update across all packages. Notably: nodemailer upgrade resolves a vulnerability in SMTPConnection pool reuse. axios upgrade bumps the node-fetch fallback for Node <18. pg upgrade includes binary binding fixes for arm64 macOS builds.
@types/nodemailer was 1 version behind — pinned to 6.9.3. No breaking API changes detected.
Unguarded PII logging in Stripe webhook handler
The stripeWebhookHandler() function contained a console.log statement in the production path that serialized the full req.body — including customer email, card BIN, and billing address — to stdout. On Render's ephemeral filesystem, stdout is streamed to structured logs; a log-shipper misconfiguration or a shared log aggregator could expose this payload. The fix replaces the logging call with a structured logger.audit() that redacts PII fields. This is a PCI-DSS scope concern and qualifies as a critical finding under OWASP A03:2021.
Bearer token logged to error output on 401
The authMiddleware error path included the Authorization header value in a logged message when a JWT expired or was malformed. Even though the token is a stateless JWT (not a static credential), logging tokens enables replay attacks if logs are ever exfiltrated. The fix strips the token from all error logs and replaces it with a 6-character opaque hash for correlation. Additionally, added a retry-from-refresh-token flow before the 401 is returned to the client.
The proposed change in src/components/ShareModal.tsx would have added a new modal component that called window.location.href directly to navigate after a share action — instead of using the useRouter() hook that Codio's routing standards require. Direct window.location mutations bypass the Next.js router's prefetch cache, create browser history entries for every share action, and prevent the shared modal's animation exit sequence from completing.
next/link for internal routes and useRouter().push() for programmatic navigation. Direct window.location mutations are forbidden.