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

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 (90) hide show
  1. package/dist/adapters/index.d.mts +1 -1
  2. package/dist/api/index.d.mts +1 -1
  3. package/dist/{audit-log-DhRRCMrv.mjs → audit-log-CQnf8nrN.mjs} +442 -46
  4. package/dist/client/index.d.mts +1 -1
  5. package/dist/client/plugins/index.d.mts +45 -45
  6. package/dist/client/plugins/index.mjs +2 -2
  7. package/dist/client/react/index.d.mts +1 -1
  8. package/dist/{client-CMsC6-rl.mjs → client-BkpNva-h.mjs} +3 -2
  9. package/dist/{client-D8XKNpua.d.mts → client-g0OAVuPQ.d.mts} +1 -1
  10. package/dist/{client-CDaFOX7A.d.mts → client-zkWmSxqy.d.mts} +4 -1
  11. package/dist/cookies/index.d.mts +2 -2
  12. package/dist/db/index.d.mts +1 -1
  13. package/dist/{index-CWxKeTtE.d.mts → index-B4HTudhm.d.mts} +6 -6
  14. package/dist/{index-C8F7PsET.d.mts → index-BHiF_ZfZ.d.mts} +13 -13
  15. package/dist/{index-382PsmkK.d.mts → index-BX55rZO5.d.mts} +2 -2
  16. package/dist/{index-DUu0ieh6.d.mts → index-BfwCJQfM.d.mts} +8 -8
  17. package/dist/{index-CIxFDcfQ.d.mts → index-BhbilPfs.d.mts} +2 -2
  18. package/dist/{index-CExSHSFz.d.mts → index-Bi-vEjDm.d.mts} +166 -166
  19. package/dist/{index-C-z4TCHD.d.mts → index-BifhxQ8O.d.mts} +10 -10
  20. package/dist/{index-CWwQ1Q7t.d.mts → index-BiomZttP.d.mts} +19 -19
  21. package/dist/{index-De2a2OyC.d.mts → index-BoHrBgTB.d.mts} +9 -9
  22. package/dist/{index-DPVukjga.d.mts → index-C5W_sTlp.d.mts} +9 -9
  23. package/dist/{index-D0SgItjY.d.mts → index-CNyQFga7.d.mts} +6 -6
  24. package/dist/{index-3lfPQHhX.d.mts → index-CTjXncwM.d.mts} +113 -113
  25. package/dist/{index-Dgyj1fTk.d.mts → index-CUUaJp3R.d.mts} +7 -7
  26. package/dist/{index-DCliG2n6.d.mts → index-CcJjgkwe.d.mts} +3 -3
  27. package/dist/{index-Dg6Ftb6f.d.mts → index-Cdfh66xb.d.mts} +9 -9
  28. package/dist/{index-COFPq-mg.d.mts → index-DBtm_waB.d.mts} +13 -13
  29. package/dist/{index-B7iZf_Dl.d.mts → index-DD_pxX-h.d.mts} +662 -354
  30. package/dist/{index-Blq8KrTy.d.mts → index-DRoa3BGG.d.mts} +1 -1
  31. package/dist/{index-DxIqV3rU.d.mts → index-M0IQ_DTL.d.mts} +4 -4
  32. package/dist/{index-DxRAXHrZ.d.mts → index-gRLqvVoc.d.mts} +6 -6
  33. package/dist/{index-B4aWSJEd.d.mts → index-i1L-uguJ.d.mts} +6 -6
  34. package/dist/{index-BhYE1_9j.d.mts → index-kBEBsEUr.d.mts} +1 -1
  35. package/dist/{index-B5r4oL5q.d.mts → index-mDmrBYrk.d.mts} +5 -5
  36. package/dist/index.d.mts +1 -1
  37. package/dist/integrations/next-js.d.mts +4 -4
  38. package/dist/integrations/node.d.mts +1 -1
  39. package/dist/integrations/react-start.d.mts +4 -4
  40. package/dist/oauth2/index.d.mts +1 -1
  41. package/dist/plugins/admin/index.d.mts +2 -2
  42. package/dist/plugins/anonymous/index.d.mts +2 -2
  43. package/dist/plugins/audit-log/client.d.mts +23 -23
  44. package/dist/plugins/audit-log/index.d.mts +23 -23
  45. package/dist/plugins/audit-log/index.mjs +3 -3
  46. package/dist/plugins/bearer/index.d.mts +1 -1
  47. package/dist/plugins/captcha/index.d.mts +1 -1
  48. package/dist/plugins/custom-session/index.d.mts +2 -2
  49. package/dist/plugins/device-authorization/index.d.mts +1 -1
  50. package/dist/plugins/email-otp/index.d.mts +1 -1
  51. package/dist/plugins/generic-oauth/index.d.mts +2 -2
  52. package/dist/plugins/haveibeenpwned/index.d.mts +1 -1
  53. package/dist/plugins/index.d.mts +23 -23
  54. package/dist/plugins/index.mjs +5 -5
  55. package/dist/plugins/jwt/index.d.mts +2 -2
  56. package/dist/plugins/magic-link/index.d.mts +1 -1
  57. package/dist/plugins/multi-session/index.d.mts +1 -1
  58. package/dist/plugins/oauth-proxy/index.d.mts +1 -1
  59. package/dist/plugins/one-tap/index.d.mts +1 -1
  60. package/dist/plugins/one-time-token/index.d.mts +2 -2
  61. package/dist/plugins/one-time-token/index.mjs +4 -4
  62. package/dist/plugins/organization/index.d.mts +2 -2
  63. package/dist/plugins/passkey/index.d.mts +2 -2
  64. package/dist/plugins/phone-number/index.d.mts +2 -2
  65. package/dist/plugins/sentinel/client.d.mts +23 -23
  66. package/dist/plugins/sentinel/client.mjs +2 -2
  67. package/dist/plugins/sentinel/index.d.mts +22 -22
  68. package/dist/plugins/sentinel/index.mjs +3 -3
  69. package/dist/plugins/two-factor/index.d.mts +2 -2
  70. package/dist/plugins/username/index.d.mts +1 -1
  71. package/dist/{registry-GztLf62p.mjs → registry-BjYhRF79.mjs} +69 -2
  72. package/dist/{sentinel-CYtaI3eO.mjs → sentinel-BttZLWPD.mjs} +109 -28
  73. package/dist/src/plugins/audit-log/error-codes.d.ts +7 -0
  74. package/dist/src/plugins/audit-log/events.d.ts +13 -0
  75. package/dist/src/plugins/audit-log/index.d.ts +114 -8
  76. package/dist/src/plugins/audit-log/integrity.d.ts +20 -0
  77. package/dist/src/plugins/audit-log/redact.d.ts +18 -0
  78. package/dist/src/plugins/audit-log/remote.d.ts +1 -0
  79. package/dist/src/plugins/audit-log/schema.d.ts +25 -0
  80. package/dist/src/plugins/audit-log/types.d.ts +73 -13
  81. package/dist/src/plugins/sentinel/actions.d.ts +0 -6
  82. package/dist/src/plugins/sentinel/client.d.ts +3 -0
  83. package/dist/src/plugins/sentinel/error-codes.d.ts +6 -0
  84. package/dist/src/plugins/sentinel/index.d.ts +80 -3
  85. package/dist/src/plugins/sentinel/types.d.ts +1 -1
  86. package/dist/test-utils/index.d.mts +273 -273
  87. package/dist/test-utils/index.mjs +4 -4
  88. package/dist/types/index.d.mts +1 -1
  89. package/package.json +3 -3
  90. /package/dist/{pow-DvkUopsK.mjs → pow-Vna_j4hx.mjs} +0 -0
@@ -1,9 +1,9 @@
1
1
  import "../../helper-BgOIGHsu.mjs";
2
- import "../../index-3lfPQHhX.mjs";
2
+ import "../../index-CTjXncwM.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
7
  import { a as memberAc, i as defaultStatements, n as defaultAc, o as ownerAc, r as defaultRoles, t as adminAc } from "../../index-QmocqGM-.mjs";
8
- import { A as organizationRoleSchema, C as TeamInput, D as invitationSchema, E as defaultRolesSchema, F as OrganizationOptions, M as roleSchema, N as teamMemberSchema, O as invitationStatus, P as teamSchema, S as Team, T as TeamMemberInput, _ as MemberInput, a as organization, b as OrganizationRole, c as InferMember, d as InferOrganizationZodRolesFromOption, f as InferTeam, g as Member, h as InvitationStatus, i as TeamEndpoints, j as organizationSchema, k as memberSchema, l as InferOrganization, m as InvitationInput, n as OrganizationEndpoints, o as parseRoles, p as Invitation, r as OrganizationPlugin, s as InferInvitation, t as DynamicAccessControlEndpoints, u as InferOrganizationRolesFromOption, v as Organization, w as TeamMember, x as OrganizationSchema, y as OrganizationInput } from "../../index-CExSHSFz.mjs";
8
+ import { A as organizationRoleSchema, C as TeamInput, D as invitationSchema, E as defaultRolesSchema, F as OrganizationOptions, M as roleSchema, N as teamMemberSchema, O as invitationStatus, P as teamSchema, S as Team, T as TeamMemberInput, _ as MemberInput, a as organization, b as OrganizationRole, c as InferMember, d as InferOrganizationZodRolesFromOption, f as InferTeam, g as Member, h as InvitationStatus, i as TeamEndpoints, j as organizationSchema, k as memberSchema, l as InferOrganization, m as InvitationInput, n as OrganizationEndpoints, o as parseRoles, p as Invitation, r as OrganizationPlugin, s as InferInvitation, t as DynamicAccessControlEndpoints, u as InferOrganizationRolesFromOption, v as Organization, w as TeamMember, x as OrganizationSchema, y as OrganizationInput } from "../../index-Bi-vEjDm.mjs";
9
9
  export { DynamicAccessControlEndpoints, InferInvitation, InferMember, InferOrganization, InferOrganizationRolesFromOption, InferOrganizationZodRolesFromOption, InferTeam, Invitation, InvitationInput, InvitationStatus, Member, MemberInput, Organization, OrganizationEndpoints, OrganizationInput, OrganizationOptions, OrganizationPlugin, OrganizationRole, OrganizationSchema, Team, TeamEndpoints, TeamInput, TeamMember, TeamMemberInput, adminAc, defaultAc, defaultRoles, defaultRolesSchema, defaultStatements, invitationSchema, invitationStatus, memberAc, memberSchema, organization, organizationRoleSchema, organizationSchema, ownerAc, parseRoles, roleSchema, teamMemberSchema, teamSchema };
@@ -1,7 +1,7 @@
1
1
  import "../../helper-BgOIGHsu.mjs";
2
- import "../../index-3lfPQHhX.mjs";
2
+ import "../../index-CTjXncwM.mjs";
3
3
  import "../../types-DNQ9XQrB.mjs";
4
4
  import "../../index-BL_t8cRp-C4QYBsac.mjs";
5
5
  import "../../plugins-Dy_FrD4Y.mjs";
6
- import { n as Passkey, r as PasskeyOptions, t as passkey } from "../../index-COFPq-mg.mjs";
6
+ import { n as Passkey, r as PasskeyOptions, t as passkey } from "../../index-DBtm_waB.mjs";
7
7
  export { Passkey, PasskeyOptions, passkey };
@@ -1,7 +1,7 @@
1
1
  import "../../helper-BgOIGHsu.mjs";
2
- import "../../index-3lfPQHhX.mjs";
2
+ import "../../index-CTjXncwM.mjs";
3
3
  import "../../types-DNQ9XQrB.mjs";
4
4
  import "../../index-BL_t8cRp-C4QYBsac.mjs";
5
5
  import "../../plugins-Dy_FrD4Y.mjs";
6
- import { n as UserWithPhoneNumber, r as phoneNumber, t as PhoneNumberOptions } from "../../index-Dgyj1fTk.mjs";
6
+ import { n as UserWithPhoneNumber, r as phoneNumber, t as PhoneNumberOptions } from "../../index-CUUaJp3R.mjs";
7
7
  export { PhoneNumberOptions, UserWithPhoneNumber, phoneNumber };
@@ -1,30 +1,30 @@
1
1
  import "../../helper-BgOIGHsu.mjs";
2
- import "../../index-3lfPQHhX.mjs";
2
+ import "../../index-CTjXncwM.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 "../../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-DRoa3BGG.mjs";
8
+ import "../../index-i1L-uguJ.mjs";
9
+ import "../../index-DD_pxX-h.mjs";
10
+ import "../../index-B4HTudhm.mjs";
11
+ import "../../index-BX55rZO5.mjs";
12
+ import "../../index-CNyQFga7.mjs";
13
+ import "../../index-gRLqvVoc.mjs";
14
+ import "../../index-BHiF_ZfZ.mjs";
15
+ import "../../index-BfwCJQfM.mjs";
16
+ import "../../index-CcJjgkwe.mjs";
17
+ import "../../index-C5W_sTlp.mjs";
18
+ import "../../index-M0IQ_DTL.mjs";
19
+ import "../../index-Cdfh66xb.mjs";
20
+ import "../../index-BifhxQ8O.mjs";
21
+ import "../../index-BhbilPfs.mjs";
22
+ import "../../index-mDmrBYrk.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";
29
- import { t as sentinelClient } from "../../client-CDaFOX7A.mjs";
24
+ import "../../index-Bi-vEjDm.mjs";
25
+ import "../../index-CUUaJp3R.mjs";
26
+ import "../../index-BiomZttP.mjs";
27
+ import "../../index-DBtm_waB.mjs";
28
+ import "../../index-BoHrBgTB.mjs";
29
+ import { t as sentinelClient } from "../../client-zkWmSxqy.mjs";
30
30
  export { sentinelClient };
@@ -1,5 +1,5 @@
1
1
  import "../../random-32E3cU5o.mjs";
2
- import "../../pow-DvkUopsK.mjs";
3
- import { t as sentinelClient } from "../../client-CMsC6-rl.mjs";
2
+ import "../../pow-Vna_j4hx.mjs";
3
+ import { t as sentinelClient } from "../../client-BkpNva-h.mjs";
4
4
 
5
5
  export { sentinelClient };
@@ -1,29 +1,29 @@
1
1
  import "../../helper-BgOIGHsu.mjs";
2
- import "../../index-3lfPQHhX.mjs";
2
+ import "../../index-CTjXncwM.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-DRoa3BGG.mjs";
8
+ import "../../index-i1L-uguJ.mjs";
9
+ import { A as verifySolution, C as POW_CHALLENGE_HEADER, D as hasLeadingZeroBits, E as createNonce, F as SentinelOptions, M as normalizeEmail, N as GeoLocation, O as parsePowHeader, P as SecurityAction, S as SENTINEL_ERROR_CODES, T as POW_SOLUTION_HEADER, j as haversineDistanceKm, k as solveChallenge, w as POW_REASON_HEADER, x as sentinel } from "../../index-DD_pxX-h.mjs";
10
+ import "../../index-B4HTudhm.mjs";
11
+ import "../../index-BX55rZO5.mjs";
12
+ import "../../index-CNyQFga7.mjs";
13
+ import "../../index-gRLqvVoc.mjs";
14
+ import "../../index-BHiF_ZfZ.mjs";
15
+ import "../../index-BfwCJQfM.mjs";
16
+ import "../../index-CcJjgkwe.mjs";
17
+ import "../../index-C5W_sTlp.mjs";
18
+ import "../../index-M0IQ_DTL.mjs";
19
+ import "../../index-Cdfh66xb.mjs";
20
+ import "../../index-BifhxQ8O.mjs";
21
+ import "../../index-BhbilPfs.mjs";
22
+ import "../../index-mDmrBYrk.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-Bi-vEjDm.mjs";
25
+ import "../../index-CUUaJp3R.mjs";
26
+ import "../../index-BiomZttP.mjs";
27
+ import "../../index-DBtm_waB.mjs";
28
+ import "../../index-BoHrBgTB.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 };
@@ -14,9 +14,9 @@ import "../../get-tables-CKvSyDST.mjs";
14
14
  import "../../types-DCPpFKUB.mjs";
15
15
  import "../../misc-fKH4d5XQ.mjs";
16
16
  import "../../session-BB3oqApE.mjs";
17
- import "../../registry-GztLf62p.mjs";
17
+ import "../../registry-BjYhRF79.mjs";
18
18
  import "../../haveibeenpwned-_3a5amT-.mjs";
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";
19
+ import { i as SENTINEL_ERROR_CODES, n as haversineDistanceKm, r as normalizeEmail, t as sentinel } from "../../sentinel-BttZLWPD.mjs";
20
+ 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-Vna_j4hx.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-CTjXncwM.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-BiomZttP.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-BoHrBgTB.mjs";
4
4
  export { USERNAME_ERROR_CODES, UsernameOptions, username };
@@ -66,7 +66,9 @@ const AUDIT_EVENT_TYPES = {
66
66
  TEAM_MEMBER_ADDED: "team_member_added",
67
67
  TEAM_MEMBER_REMOVED: "team_member_removed",
68
68
  USER_SIGN_IN_FAILED: "user_sign_in_failed",
69
- VERIFICATION_FAILED: "verification_failed"
69
+ VERIFICATION_FAILED: "verification_failed",
70
+ AUDIT_READ: "audit_read",
71
+ AUDIT_EVENTS_DELETED: "audit_events_deleted"
70
72
  };
71
73
  /**
72
74
  * Security event types recorded by the sentinel plugin
@@ -89,6 +91,34 @@ const SECURITY_EVENT_TYPES = {
89
91
  UNBLOCKED: "security_unblocked"
90
92
  };
91
93
  const ALL_EVENT_TYPES = [...Object.values(AUDIT_EVENT_TYPES), ...Object.values(SECURITY_EVENT_TYPES)];
94
+ /**
95
+ * The events that can't be excluded: who signed in or out and who failed to,
96
+ * changes to credentials, roles, bans and sessions, impersonation, reads and
97
+ * deletions of the audit log itself, and every security decision.
98
+ */
99
+ const CORE_EVENT_TYPES = [
100
+ AUDIT_EVENT_TYPES.USER_SIGNED_UP,
101
+ AUDIT_EVENT_TYPES.USER_SIGNED_IN,
102
+ AUDIT_EVENT_TYPES.USER_SIGNED_OUT,
103
+ AUDIT_EVENT_TYPES.USER_SIGN_IN_FAILED,
104
+ AUDIT_EVENT_TYPES.VERIFICATION_FAILED,
105
+ AUDIT_EVENT_TYPES.SESSION_REVOKED,
106
+ AUDIT_EVENT_TYPES.SESSIONS_REVOKED_ALL,
107
+ AUDIT_EVENT_TYPES.USER_BANNED,
108
+ AUDIT_EVENT_TYPES.USER_UNBANNED,
109
+ AUDIT_EVENT_TYPES.USER_DELETED,
110
+ AUDIT_EVENT_TYPES.USER_ROLE_UPDATED,
111
+ AUDIT_EVENT_TYPES.USER_EMAIL_CHANGED,
112
+ AUDIT_EVENT_TYPES.PASSWORD_CHANGED,
113
+ AUDIT_EVENT_TYPES.PASSWORD_RESET_COMPLETED,
114
+ AUDIT_EVENT_TYPES.TWO_FACTOR_ENABLED,
115
+ AUDIT_EVENT_TYPES.TWO_FACTOR_DISABLED,
116
+ AUDIT_EVENT_TYPES.USER_IMPERSONATED,
117
+ AUDIT_EVENT_TYPES.USER_IMPERSONATION_STOPPED,
118
+ AUDIT_EVENT_TYPES.AUDIT_READ,
119
+ AUDIT_EVENT_TYPES.AUDIT_EVENTS_DELETED,
120
+ ...Object.values(SECURITY_EVENT_TYPES)
121
+ ];
92
122
  /** Endpoints that complete a sign-in by creating a session */
93
123
  const SIGN_IN_PATHS = [
94
124
  "/sign-in/email",
@@ -185,6 +215,43 @@ const PATH_EVENTS = {
185
215
  "/organization/add-team-member": AUDIT_EVENT_TYPES.TEAM_MEMBER_ADDED,
186
216
  "/organization/remove-team-member": AUDIT_EVENT_TYPES.TEAM_MEMBER_REMOVED
187
217
  };
218
+ /**
219
+ * The severity of each event type that isn't `info`. A failed, blocked or
220
+ * challenged event is at least `warning`.
221
+ */
222
+ const EVENT_SEVERITIES = {
223
+ [AUDIT_EVENT_TYPES.USER_BANNED]: "critical",
224
+ [AUDIT_EVENT_TYPES.USER_DELETED]: "critical",
225
+ [AUDIT_EVENT_TYPES.USER_ROLE_UPDATED]: "critical",
226
+ [AUDIT_EVENT_TYPES.USER_IMPERSONATED]: "critical",
227
+ [AUDIT_EVENT_TYPES.TWO_FACTOR_DISABLED]: "critical",
228
+ [AUDIT_EVENT_TYPES.USER_EMAIL_CHANGED]: "warning",
229
+ [AUDIT_EVENT_TYPES.PASSWORD_CHANGED]: "warning",
230
+ [AUDIT_EVENT_TYPES.PASSWORD_RESET_COMPLETED]: "warning",
231
+ [AUDIT_EVENT_TYPES.SESSIONS_REVOKED_ALL]: "warning",
232
+ [AUDIT_EVENT_TYPES.ACCOUNT_UNLINKED]: "warning",
233
+ [AUDIT_EVENT_TYPES.PASSKEY_REMOVED]: "warning",
234
+ [AUDIT_EVENT_TYPES.API_KEY_CREATED]: "warning",
235
+ [AUDIT_EVENT_TYPES.API_KEY_DELETED]: "warning",
236
+ [AUDIT_EVENT_TYPES.MEMBER_ROLE_UPDATED]: "warning",
237
+ [AUDIT_EVENT_TYPES.ORGANIZATION_DELETED]: "critical",
238
+ [AUDIT_EVENT_TYPES.USER_SIGN_IN_FAILED]: "warning",
239
+ [AUDIT_EVENT_TYPES.VERIFICATION_FAILED]: "warning",
240
+ [SECURITY_EVENT_TYPES.BLOCKED]: "warning",
241
+ [SECURITY_EVENT_TYPES.CREDENTIAL_STUFFING]: "warning",
242
+ [SECURITY_EVENT_TYPES.IMPOSSIBLE_TRAVEL]: "critical",
243
+ [SECURITY_EVENT_TYPES.GEO_BLOCKED]: "warning",
244
+ [SECURITY_EVENT_TYPES.BOT_BLOCKED]: "warning",
245
+ [SECURITY_EVENT_TYPES.SUSPICIOUS_IP]: "warning",
246
+ [SECURITY_EVENT_TYPES.VELOCITY_EXCEEDED]: "warning",
247
+ [SECURITY_EVENT_TYPES.FREE_TRIAL_ABUSE]: "warning",
248
+ [SECURITY_EVENT_TYPES.COMPROMISED_PASSWORD]: "critical",
249
+ [SECURITY_EVENT_TYPES.STALE_ACCOUNT]: "warning",
250
+ [SECURITY_EVENT_TYPES.INVALID_EMAIL]: "warning",
251
+ [SECURITY_EVENT_TYPES.UNBLOCKED]: "warning",
252
+ [AUDIT_EVENT_TYPES.AUDIT_READ]: "warning",
253
+ [AUDIT_EVENT_TYPES.AUDIT_EVENTS_DELETED]: "critical"
254
+ };
188
255
 
189
256
  //#endregion
190
257
  //#region src/plugins/audit-log/registry.ts
@@ -203,4 +270,4 @@ function getAuditRecorder(context) {
203
270
  }
204
271
 
205
272
  //#endregion
206
- export { CREDENTIAL_SIGN_IN_PATHS as a, SIGN_IN_PATHS as c, AUDIT_EVENT_TYPES as i, VERIFICATION_PATHS as l, registerAuditRecorder as n, PATH_EVENTS as o, ALL_EVENT_TYPES as r, SECURITY_EVENT_TYPES as s, getAuditRecorder as t, hasRole as u };
273
+ export { CORE_EVENT_TYPES as a, PATH_EVENTS as c, VERIFICATION_PATHS as d, hasRole as f, AUDIT_EVENT_TYPES as i, SECURITY_EVENT_TYPES as l, registerAuditRecorder as n, CREDENTIAL_SIGN_IN_PATHS as o, ALL_EVENT_TYPES as r, EVENT_SEVERITIES as s, getAuditRecorder as t, SIGN_IN_PATHS as u };
@@ -3,9 +3,9 @@ import { t as safeJSONParse } from "./json-D0TBLy4q.mjs";
3
3
  import { n as deleteSessionCookie } from "./cookies-BuvlgcA-.mjs";
4
4
  import { n as mergeSchema } from "./date-CMr04reD.mjs";
5
5
  import { u as sessionMiddleware } from "./session-BB3oqApE.mjs";
6
- import { a as CREDENTIAL_SIGN_IN_PATHS, c as SIGN_IN_PATHS, l as VERIFICATION_PATHS, s as SECURITY_EVENT_TYPES, t as getAuditRecorder, u as hasRole } from "./registry-GztLf62p.mjs";
6
+ import { d as VERIFICATION_PATHS, f as hasRole, l as SECURITY_EVENT_TYPES, o as CREDENTIAL_SIGN_IN_PATHS, t as getAuditRecorder, u as SIGN_IN_PATHS } from "./registry-BjYhRF79.mjs";
7
7
  import { t as getPasswordBreachCount } from "./haveibeenpwned-_3a5amT-.mjs";
8
- import { c as verifySolution, i as createNonce, n as POW_REASON_HEADER, o as parsePowHeader, r as POW_SOLUTION_HEADER, t as POW_CHALLENGE_HEADER } from "./pow-DvkUopsK.mjs";
8
+ import { c as verifySolution, i as createNonce, n as POW_REASON_HEADER, o as parsePowHeader, r as POW_SOLUTION_HEADER, t as POW_CHALLENGE_HEADER } from "./pow-Vna_j4hx.mjs";
9
9
  import { env } from "@gatwech/core/env";
10
10
  import { PayvoAuthError } from "@gatwech/core/error";
11
11
  import { defineErrorCodes } from "@gatwech/core/utils";
@@ -14,6 +14,15 @@ import { createAuthEndpoint, createAuthMiddleware } from "@gatwech/core/api";
14
14
  import * as z$1 from "zod";
15
15
  import { betterFetch } from "@better-fetch/fetch";
16
16
 
17
+ //#region src/plugins/sentinel/error-codes.ts
18
+ const SENTINEL_ERROR_CODES = defineErrorCodes({
19
+ POW_CHALLENGE_REQUIRED: "Challenge required",
20
+ SECURITY_BLOCKED: "Request blocked for security reasons",
21
+ SECURITY_ADMIN_REQUIRED: "Only an administrator can manage security blocks",
22
+ BLOCK_NOT_FOUND: "That block doesn't exist or has ended"
23
+ });
24
+
25
+ //#endregion
17
26
  //#region src/plugins/sentinel/actions.ts
18
27
  const CHALLENGE_TTL_MS = 6e4;
19
28
  /**
@@ -111,12 +120,6 @@ function challengeHeaders(decision) {
111
120
  "access-control-expose-headers": `${POW_CHALLENGE_HEADER}, ${POW_REASON_HEADER}`
112
121
  };
113
122
  }
114
- const SENTINEL_ERROR_CODES = defineErrorCodes({
115
- POW_CHALLENGE_REQUIRED: "Challenge required",
116
- SECURITY_BLOCKED: "Request blocked for security reasons",
117
- SECURITY_ADMIN_REQUIRED: "Only an administrator can manage security blocks",
118
- BLOCK_NOT_FOUND: "That block doesn't exist or has ended"
119
- });
120
123
  /** The error for a decision, or null when the request is allowed */
121
124
  function errorForDecision(decision) {
122
125
  if (decision.outcome === "allow") return null;
@@ -1240,6 +1243,39 @@ const sentinel = (options) => {
1240
1243
  }));
1241
1244
  return Math.max(0, ...failures);
1242
1245
  }
1246
+ /**
1247
+ * Blocks an attempt counter for the cooldown and clears its counts. The
1248
+ * block is also recorded so an admin can list and lift it; it holds
1249
+ * without the record.
1250
+ */
1251
+ async function blockKey(auth, store, key, also = []) {
1252
+ if (!credentialStuffing) return;
1253
+ const { cooldownSeconds } = credentialStuffing;
1254
+ await store.increment(`${key}:blocked`, cooldownSeconds);
1255
+ await Promise.all([key, ...also].map((name) => store.reset(name)));
1256
+ await store.recordBlock({
1257
+ key,
1258
+ feature: "credential_stuffing",
1259
+ ...describeAttemptKey(key),
1260
+ blockedUntil: new Date(Date.now() + cooldownSeconds * 1e3)
1261
+ }).catch((e) => {
1262
+ auth.logger.error("[sentinel] Failed to record block", e);
1263
+ });
1264
+ }
1265
+ /**
1266
+ * Turns the counters that passed the block threshold into blocks that last
1267
+ * the cooldown, so they end then and can be listed and lifted. `count`
1268
+ * includes the attempt just made.
1269
+ */
1270
+ async function blockOverThreshold(auth, store, keys) {
1271
+ if (!credentialStuffing) return;
1272
+ const { thresholds } = credentialStuffing;
1273
+ for (const { scope, account } of keys) {
1274
+ const [total, succeeded] = await Promise.all([store.get(scope), store.get(`${scope}:succeeded`)]);
1275
+ if (total - succeeded - 1 >= thresholds.block) await blockKey(auth, store, scope, [`${scope}:succeeded`]);
1276
+ if (account && await store.get(account) - 1 >= thresholds.block) await blockKey(auth, store, account);
1277
+ }
1278
+ }
1243
1279
  /** What an attempt counter's key is for: `cs:ip:<ip>` or `cs:visitor:<id>`, plus `:account:<email>` */
1244
1280
  function describeAttemptKey(key) {
1245
1281
  const accountAt = key.indexOf(":account:");
@@ -1581,7 +1617,10 @@ const sentinel = (options) => {
1581
1617
  failedAttempts: failures,
1582
1618
  thresholds
1583
1619
  };
1584
- if (blocked || failures >= thresholds.block) return act(ctx, store, details, credentialStuffing.action === "log" ? "log" : "block", SECURITY_EVENT_TYPES.CREDENTIAL_STUFFING, "credential_stuffing", metadata);
1620
+ if (blocked || failures >= thresholds.block) {
1621
+ if (!blocked && credentialStuffing.action !== "log") await blockOverThreshold(ctx.context, store, keys);
1622
+ return act(ctx, store, details, credentialStuffing.action === "log" ? "log" : "block", SECURITY_EVENT_TYPES.CREDENTIAL_STUFFING, "credential_stuffing", metadata);
1623
+ }
1585
1624
  if (failures >= thresholds.challenge) return act(ctx, store, details, credentialStuffing.action === "log" ? "log" : "challenge", SECURITY_EVENT_TYPES.CREDENTIAL_STUFFING, "credential_stuffing", metadata);
1586
1625
  return { outcome: "allow" };
1587
1626
  }));
@@ -1635,7 +1674,7 @@ const sentinel = (options) => {
1635
1674
  try {
1636
1675
  const store = createSentinelStore(ctx.context);
1637
1676
  const keys = attemptKeys(await requestDetails(ctx));
1638
- const { windowSeconds, cooldownSeconds, thresholds } = credentialStuffing;
1677
+ const { windowSeconds, thresholds } = credentialStuffing;
1639
1678
  if (status < 400) for (const { scope, account } of keys) {
1640
1679
  const [total, succeeded, own] = await Promise.all([
1641
1680
  store.get(scope),
@@ -1649,18 +1688,7 @@ const sentinel = (options) => {
1649
1688
  } else await store.increment(`${scope}:succeeded`, windowSeconds);
1650
1689
  }
1651
1690
  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
- };
1691
+ const block = (key, also = []) => blockKey(ctx.context, store, key, also);
1664
1692
  for (const { scope, account } of keys) {
1665
1693
  const [total, succeeded] = await Promise.all([store.get(scope), store.get(`${scope}:succeeded`)]);
1666
1694
  if (total - succeeded >= thresholds.block) await block(scope, [`${scope}:succeeded`]);
@@ -1805,17 +1833,62 @@ const sentinel = (options) => {
1805
1833
  ...normalizedEmailSchema
1806
1834
  } : schema, opts.schema),
1807
1835
  endpoints: {
1808
- listBlocks: createAuthEndpoint("/sentinel/blocks", {
1836
+ listBlocks: createAuthEndpoint("/sentinel/list-blocks", {
1809
1837
  method: "GET",
1810
1838
  use: [sessionMiddleware],
1811
1839
  query: z$1.object({
1812
- limit: z$1.string().or(z$1.number()).optional(),
1813
- offset: z$1.string().or(z$1.number()).optional()
1840
+ limit: z$1.string().or(z$1.number()).meta({ description: "The number of blocks to return. Max 100, defaults to 50" }).optional(),
1841
+ offset: z$1.string().or(z$1.number()).meta({ description: "The offset to start from" }).optional()
1814
1842
  }).optional(),
1815
1843
  metadata: { openapi: {
1816
1844
  operationId: "listSentinelBlocks",
1817
1845
  summary: "List active blocks",
1818
- description: "List the visitors and IP addresses sentinel is blocking, for admins"
1846
+ description: "List the visitors and IP addresses sentinel is blocking, for admins",
1847
+ responses: { 200: {
1848
+ description: "Paginated blocks that haven't ended",
1849
+ content: { "application/json": { schema: {
1850
+ type: "object",
1851
+ properties: {
1852
+ blocks: {
1853
+ type: "array",
1854
+ items: {
1855
+ type: "object",
1856
+ properties: {
1857
+ id: { type: "string" },
1858
+ key: { type: "string" },
1859
+ feature: { type: "string" },
1860
+ kind: {
1861
+ type: "string",
1862
+ enum: ["visitor", "ip"]
1863
+ },
1864
+ identifier: { type: "string" },
1865
+ account: {
1866
+ type: "string",
1867
+ nullable: true
1868
+ },
1869
+ blockedUntil: {
1870
+ type: "string",
1871
+ format: "date-time"
1872
+ },
1873
+ createdAt: {
1874
+ type: "string",
1875
+ format: "date-time"
1876
+ }
1877
+ }
1878
+ }
1879
+ },
1880
+ total: { type: "number" },
1881
+ limit: { type: "number" },
1882
+ offset: { type: "number" }
1883
+ },
1884
+ required: [
1885
+ "blocks",
1886
+ "total",
1887
+ "limit",
1888
+ "offset"
1889
+ ]
1890
+ } } }
1891
+ } }
1819
1892
  } }
1820
1893
  }, async (ctx) => {
1821
1894
  requireAdmin(ctx.context.session.user);
@@ -1835,11 +1908,19 @@ const sentinel = (options) => {
1835
1908
  unblock: createAuthEndpoint("/sentinel/unblock", {
1836
1909
  method: "POST",
1837
1910
  use: [sessionMiddleware],
1838
- body: z$1.object({ id: z$1.string() }),
1911
+ body: z$1.object({ id: z$1.string().meta({ description: "The id of the block to lift, from the list of blocks" }) }),
1839
1912
  metadata: { openapi: {
1840
1913
  operationId: "unblockSentinel",
1841
1914
  summary: "Lift a block",
1842
- description: "Lift a block before its cooldown ends, for admins. Recorded in the audit log."
1915
+ description: "Lift a block before its cooldown ends, for admins. Recorded in the audit log.",
1916
+ responses: { 200: {
1917
+ description: "The block was lifted",
1918
+ content: { "application/json": { schema: {
1919
+ type: "object",
1920
+ properties: { success: { type: "boolean" } },
1921
+ required: ["success"]
1922
+ } } }
1923
+ } }
1843
1924
  } }
1844
1925
  }, async (ctx) => {
1845
1926
  const { user } = ctx.context.session;
@@ -0,0 +1,7 @@
1
+ export declare const AUDIT_LOG_ERROR_CODES: {
2
+ readonly AUDIT_LOG_ACCESS_DENIED: "You don't have access to these audit logs";
3
+ readonly AUDIT_CANNOT_BE_DISABLED: "Core audit events and the local audit store can't be turned off";
4
+ readonly AUDIT_LOG_UNAVAILABLE: "Audit logs are temporarily unavailable";
5
+ readonly AUDIT_RETENTION_TOO_SHORT: "Audit events can't be deleted before the retention minimum has passed";
6
+ readonly AUDIT_SIGNING_SECRET_MISSING: "Audit events must be signed in production: set integrity.secret or PAYVO_AUDIT_SIGNING_SECRET";
7
+ };
@@ -55,6 +55,8 @@ export declare const AUDIT_EVENT_TYPES: {
55
55
  readonly TEAM_MEMBER_REMOVED: "team_member_removed";
56
56
  readonly USER_SIGN_IN_FAILED: "user_sign_in_failed";
57
57
  readonly VERIFICATION_FAILED: "verification_failed";
58
+ readonly AUDIT_READ: "audit_read";
59
+ readonly AUDIT_EVENTS_DELETED: "audit_events_deleted";
58
60
  };
59
61
  /**
60
62
  * Security event types recorded by the sentinel plugin
@@ -78,6 +80,12 @@ export declare const SECURITY_EVENT_TYPES: {
78
80
  };
79
81
  export type AuditEventType = (typeof AUDIT_EVENT_TYPES)[keyof typeof AUDIT_EVENT_TYPES] | (typeof SECURITY_EVENT_TYPES)[keyof typeof SECURITY_EVENT_TYPES];
80
82
  export declare const ALL_EVENT_TYPES: AuditEventType[];
83
+ /**
84
+ * The events that can't be excluded: who signed in or out and who failed to,
85
+ * changes to credentials, roles, bans and sessions, impersonation, reads and
86
+ * deletions of the audit log itself, and every security decision.
87
+ */
88
+ export declare const CORE_EVENT_TYPES: ("user_signed_up" | "user_banned" | "user_unbanned" | "user_deleted" | "user_role_updated" | "user_email_changed" | "user_signed_in" | "user_signed_out" | "session_revoked" | "sessions_revoked_all" | "user_impersonated" | "user_impersonation_stopped" | "password_changed" | "two_factor_enabled" | "two_factor_disabled" | "password_reset_completed" | "user_sign_in_failed" | "verification_failed" | "audit_read" | "audit_events_deleted" | "security_blocked" | "security_allowed" | "security_credential_stuffing" | "security_impossible_travel" | "security_geo_blocked" | "security_bot_blocked" | "security_suspicious_ip" | "security_velocity_exceeded" | "security_free_trial_abuse" | "security_compromised_password" | "security_stale_account" | "security_invalid_email" | "security_unblocked")[];
81
89
  /** Endpoints that complete a sign-in by creating a session */
82
90
  export declare const SIGN_IN_PATHS: string[];
83
91
  /** Sign-in endpoints that check credentials, so a failure is a failed attempt */
@@ -89,3 +97,8 @@ export declare const CREDENTIAL_SIGN_IN_PATHS: string[];
89
97
  export declare const VERIFICATION_PATHS: string[];
90
98
  /** Endpoints whose successful response maps to a single event */
91
99
  export declare const PATH_EVENTS: Record<string, AuditEventType>;
100
+ /**
101
+ * The severity of each event type that isn't `info`. A failed, blocked or
102
+ * challenged event is at least `warning`.
103
+ */
104
+ export declare const EVENT_SEVERITIES: Partial<Record<AuditEventType, "warning" | "critical">>;