feat: onboarding pre-work

This commit is contained in:
Eric Gullickson
2025-12-22 21:34:05 -06:00
parent 4897f0a52c
commit 55cf4923b8
12 changed files with 537 additions and 71 deletions

193
ONBOARDING-FIX.md Normal file
View File

@@ -0,0 +1,193 @@
# 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