feat: onboarding pre-work
This commit is contained in:
193
ONBOARDING-FIX.md
Normal file
193
ONBOARDING-FIX.md
Normal 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
|
||||
Reference in New Issue
Block a user