BetterAuth Integration Summary

Overview

The authentication system uses BetterAuth for centralized identity management. This provides better ownership of user data, consistent session management across web and mobile, and more flexible authentication flows.

What Was Implemented

1. Auth Client (frontend/astro/apps/platform/src/lib/auth.ts)

  • Initialization: Configured better-auth/client with baseURL: "/api/auth".
  • Plugins: Enabled anonymousClient, adminClient, and organizationClient.
  • Enhanced Utilities:
    • Auth Methods: signUp, signIn, signOut, getSession wrapped in try-catch.
    • Admin Management: Added adminCreateUser, adminSetRole, and adminRemoveUser for platform administration.
    • Organization Management: Added createOrganization, inviteMember, updateMemberRole, and removeMember utilities.
    • Error Mapping: Centralized mapAuthError function converts BetterAuth/Network errors into user-friendly messages.
    • Logging: Server-side error logging enabled using import.meta.env.SSR.
    • Network Resilience: Handles fetch failures and timeouts gracefully.

2. Role Structure

  • Platform Roles: user, admin, superadmin (stored in the main user table).
  • Organization Roles: owner, admin, staff, member, viewer (stored in the multi-tenant member table).
  • Middleware: Correctly exposes both hasRole(platformRole) and hasOrgRole(orgRole) helpers via Astro.locals.auth.

3. Authenticated API Client (frontend/astro/apps/platform/src/lib/api.ts)

  • 401 Retry Logic: Automatic session refresh when a 401 Unauthorized is encountered.
  • Global Helper: Centralized headers management supporting both client-side and SSR contexts.
  • Domain Methods: Restored all leave management methods (getLeaveBalances, createLeaveRequest, etc.) using the authenticated wrapper.

3. Middleware & SSR Auth (frontend/astro/apps/platform/src/middleware.ts)

  • Session Validation: Uses BETTER_AUTH_SECRET to validate the better-auth.session_token cookie.
  • Local Context: Populates Astro.locals.auth with user metadata if a valid session exists.
  • Protected Routes: Logic implemented to redirect unauthenticated users from /dashboard/* to /sign-in.

4. UI Components Integration

  • Auth Forms: SignUpForm.tsx, SignInForm.tsx, and SignInAnonymous.tsx updated to use the new authClient.
  • Session Sync: Implemented client-side sync in AppLayout.astro to ensure the session token is available in window.__BETTER_AUTH_TOKEN__ for SPA requests.

How It Works (401 Retry Flow)

1

Frontend Call

Frontend calls api.getLeaveBalances().
2

401 Occurs

Request fails with 401 (Token Expired).
3

Catch & Refresh

ApiClient catches 401 and calls authClient.getSession() to refresh the cookie.
4

Retry Success

If successful, the original request is retried with the updated token.
5

Fallback

If refresh fails, the user is redirected to /sign-in.

Environment Variables Required

VariableDescriptionLocation
PUBLIC_API_URLRoot URL for the backend API.env
BETTER_AUTH_SECRETSecret key for JWT signing.env.local
BETTER_AUTH_URLThe public URL of the frontend.env.local