From 04ef38ef72e6393129d3f5976b370c6371e08ca7 Mon Sep 17 00:00:00 2001 From: Roscoe Rubin-Rottenberg Date: Wed, 24 Jun 2026 01:50:19 +0000 Subject: [PATCH] fix: add service fragment in aud check --- auth-verifier.ts | 21 ++++++++++++++++++--- tests/auth_verifier_test.ts | 16 ++++++++++++++++ 2 file(s) changed, 34 insertion(s)(+), 3 deletion(s)(-) diff --git a/auth-verifier.ts b/auth-verifier.ts --- a/auth-verifier.ts +++ b/auth-verifier.ts @@ -135,7 +135,7 @@ // Add properties and methods verifier.ownDid = opts.ownDid; - verifier.standardAudienceDids = new Set([ + verifier.standardAudienceDids = standardAudienceDidsFrom([ opts.ownDid, ...opts.alternateAudienceDids, ]); @@ -180,7 +180,7 @@ opts: AuthVerifierOpts, ) { this.ownDid = opts.ownDid; - this.standardAudienceDids = new Set([ + this.standardAudienceDids = standardAudienceDidsFrom([ opts.ownDid, ...opts.alternateAudienceDids, ]); @@ -221,7 +221,7 @@ iss: null, aud: null, }); - if (!opts.skipAudCheck && !this.standardAudienceDids.has(aud)) { + if (!opts.skipAudCheck && !this.isStandardAudience(aud)) { throw new AuthRequiredError( "jwt audience does not match service did", "BadJwtAudience", @@ -491,6 +491,10 @@ ].includes(iss); } + private isStandardAudience(aud: string): boolean { + return this.standardAudienceDids.has(aud); + } + nullCreds(): NullOutput { return { credentials: { @@ -560,6 +564,17 @@ const [username, password] = parsed; if (!username || !password) return null; return { username, password }; +}; + +export const standardAudienceDidsFrom = (dids: string[]): Set => { + const audiences = new Set(); + for (const did of dids) { + audiences.add(did); + if (!did.includes("#")) { + audiences.add(`${did}#sprk_appview`); + } + } + return audiences; }; export const buildBasicAuth = (username: string, password: string): string => { diff --git a/tests/auth_verifier_test.ts b/tests/auth_verifier_test.ts new file mode 100644 --- /dev/null +++ b/tests/auth_verifier_test.ts @@ -0,0 +1,16 @@ +import { assert, assertEquals } from "@std/assert"; + +import { standardAudienceDidsFrom } from "../auth-verifier.ts"; + +Deno.test("standardAudienceDidsFrom accepts service-fragment audiences", () => { + const audiences = standardAudienceDidsFrom([ + "did:web:api.sprk.so", + "did:web:alt.sprk.so#sprk_appview", + ]); + + assert(audiences.has("did:web:api.sprk.so")); + assert(audiences.has("did:web:api.sprk.so#sprk_appview")); + assert(audiences.has("did:web:alt.sprk.so#sprk_appview")); + assertEquals(audiences.has("did:web:api.sprk.so#other_service"), false); + assertEquals(audiences.has("did:web:alt.sprk.so"), false); +}); -- tangled.sh