Skip to content

feat(auth): migrate authentication layer to Supabase#5

Merged
cH0NKIIs34L merged 5 commits intomainfrom
feat/supabase-auth-migration
Apr 9, 2026
Merged

feat(auth): migrate authentication layer to Supabase#5
cH0NKIIs34L merged 5 commits intomainfrom
feat/supabase-auth-migration

Conversation

@cH0NKIIs34L
Copy link
Copy Markdown
Member

Summary

Replace the Express/JWT/Passport auth stack with Supabase Auth so the
client handles authentication directly without a backend relay layer.

What Changed

  • client/src/modules/api/auth/auth.api.js — rewrote all four methods
    (signup, login, logout, checkStatus) to use Supabase Auth SDK directly
  • client/src/providers/AuthProvider/AuthProvider.jsx — replaced
    fetch-based session polling with onAuthStateChange subscription and
    public.users profile fetch on SIGNED_IN
  • client/src/components/Forms/LoginForm/LoginForm.jsx — updated to
    consume { error } from AuthProvider.login() and added isSubmitting state
  • client/src/components/Forms/SignupForm/SignupForm.jsx — updated to
    consume { error } from authApi.signup() and added isSubmitting state

What

This PR replaces the entire client-side auth layer — authApi, AuthProvider,
LoginForm, and SignupForm — with equivalents that talk directly to Supabase
Auth instead of the Express backend.

Why

The migration to Supabase makes the Express auth endpoints (sign-up,
log-in, log-out, /me) redundant. Keeping the old fetch-based auth
layer would leave the app broken once those endpoints are removed in
Epic 4 (server cleanup), so auth must be migrated first.

How

  • authApi now wraps Supabase SDK methods instead of fetch — the public
    surface (signup, login, logout, checkStatus) is preserved so callers
    need minimal changes
  • Username-to-email mapping uses the username@app.local convention
    since Supabase Auth requires an email; username is stored in
    user_metadata so the DB trigger can populate public.users
  • AuthProvider subscribes to onAuthStateChange on mount and
    unsubscribes on unmount — this replaces the manual checkAuthStatus
    poll and means the client reacts to session changes in real time
  • On SIGNED_IN, the provider fetches the user's public.users row to
    get username and role, since Supabase Auth itself only holds email
  • getSession() is called on mount to rehydrate from localStorage before
    the first auth event fires, preventing a flash of unauthenticated state
  • AuthProvider.login() is now the single call site for sign-in in
    LoginForm — the form no longer calls authApi directly, keeping the
    sign-in flow consistent with how logout and session sync work
  • Both forms now track isSubmitting to disable the submit button during
    async calls, preventing duplicate submissions
  • response.ok / response.json() patterns are fully removed from both
    forms — all error handling now reads from { error } returned by the
    Supabase SDK

Pre-Merge Checklist

  • Synced with main before opening this PR
  • All tests pass locally (npm test in both client/ and server/)
  • No console.log left in production code
  • Self-reviewed my own diff before requesting review
  • Added or updated tests for the changes made
  • No new ESLint errors (npm run lint)

The existing pull request prompt and template contained formatting
inconsistencies that led to repetitive output and overlapping
sections. This refinement streamlines the structure to ensure a
clearer distinction between high-level summaries and implementation-
specific details.

This change updates the guidance for the 'How' and 'Testing' sections
to prevent redundant information while ensuring reviewers get the
necessary implementation context for efficient code reviews.
The `package.json` files for both the client and server were updated
in a previous commit, but the corresponding `package-lock.json` files
were not included. This creates a mismatch between the manifest and
the locked dependency tree.

This change synchronizes the lockfiles to ensure consistent installs
across development and deployment environments, reflecting the
recently added Supabase and testing dependencies.
The existing authApi made fetch calls to Express auth endpoints
that will no longer exist after the server cleanup. This replaces
all four methods with direct Supabase Auth SDK calls so the client
handles auth without a backend relay.
The previous AuthProvider called a custom Express /api/auth/me
endpoint on mount and managed JWT state manually. This replaces
it with a Supabase onAuthStateChange subscription that keeps the
client in sync with Supabase Auth automatically, and fetches the
user's public.users profile row on SIGNED_IN to expose role data.
Both forms previously used fetch-based response patterns tied to
the Express auth API. This updates them to consume the { data,
error } shape returned by the new Supabase-backed authApi and
AuthProvider, and removes all Express-specific patterns.
@cH0NKIIs34L cH0NKIIs34L added enhancement New feature or request chore breaking labels Apr 9, 2026
@cH0NKIIs34L cH0NKIIs34L merged commit 7e21f4d into main Apr 9, 2026
0 of 2 checks passed
@cH0NKIIs34L cH0NKIIs34L deleted the feat/supabase-auth-migration branch April 9, 2026 09:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

breaking chore enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant