Auth & Security

Authentication Flows & Security Guardrails

Kononia delegates authentication to **Supabase Auth** and implements strict client-side routing guards to guarantee data isolation and security.

Authentication Flows & Security Guardrails

Kononia delegates authentication to Supabase Auth and implements strict client-side routing guards to guarantee data isolation and security.


1. Authentication Methods

  • Email & Password: Standard sign-up and sign-in. Emails require verification if enabled in Supabase provider settings.
  • Google OAuth: Third-party federated identity provider. Integrates automatically, inserting a new profile into the database upon first successful verification.
  • Session Restoration: Handled automatically via supabase.auth.onAuthStateChange in AuthContext.tsx.

2. Platform Admins vs Tenant Users

  • Platform Administration: Access to /platform is strictly limited to emails registered in the platform.platform_admins table.
  • Dual-Enrollment Prevention: A trigger (block_tenant_signup_for_platform_admin) prevents platform admin emails from signing up as standard tenant users in public organizations, protecting administrative credentials.

3. Invitation System (pending_invites)

When a church administrator registers a new user or member, they can dispatch an invitation.

sequenceDiagram
    participant Admin as Church Admin
    participant DB as Postgres Database
    participant User as Invited User
    Admin->>DB: Inserts invite (email, role, person_id)
    User->>DB: Registers account via /auth
    DB->>DB: Claims invite matching email (claims = true)
    DB->>DB: Links user to organization & roles
    User->>DB: Accesses org dashboard

Claim Logic

  1. Invite Seeding: The admin creates a record in public.pending_invites containing the target email, the target person_id in CRM, and the assigned platform role.
  2. Registration Correlation: When a new user registers with the matching email, the client checks pending_invites for uncollected claims (claimed = false).
  3. Trigger Resolution: Upon matching, the system:
    • Updates the invite status to claimed = true.
    • Links profiles.organization_id to the inviting organization.
    • Links the auth user’s ID to the CRM’s people.linked_user_id.
    • Inserts the corresponding roles into public.user_church_roles.

4. Frontend Route Guards

To enforce logical setups, the React application wraps route hierarchies inside custom protection guards:

[Public Route] (/auth, /forgot-password, /reset-password)

       ▼ (User authenticates successfully)
[Protected Route Wrapper]

       ├──► WelcomeGuard (Checks if profiles.organization_id IS NULL)
       │         │
       │         └──► YES: Redirects user to /welcome (Force org setup)

       └──► OnboardingGuard (Checks if profiles.has_onboarded IS FALSE)

                 └──► YES: Redirects user to /onboarding (Force profile completion)
  • ProtectedRoute: Rejects unauthenticated sessions, bouncing visitors back to /auth.
  • WelcomeGuard: Evaluates whether the authenticated profile has an associated organization. If organization_id is null, the user is redirected to /welcome to create or join a church.
  • OnboardingGuard: Evaluates the has_onboarded flag on profiles. If false, the user is routed to /onboarding to fill out their basic biographical data.