Files
Kordant/tasks/kordant-unified-restructure/30-ios-auth-onboarding.md
2026-05-25 22:49:37 -04:00

126 lines
6.0 KiB
Markdown

# 30. iOS App — Authentication, Onboarding, and Account Setup
meta:
id: kordant-unified-restructure-30
feature: kordant-unified-restructure
priority: P1
depends_on: [kordant-unified-restructure-28, kordant-unified-restructure-29]
tags: [ios, swiftui, auth, onboarding, mobile]
objective:
- Build the authentication and onboarding flow for the iOS app: login, signup, password reset, and a multi-step onboarding experience. Use native iOS authentication where possible (Sign in with Apple) and maintain visual consistency with the web app.
deliverables:
- `iOS/Kordant/Views/Auth/AuthView.swift` — Auth container:
- Switches between login and signup modes
- Kordant branding at top
- Social auth buttons (Sign in with Apple, Google)
- `iOS/Kordant/Views/Auth/LoginView.swift` — Login screen:
- Email and password fields using `ShieldTextField`
- "Remember me" toggle
- "Forgot password?" link
- "Sign In" `ShieldButton`
- "Don't have an account? Sign up" link
- `iOS/Kordant/Views/Auth/SignupView.swift` — Signup screen:
- Name, email, password, confirm password fields
- Password strength indicator
- Terms of service agreement toggle
- "Create Account" button
- `iOS/Kordant/Views/Auth/ForgotPasswordView.swift` — Password reset:
- Email input + submit
- Success state with instructions
- `iOS/Kordant/Views/Onboarding/OnboardingView.swift` — Onboarding flow:
- Page-based `TabView` with 4 steps
- Step 1: Welcome + plan selection (Basic, Plus, Premium cards)
- Step 2: Add first watchlist item (email or phone)
- Step 3: Invite family members (optional)
- Step 4: Setup complete → transition to main app
- `iOS/Kordant/Views/Auth/BiometricAuthView.swift` — Face ID / Touch ID prompt:
- Triggered after first successful login
- Uses `LocalAuthentication` framework
- Stores preference in Keychain
- `iOS/Kordant/Services/AuthService.swift` — Auth business logic:
- `login(email, password)` → calls API (task 31)
- `signup(name, email, password)` → calls API
- `resetPassword(email)` → calls API
- `signInWithApple()` → handles Apple ID credential
- `signInWithGoogle()` → handles Google Sign-In
- `enableBiometricAuth()` → stores credential in Keychain
- `logout()` → clears tokens and Keychain
steps:
1. Create `iOS/Kordant/Views/Auth/` and `iOS/Kordant/Views/Onboarding/` directories.
2. **AuthView**:
- Use `@State` to toggle between login and signup
- Show Kordant logo and tagline at top
- Use `ShieldCard` for the form container
3. **LoginView**:
- `ShieldTextField` for email and password
- `Toggle` for "Remember me"
- `ShieldButton` for submit
- Link to ForgotPasswordView
- On success: store JWT in Keychain, navigate to main app or onboarding
4. **SignupView**:
- Additional fields: name, confirm password
- Password strength: check length, uppercase, number, special char
- Visual strength bar using `ShieldProgressBar`
- Terms toggle (required)
- On success: store JWT, show onboarding
5. **ForgotPasswordView**:
- Simple email field + submit
- Success message: "Check your email for reset instructions"
6. **OnboardingView**:
- `TabView` with `.tabViewStyle(.page)` for swipeable steps
- Step 1: Plan cards with feature lists, highlight recommended tier
- Step 2: Input for email/phone, "Add" button, shows added items list
- Step 3: Email inputs for family invites, "Skip" button
- Step 4: Success animation (checkmark), "Get Started" button
- Progress dots at bottom showing current step
7. **BiometricAuthView**:
- `LAContext` for Face ID / Touch ID evaluation
- On success: store "useBiometric" preference and credential in Keychain
- On failure: fall back to password
8. **AuthService**:
- Protocol-based for testability
- Implementation calls API client (task 31)
- Keychain wrapper for secure token storage
- Apple Sign-In: use `AuthenticationServices` framework (`ASAuthorizationAppleIDButton`)
- Google Sign-In: use `GoogleSignIn` SDK
9. Wire auth state to root view:
- `ContentView` observes `AuthService.isAuthenticated`
- On logout: clear state and show AuthView
steps:
- Unit: AuthService stores and retrieves tokens from Keychain
- Unit: Password strength calculator returns correct level
- Unit: Onboarding stepper advances and collects data
- Integration: Sign in with Apple button triggers ASAuthorizationController
- E2E: Complete login → onboarding → main app flow
acceptance_criteria:
- [ ] Login screen accepts email/password and authenticates via API
- [ ] Signup screen validates inputs and creates account via API
- [ ] Password reset flow sends request to API and shows success state
- [ ] Onboarding has 4 steps with progress indicator and swipe navigation
- [ ] Sign in with Apple button works and authenticates user
- [ ] Biometric auth (Face ID/Touch ID) can be enabled after first login
- [ ] Tokens are stored securely in iOS Keychain
- [ ] Logout clears all auth state and returns to login screen
- [ ] Auth flow matches web app visual style
validation:
- Run app on simulator, complete login with test credentials
- Verify JWT stored in Keychain (use Keychain utility or debug print)
- Test Sign in with Apple flow (simulator supports mock Apple ID)
- Complete onboarding and verify data sent to API
- Test Face ID prompt on device (simulator can simulate with Features menu)
- Run unit tests via Xcode Cmd+U
notes:
- Sign in with Apple is required for App Store approval if you offer other third-party sign-in options.
- Use `ASAuthorizationController` for Apple Sign-In. Handle both `.signIn` and `.credentialRevokedNotification`.
- For Google Sign-In, the `GoogleSignIn` SDK requires a `GoogleService-Info.plist`. Add setup instructions to README.
- Keychain token storage should use `kSecAttrAccessibleWhenUnlockedThisDeviceOnly` for security.
- The onboarding data (plan, watchlist items, family invites) should be collected in a local model and submitted to the API at the final step (or incrementally).
- Consider using SwiftUI's `.fullScreenCover` for the auth flow so it covers the entire screen without tab bar.