End-to-End Authentication Test Results
Date: November 9, 2025
Primary Scripts:
scripts/test-e2e-auth.jsscripts/test-checkout-urls.jsnpm 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 sessionsuccess_urlnow points tohttps://dash.reformer.la/?checkout=success&session_id=…(unit coveragenpm 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_linkAPI + Resend fallback. Verified withtest1@reformer.laanduat-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 ResendPOST /api/auth/reset-password- Resets password with Supabase recovery token- Frontend pages:
/forgot-passwordand/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
- Users redirect to client portal (
- Close CRM automations guard missing helpers and fall back to lead creation; Render logs show
updateCloseCRM: Successfor all post-fix onboarding runs. - Dropbox metadata persistence updates
dropbox_link,dropbox_path, anddropbox_created_atfor each new member (confirmed in Supabase foruat-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 persistence —
accounts.portal_sluganddashboard_slugremainNULLeven 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 ✅
- Backend health check
- Authentication protection (401 on unauthenticated access)
Pending Tests (Waiting for Fresh Accounts)
- Signup with new email
- Programmatic email verification (
SUPABASE_SERVICE_ROLE_KEY) - Login after verification
Forgot password flow✅ COMPLETE (Nov 11, 2025)Password reset flow✅ COMPLETE (Nov 11, 2025)- Checkout session creation with authenticated user (requires live Supabase token)
- Logout
Next Steps
- Wait for rate limit reset (1-2 hours)
- Obtain test Supabase session (scripted helper WIP) for authenticated checkout verification
- Re-run E2E auth script —
node scripts/test-e2e-auth.js - Capture Stripe session redirect — confirm
success_urlin live checkout dashboard when authenticated
Manual Testing Checklist
While waiting for rate limits, manually test:
- Visit
/signuppage 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-passwordpage ✅ COMPLETE (Nov 11, 2025) - Test
/reset-passwordpage ✅ COMPLETE (Nov 11, 2025) - Test checkout flow (requires login; expect dashboard redirect post-payment)
UAT Batch – November 9, 2025 @ 20:32 UTC (Post-fix)
| Signup / Login | Forgot Password | Onboarding Response | Automations (key outputs) | Notes | |
|---|---|---|---|---|---|
uat-fix1@reformer.la | ✅ | ✅ emailSent: true | Portal: https://my.reformer.la/fix-one-coffeeDropbox: 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-bakeryDropbox: link ClickUp: https://app.clickup.com | Dropbox ✅ /Reformer Clients Directory/Fix Two Bakery + linkClickUp ✅ 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-fitnessDropbox: link ClickUp: https://app.clickup.com | Dropbox ✅ /Reformer Clients Directory/Fix Three Fitness + linkClickUp ✅ 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)
| Signup / Login | Forgot Password | Onboarding Response | Automations (key outputs) | Notes | |
|---|---|---|---|---|---|
test1@reformer.la | ✅ | ❌ Error sending recovery email | Portal: https://my.reformer.la/test-one-coffeeDropbox: 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 undefinedIntercom ⚠️ 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.la | ✅ | ❌ Error sending recovery email | Portal: https://my.reformer.la/test-two-bakeryDropbox: 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.la | ✅ | ❌ Error sending recovery email | Portal: https://my.reformer.la/test-three-fitnessDropbox: 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.searchLeadswas 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, butportal_slugstayedNULLdespite 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|invalidand/api/checkout
- Confirms unauthenticated browser requests receive 302 →
npm run test -- checkout-success-url- Stubs Stripe client to assert
success_urlnow uses dashboard domain before marketing welcome handoff
- Stubs Stripe client to assert
- Live API test @ 18:02 UTC:
- Created account
checkout-test-20251109-1@reformer.lavia/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)
- Created account
- Next Live Step: Acquire Supabase JWT (service helper pending) to hit
/api/checkoutas 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 verificationNEXT_PUBLIC_SUPABASE_URL- Supabase project URLSUPABASE_ANON_KEY- Supabase anonymous key (orNEXT_PUBLIC_SUPABASE_ANON_KEY)