import type { LookupFn } from "@hanzo/bot/plugin-sdk/tlon"; import { SsrFBlockedError } from "@hanzo/bot/plugin-sdk/tlon"; import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; import { authenticate } from "./auth.js"; describe("tlon urbit auth ssrf", () => { beforeEach(() => { vi.unstubAllGlobals(); }); afterEach(() => { vi.unstubAllGlobals(); }); it("blocks private IPs by default", async () => { const mockFetch = vi.fn(); vi.stubGlobal("fetch", mockFetch); await expect(authenticate("http://127.0.0.1:8080", "code")).rejects.toBeInstanceOf( SsrFBlockedError, ); expect(mockFetch).not.toHaveBeenCalled(); }); it("allows private IPs when allowPrivateNetwork is enabled", async () => { const mockFetch = vi.fn().mockResolvedValue({ ok: true, status: 200, text: async () => "ok", headers: new Headers({ "set-cookie": "urbauth-~zod=123; Path=/; HttpOnly", }), }); vi.stubGlobal("fetch", mockFetch); const lookupFn = (async () => [{ address: "127.0.0.1", family: 4 }]) as unknown as LookupFn; const cookie = await authenticate("http://127.0.0.1:8080", "code", { ssrfPolicy: { allowPrivateNetwork: true }, lookupFn, }); expect(cookie).toContain("urbauth-~zod=123"); expect(mockFetch).toHaveBeenCalled(); }); });