@absolutejs/auth 0.74.0 → 0.75.1

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.
Files changed (47) hide show
  1. package/README.md +21 -6
  2. package/dist/agents/index.js +46 -11
  3. package/dist/agents/index.js.map +4 -4
  4. package/dist/agents/oidcAdapter.d.ts +3 -1
  5. package/dist/apikeys/routes.d.ts +1 -1
  6. package/dist/compliance/routes.d.ts +1 -1
  7. package/dist/credentials/emailVerification.d.ts +1 -1
  8. package/dist/credentials/login.d.ts +1 -1
  9. package/dist/credentials/passwordReset.d.ts +1 -1
  10. package/dist/credentials/register.d.ts +1 -1
  11. package/dist/htmx/configuredRoutes.d.ts +1 -1
  12. package/dist/htmx/routes.d.ts +1 -1
  13. package/dist/index.d.ts +1 -1
  14. package/dist/index.js +166 -68
  15. package/dist/index.js.map +8 -8
  16. package/dist/mfa/challenge.d.ts +1 -1
  17. package/dist/mfa/management.d.ts +1 -1
  18. package/dist/mfa/sms.d.ts +1 -1
  19. package/dist/mfa/totp.d.ts +1 -1
  20. package/dist/nativePush.d.ts +500 -20
  21. package/dist/oidc/dpop.d.ts +6 -2
  22. package/dist/oidc/index.d.ts +1 -0
  23. package/dist/oidc/index.js +130 -1
  24. package/dist/oidc/index.js.map +4 -3
  25. package/dist/organizations/routes.d.ts +1 -1
  26. package/dist/portal/routes.d.ts +1 -1
  27. package/dist/roles/routes.d.ts +1 -1
  28. package/dist/routes/authorize.d.ts +1 -1
  29. package/dist/routes/callback.d.ts +1 -1
  30. package/dist/routes/profile.d.ts +1 -1
  31. package/dist/routes/refresh.d.ts +1 -1
  32. package/dist/routes/revoke.d.ts +1 -1
  33. package/dist/routes/sessions.d.ts +1 -1
  34. package/dist/routes/signout.d.ts +1 -1
  35. package/dist/routes/userStatus.d.ts +1 -1
  36. package/dist/scim/routes.d.ts +1 -1
  37. package/dist/server.js +164 -68
  38. package/dist/server.js.map +8 -8
  39. package/dist/sso/discoveryRoute.d.ts +1 -1
  40. package/dist/sso/oidcRoutes.d.ts +1 -1
  41. package/dist/sso/samlIdpRoutes.d.ts +1 -1
  42. package/dist/sso/samlRoutes.d.ts +1 -1
  43. package/dist/types.d.ts +3 -1
  44. package/dist/vc/statusListRoutes.d.ts +1 -1
  45. package/dist/vc/vpRoutes.d.ts +1 -1
  46. package/dist/webauthn/routes.d.ts +1 -1
  47. package/package.json +1 -1
@@ -10,10 +10,14 @@ export declare const verifyDpopNonce: ({ now, nonce, secret }: {
10
10
  }) => Promise<boolean>;
11
11
  export type DpopResult = {
12
12
  jkt: string;
13
- jti?: string;
13
+ jti: string;
14
14
  };
15
- export declare const verifyDpopProof: ({ accessToken, htm, htu, isUsedJti, maxAgeMs, now, proof }: {
15
+ export type DpopJti = DpopResult & {
16
+ expiresAt: number;
17
+ };
18
+ export declare const verifyDpopProof: ({ accessToken, consumeJti, htm, htu, isUsedJti, maxAgeMs, now, proof }: {
16
19
  accessToken?: string;
20
+ consumeJti?: (jti: DpopJti) => boolean | Promise<boolean>;
17
21
  htm: string;
18
22
  htu: string;
19
23
  isUsedJti?: (jti: string) => boolean | Promise<boolean>;
@@ -6,6 +6,7 @@
6
6
  * through the package root.
7
7
  */
8
8
  export type { OidcProviderConfig } from './config';
9
+ export { extractDpopNonceClaim, mintDpopNonce, verifyDpopNonce, verifyDpopProof, type DpopJti, type DpopResult } from './dpop';
9
10
  export { generateSigningKey, jwkThumbprint, signJwt, signingVerificationKeys, toPublicJwk, verifyJwt, verifyJwtWithKeys, type SigningKey, type SigningKeyIdentity } from './keys';
10
11
  export { revokeOAuthClientCredentials } from './operator';
11
12
  export { createNeonAuthorizationCodeStore, createNeonClientAssertionJtiStore, createNeonClientRegistrationTokenStore, createNeonDeviceAuthorizationStore, createNeonInitialAccessTokenStore, createNeonOAuthClientStore, createNeonOidcRefreshTokenStore, createNeonSocketTicketStore, createPostgresAuthorizationCodeStore, createPostgresClientAssertionJtiStore, createPostgresClientRegistrationTokenStore, createPostgresDeviceAuthorizationStore, createPostgresInitialAccessTokenStore, createPostgresOAuthClientStore, createPostgresOidcRefreshTokenStore, createPostgresSocketTicketStore } from './postgresStores';
@@ -181,6 +181,9 @@ var init_crypto = __esm(() => {
181
181
  textDecoder3 = new TextDecoder;
182
182
  });
183
183
 
184
+ // src/oidc/dpop.ts
185
+ init_constants();
186
+
184
187
  // src/oidc/keys.ts
185
188
  var ENCODER = new TextEncoder;
186
189
  var ES256 = { hash: "SHA-256", name: "ECDSA" };
@@ -280,6 +283,128 @@ var verifyJwtWithKeys = async (token, keys) => {
280
283
  return;
281
284
  return verifyJwt(token, key.publicJwk);
282
285
  };
286
+
287
+ // src/oidc/dpop.ts
288
+ var DEFAULT_MAX_AGE_MS = 60000;
289
+ var MAX_JTI_LENGTH = 128;
290
+ var SECONDS_TO_MS = 1000;
291
+ var NONCE_WINDOW_SECONDS = 120;
292
+ var NONCE_WINDOW_MS = NONCE_WINDOW_SECONDS * MILLISECONDS_IN_A_SECOND;
293
+ var NONCE_PREVIOUS_WINDOWS_ACCEPTED = 1;
294
+ var hmacSha256 = async (secret, message) => {
295
+ const encoder = new TextEncoder;
296
+ const key = await crypto.subtle.importKey("raw", encoder.encode(secret), { hash: "SHA-256", name: "HMAC" }, false, ["sign"]);
297
+ const signature = await crypto.subtle.sign("HMAC", key, encoder.encode(message));
298
+ return Buffer.from(new Uint8Array(signature)).toString("base64url");
299
+ };
300
+ var extractDpopNonceClaim = (proof) => {
301
+ const [, payloadSegment] = proof.split(".");
302
+ if (payloadSegment === undefined)
303
+ return;
304
+ try {
305
+ const payload = JSON.parse(Buffer.from(payloadSegment, "base64url").toString("utf8"));
306
+ if (typeof payload !== "object" || payload === null)
307
+ return;
308
+ const value = Reflect.get(payload, "nonce");
309
+ return typeof value === "string" ? value : undefined;
310
+ } catch {
311
+ return;
312
+ }
313
+ };
314
+ var mintDpopNonce = async ({
315
+ now = Date.now(),
316
+ secret
317
+ }) => {
318
+ const window = Math.floor(now / NONCE_WINDOW_MS);
319
+ return hmacSha256(secret, String(window));
320
+ };
321
+ var verifyDpopNonce = async ({
322
+ now = Date.now(),
323
+ nonce,
324
+ secret
325
+ }) => {
326
+ const currentWindow = Math.floor(now / NONCE_WINDOW_MS);
327
+ const candidates = await Promise.all(Array.from({ length: NONCE_PREVIOUS_WINDOWS_ACCEPTED + 1 }, (_, offset) => hmacSha256(secret, String(currentWindow - offset))));
328
+ return candidates.some((expected) => expected === nonce);
329
+ };
330
+ var decodeHeader = (segment) => {
331
+ try {
332
+ const value = JSON.parse(Buffer.from(segment, "base64url").toString("utf8"));
333
+ return typeof value === "object" && value !== null && !Array.isArray(value) ? value : undefined;
334
+ } catch {
335
+ return;
336
+ }
337
+ };
338
+ var normalizeHtu = (value, proofClaim = false) => {
339
+ try {
340
+ const url = new URL(String(value));
341
+ if (url.username || url.password || proofClaim && (url.search.length > 0 || url.hash.length > 0))
342
+ return;
343
+ return `${url.origin}${url.pathname}`;
344
+ } catch {
345
+ return;
346
+ }
347
+ };
348
+ var isPublicEs256Jwk = (value) => {
349
+ if (typeof value !== "object" || value === null || Array.isArray(value))
350
+ return false;
351
+ const kty = Reflect.get(value, "kty");
352
+ const crv = Reflect.get(value, "crv");
353
+ const xCoordinate = Reflect.get(value, "x");
354
+ const yCoordinate = Reflect.get(value, "y");
355
+ const privateComponent = Reflect.get(value, "d");
356
+ const alg = Reflect.get(value, "alg");
357
+ return kty === "EC" && crv === "P-256" && typeof xCoordinate === "string" && xCoordinate.length > 0 && typeof yCoordinate === "string" && yCoordinate.length > 0 && privateComponent === undefined && (alg === undefined || alg === "ES256");
358
+ };
359
+ var verifyDpopProof = async ({
360
+ accessToken,
361
+ consumeJti,
362
+ htm,
363
+ htu,
364
+ isUsedJti,
365
+ maxAgeMs = DEFAULT_MAX_AGE_MS,
366
+ now = Date.now(),
367
+ proof
368
+ }) => {
369
+ if (proof === undefined)
370
+ return;
371
+ const segments = proof.split(".");
372
+ if (segments.length !== 3)
373
+ return;
374
+ const [headerSegment] = segments;
375
+ if (headerSegment === undefined)
376
+ return;
377
+ const header = decodeHeader(headerSegment);
378
+ const publicJwk = header === undefined ? undefined : Reflect.get(header, "jwk");
379
+ if (header === undefined || Reflect.get(header, "typ") !== "dpop+jwt" || Reflect.get(header, "alg") !== "ES256" || !isPublicEs256Jwk(publicJwk)) {
380
+ return;
381
+ }
382
+ const verified = await verifyJwt(proof, publicJwk).catch(() => {
383
+ return;
384
+ });
385
+ if (verified === undefined)
386
+ return;
387
+ const { payload } = verified;
388
+ if (accessToken !== undefined) {
389
+ const expectedAth = Buffer.from(await crypto.subtle.digest("SHA-256", new TextEncoder().encode(accessToken))).toString("base64url");
390
+ if (payload.ath !== expectedAth)
391
+ return;
392
+ }
393
+ const iatMs = typeof payload.iat === "number" ? payload.iat * SECONDS_TO_MS : 0;
394
+ const claimedHtu = normalizeHtu(payload.htu, true);
395
+ const expectedHtu = normalizeHtu(htu);
396
+ const jti = typeof payload.jti === "string" ? payload.jti : undefined;
397
+ if (payload.htm !== htm || claimedHtu === undefined || expectedHtu === undefined || claimedHtu !== expectedHtu || iatMs === 0 || Math.abs(now - iatMs) > maxAgeMs || jti === undefined || jti.length === 0 || jti.length > MAX_JTI_LENGTH) {
398
+ return;
399
+ }
400
+ const jkt = await jwkThumbprint(publicJwk);
401
+ if (isUsedJti !== undefined && await isUsedJti(jti)) {
402
+ return;
403
+ }
404
+ if (consumeJti !== undefined && !await consumeJti({ expiresAt: iatMs + maxAgeMs, jkt, jti }))
405
+ return;
406
+ return { jkt, jti };
407
+ };
283
408
  // src/oidc/operator.ts
284
409
  var operatorDelete = (store, storeName) => {
285
410
  if (!store.deleteForClient)
@@ -12788,13 +12913,17 @@ var issueSocketTicket = async ({
12788
12913
  export {
12789
12914
  verifyJwtWithKeys,
12790
12915
  verifyJwt,
12916
+ verifyDpopProof,
12917
+ verifyDpopNonce,
12791
12918
  toPublicJwk,
12792
12919
  signingVerificationKeys,
12793
12920
  signJwt,
12794
12921
  revokeOAuthClientCredentials,
12922
+ mintDpopNonce,
12795
12923
  jwkThumbprint,
12796
12924
  issueSocketTicket,
12797
12925
  generateSigningKey,
12926
+ extractDpopNonceClaim,
12798
12927
  createPostgresSocketTicketStore,
12799
12928
  createPostgresOidcRefreshTokenStore,
12800
12929
  createPostgresOAuthClientStore,
@@ -12815,5 +12944,5 @@ export {
12815
12944
  consumeSocketTicket
12816
12945
  };
12817
12946
 
12818
- //# debugId=B37CCAB8EEBB54A964756E2164756E21
12947
+ //# debugId=9914FF0D8636BBE564756E2164756E21
12819
12948
  //# sourceMappingURL=index.js.map