| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| import test from "node:test";
|
| import assert from "node:assert/strict";
|
| import { createOmniRouteAuthHook, createOmniRouteFetchInterceptor } from "../src/index.js";
|
|
|
| type FetchCall = { input: Parameters<typeof fetch>[0]; init?: RequestInit };
|
|
|
| function installFetchRecorder(response: Response = new Response("ok")) {
|
| const calls: FetchCall[] = [];
|
| const original = globalThis.fetch;
|
| globalThis.fetch = (async (input: any, init?: any) => {
|
| calls.push({ input, init });
|
| return response;
|
| }) as typeof fetch;
|
| const restore = () => {
|
| globalThis.fetch = original;
|
| };
|
| return { calls, restore };
|
| }
|
|
|
| const BASE = "https://or.example.com/v1";
|
| const KEY = "sk-test-fetch";
|
|
|
| test("createOmniRouteFetchInterceptor: targets baseURL → Authorization header injected", async () => {
|
| const { calls, restore } = installFetchRecorder();
|
| try {
|
| const f = createOmniRouteFetchInterceptor({ apiKey: KEY, baseURL: BASE });
|
| await f(`${BASE}/chat/completions`, {
|
| method: "POST",
|
| body: JSON.stringify({ x: 1 }),
|
| });
|
| assert.equal(calls.length, 1);
|
| const sent = calls[0]!;
|
| const sentHeaders = new Headers((sent.init as RequestInit).headers);
|
| assert.equal(sentHeaders.get("Authorization"), `Bearer ${KEY}`);
|
| } finally {
|
| restore();
|
| }
|
| });
|
|
|
| test("createOmniRouteFetchInterceptor: targets baseURL → Authorization OVERRIDES caller-supplied Bearer", async () => {
|
| const { calls, restore } = installFetchRecorder();
|
| try {
|
| const f = createOmniRouteFetchInterceptor({ apiKey: KEY, baseURL: BASE });
|
| await f(`${BASE}/chat/completions`, {
|
| method: "POST",
|
| body: "{}",
|
| headers: { Authorization: "Bearer attacker-key" },
|
| });
|
| const sent = calls[0]!;
|
| const sentHeaders = new Headers((sent.init as RequestInit).headers);
|
|
|
| assert.equal(sentHeaders.get("Authorization"), `Bearer ${KEY}`);
|
| } finally {
|
| restore();
|
| }
|
| });
|
|
|
| test("createOmniRouteFetchInterceptor: targets baseURL + body → Content-Type defaults to application/json", async () => {
|
| const { calls, restore } = installFetchRecorder();
|
| try {
|
| const f = createOmniRouteFetchInterceptor({ apiKey: KEY, baseURL: BASE });
|
| await f(`${BASE}/chat/completions`, {
|
| method: "POST",
|
| body: JSON.stringify({ m: "x" }),
|
| });
|
| const sent = calls[0]!;
|
| const sentHeaders = new Headers((sent.init as RequestInit).headers);
|
| assert.equal(sentHeaders.get("Content-Type"), "application/json");
|
| } finally {
|
| restore();
|
| }
|
| });
|
|
|
| test("createOmniRouteFetchInterceptor: caller-set Content-Type is NOT overwritten", async () => {
|
| const { calls, restore } = installFetchRecorder();
|
| try {
|
| const f = createOmniRouteFetchInterceptor({ apiKey: KEY, baseURL: BASE });
|
| await f(`${BASE}/v2/whatever`, {
|
| method: "POST",
|
| body: "raw",
|
| headers: { "Content-Type": "text/plain; charset=utf-8" },
|
| });
|
| const sent = calls[0]!;
|
| const sentHeaders = new Headers((sent.init as RequestInit).headers);
|
| assert.equal(sentHeaders.get("Content-Type"), "text/plain; charset=utf-8");
|
| } finally {
|
| restore();
|
| }
|
| });
|
|
|
| test("createOmniRouteFetchInterceptor: non-baseURL host → passthrough, no Authorization injected", async () => {
|
| const { calls, restore } = installFetchRecorder();
|
| try {
|
| const f = createOmniRouteFetchInterceptor({ apiKey: KEY, baseURL: BASE });
|
| await f("https://third-party.example.org/v1/chat", {
|
| method: "POST",
|
| body: "{}",
|
| headers: { "X-Caller": "yes" },
|
| });
|
| const sent = calls[0]!;
|
|
|
| const sentHeaders = new Headers((sent.init as RequestInit | undefined)?.headers);
|
| assert.equal(sentHeaders.get("Authorization"), null, "MUST NOT leak apiKey");
|
| assert.equal(sentHeaders.get("X-Caller"), "yes");
|
| } finally {
|
| restore();
|
| }
|
| });
|
|
|
| test("createOmniRouteFetchInterceptor: refuses suffix-spoof — `${base}-attacker.evil` does NOT match baseURL", async () => {
|
| const { calls, restore } = installFetchRecorder();
|
| try {
|
| const f = createOmniRouteFetchInterceptor({ apiKey: KEY, baseURL: BASE });
|
|
|
|
|
|
|
| await f("https://or.example.com/v1-attacker.evil/chat", {
|
| method: "POST",
|
| body: "{}",
|
| });
|
| const sent = calls[0]!;
|
| const sentHeaders = new Headers((sent.init as RequestInit | undefined)?.headers);
|
| assert.equal(sentHeaders.get("Authorization"), null);
|
| } finally {
|
| restore();
|
| }
|
| });
|
|
|
| test("createOmniRouteFetchInterceptor: URL object input is handled", async () => {
|
| const { calls, restore } = installFetchRecorder();
|
| try {
|
| const f = createOmniRouteFetchInterceptor({ apiKey: KEY, baseURL: BASE });
|
| await f(new URL(`${BASE}/models`), {});
|
| const sent = calls[0]!;
|
| const sentHeaders = new Headers((sent.init as RequestInit).headers);
|
| assert.equal(sentHeaders.get("Authorization"), `Bearer ${KEY}`);
|
| } finally {
|
| restore();
|
| }
|
| });
|
|
|
| test("createOmniRouteFetchInterceptor: Request input is handled (reads .url)", async () => {
|
| const { calls, restore } = installFetchRecorder();
|
| try {
|
| const f = createOmniRouteFetchInterceptor({ apiKey: KEY, baseURL: BASE });
|
| const req = new Request(`${BASE}/chat/completions`, {
|
| method: "POST",
|
| body: JSON.stringify({ a: 1 }),
|
| headers: { "X-Caller": "preserved" },
|
| });
|
| await f(req);
|
| const sent = calls[0]!;
|
|
|
|
|
|
|
| const sentHeaders = new Headers((sent.init as RequestInit).headers);
|
| assert.equal(sentHeaders.get("Authorization"), `Bearer ${KEY}`);
|
| assert.equal(
|
| sentHeaders.get("X-Caller"),
|
| "preserved",
|
| "Request-attached headers must survive the merge"
|
| );
|
| } finally {
|
| restore();
|
| }
|
| });
|
|
|
| test("createOmniRouteFetchInterceptor: trailing slash in baseURL is normalized", async () => {
|
| const { calls, restore } = installFetchRecorder();
|
| try {
|
| const f = createOmniRouteFetchInterceptor({
|
| apiKey: KEY,
|
| baseURL: `${BASE}////`,
|
| });
|
| await f(`${BASE}/models`, {});
|
| const sent = calls[0]!;
|
| const sentHeaders = new Headers((sent.init as RequestInit).headers);
|
| assert.equal(sentHeaders.get("Authorization"), `Bearer ${KEY}`);
|
| } finally {
|
| restore();
|
| }
|
| });
|
|
|
| test("createOmniRouteFetchInterceptor: GET without body does NOT set Content-Type", async () => {
|
| const { calls, restore } = installFetchRecorder();
|
| try {
|
| const f = createOmniRouteFetchInterceptor({ apiKey: KEY, baseURL: BASE });
|
| await f(`${BASE}/models`);
|
| const sent = calls[0]!;
|
| const sentHeaders = new Headers((sent.init as RequestInit).headers);
|
| assert.equal(sentHeaders.get("Authorization"), `Bearer ${KEY}`);
|
| assert.equal(
|
| sentHeaders.get("Content-Type"),
|
| null,
|
| "Content-Type should only default when a body exists"
|
| );
|
| } finally {
|
| restore();
|
| }
|
| });
|
|
|
|
|
|
|
|
|
|
|
| test("loader: returns fetch fn when apiKey + baseURL both present (via opts)", async () => {
|
| const hook = createOmniRouteAuthHook({ baseURL: BASE });
|
| const result = await hook.loader!(async () => ({ type: "api", key: KEY }) as never, {} as never);
|
| assert.equal((result as { apiKey: string }).apiKey, KEY);
|
| assert.equal((result as { baseURL: string }).baseURL, BASE);
|
| assert.equal(
|
| typeof (result as { fetch?: unknown }).fetch,
|
| "function",
|
| "loader must wire fetch interceptor when baseURL resolves"
|
| );
|
| });
|
|
|
| test("loader: returns fetch fn when baseURL is stashed on the auth credential", async () => {
|
|
|
|
|
| const hook = createOmniRouteAuthHook();
|
| const result = await hook.loader!(
|
| async () => ({ type: "api", key: KEY, baseURL: BASE }) as never,
|
| {} as never
|
| );
|
| assert.equal((result as { baseURL?: string }).baseURL, BASE);
|
| assert.equal(typeof (result as { fetch?: unknown }).fetch, "function");
|
| });
|
|
|
| test("loader: omits fetch fn when baseURL missing (apiKey-only return)", async () => {
|
| const hook = createOmniRouteAuthHook();
|
| const result = await hook.loader!(async () => ({ type: "api", key: KEY }) as never, {} as never);
|
|
|
|
|
| assert.deepEqual(result, { apiKey: KEY });
|
| });
|
|
|
| test("loader integration: wired interceptor actually injects Bearer when invoked", async () => {
|
|
|
|
|
| const { calls, restore } = installFetchRecorder();
|
| try {
|
| const hook = createOmniRouteAuthHook({ baseURL: BASE });
|
| const result = await hook.loader!(
|
| async () => ({ type: "api", key: KEY }) as never,
|
| {} as never
|
| );
|
| const wiredFetch = (result as { fetch: typeof fetch }).fetch;
|
| await wiredFetch(`${BASE}/v1/models`, {});
|
| assert.equal(calls.length, 1);
|
| const sentHeaders = new Headers((calls[0]!.init as RequestInit).headers);
|
| assert.equal(sentHeaders.get("Authorization"), `Bearer ${KEY}`);
|
| } finally {
|
| restore();
|
| }
|
| });
|
|
|