132 lines · 4.6 KB · TypeScript
RawDownload
import { assert, describe, it } from "@effect/vitest";import * as Effect from "effect/Effect";import { beforeEach, vi } from "vite-plus/test"; const { handleMock, netFetchMock, unhandleMock } = vi.hoisted(() => ({  handleMock: vi.fn(),  netFetchMock: vi.fn(),  unhandleMock: vi.fn(),})); vi.mock("electron", () => ({  net: { fetch: netFetchMock },  protocol: { handle: handleMock, unhandle: unhandleMock },})); import * as ElectronProtocol from "./ElectronProtocol.ts"; describe("ElectronProtocol", () => {  beforeEach(() => {    handleMock.mockReset();    netFetchMock.mockReset();    unhandleMock.mockReset();  });   it.effect("proxies the stable renderer origin to the current app server", () =>    Effect.gen(function* () {      let handler: ((request: Request) => Promise<Response>) | undefined;      handleMock.mockImplementation((_scheme, nextHandler) => {        handler = nextHandler;      });      netFetchMock.mockResolvedValue(new Response("ok"));       yield* Effect.scoped(        Effect.gen(function* () {          const protocol = yield* ElectronProtocol.ElectronProtocol;          yield* protocol.registerDesktopProtocol({            scheme: "t3code-dev",            targetOrigin: new URL("http://127.0.0.1:3773/"),            backendOrigin: new URL("http://127.0.0.1:3774/"),            clerkFrontendApiHostname: "clerk.t3.codes",          });          assert.isDefined(handler);           const response = yield* Effect.promise(() =>            handler!(new Request("t3code-dev://app/api/health?verbose=1")),          );          assert.equal(yield* Effect.promise(() => response.text()), "ok");          assert.include(            response.headers.get("content-security-policy") ?? "",            "script-src 'self' 'unsafe-inline' https://clerk.t3.codes https://challenges.cloudflare.com",          );          assert.include(            response.headers.get("content-security-policy") ?? "",            "connect-src 'self' http: https: ws: wss:",          );          assert.include(            response.headers.get("content-security-policy") ?? "",            "img-src 'self' t3code-dev: blob: data: http: https:",          );          assert.include(            response.headers.get("content-security-policy") ?? "",            "font-src 'self' t3code-dev: data:",          );        }),      );       assert.deepEqual(        handleMock.mock.calls.map((call) => call[0]),        ["t3code-dev"],      );      assert.equal(netFetchMock.mock.calls[0]?.[0], "http://127.0.0.1:3773/api/health?verbose=1");      assert.deepEqual(unhandleMock.mock.calls, [["t3code-dev"]]);    }).pipe(Effect.provide(ElectronProtocol.layer)),  );   it.effect("rejects custom protocol requests for another host", () =>    Effect.gen(function* () {      let handler: ((request: Request) => Promise<Response>) | undefined;      handleMock.mockImplementation((_scheme, nextHandler) => {        handler = nextHandler;      });       const response = yield* Effect.scoped(        Effect.gen(function* () {          const protocol = yield* ElectronProtocol.ElectronProtocol;          yield* protocol.registerDesktopProtocol({            scheme: "t3code",            targetOrigin: new URL("http://127.0.0.1:3773/"),            backendOrigin: new URL("http://127.0.0.1:3773/"),            clerkFrontendApiHostname: undefined,          });          return yield* Effect.promise(() => handler!(new Request("t3code://other/")));        }),      );       assert.equal(response.status, 404);      assert.equal(netFetchMock.mock.calls.length, 0);    }).pipe(Effect.provide(ElectronProtocol.layer)),  );   it("keeps executable sources host-restricted while allowing runtime network resources", () => {    const policy = ElectronProtocol.makeDesktopContentSecurityPolicy({      scheme: "t3code",      targetOrigin: new URL("http://127.0.0.1:3773/"),      backendOrigin: new URL("http://127.0.0.1:3773/"),      clerkFrontendApiHostname: "clerk.t3.codes",    });    const directives = Object.fromEntries(      policy.split("; ").map((directive) => {        const [name, ...sources] = directive.split(" ");        return [name, sources];      }),    );     assert.deepEqual(directives["script-src"], [      "'self'",      "'unsafe-inline'",      "https://clerk.t3.codes",      "https://challenges.cloudflare.com",    ]);    assert.deepEqual(directives["connect-src"], ["'self'", "http:", "https:", "ws:", "wss:"]);    assert.deepEqual(directives["img-src"], [      "'self'",      "t3code:",      "blob:",      "data:",      "http:",      "https:",    ]);    assert.deepEqual(directives["font-src"], ["'self'", "t3code:", "data:"]);  });});