import type Elysia from "elysia"; import { auth } from "@/utils/auth"; import { prisma } from "@/utils/db"; import logger from "@/utils/logger"; export function apiMiddleware(app: Elysia) { return app .derive(async ({ request }) => { const headers = request.headers; // First, try to get user from session (Better Auth) const userSession = await auth.api.getSession({ headers, }); if (userSession?.user) { // Return user data from session if authenticated via session return { user: { ...userSession.user, id: userSession.user.id, email: userSession.user.email, name: userSession.user.name, image: userSession.user.image, emailVerified: userSession.user.emailVerified, role: userSession.user.role || "user", }, }; } // If no session, try API key authentication let apiKey = headers.get("x-api-key"); if (!apiKey) { // Also check Authorization header for API key const authHeader = headers.get("authorization") || headers.get("Authorization"); if (authHeader?.startsWith("Bearer ")) { apiKey = authHeader.substring(7); } } if (!apiKey) { return { user: null }; } try { // Look up the API key in the database const apiKeyRecord = await prisma.apiKey.findFirst({ where: { key: apiKey, isActive: true, }, include: { user: true, // Include the associated user }, }); if (!apiKeyRecord) { return { user: null }; } // Check if API key has expired if ( apiKeyRecord.expiresAt && new Date(apiKeyRecord.expiresAt) < new Date() ) { logger.info({ keyId: apiKeyRecord.id }, "[AUTH] API key expired"); return { user: null }; } // Return the associated user data return { user: { id: apiKeyRecord.user.id, email: apiKeyRecord.user.email, name: apiKeyRecord.user.name, image: apiKeyRecord.user.image, emailVerified: apiKeyRecord.user.emailVerified, role: apiKeyRecord.user.role || "user", }, }; } catch (err) { logger.warn({ err }, "[AUTH] Error verifying API key"); return { user: null }; } }) .onBeforeHandle(({ user, set, request }) => { const url = new URL(request.url); if (url.pathname.startsWith("/api/docs")) { return; } if (!user) { logger.warn(`[AUTH] Unauthorized: ${request.method} ${request.url}`); set.status = 401; return { message: "Unauthorized" }; } }); }