alepha 0.14.4 → 0.15.1

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 (322) hide show
  1. package/README.md +44 -102
  2. package/dist/api/audits/index.d.ts +331 -443
  3. package/dist/api/audits/index.d.ts.map +1 -1
  4. package/dist/api/audits/index.js +2 -2
  5. package/dist/api/audits/index.js.map +1 -1
  6. package/dist/api/files/index.d.ts +0 -113
  7. package/dist/api/files/index.d.ts.map +1 -1
  8. package/dist/api/files/index.js +2 -3
  9. package/dist/api/files/index.js.map +1 -1
  10. package/dist/api/jobs/index.d.ts +151 -262
  11. package/dist/api/jobs/index.d.ts.map +1 -1
  12. package/dist/api/notifications/index.browser.js +4 -4
  13. package/dist/api/notifications/index.browser.js.map +1 -1
  14. package/dist/api/notifications/index.d.ts +164 -276
  15. package/dist/api/notifications/index.d.ts.map +1 -1
  16. package/dist/api/notifications/index.js +4 -4
  17. package/dist/api/notifications/index.js.map +1 -1
  18. package/dist/api/parameters/index.d.ts +265 -377
  19. package/dist/api/parameters/index.d.ts.map +1 -1
  20. package/dist/api/users/index.browser.js +1 -2
  21. package/dist/api/users/index.browser.js.map +1 -1
  22. package/dist/api/users/index.d.ts +195 -301
  23. package/dist/api/users/index.d.ts.map +1 -1
  24. package/dist/api/users/index.js +203 -184
  25. package/dist/api/users/index.js.map +1 -1
  26. package/dist/api/verifications/index.d.ts.map +1 -1
  27. package/dist/batch/index.d.ts.map +1 -1
  28. package/dist/batch/index.js +1 -2
  29. package/dist/batch/index.js.map +1 -1
  30. package/dist/bucket/index.d.ts.map +1 -1
  31. package/dist/cache/core/index.d.ts.map +1 -1
  32. package/dist/cache/redis/index.d.ts.map +1 -1
  33. package/dist/cache/redis/index.js +2 -2
  34. package/dist/cache/redis/index.js.map +1 -1
  35. package/dist/cli/index.d.ts +5900 -165
  36. package/dist/cli/index.d.ts.map +1 -1
  37. package/dist/cli/index.js +1481 -639
  38. package/dist/cli/index.js.map +1 -1
  39. package/dist/command/index.d.ts +8 -4
  40. package/dist/command/index.d.ts.map +1 -1
  41. package/dist/command/index.js +29 -25
  42. package/dist/command/index.js.map +1 -1
  43. package/dist/core/index.browser.js +563 -54
  44. package/dist/core/index.browser.js.map +1 -1
  45. package/dist/core/index.d.ts +175 -8
  46. package/dist/core/index.d.ts.map +1 -1
  47. package/dist/core/index.js +564 -54
  48. package/dist/core/index.js.map +1 -1
  49. package/dist/core/index.native.js +563 -54
  50. package/dist/core/index.native.js.map +1 -1
  51. package/dist/datetime/index.d.ts.map +1 -1
  52. package/dist/datetime/index.js +4 -4
  53. package/dist/datetime/index.js.map +1 -1
  54. package/dist/email/index.d.ts +89 -42
  55. package/dist/email/index.d.ts.map +1 -1
  56. package/dist/email/index.js +129 -33
  57. package/dist/email/index.js.map +1 -1
  58. package/dist/fake/index.d.ts +7969 -2
  59. package/dist/fake/index.d.ts.map +1 -1
  60. package/dist/fake/index.js +22 -22
  61. package/dist/fake/index.js.map +1 -1
  62. package/dist/file/index.d.ts +134 -1
  63. package/dist/file/index.d.ts.map +1 -1
  64. package/dist/file/index.js +253 -1
  65. package/dist/file/index.js.map +1 -1
  66. package/dist/lock/core/index.d.ts.map +1 -1
  67. package/dist/lock/redis/index.d.ts.map +1 -1
  68. package/dist/logger/index.d.ts +1 -2
  69. package/dist/logger/index.d.ts.map +1 -1
  70. package/dist/logger/index.js +1 -5
  71. package/dist/logger/index.js.map +1 -1
  72. package/dist/mcp/index.d.ts +19 -1
  73. package/dist/mcp/index.d.ts.map +1 -1
  74. package/dist/mcp/index.js +28 -4
  75. package/dist/mcp/index.js.map +1 -1
  76. package/dist/orm/chunk-DH6iiROE.js +38 -0
  77. package/dist/orm/index.browser.js +9 -9
  78. package/dist/orm/index.browser.js.map +1 -1
  79. package/dist/orm/index.bun.js +2821 -0
  80. package/dist/orm/index.bun.js.map +1 -0
  81. package/dist/orm/index.d.ts +318 -169
  82. package/dist/orm/index.d.ts.map +1 -1
  83. package/dist/orm/index.js +2086 -1776
  84. package/dist/orm/index.js.map +1 -1
  85. package/dist/queue/core/index.d.ts +4 -4
  86. package/dist/queue/core/index.d.ts.map +1 -1
  87. package/dist/queue/redis/index.d.ts.map +1 -1
  88. package/dist/redis/index.bun.js +285 -0
  89. package/dist/redis/index.bun.js.map +1 -0
  90. package/dist/redis/index.d.ts +13 -31
  91. package/dist/redis/index.d.ts.map +1 -1
  92. package/dist/redis/index.js +18 -38
  93. package/dist/redis/index.js.map +1 -1
  94. package/dist/retry/index.d.ts.map +1 -1
  95. package/dist/router/index.d.ts.map +1 -1
  96. package/dist/scheduler/index.d.ts +83 -1
  97. package/dist/scheduler/index.d.ts.map +1 -1
  98. package/dist/scheduler/index.js +393 -1
  99. package/dist/scheduler/index.js.map +1 -1
  100. package/dist/security/index.browser.js +5 -1
  101. package/dist/security/index.browser.js.map +1 -1
  102. package/dist/security/index.d.ts +598 -112
  103. package/dist/security/index.d.ts.map +1 -1
  104. package/dist/security/index.js +1808 -97
  105. package/dist/security/index.js.map +1 -1
  106. package/dist/server/auth/index.d.ts +1200 -175
  107. package/dist/server/auth/index.d.ts.map +1 -1
  108. package/dist/server/auth/index.js +1268 -37
  109. package/dist/server/auth/index.js.map +1 -1
  110. package/dist/server/cache/index.d.ts +6 -3
  111. package/dist/server/cache/index.d.ts.map +1 -1
  112. package/dist/server/cache/index.js +1 -1
  113. package/dist/server/cache/index.js.map +1 -1
  114. package/dist/server/compress/index.d.ts.map +1 -1
  115. package/dist/server/cookies/index.d.ts.map +1 -1
  116. package/dist/server/cookies/index.js +3 -3
  117. package/dist/server/cookies/index.js.map +1 -1
  118. package/dist/server/core/index.d.ts +115 -13
  119. package/dist/server/core/index.d.ts.map +1 -1
  120. package/dist/server/core/index.js +321 -139
  121. package/dist/server/core/index.js.map +1 -1
  122. package/dist/server/cors/index.d.ts +0 -1
  123. package/dist/server/cors/index.d.ts.map +1 -1
  124. package/dist/server/health/index.d.ts +0 -1
  125. package/dist/server/health/index.d.ts.map +1 -1
  126. package/dist/server/helmet/index.d.ts.map +1 -1
  127. package/dist/server/links/index.browser.js +9 -1
  128. package/dist/server/links/index.browser.js.map +1 -1
  129. package/dist/server/links/index.d.ts +1 -2
  130. package/dist/server/links/index.d.ts.map +1 -1
  131. package/dist/server/links/index.js +14 -7
  132. package/dist/server/links/index.js.map +1 -1
  133. package/dist/server/metrics/index.d.ts +514 -1
  134. package/dist/server/metrics/index.d.ts.map +1 -1
  135. package/dist/server/metrics/index.js +4462 -4
  136. package/dist/server/metrics/index.js.map +1 -1
  137. package/dist/server/multipart/index.d.ts.map +1 -1
  138. package/dist/server/proxy/index.d.ts +0 -1
  139. package/dist/server/proxy/index.d.ts.map +1 -1
  140. package/dist/server/rate-limit/index.d.ts.map +1 -1
  141. package/dist/server/static/index.d.ts.map +1 -1
  142. package/dist/server/swagger/index.d.ts +1 -2
  143. package/dist/server/swagger/index.d.ts.map +1 -1
  144. package/dist/server/swagger/index.js +1 -2
  145. package/dist/server/swagger/index.js.map +1 -1
  146. package/dist/sms/index.d.ts +3 -1
  147. package/dist/sms/index.d.ts.map +1 -1
  148. package/dist/sms/index.js +10 -10
  149. package/dist/sms/index.js.map +1 -1
  150. package/dist/thread/index.d.ts +0 -1
  151. package/dist/thread/index.d.ts.map +1 -1
  152. package/dist/thread/index.js +2 -2
  153. package/dist/thread/index.js.map +1 -1
  154. package/dist/topic/core/index.d.ts.map +1 -1
  155. package/dist/topic/redis/index.d.ts.map +1 -1
  156. package/dist/vite/index.d.ts +6315 -149
  157. package/dist/vite/index.d.ts.map +1 -1
  158. package/dist/vite/index.js +140 -469
  159. package/dist/vite/index.js.map +1 -1
  160. package/dist/websocket/index.browser.js +9 -9
  161. package/dist/websocket/index.browser.js.map +1 -1
  162. package/dist/websocket/index.d.ts +28 -28
  163. package/dist/websocket/index.d.ts.map +1 -1
  164. package/dist/websocket/index.js +9 -9
  165. package/dist/websocket/index.js.map +1 -1
  166. package/package.json +13 -18
  167. package/src/api/files/controllers/AdminFileStatsController.ts +0 -1
  168. package/src/api/users/atoms/realmAuthSettingsAtom.ts +5 -0
  169. package/src/api/users/controllers/{UserRealmController.ts → RealmController.ts} +11 -11
  170. package/src/api/users/entities/users.ts +1 -1
  171. package/src/api/users/index.ts +8 -8
  172. package/src/api/users/primitives/{$userRealm.ts → $realm.ts} +17 -19
  173. package/src/api/users/providers/{UserRealmProvider.ts → RealmProvider.ts} +26 -30
  174. package/src/api/users/schemas/{userRealmConfigSchema.ts → realmConfigSchema.ts} +2 -2
  175. package/src/api/users/services/CredentialService.ts +7 -7
  176. package/src/api/users/services/IdentityService.ts +4 -4
  177. package/src/api/users/services/RegistrationService.spec.ts +25 -27
  178. package/src/api/users/services/RegistrationService.ts +38 -27
  179. package/src/api/users/services/SessionCrudService.ts +3 -3
  180. package/src/api/users/services/SessionService.spec.ts +3 -3
  181. package/src/api/users/services/SessionService.ts +27 -18
  182. package/src/api/users/services/UserService.ts +7 -7
  183. package/src/batch/providers/BatchProvider.ts +1 -2
  184. package/src/cli/apps/AlephaCli.ts +2 -2
  185. package/src/cli/apps/AlephaPackageBuilderCli.ts +47 -20
  186. package/src/cli/assets/apiHelloControllerTs.ts +19 -0
  187. package/src/cli/assets/apiIndexTs.ts +16 -0
  188. package/src/cli/assets/biomeJson.ts +2 -1
  189. package/src/cli/assets/claudeMd.ts +308 -0
  190. package/src/cli/assets/dummySpecTs.ts +2 -1
  191. package/src/cli/assets/editorconfig.ts +2 -1
  192. package/src/cli/assets/mainBrowserTs.ts +4 -3
  193. package/src/cli/assets/mainCss.ts +24 -0
  194. package/src/cli/assets/mainServerTs.ts +24 -0
  195. package/src/cli/assets/tsconfigJson.ts +2 -1
  196. package/src/cli/assets/webAppRouterTs.ts +16 -0
  197. package/src/cli/assets/webHelloComponentTsx.ts +20 -0
  198. package/src/cli/assets/webIndexTs.ts +16 -0
  199. package/src/cli/atoms/appEntryOptions.ts +13 -0
  200. package/src/cli/atoms/buildOptions.ts +1 -1
  201. package/src/cli/atoms/changelogOptions.ts +1 -1
  202. package/src/cli/commands/build.ts +97 -61
  203. package/src/cli/commands/db.ts +21 -18
  204. package/src/cli/commands/deploy.ts +17 -5
  205. package/src/cli/commands/dev.ts +26 -47
  206. package/src/cli/commands/gen/env.ts +1 -1
  207. package/src/cli/commands/init.ts +79 -25
  208. package/src/cli/commands/lint.ts +9 -3
  209. package/src/cli/commands/test.ts +8 -2
  210. package/src/cli/commands/typecheck.ts +5 -1
  211. package/src/cli/commands/verify.ts +4 -2
  212. package/src/cli/defineConfig.ts +9 -0
  213. package/src/cli/index.ts +2 -1
  214. package/src/cli/providers/AppEntryProvider.ts +131 -0
  215. package/src/cli/providers/ViteBuildProvider.ts +82 -0
  216. package/src/cli/providers/ViteDevServerProvider.ts +350 -0
  217. package/src/cli/providers/ViteTemplateProvider.ts +27 -0
  218. package/src/cli/services/AlephaCliUtils.ts +72 -602
  219. package/src/cli/services/PackageManagerUtils.ts +308 -0
  220. package/src/cli/services/ProjectScaffolder.ts +329 -0
  221. package/src/command/helpers/Runner.ts +15 -3
  222. package/src/core/Alepha.ts +2 -8
  223. package/src/core/__tests__/Alepha-graph.spec.ts +4 -0
  224. package/src/core/index.shared.ts +1 -0
  225. package/src/core/index.ts +2 -0
  226. package/src/core/primitives/$hook.ts +6 -2
  227. package/src/core/primitives/$module.spec.ts +4 -0
  228. package/src/core/primitives/$module.ts +12 -0
  229. package/src/core/providers/AlsProvider.ts +1 -1
  230. package/src/core/providers/CodecManager.spec.ts +12 -6
  231. package/src/core/providers/CodecManager.ts +26 -6
  232. package/src/core/providers/EventManager.ts +169 -13
  233. package/src/core/providers/KeylessJsonSchemaCodec.spec.ts +878 -0
  234. package/src/core/providers/KeylessJsonSchemaCodec.ts +789 -0
  235. package/src/core/providers/SchemaValidator.spec.ts +236 -0
  236. package/src/core/providers/StateManager.spec.ts +27 -16
  237. package/src/email/providers/LocalEmailProvider.spec.ts +111 -87
  238. package/src/email/providers/LocalEmailProvider.ts +52 -15
  239. package/src/email/providers/NodemailerEmailProvider.ts +167 -56
  240. package/src/file/errors/FileError.ts +7 -0
  241. package/src/file/index.ts +9 -1
  242. package/src/file/providers/MemoryFileSystemProvider.ts +393 -0
  243. package/src/logger/providers/PrettyFormatterProvider.ts +0 -9
  244. package/src/mcp/errors/McpError.ts +30 -0
  245. package/src/mcp/index.ts +3 -0
  246. package/src/mcp/transports/SseMcpTransport.ts +16 -6
  247. package/src/orm/index.browser.ts +1 -19
  248. package/src/orm/index.bun.ts +77 -0
  249. package/src/orm/index.shared-server.ts +22 -0
  250. package/src/orm/index.shared.ts +15 -0
  251. package/src/orm/index.ts +19 -39
  252. package/src/orm/providers/DrizzleKitProvider.ts +3 -5
  253. package/src/orm/providers/drivers/BunPostgresProvider.ts +3 -5
  254. package/src/orm/providers/drivers/BunSqliteProvider.ts +1 -1
  255. package/src/orm/providers/drivers/CloudflareD1Provider.ts +4 -0
  256. package/src/orm/providers/drivers/DatabaseProvider.ts +4 -0
  257. package/src/orm/providers/drivers/PglitePostgresProvider.ts +4 -0
  258. package/src/orm/services/Repository.ts +19 -0
  259. package/src/redis/index.bun.ts +35 -0
  260. package/src/redis/providers/BunRedisProvider.ts +12 -43
  261. package/src/redis/providers/BunRedisSubscriberProvider.ts +2 -3
  262. package/src/redis/providers/NodeRedisProvider.ts +16 -34
  263. package/src/{server/security → security}/__tests__/BasicAuth.spec.ts +11 -11
  264. package/src/{server/security → security}/__tests__/ServerSecurityProvider-realm.spec.ts +21 -16
  265. package/src/{server/security/providers → security/__tests__}/ServerSecurityProvider.spec.ts +5 -5
  266. package/src/security/index.browser.ts +5 -0
  267. package/src/security/index.ts +90 -7
  268. package/src/security/primitives/{$realm.spec.ts → $issuer.spec.ts} +11 -11
  269. package/src/security/primitives/{$realm.ts → $issuer.ts} +20 -17
  270. package/src/security/primitives/$role.ts +5 -5
  271. package/src/security/primitives/$serviceAccount.spec.ts +5 -5
  272. package/src/security/primitives/$serviceAccount.ts +3 -3
  273. package/src/{server/security → security}/providers/ServerSecurityProvider.ts +5 -7
  274. package/src/server/auth/primitives/$auth.ts +10 -10
  275. package/src/server/auth/primitives/$authCredentials.ts +3 -3
  276. package/src/server/auth/primitives/$authGithub.ts +3 -3
  277. package/src/server/auth/primitives/$authGoogle.ts +3 -3
  278. package/src/server/auth/providers/ServerAuthProvider.ts +13 -13
  279. package/src/server/cache/providers/ServerCacheProvider.ts +1 -1
  280. package/src/server/cookies/providers/ServerCookiesProvider.ts +3 -3
  281. package/src/server/core/index.ts +1 -1
  282. package/src/server/core/providers/BunHttpServerProvider.ts +1 -1
  283. package/src/server/core/providers/NodeHttpServerProvider.spec.ts +125 -0
  284. package/src/server/core/providers/NodeHttpServerProvider.ts +92 -24
  285. package/src/server/core/providers/ServerBodyParserProvider.ts +19 -23
  286. package/src/server/core/providers/ServerLoggerProvider.ts +23 -19
  287. package/src/server/core/providers/ServerProvider.ts +144 -24
  288. package/src/server/core/providers/ServerRouterProvider.ts +259 -115
  289. package/src/server/core/providers/ServerTimingProvider.ts +2 -2
  290. package/src/server/links/atoms/apiLinksAtom.ts +7 -0
  291. package/src/server/links/index.browser.ts +2 -0
  292. package/src/server/links/index.ts +3 -1
  293. package/src/server/links/providers/LinkProvider.ts +1 -1
  294. package/src/server/swagger/index.ts +1 -1
  295. package/src/sms/providers/LocalSmsProvider.spec.ts +153 -111
  296. package/src/sms/providers/LocalSmsProvider.ts +8 -7
  297. package/src/vite/index.ts +3 -2
  298. package/src/vite/tasks/buildClient.ts +0 -1
  299. package/src/vite/tasks/buildServer.ts +80 -22
  300. package/src/vite/tasks/copyAssets.ts +5 -4
  301. package/src/vite/tasks/generateCloudflare.ts +7 -0
  302. package/src/vite/tasks/generateSitemap.ts +64 -23
  303. package/src/vite/tasks/index.ts +0 -2
  304. package/src/vite/tasks/prerenderPages.ts +49 -24
  305. package/dist/server/security/index.browser.js +0 -13
  306. package/dist/server/security/index.browser.js.map +0 -1
  307. package/dist/server/security/index.d.ts +0 -173
  308. package/dist/server/security/index.d.ts.map +0 -1
  309. package/dist/server/security/index.js +0 -311
  310. package/dist/server/security/index.js.map +0 -1
  311. package/src/cli/assets/appRouterTs.ts +0 -9
  312. package/src/cli/assets/indexHtml.ts +0 -15
  313. package/src/cli/assets/mainTs.ts +0 -13
  314. package/src/cli/commands/format.ts +0 -17
  315. package/src/server/security/index.browser.ts +0 -10
  316. package/src/server/security/index.ts +0 -94
  317. package/src/vite/helpers/boot.ts +0 -106
  318. package/src/vite/plugins/viteAlephaDev.ts +0 -177
  319. package/src/vite/tasks/devServer.ts +0 -69
  320. package/src/vite/tasks/runAlepha.ts +0 -270
  321. /package/src/{server/security → security}/primitives/$basicAuth.ts +0 -0
  322. /package/src/{server/security → security}/providers/ServerBasicAuthProvider.ts +0 -0
@@ -10,11 +10,11 @@ import { AlephaApiAudits, AuditService } from "alepha/api/audits";
10
10
  import { $logger } from "alepha/logger";
11
11
  import { $bucket } from "alepha/bucket";
12
12
  import { $client } from "alepha/server/links";
13
+ import { $authCredentials, $authGithub, $authGoogle, ServerAuthProvider, authenticationProviderSchema } from "alepha/server/auth";
13
14
  import { randomInt, randomUUID } from "node:crypto";
14
15
  import { $cache } from "alepha/cache";
15
16
  import { DateTimeProvider } from "alepha/datetime";
16
- import { $realm, CryptoProvider, InvalidCredentialsError, SecurityProvider } from "alepha/security";
17
- import { $authCredentials, $authGithub, $authGoogle, ServerAuthProvider, authenticationProviderSchema } from "alepha/server/auth";
17
+ import { $issuer, CryptoProvider, InvalidCredentialsError, SecurityProvider } from "alepha/security";
18
18
  import { FileSystemProvider } from "alepha/file";
19
19
  import { AlephaApiFiles } from "alepha/api/files";
20
20
 
@@ -37,8 +37,7 @@ const users = $entity({
37
37
  realm: db.default(t.text(), DEFAULT_USER_REALM_NAME),
38
38
  username: t.optional(t.shortText({
39
39
  minLength: 3,
40
- maxLength: 50,
41
- pattern: "^[a-zA-Z0-9._-]+$"
40
+ maxLength: 50
42
41
  })),
43
42
  email: t.optional(t.string({ format: "email" })),
44
43
  phoneNumber: t.optional(t.e164()),
@@ -99,6 +98,7 @@ const realmAuthSettingsAtom = $atom({
99
98
  emailRequired: t.boolean({ description: "Require email address for user accounts" }),
100
99
  usernameEnabled: t.boolean({ description: "Enable username as a login/registration credential" }),
101
100
  usernameRequired: t.boolean({ description: "Require username for user accounts" }),
101
+ usernameRegExp: t.string({ description: "Regular expression that usernames must match (if username is enabled)" }),
102
102
  phoneEnabled: t.boolean({ description: "Enable phone number as a login/registration credential" }),
103
103
  phoneRequired: t.boolean({ description: "Require phone number for user accounts" }),
104
104
  verifyEmailRequired: t.boolean({ description: "Require email verification for user accounts" }),
@@ -124,6 +124,7 @@ const realmAuthSettingsAtom = $atom({
124
124
  emailRequired: true,
125
125
  usernameEnabled: false,
126
126
  usernameRequired: false,
127
+ usernameRegExp: "^[a-zA-Z0-9_]{3,30}$",
127
128
  phoneEnabled: false,
128
129
  phoneRequired: false,
129
130
  verifyEmailRequired: false,
@@ -167,8 +168,8 @@ const sessions = $entity({
167
168
  });
168
169
 
169
170
  //#endregion
170
- //#region ../../src/api/users/providers/UserRealmProvider.ts
171
- var UserRealmProvider = class {
171
+ //#region ../../src/api/users/providers/RealmProvider.ts
172
+ var RealmProvider = class {
172
173
  alepha = $inject(Alepha);
173
174
  defaultIdentities = $repository(identities);
174
175
  defaultSessions = $repository(sessions);
@@ -193,46 +194,46 @@ var UserRealmProvider = class {
193
194
  });
194
195
  }
195
196
  });
196
- register(userRealmName, userRealmOptions = {}) {
197
- this.realms.set(userRealmName, {
198
- name: userRealmName,
197
+ register(realmName, realmOptions = {}) {
198
+ this.realms.set(realmName, {
199
+ name: realmName,
199
200
  repositories: {
200
- identities: userRealmOptions.entities?.identities ?? this.defaultIdentities,
201
- sessions: userRealmOptions.entities?.sessions ?? this.defaultSessions,
202
- users: userRealmOptions.entities?.users ?? this.defaultUsers
201
+ identities: realmOptions.entities?.identities ?? this.defaultIdentities,
202
+ sessions: realmOptions.entities?.sessions ?? this.defaultSessions,
203
+ users: realmOptions.entities?.users ?? this.defaultUsers
203
204
  },
204
205
  settings: {
205
206
  ...realmAuthSettingsAtom.options.default,
206
- ...userRealmOptions.settings,
207
+ ...realmOptions.settings,
207
208
  passwordPolicy: {
208
209
  ...realmAuthSettingsAtom.options.default.passwordPolicy,
209
- ...userRealmOptions.settings?.passwordPolicy
210
+ ...realmOptions.settings?.passwordPolicy
210
211
  }
211
212
  }
212
213
  });
213
- return this.getRealm(userRealmName);
214
+ return this.getRealm(realmName);
214
215
  }
215
216
  /**
216
217
  * Gets a registered realm by name, auto-creating default if needed.
217
218
  */
218
- getRealm(userRealmName = DEFAULT_USER_REALM_NAME) {
219
- let realm = this.realms.get(userRealmName);
219
+ getRealm(realmName = DEFAULT_USER_REALM_NAME) {
220
+ let realm = this.realms.get(realmName);
220
221
  if (!realm) {
221
222
  const firstRealm = Array.from(this.realms.values())[0];
222
- if (userRealmName === DEFAULT_USER_REALM_NAME && firstRealm) realm = firstRealm;
223
- else if (this.alepha.isTest()) realm = this.register(userRealmName);
224
- else throw new AlephaError(`Missing user realm '${userRealmName}', please declare $userRealm in your application.`);
223
+ if (realmName === DEFAULT_USER_REALM_NAME && firstRealm) realm = firstRealm;
224
+ else if (this.alepha.isTest()) realm = this.register(realmName);
225
+ else throw new AlephaError(`Missing realm '${realmName}', please declare $realm in your application.`);
225
226
  }
226
227
  return realm;
227
228
  }
228
- identityRepository(userRealmName = DEFAULT_USER_REALM_NAME) {
229
- return this.getRealm(userRealmName).repositories.identities;
229
+ identityRepository(realmName = DEFAULT_USER_REALM_NAME) {
230
+ return this.getRealm(realmName).repositories.identities;
230
231
  }
231
- sessionRepository(userRealmName = DEFAULT_USER_REALM_NAME) {
232
- return this.getRealm(userRealmName).repositories.sessions;
232
+ sessionRepository(realmName = DEFAULT_USER_REALM_NAME) {
233
+ return this.getRealm(realmName).repositories.sessions;
233
234
  }
234
- userRepository(userRealmName = DEFAULT_USER_REALM_NAME) {
235
- return this.getRealm(userRealmName).repositories.users;
235
+ userRepository(realmName = DEFAULT_USER_REALM_NAME) {
236
+ return this.getRealm(realmName).repositories.users;
236
237
  }
237
238
  };
238
239
 
@@ -240,10 +241,10 @@ var UserRealmProvider = class {
240
241
  //#region ../../src/api/users/services/IdentityService.ts
241
242
  var IdentityService = class {
242
243
  log = $logger();
243
- userRealmProvider = $inject(UserRealmProvider);
244
+ realmProvider = $inject(RealmProvider);
244
245
  auditService = $inject(AuditService);
245
246
  identities(userRealmName) {
246
- return this.userRealmProvider.identityRepository(userRealmName);
247
+ return this.realmProvider.identityRepository(userRealmName);
247
248
  }
248
249
  /**
249
250
  * Find identities with pagination and filtering.
@@ -295,7 +296,7 @@ var IdentityService = class {
295
296
  provider: identity.provider,
296
297
  userId: identity.userId
297
298
  });
298
- const realm = this.userRealmProvider.getRealm(userRealmName);
299
+ const realm = this.realmProvider.getRealm(userRealmName);
299
300
  await this.auditService.recordUser("update", {
300
301
  userRealm: realm.name,
301
302
  resourceId: identity.userId,
@@ -398,9 +399,9 @@ const sessionResourceSchema = t.object({
398
399
  //#region ../../src/api/users/services/SessionCrudService.ts
399
400
  var SessionCrudService = class {
400
401
  log = $logger();
401
- userRealmProvider = $inject(UserRealmProvider);
402
+ realmProvider = $inject(RealmProvider);
402
403
  sessions(userRealmName) {
403
- return this.userRealmProvider.sessionRepository(userRealmName);
404
+ return this.realmProvider.sessionRepository(userRealmName);
404
405
  }
405
406
  /**
406
407
  * Find sessions with pagination and filtering.
@@ -672,10 +673,10 @@ var UserService = class {
672
673
  log = $logger();
673
674
  verificationController = $client();
674
675
  userNotifications = $inject(UserNotifications);
675
- userRealmProvider = $inject(UserRealmProvider);
676
+ realmProvider = $inject(RealmProvider);
676
677
  auditService = $inject(AuditService);
677
678
  users(userRealmName) {
678
- return this.userRealmProvider.userRepository(userRealmName);
679
+ return this.realmProvider.userRepository(userRealmName);
679
680
  }
680
681
  /**
681
682
  * Request email verification for a user.
@@ -779,7 +780,7 @@ var UserService = class {
779
780
  userId: user.id,
780
781
  type
781
782
  });
782
- const realm = this.userRealmProvider.getRealm(userRealmName);
783
+ const realm = this.realmProvider.getRealm(userRealmName);
783
784
  await this.auditService.recordUser("update", {
784
785
  userId: user.id,
785
786
  userEmail: email,
@@ -843,7 +844,7 @@ var UserService = class {
843
844
  email: data.email,
844
845
  userRealmName
845
846
  });
846
- const realm = this.userRealmProvider.getRealm(userRealmName);
847
+ const realm = this.realmProvider.getRealm(userRealmName);
847
848
  if (data.username) {
848
849
  if (await this.users(userRealmName).findOne({ where: { username: { eq: data.username } } }).catch(() => void 0)) {
849
850
  this.log.debug("Username already taken", { username: data.username });
@@ -895,7 +896,7 @@ var UserService = class {
895
896
  const before = await this.getUserById(id, userRealmName);
896
897
  const user = await this.users(userRealmName).updateById(id, data);
897
898
  this.log.debug("User updated", { userId: id });
898
- const realm = this.userRealmProvider.getRealm(userRealmName);
899
+ const realm = this.realmProvider.getRealm(userRealmName);
899
900
  const changes = {};
900
901
  for (const key of Object.keys(data)) if (data[key] !== void 0 && before[key] !== data[key]) changes[key] = {
901
902
  from: before[key],
@@ -921,7 +922,7 @@ var UserService = class {
921
922
  const user = await this.getUserById(id, userRealmName);
922
923
  await this.users(userRealmName).deleteById(id);
923
924
  this.log.info("User deleted", { userId: id });
924
- const realm = this.userRealmProvider.getRealm(userRealmName);
925
+ const realm = this.realmProvider.getRealm(userRealmName);
925
926
  await this.auditService.recordUser("delete", {
926
927
  userRealm: realm.name,
927
928
  resourceId: id,
@@ -1025,6 +1026,67 @@ var AdminUserController = class {
1025
1026
  });
1026
1027
  };
1027
1028
 
1029
+ //#endregion
1030
+ //#region ../../src/api/users/schemas/realmConfigSchema.ts
1031
+ const realmConfigSchema = t.object({
1032
+ settings: realmAuthSettingsAtom.schema,
1033
+ realmName: t.string(),
1034
+ authenticationMethods: t.array(authenticationProviderSchema)
1035
+ });
1036
+
1037
+ //#endregion
1038
+ //#region ../../src/api/users/controllers/RealmController.ts
1039
+ /**
1040
+ * Controller for exposing realm configuration.
1041
+ * Uses $route instead of $action to keep endpoints hidden from API documentation.
1042
+ */
1043
+ var RealmController = class {
1044
+ url = "/realms";
1045
+ group = "realms";
1046
+ realmProvider = $inject(RealmProvider);
1047
+ serverAuthProvider = $inject(ServerAuthProvider);
1048
+ /**
1049
+ * Get realm configuration settings.
1050
+ * This endpoint is not exposed in the API documentation.
1051
+ */
1052
+ getRealmConfig = $action({
1053
+ group: this.group,
1054
+ method: "GET",
1055
+ path: `${this.url}/config`,
1056
+ secure: false,
1057
+ cache: {
1058
+ etag: true,
1059
+ control: { maxAge: [24, "hours"] }
1060
+ },
1061
+ schema: {
1062
+ query: t.object({ realmName: t.optional(t.string()) }),
1063
+ response: realmConfigSchema
1064
+ },
1065
+ handler: ({ query }) => {
1066
+ const { name: realmName, settings } = this.realmProvider.getRealm(query.realmName);
1067
+ return {
1068
+ settings,
1069
+ realmName,
1070
+ authenticationMethods: this.serverAuthProvider.getAuthenticationProviders({ realmName })
1071
+ };
1072
+ }
1073
+ });
1074
+ checkUsernameAvailability = $action({
1075
+ group: this.group,
1076
+ path: `${this.url}/check-username`,
1077
+ secure: false,
1078
+ schema: {
1079
+ query: t.object({ realmName: t.optional(t.text()) }),
1080
+ body: t.object({ username: t.text() }),
1081
+ response: t.object({ available: t.boolean() })
1082
+ },
1083
+ handler: async ({ query, body }) => {
1084
+ const realmName = query.realmName;
1085
+ return { available: !await this.realmProvider.userRepository(realmName).findOne({ where: { username: { eq: body.username } } }).catch(() => void 0) };
1086
+ }
1087
+ });
1088
+ };
1089
+
1028
1090
  //#endregion
1029
1091
  //#region ../../src/api/users/schemas/completePasswordResetRequestSchema.ts
1030
1092
  /**
@@ -1116,20 +1178,20 @@ var CredentialService = class {
1116
1178
  dateTimeProvider = $inject(DateTimeProvider);
1117
1179
  verificationController = $client();
1118
1180
  userNotifications = $inject(UserNotifications);
1119
- userRealmProvider = $inject(UserRealmProvider);
1181
+ realmProvider = $inject(RealmProvider);
1120
1182
  auditService = $inject(AuditService);
1121
1183
  intentCache = $cache({
1122
1184
  name: "password-reset-intents",
1123
1185
  ttl: [INTENT_TTL_MINUTES$1, "minutes"]
1124
1186
  });
1125
1187
  users(userRealmName) {
1126
- return this.userRealmProvider.userRepository(userRealmName);
1188
+ return this.realmProvider.userRepository(userRealmName);
1127
1189
  }
1128
1190
  sessions(userRealmName) {
1129
- return this.userRealmProvider.sessionRepository(userRealmName);
1191
+ return this.realmProvider.sessionRepository(userRealmName);
1130
1192
  }
1131
1193
  identities(userRealmName) {
1132
- return this.userRealmProvider.identityRepository(userRealmName);
1194
+ return this.realmProvider.identityRepository(userRealmName);
1133
1195
  }
1134
1196
  /**
1135
1197
  * Phase 1: Create a password reset intent.
@@ -1246,7 +1308,7 @@ var CredentialService = class {
1246
1308
  userId: intent.userId,
1247
1309
  email: intent.email
1248
1310
  });
1249
- const realm = this.userRealmProvider.getRealm(intent.realmName);
1311
+ const realm = this.realmProvider.getRealm(intent.realmName);
1250
1312
  await this.auditService.recordUser("update", {
1251
1313
  userId: intent.userId,
1252
1314
  userEmail: intent.email,
@@ -1305,7 +1367,7 @@ var CredentialService = class {
1305
1367
  const hashedPassword = await this.cryptoProvider.hashPassword(newPassword);
1306
1368
  await this.identities(userRealmName).updateById(identity.id, { password: hashedPassword });
1307
1369
  await this.sessions(userRealmName).deleteMany({ userId: { eq: user.id } });
1308
- const realm = this.userRealmProvider.getRealm(userRealmName);
1370
+ const realm = this.realmProvider.getRealm(userRealmName);
1309
1371
  await this.auditService.recordUser("update", {
1310
1372
  userId: user.id,
1311
1373
  userEmail: email,
@@ -1334,7 +1396,7 @@ var RegistrationService = class {
1334
1396
  cryptoProvider = $inject(CryptoProvider);
1335
1397
  verificationController = $client();
1336
1398
  userNotifications = $inject(UserNotifications);
1337
- userRealmProvider = $inject(UserRealmProvider);
1399
+ realmProvider = $inject(RealmProvider);
1338
1400
  auditService = $inject(AuditService);
1339
1401
  intentCache = $cache({
1340
1402
  name: "registration-intents",
@@ -1352,8 +1414,7 @@ var RegistrationService = class {
1352
1414
  username: body.username,
1353
1415
  userRealmName
1354
1416
  });
1355
- const realmSettings = this.userRealmProvider.getRealm(userRealmName).settings;
1356
- this.userRealmProvider.userRepository(userRealmName);
1417
+ const realmSettings = this.realmProvider.getRealm(userRealmName).settings;
1357
1418
  if (realmSettings?.registrationAllowed === false) {
1358
1419
  this.log.warn("Registration not allowed for realm", { userRealmName });
1359
1420
  throw new BadRequestError("Registration is not allowed");
@@ -1362,6 +1423,18 @@ var RegistrationService = class {
1362
1423
  this.log.debug("Registration rejected: username required", { userRealmName });
1363
1424
  throw new BadRequestError("Username is required");
1364
1425
  }
1426
+ if (body.username) {
1427
+ const usernameRegExp = realmSettings?.usernameRegExp;
1428
+ if (usernameRegExp) {
1429
+ if (!new RegExp(usernameRegExp).test(body.username)) {
1430
+ this.log.debug("Registration rejected: username regex mismatch", {
1431
+ userRealmName,
1432
+ username: body.username
1433
+ });
1434
+ throw new BadRequestError("Username does not meet the required format");
1435
+ }
1436
+ }
1437
+ }
1365
1438
  if (realmSettings?.emailRequired !== false && !body.email) {
1366
1439
  this.log.debug("Registration rejected: email required", { userRealmName });
1367
1440
  throw new BadRequestError("Email is required");
@@ -1428,8 +1501,8 @@ var RegistrationService = class {
1428
1501
  });
1429
1502
  }
1430
1503
  const userRealmName = intent.realmName;
1431
- const userRepository = this.userRealmProvider.userRepository(userRealmName);
1432
- const identityRepository = this.userRealmProvider.identityRepository(userRealmName);
1504
+ const userRepository = this.realmProvider.userRepository(userRealmName);
1505
+ const identityRepository = this.realmProvider.identityRepository(userRealmName);
1433
1506
  if (intent.requirements.email) {
1434
1507
  if (!body.emailCode) {
1435
1508
  this.log.debug("Registration completion missing email code", { intentId: body.intentId });
@@ -1477,7 +1550,7 @@ var RegistrationService = class {
1477
1550
  email: user.email,
1478
1551
  username: user.username
1479
1552
  });
1480
- const realm = this.userRealmProvider.getRealm(userRealmName);
1553
+ const realm = this.realmProvider.getRealm(userRealmName);
1481
1554
  await this.auditService.recordUser("create", {
1482
1555
  userId: user.id,
1483
1556
  userEmail: user.email ?? void 0,
@@ -1497,7 +1570,7 @@ var RegistrationService = class {
1497
1570
  * Check if username, email, and phone are available.
1498
1571
  */
1499
1572
  async checkUserAvailability(body, userRealmName) {
1500
- const userRepository = this.userRealmProvider.userRepository(userRealmName);
1573
+ const userRepository = this.realmProvider.userRepository(userRealmName);
1501
1574
  if (body.username) {
1502
1575
  if (await userRepository.findOne({ where: { username: { eq: body.username } } }).catch(() => void 0)) {
1503
1576
  this.log.debug("Username already taken", { username: body.username });
@@ -1522,23 +1595,19 @@ var RegistrationService = class {
1522
1595
  */
1523
1596
  async sendEmailVerification(email) {
1524
1597
  this.log.debug("Sending email verification code", { email });
1525
- try {
1526
- const verification = await this.verificationController.requestVerificationCode({
1527
- params: { type: "code" },
1528
- body: { target: email }
1529
- });
1530
- await this.userNotifications.emailVerification.push({
1531
- contact: email,
1532
- variables: {
1533
- email,
1534
- code: verification.token,
1535
- expiresInMinutes: Math.floor(verification.codeExpiration / 60)
1536
- }
1537
- });
1538
- this.log.debug("Email verification code sent", { email });
1539
- } catch (error) {
1540
- this.log.warn("Failed to send email verification code", error);
1541
- }
1598
+ const verification = await this.verificationController.requestVerificationCode({
1599
+ params: { type: "code" },
1600
+ body: { target: email }
1601
+ });
1602
+ await this.userNotifications.emailVerification.push({
1603
+ contact: email,
1604
+ variables: {
1605
+ email,
1606
+ code: verification.token,
1607
+ expiresInMinutes: Math.floor(verification.codeExpiration / 60)
1608
+ }
1609
+ });
1610
+ this.log.debug("Email verification code sent", { email });
1542
1611
  }
1543
1612
  /**
1544
1613
  * Send phone verification code.
@@ -1831,67 +1900,6 @@ var UserController = class {
1831
1900
  });
1832
1901
  };
1833
1902
 
1834
- //#endregion
1835
- //#region ../../src/api/users/schemas/userRealmConfigSchema.ts
1836
- const userRealmConfigSchema = t.object({
1837
- settings: realmAuthSettingsAtom.schema,
1838
- realmName: t.string(),
1839
- authenticationMethods: t.array(authenticationProviderSchema)
1840
- });
1841
-
1842
- //#endregion
1843
- //#region ../../src/api/users/controllers/UserRealmController.ts
1844
- /**
1845
- * Controller for exposing realm configuration.
1846
- * Uses $route instead of $action to keep endpoints hidden from API documentation.
1847
- */
1848
- var UserRealmController = class {
1849
- url = "/realms";
1850
- group = "realms";
1851
- userRealmProvider = $inject(UserRealmProvider);
1852
- serverAuthProvider = $inject(ServerAuthProvider);
1853
- /**
1854
- * Get realm configuration settings.
1855
- * This endpoint is not exposed in the API documentation.
1856
- */
1857
- getRealmConfig = $action({
1858
- group: this.group,
1859
- method: "GET",
1860
- path: `${this.url}/config`,
1861
- secure: false,
1862
- cache: {
1863
- etag: true,
1864
- control: { maxAge: [24, "hours"] }
1865
- },
1866
- schema: {
1867
- query: t.object({ userRealmName: t.optional(t.string()) }),
1868
- response: userRealmConfigSchema
1869
- },
1870
- handler: ({ query }) => {
1871
- const { name: realmName, settings } = this.userRealmProvider.getRealm(query.userRealmName);
1872
- return {
1873
- settings,
1874
- realmName,
1875
- authenticationMethods: this.serverAuthProvider.getAuthenticationProviders({ realmName })
1876
- };
1877
- }
1878
- });
1879
- checkUsernameAvailability = $action({
1880
- group: this.group,
1881
- path: `${this.url}/check-username`,
1882
- secure: false,
1883
- schema: {
1884
- query: t.object({ userRealmName: t.optional(t.text()) }),
1885
- body: t.object({ username: t.text() }),
1886
- response: t.object({ available: t.boolean() })
1887
- },
1888
- handler: async ({ query, body }) => {
1889
- const realmName = query.userRealmName;
1890
- return { available: !await this.userRealmProvider.userRepository(realmName).findOne({ where: { username: { eq: body.username } } }).catch(() => void 0) };
1891
- }
1892
- });
1893
- };
1894
-
1895
1903
  //#endregion
1896
1904
  //#region ../../src/api/users/services/SessionService.ts
1897
1905
  var SessionService = class {
@@ -1900,17 +1908,17 @@ var SessionService = class {
1900
1908
  dateTimeProvider = $inject(DateTimeProvider);
1901
1909
  cryptoProvider = $inject(CryptoProvider);
1902
1910
  log = $logger();
1903
- userRealmProvider = $inject(UserRealmProvider);
1911
+ realmProvider = $inject(RealmProvider);
1904
1912
  fileController = $client();
1905
1913
  auditService = $inject(AuditService);
1906
1914
  users(userRealmName) {
1907
- return this.userRealmProvider.userRepository(userRealmName);
1915
+ return this.realmProvider.userRepository(userRealmName);
1908
1916
  }
1909
1917
  sessions(userRealmName) {
1910
- return this.userRealmProvider.sessionRepository(userRealmName);
1918
+ return this.realmProvider.sessionRepository(userRealmName);
1911
1919
  }
1912
1920
  identities(userRealmName) {
1913
- return this.userRealmProvider.identityRepository(userRealmName);
1921
+ return this.realmProvider.identityRepository(userRealmName);
1914
1922
  }
1915
1923
  /**
1916
1924
  * Random delay to prevent timing attacks (50-200ms)
@@ -1923,18 +1931,37 @@ var SessionService = class {
1923
1931
  * Validate user credentials and return the user if valid.
1924
1932
  */
1925
1933
  async login(provider, username, password, userRealmName) {
1926
- const { settings, name } = this.userRealmProvider.getRealm(userRealmName);
1934
+ const { settings, name } = this.realmProvider.getRealm(userRealmName);
1927
1935
  const isEmail = username.includes("@");
1928
1936
  const isPhone = /^[+\d][\d\s()-]+$/.test(username);
1929
1937
  const isUsername = !isEmail && !isPhone;
1930
- const identities$1 = this.identities(userRealmName);
1931
- const users$1 = this.users(userRealmName);
1938
+ const identities = this.identities(userRealmName);
1939
+ const users = this.users(userRealmName);
1932
1940
  await this.randomDelay();
1933
1941
  try {
1934
- const where = users$1.createQueryWhere();
1942
+ const where = users.createQueryWhere();
1935
1943
  where.realm = name;
1936
- if (settings.usernameEnabled !== false && isUsername) where.username = username;
1937
- else if (settings.emailEnabled !== false && isEmail) where.email = username;
1944
+ if (settings.usernameEnabled !== false && isUsername) {
1945
+ if (settings.usernameRegExp) {
1946
+ if (!new RegExp(settings.usernameRegExp).test(username)) {
1947
+ this.log.warn("Username does not match required format", {
1948
+ provider,
1949
+ username,
1950
+ realm: name
1951
+ });
1952
+ await this.auditService.recordAuth("login_failed", {
1953
+ userRealm: name,
1954
+ description: "Username does not match required format",
1955
+ metadata: {
1956
+ provider,
1957
+ username
1958
+ }
1959
+ });
1960
+ throw new InvalidCredentialsError();
1961
+ }
1962
+ }
1963
+ where.username = username;
1964
+ } else if (settings.emailEnabled !== false && isEmail) where.email = username;
1938
1965
  else if (settings.phoneEnabled === true && isPhone) where.phoneNumber = username;
1939
1966
  else {
1940
1967
  this.log.warn("Invalid login identifier format", {
@@ -1952,7 +1979,7 @@ var SessionService = class {
1952
1979
  });
1953
1980
  throw new InvalidCredentialsError();
1954
1981
  }
1955
- const user = await users$1.findOne({ where }).catch(() => void 0);
1982
+ const user = await users.findOne({ where }).catch(() => void 0);
1956
1983
  if (!user) {
1957
1984
  this.log.warn("User not found during login attempt", {
1958
1985
  provider,
@@ -1969,7 +1996,7 @@ var SessionService = class {
1969
1996
  });
1970
1997
  throw new InvalidCredentialsError();
1971
1998
  }
1972
- const identity = await identities$1.findOne({ where: {
1999
+ const identity = await identities.findOne({ where: {
1973
2000
  provider: { eq: provider },
1974
2001
  userId: { eq: user.id }
1975
2002
  } });
@@ -2061,14 +2088,6 @@ var SessionService = class {
2061
2088
  sessionId: session.id,
2062
2089
  userId: session.userId
2063
2090
  });
2064
- const { name } = this.userRealmProvider.getRealm(userRealmName);
2065
- await this.auditService.recordAuth("token_refresh", {
2066
- userId: user.id,
2067
- userEmail: user.email ?? void 0,
2068
- userRealm: name,
2069
- sessionId: session.id,
2070
- description: "Session token refreshed"
2071
- });
2072
2091
  return {
2073
2092
  user,
2074
2093
  expiresIn: expiresAt.unix() - now.unix(),
@@ -2081,7 +2100,7 @@ var SessionService = class {
2081
2100
  await this.sessions(userRealmName).deleteOne({ refreshToken });
2082
2101
  this.log.debug("Session deleted");
2083
2102
  if (session) {
2084
- const { name } = this.userRealmProvider.getRealm(userRealmName);
2103
+ const { name } = this.realmProvider.getRealm(userRealmName);
2085
2104
  await this.auditService.recordAuth("logout", {
2086
2105
  userId: session.userId,
2087
2106
  userRealm: name,
@@ -2096,10 +2115,10 @@ var SessionService = class {
2096
2115
  profileSub: profile.sub,
2097
2116
  email: profile.email
2098
2117
  });
2099
- const realm = this.userRealmProvider.getRealm(userRealmName);
2100
- const identities$1 = this.identities(userRealmName);
2101
- const users$1 = this.users(userRealmName);
2102
- const identity = await identities$1.findOne({ where: {
2118
+ const realm = this.realmProvider.getRealm(userRealmName);
2119
+ const identities = this.identities(userRealmName);
2120
+ const users = this.users(userRealmName);
2121
+ const identity = await identities.findOne({ where: {
2103
2122
  provider,
2104
2123
  providerUserId: profile.sub
2105
2124
  } }).catch(() => void 0);
@@ -2109,19 +2128,19 @@ var SessionService = class {
2109
2128
  identityId: identity.id,
2110
2129
  userId: identity.userId
2111
2130
  });
2112
- const user$1 = await users$1.findById(identity.userId);
2131
+ const user = await users.findById(identity.userId);
2113
2132
  await this.auditService.recordAuth("login", {
2114
- userId: user$1.id,
2115
- userEmail: user$1.email ?? void 0,
2133
+ userId: user.id,
2134
+ userEmail: user.email ?? void 0,
2116
2135
  userRealm: realm.name,
2117
- resourceId: user$1.id,
2136
+ resourceId: user.id,
2118
2137
  description: `User logged in via OAuth2 (${provider})`,
2119
2138
  metadata: {
2120
2139
  provider,
2121
2140
  providerUserId: profile.sub
2122
2141
  }
2123
2142
  });
2124
- return user$1;
2143
+ return user;
2125
2144
  }
2126
2145
  if (!profile.email) {
2127
2146
  this.log.debug("OAuth2 profile has no email, returning profile as-is", {
@@ -2133,7 +2152,7 @@ var SessionService = class {
2133
2152
  ...profile
2134
2153
  };
2135
2154
  }
2136
- const existing = await users$1.findOne({ where: { email: profile.email } }).catch(() => void 0);
2155
+ const existing = await users.findOne({ where: { email: profile.email } }).catch(() => void 0);
2137
2156
  if (existing) {
2138
2157
  this.log.debug("Linking OAuth2 profile to existing user by email", {
2139
2158
  provider,
@@ -2141,7 +2160,7 @@ var SessionService = class {
2141
2160
  userId: existing.id,
2142
2161
  email: profile.email
2143
2162
  });
2144
- await identities$1.create({
2163
+ await identities.create({
2145
2164
  provider,
2146
2165
  providerUserId: profile.sub,
2147
2166
  userId: existing.id
@@ -2160,7 +2179,7 @@ var SessionService = class {
2160
2179
  });
2161
2180
  return existing;
2162
2181
  }
2163
- const user = await users$1.create({
2182
+ const user = await users.create({
2164
2183
  realm: realm.name,
2165
2184
  username: profile.email.split("@")[0],
2166
2185
  email: profile.email,
@@ -2177,7 +2196,7 @@ var SessionService = class {
2177
2196
  const file = this.fsp.createFile({ response });
2178
2197
  if (response.ok && response.body) {
2179
2198
  const fileEntity = await this.fileController.uploadFile({ body: { file } }, { user });
2180
- await users$1.updateById(user.id, { picture: fileEntity.id });
2199
+ await users.updateById(user.id, { picture: fileEntity.id });
2181
2200
  }
2182
2201
  } catch (error) {
2183
2202
  this.log.warn("Failed to fetch user profile picture", error);
@@ -2224,7 +2243,7 @@ var SessionService = class {
2224
2243
  };
2225
2244
 
2226
2245
  //#endregion
2227
- //#region ../../src/api/users/primitives/$userRealm.ts
2246
+ //#region ../../src/api/users/primitives/$realm.ts
2228
2247
  /**
2229
2248
  * Already configured realm for user management.
2230
2249
  *
@@ -2238,24 +2257,24 @@ var SessionService = class {
2238
2257
  * Environment Variables:
2239
2258
  * - `APP_SECRET`: Secret key for signing tokens (if not provided in options).
2240
2259
  */
2241
- const $userRealm = (options = {}) => {
2260
+ const $realm = (options = {}) => {
2242
2261
  const { alepha } = $context();
2243
2262
  const sessionService = alepha.inject(SessionService);
2244
2263
  const securityProvider = alepha.inject(SecurityProvider);
2245
- const userRealmProvider = alepha.inject(UserRealmProvider);
2246
- const name = options.realm?.name ?? DEFAULT_USER_REALM_NAME;
2264
+ const realmProvider = alepha.inject(RealmProvider);
2265
+ const name = options.issuer?.name ?? DEFAULT_USER_REALM_NAME;
2247
2266
  options.settings ??= {};
2248
2267
  if (options.settings.emailRequired) options.settings.emailEnabled = true;
2249
2268
  if (options.settings.usernameRequired) options.settings.usernameEnabled = true;
2250
2269
  if (options.settings.phoneRequired) options.settings.phoneEnabled = true;
2251
- const userRealm = userRealmProvider.register(name, options);
2270
+ const realmRegistration = realmProvider.register(name, options);
2252
2271
  alepha.with(AlephaApiFiles);
2253
2272
  alepha.with(AlephaApiAudits);
2254
- const realm = $realm({
2255
- ...options.realm,
2273
+ const realm = $issuer({
2274
+ ...options.issuer,
2256
2275
  name,
2257
2276
  secret: options.secret ?? securityProvider.secretKey,
2258
- roles: options.realm?.roles ?? [{
2277
+ roles: options.issuer?.roles ?? [{
2259
2278
  name: "admin",
2260
2279
  permissions: [{ name: "*" }]
2261
2280
  }, {
@@ -2278,24 +2297,24 @@ const $userRealm = (options = {}) => {
2278
2297
  onDeleteSession: async (refreshToken) => {
2279
2298
  await sessionService.deleteSession(refreshToken);
2280
2299
  },
2281
- ...options.realm?.settings
2300
+ ...options.issuer?.settings
2282
2301
  }
2283
2302
  });
2284
- realm.link = (name$1) => {
2285
- return (ctx) => sessionService.link(name$1, ctx.user, realm.name);
2303
+ realm.link = (name) => {
2304
+ return (ctx) => sessionService.link(name, ctx.user, realm.name);
2286
2305
  };
2287
- realm.login = (name$1) => {
2306
+ realm.login = (name) => {
2288
2307
  return (credentials) => {
2289
- return sessionService.login(name$1, credentials.username, credentials.password, realm.name);
2308
+ return sessionService.login(name, credentials.username, credentials.password, realm.name);
2290
2309
  };
2291
2310
  };
2292
- const identities$1 = options.identities ?? { credentials: true };
2293
- if (identities$1) {
2311
+ const identities = options.identities ?? { credentials: true };
2312
+ if (identities) {
2294
2313
  const auth = {};
2295
- if (identities$1.credentials) auth.credentials = $authCredentials(realm);
2296
- else userRealm.settings.registrationAllowed = false;
2297
- if (identities$1.google) auth.google = $authGoogle(realm);
2298
- if (identities$1.github) auth.github = $authGithub(realm);
2314
+ if (identities.credentials) auth.credentials = $authCredentials(realm);
2315
+ else realmRegistration.settings.registrationAllowed = false;
2316
+ if (identities.google) auth.google = $authGoogle(realm);
2317
+ if (identities.github) auth.github = $authGithub(realm);
2299
2318
  alepha.with(() => auth);
2300
2319
  }
2301
2320
  return realm;
@@ -2376,7 +2395,7 @@ const AlephaApiUsers = $module({
2376
2395
  AlephaServerHelmet,
2377
2396
  AlephaServerCompress,
2378
2397
  AlephaEmail,
2379
- UserRealmProvider,
2398
+ RealmProvider,
2380
2399
  SessionService,
2381
2400
  SessionCrudService,
2382
2401
  CredentialService,
@@ -2387,11 +2406,11 @@ const AlephaApiUsers = $module({
2387
2406
  AdminUserController,
2388
2407
  AdminSessionController,
2389
2408
  AdminIdentityController,
2390
- UserRealmController,
2409
+ RealmController,
2391
2410
  UserNotifications
2392
2411
  ]
2393
2412
  });
2394
2413
 
2395
2414
  //#endregion
2396
- export { $userRealm, AdminIdentityController, AdminSessionController, AdminUserController, AlephaApiUsers, CredentialService, DEFAULT_USER_REALM_NAME, IdentityService, RegistrationService, SessionCrudService, SessionService, UserController, UserRealmController, UserRealmProvider, UserService, completePasswordResetRequestSchema, completeRegistrationRequestSchema, createUserSchema, identities, identityQuerySchema, identityResourceSchema, loginSchema, passwordResetIntentResponseSchema, realmAuthSettingsAtom, registerSchema, registrationIntentResponseSchema, resetPasswordRequestSchema, resetPasswordSchema, sessionQuerySchema, sessionResourceSchema, sessions, updateUserSchema, userQuerySchema, userRealmConfigSchema, userResourceSchema, users };
2415
+ export { $realm, AdminIdentityController, AdminSessionController, AdminUserController, AlephaApiUsers, CredentialService, DEFAULT_USER_REALM_NAME, IdentityService, RealmController, RealmProvider, RegistrationService, SessionCrudService, SessionService, UserController, UserService, completePasswordResetRequestSchema, completeRegistrationRequestSchema, createUserSchema, identities, identityQuerySchema, identityResourceSchema, loginSchema, passwordResetIntentResponseSchema, realmAuthSettingsAtom, realmConfigSchema, registerSchema, registrationIntentResponseSchema, resetPasswordRequestSchema, resetPasswordSchema, sessionQuerySchema, sessionResourceSchema, sessions, updateUserSchema, userQuerySchema, userResourceSchema, users };
2397
2416
  //# sourceMappingURL=index.js.map