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

johnandersen777.bsky.social/atlibs-marque

0
0
main
99 lines · 5.0 KB Raw History

atlibs-marque

An atlibs wasm module (knotless://johnandersen777.bsky.social/atlibs) and a page that edit the DNS records of the domains an account registered through Marque, the AT Protocol registrar.

How Marque keeps DNS

The lexicons are published by the at.marque authority (_lexicon.marque.at TXT -> did:plc:nckosudltxrtrjkt4zz4jy5y, com.atproto.lexicon.schema records on its PDS):

  • at.marque.domain: one record per domain in the owner's repo, keyed by the FQDN (domain, status, registeredAt, expiresAt, nameServers, dnssec, autoRenew, ...). Marque's partner flow writes it into the repo of the DID that paid for the domain; that record is what this module takes as "the account owns this domain".
  • at.marque.dns: the domain's whole zone in ONE record with the same key: domain, subject (a strongRef to the at.marque.domain record), records (at.marque.dns#entry: name relative to the apex or @, recordType A/AAAA/CNAME/MX/TXT/SRV/NS/CAA, value, ttl, priority for MX and SRV) and createdAt.

Marque's docs say its nameserver consumes the public at.marque.dns record, so an edit is only a repo write: no XRPC call to Marque. (at.marque.dns.getRecords, a query on did:web:marque.at#marque_registrar for the records it actually serves, exists but no Marque permission set grants it; this module does not call it.)

The module

modules/marque, session records/marque.json, scope atproto repo:at.marque.dns?action=create&action=update: it can write DNS zones and nothing else (not at.marque.domain, and it never deletes a zone).

entryinputdoes
list_domainsthe account's at.marque.domain records (paged)
list_recordsdomainthe domain's zone: records, uri, cid, the domain's status
create_recorddomain name type value [ttl] [priority]adds a record (TTL defaults to 3600)
update_recorddomain name type value [newName] [newValue] [ttl] [priority]changes the record named by name, type and value; blank keeps its own
delete_recorddomain name type valueremoves that record

Reads are public reads of the account's own PDS, so listing works signed out for any DID. Writes read the domain and zone records, refuse a domain with no at.marque.domain record in the repo, and put the zone back with swapRecord (a concurrent edit fails with "try again" instead of being lost), keeping fields Marque added (such as baseRevision) and pointing subject at the domain record as it is now. A domain with no zone yet gets one with createRecord. Calls: listRecords, getRecord, createRecord, putRecord; anyRecords: ["at.marque.dns"], as Marque writes the zone first.

Checked in the module before any call: the name (@, or relative labels of a-z0-9-_, a leading * label, no trailing dot; SRV names _service._proto; no NS at @, those are the domain's nameservers), the value per type (IPv4, IPv6, hostnames, SRV weight port target, CAA flags tag value, TXT 1 to 4096 bytes without control characters), TTL 1 to 2^31-1, priority 0 to 65535 on MX and SRV only; and against the zone: no exact duplicates, a CNAME alone at its name. Values are stored as Marque stores them: hostnames lowercase without the trailing dot, IPv6 compressed.

Layout

  • modules/marque: the module (Rust, against atlibs' abi SDK), its module.json and test.mjs
  • web/marque: a page: sign in, your domains, a domain's records with add, edit and remove
  • records/marque.json: the session record

Set up

atlibs is a sibling checkout: Cargo fetches the abi crate from git, and the tests and the page import its JavaScript from ../atlibs.

git clone https://knotless.dev/johnandersen777.bsky.social/atlibs ../atlibs && git -C ../atlibs checkout -q 88b2ba8

Build and test

cargo wasm
node --test modules/*/test.mjs web/*/*.test.mjs
(cd ../atlibs && cargo host)   # the atlibs CLI, for the Rust host
node --import ../atlibs/rust/host/swap.mjs --test modules/*/test.mjs   # the same, on the Rust host

web/marque/marque.test.mjs boots the page in headless Chrome (skipped without Chrome).

Run

python3 -m http.server 8000 --bind 127.0.0.1 --directory web/marque

Open http://127.0.0.1:8000/ (?module=bobvmbuilder.bsky.social/marque runs the published module record instead of your build).

From a shell or a server, the same entries (reads need no sign-in):

atlibs run modules/marque list_domains '{"did":"did:plc:..."}'
atlibs run modules/marque list_records '{"did":"did:plc:...","domain":"example.com"}'
atlibs login you.example
atlibs run modules/marque create_record '{"domain":"example.com","name":"_atlibs-test","type":"TXT","value":"hello"}' --as you.example

atlibs stage --target spa --origin https://you.example/app/ --out dist modules/marque stages the module and its OAuth client for a page.