bun dw spins up a fully isolated per-worktree dev stack: Neon DB branch, Dragonfly + ElasticMQ via docker compose, portless aliases, tmux session, and emulate.dev Google OAuth. Workers, dev server, vite, checkout, and stripe-listen run as concurrently siblings. bun setup-test auto-runs on first dw and seeds unit-test-org via clearOrg+setupOrg+ensureDefaultStripeAccount with 13 features + team invites for all 5 useautumn.com members. Hardcoded localhost URLs in test scenarios now read AUTUMN_TEST_BASE_URL/AUTUMN_TEST_VITE_URL. preload-env.ts loads .env.local so bun t/cm/setup-test route to the worktree server. 1265-line scripts/dw.ts split into scripts/dw/ module (index + commands + helpers). server/src/db/initDrizzle.ts reverted to upstream (search_path concerns solved by per-branch Neon isolation). Workers enabled in agent worktrees now that SQS is per-worktree via ElasticMQ.
88 lines
2.8 KiB
TypeScript
88 lines
2.8 KiB
TypeScript
import { afterEach, describe, expect, test } from "bun:test";
|
|
import { ALLOWED_ORIGINS, isAllowedOrigin } from "@/utils/corsOrigins.js";
|
|
|
|
describe("isAllowedOrigin", () => {
|
|
const originalNodeEnv = process.env.NODE_ENV;
|
|
|
|
afterEach(() => {
|
|
process.env.NODE_ENV = originalNodeEnv;
|
|
});
|
|
|
|
describe("production", () => {
|
|
test("allows hardcoded production origins", () => {
|
|
process.env.NODE_ENV = "production";
|
|
for (const origin of ALLOWED_ORIGINS) {
|
|
expect(isAllowedOrigin(origin)).toBe(origin);
|
|
}
|
|
});
|
|
|
|
test("rejects arbitrary localhost ports", () => {
|
|
process.env.NODE_ENV = "production";
|
|
expect(isAllowedOrigin("http://localhost:3100")).toBeUndefined();
|
|
expect(isAllowedOrigin("http://localhost:8180")).toBeUndefined();
|
|
expect(isAllowedOrigin("http://localhost:9999")).toBeUndefined();
|
|
});
|
|
|
|
test("rejects external origins", () => {
|
|
process.env.NODE_ENV = "production";
|
|
expect(isAllowedOrigin("https://evil.com")).toBeUndefined();
|
|
expect(isAllowedOrigin("https://fake.useautumn.com")).toBeUndefined();
|
|
});
|
|
});
|
|
|
|
describe("non-production", () => {
|
|
test("allows hardcoded origins", () => {
|
|
process.env.NODE_ENV = "development";
|
|
for (const origin of ALLOWED_ORIGINS) {
|
|
expect(isAllowedOrigin(origin)).toBe(origin);
|
|
}
|
|
});
|
|
|
|
test("allows any localhost port (worktree offsets)", () => {
|
|
process.env.NODE_ENV = "development";
|
|
expect(isAllowedOrigin("http://localhost:3100")).toBe(
|
|
"http://localhost:3100",
|
|
);
|
|
expect(isAllowedOrigin("http://localhost:8180")).toBe(
|
|
"http://localhost:8180",
|
|
);
|
|
expect(isAllowedOrigin("http://localhost:3200")).toBe(
|
|
"http://localhost:3200",
|
|
);
|
|
});
|
|
|
|
test("allows *.localhost subdomains (portless aliases)", () => {
|
|
process.env.NODE_ENV = "development";
|
|
expect(isAllowedOrigin("https://wt8.localhost")).toBe(
|
|
"https://wt8.localhost",
|
|
);
|
|
expect(isAllowedOrigin("https://wt17-api.localhost")).toBe(
|
|
"https://wt17-api.localhost",
|
|
);
|
|
expect(isAllowedOrigin("https://google.emulate.localhost")).toBe(
|
|
"https://google.emulate.localhost",
|
|
);
|
|
});
|
|
|
|
test("rejects external origins", () => {
|
|
process.env.NODE_ENV = "development";
|
|
expect(isAllowedOrigin("https://evil.com")).toBeUndefined();
|
|
expect(isAllowedOrigin("http://evil.com:3000")).toBeUndefined();
|
|
});
|
|
|
|
test("rejects localhost with path or query", () => {
|
|
process.env.NODE_ENV = "development";
|
|
expect(isAllowedOrigin("http://localhost:3000/evil")).toBeUndefined();
|
|
expect(isAllowedOrigin("http://localhost:3000?x=1")).toBeUndefined();
|
|
});
|
|
|
|
test("rejects look-alike domains posing as localhost", () => {
|
|
process.env.NODE_ENV = "development";
|
|
expect(isAllowedOrigin("https://localhost.evil.com")).toBeUndefined();
|
|
expect(
|
|
isAllowedOrigin("https://wt8.localhost.evil.com"),
|
|
).toBeUndefined();
|
|
});
|
|
});
|
|
});
|