alepha 0.21.2 → 0.22.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.
Files changed (463) hide show
  1. package/README.md +0 -1
  2. package/dist/api/audits/index.browser.js.map +1 -1
  3. package/dist/api/audits/index.d.ts +393 -403
  4. package/dist/api/audits/index.d.ts.map +1 -1
  5. package/dist/api/audits/index.js +25 -56
  6. package/dist/api/audits/index.js.map +1 -1
  7. package/dist/api/files/index.browser.js +31 -1
  8. package/dist/api/files/index.browser.js.map +1 -1
  9. package/dist/api/files/index.d.ts +313 -208
  10. package/dist/api/files/index.d.ts.map +1 -1
  11. package/dist/api/files/index.js +152 -42
  12. package/dist/api/files/index.js.map +1 -1
  13. package/dist/api/jobs/index.browser.js +2 -2
  14. package/dist/api/jobs/index.browser.js.map +1 -1
  15. package/dist/api/jobs/index.d.ts +289 -292
  16. package/dist/api/jobs/index.d.ts.map +1 -1
  17. package/dist/api/jobs/index.js +39 -33
  18. package/dist/api/jobs/index.js.map +1 -1
  19. package/dist/api/keys/index.d.ts +211 -216
  20. package/dist/api/keys/index.d.ts.map +1 -1
  21. package/dist/api/keys/index.js.map +1 -1
  22. package/dist/api/notifications/index.browser.js.map +1 -1
  23. package/dist/api/notifications/index.d.ts +188 -195
  24. package/dist/api/notifications/index.d.ts.map +1 -1
  25. package/dist/api/notifications/index.js.map +1 -1
  26. package/dist/api/oauth/index.d.ts +71 -76
  27. package/dist/api/oauth/index.d.ts.map +1 -1
  28. package/dist/api/oauth/index.js.map +1 -1
  29. package/dist/api/organizations/index.browser.js.map +1 -1
  30. package/dist/api/organizations/index.d.ts +104 -109
  31. package/dist/api/organizations/index.d.ts.map +1 -1
  32. package/dist/api/organizations/index.js.map +1 -1
  33. package/dist/api/parameters/index.browser.js +43 -16
  34. package/dist/api/parameters/index.browser.js.map +1 -1
  35. package/dist/api/parameters/index.d.ts +488 -344
  36. package/dist/api/parameters/index.d.ts.map +1 -1
  37. package/dist/api/parameters/index.js +175 -35
  38. package/dist/api/parameters/index.js.map +1 -1
  39. package/dist/api/payments/index.d.ts +396 -402
  40. package/dist/api/payments/index.d.ts.map +1 -1
  41. package/dist/api/payments/index.js.map +1 -1
  42. package/dist/api/subscriptions/index.d.ts +644 -652
  43. package/dist/api/subscriptions/index.d.ts.map +1 -1
  44. package/dist/api/subscriptions/index.js +1 -1
  45. package/dist/api/subscriptions/index.js.map +1 -1
  46. package/dist/api/users/index.browser.js +7 -0
  47. package/dist/api/users/index.browser.js.map +1 -1
  48. package/dist/api/users/index.d.ts +1073 -1006
  49. package/dist/api/users/index.d.ts.map +1 -1
  50. package/dist/api/users/index.js +283 -61
  51. package/dist/api/users/index.js.map +1 -1
  52. package/dist/api/verifications/index.browser.js.map +1 -1
  53. package/dist/api/verifications/index.d.ts +134 -140
  54. package/dist/api/verifications/index.d.ts.map +1 -1
  55. package/dist/api/verifications/index.js.map +1 -1
  56. package/dist/background/index.d.ts +95 -0
  57. package/dist/background/index.d.ts.map +1 -0
  58. package/dist/background/index.js +121 -0
  59. package/dist/background/index.js.map +1 -0
  60. package/dist/background/index.workerd.js +110 -0
  61. package/dist/background/index.workerd.js.map +1 -0
  62. package/dist/batch/index.d.ts +5 -7
  63. package/dist/batch/index.d.ts.map +1 -1
  64. package/dist/batch/index.js.map +1 -1
  65. package/dist/bin/index.js.map +1 -1
  66. package/dist/bucket/index.d.ts +76 -54
  67. package/dist/bucket/index.d.ts.map +1 -1
  68. package/dist/bucket/index.js +58 -11
  69. package/dist/bucket/index.js.map +1 -1
  70. package/dist/bucket/index.workerd.js +200 -5
  71. package/dist/bucket/index.workerd.js.map +1 -1
  72. package/dist/cache/core/index.d.ts +7 -10
  73. package/dist/cache/core/index.d.ts.map +1 -1
  74. package/dist/cache/core/index.js.map +1 -1
  75. package/dist/cache/core/index.workerd.js.map +1 -1
  76. package/dist/cache/database/index.d.ts +22 -26
  77. package/dist/cache/database/index.d.ts.map +1 -1
  78. package/dist/cache/database/index.js.map +1 -1
  79. package/dist/cache/redis/index.d.ts +4 -7
  80. package/dist/cache/redis/index.d.ts.map +1 -1
  81. package/dist/cache/redis/index.js.map +1 -1
  82. package/dist/captcha/index.d.ts +3 -6
  83. package/dist/captcha/index.d.ts.map +1 -1
  84. package/dist/captcha/index.js.map +1 -1
  85. package/dist/cli/config/index.d.ts.map +1 -1
  86. package/dist/cli/config/index.js.map +1 -1
  87. package/dist/cli/core/index.d.ts +417 -214
  88. package/dist/cli/core/index.d.ts.map +1 -1
  89. package/dist/cli/core/index.js +325 -563
  90. package/dist/cli/core/index.js.map +1 -1
  91. package/dist/cli/devtools/index.d.ts +3 -5
  92. package/dist/cli/devtools/index.d.ts.map +1 -1
  93. package/dist/cli/devtools/index.js.map +1 -1
  94. package/dist/cli/i18n/index.d.ts +8 -12
  95. package/dist/cli/i18n/index.d.ts.map +1 -1
  96. package/dist/cli/i18n/index.js.map +1 -1
  97. package/dist/cli/platform/index.d.ts +126 -1342
  98. package/dist/cli/platform/index.d.ts.map +1 -1
  99. package/dist/cli/platform/index.js +136 -2374
  100. package/dist/cli/platform/index.js.map +1 -1
  101. package/dist/cli/platform-lib/index.d.ts +1446 -0
  102. package/dist/cli/platform-lib/index.d.ts.map +1 -0
  103. package/dist/cli/platform-lib/index.js +2597 -0
  104. package/dist/cli/platform-lib/index.js.map +1 -0
  105. package/dist/cli/vendor/index.d.ts +17 -21
  106. package/dist/cli/vendor/index.d.ts.map +1 -1
  107. package/dist/cli/vendor/index.js.map +1 -1
  108. package/dist/command/index.d.ts +21 -20
  109. package/dist/command/index.d.ts.map +1 -1
  110. package/dist/command/index.js +39 -10
  111. package/dist/command/index.js.map +1 -1
  112. package/dist/{containers → container}/core/index.d.ts +13 -15
  113. package/dist/container/core/index.d.ts.map +1 -0
  114. package/dist/{containers → container}/core/index.js +23 -14
  115. package/dist/container/core/index.js.map +1 -0
  116. package/dist/{containers → container}/core/index.workerd.js +37 -22
  117. package/dist/container/core/index.workerd.js.map +1 -0
  118. package/dist/core/index.browser.js +27 -1
  119. package/dist/core/index.browser.js.map +1 -1
  120. package/dist/core/index.d.ts +48 -24
  121. package/dist/core/index.d.ts.map +1 -1
  122. package/dist/core/index.js +27 -1
  123. package/dist/core/index.js.map +1 -1
  124. package/dist/core/index.native.js +27 -1
  125. package/dist/core/index.native.js.map +1 -1
  126. package/dist/core/index.workerd.js +27 -1
  127. package/dist/core/index.workerd.js.map +1 -1
  128. package/dist/crypto/index.browser.js.map +1 -1
  129. package/dist/crypto/index.d.ts +5 -8
  130. package/dist/crypto/index.d.ts.map +1 -1
  131. package/dist/crypto/index.js.map +1 -1
  132. package/dist/datetime/index.d.ts +3 -4
  133. package/dist/datetime/index.d.ts.map +1 -1
  134. package/dist/datetime/index.js.map +1 -1
  135. package/dist/email/brevo/index.d.ts +2 -4
  136. package/dist/email/brevo/index.d.ts.map +1 -1
  137. package/dist/email/brevo/index.js.map +1 -1
  138. package/dist/email/cloudflare/index.d.ts +20 -7
  139. package/dist/email/cloudflare/index.d.ts.map +1 -1
  140. package/dist/email/cloudflare/index.js +46 -9
  141. package/dist/email/cloudflare/index.js.map +1 -1
  142. package/dist/email/core/index.d.ts +6 -9
  143. package/dist/email/core/index.d.ts.map +1 -1
  144. package/dist/email/core/index.js.map +1 -1
  145. package/dist/email/core/index.workerd.js.map +1 -1
  146. package/dist/email/smtp/index.d.ts +10 -13
  147. package/dist/email/smtp/index.d.ts.map +1 -1
  148. package/dist/email/smtp/index.js +107 -32
  149. package/dist/email/smtp/index.js.map +1 -1
  150. package/dist/fake/index.d.ts +1 -2
  151. package/dist/fake/index.d.ts.map +1 -1
  152. package/dist/fake/index.js.map +1 -1
  153. package/dist/lock/core/index.d.ts +9 -14
  154. package/dist/lock/core/index.d.ts.map +1 -1
  155. package/dist/lock/core/index.js.map +1 -1
  156. package/dist/lock/redis/index.d.ts +2 -4
  157. package/dist/lock/redis/index.d.ts.map +1 -1
  158. package/dist/lock/redis/index.js.map +1 -1
  159. package/dist/logger/index.d.ts +105 -76
  160. package/dist/logger/index.d.ts.map +1 -1
  161. package/dist/logger/index.js +196 -174
  162. package/dist/logger/index.js.map +1 -1
  163. package/dist/mcp/index.d.ts +16 -20
  164. package/dist/mcp/index.d.ts.map +1 -1
  165. package/dist/mcp/index.js.map +1 -1
  166. package/dist/orm/core/index.browser.js.map +1 -1
  167. package/dist/orm/core/index.bun.js +19 -1
  168. package/dist/orm/core/index.bun.js.map +1 -1
  169. package/dist/orm/core/index.d.ts +76 -62
  170. package/dist/orm/core/index.d.ts.map +1 -1
  171. package/dist/orm/core/index.js +20 -2
  172. package/dist/orm/core/index.js.map +1 -1
  173. package/dist/orm/postgres/index.bun.js.map +1 -1
  174. package/dist/orm/postgres/index.d.ts +28 -20
  175. package/dist/orm/postgres/index.d.ts.map +1 -1
  176. package/dist/orm/postgres/index.js.map +1 -1
  177. package/dist/queue/core/index.d.ts +12 -15
  178. package/dist/queue/core/index.d.ts.map +1 -1
  179. package/dist/queue/core/index.js.map +1 -1
  180. package/dist/queue/core/index.workerd.js.map +1 -1
  181. package/dist/queue/redis/index.d.ts +3 -5
  182. package/dist/queue/redis/index.d.ts.map +1 -1
  183. package/dist/queue/redis/index.js.map +1 -1
  184. package/dist/react/auth/index.browser.js +9 -2
  185. package/dist/react/auth/index.browser.js.map +1 -1
  186. package/dist/react/auth/index.d.ts +14 -9
  187. package/dist/react/auth/index.d.ts.map +1 -1
  188. package/dist/react/auth/index.js +9 -2
  189. package/dist/react/auth/index.js.map +1 -1
  190. package/dist/react/core/index.d.ts +7 -8
  191. package/dist/react/core/index.d.ts.map +1 -1
  192. package/dist/react/core/index.js +6 -3
  193. package/dist/react/core/index.js.map +1 -1
  194. package/dist/react/form/index.d.ts +2 -4
  195. package/dist/react/form/index.d.ts.map +1 -1
  196. package/dist/react/form/index.js.map +1 -1
  197. package/dist/react/head/index.browser.js.map +1 -1
  198. package/dist/react/head/index.d.ts +2 -4
  199. package/dist/react/head/index.d.ts.map +1 -1
  200. package/dist/react/head/index.js.map +1 -1
  201. package/dist/react/i18n/index.d.ts +47 -11
  202. package/dist/react/i18n/index.d.ts.map +1 -1
  203. package/dist/react/i18n/index.js +33 -1
  204. package/dist/react/i18n/index.js.map +1 -1
  205. package/dist/react/intro/index.d.ts +1 -2
  206. package/dist/react/intro/index.d.ts.map +1 -1
  207. package/dist/react/intro/index.js +2 -2
  208. package/dist/react/intro/index.js.map +1 -1
  209. package/dist/react/router/index.browser.js +65 -19
  210. package/dist/react/router/index.browser.js.map +1 -1
  211. package/dist/react/router/index.d.ts +327 -222
  212. package/dist/react/router/index.d.ts.map +1 -1
  213. package/dist/react/router/index.js +65 -29
  214. package/dist/react/router/index.js.map +1 -1
  215. package/dist/react/testing/index.d.ts +1 -2
  216. package/dist/react/testing/index.d.ts.map +1 -1
  217. package/dist/react/testing/index.js +16 -17
  218. package/dist/react/testing/index.js.map +1 -1
  219. package/dist/react/ui/index.d.ts +20 -25
  220. package/dist/react/ui/index.d.ts.map +1 -1
  221. package/dist/react/ui/index.js.map +1 -1
  222. package/dist/redis/index.bun.js.map +1 -1
  223. package/dist/redis/index.d.ts +17 -19
  224. package/dist/redis/index.d.ts.map +1 -1
  225. package/dist/redis/index.js.map +1 -1
  226. package/dist/retry/index.d.ts +2 -4
  227. package/dist/retry/index.d.ts.map +1 -1
  228. package/dist/retry/index.js.map +1 -1
  229. package/dist/router/index.d.ts.map +1 -1
  230. package/dist/router/index.js.map +1 -1
  231. package/dist/scheduler/index.d.ts +10 -13
  232. package/dist/scheduler/index.d.ts.map +1 -1
  233. package/dist/scheduler/index.js.map +1 -1
  234. package/dist/scheduler/index.workerd.js.map +1 -1
  235. package/dist/security/index.browser.js.map +1 -1
  236. package/dist/security/index.d.ts +45 -48
  237. package/dist/security/index.d.ts.map +1 -1
  238. package/dist/security/index.js.map +1 -1
  239. package/dist/server/auth/index.browser.js.map +1 -1
  240. package/dist/server/auth/index.d.ts +167 -172
  241. package/dist/server/auth/index.d.ts.map +1 -1
  242. package/dist/server/auth/index.js +4 -8
  243. package/dist/server/auth/index.js.map +1 -1
  244. package/dist/server/cookies/index.browser.js.map +1 -1
  245. package/dist/server/cookies/index.d.ts +5 -7
  246. package/dist/server/cookies/index.d.ts.map +1 -1
  247. package/dist/server/cookies/index.js.map +1 -1
  248. package/dist/server/core/index.browser.js.map +1 -1
  249. package/dist/server/core/index.d.ts +88 -73
  250. package/dist/server/core/index.d.ts.map +1 -1
  251. package/dist/server/core/index.js +19 -0
  252. package/dist/server/core/index.js.map +1 -1
  253. package/dist/server/cors/index.d.ts +11 -14
  254. package/dist/server/cors/index.d.ts.map +1 -1
  255. package/dist/server/cors/index.js.map +1 -1
  256. package/dist/server/etag/index.d.ts +6 -9
  257. package/dist/server/etag/index.d.ts.map +1 -1
  258. package/dist/server/etag/index.js.map +1 -1
  259. package/dist/server/health/index.d.ts +18 -21
  260. package/dist/server/health/index.d.ts.map +1 -1
  261. package/dist/server/health/index.js.map +1 -1
  262. package/dist/server/links/index.browser.js +2 -0
  263. package/dist/server/links/index.browser.js.map +1 -1
  264. package/dist/server/links/index.d.ts +63 -67
  265. package/dist/server/links/index.d.ts.map +1 -1
  266. package/dist/server/links/index.js +2 -0
  267. package/dist/server/links/index.js.map +1 -1
  268. package/dist/server/metrics/index.d.ts +5 -7
  269. package/dist/server/metrics/index.d.ts.map +1 -1
  270. package/dist/server/metrics/index.js.map +1 -1
  271. package/dist/server/proxy/index.d.ts +3 -5
  272. package/dist/server/proxy/index.d.ts.map +1 -1
  273. package/dist/server/proxy/index.js.map +1 -1
  274. package/dist/server/rate-limit/index.d.ts +10 -13
  275. package/dist/server/rate-limit/index.d.ts.map +1 -1
  276. package/dist/server/rate-limit/index.js.map +1 -1
  277. package/dist/server/static/index.d.ts +3 -5
  278. package/dist/server/static/index.d.ts.map +1 -1
  279. package/dist/server/static/index.js.map +1 -1
  280. package/dist/server/swagger/index.d.ts +5 -8
  281. package/dist/server/swagger/index.d.ts.map +1 -1
  282. package/dist/server/swagger/index.js.map +1 -1
  283. package/dist/sms/index.d.ts +3 -5
  284. package/dist/sms/index.d.ts.map +1 -1
  285. package/dist/sms/index.js.map +1 -1
  286. package/dist/system/index.browser.js.map +1 -1
  287. package/dist/system/index.d.ts +2 -4
  288. package/dist/system/index.d.ts.map +1 -1
  289. package/dist/system/index.js.map +1 -1
  290. package/dist/system/index.workerd.js.map +1 -1
  291. package/dist/topic/core/index.d.ts +4 -6
  292. package/dist/topic/core/index.d.ts.map +1 -1
  293. package/dist/topic/core/index.js.map +1 -1
  294. package/dist/topic/redis/index.d.ts +5 -8
  295. package/dist/topic/redis/index.d.ts.map +1 -1
  296. package/dist/topic/redis/index.js.map +1 -1
  297. package/package.json +45 -22
  298. package/src/api/audits/__tests__/AuditService.spec.ts +18 -110
  299. package/src/api/audits/controllers/AdminAuditController.ts +14 -0
  300. package/src/api/audits/services/AuditService.ts +21 -88
  301. package/src/api/files/__tests__/FileService.spec.ts +207 -2
  302. package/src/api/files/index.ts +3 -0
  303. package/src/api/files/schemas/fileCreatorSummarySchema.ts +22 -0
  304. package/src/api/files/schemas/fileResourceSchema.ts +10 -1
  305. package/src/api/files/services/FileService.ts +170 -72
  306. package/src/api/jobs/__tests__/$job.spec.ts +24 -1
  307. package/src/api/jobs/index.ts +4 -3
  308. package/src/api/jobs/primitives/$job.ts +7 -3
  309. package/src/api/jobs/providers/DirectJobDispatcher.ts +17 -36
  310. package/src/api/jobs/providers/JobProvider.ts +53 -24
  311. package/src/api/jobs/schemas/jobConfigAtom.ts +1 -1
  312. package/src/api/jobs/schemas/jobExecutionResourceSchema.ts +4 -1
  313. package/src/api/keys/schemas/adminApiKeyResourceSchema.ts +3 -1
  314. package/src/api/parameters/__tests__/$parameter.spec.ts +19 -2
  315. package/src/api/parameters/audits/ParameterAudits.ts +17 -0
  316. package/src/api/parameters/controllers/AdminParameterController.ts +95 -19
  317. package/src/api/parameters/index.ts +3 -0
  318. package/src/api/parameters/schemas/activateParameterBodySchema.ts +3 -3
  319. package/src/api/parameters/schemas/createParameterVersionBodySchema.ts +3 -2
  320. package/src/api/parameters/schemas/parameterCreatorSummarySchema.ts +25 -0
  321. package/src/api/parameters/schemas/parameterResponseSchema.ts +5 -0
  322. package/src/api/parameters/schemas/rollbackParameterBodySchema.ts +4 -2
  323. package/src/api/parameters/services/ParameterProvider.ts +69 -6
  324. package/src/api/subscriptions/jobs/SubscriptionJobs.ts +1 -1
  325. package/src/api/users/__tests__/AdminSessionController.spec.ts +37 -0
  326. package/src/api/users/audits/SessionAudits.ts +33 -0
  327. package/src/api/users/audits/UserAudits.ts +19 -43
  328. package/src/api/users/controllers/AdminUserController.ts +66 -1
  329. package/src/api/users/entities/sessions.ts +6 -0
  330. package/src/api/users/entities/users.ts +2 -0
  331. package/src/api/users/index.ts +9 -1
  332. package/src/api/users/primitives/$realm.ts +3 -0
  333. package/src/api/users/schemas/sessionResourceSchema.ts +16 -0
  334. package/src/api/users/schemas/updateUserSchema.ts +1 -8
  335. package/src/api/users/schemas/userQuerySchema.ts +7 -0
  336. package/src/api/users/services/CredentialService.ts +15 -6
  337. package/src/api/users/services/IdentityService.ts +2 -1
  338. package/src/api/users/services/RegistrationService.ts +2 -1
  339. package/src/api/users/services/SessionCrudService.ts +19 -2
  340. package/src/api/users/services/SessionService.ts +39 -19
  341. package/src/api/users/services/UserService.ts +106 -8
  342. package/src/background/__tests__/BackgroundTaskProvider.spec.ts +96 -0
  343. package/src/background/index.ts +37 -0
  344. package/src/background/index.workerd.ts +28 -0
  345. package/src/background/providers/BackgroundTaskProvider.ts +70 -0
  346. package/src/background/providers/WorkerdBackgroundTaskProvider.ts +43 -0
  347. package/src/bucket/__tests__/$bucket.spec.ts +18 -0
  348. package/src/bucket/__tests__/LocalFileStorageProvider.spec.ts +5 -0
  349. package/src/bucket/__tests__/MemoryFileStorageProvider.spec.ts +5 -0
  350. package/src/bucket/__tests__/NodeS3BucketProvider.spec.ts +23 -4
  351. package/src/bucket/__tests__/shared.ts +30 -0
  352. package/src/bucket/index.ts +5 -5
  353. package/src/bucket/index.workerd.ts +11 -4
  354. package/src/bucket/primitives/$bucket.ts +27 -0
  355. package/src/bucket/providers/FileStorageProvider.ts +13 -0
  356. package/src/bucket/providers/LocalFileStorageProvider.ts +17 -1
  357. package/src/bucket/providers/MemoryFileStorageProvider.ts +7 -0
  358. package/src/bucket/providers/{CloudflareR2Provider.ts → R2FileStorageProvider.ts} +10 -1
  359. package/src/bucket/providers/{NodeS3BucketProvider.ts → S3FileStorageProvider.ts} +27 -5
  360. package/src/cli/core/__tests__/BuildDockerTask.spec.ts +25 -1
  361. package/src/cli/core/__tests__/init.spec.ts +0 -219
  362. package/src/cli/core/commands/__tests__/BuildCommand.spec.ts +43 -0
  363. package/src/cli/core/commands/build.ts +108 -30
  364. package/src/cli/core/commands/init.ts +0 -12
  365. package/src/cli/core/commands/pack.ts +133 -0
  366. package/src/cli/core/index.ts +3 -0
  367. package/src/cli/core/providers/ViteDevServerProvider.ts +40 -16
  368. package/src/cli/core/services/PackageManagerUtils.ts +0 -16
  369. package/src/cli/core/services/ProjectScaffolder.ts +29 -291
  370. package/src/cli/core/tasks/BuildCloudflareTask.ts +353 -47
  371. package/src/cli/core/tasks/BuildDockerTask.ts +33 -3
  372. package/src/cli/core/tasks/BuildTask.ts +34 -0
  373. package/src/cli/core/templates/apiIndexTs.ts +1 -22
  374. package/src/cli/core/templates/mainCss.ts +0 -1
  375. package/src/cli/core/templates/webAppRouterTs.ts +0 -99
  376. package/src/cli/core/templates/webIndexTs.ts +1 -22
  377. package/src/cli/platform/__tests__/SecretsCommand.spec.ts +5 -3
  378. package/src/cli/platform/commands/SecretsCommand.ts +8 -6
  379. package/src/cli/platform/commands/platform.ts +192 -46
  380. package/src/cli/platform/index.ts +12 -52
  381. package/src/cli/{platform → platform-lib}/__tests__/CloudflareAdapter.spec.ts +426 -169
  382. package/src/cli/{platform → platform-lib}/__tests__/NamingService.spec.ts +91 -4
  383. package/src/cli/{platform → platform-lib}/__tests__/VercelAdapter.spec.ts +56 -85
  384. package/src/cli/{platform → platform-lib}/adapters/CloudflareAdapter.ts +402 -165
  385. package/src/cli/{platform → platform-lib}/adapters/PlatformAdapter.ts +62 -35
  386. package/src/cli/{platform → platform-lib}/adapters/VercelAdapter.ts +6 -10
  387. package/src/cli/{platform → platform-lib}/atoms/platformOptions.ts +34 -1
  388. package/src/cli/platform-lib/index.ts +67 -0
  389. package/src/cli/platform-lib/services/NamingService.ts +136 -0
  390. package/src/cli/{platform → platform-lib}/services/PlatformInspector.ts +60 -13
  391. package/src/cli/{platform → platform-lib}/services/PlatformOrchestrator.ts +54 -43
  392. package/src/cli/{platform → platform-lib}/services/WranglerApi.ts +4 -2
  393. package/src/command/__tests__/Runner.spec.ts +20 -0
  394. package/src/command/helpers/EnvUtils.ts +19 -3
  395. package/src/command/helpers/Runner.ts +12 -2
  396. package/src/command/providers/CliProvider.ts +34 -1
  397. package/src/{containers → container}/core/__tests__/$container.spec.ts +5 -5
  398. package/src/{containers → container}/core/index.ts +4 -4
  399. package/src/{containers → container}/core/index.workerd.ts +19 -3
  400. package/src/{containers → container}/core/primitives/$container.ts +1 -1
  401. package/src/{containers → container}/core/providers/CloudflareContainerProvider.ts +17 -19
  402. package/src/{containers → container}/core/providers/ContainerProvider.ts +16 -2
  403. package/src/{containers → container}/core/providers/MockContainerProvider.ts +1 -1
  404. package/src/core/Alepha.ts +49 -1
  405. package/src/core/__tests__/$env.spec.ts +42 -0
  406. package/src/core/__tests__/dump.spec.ts +47 -0
  407. package/src/email/cloudflare/__tests__/CloudflareEmailProvider.spec.ts +42 -10
  408. package/src/email/cloudflare/index.ts +14 -5
  409. package/src/email/cloudflare/providers/CloudflareEmailProvider.ts +54 -9
  410. package/src/logger/__tests__/Logger.spec.ts +55 -0
  411. package/src/logger/index.ts +13 -0
  412. package/src/logger/services/Logger.ts +31 -1
  413. package/src/orm/__tests__/orm-showcase-tests.ts +27 -0
  414. package/src/orm/__tests__/orm-showcase.spec.ts +12 -0
  415. package/src/orm/core/interfaces/PgQuery.ts +4 -1
  416. package/src/orm/core/services/Repository.ts +27 -11
  417. package/src/react/auth/hooks/useAuth.ts +10 -5
  418. package/src/react/core/__tests__/useQuery.browser.spec.tsx +25 -0
  419. package/src/react/core/hooks/useAction.ts +14 -3
  420. package/src/react/core/hooks/useQuery.ts +24 -4
  421. package/src/react/i18n/components/Translate.tsx +47 -0
  422. package/src/react/i18n/index.ts +2 -0
  423. package/src/react/intro/components/GettingStartedAdminSlide.tsx +2 -2
  424. package/src/react/router/__tests__/$page.spec.tsx +3 -2
  425. package/src/react/router/__tests__/page-can.spec.ts +18 -13
  426. package/src/react/router/hooks/useQueryParams.ts +114 -14
  427. package/src/react/router/primitives/$page.ts +85 -4
  428. package/src/react/router/providers/ReactBrowserRouterProvider.ts +3 -7
  429. package/src/react/router/providers/ReactServerProvider.ts +4 -13
  430. package/src/react/ui/services/SchemaControl.ts +3 -4
  431. package/src/server/core/providers/ServerMultipartProvider.ts +19 -0
  432. package/src/server/links/providers/LinkProvider.ts +10 -0
  433. package/dist/containers/core/index.d.ts.map +0 -1
  434. package/dist/containers/core/index.js.map +0 -1
  435. package/dist/containers/core/index.workerd.js.map +0 -1
  436. package/src/cli/core/templates/componentsJsonTs.ts +0 -39
  437. package/src/cli/core/templates/saasAdminLayoutTsx.ts +0 -77
  438. package/src/cli/core/templates/saasAdminPagesTsx.ts +0 -26
  439. package/src/cli/core/templates/saasAuthLayoutTsx.ts +0 -22
  440. package/src/cli/core/templates/saasAuthPagesTsx.ts +0 -62
  441. package/src/cli/core/templates/saasRealmProviderTs.ts +0 -52
  442. package/src/cli/platform/services/NamingService.ts +0 -54
  443. /package/dist/orm/core/{chunk-o8xxKEmq.js → chunk-B4FMCO8f.js} +0 -0
  444. /package/dist/react/testing/{chunk-6Ep1yQYe.js → chunk-BpyX8vjI.js} +0 -0
  445. /package/src/cli/{platform → platform-lib}/__tests__/GitHubSecretStore.spec.ts +0 -0
  446. /package/src/cli/{platform → platform-lib}/__tests__/PlatformCacheProvider.spec.ts +0 -0
  447. /package/src/cli/{platform → platform-lib}/__tests__/PlatformInspector.spec.ts +0 -0
  448. /package/src/cli/{platform → platform-lib}/__tests__/PlatformOrchestrator.spec.ts +0 -0
  449. /package/src/cli/{platform → platform-lib}/__tests__/SecretFilterService.spec.ts +0 -0
  450. /package/src/cli/{platform → platform-lib}/__tests__/detectResources.spec.ts +0 -0
  451. /package/src/cli/{platform → platform-lib}/providers/GitHubSecretStore.ts +0 -0
  452. /package/src/cli/{platform → platform-lib}/providers/MemorySecretStore.ts +0 -0
  453. /package/src/cli/{platform → platform-lib}/providers/PlatformCacheProvider.ts +0 -0
  454. /package/src/cli/{platform → platform-lib}/providers/SecretStoreProvider.ts +0 -0
  455. /package/src/cli/{platform → platform-lib}/schemas/cloudflare.ts +0 -0
  456. /package/src/cli/{platform → platform-lib}/schemas/platform.ts +0 -0
  457. /package/src/cli/{platform → platform-lib}/schemas/vercel.ts +0 -0
  458. /package/src/cli/{platform → platform-lib}/services/CloudflareApi.ts +0 -0
  459. /package/src/cli/{platform → platform-lib}/services/SecretFilterService.ts +0 -0
  460. /package/src/cli/{platform → platform-lib}/services/VercelApi.ts +0 -0
  461. /package/src/cli/{platform → platform-lib}/services/VercelCli.ts +0 -0
  462. /package/src/{containers → container}/core/interfaces/ContainerOptions.ts +0 -0
  463. /package/src/{containers → container}/core/providers/NodeContainerProvider.ts +0 -0
@@ -1,5 +1,5 @@
1
1
  import { $atom, $context, $inject, $module, Alepha, AlephaError, t } from "alepha";
2
- import { AuditService } from "alepha/api/audits";
2
+ import { $audit } from "alepha/api/audits";
3
3
  import { $bucket } from "alepha/bucket";
4
4
  import { $issuer, $permission, $secure, CryptoProvider, InvalidCredentialsError, SecurityProvider } from "alepha/security";
5
5
  import { $action, BadRequestError, ConflictError, HttpError, UnauthorizedError, okSchema } from "alepha/server";
@@ -21,35 +21,65 @@ import { AlephaApiKeys, ApiKeyService } from "alepha/api/keys";
21
21
  import { AlephaOAuth, OAuthClientService, oauthOptions } from "alepha/api/oauth";
22
22
  import { $parameter, AlephaApiParameters } from "alepha/api/parameters";
23
23
  import { mcpStreamableHttpOptions } from "alepha/mcp";
24
- //#region ../../src/api/users/audits/UserAudits.ts
24
+ //#region ../../src/api/users/audits/SessionAudits.ts
25
25
  /**
26
- * User-specific audit wrapper service.
26
+ * Authentication & session-security audit events.
27
27
  *
28
- * This service wraps the core AuditService to provide user-related audit logging.
28
+ * Holds two audit types:
29
+ * - `auth` — login / logout / token refresh / MFA.
30
+ * - `security` — rate limiting, session invalidation, and related guards.
29
31
  *
30
- * Declared as a module variant not auto-injected. It is instantiated
31
- * lazily the first time something calls `alepha.inject(UserAudits)`.
32
+ * Failed events are logged with `success: false`; severity (`warning`) is
33
+ * derived centrally in `AuditService.create`. Register as a module variant
34
+ * and log via the exposed primitives:
35
+ * `sessionAudits(realm)?.auth.log("login", { success: false, … })`.
36
+ */
37
+ var SessionAudits = class {
38
+ auth = $audit({
39
+ type: "auth",
40
+ description: "Authentication events (login, logout, token refresh, MFA).",
41
+ actions: [
42
+ "login",
43
+ "logout",
44
+ "token_refresh",
45
+ "mfa_setup",
46
+ "mfa_verify"
47
+ ]
48
+ });
49
+ security = $audit({
50
+ type: "security",
51
+ description: "Security events (rate limiting, session invalidation, blocked access).",
52
+ actions: [
53
+ "rate_limited",
54
+ "sessions_invalidated",
55
+ "permission_denied",
56
+ "blocked"
57
+ ]
58
+ });
59
+ };
60
+ //#endregion
61
+ //#region ../../src/api/users/audits/UserAudits.ts
62
+ /**
63
+ * User-management audit events.
64
+ *
65
+ * Holds the `user` audit type. Mirrors the `$notification`/`$job` holder
66
+ * pattern (see {@link UserNotifications}) — register as a module variant and
67
+ * log via the exposed primitive: `userAudits(realm)?.user.log("create", …)`.
32
68
  */
33
69
  var UserAudits = class {
34
- auditService = $inject(AuditService);
35
- /**
36
- * Record a user-related audit event.
37
- */
38
- recordUser(action, context) {
39
- return this.auditService.recordUser(action, context);
40
- }
41
- /**
42
- * Record an authentication-related audit event.
43
- */
44
- recordAuth(action, context) {
45
- return this.auditService.recordAuth(action, context);
46
- }
47
- /**
48
- * Record a generic audit event.
49
- */
50
- record(category, action, context) {
51
- return this.auditService.record(category, action, context);
52
- }
70
+ user = $audit({
71
+ type: "user",
72
+ description: "User management events (create, update, delete, role/password changes).",
73
+ actions: [
74
+ "create",
75
+ "update",
76
+ "delete",
77
+ "role_change",
78
+ "password_change",
79
+ "enable",
80
+ "disable"
81
+ ]
82
+ });
53
83
  };
54
84
  //#endregion
55
85
  //#region ../../src/api/users/buckets/UserBuckets.ts
@@ -105,6 +135,7 @@ const users = $entity({
105
135
  picture: t.optional(t.string()),
106
136
  enabled: db.default(t.boolean(), true),
107
137
  emailVerified: db.default(t.boolean(), false),
138
+ lastLoginAt: t.optional(t.datetime()),
108
139
  organizationId: db.organization()
109
140
  }),
110
141
  indexes: [
@@ -281,6 +312,12 @@ const sessions = $entity({
281
312
  */
282
313
  lastUsedAt: t.optional(t.datetime()),
283
314
  ip: t.optional(t.text()),
315
+ /**
316
+ * ISO 3166-1 alpha-2 country code derived from the request geo headers
317
+ * (`cf-ipcountry` on Cloudflare, CDN equivalents elsewhere) at login time.
318
+ * `null` on pre-migration rows and where geo isn't available.
319
+ */
320
+ country: t.optional(t.text({ maxLength: 2 })),
284
321
  userAgent: t.optional(t.object({
285
322
  os: t.text(),
286
323
  browser: t.text(),
@@ -437,7 +474,8 @@ var IdentityService = class {
437
474
  userId: identity.userId
438
475
  });
439
476
  const realm = this.realmProvider.getRealm(userRealmName);
440
- await this.userAudits(userRealmName)?.recordUser("update", {
477
+ await this.userAudits(userRealmName)?.user.log("update", {
478
+ resourceType: "user",
441
479
  userRealm: realm.name,
442
480
  resourceId: identity.userId,
443
481
  description: `Identity provider disconnected: ${identity.provider}`,
@@ -515,6 +553,22 @@ var AdminIdentityController = class {
515
553
  const sessionQuerySchema = t.extend(pageQuerySchema, { userId: t.optional(t.uuid()) });
516
554
  //#endregion
517
555
  //#region ../../src/api/users/schemas/sessionResourceSchema.ts
556
+ /**
557
+ * Slim view of the session's owner — embedded by the admin listing so the
558
+ * UI can render a human-readable identifier instead of just a UUID. Comes
559
+ * back via a left join, so it's optional (a session whose user was deleted
560
+ * still returns; `user` is undefined).
561
+ */
562
+ const sessionUserSummarySchema = t.object({
563
+ id: t.uuid(),
564
+ email: t.optional(t.string({ format: "email" })),
565
+ username: t.optional(t.shortText({
566
+ minLength: 3,
567
+ maxLength: 30
568
+ })),
569
+ firstName: t.optional(t.string()),
570
+ lastName: t.optional(t.string())
571
+ });
518
572
  const sessionResourceSchema = t.object({
519
573
  id: t.uuid(),
520
574
  version: t.number(),
@@ -524,6 +578,7 @@ const sessionResourceSchema = t.object({
524
578
  userId: t.uuid(),
525
579
  expiresAt: t.datetime(),
526
580
  ip: t.optional(t.string()),
581
+ country: t.optional(t.string()),
527
582
  userAgent: t.optional(t.object({
528
583
  os: t.string(),
529
584
  browser: t.string(),
@@ -532,10 +587,21 @@ const sessionResourceSchema = t.object({
532
587
  "DESKTOP",
533
588
  "TABLET"
534
589
  ])
535
- }))
590
+ })),
591
+ user: t.optional(sessionUserSummarySchema)
536
592
  });
537
593
  //#endregion
538
594
  //#region ../../src/api/users/services/SessionCrudService.ts
595
+ /**
596
+ * Relation map embedding a slim user summary on every session row, so the
597
+ * admin UI can render `user.email`/`user.username` instead of a bare UUID.
598
+ * Left-join (default) so sessions whose owner was deleted still come back
599
+ * with `user: undefined`.
600
+ */
601
+ const withUser = { user: {
602
+ join: users,
603
+ on: ["userId", users.cols.id]
604
+ } };
539
605
  var SessionCrudService = class {
540
606
  log = $logger();
541
607
  realmProvider = $inject(RealmProvider);
@@ -553,7 +619,10 @@ var SessionCrudService = class {
553
619
  q.sort ??= "-createdAt";
554
620
  const where = this.sessions(userRealmName).createQueryWhere();
555
621
  if (q.userId) where.userId = { eq: q.userId };
556
- const result = await this.sessions(userRealmName).paginate(q, { where }, { count: true });
622
+ const result = await this.sessions(userRealmName).paginate(q, {
623
+ where,
624
+ with: withUser
625
+ }, { count: true });
557
626
  this.log.debug("Sessions found", {
558
627
  count: result.content.length,
559
628
  total: result.page.totalElements
@@ -568,7 +637,10 @@ var SessionCrudService = class {
568
637
  id,
569
638
  userRealmName
570
639
  });
571
- const session = await this.sessions(userRealmName).getById(id);
640
+ const session = await this.sessions(userRealmName).getOne({
641
+ where: { id: { eq: id } },
642
+ with: withUser
643
+ });
572
644
  this.log.debug("Session retrieved", {
573
645
  id,
574
646
  userId: session.userId
@@ -692,13 +764,18 @@ const updateUserSchema = t.partial(t.omit(users.insertSchema, [
692
764
  "id",
693
765
  "version",
694
766
  "createdAt",
695
- "updatedAt",
696
- "username",
697
- "emailVerified"
767
+ "updatedAt"
698
768
  ]));
699
769
  //#endregion
700
770
  //#region ../../src/api/users/schemas/userQuerySchema.ts
701
771
  const userQuerySchema = t.extend(pageQuerySchema, {
772
+ /**
773
+ * Free-text search applied (case-insensitive) across `email`,
774
+ * `username`, `firstName`, and `lastName`. Matches with a leading and
775
+ * trailing wildcard, so `?search=foo` finds any user whose email,
776
+ * username, or name contains `foo`.
777
+ */
778
+ search: t.optional(t.string()),
702
779
  email: t.optional(t.string()),
703
780
  enabled: t.optional(t.boolean()),
704
781
  emailVerified: t.optional(t.boolean()),
@@ -863,6 +940,7 @@ var UserService = class {
863
940
  log = $logger();
864
941
  verificationController = $client();
865
942
  realmProvider = $inject(RealmProvider);
943
+ cryptoProvider = $inject(CryptoProvider);
866
944
  userAudits(realmName) {
867
945
  if (this.realmProvider.getRealm(realmName).features.audits) return this.alepha.inject(UserAudits);
868
946
  }
@@ -977,7 +1055,8 @@ var UserService = class {
977
1055
  type
978
1056
  });
979
1057
  const realm = this.realmProvider.getRealm(userRealmName);
980
- await this.userAudits(userRealmName)?.recordUser("update", {
1058
+ await this.userAudits(userRealmName)?.user.log("update", {
1059
+ resourceType: "user",
981
1060
  userId: user.id,
982
1061
  userEmail: email,
983
1062
  userRealm: realm.name,
@@ -1009,6 +1088,15 @@ var UserService = class {
1009
1088
  });
1010
1089
  q.sort ??= "-createdAt";
1011
1090
  const where = this.users(userRealmName).createQueryWhere();
1091
+ if (q.search) {
1092
+ const pattern = `%${q.search}%`;
1093
+ where.or = [
1094
+ { email: { ilike: pattern } },
1095
+ { username: { ilike: pattern } },
1096
+ { firstName: { ilike: pattern } },
1097
+ { lastName: { ilike: pattern } }
1098
+ ];
1099
+ }
1012
1100
  if (q.email) where.email = { like: q.email };
1013
1101
  if (q.enabled !== void 0) where.enabled = { eq: q.enabled };
1014
1102
  if (q.emailVerified !== void 0) where.emailVerified = { eq: q.emailVerified };
@@ -1078,7 +1166,8 @@ var UserService = class {
1078
1166
  username: user.username,
1079
1167
  email: user.email
1080
1168
  });
1081
- await this.userAudits(userRealmName)?.recordUser("create", {
1169
+ await this.userAudits(userRealmName)?.user.log("create", {
1170
+ resourceType: "user",
1082
1171
  userRealm: realm.name,
1083
1172
  resourceId: user.id,
1084
1173
  description: "User created",
@@ -1099,16 +1188,33 @@ var UserService = class {
1099
1188
  userRealmName
1100
1189
  });
1101
1190
  const before = await this.getUserById(id, userRealmName);
1102
- const user = await this.users(userRealmName).updateById(id, data);
1103
- this.log.debug("User updated", { userId: id });
1104
1191
  const realm = this.realmProvider.getRealm(userRealmName);
1192
+ const users = this.users(userRealmName);
1193
+ if (data.username !== void 0 && data.username !== null && data.username !== before.username) {
1194
+ const existing = await users.findOne({ where: {
1195
+ realm: realm.name,
1196
+ username: { ilike: data.username }
1197
+ } });
1198
+ if (existing && existing.id !== id) throw new ConflictError("User with this username already exists");
1199
+ }
1200
+ if (data.email !== void 0 && data.email !== null && data.email !== before.email) {
1201
+ const existing = await users.findOne({ where: {
1202
+ realm: realm.name,
1203
+ email: { eq: data.email }
1204
+ } });
1205
+ if (existing && existing.id !== id) throw new ConflictError("User with this email already exists");
1206
+ data.emailVerified = false;
1207
+ }
1208
+ const user = await users.updateById(id, data);
1209
+ this.log.debug("User updated", { userId: id });
1105
1210
  const changes = {};
1106
1211
  for (const key of Object.keys(data)) if (data[key] !== void 0 && before[key] !== data[key]) changes[key] = {
1107
1212
  from: before[key],
1108
1213
  to: data[key]
1109
1214
  };
1110
1215
  const isRoleChange = data.roles !== void 0 && JSON.stringify(before.roles) !== JSON.stringify(data.roles);
1111
- await this.userAudits(userRealmName)?.recordUser(isRoleChange ? "role_change" : "update", {
1216
+ await this.userAudits(userRealmName)?.user.log(isRoleChange ? "role_change" : "update", {
1217
+ resourceType: "user",
1112
1218
  userRealm: realm.name,
1113
1219
  resourceId: user.id,
1114
1220
  description: isRoleChange ? "User roles changed" : `User updated: ${Object.keys(changes).join(", ")}`,
@@ -1117,6 +1223,46 @@ var UserService = class {
1117
1223
  return user;
1118
1224
  }
1119
1225
  /**
1226
+ * Set (or reset) a user's password. Upserts a "credentials" identity
1227
+ * with the new hash. Used by admin password-set flows; does NOT
1228
+ * verify any old password or token — the caller is responsible for
1229
+ * authorization.
1230
+ */
1231
+ async setPassword(id, newPassword, userRealmName) {
1232
+ this.log.trace("Setting password", {
1233
+ id,
1234
+ userRealmName
1235
+ });
1236
+ const user = await this.getUserById(id, userRealmName);
1237
+ const realm = this.realmProvider.getRealm(userRealmName);
1238
+ const settings = await realm.getSettings();
1239
+ if (settings.passwordPolicy) {
1240
+ const policy = settings.passwordPolicy;
1241
+ if (policy.minLength && newPassword.length < policy.minLength) throw new BadRequestError(`Password must be at least ${policy.minLength} characters`);
1242
+ }
1243
+ const hash = await this.cryptoProvider.hashPassword(newPassword);
1244
+ const identities = this.realmProvider.identityRepository(userRealmName);
1245
+ const existing = await identities.findOne({ where: {
1246
+ userId: { eq: id },
1247
+ provider: { eq: "credentials" }
1248
+ } });
1249
+ if (existing) await identities.updateById(existing.id, { password: hash });
1250
+ else await identities.create({
1251
+ userId: id,
1252
+ provider: "credentials",
1253
+ password: hash
1254
+ });
1255
+ await this.userAudits(userRealmName)?.user.log("password_change", {
1256
+ resourceType: "user",
1257
+ userId: id,
1258
+ userEmail: user.email ?? void 0,
1259
+ userRealm: realm.name,
1260
+ resourceId: id,
1261
+ severity: "warning",
1262
+ description: "Password set by admin"
1263
+ });
1264
+ }
1265
+ /**
1120
1266
  * Delete a user by ID.
1121
1267
  */
1122
1268
  async deleteUser(id, userRealmName) {
@@ -1130,7 +1276,8 @@ var UserService = class {
1130
1276
  await this.users(userRealmName).deleteById(id);
1131
1277
  this.log.info("User deleted", { userId: id });
1132
1278
  const realm = this.realmProvider.getRealm(userRealmName);
1133
- await this.userAudits(userRealmName)?.recordUser("delete", {
1279
+ await this.userAudits(userRealmName)?.user.log("delete", {
1280
+ resourceType: "user",
1134
1281
  userRealm: realm.name,
1135
1282
  resourceId: id,
1136
1283
  severity: "warning",
@@ -1148,6 +1295,32 @@ var AdminUserController = class {
1148
1295
  url = "/users";
1149
1296
  group = "admin:users";
1150
1297
  userService = $inject(UserService);
1298
+ securityProvider = $inject(SecurityProvider);
1299
+ /**
1300
+ * List roles available in a realm. Used by the admin UI to render the
1301
+ * role picker and grey out defaults (which cannot be removed).
1302
+ */
1303
+ findRoles = $action({
1304
+ path: "/metadata/roles",
1305
+ group: this.group,
1306
+ use: [$secure({ permissions: ["admin:user:read"] })],
1307
+ description: "List roles available in a realm",
1308
+ schema: {
1309
+ query: t.object({ userRealmName: t.optional(t.string()) }),
1310
+ response: t.array(t.object({
1311
+ name: t.string(),
1312
+ default: t.optional(t.boolean()),
1313
+ description: t.optional(t.string())
1314
+ }))
1315
+ },
1316
+ handler: ({ query }) => {
1317
+ return this.securityProvider.getRoles(query.userRealmName).map((r) => ({
1318
+ name: r.name,
1319
+ default: r.default,
1320
+ description: r.description
1321
+ }));
1322
+ }
1323
+ });
1151
1324
  /**
1152
1325
  * Find users with pagination and filtering.
1153
1326
  */
@@ -1214,6 +1387,31 @@ var AdminUserController = class {
1214
1387
  handler: ({ params, body, query }) => this.userService.updateUser(params.id, body, query.userRealmName)
1215
1388
  });
1216
1389
  /**
1390
+ * Set (or reset) a user's password. Admin-only flow — does NOT
1391
+ * require knowing the previous password. Hash is stored as a
1392
+ * "credentials" identity for the user (upsert).
1393
+ */
1394
+ setUserPassword = $action({
1395
+ method: "POST",
1396
+ path: `${this.url}/:id/password`,
1397
+ group: this.group,
1398
+ use: [$secure({ permissions: ["admin:user:update"] })],
1399
+ description: "Set a user's password",
1400
+ schema: {
1401
+ params: t.object({ id: t.uuid() }),
1402
+ query: t.object({ userRealmName: t.optional(t.string()) }),
1403
+ body: t.object({ password: t.string({ minLength: 1 }) }),
1404
+ response: okSchema
1405
+ },
1406
+ handler: async ({ params, body, query }) => {
1407
+ await this.userService.setPassword(params.id, body.password, query.userRealmName);
1408
+ return {
1409
+ ok: true,
1410
+ id: params.id
1411
+ };
1412
+ }
1413
+ });
1414
+ /**
1217
1415
  * Delete a user.
1218
1416
  */
1219
1417
  deleteUser = $action({
@@ -1421,6 +1619,9 @@ var CredentialService = class {
1421
1619
  userAudits(realmName) {
1422
1620
  if (this.realmProvider.getRealm(realmName).features.audits) return this.alepha.inject(UserAudits);
1423
1621
  }
1622
+ sessionAudits(realmName) {
1623
+ if (this.realmProvider.getRealm(realmName).features.audits) return this.alepha.inject(SessionAudits);
1624
+ }
1424
1625
  userNotifications(realmName) {
1425
1626
  if (this.realmProvider.getRealm(realmName).features.notifications) return this.alepha.inject(UserNotifications);
1426
1627
  }
@@ -1572,7 +1773,8 @@ var CredentialService = class {
1572
1773
  userId: intent.userId,
1573
1774
  email: intent.email
1574
1775
  });
1575
- await this.userAudits(intent.realmName)?.recordUser("update", {
1776
+ await this.userAudits(intent.realmName)?.user.log("update", {
1777
+ resourceType: "user",
1576
1778
  userId: intent.userId,
1577
1779
  userEmail: intent.email,
1578
1780
  userRealm: realm.name,
@@ -1580,7 +1782,7 @@ var CredentialService = class {
1580
1782
  description: "Password reset completed",
1581
1783
  metadata: { email: intent.email }
1582
1784
  });
1583
- await this.userAudits(intent.realmName)?.record("security", "sessions_invalidated", {
1785
+ await this.sessionAudits(intent.realmName)?.security.log("sessions_invalidated", {
1584
1786
  userId: intent.userId,
1585
1787
  userEmail: intent.email,
1586
1788
  userRealm: realm.name,
@@ -1629,7 +1831,8 @@ var CredentialService = class {
1629
1831
  const hashedPassword = await this.cryptoProvider.hashPassword(newPassword);
1630
1832
  await this.identities(userRealmName).updateById(identity.id, { password: hashedPassword });
1631
1833
  await this.sessions(userRealmName).deleteMany({ userId: { eq: user.id } });
1632
- await this.userAudits(userRealmName)?.recordUser("update", {
1834
+ await this.userAudits(userRealmName)?.user.log("update", {
1835
+ resourceType: "user",
1633
1836
  userId: user.id,
1634
1837
  userEmail: email,
1635
1838
  userRealm: realm.name,
@@ -1637,7 +1840,7 @@ var CredentialService = class {
1637
1840
  description: "Password reset completed (legacy)",
1638
1841
  metadata: { email }
1639
1842
  });
1640
- await this.userAudits(userRealmName)?.record("security", "sessions_invalidated", {
1843
+ await this.sessionAudits(userRealmName)?.security.log("sessions_invalidated", {
1641
1844
  userId: user.id,
1642
1845
  userEmail: email,
1643
1846
  userRealm: realm.name,
@@ -1986,7 +2189,8 @@ var RegistrationService = class {
1986
2189
  email: user.email,
1987
2190
  username: user.username
1988
2191
  });
1989
- await this.userAudits(userRealmName)?.recordUser("create", {
2192
+ await this.userAudits(userRealmName)?.user.log("create", {
2193
+ resourceType: "user",
1990
2194
  userId: user.id,
1991
2195
  userEmail: user.email ?? void 0,
1992
2196
  userRealm: realm.name,
@@ -2409,6 +2613,9 @@ var SessionService = class SessionService {
2409
2613
  userAudits(realmName) {
2410
2614
  if (this.realmProvider.getRealm(realmName).features.audits) return this.alepha.inject(UserAudits);
2411
2615
  }
2616
+ sessionAudits(realmName) {
2617
+ if (this.realmProvider.getRealm(realmName).features.audits) return this.alepha.inject(SessionAudits);
2618
+ }
2412
2619
  userNotifications(realmName) {
2413
2620
  if (this.realmProvider.getRealm(realmName).features.notifications) return this.alepha.inject(UserNotifications);
2414
2621
  }
@@ -2444,7 +2651,8 @@ var SessionService = class SessionService {
2444
2651
  username: user.username,
2445
2652
  realm: name
2446
2653
  });
2447
- await this.userAudits(userRealmName)?.recordUser("role_change", {
2654
+ await this.userAudits(userRealmName)?.user.log("role_change", {
2655
+ resourceType: "user",
2448
2656
  userId: user.id,
2449
2657
  userEmail: user.email ?? void 0,
2450
2658
  userRealm: name,
@@ -2541,8 +2749,9 @@ var SessionService = class SessionService {
2541
2749
  username,
2542
2750
  realm: name
2543
2751
  });
2544
- await this.userAudits(userRealmName)?.recordAuth("login_failed", {
2752
+ await this.sessionAudits(userRealmName)?.auth.log("login", {
2545
2753
  userRealm: name,
2754
+ success: false,
2546
2755
  description: "Username does not match required format",
2547
2756
  metadata: {
2548
2757
  provider,
@@ -2561,8 +2770,9 @@ var SessionService = class SessionService {
2561
2770
  username,
2562
2771
  realm: name
2563
2772
  });
2564
- await this.userAudits(userRealmName)?.recordAuth("login_failed", {
2773
+ await this.sessionAudits(userRealmName)?.auth.log("login", {
2565
2774
  userRealm: name,
2775
+ success: false,
2566
2776
  description: "Invalid login identifier format",
2567
2777
  metadata: {
2568
2778
  provider,
@@ -2578,8 +2788,9 @@ var SessionService = class SessionService {
2578
2788
  username,
2579
2789
  realm: name
2580
2790
  });
2581
- await this.userAudits(userRealmName)?.recordAuth("login_failed", {
2791
+ await this.sessionAudits(userRealmName)?.auth.log("login", {
2582
2792
  userRealm: name,
2793
+ success: false,
2583
2794
  description: "User not found",
2584
2795
  metadata: {
2585
2796
  provider,
@@ -2587,7 +2798,7 @@ var SessionService = class SessionService {
2587
2798
  }
2588
2799
  });
2589
2800
  if (ipKey) {
2590
- if (await this.recordFailedLogin(ipKey, loginRateLimit.ipMaxAttempts, loginRateLimit.windowMs)) await this.userAudits(userRealmName)?.record("security", "rate_limited", {
2801
+ if (await this.recordFailedLogin(ipKey, loginRateLimit.ipMaxAttempts, loginRateLimit.windowMs)) await this.sessionAudits(userRealmName)?.security.log("rate_limited", {
2591
2802
  userRealm: name,
2592
2803
  success: false,
2593
2804
  description: "IP temporarily locked due to too many failed login attempts",
@@ -2601,8 +2812,9 @@ var SessionService = class SessionService {
2601
2812
  userId: user.id,
2602
2813
  realm: name
2603
2814
  });
2604
- await this.userAudits(userRealmName)?.recordAuth("login_failed", {
2815
+ await this.sessionAudits(userRealmName)?.auth.log("login", {
2605
2816
  userRealm: name,
2817
+ success: false,
2606
2818
  resourceId: user.id,
2607
2819
  description: "Login attempt for disabled account",
2608
2820
  metadata: {
@@ -2640,8 +2852,9 @@ var SessionService = class SessionService {
2640
2852
  username,
2641
2853
  realm: name
2642
2854
  });
2643
- await this.userAudits(userRealmName)?.recordAuth("login_failed", {
2855
+ await this.sessionAudits(userRealmName)?.auth.log("login", {
2644
2856
  userRealm: name,
2857
+ success: false,
2645
2858
  resourceId: user.id,
2646
2859
  description: "Invalid password",
2647
2860
  metadata: {
@@ -2650,7 +2863,7 @@ var SessionService = class SessionService {
2650
2863
  }
2651
2864
  });
2652
2865
  if (ipKey) {
2653
- if (await this.recordFailedLogin(ipKey, loginRateLimit.ipMaxAttempts, loginRateLimit.windowMs)) await this.userAudits(userRealmName)?.record("security", "rate_limited", {
2866
+ if (await this.recordFailedLogin(ipKey, loginRateLimit.ipMaxAttempts, loginRateLimit.windowMs)) await this.sessionAudits(userRealmName)?.security.log("rate_limited", {
2654
2867
  userRealm: name,
2655
2868
  success: false,
2656
2869
  description: "IP temporarily locked due to too many failed login attempts",
@@ -2658,7 +2871,7 @@ var SessionService = class SessionService {
2658
2871
  });
2659
2872
  }
2660
2873
  if (await this.recordFailedLogin(accountKey, loginRateLimit.accountMaxAttempts, loginRateLimit.windowMs)) {
2661
- await this.userAudits(userRealmName)?.record("security", "rate_limited", {
2874
+ await this.sessionAudits(userRealmName)?.security.log("rate_limited", {
2662
2875
  userRealm: name,
2663
2876
  resourceId: user.id,
2664
2877
  success: false,
@@ -2678,7 +2891,7 @@ var SessionService = class SessionService {
2678
2891
  }
2679
2892
  throw new InvalidCredentialsError();
2680
2893
  }
2681
- await this.userAudits(userRealmName)?.recordAuth("login", {
2894
+ await this.sessionAudits(userRealmName)?.auth.log("login", {
2682
2895
  userId: user.id,
2683
2896
  userEmail: user.email ?? void 0,
2684
2897
  userRealm: name,
@@ -2705,15 +2918,18 @@ var SessionService = class SessionService {
2705
2918
  const request = this.alepha.store.get("alepha.http.request");
2706
2919
  const refreshToken = this.cryptoProvider.randomUUID();
2707
2920
  const expiresAt = this.dateTimeProvider.now().add(expiresIn, "seconds").toISOString();
2921
+ const nowIso = this.dateTimeProvider.nowISOString();
2708
2922
  const session = await this.sessions(userRealmName).create({
2709
2923
  userId: user.id,
2710
2924
  expiresAt,
2711
- lastUsedAt: this.dateTimeProvider.nowISOString(),
2925
+ lastUsedAt: nowIso,
2712
2926
  ip: request?.ip,
2927
+ country: request?.geo?.country,
2713
2928
  userAgent: request?.userAgent,
2714
2929
  refreshToken,
2715
2930
  clientId
2716
2931
  });
2932
+ await this.users(userRealmName).updateById(user.id, { lastLoginAt: nowIso });
2717
2933
  this.log.info("Session created", {
2718
2934
  sessionId: session.id,
2719
2935
  userId: user.id,
@@ -2780,7 +2996,7 @@ var SessionService = class SessionService {
2780
2996
  this.log.debug("Session deleted");
2781
2997
  if (session) {
2782
2998
  const { name } = this.realmProvider.getRealm(userRealmName);
2783
- await this.userAudits(userRealmName)?.recordAuth("logout", {
2999
+ await this.sessionAudits(userRealmName)?.auth.log("logout", {
2784
3000
  userId: session.userId,
2785
3001
  userRealm: name,
2786
3002
  sessionId: session.id,
@@ -2808,7 +3024,7 @@ var SessionService = class SessionService {
2808
3024
  userId: identity.userId
2809
3025
  });
2810
3026
  const user = await users.getById(identity.userId);
2811
- await this.userAudits(userRealmName)?.recordAuth("login", {
3027
+ await this.sessionAudits(userRealmName)?.auth.log("login", {
2812
3028
  userId: user.id,
2813
3029
  userEmail: user.email ?? void 0,
2814
3030
  userRealm: realm.name,
@@ -2856,7 +3072,7 @@ var SessionService = class SessionService {
2856
3072
  providerUserId: profile.sub,
2857
3073
  userId: existing.id
2858
3074
  });
2859
- await this.userAudits(userRealmName)?.recordAuth("login", {
3075
+ await this.sessionAudits(userRealmName)?.auth.log("login", {
2860
3076
  userId: existing.id,
2861
3077
  userEmail: existing.email ?? void 0,
2862
3078
  userRealm: realm.name,
@@ -2918,7 +3134,8 @@ var SessionService = class SessionService {
2918
3134
  email: user.email,
2919
3135
  username: user.username
2920
3136
  });
2921
- await this.userAudits(userRealmName)?.recordUser("create", {
3137
+ await this.userAudits(userRealmName)?.user.log("create", {
3138
+ resourceType: "user",
2922
3139
  userId: user.id,
2923
3140
  userEmail: user.email ?? void 0,
2924
3141
  userRealm: realm.name,
@@ -2931,7 +3148,7 @@ var SessionService = class SessionService {
2931
3148
  email: user.email
2932
3149
  }
2933
3150
  });
2934
- await this.userAudits(userRealmName)?.recordAuth("login", {
3151
+ await this.sessionAudits(userRealmName)?.auth.log("login", {
2935
3152
  userId: user.id,
2936
3153
  userEmail: user.email ?? void 0,
2937
3154
  userRealm: realm.name,
@@ -2986,7 +3203,10 @@ const $realm = (options = {}) => {
2986
3203
  }
2987
3204
  const realmRegistration = realmProvider.register(name, options);
2988
3205
  if (features.avatars) alepha.with(UserBuckets);
2989
- if (features.audits) alepha.with(UserAudits);
3206
+ if (features.audits) {
3207
+ alepha.with(UserAudits);
3208
+ alepha.with(SessionAudits);
3209
+ }
2990
3210
  if (features.jobs) alepha.with(UserJobs);
2991
3211
  if (features.notifications) {
2992
3212
  alepha.with(UserNotifications);
@@ -3008,6 +3228,7 @@ const $realm = (options = {}) => {
3008
3228
  permissions: [{ name: "*" }]
3009
3229
  }, {
3010
3230
  name: "user",
3231
+ default: true,
3011
3232
  permissions: [{
3012
3233
  name: "*",
3013
3234
  ownership: true,
@@ -3194,10 +3415,11 @@ const AlephaApiUsers = $module({
3194
3415
  UserJobs,
3195
3416
  UserNotifications,
3196
3417
  UserAudits,
3418
+ SessionAudits,
3197
3419
  UserBuckets
3198
3420
  ]
3199
3421
  });
3200
3422
  //#endregion
3201
- export { $realm, AdminIdentityController, AdminSessionController, AdminUserController, AlephaApiUsers, CredentialService, DEFAULT_USER_REALM_NAME, IdentityService, RealmController, RealmProvider, RegistrationService, SessionCrudService, SessionService, UserAudits, UserBuckets, UserController, UserJobs, UserNotifications, UserService, UsernameSlugger, completePasswordResetRequestSchema, completeRegistrationRequestSchema, createUserSchema, identities, identityQuerySchema, identityResourceSchema, loginSchema, passwordResetIntentResponseSchema, realmAuthSettingsAtom, realmConfigSchema, registerSchema, registrationIntentResponseSchema, resetPasswordRequestSchema, resetPasswordSchema, sessionQuerySchema, sessionResourceSchema, sessions, updateUserSchema, userQuerySchema, userResourceSchema, users };
3423
+ export { $realm, AdminIdentityController, AdminSessionController, AdminUserController, AlephaApiUsers, CredentialService, DEFAULT_USER_REALM_NAME, IdentityService, RealmController, RealmProvider, RegistrationService, SessionAudits, SessionCrudService, SessionService, UserAudits, UserBuckets, UserController, UserJobs, UserNotifications, UserService, UsernameSlugger, completePasswordResetRequestSchema, completeRegistrationRequestSchema, createUserSchema, identities, identityQuerySchema, identityResourceSchema, loginSchema, passwordResetIntentResponseSchema, realmAuthSettingsAtom, realmConfigSchema, registerSchema, registrationIntentResponseSchema, resetPasswordRequestSchema, resetPasswordSchema, sessionQuerySchema, sessionResourceSchema, sessionUserSummarySchema, sessions, updateUserSchema, userQuerySchema, userResourceSchema, users };
3202
3424
 
3203
3425
  //# sourceMappingURL=index.js.map