@absolutejs/auth 0.36.0-beta.0 → 0.37.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,4 +1,19 @@
1
1
  // @bun
2
+ var __defProp = Object.defineProperty;
3
+ var __returnValue = (v) => v;
4
+ function __exportSetter(name, newValue) {
5
+ this[name] = __returnValue.bind(null, newValue);
6
+ }
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, {
10
+ get: all[name],
11
+ enumerable: true,
12
+ configurable: true,
13
+ set: __exportSetter.bind(all, name)
14
+ });
15
+ };
16
+ var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
2
17
  var __require = import.meta.require;
3
18
 
4
19
  // node_modules/citra/dist/index.js
@@ -4492,6 +4507,7 @@ var RESERVED_ACCESS_CLAIMS = new Set([
4492
4507
  var buildAccessClaims = ({
4493
4508
  act,
4494
4509
  audience,
4510
+ clientCertThumbprint,
4495
4511
  clientId,
4496
4512
  dpopJkt,
4497
4513
  extraClaims,
@@ -4516,8 +4532,15 @@ var buildAccessClaims = ({
4516
4532
  };
4517
4533
  if (act !== undefined)
4518
4534
  claims.act = act;
4519
- if (dpopJkt !== undefined)
4520
- claims.cnf = { jkt: dpopJkt };
4535
+ if (dpopJkt !== undefined || clientCertThumbprint !== undefined) {
4536
+ const cnf = {};
4537
+ if (dpopJkt !== undefined)
4538
+ cnf.jkt = dpopJkt;
4539
+ if (clientCertThumbprint !== undefined) {
4540
+ cnf["x5t#S256"] = clientCertThumbprint;
4541
+ }
4542
+ claims.cnf = cnf;
4543
+ }
4521
4544
  return claims;
4522
4545
  };
4523
4546
  var exchangeToken = async ({
@@ -4567,6 +4590,7 @@ var exchangeToken = async ({
4567
4590
  var issueTokenSet = async ({
4568
4591
  acr,
4569
4592
  claims,
4593
+ clientCertThumbprint,
4570
4594
  clientId,
4571
4595
  config,
4572
4596
  dpopJkt,
@@ -4584,6 +4608,7 @@ var issueTokenSet = async ({
4584
4608
  sub
4585
4609
  });
4586
4610
  const accessPayload = buildAccessClaims({
4611
+ clientCertThumbprint,
4587
4612
  clientId,
4588
4613
  dpopJkt,
4589
4614
  extraClaims: { ...accessExtra, ...acr === undefined ? {} : { acr } },
@@ -4873,6 +4898,7 @@ var denyBackchannelAuth = async ({
4873
4898
  }) => decideBackchannel(config, authReqId, { status: "denied" });
4874
4899
  var exchangeBackchannelAuth = async ({
4875
4900
  authReqId,
4901
+ clientCertThumbprint,
4876
4902
  clientId,
4877
4903
  config,
4878
4904
  dpopJkt,
@@ -4901,6 +4927,7 @@ var exchangeBackchannelAuth = async ({
4901
4927
  }
4902
4928
  await config.backchannelAuthStore.deleteByAuthReqId(authReqId);
4903
4929
  const tokenSet = await issueTokenSet({
4930
+ clientCertThumbprint,
4904
4931
  clientId,
4905
4932
  config,
4906
4933
  dpopJkt,
@@ -5020,6 +5047,55 @@ var verifyJwtSignedByClient = ({
5020
5047
  client
5021
5048
  }) => verifyJwtSignedByClientImpl(client, jwt);
5022
5049
 
5050
+ // src/oidc/mtls.ts
5051
+ var RFC9440_HEADER = "client-cert";
5052
+ var SF_BINARY_PREFIX = ":";
5053
+ var SF_BINARY_SUFFIX = ":";
5054
+ var base64Decode2 = (value) => Uint8Array.from(atob(value), (char) => char.charCodeAt(0));
5055
+ var base64UrlEncode2 = (bytes) => {
5056
+ const binary = Array.from(bytes, (byte) => String.fromCharCode(byte)).join("");
5057
+ return btoa(binary).replace(/\+/gu, "-").replace(/\//gu, "_").replace(/=+$/u, "");
5058
+ };
5059
+ var computeCertThumbprint = async (derBytes) => {
5060
+ const digest = await crypto.subtle.digest("SHA-256", derBytes);
5061
+ return base64UrlEncode2(new Uint8Array(digest));
5062
+ };
5063
+ var extractRfc9440ClientCert = (headers) => {
5064
+ const raw = headers.get(RFC9440_HEADER);
5065
+ if (raw === null)
5066
+ return;
5067
+ const trimmed = raw.trim();
5068
+ if (!trimmed.startsWith(SF_BINARY_PREFIX) || !trimmed.endsWith(SF_BINARY_SUFFIX) || trimmed.length <= 2) {
5069
+ return;
5070
+ }
5071
+ try {
5072
+ return base64Decode2(trimmed.slice(1, -1));
5073
+ } catch {
5074
+ return;
5075
+ }
5076
+ };
5077
+ var resolveClientCert = async ({
5078
+ extract,
5079
+ headers
5080
+ }) => {
5081
+ if (extract !== undefined)
5082
+ return extract(headers);
5083
+ return extractRfc9440ClientCert(headers);
5084
+ };
5085
+ var verifyCertificateBoundToken = async ({
5086
+ cnfThumbprint,
5087
+ extract,
5088
+ headers
5089
+ }) => {
5090
+ if (cnfThumbprint === undefined)
5091
+ return false;
5092
+ const cert = await resolveClientCert({ extract, headers });
5093
+ if (cert === undefined)
5094
+ return false;
5095
+ const presented = await computeCertThumbprint(cert);
5096
+ return presented === cnfThumbprint;
5097
+ };
5098
+
5023
5099
  // src/oidc/dpop.ts
5024
5100
  var DEFAULT_MAX_AGE_MS = 60000;
5025
5101
  var SECONDS_TO_MS = 1000;
@@ -5656,27 +5732,57 @@ var oidcProviderRoutes = (config) => {
5656
5732
  const matches = await constantTimeEqual(await hashToken(clientSecret), client.hashedSecret);
5657
5733
  return matches ? client : undefined;
5658
5734
  };
5735
+ const tryMtlsAuth = async ({
5736
+ candidate,
5737
+ extract,
5738
+ requestHeaders
5739
+ }) => {
5740
+ const registered = candidate?.tlsCertificateBoundThumbprints ?? [];
5741
+ if (candidate === undefined || registered.length === 0)
5742
+ return;
5743
+ const cert = await resolveClientCert({
5744
+ extract,
5745
+ headers: requestHeaders
5746
+ });
5747
+ if (cert === undefined)
5748
+ return;
5749
+ const presented = await computeCertThumbprint(cert);
5750
+ if (!registered.includes(presented))
5751
+ return;
5752
+ return { client: candidate, clientCertThumbprint: presented };
5753
+ };
5659
5754
  const authenticateTokenClient = async ({
5660
5755
  basicClientId,
5661
5756
  basicClientSecret,
5662
5757
  bodyClientAssertion,
5663
5758
  bodyClientAssertionType,
5664
5759
  bodyClientId,
5665
- bodyClientSecret
5760
+ bodyClientSecret,
5761
+ requestHeaders
5666
5762
  }) => {
5667
5763
  if (bodyClientAssertion !== undefined && bodyClientAssertionType === CLIENT_ASSERTION_TYPE) {
5668
- return verifyClientAssertion({
5764
+ const client2 = await verifyClientAssertion({
5669
5765
  assertion: bodyClientAssertion,
5670
5766
  expectedAudience: tokenUrl,
5671
5767
  jtiStore: config.clientAssertionJtiStore,
5672
5768
  resolveClient: clientStore.findClient
5673
5769
  });
5770
+ return client2 === undefined ? undefined : { client: client2, clientCertThumbprint: undefined };
5674
5771
  }
5675
5772
  const clientId = bodyClientId ?? basicClientId;
5676
- const clientSecret = bodyClientSecret ?? basicClientSecret;
5677
5773
  if (clientId === undefined)
5678
5774
  return;
5679
- return authenticateClient(clientId, clientSecret);
5775
+ const candidate = await clientStore.findClient(clientId);
5776
+ const mtlsResult = await tryMtlsAuth({
5777
+ candidate,
5778
+ extract: config.extractTlsClientCert,
5779
+ requestHeaders
5780
+ });
5781
+ if (mtlsResult !== undefined)
5782
+ return mtlsResult;
5783
+ const clientSecret = bodyClientSecret ?? basicClientSecret;
5784
+ const client = await authenticateClient(clientId, clientSecret);
5785
+ return client === undefined ? undefined : { client, clientCertThumbprint: undefined };
5680
5786
  };
5681
5787
  const dpopNonceChallenge = async (proof) => {
5682
5788
  if (proof === undefined || config.dpopNonce === undefined) {
@@ -5701,7 +5807,7 @@ var oidcProviderRoutes = (config) => {
5701
5807
  status: HTTP_UNAUTHORIZED2
5702
5808
  });
5703
5809
  };
5704
- const grantAuthorizationCode = async (client, body, dpop) => {
5810
+ const grantAuthorizationCode = async (client, body, dpop, clientCertThumbprint) => {
5705
5811
  const {
5706
5812
  code,
5707
5813
  code_verifier: codeVerifier,
@@ -5725,6 +5831,7 @@ var oidcProviderRoutes = (config) => {
5725
5831
  return tokenResponse(await issueTokenSet({
5726
5832
  acr: record.acr,
5727
5833
  claims: record.claims,
5834
+ clientCertThumbprint,
5728
5835
  clientId: client.clientId,
5729
5836
  config,
5730
5837
  dpopJkt: dpopResult?.jkt,
@@ -5733,7 +5840,7 @@ var oidcProviderRoutes = (config) => {
5733
5840
  sub: record.userId
5734
5841
  }));
5735
5842
  };
5736
- const grantRefreshToken = async (client, body, dpop) => {
5843
+ const grantRefreshToken = async (client, body, dpop, clientCertThumbprint) => {
5737
5844
  const presented = body.refresh_token;
5738
5845
  if (presented === undefined) {
5739
5846
  return oauthError2(HTTP_BAD_REQUEST2, "invalid_request");
@@ -5755,6 +5862,7 @@ var oidcProviderRoutes = (config) => {
5755
5862
  return tokenResponse(await issueTokenSet({
5756
5863
  acr: record.acr,
5757
5864
  claims: record.claims,
5865
+ clientCertThumbprint,
5758
5866
  clientId: client.clientId,
5759
5867
  config,
5760
5868
  dpopJkt: record.dpopJkt,
@@ -5792,7 +5900,7 @@ var oidcProviderRoutes = (config) => {
5792
5900
  token_type: dpopResult === undefined ? "Bearer" : "DPoP"
5793
5901
  }, HTTP_OK2);
5794
5902
  };
5795
- const grantBackchannel = async (client, body, dpop) => {
5903
+ const grantBackchannel = async (client, body, dpop, clientCertThumbprint) => {
5796
5904
  if (config.backchannelAuthStore === undefined) {
5797
5905
  return oauthError2(HTTP_BAD_REQUEST2, "unsupported_grant_type");
5798
5906
  }
@@ -5809,6 +5917,7 @@ var oidcProviderRoutes = (config) => {
5809
5917
  }
5810
5918
  const result = await exchangeBackchannelAuth({
5811
5919
  authReqId: body.auth_req_id,
5920
+ clientCertThumbprint,
5812
5921
  clientId: client.clientId,
5813
5922
  config,
5814
5923
  dpopJkt: dpopResult?.jkt
@@ -5885,12 +5994,14 @@ var oidcProviderRoutes = (config) => {
5885
5994
  response_types_supported: ["code"],
5886
5995
  revocation_endpoint: `${issuer}${revokeRoute}`,
5887
5996
  subject_types_supported: ["public"],
5997
+ tls_client_certificate_bound_access_tokens: true,
5888
5998
  token_endpoint: tokenUrl,
5889
5999
  token_endpoint_auth_methods_supported: [
5890
6000
  "client_secret_basic",
5891
6001
  "client_secret_post",
5892
6002
  "none",
5893
- "private_key_jwt"
6003
+ "private_key_jwt",
6004
+ "self_signed_tls_client_auth"
5894
6005
  ],
5895
6006
  token_endpoint_auth_signing_alg_values_supported: ["ES256"],
5896
6007
  userinfo_endpoint: `${issuer}${userinfoRoute}`
@@ -6097,27 +6208,29 @@ var oidcProviderRoutes = (config) => {
6097
6208
  scope: t12.Optional(t12.String()),
6098
6209
  state: t12.Optional(t12.String())
6099
6210
  })
6100
- }).post(tokenRoute, async ({ body, headers }) => {
6211
+ }).post(tokenRoute, async ({ body, headers, request }) => {
6101
6212
  const basic = readBasicAuth2(headers.authorization);
6102
- const client = await authenticateTokenClient({
6213
+ const auth = await authenticateTokenClient({
6103
6214
  basicClientId: basic.clientId,
6104
6215
  basicClientSecret: basic.clientSecret,
6105
6216
  bodyClientAssertion: body.client_assertion,
6106
6217
  bodyClientAssertionType: body.client_assertion_type,
6107
6218
  bodyClientId: body.client_id,
6108
- bodyClientSecret: body.client_secret
6219
+ bodyClientSecret: body.client_secret,
6220
+ requestHeaders: request.headers
6109
6221
  });
6110
- if (client === undefined) {
6222
+ if (auth === undefined) {
6111
6223
  return oauthError2(HTTP_UNAUTHORIZED2, "invalid_client");
6112
6224
  }
6225
+ const { client, clientCertThumbprint } = auth;
6113
6226
  const nonceChallenge = await dpopNonceChallenge(headers.dpop);
6114
6227
  if (nonceChallenge !== undefined)
6115
6228
  return nonceChallenge;
6116
6229
  if (body.grant_type === "authorization_code") {
6117
- return grantAuthorizationCode(client, body, headers.dpop);
6230
+ return grantAuthorizationCode(client, body, headers.dpop, clientCertThumbprint);
6118
6231
  }
6119
6232
  if (body.grant_type === "refresh_token") {
6120
- return grantRefreshToken(client, body, headers.dpop);
6233
+ return grantRefreshToken(client, body, headers.dpop, clientCertThumbprint);
6121
6234
  }
6122
6235
  if (body.grant_type === "urn:ietf:params:oauth:grant-type:token-exchange") {
6123
6236
  return grantTokenExchange(client, body, headers.dpop);
@@ -6126,7 +6239,7 @@ var oidcProviderRoutes = (config) => {
6126
6239
  return grantDeviceCode(client, body, headers.dpop);
6127
6240
  }
6128
6241
  if (body.grant_type === CIBA_GRANT_TYPE) {
6129
- return grantBackchannel(client, body, headers.dpop);
6242
+ return grantBackchannel(client, body, headers.dpop, clientCertThumbprint);
6130
6243
  }
6131
6244
  return oauthError2(HTTP_BAD_REQUEST2, "unsupported_grant_type");
6132
6245
  }, {
@@ -6148,22 +6261,24 @@ var oidcProviderRoutes = (config) => {
6148
6261
  subject_token: t12.Optional(t12.String()),
6149
6262
  subject_token_type: t12.Optional(t12.String())
6150
6263
  })
6151
- }).post(parRoute, async ({ body, headers }) => {
6264
+ }).post(parRoute, async ({ body, headers, request }) => {
6152
6265
  if (config.pushedAuthorizationRequestStore === undefined) {
6153
6266
  return oauthError2(HTTP_NOT_IMPLEMENTED, "unsupported_response_type");
6154
6267
  }
6155
6268
  const basic = readBasicAuth2(headers.authorization);
6156
- const client = await authenticateTokenClient({
6269
+ const auth = await authenticateTokenClient({
6157
6270
  basicClientId: basic.clientId,
6158
6271
  basicClientSecret: basic.clientSecret,
6159
6272
  bodyClientAssertion: body.client_assertion,
6160
6273
  bodyClientAssertionType: body.client_assertion_type,
6161
6274
  bodyClientId: body.client_id,
6162
- bodyClientSecret: body.client_secret
6275
+ bodyClientSecret: body.client_secret,
6276
+ requestHeaders: request.headers
6163
6277
  });
6164
- if (client === undefined) {
6278
+ if (auth === undefined) {
6165
6279
  return oauthError2(HTTP_UNAUTHORIZED2, "invalid_client");
6166
6280
  }
6281
+ const { client } = auth;
6167
6282
  const isAuthField = (key) => key === "client_assertion" || key === "client_assertion_type" || key === "client_secret";
6168
6283
  const params = Object.fromEntries(Object.entries(body).filter((entry) => typeof entry[1] === "string" && !isAuthField(entry[0])));
6169
6284
  const result = await pushAuthorizationRequest({
@@ -20671,6 +20786,132 @@ var switchActiveSession = ({
20671
20786
  };
20672
20787
  // src/tenancy.ts
20673
20788
  var hasOrganizationScope = (value) => typeof value.organizationId === "string" && value.organizationId.length > 0;
20789
+ // src/credentials/backgroundOps.ts
20790
+ var HIBP_BREACHED_ACCOUNT_URL = "https://haveibeenpwned.com/api/v3/breachedaccount/";
20791
+ var HIBP_USER_AGENT = "@absolutejs/auth breach scanner";
20792
+ var DEFAULT_PAUSE_MS = 1700;
20793
+ var HIBP_NOT_FOUND = 404;
20794
+ var HIBP_RATE_LIMITED = 429;
20795
+ var MS_PER_DAY = 86400000;
20796
+ var MS_PER_SECOND3 = 1000;
20797
+ var sleep = (delayMs) => new Promise((resolve) => {
20798
+ setTimeout(resolve, delayMs);
20799
+ });
20800
+ var isBreachRecord = (entry) => {
20801
+ if (typeof entry !== "object" || entry === null)
20802
+ return false;
20803
+ if (!("name" in entry))
20804
+ return false;
20805
+ const candidate = entry;
20806
+ return typeof candidate.name === "string";
20807
+ };
20808
+ var isBreachRecordArray = (value) => Array.isArray(value) && value.every(isBreachRecord);
20809
+ var checkEmailBreaches = async (email, apiKey, truncate) => {
20810
+ const url = `${HIBP_BREACHED_ACCOUNT_URL}${encodeURIComponent(email)}?truncateResponse=${truncate ? "true" : "false"}`;
20811
+ const response = await fetch(url, {
20812
+ headers: {
20813
+ "hibp-api-key": apiKey,
20814
+ "user-agent": HIBP_USER_AGENT
20815
+ }
20816
+ });
20817
+ if (response.status === HIBP_NOT_FOUND)
20818
+ return [];
20819
+ if (response.status === HIBP_RATE_LIMITED) {
20820
+ const retryAfter = Number(response.headers.get("retry-after") ?? "0");
20821
+ if (retryAfter > 0)
20822
+ await sleep(retryAfter * MS_PER_SECOND3);
20823
+ return [];
20824
+ }
20825
+ if (!response.ok)
20826
+ return [];
20827
+ const body = await response.json();
20828
+ if (!isBreachRecordArray(body))
20829
+ return [];
20830
+ return body;
20831
+ };
20832
+ var scanEmail = async (email, apiKey, truncate, onBreachFound) => {
20833
+ const breaches = await checkEmailBreaches(email, apiKey, truncate);
20834
+ if (breaches.length === 0)
20835
+ return false;
20836
+ await onBreachFound({ breaches, email });
20837
+ return true;
20838
+ };
20839
+ var scanPage = async (options) => {
20840
+ let scanned = 0;
20841
+ let breached = 0;
20842
+ for (const email of options.emails) {
20843
+ scanned += 1;
20844
+ const hit = await scanEmail(email, options.apiKey, options.truncate, options.onBreachFound);
20845
+ if (hit)
20846
+ breached += 1;
20847
+ await sleep(options.pauseMs);
20848
+ }
20849
+ return { breached, scanned };
20850
+ };
20851
+ var runEmailBreachScan = async (input) => {
20852
+ const pauseMs = input.pauseMs ?? DEFAULT_PAUSE_MS;
20853
+ const truncate = input.truncateResponse ?? true;
20854
+ let scanned = 0;
20855
+ let breached = 0;
20856
+ let cursor;
20857
+ do {
20858
+ const page = await input.iterateEmails(cursor);
20859
+ const tally = await scanPage({
20860
+ apiKey: input.hibpApiKey,
20861
+ emails: page.emails,
20862
+ onBreachFound: input.onBreachFound,
20863
+ pauseMs,
20864
+ truncate
20865
+ });
20866
+ scanned += tally.scanned;
20867
+ breached += tally.breached;
20868
+ cursor = page.nextCursor;
20869
+ } while (cursor !== undefined);
20870
+ const result = { breached, scanned };
20871
+ return result;
20872
+ };
20873
+ var pruneCandidate = async (candidate, cutoff, dryRun, onDelete) => {
20874
+ const reference = candidate.lastLoginAt ?? candidate.createdAt;
20875
+ if (reference === undefined || reference === null)
20876
+ return false;
20877
+ if (reference >= cutoff)
20878
+ return false;
20879
+ if (!dryRun)
20880
+ await onDelete(candidate.userId);
20881
+ return true;
20882
+ };
20883
+ var prunePage = async (options) => {
20884
+ const pruned = [];
20885
+ for (const candidate of options.candidates) {
20886
+ const removed = await pruneCandidate(candidate, options.cutoff, options.dryRun, options.onDelete);
20887
+ if (removed)
20888
+ pruned.push(candidate.userId);
20889
+ }
20890
+ return pruned;
20891
+ };
20892
+ var pruneInactiveUsers = async (input) => {
20893
+ const now = input.now?.() ?? Date.now();
20894
+ const thresholdMs = input.olderThanDays * MS_PER_DAY;
20895
+ const cutoff = now - thresholdMs;
20896
+ const dryRun = input.dryRun ?? false;
20897
+ const prunedUserIds = [];
20898
+ let scanned = 0;
20899
+ let cursor;
20900
+ do {
20901
+ const page = await input.iterateUsers(cursor);
20902
+ scanned += page.users.length;
20903
+ const removed = await prunePage({
20904
+ candidates: page.users,
20905
+ cutoff,
20906
+ dryRun,
20907
+ onDelete: input.onDelete
20908
+ });
20909
+ prunedUserIds.push(...removed);
20910
+ cursor = page.nextCursor;
20911
+ } while (cursor !== undefined);
20912
+ const result = { dryRun, prunedUserIds, scanned };
20913
+ return result;
20914
+ };
20674
20915
  // src/credentials/emailValidation.ts
20675
20916
  import { resolveMx } from "dns/promises";
20676
20917
  var EMAIL_PATTERN = /^[^\s@]+@[^\s@]+\.[^\s@]+$/u;
@@ -24240,6 +24481,7 @@ export {
24240
24481
  verifyDpopNonce,
24241
24482
  verifyCognitoSha256,
24242
24483
  verifyClientAssertion,
24484
+ verifyCertificateBoundToken,
24243
24485
  verifyAuth0Pbkdf2,
24244
24486
  verifyAuditChain,
24245
24487
  verifyApiKey,
@@ -24272,6 +24514,7 @@ export {
24272
24514
  samlServiceProvidersTable,
24273
24515
  samlIdpRoutes,
24274
24516
  runMigrations,
24517
+ runEmailBreachScan,
24275
24518
  rotateVaultKey,
24276
24519
  rotateMfaEncryptionKey,
24277
24520
  rolesTable,
@@ -24288,6 +24531,7 @@ export {
24288
24531
  resolveOAuthAuthorization,
24289
24532
  resolveCookieSecure,
24290
24533
  resolveClientProviderEntry,
24534
+ resolveClientCert,
24291
24535
  resolveAuthHtmxRenderers,
24292
24536
  resolveApiPrincipal,
24293
24537
  removeFromSessionRing,
@@ -24298,6 +24542,7 @@ export {
24298
24542
  readUserInfoBearer,
24299
24543
  readSessionRing,
24300
24544
  pushAuthorizationRequest,
24545
+ pruneInactiveUsers,
24301
24546
  providers,
24302
24547
  providerOptions,
24303
24548
  protectRoutePlugin,
@@ -24384,6 +24629,7 @@ export {
24384
24629
  fingerprintDevice,
24385
24630
  fetchUserInfo,
24386
24631
  fanOutBackchannelLogout,
24632
+ extractRfc9440ClientCert,
24387
24633
  extractPropFromIdentity,
24388
24634
  extractDpopNonceClaim,
24389
24635
  exportAuditCsv,
@@ -24543,6 +24789,7 @@ export {
24543
24789
  consumePushedRequest,
24544
24790
  consumeBackupCode,
24545
24791
  constantTimeEqual,
24792
+ computeCertThumbprint,
24546
24793
  complianceRoutes,
24547
24794
  check,
24548
24795
  buildClientProviders,
@@ -24599,5 +24846,5 @@ export {
24599
24846
  AuthIdentityConflictError
24600
24847
  };
24601
24848
 
24602
- //# debugId=6F90E4F856A11E4B64756E2164756E21
24849
+ //# debugId=26C38ACE51F8A69A64756E2164756E21
24603
24850
  //# sourceMappingURL=index.js.map