@deslop/auth 0.1.1250 → 0.1.1254

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
@@ -90536,7 +90536,7 @@ base64.validate = (encoded, urlMode) => {
90536
90536
  }
90537
90537
  };
90538
90538
  base64.base64 = base64;
90539
- // ../../node_modules/.pnpm/@simplewebauthn+server@14.0.3/node_modules/@simplewebauthn/server/esm/helpers/iso/isoBase64URL.js
90539
+ // ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/helpers/iso/isoBase64URL.js
90540
90540
  /**
90541
90541
  * A runtime-agnostic collection of methods for working with Base64URL encoding
90542
90542
  * @module
@@ -90946,7 +90946,7 @@ function encodeCBOR(data) {
90946
90946
  }
90947
90947
  return output;
90948
90948
  }
90949
- // ../../node_modules/.pnpm/@simplewebauthn+server@14.0.3/node_modules/@simplewebauthn/server/esm/helpers/iso/isoCBOR.js
90949
+ // ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/helpers/iso/isoCBOR.js
90950
90950
  /**
90951
90951
  * A runtime-agnostic collection of methods for working with CBOR encoding
90952
90952
  * @module
@@ -90978,7 +90978,7 @@ function decodeFirst(input) {
90978
90978
  function encode(input) {
90979
90979
  return encodeCBOR(input);
90980
90980
  }
90981
- // ../../node_modules/.pnpm/@simplewebauthn+server@14.0.3/node_modules/@simplewebauthn/server/esm/helpers/cose.js
90981
+ // ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/helpers/cose.js
90982
90982
  /**
90983
90983
  * A type guard for determining if a COSE public key is an OKP key pair
90984
90984
  */
@@ -91088,7 +91088,7 @@ function isPQCCOSEAlg(alg) {
91088
91088
  COSEALG.ML_DSA_87
91089
91089
  ].indexOf(alg) >= 0;
91090
91090
  }
91091
- // ../../node_modules/.pnpm/@simplewebauthn+server@14.0.3/node_modules/@simplewebauthn/server/esm/helpers/iso/isoCrypto/mapCoseAlgToWebCryptoHashAlgName.js
91091
+ // ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/helpers/iso/isoCrypto/mapCoseAlgToWebCryptoHashAlgName.js
91092
91092
  /**
91093
91093
  * Convert a COSE alg ID into a corresponding hash algorithm string value that WebCrypto APIs expect
91094
91094
  *
@@ -91115,7 +91115,7 @@ function mapCoseAlgToWebCryptoHashAlgName(alg) {
91115
91115
  ].indexOf(alg) >= 0) return "SHA-512";
91116
91116
  throw new Error(`Could not map COSE alg value of ${alg} to a WebCrypto hash alg name`);
91117
91117
  }
91118
- // ../../node_modules/.pnpm/@simplewebauthn+server@14.0.3/node_modules/@simplewebauthn/server/esm/helpers/iso/isoCrypto/getWebCrypto.js
91118
+ // ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/helpers/iso/isoCrypto/getWebCrypto.js
91119
91119
  let webCrypto = void 0;
91120
91120
  /**
91121
91121
  * Try to get an instance of the Crypto API from the current runtime. Should support Node,
@@ -91160,7 +91160,7 @@ const _getWebCryptoInternals = {
91160
91160
  webCrypto = newCrypto;
91161
91161
  }
91162
91162
  };
91163
- // ../../node_modules/.pnpm/@simplewebauthn+server@14.0.3/node_modules/@simplewebauthn/server/esm/helpers/iso/isoCrypto/digest.js
91163
+ // ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/helpers/iso/isoCrypto/digest.js
91164
91164
  /**
91165
91165
  * Generate a digest of the provided data.
91166
91166
  *
@@ -91173,7 +91173,7 @@ async function digest(data, algorithm) {
91173
91173
  const hashed = await WebCrypto.subtle.digest(subtleAlgorithm, data);
91174
91174
  return new Uint8Array(hashed);
91175
91175
  }
91176
- // ../../node_modules/.pnpm/@simplewebauthn+server@14.0.3/node_modules/@simplewebauthn/server/esm/helpers/iso/isoCrypto/getRandomValues.js
91176
+ // ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/helpers/iso/isoCrypto/getRandomValues.js
91177
91177
  /**
91178
91178
  * Fill up the provided bytes array with random bytes equal to its length.
91179
91179
  *
@@ -91183,7 +91183,7 @@ async function getRandomValues(array) {
91183
91183
  (await getWebCrypto()).getRandomValues(array);
91184
91184
  return array;
91185
91185
  }
91186
- // ../../node_modules/.pnpm/@simplewebauthn+server@14.0.3/node_modules/@simplewebauthn/server/esm/helpers/convertAAGUIDToString.js
91186
+ // ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/helpers/convertAAGUIDToString.js
91187
91187
  /**
91188
91188
  * Convert the aaguid buffer in authData into a UUID string
91189
91189
  */
@@ -91197,7 +91197,7 @@ function convertAAGUIDToString(aaguid) {
91197
91197
  hex.slice(20, 32)
91198
91198
  ].join("-");
91199
91199
  }
91200
- // ../../node_modules/.pnpm/@simplewebauthn+server@14.0.3/node_modules/@simplewebauthn/server/esm/helpers/convertCOSEtoPKCS.js
91200
+ // ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/helpers/convertCOSEtoPKCS.js
91201
91201
  /**
91202
91202
  * Takes COSE-encoded public key and converts it to PKCS key
91203
91203
  */
@@ -91214,7 +91214,7 @@ function convertCOSEtoPKCS(cosePublicKey) {
91214
91214
  ]);
91215
91215
  return concat([tag, x]);
91216
91216
  }
91217
- // ../../node_modules/.pnpm/@simplewebauthn+server@14.0.3/node_modules/@simplewebauthn/server/esm/helpers/decodeAttestationObject.js
91217
+ // ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/helpers/decodeAttestationObject.js
91218
91218
  /**
91219
91219
  * Convert an AttestationObject buffer to a proper object
91220
91220
  *
@@ -91228,7 +91228,7 @@ function decodeAttestationObject(attestationObject) {
91228
91228
  * @ignore Don't include this in docs output
91229
91229
  */
91230
91230
  const _decodeAttestationObjectInternals = { stubThis: (value) => value };
91231
- // ../../node_modules/.pnpm/@simplewebauthn+server@14.0.3/node_modules/@simplewebauthn/server/esm/helpers/decodeClientDataJSON.js
91231
+ // ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/helpers/decodeClientDataJSON.js
91232
91232
  /**
91233
91233
  * Decode an authenticator's base64url-encoded clientDataJSON to JSON
91234
91234
  */
@@ -91242,7 +91242,7 @@ function decodeClientDataJSON(data) {
91242
91242
  * @ignore Don't include this in docs output
91243
91243
  */
91244
91244
  const _decodeClientDataJSONInternals = { stubThis: (value) => value };
91245
- // ../../node_modules/.pnpm/@simplewebauthn+server@14.0.3/node_modules/@simplewebauthn/server/esm/helpers/decodeCredentialPublicKey.js
91245
+ // ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/helpers/decodeCredentialPublicKey.js
91246
91246
  function decodeCredentialPublicKey(publicKey) {
91247
91247
  return _decodeCredentialPublicKeyInternals.stubThis(decodeFirst(publicKey));
91248
91248
  }
@@ -91251,7 +91251,7 @@ function decodeCredentialPublicKey(publicKey) {
91251
91251
  * @ignore Don't include this in docs output
91252
91252
  */
91253
91253
  const _decodeCredentialPublicKeyInternals = { stubThis: (value) => value };
91254
- // ../../node_modules/.pnpm/@simplewebauthn+server@14.0.3/node_modules/@simplewebauthn/server/esm/helpers/generateChallenge.js
91254
+ // ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/helpers/generateChallenge.js
91255
91255
  /**
91256
91256
  * Generate a suitably random value to be used as an attestation or assertion challenge
91257
91257
  */
@@ -91273,7 +91273,7 @@ async function generateChallenge() {
91273
91273
  * @ignore Don't include this in docs output
91274
91274
  */
91275
91275
  const _generateChallengeInternals = { stubThis: (value) => value };
91276
- // ../../node_modules/.pnpm/@simplewebauthn+server@14.0.3/node_modules/@simplewebauthn/server/esm/helpers/generateUserID.js
91276
+ // ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/helpers/generateUserID.js
91277
91277
  /**
91278
91278
  * Generate a suitably random value to be used as user ID
91279
91279
  */
@@ -99678,7 +99678,7 @@ var require_cjs$12 = /* @__PURE__ */ __commonJSMin(((exports) => {
99678
99678
  tslib_1.__exportStar(require_types$3(), exports);
99679
99679
  tslib_1.__exportStar(require_validity(), exports);
99680
99680
  }));
99681
- // ../../node_modules/.pnpm/@simplewebauthn+server@14.0.3/node_modules/@simplewebauthn/server/esm/helpers/getCertificateInfo.js
99681
+ // ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/helpers/getCertificateInfo.js
99682
99682
  var import_cjs$4 = require_cjs$13();
99683
99683
  var import_cjs$5 = require_cjs$12();
99684
99684
  const issuerSubjectIDKey = {
@@ -107916,15 +107916,15 @@ var import_x509_cjs = require_x509_cjs();
107916
107916
  * A simple method for requesting data via standard `fetch`. Should work
107917
107917
  * across multiple runtimes.
107918
107918
  */
107919
- function fetch(url) {
107920
- return _fetchInternals.stubThis(url);
107919
+ function fetch(...args) {
107920
+ return _fetchInternals.stubThis(...args);
107921
107921
  }
107922
107922
  /**
107923
107923
  * Make it possible to stub the return value during testing
107924
107924
  * @ignore Don't include this in docs output
107925
107925
  */
107926
- const _fetchInternals = { stubThis: (url) => globalThis.fetch(url) };
107927
- // ../../node_modules/.pnpm/@simplewebauthn+server@14.0.3/node_modules/@simplewebauthn/server/esm/helpers/isCertRevoked.js
107926
+ const _fetchInternals = { stubThis: (...args) => globalThis.fetch(...args) };
107927
+ // ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/helpers/isCertRevoked.js
107928
107928
  const cacheRevokedCerts = {};
107929
107929
  /**
107930
107930
  * A method to pull a CRL from a certificate and compare its serial number to the list of revoked
@@ -107992,7 +107992,7 @@ async function getIssuerKeyIdentifier(issuer) {
107992
107992
  fromExtension: false
107993
107993
  };
107994
107994
  }
107995
- // ../../node_modules/.pnpm/@simplewebauthn+server@14.0.3/node_modules/@simplewebauthn/server/esm/helpers/decodeAuthenticatorExtensions.js
107995
+ // ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/helpers/decodeAuthenticatorExtensions.js
107996
107996
  /**
107997
107997
  * Convert authenticator extension data buffer to a proper object
107998
107998
  *
@@ -108018,7 +108018,7 @@ function convertMapToObjectDeep(input) {
108018
108018
  else mapped[key] = value;
108019
108019
  return mapped;
108020
108020
  }
108021
- // ../../node_modules/.pnpm/@simplewebauthn+server@14.0.3/node_modules/@simplewebauthn/server/esm/helpers/parseAuthenticatorData.js
108021
+ // ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/helpers/parseAuthenticatorData.js
108022
108022
  /**
108023
108023
  * Make sense of the authData buffer contained in an Attestation
108024
108024
  */
@@ -108108,16 +108108,16 @@ function parseAuthenticatorData(authData) {
108108
108108
  * @ignore Don't include this in docs output
108109
108109
  */
108110
108110
  const _parseAuthenticatorDataInternals = { stubThis: (value) => value };
108111
- // ../../node_modules/.pnpm/@simplewebauthn+server@14.0.3/node_modules/@simplewebauthn/server/esm/helpers/toHash.js
108111
+ // ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/helpers/toHash.js
108112
108112
  /**
108113
- * Returns hash digest of the given data, using the given algorithm when provided. Defaults to using
108114
- * SHA-256.
108113
+ * Returns the hash of the given data, using the given algorithm when provided. If `data` is
108114
+ * a string, then it's treated like a UTF-8 string. Defaults to hashing using SHA-256.
108115
108115
  */
108116
108116
  function toHash(data, algorithm = -7) {
108117
108117
  if (typeof data === "string") data = fromUTF8String(data);
108118
108118
  return digest(data, algorithm);
108119
108119
  }
108120
- // ../../node_modules/.pnpm/@simplewebauthn+server@14.0.3/node_modules/@simplewebauthn/server/esm/helpers/iso/isoCrypto/mapCoseAlgToWebCryptoKeyAlgName.js
108120
+ // ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/helpers/iso/isoCrypto/mapCoseAlgToWebCryptoKeyAlgName.js
108121
108121
  /**
108122
108122
  * Convert a COSE alg ID into a corresponding key algorithm string value that WebCrypto APIs expect
108123
108123
  *
@@ -108148,7 +108148,7 @@ function mapCoseAlgToWebCryptoKeyAlgName(alg) {
108148
108148
  else if ([COSEALG.ML_DSA_87].indexOf(alg) >= 0) return "ML-DSA-87";
108149
108149
  throw new Error(`Could not map COSE alg value of ${alg} to a WebCrypto key alg name`);
108150
108150
  }
108151
- // ../../node_modules/.pnpm/@simplewebauthn+server@14.0.3/node_modules/@simplewebauthn/server/esm/errors/index.js
108151
+ // ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/errors/index.js
108152
108152
  /**
108153
108153
  * Base error class that helps disambiguate SimpleWebAuthn library errors from other library errors
108154
108154
  */
@@ -108174,7 +108174,7 @@ var PQCNotSupportedError = class extends SimpleWebAuthnError {
108174
108174
  });
108175
108175
  }
108176
108176
  };
108177
- // ../../node_modules/.pnpm/@simplewebauthn+server@14.0.3/node_modules/@simplewebauthn/server/esm/helpers/validateCertificatePath.js
108177
+ // ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/helpers/validateCertificatePath.js
108178
108178
  /**
108179
108179
  * Traverse an array of PEM certificates and ensure they form a proper chain
108180
108180
  * @param x5cCertsPEM Typically the result of `x5c.map(convertASN1toPEM)`
@@ -108294,7 +108294,7 @@ function assertCertIsWithinValidTimeWindow(certificate) {
108294
108294
  const now = new Date(Date.now());
108295
108295
  if (certNotBefore > now || certNotAfter < now) throw new Error("Certificate is not yet valid or expired");
108296
108296
  }
108297
- // ../../node_modules/.pnpm/@simplewebauthn+server@14.0.3/node_modules/@simplewebauthn/server/esm/helpers/mapX509SignatureAlgToCOSEAlg.js
108297
+ // ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/helpers/mapX509SignatureAlgToCOSEAlg.js
108298
108298
  var import_cjs$1 = require_cjs$9();
108299
108299
  var import_cjs$2 = require_cjs$8();
108300
108300
  var import_cjs$3 = require_cjs$2();
@@ -108316,7 +108316,7 @@ function mapX509SignatureAlgToCOSEAlg(signatureAlgorithm) {
108316
108316
  else throw new Error(`Unable to map X.509 signature algorithm ${signatureAlgorithm} to a COSE algorithm`);
108317
108317
  return alg;
108318
108318
  }
108319
- // ../../node_modules/.pnpm/@simplewebauthn+server@14.0.3/node_modules/@simplewebauthn/server/esm/helpers/convertX509PublicKeyToCOSE.js
108319
+ // ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/helpers/convertX509PublicKeyToCOSE.js
108320
108320
  function convertX509PublicKeyToCOSE(x509Certificate) {
108321
108321
  let cosePublicKey = /* @__PURE__ */ new Map();
108322
108322
  const { tbsCertificate } = import_cjs$4.AsnParser.parse(x509Certificate, import_cjs$5.Certificate);
@@ -108384,7 +108384,7 @@ function convertX509PublicKeyToCOSE(x509Certificate) {
108384
108384
  } else throw new Error(`Certificate public key contained unexpected algorithm ID ${publicKeyAlgorithmID}`);
108385
108385
  return cosePublicKey;
108386
108386
  }
108387
- // ../../node_modules/.pnpm/@simplewebauthn+server@14.0.3/node_modules/@simplewebauthn/server/esm/helpers/verifySignature.js
108387
+ // ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/helpers/verifySignature.js
108388
108388
  /**
108389
108389
  * Verify an authenticator's signature
108390
108390
  */
@@ -108407,7 +108407,7 @@ function verifySignature(opts) {
108407
108407
  * @ignore Don't include this in docs output
108408
108408
  */
108409
108409
  const _verifySignatureInternals = { stubThis: (value) => value };
108410
- // ../../node_modules/.pnpm/@simplewebauthn+server@14.0.3/node_modules/@simplewebauthn/server/esm/metadata/parseJWT.js
108410
+ // ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/metadata/parseJWT.js
108411
108411
  /**
108412
108412
  * Process a JWT into Javascript-friendly data structures
108413
108413
  */
@@ -108419,7 +108419,7 @@ function parseJWT(jwt) {
108419
108419
  parts[2]
108420
108420
  ];
108421
108421
  }
108422
- // ../../node_modules/.pnpm/@simplewebauthn+server@14.0.3/node_modules/@simplewebauthn/server/esm/helpers/mapJWSAlgToCOSEAlg.js
108422
+ // ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/helpers/mapJWSAlgToCOSEAlg.js
108423
108423
  /**
108424
108424
  * Map JWS algorithms to COSE algorithm IDs
108425
108425
  *
@@ -108436,7 +108436,7 @@ function mapJWSAlgToCOSEAlg(alg) {
108436
108436
  else throw new Error(`Unable to map JWS algorithm "${alg}" to a COSE algorithm`);
108437
108437
  return algCOSE;
108438
108438
  }
108439
- // ../../node_modules/.pnpm/@simplewebauthn+server@14.0.3/node_modules/@simplewebauthn/server/esm/helpers/iso/isoCrypto/importJWKKey.js
108439
+ // ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/helpers/iso/isoCrypto/importJWKKey.js
108440
108440
  /**
108441
108441
  * Convert a JWK-formatted public key into a WebCrypto CryptoKey that can be used for
108442
108442
  * signature verification
@@ -108446,7 +108446,7 @@ async function importJWKKey(opts) {
108446
108446
  const { keyData, algorithm } = opts;
108447
108447
  return WebCrypto.subtle.importKey("jwk", keyData, algorithm, false, ["verify"]);
108448
108448
  }
108449
- // ../../node_modules/.pnpm/@simplewebauthn+server@14.0.3/node_modules/@simplewebauthn/server/esm/helpers/iso/isoCrypto/verifyEC2.js
108449
+ // ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/helpers/iso/isoCrypto/verifyEC2.js
108450
108450
  /**
108451
108451
  * Verify a signature using an EC2 public key
108452
108452
  */
@@ -108493,7 +108493,7 @@ async function verifyEC2(opts) {
108493
108493
  };
108494
108494
  return WebCrypto.subtle.verify(verifyAlgorithm, key, signature, data);
108495
108495
  }
108496
- // ../../node_modules/.pnpm/@simplewebauthn+server@14.0.3/node_modules/@simplewebauthn/server/esm/helpers/iso/isoCrypto/verifyRSA.js
108496
+ // ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/helpers/iso/isoCrypto/verifyRSA.js
108497
108497
  /**
108498
108498
  * Verify a signature using an RSA public key
108499
108499
  */
@@ -108553,7 +108553,7 @@ async function verifyRSA(opts) {
108553
108553
  });
108554
108554
  return WebCrypto.subtle.verify(verifyAlgorithm, key, signature, data);
108555
108555
  }
108556
- // ../../node_modules/.pnpm/@simplewebauthn+server@14.0.3/node_modules/@simplewebauthn/server/esm/metadata/verifyJWT.js
108556
+ // ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/metadata/verifyJWT.js
108557
108557
  /**
108558
108558
  * Lightweight verification for FIDO MDS JWTs. Supports use of EC2 and RSA.
108559
108559
  *
@@ -108584,14 +108584,14 @@ function verifyJWT(jwt, leafCert) {
108584
108584
  const kty = certCOSE.get(COSEKEYS.kty);
108585
108585
  throw new Error(`JWT verification with public key of kty ${kty} is not supported by this method`);
108586
108586
  }
108587
- // ../../node_modules/.pnpm/@simplewebauthn+server@14.0.3/node_modules/@simplewebauthn/server/esm/helpers/convertPEMToBytes.js
108587
+ // ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/helpers/convertPEMToBytes.js
108588
108588
  /**
108589
108589
  * Take a certificate in PEM format and convert it to bytes
108590
108590
  */
108591
108591
  function convertPEMToBytes(pem) {
108592
108592
  return toBuffer(pem.replace("-----BEGIN CERTIFICATE-----", "").replace("-----END CERTIFICATE-----", "").replace(/[\n ]/g, ""), "base64");
108593
108593
  }
108594
- // ../../node_modules/.pnpm/@simplewebauthn+server@14.0.3/node_modules/@simplewebauthn/server/esm/metadata/verifyMDSBlob.js
108594
+ // ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/metadata/verifyMDSBlob.js
108595
108595
  /**
108596
108596
  * Perform authenticity and integrity verification of a
108597
108597
  * [FIDO Metadata Service (MDS)](https://fidoalliance.org/metadata/)-compatible blob, and then
@@ -108621,7 +108621,7 @@ async function verifyMDSBlob(blob) {
108621
108621
  payload
108622
108622
  };
108623
108623
  }
108624
- // ../../node_modules/.pnpm/@simplewebauthn+server@14.0.3/node_modules/@simplewebauthn/server/esm/helpers/iso/isoCrypto/verifyAKP.js
108624
+ // ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/helpers/iso/isoCrypto/verifyAKP.js
108625
108625
  /** AKP, a.k.a ML-DSA */
108626
108626
  async function verifyAKP(opts) {
108627
108627
  const { cosePublicKey, signature, data } = opts;
@@ -108654,7 +108654,7 @@ async function verifyAKP(opts) {
108654
108654
  }
108655
108655
  return WebCrypto.subtle.verify(webCryptoAlg, key, signature, data);
108656
108656
  }
108657
- // ../../node_modules/.pnpm/@simplewebauthn+server@14.0.3/node_modules/@simplewebauthn/server/esm/helpers/iso/isoCrypto/verifyOKP.js
108657
+ // ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/helpers/iso/isoCrypto/verifyOKP.js
108658
108658
  async function verifyOKP(opts) {
108659
108659
  const { cosePublicKey, signature, data } = opts;
108660
108660
  const WebCrypto = await getWebCrypto();
@@ -108684,7 +108684,7 @@ async function verifyOKP(opts) {
108684
108684
  const verifyAlgorithm = { name: _crv };
108685
108685
  return WebCrypto.subtle.verify(verifyAlgorithm, key, signature, data);
108686
108686
  }
108687
- // ../../node_modules/.pnpm/@simplewebauthn+server@14.0.3/node_modules/@simplewebauthn/server/esm/helpers/iso/isoCrypto/unwrapEC2Signature.js
108687
+ // ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/helpers/iso/isoCrypto/unwrapEC2Signature.js
108688
108688
  /**
108689
108689
  * In WebAuthn, EC2 signatures are wrapped in ASN.1 structure so we need to peel r and s apart.
108690
108690
  *
@@ -108734,7 +108734,7 @@ function toNormalizedBytes(bytes, componentLength) {
108734
108734
  else throw new Error(`Invalid signature component length ${bytes.length}, expected ${componentLength}`);
108735
108735
  return normalizedBytes;
108736
108736
  }
108737
- // ../../node_modules/.pnpm/@simplewebauthn+server@14.0.3/node_modules/@simplewebauthn/server/esm/helpers/iso/isoCrypto/verify.js
108737
+ // ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/helpers/iso/isoCrypto/verify.js
108738
108738
  /**
108739
108739
  * Verify signatures with their public key. Supports EC2 and RSA public keys.
108740
108740
  */
@@ -108768,7 +108768,7 @@ function verify(opts) {
108768
108768
  const kty = cosePublicKey.get(COSEKEYS.kty);
108769
108769
  throw new Error(`Signature verification with public key of kty ${kty} is not supported by this method`);
108770
108770
  }
108771
- // ../../node_modules/.pnpm/@simplewebauthn+server@14.0.3/node_modules/@simplewebauthn/server/esm/helpers/iso/isoUint8Array.js
108771
+ // ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/helpers/iso/isoUint8Array.js
108772
108772
  /**
108773
108773
  * A runtime-agnostic collection of methods for working with Uint8Arrays
108774
108774
  * @module
@@ -108836,7 +108836,7 @@ function fromASCIIString(value) {
108836
108836
  function toDataView(array) {
108837
108837
  return new DataView(array.buffer, array.byteOffset, array.length);
108838
108838
  }
108839
- // ../../node_modules/.pnpm/@simplewebauthn+server@14.0.3/node_modules/@simplewebauthn/server/esm/helpers/convertCertBufferToPEM.js
108839
+ // ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/helpers/convertCertBufferToPEM.js
108840
108840
  /**
108841
108841
  * Convert buffer to an OpenSSL-compatible PEM text format.
108842
108842
  */
@@ -108858,7 +108858,7 @@ function convertCertBufferToPEM(certBuffer) {
108858
108858
  PEMKey = `-----BEGIN CERTIFICATE-----\n${PEMKey}-----END CERTIFICATE-----\n`;
108859
108859
  return PEMKey;
108860
108860
  }
108861
- // ../../node_modules/.pnpm/@simplewebauthn+server@14.0.3/node_modules/@simplewebauthn/server/esm/helpers/iso/isoCrypto/runtimeSupportsWebCryptoKeyAlg.js
108861
+ // ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/helpers/iso/isoCrypto/runtimeSupportsWebCryptoKeyAlg.js
108862
108862
  /**
108863
108863
  * Use SubtleCrypto.supports() to understand if the runtime supports using the given key algorithm
108864
108864
  * for signature verification.
@@ -108872,7 +108872,7 @@ function runtimeSupportsWebCryptoKeyAlg(alg) {
108872
108872
  return false;
108873
108873
  }
108874
108874
  }
108875
- // ../../node_modules/.pnpm/@simplewebauthn+server@14.0.3/node_modules/@simplewebauthn/server/esm/services/defaultRootCerts/android-safetynet.js
108875
+ // ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/services/defaultRootCerts/android-safetynet.js
108876
108876
  /**
108877
108877
  * GlobalSign Root CA
108878
108878
  *
@@ -108905,50 +108905,7 @@ DKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveCX4XSQRjbgbME
108905
108905
  HMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A==
108906
108906
  -----END CERTIFICATE-----
108907
108907
  `;
108908
- // ../../node_modules/.pnpm/@simplewebauthn+server@14.0.3/node_modules/@simplewebauthn/server/esm/services/defaultRootCerts/android-key.js
108909
- /**
108910
- * Google Hardware Attestation Root 1
108911
- *
108912
- * Downloaded from https://developer.android.com/training/articles/security-key-attestation#root_certificate
108913
- * (first entry)
108914
- *
108915
- * Valid until 2026-05-24 @ 09:28 PST
108916
- *
108917
- * SHA256 Fingerprint
108918
- * C1:98:4A:3E:F4:5C:1E:2A:91:85:51:DE:10:60:3C:86:F7:05:1B:22:49:C4:89:1C:AE:32:30:EA:BD:0C:97:D5
108919
- */
108920
- const Google_Hardware_Attestation_Root_1 = `-----BEGIN CERTIFICATE-----
108921
- MIIFYDCCA0igAwIBAgIJAOj6GWMU0voYMA0GCSqGSIb3DQEBCwUAMBsxGTAXBgNV
108922
- BAUTEGY5MjAwOWU4NTNiNmIwNDUwHhcNMTYwNTI2MTYyODUyWhcNMjYwNTI0MTYy
108923
- ODUyWjAbMRkwFwYDVQQFExBmOTIwMDllODUzYjZiMDQ1MIICIjANBgkqhkiG9w0B
108924
- AQEFAAOCAg8AMIICCgKCAgEAr7bHgiuxpwHsK7Qui8xUFmOr75gvMsd/dTEDDJdS
108925
- Sxtf6An7xyqpRR90PL2abxM1dEqlXnf2tqw1Ne4Xwl5jlRfdnJLmN0pTy/4lj4/7
108926
- tv0Sk3iiKkypnEUtR6WfMgH0QZfKHM1+di+y9TFRtv6y//0rb+T+W8a9nsNL/ggj
108927
- nar86461qO0rOs2cXjp3kOG1FEJ5MVmFmBGtnrKpa73XpXyTqRxB/M0n1n/W9nGq
108928
- C4FSYa04T6N5RIZGBN2z2MT5IKGbFlbC8UrW0DxW7AYImQQcHtGl/m00QLVWutHQ
108929
- oVJYnFPlXTcHYvASLu+RhhsbDmxMgJJ0mcDpvsC4PjvB+TxywElgS70vE0XmLD+O
108930
- JtvsBslHZvPBKCOdT0MS+tgSOIfga+z1Z1g7+DVagf7quvmag8jfPioyKvxnK/Eg
108931
- sTUVi2ghzq8wm27ud/mIM7AY2qEORR8Go3TVB4HzWQgpZrt3i5MIlCaY504LzSRi
108932
- igHCzAPlHws+W0rB5N+er5/2pJKnfBSDiCiFAVtCLOZ7gLiMm0jhO2B6tUXHI/+M
108933
- RPjy02i59lINMRRev56GKtcd9qO/0kUJWdZTdA2XoS82ixPvZtXQpUpuL12ab+9E
108934
- aDK8Z4RHJYYfCT3Q5vNAXaiWQ+8PTWm2QgBR/bkwSWc+NpUFgNPN9PvQi8WEg5Um
108935
- AGMCAwEAAaOBpjCBozAdBgNVHQ4EFgQUNmHhAHyIBQlRi0RsR/8aTMnqTxIwHwYD
108936
- VR0jBBgwFoAUNmHhAHyIBQlRi0RsR/8aTMnqTxIwDwYDVR0TAQH/BAUwAwEB/zAO
108937
- BgNVHQ8BAf8EBAMCAYYwQAYDVR0fBDkwNzA1oDOgMYYvaHR0cHM6Ly9hbmRyb2lk
108938
- Lmdvb2dsZWFwaXMuY29tL2F0dGVzdGF0aW9uL2NybC8wDQYJKoZIhvcNAQELBQAD
108939
- ggIBACDIw41L3KlXG0aMiS//cqrG+EShHUGo8HNsw30W1kJtjn6UBwRM6jnmiwfB
108940
- Pb8VA91chb2vssAtX2zbTvqBJ9+LBPGCdw/E53Rbf86qhxKaiAHOjpvAy5Y3m00m
108941
- qC0w/Zwvju1twb4vhLaJ5NkUJYsUS7rmJKHHBnETLi8GFqiEsqTWpG/6ibYCv7rY
108942
- DBJDcR9W62BW9jfIoBQcxUCUJouMPH25lLNcDc1ssqvC2v7iUgI9LeoM1sNovqPm
108943
- QUiG9rHli1vXxzCyaMTjwftkJLkf6724DFhuKug2jITV0QkXvaJWF4nUaHOTNA4u
108944
- JU9WDvZLI1j83A+/xnAJUucIv/zGJ1AMH2boHqF8CY16LpsYgBt6tKxxWH00XcyD
108945
- CdW2KlBCeqbQPcsFmWyWugxdcekhYsAWyoSf818NUsZdBWBaR/OukXrNLfkQ79Iy
108946
- ZohZbvabO/X+MVT3rriAoKc8oE2Uws6DF+60PV7/WIPjNvXySdqspImSN78mflxD
108947
- qwLqRBYkA3I75qppLGG9rp7UCdRjxMl8ZDBld+7yvHVgt1cVzJx9xnyGCC23Uaic
108948
- MDSXYrB4I4WHXPGjxhZuCuPBLTdOLU8YRvMYdEvYebWHMpvwGCF6bAx3JBpIeOQ1
108949
- wDB5y0USicV3YgYGmi+NZfhA4URSh77Yd6uuJOJENRaNVTzk
108950
- -----END CERTIFICATE-----
108951
- `;
108908
+ // ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/services/defaultRootCerts/android-key.js
108952
108909
  /**
108953
108910
  * Google Hardware Attestation Root 2
108954
108911
  *
@@ -109037,7 +108994,7 @@ mD/vFDkzF+wm7cyWpQpCVQ==
109037
108994
  /**
109038
108995
  * Google Hardware Attestation Root 4
109039
108996
  *
109040
- * Downloaded from https://developer.android.com/training/articles/security-key-attestation#root_certificate
108997
+ * Downloaded from https://developer.android.com/privacy-and-security/security-key-attestation#root_certificate
109041
108998
  * (fourth entry)
109042
108999
  *
109043
109000
  * Valid until 2042-03-15 @ 11:07 PDT
@@ -109077,7 +109034,33 @@ vaI47gC+TNpkgYGkkBT6B/m/U01BuOBBTzhIlMEZq9qkDWuM2cA5kW5V3FJUcfHn
109077
109034
  w1IdYIg2Wxg7yHcQZemFQg==
109078
109035
  -----END CERTIFICATE-----
109079
109036
  `;
109080
- // ../../node_modules/.pnpm/@simplewebauthn+server@14.0.3/node_modules/@simplewebauthn/server/esm/services/defaultRootCerts/apple.js
109037
+ /**
109038
+ * Google Android Key Attestation CA1
109039
+ *
109040
+ * Downloaded from https://developer.android.com/privacy-and-security/security-key-attestation#root_certificate
109041
+ *
109042
+ * Valid until 2035-07-15 @ 15:32 PDT
109043
+ *
109044
+ * SHA256 Fingerprint
109045
+ * 6D:9D:B4:CE:6C:5C:0B:29:31:66:D0:89:86:E0:57:74:A8:77:6C:EB:52:5D:9E:43:29:52:0D:E1:2B:A4:BC:C0
109046
+ */
109047
+ const Google_Android_Key_Attestation_CA1 = `
109048
+ -----BEGIN CERTIFICATE-----
109049
+ MIICIjCCAaigAwIBAgIRAISp0Cl7DrWK5/8OgN52BgUwCgYIKoZIzj0EAwMwUjEc
109050
+ MBoGA1UEAwwTS2V5IEF0dGVzdGF0aW9uIENBMTEQMA4GA1UECwwHQW5kcm9pZDET
109051
+ MBEGA1UECgwKR29vZ2xlIExMQzELMAkGA1UEBhMCVVMwHhcNMjUwNzE3MjIzMjE4
109052
+ WhcNMzUwNzE1MjIzMjE4WjBSMRwwGgYDVQQDDBNLZXkgQXR0ZXN0YXRpb24gQ0Ex
109053
+ MRAwDgYDVQQLDAdBbmRyb2lkMRMwEQYDVQQKDApHb29nbGUgTExDMQswCQYDVQQG
109054
+ EwJVUzB2MBAGByqGSM49AgEGBSuBBAAiA2IABCPaI3FO3z5bBQo8cuiEas4HjqCt
109055
+ G/mLFfRT0MsIssPBEEU5Cfbt6sH5yOAxqEi5QagpU1yX4HwnGb7OtBYpDTB57uH5
109056
+ Eczm34A5FNijV3s0/f0UPl7zbJcTx6xwqMIRq6NCMEAwDwYDVR0TAQH/BAUwAwEB
109057
+ /zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFFIyuyz7RkOb3NaBqQ5lZuA0QepA
109058
+ MAoGCCqGSM49BAMDA2gAMGUCMETfjPO/HwqReR2CS7p0ZWoD/LHs6hDi422opifH
109059
+ EUaYLxwGlT9SLdjkVpz0UUOR5wIxAIoGyxGKRHVTpqpGRFiJtQEOOTp/+s1GcxeY
109060
+ uR2zh/80lQyu9vAFCj6E4AXc+osmRg==
109061
+ -----END CERTIFICATE-----
109062
+ `;
109063
+ // ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/services/defaultRootCerts/apple.js
109081
109064
  /**
109082
109065
  * Apple WebAuthn Root CA
109083
109066
  *
@@ -109103,7 +109086,7 @@ jAGGiQIwHFj+dJZYUJR786osByBelJYsVZd2GbHQu209b5RCmGQ21gpSAk9QZW4B
109103
109086
  1bWeT0vT
109104
109087
  -----END CERTIFICATE-----
109105
109088
  `;
109106
- // ../../node_modules/.pnpm/@simplewebauthn+server@14.0.3/node_modules/@simplewebauthn/server/esm/services/defaultRootCerts/mds.js
109089
+ // ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/services/defaultRootCerts/mds.js
109107
109090
  /**
109108
109091
  * GlobalSign Root CA - R3
109109
109092
  *
@@ -109178,7 +109161,7 @@ N3ec592kD3ZDZopD8p/7DEJ4Y9HiD2971KE9dJeFt0g5QdYg/NA6s/rob8SKunE3
109178
109161
  vouXsXgxT7PntgMTzlSdriVZzH81Xwj3QEUxeCp6
109179
109162
  -----END CERTIFICATE-----
109180
109163
  `;
109181
- // ../../node_modules/.pnpm/@simplewebauthn+server@14.0.3/node_modules/@simplewebauthn/server/esm/services/settingsService.js
109164
+ // ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/services/settingsService.js
109182
109165
  var BaseSettingsService = class {
109183
109166
  constructor() {
109184
109167
  Object.defineProperty(this, "pemCertificates", {
@@ -109229,10 +109212,10 @@ const SettingsService = new BaseSettingsService();
109229
109212
  SettingsService.setRootCertificates({
109230
109213
  identifier: "android-key",
109231
109214
  certificates: [
109232
- Google_Hardware_Attestation_Root_1,
109233
109215
  Google_Hardware_Attestation_Root_2,
109234
109216
  Google_Hardware_Attestation_Root_3,
109235
- Google_Hardware_Attestation_Root_4
109217
+ Google_Hardware_Attestation_Root_4,
109218
+ Google_Android_Key_Attestation_CA1
109236
109219
  ]
109237
109220
  });
109238
109221
  SettingsService.setRootCertificates({
@@ -109247,7 +109230,7 @@ SettingsService.setRootCertificates({
109247
109230
  identifier: "mds",
109248
109231
  certificates: [GlobalSign_Root_CA_R3, GlobalSign_Root_R46]
109249
109232
  });
109250
- // ../../node_modules/.pnpm/@simplewebauthn+server@14.0.3/node_modules/@simplewebauthn/server/esm/registration/generateRegistrationOptions.js
109233
+ // ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/registration/generateRegistrationOptions.js
109251
109234
  /**
109252
109235
  * Set up some default authenticator selection options as per the latest spec:
109253
109236
  * https://www.w3.org/TR/webauthn-2/#dictdef-authenticatorselectioncriteria
@@ -109389,7 +109372,7 @@ async function generateRegistrationOptions(options) {
109389
109372
  hints
109390
109373
  };
109391
109374
  }
109392
- // ../../node_modules/.pnpm/@simplewebauthn+server@14.0.3/node_modules/@simplewebauthn/server/esm/helpers/parseBackupFlags.js
109375
+ // ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/helpers/parseBackupFlags.js
109393
109376
  /**
109394
109377
  * Make sense of Bits 3 and 4 in authenticator indicating:
109395
109378
  *
@@ -109414,7 +109397,21 @@ var InvalidBackupFlags = class extends Error {
109414
109397
  this.name = "InvalidBackupFlags";
109415
109398
  }
109416
109399
  };
109417
- // ../../node_modules/.pnpm/@simplewebauthn+server@14.0.3/node_modules/@simplewebauthn/server/esm/helpers/matchExpectedRPID.js
109400
+ // ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/helpers/assertValidExpectedRPID.js
109401
+ /**
109402
+ * Check the RP ID to make sure it's valid to compare against what's reported in a WebAuthn
109403
+ * response.
109404
+ *
109405
+ * Invalid RP IDs will raise a `SimpleWebAuthnError` with `code: 'BAD_ARGUMENT'`
109406
+ */
109407
+ function assertValidExpectedRPID(rpID) {
109408
+ const asciiRPID = new URL(`https://${rpID}`).hostname;
109409
+ if (asciiRPID !== rpID) throw new SimpleWebAuthnError({
109410
+ message: `"${rpID}" is not a valid expected RP ID. Replace it with its ASCII punycode representation "${asciiRPID}" and try again`,
109411
+ code: "BAD_ARGUMENT"
109412
+ });
109413
+ }
109414
+ // ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/helpers/matchExpectedRPID.js
109418
109415
  /**
109419
109416
  * Go through each expected RP ID and try to find one that matches. Returns the unhashed RP ID
109420
109417
  * that matched the hash in the response.
@@ -109422,6 +109419,7 @@ var InvalidBackupFlags = class extends Error {
109422
109419
  * Raises an `UnexpectedRPIDHash` error if no match is found
109423
109420
  */
109424
109421
  async function matchExpectedRPID(rpIDHash, expectedRPIDs) {
109422
+ for (const rpID of expectedRPIDs) assertValidExpectedRPID(rpID);
109425
109423
  try {
109426
109424
  return await Promise.any(expectedRPIDs.map((expected) => {
109427
109425
  return new Promise((resolve, reject) => {
@@ -109432,72 +109430,188 @@ async function matchExpectedRPID(rpIDHash, expectedRPIDs) {
109432
109430
  });
109433
109431
  }));
109434
109432
  } catch (err) {
109435
- if (err.name === "AggregateError") throw new UnexpectedRPIDHash();
109433
+ if (err.name === "AggregateError") throw new SimpleWebAuthnError({
109434
+ message: "Unexpected RP ID hash",
109435
+ code: "UNEXPECTED_RP_ID"
109436
+ });
109436
109437
  throw err;
109437
109438
  }
109438
109439
  }
109439
- var UnexpectedRPIDHash = class extends Error {
109440
- constructor() {
109441
- super("Unexpected RP ID hash");
109442
- this.name = "UnexpectedRPIDHash";
109440
+ // ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/services/helpers/serviceStateTracker.js
109441
+ var SERVICE_STATE;
109442
+ (function(SERVICE_STATE) {
109443
+ SERVICE_STATE["DISABLED"] = "DISABLED";
109444
+ SERVICE_STATE["REFRESHING"] = "REFRESHING";
109445
+ SERVICE_STATE["READY"] = "READY";
109446
+ })(SERVICE_STATE || (SERVICE_STATE = {}));
109447
+ var ServiceStateTracker = class {
109448
+ constructor(name, logger) {
109449
+ Object.defineProperty(this, "name", {
109450
+ enumerable: true,
109451
+ configurable: true,
109452
+ writable: true,
109453
+ value: name
109454
+ });
109455
+ Object.defineProperty(this, "logger", {
109456
+ enumerable: true,
109457
+ configurable: true,
109458
+ writable: true,
109459
+ value: logger
109460
+ });
109461
+ Object.defineProperty(this, "state", {
109462
+ enumerable: true,
109463
+ configurable: true,
109464
+ writable: true,
109465
+ value: SERVICE_STATE.DISABLED
109466
+ });
109467
+ }
109468
+ /**
109469
+ * Get the current state
109470
+ */
109471
+ get current() {
109472
+ return this.state;
109473
+ }
109474
+ /**
109475
+ * Set a new state and report it
109476
+ */
109477
+ set(next) {
109478
+ if (this.state === next) return;
109479
+ this.state = next;
109480
+ this.logger.debug(`${this.name} is ${SERVICE_STATE[this.state]}`);
109481
+ }
109482
+ /**
109483
+ * A helper method to pause execution until the service is ready
109484
+ */
109485
+ pauseUntilReady() {
109486
+ if (this.state === SERVICE_STATE.READY) return Promise.resolve();
109487
+ return new Promise((resolve, reject) => {
109488
+ const totalTimeoutMS = 7e4;
109489
+ const intervalMS = 100;
109490
+ let iterations = totalTimeoutMS / intervalMS;
109491
+ const intervalID = globalThis.setInterval(() => {
109492
+ if (iterations < 1) {
109493
+ clearInterval(intervalID);
109494
+ reject(`State did not become ready in ${totalTimeoutMS / 1e3} seconds`);
109495
+ } else if (this.state === SERVICE_STATE.READY) {
109496
+ clearInterval(intervalID);
109497
+ resolve();
109498
+ }
109499
+ iterations -= 1;
109500
+ }, intervalMS);
109501
+ });
109443
109502
  }
109444
109503
  };
109445
- // ../../node_modules/.pnpm/@simplewebauthn+server@14.0.3/node_modules/@simplewebauthn/server/esm/registration/verifications/verifyAttestationFIDOU2F.js
109446
109504
  /**
109447
- * Verify an attestation response with fmt 'fido-u2f'
109505
+ * An MDS-aware metadata cache that tracks MDS servers and the data downloaded from them. This
109506
+ * includes tracking when an MDS server needs to be refreshed, but does not actually perform the
109507
+ * refresh.
109448
109508
  */
109449
- async function verifyAttestationFIDOU2F(options) {
109450
- const { attStmt, clientDataHash, rpIdHash, credentialID, credentialPublicKey, aaguid, rootCertificates } = options;
109451
- const signatureBase = concat([
109452
- Uint8Array.from([0]),
109453
- rpIdHash,
109454
- clientDataHash,
109455
- credentialID,
109456
- convertCOSEtoPKCS(credentialPublicKey)
109457
- ]);
109458
- const sig = attStmt.get("sig");
109459
- const x5c = attStmt.get("x5c");
109460
- if (!x5c) throw new Error("No attestation certificate provided in attestation statement (FIDOU2F)");
109461
- if (!sig) throw new Error("No attestation signature provided in attestation statement (FIDOU2F)");
109462
- const aaguidToHex = Number.parseInt(toHex(aaguid), 16);
109463
- if (aaguidToHex !== 0) throw new Error(`AAGUID "${aaguidToHex}" was not expected value`);
109464
- try {
109465
- await validateCertificatePath(x5c.map(convertCertBufferToPEM), rootCertificates);
109466
- } catch (err) {
109467
- throw new Error(`${err.message} (FIDOU2F)`);
109509
+ var MDSCache = class {
109510
+ constructor() {
109511
+ Object.defineProperty(this, "serverCache", {
109512
+ enumerable: true,
109513
+ configurable: true,
109514
+ writable: true,
109515
+ value: /* @__PURE__ */ new Map()
109516
+ });
109517
+ Object.defineProperty(this, "metadataCache", {
109518
+ enumerable: true,
109519
+ configurable: true,
109520
+ writable: true,
109521
+ value: /* @__PURE__ */ new Map()
109522
+ });
109468
109523
  }
109469
- return verifySignature({
109470
- signature: sig,
109471
- data: signatureBase,
109472
- x509Certificate: x5c[0],
109473
- hashAlgorithm: COSEALG.ES256
109474
- });
109475
- }
109476
- // ../../node_modules/.pnpm/@simplewebauthn+server@14.0.3/node_modules/@simplewebauthn/server/esm/helpers/validateExtFIDOGenCEAAGUID.js
109477
- /**
109478
- * Attestation Certificate Extension OID: `id-fido-gen-ce-aaguid`
109479
- *
109480
- * Sourced from https://fidoalliance.org/specs/fido-v2.0-ps-20150904/fido-key-attestation-v2.0-ps-20150904.html#verifying-an-attestation-statement
109481
- */
109482
- const id_fido_gen_ce_aaguid = "1.3.6.1.4.1.45724.1.1.4";
109483
- /**
109484
- * Look for the id-fido-gen-ce-aaguid certificate extension. If it's present then check it against
109485
- * the attestation statement AAGUID.
109486
- */
109487
- function validateExtFIDOGenCEAAGUID(certExtensions, aaguid) {
109488
- if (!certExtensions) return true;
109489
- const extFIDOGenCEAAGUID = certExtensions.find((ext) => ext.extnID === id_fido_gen_ce_aaguid);
109490
- if (!extFIDOGenCEAAGUID) return true;
109491
- const parsedExtFIDOGenCEAAGUID = import_cjs$4.AsnParser.parse(extFIDOGenCEAAGUID.extnValue, import_cjs$4.OctetString);
109492
- const extValue = new Uint8Array(parsedExtFIDOGenCEAAGUID.buffer);
109493
- if (!areEqual(aaguid, extValue)) {
109494
- const _debugExtHex = toHex(extValue);
109495
- const _debugAAGUIDHex = toHex(aaguid);
109496
- throw new Error(`Certificate extension id-fido-gen-ce-aaguid (${id_fido_gen_ce_aaguid}) value of "${_debugExtHex}" was present but not equal to attestation statement AAGUID value of "${_debugAAGUIDHex}"`);
109524
+ /**
109525
+ * Set up a Metadata Service API for periodic refreshes
109526
+ */
109527
+ registerMDSServer(url, no, nextUpdate) {
109528
+ this.serverCache.set(url, {
109529
+ url,
109530
+ no,
109531
+ nextUpdate
109532
+ });
109497
109533
  }
109498
- return true;
109499
- }
109500
- // ../../node_modules/.pnpm/@simplewebauthn+server@14.0.3/node_modules/@simplewebauthn/server/esm/helpers/logging.js
109534
+ /**
109535
+ * Add the provided metadata to the cache, keyed by its corresponding AAGUID
109536
+ */
109537
+ cacheMetadata(aaguid, metadata, url) {
109538
+ this.metadataCache.set(this.normalizeAAGUID(aaguid), {
109539
+ data: metadata,
109540
+ url
109541
+ });
109542
+ }
109543
+ /**
109544
+ * Retrieve cached metadata by AAGUID
109545
+ */
109546
+ getMetadata(aaguid) {
109547
+ if (!aaguid) return;
109548
+ if (aaguid instanceof Uint8Array) aaguid = convertAAGUIDToString(aaguid);
109549
+ return this.metadataCache.get(this.normalizeAAGUID(aaguid))?.data;
109550
+ }
109551
+ /**
109552
+ * Return how many metadata entries have been cached
109553
+ */
109554
+ get count() {
109555
+ return this.metadataCache.size;
109556
+ }
109557
+ /**
109558
+ * Clear out caches
109559
+ */
109560
+ reset() {
109561
+ this.serverCache = /* @__PURE__ */ new Map();
109562
+ this.metadataCache = /* @__PURE__ */ new Map();
109563
+ }
109564
+ /**
109565
+ * Remove cached Metadata Service data for a specific API server. If the URL indicates data that
109566
+ * should not be refreshed, then simply exit.
109567
+ */
109568
+ clearMetadataByURL(url) {
109569
+ if (url === "") return;
109570
+ for (const [aaguid, cached] of this.metadataCache.entries()) if (cached.url === url) this.metadataCache.delete(this.normalizeAAGUID(aaguid));
109571
+ }
109572
+ /**
109573
+ * Whether an MDS server has been registered for periodic refreshes
109574
+ */
109575
+ mdsServerIsRegistered(url) {
109576
+ return this.serverCache.has(url);
109577
+ }
109578
+ /**
109579
+ * Set the MDS server's nextUpdate
109580
+ */
109581
+ setMDSServerNextUpdate(url, newNextUpdate) {
109582
+ const server = this.serverCache.get(url);
109583
+ if (!server) throw new SimpleWebAuthnError({
109584
+ message: `No MDS server has been registered for "${url}". Register it with registerMDSServer() first`,
109585
+ code: "BAD_ARGUMENT"
109586
+ });
109587
+ server.nextUpdate = newNextUpdate;
109588
+ this.serverCache.set(url, server);
109589
+ }
109590
+ /**
109591
+ * Retrieve the version number of the MDS server's latest known data
109592
+ */
109593
+ getMDSServerDataVersion(url) {
109594
+ const server = this.serverCache.get(url);
109595
+ if (!server) throw new SimpleWebAuthnError({
109596
+ message: `No MDS server has been registered for "${url}". Register it with registerMDSServer() first`,
109597
+ code: "BAD_ARGUMENT"
109598
+ });
109599
+ return server.no;
109600
+ }
109601
+ /**
109602
+ * Return a list of MDS server URLs with nextUpdates earlier than the provided date
109603
+ */
109604
+ getStaleMDSServerURLs(date) {
109605
+ return this.serverCache.values().filter((mds) => mds.url !== "" && date > mds.nextUpdate).map((mds) => mds.url).toArray();
109606
+ }
109607
+ /**
109608
+ * Ensure that AAGUIDs are all lowercase before using them as cache keys
109609
+ */
109610
+ normalizeAAGUID(aaguid) {
109611
+ return aaguid.toLowerCase();
109612
+ }
109613
+ };
109614
+ // ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/helpers/logging.js
109501
109615
  /**
109502
109616
  * A logger instance that doesn't do anything. Useful as a default argument when no custom instance
109503
109617
  * of the `SimpleWebAuthnLogger` interface is specified.
@@ -109520,66 +109634,231 @@ function buildLoggerAllMethods(logger) {
109520
109634
  if (logger.error) toReturn.error = logger.error;
109521
109635
  return toReturn;
109522
109636
  }
109523
- // ../../node_modules/.pnpm/@simplewebauthn+server@14.0.3/node_modules/@simplewebauthn/server/esm/services/metadataService.js
109637
+ // ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/services/helpers/getInitCacheMessage.js
109524
109638
  /**
109525
- * An instance of `CachedMDS` that will not trigger attempts to refresh the associated entry's blob
109526
- */
109527
- const NonRefreshingMDS = {
109528
- url: "",
109529
- no: 0,
109530
- nextUpdate: /* @__PURE__ */ new Date(0)
109531
- };
109532
- const defaultURLMDS = "https://mds.fidoalliance.org/";
109533
- var SERVICE_STATE;
109534
- (function(SERVICE_STATE) {
109535
- SERVICE_STATE[SERVICE_STATE["DISABLED"] = 0] = "DISABLED";
109536
- SERVICE_STATE[SERVICE_STATE["REFRESHING"] = 1] = "REFRESHING";
109537
- SERVICE_STATE[SERVICE_STATE["READY"] = 2] = "READY";
109538
- })(SERVICE_STATE || (SERVICE_STATE = {}));
109539
- /**
109540
- * An implementation of `MetadataService` that can download and parse BLOBs, and support on-demand
109541
- * requesting and caching of individual metadata statements.
109639
+ * Generate a message detailing how many metadata entries were cached, and from which sources
109542
109640
  *
109543
- * https://fidoalliance.org/metadata/
109641
+ * Examples:
109642
+ *
109643
+ * - "ConvenienceMetadataService cached 322 unique metadata entries from 1 local payload(s) and 1 convenience metadata server(s)"
109644
+ * - "ConvenienceMetadataService cached 322 unique metadata entries from 1 local payload(s)"
109645
+ * - "MetadataService cached 285 unique metadata entries from 1 convenience metadata server(s)"
109646
+ * - "MetadataService cached 0 unique metadata entries"
109647
+ */
109648
+ function getInitCacheMessage(serviceName, cacheCount, numLocalFiles, numServers) {
109649
+ let message = `${serviceName} cached ${cacheCount} unique entries`;
109650
+ if (cacheCount) {
109651
+ const formatter = new Intl.ListFormat("en", {
109652
+ style: "long",
109653
+ type: "conjunction"
109654
+ });
109655
+ const sources = [];
109656
+ if (numLocalFiles) sources.push(`${numLocalFiles} local file(s)`);
109657
+ if (numServers) sources.push(`${numServers} metadata server(s)`);
109658
+ message = `${message} from ${formatter.format(sources)}`;
109659
+ }
109660
+ return message;
109661
+ }
109662
+ // ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/services/helpers/baseMDSService.js
109663
+ /**
109664
+ * Functionality shared by services that download, cache, and refresh metadata from FIDO
109665
+ * Alliance-style metadata servers (MDS and Convenience MDS.) Subclasses are responsible for
109666
+ * parsing and caching what a server returns.
109544
109667
  */
109545
- var BaseMetadataService = class {
109546
- constructor() {
109547
- Object.defineProperty(this, "mdsCache", {
109668
+ var BaseMDSService = class {
109669
+ /**
109670
+ * @param serviceName Used in logs, e.g. `"MetadataService"`
109671
+ */
109672
+ constructor(serviceName) {
109673
+ Object.defineProperty(this, "serviceName", {
109548
109674
  enumerable: true,
109549
109675
  configurable: true,
109550
109676
  writable: true,
109551
- value: {}
109677
+ value: serviceName
109552
109678
  });
109553
- Object.defineProperty(this, "statementCache", {
109679
+ Object.defineProperty(this, "metadataCache", {
109554
109680
  enumerable: true,
109555
109681
  configurable: true,
109556
109682
  writable: true,
109557
- value: {}
109683
+ value: new MDSCache()
109558
109684
  });
109559
109685
  Object.defineProperty(this, "state", {
109560
109686
  enumerable: true,
109561
109687
  configurable: true,
109562
109688
  writable: true,
109563
- value: SERVICE_STATE.DISABLED
109689
+ value: void 0
109564
109690
  });
109565
- Object.defineProperty(this, "verificationMode", {
109691
+ Object.defineProperty(this, "logger", {
109566
109692
  enumerable: true,
109567
109693
  configurable: true,
109568
109694
  writable: true,
109569
- value: "strict"
109695
+ value: DefaultNoopLogger
109570
109696
  });
109571
- Object.defineProperty(this, "logger", {
109697
+ /** How many hours to wait to check a server again when it has nothing new to download */
109698
+ Object.defineProperty(this, "defaultRefreshDelayHours", {
109572
109699
  enumerable: true,
109573
109700
  configurable: true,
109574
109701
  writable: true,
109575
- value: DefaultNoopLogger
109702
+ value: 24
109703
+ });
109704
+ /** How many hours to wait to retry a _failed_ attempt to refresh a server */
109705
+ Object.defineProperty(this, "defaultRetryDelayHours", {
109706
+ enumerable: true,
109707
+ configurable: true,
109708
+ writable: true,
109709
+ value: 3
109710
+ });
109711
+ /** Abort downloads that take longer than this many milliseconds. No limit if left `undefined` */
109712
+ Object.defineProperty(this, "downloadTimeoutMS", {
109713
+ enumerable: true,
109714
+ configurable: true,
109715
+ writable: true,
109716
+ value: 1e4
109717
+ });
109718
+ /**
109719
+ * Refresh a single server, subscribing to the refresh already in flight if there is one.
109720
+ * Failures are passed to `handleRefreshFailure()`.
109721
+ */
109722
+ Object.defineProperty(this, "serverRefreshes", {
109723
+ enumerable: true,
109724
+ configurable: true,
109725
+ writable: true,
109726
+ value: {}
109576
109727
  });
109728
+ this.state = new ServiceStateTracker(serviceName, this.logger);
109577
109729
  }
109578
- async initialize(opts = {}) {
109579
- this.statementCache = {};
109580
- const { mdsServers = [defaultURLMDS], statements, verificationMode, logger = DefaultNoopLogger } = opts;
109730
+ /**
109731
+ * Reset the service and move it to the `REFRESHING` state. Call this at the start of
109732
+ * `initialize()`.
109733
+ */
109734
+ beginInitialize(logger = DefaultNoopLogger) {
109735
+ this.metadataCache.reset();
109736
+ this.serverRefreshes = {};
109581
109737
  this.logger = buildLoggerAllMethods(logger);
109582
- this.setState(SERVICE_STATE.REFRESHING);
109738
+ this.state = new ServiceStateTracker(this.serviceName, this.logger);
109739
+ this.state.set(SERVICE_STATE.REFRESHING);
109740
+ }
109741
+ /**
109742
+ * Download and cache from each server. A server is only registered for refreshes once data from
109743
+ * it has been cached. One that can't be reached, or that doesn't respond with data, is skipped
109744
+ * so it can't cause lookups of other metadata to fail.
109745
+ *
109746
+ * Returns the number of servers entries were cached from.
109747
+ */
109748
+ async initializeServers(mdsServers) {
109749
+ let numServers = 0;
109750
+ for (const url of mdsServers ?? []) try {
109751
+ const entriesAdded = await this.downloadAndCache(url, 0);
109752
+ if (entriesAdded !== void 0) {
109753
+ numServers += 1;
109754
+ this.logger.debug(`Cached ${entriesAdded} metadata entries from "${url}"`);
109755
+ }
109756
+ } catch (err) {
109757
+ this.logger.error(`Could not download data from "${url}":`, err);
109758
+ }
109759
+ return numServers;
109760
+ }
109761
+ /**
109762
+ * Log how much was cached and report the service as ready. Call this at the end of
109763
+ * `initialize()`.
109764
+ */
109765
+ finishInitialize(numLocalFiles, numServers) {
109766
+ const cacheMessage = getInitCacheMessage(this.serviceName, this.metadataCache.count, numLocalFiles, numServers);
109767
+ this.logger.info(cacheMessage);
109768
+ this.state.set(SERVICE_STATE.READY);
109769
+ }
109770
+ /**
109771
+ * Request data from a server, with a query param that can short-circuit the download if the
109772
+ * latest version is already cached. `no` is the serial number of the last data cached from this
109773
+ * server.
109774
+ *
109775
+ * Returns `undefined` if the server responded with anything other than data, in which case the
109776
+ * next refresh will have been delayed.
109777
+ *
109778
+ * See https://fidoalliance.org/specs/mds/fido-metadata-service-v3.1-ps-20250521.html#sctn-mds-blob-proc-rules
109779
+ */
109780
+ async fetchFromServer(url, no) {
109781
+ const _url = new URL(url);
109782
+ _url.searchParams.set("localCopySerial", String(no));
109783
+ const resp = await fetch(_url.toString(), { signal: AbortSignal.timeout(this.downloadTimeoutMS) });
109784
+ if (resp.status === 304) {
109785
+ await resp.body?.cancel();
109786
+ this.logger.info(`The MDS server at "${_url.toString()}" reported nothing new to download (HTTP 304)`);
109787
+ this.delayNextRefresh(url, this.defaultRefreshDelayHours);
109788
+ return;
109789
+ }
109790
+ if (resp.status === 429) {
109791
+ await resp.body?.cancel();
109792
+ this.logger.warn(`The MDS server at "${_url.toString()}" rate-limited this request (HTTP 429)`);
109793
+ this.delayNextRefresh(url, this.defaultRetryDelayHours);
109794
+ return;
109795
+ }
109796
+ if (!resp.ok) {
109797
+ await resp.body?.cancel();
109798
+ this.logger.warn(`The MDS server at "${_url.toString()}" reported an unsuccessful request (HTTP ${resp.status})`);
109799
+ this.delayNextRefresh(url, this.defaultRetryDelayHours);
109800
+ return;
109801
+ }
109802
+ return resp;
109803
+ }
109804
+ /**
109805
+ * Refresh every server whose `nextUpdate` has passed
109806
+ */
109807
+ async refreshStaleServers() {
109808
+ const now = /* @__PURE__ */ new Date();
109809
+ const staleURLs = this.metadataCache.getStaleMDSServerURLs(now);
109810
+ await Promise.all(staleURLs.map((url) => this.refreshServer(url)));
109811
+ }
109812
+ refreshServer(url) {
109813
+ const inFlight = this.serverRefreshes[url];
109814
+ if (inFlight) return inFlight;
109815
+ this.state.set(SERVICE_STATE.REFRESHING);
109816
+ const refresh = (async () => {
109817
+ try {
109818
+ const mdsNo = this.metadataCache.getMDSServerDataVersion(url);
109819
+ await this.downloadAndCache(url, mdsNo);
109820
+ } catch (err) {
109821
+ this.logger.error(`Could not download data from "${url}":`, err);
109822
+ this.handleRefreshFailure(url, err);
109823
+ } finally {
109824
+ delete this.serverRefreshes[url];
109825
+ if (Object.keys(this.serverRefreshes).length === 0) this.state.set(SERVICE_STATE.READY);
109826
+ }
109827
+ })();
109828
+ this.serverRefreshes[url] = refresh;
109829
+ return refresh;
109830
+ }
109831
+ /**
109832
+ * Delay the next refresh attempt of this server by the specified number of hours
109833
+ */
109834
+ delayNextRefresh(url, numHours) {
109835
+ if (!this.metadataCache.mdsServerIsRegistered(url)) return;
109836
+ this.logger.debug(`Delaying next refresh of "${url}" by ${numHours} hours`);
109837
+ const numHoursMS = 36e5 * numHours;
109838
+ this.metadataCache.setMDSServerNextUpdate(url, new Date(Date.now() + numHoursMS));
109839
+ }
109840
+ };
109841
+ // ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/services/metadataService.js
109842
+ const defaultURLMDS = "https://mds.fidoalliance.org/";
109843
+ /**
109844
+ * An implementation of `MetadataService` that can download and parse BLOBs, and support on-demand
109845
+ * requesting and caching of individual metadata statements.
109846
+ *
109847
+ * https://fidoalliance.org/metadata/
109848
+ */
109849
+ var BaseMetadataService = class extends BaseMDSService {
109850
+ constructor() {
109851
+ super("MetadataService");
109852
+ Object.defineProperty(this, "verificationMode", {
109853
+ enumerable: true,
109854
+ configurable: true,
109855
+ writable: true,
109856
+ value: "strict"
109857
+ });
109858
+ }
109859
+ async initialize(opts = {}) {
109860
+ const { mdsServers = [defaultURLMDS], statements, verificationMode, logger } = opts;
109861
+ this.beginInitialize(logger);
109583
109862
  /**
109584
109863
  * If metadata statements are provided, load them into the cache first. These statements will
109585
109864
  * not be refreshed when a stale one is detected.
@@ -109587,139 +109866,240 @@ var BaseMetadataService = class {
109587
109866
  if (statements?.length) {
109588
109867
  let statementsAdded = 0;
109589
109868
  statements.forEach((statement) => {
109590
- if (statement.aaguid) {
109591
- this.statementCache[statement.aaguid] = {
109592
- entry: {
109593
- metadataStatement: statement,
109594
- statusReports: [],
109595
- timeOfLastStatusChange: "1970-01-01"
109596
- },
109597
- url: NonRefreshingMDS.url
109598
- };
109599
- statementsAdded += 1;
109600
- }
109869
+ statementsAdded += this.cacheMetadataBlobEntry("", {
109870
+ aaguid: statement.aaguid,
109871
+ metadataStatement: statement,
109872
+ statusReports: [],
109873
+ timeOfLastStatusChange: "1970-01-01"
109874
+ });
109601
109875
  });
109602
- this.logger.info(`Cached ${statementsAdded} local statements`);
109876
+ this.logger.info(`Cached ${statementsAdded} total local metadata statements`);
109603
109877
  }
109604
109878
  /**
109605
109879
  * If MDS servers are provided, then download blobs from them, verify them, and then add their
109606
109880
  * entries to the cache. Blobs loaded in this way will be refreshed when a stale entry within is
109607
109881
  * detected.
109608
109882
  */
109609
- if (mdsServers?.length) {
109610
- const currentCacheCount = Object.keys(this.statementCache).length;
109611
- let numServers = mdsServers.length;
109612
- for (const url of mdsServers) try {
109613
- const cachedMDS = {
109614
- url,
109615
- no: 0,
109616
- nextUpdate: /* @__PURE__ */ new Date(0)
109617
- };
109618
- const blob = await this.downloadBlob(cachedMDS);
109619
- await this.verifyBlob(blob, cachedMDS);
109620
- } catch (err) {
109621
- this.logger.error(`Could not download BLOB from ${url}:`, err);
109622
- numServers -= 1;
109623
- }
109624
- const cacheDiff = Object.keys(this.statementCache).length - currentCacheCount;
109625
- this.logger.info(`Cached ${cacheDiff} statements from ${numServers} metadata server(s)`);
109626
- }
109627
- if (verificationMode) this.verificationMode = verificationMode;
109628
- this.setState(SERVICE_STATE.READY);
109883
+ const numServers = await this.initializeServers(mdsServers);
109884
+ this.verificationMode = verificationMode ?? "strict";
109885
+ this.finishInitialize(statements?.length, numServers);
109629
109886
  }
109630
109887
  async getStatement(aaguid) {
109631
- if (this.state === SERVICE_STATE.DISABLED) return;
109888
+ if (this.state.current === SERVICE_STATE.DISABLED) return;
109632
109889
  if (!aaguid) return;
109633
109890
  if (aaguid instanceof Uint8Array) aaguid = convertAAGUIDToString(aaguid);
109634
- await this.pauseUntilReady();
109635
- const cachedStatement = this.statementCache[aaguid];
109636
- if (!cachedStatement) {
109891
+ await this.state.pauseUntilReady();
109892
+ await this.refreshStaleServers();
109893
+ const entry = this.metadataCache.getMetadata(aaguid);
109894
+ if (!entry) {
109637
109895
  if (this.verificationMode === "strict") throw new Error(`No metadata statement found for aaguid "${aaguid}"`);
109638
109896
  return;
109639
109897
  }
109640
- if (cachedStatement.url) {
109641
- const mds = this.mdsCache[cachedStatement.url];
109642
- if (/* @__PURE__ */ new Date() > mds.nextUpdate) try {
109643
- this.setState(SERVICE_STATE.REFRESHING);
109644
- const blob = await this.downloadBlob(mds);
109645
- await this.verifyBlob(blob, mds);
109646
- } finally {
109647
- this.setState(SERVICE_STATE.READY);
109648
- }
109649
- }
109650
- const { entry } = cachedStatement;
109651
109898
  for (const report of entry.statusReports) {
109652
109899
  const { status } = report;
109653
109900
  if (status === "USER_VERIFICATION_BYPASS" || status === "ATTESTATION_KEY_COMPROMISE" || status === "USER_KEY_REMOTE_COMPROMISE" || status === "USER_KEY_PHYSICAL_COMPROMISE") throw new Error(`Detected compromised aaguid "${aaguid}"`);
109654
109901
  }
109655
109902
  return entry.metadataStatement;
109656
109903
  }
109904
+ async getProviderMetadata(aaguid) {
109905
+ /**
109906
+ * This is a load-bearing check: without it the `this.verificationMode === 'strict'` check in
109907
+ * `getStatement()` will raise an error on this method when there's no need to do so because
109908
+ * this method's returning `undefined` does not impact the security posture of the RP.
109909
+ */
109910
+ if (!aaguid) return;
109911
+ const metadataStatement = await this.getStatement(aaguid);
109912
+ if (!metadataStatement) return;
109913
+ return {
109914
+ friendlyNames: metadataStatement.friendlyNames,
109915
+ icon: metadataStatement.icon,
109916
+ iconDark: metadataStatement.iconDark,
109917
+ providerLogoDark: metadataStatement.providerLogoDark,
109918
+ providerLogoLight: metadataStatement.providerLogoLight
109919
+ };
109920
+ }
109921
+ /**
109922
+ * Download the latest BLOB from MDS, verify it, and cache its entries
109923
+ */
109924
+ async downloadAndCache(url, no) {
109925
+ const resp = await this.fetchFromServer(url, no);
109926
+ if (!resp) return;
109927
+ const blob = await resp.text();
109928
+ return this.verifyBlob(blob, url, no);
109929
+ }
109657
109930
  /**
109658
- * Download and process the latest BLOB from MDS
109931
+ * Refresh failures are rethrown so that lookups fail closed: until the refresh succeeds the
109932
+ * server stays stale, every lookup tries again, and none of them are answered with statements
109933
+ * from the BLOB that was previously cached.
109659
109934
  */
109660
- async downloadBlob(cachedMDS) {
109661
- const { url } = cachedMDS;
109662
- return await (await fetch(url)).text();
109935
+ handleRefreshFailure(_url, err) {
109936
+ throw err;
109663
109937
  }
109664
109938
  /**
109665
- * Verify and process the MDS metadata blob
109939
+ * Verify and process the MDS metadata blob. Caches metadata and sets up refreshing when blobs
109940
+ * grow stale. `no` is the serial number of the last BLOB cached from this server.
109941
+ *
109942
+ * Returns the number of FIDO2 metadata statements that were cached.
109666
109943
  */
109667
- async verifyBlob(blob, cachedMDS) {
109668
- const { url, no } = cachedMDS;
109944
+ async verifyBlob(blob, url, no) {
109669
109945
  const { payload, parsedNextUpdate } = await verifyMDSBlob(blob);
109670
109946
  if (payload.no <= no) throw new Error(`Latest BLOB no. ${payload.no} is not greater than previous no. ${no}`);
109671
- for (const entry of payload.entries) if (entry.aaguid) this.statementCache[entry.aaguid] = {
109672
- entry,
109673
- url
109674
- };
109675
- if (url) this.mdsCache[url] = {
109676
- ...cachedMDS,
109677
- no: payload.no,
109678
- nextUpdate: parsedNextUpdate
109679
- };
109947
+ this.metadataCache.clearMetadataByURL(url);
109948
+ let totalEntries = 0;
109949
+ for (const entry of payload.entries) totalEntries += this.cacheMetadataBlobEntry(url, entry);
109950
+ if (url !== "") this.metadataCache.registerMDSServer(url, payload.no, parsedNextUpdate);
109680
109951
  else if (parsedNextUpdate < /* @__PURE__ */ new Date()) this.logger.warn(`⚠️ This MDS blob (serial: ${payload.no}) contains stale data as of ${parsedNextUpdate.toISOString()}. Please consider re-initializing MetadataService with a newer MDS blob.`);
109952
+ return totalEntries;
109681
109953
  }
109682
109954
  /**
109683
- * A helper method to pause execution until the service is ready
109955
+ * A central place to contain logic and side effects of caching a BLOB entry. Only caches FIDO2
109956
+ * statements (i.e. ones with `aaguid` as UAF authenticators won't have one.) Returns `1` if the
109957
+ * statement was cached, or `0` if it wasn't (so you can `count += cacheMetadataBlobEntry(...)`)
109684
109958
  */
109685
- pauseUntilReady() {
109686
- if (this.state === SERVICE_STATE.READY) return new Promise((resolve) => {
109687
- resolve();
109688
- });
109689
- return new Promise((resolve, reject) => {
109690
- const totalTimeoutMS = 7e4;
109691
- const intervalMS = 100;
109692
- let iterations = totalTimeoutMS / intervalMS;
109693
- const intervalID = globalThis.setInterval(() => {
109694
- if (iterations < 1) {
109695
- clearInterval(intervalID);
109696
- reject(`State did not become ready in ${totalTimeoutMS / 1e3} seconds`);
109697
- } else if (this.state === SERVICE_STATE.READY) {
109698
- clearInterval(intervalID);
109699
- resolve();
109700
- }
109701
- iterations -= 1;
109702
- }, intervalMS);
109959
+ cacheMetadataBlobEntry(url, entry) {
109960
+ if (!entry.aaguid) return 0;
109961
+ this.metadataCache.cacheMetadata(entry.aaguid, entry, url);
109962
+ return 1;
109963
+ }
109964
+ };
109965
+ /**
109966
+ * A basic service for coordinating interactions with the FIDO Metadata Service. This includes BLOB
109967
+ * download and parsing, and on-demand requesting and caching of individual metadata statements.
109968
+ *
109969
+ * https://fidoalliance.org/metadata/
109970
+ */
109971
+ const MetadataService = new BaseMetadataService();
109972
+ // ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/services/convenienceMetadataService.js
109973
+ const defaultURLConvenienceMDS = "https://c-mds.fidoalliance.org/";
109974
+ var BaseConvenienceMetadataService = class extends BaseMDSService {
109975
+ constructor() {
109976
+ super("ConvenienceMetadataService");
109977
+ }
109978
+ async initialize(opts = {}) {
109979
+ const { mdsServers = [defaultURLConvenienceMDS], payloads, logger } = opts;
109980
+ this.beginInitialize(logger);
109981
+ /**
109982
+ * If passkey provider metadata is provided, load them into the cache first.
109983
+ */
109984
+ if (payloads?.length) {
109985
+ let entriesAdded = 0;
109986
+ payloads.forEach((payload) => {
109987
+ entriesAdded += this.cacheConvenienceMDS("", payload);
109988
+ });
109989
+ this.logger.debug(`Cached ${entriesAdded} total local metadata entries`);
109990
+ }
109991
+ /**
109992
+ * If Convenience MDS server URLs are provided, then download and cache the current collection
109993
+ * of metadata from them.
109994
+ */
109995
+ const numServers = await this.initializeServers(mdsServers);
109996
+ this.finishInitialize(payloads?.length, numServers);
109997
+ }
109998
+ /**
109999
+ * Download the convenience metadata, which is surprisingly just a JSON document, and cache it
110000
+ */
110001
+ async downloadAndCache(url, no) {
110002
+ const resp = await this.fetchFromServer(url, no);
110003
+ if (!resp) return;
110004
+ const payload = await resp.json();
110005
+ return this.cacheConvenienceMDS(url, payload);
110006
+ }
110007
+ /**
110008
+ * Refresh failures cause that server's refresh to be re-attempted at a later date
110009
+ */
110010
+ handleRefreshFailure(url) {
110011
+ this.delayNextRefresh(url, this.defaultRetryDelayHours);
110012
+ }
110013
+ /**
110014
+ * Cache the AAGUID-keyed entries in a Convenience MDS payload. Returns the number of entries
110015
+ * cached (so you can `count += cacheConvenienceMDS(...)`)
110016
+ */
110017
+ cacheConvenienceMDS(url, payload) {
110018
+ let entriesAdded = 0;
110019
+ this.metadataCache.clearMetadataByURL(url);
110020
+ Object.keys(payload).forEach((aaguid) => {
110021
+ if (aaguid === "no") return;
110022
+ this.metadataCache.cacheMetadata(aaguid, payload[aaguid], url);
110023
+ entriesAdded += 1;
109703
110024
  });
110025
+ this.metadataCache.registerMDSServer(url, payload.no, new Date(Date.now() + 36e5 * this.defaultRefreshDelayHours));
110026
+ return entriesAdded;
109704
110027
  }
109705
110028
  /**
109706
- * Report service status on change
110029
+ * Get a collection of metadata about a credential manager, including localized name(s) and
110030
+ * light and dark iconography when available. Returns `undefined` if no such metadata has been
110031
+ * registered with a Convenience MDS.
109707
110032
  */
109708
- setState(newState) {
109709
- this.state = newState;
109710
- if (newState === SERVICE_STATE.DISABLED) this.logger.debug("MetadataService is DISABLED");
109711
- else if (newState === SERVICE_STATE.REFRESHING) this.logger.debug("MetadataService is REFRESHING");
109712
- else if (newState === SERVICE_STATE.READY) this.logger.debug("MetadataService is READY");
110033
+ async getProviderMetadata(aaguid) {
110034
+ if (this.state.current === SERVICE_STATE.DISABLED) return;
110035
+ await this.state.pauseUntilReady();
110036
+ await this.refreshStaleServers();
110037
+ return this.metadataCache.getMetadata(aaguid);
109713
110038
  }
109714
110039
  };
109715
110040
  /**
109716
- * A basic service for coordinating interactions with the FIDO Metadata Service. This includes BLOB
109717
- * download and parsing, and on-demand requesting and caching of individual metadata statements.
110041
+ * A basic service for coordinating interactions with the FIDO Convenience Metadata Service. This
110042
+ * includes metadata download and parsing, and on-demand requesting and caching of provider details.
109718
110043
  *
109719
110044
  * https://fidoalliance.org/metadata/
109720
110045
  */
109721
- const MetadataService = new BaseMetadataService();
109722
- // ../../node_modules/.pnpm/@simplewebauthn+server@14.0.3/node_modules/@simplewebauthn/server/esm/metadata/verifyAttestationWithMetadata.js
110046
+ const ConvenienceMetadataService = new BaseConvenienceMetadataService();
110047
+ // ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/registration/verifications/verifyAttestationFIDOU2F.js
110048
+ /**
110049
+ * Verify an attestation response with fmt 'fido-u2f'
110050
+ */
110051
+ async function verifyAttestationFIDOU2F(options) {
110052
+ const { attStmt, clientDataHash, rpIdHash, credentialID, credentialPublicKey, aaguid, rootCertificates } = options;
110053
+ const signatureBase = concat([
110054
+ Uint8Array.from([0]),
110055
+ rpIdHash,
110056
+ clientDataHash,
110057
+ credentialID,
110058
+ convertCOSEtoPKCS(credentialPublicKey)
110059
+ ]);
110060
+ const sig = attStmt.get("sig");
110061
+ const x5c = attStmt.get("x5c");
110062
+ if (!x5c) throw new Error("No attestation certificate provided in attestation statement (FIDOU2F)");
110063
+ if (!sig) throw new Error("No attestation signature provided in attestation statement (FIDOU2F)");
110064
+ const aaguidToHex = Number.parseInt(toHex(aaguid), 16);
110065
+ if (aaguidToHex !== 0) throw new Error(`AAGUID "${aaguidToHex}" was not expected value`);
110066
+ try {
110067
+ await validateCertificatePath(x5c.map(convertCertBufferToPEM), rootCertificates);
110068
+ } catch (err) {
110069
+ throw new Error(`${err.message} (FIDOU2F)`);
110070
+ }
110071
+ return verifySignature({
110072
+ signature: sig,
110073
+ data: signatureBase,
110074
+ x509Certificate: x5c[0],
110075
+ hashAlgorithm: COSEALG.ES256
110076
+ });
110077
+ }
110078
+ // ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/helpers/validateExtFIDOGenCEAAGUID.js
110079
+ /**
110080
+ * Attestation Certificate Extension OID: `id-fido-gen-ce-aaguid`
110081
+ *
110082
+ * Sourced from https://fidoalliance.org/specs/fido-v2.0-ps-20150904/fido-key-attestation-v2.0-ps-20150904.html#verifying-an-attestation-statement
110083
+ */
110084
+ const id_fido_gen_ce_aaguid = "1.3.6.1.4.1.45724.1.1.4";
110085
+ /**
110086
+ * Look for the id-fido-gen-ce-aaguid certificate extension. If it's present then check it against
110087
+ * the attestation statement AAGUID.
110088
+ */
110089
+ function validateExtFIDOGenCEAAGUID(certExtensions, aaguid) {
110090
+ if (!certExtensions) return true;
110091
+ const extFIDOGenCEAAGUID = certExtensions.find((ext) => ext.extnID === id_fido_gen_ce_aaguid);
110092
+ if (!extFIDOGenCEAAGUID) return true;
110093
+ const parsedExtFIDOGenCEAAGUID = import_cjs$4.AsnParser.parse(extFIDOGenCEAAGUID.extnValue, import_cjs$4.OctetString);
110094
+ const extValue = new Uint8Array(parsedExtFIDOGenCEAAGUID.buffer);
110095
+ if (!areEqual(aaguid, extValue)) {
110096
+ const _debugExtHex = toHex(extValue);
110097
+ const _debugAAGUIDHex = toHex(aaguid);
110098
+ throw new Error(`Certificate extension id-fido-gen-ce-aaguid (${id_fido_gen_ce_aaguid}) value of "${_debugExtHex}" was present but not equal to attestation statement AAGUID value of "${_debugAAGUIDHex}"`);
110099
+ }
110100
+ return true;
110101
+ }
110102
+ // ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/metadata/verifyAttestationWithMetadata.js
109723
110103
  /**
109724
110104
  * Match properties of the authenticator's attestation statement against expected values as
109725
110105
  * registered with the FIDO Alliance Metadata Service
@@ -109880,7 +110260,7 @@ function stringifyCOSEInfo(info) {
109880
110260
  else toReturn = `{ kty: ${kty}, alg: ${alg} }`;
109881
110261
  return toReturn;
109882
110262
  }
109883
- // ../../node_modules/.pnpm/@simplewebauthn+server@14.0.3/node_modules/@simplewebauthn/server/esm/registration/verifications/verifyAttestationPacked.js
110263
+ // ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/registration/verifications/verifyAttestationPacked.js
109884
110264
  /**
109885
110265
  * Verify an attestation response with fmt 'packed'
109886
110266
  */
@@ -109945,7 +110325,7 @@ async function verifyAttestationPacked(options) {
109945
110325
  });
109946
110326
  return verified;
109947
110327
  }
109948
- // ../../node_modules/.pnpm/@simplewebauthn+server@14.0.3/node_modules/@simplewebauthn/server/esm/registration/verifications/verifyAttestationAndroidSafetyNet.js
110328
+ // ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/registration/verifications/verifyAttestationAndroidSafetyNet.js
109949
110329
  /**
109950
110330
  * Verify an attestation response with fmt 'android-safetynet'
109951
110331
  */
@@ -110014,7 +110394,7 @@ async function verifyAttestationAndroidSafetyNet(options) {
110014
110394
  hashAlgorithm: alg
110015
110395
  });
110016
110396
  }
110017
- // ../../node_modules/.pnpm/@simplewebauthn+server@14.0.3/node_modules/@simplewebauthn/server/esm/registration/verifications/tpm/constants.js
110397
+ // ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/registration/verifications/tpm/constants.js
110018
110398
  /**
110019
110399
  * A whole lotta domain knowledge is captured here, with hazy connections to source
110020
110400
  * documents. Good places to start searching for more info on these values are the
@@ -110233,13 +110613,13 @@ const TPM_MANUFACTURERS = {
110233
110613
  * Match TPM public area curve ID's to `crv` numbers used in COSE public keys
110234
110614
  */
110235
110615
  const TPM_ECC_CURVE_COSE_CRV_MAP = {
110236
- TPM_ECC_NIST_P256: 1,
110237
- TPM_ECC_NIST_P384: 2,
110238
- TPM_ECC_NIST_P521: 3,
110239
- TPM_ECC_BN_P256: 1,
110240
- TPM_ECC_SM2_P256: 1
110616
+ TPM_ECC_NIST_P256: COSECRV.P256,
110617
+ TPM_ECC_NIST_P384: COSECRV.P384,
110618
+ TPM_ECC_NIST_P521: COSECRV.P521,
110619
+ TPM_ECC_BN_P256: COSECRV.P256,
110620
+ TPM_ECC_SM2_P256: COSECRV.P256
110241
110621
  };
110242
- // ../../node_modules/.pnpm/@simplewebauthn+server@14.0.3/node_modules/@simplewebauthn/server/esm/registration/verifications/tpm/parseCertInfo.js
110622
+ // ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/registration/verifications/tpm/parseCertInfo.js
110243
110623
  /**
110244
110624
  * Cut up a TPM attestation's certInfo into intelligible chunks
110245
110625
  */
@@ -110291,7 +110671,7 @@ function parseCertInfo(certInfo) {
110291
110671
  }
110292
110672
  };
110293
110673
  }
110294
- // ../../node_modules/.pnpm/@simplewebauthn+server@14.0.3/node_modules/@simplewebauthn/server/esm/registration/verifications/tpm/parsePubArea.js
110674
+ // ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/registration/verifications/tpm/parsePubArea.js
110295
110675
  /**
110296
110676
  * Break apart a TPM attestation's pubArea buffer
110297
110677
  *
@@ -110352,6 +110732,27 @@ function parsePubArea(pubArea) {
110352
110732
  pointer += 2;
110353
110733
  const scheme = TPM_ALG[dataView.getUint16(pointer)];
110354
110734
  pointer += 2;
110735
+ /**
110736
+ * In TPM 2.0, a non-TPM_ALG_NULL scheme is followed by alg-specific "details" bytes.
110737
+ * For TPM_ALG_ECC this is defined as TPMT_ECC_SCHEME, which is the
110738
+ * scheme (TPMI_ALG_ECC_SCHEME) followed by details (TPMU_ECC_SCHEME).
110739
+ *
110740
+ * See 11.2.5.7 TPMT_ECC_SCHEME here:
110741
+ * https://medias.cdn.trustedcomputinggroup.org/production/Trusted_Platform_Module_2_0_Library_Part_2_Structures_Version_185_pub_c0a962a931.pdf >
110742
+ */
110743
+ const details = {};
110744
+ if (scheme === "TPM_ALG_NULL") {} else if (scheme === "TPM_ALG_ECDSA") {
110745
+ details.hashAlg = TPM_ALG[dataView.getUint16(pointer)];
110746
+ pointer += 2;
110747
+ } else if (scheme === "TPM_ALG_ECSCHNORR") {
110748
+ details.hashAlg = TPM_ALG[dataView.getUint16(pointer)];
110749
+ pointer += 2;
110750
+ } else if (scheme === "TPM_ALG_ECDAA") {
110751
+ details.hashAlg = TPM_ALG[dataView.getUint16(pointer)];
110752
+ pointer += 2;
110753
+ details.count = dataView.getUint16(pointer);
110754
+ pointer += 2;
110755
+ }
110355
110756
  const curveID = TPM_ECC_CURVE[dataView.getUint16(pointer)];
110356
110757
  pointer += 2;
110357
110758
  const kdf = TPM_ALG[dataView.getUint16(pointer)];
@@ -110359,6 +110760,7 @@ function parsePubArea(pubArea) {
110359
110760
  parameters.ecc = {
110360
110761
  symmetric,
110361
110762
  scheme,
110763
+ details,
110362
110764
  curveID,
110363
110765
  kdf
110364
110766
  };
@@ -110382,12 +110784,12 @@ function parsePubArea(pubArea) {
110382
110784
  unique
110383
110785
  };
110384
110786
  }
110385
- // ../../node_modules/.pnpm/@simplewebauthn+server@14.0.3/node_modules/@simplewebauthn/server/esm/registration/verifications/tpm/isValidTPMManufacturerID.js
110787
+ // ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/registration/verifications/tpm/isValidTPMManufacturerID.js
110386
110788
  function getTPMManufacturerInfo(id) {
110387
110789
  const _normalized = `id:${id.substring(3).toUpperCase()}`;
110388
110790
  return TPM_MANUFACTURERS[_normalized];
110389
110791
  }
110390
- // ../../node_modules/.pnpm/@simplewebauthn+server@14.0.3/node_modules/@simplewebauthn/server/esm/registration/verifications/tpm/verifyAttestationTPM.js
110792
+ // ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/registration/verifications/tpm/verifyAttestationTPM.js
110391
110793
  async function verifyAttestationTPM(options) {
110392
110794
  const { aaguid, attStmt, authData, credentialPublicKey, clientDataHash, rootCertificates } = options;
110393
110795
  const ver = attStmt.get("ver");
@@ -110422,17 +110824,19 @@ async function verifyAttestationTPM(options) {
110422
110824
  if (pubAreaExponent !== eSum) throw new Error(`Unexpected public key exp ${eSum}, expected ${pubAreaExponent} (TPM|RSA)`);
110423
110825
  } else if (pubType === "TPM_ALG_ECC") {
110424
110826
  if (!isCOSEPublicKeyEC2(cosePublicKey)) throw new Error(`Credential public key with kty ${cosePublicKey.get(COSEKEYS.kty)} did not match ${pubType}`);
110425
- const crv = cosePublicKey.get(COSEKEYS.crv);
110426
- const x = cosePublicKey.get(COSEKEYS.x);
110427
- const y = cosePublicKey.get(COSEKEYS.y);
110428
- if (!crv) throw new Error("COSE public key missing crv (TPM|ECC)");
110429
- if (!x) throw new Error("COSE public key missing x (TPM|ECC)");
110430
- if (!y) throw new Error("COSE public key missing y (TPM|ECC)");
110431
- if (!areEqual(unique, concat([x, y]))) throw new Error("PubArea unique is not same as public key x and y (TPM|ECC)");
110827
+ const pubKeyAlg = cosePublicKey.get(COSEKEYS.alg);
110828
+ const pubKeyCrv = cosePublicKey.get(COSEKEYS.crv);
110829
+ const pubKeyX = cosePublicKey.get(COSEKEYS.x);
110830
+ const pubKeyY = cosePublicKey.get(COSEKEYS.y);
110831
+ if (!pubKeyAlg) throw new Error("COSE public key missing crv (TPM|ECC)");
110832
+ if (!pubKeyCrv) throw new Error("COSE public key missing crv (TPM|ECC)");
110833
+ if (!pubKeyX) throw new Error("COSE public key missing x (TPM|ECC)");
110834
+ if (!pubKeyY) throw new Error("COSE public key missing y (TPM|ECC)");
110835
+ if (!areEqual(unique, concat([pubKeyX, pubKeyY]))) throw new Error("PubArea unique is not same as public key x and y (TPM|ECC)");
110432
110836
  if (!parameters.ecc) throw new Error(`Parsed pubArea type is ECC, but missing parameters.ecc (TPM|ECC)`);
110433
110837
  const pubAreaCurveID = parameters.ecc.curveID;
110434
110838
  const pubAreaCurveIDMapToCOSECRV = TPM_ECC_CURVE_COSE_CRV_MAP[pubAreaCurveID];
110435
- if (pubAreaCurveIDMapToCOSECRV !== crv) throw new Error(`Public area key curve ID "${pubAreaCurveID}" mapped to "${pubAreaCurveIDMapToCOSECRV}" which did not match public key crv of "${crv}" (TPM|ECC)`);
110839
+ if (pubAreaCurveIDMapToCOSECRV !== pubKeyCrv) throw new Error(`Public area key curve ID "${pubAreaCurveID}" mapped to "${pubAreaCurveIDMapToCOSECRV}" which did not match public key crv of "${pubKeyCrv}" (TPM|ECC)`);
110436
110840
  } else throw new Error(`Unsupported pubArea.type "${pubType}"`);
110437
110841
  const { magic, type: certType, attested, extraData } = parseCertInfo(certInfo);
110438
110842
  if (magic !== 4283712327) throw new Error(`Unexpected magic value "${magic}", expected "0xff544347" (TPM)`);
@@ -111068,7 +111472,7 @@ var require_attestation = /* @__PURE__ */ __commonJSMin(((exports) => {
111068
111472
  repeated: "set"
111069
111473
  })], AttestationApplicationId.prototype, "signatureDigests", void 0);
111070
111474
  }));
111071
- // ../../node_modules/.pnpm/@simplewebauthn+server@14.0.3/node_modules/@simplewebauthn/server/esm/registration/verifications/verifyAttestationAndroidKey.js
111475
+ // ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/registration/verifications/verifyAttestationAndroidKey.js
111072
111476
  var import_cjs = (/* @__PURE__ */ __commonJSMin(((exports) => {
111073
111477
  Object.defineProperty(exports, "__esModule", { value: true });
111074
111478
  const tslib_1 = (init_tslib_es6$1(), __toCommonJS(tslib_es6_exports$1));
@@ -111110,7 +111514,7 @@ async function verifyAttestationAndroidKey(options) {
111110
111514
  * (i.e. These shouldn't contain the [600] tag)
111111
111515
  */
111112
111516
  if (teeEnforced.allApplications !== void 0) throw new Error("teeEnforced contained \"allApplications [600]\" tag (Android Key)");
111113
- if (softwareEnforced.allApplications !== void 0) throw new Error("teeEnforced contained \"allApplications [600]\" tag (Android Key)");
111517
+ if (softwareEnforced.allApplications !== void 0) throw new Error("softwareEnforced contained \"allApplications [600]\" tag (Android Key)");
111114
111518
  const statement = await MetadataService.getStatement(aaguid);
111115
111519
  if (statement) try {
111116
111520
  await verifyAttestationWithMetadata({
@@ -111125,22 +111529,30 @@ async function verifyAttestationAndroidKey(options) {
111125
111529
  }
111126
111530
  else {
111127
111531
  /**
111128
- * Verify that x5c contains a full certificate path.
111532
+ * Fail closed if for some reason no root certificates were registered with SettingsService
111533
+ * for this attestation format. Android Key attestation statements are a bit unique in that they
111534
+ * contain a full certificate chain, which an attacker could abuse to perform arbitrary network
111535
+ * requests within the RP's boundary if we simply validated x5c like other attestation formats.
111129
111536
  */
111537
+ if (rootCertificates.length === 0) throw new Error("No root certificates were set with SettingsService for \"android-key\" attestation (Android Key)");
111130
111538
  const x5cNoRootPEM = x5c.slice(0, -1).map(convertCertBufferToPEM);
111131
111539
  const x5cRootPEM = x5c.slice(-1).map(convertCertBufferToPEM);
111540
+ /**
111541
+ * Make sure the final cert in x5c is one of the Google Hardware Attestation Root certificates
111542
+ * before we attempt to validate the certificate chain.
111543
+ *
111544
+ * https://developer.android.com/privacy-and-security/security-key-attestation#root_certificate
111545
+ */
111546
+ if (rootCertificates.indexOf(x5cRootPEM[0]) < 0) throw new Error("x5c root certificate was not a known root certificate (Android Key)");
111547
+ /**
111548
+ * Verify that x5c contains a full certificate path.
111549
+ */
111132
111550
  try {
111133
111551
  await validateCertificatePath(x5cNoRootPEM, x5cRootPEM);
111134
111552
  } catch (err) {
111135
111553
  const _err = err;
111136
111554
  throw new Error(`${_err.message} (Android Key)`, { cause: _err });
111137
111555
  }
111138
- /**
111139
- * Make sure the root certificate is one of the Google Hardware Attestation Root certificates
111140
- *
111141
- * https://developer.android.com/privacy-and-security/security-key-attestation#root_certificate
111142
- */
111143
- if (rootCertificates.length > 0 && rootCertificates.indexOf(x5cRootPEM[0]) < 0) throw new Error("x5c root certificate was not a known root certificate (Android Key)");
111144
111556
  }
111145
111557
  return verifySignature({
111146
111558
  signature: sig,
@@ -111149,7 +111561,7 @@ async function verifyAttestationAndroidKey(options) {
111149
111561
  hashAlgorithm: alg
111150
111562
  });
111151
111563
  }
111152
- // ../../node_modules/.pnpm/@simplewebauthn+server@14.0.3/node_modules/@simplewebauthn/server/esm/registration/verifications/verifyAttestationApple.js
111564
+ // ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/registration/verifications/verifyAttestationApple.js
111153
111565
  async function verifyAttestationApple(options) {
111154
111566
  const { attStmt, authData, clientDataHash, credentialPublicKey, rootCertificates } = options;
111155
111567
  const x5c = attStmt.get("x5c");
@@ -111170,7 +111582,42 @@ async function verifyAttestationApple(options) {
111170
111582
  if (!areEqual(convertCOSEtoPKCS(credentialPublicKey), new Uint8Array(subjectPublicKeyInfo.subjectPublicKey))) throw new Error("Credential public key does not equal credCert public key (Apple)");
111171
111583
  return true;
111172
111584
  }
111173
- // ../../node_modules/.pnpm/@simplewebauthn+server@14.0.3/node_modules/@simplewebauthn/server/esm/registration/verifyRegistrationResponse.js
111585
+ // ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/helpers/assertValidExpectedOrigin.js
111586
+ /**
111587
+ * Check the origin to make sure it's valid to compare against what's reported in a WebAuthn
111588
+ * response.
111589
+ *
111590
+ * Invalid origins will raise a `SimpleWebAuthnError` with `code: 'BAD_ARGUMENT'`
111591
+ */
111592
+ function assertValidExpectedOrigin(origin) {
111593
+ if (!origin.startsWith("https://")) return;
111594
+ if (origin.endsWith("/")) throw new SimpleWebAuthnError({
111595
+ message: `"${origin}" is not a valid expected origin. Remove the trailing "/" and try again`,
111596
+ code: "BAD_ARGUMENT"
111597
+ });
111598
+ const asciiOrigin = new URL(origin).origin;
111599
+ if (asciiOrigin !== origin) throw new SimpleWebAuthnError({
111600
+ message: `"${origin}" is not a valid expected origin. Replace it with its ASCII punycode representation "${asciiOrigin}" and try again`,
111601
+ code: "BAD_ARGUMENT"
111602
+ });
111603
+ }
111604
+ // ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/helpers/matchExpectedOrigin.js
111605
+ /**
111606
+ * Check that the origin reported in a WebAuthn response is an expected one.
111607
+ *
111608
+ * Raises a `SimpleWebAuthnError` if not match is found.
111609
+ */
111610
+ function matchExpectedOrigin(origin, expectedOrigin) {
111611
+ let _expectedOrigins = [];
111612
+ if (typeof expectedOrigin === "string") _expectedOrigins = [expectedOrigin];
111613
+ else _expectedOrigins = expectedOrigin;
111614
+ for (const _origin of _expectedOrigins) assertValidExpectedOrigin(_origin);
111615
+ if (!_expectedOrigins.includes(origin)) throw new SimpleWebAuthnError({
111616
+ message: `Unexpected response origin "${origin}", expected one of: ${_expectedOrigins.join(", ")}`,
111617
+ code: "UNEXPECTED_ORIGIN"
111618
+ });
111619
+ }
111620
+ // ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/registration/verifyRegistrationResponse.js
111174
111621
  /**
111175
111622
  * Verify that the user has legitimately completed the registration process
111176
111623
  *
@@ -111205,9 +111652,7 @@ async function verifyRegistrationResponse(options) {
111205
111652
  if (typeof expectedChallenge === "function") {
111206
111653
  if (!await expectedChallenge(challenge)) throw new Error(`Custom challenge verifier returned false for registration response challenge "${challenge}"`);
111207
111654
  } else if (challenge !== expectedChallenge) throw new Error(`Unexpected registration response challenge "${challenge}", expected "${expectedChallenge}"`);
111208
- if (Array.isArray(expectedOrigin)) {
111209
- if (!expectedOrigin.includes(origin)) throw new Error(`Unexpected registration response origin "${origin}", expected one of: ${expectedOrigin.join(", ")}`);
111210
- } else if (origin !== expectedOrigin) throw new Error(`Unexpected registration response origin "${origin}", expected "${expectedOrigin}"`);
111655
+ matchExpectedOrigin(origin, expectedOrigin);
111211
111656
  if (tokenBinding) {
111212
111657
  if (typeof tokenBinding !== "object") throw new Error(`Unexpected value for TokenBinding "${tokenBinding}"`);
111213
111658
  if ([
@@ -111277,11 +111722,13 @@ async function verifyRegistrationResponse(options) {
111277
111722
  } else throw new Error(`Unsupported Attestation Format: ${fmt}`);
111278
111723
  if (!verified) return { verified: false };
111279
111724
  const { credentialDeviceType, credentialBackedUp } = parseBackupFlags(flags);
111725
+ const formattedAAGUID = convertAAGUIDToString(aaguid);
111280
111726
  return {
111281
111727
  verified: true,
111282
111728
  registrationInfo: {
111283
111729
  fmt,
111284
- aaguid: convertAAGUIDToString(aaguid),
111730
+ aaguid: formattedAAGUID,
111731
+ passkeyProviderMetadata: await MetadataService.getProviderMetadata(formattedAAGUID) ?? await ConvenienceMetadataService.getProviderMetadata(formattedAAGUID),
111285
111732
  credentialType,
111286
111733
  credential: {
111287
111734
  id: fromBuffer(credentialID),
@@ -111299,7 +111746,7 @@ async function verifyRegistrationResponse(options) {
111299
111746
  }
111300
111747
  };
111301
111748
  }
111302
- // ../../node_modules/.pnpm/@simplewebauthn+server@14.0.3/node_modules/@simplewebauthn/server/esm/authentication/generateAuthenticationOptions.js
111749
+ // ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/authentication/generateAuthenticationOptions.js
111303
111750
  /**
111304
111751
  * Prepare a value to pass into navigator.credentials.get(...) for authenticator authentication
111305
111752
  *
@@ -111335,7 +111782,7 @@ async function generateAuthenticationOptions(options) {
111335
111782
  extensions
111336
111783
  };
111337
111784
  }
111338
- // ../../node_modules/.pnpm/@simplewebauthn+server@14.0.3/node_modules/@simplewebauthn/server/esm/authentication/verifyAuthenticationResponse.js
111785
+ // ../../node_modules/.pnpm/@simplewebauthn+server@14.1.0/node_modules/@simplewebauthn/server/esm/authentication/verifyAuthenticationResponse.js
111339
111786
  /**
111340
111787
  * Verify that the user has legitimately completed the authentication process
111341
111788
  *
@@ -111399,12 +111846,7 @@ async function verifyAuthenticationResponse(options) {
111399
111846
  * See https://w3c.github.io/webauthn/#dom-collectedclientdata-toporigin.
111400
111847
  */
111401
111848
  throw new Error(`Unexpected top origin of "${topOrigin}" within a non-cross-origin authentication response. This error should be reported to the browser vendor as a WebAuthn specification violation with a link to https://w3c.github.io/webauthn/#dom-collectedclientdata-toporigin`);
111402
- if (Array.isArray(expectedOrigin)) {
111403
- if (!expectedOrigin.includes(origin)) {
111404
- const joinedExpectedOrigin = expectedOrigin.join(", ");
111405
- throw new Error(`Unexpected authentication response origin "${origin}", expected one of: ${joinedExpectedOrigin}`);
111406
- }
111407
- } else if (origin !== expectedOrigin) throw new Error(`Unexpected authentication response origin "${origin}", expected "${expectedOrigin}"`);
111849
+ matchExpectedOrigin(origin, expectedOrigin);
111408
111850
  if (!isBase64URL(assertionResponse.authenticatorData)) throw new Error("Credential response authenticatorData was not a base64url string");
111409
111851
  if (!isBase64URL(assertionResponse.signature)) throw new Error("Credential response signature was not a base64url string");
111410
111852
  if (assertionResponse.userHandle && typeof assertionResponse.userHandle !== "string") throw new Error("Credential response userHandle was not a string");