fix(did): lead DID document @context with did/v1 (did:nostr 0.1.1) - #618
Conversation
DID Core requires a DID document's @context to lead with https://www.w3.org/ns/did/v1. did:nostr 0.1.1 adopted that ordering (nostrcg/did-nostr#136, fixed by #139), so buildDidDocument now emits: [did/v1, cid/v1, w3id.org/nostr/context] cid/v1 is retained because the document's Multikey verification method comes from the Controlled Identifiers vocabulary. The requirement is normative for DID documents only, so the standalone Multikey resource (src/keys/provision.js) and the WebID profile (src/webid/profile.js) correctly keep cid/v1 alone and are untouched. Both orderings expand to the same terms under JSON-LD, so existing documents do not break; JSS's own consumer (src/auth/did-nostr.js) never reads @context — it keys on verificationMethod. Updates the full-shape assertion and adds a dedicated regression test for the leading context, so a reordering failure names itself. Closes #617
There was a problem hiding this comment.
Pull request overview
Updates the locally generated did:nostr DID document to comply with DID Core’s normative requirement that @context starts with https://www.w3.org/ns/did/v1, aligning JSS output with did:nostr 0.1.1 and keeping cid/v1 for the Multikey verification method vocabulary.
Changes:
- Prepend DID Core
did/v1to the DID document@contextemitted by the/.well-known/did/nostr/:pubkeyendpoint. - Update the existing shape assertion test to the new
@contextordering. - Add a targeted regression test asserting
@context[0]is DID Core and thatcid/v1remains present.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| src/idp/well-known-did-nostr.js | Adjusts buildDidDocument() to emit DID Core @context first, retaining CID + Nostr contexts. |
| test/well-known-did-nostr.test.js | Updates assertions for the new ordering and adds a regression test for the normative @context lead value. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| assert.strictEqual(doc['@context'][0], 'https://www.w3.org/ns/did/v1', | ||
| '@context must lead with the DID Core context'); | ||
| // The CID context must still be present — the document's Multikey | ||
| // verification method is drawn from that vocabulary. | ||
| assert.ok(doc['@context'].includes('https://www.w3.org/ns/cid/v1'), | ||
| '@context must still include the CID v1 context'); |
There was a problem hiding this comment.
Good catch — fixed in cd428df. The whole point of splitting this into its own test was that failures name their cause, and a TypeError would have undone that.
@context is now bound to a local ctx, with assert.ok(Array.isArray(ctx), '@context must be present and an array') before any indexing, and the ordering/includes checks run against the local.
Verified rather than assumed: with @context removed from buildDidDocument entirely, the test now fails with AssertionError: @context must be present and an array instead of TypeError: Cannot read properties of undefined.
The dedicated ordering test indexed doc['@context'] and called .includes() without first checking the field exists, so a regression that dropped @context entirely would surface as a TypeError instead of the intended assertion message — defeating the reason the check is a separate test. Bind @context to a local, assert Array.isArray first, then check the ordering. Verified: with @context removed from the builder the test now fails with '@context must be present and an array' rather than a TypeError.
Changes since 0.0.219: - fix(did): DID documents now lead @context with https://www.w3.org/ns/did/v1, as DID Core requires and did:nostr 0.1.1 adopted (#618, closes #617). cid/v1 still follows it for the Multikey verification method. Standalone CID resources and WebID profiles are unaffected — the requirement is normative for DID documents only. - fix(server): the onRequest dotfile guard now honors appPaths, so a plugin mounted at a dot path (e.g. webrtc at /.webrtc) is reachable instead of being 403'd before its mount can answer. Unrelated dotfiles still 403 (#206).
Closes #617.
What
DID Core requires a DID document's
@contextto lead withhttps://www.w3.org/ns/did/v1. did:nostr 0.1.1 adopted that ordering (nostrcg/did-nostr#136, fixed by #139), sobuildDidDocumentnow emits:cid/v1is retained because the document'sMultikeyverification method comes from the Controlled Identifiers vocabulary.Scope — why only this one file
The requirement is normative for DID documents only, so these are deliberately untouched (confirmed by grepping every
cid/v1reference in the repo):src/keys/provision.js— standaloneMultikey, a Controlled Identifier resource;cid/v1alone is correctsrc/webid/profile.js— WebID profile per LWS 1.0;cid/v1vocabulary is correctbuildDidDocumentis the only DID-document emitter: it holds the only@contextin the file and has a single call site (well-known-did-nostr.js:574). No docs contain a DID-document example, and JSS does not consume the upstream test vectors.Compatibility
src/auth/did-nostr.js, never reads@context— it keys entirely onverificationMethod— so the resolver side cannot break on the reordering.Tests
test/well-known-did-nostr.test.jsasserted the old ordering viadeepStrictEqual, so it is updated. Beyond that, a dedicated regression test asserts the normative property — that@context[0]is the DID Core context, and thatcid/v1is still present — so a future reordering fails with a message that names the cause rather than dumping an array diff.Verified the new test is not vacuous: reverting the source change fails both tests, with
@context must lead with the DID Core context. Restoring it passes.Suites run green:
well-known-did-nostr44 (was 43, +1 new),did-nostr27,idp51,webid19,keys-provision22,keys-provision-integration13,lws-cid47,nostr-cid-vm25,conformance27 — 275 tests, 0 failures.