30 lines · 1.2 KB
import { describe, expect, mock, test } from "bun:test";

mock.module("cloudflare:workers", () => ({
  env: {},
  waitUntil: () => undefined,
}));

const { redirectMatches } = await import("./oauth-clients");

describe("redirectMatches", () => {
  test("exact matches always pass", () => {
    expect(redirectMatches(["https://app.example/cb"], "https://app.example/cb")).toBe(true);
  });

  test("an http loopback redirect may use any port", () => {
    expect(redirectMatches(["http://127.0.0.1/cb"], "http://127.0.0.1:53121/cb")).toBe(true);
  });

  test("a registered https or custom-scheme redirect never matches a downgraded http loopback one", () => {
    expect(redirectMatches(["https://localhost/cb"], "http://localhost:8080/cb")).toBe(false);
    expect(redirectMatches(["myapp://localhost/cb"], "http://localhost:8080/cb")).toBe(false);
  });

  test("path, query, host and credentials must match", () => {
    expect(redirectMatches(["http://127.0.0.1/cb"], "http://127.0.0.1:1/other")).toBe(false);
    expect(redirectMatches(["http://127.0.0.1/cb"], "http://localhost:1/cb")).toBe(false);
    expect(redirectMatches(["http://127.0.0.1/cb"], "http://user@127.0.0.1:1/cb")).toBe(false);
  });
});