Skip to content

Commit bb86454

Browse files
committed
feat: Multiple custom domain
1 parent 3c3684d commit bb86454

File tree

15 files changed

+1677
-44
lines changed

15 files changed

+1677
-44
lines changed

MCD_EXAMPLES.md

Lines changed: 438 additions & 0 deletions
Large diffs are not rendered by default.

packages/access-token-jwt/package.json

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,5 +35,11 @@
3535
},
3636
"engines": {
3737
"node": "^12.19.0 || ^14.15.0 || ^16.13.0 || ^18.12.0 || ^20.2.0 || ^22.1.0"
38-
}
38+
},
39+
"description": "_This package is not published_",
40+
"directories": {
41+
"test": "test"
42+
},
43+
"keywords": [],
44+
"type": "commonjs"
3945
}

packages/access-token-jwt/src/discovery.ts

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -63,20 +63,27 @@ const discover = async ({
6363
throw new Error('Failed to fetch authorization server metadata');
6464
};
6565

66-
export default (opts: DiscoverOptions) => {
67-
let discovery: Promise<IssuerMetadata> | undefined;
68-
let timestamp = 0;
66+
export default (opts: Omit<DiscoverOptions, 'issuerBaseURL'>) => {
67+
// Support multiple issuers by caching discovery per issuerBaseURL
68+
const discoveryCache = new Map<
69+
string,
70+
{ promise: Promise<IssuerMetadata>; timestamp: number }
71+
>();
6972

70-
return () => {
73+
return (issuerBaseURL: string) => {
7174
const now = Date.now();
75+
const cached = discoveryCache.get(issuerBaseURL);
7276

73-
if (!discovery || now > timestamp + opts.cacheMaxAge) {
74-
timestamp = now;
75-
discovery = discover(opts).catch((e) => {
76-
discovery = undefined;
77+
if (!cached || now > cached.timestamp + opts.cacheMaxAge) {
78+
const timestamp = now;
79+
const promise = discover({ ...opts, issuerBaseURL }).catch((e) => {
80+
discoveryCache.delete(issuerBaseURL);
7781
throw e;
7882
});
83+
discoveryCache.set(issuerBaseURL, { promise, timestamp });
84+
return promise;
7985
}
80-
return discovery;
86+
87+
return cached.promise;
8188
};
8289
};

packages/access-token-jwt/src/get-key-fn.ts

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,22 +19,28 @@ export default ({
1919
cacheMaxAge,
2020
secret
2121
}: JWKSOptions) => {
22-
let getKeyFn: GetKeyFn;
23-
let prevjwksUri: string;
22+
// Support multiple issuers by caching getKeyFn per jwksUri
23+
const keyFnCache = new Map<string, GetKeyFn>();
2424

2525
const secretKey = secret && createSecretKey(Buffer.from(secret));
2626

2727
return (jwksUri: string) => {
2828
if (secretKey) return () => secretKey;
29-
if (!getKeyFn || prevjwksUri !== jwksUri) {
30-
prevjwksUri = jwksUri;
29+
30+
// Check if we have a cached getKeyFn for this jwksUri
31+
let getKeyFn = keyFnCache.get(jwksUri);
32+
33+
if (!getKeyFn) {
34+
// Create new getKeyFn for this jwksUri and cache it
3135
getKeyFn = createRemoteJWKSet(new URL(jwksUri), {
3236
agent,
3337
cooldownDuration,
3438
timeoutDuration,
3539
cacheMaxAge,
3640
});
41+
keyFnCache.set(jwksUri, getKeyFn);
3742
}
43+
3844
return getKeyFn;
3945
};
4046
};

packages/access-token-jwt/src/index.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,14 @@ export {
1414
VerifyJwtResult,
1515
JWTPayload,
1616
JWSHeaderParameters as JWTHeader,
17+
Auth0MCDOptions,
18+
AsymmetricIssuerConfig,
19+
SymmetricIssuerConfig,
20+
IssuerConfig,
21+
IssuerResolverContext,
22+
IssuerResolverResult,
23+
IssuerResolverFunction,
24+
RequestContext,
1725
} from './jwt-verifier';
1826
export {
1927
InvalidTokenError,

0 commit comments

Comments
 (0)