From 7bdceb8e0e3d8edbce43a2d4fd8dee5ed3fa4e86 Mon Sep 17 00:00:00 2001 From: Jesse Wright <63333554+jeswr@users.noreply.github.com> Date: Thu, 23 Apr 2026 02:23:17 +0100 Subject: [PATCH 1/4] feat(agent): add oidcIssuers getter for solid:oidcIssuer Mirrors the existing pimStorage / solidStorage / storageUrls getters. Solid-OIDC mandates solid:oidcIssuer for issuer discovery; downstream consumers (reactive-fetch, the ODI Solid browser extension) currently subclass Agent to add this same getter. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/webid/Agent.ts | 4 ++++ test/unit/agent.test.ts | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) create mode 100644 test/unit/agent.test.ts diff --git a/src/webid/Agent.ts b/src/webid/Agent.ts index 82267f3..0dabc6c 100644 --- a/src/webid/Agent.ts +++ b/src/webid/Agent.ts @@ -63,6 +63,10 @@ export class Agent extends TermWrapper { return SetFrom.subjectPredicate(this, SOLID.storage, NamedNodeAs.string, NamedNodeFrom.string) } + get oidcIssuers(): Set { + return SetFrom.subjectPredicate(this, SOLID.oidcIssuer, NamedNodeAs.string, NamedNodeFrom.string) + } + get email(): string | null { return this.hasEmail?.value ?? null } diff --git a/test/unit/agent.test.ts b/test/unit/agent.test.ts new file mode 100644 index 0000000..b018b4c --- /dev/null +++ b/test/unit/agent.test.ts @@ -0,0 +1,33 @@ +import { DataFactory, Parser, Store } from "n3" +import assert from "node:assert" +import { describe, it } from "node:test" + +import { Agent } from "@solid/object" + +describe("Agent oidcIssuers", () => { + + const sampleRDF = ` +@prefix solid: . +@prefix foaf: . + + + a foaf:Person ; + solid:oidcIssuer , . +`; + + it("returns the set of solid:oidcIssuer values declared on the WebID", () => { + const store = new Store() + store.addQuads(new Parser().parse(sampleRDF)) + + const agent = new Agent( + DataFactory.namedNode("https://example.org/profile/card#me"), + store, + DataFactory + ) + + assert.deepStrictEqual( + new Set(agent.oidcIssuers), + new Set(["https://idp.example.org/", "https://idp.other.example/"]) + ) + }) +}) From 1e19297120baa2007aa319249694701c80b75af0 Mon Sep 17 00:00:00 2001 From: Jesse Wright <63333554+jeswr@users.noreply.github.com> Date: Thu, 23 Apr 2026 10:01:27 +0100 Subject: [PATCH 2/4] Apply suggestion from @langsamu Co-authored-by: Samu Lang --- src/webid/Agent.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/webid/Agent.ts b/src/webid/Agent.ts index 0dabc6c..6429989 100644 --- a/src/webid/Agent.ts +++ b/src/webid/Agent.ts @@ -63,7 +63,7 @@ export class Agent extends TermWrapper { return SetFrom.subjectPredicate(this, SOLID.storage, NamedNodeAs.string, NamedNodeFrom.string) } - get oidcIssuers(): Set { + get oidcIssuer(): Set { return SetFrom.subjectPredicate(this, SOLID.oidcIssuer, NamedNodeAs.string, NamedNodeFrom.string) } From 8a8f0469f227257d3a428cfefa75fbb3498b9ffa Mon Sep 17 00:00:00 2001 From: Jesse Wright <63333554+jeswr@users.noreply.github.com> Date: Thu, 23 Apr 2026 12:02:52 +0100 Subject: [PATCH 3/4] Update test/unit/agent.test.ts Co-authored-by: Samu Lang --- test/unit/agent.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/unit/agent.test.ts b/test/unit/agent.test.ts index b018b4c..44171ae 100644 --- a/test/unit/agent.test.ts +++ b/test/unit/agent.test.ts @@ -26,7 +26,7 @@ describe("Agent oidcIssuers", () => { ) assert.deepStrictEqual( - new Set(agent.oidcIssuers), + new Set(agent.oidcIssuer), new Set(["https://idp.example.org/", "https://idp.other.example/"]) ) }) From 4e4946728a51980f885bcefdddf235618bdde03c Mon Sep 17 00:00:00 2001 From: Jesse Wright <63333554+jeswr@users.noreply.github.com> Date: Thu, 23 Apr 2026 12:03:00 +0100 Subject: [PATCH 4/4] Update test/unit/agent.test.ts Co-authored-by: Samu Lang --- test/unit/agent.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/unit/agent.test.ts b/test/unit/agent.test.ts index 44171ae..befde40 100644 --- a/test/unit/agent.test.ts +++ b/test/unit/agent.test.ts @@ -4,7 +4,7 @@ import { describe, it } from "node:test" import { Agent } from "@solid/object" -describe("Agent oidcIssuers", () => { +describe("Agent oidcIssuer", () => { const sampleRDF = ` @prefix solid: .