import assert from "node:assert/strict"; import { test } from "node:test"; import { did, load, now } from "../../../atlibs/rust/src/harness.mjs"; const { module, run, handle: runHandle } = await load(new URL("../../target/wasm32-unknown-unknown/release/fedproxy.wasm", import.meta.url)); const ENTRIES = ["list_keys", "create_key"]; const start = (fields) => ({ did, now, ...fields, state: null, event: { type: "start" } }); const handle = "alice.bsky.social"; const key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIG9BVPpCtKTckpQVk4etPSsC65Vo91Ie0kpjJH6PSdow alice@wonderland"; const record = (rkey, service, name) => ({ uri: `at://${did}/com.fedproxy.sshPublicKey/${rkey}`, value: { $type: "com.fedproxy.sshPublicKey", service, name, key, createdAt: now }, }); test("module has no imports and exports the ABI", () => { assert.equal(WebAssembly.Module.imports(module).length, 0); const names = WebAssembly.Module.exports(module).map((e) => e.name); for (const name of ["memory", "alloc", ...ENTRIES]) assert.ok(names.includes(name), name); }); test("list_keys follows cursors and groups keys by service with their hosts", async () => { const pages = [ { records: [record("1", "app", "laptop"), record("2", "*", "everything")], cursor: "next" }, { records: [record("3", "*.my.site", "wild"), record("4", "app", "desktop")] }, ]; const calls = []; const ran = await runHandle("list_keys", { handle }, { respond: ({ nsid, params }) => (calls.push({ nsid, params }), { ok: true, output: pages.shift() }) }); assert.deepEqual(calls.map((call) => call.params.cursor ?? null), [null, "next"]); assert.deepEqual(calls[0], { nsid: "com.atproto.repo.listRecords", params: { repo: did, collection: "com.fedproxy.sshPublicKey", limit: "100" }, }); assert.deepEqual( ran.result.services.map((s) => [s.service, s.host, s.keys.map((k) => k.name)]), [ ["app", "app--alice-bsky-social.fedproxy.com", ["laptop", "desktop"]], ["*", null, ["everything"]], ["*.my.site", "*.my-site--alice-bsky-social.fedproxy.com", ["wild"]], ], ); assert.equal(ran.result.services[0].keys[0].uri, record("1").uri); assert.deepEqual( ran.result.services.map((s) => s.command.match(/-R (\S+)/)[1]), ["app:80:127.0.0.1:8080", "my-cool-service:80:127.0.0.1:8080", "'*.my.site:80:127.0.0.1:8080'"], ); assert.equal( ran.result.services[0].command, "ssh -NnT -p 2222 \\\n -o UserKnownHostsFile=/dev/null \\\n -o StrictHostKeyChecking=no \\\n -o PasswordAuthentication=no \\\n -R app:80:127.0.0.1:8080 \\\n alice.bsky.social@fedproxy.com", ); }); test("list_keys needs a handle to name hosts", () => { assert.match(run("list_keys", start({})).error, /handle/); }); test("create_key writes one record and reports its host", async () => { const calls = []; const respond = ({ nsid, input }) => (calls.push({ nsid, input }), { ok: true, output: { uri: `at://${did}/com.fedproxy.sshPublicKey/new`, cid: "bafy" } }); const ran = await runHandle("create_key", { handle, name: "laptop\n", service: "my-cool-service", key: key.replace("AAAAC3", "AAAA\r\nC3") }, { respond }); assert.deepEqual(calls, [ { nsid: "com.atproto.repo.createRecord", input: { repo: did, collection: "com.fedproxy.sshPublicKey", record: { $type: "com.fedproxy.sshPublicKey", key, name: "laptop", service: "my-cool-service", createdAt: now }, }, }, ]); assert.deepEqual(ran.result, { uri: `at://${did}/com.fedproxy.sshPublicKey/new`, service: "my-cool-service", host: "my-cool-service--alice-bsky-social.fedproxy.com", }); }); test("create_key rejects bad input before any call", () => { const base = start({ handle, name: "n", service: "app", key }); assert.match(run("create_key", { ...base, name: "" }).error, /name is required/); for (const service of ["a b", "x*", "*.", "-app", "app."]) assert.match(run("create_key", { ...base, service }).error, /service must be/, service); for (const bad of ["not a key", "ssh-ed25519", "ssh-ed25519 !!!"]) assert.match(run("create_key", { ...base, key: bad }).error, /OpenSSH public key/, bad); assert.ok(run("create_key", { ...base, service: "*" }).calls); assert.ok(run("create_key", { ...base, service: "*.a.b" }).calls); }); test("create_key surfaces a failed write", async () => { const ran = await runHandle("create_key", { handle, name: "n", service: "app", key }, { respond: () => ({ ok: false, error: "createRecord failed with 403" }) }); assert.match(ran.error, /403/); });