From 818404ca89c0d41d180166242ae46a770be49890 Mon Sep 17 00:00:00 2001 From: Samu Lang Date: Sun, 14 Jun 2026 18:11:26 +0100 Subject: [PATCH 1/3] Extract client provider --- index.html | 4 ++-- src/DPoPTokenProvider.ts | 8 +++++--- src/GetClientCallback.ts | 3 +++ src/dynamicRegistrationClientCallback.ts | 6 ++++++ src/mod.ts | 2 ++ src/reactive-fetch-worker.ts | 2 +- 6 files changed, 19 insertions(+), 6 deletions(-) create mode 100644 src/GetClientCallback.ts create mode 100644 src/dynamicRegistrationClientCallback.ts diff --git a/index.html b/index.html index 406fb45..3babc61 100644 --- a/index.html +++ b/index.html @@ -13,7 +13,7 @@ } diff --git a/src/DPoPTokenProvider.ts b/src/DPoPTokenProvider.ts index 4760ae2..d979caf 100644 --- a/src/DPoPTokenProvider.ts +++ b/src/DPoPTokenProvider.ts @@ -3,16 +3,19 @@ import * as DPoP from "dpop" import type { GetCodeCallback } from "./GetCodeCallback.js" import type { TokenProvider } from "./TokenProvider.js" import type { GetIssuerCallback } from "./GetIssuerCallback.js" +import type { GetClientCallback } from "./GetClientCallback.js" export class DPoPTokenProvider implements TokenProvider { readonly #getCode: GetCodeCallback readonly #callbackUri: string readonly #getIssuer: GetIssuerCallback + readonly #getClient: GetClientCallback - constructor(callbackUri: string, getCodeCallback: GetCodeCallback, getIssuerCallback: GetIssuerCallback) { + constructor(callbackUri: string, getCodeCallback: GetCodeCallback, getIssuerCallback: GetIssuerCallback, getClientCallback: GetClientCallback) { this.#getCode = getCodeCallback this.#callbackUri = callbackUri this.#getIssuer = getIssuerCallback + this.#getClient = getClientCallback } async matches(request: Request): Promise { @@ -25,8 +28,7 @@ export class DPoPTokenProvider implements TokenProvider { const discoveryResponse = await oauth.discoveryRequest(issuer, {signal: request.signal}) const authorizationServer = await oauth.processDiscoveryResponse(issuer, discoveryResponse) - const registrationResponse = await oauth.dynamicClientRegistrationRequest(authorizationServer, {redirect_uris: [this.#callbackUri]}, {signal: request.signal}) - const clientRegistration = await oauth.processDynamicClientRegistrationResponse(registrationResponse) + const clientRegistration = await this.#getClient(authorizationServer, this.#callbackUri, request.signal) const [registeredRedirectUri] = clientRegistration.redirect_uris as string[] const [registeredResponseType] = clientRegistration.response_types as string[] diff --git a/src/GetClientCallback.ts b/src/GetClientCallback.ts new file mode 100644 index 0000000..93dd400 --- /dev/null +++ b/src/GetClientCallback.ts @@ -0,0 +1,3 @@ +import * as oauth from "oauth4webapi" + +export type GetClientCallback = (as: oauth.AuthorizationServer, redirectUri: string, signal: AbortSignal) => Promise diff --git a/src/dynamicRegistrationClientCallback.ts b/src/dynamicRegistrationClientCallback.ts new file mode 100644 index 0000000..721faec --- /dev/null +++ b/src/dynamicRegistrationClientCallback.ts @@ -0,0 +1,6 @@ +import * as oauth from "oauth4webapi" + +export async function dynamicRegistrationClientCallback(as: oauth.AuthorizationServer, redirectUri: string, signal: AbortSignal): Promise { + const registrationResponse = await oauth.dynamicClientRegistrationRequest(as, {redirect_uris: [redirectUri]}, {signal}) + return await oauth.processDynamicClientRegistrationResponse(registrationResponse) +} diff --git a/src/mod.ts b/src/mod.ts index 268eee3..6112a76 100644 --- a/src/mod.ts +++ b/src/mod.ts @@ -12,3 +12,5 @@ export * from "./TokenProvider.js" export * from "./GetIssuerCallback.js" export * from "./IdpPicker.js" export * from "./IssuerRequestCancelledError.js" +export * from "./GetClientCallback.js" +export * from "./dynamicRegistrationClientCallback.js" diff --git a/src/reactive-fetch-worker.ts b/src/reactive-fetch-worker.ts index 3a595ef..2e9a310 100644 --- a/src/reactive-fetch-worker.ts +++ b/src/reactive-fetch-worker.ts @@ -28,7 +28,7 @@ async function onFetch(e: FetchEvent): Promise { } function upgrade(request: Request, client: Client): Promise { - const dPoPTokenProvider = new DPoPTokenProvider(undefined!, postEventAndWait.bind(undefined, client), undefined!) // TODO: Callback, getIssuer + const dPoPTokenProvider = new DPoPTokenProvider(undefined!, postEventAndWait.bind(undefined, client), undefined!, undefined!) // TODO: Callback, getIssuer, getClient const bearerProvider = new BearerTokenProvider(postEventAndWait.bind(undefined, client)) return new ReactiveAuthenticationClient(self.fetch, [bearerProvider, dPoPTokenProvider]).fetch(request) From 58741ded90ea856a376c0aa921bba494ccef1428 Mon Sep 17 00:00:00 2001 From: Samu Lang Date: Sun, 14 Jun 2026 21:00:26 +0100 Subject: [PATCH 2/3] Solid-OIDC Client Id Doc --- id.jsonld | 15 +++++++++++++++ index.html | 4 ++-- src/clientIdClientCallback.ts | 7 +++++++ src/mod.ts | 1 + 4 files changed, 25 insertions(+), 2 deletions(-) create mode 100644 id.jsonld create mode 100644 src/clientIdClientCallback.ts diff --git a/id.jsonld b/id.jsonld new file mode 100644 index 0000000..32dbe36 --- /dev/null +++ b/id.jsonld @@ -0,0 +1,15 @@ +{ + "client_id": "http://localhost:8080/id.jsonld", + "redirect_uris": [ + "http://localhost:8080/callback.html" + ], + "scope": "openid webid", + "grant_types": [ + "authorization_code", + "refresh_token" + ], + "response_types": [ + "code" + ], + "@context": "https://www.w3.org/ns/solid/oidc-context.jsonld" +} diff --git a/index.html b/index.html index 3babc61..1d523ee 100644 --- a/index.html +++ b/index.html @@ -13,7 +13,7 @@ } diff --git a/src/clientIdClientCallback.ts b/src/clientIdClientCallback.ts new file mode 100644 index 0000000..a20ec05 --- /dev/null +++ b/src/clientIdClientCallback.ts @@ -0,0 +1,7 @@ +import type {GetClientCallback} from "./GetClientCallback.js" + +export function clientIdClientCallback(clientIdDocUri: URL): GetClientCallback { + return async function (_, __, signal) { + return await (await fetch(clientIdDocUri, {signal})).json() + } +} diff --git a/src/mod.ts b/src/mod.ts index 6112a76..6ef1920 100644 --- a/src/mod.ts +++ b/src/mod.ts @@ -14,3 +14,4 @@ export * from "./IdpPicker.js" export * from "./IssuerRequestCancelledError.js" export * from "./GetClientCallback.js" export * from "./dynamicRegistrationClientCallback.js" +export * from "./clientIdClientCallback.js" From 9f1e4a353cc250444522bdb1872db3edca9f9232 Mon Sep 17 00:00:00 2001 From: Samu Lang Date: Wed, 2 Sep 2026 18:02:04 +0100 Subject: [PATCH 3/3] Redo with interface instead of callback --- id.jsonld | 6 +----- index.html | 2 ++ src/ClientIdClientProvider.ts | 12 ++++++++++++ src/GetClientCallback.ts | 3 --- src/clientIdClientCallback.ts | 7 ------- src/dynamicRegistrationClientCallback.ts | 6 ------ src/mod.ts | 1 + 7 files changed, 16 insertions(+), 21 deletions(-) create mode 100644 src/ClientIdClientProvider.ts delete mode 100644 src/GetClientCallback.ts delete mode 100644 src/clientIdClientCallback.ts delete mode 100644 src/dynamicRegistrationClientCallback.ts diff --git a/id.jsonld b/id.jsonld index 32dbe36..1390baa 100644 --- a/id.jsonld +++ b/id.jsonld @@ -1,13 +1,9 @@ { + "token_endpoint_auth_method": "none", "client_id": "http://localhost:8080/id.jsonld", "redirect_uris": [ "http://localhost:8080/callback.html" ], - "scope": "openid webid", - "grant_types": [ - "authorization_code", - "refresh_token" - ], "response_types": [ "code" ], diff --git a/index.html b/index.html index 9595a13..0b998be 100644 --- a/index.html +++ b/index.html @@ -19,6 +19,7 @@ CachingAuthorizationServerProvider, CachingClientProvider, CachingIssuerProvider, + // ClientIdClientProvider, DPoPTokenProvider, DynamicRegistrationClientProvider, ReactiveFetchManager, @@ -34,6 +35,7 @@ const cachingASProvider = new CachingAuthorizationServerProvider(asProvider) const callbackUri = new URL("/callback.html", location.href).toString() const clientProvider = new DynamicRegistrationClientProvider + // const clientProvider = new ClientIdClientProvider(new URL("./id.jsonld", location.href)) const cachingClientProvider = new CachingClientProvider(clientProvider) const dPoPTokenProvider = new DPoPTokenProvider(callbackUri, ui, cachingASProvider, cachingClientProvider) diff --git a/src/ClientIdClientProvider.ts b/src/ClientIdClientProvider.ts new file mode 100644 index 0000000..2f98827 --- /dev/null +++ b/src/ClientIdClientProvider.ts @@ -0,0 +1,12 @@ +import type { ClientProvider } from "./ClientProvider.js" +import * as oauth from "oauth4webapi" + +export class ClientIdClientProvider implements ClientProvider { + constructor(private clientIdDocUri: URL) { + } + + async getClient(_: oauth.AuthorizationServer, __: string, signal: AbortSignal): Promise { + const response = await fetch(this.clientIdDocUri, {signal}) + return await response.json() + } +} diff --git a/src/GetClientCallback.ts b/src/GetClientCallback.ts deleted file mode 100644 index 93dd400..0000000 --- a/src/GetClientCallback.ts +++ /dev/null @@ -1,3 +0,0 @@ -import * as oauth from "oauth4webapi" - -export type GetClientCallback = (as: oauth.AuthorizationServer, redirectUri: string, signal: AbortSignal) => Promise diff --git a/src/clientIdClientCallback.ts b/src/clientIdClientCallback.ts deleted file mode 100644 index a20ec05..0000000 --- a/src/clientIdClientCallback.ts +++ /dev/null @@ -1,7 +0,0 @@ -import type {GetClientCallback} from "./GetClientCallback.js" - -export function clientIdClientCallback(clientIdDocUri: URL): GetClientCallback { - return async function (_, __, signal) { - return await (await fetch(clientIdDocUri, {signal})).json() - } -} diff --git a/src/dynamicRegistrationClientCallback.ts b/src/dynamicRegistrationClientCallback.ts deleted file mode 100644 index 721faec..0000000 --- a/src/dynamicRegistrationClientCallback.ts +++ /dev/null @@ -1,6 +0,0 @@ -import * as oauth from "oauth4webapi" - -export async function dynamicRegistrationClientCallback(as: oauth.AuthorizationServer, redirectUri: string, signal: AbortSignal): Promise { - const registrationResponse = await oauth.dynamicClientRegistrationRequest(as, {redirect_uris: [redirectUri]}, {signal}) - return await oauth.processDynamicClientRegistrationResponse(registrationResponse) -} diff --git a/src/mod.ts b/src/mod.ts index 5441d6c..851b4d7 100644 --- a/src/mod.ts +++ b/src/mod.ts @@ -21,3 +21,4 @@ export * from "./CachingAuthorizationServerProvider.js" export * from "./ClientProvider.js" export * from "./DynamicRegistrationClientProvider.js" export * from "./CachingClientProvider.js" +export * from "./ClientIdClientProvider.js"