~ knotless Search/
↑↓ move↵ open⇧↵ all results

johnandersen777.bsky.social/atlibs-marque

0
0
main
245 lines · 12.9 KB Raw History
import assert from "node:assert/strict";
import { readFile } from "node:fs/promises";
import { test } from "node:test";

import { runModule } from "../../../atlibs/javascript/src/run-module/index.js";
import { did, load, now } from "../../../atlibs/rust/src/harness.mjs";

const { module, run } = await load(new URL("../../target/wasm32-unknown-unknown/release/marque.wasm", import.meta.url));
const spec = JSON.parse(await readFile(new URL("./module.json", import.meta.url), "utf8"));

// The harness's handle() with module.json's grants: its calls, and anyRecords (the zones Marque wrote).
async function runHandle(entry, input, { respond }) {
	const ctx = { wasm: { run: async ({ entry, input }) => run(entry, { ...input, now }) } };
	const call = async (nsid, request) => {
		const answer = await respond({ nsid, ...request });
		if (answer?.ok === false) throw new Error(answer.error ?? "call failed");
		return answer?.output;
	};
	return runModule(ctx, { module, calls: spec.calls, anyRecords: spec.anyRecords }, entry, { did, ...input }, call);
}
const ENTRIES = ["list_domains", "list_records", "create_record", "update_record", "delete_record"];
const start = (fields) => ({ did, now, ...fields, state: null, event: { type: "start" } });

// Fixtures in the shapes Marque publishes (at.marque.domain / at.marque.dns, keyed by the FQDN).
const domainUri = `at://${did}/at.marque.domain/example.com`;
const zoneUri = `at://${did}/at.marque.dns/example.com`;
const domain = {
	uri: domainUri,
	cid: "bafydomain2",
	value: { $type: "at.marque.domain", domain: "example.com", status: "active", registeredAt: now, expiresAt: now, createdAt: now, nameServers: ["stratus.mqdns.de", "cirrus.mqdns.at", "nimbus.mqdns.app"] },
};
const records = [
	{ ttl: 60, name: "@", value: "192.0.2.1", recordType: "A" },
	{ ttl: 300, name: "www", value: "example.com", recordType: "CNAME" },
	{ ttl: 3600, name: "@", value: "mail.example.com", recordType: "MX", priority: 10 },
];
const zone = {
	uri: zoneUri,
	cid: "bafyzone1",
	value: { $type: "at.marque.dns", baseRevision: 7, domain: "example.com", subject: { uri: domainUri, cid: "bafydomain1" }, records, createdAt: "2026-01-01T00:00:00.000Z" },
};
const notFound = { ok: false, error: "com.atproto.repo.getRecord failed with RecordNotFound: Could not locate record" };

// A PDS holding the domain and (unless zone is null) its zone; records writes.
function pds({ zone: z = zone, owned = true, write } = {}) {
	const writes = [];
	const reads = [];
	const respond = ({ nsid, params, input, service }) => {
		if (nsid === "com.atproto.repo.getRecord") reads.push([params.collection, params.rkey, service]);
		if (nsid === "com.atproto.repo.getRecord") {
			if (params.collection === "at.marque.domain") return owned ? { ok: true, output: domain } : notFound;
			return z ? { ok: true, output: z } : notFound;
		}
		writes.push({ nsid, input });
		return write ?? { ok: true, output: { uri: zoneUri, cid: "bafyzone2" } };
	};
	return { respond, writes, reads };
}

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_domains pages through at.marque.domain as a public read of the account's PDS", async () => {
	const pages = [{ records: [domain], cursor: "next" }, { records: [{ uri: `at://${did}/at.marque.domain/b.dev`, value: { $type: "at.marque.domain", domain: "b.dev", status: "expired" } }] }];
	const calls = [];
	const ran = await runHandle("list_domains", {}, { respond: (call) => (calls.push(call), { ok: true, output: pages.shift() }) });
	assert.deepEqual(calls.map((c) => [c.nsid, c.service, c.params.collection, c.params.cursor ?? null]), [
		["com.atproto.repo.listRecords", did, "at.marque.domain", null],
		["com.atproto.repo.listRecords", did, "at.marque.domain", "next"],
	]);
	assert.deepEqual(ran.result.domains.map((d) => [d.domain, d.status, d.uri, d.$type]), [
		["example.com", "active", domainUri, undefined],
		["b.dev", "expired", `at://${did}/at.marque.domain/b.dev`, undefined],
	]);
});

test("list_records reads the domain and its zone", async () => {
	const { respond, reads } = pds();
	const ran = await runHandle("list_records", { domain: "Example.com" }, { respond });
	assert.deepEqual(ran.result, { domain: "example.com", status: "active", uri: zoneUri, cid: "bafyzone1", records });
	assert.deepEqual(reads, [
		["at.marque.domain", "example.com", did],
		["at.marque.dns", "example.com", did],
	]);
});

test("a domain with no at.marque.domain record in the repo is refused", async () => {
	const { respond, writes } = pds({ owned: false });
	const ran = await runHandle("create_record", { domain: "example.com", name: "x", type: "A", value: "192.0.2.9" }, { respond });
	assert.match(ran.error, /not a Marque domain/);
	assert.equal(writes.length, 0);
});

test("create_record puts the whole zone back with swapRecord, keeping Marque's fields", async () => {
	const { respond, writes } = pds();
	const ran = await runHandle("create_record", { domain: "example.com", name: "_ATproto", type: "txt", value: `did=${did}`, ttl: "600" }, { respond });
	assert.equal(ran.error, undefined, ran.error);
	const added = { name: "_atproto", recordType: "TXT", value: `did=${did}`, ttl: 600 };
	assert.deepEqual(writes, [
		{
			nsid: "com.atproto.repo.putRecord",
			input: {
				repo: did,
				collection: "at.marque.dns",
				rkey: "example.com",
				swapRecord: "bafyzone1",
				record: { ...zone.value, subject: { uri: domainUri, cid: "bafydomain2" }, records: [...records, added], createdAt: now },
			},
		},
	]);
	assert.deepEqual(ran.result, { domain: "example.com", uri: zoneUri, cid: "bafyzone2", record: added, records: 4 });
});

test("create_record starts the zone when there is none", async () => {
	const { respond, writes } = pds({ zone: null });
	const ran = await runHandle("create_record", { domain: "example.com", name: "@", type: "AAAA", value: "2001:DB8:0:0::1" }, { respond });
	assert.equal(ran.error, undefined, ran.error);
	assert.deepEqual(writes, [
		{
			nsid: "com.atproto.repo.createRecord",
			input: {
				repo: did,
				collection: "at.marque.dns",
				rkey: "example.com",
				record: { $type: "at.marque.dns", domain: "example.com", subject: { uri: domainUri, cid: "bafydomain2" }, records: [{ name: "@", recordType: "AAAA", value: "2001:db8::1", ttl: 3600 }], createdAt: now },
			},
		},
	]);
});

test("values are normalised per type", async () => {
	const cases = [
		[{ type: "MX", value: "Mail2.Example.com.", priority: 20 }, { value: "mail2.example.com", priority: 20 }],
		[{ type: "SRV", name: "_sip._tcp", value: "5  5060 sip.example.com.", priority: "1" }, { value: "5 5060 sip.example.com", priority: 1 }],
		[{ type: "CAA", value: '0 ISSUE "letsencrypt.org"' }, { value: '0 issue "letsencrypt.org"' }],
		[{ type: "NS", name: "sub", value: "ns1.other.net" }, { value: "ns1.other.net" }],
		[{ type: "A", name: "*.app", value: " 198.51.100.7 " }, { value: "198.51.100.7", name: "*.app" }],
	];
	for (const [fields, want] of cases) {
		const { respond, writes } = pds();
		const ran = await runHandle("create_record", { domain: "example.com", name: "x", ...fields }, { respond });
		assert.equal(ran.error, undefined, `${JSON.stringify(fields)}: ${ran.error}`);
		const got = writes[0].input.record.records.at(-1);
		for (const [k, v] of Object.entries(want)) assert.deepEqual(got[k], v, `${fields.type} ${k}`);
	}
});

test("create_record rejects bad input before any call", () => {
	const base = start({ domain: "example.com", name: "x", type: "A", value: "192.0.2.1" });
	const bad = [
		[{ domain: "" }, /domain must be/],
		[{ domain: "localhost" }, /registered domain/],
		[{ type: "PTR" }, /type must be one of/],
		[{ value: "300.1.1.1" }, /IPv4/],
		[{ type: "AAAA", value: "192.0.2.1" }, /IPv6/],
		[{ type: "CNAME", value: "not a host" }, /hostname/],
		[{ type: "MX", value: "mail.example.com" }, /needs a priority/],
		[{ type: "MX", value: "mail.example.com", priority: 70000 }, /needs a priority/],
		[{ priority: 1 }, /take no priority/],
		[{ type: "SRV", value: "5 5060 sip.example.com", priority: 1 }, /_service._proto/],
		[{ type: "SRV", name: "_sip._tcp", value: "5 sip.example.com", priority: 1 }, /weight port target/],
		[{ type: "SRV", name: "_sip._tcp", value: "5 99999 sip.example.com", priority: 1 }, /port/],
		[{ type: "CAA", value: "issue letsencrypt.org" }, /CAA flags|flags tag value/],
		[{ type: "TXT", value: "a\nb" }, /control characters/],
		[{ type: "TXT", value: "x".repeat(4097) }, /4096/],
		[{ type: "CAA", value: `0 issue "${"x".repeat(4096)}"` }, /4096/],
		[{ type: "NS", name: "@", value: "ns1.other.net" }, /nameservers/],
		[{ name: "www.example.com." }, /no trailing dot/],
		[{ name: "a b" }, /name must be/],
		[{ name: "a.*" }, /name must be/],
		[{ name: "-x" }, /name must be/],
		[{ ttl: 0 }, /ttl must be/],
		[{ ttl: "soon" }, /ttl must be a whole number/],
	];
	for (const [fields, error] of bad) {
		const out = run("create_record", { ...base, ...fields });
		assert.match(out.error ?? "", error, JSON.stringify(fields));
		assert.equal(out.calls, undefined, JSON.stringify(fields));
	}
	assert.ok(run("create_record", base).calls);
});

test("create_record refuses duplicates and CNAME clashes", async () => {
	for (const [fields, error] of [
		[{ name: "@", type: "A", value: "192.0.2.1" }, /already exists/],
		[{ name: "WWW", type: "A", value: "192.0.2.5" }, /CNAME cannot share/],
		[{ name: "@", type: "CNAME", value: "other.example.net" }, /CNAME cannot share/],
	]) {
		const { respond, writes } = pds();
		const ran = await runHandle("create_record", { domain: "example.com", ...fields }, { respond });
		assert.match(ran.error, error, JSON.stringify(fields));
		assert.equal(writes.length, 0);
	}
});

test("update_record changes one record in place, keeping what is not given", async () => {
	const { respond, writes } = pds();
	const ran = await runHandle("update_record", { domain: "example.com", name: "@", type: "mx", value: "MAIL.example.com.", newValue: "mx.example.net", ttl: "" }, { respond });
	assert.equal(ran.error, undefined, ran.error);
	const changed = { name: "@", recordType: "MX", value: "mx.example.net", ttl: 3600, priority: 10 };
	assert.deepEqual(writes[0].input.record.records, [records[0], records[1], changed]);
	assert.equal(writes[0].input.swapRecord, "bafyzone1");
	assert.deepEqual(ran.result.record, changed);

	const renamed = pds();
	const out = await runHandle("update_record", { domain: "example.com", name: "@", type: "A", value: "192.0.2.1", newName: "api", ttl: 120 }, { respond: renamed.respond });
	assert.deepEqual(renamed.writes[0].input.record.records[0], { name: "api", recordType: "A", value: "192.0.2.1", ttl: 120 });
	assert.equal(out.result.records, 3);
});

test("update_record checks the new record against the rest of the zone", async () => {
	const { respond, writes } = pds();
	const ran = await runHandle("update_record", { domain: "example.com", name: "@", type: "A", value: "192.0.2.1", newName: "www" }, { respond });
	assert.match(ran.error, /CNAME cannot share/);
	const missing = await runHandle("update_record", { domain: "example.com", name: "@", type: "A", value: "192.0.2.99", newValue: "192.0.2.2" }, { respond });
	assert.match(missing.error, /no A record @ 192.0.2.99/);
	const badNew = await runHandle("update_record", { domain: "example.com", name: "@", type: "A", value: "192.0.2.1", newValue: "nope" }, { respond });
	assert.match(badNew.error, /IPv4/);
	assert.equal(writes.length, 0);
});

test("delete_record removes exactly one record", async () => {
	const { respond, writes } = pds();
	const ran = await runHandle("delete_record", { domain: "example.com", name: "www", type: "CNAME", value: "Example.com." }, { respond });
	assert.equal(ran.error, undefined, ran.error);
	assert.deepEqual(writes[0].input.record.records, [records[0], records[2]]);
	assert.deepEqual(ran.result, { domain: "example.com", uri: zoneUri, cid: "bafyzone2", record: records[1], records: 2 });
	assert.match(run("delete_record", start({ domain: "example.com", name: "www", type: "CNAME" })).error, /value is required/);
	const none = pds({ zone: null });
	assert.match((await runHandle("delete_record", { domain: "example.com", name: "www", type: "CNAME", value: "example.com" }, { respond: none.respond })).error, /no CNAME record/);
});

test("a concurrent edit (swapRecord mismatch) is reported, not overwritten", async () => {
	const { respond } = pds({ write: { ok: false, error: "com.atproto.repo.putRecord failed with InvalidSwap: Record was at bafyother" } });
	const ran = await runHandle("create_record", { domain: "example.com", name: "x", type: "A", value: "192.0.2.9" }, { respond });
	assert.match(ran.error, /changed while editing it, try again/);
});

test("other read errors end the run", async () => {
	const ran = await runHandle("list_records", { domain: "example.com" }, { respond: () => ({ ok: false, error: "getRecord failed with 500" }) });
	assert.match(ran.error, /500/);
});