# Fix New User Signup Wizard Flow ## Problem Summary The new user signup wizard is broken: 1. After Auth0 callback, users go to `/garage` instead of `/verify-email` 2. Users can access `/garage/*` without verified email 3. Onboarding flow is bypassed entirely 4. **New Requirement**: Block login completely at Auth0 for unverified users ## Root Causes 1. **Auth0Provider.tsx:29** - `onRedirectCallback` defaults to `/garage` without checking verification 2. **App.tsx:472-481** - Callback route just shows "Processing login..." with no routing logic 3. **App.tsx:549+** - Protected routes have no email verification check 4. **Auth0** - No rule/action blocking unverified users from logging in --- ## Implementation Plan ### Phase 1: Auth0 Configuration (Manual Step) **Auth0 Dashboard -> Actions -> Flows -> Login** Create a Post Login Action to block unverified users: ```javascript exports.onExecutePostLogin = async (event, api) => { if (!event.user.email_verified) { api.access.deny('Please verify your email address before logging in. Check your inbox for a verification link.'); } }; ``` This ensures: - Unverified users cannot get a JWT - They see a clear error on the Auth0 login screen - They must click the verification link before logging in ### Phase 2: Update Signup Flow **After signup, redirect to a "Check Your Email" page (not /verify-email)** The new flow: 1. User submits signup form 2. Backend creates Auth0 user (unverified) 3. Auth0 automatically sends verification email 4. Frontend shows "Check Your Email" page with: - Message: "We've sent a verification link to your email" - Resend button (calls public resend endpoint) - "Back to Login" button 5. User clicks email link -> Auth0 marks as verified 6. User can now login -> goes to /onboarding ### Phase 3: Backend Changes **File: `backend/src/features/auth/api/auth.routes.ts`** - Add `POST /api/auth/resend-verification-public` (no JWT required) - Takes email address, looks up user, resends verification **File: `backend/src/features/auth/api/auth.controller.ts`** - Add `resendVerificationPublic` handler **File: `backend/src/features/auth/domain/auth.service.ts`** - Add `resendVerificationByEmail` method **File: `backend/src/features/auth/api/auth.routes.ts`** - Add `GET /api/auth/user-status` (JWT required) - Returns: `{ emailVerified, onboardingCompleted, email }` **File: `backend/src/core/plugins/auth.plugin.ts`** - Add `/api/auth/user-status` to `VERIFICATION_EXEMPT_ROUTES` ### Phase 4: Create Callback Handler **File: `frontend/src/features/auth/pages/CallbackPage.tsx`** (NEW) - Fetches user status after Auth0 callback - Routes based on status: - Not onboarded -> `/onboarding` - Onboarded -> `/garage` (or returnTo) - Note: Unverified users never reach this (blocked by Auth0) **File: `frontend/src/features/auth/mobile/CallbackMobileScreen.tsx`** (NEW) - Mobile version ### Phase 5: Update Auth0Provider **File: `frontend/src/core/auth/Auth0Provider.tsx`** Update `onRedirectCallback` (line 27-31): ```typescript const onRedirectCallback = (appState?: { returnTo?: string }) => { navigate('/callback', { replace: true, state: { returnTo: appState?.returnTo || '/garage' } }); }; ``` ### Phase 6: Rename/Update Verify Email Page **File: `frontend/src/features/auth/pages/VerifyEmailPage.tsx`** - Rename concept to "Check Your Email" page - Remove polling (user can't be authenticated) - Show static message + resend button (calls public endpoint) - Add "Back to Login" button **File: `frontend/src/features/auth/mobile/VerifyEmailMobileScreen.tsx`** - Same changes for mobile ### Phase 7: Update App.tsx Routing **File: `frontend/src/App.tsx`** 1. Replace callback handling (lines 472-481) with CallbackPage 2. Add onboarding guard after authentication check 3. Remove email verification check from frontend (Auth0 handles it) ```typescript // After isAuthenticated check: // Fetch onboarding status // If not onboarded -> /onboarding // Otherwise -> proceed to /garage ``` ### Phase 8: Create Supporting Files **File: `frontend/src/core/auth/useUserStatus.ts`** (NEW) - Hook for fetching user status **File: `frontend/src/features/auth/api/auth.api.ts`** - Add `getUserStatus()` - Add `resendVerificationPublic(email)` (no auth) --- ## Files to Modify ### Auth0 (Manual Configuration) - Create Post Login Action to block unverified users ### Backend - `backend/src/features/auth/api/auth.routes.ts` - Add endpoints - `backend/src/features/auth/api/auth.controller.ts` - Add handlers - `backend/src/features/auth/domain/auth.service.ts` - Add methods - `backend/src/core/plugins/auth.plugin.ts` - Update exempt routes ### Frontend - `frontend/src/core/auth/Auth0Provider.tsx` - Fix onRedirectCallback - `frontend/src/App.tsx` - Add route guards and callback handler - `frontend/src/features/auth/pages/CallbackPage.tsx` - NEW - `frontend/src/features/auth/mobile/CallbackMobileScreen.tsx` - NEW - `frontend/src/features/auth/pages/VerifyEmailPage.tsx` - Update to static page - `frontend/src/features/auth/mobile/VerifyEmailMobileScreen.tsx` - Update - `frontend/src/core/auth/useUserStatus.ts` - NEW - `frontend/src/features/auth/api/auth.api.ts` - Add functions --- ## New User Flow (After Fix) ``` 1. Signup form submission 2. -> POST /api/auth/signup (creates unverified Auth0 user) 3. -> Navigate to /verify-email (static "Check Your Email" page) 4. User clicks verification link in email 5. -> Auth0 marks user as verified 6. User clicks "Login" on /verify-email page 7. -> Auth0 login succeeds (user is now verified) 8. -> /callback page fetches status 9. -> Not onboarded? -> /onboarding 10. -> Complete onboarding -> /garage ``` ## Returning User Flow ``` 1. Login attempt (unverified) -> Auth0 blocks with error message 2. Login attempt (verified, not onboarded) -> /callback -> /onboarding 3. Login attempt (verified, onboarded) -> /callback -> /garage ``` --- ## Testing Checklist - [ ] Auth0 Action blocks unverified login with clear error - [ ] Signup -> check-email page -> verify via email -> login works - [ ] Resend verification from check-email page works - [ ] Verified user (no onboarding) -> onboarding wizard - [ ] Verified + onboarded user -> direct to garage - [ ] Direct URL access to /garage -> requires login - [ ] All flows work on mobile - [ ] All flows work on desktop