Skip to main content

End-to-End Authentication Test Results

Date: November 9, 2025
Primary Scripts:

  • scripts/test-e2e-auth.js
  • scripts/test-checkout-urls.js
  • npm run test -- checkout-success-url

Current Status

✅ Working & Verified

  • /health — Production instance healthy (curl -I https://reformer-platform.onrender.com/health)
  • /api/checkout — Redirects unauthenticated browser traffic to dashboard signup with preserved return URL (see Checkout Verification below)
  • handleCheckout — Stripe session success_url now points to https://dash.reformer.la/?checkout=success&session_id=… (unit coverage npm run test -- checkout-success-url)
  • /api/auth/me — Correctly rejects unauthenticated requests (401)

✅ Resolved (Nov 9, 2025 @ 20:30 UTC)

  • Forgot password flow now uses the Supabase admin generate_link API + Resend fallback. Verified with test1@reformer.la and uat-fix1@reformer.la (emailSent: true, Render no longer reports high error rate).

✅ Completed (Nov 11, 2025)

  • Password reset system fully implemented and deployed:
    • POST /api/auth/forgot-password - Sends recovery email via Resend
    • POST /api/auth/reset-password - Resets password with Supabase recovery token
    • Frontend pages: /forgot-password and /reset-password
    • Password strength validation (8+ chars, uppercase, lowercase, number)
    • Token extraction from URL hash (#access_token=xxx&type=recovery)
    • Rate limiting on both endpoints
  • Email verification redirects fixed:
    • Users redirect to client portal (my.reformer.la/{clientslug}) after verification
    • Onboarding form displays on portal home page
    • Removed blocking messages that prevented onboarding access
  • Close CRM automations guard missing helpers and fall back to lead creation; Render logs show updateCloseCRM: Success for all post-fix onboarding runs.
  • Dropbox metadata persistence updates dropbox_link, dropbox_path, and dropbox_created_at for each new member (confirmed in Supabase for uat-fix* accounts).
  • Stripe webhook endpoint now accepts signed events (returns 200) and rejects unsigned payloads with 400 — verified at 20:53 UTC using generated HMAC signature.

⚠️ Remaining Gaps

  • Intercom updates still return an initial HTTP 400 before a retry logs success; needs cleanup/verification.
  • Portal slug persistenceaccounts.portal_slug and dashboard_slug remain NULL even though the API returns slugs.
  • Pirsch analytics continues to skip because no client ID is configured (expected but noted for completeness).

Test Plan

Completed Tests ✅

  1. Backend health check
  2. Authentication protection (401 on unauthenticated access)

Pending Tests (Waiting for Fresh Accounts)

  1. Signup with new email
  2. Programmatic email verification (SUPABASE_SERVICE_ROLE_KEY)
  3. Login after verification
  4. Forgot password flowCOMPLETE (Nov 11, 2025)
  5. Password reset flowCOMPLETE (Nov 11, 2025)
  6. Checkout session creation with authenticated user (requires live Supabase token)
  7. Logout

Next Steps

  1. Wait for rate limit reset (1-2 hours)
  2. Obtain test Supabase session (scripted helper WIP) for authenticated checkout verification
  3. Re-run E2E auth script — node scripts/test-e2e-auth.js
  4. Capture Stripe session redirect — confirm success_url in live checkout dashboard when authenticated

Manual Testing Checklist

While waiting for rate limits, manually test:

  • Visit /signup page on dashboard
  • Create account with unique email
  • Check email for verification link
  • Click verification link
  • Login with verified account
  • Access /dashboard (protected route)
  • Test /forgot-password page ✅ COMPLETE (Nov 11, 2025)
  • Test /reset-password page ✅ COMPLETE (Nov 11, 2025)
  • Test checkout flow (requires login; expect dashboard redirect post-payment)

UAT Batch – November 9, 2025 @ 20:32 UTC (Post-fix)

EmailSignup / LoginForgot PasswordOnboarding ResponseAutomations (key outputs)Notes
uat-fix1@reformer.laemailSent: truePortal: https://my.reformer.la/fix-one-coffee
Dropbox: link
ClickUp: https://app.clickup.com
Dropbox ✅ /Reformer Clients Directory/Fix One Coffee (10 subfolders + shared link)
ClickUp ✅ project + onboarding/webflow/maintenance task lists
Resend ✅ Dropbox-ready email
Close CRM ✅ lead updated & Dropbox link propagated
Google Workspace ✅ folder provisioned
dropbox_created_at persisted; activity logs record all integrations. portal_slug still NULL.
uat-fix2@reformer.la✅ (inferred)Portal: https://my.reformer.la/fix-two-bakery
Dropbox: link
ClickUp: https://app.clickup.com
Dropbox ✅ /Reformer Clients Directory/Fix Two Bakery + link
ClickUp ✅ project + 13 tasks
Resend ✅ Dropbox-ready email
Close CRM ✅ lead update
Google Workspace ✅ folder provisioned
All automations succeeded; portal slug still empty.
uat-fix3@reformer.la✅ (inferred)Portal: https://my.reformer.la/fix-three-fitness
Dropbox: link
ClickUp: https://app.clickup.com
Dropbox ✅ /Reformer Clients Directory/Fix Three Fitness + link
ClickUp ✅ project + 13 tasks
Resend ✅ Dropbox-ready email
Close CRM ✅ lead update
Google Workspace ✅ folder provisioned
Intercom still logs a 400 before retrying. Portal slug remains unset.

UAT Batch – November 9, 2025 @ 19:13 UTC (Pre-fix)

EmailSignup / LoginForgot PasswordOnboarding ResponseAutomations (key outputs)Notes
test1@reformer.laError sending recovery emailPortal: https://my.reformer.la/test-one-coffee
Dropbox: link
ClickUp: https://app.clickup.com
Dropbox ✅ /Reformer Clients Directory/Test One Coffee (10 subfolders)
ClickUp ✅ folder 90173757516 (Onboarding/Webflow/Maintenance lists + tasks)
Resend ✅ Dropbox-ready email
Pirsch ⚠️ skipped (no client ID)
Close CRM ❌ searchLeads undefined
Intercom ⚠️ 400 before retry success
portal_slug remained NULL; members.dropbox_link not persisted (dropbox_created_at missing); forgot-password failures triggered Render alert
test2@reformer.laError sending recovery emailPortal: https://my.reformer.la/test-two-bakery
Dropbox: link
ClickUp: https://app.clickup.com
Dropbox ✅ /Reformer Clients Directory/Test Two Bakery (10 subfolders)
ClickUp ✅ folder 90173757549 (lists + tasks)
Resend ✅ Dropbox-ready email
Pirsch ⚠️ skipped
Close CRM ❌
Intercom ⚠️ 400 then success
Same schema issue (dropbox_created_at); portal slug not set; initial Dropbox API 409 warnings before folder creation
test3@reformer.laError sending recovery emailPortal: https://my.reformer.la/test-three-fitness
Dropbox: link
ClickUp: https://app.clickup.com
Dropbox ✅ /Reformer Clients Directory/Test Three Fitness (10 subfolders)
ClickUp ✅ folder 90173757576 (lists + tasks)
Resend ✅ Dropbox-ready email
Pirsch ⚠️ skipped
Close CRM ❌
Intercom ⚠️ 400 then success
Same schema gap; portal slug not persisted; Dropbox metadata save failed; forgot-password 400

Automation Observations (Pre-fix)

  • Every onboarding run created the Dropbox directory structure, generated shared links, and opened ClickUp projects with onboarding/webflow/maintenance lists (13 tasks total).
  • Resend delivered the “Dropbox workspace ready” transactional email for all three accounts.
  • closeCRM.searchLeads was missing, so CRM syncing and Dropbox-link propagation failed consistently.
  • Pirsch integration is skipped by design due to missing credentials.
  • Render triggered a high-error-rate alert because the forgot-password endpoint returned Supabase errors on every request.
  • Accounts landed in status provisioning, but portal_slug stayed NULL despite the API returning slugs — still under investigation.

Checkout Verification (Nov 9, 2025)

  • node scripts/test-checkout-urls.js
    • Confirms unauthenticated browser requests receive 302 → https://dash.reformer.la/signup?redirect=<encoded_request>
    • Covers /api/checkout?plan=starter|pro|enterprise|invalid and /api/checkout
  • npm run test -- checkout-success-url
    • Stubs Stripe client to assert success_url now uses dashboard domain before marketing welcome handoff
  • Live API test @ 18:02 UTC:
    • Created account checkout-test-20251109-1@reformer.la via /api/auth/signup (auto-verified; captured bearer token)
    • GET /api/checkout?plan=free (auth header) returned 303 → https://checkout.stripe.com/...
    • stripe checkout.sessions.retrieve"success_url": "https://dash.reformer.la/?checkout=success&session_id={CHECKOUT_SESSION_ID}"
    • Session expired immediately after verification (POST /v1/checkout/sessions/{id}/expire)
  • Next Live Step: Acquire Supabase JWT (service helper pending) to hit /api/checkout as an authenticated client and record returned Stripe session URL + success redirect behaviour end-to-end.

Environment Variables Needed

For full test suite to work:

  • SUPABASE_SERVICE_ROLE_KEY - For programmatic email verification
  • NEXT_PUBLIC_SUPABASE_URL - Supabase project URL
  • SUPABASE_ANON_KEY - Supabase anonymous key (or NEXT_PUBLIC_SUPABASE_ANON_KEY)