Files
element-call/src/lotus/lotusWidgetOrigin.test.ts
T

66 lines
2.0 KiB
TypeScript
Raw Normal View History

/*
Copyright 2026 Lotus Guild
SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
Please see LICENSE in the repository root for full details.
*/
import { describe, expect, it } from "vitest";
import { isFromHost, restrictToHost } from "./lotusWidgetOrigin";
const parent = {} as Window;
const other = {} as Window;
const HOST = "https://chat.example.org";
describe("isFromHost", () => {
it("accepts only the parent window at the host origin", () => {
expect(isFromHost({ source: parent, origin: HOST }, parent, HOST)).toBe(
true,
);
expect(isFromHost({ source: other, origin: HOST }, parent, HOST)).toBe(
false,
);
expect(
isFromHost(
{ source: parent, origin: "https://evil.example" },
parent,
HOST,
),
).toBe(false);
expect(isFromHost({ source: parent, origin: "null" }, parent, HOST)).toBe(
false,
);
});
});
describe("restrictToHost", () => {
it("replaces the listener and drops foreign messages", () => {
const seen: unknown[] = [];
const original = (ev: MessageEvent): void => {
seen.push(ev.data);
};
const transport = { handleMessage: original };
const listeners = new Set<EventListener>([original as EventListener]);
const inbound = {
addEventListener: (_t: string, l: EventListener): void => {
listeners.add(l);
},
removeEventListener: (_t: string, l: EventListener): void => {
listeners.delete(l);
},
} as unknown as Window;
restrictToHost(transport, HOST, parent, inbound);
expect(listeners.has(original as EventListener)).toBe(false);
expect(listeners.size).toBe(1);
const dispatch = (ev: Partial<MessageEvent>): void =>
listeners.forEach((l) => l(ev as unknown as Event));
dispatch({ source: other, origin: HOST, data: "spoof" });
dispatch({ source: parent, origin: "https://evil.example", data: "bad" });
dispatch({ source: parent, origin: HOST, data: "real" });
expect(seen).toEqual(["real"]);
});
});