@gatwech/auth 1.0.0-beta.23 → 1.0.0-beta.24

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. package/dist/adapters/index.d.mts +1 -1
  2. package/dist/api/index.d.mts +1 -1
  3. package/dist/client/index.d.mts +1 -1
  4. package/dist/client/plugins/index.d.mts +27 -27
  5. package/dist/client/react/index.d.mts +15 -15
  6. package/dist/{client-D8XKNpua.d.mts → client-CGV_kj99.d.mts} +1 -1
  7. package/dist/{client-CDaFOX7A.d.mts → client-CT-acJeN.d.mts} +4 -4
  8. package/dist/cookies/index.d.mts +2 -2
  9. package/dist/db/index.d.mts +1 -1
  10. package/dist/{index-Dg6Ftb6f.d.mts → index-B-i2ob-C.d.mts} +9 -9
  11. package/dist/{index-BhYE1_9j.d.mts → index-B6to9CaK.d.mts} +1 -1
  12. package/dist/{index-B5r4oL5q.d.mts → index-BRUQHEUF.d.mts} +5 -5
  13. package/dist/{index-Blq8KrTy.d.mts → index-BYxt8qOP.d.mts} +33 -33
  14. package/dist/{index-Dgyj1fTk.d.mts → index-CGGitykk.d.mts} +7 -7
  15. package/dist/{index-COFPq-mg.d.mts → index-CHMYUshk.d.mts} +13 -13
  16. package/dist/{index-D0SgItjY.d.mts → index-CLhlur69.d.mts} +6 -6
  17. package/dist/{index-3lfPQHhX.d.mts → index-CZtQ0rUe.d.mts} +113 -113
  18. package/dist/{index-C-z4TCHD.d.mts → index-Cl9ITXy1.d.mts} +10 -10
  19. package/dist/{index-DUu0ieh6.d.mts → index-Clwezlxm.d.mts} +8 -8
  20. package/dist/{index-CWxKeTtE.d.mts → index-Czr_eQFE.d.mts} +6 -6
  21. package/dist/{index-DxIqV3rU.d.mts → index-D5cyFBEb.d.mts} +4 -4
  22. package/dist/{index-DCliG2n6.d.mts → index-D85KXOKz.d.mts} +3 -3
  23. package/dist/{index-CIxFDcfQ.d.mts → index-DGRGLg16.d.mts} +2 -2
  24. package/dist/{index-CWwQ1Q7t.d.mts → index-DWGj7du8.d.mts} +19 -19
  25. package/dist/{index-B7iZf_Dl.d.mts → index-DWSbFJWU.d.mts} +55 -55
  26. package/dist/{index-C8F7PsET.d.mts → index-DYqQWdEv.d.mts} +13 -13
  27. package/dist/{index-382PsmkK.d.mts → index-Dmjw6re9.d.mts} +2 -2
  28. package/dist/{index-B4aWSJEd.d.mts → index-Dt6JhAV4.d.mts} +6 -6
  29. package/dist/{index-De2a2OyC.d.mts → index-Hoybqpnt.d.mts} +9 -9
  30. package/dist/{index-CExSHSFz.d.mts → index-JzSy-vFn.d.mts} +166 -166
  31. package/dist/{index-DPVukjga.d.mts → index-UDzaYKxq.d.mts} +9 -9
  32. package/dist/{index-DxRAXHrZ.d.mts → index-rcUKPBBy.d.mts} +6 -6
  33. package/dist/index.d.mts +1 -1
  34. package/dist/integrations/next-js.d.mts +2 -2
  35. package/dist/integrations/node.d.mts +1 -1
  36. package/dist/integrations/react-start.d.mts +4 -4
  37. package/dist/oauth2/index.d.mts +1 -1
  38. package/dist/plugins/admin/index.d.mts +2 -2
  39. package/dist/plugins/anonymous/index.d.mts +2 -2
  40. package/dist/plugins/audit-log/client.d.mts +23 -23
  41. package/dist/plugins/audit-log/index.d.mts +22 -22
  42. package/dist/plugins/bearer/index.d.mts +1 -1
  43. package/dist/plugins/captcha/index.d.mts +1 -1
  44. package/dist/plugins/custom-session/index.d.mts +2 -2
  45. package/dist/plugins/device-authorization/index.d.mts +1 -1
  46. package/dist/plugins/email-otp/index.d.mts +1 -1
  47. package/dist/plugins/generic-oauth/index.d.mts +2 -2
  48. package/dist/plugins/haveibeenpwned/index.d.mts +1 -1
  49. package/dist/plugins/index.d.mts +22 -22
  50. package/dist/plugins/index.mjs +1 -1
  51. package/dist/plugins/jwt/index.d.mts +2 -2
  52. package/dist/plugins/magic-link/index.d.mts +1 -1
  53. package/dist/plugins/multi-session/index.d.mts +1 -1
  54. package/dist/plugins/oauth-proxy/index.d.mts +1 -1
  55. package/dist/plugins/one-tap/index.d.mts +1 -1
  56. package/dist/plugins/one-time-token/index.d.mts +2 -2
  57. package/dist/plugins/one-time-token/index.mjs +1 -1
  58. package/dist/plugins/organization/index.d.mts +2 -2
  59. package/dist/plugins/passkey/index.d.mts +2 -2
  60. package/dist/plugins/phone-number/index.d.mts +2 -2
  61. package/dist/plugins/sentinel/client.d.mts +23 -23
  62. package/dist/plugins/sentinel/index.d.mts +22 -22
  63. package/dist/plugins/sentinel/index.mjs +1 -1
  64. package/dist/plugins/two-factor/index.d.mts +2 -2
  65. package/dist/plugins/username/index.d.mts +1 -1
  66. package/dist/{sentinel-CYtaI3eO.mjs → sentinel-b8XEetew.mjs} +39 -14
  67. package/dist/test-utils/index.d.mts +273 -273
  68. package/dist/test-utils/index.mjs +1 -1
  69. package/dist/types/index.d.mts +1 -1
  70. package/package.json +3 -3
@@ -1,29 +1,29 @@
1
1
  import "../../helper-BgOIGHsu.mjs";
2
- import "../../index-3lfPQHhX.mjs";
2
+ import "../../index-CZtQ0rUe.mjs";
3
3
  import "../../types-DNQ9XQrB.mjs";
4
4
  import "../../index-BL_t8cRp-C4QYBsac.mjs";
5
5
  import "../../plugins-Dy_FrD4Y.mjs";
6
6
  import "../../index-CxlWnL9c.mjs";
7
- import "../../index-Blq8KrTy.mjs";
8
- import "../../index-B4aWSJEd.mjs";
9
- import { S as SentinelOptions, _ as haversineDistanceKm, b as GeoLocation, c as sentinel, d as POW_SOLUTION_HEADER, f as createNonce, g as verifySolution, h as solveChallenge, l as POW_CHALLENGE_HEADER, m as parsePowHeader, p as hasLeadingZeroBits, u as POW_REASON_HEADER, v as normalizeEmail, x as SecurityAction, y as SENTINEL_ERROR_CODES } from "../../index-B7iZf_Dl.mjs";
10
- import "../../index-CWxKeTtE.mjs";
11
- import "../../index-382PsmkK.mjs";
12
- import "../../index-D0SgItjY.mjs";
13
- import "../../index-DxRAXHrZ.mjs";
14
- import "../../index-C8F7PsET.mjs";
15
- import "../../index-DUu0ieh6.mjs";
16
- import "../../index-DCliG2n6.mjs";
17
- import "../../index-DPVukjga.mjs";
18
- import "../../index-DxIqV3rU.mjs";
19
- import "../../index-Dg6Ftb6f.mjs";
20
- import "../../index-C-z4TCHD.mjs";
21
- import "../../index-CIxFDcfQ.mjs";
22
- import "../../index-B5r4oL5q.mjs";
7
+ import "../../index-BYxt8qOP.mjs";
8
+ import "../../index-Dt6JhAV4.mjs";
9
+ import { S as SentinelOptions, _ as haversineDistanceKm, b as GeoLocation, c as sentinel, d as POW_SOLUTION_HEADER, f as createNonce, g as verifySolution, h as solveChallenge, l as POW_CHALLENGE_HEADER, m as parsePowHeader, p as hasLeadingZeroBits, u as POW_REASON_HEADER, v as normalizeEmail, x as SecurityAction, y as SENTINEL_ERROR_CODES } from "../../index-DWSbFJWU.mjs";
10
+ import "../../index-Czr_eQFE.mjs";
11
+ import "../../index-Dmjw6re9.mjs";
12
+ import "../../index-CLhlur69.mjs";
13
+ import "../../index-rcUKPBBy.mjs";
14
+ import "../../index-DYqQWdEv.mjs";
15
+ import "../../index-Clwezlxm.mjs";
16
+ import "../../index-D85KXOKz.mjs";
17
+ import "../../index-UDzaYKxq.mjs";
18
+ import "../../index-D5cyFBEb.mjs";
19
+ import "../../index-B-i2ob-C.mjs";
20
+ import "../../index-Cl9ITXy1.mjs";
21
+ import "../../index-DGRGLg16.mjs";
22
+ import "../../index-BRUQHEUF.mjs";
23
23
  import "../../index-QmocqGM-.mjs";
24
- import "../../index-CExSHSFz.mjs";
25
- import "../../index-Dgyj1fTk.mjs";
26
- import "../../index-CWwQ1Q7t.mjs";
27
- import "../../index-COFPq-mg.mjs";
28
- import "../../index-De2a2OyC.mjs";
24
+ import "../../index-JzSy-vFn.mjs";
25
+ import "../../index-CGGitykk.mjs";
26
+ import "../../index-DWGj7du8.mjs";
27
+ import "../../index-CHMYUshk.mjs";
28
+ import "../../index-Hoybqpnt.mjs";
29
29
  export { GeoLocation, POW_CHALLENGE_HEADER, POW_REASON_HEADER, POW_SOLUTION_HEADER, SENTINEL_ERROR_CODES, SecurityAction, SentinelOptions, createNonce, hasLeadingZeroBits, haversineDistanceKm, normalizeEmail, parsePowHeader, sentinel, solveChallenge, verifySolution };
@@ -17,6 +17,6 @@ import "../../session-BB3oqApE.mjs";
17
17
  import "../../registry-GztLf62p.mjs";
18
18
  import "../../haveibeenpwned-_3a5amT-.mjs";
19
19
  import { a as hasLeadingZeroBits, c as verifySolution, i as createNonce, n as POW_REASON_HEADER, o as parsePowHeader, r as POW_SOLUTION_HEADER, s as solveChallenge, t as POW_CHALLENGE_HEADER } from "../../pow-DvkUopsK.mjs";
20
- import { i as SENTINEL_ERROR_CODES, n as haversineDistanceKm, r as normalizeEmail, t as sentinel } from "../../sentinel-CYtaI3eO.mjs";
20
+ import { i as SENTINEL_ERROR_CODES, n as haversineDistanceKm, r as normalizeEmail, t as sentinel } from "../../sentinel-b8XEetew.mjs";
21
21
 
22
22
  export { POW_CHALLENGE_HEADER, POW_REASON_HEADER, POW_SOLUTION_HEADER, SENTINEL_ERROR_CODES, createNonce, hasLeadingZeroBits, haversineDistanceKm, normalizeEmail, parsePowHeader, sentinel, solveChallenge, verifySolution };
@@ -1,7 +1,7 @@
1
1
  import "../../helper-BgOIGHsu.mjs";
2
- import "../../index-3lfPQHhX.mjs";
2
+ import "../../index-CZtQ0rUe.mjs";
3
3
  import "../../types-DNQ9XQrB.mjs";
4
4
  import "../../index-BL_t8cRp-C4QYBsac.mjs";
5
5
  import "../../plugins-Dy_FrD4Y.mjs";
6
- import { a as TwoFactorProvider, i as TwoFactorOptions, n as twoFactorClient, o as TwoFactorTable, r as TWO_FACTOR_ERROR_CODES, s as UserWithTwoFactor, t as twoFactor } from "../../index-CWwQ1Q7t.mjs";
6
+ import { a as TwoFactorProvider, i as TwoFactorOptions, n as twoFactorClient, o as TwoFactorTable, r as TWO_FACTOR_ERROR_CODES, s as UserWithTwoFactor, t as twoFactor } from "../../index-DWGj7du8.mjs";
7
7
  export { TWO_FACTOR_ERROR_CODES, TwoFactorOptions, TwoFactorProvider, TwoFactorTable, UserWithTwoFactor, twoFactor, twoFactorClient };
@@ -1,4 +1,4 @@
1
1
  import "../../helper-BgOIGHsu.mjs";
2
2
  import "../../plugins-Dy_FrD4Y.mjs";
3
- import { n as username, r as USERNAME_ERROR_CODES, t as UsernameOptions } from "../../index-De2a2OyC.mjs";
3
+ import { n as username, r as USERNAME_ERROR_CODES, t as UsernameOptions } from "../../index-Hoybqpnt.mjs";
4
4
  export { USERNAME_ERROR_CODES, UsernameOptions, username };
@@ -1240,6 +1240,39 @@ const sentinel = (options) => {
1240
1240
  }));
1241
1241
  return Math.max(0, ...failures);
1242
1242
  }
1243
+ /**
1244
+ * Blocks an attempt counter for the cooldown and clears its counts. The
1245
+ * block is also recorded so an admin can list and lift it; it holds
1246
+ * without the record.
1247
+ */
1248
+ async function blockKey(auth, store, key, also = []) {
1249
+ if (!credentialStuffing) return;
1250
+ const { cooldownSeconds } = credentialStuffing;
1251
+ await store.increment(`${key}:blocked`, cooldownSeconds);
1252
+ await Promise.all([key, ...also].map((name) => store.reset(name)));
1253
+ await store.recordBlock({
1254
+ key,
1255
+ feature: "credential_stuffing",
1256
+ ...describeAttemptKey(key),
1257
+ blockedUntil: new Date(Date.now() + cooldownSeconds * 1e3)
1258
+ }).catch((e) => {
1259
+ auth.logger.error("[sentinel] Failed to record block", e);
1260
+ });
1261
+ }
1262
+ /**
1263
+ * Turns the counters that passed the block threshold into blocks that last
1264
+ * the cooldown, so they end then and can be listed and lifted. `count`
1265
+ * includes the attempt just made.
1266
+ */
1267
+ async function blockOverThreshold(auth, store, keys) {
1268
+ if (!credentialStuffing) return;
1269
+ const { thresholds } = credentialStuffing;
1270
+ for (const { scope, account } of keys) {
1271
+ const [total, succeeded] = await Promise.all([store.get(scope), store.get(`${scope}:succeeded`)]);
1272
+ if (total - succeeded - 1 >= thresholds.block) await blockKey(auth, store, scope, [`${scope}:succeeded`]);
1273
+ if (account && await store.get(account) - 1 >= thresholds.block) await blockKey(auth, store, account);
1274
+ }
1275
+ }
1243
1276
  /** What an attempt counter's key is for: `cs:ip:<ip>` or `cs:visitor:<id>`, plus `:account:<email>` */
1244
1277
  function describeAttemptKey(key) {
1245
1278
  const accountAt = key.indexOf(":account:");
@@ -1581,7 +1614,10 @@ const sentinel = (options) => {
1581
1614
  failedAttempts: failures,
1582
1615
  thresholds
1583
1616
  };
1584
- if (blocked || failures >= thresholds.block) return act(ctx, store, details, credentialStuffing.action === "log" ? "log" : "block", SECURITY_EVENT_TYPES.CREDENTIAL_STUFFING, "credential_stuffing", metadata);
1617
+ if (blocked || failures >= thresholds.block) {
1618
+ if (!blocked && credentialStuffing.action !== "log") await blockOverThreshold(ctx.context, store, keys);
1619
+ return act(ctx, store, details, credentialStuffing.action === "log" ? "log" : "block", SECURITY_EVENT_TYPES.CREDENTIAL_STUFFING, "credential_stuffing", metadata);
1620
+ }
1585
1621
  if (failures >= thresholds.challenge) return act(ctx, store, details, credentialStuffing.action === "log" ? "log" : "challenge", SECURITY_EVENT_TYPES.CREDENTIAL_STUFFING, "credential_stuffing", metadata);
1586
1622
  return { outcome: "allow" };
1587
1623
  }));
@@ -1635,7 +1671,7 @@ const sentinel = (options) => {
1635
1671
  try {
1636
1672
  const store = createSentinelStore(ctx.context);
1637
1673
  const keys = attemptKeys(await requestDetails(ctx));
1638
- const { windowSeconds, cooldownSeconds, thresholds } = credentialStuffing;
1674
+ const { windowSeconds, thresholds } = credentialStuffing;
1639
1675
  if (status < 400) for (const { scope, account } of keys) {
1640
1676
  const [total, succeeded, own] = await Promise.all([
1641
1677
  store.get(scope),
@@ -1649,18 +1685,7 @@ const sentinel = (options) => {
1649
1685
  } else await store.increment(`${scope}:succeeded`, windowSeconds);
1650
1686
  }
1651
1687
  else if (!SENTINEL_STATUSES.has(status) && status < 500) {
1652
- const block = async (key, also = []) => {
1653
- await store.increment(`${key}:blocked`, cooldownSeconds);
1654
- await Promise.all([key, ...also].map((name) => store.reset(name)));
1655
- await store.recordBlock({
1656
- key,
1657
- feature: "credential_stuffing",
1658
- ...describeAttemptKey(key),
1659
- blockedUntil: new Date(Date.now() + cooldownSeconds * 1e3)
1660
- }).catch((e) => {
1661
- ctx.context.logger.error("[sentinel] Failed to record block", e);
1662
- });
1663
- };
1688
+ const block = (key, also = []) => blockKey(ctx.context, store, key, also);
1664
1689
  for (const { scope, account } of keys) {
1665
1690
  const [total, succeeded] = await Promise.all([store.get(scope), store.get(`${scope}:succeeded`)]);
1666
1691
  if (total - succeeded >= thresholds.block) await block(scope, [`${scope}:succeeded`]);