| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
Adds a single CID 1.0 service entry to generated WebID profiles, mirroring the existing `solid:oidcIssuer` predicate. LWS-aware verifiers can now establish trust against JSS-issued profiles by looking up `service[type=lws:OpenIdProvider].serviceEndpoint` per the LWS 1.0 OpenID Connect FPWD. Additive only — all existing WebID predicates remain unchanged, so Mashlib, solid-client-authn, rdflib.js, etc. see the same profile they see today. Storage/Inbox/verificationMethod are deferred until LWS normatively defines those types.
There was a problem hiding this comment.
Adds a CID 1.0 service[] entry (typed lws:OpenIdProvider) to emitted WebID profile JSON-LD so LWS-aware verifiers can discover the issuer via serviceEndpoint, while keeping existing Solid predicates for backwards compatibility.
Changes:
Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| src/webid/profile.js | Adds CID/LWS context terms and emits a CID service[] entry mirroring oidcIssuer. |
| test/webid.test.js | Adds coverage for the new CID service[] entry and its serviceEndpoint/id values. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Sorry, something went wrong.
| 'id': `${docUrl}#oidc`, | ||
| 'type': 'lws:OpenIdProvider', |
| it('lws:OpenIdProvider service.serviceEndpoint mirrors oidcIssuer', async () => { | ||
| const res = await request(profilePath); | ||
| const jsonLd = await res.json(); | ||
| const oidc = jsonLd.service.find((s) => s.type === 'lws:OpenIdProvider'); | ||
| assert.strictEqual( | ||
| oidc.serviceEndpoint, | ||
| jsonLd.oidcIssuer, | ||
| 'serviceEndpoint must equal the existing oidcIssuer value' | ||
| ); |
| it('lws:OpenIdProvider service.id is a fragment on the profile document', async () => { | ||
| const res = await request(profilePath); | ||
| const jsonLd = await res.json(); | ||
| const oidc = jsonLd.service.find((s) => s.type === 'lws:OpenIdProvider'); | ||
| const docUrl = jsonLd['@id'].split('#')[0]; | ||
| assert.strictEqual(oidc.id, `${docUrl}#oidc`, | ||
| 'service entry id should be `<profile-doc>#oidc`'); |
- Alias `id`/`type` to @id/@type in @context so nested service[] entries are interpreted as real JSON-LD node identifiers/types rather than plain properties. CID 1.0 and DID contexts do the same; LWS verifiers that expand JSON-LD would otherwise fail to read these entries. - Tighten the two service-entry tests with explicit assertions on `jsonLd.service` being an array and `oidc` being truthy, so missing data produces clean assertion failures instead of TypeError.
There was a problem hiding this comment.
This PR updates generated WebID profile JSON-LD to additionally emit a CID 1.0 service[] entry of type lws:OpenIdProvider, mirroring the existing solid:oidcIssuer, to align JSS profiles with the LWS 1.0 OpenID Connect discovery expectations.
Changes:
Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| src/webid/profile.js | Adds CID/LWS context terms and emits the new service[] entry in generated profiles. |
| test/webid.test.js | Adds assertions for presence/shape of the new CID service[] entry. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Sorry, something went wrong.
| 'cid': CID, | ||
| 'lws': LWS, | ||
| // Alias `id` → @id and `type` → @type so nested nodes (like each | ||
| // `service[]` entry) are interpreted correctly by JSON-LD processors. | ||
| // CID 1.0 and DID contexts do the same. | ||
| 'id': '@id', | ||
| 'type': '@type', | ||
| 'inbox': { '@id': 'ldp:inbox', '@type': '@id' }, | ||
| 'storage': { '@id': 'pim:storage', '@type': '@id' }, | ||
| 'oidcIssuer': { '@id': 'solid:oidcIssuer', '@type': '@id' }, | ||
| 'preferencesFile': { '@id': 'pim:preferencesFile', '@type': '@id' }, | ||
| 'publicTypeIndex': { '@id': 'solid:publicTypeIndex', '@type': '@id' }, | ||
| 'privateTypeIndex': { '@id': 'solid:privateTypeIndex', '@type': '@id' }, | ||
| 'isPrimaryTopicOf': { '@id': 'foaf:isPrimaryTopicOf', '@type': '@id' }, | ||
| 'mainEntityOfPage': { '@id': 'schema:mainEntityOfPage', '@type': '@id' } | ||
| 'mainEntityOfPage': { '@id': 'schema:mainEntityOfPage', '@type': '@id' }, | ||
| 'service': { '@id': 'cid:service', '@container': '@set' }, | ||
| 'serviceEndpoint': { '@id': 'cid:serviceEndpoint', '@type': '@id' } |
| it('should emit a CID service[] with an lws:OpenIdProvider entry', async () => { | ||
| const res = await request(profilePath); | ||
| const jsonLd = await res.json(); | ||
| assert.ok(Array.isArray(jsonLd.service), 'profile should have a service array'); | ||
| const oidc = jsonLd.service.find((s) => s.type === 'lws:OpenIdProvider'); | ||
| assert.ok(oidc, 'service[] must include an lws:OpenIdProvider entry'); | ||
| }); | ||
|
|
||
| it('lws:OpenIdProvider service.serviceEndpoint mirrors oidcIssuer', async () => { | ||
| const res = await request(profilePath); | ||
| const jsonLd = await res.json(); | ||
| assert.ok(Array.isArray(jsonLd.service), 'profile should have a service array'); | ||
| const oidc = jsonLd.service.find((s) => s.type === 'lws:OpenIdProvider'); | ||
| assert.ok(oidc, 'service[] must include an lws:OpenIdProvider entry'); | ||
| assert.strictEqual( | ||
| oidc.serviceEndpoint, | ||
| jsonLd.oidcIssuer, | ||
| 'serviceEndpoint must equal the existing oidcIssuer value' | ||
| ); | ||
| }); | ||
|
|
||
| it('lws:OpenIdProvider service.id is a fragment on the profile document', async () => { | ||
| const res = await request(profilePath); | ||
| const jsonLd = await res.json(); | ||
| assert.ok(Array.isArray(jsonLd.service), 'profile should have a service array'); | ||
| const oidc = jsonLd.service.find((s) => s.type === 'lws:OpenIdProvider'); | ||
| assert.ok(oidc, 'service[] must include an lws:OpenIdProvider entry'); | ||
| const docUrl = jsonLd['@id'].split('#')[0]; | ||
| assert.strictEqual(oidc.id, `${docUrl}#oidc`, | ||
| 'service entry id should be `<profile-doc>#oidc`'); | ||
| }); |
| 'service': [ | ||
| { | ||
| 'id': `${docUrl}#oidc`, | ||
| 'type': 'lws:OpenIdProvider', | ||
| 'serviceEndpoint': issuer | ||
| } | ||
| ] |
Copilot spotted that the JSON-LD → Turtle converter dropped nested node objects silently: property values that were objects with their own @id/@type/properties (like a CID service[] entry) were collapsed to a bare URI reference, losing the entry's type and serviceEndpoint. The Turtle variant of a JSS profile therefore had no usable CID service data — LWS verifiers asking for Turtle would see only dangling refs. Three fixes: - src/rdf/turtle.js — the main conversion loop now does a BFS over nodes, discovering nested node objects and emitting their triples as their own subjects. - src/rdf/turtle.js — expandUri recursively expands context values that are themselves CURIEs (e.g. `cid:service` in a context term's @id), so prefixed identifiers resolve to full URIs instead of leaking as `<cid:service>` in the output. - src/webid/profile.js — service entries use @id/@type directly and the id/type aliases added in the previous commit are removed. Direct JSON-LD keywords interoperate with the converter cleanly and match the custom-context style used elsewhere in this file. Test plan: - New Turtle-conneg regression test asserts the service predicate, the lws:OpenIdProvider type, the cid:serviceEndpoint predicate, and that the service entry appears as a subject (first-class node) in Turtle. - Existing webid tests updated to check s['@type'] / s['@id'] on the nested service objects rather than the aliased keys. - Full suite green (444/444).
There was a problem hiding this comment.
Adds LWS/CID-compatible service[] metadata to generated WebID profiles and updates JSON-LD→Turtle conversion so nested service nodes are preserved when conneg is enabled.
Changes:
Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| src/webid/profile.js | Adds CID/LWS prefixes and emits a CID service[] entry for OIDC trust discovery. |
| src/rdf/turtle.js | Updates JSON-LD→quads conversion to include nested nodes and expands context CURIE mappings. |
| test/webid.test.js | Adds assertions for CID service[] in JSON-LD and ensures Turtle conneg output retains nested service triples. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Sorry, something went wrong.
| while (queue.length) { | ||
| const node = queue.shift(); |
| const subjectUri = resolveUri(node['@id'], baseUri); | ||
| if (visited.has(subjectUri)) continue; | ||
| visited.add(subjectUri); |
| // Check if it's a term in context. A context value can itself be a | ||
| // CURIE (`cid:service`) that still needs prefix expansion, so recurse. | ||
| if (context[uri]) { | ||
| const expansion = context[uri]; | ||
| if (typeof expansion === 'string') { | ||
| return expansion; | ||
| return expandUri(expansion, context); | ||
| } | ||
| if (expansion['@id']) { | ||
| return expansion['@id']; | ||
| return expandUri(expansion['@id'], context); | ||
| } |
Three fixes to the JSON-LD → Turtle converter, all prompted by Copilot review on #321: - Replace queue.shift() (O(n) per step) with index-based iteration so the BFS is linear in the number of nodes, not quadratic. - Drop the per-subject visited-set that was silently suppressing a second top-level document with the same @id. Duplicate RDF triples are harmless; losing data is not. Cycle protection now happens at the enqueue step via a WeakSet on object identity, which prevents the same nested object from being enqueued twice but still lets distinct top-level docs for the same subject both emit. - Add cycle protection to expandUri. Without it a user-supplied context carrying a term-level loop (a → b → a) could cause unbounded recursion and a stack overflow on the server — a remote DoS once conneg is enabled on a pod. New test/turtle.test.js covers: - Cyclic context (a → b → a) does not hang - Self-loop context (a → a) does not hang - Duplicate top-level @id does not drop data - Cyclical nested node graph does not hang Full suite: 448/448.
There was a problem hiding this comment.
Adds LWS/CID-aligned service[] metadata to generated WebID profiles and ensures Turtle conneg preserves nested service node triples, supporting LWS-aware issuer trust checks.
Changes:
Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| src/webid/profile.js | Adds CID/LWS context terms and emits the new service[] entry in generated profiles. |
| src/rdf/turtle.js | Ensures nested JSON-LD nodes (like service[] entries) are emitted as first-class Turtle subjects; adds cycle guard in context expansion. |
| test/webid.test.js | Adds assertions for the new service[] entry and verifies it survives Turtle content negotiation. |
| test/turtle.test.js | Adds unit tests for converter regressions (cycle safety, duplicate @id handling, cyclical nested references). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Sorry, something went wrong.
| 'service': [ | ||
| { | ||
| '@id': `${docUrl}#oidc`, | ||
| '@type': 'lws:OpenIdProvider', | ||
| 'serviceEndpoint': issuer | ||
| } |
There was a problem hiding this comment.
Good catch — my issue-body example was inconsistent with the code. I've updated #320's Before/After to use @id/@type (matching what this PR actually emits) and added a short rationale:
Nested service entries use the JSON-LD keywords @id and @type directly. CID 1.0's own context URL (https://www.w3.org/ns/cid/v1) provides id/type aliases for authors who prefer the shorter form, but since this profile uses inline term definitions rather than a context URL, we stick with the keywords — they're JSON-LD-native and don't depend on an out-of-band context fetch. A verifier that runs a JSON-LD processor (the expected behaviour for CID-conformant tooling) expands both forms identically.
On the naive-plain-JSON-lookup concern specifically: a verifier that reads this doc as plain JSON would also see "@type": "lws:OpenIdProvider" — which is a CURIE that only expands to https://www.w3.org/ns/lws#OpenIdProvider via the context. So any verifier that doesn't run JSON-LD expansion is already broken regardless of id vs @id. Running a JSON-LD processor is the minimum bar for reading CID-conformant documents, and once that's in play both key shapes are equivalent.
Could you re-review now that the PR description / issue examples match the code?
Sorry, something went wrong.
There was a problem hiding this comment.
Adds LWS/CID-aligned service[] data to generated WebID profiles and ensures the JSON-LD→Turtle conversion preserves nested service node triples (needed for LWS verifiers requesting Turtle).
Changes:
Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| src/webid/profile.js | Adds CID/LWS context terms and emits the service[] entry referencing the issuer. |
| src/rdf/turtle.js | Preserves nested nodes during conversion and adds cycle-safety for context expansion. |
| test/webid.test.js | Adds assertions for service[] and verifies Turtle conneg retains nested service triples. |
| test/turtle.test.js | Adds direct unit tests for converter regressions (cycles, duplicate @id, cyclical nested refs). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Sorry, something went wrong.
| if (uri.includes(':')) { | ||
| const [prefix, local] = uri.split(':', 2); | ||
| const ns = context[prefix] || COMMON_PREFIXES[prefix]; | ||
| if (ns) { | ||
| return ns + local; | ||
| } |
There was a problem hiding this comment.
Adds LWS/CID-compatible OpenID Provider service discovery data to generated WebID profiles, and ensures RDF conneg (JSON-LD → Turtle) preserves nested CID service nodes needed by LWS verifiers.
Changes:
Copilot reviewed 4 out of 4 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| test/webid.test.js | Adds assertions for emitted CID service[] and verifies Turtle conneg retains nested service-node triples. |
| test/turtle.test.js | Adds unit tests covering Turtle conversion regressions (nested nodes, cycles, duplicate @id, context pitfalls). |
| src/webid/profile.js | Adds CID/LWS context terms and emits a single service[] entry for LWS OpenID Provider discovery. |
| src/rdf/turtle.js | Ensures nested node objects are emitted as subjects in Turtle output and hardens URI expansion against cyclic contexts. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Sorry, something went wrong.
…iptSolidServer#325) Two related conneg bugs filed in JavaScriptSolidServer#325: 1. Q-weights ignored in the dispatch. src/handlers/resource.js used naive `acceptHeader.includes('text/turtle')` substring matching to decide between JSON-LD and Turtle. An Accept header of `application/ld+json, text/turtle;q=0.1` returned Turtle even though JSON-LD was the higher-q preference. Replaced five substring sites (handleGet container-with-index, container listing, resource HTML data island; handleHead container) with the existing q-aware `selectContentType` from src/rdf/conneg.js. 2. HEAD/GET divergence on containers without index.html. handleHead hard-coded `application/ld+json` for that case regardless of Accept, so HEAD reported a content-type that didn't match what GET would emit. The mismatch confused tooling that read HEAD content-type and then GET'd the body. handleHead now runs the same q-aware Accept logic so HEAD content-type tracks GET. The auth-vs-anonymous mismatch in JavaScriptSolidServer#325 doesn't reproduce on the current tip — likely fixed by the Turtle-converter work in JavaScriptSolidServer#321. Both anon and auth paths now return identical content-type for the same Accept. Tests: new conneg.test.js block exercises q-weight respect, HEAD/GET parity across four Accept shapes, and auth-vs-anon parity. 470/470.
| Back | FazBrowse Home | New Git URL |
Summary
Adds a single CID 1.0 service[] entry to generated WebID profiles, mirroring the existing solid:oidcIssuer predicate. This lets LWS-aware verifiers establish trust against JSS-issued profiles per the LWS 1.0 OpenID Connect FPWD, which prescribes looking up service[type=lws:OpenIdProvider].serviceEndpoint to confirm the token's iss claim.
What changes
src/webid/profile.js — four small additions to generateProfileJsonLd:
Properties
Test plan
Part of #319 (LWS 1.0 Auth Suite alignment). Fixes #320.