import "server-only"; import { parseBearerAccessKey } from "@/lib/access-keys/token"; import { authenticateUserAccessKey, type AccessKeyPrincipal, type AccessKeyScope, } from "@/lib/access-keys/service"; export class OpenApiAuthError extends Error { status: number; code: string; constructor(message: string, status: number, code: string) { super(message); this.name = "OpenApiAuthError"; this.status = status; this.code = code; } } export async function requireOpenApiPrincipal( request: Request, requiredScope?: AccessKeyScope ): Promise { const token = parseBearerAccessKey(request.headers.get("authorization")); if (!token) { throw new OpenApiAuthError( "Missing or invalid Bearer Access Key", 401, "ACCESS_KEY_REQUIRED" ); } const principal = await authenticateUserAccessKey(token); if (!principal) { throw new OpenApiAuthError( "Access Key is invalid, expired, or revoked", 401, "ACCESS_KEY_INVALID" ); } if (requiredScope && !principal.scopes.includes(requiredScope)) { throw new OpenApiAuthError( `Access Key is missing scope: ${requiredScope}`, 403, "ACCESS_KEY_SCOPE_REQUIRED" ); } return principal; } export function openApiErrorResponse(error: unknown) { if (error instanceof OpenApiAuthError) { return Response.json( { success: false, error: error.message, code: error.code }, { status: error.status } ); } return Response.json( { success: false, error: "OpenAPI request failed", code: "OPENAPI_ERROR" }, { status: 500 } ); }