@gatwech/auth 1.0.0-beta.18 → 1.0.0-beta.20

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 (225) hide show
  1. package/README.md +8 -14
  2. package/dist/{access-C6O_osEz.mjs → access-CrwEFPHE.mjs} +1 -1
  3. package/dist/{access-DT1f6l5k.mjs → access-bhklJd7m.mjs} +1 -1
  4. package/dist/{adapter-factory-BZ2Qiqpn.mjs → adapter-factory-xbLUJt85.mjs} +2 -2
  5. package/dist/adapters/drizzle-adapter/index.mjs +6 -5
  6. package/dist/adapters/index.d.mts +5 -5
  7. package/dist/adapters/index.mjs +6 -5
  8. package/dist/adapters/kysely-adapter/index.d.mts +1 -1
  9. package/dist/adapters/kysely-adapter/index.mjs +8 -7
  10. package/dist/adapters/memory-adapter/index.d.mts +1 -1
  11. package/dist/adapters/memory-adapter/index.mjs +6 -5
  12. package/dist/adapters/mongodb-adapter/index.mjs +6 -5
  13. package/dist/adapters/prisma-adapter/index.mjs +6 -5
  14. package/dist/adapters/test.mjs +4 -3
  15. package/dist/{admin-Bcq53Nwj.mjs → admin-BzUJL6tr.mjs} +6 -6
  16. package/dist/{anonymous-CRt1imBW.mjs → anonymous-BjlTk4gl.mjs} +5 -5
  17. package/dist/api/index.d.mts +5 -5
  18. package/dist/api/index.mjs +12 -11
  19. package/dist/{api-0pR_I-Nx.mjs → api-Dk8Yj_J5.mjs} +15 -5
  20. package/dist/audit-log-DKsUWR8O.mjs +772 -0
  21. package/dist/{auth-CBUoBX6o.mjs → auth-vfCyIIeV.mjs} +8 -8
  22. package/dist/{bearer-Djf_awfo.mjs → bearer-DvQLM00l.mjs} +2 -2
  23. package/dist/client/index.d.mts +19 -19
  24. package/dist/client/index.mjs +4 -4
  25. package/dist/client/plugins/index.d.mts +42 -34
  26. package/dist/client/plugins/index.mjs +16 -12
  27. package/dist/client/react/index.d.mts +5 -5
  28. package/dist/client/react/index.mjs +2 -2
  29. package/dist/client-4QEb0rUr.mjs +95 -0
  30. package/dist/client-C_qmyez2.d.mts +75 -0
  31. package/dist/client-DzOqXJUm.mjs +15 -0
  32. package/dist/client-F67q-Lbi.d.mts +14 -0
  33. package/dist/{client-aExCkfwm.mjs → client-xga7yFIX.mjs} +2 -2
  34. package/dist/cookies/index.d.mts +6 -6
  35. package/dist/cookies/index.mjs +2 -2
  36. package/dist/{cookies-cJObLwn1.mjs → cookies-BuvlgcA-.mjs} +1 -1
  37. package/dist/crypto/index.mjs +2 -1
  38. package/dist/{crypto-Bb42eMrH.mjs → crypto-CCyta8xj.mjs} +1 -6
  39. package/dist/{custom-session-L3t7ecsd.mjs → custom-session-DN_-pfi_.mjs} +2 -2
  40. package/dist/db/index.d.mts +5 -5
  41. package/dist/db/index.mjs +9 -8
  42. package/dist/{db-BrstmDhc.mjs → db-7vHnL1XA.mjs} +15 -9
  43. package/dist/{device-authorization-V4s3h4Mj.mjs → device-authorization-BKnNhlsz.mjs} +4 -4
  44. package/dist/{dialect-CeddeGHf.mjs → dialect-HsWUfpYY.mjs} +2 -2
  45. package/dist/{email-otp-BtDHSw14.mjs → email-otp-Dw0DypjQ.mjs} +7 -6
  46. package/dist/{generic-oauth-CL5X27ZI.mjs → generic-oauth-DFj27JY8.mjs} +4 -4
  47. package/dist/{has-permission-BpAr7uCn.mjs → has-permission-Bvg8de8g.mjs} +1 -1
  48. package/dist/{haveibeenpwned-cMpJvmzI.mjs → haveibeenpwned-CzNda7Tn.mjs} +28 -15
  49. package/dist/{index-BYMI9r_d.d.mts → index-4I1YhYhk.d.mts} +4 -4
  50. package/dist/{index-Cxi7TbLE.d.mts → index-BNhJglHC.d.mts} +122 -122
  51. package/dist/{index-DlaMq1nb.d.mts → index-BX7rl07Z.d.mts} +14 -14
  52. package/dist/{client-BOX93C3d.d.mts → index-Bml-PCqP.d.mts} +52 -52
  53. package/dist/{index-zjjNBRY2.d.mts → index-BsSKcKgO.d.mts} +6 -6
  54. package/dist/{index-Buhn3hkR.d.mts → index-CBiGsvDd.d.mts} +8 -8
  55. package/dist/{index-D_k662QG.d.mts → index-CC920PPp.d.mts} +14 -14
  56. package/dist/{index-B3n8e37d.d.mts → index-CNd5jqLl.d.mts} +7 -7
  57. package/dist/{index-BqhKCbPH.d.mts → index-CP8x1TFq.d.mts} +6 -6
  58. package/dist/{index-DKNNV1kb.d.mts → index-CofuaNMl.d.mts} +8 -8
  59. package/dist/{index-DR0xXno9.d.mts → index-CsxtcAO0.d.mts} +1 -1
  60. package/dist/{index-C7fQuk-V.d.mts → index-CxlWnL9c.d.mts} +1 -1
  61. package/dist/{index-CuFzhoS6.d.mts → index-CzpdkTdv.d.mts} +10 -10
  62. package/dist/index-D57DuhZR.d.mts +3769 -0
  63. package/dist/{index-C-u1h_WX.d.mts → index-D6ku0rUC.d.mts} +5 -5
  64. package/dist/{client-CNY0tn9g.d.mts → index-DFSRYWFI.d.mts} +21 -21
  65. package/dist/{index-BBm8nQ9Q.d.mts → index-DGeoJ4gu.d.mts} +2 -2
  66. package/dist/{index-G6V0Z_Mn.d.mts → index-DTkcY7xH.d.mts} +10 -10
  67. package/dist/{index-65G5U5DB-DSdjzreF.d.mts → index-Df0KhQRf-BEa5tdwJ.d.mts} +3 -2
  68. package/dist/{index-34ONrP8l.d.mts → index-Dnd8S4S4.d.mts} +11 -11
  69. package/dist/{index-B-XKqFvY.d.mts → index-DwPAddfE.d.mts} +11 -4
  70. package/dist/{index-DoXZYQpq.d.mts → index-DyXi7S2M.d.mts} +10 -10
  71. package/dist/{index-BHoQlf7a.d.mts → index-KhbNmMmG.d.mts} +178 -178
  72. package/dist/{index-z0KSvE5i.d.mts → index-QmocqGM-.d.mts} +1 -1
  73. package/dist/{admin-DtfO1PLg.d.mts → index-XfE0WjTN.d.mts} +36 -36
  74. package/dist/{index-DaBcikv9.d.mts → index-sb-UFLuo.d.mts} +2 -2
  75. package/dist/index.d.mts +5 -5
  76. package/dist/index.mjs +16 -15
  77. package/dist/integrations/next-js.d.mts +4 -4
  78. package/dist/integrations/next-js.mjs +2 -2
  79. package/dist/integrations/node.d.mts +5 -5
  80. package/dist/integrations/react-start.d.mts +4 -4
  81. package/dist/integrations/react-start.mjs +2 -2
  82. package/dist/{jwt-lHV4QHpD.mjs → jwt-DBN2mu0r.mjs} +4 -4
  83. package/dist/{kysely-adapter-DpzYO8Yf.mjs → kysely-adapter-Bkm1liPW.mjs} +1 -1
  84. package/dist/{magic-link-Bk-ueorR.mjs → magic-link-D9Em1aOR.mjs} +3 -3
  85. package/dist/{multi-session-DRrLKrg9.mjs → multi-session-Dno_8DxC.mjs} +5 -5
  86. package/dist/{oauth-proxy-D1sWh9B_.mjs → oauth-proxy-DW-zt8wv.mjs} +2 -2
  87. package/dist/oauth2/index.d.mts +5 -5
  88. package/dist/oauth2/index.mjs +12 -11
  89. package/dist/{one-tap-DMswkTEc.mjs → one-tap-CodeyQb8.mjs} +2 -2
  90. package/dist/{organization-BArHO_5v.mjs → organization-CkTKs7bx.mjs} +9 -9
  91. package/dist/{passkey-CcD4CnhM.mjs → passkey-JNQTz5a0.mjs} +5 -5
  92. package/dist/{phone-number-rHDIlh-2.mjs → phone-number-Dqz8aeyF.mjs} +4 -4
  93. package/dist/plugins/access/index.d.mts +2 -2
  94. package/dist/plugins/access/index.mjs +1 -1
  95. package/dist/plugins/admin/access/index.d.mts +2 -2
  96. package/dist/plugins/admin/access/index.mjs +2 -2
  97. package/dist/plugins/admin/index.d.mts +7 -8
  98. package/dist/plugins/admin/index.mjs +17 -16
  99. package/dist/plugins/anonymous/index.d.mts +6 -6
  100. package/dist/plugins/anonymous/index.mjs +13 -12
  101. package/dist/plugins/audit-log/client.d.mts +30 -0
  102. package/dist/plugins/audit-log/client.mjs +3 -0
  103. package/dist/plugins/audit-log/index.d.mts +29 -0
  104. package/dist/plugins/audit-log/index.mjs +20 -0
  105. package/dist/plugins/bearer/index.d.mts +1 -1
  106. package/dist/plugins/bearer/index.mjs +3 -3
  107. package/dist/plugins/captcha/index.d.mts +1 -1
  108. package/dist/plugins/captcha/index.mjs +1 -1
  109. package/dist/plugins/custom-session/index.d.mts +6 -6
  110. package/dist/plugins/custom-session/index.mjs +14 -13
  111. package/dist/plugins/device-authorization/index.d.mts +3 -3
  112. package/dist/plugins/device-authorization/index.mjs +13 -12
  113. package/dist/plugins/email-otp/index.d.mts +2 -2
  114. package/dist/plugins/email-otp/index.mjs +14 -13
  115. package/dist/plugins/generic-oauth/index.d.mts +6 -6
  116. package/dist/plugins/generic-oauth/index.mjs +13 -12
  117. package/dist/plugins/haveibeenpwned/index.d.mts +2 -2
  118. package/dist/plugins/haveibeenpwned/index.mjs +14 -13
  119. package/dist/plugins/index.d.mts +29 -139
  120. package/dist/plugins/index.mjs +47 -42
  121. package/dist/plugins/jwt/index.d.mts +6 -6
  122. package/dist/plugins/jwt/index.mjs +13 -12
  123. package/dist/plugins/magic-link/index.d.mts +1 -1
  124. package/dist/plugins/magic-link/index.mjs +13 -12
  125. package/dist/plugins/multi-session/index.d.mts +2 -2
  126. package/dist/plugins/multi-session/index.mjs +13 -12
  127. package/dist/plugins/oauth-proxy/index.d.mts +1 -1
  128. package/dist/plugins/oauth-proxy/index.mjs +13 -12
  129. package/dist/plugins/one-tap/index.d.mts +1 -1
  130. package/dist/plugins/one-tap/index.mjs +13 -12
  131. package/dist/plugins/one-time-token/index.d.mts +6 -6
  132. package/dist/plugins/one-time-token/index.mjs +46 -41
  133. package/dist/plugins/organization/access/index.d.mts +3 -3
  134. package/dist/plugins/organization/access/index.mjs +2 -2
  135. package/dist/plugins/organization/index.d.mts +8 -8
  136. package/dist/plugins/organization/index.mjs +17 -16
  137. package/dist/plugins/passkey/index.d.mts +6 -6
  138. package/dist/plugins/passkey/index.mjs +13 -12
  139. package/dist/plugins/phone-number/index.d.mts +6 -6
  140. package/dist/plugins/phone-number/index.mjs +13 -12
  141. package/dist/plugins/sentinel/client.d.mts +30 -0
  142. package/dist/plugins/sentinel/client.mjs +5 -0
  143. package/dist/plugins/sentinel/index.d.mts +29 -0
  144. package/dist/plugins/sentinel/index.mjs +22 -0
  145. package/dist/plugins/two-factor/index.d.mts +6 -6
  146. package/dist/plugins/two-factor/index.mjs +15 -14
  147. package/dist/plugins/username/index.d.mts +3 -3
  148. package/dist/plugins/username/index.mjs +13 -12
  149. package/dist/{plugins-hFZT3hmK.d.mts → plugins-Dy_FrD4Y.d.mts} +1 -1
  150. package/dist/{plugins-3jfNste3.mjs → plugins-yF8CFUDR.mjs} +11 -8
  151. package/dist/pow-OK01yPG3.mjs +61 -0
  152. package/dist/{proxy-CL9PZXJA.mjs → proxy-C_KXfOhk.mjs} +1 -1
  153. package/dist/random-32E3cU5o.mjs +7 -0
  154. package/dist/registry-CqG_3Qnx.mjs +194 -0
  155. package/dist/sentinel-DiPqydKG.mjs +1426 -0
  156. package/dist/{session-Dgp133Yt.mjs → session-BB3oqApE.mjs} +2 -2
  157. package/dist/src/adapters/memory-adapter/memory-adapter.d.ts +1 -1
  158. package/dist/src/adapters/prisma-adapter/test/auth.d.ts +1 -1
  159. package/dist/src/adapters/tests/auth-flow.d.ts +3 -3
  160. package/dist/src/adapters/tests/normal.d.ts +1 -1
  161. package/dist/src/adapters/tests/number-id.d.ts +3 -3
  162. package/dist/src/adapters/tests/performance.d.ts +3 -3
  163. package/dist/src/adapters/tests/transactions.d.ts +3 -3
  164. package/dist/src/api/index.d.ts +8 -8
  165. package/dist/src/client/plugins/index.d.ts +2 -0
  166. package/dist/src/plugins/admin/admin.d.ts +2 -2
  167. package/dist/src/plugins/api-key/index.d.ts +2 -2
  168. package/dist/src/plugins/audit-log/client.d.ts +10 -0
  169. package/dist/src/plugins/audit-log/events.d.ts +90 -0
  170. package/dist/src/plugins/audit-log/index.d.ts +614 -0
  171. package/dist/src/plugins/audit-log/registry.d.ts +13 -0
  172. package/dist/src/plugins/audit-log/remote.d.ts +34 -0
  173. package/dist/src/plugins/audit-log/schema.d.ts +50 -0
  174. package/dist/src/plugins/audit-log/types.d.ts +117 -0
  175. package/dist/src/plugins/email-otp/index.d.ts +1 -1
  176. package/dist/src/plugins/haveibeenpwned/index.d.ts +6 -0
  177. package/dist/src/plugins/index.d.ts +2 -0
  178. package/dist/src/plugins/multi-session/index.d.ts +8 -8
  179. package/dist/src/plugins/organization/organization.d.ts +5 -5
  180. package/dist/src/plugins/organization/routes/crud-access-control.d.ts +8 -8
  181. package/dist/src/plugins/organization/routes/crud-invites.d.ts +46 -46
  182. package/dist/src/plugins/organization/routes/crud-members.d.ts +40 -40
  183. package/dist/src/plugins/organization/routes/crud-org.d.ts +36 -36
  184. package/dist/src/plugins/organization/routes/crud-team.d.ts +50 -50
  185. package/dist/src/plugins/sentinel/actions.d.ts +64 -0
  186. package/dist/src/plugins/sentinel/client.d.ts +67 -0
  187. package/dist/src/plugins/sentinel/email.d.ts +28 -0
  188. package/dist/src/plugins/sentinel/geo.d.ts +22 -0
  189. package/dist/src/plugins/sentinel/index.d.ts +326 -0
  190. package/dist/src/plugins/sentinel/intel.d.ts +45 -0
  191. package/dist/src/plugins/sentinel/pow.d.ts +21 -0
  192. package/dist/src/plugins/sentinel/schema.d.ts +110 -0
  193. package/dist/src/plugins/sentinel/store.d.ts +37 -0
  194. package/dist/src/plugins/sentinel/types.d.ts +412 -0
  195. package/dist/src/test-utils/memory-secondary-storage.d.ts +16 -0
  196. package/dist/src/test-utils/password.d.ts +12 -0
  197. package/dist/src/test-utils/test-instance.d.ts +25 -25
  198. package/dist/test-utils/index.d.mts +293 -293
  199. package/dist/test-utils/index.mjs +53 -48
  200. package/dist/{two-factor-ClUXxom2.mjs → two-factor-CDVjxx4f.mjs} +6 -5
  201. package/dist/types/index.d.mts +5 -5
  202. package/dist/types/index.mjs +1 -1
  203. package/dist/{username-DiGklOGl.mjs → username-BHNvcvsY.mjs} +3 -3
  204. package/dist/{utils-SOMB4Px5.mjs → utils-B03WRaGi.mjs} +2 -1
  205. package/package.json +36 -3
  206. package/dist/index-CM-CFWwr.d.mts +0 -1919
  207. package/dist/index-DB7t8whN.d.mts +0 -1
  208. /package/dist/{access-BO2g7QVe.mjs → access-BM6jSA5j.mjs} +0 -0
  209. /package/dist/{bun-sqlite-dialect-CeNvMaZz.mjs → bun-sqlite-dialect-CDGusFqF.mjs} +0 -0
  210. /package/dist/{captcha-BqaMxlKC.mjs → captcha-DGP9lCRe.mjs} +0 -0
  211. /package/dist/{client-CygJhqeB.mjs → client-BuveH3MN.mjs} +0 -0
  212. /package/dist/{client-WiN43tAS.mjs → client-cBiytuOL.mjs} +0 -0
  213. /package/dist/{date-Cx2yCiC4.mjs → date-CMr04reD.mjs} +0 -0
  214. /package/dist/{esm-C-QicDNz.mjs → esm-BbvI87Z2.mjs} +0 -0
  215. /package/dist/{get-tables-BQP7YW9c.mjs → get-tables-CKvSyDST.mjs} +0 -0
  216. /package/dist/{helper-tmxW3BHj.d.mts → helper-BgOIGHsu.d.mts} +0 -0
  217. /package/dist/{misc-beA1w3XV.mjs → misc-fKH4d5XQ.mjs} +0 -0
  218. /package/dist/{node-sqlite-dialect-BcKxBQnm.mjs → node-sqlite-dialect-CIOjcg31.mjs} +0 -0
  219. /package/dist/{parser-DcrIEuXE.mjs → parser-D7EkhAjZ.mjs} +0 -0
  220. /package/dist/{password-sVC4nePO.mjs → password-5CdcAVaH.mjs} +0 -0
  221. /package/dist/{permission-DLYUF3cW.mjs → permission-CDDWgA_O.mjs} +0 -0
  222. /package/dist/{plugin-helper-4L-lzsjZ.mjs → plugin-helper-RJJBTOba.mjs} +0 -0
  223. /package/dist/{promise-8rrEHRXd.mjs → promise-D7Oo6_cY.mjs} +0 -0
  224. /package/dist/{types-Bjn15Uy6.mjs → types-DCPpFKUB.mjs} +0 -0
  225. /package/dist/{types-B1OL7hyf.d.mts → types-DNQ9XQrB.d.mts} +0 -0
@@ -0,0 +1,772 @@
1
+ import { t as getIp } from "./get-request-ip-DSjrEpGo.mjs";
2
+ import { t as generateRandomString } from "./random-32E3cU5o.mjs";
3
+ import { n as mergeSchema } from "./date-CMr04reD.mjs";
4
+ import { r as getSessionFromCtx, u as sessionMiddleware } from "./session-BB3oqApE.mjs";
5
+ import { a as CREDENTIAL_SIGN_IN_PATHS, c as SIGN_IN_PATHS, i as AUDIT_EVENT_TYPES, l as VERIFICATION_PATHS, n as registerAuditRecorder, o as PATH_EVENTS, r as ALL_EVENT_TYPES } from "./registry-CqG_3Qnx.mjs";
6
+ import { env } from "@gatwech/core/env";
7
+ import { defineErrorCodes } from "@gatwech/core/utils";
8
+ import { APIError } from "better-call";
9
+ import { createAuthEndpoint, createAuthMiddleware } from "@gatwech/core/api";
10
+ import * as z$1 from "zod";
11
+ import { betterFetch } from "@better-fetch/fetch";
12
+
13
+ //#region src/plugins/audit-log/remote.ts
14
+ /**
15
+ * Batches events and sends them to the hosted backend. Sending is never
16
+ * awaited by the auth flow, and failures are logged and dropped.
17
+ */
18
+ function createRemoteSink(options) {
19
+ if (options === false) return {
20
+ sink: null,
21
+ misconfigured: false
22
+ };
23
+ const apiKey = options?.apiKey ?? env.PAYVO_INFRA_API_KEY;
24
+ const apiUrl = options?.apiUrl ?? env.PAYVO_INFRA_API_URL;
25
+ if (!apiKey || !apiUrl) return {
26
+ sink: null,
27
+ misconfigured: Boolean(options)
28
+ };
29
+ const baseURL = apiUrl.replace(/\/+$/, "");
30
+ const timeout = options?.timeout ?? 3e3;
31
+ const maxSize = options?.batch?.maxSize ?? 25;
32
+ const flushIntervalMs = options?.batch?.flushIntervalMs ?? 2e3;
33
+ const headers = {
34
+ ...options?.headers,
35
+ authorization: `Bearer ${apiKey}`
36
+ };
37
+ let buffer = [];
38
+ let timer = null;
39
+ async function send(events, logger$1) {
40
+ const { error } = await betterFetch(`${baseURL}/v1/events`, {
41
+ method: "POST",
42
+ headers,
43
+ body: { events },
44
+ timeout
45
+ }).catch((e) => ({ error: e }));
46
+ if (error) logger$1?.error("[audit-log] Failed to send audit events", error);
47
+ }
48
+ async function flush(logger$1) {
49
+ if (timer) {
50
+ clearTimeout(timer);
51
+ timer = null;
52
+ }
53
+ if (!buffer.length) return;
54
+ const events = buffer;
55
+ buffer = [];
56
+ await send(events, logger$1);
57
+ }
58
+ return {
59
+ sink: {
60
+ push(event, logger$1) {
61
+ buffer.push(event);
62
+ if (buffer.length >= maxSize) {
63
+ flush(logger$1);
64
+ return;
65
+ }
66
+ if (!timer) {
67
+ timer = setTimeout(() => void flush(logger$1), flushIntervalMs);
68
+ timer.unref?.();
69
+ }
70
+ },
71
+ flush,
72
+ async query({ userIds, organizationIds,...query }) {
73
+ const params = new URLSearchParams();
74
+ for (const [key, value] of Object.entries(query)) if (value !== void 0) params.set(key, String(value));
75
+ for (const id of userIds ?? []) params.append("userId", id);
76
+ for (const id of organizationIds ?? []) params.append("organizationId", id);
77
+ const { data, error } = await betterFetch(`${baseURL}/v1/events?${params.toString()}`, {
78
+ headers,
79
+ timeout
80
+ });
81
+ if (error || !data) throw new Error(`Failed to query audit events: ${error?.status ?? "no response"}`);
82
+ return {
83
+ ...data,
84
+ events: data.events.map((event) => ({
85
+ ...event,
86
+ createdAt: new Date(event.createdAt)
87
+ }))
88
+ };
89
+ }
90
+ },
91
+ misconfigured: false
92
+ };
93
+ }
94
+
95
+ //#endregion
96
+ //#region src/plugins/audit-log/schema.ts
97
+ const schema = { auditLog: { fields: {
98
+ eventType: {
99
+ type: "string",
100
+ required: true
101
+ },
102
+ userId: {
103
+ type: "string",
104
+ required: false
105
+ },
106
+ identifier: {
107
+ type: "string",
108
+ required: false
109
+ },
110
+ organizationId: {
111
+ type: "string",
112
+ required: false
113
+ },
114
+ status: {
115
+ type: "string",
116
+ required: true
117
+ },
118
+ path: {
119
+ type: "string",
120
+ required: false
121
+ },
122
+ ipAddress: {
123
+ type: "string",
124
+ required: false
125
+ },
126
+ userAgent: {
127
+ type: "string",
128
+ required: false
129
+ },
130
+ visitorId: {
131
+ type: "string",
132
+ required: false
133
+ },
134
+ eventData: {
135
+ type: "json",
136
+ required: false
137
+ },
138
+ createdAt: {
139
+ type: "date",
140
+ required: true
141
+ }
142
+ } } };
143
+
144
+ //#endregion
145
+ //#region src/plugins/audit-log/index.ts
146
+ const AUDIT_LOG_ERROR_CODES = defineErrorCodes({
147
+ AUDIT_LOG_ACCESS_DENIED: "You don't have access to these audit logs",
148
+ AUDIT_LOG_UNAVAILABLE: "Audit logs are temporarily unavailable"
149
+ });
150
+ /** User fields that change as a side effect and aren't profile edits */
151
+ const INTERNAL_USER_FIELDS = new Set([
152
+ "updatedAt",
153
+ "emailVerified",
154
+ "image",
155
+ "banned",
156
+ "banReason",
157
+ "banExpires",
158
+ "lastLoginMethod",
159
+ "twoFactorEnabled",
160
+ "role"
161
+ ]);
162
+ const isDate = (value) => !Number.isNaN(new Date(value).getTime());
163
+ const auditLogQuery = {
164
+ limit: z$1.string().meta({ description: "The number of events to return. Max 100, defaults to 50" }).or(z$1.number()).optional(),
165
+ offset: z$1.string().meta({ description: "The offset to start from" }).or(z$1.number()).optional(),
166
+ eventType: z$1.string().meta({ description: "Filter by event type. Eg: \"user_signed_in\"" }).optional(),
167
+ identifier: z$1.string().meta({ description: "Filter by the actor's identifier. Eg: \"user@example.com\"" }).optional(),
168
+ organizationId: z$1.string().meta({ description: "Filter by organization" }).optional(),
169
+ userId: z$1.string().meta({ description: "Filter by user" }).optional(),
170
+ startDate: z$1.string().refine(isDate, "Invalid date").meta({ description: "Only return events created at or after this date. Eg: \"2026-01-01\"" }).optional(),
171
+ endDate: z$1.string().refine(isDate, "Invalid date").meta({ description: "Only return events created at or before this date. Eg: \"2026-01-31\"" }).optional()
172
+ };
173
+ function toPagination(query) {
174
+ const limit = Number(query.limit) || 50;
175
+ return {
176
+ limit: Math.min(Math.max(Math.trunc(limit), 1), 100),
177
+ offset: Math.max(Math.trunc(Number(query.offset) || 0), 0)
178
+ };
179
+ }
180
+ const auditLog = (options) => {
181
+ const opts = {
182
+ ...options,
183
+ database: options?.database ?? true,
184
+ trackFailedSignIns: options?.trackFailedSignIns ?? true,
185
+ adminRoles: options?.adminRoles ?? ["admin"]
186
+ };
187
+ const excluded = new Set(opts.exclude ?? []);
188
+ const { sink: remote, misconfigured } = createRemoteSink(opts.remote);
189
+ const mergedSchema = mergeSchema(schema, opts.schema);
190
+ let authContext;
191
+ /** Pending update payloads, so `update.after` knows which fields changed */
192
+ const pendingUserUpdates = /* @__PURE__ */ new WeakMap();
193
+ const noContextKey = {};
194
+ /** Users created in a request, so their first account isn't a link */
195
+ const createdUsers = /* @__PURE__ */ new WeakMap();
196
+ /**
197
+ * The signed-in actor of an audited request, keyed by the request headers
198
+ * both hooks receive. Read before the endpoint runs because some endpoints
199
+ * delete the session, and sessions are deleted without database hooks.
200
+ */
201
+ const actors = /* @__PURE__ */ new WeakMap();
202
+ /** The user an admin endpoint acted on, when the body doesn't name them */
203
+ const targets = /* @__PURE__ */ new WeakMap();
204
+ /** The organization an organization endpoint acted on */
205
+ async function resolveOrganizationId(auth, path, body, result, activeOrganizationId) {
206
+ const direct = body.organizationId ?? result.organizationId ?? result.member?.organizationId ?? result.invitation?.organizationId ?? (path === "/organization/create" || path === "/organization/update" ? result.id : void 0);
207
+ if (typeof direct === "string") return direct;
208
+ if (!path.startsWith("/organization/")) return null;
209
+ if (typeof body.teamId === "string") {
210
+ const team = await auth.adapter.findOne({
211
+ model: "team",
212
+ where: [{
213
+ field: "id",
214
+ value: body.teamId
215
+ }]
216
+ }).catch(() => null);
217
+ if (team) return team.organizationId;
218
+ }
219
+ return activeOrganizationId;
220
+ }
221
+ function requestMeta(ctx, auth) {
222
+ const headers = ctx?.headers ?? ctx?.request?.headers;
223
+ return {
224
+ path: ctx?.path ?? null,
225
+ ipAddress: headers ? getIp(headers, auth.options) : null,
226
+ userAgent: headers?.get("user-agent") ?? null,
227
+ visitorId: headers?.get("x-visitor-id") ?? null
228
+ };
229
+ }
230
+ /**
231
+ * The signed-in user making a request, and the admin impersonating them,
232
+ * when known
233
+ */
234
+ function actorOf(ctx) {
235
+ const session = (ctx?.context)?.session;
236
+ if (session?.user?.id) return {
237
+ id: session.user.id,
238
+ impersonatedBy: session.session?.impersonatedBy ?? null
239
+ };
240
+ const headers = ctx?.headers ?? ctx?.request?.headers;
241
+ const actor = headers ? actors.get(headers) : void 0;
242
+ return {
243
+ id: actor?.id ?? null,
244
+ impersonatedBy: actor?.impersonatedBy ?? null
245
+ };
246
+ }
247
+ /**
248
+ * Records an event in every enabled sink. Never throws: audit logging must
249
+ * not break authentication.
250
+ */
251
+ async function record(ctx, event) {
252
+ const auth = ctx?.context?.adapter ? ctx.context : authContext;
253
+ if (!auth || excluded.has(event.eventType)) return;
254
+ try {
255
+ const meta = requestMeta(ctx, auth);
256
+ const actor = actorOf(ctx);
257
+ const attribution = {
258
+ ...actor.id && actor.id !== event.userId ? { actorId: actor.id } : {},
259
+ ...actor.impersonatedBy ? { impersonatedBy: actor.impersonatedBy } : {}
260
+ };
261
+ const eventData = Object.keys(attribution).length ? {
262
+ ...event.eventData,
263
+ ...attribution
264
+ } : event.eventData ?? null;
265
+ const { id: _,...data } = {
266
+ id: "",
267
+ status: "success",
268
+ userId: null,
269
+ identifier: null,
270
+ organizationId: null,
271
+ ...meta,
272
+ ...event,
273
+ eventData,
274
+ createdAt: /* @__PURE__ */ new Date()
275
+ };
276
+ let id = auth.generateId({ model: "auditLog" }) || "";
277
+ if (opts.database) {
278
+ const row = id ? {
279
+ ...data,
280
+ id
281
+ } : data;
282
+ id = (await auth.adapter.create({
283
+ model: "auditLog",
284
+ data: row,
285
+ forceAllowId: Boolean(id)
286
+ }).catch((e) => {
287
+ auth.logger.error("[audit-log] Failed to write audit log", e);
288
+ return null;
289
+ }))?.id ?? id;
290
+ }
291
+ const full = {
292
+ ...data,
293
+ id: id || generateRandomString(32)
294
+ };
295
+ remote?.push(full, auth.logger);
296
+ const onEvent = opts.onEvent;
297
+ if (onEvent) await Promise.resolve().then(() => onEvent(full)).catch((e) => auth.logger.error("[audit-log] onEvent handler failed", e));
298
+ } catch (e) {
299
+ auth.logger.error("[audit-log] Failed to record audit event", e);
300
+ }
301
+ }
302
+ function userEventsFromUpdate(data) {
303
+ const events = [];
304
+ if (data.emailVerified === true) events.push({ eventType: AUDIT_EVENT_TYPES.USER_EMAIL_VERIFIED });
305
+ if (data.banned === true) events.push({ eventType: AUDIT_EVENT_TYPES.USER_BANNED });
306
+ if (data.banned === false) events.push({ eventType: AUDIT_EVENT_TYPES.USER_UNBANNED });
307
+ if (data.email !== void 0) events.push({ eventType: AUDIT_EVENT_TYPES.USER_EMAIL_CHANGED });
308
+ if (data.phoneNumber !== void 0) events.push({ eventType: AUDIT_EVENT_TYPES.USER_PHONE_NUMBER_CHANGED });
309
+ if (data.role !== void 0) events.push({
310
+ eventType: AUDIT_EVENT_TYPES.USER_ROLE_UPDATED,
311
+ eventData: { role: data.role }
312
+ });
313
+ if (data.twoFactorEnabled === true) events.push({ eventType: AUDIT_EVENT_TYPES.TWO_FACTOR_ENABLED });
314
+ if (data.twoFactorEnabled === false) events.push({ eventType: AUDIT_EVENT_TYPES.TWO_FACTOR_DISABLED });
315
+ if (data.image !== void 0) events.push({ eventType: AUDIT_EVENT_TYPES.USER_PROFILE_IMAGE_UPDATED });
316
+ if (Object.entries(data).some(([key, value]) => value !== void 0 && !INTERNAL_USER_FIELDS.has(key))) events.push({ eventType: AUDIT_EVENT_TYPES.USER_PROFILE_UPDATED });
317
+ return events;
318
+ }
319
+ async function queryEvents(auth, query) {
320
+ const { limit, offset } = query;
321
+ if (remote) return remote.query(query);
322
+ const where = [];
323
+ if (query.userIds) where.push({
324
+ field: "userId",
325
+ operator: "in",
326
+ value: query.userIds
327
+ });
328
+ if (query.organizationIds) where.push({
329
+ field: "organizationId",
330
+ operator: "in",
331
+ value: query.organizationIds
332
+ });
333
+ for (const field of [
334
+ "eventType",
335
+ "identifier",
336
+ "userId",
337
+ "organizationId"
338
+ ]) {
339
+ const value = query[field];
340
+ if (value) where.push({
341
+ field,
342
+ value
343
+ });
344
+ }
345
+ if (query.startDate) where.push({
346
+ field: "createdAt",
347
+ operator: "gte",
348
+ value: new Date(query.startDate)
349
+ });
350
+ if (query.endDate) where.push({
351
+ field: "createdAt",
352
+ operator: "lte",
353
+ value: new Date(query.endDate)
354
+ });
355
+ const [events, total] = await Promise.all([auth.adapter.findMany({
356
+ model: "auditLog",
357
+ where,
358
+ limit,
359
+ offset,
360
+ sortBy: {
361
+ field: "createdAt",
362
+ direction: "desc"
363
+ }
364
+ }), auth.adapter.count({
365
+ model: "auditLog",
366
+ where
367
+ })]);
368
+ return {
369
+ events,
370
+ total,
371
+ limit,
372
+ offset
373
+ };
374
+ }
375
+ /** Organization memberships of a user, empty without the organization plugin */
376
+ async function findMemberships(auth, userId) {
377
+ try {
378
+ return await auth.adapter.findMany({
379
+ model: "member",
380
+ where: [{
381
+ field: "userId",
382
+ value: userId
383
+ }]
384
+ });
385
+ } catch {
386
+ return [];
387
+ }
388
+ }
389
+ function hasRole(roleField, roles) {
390
+ if (typeof roleField !== "string") return false;
391
+ return roleField.split(",").map((role) => role.trim()).some((role) => roles.includes(role));
392
+ }
393
+ async function runQuery(auth, query) {
394
+ try {
395
+ return await queryEvents(auth, query);
396
+ } catch (e) {
397
+ auth.logger.error("[audit-log] Failed to query audit logs", e);
398
+ throw new APIError("SERVICE_UNAVAILABLE", { message: AUDIT_LOG_ERROR_CODES.AUDIT_LOG_UNAVAILABLE });
399
+ }
400
+ }
401
+ return {
402
+ id: "audit-log",
403
+ init(ctx) {
404
+ authContext = ctx;
405
+ registerAuditRecorder(ctx, record);
406
+ if (misconfigured) ctx.logger.warn("[audit-log] Missing PAYVO_INFRA_API_URL or PAYVO_INFRA_API_KEY. Remote audit logging is disabled.");
407
+ return { options: { databaseHooks: {
408
+ user: {
409
+ create: { async after(user, context) {
410
+ if (context) {
411
+ const created = createdUsers.get(context) ?? /* @__PURE__ */ new Set();
412
+ created.add(user.id);
413
+ createdUsers.set(context, created);
414
+ }
415
+ await record(context ?? void 0, {
416
+ eventType: AUDIT_EVENT_TYPES.USER_SIGNED_UP,
417
+ userId: user.id,
418
+ identifier: user.email
419
+ });
420
+ } },
421
+ update: {
422
+ async before(data, context) {
423
+ const key = context ?? noContextKey;
424
+ const queue = pendingUserUpdates.get(key) ?? [];
425
+ queue.push(data);
426
+ pendingUserUpdates.set(key, queue);
427
+ return { data };
428
+ },
429
+ async after(user, context) {
430
+ const key = context ?? noContextKey;
431
+ const data = pendingUserUpdates.get(key)?.shift();
432
+ if (!user || !data) return;
433
+ for (const event of userEventsFromUpdate(data)) await record(context ?? void 0, {
434
+ ...event,
435
+ userId: user.id,
436
+ identifier: user.email
437
+ });
438
+ }
439
+ },
440
+ delete: { async after(user, context) {
441
+ await record(context ?? void 0, {
442
+ eventType: AUDIT_EVENT_TYPES.USER_DELETED,
443
+ userId: user.id,
444
+ identifier: user.email
445
+ });
446
+ } }
447
+ },
448
+ session: { create: { async after(session, context) {
449
+ await record(context ?? void 0, {
450
+ eventType: AUDIT_EVENT_TYPES.SESSION_CREATED,
451
+ userId: session.userId
452
+ });
453
+ const impersonatedBy = session.impersonatedBy;
454
+ if (impersonatedBy) await record(context ?? void 0, {
455
+ eventType: AUDIT_EVENT_TYPES.USER_IMPERSONATED,
456
+ userId: session.userId,
457
+ eventData: { impersonatedBy }
458
+ });
459
+ } } },
460
+ account: { create: { async after(account, context) {
461
+ if (context && createdUsers.get(context)?.has(account.userId)) return;
462
+ await record(context ?? void 0, {
463
+ eventType: AUDIT_EVENT_TYPES.ACCOUNT_LINKED,
464
+ userId: account.userId,
465
+ eventData: { providerId: account.providerId }
466
+ });
467
+ } } }
468
+ } } };
469
+ },
470
+ hooks: {
471
+ before: [{
472
+ matcher(context) {
473
+ return context.path === "/sign-out" || context.path in PATH_EVENTS;
474
+ },
475
+ handler: createAuthMiddleware(async (ctx) => {
476
+ if (!ctx.headers) return;
477
+ const session = await getSessionFromCtx(ctx).catch(() => null);
478
+ if (session) actors.set(ctx.headers, {
479
+ id: session.user.id,
480
+ email: session.user.email,
481
+ activeOrganizationId: session.session.activeOrganizationId ?? null,
482
+ impersonatedBy: session.session.impersonatedBy ?? null
483
+ });
484
+ const sessionToken = ctx.body?.sessionToken;
485
+ if (ctx.path === "/admin/revoke-user-session" && typeof sessionToken === "string") {
486
+ const revoked = await ctx.context.internalAdapter.findSession(sessionToken).catch(() => null);
487
+ if (revoked) targets.set(ctx.headers, revoked.session.userId);
488
+ }
489
+ })
490
+ }],
491
+ after: [{
492
+ matcher(context) {
493
+ return context.path === "/sign-out" || SIGN_IN_PATHS.includes(context.path) || VERIFICATION_PATHS.includes(context.path) || context.path in PATH_EVENTS;
494
+ },
495
+ handler: createAuthMiddleware(async (ctx) => {
496
+ const returned = ctx.context.returned;
497
+ const failed = returned instanceof APIError && returned.statusCode >= 400;
498
+ const body = ctx.body ?? {};
499
+ const identifier = [
500
+ body.email,
501
+ body.username,
502
+ body.phoneNumber
503
+ ].find((value) => typeof value === "string") ?? null;
504
+ if (ctx.path === "/sign-out") {
505
+ const actor$1 = ctx.headers && actors.get(ctx.headers);
506
+ if (!actor$1 || failed) return;
507
+ await record(ctx, {
508
+ eventType: AUDIT_EVENT_TYPES.USER_SIGNED_OUT,
509
+ userId: actor$1.id,
510
+ identifier: actor$1.email
511
+ });
512
+ return;
513
+ }
514
+ const isCredentialCheck = CREDENTIAL_SIGN_IN_PATHS.includes(ctx.path);
515
+ if (returned instanceof APIError && failed && opts.trackFailedSignIns && (isCredentialCheck || VERIFICATION_PATHS.includes(ctx.path))) {
516
+ await record(ctx, {
517
+ eventType: isCredentialCheck ? AUDIT_EVENT_TYPES.USER_SIGN_IN_FAILED : AUDIT_EVENT_TYPES.VERIFICATION_FAILED,
518
+ status: "failure",
519
+ identifier,
520
+ eventData: {
521
+ code: returned.body?.code,
522
+ status: returned.statusCode
523
+ }
524
+ });
525
+ return;
526
+ }
527
+ if (SIGN_IN_PATHS.includes(ctx.path)) {
528
+ const newSession = ctx.context.newSession;
529
+ if (!failed && newSession && !(returned && "twoFactorRedirect" in returned)) await record(ctx, {
530
+ eventType: AUDIT_EVENT_TYPES.USER_SIGNED_IN,
531
+ userId: newSession.user.id,
532
+ identifier: newSession.user.email
533
+ });
534
+ return;
535
+ }
536
+ const eventType = PATH_EVENTS[ctx.path];
537
+ if (!eventType || failed) return;
538
+ if (ctx.path === "/email-otp/send-verification-otp" && body.type !== "email-verification") return;
539
+ const result = returned ?? {};
540
+ const actor = ctx.headers ? actors.get(ctx.headers) : void 0;
541
+ const target = (ctx.headers && targets.get(ctx.headers)) ?? (ctx.path.startsWith("/admin/") && typeof body.userId === "string" ? body.userId : null);
542
+ const organizationId = await resolveOrganizationId(ctx.context, ctx.path, body, result, actor?.activeOrganizationId ?? null);
543
+ const eventData = {};
544
+ if (ctx.path === "/unlink-account") eventData.providerId = body.providerId;
545
+ if (ctx.path === "/organization/invite-member") {
546
+ eventData.email = body.email;
547
+ eventData.role = body.role;
548
+ }
549
+ if (ctx.path === "/organization/update-member-role") {
550
+ eventData.memberId = body.memberId;
551
+ eventData.role = body.role;
552
+ }
553
+ if (ctx.path.startsWith("/organization/") && ctx.path.endsWith("-role")) eventData.role = body.role ?? body.roleName ?? body.roleId;
554
+ let owner = null;
555
+ if (ctx.path.startsWith("/api-key/")) {
556
+ eventData.keyId = body.keyId ?? result.id;
557
+ owner = result.userId ?? null;
558
+ }
559
+ if (ctx.path.startsWith("/passkey/")) eventData.passkeyId = body.id ?? result.id;
560
+ await record(ctx, {
561
+ eventType,
562
+ userId: target ?? actor?.id ?? result.user?.id ?? owner,
563
+ identifier: actor?.email ?? identifier,
564
+ organizationId,
565
+ eventData: Object.keys(eventData).length ? eventData : null
566
+ });
567
+ })
568
+ }]
569
+ },
570
+ endpoints: {
571
+ getAuditLogs: createAuthEndpoint("/audit-log/get-audit-logs", {
572
+ method: "GET",
573
+ use: [sessionMiddleware],
574
+ query: z$1.object(auditLogQuery).optional(),
575
+ metadata: { openapi: {
576
+ operationId: "getAuditLogs",
577
+ summary: "Get audit logs",
578
+ description: "Get the current user's audit events, optionally restricted to an organization",
579
+ responses: { 200: {
580
+ description: "Paginated audit events",
581
+ content: { "application/json": { schema: {
582
+ type: "object",
583
+ properties: {
584
+ events: {
585
+ type: "array",
586
+ items: {
587
+ type: "object",
588
+ properties: {
589
+ id: { type: "string" },
590
+ eventType: { type: "string" },
591
+ status: { type: "string" },
592
+ userId: {
593
+ type: "string",
594
+ nullable: true
595
+ },
596
+ identifier: {
597
+ type: "string",
598
+ nullable: true
599
+ },
600
+ organizationId: {
601
+ type: "string",
602
+ nullable: true
603
+ },
604
+ path: {
605
+ type: "string",
606
+ nullable: true
607
+ },
608
+ ipAddress: {
609
+ type: "string",
610
+ nullable: true
611
+ },
612
+ userAgent: {
613
+ type: "string",
614
+ nullable: true
615
+ },
616
+ visitorId: {
617
+ type: "string",
618
+ nullable: true
619
+ },
620
+ eventData: {
621
+ type: "object",
622
+ nullable: true
623
+ },
624
+ createdAt: {
625
+ type: "string",
626
+ format: "date-time"
627
+ }
628
+ }
629
+ }
630
+ },
631
+ total: { type: "number" },
632
+ limit: { type: "number" },
633
+ offset: { type: "number" }
634
+ },
635
+ required: [
636
+ "events",
637
+ "total",
638
+ "limit",
639
+ "offset"
640
+ ]
641
+ } } }
642
+ } }
643
+ } }
644
+ }, async (ctx) => {
645
+ const { user } = ctx.context.session;
646
+ const { limit: _limit, offset: _offset,...filters } = ctx.query ?? {};
647
+ const pagination = toPagination(ctx.query ?? {});
648
+ if (filters.userId && filters.userId !== user.id) throw new APIError("FORBIDDEN", { message: AUDIT_LOG_ERROR_CODES.AUDIT_LOG_ACCESS_DENIED });
649
+ return ctx.json(await runQuery(ctx.context, {
650
+ ...filters,
651
+ ...pagination,
652
+ userId: user.id
653
+ }));
654
+ }),
655
+ getAllAuditLogs: createAuthEndpoint("/audit-log/get-all-audit-logs", {
656
+ method: "GET",
657
+ use: [sessionMiddleware],
658
+ query: z$1.object(auditLogQuery).optional(),
659
+ metadata: { openapi: {
660
+ operationId: "getAllAuditLogs",
661
+ summary: "Get all audit logs",
662
+ description: "Get audit events across organizations the user owns or administers, or every event for admins",
663
+ responses: { 200: {
664
+ description: "Paginated audit events",
665
+ content: { "application/json": { schema: {
666
+ type: "object",
667
+ properties: {
668
+ events: {
669
+ type: "array",
670
+ items: {
671
+ type: "object",
672
+ properties: {
673
+ id: { type: "string" },
674
+ eventType: { type: "string" },
675
+ status: { type: "string" },
676
+ userId: {
677
+ type: "string",
678
+ nullable: true
679
+ },
680
+ identifier: {
681
+ type: "string",
682
+ nullable: true
683
+ },
684
+ organizationId: {
685
+ type: "string",
686
+ nullable: true
687
+ },
688
+ path: {
689
+ type: "string",
690
+ nullable: true
691
+ },
692
+ ipAddress: {
693
+ type: "string",
694
+ nullable: true
695
+ },
696
+ userAgent: {
697
+ type: "string",
698
+ nullable: true
699
+ },
700
+ visitorId: {
701
+ type: "string",
702
+ nullable: true
703
+ },
704
+ eventData: {
705
+ type: "object",
706
+ nullable: true
707
+ },
708
+ createdAt: {
709
+ type: "string",
710
+ format: "date-time"
711
+ }
712
+ }
713
+ }
714
+ },
715
+ total: { type: "number" },
716
+ limit: { type: "number" },
717
+ offset: { type: "number" }
718
+ },
719
+ required: [
720
+ "events",
721
+ "total",
722
+ "limit",
723
+ "offset"
724
+ ]
725
+ } } }
726
+ } }
727
+ } }
728
+ }, async (ctx) => {
729
+ const { user } = ctx.context.session;
730
+ const { limit: _limit, offset: _offset,...filters } = ctx.query ?? {};
731
+ const pagination = toPagination(ctx.query ?? {});
732
+ if (hasRole(user.role, opts.adminRoles)) return ctx.json(await runQuery(ctx.context, {
733
+ ...filters,
734
+ ...pagination
735
+ }));
736
+ const administered = (await findMemberships(ctx.context, user.id)).filter((m) => hasRole(m.role, ["owner", "admin"])).map((m) => m.organizationId);
737
+ if (!administered.length || filters.organizationId && !administered.includes(filters.organizationId)) throw new APIError("FORBIDDEN", { message: AUDIT_LOG_ERROR_CODES.AUDIT_LOG_ACCESS_DENIED });
738
+ return ctx.json(await runQuery(ctx.context, {
739
+ ...filters,
740
+ ...pagination,
741
+ organizationIds: filters.organizationId ? void 0 : administered
742
+ }));
743
+ }),
744
+ getEventTypes: createAuthEndpoint("/audit-log/get-event-types", {
745
+ method: "GET",
746
+ use: [sessionMiddleware],
747
+ metadata: { openapi: {
748
+ operationId: "getAuditLogEventTypes",
749
+ summary: "Get audit log event types",
750
+ description: "Get the event types the audit log can record",
751
+ responses: { 200: {
752
+ description: "Event types",
753
+ content: { "application/json": { schema: {
754
+ type: "object",
755
+ properties: { types: {
756
+ type: "array",
757
+ items: { type: "string" }
758
+ } },
759
+ required: ["types"]
760
+ } } }
761
+ } }
762
+ } }
763
+ }, async (ctx) => ctx.json({ types: ALL_EVENT_TYPES }))
764
+ },
765
+ schema: mergedSchema,
766
+ $ERROR_CODES: AUDIT_LOG_ERROR_CODES,
767
+ options: opts
768
+ };
769
+ };
770
+
771
+ //#endregion
772
+ export { auditLog as n, AUDIT_LOG_ERROR_CODES as t };