Files
wehub-resource-sync b3a7f98e5a
CI / E2E Cloudflare (4/8) (push) Failing after 0s
CI / E2E Cloudflare (8/8) (push) Failing after 1s
CI / Lint (push) Failing after 1s
Auto Extract / Extract (push) Failing after 4s
CI / Version Check (push) Failing after 9s
CI / Integration Tests (push) Failing after 1s
CI / E2E tests (1/8) (push) Failing after 1s
CI / E2E tests (2/8) (push) Failing after 2s
CI / E2E tests (3/8) (push) Failing after 2s
CI / Browser Tests (push) Failing after 1s
CI / E2E tests (5/8) (push) Failing after 1s
CI / E2E Cloudflare (2/8) (push) Failing after 2s
CI / Typecheck (push) Failing after 1s
CI / Changeset Validation (push) Failing after 2s
CI / E2E Cloudflare (5/8) (push) Failing after 1s
CI / E2E Cloudflare (6/8) (push) Failing after 1s
CI / E2E Cloudflare (7/8) (push) Failing after 1s
CodeQL / Analyze (javascript-typescript) (push) Failing after 1s
Format / Format (push) Failing after 0s
CodeQL / Analyze (actions) (push) Failing after 4s
CI / E2E tests (4/8) (push) Failing after 1s
CI / E2E tests (6/8) (push) Failing after 1s
CI / E2E tests (7/8) (push) Failing after 2s
CI / E2E tests (8/8) (push) Failing after 1s
CI / E2E Cloudflare (1/8) (push) Failing after 1s
CI / E2E Cloudflare (3/8) (push) Failing after 2s
Preview Releases / Publish Preview (push) Failing after 0s
zizmor / Run zizmor (push) Failing after 1s
Release / Release (push) Failing after 2s
CI / Smoke Tests (push) Failing after 5m36s
CI / Tests (push) Failing after 6m36s
Release / Sync Templates (push) Has been skipped
CI / E2E Tests (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:23:53 +08:00

95 lines
3.6 KiB
TypeScript

import { describe, it, expect } from "vitest";
import { signPreviewUrl, verifyPreviewSignature } from "../../src/db/do-preview-sign.js";
const SECRET = "test-secret-key";
const DIGITS = /^\d+$/;
const HEX_64 = /^[0-9a-f]{64}$/;
describe("signPreviewUrl", () => {
it("returns a URL with source, exp, and sig params", async () => {
const url = await signPreviewUrl("https://preview.example.com", "https://mysite.com", SECRET);
const parsed = new URL(url);
expect(parsed.origin).toBe("https://preview.example.com");
expect(parsed.searchParams.get("source")).toBe("https://mysite.com");
expect(parsed.searchParams.get("exp")).toMatch(DIGITS);
expect(parsed.searchParams.get("sig")).toMatch(HEX_64);
});
it("sets expiry based on ttl", async () => {
const before = Math.floor(Date.now() / 1000);
const url = await signPreviewUrl(
"https://preview.example.com",
"https://mysite.com",
SECRET,
7200,
);
const after = Math.floor(Date.now() / 1000);
const exp = Number(new URL(url).searchParams.get("exp"));
expect(exp).toBeGreaterThanOrEqual(before + 7200);
expect(exp).toBeLessThanOrEqual(after + 7200);
});
it("defaults to 1 hour TTL", async () => {
const before = Math.floor(Date.now() / 1000);
const url = await signPreviewUrl("https://preview.example.com", "https://mysite.com", SECRET);
const exp = Number(new URL(url).searchParams.get("exp"));
expect(exp).toBeGreaterThanOrEqual(before + 3600);
});
});
describe("verifyPreviewSignature", () => {
it("verifies a signature produced by signPreviewUrl", async () => {
const url = await signPreviewUrl("https://preview.example.com", "https://mysite.com", SECRET);
const parsed = new URL(url);
const source = parsed.searchParams.get("source")!;
const exp = Number(parsed.searchParams.get("exp"));
const sig = parsed.searchParams.get("sig")!;
expect(await verifyPreviewSignature(source, exp, sig, SECRET)).toBe(true);
});
it("rejects a wrong secret", async () => {
const url = await signPreviewUrl("https://preview.example.com", "https://mysite.com", SECRET);
const parsed = new URL(url);
const source = parsed.searchParams.get("source")!;
const exp = Number(parsed.searchParams.get("exp"));
const sig = parsed.searchParams.get("sig")!;
expect(await verifyPreviewSignature(source, exp, sig, "wrong-secret")).toBe(false);
});
it("rejects a tampered source", async () => {
const url = await signPreviewUrl("https://preview.example.com", "https://mysite.com", SECRET);
const parsed = new URL(url);
const exp = Number(parsed.searchParams.get("exp"));
const sig = parsed.searchParams.get("sig")!;
expect(await verifyPreviewSignature("https://evil.com", exp, sig, SECRET)).toBe(false);
});
it("rejects a tampered expiry", async () => {
const url = await signPreviewUrl("https://preview.example.com", "https://mysite.com", SECRET);
const parsed = new URL(url);
const source = parsed.searchParams.get("source")!;
const sig = parsed.searchParams.get("sig")!;
expect(await verifyPreviewSignature(source, 9999999999, sig, SECRET)).toBe(false);
});
it("rejects a tampered signature", async () => {
const url = await signPreviewUrl("https://preview.example.com", "https://mysite.com", SECRET);
const parsed = new URL(url);
const source = parsed.searchParams.get("source")!;
const exp = Number(parsed.searchParams.get("exp"));
expect(await verifyPreviewSignature(source, exp, "a".repeat(64), SECRET)).toBe(false);
});
it("rejects a signature with wrong length", async () => {
expect(await verifyPreviewSignature("https://x.com", 123, "tooshort", SECRET)).toBe(false);
});
});