oidc-spa 8.6.19 → 8.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/backend.d.ts +3 -20
- package/backend.js +50 -242
- package/backend.js.map +1 -1
- package/core/OidcMetadata.d.ts +2 -2
- package/core/OidcMetadata.js.map +1 -1
- package/core/createOidc.d.ts +2 -4
- package/core/createOidc.js +41 -3
- package/core/createOidc.js.map +1 -1
- package/core/dpop.d.ts +20 -0
- package/core/dpop.js +389 -0
- package/core/dpop.js.map +1 -0
- package/core/earlyInit.js +2 -0
- package/core/earlyInit.js.map +1 -1
- package/core/oidcClientTsUserToTokens.d.ts +1 -0
- package/core/oidcClientTsUserToTokens.js +15 -5
- package/core/oidcClientTsUserToTokens.js.map +1 -1
- package/core/tokenExfiltrationDefense.js +49 -6
- package/core/tokenExfiltrationDefense.js.map +1 -1
- package/esm/angular.d.ts +2 -0
- package/esm/angular.mjs.map +1 -1
- package/esm/backend.d.ts +3 -20
- package/esm/backend.mjs +50 -242
- package/esm/backend.mjs.map +1 -1
- package/esm/core/OidcMetadata.d.ts +2 -2
- package/esm/core/OidcMetadata.mjs.map +1 -1
- package/esm/core/createOidc.d.ts +2 -4
- package/esm/core/createOidc.mjs +41 -3
- package/esm/core/createOidc.mjs.map +1 -1
- package/esm/core/dpop.d.ts +20 -0
- package/esm/core/dpop.mjs +384 -0
- package/esm/core/dpop.mjs.map +1 -0
- package/esm/core/earlyInit.mjs +2 -0
- package/esm/core/earlyInit.mjs.map +1 -1
- package/esm/core/oidcClientTsUserToTokens.d.ts +1 -0
- package/esm/core/oidcClientTsUserToTokens.mjs +15 -5
- package/esm/core/oidcClientTsUserToTokens.mjs.map +1 -1
- package/esm/core/tokenExfiltrationDefense.mjs +49 -6
- package/esm/core/tokenExfiltrationDefense.mjs.map +1 -1
- package/esm/react-spa/createOidcSpaApi.mjs +2 -1
- package/esm/react-spa/createOidcSpaApi.mjs.map +1 -1
- package/esm/react-spa/types.d.ts +2 -0
- package/esm/server/createOidcSpaUtils.d.ts +5 -0
- package/esm/server/createOidcSpaUtils.mjs +639 -0
- package/esm/server/createOidcSpaUtils.mjs.map +1 -0
- package/esm/server/index.d.ts +2 -0
- package/esm/server/index.mjs +3 -0
- package/esm/server/index.mjs.map +1 -0
- package/esm/server/types.d.ts +79 -0
- package/esm/server/types.mjs +2 -0
- package/esm/server/types.mjs.map +1 -0
- package/esm/server/utilsBuilder.d.ts +10 -0
- package/esm/server/utilsBuilder.mjs +13 -0
- package/esm/server/utilsBuilder.mjs.map +1 -0
- package/esm/tanstack-start/react/accessTokenValidation_rfc9068.d.ts +1 -1
- package/esm/tanstack-start/react/accessTokenValidation_rfc9068.mjs +102 -94
- package/esm/tanstack-start/react/accessTokenValidation_rfc9068.mjs.map +1 -1
- package/esm/tanstack-start/react/createOidcSpaApi.d.ts +2 -2
- package/esm/tanstack-start/react/createOidcSpaApi.mjs +60 -51
- package/esm/tanstack-start/react/createOidcSpaApi.mjs.map +1 -1
- package/esm/tanstack-start/react/index.d.ts +1 -1
- package/esm/tanstack-start/react/index.mjs +2 -2
- package/esm/tanstack-start/react/index.mjs.map +1 -1
- package/esm/tanstack-start/react/types.d.ts +36 -11
- package/esm/tanstack-start/react/{apiBuilder.d.ts → utilsBuilder.d.ts} +9 -9
- package/esm/tanstack-start/react/{apiBuilder.mjs → utilsBuilder.mjs} +6 -6
- package/esm/tanstack-start/react/utilsBuilder.mjs.map +1 -0
- package/esm/tools/generateES256DPoPProof.d.ts +8 -0
- package/esm/tools/generateES256DPoPProof.mjs +48 -0
- package/esm/tools/generateES256DPoPProof.mjs.map +1 -0
- package/esm/tools/getServerDateNow.d.ts +5 -0
- package/esm/tools/getServerDateNow.mjs +7 -0
- package/esm/tools/getServerDateNow.mjs.map +1 -0
- package/esm/vendor/{backend → server}/evt.mjs +84 -140
- package/esm/vendor/{backend → server}/jose.mjs +5 -27
- package/esm/vendor/{backend → server}/tsafe.d.ts +1 -0
- package/esm/vendor/{backend → server}/tsafe.mjs +6 -0
- package/esm/vendor/{backend → server}/zod.mjs +196 -50
- package/package.json +6 -1
- package/react-spa/createOidcSpaApi.js +2 -1
- package/react-spa/createOidcSpaApi.js.map +1 -1
- package/react-spa/types.d.ts +2 -0
- package/server/createOidcSpaUtils.d.ts +5 -0
- package/server/createOidcSpaUtils.js +642 -0
- package/server/createOidcSpaUtils.js.map +1 -0
- package/server/index.d.ts +2 -0
- package/server/index.js +6 -0
- package/server/index.js.map +1 -0
- package/server/types.d.ts +79 -0
- package/server/types.js +3 -0
- package/server/types.js.map +1 -0
- package/server/utilsBuilder.d.ts +10 -0
- package/server/utilsBuilder.js +16 -0
- package/server/utilsBuilder.js.map +1 -0
- package/src/angular.ts +3 -0
- package/src/backend.ts +63 -364
- package/src/core/OidcMetadata.ts +4 -2
- package/src/core/createOidc.ts +54 -6
- package/src/core/dpop.ts +583 -0
- package/src/core/earlyInit.ts +3 -0
- package/src/core/oidcClientTsUserToTokens.ts +18 -4
- package/src/core/tokenExfiltrationDefense.ts +60 -5
- package/src/react-spa/createOidcSpaApi.ts +2 -1
- package/src/react-spa/types.tsx +3 -0
- package/src/server/createOidcSpaUtils.ts +848 -0
- package/src/server/index.ts +4 -0
- package/src/server/types.tsx +99 -0
- package/src/server/utilsBuilder.ts +41 -0
- package/src/tanstack-start/react/accessTokenValidation_rfc9068.ts +134 -124
- package/src/tanstack-start/react/createOidcSpaApi.ts +73 -69
- package/src/tanstack-start/react/index.ts +2 -2
- package/src/tanstack-start/react/types.tsx +44 -12
- package/src/tanstack-start/react/{apiBuilder.ts → utilsBuilder.ts} +14 -14
- package/src/tools/generateES256DPoPProof.ts +74 -0
- package/src/tools/getServerDateNow.ts +11 -0
- package/src/vendor/{backend → server}/tsafe.ts +1 -0
- package/tools/generateES256DPoPProof.d.ts +8 -0
- package/tools/generateES256DPoPProof.js +51 -0
- package/tools/generateES256DPoPProof.js.map +1 -0
- package/tools/getServerDateNow.d.ts +5 -0
- package/tools/getServerDateNow.js +10 -0
- package/tools/getServerDateNow.js.map +1 -0
- package/vendor/server/evt.js +3 -0
- package/vendor/server/jose.js +3 -0
- package/vendor/{backend → server}/tsafe.d.ts +1 -0
- package/vendor/server/tsafe.js +2 -0
- package/vendor/server/zod.js +3 -0
- package/esm/tanstack-start/react/apiBuilder.mjs.map +0 -1
- package/vendor/backend/evt.js +0 -3
- package/vendor/backend/jose.js +0 -3
- package/vendor/backend/tsafe.js +0 -2
- package/vendor/backend/zod.js +0 -3
- /package/esm/vendor/{backend → server}/evt.d.ts +0 -0
- /package/esm/vendor/{backend → server}/jose.d.ts +0 -0
- /package/esm/vendor/{backend → server}/zod.d.ts +0 -0
- /package/src/vendor/{backend → server}/evt.ts +0 -0
- /package/src/vendor/{backend → server}/jose.ts +0 -0
- /package/src/vendor/{backend → server}/zod.ts +0 -0
- /package/vendor/{backend → server}/evt.d.ts +0 -0
- /package/vendor/{backend → server}/jose.d.ts +0 -0
- /package/vendor/{backend → server}/zod.d.ts +0 -0
|
@@ -0,0 +1,639 @@
|
|
|
1
|
+
import { Deferred } from "../tools/Deferred.mjs";
|
|
2
|
+
import { decodeProtectedHeader, jwtVerify, createLocalJWKSet, errors, importJWK, calculateJwkThumbprint } from "../vendor/server/jose.mjs";
|
|
3
|
+
import { assert, isAmong, id, is, Reflect } from "../vendor/server/tsafe.mjs";
|
|
4
|
+
import { z } from "../vendor/server/zod.mjs";
|
|
5
|
+
import { Evt, throttleTime } from "../vendor/server/evt.mjs";
|
|
6
|
+
import { decodeJwt } from "../tools/decodeJwt.mjs";
|
|
7
|
+
import { createHash } from "crypto";
|
|
8
|
+
export function createOidcSpaUtils(params) {
|
|
9
|
+
const { decodedAccessTokenSchema } = params;
|
|
10
|
+
const dParamsOfBootstrap = new Deferred();
|
|
11
|
+
const evtPublicSigningKeys = Evt.create(undefined);
|
|
12
|
+
const evtInvalidSignature = Evt.create();
|
|
13
|
+
evtInvalidSignature.pipe(throttleTime(3600000)).attach(async () => {
|
|
14
|
+
const publicSigningKeys_new = await (async function callee(count) {
|
|
15
|
+
const paramsOfBootstrap = await dParamsOfBootstrap.pr;
|
|
16
|
+
assert(paramsOfBootstrap.implementation === "real");
|
|
17
|
+
const { issuerUri } = paramsOfBootstrap;
|
|
18
|
+
let wrap;
|
|
19
|
+
try {
|
|
20
|
+
wrap = await fetchPublicSigningKeys({ issuerUri });
|
|
21
|
+
}
|
|
22
|
+
catch (error) {
|
|
23
|
+
if (count === 9) {
|
|
24
|
+
console.warn(`Failed to refresh public key and signing algorithm after ${count + 1} attempts`);
|
|
25
|
+
return undefined;
|
|
26
|
+
}
|
|
27
|
+
const delayMs = 1000 * Math.pow(2, count);
|
|
28
|
+
console.warn(`Failed to refresh public key and signing algorithm: ${String(error)}, retrying in ${delayMs}ms`);
|
|
29
|
+
await new Promise(resolve => setTimeout(resolve, delayMs));
|
|
30
|
+
return callee(count + 1);
|
|
31
|
+
}
|
|
32
|
+
return wrap;
|
|
33
|
+
})(0);
|
|
34
|
+
if (publicSigningKeys_new === undefined) {
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
evtPublicSigningKeys.state = publicSigningKeys_new;
|
|
38
|
+
});
|
|
39
|
+
let bootstrapAuth_prResolved = undefined;
|
|
40
|
+
const bootstrapAuth = paramsOfBootstrap => {
|
|
41
|
+
if (bootstrapAuth_prResolved !== undefined) {
|
|
42
|
+
return bootstrapAuth_prResolved;
|
|
43
|
+
}
|
|
44
|
+
return (bootstrapAuth_prResolved = (async () => {
|
|
45
|
+
dParamsOfBootstrap.resolve(paramsOfBootstrap);
|
|
46
|
+
if (paramsOfBootstrap.implementation === "real") {
|
|
47
|
+
evtPublicSigningKeys.state = await fetchPublicSigningKeys({
|
|
48
|
+
issuerUri: paramsOfBootstrap.issuerUri
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
})());
|
|
52
|
+
};
|
|
53
|
+
const { getIsDpopPoofSeenRecordIfNotSeen } = (() => {
|
|
54
|
+
const timeSeenByDpopProofId = new Map();
|
|
55
|
+
const evtDpopProofAdded = Evt.create();
|
|
56
|
+
evtDpopProofAdded.pipe(throttleTime(40000)).attach(async () => {
|
|
57
|
+
await Promise.resolve();
|
|
58
|
+
const now = Date.now();
|
|
59
|
+
for (const [dpopProofId, timeSeen] of timeSeenByDpopProofId) {
|
|
60
|
+
if (now - timeSeen > 40000) {
|
|
61
|
+
timeSeenByDpopProofId.delete(dpopProofId);
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
// NOTE: All entries added after are more recent.
|
|
65
|
+
break;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
function getIsDpopPoofSeenRecordIfNotSeen(params) {
|
|
70
|
+
const { jkt, jti } = params;
|
|
71
|
+
const dpopProofId = `${jkt}:${jti}`;
|
|
72
|
+
if (timeSeenByDpopProofId.has(dpopProofId)) {
|
|
73
|
+
return true;
|
|
74
|
+
}
|
|
75
|
+
{
|
|
76
|
+
timeSeenByDpopProofId.set(dpopProofId, Date.now());
|
|
77
|
+
if (timeSeenByDpopProofId.size > 50000) {
|
|
78
|
+
const firstEntry = timeSeenByDpopProofId[Symbol.iterator]().next().value;
|
|
79
|
+
assert(firstEntry !== undefined);
|
|
80
|
+
const [key] = firstEntry;
|
|
81
|
+
timeSeenByDpopProofId.delete(key);
|
|
82
|
+
}
|
|
83
|
+
evtDpopProofAdded.post();
|
|
84
|
+
}
|
|
85
|
+
return false;
|
|
86
|
+
}
|
|
87
|
+
return { getIsDpopPoofSeenRecordIfNotSeen };
|
|
88
|
+
})();
|
|
89
|
+
const validateAndDecodeAccessToken = async ({ request }) => {
|
|
90
|
+
const paramsOfBootstrap = await dParamsOfBootstrap.pr;
|
|
91
|
+
if (paramsOfBootstrap.implementation === "mock" &&
|
|
92
|
+
paramsOfBootstrap.behavior === "use static identity") {
|
|
93
|
+
return id({
|
|
94
|
+
isSuccess: true,
|
|
95
|
+
decodedAccessToken: paramsOfBootstrap.decodedAccessToken_mock,
|
|
96
|
+
get accessToken() {
|
|
97
|
+
if (paramsOfBootstrap.accessToken_mock === undefined) {
|
|
98
|
+
throw new Error([
|
|
99
|
+
"oidc-spa: No mock provided for accessToken.",
|
|
100
|
+
"Provide accessToken_mock to bootstrapAuth"
|
|
101
|
+
].join(" "));
|
|
102
|
+
}
|
|
103
|
+
return paramsOfBootstrap.accessToken_mock;
|
|
104
|
+
},
|
|
105
|
+
get decodedAccessToken_original() {
|
|
106
|
+
if (paramsOfBootstrap.decodedAccessToken_original_mock === undefined) {
|
|
107
|
+
throw new Error([
|
|
108
|
+
"oidc-spa: No mock provided for decodedAccessToken_original.",
|
|
109
|
+
"Provide decodedAccessToken_original_mock to bootstrapAuth"
|
|
110
|
+
].join(" "));
|
|
111
|
+
}
|
|
112
|
+
return paramsOfBootstrap.decodedAccessToken_original_mock;
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
if (!request.headers.Authorization) {
|
|
117
|
+
return id({
|
|
118
|
+
isSuccess: false,
|
|
119
|
+
errorCause: "missing Authorization header",
|
|
120
|
+
debugErrorMessage: "The request is anonymous, no Authorization header"
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
const match = request.headers.Authorization.trim().match(/^((?:Bearer)|(?:DPoP))\s+(.+)$/i);
|
|
124
|
+
if (match === null) {
|
|
125
|
+
return id({
|
|
126
|
+
isSuccess: false,
|
|
127
|
+
errorCause: "validation error",
|
|
128
|
+
debugErrorMessage: "Malformed Authorization header"
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
const [, scheme, accessToken] = match;
|
|
132
|
+
if (!isAmong(["Bearer", "DPoP"], scheme)) {
|
|
133
|
+
return id({
|
|
134
|
+
isSuccess: false,
|
|
135
|
+
errorCause: "validation error",
|
|
136
|
+
debugErrorMessage: `Unsupported scheme ${scheme}, expected Bearer or DPoP`
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
let decodedAccessToken_original;
|
|
140
|
+
validation: {
|
|
141
|
+
if (paramsOfBootstrap.implementation === "mock") {
|
|
142
|
+
assert;
|
|
143
|
+
decodedAccessToken_original = decodeJwt(accessToken);
|
|
144
|
+
try {
|
|
145
|
+
zDecodedAccessToken_RFC9068.parse(decodedAccessToken_original);
|
|
146
|
+
}
|
|
147
|
+
catch (error) {
|
|
148
|
+
assert(error instanceof Error, "38292332");
|
|
149
|
+
return id({
|
|
150
|
+
isSuccess: false,
|
|
151
|
+
errorCause: "validation error",
|
|
152
|
+
debugErrorMessage: [
|
|
153
|
+
`The decoded access token does not satisfies`,
|
|
154
|
+
`the shape mandated by RFC9068: ${error.message}`
|
|
155
|
+
].join(" ")
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
assert(is(decodedAccessToken_original));
|
|
159
|
+
break validation;
|
|
160
|
+
}
|
|
161
|
+
let kid;
|
|
162
|
+
let alg;
|
|
163
|
+
{
|
|
164
|
+
let header;
|
|
165
|
+
try {
|
|
166
|
+
header = decodeProtectedHeader(accessToken);
|
|
167
|
+
}
|
|
168
|
+
catch {
|
|
169
|
+
return id({
|
|
170
|
+
isSuccess: false,
|
|
171
|
+
errorCause: "validation error",
|
|
172
|
+
debugErrorMessage: "Failed to decode the JWT header"
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
const { kid: kidFromHeader, alg: algFromHeader } = header;
|
|
176
|
+
if (typeof kidFromHeader !== "string" || kidFromHeader.length === 0) {
|
|
177
|
+
return id({
|
|
178
|
+
isSuccess: false,
|
|
179
|
+
errorCause: "validation error",
|
|
180
|
+
debugErrorMessage: "The decoded JWT header does not have a kid property"
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
if (typeof algFromHeader !== "string") {
|
|
184
|
+
return id({
|
|
185
|
+
isSuccess: false,
|
|
186
|
+
errorCause: "validation error",
|
|
187
|
+
debugErrorMessage: "The decoded JWT header does not specify an algorithm"
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
if (!isAmong([
|
|
191
|
+
"RS256",
|
|
192
|
+
"RS384",
|
|
193
|
+
"RS512",
|
|
194
|
+
"ES256",
|
|
195
|
+
"ES384",
|
|
196
|
+
"ES512",
|
|
197
|
+
"PS256",
|
|
198
|
+
"PS384",
|
|
199
|
+
"PS512"
|
|
200
|
+
], algFromHeader)) {
|
|
201
|
+
return id({
|
|
202
|
+
isSuccess: false,
|
|
203
|
+
errorCause: "validation error",
|
|
204
|
+
debugErrorMessage: `Unsupported or too weak algorithm ${algFromHeader}`
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
kid = kidFromHeader;
|
|
208
|
+
alg = algFromHeader;
|
|
209
|
+
}
|
|
210
|
+
const publicSigningKeys = evtPublicSigningKeys.state;
|
|
211
|
+
assert(publicSigningKeys !== undefined);
|
|
212
|
+
if (!publicSigningKeys.kidSet.has(kid)) {
|
|
213
|
+
return id({
|
|
214
|
+
isSuccess: false,
|
|
215
|
+
errorCause: "validation error",
|
|
216
|
+
debugErrorMessage: `No public signing key found with kid ${kid}`
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
try {
|
|
220
|
+
const verification = await jwtVerify(accessToken, publicSigningKeys.keyResolver, {
|
|
221
|
+
algorithms: [alg]
|
|
222
|
+
});
|
|
223
|
+
decodedAccessToken_original = verification.payload;
|
|
224
|
+
}
|
|
225
|
+
catch (error) {
|
|
226
|
+
assert(error instanceof Error, "3922843");
|
|
227
|
+
if (error instanceof errors.JWTExpired) {
|
|
228
|
+
return id({
|
|
229
|
+
isSuccess: false,
|
|
230
|
+
errorCause: "validation error - access token expired",
|
|
231
|
+
debugErrorMessage: error.message
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
evtInvalidSignature.post();
|
|
235
|
+
return id({
|
|
236
|
+
isSuccess: false,
|
|
237
|
+
errorCause: "validation error - invalid signature",
|
|
238
|
+
debugErrorMessage: error.message
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
try {
|
|
242
|
+
zDecodedAccessToken_RFC9068.parse(decodedAccessToken_original);
|
|
243
|
+
}
|
|
244
|
+
catch (error) {
|
|
245
|
+
assert(error instanceof Error, "382923");
|
|
246
|
+
return id({
|
|
247
|
+
isSuccess: false,
|
|
248
|
+
errorCause: "validation error",
|
|
249
|
+
debugErrorMessage: [
|
|
250
|
+
`The decoded access token does not satisfies`,
|
|
251
|
+
`the shape mandated by RFC9068: ${error.message}`
|
|
252
|
+
].join(" ")
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
assert(is(decodedAccessToken_original));
|
|
256
|
+
// Validate issuer
|
|
257
|
+
{
|
|
258
|
+
const { issuerUri } = paramsOfBootstrap;
|
|
259
|
+
const normalize = (url) => url.replace(/\/$/, "");
|
|
260
|
+
if (normalize(decodedAccessToken_original.iss) !== normalize(issuerUri)) {
|
|
261
|
+
return id({
|
|
262
|
+
isSuccess: false,
|
|
263
|
+
errorCause: "validation error",
|
|
264
|
+
debugErrorMessage: [
|
|
265
|
+
`iss claim in access token payload "${decodedAccessToken_original.iss}"`,
|
|
266
|
+
`does not match the issuerUri "${issuerUri}".`
|
|
267
|
+
].join(" ")
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
validate_audience: {
|
|
272
|
+
const { expectedAudience } = paramsOfBootstrap;
|
|
273
|
+
if (expectedAudience === undefined) {
|
|
274
|
+
break validate_audience;
|
|
275
|
+
}
|
|
276
|
+
const audiences = decodedAccessToken_original.aud instanceof Array
|
|
277
|
+
? decodedAccessToken_original.aud
|
|
278
|
+
: [decodedAccessToken_original.aud];
|
|
279
|
+
if (!audiences.includes(expectedAudience)) {
|
|
280
|
+
return id({
|
|
281
|
+
isSuccess: false,
|
|
282
|
+
errorCause: "validation error",
|
|
283
|
+
debugErrorMessage: [
|
|
284
|
+
`Not expected audience, got aud claim ${JSON.stringify(decodedAccessToken_original.aud)}`,
|
|
285
|
+
`but expected "${expectedAudience}".`
|
|
286
|
+
].join(" ")
|
|
287
|
+
});
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
validate_DPoP: {
|
|
291
|
+
const cnf_jkt = decodedAccessToken_original.cnf === undefined
|
|
292
|
+
? undefined
|
|
293
|
+
: decodedAccessToken_original.cnf.jkt;
|
|
294
|
+
if (cnf_jkt !== undefined && typeof cnf_jkt !== "string") {
|
|
295
|
+
return id({
|
|
296
|
+
isSuccess: false,
|
|
297
|
+
errorCause: "validation error",
|
|
298
|
+
debugErrorMessage: "cnf.jkt claim is expected to be a string"
|
|
299
|
+
});
|
|
300
|
+
}
|
|
301
|
+
if (scheme === "Bearer") {
|
|
302
|
+
if (cnf_jkt !== undefined) {
|
|
303
|
+
return id({
|
|
304
|
+
isSuccess: false,
|
|
305
|
+
errorCause: "validation error",
|
|
306
|
+
debugErrorMessage: [
|
|
307
|
+
"access token is DPoP bound (cnf.jkt claim present)",
|
|
308
|
+
"but used with bearer scheme"
|
|
309
|
+
].join(" ")
|
|
310
|
+
});
|
|
311
|
+
}
|
|
312
|
+
break validate_DPoP;
|
|
313
|
+
}
|
|
314
|
+
assert;
|
|
315
|
+
if (cnf_jkt === undefined) {
|
|
316
|
+
return id({
|
|
317
|
+
isSuccess: false,
|
|
318
|
+
errorCause: "validation error",
|
|
319
|
+
debugErrorMessage: [
|
|
320
|
+
"DPoP validation error, missing cnf.jtk claim",
|
|
321
|
+
"in the access token payload"
|
|
322
|
+
].join(" ")
|
|
323
|
+
});
|
|
324
|
+
}
|
|
325
|
+
if (!request.headers.DPoP) {
|
|
326
|
+
return id({
|
|
327
|
+
isSuccess: false,
|
|
328
|
+
errorCause: "validation error",
|
|
329
|
+
debugErrorMessage: "Scheme DPoP was specified but the DPoP header is missing"
|
|
330
|
+
});
|
|
331
|
+
}
|
|
332
|
+
const dpopHeaderValue = request.headers.DPoP.trim();
|
|
333
|
+
let dpopHeader;
|
|
334
|
+
try {
|
|
335
|
+
dpopHeader = decodeProtectedHeader(dpopHeaderValue);
|
|
336
|
+
}
|
|
337
|
+
catch {
|
|
338
|
+
return id({
|
|
339
|
+
isSuccess: false,
|
|
340
|
+
errorCause: "validation error",
|
|
341
|
+
debugErrorMessage: "Failed to decode DPoP proof header"
|
|
342
|
+
});
|
|
343
|
+
}
|
|
344
|
+
const { jwk, alg: dpopAlg, typ: dpopTyp } = dpopHeader;
|
|
345
|
+
if (dpopAlg === undefined) {
|
|
346
|
+
return id({
|
|
347
|
+
isSuccess: false,
|
|
348
|
+
errorCause: "validation error",
|
|
349
|
+
debugErrorMessage: "DPoP proof header missing alg"
|
|
350
|
+
});
|
|
351
|
+
}
|
|
352
|
+
if (!isAmong([
|
|
353
|
+
"RS256",
|
|
354
|
+
"RS384",
|
|
355
|
+
"RS512",
|
|
356
|
+
"ES256",
|
|
357
|
+
"ES384",
|
|
358
|
+
"ES512",
|
|
359
|
+
"PS256",
|
|
360
|
+
"PS384",
|
|
361
|
+
"PS512"
|
|
362
|
+
], dpopAlg)) {
|
|
363
|
+
return id({
|
|
364
|
+
isSuccess: false,
|
|
365
|
+
errorCause: "validation error",
|
|
366
|
+
debugErrorMessage: `Unsupported or too weak DPoP algorithm ${dpopAlg}`
|
|
367
|
+
});
|
|
368
|
+
}
|
|
369
|
+
if (dpopTyp === undefined || dpopTyp.toLowerCase() !== "dpop+jwt") {
|
|
370
|
+
return id({
|
|
371
|
+
isSuccess: false,
|
|
372
|
+
errorCause: "validation error",
|
|
373
|
+
debugErrorMessage: "DPoP proof header typ must be dpop+jwt"
|
|
374
|
+
});
|
|
375
|
+
}
|
|
376
|
+
if (jwk === undefined) {
|
|
377
|
+
return id({
|
|
378
|
+
isSuccess: false,
|
|
379
|
+
errorCause: "validation error",
|
|
380
|
+
debugErrorMessage: "DPoP proof header missing jwk"
|
|
381
|
+
});
|
|
382
|
+
}
|
|
383
|
+
let jkt_calculated;
|
|
384
|
+
try {
|
|
385
|
+
jkt_calculated = await calculateJwkThumbprint(jwk);
|
|
386
|
+
}
|
|
387
|
+
catch (error) {
|
|
388
|
+
return id({
|
|
389
|
+
isSuccess: false,
|
|
390
|
+
errorCause: "validation error",
|
|
391
|
+
debugErrorMessage: `Failed to calculate DPoP jwk thumbprint: ${String(error)}`
|
|
392
|
+
});
|
|
393
|
+
}
|
|
394
|
+
if (jkt_calculated !== cnf_jkt) {
|
|
395
|
+
return id({
|
|
396
|
+
isSuccess: false,
|
|
397
|
+
errorCause: "validation error",
|
|
398
|
+
debugErrorMessage: "DPoP jwk thumbprint does not match cnf.jkt claim"
|
|
399
|
+
});
|
|
400
|
+
}
|
|
401
|
+
let dpopPayload;
|
|
402
|
+
try {
|
|
403
|
+
const key = await importJWK(jwk, dpopAlg);
|
|
404
|
+
const verification = await jwtVerify(dpopHeaderValue, key, {
|
|
405
|
+
algorithms: [dpopAlg],
|
|
406
|
+
typ: "dpop+jwt"
|
|
407
|
+
});
|
|
408
|
+
dpopPayload = verification.payload;
|
|
409
|
+
}
|
|
410
|
+
catch (error) {
|
|
411
|
+
assert(error instanceof Error);
|
|
412
|
+
return id({
|
|
413
|
+
isSuccess: false,
|
|
414
|
+
errorCause: "validation error",
|
|
415
|
+
debugErrorMessage: `DPoP proof signature/structure invalid: ${error.message}`
|
|
416
|
+
});
|
|
417
|
+
}
|
|
418
|
+
const { htm, htu, ath, iat, jti } = dpopPayload;
|
|
419
|
+
{
|
|
420
|
+
if (iat === undefined) {
|
|
421
|
+
return id({
|
|
422
|
+
isSuccess: false,
|
|
423
|
+
errorCause: "validation error",
|
|
424
|
+
debugErrorMessage: "DPoP proof missing or invalid iat claim"
|
|
425
|
+
});
|
|
426
|
+
}
|
|
427
|
+
const now = Math.floor(Date.now() / 1000);
|
|
428
|
+
const maxAgeSeconds = 40;
|
|
429
|
+
const maxFutureSkewSeconds = 3;
|
|
430
|
+
if (iat - now > maxFutureSkewSeconds) {
|
|
431
|
+
return id({
|
|
432
|
+
isSuccess: false,
|
|
433
|
+
errorCause: "validation error",
|
|
434
|
+
debugErrorMessage: "DPoP proof iat is in the future"
|
|
435
|
+
});
|
|
436
|
+
}
|
|
437
|
+
if (now - iat > maxAgeSeconds) {
|
|
438
|
+
return id({
|
|
439
|
+
isSuccess: false,
|
|
440
|
+
errorCause: "validation error",
|
|
441
|
+
debugErrorMessage: "DPoP proof iat too old"
|
|
442
|
+
});
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
if (typeof htm !== "string" || htm.toUpperCase() !== request.method.toUpperCase()) {
|
|
446
|
+
return id({
|
|
447
|
+
isSuccess: false,
|
|
448
|
+
errorCause: "validation error",
|
|
449
|
+
debugErrorMessage: "DPoP proof htm claim does not match request method"
|
|
450
|
+
});
|
|
451
|
+
}
|
|
452
|
+
const expectedHtu = (() => {
|
|
453
|
+
try {
|
|
454
|
+
const url = new URL(request.url);
|
|
455
|
+
return `${url.origin}${url.pathname}`;
|
|
456
|
+
}
|
|
457
|
+
catch {
|
|
458
|
+
return undefined;
|
|
459
|
+
}
|
|
460
|
+
})();
|
|
461
|
+
if (expectedHtu === undefined || typeof htu !== "string" || htu !== expectedHtu) {
|
|
462
|
+
return id({
|
|
463
|
+
isSuccess: false,
|
|
464
|
+
errorCause: "validation error",
|
|
465
|
+
debugErrorMessage: "DPoP proof htu claim does not match request url"
|
|
466
|
+
});
|
|
467
|
+
}
|
|
468
|
+
if (typeof ath !== "string") {
|
|
469
|
+
return id({
|
|
470
|
+
isSuccess: false,
|
|
471
|
+
errorCause: "validation error",
|
|
472
|
+
debugErrorMessage: "DPoP proof missing ath claim"
|
|
473
|
+
});
|
|
474
|
+
}
|
|
475
|
+
const expectedAth = createHash("sha256").update(accessToken).digest("base64url");
|
|
476
|
+
if (ath !== expectedAth) {
|
|
477
|
+
return id({
|
|
478
|
+
isSuccess: false,
|
|
479
|
+
errorCause: "validation error",
|
|
480
|
+
debugErrorMessage: "DPoP proof ath claim does not match access token"
|
|
481
|
+
});
|
|
482
|
+
}
|
|
483
|
+
if (jti === undefined) {
|
|
484
|
+
return id({
|
|
485
|
+
isSuccess: false,
|
|
486
|
+
errorCause: "validation error",
|
|
487
|
+
debugErrorMessage: "DPoP proof missing jti claim"
|
|
488
|
+
});
|
|
489
|
+
}
|
|
490
|
+
if (getIsDpopPoofSeenRecordIfNotSeen({ jkt: cnf_jkt, jti })) {
|
|
491
|
+
return id({
|
|
492
|
+
isSuccess: false,
|
|
493
|
+
errorCause: "validation error",
|
|
494
|
+
debugErrorMessage: "DPoP proof replayed"
|
|
495
|
+
});
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
let decodedAccessToken;
|
|
500
|
+
if (decodedAccessTokenSchema === undefined) {
|
|
501
|
+
// @ts-expect-error: We know it will match because DecodedAccessToken will default to DecodedAccessToken_RFC9068
|
|
502
|
+
decodedAccessToken = decodedAccessToken_original;
|
|
503
|
+
}
|
|
504
|
+
else {
|
|
505
|
+
try {
|
|
506
|
+
decodedAccessToken = decodedAccessTokenSchema.parse(decodedAccessToken_original);
|
|
507
|
+
}
|
|
508
|
+
catch (error) {
|
|
509
|
+
assert(error instanceof Error);
|
|
510
|
+
return id({
|
|
511
|
+
isSuccess: false,
|
|
512
|
+
errorCause: "validation error",
|
|
513
|
+
debugErrorMessage: [
|
|
514
|
+
`The decoded access token does not satisfies`,
|
|
515
|
+
`the shape that the application expects: ${error.message}`
|
|
516
|
+
].join(" ")
|
|
517
|
+
});
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
return id({
|
|
521
|
+
isSuccess: true,
|
|
522
|
+
decodedAccessToken,
|
|
523
|
+
decodedAccessToken_original,
|
|
524
|
+
accessToken
|
|
525
|
+
});
|
|
526
|
+
};
|
|
527
|
+
return {
|
|
528
|
+
bootstrapAuth,
|
|
529
|
+
validateAndDecodeAccessToken,
|
|
530
|
+
ofTypeDecodedAccessToken: Reflect()
|
|
531
|
+
};
|
|
532
|
+
}
|
|
533
|
+
async function fetchPublicSigningKeys(params) {
|
|
534
|
+
const { issuerUri } = params;
|
|
535
|
+
const { jwks_uri } = await (async () => {
|
|
536
|
+
const url = `${issuerUri.replace(/\/$/, "")}/.well-known/openid-configuration`;
|
|
537
|
+
const response = await fetch(url);
|
|
538
|
+
if (!response.ok) {
|
|
539
|
+
throw new Error(`Failed to fetch openid configuration of the issuerUri: ${issuerUri} (${url}): ${response.statusText}`);
|
|
540
|
+
}
|
|
541
|
+
let data;
|
|
542
|
+
try {
|
|
543
|
+
data = await response.json();
|
|
544
|
+
}
|
|
545
|
+
catch (error) {
|
|
546
|
+
throw new Error(`Failed to parse json from ${url}: ${String(error)}`);
|
|
547
|
+
}
|
|
548
|
+
{
|
|
549
|
+
const zWellKnownConfiguration = z.object({
|
|
550
|
+
jwks_uri: z.string()
|
|
551
|
+
});
|
|
552
|
+
assert();
|
|
553
|
+
try {
|
|
554
|
+
zWellKnownConfiguration.parse(data);
|
|
555
|
+
}
|
|
556
|
+
catch {
|
|
557
|
+
throw new Error(`${url} does not have a jwks_uri property`);
|
|
558
|
+
}
|
|
559
|
+
assert(is(data));
|
|
560
|
+
}
|
|
561
|
+
const { jwks_uri } = data;
|
|
562
|
+
return { jwks_uri };
|
|
563
|
+
})();
|
|
564
|
+
const { jwks } = await (async () => {
|
|
565
|
+
const response = await fetch(jwks_uri);
|
|
566
|
+
if (!response.ok) {
|
|
567
|
+
throw new Error(`Failed to fetch public key and algorithm from ${jwks_uri}: ${response.statusText}`);
|
|
568
|
+
}
|
|
569
|
+
let jwks;
|
|
570
|
+
try {
|
|
571
|
+
jwks = await response.json();
|
|
572
|
+
}
|
|
573
|
+
catch (error) {
|
|
574
|
+
throw new Error(`Failed to parse json from ${jwks_uri}: ${String(error)}`);
|
|
575
|
+
}
|
|
576
|
+
{
|
|
577
|
+
const zJwks = z.object({
|
|
578
|
+
keys: z.array(z.object({
|
|
579
|
+
kid: z.string(),
|
|
580
|
+
kty: z.string(),
|
|
581
|
+
use: z.string().optional(),
|
|
582
|
+
alg: z.string().optional()
|
|
583
|
+
}))
|
|
584
|
+
});
|
|
585
|
+
assert();
|
|
586
|
+
try {
|
|
587
|
+
zJwks.parse(jwks);
|
|
588
|
+
}
|
|
589
|
+
catch {
|
|
590
|
+
throw new Error(`${jwks_uri} does not have the expected shape`);
|
|
591
|
+
}
|
|
592
|
+
assert(is(jwks));
|
|
593
|
+
}
|
|
594
|
+
return { jwks };
|
|
595
|
+
})();
|
|
596
|
+
//const signatureKeys = jwks.keys.filter((key): key is JWKS["keys"][number] & { kid: string } => {
|
|
597
|
+
const signatureKeys = jwks.keys.filter(key => {
|
|
598
|
+
if (typeof key.kid !== "string" || key.kid.length === 0) {
|
|
599
|
+
return false;
|
|
600
|
+
}
|
|
601
|
+
if (key.use !== undefined && key.use !== "sig") {
|
|
602
|
+
return false;
|
|
603
|
+
}
|
|
604
|
+
const supportedKty = ["RSA", "EC"];
|
|
605
|
+
if (!supportedKty.includes(key.kty)) {
|
|
606
|
+
return false;
|
|
607
|
+
}
|
|
608
|
+
return true;
|
|
609
|
+
});
|
|
610
|
+
assert(signatureKeys.length !== 0, `No public signing key found at ${jwks_uri}, ${JSON.stringify(jwks, null, 2)}`);
|
|
611
|
+
const kidSet = new Set(signatureKeys.map(({ kid }) => kid));
|
|
612
|
+
const keyResolver = createLocalJWKSet({
|
|
613
|
+
keys: signatureKeys
|
|
614
|
+
});
|
|
615
|
+
return {
|
|
616
|
+
keyResolver,
|
|
617
|
+
kidSet
|
|
618
|
+
};
|
|
619
|
+
}
|
|
620
|
+
const zDecodedAccessToken_RFC9068 = (() => {
|
|
621
|
+
const zTargetType = z
|
|
622
|
+
.object({
|
|
623
|
+
iss: z.string(),
|
|
624
|
+
sub: z.string(),
|
|
625
|
+
aud: z.union([z.string(), z.array(z.string())]),
|
|
626
|
+
exp: z.number(),
|
|
627
|
+
iat: z.number(),
|
|
628
|
+
client_id: z.string().optional(),
|
|
629
|
+
scope: z.string().optional(),
|
|
630
|
+
jti: z.string().optional(),
|
|
631
|
+
nbf: z.number().optional(),
|
|
632
|
+
auth_time: z.number().optional(),
|
|
633
|
+
cnf: z.record(z.string(), z.unknown()).optional()
|
|
634
|
+
})
|
|
635
|
+
.catchall(z.unknown());
|
|
636
|
+
assert;
|
|
637
|
+
return id(zTargetType);
|
|
638
|
+
})();
|
|
639
|
+
//# sourceMappingURL=createOidcSpaUtils.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createOidcSpaUtils.mjs","sourceRoot":"","sources":["../../src/server/createOidcSpaUtils.ts"],"names":[],"mappings":"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"}
|