๐Ÿ” Hypnoelp Supabase Authentication System

Complete documentation of authentication flow, database structure, and user management

Version 2 | Last Updated: September 9, 2025

๐Ÿ“‹ Overview

Hypnoelp uses Supabase Authentication for user management, providing secure email/password authentication and comprehensive user session management. The system includes email verification, password reset functionality, and seamless offline support.

โœ‰๏ธ

Email/Password Auth

Traditional authentication with email confirmation requirement

๐Ÿ“ฑ

Cross-Platform

Works on Android, with Web (future) and iOS (future) support

๐Ÿ”„

Offline Support

Cached profiles for offline access

๐Ÿ—„๏ธ Database Structure

Tables Used

Table Name Purpose Key Fields
auth.users Supabase built-in authentication table id, email, encrypted_password, email_confirmed_at, user_metadata
public.user_profile Application user profiles with comprehensive data user_id (FK to auth.users), first_name, last_name, email, phone_number, country, created_at, updated_at, lead_source
public.app_logs Application logging for signup tracking id, user_id, log_type, message, origin, created_at, updated_at

Edge Functions

Function Name Purpose Input Action
delete-unlinked-user Clean up auth users without user_profile records email address Deletes orphaned auth.users record using admin privileges
Data Consistency: The system maintains strict consistency between auth.users and user_profile tables:
  • โœ… Normal State: Both auth.users record AND user_profile record exist with matching user_id
  • ๐Ÿ”„ Pending State: Only auth.users record exists (unconfirmed email) - user_profile created after confirmation
  • ๐Ÿงน Cleanup State: Unlinked auth users (no matching user_profile) are automatically deleted during signup
  • ๐Ÿ”ง Self-Healing: Unlinked user_profiles (no matching auth user) are updated with new auth user_id during signup

Table Schemas

user_profile table schema: - user_id: UUID (Primary Key, Foreign Key to auth.users.id) - first_name: TEXT (User's first name) - last_name: TEXT (User's last name) - email: TEXT (User's email address - normalized lowercase) - phone_number: TEXT (User's phone with country code, e.g., +639686258155) - country: TEXT (User's country, e.g., "Philippines") - lead_source: TEXT (How user discovered the app - nullable) - created_at: TIMESTAMPZ (Account creation time) - updated_at: TIMESTAMPZ (Last profile update time) app_logs table schema: - id: uuid (Primary Key) - user_id: UUID (Foreign Key to auth.users.id - allows logging before user_profile creation) - log_type: TEXT (Type of log entry, e.g., 'sign_up') - message: TEXT (Log message describing the event) - origin: TEXT (Always 'app' for application logs) - created_at: TIMESTAMPZ (Log entry creation time) - updated_at: TIMESTAMPZ (Last update time for status changes)

Signup Logging Flow

Stage Log Message Action
Initial Signup "Waiting for email confirmation" INSERT new log entry
Email Confirmed "Email confirmed and account created successfully" UPDATE existing log entry
Profile Creation Failed "Failed to create user profile: [error details]" UPDATE existing log entry

๐Ÿ”‘ Authentication Methods

1. Email/Password Authentication

Enhanced Sign Up Flow with Unlinked User Cleanup:

  1. User enters: First Name, Last Name, Email, Password, Phone, Country
  2. ๐Ÿ” Pre-flight Checks:
    • Check if email exists in user_profile table
    • If yes: Show "Email already registered" error
    • If no: Check for unlinked auth users
  3. ๐Ÿงน Unlinked User Cleanup:
    • Detect auth users without matching user_profile
    • Call delete-unlinked-user edge function
    • Wait 500ms for cleanup completion
  4. โœจ Fresh Signup:
    • Creates new auth.users record (pending confirmation)
    • Sends confirmation email with redirect link
    • Shows green "Check your email" message
  5. ๐Ÿ”„ Email Confirmation Polling:
    • Polls every 3 seconds for confirmation (up to 5 minutes)
    • Attempts sign-in with provided credentials
    • Once successful: Creates user_profile record
  6. ๐ŸŽ‰ Account Activation:
    • Shows "Processing account..." dialog
    • Creates user_profile with full data
    • Updates local JSON cache
    • Navigates to home screen with welcome dialog
๐Ÿ› ๏ธ Unlinked User Detection Logic:
  • Step 1: Check if user_profile exists for email โ†’ If yes, no cleanup needed
  • Step 2: Try dummy sign-in with email + random password
  • Step 3: If error = "invalid_credentials" โ†’ Unlinked auth user found
  • Step 4: If error = "user not found" โ†’ No unlinked user
  • Step 5: Call edge function to delete unlinked auth user safely
Enhanced Sign Up Implementation:
  • โœ… Validates email doesn't exist in user_profile table
  • โœ… Automatically cleans up unlinked auth users before signup
  • โœ… Creates fresh auth user with proper confirmation flow
  • โœ… Stores comprehensive user data (name, phone, country)
  • โœ… Handles both same-password and different-password scenarios
  • โœ… Ensures confirmation emails are sent properly

๐Ÿ”„ Authentication States & Flows

Login Process

Scenario User Experience Backend Process
Valid Credentials Immediate login and redirect to home Auth token created, user profile loaded
Invalid Email Error: "Please enter a valid email" Validation fails client-side
Wrong Password Error: "Invalid login credentials" Supabase auth rejection
Unconfirmed Email Error: "Email not confirmed" Auth blocked until confirmation
No Internet Uses cached profile if available Offline mode activated
Unlinked Auth User Signup appears to fail initially Automatic cleanup โ†’ fresh signup succeeds
Unlinked User Profile Signup succeeds normally Self-healing: updates existing profile with new auth ID

Email Confirmation Process

Confirmation Email Polling:

  • Polls every 3 seconds to check if email is confirmed
  • Attempts to sign in with provided credentials
  • Once successful, cancels the polling timer
  • Creates user profile in database
  • Navigates to home screen
  • Maximum polling duration: 5 minutes
Rate Limiting: Email resend is limited to once per 60 seconds to comply with Supabase rate limits. The UI shows a countdown timer during this period.

๐Ÿ” Password Reset Flow

Forgot Password Process

  1. Email Verification: System first checks if email exists in database
  2. Send Reset Link: If email exists, sends password reset email
  3. User Clicks Link: Opens reset form in browser
  4. New Password Entry: User enters new password (min 6 characters)
  5. Password Update: Updates in auth.users table
  6. Auto Login: User automatically signed in with new password
Error Handling:
  • โŒ Email not found: "This account is not currently registered"
  • โŒ Rate limit exceeded: "Too many requests, please wait 60 seconds"
  • โŒ Same password: "New password must be different from old password"
Password Reset Implementation:
  • First verifies the email exists in the database
  • If not found, shows "Account not registered" error
  • If found, sends password reset email via Supabase
  • Email contains link to reset password page
  • Rate limited to prevent abuse

๐Ÿ“Š Data Storage & Management

User Data Storage Locations

๐Ÿ—„๏ธ Supabase Database

  • Authentication credentials (auth.users)
  • User profile - name, email (public.user)

๐Ÿ’พ SharedPreferences

  • user_id
  • is_new_user flag
  • cached_user_profile
  • pending_email (during confirmation)

๐Ÿ“ JSON Reference

  • user_profile.json

Profile Caching Strategy

How Profile Caching Works:
  • User profile is saved to SharedPreferences as JSON
  • Cached profile is loaded when app starts
  • Enables offline access to user data
  • Updates cache whenever profile changes
  • Returns cached data when network is unavailable

๐Ÿ›ก๏ธ Security Features

๐Ÿ”’ Password Security

  • Minimum 6 characters required
  • Encrypted using bcrypt
  • Never stored in plain text
  • Confirmation required for signup

โœ‰๏ธ Email Verification

  • Required for new accounts
  • Confirmation link expires in 24 hours
  • Resend limited to 60-second intervals
  • Deep link support for mobile

๐Ÿ” Session Management

  • JWT tokens for authentication
  • Automatic token refresh
  • Secure storage in Supabase
  • Session persistence across app restarts

๐Ÿšซ Rate Limiting

  • Email operations: 60-second cooldown
  • Login attempts: Protected by Supabase
  • API calls: Automatic retry with backoff
  • Prevention of brute force attacks

โš ๏ธ Error Handling

Common Error Scenarios

Error Type User Message Resolution
Network Error "Unable to connect. Please check your internet connection" Retry button provided, offline mode activated
Duplicate Email "This email is already registered" Suggest sign-in instead of sign-up
Invalid Credentials "Invalid login credentials" Clear password field, show forgot password link
Rate Limit "Too many requests. Please wait X seconds" Show countdown timer, disable action button
Email Not Confirmed "Please check your email to confirm your account" Show resend button with cooldown
Unlinked Auth Cleanup Transparent to user (background process) Edge function deletes auth user, allows fresh signup
Edge Function Error Signup continues normally Cleanup fails gracefully, doesn't block user flow
Email Send Rate Limit "For security purposes, you can only request this after X seconds" Cleanup skipped, fresh signup attempted anyway

Debouncing & Duplicate Prevention

How Duplicate Prevention Works:
  • Tracks last authenticated user ID and timestamp
  • Ignores duplicate auth changes within 2 seconds
  • Prevents multiple navigation attempts
  • Ensures stable authentication flow

๐Ÿš€ Special Features

Welcome Flow for New Users

  1. New user completes sign-up
  2. is_new_user flag set to true
  3. Free trial plan automatically assigned
  4. Welcome dialog shown on first login
  5. Onboarding guide available

Deep Link Support

Platform Deep Link Format Usage
Android io.lucidflow://login-callback Email confirmation redirect
iOS (future) io.lucidflow://login-callback Email confirmation redirect
Web (future) https://hypno-56118.web.app/ Standard web URLs

Offline Mode Support

Offline Capabilities:
  • โœ… Access previously loaded user profile
  • โœ… Play downloaded audio content
  • โœ… View course information
  • โŒ Cannot make new purchases
  • โŒ Cannot change account settings

๐Ÿ“ Implementation Files

File Purpose
lib/screens/login_screen.dart Login/Signup UI, form validation, user interaction
lib/screens/forgot_password_screen.dart Password reset UI and flow management
lib/providers/user_provider.dart State management, auth logic, profile caching, email confirmation polling
lib/services/supabase_service.dart Supabase API calls, database operations, unlinked user detection & cleanup
lib/models/user_profile.dart User data model and JSON serialization
supabase/functions/delete-unlinked-user/index.ts Edge function for safely deleting unlinked auth users with admin privileges

๐ŸŽฏ Summary

The Hypnoelp authentication system provides a robust, secure, and user-friendly authentication experience with:

๐ŸŽ‰ Key Achievement: The system handles all edge cases gracefully, including unlinked auth users, unlinked profiles, network failures, duplicate accounts, rate limiting, and email confirmation delays. The new cleanup mechanisms ensure data consistency and prevent signup failures, providing a seamless user experience across all scenarios.
๐Ÿ”ง Recent Enhancements:
  • Unlinked User Cleanup: Automatically detects and removes auth users without corresponding profiles
  • Edge Function Integration: Server-side cleanup with admin privileges for secure operations
  • Enhanced Data Collection: Full user profiles with names, phone numbers, and country information
  • Self-Healing Architecture: Handles both auth-without-profile and profile-without-auth scenarios
  • Robust Error Recovery: Graceful fallbacks when cleanup operations fail