1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
// node --test javascript/src/run-module/host-call.test.mjs (no network)
import assert from "node:assert/strict";
import { test } from "node:test";
import { hostCall, json, sessionXrpc, sseEvents } from "./host-call.js";
const SUB = "com.atproto.sync.subscribeRepos";
// review 3a L5 / 3b #10: the pages built aud as did:web:<host:port> or dropped the port; every host now
// mints through serviceAud.
test("a page's host call (canHeader false): aud keeps the port as %3A, the page's own pseudo-calls, the rest refused", async () => {
const minted = [];
const fetched = [];
const urls = [];
class FakeSocket {
constructor(url) {
urls.push(url);
this.readyState = 1;
}
close() {}
}
const xrpc = async (nsid, { params }) => (minted.push(params), { token: "jwt1" });
const ctx = { http: { fetch: async (url, init) => (fetched.push([url, init.headers]), new Response("{}")) } };
const own = [];
const call = hostCall({ ctx, xrpc, canHeader: false, WebSocket: FakeSocket, calls: { "com.fedfork.exec.webrtc.connect": (r) => (own.push(r.subscribe === true), "mine") } });
await call(SUB, { subscribe: true, service: "https://svc.example:8443", serviceAuth: { param: "auth" } });
await call("com.example.q", { service: "https://svc.example:8443", params: { a: "1" } });
assert.deepEqual(minted, [{ aud: "did:web:svc.example%3A8443", lxm: SUB }, { aud: "did:web:svc.example%3A8443", lxm: "com.example.q" }]);
assert.deepEqual(urls, [`wss://svc.example:8443/xrpc/${SUB}?auth=jwt1`]);
assert.deepEqual(fetched, [["https://svc.example:8443/xrpc/com.example.q?a=1", { authorization: "Bearer jwt1" }]]);
await assert.rejects(call(SUB, { subscribe: true, service: "https://svc.example", serviceAuth: {} }), /browsers cannot set WebSocket headers/);
assert.equal(await call("com.fedfork.exec.webrtc.connect", { input: {} }), "mine");
assert.equal(await call("com.fedfork.exec.webrtc.connect", { subscribe: true }), "mine");
assert.deepEqual(own, [false, true]);
// a transport this host has none of: the same text as rust/host's transport::unavailable
for (const request of [{ input: {} }, { subscribe: true }]) await assert.rejects(call("com.fedfork.exec.iroh.connect", request), { message: "com.fedfork.exec.iroh.connect: not available on this host (built without iroh)" });
await assert.rejects(call("com.fedfork.exec.didkey.sign", { input: {} }), { message: "com.fedfork.exec.didkey.sign is not available on this host" });
await assert.rejects(call("com.fedfork.exec.attest", { subscribe: true }), /cannot be subscribed to on this host/);
await assert.rejects(hostCall({ ctx, signIn: "sign in" })("com.atproto.repo.createRecord", { input: {} }), /needs a session \(sign in\)/);
});
test("an event-stream answer is read whole into { events } (Rust json_response the same)", async () => {
const body = 'event: meta\ndata: {"jobUri":"at://x"}\n\n: comment\n\ndata: one\ndata: two\n\n';
const response = new Response(body, { headers: { "content-type": "text/event-stream; charset=utf-8" } });
assert.deepEqual(await json("dev.cocore.inference.dispatch", response), { events: [{ event: "meta", data: { jobUri: "at://x" } }, { event: "message", data: "one\ntwo" }] });
assert.deepEqual(sseEvents("data: x\r\n\r\nevent: e\r\ndata: 1\r\n\r\n"), [{ event: "message", data: "x" }, { event: "e", data: 1 }]);
});
test("signed out, a proxied query goes straight to the did#id's endpoint with no credentials; a did#id service too", async () => {
const fetched = [];
const doc = { service: [{ id: "#atproto_pds", serviceEndpoint: "https://pds.example" }, { id: "#svc", serviceEndpoint: "https://api.example" }] };
const ctx = { http: { fetch: async (url, init) => (fetched.push([url, init?.headers]), Response.json(url.endsWith("did.json") ? doc : { ok: url })) } };
const call = hostCall({ ctx });
assert.deepEqual(await call("com.example.q", { proxy: "did:web:api.example#svc", params: { a: "1" } }), { ok: "https://api.example/xrpc/com.example.q?a=1" });
assert.deepEqual(await call("com.example.q", { service: "did:web:api.example#svc" }), { ok: "https://api.example/xrpc/com.example.q" });
assert.deepEqual(await call("com.example.q", { service: "did:web:api.example" }), { ok: "https://pds.example/xrpc/com.example.q" });
assert.ok(fetched.every(([, headers]) => headers === undefined), "no credentials");
await assert.rejects(call("com.example.p", { proxy: "did:web:api.example#svc", input: {} }), /com.example.p needs a session/);
await assert.rejects(call("com.example.q", { proxy: "did:web:api.example#nope" }), { message: "did:web:api.example has no #nope service" });
// signed in, the proxy still goes through the session
const sent = [];
await hostCall({ ctx, xrpc: async (nsid, init) => (sent.push(init.headers), {}) })("com.example.q", { proxy: "did:web:api.example#svc" });
assert.deepEqual(sent, [{ "atproto-proxy": "did:web:api.example#svc" }]);
});
test("bytes: a { $bytes } input goes as those bytes with its encoding; a binary answer comes back as { $bytes } (Rust the same)", async () => {
const sent = [];
const agent = { fetchHandler: async (path, init) => (sent.push([path, init]), new Response(Uint8Array.of(0, 1, 2, 255), { headers: { "content-type": "application/x-git-packed-objects" } })) };
const call = hostCall({ ctx: { http: { fetch } }, xrpc: sessionXrpc(agent) });
assert.deepEqual(await call("com.atproto.repo.uploadBlob", { input: { $bytes: "AAEC/w" }, encoding: "application/x-git-packed-objects" }), { $bytes: "AAEC/w" });
await call("com.atproto.repo.uploadBlob", { input: { $bytes: "AAEC/w==" } });
assert.deepEqual(sent.map(([path, init]) => [path, init.method, init.headers["content-type"], [...init.body]]), [
["/xrpc/com.atproto.repo.uploadBlob", "POST", "application/x-git-packed-objects", [0, 1, 2, 255]],
["/xrpc/com.atproto.repo.uploadBlob", "POST", "application/octet-stream", [0, 1, 2, 255]],
]);
// JSON and text answers are read as before; a JSON input that merely has $bytes beside other keys stays JSON
assert.deepEqual(await json("x", new Response("{}")), {});
assert.deepEqual(await json("x", Response.json({ a: 1 })), { a: 1 });
await sessionXrpc({ fetchHandler: async (path, init) => (sent.push([path, init]), Response.json({})) })("a.b.c", { input: { $bytes: "AA", x: 1 } });
assert.deepEqual([sent.at(-1)[1].headers["content-type"], sent.at(-1)[1].body], ["application/json", '{"$bytes":"AA","x":1}']);
});
test("a did#id call with endpoints: a fetcher's scheme first, else https, with service auth aud did#id; none reachable is an error (Rust TransportCall/HostCall the same)", async () => {
const minted = [];
const sent = [];
const xrpc = async (nsid, { params }) => (minted.push([nsid, params]), { token: "jwt1" });
const ctx = { http: { fetch: async (url, init) => (sent.push(["https", url, init.method, init.headers.authorization, init.body]), Response.json({ via: "https" })) } };
const fetchers = { "iroh:": async ({ url, method, headers, body }) => (sent.push(["iroh", url, method, headers.authorization, body]), { status: 200, headers: { "content-type": "application/json" }, body: '{"via":"iroh"}' }) };
const aud = "did:plc:bidder#pdr_temp_market";
const endpoints = [{ kind: "https", address: "https://bidder.example" }, { kind: "iroh", address: "endpointabc234" }];
const nsid = "com.publicdomainrelay.temp.market.submitRfp";
assert.deepEqual(await hostCall({ ctx, xrpc, fetchers })(nsid, { service: aud, endpoints, input: { a: 1 } }), { via: "iroh" });
assert.deepEqual(await hostCall({ ctx, xrpc })(nsid, { service: aud, endpoints, input: { a: 1 } }), { via: "https" });
assert.deepEqual(minted, [["com.atproto.server.getServiceAuth", { aud, lxm: nsid }], ["com.atproto.server.getServiceAuth", { aud, lxm: nsid }]]);
assert.deepEqual(sent, [
["iroh", `iroh://endpointabc234/xrpc/${nsid}`, "POST", "Bearer jwt1", '{"a":1}'],
["https", `https://bidder.example/xrpc/${nsid}`, "POST", "Bearer jwt1", '{"a":1}'],
]);
await assert.rejects(hostCall({ ctx, xrpc })(nsid, { service: aud, endpoints: [{ kind: "iroh", address: "endpointabc234" }, { kind: "https", address: "http://plain.example" }], input: {} }), { message: `${nsid}: this host reaches none of ${aud}'s endpoints` });
await assert.rejects(hostCall({ ctx, fetchers })(nsid, { service: aud, endpoints, input: {} }), /needs a session/);
});