@absolutejs/auth 0.75.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.
package/dist/server.js CHANGED
@@ -7187,8 +7187,8 @@ var createMfaGate = ({ getUserId, mfaStore }) => async (user) => isMfaEnrolled(a
7187
7187
 
7188
7188
  // src/nativePush.ts
7189
7189
  import { Elysia as Elysia17, t as t11 } from "elysia";
7190
- var DEFAULT_PUSH_ROUTE = "/auth/push";
7191
7190
  var DEFAULT_NATIVE_PUSH_ROUTE = "/auth/mobile/push";
7191
+ var DEFAULT_PUSH_ROUTE = "/auth/push";
7192
7192
  var requireServerText = (value, field) => {
7193
7193
  const normalized = value.trim();
7194
7194
  if (!normalized)
@@ -7242,9 +7242,11 @@ var pushRoutes = ({
7242
7242
  }
7243
7243
  return true;
7244
7244
  };
7245
+ const installationIdSchema = t11.Optional(t11.String({ maxLength: 128, minLength: 1 }));
7246
+ const localeSchema = t11.Optional(t11.String({ maxLength: 64, minLength: 1 }));
7245
7247
  const commonRegistrationFields = {
7246
- installationId: t11.Optional(t11.String({ maxLength: 128, minLength: 1 })),
7247
- locale: t11.Optional(t11.String({ maxLength: 64, minLength: 1 }))
7248
+ installationId: installationIdSchema,
7249
+ locale: localeSchema
7248
7250
  };
7249
7251
  const registrationBody = t11.Union([
7250
7252
  t11.Object({
@@ -7264,18 +7266,20 @@ var pushRoutes = ({
7264
7266
  })
7265
7267
  })
7266
7268
  ]);
7269
+ const requirePushPrincipal = ({
7270
+ pushPrincipal,
7271
+ status
7272
+ }) => pushPrincipal ? undefined : status("Unauthorized", "User is not authenticated");
7267
7273
  const registrationOptions = {
7268
- body: registrationBody,
7269
- beforeHandle: ({
7270
- pushPrincipal,
7271
- status
7272
- }) => pushPrincipal ? undefined : status("Unauthorized", "User is not authenticated")
7274
+ beforeHandle: requirePushPrincipal,
7275
+ body: registrationBody
7273
7276
  };
7277
+ const removalBody = t11.Object({
7278
+ installationId: t11.String({ maxLength: 128, minLength: 1 })
7279
+ });
7274
7280
  const removalOptions = {
7275
- body: t11.Object({
7276
- installationId: t11.String({ maxLength: 128, minLength: 1 })
7277
- }),
7278
- beforeHandle: registrationOptions.beforeHandle
7281
+ beforeHandle: requirePushPrincipal,
7282
+ body: removalBody
7279
7283
  };
7280
7284
  return new Elysia17({ name: "@absolutejs/auth/push" }).use(sessionStore()).guard({
7281
7285
  cookie: t11.Cookie({ user_session_id: userSessionIdTypebox }),
@@ -9082,6 +9086,7 @@ var verifyCertificateBoundToken = async ({
9082
9086
  // src/oidc/dpop.ts
9083
9087
  init_constants();
9084
9088
  var DEFAULT_MAX_AGE_MS = 60000;
9089
+ var MAX_JTI_LENGTH = 128;
9085
9090
  var SECONDS_TO_MS = 1000;
9086
9091
  var NONCE_WINDOW_SECONDS = 120;
9087
9092
  var NONCE_WINDOW_MS = NONCE_WINDOW_SECONDS * MILLISECONDS_IN_A_SECOND;
@@ -9122,17 +9127,38 @@ var verifyDpopNonce = async ({
9122
9127
  const candidates = await Promise.all(Array.from({ length: NONCE_PREVIOUS_WINDOWS_ACCEPTED + 1 }, (_, offset) => hmacSha2562(secret, String(currentWindow - offset))));
9123
9128
  return candidates.some((expected) => expected === nonce);
9124
9129
  };
9125
- var decodeHeader = (segment) => JSON.parse(Buffer.from(segment, "base64url").toString("utf8"));
9126
- var normalizeHtu = (value) => {
9130
+ var decodeHeader = (segment) => {
9131
+ try {
9132
+ const value = JSON.parse(Buffer.from(segment, "base64url").toString("utf8"));
9133
+ return typeof value === "object" && value !== null && !Array.isArray(value) ? value : undefined;
9134
+ } catch {
9135
+ return;
9136
+ }
9137
+ };
9138
+ var normalizeHtu = (value, proofClaim = false) => {
9127
9139
  try {
9128
9140
  const url = new URL(String(value));
9141
+ if (url.username || url.password || proofClaim && (url.search.length > 0 || url.hash.length > 0))
9142
+ return;
9129
9143
  return `${url.origin}${url.pathname}`;
9130
9144
  } catch {
9131
- return "";
9145
+ return;
9132
9146
  }
9133
9147
  };
9148
+ var isPublicEs256Jwk = (value) => {
9149
+ if (typeof value !== "object" || value === null || Array.isArray(value))
9150
+ return false;
9151
+ const kty = Reflect.get(value, "kty");
9152
+ const crv = Reflect.get(value, "crv");
9153
+ const xCoordinate = Reflect.get(value, "x");
9154
+ const yCoordinate = Reflect.get(value, "y");
9155
+ const privateComponent = Reflect.get(value, "d");
9156
+ const alg = Reflect.get(value, "alg");
9157
+ return kty === "EC" && crv === "P-256" && typeof xCoordinate === "string" && xCoordinate.length > 0 && typeof yCoordinate === "string" && yCoordinate.length > 0 && privateComponent === undefined && (alg === undefined || alg === "ES256");
9158
+ };
9134
9159
  var verifyDpopProof = async ({
9135
9160
  accessToken,
9161
+ consumeJti,
9136
9162
  htm,
9137
9163
  htu,
9138
9164
  isUsedJti,
@@ -9142,14 +9168,20 @@ var verifyDpopProof = async ({
9142
9168
  }) => {
9143
9169
  if (proof === undefined)
9144
9170
  return;
9145
- const [headerSegment] = proof.split(".");
9171
+ const segments = proof.split(".");
9172
+ if (segments.length !== 3)
9173
+ return;
9174
+ const [headerSegment] = segments;
9146
9175
  if (headerSegment === undefined)
9147
9176
  return;
9148
9177
  const header = decodeHeader(headerSegment);
9149
- if (header?.typ !== "dpop+jwt" || header.alg !== "ES256" || header.jwk === undefined) {
9178
+ const publicJwk = header === undefined ? undefined : Reflect.get(header, "jwk");
9179
+ if (header === undefined || Reflect.get(header, "typ") !== "dpop+jwt" || Reflect.get(header, "alg") !== "ES256" || !isPublicEs256Jwk(publicJwk)) {
9150
9180
  return;
9151
9181
  }
9152
- const verified = await verifyJwt(proof, header.jwk);
9182
+ const verified = await verifyJwt(proof, publicJwk).catch(() => {
9183
+ return;
9184
+ });
9153
9185
  if (verified === undefined)
9154
9186
  return;
9155
9187
  const { payload } = verified;
@@ -9159,14 +9191,19 @@ var verifyDpopProof = async ({
9159
9191
  return;
9160
9192
  }
9161
9193
  const iatMs = typeof payload.iat === "number" ? payload.iat * SECONDS_TO_MS : 0;
9162
- if (payload.htm !== htm || normalizeHtu(payload.htu) !== normalizeHtu(htu) || iatMs === 0 || Math.abs(now - iatMs) > maxAgeMs) {
9194
+ const claimedHtu = normalizeHtu(payload.htu, true);
9195
+ const expectedHtu = normalizeHtu(htu);
9196
+ const jti = typeof payload.jti === "string" ? payload.jti : undefined;
9197
+ 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) {
9163
9198
  return;
9164
9199
  }
9165
- const jti = typeof payload.jti === "string" ? payload.jti : undefined;
9166
- if (jti !== undefined && isUsedJti !== undefined && await isUsedJti(jti)) {
9200
+ const jkt = await jwkThumbprint(publicJwk);
9201
+ if (isUsedJti !== undefined && await isUsedJti(jti)) {
9167
9202
  return;
9168
9203
  }
9169
- return { jkt: await jwkThumbprint(header.jwk), jti };
9204
+ if (consumeJti !== undefined && !await consumeJti({ expiresAt: iatMs + maxAgeMs, jkt, jti }))
9205
+ return;
9206
+ return { jkt, jti };
9170
9207
  };
9171
9208
 
9172
9209
  // src/oidc/logout.ts
@@ -9905,7 +9942,7 @@ var oidcProviderRoutes = (config) => {
9905
9942
  "dpop-nonce": fresh,
9906
9943
  "www-authenticate": 'DPoP error="use_dpop_nonce"'
9907
9944
  },
9908
- status: HTTP_UNAUTHORIZED4
9945
+ status: HTTP_BAD_REQUEST3
9909
9946
  });
9910
9947
  };
9911
9948
  const grantAuthorizationCode = async (client, body, dpop, clientCertThumbprint) => {
@@ -37602,6 +37639,7 @@ var readAudience = (audience) => {
37602
37639
  };
37603
37640
  var createOidcAgentCredentialVerifier = ({
37604
37641
  issuer,
37642
+ consumeDpopJti,
37605
37643
  isUsedDpopJti,
37606
37644
  maxDpopAgeMs,
37607
37645
  publicJwk,
@@ -37630,6 +37668,7 @@ var createOidcAgentCredentialVerifier = ({
37630
37668
  return;
37631
37669
  const proof = await verifyDpopProof({
37632
37670
  accessToken: token,
37671
+ consumeJti: consumeDpopJti,
37633
37672
  htm: request.method,
37634
37673
  htu: request.url,
37635
37674
  isUsedJti: isUsedDpopJti,
@@ -41619,5 +41658,5 @@ export {
41619
41658
  VerificationProviderError
41620
41659
  };
41621
41660
 
41622
- //# debugId=471E09DA92BB95D564756E2164756E21
41661
+ //# debugId=77EFAA9D607737B964756E2164756E21
41623
41662
  //# sourceMappingURL=server.js.map