ca85d9fe69
- Changed `DEFAULT_RELAY_URL` in `@oh-my-pi/pi-wire` from `wss://relay.omp.sh` to `wss://my.omp.sh` and updated the constants, collab-link, and join-command tests asserting the old origin. - Added `DEFAULT_SHARE_URL` (`https://my.omp.sh/s`) to pi-wire with its changelog entry; it shares a changed run with the relay constant and is consumed by the upcoming /share work. - Updated collab-web canonical/OG/twitter URLs in `index.html`, `robots.txt`, `sitemap.xml`, README, and the `local-relay.ts` doc comment to the new domain. - Refreshed the `/collab` entry in the coding-agent changelog to reference the new relay origin.
168 lines
6.7 KiB
TypeScript
168 lines
6.7 KiB
TypeScript
import { describe, expect, it } from "bun:test";
|
|
import {
|
|
generateRoomKey,
|
|
generateWriteToken,
|
|
importRoomKey,
|
|
open,
|
|
seal,
|
|
} from "@oh-my-pi/pi-coding-agent/collab/crypto";
|
|
import {
|
|
type CollabFrame,
|
|
DEFAULT_RELAY_URL,
|
|
formatCollabLink,
|
|
formatCollabWebLink,
|
|
generateRoomId,
|
|
packEnvelope,
|
|
parseCollabLink,
|
|
rewriteEnvelopePeer,
|
|
unpackEnvelope,
|
|
} from "@oh-my-pi/pi-coding-agent/collab/protocol";
|
|
|
|
describe("collab crypto", () => {
|
|
it("round-trips a frame through seal/open", async () => {
|
|
const key = await importRoomKey(generateRoomKey());
|
|
const frame: CollabFrame = { t: "prompt", text: "check bun.lock — and ünïcode 🚀" };
|
|
const sealed = await seal(key, frame);
|
|
expect(await open(key, sealed)).toEqual(frame);
|
|
});
|
|
|
|
it("rejects tampered ciphertext", async () => {
|
|
const key = await importRoomKey(generateRoomKey());
|
|
const sealed = await seal(key, { t: "abort" });
|
|
sealed[sealed.length - 1]! ^= 0xff;
|
|
expect(open(key, sealed)).rejects.toThrow();
|
|
});
|
|
|
|
it("rejects frames sealed with a different key", async () => {
|
|
const sealed = await seal(await importRoomKey(generateRoomKey()), { t: "abort" });
|
|
const otherKey = await importRoomKey(generateRoomKey());
|
|
expect(open(otherKey, sealed)).rejects.toThrow();
|
|
});
|
|
});
|
|
|
|
describe("collab link format", () => {
|
|
const key = generateRoomKey();
|
|
const roomId = generateRoomId();
|
|
|
|
it("collapses the default relay to a bare roomId#key link", () => {
|
|
const link = formatCollabLink(DEFAULT_RELAY_URL, roomId, key);
|
|
expect(link).toBe(`${roomId}#${Buffer.from(key).toString("base64url")}`);
|
|
const parsed = parseCollabLink(link);
|
|
if ("error" in parsed) throw new Error(parsed.error);
|
|
expect(parsed.wsUrl).toBe(`${DEFAULT_RELAY_URL}/r/${roomId}`);
|
|
expect(parsed.roomId).toBe(roomId);
|
|
expect(parsed.key).toEqual(key);
|
|
});
|
|
|
|
it("drops the wss scheme for custom relays and infers it on parse", () => {
|
|
const link = formatCollabLink("wss://relay.example.com:8443", roomId, key);
|
|
expect(link.startsWith("relay.example.com:8443/r/")).toBe(true);
|
|
const parsed = parseCollabLink(link);
|
|
if ("error" in parsed) throw new Error(parsed.error);
|
|
expect(parsed.wsUrl).toBe(`wss://relay.example.com:8443/r/${roomId}`);
|
|
});
|
|
|
|
it("keeps full ws:// URLs for localhost relays", () => {
|
|
const link = formatCollabLink("ws://localhost:7475", roomId, key);
|
|
expect(link.startsWith("ws://localhost:7475/r/")).toBe(true);
|
|
const parsed = parseCollabLink(link);
|
|
if ("error" in parsed) throw new Error(parsed.error);
|
|
expect(parsed.wsUrl).toBe(`ws://localhost:7475/r/${roomId}`);
|
|
});
|
|
|
|
it("rewrites https relay URLs to wss", () => {
|
|
const parsed = parseCollabLink(`https://relay.example.com/r/${roomId}#${Buffer.from(key).toString("base64url")}`);
|
|
if ("error" in parsed) throw new Error(parsed.error);
|
|
expect(parsed.wsUrl).toBe(`wss://relay.example.com/r/${roomId}`);
|
|
});
|
|
|
|
it("rejects plain ws:// for non-localhost hosts", () => {
|
|
const parsed = parseCollabLink(`ws://relay.example.com/r/${roomId}#${Buffer.from(key).toString("base64url")}`);
|
|
expect("error" in parsed && parsed.error.includes("wss://")).toBe(true);
|
|
});
|
|
|
|
it("rejects keys that are not 32 base64url bytes", () => {
|
|
expect("error" in parseCollabLink(`${roomId}#dG9vc2hvcnQ`)).toBe(true);
|
|
expect("error" in parseCollabLink(`${roomId}#not+base64url/`)).toBe(true);
|
|
});
|
|
|
|
it("renders web deep links that parse back to the same room", () => {
|
|
for (const relay of [DEFAULT_RELAY_URL, "wss://relay.example.com:8443", "ws://localhost:7475"]) {
|
|
const webLink = formatCollabWebLink(relay, roomId, key);
|
|
const direct = parseCollabLink(formatCollabLink(relay, roomId, key));
|
|
const viaWeb = parseCollabLink(webLink);
|
|
if ("error" in direct) throw new Error(direct.error);
|
|
if ("error" in viaWeb) throw new Error(viaWeb.error);
|
|
expect(webLink.startsWith(relay === "ws://localhost:7475" ? "http://" : "https://")).toBe(true);
|
|
expect(webLink.includes("/#")).toBe(true);
|
|
expect(viaWeb.wsUrl).toBe(direct.wsUrl);
|
|
expect(viaWeb.roomId).toBe(roomId);
|
|
expect(Buffer.from(viaWeb.key)).toEqual(Buffer.from(key));
|
|
}
|
|
});
|
|
|
|
it("parses the scheme-less display form of web deep links", () => {
|
|
const parsed = parseCollabLink(`my.omp.sh/#${formatCollabLink(DEFAULT_RELAY_URL, roomId, key)}`);
|
|
if ("error" in parsed) throw new Error(parsed.error);
|
|
expect(parsed.wsUrl).toBe(`${DEFAULT_RELAY_URL}/r/${roomId}`);
|
|
expect(Buffer.from(parsed.key)).toEqual(Buffer.from(key));
|
|
});
|
|
|
|
it("embeds the write token in full links and omits it from view links", () => {
|
|
const token = generateWriteToken();
|
|
const full = parseCollabLink(formatCollabLink(DEFAULT_RELAY_URL, roomId, key, token));
|
|
if ("error" in full) throw new Error(full.error);
|
|
expect(Buffer.from(full.key)).toEqual(Buffer.from(key));
|
|
expect(Buffer.from(full.writeToken ?? new Uint8Array())).toEqual(Buffer.from(token));
|
|
|
|
const view = parseCollabLink(formatCollabLink(DEFAULT_RELAY_URL, roomId, key));
|
|
if ("error" in view) throw new Error(view.error);
|
|
expect(Buffer.from(view.key)).toEqual(Buffer.from(key));
|
|
expect(view.writeToken).toBeUndefined();
|
|
});
|
|
|
|
it("carries the write token through web deep links", () => {
|
|
const token = generateWriteToken();
|
|
const parsed = parseCollabLink(formatCollabWebLink(DEFAULT_RELAY_URL, roomId, key, token));
|
|
if ("error" in parsed) throw new Error(parsed.error);
|
|
expect(Buffer.from(parsed.key)).toEqual(Buffer.from(key));
|
|
expect(Buffer.from(parsed.writeToken ?? new Uint8Array())).toEqual(Buffer.from(token));
|
|
});
|
|
|
|
it("rejects secrets that are neither 32 nor 48 bytes", () => {
|
|
const bad = Buffer.alloc(40, 1).toString("base64url");
|
|
expect("error" in parseCollabLink(`${roomId}#${bad}`)).toBe(true);
|
|
});
|
|
|
|
it("keeps the key out of web-link path and query", () => {
|
|
const webLink = formatCollabWebLink(DEFAULT_RELAY_URL, roomId, key);
|
|
const url = new URL(webLink);
|
|
expect(url.origin).toBe("https://my.omp.sh");
|
|
expect(url.pathname).toBe("/");
|
|
expect(url.search).toBe("");
|
|
expect(url.hash).toBe(`#${roomId}#${Buffer.from(key).toString("base64url")}`);
|
|
});
|
|
});
|
|
|
|
describe("collab wire envelope", () => {
|
|
it("round-trips peer id and payload", () => {
|
|
const payload = new Uint8Array([1, 2, 3, 250]);
|
|
const packed = packEnvelope(0xdeadbeef, payload);
|
|
const unpacked = unpackEnvelope(packed);
|
|
expect(unpacked?.peerId).toBe(0xdeadbeef);
|
|
expect(unpacked?.payload).toEqual(payload);
|
|
});
|
|
|
|
it("rewrites the peer id in place without touching the payload", () => {
|
|
const packed = packEnvelope(0, new Uint8Array([9, 8, 7]));
|
|
rewriteEnvelopePeer(packed, 42);
|
|
const unpacked = unpackEnvelope(packed);
|
|
expect(unpacked?.peerId).toBe(42);
|
|
expect(unpacked?.payload).toEqual(new Uint8Array([9, 8, 7]));
|
|
});
|
|
|
|
it("returns null for frames shorter than the header", () => {
|
|
expect(unpackEnvelope(new Uint8Array([0, 0]))).toBeNull();
|
|
});
|
|
});
|