Files
GearBox/src/server/middleware/auth.ts
Jean-Luc Makiola e044547121
Some checks failed
CI / ci (push) Failing after 1m41s
CI / e2e (push) Has been skipped
CI / deploy (push) Has been skipped
chore: fix lint errors — auto-format, isNaN, unused imports, button type
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-19 22:54:37 +02:00

67 lines
1.9 KiB
TypeScript

import { eq } from "drizzle-orm";
import type { Context, Next } from "hono";
import { users } from "../../db/schema.ts";
import { getOrCreateUser, verifyApiKey } from "../services/auth.service";
import { getOrCreateUncategorized } from "../services/category.service";
import { verifyAccessToken } from "../services/oauth.service";
export async function requireAuth(c: Context, next: Next) {
const db = c.get("db");
// Check API key first
const apiKey = c.req.header("X-API-Key");
if (apiKey) {
const result = await verifyApiKey(db, apiKey);
if (result) {
c.set("userId", result.userId);
return next();
}
return c.json({ error: "Invalid API key" }, 401);
}
// Check OAuth Bearer token
const authHeader = c.req.header("Authorization");
if (authHeader?.startsWith("Bearer ")) {
const token = authHeader.slice(7);
const result = await verifyAccessToken(db, token);
if (result) {
c.set("userId", result.userId);
return next();
}
return c.json({ error: "Invalid or expired token" }, 401);
}
// Check OIDC session (browser users via Logto)
try {
const { getAuth } = await import("@hono/oidc-auth");
const auth = await getAuth(c);
if (auth?.sub) {
const user = await getOrCreateUser(db, auth.sub);
await getOrCreateUncategorized(db, user.id);
c.set("userId", user.id);
return next();
}
} catch (err) {
console.error("[auth] OIDC auth failed:", err);
// OIDC not configured or session invalid — fall through
}
return c.json({ error: "Authentication required" }, 401);
}
export async function requireAdmin(c: Context, next: Next) {
const db = c.get("db");
const userId = c.get("userId");
if (!userId) {
return c.json({ error: "Authentication required" }, 401);
}
const [user] = await db
.select({ isAdmin: users.isAdmin })
.from(users)
.where(eq(users.id, userId));
if (!user?.isAdmin) {
return c.json({ error: "Forbidden" }, 403);
}
return next();
}