@nekm/sveltekit-armor 0.2.4 → 0.3.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/dist/browser/index.d.ts +8 -0
- package/dist/contracts.d.ts +4 -1
- package/dist/errors.d.ts +2 -0
- package/dist/index.d.ts +0 -2
- package/dist/index.esm.js +135 -18
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +133 -18
- package/dist/index.js.map +1 -1
- package/dist/routes/refresh.d.ts +3 -0
- package/dist/routes/routes.d.ts +2 -1
- package/dist/utils/refresh.d.ts +3 -0
- package/dist/utils/utils.d.ts +3 -1
- package/package.json +23 -12
- package/src/browser/index.ts +32 -0
- package/src/contracts.ts +6 -1
- package/src/errors.ts +1 -0
- package/src/index.ts +25 -11
- package/src/routes/login.ts +3 -1
- package/src/routes/logout.ts +1 -0
- package/src/routes/redirect-login.ts +3 -1
- package/src/routes/redirect-logout.ts +1 -0
- package/src/routes/refresh.ts +39 -0
- package/src/routes/routes.ts +6 -2
- package/src/session/cookie.ts +5 -3
- package/src/utils/refresh.ts +87 -0
- package/src/utils/utils.ts +13 -1
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export interface ArmorBrowserRefresh {
|
|
2
|
+
readonly idToken: string;
|
|
3
|
+
readonly accessToken: string;
|
|
4
|
+
readonly expiresAt: Date;
|
|
5
|
+
}
|
|
6
|
+
export declare const ARMOR_REFRESH = "/_armor/refresh";
|
|
7
|
+
export declare const ARMOR_LOGIN = "/_armor/login";
|
|
8
|
+
export declare function armorRefresh(): Promise<ArmorBrowserRefresh>;
|
package/dist/contracts.d.ts
CHANGED
|
@@ -18,6 +18,7 @@ export interface ArmorTokens {
|
|
|
18
18
|
readonly exchange: ArmorTokenExchange;
|
|
19
19
|
readonly idToken: ArmorIdToken;
|
|
20
20
|
readonly accessToken: ArmorAccessToken | string;
|
|
21
|
+
readonly expiresAt: Date;
|
|
21
22
|
}
|
|
22
23
|
interface OauthBaseUrl {
|
|
23
24
|
readonly baseUrl: string;
|
|
@@ -25,6 +26,7 @@ interface OauthBaseUrl {
|
|
|
25
26
|
readonly authorizeEndpoint?: never;
|
|
26
27
|
readonly logoutEndpoint?: never;
|
|
27
28
|
readonly tokenEndpoint?: never;
|
|
29
|
+
readonly refreshEndpoint?: never;
|
|
28
30
|
}
|
|
29
31
|
interface OauthEndpoints {
|
|
30
32
|
readonly baseUrl?: never;
|
|
@@ -32,13 +34,14 @@ interface OauthEndpoints {
|
|
|
32
34
|
readonly authorizeEndpoint: string;
|
|
33
35
|
readonly logoutEndpoint?: string;
|
|
34
36
|
readonly tokenEndpoint: string;
|
|
37
|
+
readonly refreshEndpoint: string;
|
|
35
38
|
}
|
|
36
39
|
type OauthEndpointsOrBaseUrl = OauthBaseUrl | OauthEndpoints;
|
|
37
40
|
export interface ArmorConfig {
|
|
38
41
|
readonly session: {
|
|
39
|
-
readonly exists: (event: RequestEvent) => Promise<boolean> | boolean;
|
|
40
42
|
readonly login: (event: RequestEvent, tokens: ArmorTokens) => Promise<void> | void;
|
|
41
43
|
readonly logout: (event: RequestEvent) => Promise<void> | void;
|
|
44
|
+
readonly getTokens: (event: RequestEvent) => Promise<ArmorTokens | undefined> | ArmorTokens | undefined;
|
|
42
45
|
};
|
|
43
46
|
readonly oauth: OauthEndpointsOrBaseUrl & {
|
|
44
47
|
readonly clientId: string;
|
package/dist/errors.d.ts
CHANGED
package/dist/index.d.ts
CHANGED
|
@@ -2,8 +2,6 @@ import { type Handle } from "@sveltejs/kit";
|
|
|
2
2
|
import type { ArmorConfig, ArmorOpenIdConfig, ArmorTokens } from "./contracts";
|
|
3
3
|
export type { ArmorConfig, ArmorTokens };
|
|
4
4
|
export { armorCookieSession, armorCookieSessionGet } from "./session/cookie";
|
|
5
|
-
export declare const ARMOR_LOGIN = "/_armor/login";
|
|
6
|
-
export declare const ARMOR_LOGOUT = "/_armor/logout";
|
|
7
5
|
export declare function armor(config: ArmorConfig): Handle;
|
|
8
6
|
/**
|
|
9
7
|
* Some IdP's expose a /.well-known/openid-configuration that specifies how to configure.
|
package/dist/index.esm.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { redirect } from '@sveltejs/kit';
|
|
1
|
+
import { redirect, error, json } from '@sveltejs/kit';
|
|
2
2
|
import { strTrimEnd, strTrimStart, throwIfUndefined, queryParamsCreate } from '@nekm/core';
|
|
3
3
|
import { jwtVerify, createRemoteJWKSet } from 'jose';
|
|
4
4
|
import { randomUUID } from 'node:crypto';
|
|
@@ -13,6 +13,15 @@ function isTokenExchange(value) {
|
|
|
13
13
|
// Optional fields
|
|
14
14
|
typeof obj.id_token === "string" || obj.id_token === undefined) && (typeof obj.refresh_token === "string" || obj.refresh_token === undefined) && (typeof obj.scope === "string" || obj.scope === undefined);
|
|
15
15
|
}
|
|
16
|
+
const MINUTES_MS = 60 * 1000;
|
|
17
|
+
function shouldRefresh(tokens) {
|
|
18
|
+
return tokens.expiresAt.getTime() < Date.now() + 5 * MINUTES_MS;
|
|
19
|
+
}
|
|
20
|
+
function createExpiresAt(seconds) {
|
|
21
|
+
const now = new Date();
|
|
22
|
+
now.setSeconds(now.getSeconds() + seconds);
|
|
23
|
+
return now;
|
|
24
|
+
}
|
|
16
25
|
|
|
17
26
|
function jwtIsCompactJwt(token) {
|
|
18
27
|
// Must be three base64url segments
|
|
@@ -91,6 +100,7 @@ class ArmorError extends Error {}
|
|
|
91
100
|
class ArmorOpenIdConfigError extends ArmorError {}
|
|
92
101
|
class ArmorInvalidStateError extends ArmorError {}
|
|
93
102
|
class ArmorAuthMissingError extends ArmorError {}
|
|
103
|
+
class ArmorRefreshError extends ArmorError {}
|
|
94
104
|
|
|
95
105
|
function eventStateValidOrThrow(event) {
|
|
96
106
|
var _event$url$searchPara;
|
|
@@ -139,6 +149,7 @@ const routeRedirectLoginFactory = config => {
|
|
|
139
149
|
}
|
|
140
150
|
return {
|
|
141
151
|
path: ROUTE_PATH_REDIRECT_LOGIN,
|
|
152
|
+
method: "GET",
|
|
142
153
|
async handle({
|
|
143
154
|
event
|
|
144
155
|
}) {
|
|
@@ -171,20 +182,25 @@ const routeRedirectLoginFactory = config => {
|
|
|
171
182
|
idToken: idToken,
|
|
172
183
|
// Generally, IdP's require an audience to get a JWT
|
|
173
184
|
// access token. Most cases, this doesn't matter.
|
|
174
|
-
accessToken: accessToken != null ? accessToken : exchange.access_token
|
|
185
|
+
accessToken: accessToken != null ? accessToken : exchange.access_token,
|
|
186
|
+
expiresAt: createExpiresAt(exchange.expires_in)
|
|
175
187
|
});
|
|
176
188
|
throw redirect(302, "/");
|
|
177
189
|
}
|
|
178
190
|
};
|
|
179
191
|
};
|
|
180
192
|
|
|
181
|
-
const
|
|
193
|
+
const ARMOR_REFRESH = "/_armor/refresh";
|
|
194
|
+
const ARMOR_LOGIN = "/_armor/login";
|
|
195
|
+
|
|
196
|
+
const ROUTE_PATH_LOGIN = ARMOR_LOGIN;
|
|
182
197
|
const routeLoginFactory = config => {
|
|
183
198
|
var _config$oauth$authori, _config$oauth$scope;
|
|
184
199
|
const authorizeEndpoint = (_config$oauth$authori = config.oauth.authorizeEndpoint) != null ? _config$oauth$authori : urlConcat(config.oauth.baseUrl, "oauth2/authorize");
|
|
185
200
|
const scope = (_config$oauth$scope = config.oauth.scope) != null ? _config$oauth$scope : "openid profile email";
|
|
186
201
|
return {
|
|
187
202
|
path: ROUTE_PATH_LOGIN,
|
|
203
|
+
method: "GET",
|
|
188
204
|
async handle({
|
|
189
205
|
event
|
|
190
206
|
}) {
|
|
@@ -211,6 +227,7 @@ const routeRedirectLogoutFactory = config => {
|
|
|
211
227
|
}
|
|
212
228
|
return {
|
|
213
229
|
path: ROUTE_PATH_REDIRECT_LOGOUT,
|
|
230
|
+
method: "GET",
|
|
214
231
|
async handle({
|
|
215
232
|
event
|
|
216
233
|
}) {
|
|
@@ -231,6 +248,7 @@ const routeLogoutFactory = config => {
|
|
|
231
248
|
const returnTo = (_config$oauth$logoutR = config.oauth.logoutReturnToParam) != null ? _config$oauth$logoutR : "logout_uri";
|
|
232
249
|
return {
|
|
233
250
|
path: ROUTE_PATH_LOGOUT,
|
|
251
|
+
method: "GET",
|
|
234
252
|
async handle({
|
|
235
253
|
event
|
|
236
254
|
}) {
|
|
@@ -246,17 +264,104 @@ const routeLogoutFactory = config => {
|
|
|
246
264
|
};
|
|
247
265
|
};
|
|
248
266
|
|
|
249
|
-
|
|
267
|
+
function createRefresh(config) {
|
|
268
|
+
var _config$oauth$refresh, _config$oauth$jwksEnd;
|
|
269
|
+
const refreshEndpoint = (_config$oauth$refresh = config.oauth.refreshEndpoint) != null ? _config$oauth$refresh : urlConcat(config.oauth.baseUrl, "oauth2/token");
|
|
270
|
+
const jwksUrl = new URL((_config$oauth$jwksEnd = config.oauth.jwksEndpoint) != null ? _config$oauth$jwksEnd : urlConcat(config.oauth.baseUrl, ".well-known/jwks.json"));
|
|
271
|
+
const refresh = async (fetch, refreshToken) => {
|
|
272
|
+
var _json$refresh_token;
|
|
273
|
+
const body = new URLSearchParams({
|
|
274
|
+
grant_type: "refresh_token",
|
|
275
|
+
client_id: config.oauth.clientId,
|
|
276
|
+
client_secret: config.oauth.clientSecret,
|
|
277
|
+
refresh_token: refreshToken
|
|
278
|
+
});
|
|
279
|
+
if (config.oauth.scope) {
|
|
280
|
+
body.set("scope", config.oauth.scope);
|
|
281
|
+
}
|
|
282
|
+
const response = await fetch(refreshEndpoint, {
|
|
283
|
+
headers: {
|
|
284
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
285
|
+
Accept: "application/json"
|
|
286
|
+
},
|
|
287
|
+
body: body.toString()
|
|
288
|
+
});
|
|
289
|
+
if (!response.ok) {
|
|
290
|
+
const error = await response.text();
|
|
291
|
+
throw new ArmorRefreshError(`Could not refresh token: ${error}`);
|
|
292
|
+
}
|
|
293
|
+
const json = await response.json();
|
|
294
|
+
return {
|
|
295
|
+
...json,
|
|
296
|
+
refresh_token: (_json$refresh_token = json.refresh_token) != null ? _json$refresh_token : refreshToken
|
|
297
|
+
};
|
|
298
|
+
};
|
|
299
|
+
return async (event, tokens) => {
|
|
300
|
+
var _tokens$exchange;
|
|
301
|
+
const refreshToken = (_tokens$exchange = tokens.exchange) == null ? void 0 : _tokens$exchange.refresh_token;
|
|
302
|
+
if (!refreshToken) {
|
|
303
|
+
throw new ArmorRefreshError("Could not find refresh token");
|
|
304
|
+
}
|
|
305
|
+
const newExchange = await refresh(event.fetch, refreshToken);
|
|
306
|
+
const jwks = createRemoteJWKSet(jwksUrl);
|
|
307
|
+
const [idToken, accessToken] = await Promise.all([jwtVerifyIdToken(config, jwks, newExchange.id_token), jwtVerifyAccessToken(config, jwks, newExchange.access_token)]);
|
|
308
|
+
return {
|
|
309
|
+
exchange: newExchange,
|
|
310
|
+
idToken: idToken,
|
|
311
|
+
// Generally, IdP's require an audience to get a JWT
|
|
312
|
+
// access token. Most cases, this doesn't matter.
|
|
313
|
+
accessToken: accessToken != null ? accessToken : newExchange.access_token,
|
|
314
|
+
expiresAt: createExpiresAt(newExchange.expires_in)
|
|
315
|
+
};
|
|
316
|
+
};
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
const ROUTE_PATH_REFRESH = ARMOR_REFRESH;
|
|
320
|
+
const routeRefreshFactory = config => {
|
|
321
|
+
const refresh = createRefresh(config);
|
|
322
|
+
return {
|
|
323
|
+
path: ROUTE_PATH_REFRESH,
|
|
324
|
+
method: "POST",
|
|
325
|
+
async handle({
|
|
326
|
+
event
|
|
327
|
+
}) {
|
|
328
|
+
try {
|
|
329
|
+
const tokens = await config.session.getTokens(event);
|
|
330
|
+
if (!tokens) {
|
|
331
|
+
return error(401, "Unauthorized");
|
|
332
|
+
}
|
|
333
|
+
const {
|
|
334
|
+
idToken,
|
|
335
|
+
expiresAt,
|
|
336
|
+
accessToken
|
|
337
|
+
} = await refresh(event, tokens);
|
|
338
|
+
return json({
|
|
339
|
+
idToken,
|
|
340
|
+
expiresAt,
|
|
341
|
+
accessToken
|
|
342
|
+
});
|
|
343
|
+
} catch (ex) {
|
|
344
|
+
if (ex instanceof ArmorRefreshError) {
|
|
345
|
+
return error(401, "Unauthorized");
|
|
346
|
+
}
|
|
347
|
+
throw ex;
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
};
|
|
351
|
+
};
|
|
352
|
+
|
|
353
|
+
const routeFactories = Object.freeze([routeLoginFactory, routeLogoutFactory, routeRedirectLoginFactory, routeRedirectLogoutFactory, routeRefreshFactory]);
|
|
250
354
|
function routeCreate(config) {
|
|
355
|
+
// @ts-expect-error Incorrect typing error.
|
|
251
356
|
return new Map(routeFactories.map(routeFactory => routeFactory(config)).filter(route => Boolean(route))
|
|
252
357
|
// @ts-expect-error Incorrect typing error.
|
|
253
|
-
.map(route => [route.path, route
|
|
358
|
+
.map(route => [route.path, route]));
|
|
254
359
|
}
|
|
255
360
|
|
|
256
|
-
function
|
|
361
|
+
function cookieSessionGetTokens({
|
|
257
362
|
cookies
|
|
258
363
|
}) {
|
|
259
|
-
return
|
|
364
|
+
return cookies.get(COOKIE_TOKENS);
|
|
260
365
|
}
|
|
261
366
|
function cookieSessionLogin({
|
|
262
367
|
cookies
|
|
@@ -278,30 +383,41 @@ function armorCookieSessionGet({
|
|
|
278
383
|
return tokens;
|
|
279
384
|
}
|
|
280
385
|
const armorCookieSession = {
|
|
281
|
-
|
|
386
|
+
getTokens: cookieSessionGetTokens,
|
|
282
387
|
login: cookieSessionLogin,
|
|
283
388
|
logout: cookieSessionLogout
|
|
284
389
|
};
|
|
285
390
|
|
|
286
|
-
const ARMOR_LOGIN = ROUTE_PATH_LOGIN;
|
|
287
|
-
const ARMOR_LOGOUT = ROUTE_PATH_LOGOUT;
|
|
288
391
|
function armor(config) {
|
|
289
|
-
const
|
|
392
|
+
const routeByPath = routeCreate(config);
|
|
393
|
+
const refresh = createRefresh(config);
|
|
290
394
|
return async ({
|
|
291
395
|
event,
|
|
292
396
|
resolve
|
|
293
397
|
}) => {
|
|
294
|
-
const
|
|
295
|
-
if (
|
|
296
|
-
return
|
|
398
|
+
const route = routeByPath.get(event.url.pathname);
|
|
399
|
+
if (route && route.method === event.request.method) {
|
|
400
|
+
return route.handle({
|
|
297
401
|
event,
|
|
298
402
|
resolve
|
|
299
403
|
});
|
|
300
404
|
}
|
|
301
|
-
const
|
|
302
|
-
if (!
|
|
405
|
+
const tokens = await config.session.getTokens(event);
|
|
406
|
+
if (!tokens) {
|
|
303
407
|
throw redirect(302, ROUTE_PATH_LOGIN);
|
|
304
408
|
}
|
|
409
|
+
try {
|
|
410
|
+
if (shouldRefresh(tokens)) {
|
|
411
|
+
console.log("Refreshing token...");
|
|
412
|
+
await refresh(event, tokens);
|
|
413
|
+
}
|
|
414
|
+
} catch (error) {
|
|
415
|
+
if (error instanceof ArmorRefreshError) {
|
|
416
|
+
console.error("Could not refresh token. Redirect user to login...");
|
|
417
|
+
throw redirect(302, ROUTE_PATH_LOGIN);
|
|
418
|
+
}
|
|
419
|
+
throw error;
|
|
420
|
+
}
|
|
305
421
|
return resolve(event);
|
|
306
422
|
};
|
|
307
423
|
}
|
|
@@ -332,10 +448,11 @@ async function armorConfigFromOpenId(config, fetch) {
|
|
|
332
448
|
authorizeEndpoint: body.authorization_endpoint,
|
|
333
449
|
issuer: body.issuer,
|
|
334
450
|
jwksEndpoint: body.jwks_uri,
|
|
335
|
-
logoutEndpoint: (_body$end_session_end = body.end_session_endpoint) != null ? _body$end_session_end : undefined
|
|
451
|
+
logoutEndpoint: (_body$end_session_end = body.end_session_endpoint) != null ? _body$end_session_end : undefined,
|
|
452
|
+
refreshEndpoint: body.token_endpoint
|
|
336
453
|
}
|
|
337
454
|
};
|
|
338
455
|
}
|
|
339
456
|
|
|
340
|
-
export {
|
|
457
|
+
export { armor, armorConfigFromOpenId, armorCookieSession, armorCookieSessionGet };
|
|
341
458
|
//# sourceMappingURL=index.esm.js.map
|
package/dist/index.esm.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.esm.js","sources":["../src/utils/utils.ts","../src/utils/jwt.ts","../src/utils/cookie.ts","../src/errors.ts","../src/utils/event.ts","../src/routes/redirect-login.ts","../src/routes/login.ts","../src/routes/redirect-logout.ts","../src/routes/logout.ts","../src/routes/routes.ts","../src/session/cookie.ts","../src/index.ts"],"sourcesContent":["import { strTrimEnd, strTrimStart } from \"@nekm/core\";\nimport type { ArmorTokenExchange } from \"../contracts\";\n\nexport function urlConcat(origin: string, path: string): string {\n\treturn [strTrimEnd(origin, \"/\"), strTrimStart(path, \"/\")].join(\"/\");\n}\n\nexport function isTokenExchange(value: unknown): value is ArmorTokenExchange {\n\tif (typeof value !== \"object\" || value === null) return false;\n\n\tconst obj = value as Record<string, unknown>;\n\n\treturn (\n\t\ttypeof obj.access_token === \"string\" &&\n\t\tobj.token_type === \"Bearer\" &&\n\t\ttypeof obj.expires_in === \"number\" &&\n\t\t// Optional fields\n\t\t(typeof obj.id_token === \"string\" || obj.id_token === undefined) &&\n\t\t(typeof obj.refresh_token === \"string\" ||\n\t\t\tobj.refresh_token === undefined) &&\n\t\t(typeof obj.scope === \"string\" || obj.scope === undefined)\n\t);\n}\n","import { ArmorConfig } from \"../contracts\";\nimport { JWTPayload, jwtVerify, JWTVerifyGetKey, JWTVerifyOptions } from \"jose\";\nimport { throwIfUndefined } from \"@nekm/core\";\n\nfunction jwtIsCompactJwt(token: string): boolean {\n\t// Must be three base64url segments\n\tconst parts = token.trim().split(\".\");\n\treturn parts.length === 3 && parts.every((p) => p.length > 0);\n}\n\nexport function jwtVerifyIdToken(\n\tconfig: ArmorConfig,\n\tjwks: JWTVerifyGetKey,\n\tidToken: string,\n): Promise<JWTPayload> {\n\tconst payload = jwtVerifyToken(\n\t\tjwks,\n\t\t{\n\t\t\tissuer: config.oauth.issuer,\n\t\t\taudience: config.oauth.clientId,\n\t\t},\n\t\tidToken,\n\t);\n\tthrowIfUndefined(payload);\n\t// @ts-expect-error We're already verifying non-null above.\n\treturn payload;\n}\n\nexport function jwtVerifyAccessToken(\n\tconfig: ArmorConfig,\n\tjwks: JWTVerifyGetKey,\n\taccessToken: string,\n): Promise<JWTPayload | undefined> {\n\tconst opts: JWTVerifyOptions = { issuer: config.oauth.issuer };\n\n\tif (config.oauth.audience) {\n\t\topts.audience = config.oauth.audience;\n\t}\n\n\treturn jwtVerifyToken(jwks, opts, accessToken);\n}\n\nfunction isInvalidCompactJwt(error: unknown): boolean {\n\treturn Boolean(\n\t\ttypeof error === \"object\" &&\n\t\terror &&\n\t\t\"message\" in error &&\n\t\ttypeof error.message === \"string\" &&\n\t\t/invalid compact jws/gi.test(error.message),\n\t);\n}\n\nasync function jwtVerifyToken(\n\tjwks: JWTVerifyGetKey,\n\topts: JWTVerifyOptions,\n\ttoken: string,\n): Promise<JWTPayload | undefined> {\n\ttry {\n\t\tif (!jwtIsCompactJwt(token)) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst { payload } = await jwtVerify(token, jwks, opts);\n\t\treturn payload;\n\t} catch (error) {\n\t\tif (isInvalidCompactJwt(error)) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tthrow error;\n\t}\n}\n","import { Cookies } from \"@sveltejs/kit\";\n\nexport const COOKIE_TOKENS = \"tokens\";\nexport const COOKIE_STATE = \"state\";\n\nconst cookieDeleteOptions = Object.freeze({ path: \"/\" });\n\nconst cookieSetOptions = Object.freeze({\n\t...cookieDeleteOptions,\n\thttpOnly: true,\n\tsecure: true,\n\tsameSite: \"lax\",\n\tmaxAge: 1800, // 30 minutes\n});\n\nexport function cookieSet(\n\tcookies: Cookies,\n\tkey: string,\n\tvalue: string | object,\n) {\n\tcookies.set(key, JSON.stringify(value), cookieSetOptions);\n}\n\nexport function cookieGetAndDelete<T>(\n\tcookies: Cookies,\n\tkey: string,\n): T | undefined {\n\tconst value = cookieGet<T>(cookies, key);\n\n\tif (value) {\n\t\tcookies.delete(key, cookieDeleteOptions);\n\t}\n\n\treturn value;\n}\n\nexport function cookieGet<T>(cookies: Cookies, key: string): T | undefined {\n\tconst value = cookies.get(key);\n\n\treturn !value ? undefined : JSON.parse(value);\n}\n\nexport function cookieDelete(cookies: Cookies, key: string): void {\n\tcookies.delete(key, cookieDeleteOptions);\n}\n","export class ArmorError extends Error {}\nexport class ArmorOpenIdConfigError extends ArmorError {}\nexport class ArmorInvalidStateError extends ArmorError {}\nexport class ArmorAuthMissingError extends ArmorError {}\n","import { RequestEvent } from \"@sveltejs/kit\";\nimport { COOKIE_STATE, cookieGetAndDelete } from \"./cookie\";\nimport { ArmorInvalidStateError } from \"../errors\";\n\nexport function eventStateValidOrThrow(event: RequestEvent): void {\n\tconst state = event.url.searchParams.get(\"state\") ?? undefined;\n\tconst stateCookie = cookieGetAndDelete(event.cookies, COOKIE_STATE);\n\n\tif (state !== stateCookie) {\n\t\tthrow new ArmorInvalidStateError();\n\t}\n}\n","import { redirect } from \"@sveltejs/kit\";\nimport type {\n\tArmorConfig,\n\tArmorIdToken,\n\tArmorTokenExchange,\n} from \"../contracts\";\nimport { queryParamsCreate, throwIfUndefined } from \"@nekm/core\";\nimport { createRemoteJWKSet } from \"jose\";\nimport type { RouteFactory } from \"./routes\";\nimport { urlConcat, isTokenExchange } from \"../utils/utils\";\nimport { jwtVerifyAccessToken, jwtVerifyIdToken } from \"../utils/jwt\";\nimport { eventStateValidOrThrow } from \"../utils/event\";\n\nexport const ROUTE_PATH_REDIRECT_LOGIN = \"/_armor/redirect/login\";\n\nexport const routeRedirectLoginFactory: RouteFactory = (\n\tconfig: ArmorConfig,\n) => {\n\tconst jwksUrl = new URL(\n\t\tconfig.oauth.jwksEndpoint ??\n\t\t\turlConcat(config.oauth.baseUrl, \".well-known/jwks.json\"),\n\t);\n\n\tconst tokenUrl =\n\t\tconfig.oauth.tokenEndpoint ??\n\t\turlConcat(config.oauth.baseUrl, \"oauth2/token\");\n\n\tconst scope = config.oauth.scope ?? \"openid profile email\";\n\n\tasync function exchangeCodeForToken(\n\t\tfetch: typeof global.fetch,\n\t\torigin: string,\n\t\tcode: string,\n\t): Promise<ArmorTokenExchange> {\n\t\tconst params: Record<string, string> = {\n\t\t\tgrant_type: \"authorization_code\",\n\t\t\tclient_id: config.oauth.clientId,\n\t\t\tclient_secret: config.oauth.clientSecret,\n\t\t\tcode,\n\t\t\tredirect_uri: urlConcat(origin, ROUTE_PATH_REDIRECT_LOGIN),\n\t\t\tscope,\n\t\t};\n\n\t\tif (config.oauth.audience) {\n\t\t\tparams.audience = config.oauth.audience;\n\t\t}\n\n\t\tconst response = await fetch(tokenUrl, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: {\n\t\t\t\t\"Content-Type\": \"application/x-www-form-urlencoded\",\n\t\t\t\tAccept: \"application/json\",\n\t\t\t},\n\t\t\tbody: new URLSearchParams(params).toString(),\n\t\t});\n\n\t\tif (!response.ok) {\n\t\t\tconst error = await response.text();\n\t\t\tthrow new Error(`Token exchange failed: ${error}`);\n\t\t}\n\n\t\tconst token = await response.json();\n\n\t\tif (!isTokenExchange(token)) {\n\t\t\tthrow new Error(\"Response is not a valid token exchange.\");\n\t\t}\n\n\t\treturn token;\n\t}\n\n\treturn {\n\t\tpath: ROUTE_PATH_REDIRECT_LOGIN,\n\t\tasync handle({ event }) {\n\t\t\teventStateValidOrThrow(event);\n\n\t\t\tconst error = event.url.searchParams.get(\"error\") ?? undefined;\n\n\t\t\tif (error) {\n\t\t\t\tconst error_description =\n\t\t\t\t\tevent.url.searchParams.get(\"error_description\") ?? undefined;\n\n\t\t\t\tif (!config.oauth.errorLoginRedirectPath) {\n\t\t\t\t\treturn new Response(`${error}\\n${error_description}`.trimEnd(), {\n\t\t\t\t\t\theaders: {\n\t\t\t\t\t\t\t\"Content-Type\": \"text/plain\",\n\t\t\t\t\t\t},\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\tconst errorParams = queryParamsCreate({ error, error_description });\n\t\t\t\tthrow redirect(\n\t\t\t\t\t302,\n\t\t\t\t\t`${config.oauth.errorLoginRedirectPath}?${errorParams}`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst code = event.url.searchParams.get(\"code\") ?? undefined;\n\t\t\tthrowIfUndefined(code);\n\n\t\t\tconst exchange = await exchangeCodeForToken(\n\t\t\t\tevent.fetch,\n\t\t\t\tevent.url.origin,\n\t\t\t\tcode,\n\t\t\t);\n\n\t\t\tconst jwks = createRemoteJWKSet(jwksUrl);\n\n\t\t\tconst [idToken, accessToken] = await Promise.all([\n\t\t\t\tjwtVerifyIdToken(config, jwks, exchange.id_token),\n\t\t\t\tjwtVerifyAccessToken(config, jwks, exchange.access_token),\n\t\t\t]);\n\n\t\t\tawait config.session.login(event, {\n\t\t\t\texchange,\n\t\t\t\tidToken: idToken as ArmorIdToken,\n\t\t\t\t// Generally, IdP's require an audience to get a JWT\n\t\t\t\t// access token. Most cases, this doesn't matter.\n\t\t\t\taccessToken: accessToken ?? exchange.access_token,\n\t\t\t});\n\n\t\t\tthrow redirect(302, \"/\");\n\t\t},\n\t};\n};\n","import { redirect } from \"@sveltejs/kit\";\nimport type { ArmorConfig } from \"../contracts\";\nimport { queryParamsCreate } from \"@nekm/core\";\nimport { ROUTE_PATH_REDIRECT_LOGIN } from \"./redirect-login\";\nimport { randomUUID } from \"node:crypto\";\nimport type { RouteFactory } from \"./routes\";\nimport { COOKIE_STATE, cookieSet } from \"../utils/cookie\";\nimport { urlConcat } from \"../utils/utils\";\n\nexport const ROUTE_PATH_LOGIN = \"/_armor/login\";\n\nexport const routeLoginFactory: RouteFactory = (config: ArmorConfig) => {\n\tconst authorizeEndpoint =\n\t\tconfig.oauth.authorizeEndpoint ??\n\t\turlConcat(config.oauth.baseUrl, \"oauth2/authorize\");\n\n\tconst scope = config.oauth.scope ?? \"openid profile email\";\n\n\treturn {\n\t\tpath: ROUTE_PATH_LOGIN,\n\t\tasync handle({ event }) {\n\t\t\tconst state = randomUUID();\n\t\t\tcookieSet(event.cookies, COOKIE_STATE, state);\n\n\t\t\tconst params = queryParamsCreate({\n\t\t\t\tclient_id: config.oauth.clientId,\n\t\t\t\tresponse_type: \"code\",\n\t\t\t\tredirect_uri: urlConcat(event.url.origin, ROUTE_PATH_REDIRECT_LOGIN),\n\t\t\t\tstate,\n\t\t\t\tscope,\n\t\t\t\taudience: config.oauth.audience,\n\t\t\t});\n\n\t\t\tthrow redirect(302, `${authorizeEndpoint}?${params}`);\n\t\t},\n\t};\n};\n","import { redirect } from \"@sveltejs/kit\";\nimport type { ArmorConfig } from \"../contracts\";\nimport type { RouteFactory } from \"./routes\";\nimport { eventStateValidOrThrow } from \"../utils/event\";\n\nexport const ROUTE_PATH_REDIRECT_LOGOUT = \"/_armor/redirect/logout\";\n\nexport const routeRedirectLogoutFactory: RouteFactory = (\n\tconfig: ArmorConfig,\n) => {\n\t// Check if the oauth provider supports a logout path.\n\tif (!config.oauth.logoutEndpoint) {\n\t\treturn undefined;\n\t}\n\n\treturn {\n\t\tpath: ROUTE_PATH_REDIRECT_LOGOUT,\n\t\tasync handle({ event }) {\n\t\t\teventStateValidOrThrow(event);\n\n\t\t\tawait config.session.logout(event);\n\n\t\t\tthrow redirect(302, \"/\");\n\t\t},\n\t};\n};\n","import { redirect } from \"@sveltejs/kit\";\nimport type { ArmorConfig } from \"../contracts\";\nimport { queryParamsCreate } from \"@nekm/core\";\nimport { ROUTE_PATH_REDIRECT_LOGOUT } from \"./redirect-logout\";\nimport type { RouteFactory } from \"./routes\";\nimport { urlConcat } from \"../utils/utils\";\nimport { randomUUID } from \"node:crypto\";\nimport { COOKIE_STATE, cookieSet } from \"../utils/cookie\";\n\nexport const ROUTE_PATH_LOGOUT = \"/_armor/logout\";\n\nexport const routeLogoutFactory: RouteFactory = (config: ArmorConfig) => {\n\t// Check if the oauth provider supports a logout path.\n\tif (!config.oauth.logoutEndpoint) {\n\t\treturn undefined;\n\t}\n\n\tconst returnTo = config.oauth.logoutReturnToParam ?? \"logout_uri\";\n\n\treturn {\n\t\tpath: ROUTE_PATH_LOGOUT,\n\t\tasync handle({ event }) {\n\t\t\tconst state = randomUUID();\n\t\t\tcookieSet(event.cookies, COOKIE_STATE, state);\n\n\t\t\tconst params = queryParamsCreate({\n\t\t\t\t[returnTo]: urlConcat(event.url.origin, ROUTE_PATH_REDIRECT_LOGOUT),\n\t\t\t\tclient_id: config.oauth.clientId,\n\t\t\t\tstate,\n\t\t\t});\n\n\t\t\tthrow redirect(302, `${config.oauth.logoutEndpoint}?${params}`);\n\t\t},\n\t};\n};\n","import type { Handle } from \"@sveltejs/kit\";\nimport type { ArmorConfig } from \"../contracts\";\nimport { routeLoginFactory } from \"./login\";\nimport { routeLogoutFactory } from \"./logout\";\nimport { routeRedirectLogoutFactory } from \"./redirect-logout\";\nimport { routeRedirectLoginFactory } from \"./redirect-login\";\n\nexport interface Route {\n\treadonly path: string;\n\treadonly handle: Handle;\n}\n\nexport type RouteFactory = (config: ArmorConfig) => Route | undefined;\n\nconst routeFactories = Object.freeze([\n\trouteLoginFactory,\n\trouteLogoutFactory,\n\trouteRedirectLoginFactory,\n\trouteRedirectLogoutFactory,\n]);\n\nexport function routeCreate(config: ArmorConfig): Map<string, Handle> {\n\treturn new Map(\n\t\trouteFactories\n\t\t\t.map((routeFactory) => routeFactory(config))\n\t\t\t.filter((route) => Boolean(route))\n\t\t\t// @ts-expect-error Incorrect typing error.\n\t\t\t.map((route) => [route.path, route.handle]),\n\t);\n}\n","import { RequestEvent } from \"@sveltejs/kit\";\nimport {\n\tCOOKIE_TOKENS,\n\tcookieDelete,\n\tcookieGet,\n\tcookieSet,\n} from \"../utils/cookie\";\nimport { ArmorConfig, ArmorTokens } from \"../contracts\";\nimport { ArmorAuthMissingError } from \"../errors\";\n\nfunction cookieSessionExists({ cookies }: RequestEvent): boolean {\n\treturn Boolean(cookies.get(COOKIE_TOKENS));\n}\n\nexport function cookieSessionLogin(\n\t{ cookies }: RequestEvent,\n\ttokens: ArmorTokens,\n): void {\n\tcookieSet(cookies, COOKIE_TOKENS, tokens);\n}\n\nfunction cookieSessionLogout({ cookies }: RequestEvent): void {\n\tcookieDelete(cookies, COOKIE_TOKENS);\n}\n\nexport function armorCookieSessionGet({ cookies }: RequestEvent): ArmorTokens {\n\tconst tokens = cookieGet<ArmorTokens>(cookies, COOKIE_TOKENS);\n\n\tif (!tokens) {\n\t\tthrow new ArmorAuthMissingError();\n\t}\n\n\treturn tokens;\n}\n\nexport const armorCookieSession: ArmorConfig[\"session\"] = {\n\texists: cookieSessionExists,\n\tlogin: cookieSessionLogin,\n\tlogout: cookieSessionLogout,\n};\n","import { redirect, type Handle } from \"@sveltejs/kit\";\nimport { ROUTE_PATH_LOGIN } from \"./routes/login\";\nimport type { ArmorConfig, ArmorOpenIdConfig, ArmorTokens } from \"./contracts\";\nimport { ROUTE_PATH_LOGOUT } from \"./routes/logout\";\nimport { routeCreate } from \"./routes/routes\";\nimport { ArmorOpenIdConfigError } from \"./errors\";\n\nexport type { ArmorConfig, ArmorTokens };\nexport { armorCookieSession, armorCookieSessionGet } from \"./session/cookie\";\n\nexport const ARMOR_LOGIN = ROUTE_PATH_LOGIN;\nexport const ARMOR_LOGOUT = ROUTE_PATH_LOGOUT;\n\nexport function armor(config: ArmorConfig): Handle {\n\tconst routes = routeCreate(config);\n\n\treturn async ({ event, resolve }) => {\n\t\tconst routeHandle = routes.get(event.url.pathname);\n\n\t\tif (routeHandle) {\n\t\t\treturn routeHandle({ event, resolve });\n\t\t}\n\n\t\tconst exists = await config.session.exists(event);\n\n\t\tif (!exists) {\n\t\t\tthrow redirect(302, ROUTE_PATH_LOGIN);\n\t\t}\n\n\t\treturn resolve(event);\n\t};\n}\n\n/**\n * Some IdP's expose a /.well-known/openid-configuration that specifies how to configure.\n * Use that to create your config.\n * @param config\n * @param fetch\n */\nexport async function armorConfigFromOpenId(\n\tconfig: ArmorOpenIdConfig,\n\tfetch?: typeof global.fetch,\n): Promise<ArmorConfig> {\n\tconst fetchToUse = fetch ?? global.fetch;\n\n\tconst response = await fetchToUse(config.oauth.openIdConfigEndpoint, {\n\t\theaders: {\n\t\t\tAccept: \"application/json\",\n\t\t},\n\t});\n\n\tif (!response.ok) {\n\t\tconst text = await response.text();\n\t\tthrow new ArmorOpenIdConfigError(text);\n\t}\n\n\tconst body = await response.json();\n\n\treturn {\n\t\t...config,\n\t\toauth: {\n\t\t\t...config.oauth,\n\t\t\ttokenEndpoint: body.token_endpoint,\n\t\t\tauthorizeEndpoint: body.authorization_endpoint,\n\t\t\tissuer: body.issuer,\n\t\t\tjwksEndpoint: body.jwks_uri,\n\t\t\tlogoutEndpoint: body.end_session_endpoint ?? undefined,\n\t\t},\n\t};\n}\n"],"names":["urlConcat","origin","path","strTrimEnd","strTrimStart","join","isTokenExchange","value","obj","access_token","token_type","expires_in","id_token","undefined","refresh_token","scope","jwtIsCompactJwt","token","parts","trim","split","length","every","p","jwtVerifyIdToken","config","jwks","idToken","payload","jwtVerifyToken","issuer","oauth","audience","clientId","throwIfUndefined","jwtVerifyAccessToken","accessToken","opts","isInvalidCompactJwt","error","Boolean","message","test","jwtVerify","COOKIE_TOKENS","COOKIE_STATE","cookieDeleteOptions","Object","freeze","cookieSetOptions","httpOnly","secure","sameSite","maxAge","cookieSet","cookies","key","set","JSON","stringify","cookieGetAndDelete","cookieGet","delete","get","parse","cookieDelete","ArmorError","Error","ArmorOpenIdConfigError","ArmorInvalidStateError","ArmorAuthMissingError","eventStateValidOrThrow","event","_event$url$searchPara","state","url","searchParams","stateCookie","ROUTE_PATH_REDIRECT_LOGIN","routeRedirectLoginFactory","_config$oauth$jwksEnd","_config$oauth$tokenEn","_config$oauth$scope","jwksUrl","URL","jwksEndpoint","baseUrl","tokenUrl","tokenEndpoint","exchangeCodeForToken","fetch","code","params","grant_type","client_id","client_secret","clientSecret","redirect_uri","response","method","headers","Accept","body","URLSearchParams","toString","ok","text","json","handle","_event$url$searchPara3","_event$url$searchPara2","error_description","errorLoginRedirectPath","Response","trimEnd","errorParams","queryParamsCreate","redirect","exchange","createRemoteJWKSet","Promise","all","session","login","ROUTE_PATH_LOGIN","routeLoginFactory","_config$oauth$authori","authorizeEndpoint","randomUUID","response_type","ROUTE_PATH_REDIRECT_LOGOUT","routeRedirectLogoutFactory","logoutEndpoint","logout","ROUTE_PATH_LOGOUT","routeLogoutFactory","_config$oauth$logoutR","returnTo","logoutReturnToParam","routeFactories","routeCreate","Map","map","routeFactory","filter","route","cookieSessionExists","cookieSessionLogin","tokens","cookieSessionLogout","armorCookieSessionGet","armorCookieSession","exists","ARMOR_LOGIN","ARMOR_LOGOUT","armor","routes","resolve","routeHandle","pathname","armorConfigFromOpenId","_body$end_session_end","fetchToUse","global","openIdConfigEndpoint","token_endpoint","authorization_endpoint","jwks_uri","end_session_endpoint"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.esm.js","sources":["../src/utils/utils.ts","../src/utils/jwt.ts","../src/utils/cookie.ts","../src/errors.ts","../src/utils/event.ts","../src/routes/redirect-login.ts","../src/browser/index.ts","../src/routes/login.ts","../src/routes/redirect-logout.ts","../src/routes/logout.ts","../src/utils/refresh.ts","../src/routes/refresh.ts","../src/routes/routes.ts","../src/session/cookie.ts","../src/index.ts"],"sourcesContent":["import { strTrimEnd, strTrimStart } from \"@nekm/core\";\nimport type { ArmorTokenExchange, ArmorTokens } from \"../contracts\";\n\nexport function urlConcat(origin: string, path: string): string {\n\treturn [strTrimEnd(origin, \"/\"), strTrimStart(path, \"/\")].join(\"/\");\n}\n\nexport function isTokenExchange(value: unknown): value is ArmorTokenExchange {\n\tif (typeof value !== \"object\" || value === null) return false;\n\n\tconst obj = value as Record<string, unknown>;\n\n\treturn (\n\t\ttypeof obj.access_token === \"string\" &&\n\t\tobj.token_type === \"Bearer\" &&\n\t\ttypeof obj.expires_in === \"number\" &&\n\t\t// Optional fields\n\t\t(typeof obj.id_token === \"string\" || obj.id_token === undefined) &&\n\t\t(typeof obj.refresh_token === \"string\" ||\n\t\t\tobj.refresh_token === undefined) &&\n\t\t(typeof obj.scope === \"string\" || obj.scope === undefined)\n\t);\n}\n\nconst MINUTES_MS = 60 * 1000;\n\nexport function shouldRefresh(tokens: ArmorTokens) {\n\treturn tokens.expiresAt.getTime() < Date.now() + 5 * MINUTES_MS;\n}\n\nexport function createExpiresAt(seconds: number): Date {\n\tconst now = new Date();\n\tnow.setSeconds(now.getSeconds() + seconds);\n\treturn now;\n}\n","import { ArmorConfig } from \"../contracts\";\nimport { JWTPayload, jwtVerify, JWTVerifyGetKey, JWTVerifyOptions } from \"jose\";\nimport { throwIfUndefined } from \"@nekm/core\";\n\nfunction jwtIsCompactJwt(token: string): boolean {\n\t// Must be three base64url segments\n\tconst parts = token.trim().split(\".\");\n\treturn parts.length === 3 && parts.every((p) => p.length > 0);\n}\n\nexport function jwtVerifyIdToken(\n\tconfig: ArmorConfig,\n\tjwks: JWTVerifyGetKey,\n\tidToken: string,\n): Promise<JWTPayload> {\n\tconst payload = jwtVerifyToken(\n\t\tjwks,\n\t\t{\n\t\t\tissuer: config.oauth.issuer,\n\t\t\taudience: config.oauth.clientId,\n\t\t},\n\t\tidToken,\n\t);\n\tthrowIfUndefined(payload);\n\t// @ts-expect-error We're already verifying non-null above.\n\treturn payload;\n}\n\nexport function jwtVerifyAccessToken(\n\tconfig: ArmorConfig,\n\tjwks: JWTVerifyGetKey,\n\taccessToken: string,\n): Promise<JWTPayload | undefined> {\n\tconst opts: JWTVerifyOptions = { issuer: config.oauth.issuer };\n\n\tif (config.oauth.audience) {\n\t\topts.audience = config.oauth.audience;\n\t}\n\n\treturn jwtVerifyToken(jwks, opts, accessToken);\n}\n\nfunction isInvalidCompactJwt(error: unknown): boolean {\n\treturn Boolean(\n\t\ttypeof error === \"object\" &&\n\t\terror &&\n\t\t\"message\" in error &&\n\t\ttypeof error.message === \"string\" &&\n\t\t/invalid compact jws/gi.test(error.message),\n\t);\n}\n\nasync function jwtVerifyToken(\n\tjwks: JWTVerifyGetKey,\n\topts: JWTVerifyOptions,\n\ttoken: string,\n): Promise<JWTPayload | undefined> {\n\ttry {\n\t\tif (!jwtIsCompactJwt(token)) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tconst { payload } = await jwtVerify(token, jwks, opts);\n\t\treturn payload;\n\t} catch (error) {\n\t\tif (isInvalidCompactJwt(error)) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\tthrow error;\n\t}\n}\n","import { Cookies } from \"@sveltejs/kit\";\n\nexport const COOKIE_TOKENS = \"tokens\";\nexport const COOKIE_STATE = \"state\";\n\nconst cookieDeleteOptions = Object.freeze({ path: \"/\" });\n\nconst cookieSetOptions = Object.freeze({\n\t...cookieDeleteOptions,\n\thttpOnly: true,\n\tsecure: true,\n\tsameSite: \"lax\",\n\tmaxAge: 1800, // 30 minutes\n});\n\nexport function cookieSet(\n\tcookies: Cookies,\n\tkey: string,\n\tvalue: string | object,\n) {\n\tcookies.set(key, JSON.stringify(value), cookieSetOptions);\n}\n\nexport function cookieGetAndDelete<T>(\n\tcookies: Cookies,\n\tkey: string,\n): T | undefined {\n\tconst value = cookieGet<T>(cookies, key);\n\n\tif (value) {\n\t\tcookies.delete(key, cookieDeleteOptions);\n\t}\n\n\treturn value;\n}\n\nexport function cookieGet<T>(cookies: Cookies, key: string): T | undefined {\n\tconst value = cookies.get(key);\n\n\treturn !value ? undefined : JSON.parse(value);\n}\n\nexport function cookieDelete(cookies: Cookies, key: string): void {\n\tcookies.delete(key, cookieDeleteOptions);\n}\n","export class ArmorError extends Error {}\nexport class ArmorOpenIdConfigError extends ArmorError {}\nexport class ArmorInvalidStateError extends ArmorError {}\nexport class ArmorAuthMissingError extends ArmorError {}\nexport class ArmorRefreshError extends ArmorError {}\n","import { RequestEvent } from \"@sveltejs/kit\";\nimport { COOKIE_STATE, cookieGetAndDelete } from \"./cookie\";\nimport { ArmorInvalidStateError } from \"../errors\";\n\nexport function eventStateValidOrThrow(event: RequestEvent): void {\n\tconst state = event.url.searchParams.get(\"state\") ?? undefined;\n\tconst stateCookie = cookieGetAndDelete(event.cookies, COOKIE_STATE);\n\n\tif (state !== stateCookie) {\n\t\tthrow new ArmorInvalidStateError();\n\t}\n}\n","import { redirect } from \"@sveltejs/kit\";\nimport type {\n\tArmorConfig,\n\tArmorIdToken,\n\tArmorTokenExchange,\n} from \"../contracts\";\nimport { queryParamsCreate, throwIfUndefined } from \"@nekm/core\";\nimport { createRemoteJWKSet } from \"jose\";\nimport type { RouteFactory } from \"./routes\";\nimport { urlConcat, isTokenExchange, createExpiresAt } from \"../utils/utils\";\nimport { jwtVerifyAccessToken, jwtVerifyIdToken } from \"../utils/jwt\";\nimport { eventStateValidOrThrow } from \"../utils/event\";\n\nexport const ROUTE_PATH_REDIRECT_LOGIN = \"/_armor/redirect/login\";\n\nexport const routeRedirectLoginFactory: RouteFactory = (\n\tconfig: ArmorConfig,\n) => {\n\tconst jwksUrl = new URL(\n\t\tconfig.oauth.jwksEndpoint ??\n\t\t\turlConcat(config.oauth.baseUrl, \".well-known/jwks.json\"),\n\t);\n\n\tconst tokenUrl =\n\t\tconfig.oauth.tokenEndpoint ??\n\t\turlConcat(config.oauth.baseUrl, \"oauth2/token\");\n\n\tconst scope = config.oauth.scope ?? \"openid profile email\";\n\n\tasync function exchangeCodeForToken(\n\t\tfetch: typeof global.fetch,\n\t\torigin: string,\n\t\tcode: string,\n\t): Promise<ArmorTokenExchange> {\n\t\tconst params: Record<string, string> = {\n\t\t\tgrant_type: \"authorization_code\",\n\t\t\tclient_id: config.oauth.clientId,\n\t\t\tclient_secret: config.oauth.clientSecret,\n\t\t\tcode,\n\t\t\tredirect_uri: urlConcat(origin, ROUTE_PATH_REDIRECT_LOGIN),\n\t\t\tscope,\n\t\t};\n\n\t\tif (config.oauth.audience) {\n\t\t\tparams.audience = config.oauth.audience;\n\t\t}\n\n\t\tconst response = await fetch(tokenUrl, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: {\n\t\t\t\t\"Content-Type\": \"application/x-www-form-urlencoded\",\n\t\t\t\tAccept: \"application/json\",\n\t\t\t},\n\t\t\tbody: new URLSearchParams(params).toString(),\n\t\t});\n\n\t\tif (!response.ok) {\n\t\t\tconst error = await response.text();\n\t\t\tthrow new Error(`Token exchange failed: ${error}`);\n\t\t}\n\n\t\tconst token = await response.json();\n\n\t\tif (!isTokenExchange(token)) {\n\t\t\tthrow new Error(\"Response is not a valid token exchange.\");\n\t\t}\n\n\t\treturn token;\n\t}\n\n\treturn {\n\t\tpath: ROUTE_PATH_REDIRECT_LOGIN,\n\t\tmethod: \"GET\",\n\t\tasync handle({ event }) {\n\t\t\teventStateValidOrThrow(event);\n\n\t\t\tconst error = event.url.searchParams.get(\"error\") ?? undefined;\n\n\t\t\tif (error) {\n\t\t\t\tconst error_description =\n\t\t\t\t\tevent.url.searchParams.get(\"error_description\") ?? undefined;\n\n\t\t\t\tif (!config.oauth.errorLoginRedirectPath) {\n\t\t\t\t\treturn new Response(`${error}\\n${error_description}`.trimEnd(), {\n\t\t\t\t\t\theaders: {\n\t\t\t\t\t\t\t\"Content-Type\": \"text/plain\",\n\t\t\t\t\t\t},\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\tconst errorParams = queryParamsCreate({ error, error_description });\n\t\t\t\tthrow redirect(\n\t\t\t\t\t302,\n\t\t\t\t\t`${config.oauth.errorLoginRedirectPath}?${errorParams}`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst code = event.url.searchParams.get(\"code\") ?? undefined;\n\t\t\tthrowIfUndefined(code);\n\n\t\t\tconst exchange = await exchangeCodeForToken(\n\t\t\t\tevent.fetch,\n\t\t\t\tevent.url.origin,\n\t\t\t\tcode,\n\t\t\t);\n\n\t\t\tconst jwks = createRemoteJWKSet(jwksUrl);\n\n\t\t\tconst [idToken, accessToken] = await Promise.all([\n\t\t\t\tjwtVerifyIdToken(config, jwks, exchange.id_token),\n\t\t\t\tjwtVerifyAccessToken(config, jwks, exchange.access_token),\n\t\t\t]);\n\n\t\t\tawait config.session.login(event, {\n\t\t\t\texchange,\n\t\t\t\tidToken: idToken as ArmorIdToken,\n\t\t\t\t// Generally, IdP's require an audience to get a JWT\n\t\t\t\t// access token. Most cases, this doesn't matter.\n\t\t\t\taccessToken: accessToken ?? exchange.access_token,\n\t\t\t\texpiresAt: createExpiresAt(exchange.expires_in),\n\t\t\t});\n\n\t\t\tthrow redirect(302, \"/\");\n\t\t},\n\t};\n};\n","import { ArmorRefreshError } from \"../errors\";\n\nexport interface ArmorBrowserRefresh {\n\treadonly idToken: string;\n\treadonly accessToken: string;\n\treadonly expiresAt: Date;\n}\n\nexport const ARMOR_REFRESH = \"/_armor/refresh\";\nexport const ARMOR_LOGIN = \"/_armor/login\";\n\nexport async function armorRefresh(): Promise<ArmorBrowserRefresh> {\n\tconst response = await fetch(ARMOR_REFRESH, {\n\t\tmethod: \"POST\",\n\t\theaders: {\n\t\t\tAccept: \"application/json\",\n\t\t},\n\t});\n\n\tif (!response.ok) {\n\t\tif (response.status === 401) {\n\t\t\t// eslint-disable-next-line no-undef\n\t\t\twindow.location.href = ARMOR_LOGIN;\n\t\t\tthrow new ArmorRefreshError(\"Redirecting to login\");\n\t\t}\n\n\t\tconst error = await response.text();\n\t\tthrow new ArmorRefreshError(`Could not refresh token: ${error}`);\n\t}\n\n\treturn response.json();\n}\n","import { redirect } from \"@sveltejs/kit\";\nimport type { ArmorConfig } from \"../contracts\";\nimport { queryParamsCreate } from \"@nekm/core\";\nimport { ROUTE_PATH_REDIRECT_LOGIN } from \"./redirect-login\";\nimport { randomUUID } from \"node:crypto\";\nimport type { RouteFactory } from \"./routes\";\nimport { COOKIE_STATE, cookieSet } from \"../utils/cookie\";\nimport { urlConcat } from \"../utils/utils\";\nimport { ARMOR_LOGIN } from \"../browser\";\n\nexport const ROUTE_PATH_LOGIN = ARMOR_LOGIN;\n\nexport const routeLoginFactory: RouteFactory = (config: ArmorConfig) => {\n\tconst authorizeEndpoint =\n\t\tconfig.oauth.authorizeEndpoint ??\n\t\turlConcat(config.oauth.baseUrl, \"oauth2/authorize\");\n\n\tconst scope = config.oauth.scope ?? \"openid profile email\";\n\n\treturn {\n\t\tpath: ROUTE_PATH_LOGIN,\n\t\tmethod: \"GET\",\n\t\tasync handle({ event }) {\n\t\t\tconst state = randomUUID();\n\t\t\tcookieSet(event.cookies, COOKIE_STATE, state);\n\n\t\t\tconst params = queryParamsCreate({\n\t\t\t\tclient_id: config.oauth.clientId,\n\t\t\t\tresponse_type: \"code\",\n\t\t\t\tredirect_uri: urlConcat(event.url.origin, ROUTE_PATH_REDIRECT_LOGIN),\n\t\t\t\tstate,\n\t\t\t\tscope,\n\t\t\t\taudience: config.oauth.audience,\n\t\t\t});\n\n\t\t\tthrow redirect(302, `${authorizeEndpoint}?${params}`);\n\t\t},\n\t};\n};\n","import { redirect } from \"@sveltejs/kit\";\nimport type { ArmorConfig } from \"../contracts\";\nimport type { RouteFactory } from \"./routes\";\nimport { eventStateValidOrThrow } from \"../utils/event\";\n\nexport const ROUTE_PATH_REDIRECT_LOGOUT = \"/_armor/redirect/logout\";\n\nexport const routeRedirectLogoutFactory: RouteFactory = (\n\tconfig: ArmorConfig,\n) => {\n\t// Check if the oauth provider supports a logout path.\n\tif (!config.oauth.logoutEndpoint) {\n\t\treturn undefined;\n\t}\n\n\treturn {\n\t\tpath: ROUTE_PATH_REDIRECT_LOGOUT,\n\t\tmethod: \"GET\",\n\t\tasync handle({ event }) {\n\t\t\teventStateValidOrThrow(event);\n\n\t\t\tawait config.session.logout(event);\n\n\t\t\tthrow redirect(302, \"/\");\n\t\t},\n\t};\n};\n","import { redirect } from \"@sveltejs/kit\";\nimport type { ArmorConfig } from \"../contracts\";\nimport { queryParamsCreate } from \"@nekm/core\";\nimport { ROUTE_PATH_REDIRECT_LOGOUT } from \"./redirect-logout\";\nimport type { RouteFactory } from \"./routes\";\nimport { urlConcat } from \"../utils/utils\";\nimport { randomUUID } from \"node:crypto\";\nimport { COOKIE_STATE, cookieSet } from \"../utils/cookie\";\n\nexport const ROUTE_PATH_LOGOUT = \"/_armor/logout\";\n\nexport const routeLogoutFactory: RouteFactory = (config: ArmorConfig) => {\n\t// Check if the oauth provider supports a logout path.\n\tif (!config.oauth.logoutEndpoint) {\n\t\treturn undefined;\n\t}\n\n\tconst returnTo = config.oauth.logoutReturnToParam ?? \"logout_uri\";\n\n\treturn {\n\t\tpath: ROUTE_PATH_LOGOUT,\n\t\tmethod: \"GET\",\n\t\tasync handle({ event }) {\n\t\t\tconst state = randomUUID();\n\t\t\tcookieSet(event.cookies, COOKIE_STATE, state);\n\n\t\t\tconst params = queryParamsCreate({\n\t\t\t\t[returnTo]: urlConcat(event.url.origin, ROUTE_PATH_REDIRECT_LOGOUT),\n\t\t\t\tclient_id: config.oauth.clientId,\n\t\t\t\tstate,\n\t\t\t});\n\n\t\t\tthrow redirect(302, `${config.oauth.logoutEndpoint}?${params}`);\n\t\t},\n\t};\n};\n","import { createRemoteJWKSet } from \"jose\";\nimport {\n\tArmorConfig,\n\tArmorIdToken,\n\tArmorTokenExchange,\n\tArmorTokens,\n} from \"../contracts\";\nimport { ArmorRefreshError } from \"../errors\";\nimport { createExpiresAt, urlConcat } from \"./utils\";\nimport { jwtVerifyAccessToken, jwtVerifyIdToken } from \"./jwt\";\nimport { RequestEvent } from \"@sveltejs/kit\";\n\nexport function createRefresh(config: ArmorConfig) {\n\tconst refreshEndpoint =\n\t\tconfig.oauth.refreshEndpoint ??\n\t\turlConcat(config.oauth.baseUrl, \"oauth2/token\");\n\n\tconst jwksUrl = new URL(\n\t\tconfig.oauth.jwksEndpoint ??\n\t\t\turlConcat(config.oauth.baseUrl, \".well-known/jwks.json\"),\n\t);\n\n\tconst refresh = async (\n\t\tfetch: typeof global.fetch,\n\t\trefreshToken: string,\n\t): Promise<ArmorTokenExchange> => {\n\t\tconst body = new URLSearchParams({\n\t\t\tgrant_type: \"refresh_token\",\n\t\t\tclient_id: config.oauth.clientId,\n\t\t\tclient_secret: config.oauth.clientSecret,\n\t\t\trefresh_token: refreshToken,\n\t\t});\n\n\t\tif (config.oauth.scope) {\n\t\t\tbody.set(\"scope\", config.oauth.scope);\n\t\t}\n\n\t\tconst response = await fetch(refreshEndpoint, {\n\t\t\theaders: {\n\t\t\t\t\"Content-Type\": \"application/x-www-form-urlencoded\",\n\t\t\t\tAccept: \"application/json\",\n\t\t\t},\n\t\t\tbody: body.toString(),\n\t\t});\n\n\t\tif (!response.ok) {\n\t\t\tconst error = await response.text();\n\t\t\tthrow new ArmorRefreshError(`Could not refresh token: ${error}`);\n\t\t}\n\n\t\tconst json: ArmorTokenExchange = await response.json();\n\n\t\treturn {\n\t\t\t...json,\n\t\t\trefresh_token: json.refresh_token ?? refreshToken,\n\t\t};\n\t};\n\n\treturn async (\n\t\tevent: RequestEvent,\n\t\ttokens: ArmorTokens,\n\t): Promise<ArmorTokens> => {\n\t\tconst refreshToken = tokens.exchange?.refresh_token;\n\n\t\tif (!refreshToken) {\n\t\t\tthrow new ArmorRefreshError(\"Could not find refresh token\");\n\t\t}\n\n\t\tconst newExchange = await refresh(event.fetch, refreshToken);\n\n\t\tconst jwks = createRemoteJWKSet(jwksUrl);\n\n\t\tconst [idToken, accessToken] = await Promise.all([\n\t\t\tjwtVerifyIdToken(config, jwks, newExchange.id_token),\n\t\t\tjwtVerifyAccessToken(config, jwks, newExchange.access_token),\n\t\t]);\n\n\t\treturn {\n\t\t\texchange: newExchange,\n\t\t\tidToken: idToken as ArmorIdToken,\n\t\t\t// Generally, IdP's require an audience to get a JWT\n\t\t\t// access token. Most cases, this doesn't matter.\n\t\t\taccessToken: accessToken ?? newExchange.access_token,\n\t\t\texpiresAt: createExpiresAt(newExchange.expires_in),\n\t\t};\n\t};\n}\n","import { error, json } from \"@sveltejs/kit\";\nimport type { ArmorConfig } from \"../contracts\";\nimport type { RouteFactory } from \"./routes\";\nimport { createRefresh } from \"../utils/refresh\";\nimport { ARMOR_REFRESH } from \"../browser\";\nimport { ArmorRefreshError } from \"../errors\";\n\nexport const ROUTE_PATH_REFRESH = ARMOR_REFRESH;\n\nexport const routeRefreshFactory: RouteFactory = (config: ArmorConfig) => {\n\tconst refresh = createRefresh(config);\n\n\treturn {\n\t\tpath: ROUTE_PATH_REFRESH,\n\t\tmethod: \"POST\",\n\t\tasync handle({ event }) {\n\t\t\ttry {\n\t\t\t\tconst tokens = await config.session.getTokens(event);\n\n\t\t\t\tif (!tokens) {\n\t\t\t\t\treturn error(401, \"Unauthorized\");\n\t\t\t\t}\n\n\t\t\t\tconst { idToken, expiresAt, accessToken } = await refresh(\n\t\t\t\t\tevent,\n\t\t\t\t\ttokens,\n\t\t\t\t);\n\n\t\t\t\treturn json({ idToken, expiresAt, accessToken });\n\t\t\t} catch (ex) {\n\t\t\t\tif (ex instanceof ArmorRefreshError) {\n\t\t\t\t\treturn error(401, \"Unauthorized\");\n\t\t\t\t}\n\n\t\t\t\tthrow ex;\n\t\t\t}\n\t\t},\n\t};\n};\n","import type { Handle } from \"@sveltejs/kit\";\nimport type { ArmorConfig } from \"../contracts\";\nimport { routeLoginFactory } from \"./login\";\nimport { routeLogoutFactory } from \"./logout\";\nimport { routeRedirectLogoutFactory } from \"./redirect-logout\";\nimport { routeRedirectLoginFactory } from \"./redirect-login\";\nimport { routeRefreshFactory } from \"./refresh\";\n\nexport interface Route {\n\treadonly path: string;\n\treadonly handle: Handle;\n\treadonly method: \"GET\" | \"POST\";\n}\n\nexport type RouteFactory = (config: ArmorConfig) => Route | undefined;\n\nconst routeFactories = Object.freeze([\n\trouteLoginFactory,\n\trouteLogoutFactory,\n\trouteRedirectLoginFactory,\n\trouteRedirectLogoutFactory,\n\trouteRefreshFactory,\n]);\n\nexport function routeCreate(config: ArmorConfig): Map<string, Route> {\n\t// @ts-expect-error Incorrect typing error.\n\treturn new Map(\n\t\trouteFactories\n\t\t\t.map((routeFactory) => routeFactory(config))\n\t\t\t.filter((route) => Boolean(route))\n\t\t\t// @ts-expect-error Incorrect typing error.\n\t\t\t.map((route) => [route.path, route]),\n\t);\n}\n","import { RequestEvent } from \"@sveltejs/kit\";\nimport {\n\tCOOKIE_TOKENS,\n\tcookieDelete,\n\tcookieGet,\n\tcookieSet,\n} from \"../utils/cookie\";\nimport { ArmorConfig, ArmorTokens } from \"../contracts\";\nimport { ArmorAuthMissingError } from \"../errors\";\n\nfunction cookieSessionGetTokens({\n\tcookies,\n}: RequestEvent): ArmorTokens | undefined {\n\treturn cookies.get(COOKIE_TOKENS) as ArmorTokens | undefined;\n}\n\nexport function cookieSessionLogin(\n\t{ cookies }: RequestEvent,\n\ttokens: ArmorTokens,\n): void {\n\tcookieSet(cookies, COOKIE_TOKENS, tokens);\n}\n\nfunction cookieSessionLogout({ cookies }: RequestEvent): void {\n\tcookieDelete(cookies, COOKIE_TOKENS);\n}\n\nexport function armorCookieSessionGet({ cookies }: RequestEvent): ArmorTokens {\n\tconst tokens = cookieGet<ArmorTokens>(cookies, COOKIE_TOKENS);\n\n\tif (!tokens) {\n\t\tthrow new ArmorAuthMissingError();\n\t}\n\n\treturn tokens;\n}\n\nexport const armorCookieSession: ArmorConfig[\"session\"] = {\n\tgetTokens: cookieSessionGetTokens,\n\tlogin: cookieSessionLogin,\n\tlogout: cookieSessionLogout,\n};\n","import { redirect, type Handle } from \"@sveltejs/kit\";\nimport { ROUTE_PATH_LOGIN } from \"./routes/login\";\nimport type { ArmorConfig, ArmorOpenIdConfig, ArmorTokens } from \"./contracts\";\nimport { routeCreate } from \"./routes/routes\";\nimport { ArmorOpenIdConfigError, ArmorRefreshError } from \"./errors\";\nimport { shouldRefresh } from \"./utils/utils\";\nimport { createRefresh } from \"./utils/refresh\";\n\nexport type { ArmorConfig, ArmorTokens };\nexport { armorCookieSession, armorCookieSessionGet } from \"./session/cookie\";\n\nexport function armor(config: ArmorConfig): Handle {\n\tconst routeByPath = routeCreate(config);\n\tconst refresh = createRefresh(config);\n\n\treturn async ({ event, resolve }) => {\n\t\tconst route = routeByPath.get(event.url.pathname);\n\n\t\tif (route && route.method === event.request.method) {\n\t\t\treturn route.handle({ event, resolve });\n\t\t}\n\n\t\tconst tokens = await config.session.getTokens(event);\n\n\t\tif (!tokens) {\n\t\t\tthrow redirect(302, ROUTE_PATH_LOGIN);\n\t\t}\n\n\t\ttry {\n\t\t\tif (shouldRefresh(tokens)) {\n\t\t\t\tconsole.log(\"Refreshing token...\");\n\t\t\t\tawait refresh(event, tokens);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tif (error instanceof ArmorRefreshError) {\n\t\t\t\tconsole.error(\"Could not refresh token. Redirect user to login...\");\n\t\t\t\tthrow redirect(302, ROUTE_PATH_LOGIN);\n\t\t\t}\n\n\t\t\tthrow error;\n\t\t}\n\n\t\treturn resolve(event);\n\t};\n}\n\n/**\n * Some IdP's expose a /.well-known/openid-configuration that specifies how to configure.\n * Use that to create your config.\n * @param config\n * @param fetch\n */\nexport async function armorConfigFromOpenId(\n\tconfig: ArmorOpenIdConfig,\n\tfetch?: typeof global.fetch,\n): Promise<ArmorConfig> {\n\tconst fetchToUse = fetch ?? global.fetch;\n\n\tconst response = await fetchToUse(config.oauth.openIdConfigEndpoint, {\n\t\theaders: {\n\t\t\tAccept: \"application/json\",\n\t\t},\n\t});\n\n\tif (!response.ok) {\n\t\tconst text = await response.text();\n\t\tthrow new ArmorOpenIdConfigError(text);\n\t}\n\n\tconst body = await response.json();\n\n\treturn {\n\t\t...config,\n\t\toauth: {\n\t\t\t...config.oauth,\n\t\t\ttokenEndpoint: body.token_endpoint,\n\t\t\tauthorizeEndpoint: body.authorization_endpoint,\n\t\t\tissuer: body.issuer,\n\t\t\tjwksEndpoint: body.jwks_uri,\n\t\t\tlogoutEndpoint: body.end_session_endpoint ?? undefined,\n\t\t\trefreshEndpoint: body.token_endpoint,\n\t\t},\n\t};\n}\n"],"names":["urlConcat","origin","path","strTrimEnd","strTrimStart","join","isTokenExchange","value","obj","access_token","token_type","expires_in","id_token","undefined","refresh_token","scope","MINUTES_MS","shouldRefresh","tokens","expiresAt","getTime","Date","now","createExpiresAt","seconds","setSeconds","getSeconds","jwtIsCompactJwt","token","parts","trim","split","length","every","p","jwtVerifyIdToken","config","jwks","idToken","payload","jwtVerifyToken","issuer","oauth","audience","clientId","throwIfUndefined","jwtVerifyAccessToken","accessToken","opts","isInvalidCompactJwt","error","Boolean","message","test","jwtVerify","COOKIE_TOKENS","COOKIE_STATE","cookieDeleteOptions","Object","freeze","cookieSetOptions","httpOnly","secure","sameSite","maxAge","cookieSet","cookies","key","set","JSON","stringify","cookieGetAndDelete","cookieGet","delete","get","parse","cookieDelete","ArmorError","Error","ArmorOpenIdConfigError","ArmorInvalidStateError","ArmorAuthMissingError","ArmorRefreshError","eventStateValidOrThrow","event","_event$url$searchPara","state","url","searchParams","stateCookie","ROUTE_PATH_REDIRECT_LOGIN","routeRedirectLoginFactory","_config$oauth$jwksEnd","_config$oauth$tokenEn","_config$oauth$scope","jwksUrl","URL","jwksEndpoint","baseUrl","tokenUrl","tokenEndpoint","exchangeCodeForToken","fetch","code","params","grant_type","client_id","client_secret","clientSecret","redirect_uri","response","method","headers","Accept","body","URLSearchParams","toString","ok","text","json","handle","_event$url$searchPara3","_event$url$searchPara2","error_description","errorLoginRedirectPath","Response","trimEnd","errorParams","queryParamsCreate","redirect","exchange","createRemoteJWKSet","Promise","all","session","login","ARMOR_REFRESH","ARMOR_LOGIN","ROUTE_PATH_LOGIN","routeLoginFactory","_config$oauth$authori","authorizeEndpoint","randomUUID","response_type","ROUTE_PATH_REDIRECT_LOGOUT","routeRedirectLogoutFactory","logoutEndpoint","logout","ROUTE_PATH_LOGOUT","routeLogoutFactory","_config$oauth$logoutR","returnTo","logoutReturnToParam","createRefresh","_config$oauth$refresh","refreshEndpoint","refresh","refreshToken","_json$refresh_token","_tokens$exchange","newExchange","ROUTE_PATH_REFRESH","routeRefreshFactory","getTokens","ex","routeFactories","routeCreate","Map","map","routeFactory","filter","route","cookieSessionGetTokens","cookieSessionLogin","cookieSessionLogout","armorCookieSessionGet","armorCookieSession","armor","routeByPath","resolve","pathname","request","console","log","armorConfigFromOpenId","_body$end_session_end","fetchToUse","global","openIdConfigEndpoint","token_endpoint","authorization_endpoint","jwks_uri","end_session_endpoint"],"mappings":"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"}
|