tinyrelayfile
tinyrelay/scripts/private-services.test.mjs/

scripts/private-services.test.mjs raw
1import assert from "node:assert/strict";
2import {readFile} from "node:fs/promises";
3import test from "node:test";
4import vm from "node:vm";
5
6const shared = await readFile(new URL("../tinyclient/tiny.js", import.meta.url), "utf8");
7const source = await readFile(new URL("../tinyclient/private-services.js", import.meta.url), "utf8");
8class Element {}
9const definitions = new Map();
10const sandbox = {
11 URL, TextEncoder, HTMLElement: Element,
12 document: {}, Response,
13 customElements: {define(name, value) { if (definitions.has(name)) throw Error("duplicate definition"); definitions.set(name, value); }, get(name) { return definitions.get(name); }},
14 tinySigner: {
15 getPublicKey: async () => "a".repeat(64),
16 nip44Encrypt: async (_pubkey, value) => "enc:" + value,
17 nip44Decrypt: async (_pubkey, value) => value.replace(/^enc:/, "")
18 },
19 nostr: {signEvent: async event => event},
20 NostrSigner: {verifyEvent: () => true}
21};
22sandbox.window = sandbox;
23 sandbox.tiny = {files: {}};
24vm.runInNewContext(shared + source, sandbox);
25const api = sandbox.tiny.files.privateServices;
26
27test("can be evaluated again after in-place navigation", async () => {
28 assert.doesNotThrow(() => vm.runInNewContext(source, sandbox));
29 assert.equal(definitions.size, 1);
30});
31
32test("accepts tenant paths while rejecting unsafe relay URLs", () => {
33 assert.equal(api.validURL("wss://Relay.Example/r/Private"), true);
34 assert.equal(api.canonicalURL("wss://Relay.Example/r/Private/"), "wss://relay.example/r/Private");
35 assert.equal(api.validURL("wss://relay.example/?token=secret"), false);
36 assert.equal(api.validURL("wss://user:pass@relay.example"), false);
37 assert.equal(api.validURL("https://relay.example"), false);
38});
39
40test("NIP-44 helpers round-trip and retain unrelated private entries", async () => {
41 const clear = JSON.stringify([["name", "work"], ["g", "wss://old.example"], ["p", "b".repeat(64)]]);
42 const encrypted = await api.encrypt("a".repeat(64), clear);
43 assert.equal(await api.decrypt("a".repeat(64), encrypted), clear);
44 assert.deepEqual(JSON.parse(JSON.stringify(api.mergeRows([["name", "work"], ["g", "wss://old.example"], ["p", "b".repeat(64)]], ["wss://new.example/r/tenant"]))), [["name", "work"], ["p", "b".repeat(64)], ["g", "wss://new.example/r/tenant"]]);
45});
46
47test("NIP-07 nip44 methods are accepted alongside bunker methods", async () => {
48 sandbox.tinySigner = null;
49 sandbox.nostr = {nip44: {
50 encrypt: async (_pubkey, value) => "nip07:" + value,
51 decrypt: async (_pubkey, value) => value.replace(/^nip07:/, "")
52 }};
53 const encrypted = await api.encrypt("a".repeat(64), "private");
54 assert.equal(encrypted, "nip07:private");
55 assert.equal(await api.decrypt("a".repeat(64), encrypted), "private");
56});
57
58test("kind 10318 wire has no public tags", () => {
59 const event = api.wireEvent("ciphertext");
60 assert.equal(event.kind, 10318);
61 assert.equal(JSON.stringify(event.tags), "[]");
62 assert.equal(event.content, "ciphertext");
63});
64
65test("reads only a verified kind 10318 event for the requested author", async () => {
66 const pubkey = "a".repeat(64);
67 const event = {kind: 10318, pubkey, tags: [], content: "ciphertext", id: "1", sig: "2"};
68 const requests = [];
69 sandbox.tiny = {signedFetch: async (_path, _method, body) => {
70 requests.push(JSON.parse(body));
71 return new Response(JSON.stringify([event]), {status: 200});
72 }};
73 sandbox.NostrSigner.verifyEvent = () => true;
74 assert.deepEqual(JSON.parse(JSON.stringify(await api.readList(pubkey))), event);
75 assert.deepEqual(JSON.parse(JSON.stringify(requests[0])), [{kinds: [10318], authors: [pubkey], limit: 1}]);
76 sandbox.tiny.signedFetch = async () => new Response(JSON.stringify([{...event, pubkey: "b".repeat(64)}]), {status: 200});
77 await assert.rejects(api.readList(pubkey), /invalid/);
78 sandbox.tiny.signedFetch = async () => new Response(JSON.stringify({items: []}), {status: 200});
79 await assert.rejects(api.readList(pubkey), /malformed/);
80});
81
82test("rejects a failed event signature", () => {
83 sandbox.NostrSigner.verifyEvent = () => false;
84 assert.equal(api.acceptEvent({kind: 10318, pubkey: "a".repeat(64), tags: [], content: ""}, "a".repeat(64)), false);
85});

About

ownerc01503e8035f
visibilitypublic
headd730679639bf

Maintainers

  • c01503e8035f owner
  • ba1b5beed5b5 agent hermes

Clone

  • https://012.run/npub1cq2s86qrtadf36eqq3epm38wmhdynrrcwxf84eldk3f94dkv7ttsrulrz5/tinyrelay.git

Refs