diff --git a/.claude/settings.local.json b/.claude/settings.local.json index 5e51b2d..72e3c4e 100644 --- a/.claude/settings.local.json +++ b/.claude/settings.local.json @@ -14,7 +14,9 @@ "Bash(az webapp config appsettings list:*)", "Bash(node:*)", "Bash(python3:*)", - "Bash(echo:*)" + "Bash(echo:*)", + "Bash(git -C ka-note check-ignore .env)", + "Bash(git -C . check-ignore ka-note/.env)" ] } } diff --git a/ka-note/.env.example b/ka-note/.env.example index 46814c9..f896b3a 100644 --- a/ka-note/.env.example +++ b/ka-note/.env.example @@ -1,6 +1,9 @@ AZURE_CLIENT_ID= AZURE_TENANT_ID= +# Set to true for local dev to skip JWT verification (never use in production) +# DEV_AUTH_BYPASS=true + # Client needs VITE_ prefix — create client/.env with: # VITE_AZURE_CLIENT_ID= # VITE_AZURE_TENANT_ID= diff --git a/ka-note/server/ka-note.db-shm b/ka-note/server/ka-note.db-shm index b1bb41a..52d4c43 100644 Binary files a/ka-note/server/ka-note.db-shm and b/ka-note/server/ka-note.db-shm differ diff --git a/ka-note/server/ka-note.db-wal b/ka-note/server/ka-note.db-wal index e7888d0..fbff5e8 100644 Binary files a/ka-note/server/ka-note.db-wal and b/ka-note/server/ka-note.db-wal differ diff --git a/ka-note/server/package.json b/ka-note/server/package.json index 4beadd1..bae9e7d 100644 --- a/ka-note/server/package.json +++ b/ka-note/server/package.json @@ -4,7 +4,7 @@ "private": true, "type": "module", "scripts": { - "dev": "node --watch --import tsx/esm src/index.ts", + "dev": "node --env-file=../.env --watch --import tsx/esm src/index.ts", "build": "tsc", "start": "node dist/index.js", "db:generate": "drizzle-kit generate", diff --git a/ka-note/server/src/middleware/auth.ts b/ka-note/server/src/middleware/auth.ts index 407aa59..078ebef 100644 --- a/ka-note/server/src/middleware/auth.ts +++ b/ka-note/server/src/middleware/auth.ts @@ -13,14 +13,22 @@ export type AuthEnv = { const clientId = process.env.AZURE_CLIENT_ID ?? ''; const tenantId = process.env.AZURE_TENANT_ID ?? ''; +const devBypass = process.env.DEV_AUTH_BYPASS === 'true'; const jwksUrl = `https://login.microsoftonline.com/${tenantId}/discovery/v2.0/keys`; const issuerV2 = `https://login.microsoftonline.com/${tenantId}/v2.0`; const issuerV1 = `https://sts.windows.net/${tenantId}/`; -const JWKS = createRemoteJWKSet(new URL(jwksUrl)); +const JWKS = devBypass ? null : createRemoteJWKSet(new URL(jwksUrl)); export const authMiddleware = createMiddleware(async (c, next) => { + if (devBypass) { + console.warn('[auth] DEV_AUTH_BYPASS active — skipping JWT verification'); + c.set('auth', { userId: 'dev-user', name: 'Dev User', email: 'dev@localhost' }); + await next(); + return; + } + const authHeader = c.req.header('Authorization'); if (!authHeader?.startsWith('Bearer ')) { return c.json({ error: 'Missing or invalid Authorization header' }, 401); @@ -28,7 +36,7 @@ export const authMiddleware = createMiddleware(async (c, next) => { const token = authHeader.slice(7); try { - const { payload } = await jwtVerify(token, JWKS, { + const { payload } = await jwtVerify(token, JWKS!, { issuer: [issuerV2, issuerV1], audience: `api://${clientId}`, });