Skip to content

fix: harden real-portal integration after the mock-portal swap - #227

Merged
kevinrutledge merged 1 commit into
developfrom
fix/portal-integration-hardening
Jun 9, 2026
Merged

fix: harden real-portal integration after the mock-portal swap#227
kevinrutledge merged 1 commit into
developfrom
fix/portal-integration-hardening

Conversation

@kevinrutledge

@kevinrutledge kevinrutledge commented Jun 9, 2026

Copy link
Copy Markdown
Collaborator

Developer

Kevin Rutledge

What changed?

The mock portal ran inside the app's own origin, so assumptions that held there broke once login and member data came from the real cross-origin portal. This PR hardens that integration. The login callback redirects with 303 so the SameSite=Lax cookie survives the cross-site POST from the portal. Every portal call gets an 8-second timeout and treats the portal's 200-on-failure responses (an INVALID_KEY sentinel, a PHP notice) as errors with a logged raw snippet. The email blast drops its 1-second per-batch sleep, which Brevo does not need, so it stays inside the function budget. Member reads are memoized per request, SMS consent refuses an empty phone, and the 1-hour session redirects to re-login and is documented as a portal constraint.

  • src/app/api/auth/callback/route.ts, src/app/api/auth/logout/route.ts - redirect with 303 (See Other) instead of the default 307
  • src/lib/api/portal-api.ts - add AbortSignal.timeout(8000) to every portal call and surface the portal's 200-on-failure shapes with a raw snippet
  • src/lib/api/member-api.ts - wrap the roster and member reads in React cache() for per-request dedup
  • src/services/email.ts - drop the inter-batch delay, raise BATCH_SIZE to 25
  • src/services/sms-consent.ts, src/actions/settings.ts - reject SMS consent without a phone and check before persisting the toggle
  • src/utils/auth-redirect.ts - send a missing portal token back to sign-in
  • docs/architecture.md, docs/decisions/auth-patterns.md - document the portal read and cache strategy, the 303 reason, and the 1-hour cap
  • tests in test/auth, test/lib/api, test/services, test/utils

How to test

  1. npm test passes (719 unit tests) and npm run build succeeds.
  2. The auth callback returns 303 to /home with the prfc_auth cookie set, so a cross-site portal POST lands logged in (see test/auth/auth-flow.test.ts).

Checklist

  • Code works and is readable
  • Tested locally
  • Commits follow conventional commits
  • Assigned reviewers

@kevinrutledge
kevinrutledge merged commit 0e7a67b into develop Jun 9, 2026
2 checks passed
@kevinrutledge
kevinrutledge deleted the fix/portal-integration-hardening branch June 10, 2026 03:06
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