DocHub
Auth flow (Supabase, Google, offline), cross-platform IAP with Apple/Google receipt validation

Authentication & In-App Purchases

Authentication Flow

Auto-Login

On app start, UserProvider.initialize() triggers auto-login:

  1. Check for a cached Supabase session locally
  2. If found, restore session and navigate to HomeScreen
  3. If no network, enter offline mode with cached session
  4. If no session at all, show LoginScreen

Supported Auth Methods

Method Details
Email/password Standard Supabase auth
Google Sign-In OAuth via Supabase, detected via provider == 'google' in auth state
Magic links Used for device removal confirmation
Password reset Via deep links (lucidflow:// on mobile, web URL on browser)

Offline Mode

  • App checks for network on startup
  • If offline but a local session exists, the user goes straight to HomeScreen
  • Controlled by AppConfig.enableOfflineMode flag
  • Sessions are cached using Supabase’s built-in local storage
  • Mobile: lucidflow://app scheme
  • Web: Uri.base.origin (browser origin URL)
  • Password reset links are browser-specific (Supabase limitation)

In-App Purchases

Product ID Format

Platform Format Example
Android Lowercase course code h01enb
iOS Bundle prefix + lowercase code me.hypnoelp.app.h01enb

Course codes come from shop.json (e.g., H01ENB).

Purchase Flow

  1. User selects course and voice (M/F) in the shop
  2. Platform-specific product ID is generated from the course code
  3. InAppPurchaseService.purchaseCourse() initiates native purchase
  4. Purchase token/receipt sent to /functions/v1/validate_purchase
  5. Backend validates with Apple (verifyReceipt API) or Google Play
  6. On success, course added to user account
  7. Sync triggered to download the purchased course content

iOS-Specific Details

  • Receipt retrieved via method channel (app_receipt) from Bundle.main.appStoreReceiptURL
  • Binary receipt, base64-encoded for validation
  • Backend uses production + sandbox fallback for Apple validation
  • Non-consumable products may show as PurchaseStatus.restored after first purchase — this is expected

Sandbox Mode

AppConfig.useSandboxIAP is automatically true in debug builds, false in release. In sandbox mode the backend skips store API validation.

Backend Endpoints

Endpoint Purpose
/functions/v1/validate_purchase Course & subscription IAP validation
/functions/v1/validate_purchase_ai_credits AI credit IAP validation
/functions/v1/actions Course switch operations