From 46481211ecf4ac04150100c4d248015866878319 Mon Sep 17 00:00:00 2001 From: Michael Date: Mon, 25 May 2026 21:39:02 -0700 Subject: [PATCH] fix(07): skip auth+setup paths in /api/* catch-all MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Regression introduced by Phase 07 merge: /api/auth/* and /api/setup were mounted before the JWT catch-all but the catch-all's skip list never listed them. Result: prod auth was returning 401 Unauthorized on /api/auth/login/request-link, /api/auth/me, /api/auth/login/callback — breaking every magic-link login attempt. Same fix applied to the license-gate middleware that immediately follows authMiddleware. Co-Authored-By: Claude Opus 4.7 (1M context) --- hub/src/index.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/hub/src/index.ts b/hub/src/index.ts index acc8288..b332e67 100644 --- a/hub/src/index.ts +++ b/hub/src/index.ts @@ -157,6 +157,11 @@ app.use('/api/*', async (c, next) => { if (c.req.path === '/api/github/callback') return next() if (c.req.path.startsWith('/api/sentry/')) return next() if (c.req.path.startsWith('/api/coolify/webhook/')) return next() + // Phase 07: public auth endpoints (login request-link, callback, logout, me). + // The authRouter handles its own auth state internally where needed. + if (c.req.path.startsWith('/api/auth/')) return next() + // Public setup bootstrap (guarded by user-count check inside). + if (c.req.path.startsWith('/api/setup')) return next() return authMiddleware(c, next) }) app.use('/api/*', rateLimit({ windowMs: 60_000, max: 120, keyFn: (c) => c.get('userId') || 'anon' })) @@ -171,6 +176,8 @@ app.use('/api/*', async (c, next) => { if (c.req.path === '/api/github/callback') return next() if (c.req.path.startsWith('/api/sentry/')) return next() if (c.req.path.startsWith('/api/coolify/webhook/')) return next() + if (c.req.path.startsWith('/api/auth/')) return next() + if (c.req.path.startsWith('/api/setup')) return next() return requireActiveLicense({ readOnlyOk: true })(c, next) })