Auth stripped to a hardcoded stub, then partially rebuilt on Supabase JWT

clapointe-carbonleo gutted upstream auth in one commit, re-added a real login page in a second, then restored JWT verification in a third - but never fixed the backend access helpers. The result is a codebase where users authenticate with real tokens but every authorization check returns true for every request.

securitymulti-tenant

The first commit (e6568f8) is a single-tenant kiosk move: requireAuth stops calling Supabase and sets res.locals.userId = 'internal' unconditionally. The login and signup pages are deleted. AuthContext becomes a constant. And backend/src/lib/access.ts - the module that checks project ownership and shared-with membership - is rewritten so every function returns { ok: true, isOwner: true } regardless of inputs. The commit message says "all users 'internal' for now," making the placeholder intent explicit, though it also bundles an unrelated SQL change adding a workflow jsonb column to chat_messages.

A few hours later, 2217a5d adds a functional login page: email/password form with Carbonleo branding (#292629 background, #FEEA0F accent), AuthContext wired to supabase.auth.onAuthStateChange, layout redirecting unauthenticated users to /login. Then fffe4396 restores JWT verification in requireAuth via createServerSupabase().auth.getUser(token), so real user IDs flow through again.

The problem: access.ts was never restored. After fffe4396, the backend correctly identifies who is logged in, then hands every project and document to every authenticated user anyway. checkProjectAccess, ensureDocAccess, ensureReviewAccess, and listAccessibleProjectIds all still return hardcoded success. In a single-tenant internal deployment that may be fine; in any multi-user setup it is a straightforward authorization bypass, not a placeholder.

The login page UI in 2217a5d is reusable if you want a Supabase email/password flow with custom branding. The auth-stripping commit is not. Anyone considering fffe4396 should also restore the ownership and sharing logic from upstream or write their own, or they will ship authenticated-but-unscoped data access.

So what Skip unless you specifically want the branded login page from `2217a5d`. Treat the whole arc as a signal about how carefully this fork is being maintained: a critical authorization bug was introduced and partially obscured by the surrounding commit activity, and remains unfixed as of these commits.

View this fork on GitHub →

Spotted something wrong? Or know the PR text has fresher detail than the writeup above?

Commits in this thread

3 commits from clapointe-carbonleo/mike-legal, oldest first. Source extracted verbatim from the harvested git log.

SHA Subject Author Date
e6568f87 feat(mike): ic - remove auth - fix sql - all users 'internal' for now clapointe-carbonleo 2026-05-06 ↗ GitHub
2217a5df Add Supabase email/password authentication clapointe-carbonleo 2026-05-06 ↗ GitHub
commit body
- AuthContext now uses real Supabase session (onAuthStateChange)
- (pages) layout redirects to /login when not authenticated
- Login page with Carbonleo brand styling (dark bg, yellow CTA)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
fffe4396 Validate real Supabase JWT in requireAuth middleware clapointe-carbonleo 2026-05-06 ↗ GitHub
commit body
Replaces hardcoded 'internal' userId with the actual Supabase user ID
extracted from the Bearer token sent by the frontend. Each user now has
their own isolated data in the database.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

Capture this thread into my fork

Download a single Markdown prompt that tells Claude how to port every commit above into your working tree — adapting paths and structure to match your repo. Run it via claude -p < capture-thread-8.md from inside the repo you want the changes in.

⬇ Download capture-thread-8.md