alepha 0.21.2 → 0.23.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 (519) 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 +282 -285
  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 +217 -222
  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 +1106 -1005
  49. package/dist/api/users/index.d.ts.map +1 -1
  50. package/dist/api/users/index.js +307 -64
  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 +137 -143
  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 +458 -249
  88. package/dist/cli/core/index.d.ts.map +1 -1
  89. package/dist/cli/core/index.js +372 -660
  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 +20 -17
  95. package/dist/cli/i18n/index.d.ts.map +1 -1
  96. package/dist/cli/i18n/index.js +45 -11
  97. package/dist/cli/i18n/index.js.map +1 -1
  98. package/dist/cli/platform/index.d.ts +126 -1342
  99. package/dist/cli/platform/index.d.ts.map +1 -1
  100. package/dist/cli/platform/index.js +136 -2374
  101. package/dist/cli/platform/index.js.map +1 -1
  102. package/dist/cli/platform-lib/index.d.ts +1472 -0
  103. package/dist/cli/platform-lib/index.d.ts.map +1 -0
  104. package/dist/cli/platform-lib/index.js +2660 -0
  105. package/dist/cli/platform-lib/index.js.map +1 -0
  106. package/dist/cli/vendor/index.d.ts +17 -21
  107. package/dist/cli/vendor/index.d.ts.map +1 -1
  108. package/dist/cli/vendor/index.js.map +1 -1
  109. package/dist/command/index.d.ts +20 -19
  110. package/dist/command/index.d.ts.map +1 -1
  111. package/dist/command/index.js +39 -10
  112. package/dist/command/index.js.map +1 -1
  113. package/dist/{containers → container}/core/index.d.ts +13 -15
  114. package/dist/container/core/index.d.ts.map +1 -0
  115. package/dist/{containers → container}/core/index.js +23 -14
  116. package/dist/container/core/index.js.map +1 -0
  117. package/dist/{containers → container}/core/index.workerd.js +37 -22
  118. package/dist/container/core/index.workerd.js.map +1 -0
  119. package/dist/core/index.browser.js +27 -1
  120. package/dist/core/index.browser.js.map +1 -1
  121. package/dist/core/index.d.ts +48 -24
  122. package/dist/core/index.d.ts.map +1 -1
  123. package/dist/core/index.js +27 -1
  124. package/dist/core/index.js.map +1 -1
  125. package/dist/core/index.native.js +27 -1
  126. package/dist/core/index.native.js.map +1 -1
  127. package/dist/core/index.workerd.js +27 -1
  128. package/dist/core/index.workerd.js.map +1 -1
  129. package/dist/crypto/index.browser.js.map +1 -1
  130. package/dist/crypto/index.d.ts +5 -8
  131. package/dist/crypto/index.d.ts.map +1 -1
  132. package/dist/crypto/index.js.map +1 -1
  133. package/dist/datetime/index.d.ts +3 -4
  134. package/dist/datetime/index.d.ts.map +1 -1
  135. package/dist/datetime/index.js.map +1 -1
  136. package/dist/email/brevo/index.d.ts +2 -4
  137. package/dist/email/brevo/index.d.ts.map +1 -1
  138. package/dist/email/brevo/index.js.map +1 -1
  139. package/dist/email/cloudflare/index.d.ts +20 -7
  140. package/dist/email/cloudflare/index.d.ts.map +1 -1
  141. package/dist/email/cloudflare/index.js +46 -9
  142. package/dist/email/cloudflare/index.js.map +1 -1
  143. package/dist/email/core/index.d.ts +6 -9
  144. package/dist/email/core/index.d.ts.map +1 -1
  145. package/dist/email/core/index.js.map +1 -1
  146. package/dist/email/core/index.workerd.js.map +1 -1
  147. package/dist/email/smtp/index.d.ts +10 -13
  148. package/dist/email/smtp/index.d.ts.map +1 -1
  149. package/dist/email/smtp/index.js +107 -32
  150. package/dist/email/smtp/index.js.map +1 -1
  151. package/dist/fake/index.d.ts +1 -2
  152. package/dist/fake/index.d.ts.map +1 -1
  153. package/dist/fake/index.js.map +1 -1
  154. package/dist/lock/core/index.d.ts +9 -14
  155. package/dist/lock/core/index.d.ts.map +1 -1
  156. package/dist/lock/core/index.js.map +1 -1
  157. package/dist/lock/redis/index.d.ts +2 -4
  158. package/dist/lock/redis/index.d.ts.map +1 -1
  159. package/dist/lock/redis/index.js.map +1 -1
  160. package/dist/logger/index.d.ts +105 -76
  161. package/dist/logger/index.d.ts.map +1 -1
  162. package/dist/logger/index.js +196 -174
  163. package/dist/logger/index.js.map +1 -1
  164. package/dist/mcp/index.d.ts +25 -20
  165. package/dist/mcp/index.d.ts.map +1 -1
  166. package/dist/mcp/index.js +23 -0
  167. package/dist/mcp/index.js.map +1 -1
  168. package/dist/orm/core/index.browser.js.map +1 -1
  169. package/dist/orm/core/index.bun.js +19 -1
  170. package/dist/orm/core/index.bun.js.map +1 -1
  171. package/dist/orm/core/index.d.ts +76 -62
  172. package/dist/orm/core/index.d.ts.map +1 -1
  173. package/dist/orm/core/index.js +20 -2
  174. package/dist/orm/core/index.js.map +1 -1
  175. package/dist/orm/postgres/index.bun.js.map +1 -1
  176. package/dist/orm/postgres/index.d.ts +28 -20
  177. package/dist/orm/postgres/index.d.ts.map +1 -1
  178. package/dist/orm/postgres/index.js.map +1 -1
  179. package/dist/queue/core/index.d.ts +12 -15
  180. package/dist/queue/core/index.d.ts.map +1 -1
  181. package/dist/queue/core/index.js.map +1 -1
  182. package/dist/queue/core/index.workerd.js.map +1 -1
  183. package/dist/queue/redis/index.d.ts +3 -5
  184. package/dist/queue/redis/index.d.ts.map +1 -1
  185. package/dist/queue/redis/index.js.map +1 -1
  186. package/dist/react/auth/index.browser.js +9 -2
  187. package/dist/react/auth/index.browser.js.map +1 -1
  188. package/dist/react/auth/index.d.ts +14 -9
  189. package/dist/react/auth/index.d.ts.map +1 -1
  190. package/dist/react/auth/index.js +9 -2
  191. package/dist/react/auth/index.js.map +1 -1
  192. package/dist/react/core/index.d.ts +7 -8
  193. package/dist/react/core/index.d.ts.map +1 -1
  194. package/dist/react/core/index.js +6 -3
  195. package/dist/react/core/index.js.map +1 -1
  196. package/dist/react/form/index.d.ts +2 -5
  197. package/dist/react/form/index.d.ts.map +1 -1
  198. package/dist/react/form/index.js +16 -15
  199. package/dist/react/form/index.js.map +1 -1
  200. package/dist/react/head/index.browser.js.map +1 -1
  201. package/dist/react/head/index.d.ts +2 -4
  202. package/dist/react/head/index.d.ts.map +1 -1
  203. package/dist/react/head/index.js.map +1 -1
  204. package/dist/react/i18n/index.d.ts +90 -11
  205. package/dist/react/i18n/index.d.ts.map +1 -1
  206. package/dist/react/i18n/index.js +147 -11
  207. package/dist/react/i18n/index.js.map +1 -1
  208. package/dist/react/intro/index.d.ts +1 -2
  209. package/dist/react/intro/index.d.ts.map +1 -1
  210. package/dist/react/intro/index.js +2 -2
  211. package/dist/react/intro/index.js.map +1 -1
  212. package/dist/react/router/index.browser.js +193 -24
  213. package/dist/react/router/index.browser.js.map +1 -1
  214. package/dist/react/router/index.d.ts +434 -222
  215. package/dist/react/router/index.d.ts.map +1 -1
  216. package/dist/react/router/index.js +249 -35
  217. package/dist/react/router/index.js.map +1 -1
  218. package/dist/react/sitemap/index.browser.js +35 -0
  219. package/dist/react/sitemap/index.browser.js.map +1 -0
  220. package/dist/react/sitemap/index.d.ts +92 -0
  221. package/dist/react/sitemap/index.d.ts.map +1 -0
  222. package/dist/react/sitemap/index.js +131 -0
  223. package/dist/react/sitemap/index.js.map +1 -0
  224. package/dist/react/testing/index.d.ts +1 -2
  225. package/dist/react/testing/index.d.ts.map +1 -1
  226. package/dist/react/testing/index.js +16 -17
  227. package/dist/react/testing/index.js.map +1 -1
  228. package/dist/react/ui/index.d.ts +20 -25
  229. package/dist/react/ui/index.d.ts.map +1 -1
  230. package/dist/react/ui/index.js.map +1 -1
  231. package/dist/redis/index.bun.js.map +1 -1
  232. package/dist/redis/index.d.ts +17 -19
  233. package/dist/redis/index.d.ts.map +1 -1
  234. package/dist/redis/index.js.map +1 -1
  235. package/dist/retry/index.d.ts +2 -4
  236. package/dist/retry/index.d.ts.map +1 -1
  237. package/dist/retry/index.js.map +1 -1
  238. package/dist/router/index.d.ts.map +1 -1
  239. package/dist/router/index.js.map +1 -1
  240. package/dist/scheduler/index.d.ts +10 -13
  241. package/dist/scheduler/index.d.ts.map +1 -1
  242. package/dist/scheduler/index.js.map +1 -1
  243. package/dist/scheduler/index.workerd.js.map +1 -1
  244. package/dist/security/index.browser.js.map +1 -1
  245. package/dist/security/index.d.ts +45 -48
  246. package/dist/security/index.d.ts.map +1 -1
  247. package/dist/security/index.js.map +1 -1
  248. package/dist/server/auth/index.browser.js.map +1 -1
  249. package/dist/server/auth/index.d.ts +272 -173
  250. package/dist/server/auth/index.d.ts.map +1 -1
  251. package/dist/server/auth/index.js +1608 -15
  252. package/dist/server/auth/index.js.map +1 -1
  253. package/dist/server/cookies/index.browser.js.map +1 -1
  254. package/dist/server/cookies/index.d.ts +20 -7
  255. package/dist/server/cookies/index.d.ts.map +1 -1
  256. package/dist/server/cookies/index.js +22 -3
  257. package/dist/server/cookies/index.js.map +1 -1
  258. package/dist/server/core/index.browser.js.map +1 -1
  259. package/dist/server/core/index.d.ts +106 -73
  260. package/dist/server/core/index.d.ts.map +1 -1
  261. package/dist/server/core/index.js +44 -0
  262. package/dist/server/core/index.js.map +1 -1
  263. package/dist/server/cors/index.d.ts +11 -14
  264. package/dist/server/cors/index.d.ts.map +1 -1
  265. package/dist/server/cors/index.js.map +1 -1
  266. package/dist/server/etag/index.d.ts +6 -9
  267. package/dist/server/etag/index.d.ts.map +1 -1
  268. package/dist/server/etag/index.js.map +1 -1
  269. package/dist/server/health/index.d.ts +18 -21
  270. package/dist/server/health/index.d.ts.map +1 -1
  271. package/dist/server/health/index.js.map +1 -1
  272. package/dist/server/links/index.browser.js +2 -0
  273. package/dist/server/links/index.browser.js.map +1 -1
  274. package/dist/server/links/index.d.ts +63 -67
  275. package/dist/server/links/index.d.ts.map +1 -1
  276. package/dist/server/links/index.js +2 -0
  277. package/dist/server/links/index.js.map +1 -1
  278. package/dist/server/metrics/index.d.ts +5 -7
  279. package/dist/server/metrics/index.d.ts.map +1 -1
  280. package/dist/server/metrics/index.js.map +1 -1
  281. package/dist/server/proxy/index.d.ts +3 -5
  282. package/dist/server/proxy/index.d.ts.map +1 -1
  283. package/dist/server/proxy/index.js.map +1 -1
  284. package/dist/server/rate-limit/index.d.ts +10 -13
  285. package/dist/server/rate-limit/index.d.ts.map +1 -1
  286. package/dist/server/rate-limit/index.js.map +1 -1
  287. package/dist/server/static/index.d.ts +3 -5
  288. package/dist/server/static/index.d.ts.map +1 -1
  289. package/dist/server/static/index.js.map +1 -1
  290. package/dist/server/swagger/index.d.ts +5 -8
  291. package/dist/server/swagger/index.d.ts.map +1 -1
  292. package/dist/server/swagger/index.js.map +1 -1
  293. package/dist/sms/index.d.ts +3 -5
  294. package/dist/sms/index.d.ts.map +1 -1
  295. package/dist/sms/index.js.map +1 -1
  296. package/dist/system/index.browser.js.map +1 -1
  297. package/dist/system/index.d.ts +2 -4
  298. package/dist/system/index.d.ts.map +1 -1
  299. package/dist/system/index.js.map +1 -1
  300. package/dist/system/index.workerd.js.map +1 -1
  301. package/dist/topic/core/index.d.ts +4 -6
  302. package/dist/topic/core/index.d.ts.map +1 -1
  303. package/dist/topic/core/index.js.map +1 -1
  304. package/dist/topic/redis/index.d.ts +5 -8
  305. package/dist/topic/redis/index.d.ts.map +1 -1
  306. package/dist/topic/redis/index.js.map +1 -1
  307. package/package.json +59 -23
  308. package/src/api/audits/__tests__/AuditService.spec.ts +18 -110
  309. package/src/api/audits/controllers/AdminAuditController.ts +14 -0
  310. package/src/api/audits/services/AuditService.ts +21 -88
  311. package/src/api/files/__tests__/FileService.spec.ts +207 -2
  312. package/src/api/files/index.ts +3 -0
  313. package/src/api/files/schemas/fileCreatorSummarySchema.ts +22 -0
  314. package/src/api/files/schemas/fileResourceSchema.ts +10 -1
  315. package/src/api/files/services/FileService.ts +170 -72
  316. package/src/api/jobs/__tests__/$job.spec.ts +24 -1
  317. package/src/api/jobs/index.ts +4 -3
  318. package/src/api/jobs/primitives/$job.ts +7 -3
  319. package/src/api/jobs/providers/DirectJobDispatcher.ts +17 -36
  320. package/src/api/jobs/providers/JobProvider.ts +53 -24
  321. package/src/api/jobs/schemas/jobConfigAtom.ts +1 -1
  322. package/src/api/jobs/schemas/jobExecutionResourceSchema.ts +4 -1
  323. package/src/api/keys/schemas/adminApiKeyResourceSchema.ts +3 -1
  324. package/src/api/parameters/__tests__/$parameter.spec.ts +19 -2
  325. package/src/api/parameters/audits/ParameterAudits.ts +17 -0
  326. package/src/api/parameters/controllers/AdminParameterController.ts +95 -19
  327. package/src/api/parameters/index.ts +3 -0
  328. package/src/api/parameters/schemas/activateParameterBodySchema.ts +3 -3
  329. package/src/api/parameters/schemas/createParameterVersionBodySchema.ts +3 -2
  330. package/src/api/parameters/schemas/parameterCreatorSummarySchema.ts +25 -0
  331. package/src/api/parameters/schemas/parameterResponseSchema.ts +5 -0
  332. package/src/api/parameters/schemas/rollbackParameterBodySchema.ts +4 -2
  333. package/src/api/parameters/services/ParameterProvider.ts +69 -6
  334. package/src/api/subscriptions/jobs/SubscriptionJobs.ts +1 -1
  335. package/src/api/users/__tests__/AdminSessionController.spec.ts +37 -0
  336. package/src/api/users/audits/SessionAudits.ts +33 -0
  337. package/src/api/users/audits/UserAudits.ts +19 -43
  338. package/src/api/users/controllers/AdminUserController.ts +66 -1
  339. package/src/api/users/controllers/RealmController.ts +1 -0
  340. package/src/api/users/entities/sessions.ts +6 -0
  341. package/src/api/users/entities/users.ts +2 -0
  342. package/src/api/users/index.ts +9 -1
  343. package/src/api/users/primitives/$realm.ts +29 -0
  344. package/src/api/users/providers/RealmProvider.ts +15 -0
  345. package/src/api/users/schemas/realmConfigSchema.ts +14 -0
  346. package/src/api/users/schemas/sessionResourceSchema.ts +16 -0
  347. package/src/api/users/schemas/updateUserSchema.ts +1 -8
  348. package/src/api/users/schemas/userQuerySchema.ts +7 -0
  349. package/src/api/users/services/CredentialService.ts +15 -6
  350. package/src/api/users/services/IdentityService.ts +2 -1
  351. package/src/api/users/services/RegistrationService.ts +2 -1
  352. package/src/api/users/services/SessionCrudService.ts +19 -2
  353. package/src/api/users/services/SessionService.ts +39 -19
  354. package/src/api/users/services/UserService.ts +106 -8
  355. package/src/background/__tests__/BackgroundTaskProvider.spec.ts +96 -0
  356. package/src/background/index.ts +37 -0
  357. package/src/background/index.workerd.ts +28 -0
  358. package/src/background/providers/BackgroundTaskProvider.ts +70 -0
  359. package/src/background/providers/WorkerdBackgroundTaskProvider.ts +43 -0
  360. package/src/bucket/__tests__/$bucket.spec.ts +18 -0
  361. package/src/bucket/__tests__/LocalFileStorageProvider.spec.ts +5 -0
  362. package/src/bucket/__tests__/MemoryFileStorageProvider.spec.ts +5 -0
  363. package/src/bucket/__tests__/NodeS3BucketProvider.spec.ts +23 -4
  364. package/src/bucket/__tests__/shared.ts +30 -0
  365. package/src/bucket/index.ts +5 -5
  366. package/src/bucket/index.workerd.ts +11 -4
  367. package/src/bucket/primitives/$bucket.ts +27 -0
  368. package/src/bucket/providers/FileStorageProvider.ts +13 -0
  369. package/src/bucket/providers/LocalFileStorageProvider.ts +17 -1
  370. package/src/bucket/providers/MemoryFileStorageProvider.ts +7 -0
  371. package/src/bucket/providers/{CloudflareR2Provider.ts → R2FileStorageProvider.ts} +10 -1
  372. package/src/bucket/providers/{NodeS3BucketProvider.ts → S3FileStorageProvider.ts} +27 -5
  373. package/src/cli/core/__tests__/BuildDockerTask.spec.ts +25 -1
  374. package/src/cli/core/__tests__/init.spec.ts +0 -219
  375. package/src/cli/core/atoms/buildOptions.ts +0 -12
  376. package/src/cli/core/commands/__tests__/BuildCommand.spec.ts +43 -0
  377. package/src/cli/core/commands/build.ts +105 -37
  378. package/src/cli/core/commands/init.ts +0 -12
  379. package/src/cli/core/commands/pack.ts +133 -0
  380. package/src/cli/core/index.ts +3 -3
  381. package/src/cli/core/providers/ViteDevServerProvider.ts +40 -16
  382. package/src/cli/core/services/PackageManagerUtils.ts +0 -16
  383. package/src/cli/core/services/ProjectScaffolder.ts +29 -291
  384. package/src/cli/core/tasks/BuildCloudflareTask.ts +382 -56
  385. package/src/cli/core/tasks/BuildDockerTask.ts +33 -3
  386. package/src/cli/core/tasks/BuildPrerenderTask.ts +44 -7
  387. package/src/cli/core/tasks/BuildTask.ts +34 -0
  388. package/src/cli/core/templates/apiIndexTs.ts +1 -22
  389. package/src/cli/core/templates/mainCss.ts +0 -1
  390. package/src/cli/core/templates/webAppRouterTs.ts +0 -99
  391. package/src/cli/core/templates/webIndexTs.ts +1 -22
  392. package/src/cli/i18n/__tests__/I18nCheckService.spec.ts +48 -0
  393. package/src/cli/i18n/services/I18nCheckService.ts +65 -11
  394. package/src/cli/platform/__tests__/SecretsCommand.spec.ts +5 -3
  395. package/src/cli/platform/commands/SecretsCommand.ts +8 -6
  396. package/src/cli/platform/commands/platform.ts +192 -46
  397. package/src/cli/platform/index.ts +12 -52
  398. package/src/cli/{platform → platform-lib}/__tests__/CloudflareAdapter.spec.ts +426 -169
  399. package/src/cli/{platform → platform-lib}/__tests__/NamingService.spec.ts +91 -4
  400. package/src/cli/{platform → platform-lib}/__tests__/VercelAdapter.spec.ts +56 -85
  401. package/src/cli/{platform → platform-lib}/adapters/CloudflareAdapter.ts +519 -190
  402. package/src/cli/{platform → platform-lib}/adapters/PlatformAdapter.ts +62 -35
  403. package/src/cli/{platform → platform-lib}/adapters/VercelAdapter.ts +6 -10
  404. package/src/cli/{platform → platform-lib}/atoms/platformOptions.ts +34 -1
  405. package/src/cli/platform-lib/index.ts +67 -0
  406. package/src/cli/platform-lib/services/NamingService.ts +136 -0
  407. package/src/cli/{platform → platform-lib}/services/PlatformInspector.ts +60 -13
  408. package/src/cli/{platform → platform-lib}/services/PlatformOrchestrator.ts +54 -43
  409. package/src/cli/{platform → platform-lib}/services/WranglerApi.ts +4 -2
  410. package/src/command/__tests__/Runner.spec.ts +20 -0
  411. package/src/command/helpers/EnvUtils.ts +19 -3
  412. package/src/command/helpers/Runner.ts +12 -2
  413. package/src/command/providers/CliProvider.ts +34 -1
  414. package/src/{containers → container}/core/__tests__/$container.spec.ts +5 -5
  415. package/src/{containers → container}/core/index.ts +4 -4
  416. package/src/{containers → container}/core/index.workerd.ts +19 -3
  417. package/src/{containers → container}/core/primitives/$container.ts +1 -1
  418. package/src/{containers → container}/core/providers/CloudflareContainerProvider.ts +17 -19
  419. package/src/{containers → container}/core/providers/ContainerProvider.ts +16 -2
  420. package/src/{containers → container}/core/providers/MockContainerProvider.ts +1 -1
  421. package/src/core/Alepha.ts +49 -1
  422. package/src/core/__tests__/$env.spec.ts +42 -0
  423. package/src/core/__tests__/dump.spec.ts +47 -0
  424. package/src/email/cloudflare/__tests__/CloudflareEmailProvider.spec.ts +42 -10
  425. package/src/email/cloudflare/index.ts +14 -5
  426. package/src/email/cloudflare/providers/CloudflareEmailProvider.ts +54 -9
  427. package/src/logger/__tests__/Logger.spec.ts +55 -0
  428. package/src/logger/index.ts +13 -0
  429. package/src/logger/services/Logger.ts +31 -1
  430. package/src/mcp/__tests__/McpServerProvider.spec.ts +71 -0
  431. package/src/mcp/providers/McpServerProvider.ts +55 -0
  432. package/src/orm/__tests__/orm-showcase-tests.ts +27 -0
  433. package/src/orm/__tests__/orm-showcase.spec.ts +12 -0
  434. package/src/orm/core/interfaces/PgQuery.ts +4 -1
  435. package/src/orm/core/services/Repository.ts +27 -11
  436. package/src/react/auth/hooks/useAuth.ts +10 -5
  437. package/src/react/core/__tests__/useQuery.browser.spec.tsx +25 -0
  438. package/src/react/core/hooks/useAction.ts +14 -3
  439. package/src/react/core/hooks/useQuery.ts +24 -4
  440. package/src/react/form/__tests__/FormModel-submit-loading.spec.ts +71 -0
  441. package/src/react/form/__tests__/form-submitting-reactive.browser.spec.tsx +96 -0
  442. package/src/react/form/services/FormModel.ts +57 -39
  443. package/src/react/i18n/__tests__/I18nProvider.spec.ts +89 -0
  444. package/src/react/i18n/__tests__/locale-routing.spec.ts +107 -0
  445. package/src/react/i18n/components/Translate.tsx +47 -0
  446. package/src/react/i18n/index.ts +2 -0
  447. package/src/react/i18n/providers/I18nProvider.ts +171 -12
  448. package/src/react/intro/components/GettingStartedAdminSlide.tsx +2 -2
  449. package/src/react/router/__tests__/$page.spec.tsx +3 -2
  450. package/src/react/router/__tests__/RouterLocaleProvider.spec.ts +127 -0
  451. package/src/react/router/__tests__/page-can.spec.ts +18 -13
  452. package/src/react/router/hooks/useQueryParams.ts +114 -14
  453. package/src/react/router/index.browser.ts +4 -0
  454. package/src/react/router/index.shared.ts +1 -0
  455. package/src/react/router/index.ts +9 -0
  456. package/src/react/router/primitives/$page.ts +85 -4
  457. package/src/react/router/providers/ReactBrowserRouterProvider.ts +18 -8
  458. package/src/react/router/providers/ReactPageProvider.ts +12 -1
  459. package/src/react/router/providers/ReactServerProvider.ts +96 -14
  460. package/src/react/router/providers/RootComponentsProvider.ts +13 -0
  461. package/src/react/router/providers/RouterLocaleProvider.ts +125 -0
  462. package/src/react/router/providers/__tests__/RootComponentsProvider.spec.ts +15 -0
  463. package/src/react/router/providers/__tests__/rootComponents.ssr.browser.spec.tsx +67 -0
  464. package/src/react/sitemap/__tests__/$sitemap.spec.ts +131 -0
  465. package/src/react/sitemap/index.browser.ts +21 -0
  466. package/src/react/sitemap/index.ts +25 -0
  467. package/src/react/sitemap/primitives/$sitemap.browser.ts +26 -0
  468. package/src/react/sitemap/primitives/$sitemap.ts +196 -0
  469. package/src/react/ui/services/SchemaControl.ts +3 -4
  470. package/src/server/auth/__tests__/appleClientSecret.spec.ts +34 -0
  471. package/src/server/auth/__tests__/authFederationClient.spec.ts +40 -0
  472. package/src/server/auth/__tests__/federationAssertion.spec.ts +146 -0
  473. package/src/server/auth/__tests__/federationRedirectReplay.spec.ts +44 -0
  474. package/src/server/auth/helpers/appleClientSecret.ts +24 -0
  475. package/src/server/auth/helpers/federationAssertion.ts +74 -0
  476. package/src/server/auth/helpers/jtiReplayGuard.ts +41 -0
  477. package/src/server/auth/helpers/safeRedirectPath.ts +19 -0
  478. package/src/server/auth/index.ts +4 -0
  479. package/src/server/auth/primitives/$authFederationBroker.ts +273 -0
  480. package/src/server/auth/primitives/$authFederationClient.ts +89 -0
  481. package/src/server/auth/providers/ServerAuthProvider.ts +18 -4
  482. package/src/server/cookies/__tests__/ServerCookiesProvider.spec.ts +70 -0
  483. package/src/server/cookies/providers/ServerCookiesProvider.ts +23 -3
  484. package/src/server/core/interfaces/ServerRequest.ts +8 -0
  485. package/src/server/core/primitives/$route.ts +27 -0
  486. package/src/server/core/providers/ServerMultipartProvider.ts +19 -0
  487. package/src/server/links/providers/LinkProvider.ts +10 -0
  488. package/dist/containers/core/index.d.ts.map +0 -1
  489. package/dist/containers/core/index.js.map +0 -1
  490. package/dist/containers/core/index.workerd.js.map +0 -1
  491. package/src/cli/core/tasks/BuildSitemapTask.ts +0 -130
  492. package/src/cli/core/templates/componentsJsonTs.ts +0 -39
  493. package/src/cli/core/templates/saasAdminLayoutTsx.ts +0 -77
  494. package/src/cli/core/templates/saasAdminPagesTsx.ts +0 -26
  495. package/src/cli/core/templates/saasAuthLayoutTsx.ts +0 -22
  496. package/src/cli/core/templates/saasAuthPagesTsx.ts +0 -62
  497. package/src/cli/core/templates/saasRealmProviderTs.ts +0 -52
  498. package/src/cli/platform/services/NamingService.ts +0 -54
  499. /package/dist/orm/core/{chunk-o8xxKEmq.js → chunk-B4FMCO8f.js} +0 -0
  500. /package/dist/react/testing/{chunk-6Ep1yQYe.js → chunk-BpyX8vjI.js} +0 -0
  501. /package/src/cli/{platform → platform-lib}/__tests__/GitHubSecretStore.spec.ts +0 -0
  502. /package/src/cli/{platform → platform-lib}/__tests__/PlatformCacheProvider.spec.ts +0 -0
  503. /package/src/cli/{platform → platform-lib}/__tests__/PlatformInspector.spec.ts +0 -0
  504. /package/src/cli/{platform → platform-lib}/__tests__/PlatformOrchestrator.spec.ts +0 -0
  505. /package/src/cli/{platform → platform-lib}/__tests__/SecretFilterService.spec.ts +0 -0
  506. /package/src/cli/{platform → platform-lib}/__tests__/detectResources.spec.ts +0 -0
  507. /package/src/cli/{platform → platform-lib}/providers/GitHubSecretStore.ts +0 -0
  508. /package/src/cli/{platform → platform-lib}/providers/MemorySecretStore.ts +0 -0
  509. /package/src/cli/{platform → platform-lib}/providers/PlatformCacheProvider.ts +0 -0
  510. /package/src/cli/{platform → platform-lib}/providers/SecretStoreProvider.ts +0 -0
  511. /package/src/cli/{platform → platform-lib}/schemas/cloudflare.ts +0 -0
  512. /package/src/cli/{platform → platform-lib}/schemas/platform.ts +0 -0
  513. /package/src/cli/{platform → platform-lib}/schemas/vercel.ts +0 -0
  514. /package/src/cli/{platform → platform-lib}/services/CloudflareApi.ts +0 -0
  515. /package/src/cli/{platform → platform-lib}/services/SecretFilterService.ts +0 -0
  516. /package/src/cli/{platform → platform-lib}/services/VercelApi.ts +0 -0
  517. /package/src/cli/{platform → platform-lib}/services/VercelCli.ts +0 -0
  518. /package/src/{containers → container}/core/interfaces/ContainerOptions.ts +0 -0
  519. /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";
@@ -8,7 +8,7 @@ import { $logger } from "alepha/logger";
8
8
  import { $client } from "alepha/server/links";
9
9
  import { $notification } from "alepha/api/notifications";
10
10
  import { CaptchaProvider } from "alepha/captcha";
11
- import { $authApple, $authCredentials, $authFacebook, $authFranceConnect, $authGithub, $authGoogle, $authMicrosoft, ServerAuthProvider, authenticationProviderSchema } from "alepha/server/auth";
11
+ import { $authApple, $authCredentials, $authFacebook, $authFederationClient, $authFranceConnect, $authGithub, $authGoogle, $authMicrosoft, ServerAuthProvider, authenticationProviderSchema } from "alepha/server/auth";
12
12
  import { $etag } from "alepha/server/etag";
13
13
  import { AlephaApiVerification, VerificationService } from "alepha/api/verifications";
14
14
  import { $cache, CacheProvider } from "alepha/cache";
@@ -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(),
@@ -343,6 +380,10 @@ var RealmProvider = class {
343
380
  }
344
381
  },
345
382
  features,
383
+ federated: realmOptions.identities?.federated ? {
384
+ brokerUrl: realmOptions.identities.federated.brokerUrl,
385
+ providers: realmOptions.identities.federated.providers
386
+ } : void 0,
346
387
  getSettings: async function() {
347
388
  if (this.settingsParameter) return await this.settingsParameter.get();
348
389
  return this.settings;
@@ -437,7 +478,8 @@ var IdentityService = class {
437
478
  userId: identity.userId
438
479
  });
439
480
  const realm = this.realmProvider.getRealm(userRealmName);
440
- await this.userAudits(userRealmName)?.recordUser("update", {
481
+ await this.userAudits(userRealmName)?.user.log("update", {
482
+ resourceType: "user",
441
483
  userRealm: realm.name,
442
484
  resourceId: identity.userId,
443
485
  description: `Identity provider disconnected: ${identity.provider}`,
@@ -515,6 +557,22 @@ var AdminIdentityController = class {
515
557
  const sessionQuerySchema = t.extend(pageQuerySchema, { userId: t.optional(t.uuid()) });
516
558
  //#endregion
517
559
  //#region ../../src/api/users/schemas/sessionResourceSchema.ts
560
+ /**
561
+ * Slim view of the session's owner — embedded by the admin listing so the
562
+ * UI can render a human-readable identifier instead of just a UUID. Comes
563
+ * back via a left join, so it's optional (a session whose user was deleted
564
+ * still returns; `user` is undefined).
565
+ */
566
+ const sessionUserSummarySchema = t.object({
567
+ id: t.uuid(),
568
+ email: t.optional(t.string({ format: "email" })),
569
+ username: t.optional(t.shortText({
570
+ minLength: 3,
571
+ maxLength: 30
572
+ })),
573
+ firstName: t.optional(t.string()),
574
+ lastName: t.optional(t.string())
575
+ });
518
576
  const sessionResourceSchema = t.object({
519
577
  id: t.uuid(),
520
578
  version: t.number(),
@@ -524,6 +582,7 @@ const sessionResourceSchema = t.object({
524
582
  userId: t.uuid(),
525
583
  expiresAt: t.datetime(),
526
584
  ip: t.optional(t.string()),
585
+ country: t.optional(t.string()),
527
586
  userAgent: t.optional(t.object({
528
587
  os: t.string(),
529
588
  browser: t.string(),
@@ -532,10 +591,21 @@ const sessionResourceSchema = t.object({
532
591
  "DESKTOP",
533
592
  "TABLET"
534
593
  ])
535
- }))
594
+ })),
595
+ user: t.optional(sessionUserSummarySchema)
536
596
  });
537
597
  //#endregion
538
598
  //#region ../../src/api/users/services/SessionCrudService.ts
599
+ /**
600
+ * Relation map embedding a slim user summary on every session row, so the
601
+ * admin UI can render `user.email`/`user.username` instead of a bare UUID.
602
+ * Left-join (default) so sessions whose owner was deleted still come back
603
+ * with `user: undefined`.
604
+ */
605
+ const withUser = { user: {
606
+ join: users,
607
+ on: ["userId", users.cols.id]
608
+ } };
539
609
  var SessionCrudService = class {
540
610
  log = $logger();
541
611
  realmProvider = $inject(RealmProvider);
@@ -553,7 +623,10 @@ var SessionCrudService = class {
553
623
  q.sort ??= "-createdAt";
554
624
  const where = this.sessions(userRealmName).createQueryWhere();
555
625
  if (q.userId) where.userId = { eq: q.userId };
556
- const result = await this.sessions(userRealmName).paginate(q, { where }, { count: true });
626
+ const result = await this.sessions(userRealmName).paginate(q, {
627
+ where,
628
+ with: withUser
629
+ }, { count: true });
557
630
  this.log.debug("Sessions found", {
558
631
  count: result.content.length,
559
632
  total: result.page.totalElements
@@ -568,7 +641,10 @@ var SessionCrudService = class {
568
641
  id,
569
642
  userRealmName
570
643
  });
571
- const session = await this.sessions(userRealmName).getById(id);
644
+ const session = await this.sessions(userRealmName).getOne({
645
+ where: { id: { eq: id } },
646
+ with: withUser
647
+ });
572
648
  this.log.debug("Session retrieved", {
573
649
  id,
574
650
  userId: session.userId
@@ -692,13 +768,18 @@ const updateUserSchema = t.partial(t.omit(users.insertSchema, [
692
768
  "id",
693
769
  "version",
694
770
  "createdAt",
695
- "updatedAt",
696
- "username",
697
- "emailVerified"
771
+ "updatedAt"
698
772
  ]));
699
773
  //#endregion
700
774
  //#region ../../src/api/users/schemas/userQuerySchema.ts
701
775
  const userQuerySchema = t.extend(pageQuerySchema, {
776
+ /**
777
+ * Free-text search applied (case-insensitive) across `email`,
778
+ * `username`, `firstName`, and `lastName`. Matches with a leading and
779
+ * trailing wildcard, so `?search=foo` finds any user whose email,
780
+ * username, or name contains `foo`.
781
+ */
782
+ search: t.optional(t.string()),
702
783
  email: t.optional(t.string()),
703
784
  enabled: t.optional(t.boolean()),
704
785
  emailVerified: t.optional(t.boolean()),
@@ -863,6 +944,7 @@ var UserService = class {
863
944
  log = $logger();
864
945
  verificationController = $client();
865
946
  realmProvider = $inject(RealmProvider);
947
+ cryptoProvider = $inject(CryptoProvider);
866
948
  userAudits(realmName) {
867
949
  if (this.realmProvider.getRealm(realmName).features.audits) return this.alepha.inject(UserAudits);
868
950
  }
@@ -977,7 +1059,8 @@ var UserService = class {
977
1059
  type
978
1060
  });
979
1061
  const realm = this.realmProvider.getRealm(userRealmName);
980
- await this.userAudits(userRealmName)?.recordUser("update", {
1062
+ await this.userAudits(userRealmName)?.user.log("update", {
1063
+ resourceType: "user",
981
1064
  userId: user.id,
982
1065
  userEmail: email,
983
1066
  userRealm: realm.name,
@@ -1009,6 +1092,15 @@ var UserService = class {
1009
1092
  });
1010
1093
  q.sort ??= "-createdAt";
1011
1094
  const where = this.users(userRealmName).createQueryWhere();
1095
+ if (q.search) {
1096
+ const pattern = `%${q.search}%`;
1097
+ where.or = [
1098
+ { email: { ilike: pattern } },
1099
+ { username: { ilike: pattern } },
1100
+ { firstName: { ilike: pattern } },
1101
+ { lastName: { ilike: pattern } }
1102
+ ];
1103
+ }
1012
1104
  if (q.email) where.email = { like: q.email };
1013
1105
  if (q.enabled !== void 0) where.enabled = { eq: q.enabled };
1014
1106
  if (q.emailVerified !== void 0) where.emailVerified = { eq: q.emailVerified };
@@ -1078,7 +1170,8 @@ var UserService = class {
1078
1170
  username: user.username,
1079
1171
  email: user.email
1080
1172
  });
1081
- await this.userAudits(userRealmName)?.recordUser("create", {
1173
+ await this.userAudits(userRealmName)?.user.log("create", {
1174
+ resourceType: "user",
1082
1175
  userRealm: realm.name,
1083
1176
  resourceId: user.id,
1084
1177
  description: "User created",
@@ -1099,16 +1192,33 @@ var UserService = class {
1099
1192
  userRealmName
1100
1193
  });
1101
1194
  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
1195
  const realm = this.realmProvider.getRealm(userRealmName);
1196
+ const users = this.users(userRealmName);
1197
+ if (data.username !== void 0 && data.username !== null && data.username !== before.username) {
1198
+ const existing = await users.findOne({ where: {
1199
+ realm: realm.name,
1200
+ username: { ilike: data.username }
1201
+ } });
1202
+ if (existing && existing.id !== id) throw new ConflictError("User with this username already exists");
1203
+ }
1204
+ if (data.email !== void 0 && data.email !== null && data.email !== before.email) {
1205
+ const existing = await users.findOne({ where: {
1206
+ realm: realm.name,
1207
+ email: { eq: data.email }
1208
+ } });
1209
+ if (existing && existing.id !== id) throw new ConflictError("User with this email already exists");
1210
+ data.emailVerified = false;
1211
+ }
1212
+ const user = await users.updateById(id, data);
1213
+ this.log.debug("User updated", { userId: id });
1105
1214
  const changes = {};
1106
1215
  for (const key of Object.keys(data)) if (data[key] !== void 0 && before[key] !== data[key]) changes[key] = {
1107
1216
  from: before[key],
1108
1217
  to: data[key]
1109
1218
  };
1110
1219
  const isRoleChange = data.roles !== void 0 && JSON.stringify(before.roles) !== JSON.stringify(data.roles);
1111
- await this.userAudits(userRealmName)?.recordUser(isRoleChange ? "role_change" : "update", {
1220
+ await this.userAudits(userRealmName)?.user.log(isRoleChange ? "role_change" : "update", {
1221
+ resourceType: "user",
1112
1222
  userRealm: realm.name,
1113
1223
  resourceId: user.id,
1114
1224
  description: isRoleChange ? "User roles changed" : `User updated: ${Object.keys(changes).join(", ")}`,
@@ -1117,6 +1227,46 @@ var UserService = class {
1117
1227
  return user;
1118
1228
  }
1119
1229
  /**
1230
+ * Set (or reset) a user's password. Upserts a "credentials" identity
1231
+ * with the new hash. Used by admin password-set flows; does NOT
1232
+ * verify any old password or token — the caller is responsible for
1233
+ * authorization.
1234
+ */
1235
+ async setPassword(id, newPassword, userRealmName) {
1236
+ this.log.trace("Setting password", {
1237
+ id,
1238
+ userRealmName
1239
+ });
1240
+ const user = await this.getUserById(id, userRealmName);
1241
+ const realm = this.realmProvider.getRealm(userRealmName);
1242
+ const settings = await realm.getSettings();
1243
+ if (settings.passwordPolicy) {
1244
+ const policy = settings.passwordPolicy;
1245
+ if (policy.minLength && newPassword.length < policy.minLength) throw new BadRequestError(`Password must be at least ${policy.minLength} characters`);
1246
+ }
1247
+ const hash = await this.cryptoProvider.hashPassword(newPassword);
1248
+ const identities = this.realmProvider.identityRepository(userRealmName);
1249
+ const existing = await identities.findOne({ where: {
1250
+ userId: { eq: id },
1251
+ provider: { eq: "credentials" }
1252
+ } });
1253
+ if (existing) await identities.updateById(existing.id, { password: hash });
1254
+ else await identities.create({
1255
+ userId: id,
1256
+ provider: "credentials",
1257
+ password: hash
1258
+ });
1259
+ await this.userAudits(userRealmName)?.user.log("password_change", {
1260
+ resourceType: "user",
1261
+ userId: id,
1262
+ userEmail: user.email ?? void 0,
1263
+ userRealm: realm.name,
1264
+ resourceId: id,
1265
+ severity: "warning",
1266
+ description: "Password set by admin"
1267
+ });
1268
+ }
1269
+ /**
1120
1270
  * Delete a user by ID.
1121
1271
  */
1122
1272
  async deleteUser(id, userRealmName) {
@@ -1130,7 +1280,8 @@ var UserService = class {
1130
1280
  await this.users(userRealmName).deleteById(id);
1131
1281
  this.log.info("User deleted", { userId: id });
1132
1282
  const realm = this.realmProvider.getRealm(userRealmName);
1133
- await this.userAudits(userRealmName)?.recordUser("delete", {
1283
+ await this.userAudits(userRealmName)?.user.log("delete", {
1284
+ resourceType: "user",
1134
1285
  userRealm: realm.name,
1135
1286
  resourceId: id,
1136
1287
  severity: "warning",
@@ -1148,6 +1299,32 @@ var AdminUserController = class {
1148
1299
  url = "/users";
1149
1300
  group = "admin:users";
1150
1301
  userService = $inject(UserService);
1302
+ securityProvider = $inject(SecurityProvider);
1303
+ /**
1304
+ * List roles available in a realm. Used by the admin UI to render the
1305
+ * role picker and grey out defaults (which cannot be removed).
1306
+ */
1307
+ findRoles = $action({
1308
+ path: "/metadata/roles",
1309
+ group: this.group,
1310
+ use: [$secure({ permissions: ["admin:user:read"] })],
1311
+ description: "List roles available in a realm",
1312
+ schema: {
1313
+ query: t.object({ userRealmName: t.optional(t.string()) }),
1314
+ response: t.array(t.object({
1315
+ name: t.string(),
1316
+ default: t.optional(t.boolean()),
1317
+ description: t.optional(t.string())
1318
+ }))
1319
+ },
1320
+ handler: ({ query }) => {
1321
+ return this.securityProvider.getRoles(query.userRealmName).map((r) => ({
1322
+ name: r.name,
1323
+ default: r.default,
1324
+ description: r.description
1325
+ }));
1326
+ }
1327
+ });
1151
1328
  /**
1152
1329
  * Find users with pagination and filtering.
1153
1330
  */
@@ -1214,6 +1391,31 @@ var AdminUserController = class {
1214
1391
  handler: ({ params, body, query }) => this.userService.updateUser(params.id, body, query.userRealmName)
1215
1392
  });
1216
1393
  /**
1394
+ * Set (or reset) a user's password. Admin-only flow — does NOT
1395
+ * require knowing the previous password. Hash is stored as a
1396
+ * "credentials" identity for the user (upsert).
1397
+ */
1398
+ setUserPassword = $action({
1399
+ method: "POST",
1400
+ path: `${this.url}/:id/password`,
1401
+ group: this.group,
1402
+ use: [$secure({ permissions: ["admin:user:update"] })],
1403
+ description: "Set a user's password",
1404
+ schema: {
1405
+ params: t.object({ id: t.uuid() }),
1406
+ query: t.object({ userRealmName: t.optional(t.string()) }),
1407
+ body: t.object({ password: t.string({ minLength: 1 }) }),
1408
+ response: okSchema
1409
+ },
1410
+ handler: async ({ params, body, query }) => {
1411
+ await this.userService.setPassword(params.id, body.password, query.userRealmName);
1412
+ return {
1413
+ ok: true,
1414
+ id: params.id
1415
+ };
1416
+ }
1417
+ });
1418
+ /**
1217
1419
  * Delete a user.
1218
1420
  */
1219
1421
  deleteUser = $action({
@@ -1270,7 +1472,15 @@ const realmConfigSchema = t.object({
1270
1472
  settings: realmAuthSettingsAtom.schema,
1271
1473
  realmName: t.string(),
1272
1474
  authenticationMethods: t.array(authenticationProviderSchema),
1273
- captchaSiteKey: t.optional(t.string({ description: "Public site key for the captcha widget (when settings.captchaRequired is true)" }))
1475
+ captchaSiteKey: t.optional(t.string({ description: "Public site key for the captcha widget (when settings.captchaRequired is true)" })),
1476
+ /**
1477
+ * Federated (broker) social login. When present, the login UI renders one
1478
+ * button per provider linking to `{brokerUrl}/auth/federated/start`.
1479
+ */
1480
+ federated: t.optional(t.object({
1481
+ brokerUrl: t.string({ description: "Broker origin that performs the OIDC dance." }),
1482
+ providers: t.array(t.union([t.const("google"), t.const("apple")]), { description: "Federated providers to surface as login buttons." })
1483
+ }))
1274
1484
  });
1275
1485
  //#endregion
1276
1486
  //#region ../../src/api/users/controllers/RealmController.ts
@@ -1305,7 +1515,8 @@ var RealmController = class {
1305
1515
  settings,
1306
1516
  realmName,
1307
1517
  authenticationMethods: this.serverAuthProvider.getAuthenticationProviders({ realmName }),
1308
- captchaSiteKey: settings.captchaRequired ? this.captchaProvider.getSiteKey() : void 0
1518
+ captchaSiteKey: settings.captchaRequired ? this.captchaProvider.getSiteKey() : void 0,
1519
+ federated: realm.federated
1309
1520
  };
1310
1521
  }
1311
1522
  });
@@ -1421,6 +1632,9 @@ var CredentialService = class {
1421
1632
  userAudits(realmName) {
1422
1633
  if (this.realmProvider.getRealm(realmName).features.audits) return this.alepha.inject(UserAudits);
1423
1634
  }
1635
+ sessionAudits(realmName) {
1636
+ if (this.realmProvider.getRealm(realmName).features.audits) return this.alepha.inject(SessionAudits);
1637
+ }
1424
1638
  userNotifications(realmName) {
1425
1639
  if (this.realmProvider.getRealm(realmName).features.notifications) return this.alepha.inject(UserNotifications);
1426
1640
  }
@@ -1572,7 +1786,8 @@ var CredentialService = class {
1572
1786
  userId: intent.userId,
1573
1787
  email: intent.email
1574
1788
  });
1575
- await this.userAudits(intent.realmName)?.recordUser("update", {
1789
+ await this.userAudits(intent.realmName)?.user.log("update", {
1790
+ resourceType: "user",
1576
1791
  userId: intent.userId,
1577
1792
  userEmail: intent.email,
1578
1793
  userRealm: realm.name,
@@ -1580,7 +1795,7 @@ var CredentialService = class {
1580
1795
  description: "Password reset completed",
1581
1796
  metadata: { email: intent.email }
1582
1797
  });
1583
- await this.userAudits(intent.realmName)?.record("security", "sessions_invalidated", {
1798
+ await this.sessionAudits(intent.realmName)?.security.log("sessions_invalidated", {
1584
1799
  userId: intent.userId,
1585
1800
  userEmail: intent.email,
1586
1801
  userRealm: realm.name,
@@ -1629,7 +1844,8 @@ var CredentialService = class {
1629
1844
  const hashedPassword = await this.cryptoProvider.hashPassword(newPassword);
1630
1845
  await this.identities(userRealmName).updateById(identity.id, { password: hashedPassword });
1631
1846
  await this.sessions(userRealmName).deleteMany({ userId: { eq: user.id } });
1632
- await this.userAudits(userRealmName)?.recordUser("update", {
1847
+ await this.userAudits(userRealmName)?.user.log("update", {
1848
+ resourceType: "user",
1633
1849
  userId: user.id,
1634
1850
  userEmail: email,
1635
1851
  userRealm: realm.name,
@@ -1637,7 +1853,7 @@ var CredentialService = class {
1637
1853
  description: "Password reset completed (legacy)",
1638
1854
  metadata: { email }
1639
1855
  });
1640
- await this.userAudits(userRealmName)?.record("security", "sessions_invalidated", {
1856
+ await this.sessionAudits(userRealmName)?.security.log("sessions_invalidated", {
1641
1857
  userId: user.id,
1642
1858
  userEmail: email,
1643
1859
  userRealm: realm.name,
@@ -1986,7 +2202,8 @@ var RegistrationService = class {
1986
2202
  email: user.email,
1987
2203
  username: user.username
1988
2204
  });
1989
- await this.userAudits(userRealmName)?.recordUser("create", {
2205
+ await this.userAudits(userRealmName)?.user.log("create", {
2206
+ resourceType: "user",
1990
2207
  userId: user.id,
1991
2208
  userEmail: user.email ?? void 0,
1992
2209
  userRealm: realm.name,
@@ -2409,6 +2626,9 @@ var SessionService = class SessionService {
2409
2626
  userAudits(realmName) {
2410
2627
  if (this.realmProvider.getRealm(realmName).features.audits) return this.alepha.inject(UserAudits);
2411
2628
  }
2629
+ sessionAudits(realmName) {
2630
+ if (this.realmProvider.getRealm(realmName).features.audits) return this.alepha.inject(SessionAudits);
2631
+ }
2412
2632
  userNotifications(realmName) {
2413
2633
  if (this.realmProvider.getRealm(realmName).features.notifications) return this.alepha.inject(UserNotifications);
2414
2634
  }
@@ -2444,7 +2664,8 @@ var SessionService = class SessionService {
2444
2664
  username: user.username,
2445
2665
  realm: name
2446
2666
  });
2447
- await this.userAudits(userRealmName)?.recordUser("role_change", {
2667
+ await this.userAudits(userRealmName)?.user.log("role_change", {
2668
+ resourceType: "user",
2448
2669
  userId: user.id,
2449
2670
  userEmail: user.email ?? void 0,
2450
2671
  userRealm: name,
@@ -2541,8 +2762,9 @@ var SessionService = class SessionService {
2541
2762
  username,
2542
2763
  realm: name
2543
2764
  });
2544
- await this.userAudits(userRealmName)?.recordAuth("login_failed", {
2765
+ await this.sessionAudits(userRealmName)?.auth.log("login", {
2545
2766
  userRealm: name,
2767
+ success: false,
2546
2768
  description: "Username does not match required format",
2547
2769
  metadata: {
2548
2770
  provider,
@@ -2561,8 +2783,9 @@ var SessionService = class SessionService {
2561
2783
  username,
2562
2784
  realm: name
2563
2785
  });
2564
- await this.userAudits(userRealmName)?.recordAuth("login_failed", {
2786
+ await this.sessionAudits(userRealmName)?.auth.log("login", {
2565
2787
  userRealm: name,
2788
+ success: false,
2566
2789
  description: "Invalid login identifier format",
2567
2790
  metadata: {
2568
2791
  provider,
@@ -2578,8 +2801,9 @@ var SessionService = class SessionService {
2578
2801
  username,
2579
2802
  realm: name
2580
2803
  });
2581
- await this.userAudits(userRealmName)?.recordAuth("login_failed", {
2804
+ await this.sessionAudits(userRealmName)?.auth.log("login", {
2582
2805
  userRealm: name,
2806
+ success: false,
2583
2807
  description: "User not found",
2584
2808
  metadata: {
2585
2809
  provider,
@@ -2587,7 +2811,7 @@ var SessionService = class SessionService {
2587
2811
  }
2588
2812
  });
2589
2813
  if (ipKey) {
2590
- if (await this.recordFailedLogin(ipKey, loginRateLimit.ipMaxAttempts, loginRateLimit.windowMs)) await this.userAudits(userRealmName)?.record("security", "rate_limited", {
2814
+ if (await this.recordFailedLogin(ipKey, loginRateLimit.ipMaxAttempts, loginRateLimit.windowMs)) await this.sessionAudits(userRealmName)?.security.log("rate_limited", {
2591
2815
  userRealm: name,
2592
2816
  success: false,
2593
2817
  description: "IP temporarily locked due to too many failed login attempts",
@@ -2601,8 +2825,9 @@ var SessionService = class SessionService {
2601
2825
  userId: user.id,
2602
2826
  realm: name
2603
2827
  });
2604
- await this.userAudits(userRealmName)?.recordAuth("login_failed", {
2828
+ await this.sessionAudits(userRealmName)?.auth.log("login", {
2605
2829
  userRealm: name,
2830
+ success: false,
2606
2831
  resourceId: user.id,
2607
2832
  description: "Login attempt for disabled account",
2608
2833
  metadata: {
@@ -2640,8 +2865,9 @@ var SessionService = class SessionService {
2640
2865
  username,
2641
2866
  realm: name
2642
2867
  });
2643
- await this.userAudits(userRealmName)?.recordAuth("login_failed", {
2868
+ await this.sessionAudits(userRealmName)?.auth.log("login", {
2644
2869
  userRealm: name,
2870
+ success: false,
2645
2871
  resourceId: user.id,
2646
2872
  description: "Invalid password",
2647
2873
  metadata: {
@@ -2650,7 +2876,7 @@ var SessionService = class SessionService {
2650
2876
  }
2651
2877
  });
2652
2878
  if (ipKey) {
2653
- if (await this.recordFailedLogin(ipKey, loginRateLimit.ipMaxAttempts, loginRateLimit.windowMs)) await this.userAudits(userRealmName)?.record("security", "rate_limited", {
2879
+ if (await this.recordFailedLogin(ipKey, loginRateLimit.ipMaxAttempts, loginRateLimit.windowMs)) await this.sessionAudits(userRealmName)?.security.log("rate_limited", {
2654
2880
  userRealm: name,
2655
2881
  success: false,
2656
2882
  description: "IP temporarily locked due to too many failed login attempts",
@@ -2658,7 +2884,7 @@ var SessionService = class SessionService {
2658
2884
  });
2659
2885
  }
2660
2886
  if (await this.recordFailedLogin(accountKey, loginRateLimit.accountMaxAttempts, loginRateLimit.windowMs)) {
2661
- await this.userAudits(userRealmName)?.record("security", "rate_limited", {
2887
+ await this.sessionAudits(userRealmName)?.security.log("rate_limited", {
2662
2888
  userRealm: name,
2663
2889
  resourceId: user.id,
2664
2890
  success: false,
@@ -2678,7 +2904,7 @@ var SessionService = class SessionService {
2678
2904
  }
2679
2905
  throw new InvalidCredentialsError();
2680
2906
  }
2681
- await this.userAudits(userRealmName)?.recordAuth("login", {
2907
+ await this.sessionAudits(userRealmName)?.auth.log("login", {
2682
2908
  userId: user.id,
2683
2909
  userEmail: user.email ?? void 0,
2684
2910
  userRealm: name,
@@ -2705,15 +2931,18 @@ var SessionService = class SessionService {
2705
2931
  const request = this.alepha.store.get("alepha.http.request");
2706
2932
  const refreshToken = this.cryptoProvider.randomUUID();
2707
2933
  const expiresAt = this.dateTimeProvider.now().add(expiresIn, "seconds").toISOString();
2934
+ const nowIso = this.dateTimeProvider.nowISOString();
2708
2935
  const session = await this.sessions(userRealmName).create({
2709
2936
  userId: user.id,
2710
2937
  expiresAt,
2711
- lastUsedAt: this.dateTimeProvider.nowISOString(),
2938
+ lastUsedAt: nowIso,
2712
2939
  ip: request?.ip,
2940
+ country: request?.geo?.country,
2713
2941
  userAgent: request?.userAgent,
2714
2942
  refreshToken,
2715
2943
  clientId
2716
2944
  });
2945
+ await this.users(userRealmName).updateById(user.id, { lastLoginAt: nowIso });
2717
2946
  this.log.info("Session created", {
2718
2947
  sessionId: session.id,
2719
2948
  userId: user.id,
@@ -2780,7 +3009,7 @@ var SessionService = class SessionService {
2780
3009
  this.log.debug("Session deleted");
2781
3010
  if (session) {
2782
3011
  const { name } = this.realmProvider.getRealm(userRealmName);
2783
- await this.userAudits(userRealmName)?.recordAuth("logout", {
3012
+ await this.sessionAudits(userRealmName)?.auth.log("logout", {
2784
3013
  userId: session.userId,
2785
3014
  userRealm: name,
2786
3015
  sessionId: session.id,
@@ -2808,7 +3037,7 @@ var SessionService = class SessionService {
2808
3037
  userId: identity.userId
2809
3038
  });
2810
3039
  const user = await users.getById(identity.userId);
2811
- await this.userAudits(userRealmName)?.recordAuth("login", {
3040
+ await this.sessionAudits(userRealmName)?.auth.log("login", {
2812
3041
  userId: user.id,
2813
3042
  userEmail: user.email ?? void 0,
2814
3043
  userRealm: realm.name,
@@ -2856,7 +3085,7 @@ var SessionService = class SessionService {
2856
3085
  providerUserId: profile.sub,
2857
3086
  userId: existing.id
2858
3087
  });
2859
- await this.userAudits(userRealmName)?.recordAuth("login", {
3088
+ await this.sessionAudits(userRealmName)?.auth.log("login", {
2860
3089
  userId: existing.id,
2861
3090
  userEmail: existing.email ?? void 0,
2862
3091
  userRealm: realm.name,
@@ -2918,7 +3147,8 @@ var SessionService = class SessionService {
2918
3147
  email: user.email,
2919
3148
  username: user.username
2920
3149
  });
2921
- await this.userAudits(userRealmName)?.recordUser("create", {
3150
+ await this.userAudits(userRealmName)?.user.log("create", {
3151
+ resourceType: "user",
2922
3152
  userId: user.id,
2923
3153
  userEmail: user.email ?? void 0,
2924
3154
  userRealm: realm.name,
@@ -2931,7 +3161,7 @@ var SessionService = class SessionService {
2931
3161
  email: user.email
2932
3162
  }
2933
3163
  });
2934
- await this.userAudits(userRealmName)?.recordAuth("login", {
3164
+ await this.sessionAudits(userRealmName)?.auth.log("login", {
2935
3165
  userId: user.id,
2936
3166
  userEmail: user.email ?? void 0,
2937
3167
  userRealm: realm.name,
@@ -2986,7 +3216,10 @@ const $realm = (options = {}) => {
2986
3216
  }
2987
3217
  const realmRegistration = realmProvider.register(name, options);
2988
3218
  if (features.avatars) alepha.with(UserBuckets);
2989
- if (features.audits) alepha.with(UserAudits);
3219
+ if (features.audits) {
3220
+ alepha.with(UserAudits);
3221
+ alepha.with(SessionAudits);
3222
+ }
2990
3223
  if (features.jobs) alepha.with(UserJobs);
2991
3224
  if (features.notifications) {
2992
3225
  alepha.with(UserNotifications);
@@ -3008,6 +3241,7 @@ const $realm = (options = {}) => {
3008
3241
  permissions: [{ name: "*" }]
3009
3242
  }, {
3010
3243
  name: "user",
3244
+ default: true,
3011
3245
  permissions: [{
3012
3246
  name: "*",
3013
3247
  ownership: true,
@@ -3088,6 +3322,14 @@ const $realm = (options = {}) => {
3088
3322
  if (identities.microsoft) auth.microsoft = $authMicrosoft(realm);
3089
3323
  if (identities.franceconnect) auth.franceconnect = $authFranceConnect(realm);
3090
3324
  alepha.with(() => auth);
3325
+ if (identities.federated) {
3326
+ const fed = $authFederationClient({
3327
+ realm,
3328
+ brokerUrl: identities.federated.brokerUrl,
3329
+ publicKeyPem: identities.federated.publicKey
3330
+ });
3331
+ alepha.with(() => ({ federationCallback: fed.callback }));
3332
+ }
3091
3333
  }
3092
3334
  if (features.parameters) {
3093
3335
  alepha.with(AlephaApiParameters);
@@ -3194,10 +3436,11 @@ const AlephaApiUsers = $module({
3194
3436
  UserJobs,
3195
3437
  UserNotifications,
3196
3438
  UserAudits,
3439
+ SessionAudits,
3197
3440
  UserBuckets
3198
3441
  ]
3199
3442
  });
3200
3443
  //#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 };
3444
+ 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
3445
 
3203
3446
  //# sourceMappingURL=index.js.map