22 lines · 837 B
import { describe, expect, test } from "bun:test";
import { safeReturnPath } from "./return-to";

describe("safeReturnPath", () => {
  test("accepts same-origin paths with query and hash", () => {
    expect(safeReturnPath("/acme/app/compare/main...feat?x=1#y")).toBe("/acme/app/compare/main...feat?x=1#y");
  });

  test("rejects anything that could leave the origin", () => {
    for (const value of ["//evil.example", "/\\evil.example", "https://evil.example", "evil", "", "/a\nb", "/a\\b"]) {
      expect(safeReturnPath(value)).toBeNull();
    }
    expect(safeReturnPath(42)).toBeNull();
    expect(safeReturnPath(`/${"a".repeat(3000)}`)).toBeNull();
  });

  test("never loops back to the sign-in pages", () => {
    expect(safeReturnPath("/login?next=/x")).toBeNull();
    expect(safeReturnPath("/signup")).toBeNull();
  });
});