mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-08-12 18:22:48 +03:00
* fix(api): enforce image generation API key auth * fix(api): align image route auth guard with clientApiPolicy The route-level guard added for image generation was stricter than the authz middleware that already fronts /api/v1/* (src/proxy.ts → clientApiPolicy), so requests the pipeline admits were 401'd by the handler: - A cookie-authenticated dashboard session was rejected under REQUIRE_API_KEY=true. The dashboard Media page (dashboard/cache/media) and the Playground call these routes with a session and no Bearer — the same mismatch already fixed for /api/playground/presets. - A presented invalid key was rejected even with REQUIRE_API_KEY=false, where clientApiPolicy (#2257) and the sibling /v1/embeddings and /v1/web/fetch routes degrade a stale CLI key to anonymous instead. Extract the shared guard into shared/utils/clientApiRouteAuth so both image routes (and future /v1 handlers) mirror the middleware contract instead of re-deriving it, and drop the now-dead auth imports. Also switch the call-log attribution fallback back to `||`: with `??`, an empty-string apiKeyId/apiKeyName would be persisted verbatim and would block the request-scoped context, which the previous `entry.apiKeyId || null` never did. Tests: cover the dashboard-session and keyless-mode-invalid-key branches, and split the auth/attribution cases into image-generation-route-auth.test.ts to stay under the 800-line new-test-file cap. Co-authored-by: Claude Opus 5 <noreply@anthropic.com> --------- Co-authored-by: alexey.nazarov@softmg.ru <alexey.nazarov@softmg.ru> Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
27 lines
841 B
TypeScript
27 lines
841 B
TypeScript
import { AsyncLocalStorage } from "node:async_hooks";
|
|
|
|
export interface CallLogApiKeyContext {
|
|
apiKeyId: string | null;
|
|
apiKeyName: string | null;
|
|
}
|
|
|
|
const callLogApiKeyContext = new AsyncLocalStorage<CallLogApiKeyContext>();
|
|
|
|
/**
|
|
* Bind API-key attribution to every call log emitted by one request.
|
|
*
|
|
* Modal handlers fan out into provider-specific helpers that write their own
|
|
* call logs. Request-scoped storage keeps that attribution available without
|
|
* threading identity parameters through every provider handler.
|
|
*/
|
|
export function runWithCallLogApiKeyContext<TResult>(
|
|
context: CallLogApiKeyContext,
|
|
callback: () => TResult
|
|
): TResult {
|
|
return callLogApiKeyContext.run(context, callback);
|
|
}
|
|
|
|
export function getCallLogApiKeyContext(): CallLogApiKeyContext | null {
|
|
return callLogApiKeyContext.getStore() ?? null;
|
|
}
|