@openora/core 0.4.1-canary.18 → 0.4.1-canary.181

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 (2449) hide show
  1. package/README.md +10 -10
  2. package/bin/migrate.mjs +55 -0
  3. package/dist/.tsbuildinfo +1 -1
  4. package/dist/admin-console/__tests__/backoffice.router.test.js +82 -51
  5. package/dist/admin-console/__tests__/backoffice.router.test.js.map +1 -1
  6. package/dist/admin-console/__tests__/backoffice.service.int.test.d.ts +2 -0
  7. package/dist/admin-console/__tests__/backoffice.service.int.test.d.ts.map +1 -0
  8. package/dist/admin-console/__tests__/backoffice.service.int.test.js +351 -0
  9. package/dist/admin-console/__tests__/backoffice.service.int.test.js.map +1 -0
  10. package/dist/admin-console/contract/index.d.ts +359 -28
  11. package/dist/admin-console/contract/index.d.ts.map +1 -1
  12. package/dist/admin-console/contract/index.js +100 -6
  13. package/dist/admin-console/contract/index.js.map +1 -1
  14. package/dist/admin-console/plugin.d.ts +187 -1
  15. package/dist/admin-console/plugin.d.ts.map +1 -1
  16. package/dist/admin-console/plugin.js +6 -6
  17. package/dist/admin-console/plugin.js.map +1 -1
  18. package/dist/admin-console/router/index.d.ts +159 -18
  19. package/dist/admin-console/router/index.d.ts.map +1 -1
  20. package/dist/admin-console/router/index.js +23 -3
  21. package/dist/admin-console/router/index.js.map +1 -1
  22. package/dist/admin-console/service/backoffice.service.d.ts +77 -10
  23. package/dist/admin-console/service/backoffice.service.d.ts.map +1 -1
  24. package/dist/admin-console/service/backoffice.service.js +98 -12
  25. package/dist/admin-console/service/backoffice.service.js.map +1 -1
  26. package/dist/analytics/__tests__/analytics.contract.test.d.ts +2 -0
  27. package/dist/analytics/__tests__/analytics.contract.test.d.ts.map +1 -0
  28. package/dist/analytics/__tests__/analytics.contract.test.js +36 -0
  29. package/dist/analytics/__tests__/analytics.contract.test.js.map +1 -0
  30. package/dist/analytics/__tests__/analytics.router.test.d.ts +2 -0
  31. package/dist/analytics/__tests__/analytics.router.test.d.ts.map +1 -0
  32. package/dist/analytics/__tests__/analytics.router.test.js +56 -0
  33. package/dist/analytics/__tests__/analytics.router.test.js.map +1 -0
  34. package/dist/analytics/__tests__/financial-analytics.service.test.d.ts +2 -0
  35. package/dist/analytics/__tests__/financial-analytics.service.test.d.ts.map +1 -0
  36. package/dist/analytics/__tests__/financial-analytics.service.test.js +87 -0
  37. package/dist/analytics/__tests__/financial-analytics.service.test.js.map +1 -0
  38. package/dist/analytics/__tests__/funnel-analytics.service.test.d.ts +2 -0
  39. package/dist/analytics/__tests__/funnel-analytics.service.test.d.ts.map +1 -0
  40. package/dist/analytics/__tests__/funnel-analytics.service.test.js +42 -0
  41. package/dist/analytics/__tests__/funnel-analytics.service.test.js.map +1 -0
  42. package/dist/analytics/contract/financial.d.ts +121 -0
  43. package/dist/analytics/contract/financial.d.ts.map +1 -0
  44. package/dist/analytics/contract/financial.js +45 -0
  45. package/dist/analytics/contract/financial.js.map +1 -0
  46. package/dist/analytics/contract/funnel.d.ts +52 -0
  47. package/dist/analytics/contract/funnel.d.ts.map +1 -0
  48. package/dist/analytics/contract/funnel.js +24 -0
  49. package/dist/analytics/contract/funnel.js.map +1 -0
  50. package/dist/analytics/contract/index.d.ts +68 -0
  51. package/dist/analytics/contract/index.d.ts.map +1 -0
  52. package/dist/analytics/contract/index.js +9 -0
  53. package/dist/analytics/contract/index.js.map +1 -0
  54. package/dist/analytics/index.d.ts +2 -0
  55. package/dist/analytics/index.d.ts.map +1 -0
  56. package/dist/analytics/index.js +2 -0
  57. package/dist/analytics/index.js.map +1 -0
  58. package/dist/analytics/plugin.d.ts +189 -0
  59. package/dist/analytics/plugin.d.ts.map +1 -0
  60. package/dist/analytics/plugin.js +13 -0
  61. package/dist/analytics/plugin.js.map +1 -0
  62. package/dist/analytics/router/index.d.ts +69 -0
  63. package/dist/analytics/router/index.d.ts.map +1 -0
  64. package/dist/analytics/router/index.js +24 -0
  65. package/dist/analytics/router/index.js.map +1 -0
  66. package/dist/analytics/server.d.ts +5 -0
  67. package/dist/analytics/server.d.ts.map +1 -0
  68. package/dist/analytics/server.js +5 -0
  69. package/dist/analytics/server.js.map +1 -0
  70. package/dist/analytics/service/financial-analytics.service.d.ts +14 -0
  71. package/dist/analytics/service/financial-analytics.service.d.ts.map +1 -0
  72. package/dist/analytics/service/financial-analytics.service.js +146 -0
  73. package/dist/analytics/service/financial-analytics.service.js.map +1 -0
  74. package/dist/analytics/service/funnel-analytics.service.d.ts +11 -0
  75. package/dist/analytics/service/funnel-analytics.service.d.ts.map +1 -0
  76. package/dist/analytics/service/funnel-analytics.service.js +83 -0
  77. package/dist/analytics/service/funnel-analytics.service.js.map +1 -0
  78. package/dist/audit/__tests__/audit.service.int.test.d.ts +2 -0
  79. package/dist/audit/__tests__/audit.service.int.test.d.ts.map +1 -0
  80. package/dist/audit/__tests__/audit.service.int.test.js +906 -0
  81. package/dist/audit/__tests__/audit.service.int.test.js.map +1 -0
  82. package/dist/audit/__tests__/map-event.test.d.ts +2 -0
  83. package/dist/audit/__tests__/map-event.test.d.ts.map +1 -0
  84. package/dist/audit/__tests__/map-event.test.js +488 -0
  85. package/dist/audit/__tests__/map-event.test.js.map +1 -0
  86. package/dist/audit/contract/index.d.ts +154 -10
  87. package/dist/audit/contract/index.d.ts.map +1 -1
  88. package/dist/audit/contract/index.js +45 -5
  89. package/dist/audit/contract/index.js.map +1 -1
  90. package/dist/audit/migrate.d.ts.map +1 -1
  91. package/dist/audit/migrate.js +12 -0
  92. package/dist/audit/migrate.js.map +1 -1
  93. package/dist/audit/plugin.d.ts +188 -1
  94. package/dist/audit/plugin.d.ts.map +1 -1
  95. package/dist/audit/plugin.js +852 -54
  96. package/dist/audit/plugin.js.map +1 -1
  97. package/dist/audit/router/index.d.ts +73 -5
  98. package/dist/audit/router/index.d.ts.map +1 -1
  99. package/dist/audit/router/index.js +2 -5
  100. package/dist/audit/router/index.js.map +1 -1
  101. package/dist/audit/service/audit.service.d.ts +40 -14
  102. package/dist/audit/service/audit.service.d.ts.map +1 -1
  103. package/dist/audit/service/audit.service.js +86 -16
  104. package/dist/audit/service/audit.service.js.map +1 -1
  105. package/dist/casino/gaming/__tests__/admin-reporting.int.test.d.ts +2 -0
  106. package/dist/casino/gaming/__tests__/admin-reporting.int.test.d.ts.map +1 -0
  107. package/dist/casino/gaming/__tests__/admin-reporting.int.test.js +277 -0
  108. package/dist/casino/gaming/__tests__/admin-reporting.int.test.js.map +1 -0
  109. package/dist/casino/gaming/__tests__/game-bulk.router.int.test.d.ts +2 -0
  110. package/dist/casino/gaming/__tests__/game-bulk.router.int.test.d.ts.map +1 -0
  111. package/dist/casino/gaming/__tests__/game-bulk.router.int.test.js +447 -0
  112. package/dist/casino/gaming/__tests__/game-bulk.router.int.test.js.map +1 -0
  113. package/dist/casino/gaming/__tests__/game-catalog-reader.service.int.test.d.ts +2 -0
  114. package/dist/casino/gaming/__tests__/game-catalog-reader.service.int.test.d.ts.map +1 -0
  115. package/dist/casino/gaming/__tests__/game-catalog-reader.service.int.test.js +294 -0
  116. package/dist/casino/gaming/__tests__/game-catalog-reader.service.int.test.js.map +1 -0
  117. package/dist/casino/gaming/__tests__/game-category.service.int.test.d.ts +2 -0
  118. package/dist/casino/gaming/__tests__/game-category.service.int.test.d.ts.map +1 -0
  119. package/dist/casino/gaming/__tests__/game-category.service.int.test.js +134 -0
  120. package/dist/casino/gaming/__tests__/game-category.service.int.test.js.map +1 -0
  121. package/dist/casino/gaming/__tests__/game-provider.service.int.test.d.ts +2 -0
  122. package/dist/casino/gaming/__tests__/game-provider.service.int.test.d.ts.map +1 -0
  123. package/dist/casino/gaming/__tests__/game-provider.service.int.test.js +274 -0
  124. package/dist/casino/gaming/__tests__/game-provider.service.int.test.js.map +1 -0
  125. package/dist/casino/gaming/__tests__/game-tag.service.int.test.d.ts +2 -0
  126. package/dist/casino/gaming/__tests__/game-tag.service.int.test.d.ts.map +1 -0
  127. package/dist/casino/gaming/__tests__/game-tag.service.int.test.js +143 -0
  128. package/dist/casino/gaming/__tests__/game-tag.service.int.test.js.map +1 -0
  129. package/dist/casino/gaming/__tests__/gaming-catalog-admin.router.int.test.d.ts +2 -0
  130. package/dist/casino/gaming/__tests__/gaming-catalog-admin.router.int.test.d.ts.map +1 -0
  131. package/dist/casino/gaming/__tests__/gaming-catalog-admin.router.int.test.js +332 -0
  132. package/dist/casino/gaming/__tests__/gaming-catalog-admin.router.int.test.js.map +1 -0
  133. package/dist/casino/gaming/__tests__/gaming-migration.int.test.d.ts +2 -0
  134. package/dist/casino/gaming/__tests__/gaming-migration.int.test.d.ts.map +1 -0
  135. package/dist/casino/gaming/__tests__/gaming-migration.int.test.js +166 -0
  136. package/dist/casino/gaming/__tests__/gaming-migration.int.test.js.map +1 -0
  137. package/dist/casino/gaming/__tests__/gaming.service.int.test.d.ts +2 -0
  138. package/dist/casino/gaming/__tests__/gaming.service.int.test.d.ts.map +1 -0
  139. package/dist/casino/gaming/__tests__/gaming.service.int.test.js +861 -0
  140. package/dist/casino/gaming/__tests__/gaming.service.int.test.js.map +1 -0
  141. package/dist/casino/gaming/adapters/game-catalog-reader.service.d.ts +68 -0
  142. package/dist/casino/gaming/adapters/game-catalog-reader.service.d.ts.map +1 -0
  143. package/dist/casino/gaming/adapters/game-catalog-reader.service.js +143 -0
  144. package/dist/casino/gaming/adapters/game-catalog-reader.service.js.map +1 -0
  145. package/dist/casino/gaming/adapters/mock/mock-game-adapter.d.ts.map +1 -1
  146. package/dist/casino/gaming/adapters/mock/mock-game-adapter.js +3 -1
  147. package/dist/casino/gaming/adapters/mock/mock-game-adapter.js.map +1 -1
  148. package/dist/casino/gaming/admin-reporting.d.ts +10 -0
  149. package/dist/casino/gaming/admin-reporting.d.ts.map +1 -0
  150. package/dist/casino/gaming/admin-reporting.js +143 -0
  151. package/dist/casino/gaming/admin-reporting.js.map +1 -0
  152. package/dist/casino/gaming/contract/index.d.ts +903 -15
  153. package/dist/casino/gaming/contract/index.d.ts.map +1 -1
  154. package/dist/casino/gaming/contract/index.js +286 -5
  155. package/dist/casino/gaming/contract/index.js.map +1 -1
  156. package/dist/casino/gaming/drizzle/migrations/0002_yummy_lifeguard.sql +4 -0
  157. package/dist/casino/gaming/drizzle/migrations/0003_wealthy_greymalkin.sql +2 -0
  158. package/dist/casino/gaming/drizzle/migrations/0004_serious_storm.sql +4 -0
  159. package/dist/casino/gaming/drizzle/migrations/0005_natural_thunderbolt_ross.sql +223 -0
  160. package/dist/casino/gaming/drizzle/migrations/0006_young_wrecker.sql +25 -0
  161. package/dist/casino/gaming/drizzle/migrations/0007_flowery_toad.sql +1 -0
  162. package/dist/casino/gaming/drizzle/migrations/meta/0002_snapshot.json +237 -0
  163. package/dist/casino/gaming/drizzle/migrations/meta/0003_snapshot.json +259 -0
  164. package/dist/casino/gaming/drizzle/migrations/meta/0004_snapshot.json +259 -0
  165. package/dist/casino/gaming/drizzle/migrations/meta/0005_snapshot.json +680 -0
  166. package/dist/casino/gaming/drizzle/migrations/meta/0006_snapshot.json +885 -0
  167. package/dist/casino/gaming/drizzle/migrations/meta/0007_snapshot.json +892 -0
  168. package/dist/casino/gaming/drizzle/migrations/meta/_journal.json +42 -0
  169. package/dist/casino/gaming/plugin.d.ts +188 -1
  170. package/dist/casino/gaming/plugin.d.ts.map +1 -1
  171. package/dist/casino/gaming/plugin.js +29 -5
  172. package/dist/casino/gaming/plugin.js.map +1 -1
  173. package/dist/casino/gaming/router/index.d.ts +604 -14
  174. package/dist/casino/gaming/router/index.d.ts.map +1 -1
  175. package/dist/casino/gaming/router/index.js +114 -7
  176. package/dist/casino/gaming/router/index.js.map +1 -1
  177. package/dist/casino/gaming/schema/index.d.ts +769 -32
  178. package/dist/casino/gaming/schema/index.d.ts.map +1 -1
  179. package/dist/casino/gaming/schema/index.js +119 -8
  180. package/dist/casino/gaming/schema/index.js.map +1 -1
  181. package/dist/casino/gaming/service/game-bulk.service.d.ts +54 -0
  182. package/dist/casino/gaming/service/game-bulk.service.d.ts.map +1 -0
  183. package/dist/casino/gaming/service/game-bulk.service.js +338 -0
  184. package/dist/casino/gaming/service/game-bulk.service.js.map +1 -0
  185. package/dist/casino/gaming/service/game-category.service.d.ts +105 -0
  186. package/dist/casino/gaming/service/game-category.service.d.ts.map +1 -0
  187. package/dist/casino/gaming/service/game-category.service.js +169 -0
  188. package/dist/casino/gaming/service/game-category.service.js.map +1 -0
  189. package/dist/casino/gaming/service/game-provider.service.d.ts +126 -0
  190. package/dist/casino/gaming/service/game-provider.service.d.ts.map +1 -0
  191. package/dist/casino/gaming/service/game-provider.service.js +246 -0
  192. package/dist/casino/gaming/service/game-provider.service.js.map +1 -0
  193. package/dist/casino/gaming/service/game-tag.service.d.ts +63 -0
  194. package/dist/casino/gaming/service/game-tag.service.d.ts.map +1 -0
  195. package/dist/casino/gaming/service/game-tag.service.js +140 -0
  196. package/dist/casino/gaming/service/game-tag.service.js.map +1 -0
  197. package/dist/casino/gaming/service/gaming.service.d.ts +233 -19
  198. package/dist/casino/gaming/service/gaming.service.d.ts.map +1 -1
  199. package/dist/casino/gaming/service/gaming.service.js +463 -41
  200. package/dist/casino/gaming/service/gaming.service.js.map +1 -1
  201. package/dist/casino/lobby/__tests__/lobby-contract.test.d.ts +2 -0
  202. package/dist/casino/lobby/__tests__/lobby-contract.test.d.ts.map +1 -0
  203. package/dist/casino/lobby/__tests__/lobby-contract.test.js +39 -0
  204. package/dist/casino/lobby/__tests__/lobby-contract.test.js.map +1 -0
  205. package/dist/casino/lobby/__tests__/lobby-layout.int.test.d.ts +2 -0
  206. package/dist/casino/lobby/__tests__/lobby-layout.int.test.d.ts.map +1 -0
  207. package/dist/casino/lobby/__tests__/lobby-layout.int.test.js +145 -0
  208. package/dist/casino/lobby/__tests__/lobby-layout.int.test.js.map +1 -0
  209. package/dist/casino/lobby/__tests__/lobby.cache.int.test.d.ts +2 -0
  210. package/dist/casino/lobby/__tests__/lobby.cache.int.test.d.ts.map +1 -0
  211. package/dist/casino/lobby/__tests__/lobby.cache.int.test.js +249 -0
  212. package/dist/casino/lobby/__tests__/lobby.cache.int.test.js.map +1 -0
  213. package/dist/casino/lobby/contract/index.d.ts +204 -8
  214. package/dist/casino/lobby/contract/index.d.ts.map +1 -1
  215. package/dist/casino/lobby/contract/index.js +42 -3
  216. package/dist/casino/lobby/contract/index.js.map +1 -1
  217. package/dist/casino/lobby/drizzle/migrations/0001_true_clea.sql +20 -0
  218. package/dist/casino/lobby/drizzle/migrations/meta/0001_snapshot.json +343 -0
  219. package/dist/casino/lobby/drizzle/migrations/meta/_journal.json +7 -0
  220. package/dist/casino/lobby/plugin.d.ts +186 -1
  221. package/dist/casino/lobby/plugin.d.ts.map +1 -1
  222. package/dist/casino/lobby/plugin.js +9 -5
  223. package/dist/casino/lobby/plugin.js.map +1 -1
  224. package/dist/casino/lobby/router/index.d.ts +102 -6
  225. package/dist/casino/lobby/router/index.d.ts.map +1 -1
  226. package/dist/casino/lobby/router/index.js +13 -2
  227. package/dist/casino/lobby/router/index.js.map +1 -1
  228. package/dist/casino/lobby/schema/index.d.ts +222 -0
  229. package/dist/casino/lobby/schema/index.d.ts.map +1 -1
  230. package/dist/casino/lobby/schema/index.js +21 -1
  231. package/dist/casino/lobby/schema/index.js.map +1 -1
  232. package/dist/casino/lobby/service/lobby.service.d.ts +87 -8
  233. package/dist/casino/lobby/service/lobby.service.d.ts.map +1 -1
  234. package/dist/casino/lobby/service/lobby.service.js +328 -38
  235. package/dist/casino/lobby/service/lobby.service.js.map +1 -1
  236. package/dist/casino/server.d.ts +1 -0
  237. package/dist/casino/server.d.ts.map +1 -1
  238. package/dist/casino/server.js +1 -0
  239. package/dist/casino/server.js.map +1 -1
  240. package/dist/casino/shared/game-catalog.d.ts +235 -0
  241. package/dist/casino/shared/game-catalog.d.ts.map +1 -0
  242. package/dist/casino/shared/game-catalog.js +105 -0
  243. package/dist/casino/shared/game-catalog.js.map +1 -0
  244. package/dist/cms/__tests__/cms.reads.int.test.d.ts +2 -0
  245. package/dist/cms/__tests__/cms.reads.int.test.d.ts.map +1 -0
  246. package/dist/cms/__tests__/cms.reads.int.test.js +119 -0
  247. package/dist/cms/__tests__/cms.reads.int.test.js.map +1 -0
  248. package/dist/cms/__tests__/cms.router.int.test.d.ts +2 -0
  249. package/dist/cms/__tests__/cms.router.int.test.d.ts.map +1 -0
  250. package/dist/cms/__tests__/cms.router.int.test.js +369 -0
  251. package/dist/cms/__tests__/cms.router.int.test.js.map +1 -0
  252. package/dist/cms/__tests__/cms.service.int.test.d.ts +2 -0
  253. package/dist/cms/__tests__/cms.service.int.test.d.ts.map +1 -0
  254. package/dist/cms/__tests__/cms.service.int.test.js +951 -0
  255. package/dist/cms/__tests__/cms.service.int.test.js.map +1 -0
  256. package/dist/cms/contract/index.d.ts +413 -42
  257. package/dist/cms/contract/index.d.ts.map +1 -1
  258. package/dist/cms/contract/index.js +161 -35
  259. package/dist/cms/contract/index.js.map +1 -1
  260. package/dist/cms/drizzle/migrations/0001_steep_starjammers.sql +29 -0
  261. package/dist/cms/drizzle/migrations/0002_naive_kingpin.sql +14 -0
  262. package/dist/cms/drizzle/migrations/0003_worthless_titanium_man.sql +2 -0
  263. package/dist/cms/drizzle/migrations/0004_milky_living_lightning.sql +1 -0
  264. package/dist/cms/drizzle/migrations/meta/0001_snapshot.json +303 -0
  265. package/dist/cms/drizzle/migrations/meta/0002_snapshot.json +412 -0
  266. package/dist/cms/drizzle/migrations/meta/0003_snapshot.json +442 -0
  267. package/dist/cms/drizzle/migrations/meta/0004_snapshot.json +457 -0
  268. package/dist/cms/drizzle/migrations/meta/_journal.json +28 -0
  269. package/dist/cms/moderation/validate-banner-image-url.d.ts +8 -0
  270. package/dist/cms/moderation/validate-banner-image-url.d.ts.map +1 -0
  271. package/dist/cms/moderation/validate-banner-image-url.js +20 -0
  272. package/dist/cms/moderation/validate-banner-image-url.js.map +1 -0
  273. package/dist/cms/plugin.d.ts +186 -1
  274. package/dist/cms/plugin.d.ts.map +1 -1
  275. package/dist/cms/plugin.js +5 -5
  276. package/dist/cms/plugin.js.map +1 -1
  277. package/dist/cms/router/index.d.ts +219 -37
  278. package/dist/cms/router/index.d.ts.map +1 -1
  279. package/dist/cms/router/index.js +83 -21
  280. package/dist/cms/router/index.js.map +1 -1
  281. package/dist/cms/schema/index.d.ts +283 -28
  282. package/dist/cms/schema/index.d.ts.map +1 -1
  283. package/dist/cms/schema/index.js +58 -7
  284. package/dist/cms/schema/index.js.map +1 -1
  285. package/dist/cms/server.d.ts +1 -1
  286. package/dist/cms/server.d.ts.map +1 -1
  287. package/dist/cms/server.js +1 -1
  288. package/dist/cms/server.js.map +1 -1
  289. package/dist/cms/service/cms.service.d.ts +235 -45
  290. package/dist/cms/service/cms.service.d.ts.map +1 -1
  291. package/dist/cms/service/cms.service.js +722 -67
  292. package/dist/cms/service/cms.service.js.map +1 -1
  293. package/dist/common/errors/__tests__/errors.mapper.test.d.ts +2 -0
  294. package/dist/common/errors/__tests__/errors.mapper.test.d.ts.map +1 -0
  295. package/dist/common/errors/__tests__/errors.mapper.test.js +59 -0
  296. package/dist/common/errors/__tests__/errors.mapper.test.js.map +1 -0
  297. package/dist/common/errors/errors.classes.js +3 -3
  298. package/dist/common/errors/errors.classes.js.map +1 -1
  299. package/dist/common/errors/errors.mapper.js +1 -1
  300. package/dist/common/errors/errors.mapper.js.map +1 -1
  301. package/dist/compliance/__tests__/assert.test.d.ts +2 -0
  302. package/dist/compliance/__tests__/assert.test.d.ts.map +1 -0
  303. package/dist/compliance/__tests__/assert.test.js +34 -0
  304. package/dist/compliance/__tests__/assert.test.js.map +1 -0
  305. package/dist/compliance/__tests__/compliance.service.int.test.d.ts +2 -0
  306. package/dist/compliance/__tests__/compliance.service.int.test.d.ts.map +1 -0
  307. package/dist/compliance/__tests__/compliance.service.int.test.js +602 -0
  308. package/dist/compliance/__tests__/compliance.service.int.test.js.map +1 -0
  309. package/dist/compliance/__tests__/hmac-kyc-webhook-verifier.int.test.d.ts +2 -0
  310. package/dist/compliance/__tests__/hmac-kyc-webhook-verifier.int.test.d.ts.map +1 -0
  311. package/dist/compliance/__tests__/hmac-kyc-webhook-verifier.int.test.js +82 -0
  312. package/dist/compliance/__tests__/hmac-kyc-webhook-verifier.int.test.js.map +1 -0
  313. package/dist/compliance/__tests__/kyc-admin.router.int.test.d.ts +2 -0
  314. package/dist/compliance/__tests__/kyc-admin.router.int.test.d.ts.map +1 -0
  315. package/dist/compliance/__tests__/kyc-admin.router.int.test.js +198 -0
  316. package/dist/compliance/__tests__/kyc-admin.router.int.test.js.map +1 -0
  317. package/dist/compliance/__tests__/kyc-webhook.router.int.test.d.ts +2 -0
  318. package/dist/compliance/__tests__/kyc-webhook.router.int.test.d.ts.map +1 -0
  319. package/dist/compliance/__tests__/kyc-webhook.router.int.test.js +177 -0
  320. package/dist/compliance/__tests__/kyc-webhook.router.int.test.js.map +1 -0
  321. package/dist/compliance/__tests__/kyc.service.int.test.d.ts +2 -0
  322. package/dist/compliance/__tests__/kyc.service.int.test.d.ts.map +1 -0
  323. package/dist/compliance/__tests__/kyc.service.int.test.js +397 -0
  324. package/dist/compliance/__tests__/kyc.service.int.test.js.map +1 -0
  325. package/dist/compliance/__tests__/limits.contract.test.d.ts +2 -0
  326. package/dist/compliance/__tests__/limits.contract.test.d.ts.map +1 -0
  327. package/dist/compliance/__tests__/limits.contract.test.js +83 -0
  328. package/dist/compliance/__tests__/limits.contract.test.js.map +1 -0
  329. package/dist/compliance/__tests__/regulatory-overview.router.int.test.d.ts +2 -0
  330. package/dist/compliance/__tests__/regulatory-overview.router.int.test.d.ts.map +1 -0
  331. package/dist/compliance/__tests__/regulatory-overview.router.int.test.js +102 -0
  332. package/dist/compliance/__tests__/regulatory-overview.router.int.test.js.map +1 -0
  333. package/dist/compliance/__tests__/rg-eval.test.js +28 -1
  334. package/dist/compliance/__tests__/rg-eval.test.js.map +1 -1
  335. package/dist/compliance/__tests__/rg-monitoring.service.int.test.d.ts +2 -0
  336. package/dist/compliance/__tests__/rg-monitoring.service.int.test.d.ts.map +1 -0
  337. package/dist/compliance/__tests__/rg-monitoring.service.int.test.js +526 -0
  338. package/dist/compliance/__tests__/rg-monitoring.service.int.test.js.map +1 -0
  339. package/dist/compliance/__tests__/rg-self-service.int.test.d.ts +2 -0
  340. package/dist/compliance/__tests__/rg-self-service.int.test.d.ts.map +1 -0
  341. package/dist/compliance/__tests__/rg-self-service.int.test.js +539 -0
  342. package/dist/compliance/__tests__/rg-self-service.int.test.js.map +1 -0
  343. package/dist/compliance/__tests__/rg.contract.test.js +60 -20
  344. package/dist/compliance/__tests__/rg.contract.test.js.map +1 -1
  345. package/dist/compliance/__tests__/rg.router.int.test.d.ts +2 -0
  346. package/dist/compliance/__tests__/rg.router.int.test.d.ts.map +1 -0
  347. package/dist/compliance/__tests__/rg.router.int.test.js +325 -0
  348. package/dist/compliance/__tests__/rg.router.int.test.js.map +1 -0
  349. package/dist/compliance/__tests__/rg.service.int.test.d.ts +2 -0
  350. package/dist/compliance/__tests__/rg.service.int.test.d.ts.map +1 -0
  351. package/dist/compliance/__tests__/rg.service.int.test.js +747 -0
  352. package/dist/compliance/__tests__/rg.service.int.test.js.map +1 -0
  353. package/dist/compliance/adapters/hmac-kyc-webhook-verifier.d.ts +16 -3
  354. package/dist/compliance/adapters/hmac-kyc-webhook-verifier.d.ts.map +1 -1
  355. package/dist/compliance/adapters/hmac-kyc-webhook-verifier.js +47 -5
  356. package/dist/compliance/adapters/hmac-kyc-webhook-verifier.js.map +1 -1
  357. package/dist/compliance/adapters/rg-limit-gate.d.ts +17 -0
  358. package/dist/compliance/adapters/rg-limit-gate.d.ts.map +1 -0
  359. package/dist/compliance/adapters/rg-limit-gate.js +107 -0
  360. package/dist/compliance/adapters/rg-limit-gate.js.map +1 -0
  361. package/dist/compliance/contract/index.d.ts +1530 -124
  362. package/dist/compliance/contract/index.d.ts.map +1 -1
  363. package/dist/compliance/contract/index.js +215 -9
  364. package/dist/compliance/contract/index.js.map +1 -1
  365. package/dist/compliance/contract/limits.d.ts +52 -0
  366. package/dist/compliance/contract/limits.d.ts.map +1 -1
  367. package/dist/compliance/contract/limits.js +27 -7
  368. package/dist/compliance/contract/limits.js.map +1 -1
  369. package/dist/compliance/contract/rg.d.ts +337 -7
  370. package/dist/compliance/contract/rg.d.ts.map +1 -1
  371. package/dist/compliance/contract/rg.js +61 -15
  372. package/dist/compliance/contract/rg.js.map +1 -1
  373. package/dist/compliance/drizzle/migrations/0002_condemned_monster_badoon.sql +3 -0
  374. package/dist/compliance/drizzle/migrations/0003_public_spirit.sql +1 -0
  375. package/dist/compliance/drizzle/migrations/0004_military_silk_fever.sql +2 -0
  376. package/dist/compliance/drizzle/migrations/0005_reflective_magma.sql +13 -0
  377. package/dist/compliance/drizzle/migrations/0006_backfill_session_limit_currency.sql +15 -0
  378. package/dist/compliance/drizzle/migrations/0007_romantic_toxin.sql +6 -0
  379. package/dist/compliance/drizzle/migrations/0008_omniscient_northstar.sql +14 -0
  380. package/dist/compliance/drizzle/migrations/0009_living_felicia_hardy.sql +12 -0
  381. package/dist/compliance/drizzle/migrations/0010_same_the_twelve.sql +12 -0
  382. package/dist/compliance/drizzle/migrations/meta/0002_snapshot.json +673 -0
  383. package/dist/compliance/drizzle/migrations/meta/0003_snapshot.json +679 -0
  384. package/dist/compliance/drizzle/migrations/meta/0004_snapshot.json +679 -0
  385. package/dist/compliance/drizzle/migrations/meta/0005_snapshot.json +754 -0
  386. package/dist/compliance/drizzle/migrations/meta/0006_snapshot.json +754 -0
  387. package/dist/compliance/drizzle/migrations/meta/0007_snapshot.json +785 -0
  388. package/dist/compliance/drizzle/migrations/meta/0008_snapshot.json +870 -0
  389. package/dist/compliance/drizzle/migrations/meta/0009_snapshot.json +974 -0
  390. package/dist/compliance/drizzle/migrations/meta/0010_snapshot.json +1078 -0
  391. package/dist/compliance/drizzle/migrations/meta/_journal.json +63 -0
  392. package/dist/compliance/plugin.d.ts +189 -1
  393. package/dist/compliance/plugin.d.ts.map +1 -1
  394. package/dist/compliance/plugin.js +86 -14
  395. package/dist/compliance/plugin.js.map +1 -1
  396. package/dist/compliance/router/index.d.ts +971 -61
  397. package/dist/compliance/router/index.d.ts.map +1 -1
  398. package/dist/compliance/router/index.js +160 -25
  399. package/dist/compliance/router/index.js.map +1 -1
  400. package/dist/compliance/schema/index.d.ts +638 -19
  401. package/dist/compliance/schema/index.d.ts.map +1 -1
  402. package/dist/compliance/schema/index.js +83 -6
  403. package/dist/compliance/schema/index.js.map +1 -1
  404. package/dist/compliance/server.d.ts +1 -1
  405. package/dist/compliance/server.d.ts.map +1 -1
  406. package/dist/compliance/server.js +1 -1
  407. package/dist/compliance/server.js.map +1 -1
  408. package/dist/compliance/service/compliance.service.d.ts +169 -37
  409. package/dist/compliance/service/compliance.service.d.ts.map +1 -1
  410. package/dist/compliance/service/compliance.service.js +475 -55
  411. package/dist/compliance/service/compliance.service.js.map +1 -1
  412. package/dist/compliance/service/kyc.service.d.ts +228 -10
  413. package/dist/compliance/service/kyc.service.d.ts.map +1 -1
  414. package/dist/compliance/service/kyc.service.js +566 -62
  415. package/dist/compliance/service/kyc.service.js.map +1 -1
  416. package/dist/compliance/service/rg-eval.d.ts +7 -2
  417. package/dist/compliance/service/rg-eval.d.ts.map +1 -1
  418. package/dist/compliance/service/rg-eval.js +10 -2
  419. package/dist/compliance/service/rg-eval.js.map +1 -1
  420. package/dist/compliance/service/rg-monitoring.service.d.ts +24 -6
  421. package/dist/compliance/service/rg-monitoring.service.d.ts.map +1 -1
  422. package/dist/compliance/service/rg-monitoring.service.js +109 -20
  423. package/dist/compliance/service/rg-monitoring.service.js.map +1 -1
  424. package/dist/compliance/service/rg-self-service.service.d.ts +84 -0
  425. package/dist/compliance/service/rg-self-service.service.d.ts.map +1 -0
  426. package/dist/compliance/service/rg-self-service.service.js +449 -0
  427. package/dist/compliance/service/rg-self-service.service.js.map +1 -0
  428. package/dist/compliance/service/rg.service.d.ts +103 -15
  429. package/dist/compliance/service/rg.service.d.ts.map +1 -1
  430. package/dist/compliance/service/rg.service.js +331 -61
  431. package/dist/compliance/service/rg.service.js.map +1 -1
  432. package/dist/contracts/__tests__/compose-contract.test.d.ts +2 -0
  433. package/dist/contracts/__tests__/compose-contract.test.d.ts.map +1 -0
  434. package/dist/contracts/__tests__/compose-contract.test.js +27 -0
  435. package/dist/contracts/__tests__/compose-contract.test.js.map +1 -0
  436. package/dist/contracts/__tests__/identity.test.d.ts +2 -0
  437. package/dist/contracts/__tests__/identity.test.d.ts.map +1 -0
  438. package/dist/contracts/__tests__/identity.test.js +54 -0
  439. package/dist/contracts/__tests__/identity.test.js.map +1 -0
  440. package/dist/contracts/__tests__/kit.test.js +21 -1
  441. package/dist/contracts/__tests__/kit.test.js.map +1 -1
  442. package/dist/contracts/__tests__/player.test.d.ts +2 -0
  443. package/dist/contracts/__tests__/player.test.d.ts.map +1 -0
  444. package/dist/contracts/__tests__/player.test.js +51 -0
  445. package/dist/contracts/__tests__/player.test.js.map +1 -0
  446. package/dist/contracts/adapters/__tests__/geo-ip.test.d.ts +2 -0
  447. package/dist/contracts/adapters/__tests__/geo-ip.test.d.ts.map +1 -0
  448. package/dist/contracts/adapters/__tests__/geo-ip.test.js +13 -0
  449. package/dist/contracts/adapters/__tests__/geo-ip.test.js.map +1 -0
  450. package/dist/contracts/adapters/__tests__/lobby-section-catalog.test.d.ts +2 -0
  451. package/dist/contracts/adapters/__tests__/lobby-section-catalog.test.d.ts.map +1 -0
  452. package/dist/contracts/adapters/__tests__/lobby-section-catalog.test.js +25 -0
  453. package/dist/contracts/adapters/__tests__/lobby-section-catalog.test.js.map +1 -0
  454. package/dist/contracts/adapters/__tests__/rate-limit.test.d.ts +2 -0
  455. package/dist/contracts/adapters/__tests__/rate-limit.test.d.ts.map +1 -0
  456. package/dist/contracts/adapters/__tests__/rate-limit.test.js +13 -0
  457. package/dist/contracts/adapters/__tests__/rate-limit.test.js.map +1 -0
  458. package/dist/contracts/adapters/__tests__/token.test.d.ts +2 -0
  459. package/dist/contracts/adapters/__tests__/token.test.d.ts.map +1 -0
  460. package/dist/contracts/adapters/__tests__/token.test.js +14 -0
  461. package/dist/contracts/adapters/__tests__/token.test.js.map +1 -0
  462. package/dist/contracts/adapters/admin-game-reporting.d.ts +74 -0
  463. package/dist/contracts/adapters/admin-game-reporting.d.ts.map +1 -0
  464. package/dist/contracts/adapters/admin-game-reporting.js +17 -0
  465. package/dist/contracts/adapters/admin-game-reporting.js.map +1 -0
  466. package/dist/contracts/adapters/admin-permission.d.ts +11 -0
  467. package/dist/contracts/adapters/admin-permission.d.ts.map +1 -1
  468. package/dist/contracts/adapters/admin-permission.js +6 -4
  469. package/dist/contracts/adapters/admin-permission.js.map +1 -1
  470. package/dist/contracts/adapters/admin-player-activity.d.ts +51 -0
  471. package/dist/contracts/adapters/admin-player-activity.d.ts.map +1 -0
  472. package/dist/contracts/adapters/admin-player-activity.js +3 -0
  473. package/dist/contracts/adapters/admin-player-activity.js.map +1 -0
  474. package/dist/contracts/adapters/admin-role-assignment-directory.d.ts +12 -0
  475. package/dist/contracts/adapters/admin-role-assignment-directory.d.ts.map +1 -0
  476. package/dist/contracts/adapters/admin-role-assignment-directory.js +3 -0
  477. package/dist/contracts/adapters/admin-role-assignment-directory.js.map +1 -0
  478. package/dist/contracts/adapters/admin-security.d.ts +27 -0
  479. package/dist/contracts/adapters/admin-security.d.ts.map +1 -0
  480. package/dist/contracts/adapters/admin-security.js +9 -0
  481. package/dist/contracts/adapters/admin-security.js.map +1 -0
  482. package/dist/contracts/adapters/admin-user-directory.d.ts +52 -4
  483. package/dist/contracts/adapters/admin-user-directory.d.ts.map +1 -1
  484. package/dist/contracts/adapters/admin-user-directory.js +8 -0
  485. package/dist/contracts/adapters/admin-user-directory.js.map +1 -1
  486. package/dist/contracts/adapters/admin-wallet-reporting.d.ts +11 -0
  487. package/dist/contracts/adapters/admin-wallet-reporting.d.ts.map +1 -1
  488. package/dist/contracts/adapters/admin-wallet-reporting.js +9 -0
  489. package/dist/contracts/adapters/admin-wallet-reporting.js.map +1 -1
  490. package/dist/contracts/adapters/aggregator.d.ts +12 -0
  491. package/dist/contracts/adapters/aggregator.d.ts.map +1 -1
  492. package/dist/contracts/adapters/aggregator.js +5 -3
  493. package/dist/contracts/adapters/aggregator.js.map +1 -1
  494. package/dist/contracts/adapters/audit.d.ts +30 -4
  495. package/dist/contracts/adapters/audit.d.ts.map +1 -1
  496. package/dist/contracts/adapters/audit.js.map +1 -1
  497. package/dist/contracts/adapters/broker.d.ts +23 -0
  498. package/dist/contracts/adapters/broker.d.ts.map +1 -1
  499. package/dist/contracts/adapters/broker.js +8 -6
  500. package/dist/contracts/adapters/broker.js.map +1 -1
  501. package/dist/contracts/adapters/cache.d.ts +11 -0
  502. package/dist/contracts/adapters/cache.d.ts.map +1 -1
  503. package/dist/contracts/adapters/cache.js +8 -6
  504. package/dist/contracts/adapters/cache.js.map +1 -1
  505. package/dist/contracts/adapters/chat-block-writer.d.ts +18 -0
  506. package/dist/contracts/adapters/chat-block-writer.d.ts.map +1 -0
  507. package/dist/contracts/adapters/chat-block-writer.js +7 -0
  508. package/dist/contracts/adapters/chat-block-writer.js.map +1 -0
  509. package/dist/contracts/adapters/chat-moderation.d.ts +75 -0
  510. package/dist/contracts/adapters/chat-moderation.d.ts.map +1 -0
  511. package/dist/contracts/adapters/chat-moderation.js +3 -0
  512. package/dist/contracts/adapters/chat-moderation.js.map +1 -0
  513. package/dist/contracts/adapters/chat-room-access.d.ts +6 -0
  514. package/dist/contracts/adapters/chat-room-access.d.ts.map +1 -0
  515. package/dist/contracts/adapters/chat-room-access.js +3 -0
  516. package/dist/contracts/adapters/chat-room-access.js.map +1 -0
  517. package/dist/contracts/adapters/chat-system-writer.d.ts +19 -0
  518. package/dist/contracts/adapters/chat-system-writer.d.ts.map +1 -0
  519. package/dist/contracts/adapters/chat-system-writer.js +3 -0
  520. package/dist/contracts/adapters/chat-system-writer.js.map +1 -0
  521. package/dist/contracts/adapters/email-template.d.ts +12 -0
  522. package/dist/contracts/adapters/email-template.d.ts.map +1 -0
  523. package/dist/contracts/adapters/email-template.js +3 -0
  524. package/dist/contracts/adapters/email-template.js.map +1 -0
  525. package/dist/contracts/adapters/error-tracking.d.ts +12 -0
  526. package/dist/contracts/adapters/error-tracking.d.ts.map +1 -0
  527. package/dist/contracts/adapters/error-tracking.js +3 -0
  528. package/dist/contracts/adapters/error-tracking.js.map +1 -0
  529. package/dist/contracts/adapters/exchange-rate-provider.d.ts +14 -0
  530. package/dist/contracts/adapters/exchange-rate-provider.d.ts.map +1 -0
  531. package/dist/contracts/adapters/exchange-rate-provider.js +5 -0
  532. package/dist/contracts/adapters/exchange-rate-provider.js.map +1 -0
  533. package/dist/contracts/adapters/exchange-rate-reader.d.ts +16 -0
  534. package/dist/contracts/adapters/exchange-rate-reader.d.ts.map +1 -0
  535. package/dist/contracts/adapters/exchange-rate-reader.js +3 -0
  536. package/dist/contracts/adapters/exchange-rate-reader.js.map +1 -0
  537. package/dist/contracts/adapters/game-catalog-reader.d.ts +41 -0
  538. package/dist/contracts/adapters/game-catalog-reader.d.ts.map +1 -0
  539. package/dist/contracts/adapters/game-catalog-reader.js +11 -0
  540. package/dist/contracts/adapters/game-catalog-reader.js.map +1 -0
  541. package/dist/contracts/adapters/game-geo-check.d.ts +37 -0
  542. package/dist/contracts/adapters/game-geo-check.d.ts.map +1 -0
  543. package/dist/contracts/adapters/game-geo-check.js +29 -0
  544. package/dist/contracts/adapters/game-geo-check.js.map +1 -0
  545. package/dist/contracts/adapters/game.d.ts +13 -1
  546. package/dist/contracts/adapters/game.d.ts.map +1 -1
  547. package/dist/contracts/adapters/game.js +4 -2
  548. package/dist/contracts/adapters/game.js.map +1 -1
  549. package/dist/contracts/adapters/gaming-commands.d.ts +36 -0
  550. package/dist/contracts/adapters/gaming-commands.d.ts.map +1 -0
  551. package/dist/contracts/adapters/gaming-commands.js +8 -0
  552. package/dist/contracts/adapters/gaming-commands.js.map +1 -0
  553. package/dist/contracts/adapters/geo-check-commands.d.ts +8 -0
  554. package/dist/contracts/adapters/geo-check-commands.d.ts.map +1 -0
  555. package/dist/contracts/adapters/geo-check-commands.js +3 -0
  556. package/dist/contracts/adapters/geo-check-commands.js.map +1 -0
  557. package/dist/contracts/adapters/geo-ip.d.ts +2 -0
  558. package/dist/contracts/adapters/geo-ip.d.ts.map +1 -1
  559. package/dist/contracts/adapters/geo-ip.js +13 -2
  560. package/dist/contracts/adapters/geo-ip.js.map +1 -1
  561. package/dist/contracts/adapters/identity-reader.d.ts +20 -4
  562. package/dist/contracts/adapters/identity-reader.d.ts.map +1 -1
  563. package/dist/contracts/adapters/identity-reader.js.map +1 -1
  564. package/dist/contracts/adapters/identity.d.ts +32 -0
  565. package/dist/contracts/adapters/identity.d.ts.map +1 -1
  566. package/dist/contracts/adapters/identity.js +5 -2
  567. package/dist/contracts/adapters/identity.js.map +1 -1
  568. package/dist/contracts/adapters/index.d.ts +82 -22
  569. package/dist/contracts/adapters/index.d.ts.map +1 -1
  570. package/dist/contracts/adapters/index.js +43 -14
  571. package/dist/contracts/adapters/index.js.map +1 -1
  572. package/dist/contracts/adapters/job-queue.d.ts +55 -0
  573. package/dist/contracts/adapters/job-queue.d.ts.map +1 -1
  574. package/dist/contracts/adapters/job-queue.js +11 -9
  575. package/dist/contracts/adapters/job-queue.js.map +1 -1
  576. package/dist/contracts/adapters/kyc.d.ts +110 -11
  577. package/dist/contracts/adapters/kyc.d.ts.map +1 -1
  578. package/dist/contracts/adapters/kyc.js +23 -0
  579. package/dist/contracts/adapters/kyc.js.map +1 -1
  580. package/dist/contracts/adapters/lobby-section-catalog.d.ts +39 -0
  581. package/dist/contracts/adapters/lobby-section-catalog.d.ts.map +1 -0
  582. package/dist/contracts/adapters/lobby-section-catalog.js +34 -0
  583. package/dist/contracts/adapters/lobby-section-catalog.js.map +1 -0
  584. package/dist/contracts/adapters/login-enforcement.d.ts +8 -0
  585. package/dist/contracts/adapters/login-enforcement.d.ts.map +1 -1
  586. package/dist/contracts/adapters/login-enforcement.js +8 -6
  587. package/dist/contracts/adapters/login-enforcement.js.map +1 -1
  588. package/dist/contracts/adapters/mail-recipient-directory.d.ts +17 -0
  589. package/dist/contracts/adapters/mail-recipient-directory.d.ts.map +1 -0
  590. package/dist/contracts/adapters/mail-recipient-directory.js +3 -0
  591. package/dist/contracts/adapters/mail-recipient-directory.js.map +1 -0
  592. package/dist/contracts/adapters/mail.d.ts +32 -0
  593. package/dist/contracts/adapters/mail.d.ts.map +1 -0
  594. package/dist/contracts/adapters/mail.js +4 -0
  595. package/dist/contracts/adapters/mail.js.map +1 -0
  596. package/dist/contracts/adapters/outbox.d.ts +14 -0
  597. package/dist/contracts/adapters/outbox.d.ts.map +1 -1
  598. package/dist/contracts/adapters/outbox.js +14 -12
  599. package/dist/contracts/adapters/outbox.js.map +1 -1
  600. package/dist/contracts/adapters/payment.d.ts +165 -3
  601. package/dist/contracts/adapters/payment.d.ts.map +1 -1
  602. package/dist/contracts/adapters/payment.js +26 -3
  603. package/dist/contracts/adapters/payment.js.map +1 -1
  604. package/dist/contracts/adapters/play-eligibility.d.ts +15 -0
  605. package/dist/contracts/adapters/play-eligibility.d.ts.map +1 -0
  606. package/dist/contracts/adapters/play-eligibility.js +3 -0
  607. package/dist/contracts/adapters/play-eligibility.js.map +1 -0
  608. package/dist/contracts/adapters/player-activity.d.ts +6 -0
  609. package/dist/contracts/adapters/player-activity.d.ts.map +1 -0
  610. package/dist/contracts/adapters/player-activity.js +3 -0
  611. package/dist/contracts/adapters/player-activity.js.map +1 -0
  612. package/dist/contracts/adapters/player-provisioning.d.ts +29 -0
  613. package/dist/contracts/adapters/player-provisioning.d.ts.map +1 -0
  614. package/dist/contracts/adapters/player-provisioning.js +3 -0
  615. package/dist/contracts/adapters/player-provisioning.js.map +1 -0
  616. package/dist/contracts/adapters/player-tags.d.ts +4 -0
  617. package/dist/contracts/adapters/player-tags.d.ts.map +1 -1
  618. package/dist/contracts/adapters/player-tags.js.map +1 -1
  619. package/dist/contracts/adapters/rate-limit.d.ts +25 -0
  620. package/dist/contracts/adapters/rate-limit.d.ts.map +1 -1
  621. package/dist/contracts/adapters/rate-limit.js +19 -6
  622. package/dist/contracts/adapters/rate-limit.js.map +1 -1
  623. package/dist/contracts/adapters/realtime.d.ts +156 -7
  624. package/dist/contracts/adapters/realtime.d.ts.map +1 -1
  625. package/dist/contracts/adapters/realtime.js +33 -10
  626. package/dist/contracts/adapters/realtime.js.map +1 -1
  627. package/dist/contracts/adapters/rg-limits.d.ts +47 -0
  628. package/dist/contracts/adapters/rg-limits.d.ts.map +1 -0
  629. package/dist/contracts/adapters/rg-limits.js +18 -0
  630. package/dist/contracts/adapters/rg-limits.js.map +1 -0
  631. package/dist/contracts/adapters/rng.d.ts +11 -0
  632. package/dist/contracts/adapters/rng.d.ts.map +1 -1
  633. package/dist/contracts/adapters/rng.js +11 -9
  634. package/dist/contracts/adapters/rng.js.map +1 -1
  635. package/dist/contracts/adapters/session-idle-policy.d.ts +16 -0
  636. package/dist/contracts/adapters/session-idle-policy.d.ts.map +1 -0
  637. package/dist/contracts/adapters/session-idle-policy.js +13 -0
  638. package/dist/contracts/adapters/session-idle-policy.js.map +1 -0
  639. package/dist/contracts/adapters/sms.d.ts +15 -0
  640. package/dist/contracts/adapters/sms.d.ts.map +1 -0
  641. package/dist/contracts/adapters/sms.js +9 -0
  642. package/dist/contracts/adapters/sms.js.map +1 -0
  643. package/dist/contracts/adapters/social-commands.d.ts +12 -0
  644. package/dist/contracts/adapters/social-commands.d.ts.map +1 -0
  645. package/dist/contracts/adapters/social-commands.js +7 -0
  646. package/dist/contracts/adapters/social-commands.js.map +1 -0
  647. package/dist/contracts/adapters/swap.d.ts +80 -0
  648. package/dist/contracts/adapters/swap.d.ts.map +1 -0
  649. package/dist/contracts/adapters/swap.js +5 -0
  650. package/dist/contracts/adapters/swap.js.map +1 -0
  651. package/dist/contracts/adapters/tag-evaluation-commands.d.ts +20 -0
  652. package/dist/contracts/adapters/tag-evaluation-commands.d.ts.map +1 -0
  653. package/dist/contracts/adapters/tag-evaluation-commands.js +13 -0
  654. package/dist/contracts/adapters/tag-evaluation-commands.js.map +1 -0
  655. package/dist/contracts/adapters/token.d.ts +28 -5
  656. package/dist/contracts/adapters/token.d.ts.map +1 -1
  657. package/dist/contracts/adapters/token.js +10 -8
  658. package/dist/contracts/adapters/token.js.map +1 -1
  659. package/dist/contracts/adapters/wallet-asset-catalog.d.ts +34 -0
  660. package/dist/contracts/adapters/wallet-asset-catalog.d.ts.map +1 -0
  661. package/dist/contracts/adapters/wallet-asset-catalog.js +3 -0
  662. package/dist/contracts/adapters/wallet-asset-catalog.js.map +1 -0
  663. package/dist/contracts/adapters/wallet-commands.d.ts +25 -0
  664. package/dist/contracts/adapters/wallet-commands.d.ts.map +1 -1
  665. package/dist/contracts/adapters/wallet-commands.js.map +1 -1
  666. package/dist/contracts/adapters/wallet-reader.d.ts +43 -1
  667. package/dist/contracts/adapters/wallet-reader.d.ts.map +1 -1
  668. package/dist/contracts/adapters/wallet-reader.js.map +1 -1
  669. package/dist/contracts/kit.d.ts +18 -0
  670. package/dist/contracts/kit.d.ts.map +1 -1
  671. package/dist/contracts/kit.js +9 -0
  672. package/dist/contracts/kit.js.map +1 -1
  673. package/dist/contracts/schemas/__tests__/common-schemas.test.js +33 -4
  674. package/dist/contracts/schemas/__tests__/common-schemas.test.js.map +1 -1
  675. package/dist/contracts/schemas/__tests__/events.test.d.ts +2 -0
  676. package/dist/contracts/schemas/__tests__/events.test.d.ts.map +1 -0
  677. package/dist/contracts/schemas/__tests__/events.test.js +294 -0
  678. package/dist/contracts/schemas/__tests__/events.test.js.map +1 -0
  679. package/dist/contracts/schemas/__tests__/game-schemas.test.d.ts +2 -0
  680. package/dist/contracts/schemas/__tests__/game-schemas.test.d.ts.map +1 -0
  681. package/dist/contracts/schemas/__tests__/game-schemas.test.js +69 -0
  682. package/dist/contracts/schemas/__tests__/game-schemas.test.js.map +1 -0
  683. package/dist/contracts/schemas/__tests__/igaming-config.test.d.ts +2 -0
  684. package/dist/contracts/schemas/__tests__/igaming-config.test.d.ts.map +1 -0
  685. package/dist/contracts/schemas/__tests__/igaming-config.test.js +38 -0
  686. package/dist/contracts/schemas/__tests__/igaming-config.test.js.map +1 -0
  687. package/dist/contracts/schemas/__tests__/platform-config.test.d.ts +2 -0
  688. package/dist/contracts/schemas/__tests__/platform-config.test.d.ts.map +1 -0
  689. package/dist/contracts/schemas/__tests__/platform-config.test.js +16 -0
  690. package/dist/contracts/schemas/__tests__/platform-config.test.js.map +1 -0
  691. package/dist/contracts/schemas/__tests__/player-schemas.test.d.ts +2 -0
  692. package/dist/contracts/schemas/__tests__/player-schemas.test.d.ts.map +1 -0
  693. package/dist/contracts/schemas/__tests__/player-schemas.test.js +30 -0
  694. package/dist/contracts/schemas/__tests__/player-schemas.test.js.map +1 -0
  695. package/dist/contracts/schemas/__tests__/reporting-schemas.test.d.ts +2 -0
  696. package/dist/contracts/schemas/__tests__/reporting-schemas.test.d.ts.map +1 -0
  697. package/dist/contracts/schemas/__tests__/reporting-schemas.test.js +21 -0
  698. package/dist/contracts/schemas/__tests__/reporting-schemas.test.js.map +1 -0
  699. package/dist/contracts/schemas/__tests__/tag-schemas.test.d.ts +2 -0
  700. package/dist/contracts/schemas/__tests__/tag-schemas.test.d.ts.map +1 -0
  701. package/dist/contracts/schemas/__tests__/tag-schemas.test.js +42 -0
  702. package/dist/contracts/schemas/__tests__/tag-schemas.test.js.map +1 -0
  703. package/dist/contracts/schemas/chat-attachment.d.ts +20 -0
  704. package/dist/contracts/schemas/chat-attachment.d.ts.map +1 -0
  705. package/dist/contracts/schemas/chat-attachment.js +14 -0
  706. package/dist/contracts/schemas/chat-attachment.js.map +1 -0
  707. package/dist/contracts/schemas/chat-command-metadata.d.ts +73 -0
  708. package/dist/contracts/schemas/chat-command-metadata.d.ts.map +1 -0
  709. package/dist/contracts/schemas/chat-command-metadata.js +67 -0
  710. package/dist/contracts/schemas/chat-command-metadata.js.map +1 -0
  711. package/dist/contracts/schemas/chat-command.d.ts +224 -0
  712. package/dist/contracts/schemas/chat-command.d.ts.map +1 -0
  713. package/dist/contracts/schemas/chat-command.js +55 -0
  714. package/dist/contracts/schemas/chat-command.js.map +1 -0
  715. package/dist/contracts/schemas/common.d.ts +36 -0
  716. package/dist/contracts/schemas/common.d.ts.map +1 -1
  717. package/dist/contracts/schemas/common.js +67 -2
  718. package/dist/contracts/schemas/common.js.map +1 -1
  719. package/dist/contracts/schemas/compliance.d.ts +24 -1
  720. package/dist/contracts/schemas/compliance.d.ts.map +1 -1
  721. package/dist/contracts/schemas/compliance.js +13 -0
  722. package/dist/contracts/schemas/compliance.js.map +1 -1
  723. package/dist/contracts/schemas/display-currency.d.ts +14 -0
  724. package/dist/contracts/schemas/display-currency.d.ts.map +1 -0
  725. package/dist/contracts/schemas/display-currency.js +45 -0
  726. package/dist/contracts/schemas/display-currency.js.map +1 -0
  727. package/dist/contracts/schemas/events.d.ts +1343 -12
  728. package/dist/contracts/schemas/events.d.ts.map +1 -1
  729. package/dist/contracts/schemas/events.js +830 -71
  730. package/dist/contracts/schemas/events.js.map +1 -1
  731. package/dist/contracts/schemas/game.d.ts +104 -0
  732. package/dist/contracts/schemas/game.d.ts.map +1 -0
  733. package/dist/contracts/schemas/game.js +62 -0
  734. package/dist/contracts/schemas/game.js.map +1 -0
  735. package/dist/contracts/schemas/iam.d.ts +32 -0
  736. package/dist/contracts/schemas/iam.d.ts.map +1 -1
  737. package/dist/contracts/schemas/iam.js +35 -0
  738. package/dist/contracts/schemas/iam.js.map +1 -1
  739. package/dist/contracts/schemas/identity.d.ts +250 -6
  740. package/dist/contracts/schemas/identity.d.ts.map +1 -1
  741. package/dist/contracts/schemas/identity.js +236 -9
  742. package/dist/contracts/schemas/identity.js.map +1 -1
  743. package/dist/contracts/schemas/igaming-config.d.ts +31 -1
  744. package/dist/contracts/schemas/igaming-config.d.ts.map +1 -1
  745. package/dist/contracts/schemas/igaming-config.js +9 -1
  746. package/dist/contracts/schemas/igaming-config.js.map +1 -1
  747. package/dist/contracts/schemas/index.d.ts +8 -0
  748. package/dist/contracts/schemas/index.d.ts.map +1 -1
  749. package/dist/contracts/schemas/index.js +8 -0
  750. package/dist/contracts/schemas/index.js.map +1 -1
  751. package/dist/contracts/schemas/lobby.d.ts +27 -0
  752. package/dist/contracts/schemas/lobby.d.ts.map +1 -0
  753. package/dist/contracts/schemas/lobby.js +22 -0
  754. package/dist/contracts/schemas/lobby.js.map +1 -0
  755. package/dist/contracts/schemas/mail.d.ts +306 -0
  756. package/dist/contracts/schemas/mail.d.ts.map +1 -0
  757. package/dist/contracts/schemas/mail.js +112 -0
  758. package/dist/contracts/schemas/mail.js.map +1 -0
  759. package/dist/contracts/schemas/platform-config.d.ts +211 -32
  760. package/dist/contracts/schemas/platform-config.d.ts.map +1 -1
  761. package/dist/contracts/schemas/platform-config.js +239 -7
  762. package/dist/contracts/schemas/platform-config.js.map +1 -1
  763. package/dist/contracts/schemas/player.d.ts +96 -4
  764. package/dist/contracts/schemas/player.d.ts.map +1 -1
  765. package/dist/contracts/schemas/player.js +83 -9
  766. package/dist/contracts/schemas/player.js.map +1 -1
  767. package/dist/contracts/schemas/reporting.d.ts +25 -0
  768. package/dist/contracts/schemas/reporting.d.ts.map +1 -0
  769. package/dist/contracts/schemas/reporting.js +32 -0
  770. package/dist/contracts/schemas/reporting.js.map +1 -0
  771. package/dist/contracts/schemas/tag.d.ts +86 -2
  772. package/dist/contracts/schemas/tag.d.ts.map +1 -1
  773. package/dist/contracts/schemas/tag.js +13 -1
  774. package/dist/contracts/schemas/tag.js.map +1 -1
  775. package/dist/contracts/schemas/wallet-tx.d.ts +50 -3
  776. package/dist/contracts/schemas/wallet-tx.d.ts.map +1 -1
  777. package/dist/contracts/schemas/wallet-tx.js +50 -3
  778. package/dist/contracts/schemas/wallet-tx.js.map +1 -1
  779. package/dist/engagement/chat/__tests__/chat-moderation-expiry.int.test.d.ts +2 -0
  780. package/dist/engagement/chat/__tests__/chat-moderation-expiry.int.test.d.ts.map +1 -0
  781. package/dist/engagement/chat/__tests__/chat-moderation-expiry.int.test.js +155 -0
  782. package/dist/engagement/chat/__tests__/chat-moderation-expiry.int.test.js.map +1 -0
  783. package/dist/engagement/chat/__tests__/chat-mute-listing.int.test.d.ts +2 -0
  784. package/dist/engagement/chat/__tests__/chat-mute-listing.int.test.d.ts.map +1 -0
  785. package/dist/engagement/chat/__tests__/chat-mute-listing.int.test.js +81 -0
  786. package/dist/engagement/chat/__tests__/chat-mute-listing.int.test.js.map +1 -0
  787. package/dist/engagement/chat/__tests__/chat.router.test.d.ts +2 -0
  788. package/dist/engagement/chat/__tests__/chat.router.test.d.ts.map +1 -0
  789. package/dist/engagement/chat/__tests__/chat.router.test.js +44 -0
  790. package/dist/engagement/chat/__tests__/chat.router.test.js.map +1 -0
  791. package/dist/engagement/chat/__tests__/chat.service.int.test.d.ts +2 -0
  792. package/dist/engagement/chat/__tests__/chat.service.int.test.d.ts.map +1 -0
  793. package/dist/engagement/chat/__tests__/chat.service.int.test.js +2363 -0
  794. package/dist/engagement/chat/__tests__/chat.service.int.test.js.map +1 -0
  795. package/dist/engagement/chat/__tests__/contract.test.d.ts +2 -0
  796. package/dist/engagement/chat/__tests__/contract.test.d.ts.map +1 -0
  797. package/dist/engagement/chat/__tests__/contract.test.js +44 -0
  798. package/dist/engagement/chat/__tests__/contract.test.js.map +1 -0
  799. package/dist/engagement/chat/__tests__/global-chat-room.int.test.d.ts +2 -0
  800. package/dist/engagement/chat/__tests__/global-chat-room.int.test.d.ts.map +1 -0
  801. package/dist/engagement/chat/__tests__/global-chat-room.int.test.js +100 -0
  802. package/dist/engagement/chat/__tests__/global-chat-room.int.test.js.map +1 -0
  803. package/dist/engagement/chat/__tests__/moderation.test.js +2 -0
  804. package/dist/engagement/chat/__tests__/moderation.test.js.map +1 -1
  805. package/dist/engagement/chat/__tests__/room-ownership-handover.int.test.d.ts +2 -0
  806. package/dist/engagement/chat/__tests__/room-ownership-handover.int.test.d.ts.map +1 -0
  807. package/dist/engagement/chat/__tests__/room-ownership-handover.int.test.js +736 -0
  808. package/dist/engagement/chat/__tests__/room-ownership-handover.int.test.js.map +1 -0
  809. package/dist/engagement/chat/__tests__/validate-attachment.test.d.ts +2 -0
  810. package/dist/engagement/chat/__tests__/validate-attachment.test.d.ts.map +1 -0
  811. package/dist/engagement/chat/__tests__/validate-attachment.test.js +38 -0
  812. package/dist/engagement/chat/__tests__/validate-attachment.test.js.map +1 -0
  813. package/dist/engagement/chat/contract/constants.d.ts +15 -0
  814. package/dist/engagement/chat/contract/constants.d.ts.map +1 -0
  815. package/dist/engagement/chat/contract/constants.js +20 -0
  816. package/dist/engagement/chat/contract/constants.js.map +1 -0
  817. package/dist/engagement/chat/contract/index.d.ts +2190 -16
  818. package/dist/engagement/chat/contract/index.d.ts.map +1 -1
  819. package/dist/engagement/chat/contract/index.js +457 -12
  820. package/dist/engagement/chat/contract/index.js.map +1 -1
  821. package/dist/engagement/chat/drizzle/migrations/0001_cloudy_groot.sql +32 -0
  822. package/dist/engagement/chat/drizzle/migrations/0002_steep_zodiak.sql +3 -0
  823. package/dist/engagement/chat/drizzle/migrations/0003_stormy_king_bedlam.sql +9 -0
  824. package/dist/engagement/chat/drizzle/migrations/0004_panoramic_robin_chapel.sql +6 -0
  825. package/dist/engagement/chat/drizzle/migrations/0005_tranquil_gwen_stacy.sql +100 -0
  826. package/dist/engagement/chat/drizzle/migrations/0006_tiny_ultron.sql +3 -0
  827. package/dist/engagement/chat/drizzle/migrations/0007_seed_global_chat_room.sql +8 -0
  828. package/dist/engagement/chat/drizzle/migrations/0008_robust_korvac.sql +1 -0
  829. package/dist/engagement/chat/drizzle/migrations/0009_massive_bill_hollister.sql +1 -0
  830. package/dist/engagement/chat/drizzle/migrations/0010_backfill_role_assigned_at.sql +9 -0
  831. package/dist/engagement/chat/drizzle/migrations/0011_light_changeling.sql +1 -0
  832. package/dist/engagement/chat/drizzle/migrations/0012_strange_mephisto.sql +3 -0
  833. package/dist/engagement/chat/drizzle/migrations/0013_chilly_sprite.sql +6 -0
  834. package/dist/engagement/chat/drizzle/migrations/0014_chat_moderation_expiry_recorded.sql +19 -0
  835. package/dist/engagement/chat/drizzle/migrations/meta/0001_snapshot.json +557 -0
  836. package/dist/engagement/chat/drizzle/migrations/meta/0002_snapshot.json +576 -0
  837. package/dist/engagement/chat/drizzle/migrations/meta/0003_snapshot.json +652 -0
  838. package/dist/engagement/chat/drizzle/migrations/meta/0004_snapshot.json +666 -0
  839. package/dist/engagement/chat/drizzle/migrations/meta/0005_snapshot.json +1422 -0
  840. package/dist/engagement/chat/drizzle/migrations/meta/0006_snapshot.json +1456 -0
  841. package/dist/engagement/chat/drizzle/migrations/meta/0007_snapshot.json +1456 -0
  842. package/dist/engagement/chat/drizzle/migrations/meta/0008_snapshot.json +1462 -0
  843. package/dist/engagement/chat/drizzle/migrations/meta/0009_snapshot.json +1468 -0
  844. package/dist/engagement/chat/drizzle/migrations/meta/0010_snapshot.json +1468 -0
  845. package/dist/engagement/chat/drizzle/migrations/meta/0011_snapshot.json +1489 -0
  846. package/dist/engagement/chat/drizzle/migrations/meta/0012_snapshot.json +1517 -0
  847. package/dist/engagement/chat/drizzle/migrations/meta/0013_snapshot.json +1517 -0
  848. package/dist/engagement/chat/drizzle/migrations/meta/0014_snapshot.json +1544 -0
  849. package/dist/engagement/chat/drizzle/migrations/meta/_journal.json +98 -0
  850. package/dist/engagement/chat/index.d.ts +1 -2
  851. package/dist/engagement/chat/index.d.ts.map +1 -1
  852. package/dist/engagement/chat/index.js +1 -2
  853. package/dist/engagement/chat/index.js.map +1 -1
  854. package/dist/engagement/chat/moderation/index.d.ts +1 -0
  855. package/dist/engagement/chat/moderation/index.d.ts.map +1 -1
  856. package/dist/engagement/chat/moderation/index.js +1 -0
  857. package/dist/engagement/chat/moderation/index.js.map +1 -1
  858. package/dist/engagement/chat/moderation/profanity.d.ts.map +1 -1
  859. package/dist/engagement/chat/moderation/profanity.js +2 -0
  860. package/dist/engagement/chat/moderation/profanity.js.map +1 -1
  861. package/dist/engagement/chat/moderation/validate-attachment.d.ts +9 -0
  862. package/dist/engagement/chat/moderation/validate-attachment.d.ts.map +1 -0
  863. package/dist/engagement/chat/moderation/validate-attachment.js +27 -0
  864. package/dist/engagement/chat/moderation/validate-attachment.js.map +1 -0
  865. package/dist/engagement/chat/plugin.d.ts +188 -1
  866. package/dist/engagement/chat/plugin.d.ts.map +1 -1
  867. package/dist/engagement/chat/plugin.js +211 -5
  868. package/dist/engagement/chat/plugin.js.map +1 -1
  869. package/dist/engagement/chat/router/index.d.ts +1662 -16
  870. package/dist/engagement/chat/router/index.d.ts.map +1 -1
  871. package/dist/engagement/chat/router/index.js +302 -27
  872. package/dist/engagement/chat/router/index.js.map +1 -1
  873. package/dist/engagement/chat/schema/index.d.ts +1621 -0
  874. package/dist/engagement/chat/schema/index.d.ts.map +1 -1
  875. package/dist/engagement/chat/schema/index.js +192 -4
  876. package/dist/engagement/chat/schema/index.js.map +1 -1
  877. package/dist/engagement/chat/service/chat-ban.service.d.ts +26 -0
  878. package/dist/engagement/chat/service/chat-ban.service.d.ts.map +1 -0
  879. package/dist/engagement/chat/service/chat-ban.service.js +144 -0
  880. package/dist/engagement/chat/service/chat-ban.service.js.map +1 -0
  881. package/dist/engagement/chat/service/chat-message-moderation.service.d.ts +14 -0
  882. package/dist/engagement/chat/service/chat-message-moderation.service.d.ts.map +1 -0
  883. package/dist/engagement/chat/service/chat-message-moderation.service.js +48 -0
  884. package/dist/engagement/chat/service/chat-message-moderation.service.js.map +1 -0
  885. package/dist/engagement/chat/service/chat-moderation-expiry.service.d.ts +22 -0
  886. package/dist/engagement/chat/service/chat-moderation-expiry.service.d.ts.map +1 -0
  887. package/dist/engagement/chat/service/chat-moderation-expiry.service.js +80 -0
  888. package/dist/engagement/chat/service/chat-moderation-expiry.service.js.map +1 -0
  889. package/dist/engagement/chat/service/chat-moderation.service.d.ts +30 -0
  890. package/dist/engagement/chat/service/chat-moderation.service.d.ts.map +1 -0
  891. package/dist/engagement/chat/service/chat-moderation.service.js +40 -0
  892. package/dist/engagement/chat/service/chat-moderation.service.js.map +1 -0
  893. package/dist/engagement/chat/service/chat-mute.service.d.ts +26 -0
  894. package/dist/engagement/chat/service/chat-mute.service.d.ts.map +1 -0
  895. package/dist/engagement/chat/service/chat-mute.service.js +159 -0
  896. package/dist/engagement/chat/service/chat-mute.service.js.map +1 -0
  897. package/dist/engagement/chat/service/chat-room-ban.service.d.ts +29 -0
  898. package/dist/engagement/chat/service/chat-room-ban.service.d.ts.map +1 -0
  899. package/dist/engagement/chat/service/chat-room-ban.service.js +107 -0
  900. package/dist/engagement/chat/service/chat-room-ban.service.js.map +1 -0
  901. package/dist/engagement/chat/service/chat-room-membership.service.d.ts +107 -0
  902. package/dist/engagement/chat/service/chat-room-membership.service.d.ts.map +1 -0
  903. package/dist/engagement/chat/service/chat-room-membership.service.js +536 -0
  904. package/dist/engagement/chat/service/chat-room-membership.service.js.map +1 -0
  905. package/dist/engagement/chat/service/chat-room-mute.service.d.ts +25 -0
  906. package/dist/engagement/chat/service/chat-room-mute.service.d.ts.map +1 -0
  907. package/dist/engagement/chat/service/chat-room-mute.service.js +89 -0
  908. package/dist/engagement/chat/service/chat-room-mute.service.js.map +1 -0
  909. package/dist/engagement/chat/service/chat-room-purge.service.d.ts +13 -0
  910. package/dist/engagement/chat/service/chat-room-purge.service.d.ts.map +1 -0
  911. package/dist/engagement/chat/service/chat-room-purge.service.js +75 -0
  912. package/dist/engagement/chat/service/chat-room-purge.service.js.map +1 -0
  913. package/dist/engagement/chat/service/chat.service.d.ts +1144 -35
  914. package/dist/engagement/chat/service/chat.service.d.ts.map +1 -1
  915. package/dist/engagement/chat/service/chat.service.js +1243 -70
  916. package/dist/engagement/chat/service/chat.service.js.map +1 -1
  917. package/dist/engagement/chat/service/errors/chat-moderation.errors.d.ts +42 -0
  918. package/dist/engagement/chat/service/errors/chat-moderation.errors.d.ts.map +1 -0
  919. package/dist/engagement/chat/service/errors/chat-moderation.errors.js +32 -0
  920. package/dist/engagement/chat/service/errors/chat-moderation.errors.js.map +1 -0
  921. package/dist/engagement/chat-commands/__tests__/migration-upgrade.int.test.d.ts +2 -0
  922. package/dist/engagement/chat-commands/__tests__/migration-upgrade.int.test.d.ts.map +1 -0
  923. package/dist/engagement/chat-commands/__tests__/migration-upgrade.int.test.js +98 -0
  924. package/dist/engagement/chat-commands/__tests__/migration-upgrade.int.test.js.map +1 -0
  925. package/dist/engagement/chat-commands/contract/index.d.ts +201 -0
  926. package/dist/engagement/chat-commands/contract/index.d.ts.map +1 -0
  927. package/dist/engagement/chat-commands/contract/index.js +70 -0
  928. package/dist/engagement/chat-commands/contract/index.js.map +1 -0
  929. package/dist/engagement/chat-commands/drizzle/migrations/0000_daffy_lady_bullseye.sql +24 -0
  930. package/dist/engagement/chat-commands/drizzle/migrations/0001_sturdy_barracuda.sql +1 -0
  931. package/dist/engagement/chat-commands/drizzle/migrations/0002_single_currency_command_limits.sql +45 -0
  932. package/dist/engagement/chat-commands/drizzle/migrations/meta/0000_snapshot.json +164 -0
  933. package/dist/engagement/chat-commands/drizzle/migrations/meta/0001_snapshot.json +83 -0
  934. package/dist/engagement/chat-commands/drizzle/migrations/meta/0002_snapshot.json +83 -0
  935. package/dist/engagement/chat-commands/drizzle/migrations/meta/_journal.json +27 -0
  936. package/dist/engagement/chat-commands/drizzle.config.d.ts +4 -0
  937. package/dist/engagement/chat-commands/drizzle.config.d.ts.map +1 -0
  938. package/dist/engagement/chat-commands/drizzle.config.js +21 -0
  939. package/dist/engagement/chat-commands/drizzle.config.js.map +1 -0
  940. package/dist/engagement/chat-commands/migrate.d.ts +2 -0
  941. package/dist/engagement/chat-commands/migrate.d.ts.map +1 -0
  942. package/dist/engagement/chat-commands/migrate.js +20 -0
  943. package/dist/engagement/chat-commands/migrate.js.map +1 -0
  944. package/dist/engagement/chat-commands/plugin.d.ts +189 -0
  945. package/dist/engagement/chat-commands/plugin.d.ts.map +1 -0
  946. package/dist/engagement/chat-commands/plugin.js +15 -0
  947. package/dist/engagement/chat-commands/plugin.js.map +1 -0
  948. package/dist/engagement/chat-commands/router/index.d.ts +137 -0
  949. package/dist/engagement/chat-commands/router/index.d.ts.map +1 -0
  950. package/dist/engagement/chat-commands/router/index.js +24 -0
  951. package/dist/engagement/chat-commands/router/index.js.map +1 -0
  952. package/dist/engagement/chat-commands/schema/index.d.ts +140 -0
  953. package/dist/engagement/chat-commands/schema/index.d.ts.map +1 -0
  954. package/dist/engagement/chat-commands/schema/index.js +13 -0
  955. package/dist/engagement/chat-commands/schema/index.js.map +1 -0
  956. package/dist/engagement/chat-commands/seed/index.d.ts +3 -0
  957. package/dist/engagement/chat-commands/seed/index.d.ts.map +1 -0
  958. package/dist/engagement/chat-commands/seed/index.js +66 -0
  959. package/dist/engagement/chat-commands/seed/index.js.map +1 -0
  960. package/dist/engagement/chat-commands/service/__tests__/chat-commands.service.test.d.ts +2 -0
  961. package/dist/engagement/chat-commands/service/__tests__/chat-commands.service.test.d.ts.map +1 -0
  962. package/dist/engagement/chat-commands/service/__tests__/chat-commands.service.test.js +157 -0
  963. package/dist/engagement/chat-commands/service/__tests__/chat-commands.service.test.js.map +1 -0
  964. package/dist/engagement/chat-commands/service/chat-commands.service.d.ts +60 -0
  965. package/dist/engagement/chat-commands/service/chat-commands.service.d.ts.map +1 -0
  966. package/dist/engagement/chat-commands/service/chat-commands.service.js +147 -0
  967. package/dist/engagement/chat-commands/service/chat-commands.service.js.map +1 -0
  968. package/dist/engagement/contracts.d.ts +2 -0
  969. package/dist/engagement/contracts.d.ts.map +1 -1
  970. package/dist/engagement/contracts.js +2 -0
  971. package/dist/engagement/contracts.js.map +1 -1
  972. package/dist/engagement/index.d.ts +2 -0
  973. package/dist/engagement/index.d.ts.map +1 -1
  974. package/dist/engagement/index.js +2 -0
  975. package/dist/engagement/index.js.map +1 -1
  976. package/dist/engagement/notifications/__tests__/chat-room-notifications.int.test.d.ts +2 -0
  977. package/dist/engagement/notifications/__tests__/chat-room-notifications.int.test.d.ts.map +1 -0
  978. package/dist/engagement/notifications/__tests__/chat-room-notifications.int.test.js +184 -0
  979. package/dist/engagement/notifications/__tests__/chat-room-notifications.int.test.js.map +1 -0
  980. package/dist/engagement/notifications/__tests__/notification-event-map.test.d.ts +2 -0
  981. package/dist/engagement/notifications/__tests__/notification-event-map.test.d.ts.map +1 -0
  982. package/dist/engagement/notifications/__tests__/notification-event-map.test.js +337 -0
  983. package/dist/engagement/notifications/__tests__/notification-event-map.test.js.map +1 -0
  984. package/dist/engagement/notifications/__tests__/notifications.router.int.test.d.ts +2 -0
  985. package/dist/engagement/notifications/__tests__/notifications.router.int.test.d.ts.map +1 -0
  986. package/dist/engagement/notifications/__tests__/notifications.router.int.test.js +148 -0
  987. package/dist/engagement/notifications/__tests__/notifications.router.int.test.js.map +1 -0
  988. package/dist/engagement/notifications/__tests__/notifications.service.int.test.d.ts +2 -0
  989. package/dist/engagement/notifications/__tests__/notifications.service.int.test.d.ts.map +1 -0
  990. package/dist/engagement/notifications/__tests__/notifications.service.int.test.js +298 -0
  991. package/dist/engagement/notifications/__tests__/notifications.service.int.test.js.map +1 -0
  992. package/dist/engagement/notifications/contract/index.d.ts +126 -13
  993. package/dist/engagement/notifications/contract/index.d.ts.map +1 -1
  994. package/dist/engagement/notifications/contract/index.js +46 -5
  995. package/dist/engagement/notifications/contract/index.js.map +1 -1
  996. package/dist/engagement/notifications/drizzle/migrations/0001_classy_pixie.sql +1 -0
  997. package/dist/engagement/notifications/drizzle/migrations/0002_open_madame_web.sql +2 -0
  998. package/dist/engagement/notifications/drizzle/migrations/meta/0001_snapshot.json +98 -0
  999. package/dist/engagement/notifications/drizzle/migrations/meta/0002_snapshot.json +119 -0
  1000. package/dist/engagement/notifications/drizzle/migrations/meta/_journal.json +14 -0
  1001. package/dist/engagement/notifications/plugin.d.ts +205 -1
  1002. package/dist/engagement/notifications/plugin.d.ts.map +1 -1
  1003. package/dist/engagement/notifications/plugin.js +466 -46
  1004. package/dist/engagement/notifications/plugin.js.map +1 -1
  1005. package/dist/engagement/notifications/react/notifications.d.ts +20 -0
  1006. package/dist/engagement/notifications/react/notifications.d.ts.map +1 -0
  1007. package/dist/engagement/notifications/react/notifications.js +39 -0
  1008. package/dist/engagement/notifications/react/notifications.js.map +1 -0
  1009. package/dist/engagement/notifications/router/index.d.ts +74 -13
  1010. package/dist/engagement/notifications/router/index.d.ts.map +1 -1
  1011. package/dist/engagement/notifications/router/index.js +37 -16
  1012. package/dist/engagement/notifications/router/index.js.map +1 -1
  1013. package/dist/engagement/notifications/schema/index.d.ts +36 -0
  1014. package/dist/engagement/notifications/schema/index.d.ts.map +1 -1
  1015. package/dist/engagement/notifications/schema/index.js +7 -2
  1016. package/dist/engagement/notifications/schema/index.js.map +1 -1
  1017. package/dist/engagement/notifications/service/notifications.service.d.ts +33 -21
  1018. package/dist/engagement/notifications/service/notifications.service.d.ts.map +1 -1
  1019. package/dist/engagement/notifications/service/notifications.service.js +41 -11
  1020. package/dist/engagement/notifications/service/notifications.service.js.map +1 -1
  1021. package/dist/engagement/react.d.ts +1 -1
  1022. package/dist/engagement/react.d.ts.map +1 -1
  1023. package/dist/engagement/react.js +2 -2
  1024. package/dist/engagement/react.js.map +1 -1
  1025. package/dist/engagement/server.d.ts +2 -0
  1026. package/dist/engagement/server.d.ts.map +1 -1
  1027. package/dist/engagement/server.js +2 -0
  1028. package/dist/engagement/server.js.map +1 -1
  1029. package/dist/engagement/social/__tests__/social.plugin.int.test.d.ts +2 -0
  1030. package/dist/engagement/social/__tests__/social.plugin.int.test.d.ts.map +1 -0
  1031. package/dist/engagement/social/__tests__/social.plugin.int.test.js +100 -0
  1032. package/dist/engagement/social/__tests__/social.plugin.int.test.js.map +1 -0
  1033. package/dist/engagement/social/__tests__/social.router.int.test.d.ts +2 -0
  1034. package/dist/engagement/social/__tests__/social.router.int.test.d.ts.map +1 -0
  1035. package/dist/engagement/social/__tests__/social.router.int.test.js +215 -0
  1036. package/dist/engagement/social/__tests__/social.router.int.test.js.map +1 -0
  1037. package/dist/engagement/social/__tests__/social.service.int.test.d.ts +2 -0
  1038. package/dist/engagement/social/__tests__/social.service.int.test.d.ts.map +1 -0
  1039. package/dist/engagement/social/__tests__/social.service.int.test.js +810 -0
  1040. package/dist/engagement/social/__tests__/social.service.int.test.js.map +1 -0
  1041. package/dist/engagement/social/contract/index.d.ts +187 -0
  1042. package/dist/engagement/social/contract/index.d.ts.map +1 -0
  1043. package/dist/engagement/social/contract/index.js +107 -0
  1044. package/dist/engagement/social/contract/index.js.map +1 -0
  1045. package/dist/engagement/social/drizzle/migrations/0000_fine_jamie_braddock.sql +24 -0
  1046. package/dist/engagement/social/drizzle/migrations/0001_lame_eddie_brock.sql +10 -0
  1047. package/dist/engagement/social/drizzle/migrations/0002_foamy_saracen.sql +1 -0
  1048. package/dist/engagement/social/drizzle/migrations/0003_fuzzy_shadow_king.sql +4 -0
  1049. package/dist/engagement/social/drizzle/migrations/0004_friendship-cancel-constraint.sql +2 -0
  1050. package/dist/engagement/social/drizzle/migrations/meta/0000_snapshot.json +232 -0
  1051. package/dist/engagement/social/drizzle/migrations/meta/0001_snapshot.json +129 -0
  1052. package/dist/engagement/social/drizzle/migrations/meta/0002_snapshot.json +134 -0
  1053. package/dist/engagement/social/drizzle/migrations/meta/0003_snapshot.json +145 -0
  1054. package/dist/engagement/social/drizzle/migrations/meta/0004_snapshot.json +145 -0
  1055. package/dist/engagement/social/drizzle/migrations/meta/_journal.json +41 -0
  1056. package/dist/engagement/social/drizzle.config.d.ts +4 -0
  1057. package/dist/engagement/social/drizzle.config.d.ts.map +1 -0
  1058. package/dist/engagement/social/drizzle.config.js +21 -0
  1059. package/dist/engagement/social/drizzle.config.js.map +1 -0
  1060. package/dist/engagement/social/index.d.ts +3 -0
  1061. package/dist/engagement/social/index.d.ts.map +1 -0
  1062. package/dist/engagement/social/index.js +6 -0
  1063. package/dist/engagement/social/index.js.map +1 -0
  1064. package/dist/engagement/social/migrate.d.ts +5 -0
  1065. package/dist/engagement/social/migrate.d.ts.map +1 -0
  1066. package/dist/engagement/social/migrate.js +17 -0
  1067. package/dist/engagement/social/migrate.js.map +1 -0
  1068. package/dist/engagement/social/plugin.d.ts +189 -0
  1069. package/dist/engagement/social/plugin.d.ts.map +1 -0
  1070. package/dist/engagement/social/plugin.js +17 -0
  1071. package/dist/engagement/social/plugin.js.map +1 -0
  1072. package/dist/engagement/social/router/index.d.ts +98 -0
  1073. package/dist/engagement/social/router/index.d.ts.map +1 -0
  1074. package/dist/engagement/social/router/index.js +68 -0
  1075. package/dist/engagement/social/router/index.js.map +1 -0
  1076. package/dist/engagement/social/schema/index.d.ts +145 -0
  1077. package/dist/engagement/social/schema/index.d.ts.map +1 -0
  1078. package/dist/engagement/social/schema/index.js +24 -0
  1079. package/dist/engagement/social/schema/index.js.map +1 -0
  1080. package/dist/engagement/social/service/social.service.d.ts +73 -0
  1081. package/dist/engagement/social/service/social.service.d.ts.map +1 -0
  1082. package/dist/engagement/social/service/social.service.js +479 -0
  1083. package/dist/engagement/social/service/social.service.js.map +1 -0
  1084. package/dist/fx/contracts.d.ts +2 -0
  1085. package/dist/fx/contracts.d.ts.map +1 -0
  1086. package/dist/fx/contracts.js +2 -0
  1087. package/dist/fx/contracts.js.map +1 -0
  1088. package/dist/fx/exchange-rate/__tests__/exchange-rate-reader.service.int.test.d.ts +2 -0
  1089. package/dist/fx/exchange-rate/__tests__/exchange-rate-reader.service.int.test.d.ts.map +1 -0
  1090. package/dist/fx/exchange-rate/__tests__/exchange-rate-reader.service.int.test.js +236 -0
  1091. package/dist/fx/exchange-rate/__tests__/exchange-rate-reader.service.int.test.js.map +1 -0
  1092. package/dist/fx/exchange-rate/__tests__/select-provider.test.d.ts +2 -0
  1093. package/dist/fx/exchange-rate/__tests__/select-provider.test.d.ts.map +1 -0
  1094. package/dist/fx/exchange-rate/__tests__/select-provider.test.js +26 -0
  1095. package/dist/fx/exchange-rate/__tests__/select-provider.test.js.map +1 -0
  1096. package/dist/fx/exchange-rate/adapters/exchange-rate-reader.service.d.ts +61 -0
  1097. package/dist/fx/exchange-rate/adapters/exchange-rate-reader.service.d.ts.map +1 -0
  1098. package/dist/fx/exchange-rate/adapters/exchange-rate-reader.service.js +227 -0
  1099. package/dist/fx/exchange-rate/adapters/exchange-rate-reader.service.js.map +1 -0
  1100. package/dist/fx/exchange-rate/contract/index.d.ts +44 -0
  1101. package/dist/fx/exchange-rate/contract/index.d.ts.map +1 -0
  1102. package/dist/fx/exchange-rate/contract/index.js +30 -0
  1103. package/dist/fx/exchange-rate/contract/index.js.map +1 -0
  1104. package/dist/fx/exchange-rate/drizzle/migrations/0000_hot_trauma.sql +10 -0
  1105. package/dist/fx/exchange-rate/drizzle/migrations/meta/0000_snapshot.json +92 -0
  1106. package/dist/fx/exchange-rate/drizzle/migrations/meta/_journal.json +13 -0
  1107. package/dist/fx/exchange-rate/drizzle.config.d.ts +4 -0
  1108. package/dist/fx/exchange-rate/drizzle.config.d.ts.map +1 -0
  1109. package/dist/fx/exchange-rate/drizzle.config.js +18 -0
  1110. package/dist/fx/exchange-rate/drizzle.config.js.map +1 -0
  1111. package/dist/fx/exchange-rate/index.d.ts +3 -0
  1112. package/dist/fx/exchange-rate/index.d.ts.map +1 -0
  1113. package/dist/fx/exchange-rate/index.js +3 -0
  1114. package/dist/fx/exchange-rate/index.js.map +1 -0
  1115. package/dist/fx/exchange-rate/migrate.d.ts +5 -0
  1116. package/dist/fx/exchange-rate/migrate.d.ts.map +1 -0
  1117. package/dist/fx/exchange-rate/migrate.js +14 -0
  1118. package/dist/fx/exchange-rate/migrate.js.map +1 -0
  1119. package/dist/fx/exchange-rate/plugin.d.ts +188 -0
  1120. package/dist/fx/exchange-rate/plugin.d.ts.map +1 -0
  1121. package/dist/fx/exchange-rate/plugin.js +42 -0
  1122. package/dist/fx/exchange-rate/plugin.js.map +1 -0
  1123. package/dist/fx/exchange-rate/react/exchange-rate.d.ts +12 -0
  1124. package/dist/fx/exchange-rate/react/exchange-rate.d.ts.map +1 -0
  1125. package/dist/fx/exchange-rate/react/exchange-rate.js +17 -0
  1126. package/dist/fx/exchange-rate/react/exchange-rate.js.map +1 -0
  1127. package/dist/fx/exchange-rate/router/index.d.ts +22 -0
  1128. package/dist/fx/exchange-rate/router/index.d.ts.map +1 -0
  1129. package/dist/fx/exchange-rate/router/index.js +18 -0
  1130. package/dist/fx/exchange-rate/router/index.js.map +1 -0
  1131. package/dist/fx/exchange-rate/schema/index.d.ts +116 -0
  1132. package/dist/fx/exchange-rate/schema/index.d.ts.map +1 -0
  1133. package/dist/fx/exchange-rate/schema/index.js +18 -0
  1134. package/dist/fx/exchange-rate/schema/index.js.map +1 -0
  1135. package/dist/fx/exchange-rate/service/exchange-rate.service.d.ts +22 -0
  1136. package/dist/fx/exchange-rate/service/exchange-rate.service.d.ts.map +1 -0
  1137. package/dist/fx/exchange-rate/service/exchange-rate.service.js +38 -0
  1138. package/dist/fx/exchange-rate/service/exchange-rate.service.js.map +1 -0
  1139. package/dist/fx/index.d.ts +2 -0
  1140. package/dist/fx/index.d.ts.map +1 -0
  1141. package/dist/fx/index.js +2 -0
  1142. package/dist/fx/index.js.map +1 -0
  1143. package/dist/fx/react.d.ts +2 -0
  1144. package/dist/fx/react.d.ts.map +1 -0
  1145. package/dist/fx/react.js +2 -0
  1146. package/dist/fx/react.js.map +1 -0
  1147. package/dist/fx/server.d.ts +2 -0
  1148. package/dist/fx/server.d.ts.map +1 -0
  1149. package/dist/fx/server.js +2 -0
  1150. package/dist/fx/server.js.map +1 -0
  1151. package/dist/iam/__tests__/admin-player-activity.int.test.d.ts +2 -0
  1152. package/dist/iam/__tests__/admin-player-activity.int.test.d.ts.map +1 -0
  1153. package/dist/iam/__tests__/admin-player-activity.int.test.js +119 -0
  1154. package/dist/iam/__tests__/admin-player-activity.int.test.js.map +1 -0
  1155. package/dist/iam/__tests__/iam.service.int.test.d.ts +2 -0
  1156. package/dist/iam/__tests__/iam.service.int.test.d.ts.map +1 -0
  1157. package/dist/iam/__tests__/iam.service.int.test.js +580 -0
  1158. package/dist/iam/__tests__/iam.service.int.test.js.map +1 -0
  1159. package/dist/iam/adapters/admin-player-activity.d.ts +10 -0
  1160. package/dist/iam/adapters/admin-player-activity.d.ts.map +1 -0
  1161. package/dist/iam/adapters/admin-player-activity.js +106 -0
  1162. package/dist/iam/adapters/admin-player-activity.js.map +1 -0
  1163. package/dist/iam/adapters/admin-role-assignment-directory.d.ts +8 -0
  1164. package/dist/iam/adapters/admin-role-assignment-directory.d.ts.map +1 -0
  1165. package/dist/iam/adapters/admin-role-assignment-directory.js +23 -0
  1166. package/dist/iam/adapters/admin-role-assignment-directory.js.map +1 -0
  1167. package/dist/iam/contract/index.d.ts +58 -0
  1168. package/dist/iam/contract/index.d.ts.map +1 -1
  1169. package/dist/iam/contract/index.js +30 -4
  1170. package/dist/iam/contract/index.js.map +1 -1
  1171. package/dist/iam/plugin.d.ts +188 -1
  1172. package/dist/iam/plugin.d.ts.map +1 -1
  1173. package/dist/iam/plugin.js +10 -5
  1174. package/dist/iam/plugin.js.map +1 -1
  1175. package/dist/iam/router/index.d.ts +37 -0
  1176. package/dist/iam/router/index.d.ts.map +1 -1
  1177. package/dist/iam/router/index.js +7 -1
  1178. package/dist/iam/router/index.js.map +1 -1
  1179. package/dist/iam/seed/data/default-admin-roles.d.ts.map +1 -1
  1180. package/dist/iam/seed/data/default-admin-roles.js +6 -0
  1181. package/dist/iam/seed/data/default-admin-roles.js.map +1 -1
  1182. package/dist/iam/service/iam.service.d.ts +55 -26
  1183. package/dist/iam/service/iam.service.d.ts.map +1 -1
  1184. package/dist/iam/service/iam.service.js +122 -17
  1185. package/dist/iam/service/iam.service.js.map +1 -1
  1186. package/dist/mail/__tests__/default-email-template-renderer.test.d.ts +2 -0
  1187. package/dist/mail/__tests__/default-email-template-renderer.test.d.ts.map +1 -0
  1188. package/dist/mail/__tests__/default-email-template-renderer.test.js +212 -0
  1189. package/dist/mail/__tests__/default-email-template-renderer.test.js.map +1 -0
  1190. package/dist/mail/__tests__/mail.service.test.d.ts +2 -0
  1191. package/dist/mail/__tests__/mail.service.test.d.ts.map +1 -0
  1192. package/dist/mail/__tests__/mail.service.test.js +271 -0
  1193. package/dist/mail/__tests__/mail.service.test.js.map +1 -0
  1194. package/dist/mail/adapters/default-email-template-renderer.d.ts +5 -0
  1195. package/dist/mail/adapters/default-email-template-renderer.d.ts.map +1 -0
  1196. package/dist/mail/adapters/default-email-template-renderer.js +151 -0
  1197. package/dist/mail/adapters/default-email-template-renderer.js.map +1 -0
  1198. package/dist/mail/adapters/stdout-email-sender.d.ts +5 -0
  1199. package/dist/mail/adapters/stdout-email-sender.d.ts.map +1 -0
  1200. package/dist/mail/adapters/stdout-email-sender.js +8 -0
  1201. package/dist/mail/adapters/stdout-email-sender.js.map +1 -0
  1202. package/dist/mail/contract/index.d.ts +202 -0
  1203. package/dist/mail/contract/index.d.ts.map +1 -0
  1204. package/dist/mail/contract/index.js +23 -0
  1205. package/dist/mail/contract/index.js.map +1 -0
  1206. package/dist/mail/index.d.ts +5 -0
  1207. package/dist/mail/index.d.ts.map +1 -0
  1208. package/dist/mail/index.js +5 -0
  1209. package/dist/mail/index.js.map +1 -0
  1210. package/dist/mail/plugin.d.ts +188 -0
  1211. package/dist/mail/plugin.d.ts.map +1 -0
  1212. package/dist/mail/plugin.js +66 -0
  1213. package/dist/mail/plugin.js.map +1 -0
  1214. package/dist/mail/service/mail-payload.service.d.ts +8 -0
  1215. package/dist/mail/service/mail-payload.service.d.ts.map +1 -0
  1216. package/dist/mail/service/mail-payload.service.js +43 -0
  1217. package/dist/mail/service/mail-payload.service.js.map +1 -0
  1218. package/dist/mail/service/mail.service.d.ts +30 -0
  1219. package/dist/mail/service/mail.service.d.ts.map +1 -0
  1220. package/dist/mail/service/mail.service.js +165 -0
  1221. package/dist/mail/service/mail.service.js.map +1 -0
  1222. package/dist/pam/identity/__tests__/admin-security.int.test.d.ts +2 -0
  1223. package/dist/pam/identity/__tests__/admin-security.int.test.d.ts.map +1 -0
  1224. package/dist/pam/identity/__tests__/admin-security.int.test.js +153 -0
  1225. package/dist/pam/identity/__tests__/admin-security.int.test.js.map +1 -0
  1226. package/dist/pam/identity/__tests__/admin-user-directory.int.test.d.ts +2 -0
  1227. package/dist/pam/identity/__tests__/admin-user-directory.int.test.d.ts.map +1 -0
  1228. package/dist/pam/identity/__tests__/admin-user-directory.int.test.js +234 -0
  1229. package/dist/pam/identity/__tests__/admin-user-directory.int.test.js.map +1 -0
  1230. package/dist/pam/identity/__tests__/device-fingerprint.test.d.ts +2 -0
  1231. package/dist/pam/identity/__tests__/device-fingerprint.test.d.ts.map +1 -0
  1232. package/dist/pam/identity/__tests__/device-fingerprint.test.js +105 -0
  1233. package/dist/pam/identity/__tests__/device-fingerprint.test.js.map +1 -0
  1234. package/dist/pam/identity/__tests__/identity.rate-limit.int.test.d.ts +2 -0
  1235. package/dist/pam/identity/__tests__/identity.rate-limit.int.test.d.ts.map +1 -0
  1236. package/dist/pam/identity/__tests__/identity.rate-limit.int.test.js +370 -0
  1237. package/dist/pam/identity/__tests__/identity.rate-limit.int.test.js.map +1 -0
  1238. package/dist/pam/identity/__tests__/identity.registration-gates.int.test.d.ts +2 -0
  1239. package/dist/pam/identity/__tests__/identity.registration-gates.int.test.d.ts.map +1 -0
  1240. package/dist/pam/identity/__tests__/identity.registration-gates.int.test.js +119 -0
  1241. package/dist/pam/identity/__tests__/identity.registration-gates.int.test.js.map +1 -0
  1242. package/dist/pam/identity/__tests__/identity.service.int.test.d.ts +2 -0
  1243. package/dist/pam/identity/__tests__/identity.service.int.test.d.ts.map +1 -0
  1244. package/dist/pam/identity/__tests__/identity.service.int.test.js +1292 -0
  1245. package/dist/pam/identity/__tests__/identity.service.int.test.js.map +1 -0
  1246. package/dist/pam/identity/__tests__/login-enforcement.service.int.test.d.ts +2 -0
  1247. package/dist/pam/identity/__tests__/login-enforcement.service.int.test.d.ts.map +1 -0
  1248. package/dist/pam/identity/__tests__/login-enforcement.service.int.test.js +99 -0
  1249. package/dist/pam/identity/__tests__/login-enforcement.service.int.test.js.map +1 -0
  1250. package/dist/pam/identity/__tests__/phone-login.service.int.test.d.ts +2 -0
  1251. package/dist/pam/identity/__tests__/phone-login.service.int.test.d.ts.map +1 -0
  1252. package/dist/pam/identity/__tests__/phone-login.service.int.test.js +394 -0
  1253. package/dist/pam/identity/__tests__/phone-login.service.int.test.js.map +1 -0
  1254. package/dist/pam/identity/__tests__/phone-verification.service.int.test.d.ts +2 -0
  1255. package/dist/pam/identity/__tests__/phone-verification.service.int.test.d.ts.map +1 -0
  1256. package/dist/pam/identity/__tests__/phone-verification.service.int.test.js +274 -0
  1257. package/dist/pam/identity/__tests__/phone-verification.service.int.test.js.map +1 -0
  1258. package/dist/pam/identity/__tests__/play-eligibility.test.d.ts +2 -0
  1259. package/dist/pam/identity/__tests__/play-eligibility.test.d.ts.map +1 -0
  1260. package/dist/pam/identity/__tests__/play-eligibility.test.js +30 -0
  1261. package/dist/pam/identity/__tests__/play-eligibility.test.js.map +1 -0
  1262. package/dist/pam/identity/__tests__/rg-guard.test.d.ts +2 -0
  1263. package/dist/pam/identity/__tests__/rg-guard.test.d.ts.map +1 -0
  1264. package/dist/pam/identity/__tests__/rg-guard.test.js +21 -0
  1265. package/dist/pam/identity/__tests__/rg-guard.test.js.map +1 -0
  1266. package/dist/pam/identity/__tests__/session-idle.service.int.test.d.ts +2 -0
  1267. package/dist/pam/identity/__tests__/session-idle.service.int.test.d.ts.map +1 -0
  1268. package/dist/pam/identity/__tests__/session-idle.service.int.test.js +137 -0
  1269. package/dist/pam/identity/__tests__/session-idle.service.int.test.js.map +1 -0
  1270. package/dist/pam/identity/__tests__/session.service.int.test.d.ts +2 -0
  1271. package/dist/pam/identity/__tests__/session.service.int.test.d.ts.map +1 -0
  1272. package/dist/pam/identity/__tests__/session.service.int.test.js +127 -0
  1273. package/dist/pam/identity/__tests__/session.service.int.test.js.map +1 -0
  1274. package/dist/pam/identity/__tests__/two-factor-delivery.test.d.ts +2 -0
  1275. package/dist/pam/identity/__tests__/two-factor-delivery.test.d.ts.map +1 -0
  1276. package/dist/pam/identity/__tests__/two-factor-delivery.test.js +23 -0
  1277. package/dist/pam/identity/__tests__/two-factor-delivery.test.js.map +1 -0
  1278. package/dist/pam/identity/__tests__/user-commands.int.test.d.ts +2 -0
  1279. package/dist/pam/identity/__tests__/user-commands.int.test.d.ts.map +1 -0
  1280. package/dist/pam/identity/__tests__/user-commands.int.test.js +33 -0
  1281. package/dist/pam/identity/__tests__/user-commands.int.test.js.map +1 -0
  1282. package/dist/pam/identity/__tests__/username-backfill.int.test.d.ts +2 -0
  1283. package/dist/pam/identity/__tests__/username-backfill.int.test.d.ts.map +1 -0
  1284. package/dist/pam/identity/__tests__/username-backfill.int.test.js +103 -0
  1285. package/dist/pam/identity/__tests__/username-backfill.int.test.js.map +1 -0
  1286. package/dist/pam/identity/__tests__/withdrawal-pin.service.int.test.d.ts +2 -0
  1287. package/dist/pam/identity/__tests__/withdrawal-pin.service.int.test.d.ts.map +1 -0
  1288. package/dist/pam/identity/__tests__/withdrawal-pin.service.int.test.js +172 -0
  1289. package/dist/pam/identity/__tests__/withdrawal-pin.service.int.test.js.map +1 -0
  1290. package/dist/pam/identity/adapters/identity-reader.service.d.ts +9 -4
  1291. package/dist/pam/identity/adapters/identity-reader.service.d.ts.map +1 -1
  1292. package/dist/pam/identity/adapters/identity-reader.service.js +61 -2
  1293. package/dist/pam/identity/adapters/identity-reader.service.js.map +1 -1
  1294. package/dist/pam/identity/adapters/mock/mock-kyc-adapter.d.ts +3 -3
  1295. package/dist/pam/identity/adapters/mock/mock-kyc-adapter.d.ts.map +1 -1
  1296. package/dist/pam/identity/adapters/mock/mock-kyc-adapter.js +3 -3
  1297. package/dist/pam/identity/adapters/mock/mock-kyc-adapter.js.map +1 -1
  1298. package/dist/pam/identity/adapters/mock/mock-sms-adapter.d.ts +8 -0
  1299. package/dist/pam/identity/adapters/mock/mock-sms-adapter.d.ts.map +1 -0
  1300. package/dist/pam/identity/adapters/mock/mock-sms-adapter.js +7 -0
  1301. package/dist/pam/identity/adapters/mock/mock-sms-adapter.js.map +1 -0
  1302. package/dist/pam/identity/admin-user-directory.d.ts +50 -8
  1303. package/dist/pam/identity/admin-user-directory.d.ts.map +1 -1
  1304. package/dist/pam/identity/admin-user-directory.js +111 -35
  1305. package/dist/pam/identity/admin-user-directory.js.map +1 -1
  1306. package/dist/pam/identity/contract/index.d.ts +522 -16
  1307. package/dist/pam/identity/contract/index.d.ts.map +1 -1
  1308. package/dist/pam/identity/contract/index.js +214 -9
  1309. package/dist/pam/identity/contract/index.js.map +1 -1
  1310. package/dist/pam/identity/drizzle/migrations/0001_rainy_peter_quill.sql +18 -0
  1311. package/dist/pam/identity/drizzle/migrations/0002_outstanding_patriot.sql +1 -0
  1312. package/dist/pam/identity/drizzle/migrations/0003_open_shotgun.sql +1 -0
  1313. package/dist/pam/identity/drizzle/migrations/0004_round_giant_girl.sql +1 -0
  1314. package/dist/pam/identity/drizzle/migrations/0005_daily_black_tom.sql +1 -0
  1315. package/dist/pam/identity/drizzle/migrations/0006_brave_sabra.sql +1 -0
  1316. package/dist/pam/identity/drizzle/migrations/0007_fuzzy_barracuda.sql +44 -0
  1317. package/dist/pam/identity/drizzle/migrations/0008_pink_bucky.sql +23 -0
  1318. package/dist/pam/identity/drizzle/migrations/0009_hard_sauron.sql +2 -0
  1319. package/dist/pam/identity/drizzle/migrations/0010_lying_young_avengers.sql +19 -0
  1320. package/dist/pam/identity/drizzle/migrations/0011_useful_the_executioner.sql +2 -0
  1321. package/dist/pam/identity/drizzle/migrations/0012_worried_nuke.sql +2 -0
  1322. package/dist/pam/identity/drizzle/migrations/0013_backfill_two_factor_method.sql +6 -0
  1323. package/dist/pam/identity/drizzle/migrations/0014_spicy_mephistopheles.sql +1 -0
  1324. package/dist/pam/identity/drizzle/migrations/0015_parallel_moira_mactaggert.sql +3 -0
  1325. package/dist/pam/identity/drizzle/migrations/meta/0001_snapshot.json +684 -0
  1326. package/dist/pam/identity/drizzle/migrations/meta/0002_snapshot.json +690 -0
  1327. package/dist/pam/identity/drizzle/migrations/meta/0003_snapshot.json +695 -0
  1328. package/dist/pam/identity/drizzle/migrations/meta/0004_snapshot.json +680 -0
  1329. package/dist/pam/identity/drizzle/migrations/meta/0005_snapshot.json +695 -0
  1330. package/dist/pam/identity/drizzle/migrations/meta/0006_snapshot.json +701 -0
  1331. package/dist/pam/identity/drizzle/migrations/meta/0007_snapshot.json +737 -0
  1332. package/dist/pam/identity/drizzle/migrations/meta/0008_snapshot.json +913 -0
  1333. package/dist/pam/identity/drizzle/migrations/meta/0009_snapshot.json +926 -0
  1334. package/dist/pam/identity/drizzle/migrations/meta/0010_snapshot.json +1066 -0
  1335. package/dist/pam/identity/drizzle/migrations/meta/0011_snapshot.json +1078 -0
  1336. package/dist/pam/identity/drizzle/migrations/meta/0012_snapshot.json +1090 -0
  1337. package/dist/pam/identity/drizzle/migrations/meta/0013_snapshot.json +1090 -0
  1338. package/dist/pam/identity/drizzle/migrations/meta/0014_snapshot.json +1096 -0
  1339. package/dist/pam/identity/drizzle/migrations/meta/0015_snapshot.json +1116 -0
  1340. package/dist/pam/identity/drizzle/migrations/meta/_journal.json +105 -0
  1341. package/dist/pam/identity/plugin.d.ts +188 -1
  1342. package/dist/pam/identity/plugin.d.ts.map +1 -1
  1343. package/dist/pam/identity/plugin.js +185 -20
  1344. package/dist/pam/identity/plugin.js.map +1 -1
  1345. package/dist/pam/identity/react/account.d.ts +89 -13
  1346. package/dist/pam/identity/react/account.d.ts.map +1 -1
  1347. package/dist/pam/identity/react/account.js +100 -6
  1348. package/dist/pam/identity/react/account.js.map +1 -1
  1349. package/dist/pam/identity/react/auth.d.ts +23 -13
  1350. package/dist/pam/identity/react/auth.d.ts.map +1 -1
  1351. package/dist/pam/identity/router/index.d.ts +486 -18
  1352. package/dist/pam/identity/router/index.d.ts.map +1 -1
  1353. package/dist/pam/identity/router/index.js +170 -28
  1354. package/dist/pam/identity/router/index.js.map +1 -1
  1355. package/dist/pam/identity/schema/index.d.ts +1083 -224
  1356. package/dist/pam/identity/schema/index.d.ts.map +1 -1
  1357. package/dist/pam/identity/schema/index.js +119 -3
  1358. package/dist/pam/identity/schema/index.js.map +1 -1
  1359. package/dist/pam/identity/service/admin-security.service.d.ts +84 -0
  1360. package/dist/pam/identity/service/admin-security.service.d.ts.map +1 -0
  1361. package/dist/pam/identity/service/admin-security.service.js +284 -0
  1362. package/dist/pam/identity/service/admin-security.service.js.map +1 -0
  1363. package/dist/pam/identity/service/capture-timezone.service.d.ts +10 -0
  1364. package/dist/pam/identity/service/capture-timezone.service.d.ts.map +1 -0
  1365. package/dist/pam/identity/service/capture-timezone.service.js +21 -0
  1366. package/dist/pam/identity/service/capture-timezone.service.js.map +1 -0
  1367. package/dist/pam/identity/service/device-fingerprint.service.d.ts +32 -0
  1368. package/dist/pam/identity/service/device-fingerprint.service.d.ts.map +1 -0
  1369. package/dist/pam/identity/service/device-fingerprint.service.js +79 -0
  1370. package/dist/pam/identity/service/device-fingerprint.service.js.map +1 -0
  1371. package/dist/pam/identity/service/fresh-reauthentication.service.d.ts +21 -0
  1372. package/dist/pam/identity/service/fresh-reauthentication.service.d.ts.map +1 -0
  1373. package/dist/pam/identity/service/fresh-reauthentication.service.js +45 -0
  1374. package/dist/pam/identity/service/fresh-reauthentication.service.js.map +1 -0
  1375. package/dist/pam/identity/service/identity.service.d.ts +249 -40
  1376. package/dist/pam/identity/service/identity.service.d.ts.map +1 -1
  1377. package/dist/pam/identity/service/identity.service.js +1808 -131
  1378. package/dist/pam/identity/service/identity.service.js.map +1 -1
  1379. package/dist/pam/identity/service/lockout-policy.service.d.ts +30 -0
  1380. package/dist/pam/identity/service/lockout-policy.service.d.ts.map +1 -0
  1381. package/dist/pam/identity/service/lockout-policy.service.js +40 -0
  1382. package/dist/pam/identity/service/lockout-policy.service.js.map +1 -0
  1383. package/dist/pam/identity/service/phone-login.service.d.ts +65 -0
  1384. package/dist/pam/identity/service/phone-login.service.d.ts.map +1 -0
  1385. package/dist/pam/identity/service/phone-login.service.js +393 -0
  1386. package/dist/pam/identity/service/phone-login.service.js.map +1 -0
  1387. package/dist/pam/identity/service/phone-verification.service.d.ts +39 -0
  1388. package/dist/pam/identity/service/phone-verification.service.d.ts.map +1 -0
  1389. package/dist/pam/identity/service/phone-verification.service.js +223 -0
  1390. package/dist/pam/identity/service/phone-verification.service.js.map +1 -0
  1391. package/dist/pam/identity/service/play-eligibility.service.d.ts +8 -0
  1392. package/dist/pam/identity/service/play-eligibility.service.d.ts.map +1 -0
  1393. package/dist/pam/identity/service/play-eligibility.service.js +21 -0
  1394. package/dist/pam/identity/service/play-eligibility.service.js.map +1 -0
  1395. package/dist/pam/identity/service/rg-guard.service.d.ts +37 -0
  1396. package/dist/pam/identity/service/rg-guard.service.d.ts.map +1 -0
  1397. package/dist/pam/identity/service/rg-guard.service.js +60 -0
  1398. package/dist/pam/identity/service/rg-guard.service.js.map +1 -0
  1399. package/dist/pam/identity/service/security-controls.service.d.ts +4 -0
  1400. package/dist/pam/identity/service/security-controls.service.d.ts.map +1 -0
  1401. package/dist/pam/identity/service/security-controls.service.js +38 -0
  1402. package/dist/pam/identity/service/security-controls.service.js.map +1 -0
  1403. package/dist/pam/identity/service/session-idle.service.d.ts +22 -0
  1404. package/dist/pam/identity/service/session-idle.service.d.ts.map +1 -0
  1405. package/dist/pam/identity/service/session-idle.service.js +101 -0
  1406. package/dist/pam/identity/service/session-idle.service.js.map +1 -0
  1407. package/dist/pam/identity/service/session.service.d.ts +63 -6
  1408. package/dist/pam/identity/service/session.service.d.ts.map +1 -1
  1409. package/dist/pam/identity/service/session.service.js +137 -23
  1410. package/dist/pam/identity/service/session.service.js.map +1 -1
  1411. package/dist/pam/identity/service/trusted-device.service.d.ts +57 -0
  1412. package/dist/pam/identity/service/trusted-device.service.d.ts.map +1 -0
  1413. package/dist/pam/identity/service/trusted-device.service.js +163 -0
  1414. package/dist/pam/identity/service/trusted-device.service.js.map +1 -0
  1415. package/dist/pam/identity/service/two-factor-challenge.service.d.ts +36 -0
  1416. package/dist/pam/identity/service/two-factor-challenge.service.d.ts.map +1 -0
  1417. package/dist/pam/identity/service/two-factor-challenge.service.js +30 -0
  1418. package/dist/pam/identity/service/two-factor-challenge.service.js.map +1 -0
  1419. package/dist/pam/identity/service/two-factor-delivery.service.d.ts +67 -0
  1420. package/dist/pam/identity/service/two-factor-delivery.service.d.ts.map +1 -0
  1421. package/dist/pam/identity/service/two-factor-delivery.service.js +135 -0
  1422. package/dist/pam/identity/service/two-factor-delivery.service.js.map +1 -0
  1423. package/dist/pam/identity/service/two-factor-lockout.service.d.ts +25 -0
  1424. package/dist/pam/identity/service/two-factor-lockout.service.d.ts.map +1 -0
  1425. package/dist/pam/identity/service/two-factor-lockout.service.js +121 -0
  1426. package/dist/pam/identity/service/two-factor-lockout.service.js.map +1 -0
  1427. package/dist/pam/identity/service/user-commands.service.d.ts +11 -0
  1428. package/dist/pam/identity/service/user-commands.service.d.ts.map +1 -0
  1429. package/dist/pam/identity/service/user-commands.service.js +32 -0
  1430. package/dist/pam/identity/service/user-commands.service.js.map +1 -0
  1431. package/dist/pam/identity/service/withdrawal-pin-hash.service.d.ts +3 -0
  1432. package/dist/pam/identity/service/withdrawal-pin-hash.service.d.ts.map +1 -0
  1433. package/dist/pam/identity/service/withdrawal-pin-hash.service.js +10 -0
  1434. package/dist/pam/identity/service/withdrawal-pin-hash.service.js.map +1 -0
  1435. package/dist/pam/identity/service/withdrawal-pin.service.d.ts +36 -0
  1436. package/dist/pam/identity/service/withdrawal-pin.service.d.ts.map +1 -0
  1437. package/dist/pam/identity/service/withdrawal-pin.service.js +132 -0
  1438. package/dist/pam/identity/service/withdrawal-pin.service.js.map +1 -0
  1439. package/dist/pam/player-management/__tests__/kyc-status-writer.int.test.d.ts +2 -0
  1440. package/dist/pam/player-management/__tests__/kyc-status-writer.int.test.d.ts.map +1 -0
  1441. package/dist/pam/player-management/__tests__/kyc-status-writer.int.test.js +81 -0
  1442. package/dist/pam/player-management/__tests__/kyc-status-writer.int.test.js.map +1 -0
  1443. package/dist/pam/player-management/__tests__/player.router.int.test.d.ts +2 -0
  1444. package/dist/pam/player-management/__tests__/player.router.int.test.d.ts.map +1 -0
  1445. package/dist/pam/player-management/__tests__/player.router.int.test.js +107 -0
  1446. package/dist/pam/player-management/__tests__/player.router.int.test.js.map +1 -0
  1447. package/dist/pam/player-management/__tests__/player.service.int.test.d.ts +2 -0
  1448. package/dist/pam/player-management/__tests__/player.service.int.test.d.ts.map +1 -0
  1449. package/dist/pam/player-management/__tests__/player.service.int.test.js +479 -0
  1450. package/dist/pam/player-management/__tests__/player.service.int.test.js.map +1 -0
  1451. package/dist/pam/player-management/contract/index.d.ts +125 -15
  1452. package/dist/pam/player-management/contract/index.d.ts.map +1 -1
  1453. package/dist/pam/player-management/contract/index.js +35 -5
  1454. package/dist/pam/player-management/contract/index.js.map +1 -1
  1455. package/dist/pam/player-management/plugin.d.ts +187 -1
  1456. package/dist/pam/player-management/plugin.d.ts.map +1 -1
  1457. package/dist/pam/player-management/plugin.js +11 -8
  1458. package/dist/pam/player-management/plugin.js.map +1 -1
  1459. package/dist/pam/player-management/router/index.d.ts +95 -15
  1460. package/dist/pam/player-management/router/index.d.ts.map +1 -1
  1461. package/dist/pam/player-management/router/index.js +54 -17
  1462. package/dist/pam/player-management/router/index.js.map +1 -1
  1463. package/dist/pam/player-management/service/kyc-status-writer.d.ts +5 -7
  1464. package/dist/pam/player-management/service/kyc-status-writer.d.ts.map +1 -1
  1465. package/dist/pam/player-management/service/kyc-status-writer.js +23 -19
  1466. package/dist/pam/player-management/service/kyc-status-writer.js.map +1 -1
  1467. package/dist/pam/player-management/service/player.service.d.ts +65 -22
  1468. package/dist/pam/player-management/service/player.service.d.ts.map +1 -1
  1469. package/dist/pam/player-management/service/player.service.js +148 -43
  1470. package/dist/pam/player-management/service/player.service.js.map +1 -1
  1471. package/dist/pam/player-note/__tests__/player-note.router.int.test.d.ts +2 -0
  1472. package/dist/pam/player-note/__tests__/player-note.router.int.test.d.ts.map +1 -0
  1473. package/dist/pam/player-note/__tests__/player-note.router.int.test.js +52 -0
  1474. package/dist/pam/player-note/__tests__/player-note.router.int.test.js.map +1 -0
  1475. package/dist/pam/player-note/contract/index.d.ts +14 -0
  1476. package/dist/pam/player-note/contract/index.d.ts.map +1 -1
  1477. package/dist/pam/player-note/contract/index.js +8 -2
  1478. package/dist/pam/player-note/contract/index.js.map +1 -1
  1479. package/dist/pam/player-note/plugin.d.ts +187 -1
  1480. package/dist/pam/player-note/plugin.d.ts.map +1 -1
  1481. package/dist/pam/player-note/plugin.js +6 -4
  1482. package/dist/pam/player-note/plugin.js.map +1 -1
  1483. package/dist/pam/player-note/router/index.d.ts +10 -1
  1484. package/dist/pam/player-note/router/index.d.ts.map +1 -1
  1485. package/dist/pam/player-note/router/index.js +20 -3
  1486. package/dist/pam/player-note/router/index.js.map +1 -1
  1487. package/dist/pam/player-note/service/player-note.service.d.ts +5 -3
  1488. package/dist/pam/player-note/service/player-note.service.d.ts.map +1 -1
  1489. package/dist/pam/player-note/service/player-note.service.js +5 -3
  1490. package/dist/pam/player-note/service/player-note.service.js.map +1 -1
  1491. package/dist/pam/profile/__tests__/profile.service.int.test.d.ts +2 -0
  1492. package/dist/pam/profile/__tests__/profile.service.int.test.d.ts.map +1 -0
  1493. package/dist/pam/profile/__tests__/profile.service.int.test.js +296 -0
  1494. package/dist/pam/profile/__tests__/profile.service.int.test.js.map +1 -0
  1495. package/dist/pam/profile/contract/index.d.ts +74 -36
  1496. package/dist/pam/profile/contract/index.d.ts.map +1 -1
  1497. package/dist/pam/profile/contract/index.js +16 -1
  1498. package/dist/pam/profile/contract/index.js.map +1 -1
  1499. package/dist/pam/profile/drizzle/migrations/0001_powerful_tiger_shark.sql +1 -0
  1500. package/dist/pam/profile/drizzle/migrations/0002_sour_alex_wilder.sql +7 -0
  1501. package/dist/pam/profile/drizzle/migrations/0003_absurd_morbius.sql +4 -0
  1502. package/dist/pam/profile/drizzle/migrations/0004_fuzzy_korvac.sql +1 -0
  1503. package/dist/pam/profile/drizzle/migrations/0005_moaning_rachel_grey.sql +2 -0
  1504. package/dist/pam/profile/drizzle/migrations/meta/0001_snapshot.json +191 -0
  1505. package/dist/pam/profile/drizzle/migrations/meta/0002_snapshot.json +200 -0
  1506. package/dist/pam/profile/drizzle/migrations/meta/0003_snapshot.json +224 -0
  1507. package/dist/pam/profile/drizzle/migrations/meta/0004_snapshot.json +230 -0
  1508. package/dist/pam/profile/drizzle/migrations/meta/0005_snapshot.json +242 -0
  1509. package/dist/pam/profile/drizzle/migrations/meta/_journal.json +35 -0
  1510. package/dist/pam/profile/migrate.d.ts.map +1 -1
  1511. package/dist/pam/profile/migrate.js +3 -1
  1512. package/dist/pam/profile/migrate.js.map +1 -1
  1513. package/dist/pam/profile/plugin.d.ts +187 -1
  1514. package/dist/pam/profile/plugin.d.ts.map +1 -1
  1515. package/dist/pam/profile/plugin.js +8 -4
  1516. package/dist/pam/profile/plugin.js.map +1 -1
  1517. package/dist/pam/profile/react/profile.d.ts +34 -6
  1518. package/dist/pam/profile/react/profile.d.ts.map +1 -1
  1519. package/dist/pam/profile/react/profile.js +12 -0
  1520. package/dist/pam/profile/react/profile.js.map +1 -1
  1521. package/dist/pam/profile/router/index.d.ts +32 -4
  1522. package/dist/pam/profile/router/index.d.ts.map +1 -1
  1523. package/dist/pam/profile/router/index.js +4 -1
  1524. package/dist/pam/profile/router/index.js.map +1 -1
  1525. package/dist/pam/profile/schema/index.d.ts +193 -6
  1526. package/dist/pam/profile/schema/index.d.ts.map +1 -1
  1527. package/dist/pam/profile/schema/index.js +22 -10
  1528. package/dist/pam/profile/schema/index.js.map +1 -1
  1529. package/dist/pam/profile/service/profile.service.d.ts +55 -8
  1530. package/dist/pam/profile/service/profile.service.d.ts.map +1 -1
  1531. package/dist/pam/profile/service/profile.service.js +128 -23
  1532. package/dist/pam/profile/service/profile.service.js.map +1 -1
  1533. package/dist/pam/react.d.ts +2 -2
  1534. package/dist/pam/react.d.ts.map +1 -1
  1535. package/dist/pam/react.js +2 -2
  1536. package/dist/pam/react.js.map +1 -1
  1537. package/dist/pam/shared/__tests__/shared-mappers.test.d.ts +2 -0
  1538. package/dist/pam/shared/__tests__/shared-mappers.test.d.ts.map +1 -0
  1539. package/dist/pam/shared/__tests__/shared-mappers.test.js +61 -0
  1540. package/dist/pam/shared/__tests__/shared-mappers.test.js.map +1 -0
  1541. package/dist/pam/shared/language.d.ts +3 -1
  1542. package/dist/pam/shared/language.d.ts.map +1 -1
  1543. package/dist/pam/shared/language.js +6 -0
  1544. package/dist/pam/shared/language.js.map +1 -1
  1545. package/dist/pam/shared/otp.d.ts +3 -0
  1546. package/dist/pam/shared/otp.d.ts.map +1 -0
  1547. package/dist/pam/shared/otp.js +11 -0
  1548. package/dist/pam/shared/otp.js.map +1 -0
  1549. package/dist/pam/shared/player-mapper.d.ts +14 -4
  1550. package/dist/pam/shared/player-mapper.d.ts.map +1 -1
  1551. package/dist/pam/shared/player-mapper.js +14 -5
  1552. package/dist/pam/shared/player-mapper.js.map +1 -1
  1553. package/dist/pam/tag/__tests__/get-active-tag-keys.int.test.d.ts +2 -0
  1554. package/dist/pam/tag/__tests__/get-active-tag-keys.int.test.d.ts.map +1 -0
  1555. package/dist/pam/tag/__tests__/get-active-tag-keys.int.test.js +77 -0
  1556. package/dist/pam/tag/__tests__/get-active-tag-keys.int.test.js.map +1 -0
  1557. package/dist/pam/tag/__tests__/tag-evaluation.service.int.test.d.ts +2 -0
  1558. package/dist/pam/tag/__tests__/tag-evaluation.service.int.test.d.ts.map +1 -0
  1559. package/dist/pam/tag/__tests__/tag-evaluation.service.int.test.js +1024 -0
  1560. package/dist/pam/tag/__tests__/tag-evaluation.service.int.test.js.map +1 -0
  1561. package/dist/pam/tag/__tests__/tag-mappers.test.js +25 -0
  1562. package/dist/pam/tag/__tests__/tag-mappers.test.js.map +1 -1
  1563. package/dist/pam/tag/__tests__/tag-rule.service.int.test.d.ts +2 -0
  1564. package/dist/pam/tag/__tests__/tag-rule.service.int.test.d.ts.map +1 -0
  1565. package/dist/pam/tag/__tests__/tag-rule.service.int.test.js +145 -0
  1566. package/dist/pam/tag/__tests__/tag-rule.service.int.test.js.map +1 -0
  1567. package/dist/pam/tag/__tests__/tag.router.int.test.d.ts +2 -0
  1568. package/dist/pam/tag/__tests__/tag.router.int.test.d.ts.map +1 -0
  1569. package/dist/pam/tag/__tests__/tag.router.int.test.js +222 -0
  1570. package/dist/pam/tag/__tests__/tag.router.int.test.js.map +1 -0
  1571. package/dist/pam/tag/__tests__/tag.service.int.test.d.ts +2 -0
  1572. package/dist/pam/tag/__tests__/tag.service.int.test.d.ts.map +1 -0
  1573. package/dist/pam/tag/__tests__/tag.service.int.test.js +571 -0
  1574. package/dist/pam/tag/__tests__/tag.service.int.test.js.map +1 -0
  1575. package/dist/pam/tag/contract/index.d.ts +139 -1
  1576. package/dist/pam/tag/contract/index.d.ts.map +1 -1
  1577. package/dist/pam/tag/contract/index.js +12 -2
  1578. package/dist/pam/tag/contract/index.js.map +1 -1
  1579. package/dist/pam/tag/contract/player-tag-assign-metadata.d.ts +37 -0
  1580. package/dist/pam/tag/contract/player-tag-assign-metadata.d.ts.map +1 -0
  1581. package/dist/pam/tag/contract/player-tag-assign-metadata.js +20 -0
  1582. package/dist/pam/tag/contract/player-tag-assign-metadata.js.map +1 -0
  1583. package/dist/pam/tag/drizzle/migrations/0002_silent_skaar.sql +4 -0
  1584. package/dist/pam/tag/drizzle/migrations/0003_overconfident_guardian.sql +3 -0
  1585. package/dist/pam/tag/drizzle/migrations/0004_curvy_wither.sql +2 -0
  1586. package/dist/pam/tag/drizzle/migrations/meta/0002_snapshot.json +335 -0
  1587. package/dist/pam/tag/drizzle/migrations/meta/0003_snapshot.json +343 -0
  1588. package/dist/pam/tag/drizzle/migrations/meta/0004_snapshot.json +345 -0
  1589. package/dist/pam/tag/drizzle/migrations/meta/_journal.json +21 -0
  1590. package/dist/pam/tag/migrate.d.ts.map +1 -1
  1591. package/dist/pam/tag/migrate.js +34 -0
  1592. package/dist/pam/tag/migrate.js.map +1 -1
  1593. package/dist/pam/tag/plugin.d.ts +187 -1
  1594. package/dist/pam/tag/plugin.d.ts.map +1 -1
  1595. package/dist/pam/tag/plugin.js +46 -19
  1596. package/dist/pam/tag/plugin.js.map +1 -1
  1597. package/dist/pam/tag/router/index.d.ts +114 -1
  1598. package/dist/pam/tag/router/index.d.ts.map +1 -1
  1599. package/dist/pam/tag/router/index.js +38 -9
  1600. package/dist/pam/tag/router/index.js.map +1 -1
  1601. package/dist/pam/tag/schema/index.d.ts +32 -3
  1602. package/dist/pam/tag/schema/index.d.ts.map +1 -1
  1603. package/dist/pam/tag/schema/index.js +15 -2
  1604. package/dist/pam/tag/schema/index.js.map +1 -1
  1605. package/dist/pam/tag/seed/data/default-tag-rules.d.ts.map +1 -1
  1606. package/dist/pam/tag/seed/data/default-tag-rules.js +42 -0
  1607. package/dist/pam/tag/seed/data/default-tag-rules.js.map +1 -1
  1608. package/dist/pam/tag/seed/data/default-tags.d.ts.map +1 -1
  1609. package/dist/pam/tag/seed/data/default-tags.js +6 -0
  1610. package/dist/pam/tag/seed/data/default-tags.js.map +1 -1
  1611. package/dist/pam/tag/service/tag-evaluation.service.d.ts +147 -17
  1612. package/dist/pam/tag/service/tag-evaluation.service.d.ts.map +1 -1
  1613. package/dist/pam/tag/service/tag-evaluation.service.js +491 -48
  1614. package/dist/pam/tag/service/tag-evaluation.service.js.map +1 -1
  1615. package/dist/pam/tag/service/tag-mappers.d.ts +1 -1
  1616. package/dist/pam/tag/service/tag-mappers.d.ts.map +1 -1
  1617. package/dist/pam/tag/service/tag-mappers.js +1 -0
  1618. package/dist/pam/tag/service/tag-mappers.js.map +1 -1
  1619. package/dist/pam/tag/service/tag-rule.service.d.ts +8 -6
  1620. package/dist/pam/tag/service/tag-rule.service.d.ts.map +1 -1
  1621. package/dist/pam/tag/service/tag-rule.service.js +8 -2
  1622. package/dist/pam/tag/service/tag-rule.service.js.map +1 -1
  1623. package/dist/pam/tag/service/tag.service.d.ts +162 -16
  1624. package/dist/pam/tag/service/tag.service.d.ts.map +1 -1
  1625. package/dist/pam/tag/service/tag.service.js +297 -30
  1626. package/dist/pam/tag/service/tag.service.js.map +1 -1
  1627. package/dist/react/client.d.ts +2 -1
  1628. package/dist/react/client.d.ts.map +1 -1
  1629. package/dist/react/client.js +2 -1
  1630. package/dist/react/client.js.map +1 -1
  1631. package/dist/react/context/__tests__/realtime-client.test.d.ts +2 -0
  1632. package/dist/react/context/__tests__/realtime-client.test.d.ts.map +1 -0
  1633. package/dist/react/context/__tests__/realtime-client.test.js +75 -0
  1634. package/dist/react/context/__tests__/realtime-client.test.js.map +1 -0
  1635. package/dist/react/context/realtime-client.d.ts +15 -0
  1636. package/dist/react/context/realtime-client.d.ts.map +1 -1
  1637. package/dist/react/context/realtime-client.js.map +1 -1
  1638. package/dist/react/hooks/__tests__/use-event-stream.test.d.ts +2 -0
  1639. package/dist/react/hooks/__tests__/use-event-stream.test.d.ts.map +1 -0
  1640. package/dist/react/hooks/__tests__/use-event-stream.test.js +153 -0
  1641. package/dist/react/hooks/__tests__/use-event-stream.test.js.map +1 -0
  1642. package/dist/react/hooks/use-event-stream.d.ts +3 -3
  1643. package/dist/react/hooks/use-event-stream.d.ts.map +1 -1
  1644. package/dist/react/hooks/use-event-stream.js +60 -28
  1645. package/dist/react/hooks/use-event-stream.js.map +1 -1
  1646. package/dist/server/auth/__tests__/admin-guard.int.test.d.ts +2 -0
  1647. package/dist/server/auth/__tests__/admin-guard.int.test.d.ts.map +1 -0
  1648. package/dist/server/auth/__tests__/admin-guard.int.test.js +199 -0
  1649. package/dist/server/auth/__tests__/admin-guard.int.test.js.map +1 -0
  1650. package/dist/server/auth/__tests__/auth.test.d.ts +2 -0
  1651. package/dist/server/auth/__tests__/auth.test.d.ts.map +1 -0
  1652. package/dist/server/auth/__tests__/auth.test.js +178 -0
  1653. package/dist/server/auth/__tests__/auth.test.js.map +1 -0
  1654. package/dist/server/auth/__tests__/permission-levels.test.d.ts +2 -0
  1655. package/dist/server/auth/__tests__/permission-levels.test.d.ts.map +1 -0
  1656. package/dist/server/auth/__tests__/permission-levels.test.js +89 -0
  1657. package/dist/server/auth/__tests__/permission-levels.test.js.map +1 -0
  1658. package/dist/server/auth/__tests__/permissions.test.d.ts +2 -0
  1659. package/dist/server/auth/__tests__/permissions.test.d.ts.map +1 -0
  1660. package/dist/server/auth/__tests__/permissions.test.js +15 -0
  1661. package/dist/server/auth/__tests__/permissions.test.js.map +1 -0
  1662. package/dist/server/auth/__tests__/session-resolver.int.test.d.ts +2 -0
  1663. package/dist/server/auth/__tests__/session-resolver.int.test.d.ts.map +1 -0
  1664. package/dist/server/auth/__tests__/session-resolver.int.test.js +59 -0
  1665. package/dist/server/auth/__tests__/session-resolver.int.test.js.map +1 -0
  1666. package/dist/server/auth/__tests__/sign-session-cookie.test.d.ts +2 -0
  1667. package/dist/server/auth/__tests__/sign-session-cookie.test.d.ts.map +1 -0
  1668. package/dist/server/auth/__tests__/sign-session-cookie.test.js +59 -0
  1669. package/dist/server/auth/__tests__/sign-session-cookie.test.js.map +1 -0
  1670. package/dist/server/auth/admin-guard.d.ts +13 -10
  1671. package/dist/server/auth/admin-guard.d.ts.map +1 -1
  1672. package/dist/server/auth/admin-guard.js +106 -44
  1673. package/dist/server/auth/admin-guard.js.map +1 -1
  1674. package/dist/server/auth/auth.d.ts +50 -5
  1675. package/dist/server/auth/auth.d.ts.map +1 -1
  1676. package/dist/server/auth/auth.js +113 -19
  1677. package/dist/server/auth/auth.js.map +1 -1
  1678. package/dist/server/auth/index.d.ts +3 -1
  1679. package/dist/server/auth/index.d.ts.map +1 -1
  1680. package/dist/server/auth/index.js +1 -0
  1681. package/dist/server/auth/index.js.map +1 -1
  1682. package/dist/server/auth/permissions.d.ts +169 -38
  1683. package/dist/server/auth/permissions.d.ts.map +1 -1
  1684. package/dist/server/auth/permissions.js +18 -22
  1685. package/dist/server/auth/permissions.js.map +1 -1
  1686. package/dist/server/auth/session-resolver.d.ts +4 -0
  1687. package/dist/server/auth/session-resolver.d.ts.map +1 -1
  1688. package/dist/server/auth/session-resolver.js +9 -2
  1689. package/dist/server/auth/session-resolver.js.map +1 -1
  1690. package/dist/server/auth/sign-session-cookie.d.ts +18 -0
  1691. package/dist/server/auth/sign-session-cookie.d.ts.map +1 -0
  1692. package/dist/server/auth/sign-session-cookie.js +15 -0
  1693. package/dist/server/auth/sign-session-cookie.js.map +1 -0
  1694. package/dist/server/db/__tests__/migrate.test.d.ts +2 -0
  1695. package/dist/server/db/__tests__/migrate.test.d.ts.map +1 -0
  1696. package/dist/server/db/__tests__/migrate.test.js +158 -0
  1697. package/dist/server/db/__tests__/migrate.test.js.map +1 -0
  1698. package/dist/server/db/__tests__/query-helpers.test.js +232 -1
  1699. package/dist/server/db/__tests__/query-helpers.test.js.map +1 -1
  1700. package/dist/server/db/__tests__/zod-jsonb.test.d.ts +2 -0
  1701. package/dist/server/db/__tests__/zod-jsonb.test.d.ts.map +1 -0
  1702. package/dist/server/db/__tests__/zod-jsonb.test.js +56 -0
  1703. package/dist/server/db/__tests__/zod-jsonb.test.js.map +1 -0
  1704. package/dist/server/db/drizzle.service.d.ts.map +1 -1
  1705. package/dist/server/db/drizzle.service.js +8 -0
  1706. package/dist/server/db/drizzle.service.js.map +1 -1
  1707. package/dist/server/db/index.d.ts +2 -1
  1708. package/dist/server/db/index.d.ts.map +1 -1
  1709. package/dist/server/db/index.js +2 -1
  1710. package/dist/server/db/index.js.map +1 -1
  1711. package/dist/server/db/migrate.d.ts +38 -0
  1712. package/dist/server/db/migrate.d.ts.map +1 -1
  1713. package/dist/server/db/migrate.js +81 -12
  1714. package/dist/server/db/migrate.js.map +1 -1
  1715. package/dist/server/db/outbox/__tests__/relay.int.test.d.ts +2 -0
  1716. package/dist/server/db/outbox/__tests__/relay.int.test.d.ts.map +1 -0
  1717. package/dist/server/db/outbox/__tests__/relay.int.test.js +183 -0
  1718. package/dist/server/db/outbox/__tests__/relay.int.test.js.map +1 -0
  1719. package/dist/server/db/query-helpers.d.ts +15 -0
  1720. package/dist/server/db/query-helpers.d.ts.map +1 -1
  1721. package/dist/server/db/query-helpers.js +121 -0
  1722. package/dist/server/db/query-helpers.js.map +1 -1
  1723. package/dist/server/db/zod-jsonb.d.ts +52 -0
  1724. package/dist/server/db/zod-jsonb.d.ts.map +1 -0
  1725. package/dist/server/db/zod-jsonb.js +52 -0
  1726. package/dist/server/db/zod-jsonb.js.map +1 -0
  1727. package/dist/server/kernel/__tests__/bullmq-job-queue.int.test.d.ts +2 -0
  1728. package/dist/server/kernel/__tests__/bullmq-job-queue.int.test.d.ts.map +1 -0
  1729. package/dist/server/kernel/__tests__/bullmq-job-queue.int.test.js +240 -0
  1730. package/dist/server/kernel/__tests__/bullmq-job-queue.int.test.js.map +1 -0
  1731. package/dist/server/kernel/__tests__/cache.int.test.d.ts +2 -0
  1732. package/dist/server/kernel/__tests__/cache.int.test.d.ts.map +1 -0
  1733. package/dist/server/kernel/__tests__/cache.int.test.js +52 -0
  1734. package/dist/server/kernel/__tests__/cache.int.test.js.map +1 -0
  1735. package/dist/server/kernel/__tests__/domain-error.test.d.ts +2 -0
  1736. package/dist/server/kernel/__tests__/domain-error.test.d.ts.map +1 -0
  1737. package/dist/server/kernel/__tests__/domain-error.test.js +35 -0
  1738. package/dist/server/kernel/__tests__/domain-error.test.js.map +1 -0
  1739. package/dist/server/kernel/__tests__/error-reporter.test.d.ts +2 -0
  1740. package/dist/server/kernel/__tests__/error-reporter.test.d.ts.map +1 -0
  1741. package/dist/server/kernel/__tests__/error-reporter.test.js +52 -0
  1742. package/dist/server/kernel/__tests__/error-reporter.test.js.map +1 -0
  1743. package/dist/server/kernel/__tests__/event-bus.int.test.d.ts +2 -0
  1744. package/dist/server/kernel/__tests__/event-bus.int.test.d.ts.map +1 -0
  1745. package/dist/server/kernel/__tests__/event-bus.int.test.js +201 -0
  1746. package/dist/server/kernel/__tests__/event-bus.int.test.js.map +1 -0
  1747. package/dist/server/kernel/__tests__/helpers.test.js +26 -0
  1748. package/dist/server/kernel/__tests__/helpers.test.js.map +1 -1
  1749. package/dist/server/kernel/__tests__/logger.test.d.ts +2 -0
  1750. package/dist/server/kernel/__tests__/logger.test.d.ts.map +1 -0
  1751. package/dist/server/kernel/__tests__/logger.test.js +44 -0
  1752. package/dist/server/kernel/__tests__/logger.test.js.map +1 -0
  1753. package/dist/server/kernel/__tests__/orpc-error-map.test.d.ts +2 -0
  1754. package/dist/server/kernel/__tests__/orpc-error-map.test.d.ts.map +1 -0
  1755. package/dist/server/kernel/__tests__/orpc-error-map.test.js +54 -0
  1756. package/dist/server/kernel/__tests__/orpc-error-map.test.js.map +1 -0
  1757. package/dist/server/kernel/__tests__/platform-config-loader.test.d.ts +2 -0
  1758. package/dist/server/kernel/__tests__/platform-config-loader.test.d.ts.map +1 -0
  1759. package/dist/server/kernel/__tests__/platform-config-loader.test.js +112 -0
  1760. package/dist/server/kernel/__tests__/platform-config-loader.test.js.map +1 -0
  1761. package/dist/server/kernel/__tests__/rate-limiter.int.test.d.ts +2 -0
  1762. package/dist/server/kernel/__tests__/rate-limiter.int.test.d.ts.map +1 -0
  1763. package/dist/server/kernel/__tests__/rate-limiter.int.test.js +44 -0
  1764. package/dist/server/kernel/__tests__/rate-limiter.int.test.js.map +1 -0
  1765. package/dist/server/kernel/__tests__/redis-cache.int.test.d.ts +2 -0
  1766. package/dist/server/kernel/__tests__/redis-cache.int.test.d.ts.map +1 -0
  1767. package/dist/server/kernel/__tests__/redis-cache.int.test.js +49 -0
  1768. package/dist/server/kernel/__tests__/redis-cache.int.test.js.map +1 -0
  1769. package/dist/server/kernel/__tests__/redis-pubsub-realtime-transport.int.test.d.ts +2 -0
  1770. package/dist/server/kernel/__tests__/redis-pubsub-realtime-transport.int.test.d.ts.map +1 -0
  1771. package/dist/server/kernel/__tests__/redis-pubsub-realtime-transport.int.test.js +251 -0
  1772. package/dist/server/kernel/__tests__/redis-pubsub-realtime-transport.int.test.js.map +1 -0
  1773. package/dist/server/kernel/__tests__/redis-rate-limiter.int.test.d.ts +2 -0
  1774. package/dist/server/kernel/__tests__/redis-rate-limiter.int.test.d.ts.map +1 -0
  1775. package/dist/server/kernel/__tests__/redis-rate-limiter.int.test.js +61 -0
  1776. package/dist/server/kernel/__tests__/redis-rate-limiter.int.test.js.map +1 -0
  1777. package/dist/server/kernel/__tests__/redis-streams-broker.int.test.d.ts +2 -0
  1778. package/dist/server/kernel/__tests__/redis-streams-broker.int.test.d.ts.map +1 -0
  1779. package/dist/server/kernel/__tests__/redis-streams-broker.int.test.js +190 -0
  1780. package/dist/server/kernel/__tests__/redis-streams-broker.int.test.js.map +1 -0
  1781. package/dist/server/kernel/__tests__/request-context.test.d.ts +2 -0
  1782. package/dist/server/kernel/__tests__/request-context.test.d.ts.map +1 -0
  1783. package/dist/server/kernel/__tests__/request-context.test.js +64 -0
  1784. package/dist/server/kernel/__tests__/request-context.test.js.map +1 -0
  1785. package/dist/server/kernel/__tests__/router-utils.test.d.ts +2 -0
  1786. package/dist/server/kernel/__tests__/router-utils.test.d.ts.map +1 -0
  1787. package/dist/server/kernel/__tests__/router-utils.test.js +87 -0
  1788. package/dist/server/kernel/__tests__/router-utils.test.js.map +1 -0
  1789. package/dist/server/kernel/bullmq-job-queue.d.ts.map +1 -1
  1790. package/dist/server/kernel/bullmq-job-queue.js +27 -4
  1791. package/dist/server/kernel/bullmq-job-queue.js.map +1 -1
  1792. package/dist/server/kernel/cache.d.ts +0 -12
  1793. package/dist/server/kernel/cache.d.ts.map +1 -1
  1794. package/dist/server/kernel/cache.js +0 -55
  1795. package/dist/server/kernel/cache.js.map +1 -1
  1796. package/dist/server/kernel/container.d.ts +7 -6
  1797. package/dist/server/kernel/container.d.ts.map +1 -1
  1798. package/dist/server/kernel/container.js +3 -0
  1799. package/dist/server/kernel/container.js.map +1 -1
  1800. package/dist/server/kernel/domain-error.d.ts +15 -5
  1801. package/dist/server/kernel/domain-error.d.ts.map +1 -1
  1802. package/dist/server/kernel/domain-error.js +4 -2
  1803. package/dist/server/kernel/domain-error.js.map +1 -1
  1804. package/dist/server/kernel/error-reporter.d.ts +5 -0
  1805. package/dist/server/kernel/error-reporter.d.ts.map +1 -0
  1806. package/dist/server/kernel/error-reporter.js +20 -0
  1807. package/dist/server/kernel/error-reporter.js.map +1 -0
  1808. package/dist/server/kernel/event-bus.d.ts +2 -18
  1809. package/dist/server/kernel/event-bus.d.ts.map +1 -1
  1810. package/dist/server/kernel/event-bus.js +28 -44
  1811. package/dist/server/kernel/event-bus.js.map +1 -1
  1812. package/dist/server/kernel/event-stream.d.ts.map +1 -1
  1813. package/dist/server/kernel/event-stream.js +19 -4
  1814. package/dist/server/kernel/event-stream.js.map +1 -1
  1815. package/dist/server/kernel/index.d.ts +10 -8
  1816. package/dist/server/kernel/index.d.ts.map +1 -1
  1817. package/dist/server/kernel/index.js +8 -7
  1818. package/dist/server/kernel/index.js.map +1 -1
  1819. package/dist/server/kernel/logger.d.ts.map +1 -1
  1820. package/dist/server/kernel/logger.js +51 -2
  1821. package/dist/server/kernel/logger.js.map +1 -1
  1822. package/dist/server/kernel/orpc-error-map.d.ts.map +1 -1
  1823. package/dist/server/kernel/orpc-error-map.js +4 -1
  1824. package/dist/server/kernel/orpc-error-map.js.map +1 -1
  1825. package/dist/server/kernel/rate-limiter.d.ts +1 -10
  1826. package/dist/server/kernel/rate-limiter.d.ts.map +1 -1
  1827. package/dist/server/kernel/rate-limiter.js +0 -38
  1828. package/dist/server/kernel/rate-limiter.js.map +1 -1
  1829. package/dist/server/kernel/realtime-authorizer.d.ts +2 -4
  1830. package/dist/server/kernel/realtime-authorizer.d.ts.map +1 -1
  1831. package/dist/server/kernel/realtime-authorizer.js +3 -2
  1832. package/dist/server/kernel/realtime-authorizer.js.map +1 -1
  1833. package/dist/server/kernel/redis-cache.d.ts +3 -0
  1834. package/dist/server/kernel/redis-cache.d.ts.map +1 -1
  1835. package/dist/server/kernel/redis-cache.js +10 -0
  1836. package/dist/server/kernel/redis-cache.js.map +1 -1
  1837. package/dist/server/kernel/redis-client.d.ts.map +1 -1
  1838. package/dist/server/kernel/redis-client.js +5 -1
  1839. package/dist/server/kernel/redis-client.js.map +1 -1
  1840. package/dist/server/kernel/redis-pubsub-realtime-transport.d.ts +51 -0
  1841. package/dist/server/kernel/redis-pubsub-realtime-transport.d.ts.map +1 -0
  1842. package/dist/server/kernel/redis-pubsub-realtime-transport.js +0 -0
  1843. package/dist/server/kernel/redis-pubsub-realtime-transport.js.map +1 -0
  1844. package/dist/server/kernel/redis-streams-broker.d.ts +65 -0
  1845. package/dist/server/kernel/redis-streams-broker.d.ts.map +1 -0
  1846. package/dist/server/kernel/redis-streams-broker.js +203 -0
  1847. package/dist/server/kernel/redis-streams-broker.js.map +1 -0
  1848. package/dist/server/kernel/request-context.d.ts +4 -0
  1849. package/dist/server/kernel/request-context.d.ts.map +1 -1
  1850. package/dist/server/kernel/request-context.js +4 -0
  1851. package/dist/server/kernel/request-context.js.map +1 -1
  1852. package/dist/server/kernel/router-utils.d.ts +7 -0
  1853. package/dist/server/kernel/router-utils.d.ts.map +1 -1
  1854. package/dist/server/kernel/router-utils.js +33 -2
  1855. package/dist/server/kernel/router-utils.js.map +1 -1
  1856. package/dist/server/plugin-host/__tests__/core-plugins.test.d.ts +2 -0
  1857. package/dist/server/plugin-host/__tests__/core-plugins.test.d.ts.map +1 -0
  1858. package/dist/server/plugin-host/__tests__/core-plugins.test.js +27 -0
  1859. package/dist/server/plugin-host/__tests__/core-plugins.test.js.map +1 -0
  1860. package/dist/server/plugin-host/__tests__/load-plugins.test.d.ts +2 -0
  1861. package/dist/server/plugin-host/__tests__/load-plugins.test.d.ts.map +1 -0
  1862. package/dist/server/plugin-host/__tests__/load-plugins.test.js +31 -0
  1863. package/dist/server/plugin-host/__tests__/load-plugins.test.js.map +1 -0
  1864. package/dist/server/plugin-host/__tests__/module-registry.test.js.map +1 -1
  1865. package/dist/server/plugin-host/__tests__/required-ports.test.js +1 -0
  1866. package/dist/server/plugin-host/__tests__/required-ports.test.js.map +1 -1
  1867. package/dist/server/plugin-host/__tests__/typed-plugin.test.d.ts +2 -0
  1868. package/dist/server/plugin-host/__tests__/typed-plugin.test.d.ts.map +1 -0
  1869. package/dist/server/plugin-host/__tests__/typed-plugin.test.js +82 -0
  1870. package/dist/server/plugin-host/__tests__/typed-plugin.test.js.map +1 -0
  1871. package/dist/server/plugin-host/core-plugins.d.ts +16 -0
  1872. package/dist/server/plugin-host/core-plugins.d.ts.map +1 -0
  1873. package/dist/server/plugin-host/core-plugins.js +42 -0
  1874. package/dist/server/plugin-host/core-plugins.js.map +1 -0
  1875. package/dist/server/plugin-host/define-plugin.d.ts +24 -24
  1876. package/dist/server/plugin-host/define-plugin.d.ts.map +1 -1
  1877. package/dist/server/plugin-host/define-plugin.js +1 -3
  1878. package/dist/server/plugin-host/define-plugin.js.map +1 -1
  1879. package/dist/server/plugin-host/index.d.ts +3 -3
  1880. package/dist/server/plugin-host/index.d.ts.map +1 -1
  1881. package/dist/server/plugin-host/index.js +2 -2
  1882. package/dist/server/plugin-host/index.js.map +1 -1
  1883. package/dist/server/plugin-host/load-extensions.d.ts +2 -2
  1884. package/dist/server/plugin-host/load-extensions.js +2 -2
  1885. package/dist/server/plugin-host/load-plugins.d.ts +7 -3
  1886. package/dist/server/plugin-host/load-plugins.d.ts.map +1 -1
  1887. package/dist/server/plugin-host/load-plugins.js +10 -2
  1888. package/dist/server/plugin-host/load-plugins.js.map +1 -1
  1889. package/dist/server/plugin-host/module-registry.d.ts +9 -14
  1890. package/dist/server/plugin-host/module-registry.d.ts.map +1 -1
  1891. package/dist/server/plugin-host/module-registry.js +2 -9
  1892. package/dist/server/plugin-host/module-registry.js.map +1 -1
  1893. package/dist/server/runtime/__tests__/client-address.test.d.ts +2 -0
  1894. package/dist/server/runtime/__tests__/client-address.test.d.ts.map +1 -0
  1895. package/dist/server/runtime/__tests__/client-address.test.js +122 -0
  1896. package/dist/server/runtime/__tests__/client-address.test.js.map +1 -0
  1897. package/dist/server/runtime/__tests__/create-app.test.d.ts +2 -0
  1898. package/dist/server/runtime/__tests__/create-app.test.d.ts.map +1 -0
  1899. package/dist/server/runtime/__tests__/create-app.test.js +294 -0
  1900. package/dist/server/runtime/__tests__/create-app.test.js.map +1 -0
  1901. package/dist/server/runtime/assert-durable-seams.d.ts +19 -0
  1902. package/dist/server/runtime/assert-durable-seams.d.ts.map +1 -0
  1903. package/dist/server/runtime/assert-durable-seams.js +37 -0
  1904. package/dist/server/runtime/assert-durable-seams.js.map +1 -0
  1905. package/dist/server/runtime/client-address.d.ts +8 -0
  1906. package/dist/server/runtime/client-address.d.ts.map +1 -0
  1907. package/dist/server/runtime/client-address.js +113 -0
  1908. package/dist/server/runtime/client-address.js.map +1 -0
  1909. package/dist/server/runtime/core-token-catalog.d.ts +186 -0
  1910. package/dist/server/runtime/core-token-catalog.d.ts.map +1 -0
  1911. package/dist/server/runtime/core-token-catalog.js +75 -0
  1912. package/dist/server/runtime/core-token-catalog.js.map +1 -0
  1913. package/dist/server/runtime/create-app.d.ts +21 -23
  1914. package/dist/server/runtime/create-app.d.ts.map +1 -1
  1915. package/dist/server/runtime/create-app.js +180 -98
  1916. package/dist/server/runtime/create-app.js.map +1 -1
  1917. package/dist/server/runtime/index.d.ts +3 -4
  1918. package/dist/server/runtime/index.d.ts.map +1 -1
  1919. package/dist/server/runtime/index.js +1 -3
  1920. package/dist/server/runtime/index.js.map +1 -1
  1921. package/dist/testing/global-setup.d.ts +15 -0
  1922. package/dist/testing/global-setup.d.ts.map +1 -0
  1923. package/dist/testing/global-setup.js +33 -0
  1924. package/dist/testing/global-setup.js.map +1 -0
  1925. package/dist/testing/index.d.ts +6 -0
  1926. package/dist/testing/index.d.ts.map +1 -0
  1927. package/dist/testing/index.js +6 -0
  1928. package/dist/testing/index.js.map +1 -0
  1929. package/dist/testing/mock.d.ts +58 -15
  1930. package/dist/testing/mock.d.ts.map +1 -1
  1931. package/dist/testing/mock.js +163 -39
  1932. package/dist/testing/mock.js.map +1 -1
  1933. package/dist/testing/real-infra.d.ts +68 -0
  1934. package/dist/testing/real-infra.d.ts.map +1 -0
  1935. package/dist/testing/real-infra.js +151 -0
  1936. package/dist/testing/real-infra.js.map +1 -0
  1937. package/dist/testing/realtime-transport-conformance.d.ts +35 -0
  1938. package/dist/testing/realtime-transport-conformance.d.ts.map +1 -0
  1939. package/dist/testing/realtime-transport-conformance.js +94 -0
  1940. package/dist/testing/realtime-transport-conformance.js.map +1 -0
  1941. package/dist/testing/seed-player.d.ts +119 -0
  1942. package/dist/testing/seed-player.d.ts.map +1 -0
  1943. package/dist/testing/seed-player.js +43 -0
  1944. package/dist/testing/seed-player.js.map +1 -0
  1945. package/dist/testing/seed-wallet.d.ts +9 -0
  1946. package/dist/testing/seed-wallet.d.ts.map +1 -0
  1947. package/dist/testing/seed-wallet.js +27 -0
  1948. package/dist/testing/seed-wallet.js.map +1 -0
  1949. package/dist/wallet/__tests__/admin-reporting.int.test.d.ts +2 -0
  1950. package/dist/wallet/__tests__/admin-reporting.int.test.d.ts.map +1 -0
  1951. package/dist/wallet/__tests__/admin-reporting.int.test.js +236 -0
  1952. package/dist/wallet/__tests__/admin-reporting.int.test.js.map +1 -0
  1953. package/dist/wallet/__tests__/bonus-rollover-concurrency.int.test.d.ts +2 -0
  1954. package/dist/wallet/__tests__/bonus-rollover-concurrency.int.test.d.ts.map +1 -0
  1955. package/dist/wallet/__tests__/bonus-rollover-concurrency.int.test.js +163 -0
  1956. package/dist/wallet/__tests__/bonus-rollover-concurrency.int.test.js.map +1 -0
  1957. package/dist/wallet/__tests__/bonus-rollover.int.test.d.ts +2 -0
  1958. package/dist/wallet/__tests__/bonus-rollover.int.test.d.ts.map +1 -0
  1959. package/dist/wallet/__tests__/bonus-rollover.int.test.js +444 -0
  1960. package/dist/wallet/__tests__/bonus-rollover.int.test.js.map +1 -0
  1961. package/dist/wallet/__tests__/custody-sweep-gate.test.d.ts +2 -0
  1962. package/dist/wallet/__tests__/custody-sweep-gate.test.d.ts.map +1 -0
  1963. package/dist/wallet/__tests__/custody-sweep-gate.test.js +70 -0
  1964. package/dist/wallet/__tests__/custody-sweep-gate.test.js.map +1 -0
  1965. package/dist/wallet/__tests__/custody-sweep.service.int.test.d.ts +2 -0
  1966. package/dist/wallet/__tests__/custody-sweep.service.int.test.d.ts.map +1 -0
  1967. package/dist/wallet/__tests__/custody-sweep.service.int.test.js +274 -0
  1968. package/dist/wallet/__tests__/custody-sweep.service.int.test.js.map +1 -0
  1969. package/dist/wallet/__tests__/deposit-gate.test.d.ts +2 -0
  1970. package/dist/wallet/__tests__/deposit-gate.test.d.ts.map +1 -0
  1971. package/dist/wallet/__tests__/deposit-gate.test.js +46 -0
  1972. package/dist/wallet/__tests__/deposit-gate.test.js.map +1 -0
  1973. package/dist/wallet/__tests__/rail-for.test.d.ts +2 -0
  1974. package/dist/wallet/__tests__/rail-for.test.d.ts.map +1 -0
  1975. package/dist/wallet/__tests__/rail-for.test.js +29 -0
  1976. package/dist/wallet/__tests__/rail-for.test.js.map +1 -0
  1977. package/dist/wallet/__tests__/reconciliation-diff.test.d.ts +2 -0
  1978. package/dist/wallet/__tests__/reconciliation-diff.test.d.ts.map +1 -0
  1979. package/dist/wallet/__tests__/reconciliation-diff.test.js +49 -0
  1980. package/dist/wallet/__tests__/reconciliation-diff.test.js.map +1 -0
  1981. package/dist/wallet/__tests__/reconciliation.service.int.test.d.ts +2 -0
  1982. package/dist/wallet/__tests__/reconciliation.service.int.test.d.ts.map +1 -0
  1983. package/dist/wallet/__tests__/reconciliation.service.int.test.js +735 -0
  1984. package/dist/wallet/__tests__/reconciliation.service.int.test.js.map +1 -0
  1985. package/dist/wallet/__tests__/settlement-network.test.d.ts +2 -0
  1986. package/dist/wallet/__tests__/settlement-network.test.d.ts.map +1 -0
  1987. package/dist/wallet/__tests__/settlement-network.test.js +54 -0
  1988. package/dist/wallet/__tests__/settlement-network.test.js.map +1 -0
  1989. package/dist/wallet/__tests__/swap.service.int.test.d.ts +2 -0
  1990. package/dist/wallet/__tests__/swap.service.int.test.d.ts.map +1 -0
  1991. package/dist/wallet/__tests__/swap.service.int.test.js +398 -0
  1992. package/dist/wallet/__tests__/swap.service.int.test.js.map +1 -0
  1993. package/dist/wallet/__tests__/wallet-address-format.test.d.ts +2 -0
  1994. package/dist/wallet/__tests__/wallet-address-format.test.d.ts.map +1 -0
  1995. package/dist/wallet/__tests__/wallet-address-format.test.js +102 -0
  1996. package/dist/wallet/__tests__/wallet-address-format.test.js.map +1 -0
  1997. package/dist/wallet/__tests__/wallet-asset.router.int.test.d.ts +2 -0
  1998. package/dist/wallet/__tests__/wallet-asset.router.int.test.d.ts.map +1 -0
  1999. package/dist/wallet/__tests__/wallet-asset.router.int.test.js +263 -0
  2000. package/dist/wallet/__tests__/wallet-asset.router.int.test.js.map +1 -0
  2001. package/dist/wallet/__tests__/wallet-auto-rule.router.int.test.d.ts +2 -0
  2002. package/dist/wallet/__tests__/wallet-auto-rule.router.int.test.d.ts.map +1 -0
  2003. package/dist/wallet/__tests__/wallet-auto-rule.router.int.test.js +137 -0
  2004. package/dist/wallet/__tests__/wallet-auto-rule.router.int.test.js.map +1 -0
  2005. package/dist/wallet/__tests__/wallet-auto-withdrawal-config.router.int.test.d.ts +2 -0
  2006. package/dist/wallet/__tests__/wallet-auto-withdrawal-config.router.int.test.d.ts.map +1 -0
  2007. package/dist/wallet/__tests__/wallet-auto-withdrawal-config.router.int.test.js +205 -0
  2008. package/dist/wallet/__tests__/wallet-auto-withdrawal-config.router.int.test.js.map +1 -0
  2009. package/dist/wallet/__tests__/wallet-auto-withdrawal.int.test.d.ts +2 -0
  2010. package/dist/wallet/__tests__/wallet-auto-withdrawal.int.test.d.ts.map +1 -0
  2011. package/dist/wallet/__tests__/wallet-auto-withdrawal.int.test.js +900 -0
  2012. package/dist/wallet/__tests__/wallet-auto-withdrawal.int.test.js.map +1 -0
  2013. package/dist/wallet/__tests__/wallet-balance-stream.router.int.test.d.ts +2 -0
  2014. package/dist/wallet/__tests__/wallet-balance-stream.router.int.test.d.ts.map +1 -0
  2015. package/dist/wallet/__tests__/wallet-balance-stream.router.int.test.js +38 -0
  2016. package/dist/wallet/__tests__/wallet-balance-stream.router.int.test.js.map +1 -0
  2017. package/dist/wallet/__tests__/wallet-bonus-rollover-config.router.int.test.d.ts +2 -0
  2018. package/dist/wallet/__tests__/wallet-bonus-rollover-config.router.int.test.d.ts.map +1 -0
  2019. package/dist/wallet/__tests__/wallet-bonus-rollover-config.router.int.test.js +114 -0
  2020. package/dist/wallet/__tests__/wallet-bonus-rollover-config.router.int.test.js.map +1 -0
  2021. package/dist/wallet/__tests__/wallet-commands.service.int.test.d.ts +2 -0
  2022. package/dist/wallet/__tests__/wallet-commands.service.int.test.d.ts.map +1 -0
  2023. package/dist/wallet/__tests__/wallet-commands.service.int.test.js +419 -0
  2024. package/dist/wallet/__tests__/wallet-commands.service.int.test.js.map +1 -0
  2025. package/dist/wallet/__tests__/wallet-currency-code.test.d.ts +2 -0
  2026. package/dist/wallet/__tests__/wallet-currency-code.test.d.ts.map +1 -0
  2027. package/dist/wallet/__tests__/wallet-currency-code.test.js +48 -0
  2028. package/dist/wallet/__tests__/wallet-currency-code.test.js.map +1 -0
  2029. package/dist/wallet/__tests__/wallet-custody-routes.router.test.d.ts +2 -0
  2030. package/dist/wallet/__tests__/wallet-custody-routes.router.test.d.ts.map +1 -0
  2031. package/dist/wallet/__tests__/wallet-custody-routes.router.test.js +129 -0
  2032. package/dist/wallet/__tests__/wallet-custody-routes.router.test.js.map +1 -0
  2033. package/dist/wallet/__tests__/wallet-kyc-gate.int.test.d.ts +2 -0
  2034. package/dist/wallet/__tests__/wallet-kyc-gate.int.test.d.ts.map +1 -0
  2035. package/dist/wallet/__tests__/wallet-kyc-gate.int.test.js +104 -0
  2036. package/dist/wallet/__tests__/wallet-kyc-gate.int.test.js.map +1 -0
  2037. package/dist/wallet/__tests__/wallet-reader.service.int.test.d.ts +2 -0
  2038. package/dist/wallet/__tests__/wallet-reader.service.int.test.d.ts.map +1 -0
  2039. package/dist/wallet/__tests__/wallet-reader.service.int.test.js +111 -0
  2040. package/dist/wallet/__tests__/wallet-reader.service.int.test.js.map +1 -0
  2041. package/dist/wallet/__tests__/wallet-rg-limit-gate.int.test.d.ts +2 -0
  2042. package/dist/wallet/__tests__/wallet-rg-limit-gate.int.test.d.ts.map +1 -0
  2043. package/dist/wallet/__tests__/wallet-rg-limit-gate.int.test.js +93 -0
  2044. package/dist/wallet/__tests__/wallet-rg-limit-gate.int.test.js.map +1 -0
  2045. package/dist/wallet/__tests__/wallet-transaction-direction-backfill.test.d.ts +2 -0
  2046. package/dist/wallet/__tests__/wallet-transaction-direction-backfill.test.d.ts.map +1 -0
  2047. package/dist/wallet/__tests__/wallet-transaction-direction-backfill.test.js +37 -0
  2048. package/dist/wallet/__tests__/wallet-transaction-direction-backfill.test.js.map +1 -0
  2049. package/dist/wallet/__tests__/wallet-webhook.router.int.test.d.ts +2 -0
  2050. package/dist/wallet/__tests__/wallet-webhook.router.int.test.d.ts.map +1 -0
  2051. package/dist/wallet/__tests__/wallet-webhook.router.int.test.js +311 -0
  2052. package/dist/wallet/__tests__/wallet-webhook.router.int.test.js.map +1 -0
  2053. package/dist/wallet/__tests__/wallet-withdrawal-address-cap.int.test.d.ts +2 -0
  2054. package/dist/wallet/__tests__/wallet-withdrawal-address-cap.int.test.d.ts.map +1 -0
  2055. package/dist/wallet/__tests__/wallet-withdrawal-address-cap.int.test.js +64 -0
  2056. package/dist/wallet/__tests__/wallet-withdrawal-address-cap.int.test.js.map +1 -0
  2057. package/dist/wallet/__tests__/wallet-withdrawal-address.router.int.test.d.ts +2 -0
  2058. package/dist/wallet/__tests__/wallet-withdrawal-address.router.int.test.d.ts.map +1 -0
  2059. package/dist/wallet/__tests__/wallet-withdrawal-address.router.int.test.js +179 -0
  2060. package/dist/wallet/__tests__/wallet-withdrawal-address.router.int.test.js.map +1 -0
  2061. package/dist/wallet/__tests__/wallet.rate-limit.int.test.d.ts +2 -0
  2062. package/dist/wallet/__tests__/wallet.rate-limit.int.test.d.ts.map +1 -0
  2063. package/dist/wallet/__tests__/wallet.rate-limit.int.test.js +117 -0
  2064. package/dist/wallet/__tests__/wallet.rate-limit.int.test.js.map +1 -0
  2065. package/dist/wallet/__tests__/wallet.router.int.test.d.ts +2 -0
  2066. package/dist/wallet/__tests__/wallet.router.int.test.d.ts.map +1 -0
  2067. package/dist/wallet/__tests__/wallet.router.int.test.js +104 -0
  2068. package/dist/wallet/__tests__/wallet.router.int.test.js.map +1 -0
  2069. package/dist/wallet/__tests__/wallet.service.int.test.d.ts +2 -0
  2070. package/dist/wallet/__tests__/wallet.service.int.test.d.ts.map +1 -0
  2071. package/dist/wallet/__tests__/wallet.service.int.test.js +1722 -0
  2072. package/dist/wallet/__tests__/wallet.service.int.test.js.map +1 -0
  2073. package/dist/wallet/adapters/wallet-asset-catalog.service.d.ts +14 -0
  2074. package/dist/wallet/adapters/wallet-asset-catalog.service.d.ts.map +1 -0
  2075. package/dist/wallet/adapters/wallet-asset-catalog.service.js +37 -0
  2076. package/dist/wallet/adapters/wallet-asset-catalog.service.js.map +1 -0
  2077. package/dist/wallet/adapters/wallet-reader.service.d.ts +8 -1
  2078. package/dist/wallet/adapters/wallet-reader.service.d.ts.map +1 -1
  2079. package/dist/wallet/adapters/wallet-reader.service.js +52 -1
  2080. package/dist/wallet/adapters/wallet-reader.service.js.map +1 -1
  2081. package/dist/wallet/admin-reporting.d.ts +3 -3
  2082. package/dist/wallet/admin-reporting.d.ts.map +1 -1
  2083. package/dist/wallet/admin-reporting.js +11 -3
  2084. package/dist/wallet/admin-reporting.js.map +1 -1
  2085. package/dist/wallet/contract/index.d.ts +1018 -19
  2086. package/dist/wallet/contract/index.d.ts.map +1 -1
  2087. package/dist/wallet/contract/index.js +513 -15
  2088. package/dist/wallet/contract/index.js.map +1 -1
  2089. package/dist/wallet/drizzle/migrations/0003_certain_ogun.sql +2 -0
  2090. package/dist/wallet/drizzle/migrations/0004_reflective_shriek.sql +2 -0
  2091. package/dist/wallet/drizzle/migrations/0005_gigantic_dust.sql +10 -0
  2092. package/dist/wallet/drizzle/migrations/0006_lush_morg.sql +1 -0
  2093. package/dist/wallet/drizzle/migrations/0007_bouncy_swordsman.sql +17 -0
  2094. package/dist/wallet/drizzle/migrations/0008_gorgeous_colonel_america.sql +1 -0
  2095. package/dist/wallet/drizzle/migrations/0009_smooth_sue_storm.sql +17 -0
  2096. package/dist/wallet/drizzle/migrations/0010_worthless_quasimodo.sql +84 -0
  2097. package/dist/wallet/drizzle/migrations/0011_premium_natasha_romanoff.sql +30 -0
  2098. package/dist/wallet/drizzle/migrations/0012_long_wong.sql +15 -0
  2099. package/dist/wallet/drizzle/migrations/0013_polite_peter_parker.sql +1 -0
  2100. package/dist/wallet/drizzle/migrations/0014_abandoned_madripoor.sql +20 -0
  2101. package/dist/wallet/drizzle/migrations/0015_right_oracle.sql +3 -0
  2102. package/dist/wallet/drizzle/migrations/0016_curly_ben_urich.sql +2 -0
  2103. package/dist/wallet/drizzle/migrations/0017_workable_wolf_cub.sql +2 -0
  2104. package/dist/wallet/drizzle/migrations/0018_marvelous_demogoblin.sql +3 -0
  2105. package/dist/wallet/drizzle/migrations/0019_awesome_drax.sql +2 -0
  2106. package/dist/wallet/drizzle/migrations/0020_salty_infant_terrible.sql +1 -0
  2107. package/dist/wallet/drizzle/migrations/0021_mean_chameleon.sql +3 -0
  2108. package/dist/wallet/drizzle/migrations/0022_natural_exodus.sql +1 -0
  2109. package/dist/wallet/drizzle/migrations/meta/0003_snapshot.json +567 -0
  2110. package/dist/wallet/drizzle/migrations/meta/0004_snapshot.json +631 -0
  2111. package/dist/wallet/drizzle/migrations/meta/0006_snapshot.json +638 -0
  2112. package/dist/wallet/drizzle/migrations/meta/0007_snapshot.json +723 -0
  2113. package/dist/wallet/drizzle/migrations/meta/0008_snapshot.json +716 -0
  2114. package/dist/wallet/drizzle/migrations/meta/0009_snapshot.json +895 -0
  2115. package/dist/wallet/drizzle/migrations/meta/0010_snapshot.json +1565 -0
  2116. package/dist/wallet/drizzle/migrations/meta/0011_snapshot.json +1777 -0
  2117. package/dist/wallet/drizzle/migrations/meta/0012_snapshot.json +1907 -0
  2118. package/dist/wallet/drizzle/migrations/meta/0013_snapshot.json +1913 -0
  2119. package/dist/wallet/drizzle/migrations/meta/0014_snapshot.json +1925 -0
  2120. package/dist/wallet/drizzle/migrations/meta/0015_snapshot.json +1937 -0
  2121. package/dist/wallet/drizzle/migrations/meta/0016_snapshot.json +1943 -0
  2122. package/dist/wallet/drizzle/migrations/meta/0017_snapshot.json +1945 -0
  2123. package/dist/wallet/drizzle/migrations/meta/0018_snapshot.json +1967 -0
  2124. package/dist/wallet/drizzle/migrations/meta/0019_snapshot.json +1973 -0
  2125. package/dist/wallet/drizzle/migrations/meta/0020_snapshot.json +1979 -0
  2126. package/dist/wallet/drizzle/migrations/meta/0021_snapshot.json +1986 -0
  2127. package/dist/wallet/drizzle/migrations/meta/0022_snapshot.json +1987 -0
  2128. package/dist/wallet/drizzle/migrations/meta/_journal.json +140 -0
  2129. package/dist/wallet/index.d.ts.map +1 -1
  2130. package/dist/wallet/index.js +0 -2
  2131. package/dist/wallet/index.js.map +1 -1
  2132. package/dist/wallet/migrate.d.ts +0 -1
  2133. package/dist/wallet/migrate.d.ts.map +1 -1
  2134. package/dist/wallet/migrate.js +0 -4
  2135. package/dist/wallet/migrate.js.map +1 -1
  2136. package/dist/wallet/plugin.d.ts +188 -1
  2137. package/dist/wallet/plugin.d.ts.map +1 -1
  2138. package/dist/wallet/plugin.js +223 -19
  2139. package/dist/wallet/plugin.js.map +1 -1
  2140. package/dist/wallet/router/index.d.ts +557 -12
  2141. package/dist/wallet/router/index.d.ts.map +1 -1
  2142. package/dist/wallet/router/index.js +273 -36
  2143. package/dist/wallet/router/index.js.map +1 -1
  2144. package/dist/wallet/schema/index.d.ts +1990 -9
  2145. package/dist/wallet/schema/index.d.ts.map +1 -1
  2146. package/dist/wallet/schema/index.js +290 -7
  2147. package/dist/wallet/schema/index.js.map +1 -1
  2148. package/dist/wallet/seed/index.d.ts +3 -0
  2149. package/dist/wallet/seed/index.d.ts.map +1 -0
  2150. package/dist/wallet/seed/index.js +3 -0
  2151. package/dist/wallet/seed/index.js.map +1 -0
  2152. package/dist/wallet/seed/seed-auto-withdrawal-config.d.ts +11 -0
  2153. package/dist/wallet/seed/seed-auto-withdrawal-config.d.ts.map +1 -0
  2154. package/dist/wallet/seed/seed-auto-withdrawal-config.js +16 -0
  2155. package/dist/wallet/seed/seed-auto-withdrawal-config.js.map +1 -0
  2156. package/dist/wallet/seed/seed-bonus-rollover-config.d.ts +3 -0
  2157. package/dist/wallet/seed/seed-bonus-rollover-config.d.ts.map +1 -0
  2158. package/dist/wallet/seed/seed-bonus-rollover-config.js +8 -0
  2159. package/dist/wallet/seed/seed-bonus-rollover-config.js.map +1 -0
  2160. package/dist/wallet/service/custody-sweep.service.d.ts +77 -0
  2161. package/dist/wallet/service/custody-sweep.service.d.ts.map +1 -0
  2162. package/dist/wallet/service/custody-sweep.service.js +388 -0
  2163. package/dist/wallet/service/custody-sweep.service.js.map +1 -0
  2164. package/dist/wallet/service/reconciliation-finding.service.d.ts +68 -0
  2165. package/dist/wallet/service/reconciliation-finding.service.d.ts.map +1 -0
  2166. package/dist/wallet/service/reconciliation-finding.service.js +82 -0
  2167. package/dist/wallet/service/reconciliation-finding.service.js.map +1 -0
  2168. package/dist/wallet/service/reconciliation.service.d.ts +144 -0
  2169. package/dist/wallet/service/reconciliation.service.d.ts.map +1 -0
  2170. package/dist/wallet/service/reconciliation.service.js +729 -0
  2171. package/dist/wallet/service/reconciliation.service.js.map +1 -0
  2172. package/dist/wallet/service/swap.service.d.ts +78 -0
  2173. package/dist/wallet/service/swap.service.d.ts.map +1 -0
  2174. package/dist/wallet/service/swap.service.js +336 -0
  2175. package/dist/wallet/service/swap.service.js.map +1 -0
  2176. package/dist/wallet/service/wallet-commands.service.d.ts +19 -4
  2177. package/dist/wallet/service/wallet-commands.service.d.ts.map +1 -1
  2178. package/dist/wallet/service/wallet-commands.service.js +238 -31
  2179. package/dist/wallet/service/wallet-commands.service.js.map +1 -1
  2180. package/dist/wallet/service/wallet.service.d.ts +681 -32
  2181. package/dist/wallet/service/wallet.service.d.ts.map +1 -1
  2182. package/dist/wallet/service/wallet.service.js +1424 -168
  2183. package/dist/wallet/service/wallet.service.js.map +1 -1
  2184. package/generators/src/config.ts +547 -0
  2185. package/generators/src/templates/adapter.hbs +19 -0
  2186. package/generators/src/templates/contract.hbs +19 -0
  2187. package/generators/src/templates/job-worker.hbs +34 -0
  2188. package/generators/src/templates/module/drizzle.config.hbs +22 -0
  2189. package/generators/src/templates/module/index.hbs +5 -0
  2190. package/generators/src/templates/module/migrate.hbs +17 -0
  2191. package/generators/src/templates/module/plugin.hbs +19 -0
  2192. package/generators/src/templates/module/router.hbs +19 -0
  2193. package/generators/src/templates/module/schema.hbs +14 -0
  2194. package/generators/src/templates/module/service.hbs +26 -0
  2195. package/generators/src/templates/plugin.hbs +20 -0
  2196. package/package.json +169 -12
  2197. package/dist/admin-console/__tests__/backoffice.service.test.d.ts +0 -2
  2198. package/dist/admin-console/__tests__/backoffice.service.test.d.ts.map +0 -1
  2199. package/dist/admin-console/__tests__/backoffice.service.test.js +0 -156
  2200. package/dist/admin-console/__tests__/backoffice.service.test.js.map +0 -1
  2201. package/dist/audit/__tests__/audit.service.test.d.ts +0 -2
  2202. package/dist/audit/__tests__/audit.service.test.d.ts.map +0 -1
  2203. package/dist/audit/__tests__/audit.service.test.js +0 -442
  2204. package/dist/audit/__tests__/audit.service.test.js.map +0 -1
  2205. package/dist/casino/gaming/__tests__/gaming.service.test.d.ts +0 -2
  2206. package/dist/casino/gaming/__tests__/gaming.service.test.d.ts.map +0 -1
  2207. package/dist/casino/gaming/__tests__/gaming.service.test.js +0 -55
  2208. package/dist/casino/gaming/__tests__/gaming.service.test.js.map +0 -1
  2209. package/dist/casino/lobby/__tests__/lobby.cache.test.d.ts +0 -2
  2210. package/dist/casino/lobby/__tests__/lobby.cache.test.d.ts.map +0 -1
  2211. package/dist/casino/lobby/__tests__/lobby.cache.test.js +0 -47
  2212. package/dist/casino/lobby/__tests__/lobby.cache.test.js.map +0 -1
  2213. package/dist/casino/lobby/__tests__/lobby.service.test.d.ts +0 -2
  2214. package/dist/casino/lobby/__tests__/lobby.service.test.d.ts.map +0 -1
  2215. package/dist/casino/lobby/__tests__/lobby.service.test.js +0 -11
  2216. package/dist/casino/lobby/__tests__/lobby.service.test.js.map +0 -1
  2217. package/dist/cms/__tests__/cms.cache.test.d.ts +0 -2
  2218. package/dist/cms/__tests__/cms.cache.test.d.ts.map +0 -1
  2219. package/dist/cms/__tests__/cms.cache.test.js +0 -87
  2220. package/dist/cms/__tests__/cms.cache.test.js.map +0 -1
  2221. package/dist/cms/__tests__/cms.router.test.d.ts +0 -2
  2222. package/dist/cms/__tests__/cms.router.test.d.ts.map +0 -1
  2223. package/dist/cms/__tests__/cms.router.test.js +0 -51
  2224. package/dist/cms/__tests__/cms.router.test.js.map +0 -1
  2225. package/dist/cms/__tests__/cms.service.test.d.ts +0 -2
  2226. package/dist/cms/__tests__/cms.service.test.d.ts.map +0 -1
  2227. package/dist/cms/__tests__/cms.service.test.js +0 -17
  2228. package/dist/cms/__tests__/cms.service.test.js.map +0 -1
  2229. package/dist/compliance/__tests__/compliance.service.test.d.ts +0 -2
  2230. package/dist/compliance/__tests__/compliance.service.test.d.ts.map +0 -1
  2231. package/dist/compliance/__tests__/compliance.service.test.js +0 -96
  2232. package/dist/compliance/__tests__/compliance.service.test.js.map +0 -1
  2233. package/dist/compliance/__tests__/hmac-kyc-webhook-verifier.test.d.ts +0 -2
  2234. package/dist/compliance/__tests__/hmac-kyc-webhook-verifier.test.d.ts.map +0 -1
  2235. package/dist/compliance/__tests__/hmac-kyc-webhook-verifier.test.js +0 -25
  2236. package/dist/compliance/__tests__/hmac-kyc-webhook-verifier.test.js.map +0 -1
  2237. package/dist/compliance/__tests__/kyc.service.test.d.ts +0 -2
  2238. package/dist/compliance/__tests__/kyc.service.test.d.ts.map +0 -1
  2239. package/dist/compliance/__tests__/kyc.service.test.js +0 -177
  2240. package/dist/compliance/__tests__/kyc.service.test.js.map +0 -1
  2241. package/dist/compliance/__tests__/rg-monitoring.service.test.d.ts +0 -2
  2242. package/dist/compliance/__tests__/rg-monitoring.service.test.d.ts.map +0 -1
  2243. package/dist/compliance/__tests__/rg-monitoring.service.test.js +0 -110
  2244. package/dist/compliance/__tests__/rg-monitoring.service.test.js.map +0 -1
  2245. package/dist/compliance/__tests__/rg.router.test.d.ts +0 -2
  2246. package/dist/compliance/__tests__/rg.router.test.d.ts.map +0 -1
  2247. package/dist/compliance/__tests__/rg.router.test.js +0 -66
  2248. package/dist/compliance/__tests__/rg.router.test.js.map +0 -1
  2249. package/dist/compliance/__tests__/rg.service.test.d.ts +0 -2
  2250. package/dist/compliance/__tests__/rg.service.test.d.ts.map +0 -1
  2251. package/dist/compliance/__tests__/rg.service.test.js +0 -212
  2252. package/dist/compliance/__tests__/rg.service.test.js.map +0 -1
  2253. package/dist/contracts/adapters/email.d.ts +0 -10
  2254. package/dist/contracts/adapters/email.d.ts.map +0 -1
  2255. package/dist/contracts/adapters/email.js +0 -8
  2256. package/dist/contracts/adapters/email.js.map +0 -1
  2257. package/dist/contracts/adapters/notification.d.ts +0 -6
  2258. package/dist/contracts/adapters/notification.d.ts.map +0 -1
  2259. package/dist/contracts/adapters/notification.js +0 -8
  2260. package/dist/contracts/adapters/notification.js.map +0 -1
  2261. package/dist/contracts/schemas/__tests__/identity-schemas.test.d.ts +0 -2
  2262. package/dist/contracts/schemas/__tests__/identity-schemas.test.d.ts.map +0 -1
  2263. package/dist/contracts/schemas/__tests__/identity-schemas.test.js +0 -38
  2264. package/dist/contracts/schemas/__tests__/identity-schemas.test.js.map +0 -1
  2265. package/dist/engagement/chat/__tests__/chat.service.test.d.ts +0 -2
  2266. package/dist/engagement/chat/__tests__/chat.service.test.d.ts.map +0 -1
  2267. package/dist/engagement/chat/__tests__/chat.service.test.js +0 -170
  2268. package/dist/engagement/chat/__tests__/chat.service.test.js.map +0 -1
  2269. package/dist/engagement/chat/react/use-chat-stream.d.ts +0 -26
  2270. package/dist/engagement/chat/react/use-chat-stream.d.ts.map +0 -1
  2271. package/dist/engagement/chat/react/use-chat-stream.js +0 -54
  2272. package/dist/engagement/chat/react/use-chat-stream.js.map +0 -1
  2273. package/dist/engagement/notifications/__tests__/notifications.service.test.d.ts +0 -2
  2274. package/dist/engagement/notifications/__tests__/notifications.service.test.d.ts.map +0 -1
  2275. package/dist/engagement/notifications/__tests__/notifications.service.test.js +0 -84
  2276. package/dist/engagement/notifications/__tests__/notifications.service.test.js.map +0 -1
  2277. package/dist/engagement/notifications/adapters/mock/mock-notification-adapter.d.ts +0 -5
  2278. package/dist/engagement/notifications/adapters/mock/mock-notification-adapter.d.ts.map +0 -1
  2279. package/dist/engagement/notifications/adapters/mock/mock-notification-adapter.js +0 -6
  2280. package/dist/engagement/notifications/adapters/mock/mock-notification-adapter.js.map +0 -1
  2281. package/dist/iam/__tests__/iam.service.test.d.ts +0 -2
  2282. package/dist/iam/__tests__/iam.service.test.d.ts.map +0 -1
  2283. package/dist/iam/__tests__/iam.service.test.js +0 -744
  2284. package/dist/iam/__tests__/iam.service.test.js.map +0 -1
  2285. package/dist/pam/identity/__tests__/admin-user-directory.test.d.ts +0 -2
  2286. package/dist/pam/identity/__tests__/admin-user-directory.test.d.ts.map +0 -1
  2287. package/dist/pam/identity/__tests__/admin-user-directory.test.js +0 -93
  2288. package/dist/pam/identity/__tests__/admin-user-directory.test.js.map +0 -1
  2289. package/dist/pam/identity/__tests__/identity.rate-limit.test.d.ts +0 -2
  2290. package/dist/pam/identity/__tests__/identity.rate-limit.test.d.ts.map +0 -1
  2291. package/dist/pam/identity/__tests__/identity.rate-limit.test.js +0 -127
  2292. package/dist/pam/identity/__tests__/identity.rate-limit.test.js.map +0 -1
  2293. package/dist/pam/identity/__tests__/identity.service.test.d.ts +0 -2
  2294. package/dist/pam/identity/__tests__/identity.service.test.d.ts.map +0 -1
  2295. package/dist/pam/identity/__tests__/identity.service.test.js +0 -323
  2296. package/dist/pam/identity/__tests__/identity.service.test.js.map +0 -1
  2297. package/dist/pam/identity/__tests__/login-enforcement.service.test.d.ts +0 -2
  2298. package/dist/pam/identity/__tests__/login-enforcement.service.test.d.ts.map +0 -1
  2299. package/dist/pam/identity/__tests__/login-enforcement.service.test.js +0 -41
  2300. package/dist/pam/identity/__tests__/login-enforcement.service.test.js.map +0 -1
  2301. package/dist/pam/player-management/__tests__/kyc-status-writer.test.d.ts +0 -2
  2302. package/dist/pam/player-management/__tests__/kyc-status-writer.test.d.ts.map +0 -1
  2303. package/dist/pam/player-management/__tests__/kyc-status-writer.test.js +0 -38
  2304. package/dist/pam/player-management/__tests__/kyc-status-writer.test.js.map +0 -1
  2305. package/dist/pam/player-management/__tests__/player.router.test.d.ts +0 -2
  2306. package/dist/pam/player-management/__tests__/player.router.test.d.ts.map +0 -1
  2307. package/dist/pam/player-management/__tests__/player.router.test.js +0 -57
  2308. package/dist/pam/player-management/__tests__/player.router.test.js.map +0 -1
  2309. package/dist/pam/player-management/__tests__/player.service.test.d.ts +0 -2
  2310. package/dist/pam/player-management/__tests__/player.service.test.d.ts.map +0 -1
  2311. package/dist/pam/player-management/__tests__/player.service.test.js +0 -144
  2312. package/dist/pam/player-management/__tests__/player.service.test.js.map +0 -1
  2313. package/dist/pam/profile/__tests__/profile.service.test.d.ts +0 -2
  2314. package/dist/pam/profile/__tests__/profile.service.test.d.ts.map +0 -1
  2315. package/dist/pam/profile/__tests__/profile.service.test.js +0 -48
  2316. package/dist/pam/profile/__tests__/profile.service.test.js.map +0 -1
  2317. package/dist/pam/tag/__tests__/get-active-tag-keys.test.d.ts +0 -2
  2318. package/dist/pam/tag/__tests__/get-active-tag-keys.test.d.ts.map +0 -1
  2319. package/dist/pam/tag/__tests__/get-active-tag-keys.test.js +0 -38
  2320. package/dist/pam/tag/__tests__/get-active-tag-keys.test.js.map +0 -1
  2321. package/dist/pam/tag/__tests__/tag-evaluation.service.test.d.ts +0 -2
  2322. package/dist/pam/tag/__tests__/tag-evaluation.service.test.d.ts.map +0 -1
  2323. package/dist/pam/tag/__tests__/tag-evaluation.service.test.js +0 -269
  2324. package/dist/pam/tag/__tests__/tag-evaluation.service.test.js.map +0 -1
  2325. package/dist/pam/tag/__tests__/tag-rule.service.test.d.ts +0 -2
  2326. package/dist/pam/tag/__tests__/tag-rule.service.test.d.ts.map +0 -1
  2327. package/dist/pam/tag/__tests__/tag-rule.service.test.js +0 -149
  2328. package/dist/pam/tag/__tests__/tag-rule.service.test.js.map +0 -1
  2329. package/dist/pam/tag/__tests__/tag.router.test.d.ts +0 -2
  2330. package/dist/pam/tag/__tests__/tag.router.test.d.ts.map +0 -1
  2331. package/dist/pam/tag/__tests__/tag.router.test.js +0 -38
  2332. package/dist/pam/tag/__tests__/tag.router.test.js.map +0 -1
  2333. package/dist/pam/tag/__tests__/tag.service.test.d.ts +0 -2
  2334. package/dist/pam/tag/__tests__/tag.service.test.d.ts.map +0 -1
  2335. package/dist/pam/tag/__tests__/tag.service.test.js +0 -262
  2336. package/dist/pam/tag/__tests__/tag.service.test.js.map +0 -1
  2337. package/dist/server/auth/__tests__/admin-guard.test.d.ts +0 -2
  2338. package/dist/server/auth/__tests__/admin-guard.test.d.ts.map +0 -1
  2339. package/dist/server/auth/__tests__/admin-guard.test.js +0 -133
  2340. package/dist/server/auth/__tests__/admin-guard.test.js.map +0 -1
  2341. package/dist/server/auth/__tests__/session-resolver.test.d.ts +0 -2
  2342. package/dist/server/auth/__tests__/session-resolver.test.d.ts.map +0 -1
  2343. package/dist/server/auth/__tests__/session-resolver.test.js +0 -27
  2344. package/dist/server/auth/__tests__/session-resolver.test.js.map +0 -1
  2345. package/dist/server/db/outbox/__tests__/relay.test.d.ts +0 -2
  2346. package/dist/server/db/outbox/__tests__/relay.test.d.ts.map +0 -1
  2347. package/dist/server/db/outbox/__tests__/relay.test.js +0 -124
  2348. package/dist/server/db/outbox/__tests__/relay.test.js.map +0 -1
  2349. package/dist/server/kernel/__tests__/bullmq-job-queue.test.d.ts +0 -2
  2350. package/dist/server/kernel/__tests__/bullmq-job-queue.test.d.ts.map +0 -1
  2351. package/dist/server/kernel/__tests__/bullmq-job-queue.test.js +0 -190
  2352. package/dist/server/kernel/__tests__/bullmq-job-queue.test.js.map +0 -1
  2353. package/dist/server/kernel/__tests__/cache.test.d.ts +0 -2
  2354. package/dist/server/kernel/__tests__/cache.test.d.ts.map +0 -1
  2355. package/dist/server/kernel/__tests__/cache.test.js +0 -84
  2356. package/dist/server/kernel/__tests__/cache.test.js.map +0 -1
  2357. package/dist/server/kernel/__tests__/event-bus.test.d.ts +0 -2
  2358. package/dist/server/kernel/__tests__/event-bus.test.d.ts.map +0 -1
  2359. package/dist/server/kernel/__tests__/event-bus.test.js +0 -116
  2360. package/dist/server/kernel/__tests__/event-bus.test.js.map +0 -1
  2361. package/dist/server/kernel/__tests__/job-queue.test.d.ts +0 -2
  2362. package/dist/server/kernel/__tests__/job-queue.test.d.ts.map +0 -1
  2363. package/dist/server/kernel/__tests__/job-queue.test.js +0 -135
  2364. package/dist/server/kernel/__tests__/job-queue.test.js.map +0 -1
  2365. package/dist/server/kernel/__tests__/rate-limiter.test.d.ts +0 -2
  2366. package/dist/server/kernel/__tests__/rate-limiter.test.d.ts.map +0 -1
  2367. package/dist/server/kernel/__tests__/rate-limiter.test.js +0 -74
  2368. package/dist/server/kernel/__tests__/rate-limiter.test.js.map +0 -1
  2369. package/dist/server/kernel/__tests__/realtime-authorizer.test.d.ts +0 -2
  2370. package/dist/server/kernel/__tests__/realtime-authorizer.test.d.ts.map +0 -1
  2371. package/dist/server/kernel/__tests__/realtime-authorizer.test.js +0 -19
  2372. package/dist/server/kernel/__tests__/realtime-authorizer.test.js.map +0 -1
  2373. package/dist/server/kernel/__tests__/realtime-transport.test.d.ts +0 -2
  2374. package/dist/server/kernel/__tests__/realtime-transport.test.d.ts.map +0 -1
  2375. package/dist/server/kernel/__tests__/realtime-transport.test.js +0 -50
  2376. package/dist/server/kernel/__tests__/realtime-transport.test.js.map +0 -1
  2377. package/dist/server/kernel/__tests__/redis-cache.test.d.ts +0 -2
  2378. package/dist/server/kernel/__tests__/redis-cache.test.d.ts.map +0 -1
  2379. package/dist/server/kernel/__tests__/redis-cache.test.js +0 -49
  2380. package/dist/server/kernel/__tests__/redis-cache.test.js.map +0 -1
  2381. package/dist/server/kernel/__tests__/redis-rate-limiter.test.d.ts +0 -2
  2382. package/dist/server/kernel/__tests__/redis-rate-limiter.test.d.ts.map +0 -1
  2383. package/dist/server/kernel/__tests__/redis-rate-limiter.test.js +0 -56
  2384. package/dist/server/kernel/__tests__/redis-rate-limiter.test.js.map +0 -1
  2385. package/dist/server/kernel/job-queue.d.ts +0 -40
  2386. package/dist/server/kernel/job-queue.d.ts.map +0 -1
  2387. package/dist/server/kernel/job-queue.js +0 -200
  2388. package/dist/server/kernel/job-queue.js.map +0 -1
  2389. package/dist/server/kernel/realtime-transport.d.ts +0 -8
  2390. package/dist/server/kernel/realtime-transport.d.ts.map +0 -1
  2391. package/dist/server/kernel/realtime-transport.js +0 -57
  2392. package/dist/server/kernel/realtime-transport.js.map +0 -1
  2393. package/dist/server/runtime/openapi.d.ts +0 -15
  2394. package/dist/server/runtime/openapi.d.ts.map +0 -1
  2395. package/dist/server/runtime/openapi.js +0 -26
  2396. package/dist/server/runtime/openapi.js.map +0 -1
  2397. package/dist/wallet/__tests__/admin-reporting.test.d.ts +0 -2
  2398. package/dist/wallet/__tests__/admin-reporting.test.d.ts.map +0 -1
  2399. package/dist/wallet/__tests__/admin-reporting.test.js +0 -124
  2400. package/dist/wallet/__tests__/admin-reporting.test.js.map +0 -1
  2401. package/dist/wallet/__tests__/wallet-auto-rule.router.test.d.ts +0 -2
  2402. package/dist/wallet/__tests__/wallet-auto-rule.router.test.d.ts.map +0 -1
  2403. package/dist/wallet/__tests__/wallet-auto-rule.router.test.js +0 -100
  2404. package/dist/wallet/__tests__/wallet-auto-rule.router.test.js.map +0 -1
  2405. package/dist/wallet/__tests__/wallet-auto-withdrawal.test.d.ts +0 -2
  2406. package/dist/wallet/__tests__/wallet-auto-withdrawal.test.d.ts.map +0 -1
  2407. package/dist/wallet/__tests__/wallet-auto-withdrawal.test.js +0 -517
  2408. package/dist/wallet/__tests__/wallet-auto-withdrawal.test.js.map +0 -1
  2409. package/dist/wallet/__tests__/wallet-commands.service.test.d.ts +0 -2
  2410. package/dist/wallet/__tests__/wallet-commands.service.test.d.ts.map +0 -1
  2411. package/dist/wallet/__tests__/wallet-commands.service.test.js +0 -176
  2412. package/dist/wallet/__tests__/wallet-commands.service.test.js.map +0 -1
  2413. package/dist/wallet/__tests__/wallet-kyc-gate.test.d.ts +0 -2
  2414. package/dist/wallet/__tests__/wallet-kyc-gate.test.d.ts.map +0 -1
  2415. package/dist/wallet/__tests__/wallet-kyc-gate.test.js +0 -61
  2416. package/dist/wallet/__tests__/wallet-kyc-gate.test.js.map +0 -1
  2417. package/dist/wallet/__tests__/wallet-webhook.router.test.d.ts +0 -2
  2418. package/dist/wallet/__tests__/wallet-webhook.router.test.d.ts.map +0 -1
  2419. package/dist/wallet/__tests__/wallet-webhook.router.test.js +0 -78
  2420. package/dist/wallet/__tests__/wallet-webhook.router.test.js.map +0 -1
  2421. package/dist/wallet/__tests__/wallet.rate-limit.test.d.ts +0 -2
  2422. package/dist/wallet/__tests__/wallet.rate-limit.test.d.ts.map +0 -1
  2423. package/dist/wallet/__tests__/wallet.rate-limit.test.js +0 -34
  2424. package/dist/wallet/__tests__/wallet.rate-limit.test.js.map +0 -1
  2425. package/dist/wallet/__tests__/wallet.router.test.d.ts +0 -2
  2426. package/dist/wallet/__tests__/wallet.router.test.d.ts.map +0 -1
  2427. package/dist/wallet/__tests__/wallet.router.test.js +0 -45
  2428. package/dist/wallet/__tests__/wallet.router.test.js.map +0 -1
  2429. package/dist/wallet/__tests__/wallet.service.test.d.ts +0 -2
  2430. package/dist/wallet/__tests__/wallet.service.test.d.ts.map +0 -1
  2431. package/dist/wallet/__tests__/wallet.service.test.js +0 -971
  2432. package/dist/wallet/__tests__/wallet.service.test.js.map +0 -1
  2433. package/turbo-generators/src/config.ts +0 -478
  2434. package/turbo-generators/src/templates/adapter.hbs +0 -19
  2435. package/turbo-generators/src/templates/contract.hbs +0 -18
  2436. package/turbo-generators/src/templates/job-worker.hbs +0 -34
  2437. package/turbo-generators/src/templates/module/agents.hbs +0 -67
  2438. package/turbo-generators/src/templates/module/drizzle.config.hbs +0 -22
  2439. package/turbo-generators/src/templates/module/index.hbs +0 -5
  2440. package/turbo-generators/src/templates/module/migrate.hbs +0 -15
  2441. package/turbo-generators/src/templates/module/package.json.hbs +0 -62
  2442. package/turbo-generators/src/templates/module/plugin.hbs +0 -20
  2443. package/turbo-generators/src/templates/module/router.hbs +0 -19
  2444. package/turbo-generators/src/templates/module/schema.hbs +0 -21
  2445. package/turbo-generators/src/templates/module/service.hbs +0 -26
  2446. package/turbo-generators/src/templates/module/tsconfig.json.hbs +0 -8
  2447. package/turbo-generators/src/templates/plugin.hbs +0 -20
  2448. /package/{turbo-generators → generators}/src/templates/adr.hbs +0 -0
  2449. /package/{turbo-generators → generators}/src/templates/config.hbs +0 -0
@@ -1,9 +1,19 @@
1
+ import { randomUUID } from 'node:crypto';
1
2
  import { ORPCError } from '@orpc/server';
2
- import { createAuth, assertRateLimit, findOneOrThrow, makeNotFoundError, } from '@openora/core/server';
3
+ import { createAuth, assertRateLimit, extractClientMeta, getCurrentClientMeta, findOneOrThrow, makeConflictError, makeNotFoundError, createLogger, } from '@openora/core/server';
3
4
  import { parseCookies } from 'better-auth/cookies';
4
- import { eq, sql } from 'drizzle-orm';
5
+ import { and, eq, isNull, lte, ne, sql } from 'drizzle-orm';
6
+ import * as z from 'zod';
5
7
  import { user, session, account, verification, twoFactor } from '../schema/index.js';
8
+ import { captureTimezone } from './capture-timezone.service.js';
9
+ import { maskEmail, maskPhone, } from './two-factor-delivery.service.js';
10
+ import { RATE_LIMIT_KEYS, makeRateLimitKey } from '@openora/core/contracts';
6
11
  import { assertSupportedLanguage } from '../../shared/language.js';
12
+ import { assertAccountNotBlocked } from './rg-guard.service.js';
13
+ import { DEFAULT_LOCKOUT_DURATION_MS, DEFAULT_MAX_LOGIN_ATTEMPTS, computeLockoutTier, createAccountLockedError, hasFailedLoginWindowExpired, makeLoginSecurityState, } from './lockout-policy.service.js';
14
+ import { getSecurityControls } from './security-controls.service.js';
15
+ import { resolveChallengeMethod, verifyChallengeCode } from './two-factor-challenge.service.js';
16
+ import { assertFreshReauthentication } from './fresh-reauthentication.service.js';
7
17
  function nodeHeadersToHeaders(nodeHeaders) {
8
18
  const headers = new Headers();
9
19
  for (const [key, value] of Object.entries(nodeHeaders)) {
@@ -14,14 +24,22 @@ function nodeHeadersToHeaders(nodeHeaders) {
14
24
  }
15
25
  return headers;
16
26
  }
17
- export function createAccountLockedError(lockoutUntil) {
18
- return new ORPCError('UNAUTHORIZED', {
19
- message: 'Account is temporarily locked. Please try again later.',
20
- data: {
21
- code: 'ACCOUNT_LOCKED',
22
- lockoutUntil: lockoutUntil.toISOString(),
23
- },
24
- });
27
+ // Deletes every session row for `userId` created at or before `deadline`, except the
28
+ // caller's freshly minted one (matched by `sparedToken`), and returns the ids of what
29
+ // it deleted. Run a short delay after a password change: better-auth rotates the
30
+ // password hash and deletes sessions in separate, untransacted statements, so a
31
+ // sign-in that verified the OLD password just before the rotation can still insert
32
+ // its session row immediately after `deleteUserSessions()` ran. That row predates
33
+ // `deadline` (captured once the change is known committed), so this catches it while
34
+ // sparing anything created afterwards.
35
+ // Exported for direct testing; the service schedules it via setTimeout.
36
+ export async function sweepRacedSessionsAfterPasswordChange(db, params) {
37
+ const { userId, sparedToken, deadline } = params;
38
+ const deleted = await db
39
+ .delete(session)
40
+ .where(and(eq(session.userId, userId), ne(session.token, sparedToken), lte(session.createdAt, deadline)))
41
+ .returning({ id: session.id });
42
+ return deleted.map((row) => row.id);
25
43
  }
26
44
  function toIso(value) {
27
45
  return value instanceof Date ? value.toISOString() : value;
@@ -31,20 +49,22 @@ function toUser(u) {
31
49
  id: u.id,
32
50
  email: u.email,
33
51
  name: u.name,
52
+ username: u.username,
34
53
  emailVerified: u.emailVerified,
35
54
  theme: u.theme ?? 'system',
36
55
  language: u.language ?? 'en',
56
+ twoFactorEnabled: u.twoFactorEnabled ?? false,
37
57
  createdAt: toIso(u.createdAt),
38
58
  updatedAt: toIso(u.updatedAt),
39
59
  };
40
60
  return u.image !== undefined ? { ...base, image: u.image } : base;
41
61
  }
42
- function clientIp(headers) {
43
- return headers.get('x-forwarded-for')?.split(',')[0]?.trim() || headers.get('x-real-ip') || null;
44
- }
45
62
  function makeLoginRateLimitKey(email) {
46
63
  return `login:${email.toLowerCase()}`;
47
64
  }
65
+ function makeLoginIpRateLimitKey(ip) {
66
+ return `login-ip:${ip}`;
67
+ }
48
68
  // Key on the `.two_factor` cookie VALUE, never the raw Cookie header: an attacker can
49
69
  // otherwise churn the rate-limit key each retry by appending unrelated cookie pairs.
50
70
  function twoFactorPendingCookieValue(headers) {
@@ -59,30 +79,111 @@ function twoFactorPendingCookieValue(headers) {
59
79
  }
60
80
  return undefined;
61
81
  }
82
+ // A web Response exposes Set-Cookie as full attribute strings; a request carries only
83
+ // the name=value pairs.
84
+ function requestCookieHeader(res) {
85
+ return (res.headers.getSetCookie?.() ?? [])
86
+ .map((cookie) => {
87
+ const [pair = ''] = cookie.split(';');
88
+ return pair.trim();
89
+ })
90
+ .filter((pair) => pair.length > 0)
91
+ .join('; ');
92
+ }
93
+ function hasTrustDeviceCookie(headers) {
94
+ const cookieHeader = headers.get('cookie');
95
+ if (!cookieHeader) {
96
+ return false;
97
+ }
98
+ for (const [name] of parseCookies(cookieHeader)) {
99
+ if (name.endsWith('.trust_device')) {
100
+ return true;
101
+ }
102
+ }
103
+ return false;
104
+ }
105
+ // better-auth sets `<prefix>.dont_remember` when a user signs in with `rememberMe: false`.
106
+ // Presence is enough here: we only use it to shorten the caller's own rotated session,
107
+ // so a forged cookie can at worst clamp its owner's session earlier - never extend one.
108
+ function hasDontRememberCookie(headers) {
109
+ const cookieHeader = headers.get('cookie');
110
+ if (!cookieHeader) {
111
+ return false;
112
+ }
113
+ for (const [name] of parseCookies(cookieHeader)) {
114
+ if (name.endsWith('.dont_remember') || name === 'dont_remember') {
115
+ return true;
116
+ }
117
+ }
118
+ return false;
119
+ }
120
+ // Drops the one pair and leaves every other byte alone: the cookies that stay carry
121
+ // signed, percent-encoded values better-auth re-verifies exactly as the browser sent them.
122
+ function withoutTrustDeviceCookie(headers) {
123
+ const cookieHeader = headers.get('cookie');
124
+ if (!cookieHeader) {
125
+ return headers;
126
+ }
127
+ const kept = cookieHeader
128
+ .split(';')
129
+ .map((pair) => pair.trim())
130
+ .filter((pair) => {
131
+ const [name = ''] = pair.split('=');
132
+ return !name.endsWith('.trust_device');
133
+ });
134
+ const next = new Headers(headers);
135
+ if (kept.length === 0) {
136
+ next.delete('cookie');
137
+ }
138
+ else {
139
+ next.set('cookie', kept.join('; '));
140
+ }
141
+ return next;
142
+ }
62
143
  const SUCCESS = { success: true };
63
144
  export const UserNotFoundError = makeNotFoundError('User');
145
+ export const UsernameConflictError = makeConflictError('Username', 'Username is already in use');
146
+ const BetterAuthErrorBodySchema = z.object({
147
+ message: z.string().optional(),
148
+ code: z.string().optional(),
149
+ });
64
150
  // better-auth calls use `asResponse: true`, which returns an error *Response*
65
151
  // (4xx/5xx) rather than throwing. Surface those as ORPCErrors so oRPC maps them
66
152
  // to the right HTTP status instead of the handler silently returning success.
67
153
  // Only reads the body on failure, so a subsequent res.json() on success is safe.
68
- async function ensureOk(res) {
154
+ // 401 -> UNAUTHORIZED (bad credentials), 403 -> FORBIDDEN (better-auth's
155
+ // TOO_MANY_ATTEMPTS on checkVerificationOTP/resetPasswordEmailOTP), else BAD_REQUEST.
156
+ // `opts.genericMessage` lets a BAD_REQUEST *or* FORBIDDEN caller opt into a fixed
157
+ // message instead of better-auth's raw one - some better-auth 400s (eg
158
+ // checkVerificationOTP's USER_NOT_FOUND-before-INVALID_OTP ordering) leak account
159
+ // existence otherwise. When genericMessage is set, a 403 is masked down to
160
+ // BAD_REQUEST too, so a caller can't tell "too many attempts" apart from "wrong code".
161
+ async function ensureOk(res, opts) {
69
162
  if (res.ok) {
70
163
  return;
71
164
  }
165
+ const code = res.status === 401 ? 'UNAUTHORIZED' : res.status === 403 ? 'FORBIDDEN' : 'BAD_REQUEST';
166
+ if ((code === 'BAD_REQUEST' || code === 'FORBIDDEN') && opts?.genericMessage) {
167
+ throw new ORPCError(code === 'FORBIDDEN' ? 'BAD_REQUEST' : code, {
168
+ message: opts.genericMessage,
169
+ });
170
+ }
72
171
  let message = `Request failed (${res.status})`;
73
- try {
74
- const parsed = JSON.parse(await res.text());
75
- if (parsed.message) {
76
- message = parsed.message;
172
+ let betterAuthCode;
173
+ const body = BetterAuthErrorBodySchema.safeParse(await res.json().catch(() => null));
174
+ if (body.success) {
175
+ if (body.data.message) {
176
+ message = body.data.message;
177
+ }
178
+ if (body.data.code) {
179
+ betterAuthCode = body.data.code;
77
180
  }
78
181
  }
79
- catch {
80
- // non-JSON body - keep the default message
81
- }
82
- throw new ORPCError(res.status === 401 ? 'UNAUTHORIZED' : 'BAD_REQUEST', { message });
182
+ throw new ORPCError(code, {
183
+ message,
184
+ ...(betterAuthCode ? { data: { code: betterAuthCode } } : {}),
185
+ });
83
186
  }
84
- const DEFAULT_MAX_LOGIN_ATTEMPTS = 5;
85
- const DEFAULT_LOCKOUT_DURATION_MS = 15 * 60 * 1000;
86
187
  const MINUTE_MS = 60 * 1000;
87
188
  export const SESSION_DURATION_IN_SECONDS = 30 * 24 * 60 * 60; // 30 days
88
189
  // Coarse abuse throttles keyed by the caller identifier the context provides (email/
@@ -93,27 +194,87 @@ export const SESSION_DURATION_IN_SECONDS = 30 * 24 * 60 * 60; // 30 days
93
194
  // unthrottled login/2fa/reset window is worse than a transient 429. The volume
94
195
  // throttles (register/resend/etc.) keep the default fail-open.
95
196
  const LOGIN_RATE_LIMIT = { limit: 10, windowMs: 5 * MINUTE_MS, onUnavailable: 'deny' };
197
+ // Per-IP companion to LOGIN_RATE_LIMIT above: catches credential stuffing spread across
198
+ // many accounts from one source, which the per-email counter can't see (each guess lands
199
+ // on a different key). Limit is deliberately far above LOGIN_RATE_LIMIT's per-account 10/5min
200
+ // so a shared network (office NAT) never blocks legitimate players signing into their own
201
+ // accounts. Overridable via IDENTITY_OPTIONS.loginIpRateLimit.
202
+ const DEFAULT_LOGIN_IP_RATE_LIMIT = {
203
+ limit: 100,
204
+ windowMs: 15 * MINUTE_MS,
205
+ onUnavailable: 'deny',
206
+ };
96
207
  const REGISTER_RATE_LIMIT = { limit: 5, windowMs: 15 * MINUTE_MS };
208
+ // Keyed on the caller, not the handle: the abuse shape here is enumerating many
209
+ // usernames from one client, not probing one username repeatedly.
210
+ const USERNAME_AVAILABILITY_RATE_LIMIT = { limit: 30, windowMs: MINUTE_MS };
97
211
  const PASSWORD_RESET_REQUEST_RATE_LIMIT = { limit: 3, windowMs: 15 * MINUTE_MS };
98
212
  const PASSWORD_RESET_RATE_LIMIT = {
99
213
  limit: 5,
100
214
  windowMs: 15 * MINUTE_MS,
101
215
  onUnavailable: 'deny',
102
216
  };
217
+ const PASSWORD_RESET_VERIFY_RATE_LIMIT = {
218
+ limit: 5,
219
+ windowMs: 5 * MINUTE_MS,
220
+ onUnavailable: 'deny',
221
+ };
103
222
  const VERIFY_2FA_RATE_LIMIT = { limit: 5, windowMs: 5 * MINUTE_MS, onUnavailable: 'deny' };
104
- const EMAIL_VERIFICATION_RATE_LIMIT = { limit: 3, windowMs: 15 * MINUTE_MS };
105
- const VERIFY_EMAIL_RATE_LIMIT = { limit: 5, windowMs: 15 * MINUTE_MS };
223
+ // Fails closed with the verify budget below: better-auth issues a fresh code (and a fresh
224
+ // 3-attempt counter) per resend, so an unbounded resend loop is an unbounded guess budget.
225
+ const EMAIL_VERIFICATION_RATE_LIMIT = {
226
+ limit: 3,
227
+ windowMs: 15 * MINUTE_MS,
228
+ onUnavailable: 'deny',
229
+ };
230
+ // Fails closed like the other secret-guessing budgets: the emailed code is six digits,
231
+ // so an unthrottled window is a brute-force window, not a degraded-UX window.
232
+ const VERIFY_EMAIL_RATE_LIMIT = {
233
+ limit: 5,
234
+ windowMs: 15 * MINUTE_MS,
235
+ onUnavailable: 'deny',
236
+ };
106
237
  const CHANGE_PASSWORD_RATE_LIMIT = { limit: 5, windowMs: 15 * MINUTE_MS };
238
+ // How long after a password change to re-sweep the user's sessions for a row that a
239
+ // concurrent old-password sign-in raced in just after better-auth's revoke ran. This
240
+ // is the residual exposure window; keep it short.
241
+ const RACED_SESSION_SWEEP_DELAY_MS = 2_000;
242
+ // better-auth's `createSession` gives a `dontRememberMe` session this fixed TTL
243
+ // (`getDate(3600 * 24, 'sec')`). `revokeOtherSessions` mints the caller's replacement
244
+ // session without that flag, so we re-apply the clamp when the request carries the
245
+ // `dont_remember` cookie. Matches `SESSION_TTL_MS` in phone-login.service.
246
+ const DONT_REMEMBER_SESSION_TTL_MS = 24 * 60 * 60 * 1000;
107
247
  const TWO_FACTOR_PASSWORD_RATE_LIMIT = { limit: 5, windowMs: 5 * MINUTE_MS };
248
+ // Fails closed: every call spends real money on an `sms` enrolment and fills a mailbox
249
+ // on an `email` one, and better-auth issues a fresh code per send, so an unbounded
250
+ // resend loop is both a toll-fraud channel and an unbounded guess budget.
251
+ const SEND_2FA_OTP_RATE_LIMIT = {
252
+ limit: 3,
253
+ windowMs: 5 * MINUTE_MS,
254
+ onUnavailable: 'deny',
255
+ };
256
+ const ANTI_PHISHING_CODE_RATE_LIMIT = {
257
+ limit: 5,
258
+ windowMs: 5 * MINUTE_MS,
259
+ onUnavailable: 'deny',
260
+ };
261
+ const FAKE_LOGIN_SHADOW_TTL_MS = 7 * 24 * 60 * 60 * 1000;
262
+ function loginShadowKey(email) {
263
+ return `login-shadow:${email}`;
264
+ }
265
+ const loginShadowLogger = createLogger('login-shadow');
266
+ const identityLogger = createLogger('identity');
267
+ function hasErrorCode(error, code) {
268
+ if (typeof error !== 'object' || error === null || !('data' in error)) {
269
+ return false;
270
+ }
271
+ const data = error.data;
272
+ return typeof data === 'object' && data !== null && 'code' in data && data.code === code;
273
+ }
108
274
  function computeLockoutState({ attempts, maxAttempts, durationMs, nowMs, }) {
109
275
  const isLocking = attempts >= maxAttempts;
110
276
  return { isLocking, lockoutUntil: isLocking ? new Date(nowMs + durationMs) : null };
111
277
  }
112
- // A finite rgBlockedUntil in the past = a lapsed cooling-off; a null one = indefinite
113
- // (self-exclusion / permanent). Blocked only while set and not elapsed.
114
- function isRgBlocked(u) {
115
- return u.rgBlocked && (u.rgBlockedUntil === null || u.rgBlockedUntil > new Date());
116
- }
117
278
  /**
118
279
  * Thin wrapper over the shared better-auth instance (register/login/2FA/
119
280
  * password/email flows) that layers on platform-specific policy better-auth
@@ -127,23 +288,104 @@ export class IdentityService {
127
288
  auth;
128
289
  drizzle;
129
290
  events;
130
- email;
291
+ identityReader;
292
+ mailDispatch;
131
293
  options;
132
294
  limiter;
133
295
  platformConfig;
134
- constructor({ drizzle, events, email, options, limiter, platformConfig }) {
296
+ playerProvisioning;
297
+ geoCheck;
298
+ cache;
299
+ // Addresses whose reset code is being sent because a sign-up hit an existing account.
300
+ // Held only for the duration of that send: `requestPasswordResetEmailOTP` drives
301
+ // `sendVerificationOTP` -> `render` inside the same await, so the flag is read before
302
+ // the `finally` clears it. Not cache-backed - it never has to outlive the call or
303
+ // cross a process.
304
+ existingAccountSignUps = new Set();
305
+ trustedDevices;
306
+ twoFactorLockout;
307
+ twoFactorDelivery;
308
+ sessions;
309
+ constructor({ drizzle, events, identityReader, mailDispatch, options, limiter, platformConfig, geoCheck, playerProvisioning, cache, trustedDevices, twoFactorLockout, twoFactorDelivery, sessions, }) {
135
310
  this.drizzle = drizzle;
136
311
  this.events = events;
137
- this.email = email;
312
+ this.identityReader = identityReader;
313
+ this.mailDispatch = mailDispatch;
138
314
  this.options = options;
139
315
  this.limiter = limiter;
140
316
  this.platformConfig = platformConfig;
317
+ this.geoCheck = geoCheck;
318
+ this.playerProvisioning = playerProvisioning;
319
+ this.cache = cache;
320
+ this.trustedDevices = trustedDevices;
321
+ this.twoFactorLockout = twoFactorLockout;
322
+ this.twoFactorDelivery = twoFactorDelivery;
323
+ this.sessions = sessions;
141
324
  this.auth = createAuth({
142
325
  db: drizzle.db,
143
326
  schema: { user, session, account, verification, twoFactor },
144
- ...(email ? { sendEmail: (args) => email.send(args) } : {}),
327
+ ...(mailDispatch
328
+ ? {
329
+ dispatchOtpMail: async ({ to, template, recipientName, antiPhishingCode }) => {
330
+ const idempotencyKey = `otp:${template.key}:${randomUUID()}`;
331
+ const recipient = await this.findUserByEmail(to);
332
+ if (recipient) {
333
+ await mailDispatch.toUser({ userId: recipient.id, template, idempotencyKey });
334
+ return;
335
+ }
336
+ await mailDispatch.toAddress({
337
+ email: to,
338
+ template,
339
+ idempotencyKey,
340
+ ...(recipientName !== undefined ? { recipientName } : {}),
341
+ ...(antiPhishingCode !== undefined ? { antiPhishingCode } : {}),
342
+ });
343
+ },
344
+ }
345
+ : {}),
346
+ // Binds the plugin's OTP hook to the transport fan-out. Without it better-auth
347
+ // still mints codes for the `email`/`sms` methods and drops them on the floor.
348
+ twoFactor: { sendOtp: (args) => twoFactorDelivery.deliver(args) },
349
+ requireEmailVerification: this.platformConfig?.registration?.requireEmailVerification ?? false,
350
+ isExistingAccountSignUp: (lookupEmail) => this.existingAccountSignUps.has(lookupEmail.toLowerCase()),
351
+ isAdminPasswordReset: (lookupEmail) => this.isAdminPasswordReset(lookupEmail),
352
+ onExistingUserSignUp: async (existing) => {
353
+ const key = existing.email.toLowerCase();
354
+ this.existingAccountSignUps.add(key);
355
+ try {
356
+ const response = await this.api.requestPasswordResetEmailOTP({
357
+ body: { email: existing.email },
358
+ headers: new Headers(),
359
+ asResponse: true,
360
+ });
361
+ await ensureOk(response);
362
+ }
363
+ finally {
364
+ this.existingAccountSignUps.delete(key);
365
+ }
366
+ },
367
+ onPasswordReset: async (resetUser) => {
368
+ await this.drizzle.db
369
+ .update(user)
370
+ .set({ passwordMeetsPolicy: true })
371
+ .where(eq(user.id, resetUser.id));
372
+ this.events.emit('identity.password.reset', {
373
+ userId: resetUser.id,
374
+ playerId: await this.identityReader.getPlayerIdByUserIdSafe(resetUser.id),
375
+ ...getCurrentClientMeta(),
376
+ });
377
+ await this.clearLockout(resetUser.id);
378
+ },
145
379
  });
146
380
  }
381
+ async findUserByEmail(email) {
382
+ const [row] = await this.drizzle.db
383
+ .select({ id: user.id })
384
+ .from(user)
385
+ .where(eq(user.email, email.toLowerCase()))
386
+ .limit(1);
387
+ return row;
388
+ }
147
389
  get api() {
148
390
  // Library boundary: the admin/organization plugin endpoints aren't on better-auth's
149
391
  // base `api` type. Sanctioned cast, see conventions.
@@ -156,21 +398,199 @@ export class IdentityService {
156
398
  }
157
399
  }
158
400
  async currentUserId(headers) {
159
- const session = await this.auth.api.getSession({ headers });
160
- return session?.user?.id ?? null;
401
+ return (await this.currentSession(headers))?.userId ?? null;
402
+ }
403
+ // Both the caller's userId and the id of the session row they are authenticating
404
+ // with, for handlers that must tell the caller's own device apart from their others
405
+ // (eg sparing the acting session from a revoke-all).
406
+ async currentSession(headers) {
407
+ const resolved = await this.auth.api.getSession({ headers });
408
+ const userId = resolved?.user?.id;
409
+ return userId ? { userId, sessionId: resolved?.session?.id } : null;
410
+ }
411
+ async securityControlsFor(userId) {
412
+ // 0 when trusted devices are not wired at all (some deployments), matching what
413
+ // `trust()` itself does with a non-positive `trustedDeviceDays`: a client reading 0
414
+ // knows the offer is not real anywhere it might otherwise render one.
415
+ const controls = await getSecurityControls(this.drizzle, userId, this.trustedDevices?.getTrustedDeviceDays() ?? 0);
416
+ if (!controls) {
417
+ throw new UserNotFoundError(userId);
418
+ }
419
+ return controls;
161
420
  }
162
- async register(input, reqHeaders, resHeaders) {
163
- await assertRateLimit(this.limiter, `register:${input.email.toLowerCase()}`, REGISTER_RATE_LIMIT);
421
+ // Same gate as password login and phone login, from the one shared implementation.
422
+ assertAccountNotBlocked(account, meta) {
423
+ return assertAccountNotBlocked({ drizzle: this.drizzle, events: this.events }, account, meta, {
424
+ revokeSessions: true,
425
+ errorData: { rgBlocked: { code: 'RG_BLOCKED' }, suspended: { code: 'ACCOUNT_SUSPENDED' } },
426
+ });
427
+ }
428
+ /**
429
+ * Emitted on every registration attempt that produced no account. The audit trail is
430
+ * the one place that records what actually happened - the HTTP response deliberately
431
+ * does not, because a truthful answer on a known address is an enumeration oracle.
432
+ */
433
+ emitRegistrationFailed(reason, input, { ip, userAgent }) {
434
+ this.events.emit('identity.user.registration.failed', {
435
+ email: input.email,
436
+ username: input.username,
437
+ reason,
438
+ ip,
439
+ userAgent,
440
+ });
441
+ }
442
+ async register(input, reqHeaders) {
443
+ // Read before the config guard: a rejected attempt is audited too, and an audit row
444
+ // with no origin is barely a record.
445
+ const { ip, userAgent } = extractClientMeta(reqHeaders);
446
+ const meta = { ip, userAgent };
447
+ const registration = this.platformConfig?.registration;
448
+ const provisioning = this.playerProvisioning;
449
+ if (!registration || !provisioning) {
450
+ this.emitRegistrationFailed('registration_disabled', input, meta);
451
+ throw new ORPCError('FORBIDDEN', { message: 'Registration is unavailable' });
452
+ }
453
+ // `assertRateLimit` throws and is shared by a dozen call sites, so the emit wraps it
454
+ // here rather than moving into it.
455
+ try {
456
+ await assertRateLimit(this.limiter, `register:${input.email.toLowerCase()}`, REGISTER_RATE_LIMIT);
457
+ await assertRateLimit(this.limiter, `register-ip:${ip ?? 'unknown'}`, REGISTER_RATE_LIMIT);
458
+ }
459
+ catch (err) {
460
+ this.emitRegistrationFailed('rate_limited', input, meta);
461
+ throw err;
462
+ }
463
+ if (this.geoCheck && !(await this.geoCheck.checkRegistration(ip)).allowed) {
464
+ this.emitRegistrationFailed('geo_blocked', input, meta);
465
+ throw new ORPCError('FORBIDDEN', { message: 'Registration is unavailable' });
466
+ }
164
467
  const headers = nodeHeadersToHeaders(reqHeaders);
165
- const authResponse = await this.auth.api.signUpEmail({
166
- body: { email: input.email, password: input.password, name: input.name },
468
+ const authResponse = await this.api.signUpEmail({
469
+ body: {
470
+ email: input.email,
471
+ password: input.password,
472
+ name: input.username,
473
+ username: input.username,
474
+ },
167
475
  headers,
168
476
  asResponse: true,
169
477
  });
170
- this.forwardCookies(authResponse, resHeaders);
478
+ if (!authResponse.ok) {
479
+ // The `lower(username)` unique index is the only arbiter - a pre-flight check
480
+ // could not close the race anyway, so the taken handle is read off the failure.
481
+ if (await this.findUserIdByUsername(input.username)) {
482
+ this.emitRegistrationFailed('username_taken', input, meta);
483
+ throw new UsernameConflictError();
484
+ }
485
+ // `ensureOk` always throws on a non-ok response, so emitting first needs no catch.
486
+ this.emitRegistrationFailed('error', input, meta);
487
+ await ensureOk(authResponse, { genericMessage: 'Registration is unavailable' });
488
+ }
171
489
  const body = (await authResponse.json());
172
- this.events.emit('identity.user.registered', { userId: body.user.id });
173
- return { user: toUser(body.user) };
490
+ // A known address gets an indistinguishable success response (and a reset mail)
491
+ // rather than a new account, so only a genuinely new user is provisioned.
492
+ if ((await this.findUserIdByEmail(input.email)) !== body.user.id) {
493
+ // The known-address branch: no account was created, so the attempt failed even
494
+ // though the caller is told it succeeded. Only the audit trail says so.
495
+ this.emitRegistrationFailed('email_already_registered', input, meta);
496
+ return { status: 'check-email' };
497
+ }
498
+ await this.drizzle.db
499
+ .update(user)
500
+ .set({ passwordMeetsPolicy: true })
501
+ .where(eq(user.id, body.user.id));
502
+ let consent;
503
+ try {
504
+ consent = await this.recordRegistrationConsent(provisioning, body.user.id, registration.termsVersion, { ip, userAgent });
505
+ }
506
+ catch (err) {
507
+ this.emitRegistrationFailed('error', input, meta);
508
+ throw err;
509
+ }
510
+ const { playerId, consentStored } = consent;
511
+ // After the consent write, which is what materialises the player row the zone lands on.
512
+ // No session yet, but the browser is here now and a first login may be days away.
513
+ await captureTimezone(this.playerProvisioning, body.user.id, input.timezone);
514
+ this.events.emit('identity.user.registered', {
515
+ userId: body.user.id,
516
+ playerId: playerId ?? (await this.identityReader.getPlayerIdByUserIdSafe(body.user.id)),
517
+ // Only claimed when the consent row was actually written - a discarded capture
518
+ // must not leave an audit trail implying evidence that does not exist.
519
+ ...(consentStored
520
+ ? {
521
+ termsVersion: registration.termsVersion,
522
+ acceptedTerms: input.acceptedTerms,
523
+ acceptedAge: input.acceptedAge,
524
+ }
525
+ : {}),
526
+ ip,
527
+ userAgent,
528
+ });
529
+ // Sent here rather than by better-auth's sendOnSignUp hook: that hook also fires on
530
+ // the synthetic duplicate-email response, mailing a live code to an address whose
531
+ // owner never asked for it - and `verifyEmail` signs that code's bearer in.
532
+ // A mail failure is logged, never surfaced: the account exists either way and the
533
+ // player can ask for a new code, so failing the call here would only mislead them.
534
+ const otpResponse = await this.api.sendVerificationOTP({
535
+ body: { email: input.email, type: 'email-verification' },
536
+ headers,
537
+ asResponse: true,
538
+ });
539
+ if (!otpResponse.ok) {
540
+ identityLogger.error({ userId: body.user.id, status: otpResponse.status }, 'verification code could not be sent - player must request a new one');
541
+ }
542
+ return { status: 'check-email' };
543
+ }
544
+ async findUserIdByUsername(username) {
545
+ const [row] = await this.drizzle.db
546
+ .select({ id: user.id })
547
+ .from(user)
548
+ .where(eq(sql `lower(${user.username})`, username.toLowerCase()))
549
+ .limit(1);
550
+ return row?.id ?? null;
551
+ }
552
+ async findUserIdByEmail(email) {
553
+ const [row] = await this.drizzle.db
554
+ .select({ id: user.id })
555
+ .from(user)
556
+ .where(eq(user.email, email.toLowerCase()))
557
+ .limit(1);
558
+ return row?.id ?? null;
559
+ }
560
+ /**
561
+ * Better Auth commits the user inside its own transaction before returning, so a
562
+ * failure here would otherwise leave an account with no consent record. The user is
563
+ * deleted instead (sessions and accounts cascade), making registration all-or-nothing.
564
+ */
565
+ async recordRegistrationConsent(provisioning, userId, termsVersion, { ip, userAgent }) {
566
+ const now = new Date();
567
+ let outcome;
568
+ try {
569
+ outcome = await provisioning.createForRegistration({
570
+ userId,
571
+ termsVersion,
572
+ termsAcceptedAt: now,
573
+ ageAcceptedAt: now,
574
+ registrationIp: ip,
575
+ registrationUserAgent: userAgent,
576
+ });
577
+ }
578
+ catch (err) {
579
+ identityLogger.error({ err, userId }, 'registration consent write failed - rolling back user');
580
+ await this.drizzle.db.delete(user).where(eq(user.id, userId));
581
+ throw new ORPCError('INTERNAL_SERVER_ERROR', { message: 'Registration is unavailable' });
582
+ }
583
+ if (!outcome.created) {
584
+ // A player row already existed, so this consent capture was discarded. Never
585
+ // silent: the acceptance evidence is a compliance record.
586
+ identityLogger.error({ userId, termsVersion }, 'registration consent not stored - player row already existed');
587
+ }
588
+ return { playerId: outcome.playerId ?? null, consentStored: outcome.created };
589
+ }
590
+ async usernameAvailable(username, reqHeaders) {
591
+ const { ip } = extractClientMeta(reqHeaders);
592
+ await assertRateLimit(this.limiter, `check-username:${ip ?? 'unknown'}`, USERNAME_AVAILABILITY_RATE_LIMIT);
593
+ return { available: !(await this.findUserIdByUsername(username)) };
174
594
  }
175
595
  /**
176
596
  * Credentials are verified FIRST; the RG login block is checked only AFTER
@@ -185,11 +605,33 @@ export class IdentityService {
185
605
  * read a stale count and slip past the lockout threshold.
186
606
  */
187
607
  async login(input, reqHeaders, resHeaders) {
608
+ const { ip, userAgent } = extractClientMeta(reqHeaders);
188
609
  const headers = nodeHeadersToHeaders(reqHeaders);
189
- const ip = clientIp(headers);
190
- const userAgent = headers.get('user-agent') || null;
191
610
  // better-auth lowercases emails on write, so the lockout lookup must match on the same form.
192
611
  const email = input.email.toLowerCase();
612
+ // IP gate runs before the per-email one: it is the broad, cheap-to-refill resource
613
+ // (100/15min) guarding the narrow, scarce one (10/5min) - an IP that has already
614
+ // tripped its own throttle must not keep spending a targeted email's budget on every
615
+ // further attempt. Falls back to a shared 'unknown' bucket when the IP can't be
616
+ // derived, matching every sibling per-IP key in this file (register-ip:,
617
+ // verify-email-ip:, change-email-ip:, confirm-email-change-ip:) - skipping the gate
618
+ // outright on a missing IP would let an attacker disable this protection for free by
619
+ // simply not sending the header.
620
+ //
621
+ // `ip` is X-Real-IP as `createApp` leaves it: the socket address, unless the peer is a
622
+ // configured trusted proxy (`trustedProxies` / TRUSTED_PROXIES), in which case it is
623
+ // derived from that proxy's appended X-Forwarded-For address. A direct caller cannot
624
+ // choose its bucket by rotating either forwarding header.
625
+ const ipRateLimitOptions = this.options?.loginIpRateLimit;
626
+ if (ipRateLimitOptions?.enabled ?? true) {
627
+ await assertRateLimit(this.limiter, makeLoginIpRateLimitKey(ip ?? 'unknown'), {
628
+ ...DEFAULT_LOGIN_IP_RATE_LIMIT,
629
+ ...(ipRateLimitOptions?.limit !== undefined ? { limit: ipRateLimitOptions.limit } : {}),
630
+ ...(ipRateLimitOptions?.windowMs !== undefined
631
+ ? { windowMs: ipRateLimitOptions.windowMs }
632
+ : {}),
633
+ });
634
+ }
193
635
  await assertRateLimit(this.limiter, makeLoginRateLimitKey(email), LOGIN_RATE_LIMIT);
194
636
  const configLockoutEnabled = this.options?.lockout?.enabled ?? true;
195
637
  // Read once for the lockout budget, the admin-bypass check, and the RG login gate
@@ -200,9 +642,13 @@ export class IdentityService {
200
642
  id: user.id,
201
643
  failedLoginAttempts: user.failedLoginAttempts,
202
644
  lockoutUntil: user.lockoutUntil,
645
+ lockoutCount: user.lockoutCount,
646
+ lastLockoutAt: user.lastLockoutAt,
647
+ lastFailedLoginAt: user.lastFailedLoginAt,
203
648
  role: user.role,
204
649
  rgBlocked: user.rgBlocked,
205
650
  rgBlockedUntil: user.rgBlockedUntil,
651
+ requireTwoFactorOnLogin: user.requireTwoFactorOnLogin,
206
652
  })
207
653
  .from(user)
208
654
  .where(eq(user.email, email))
@@ -211,8 +657,9 @@ export class IdentityService {
211
657
  const isAdmin = existingUser?.role === 'admin';
212
658
  const bypassForAdmins = this.options?.lockout?.bypassForAdmins ?? false;
213
659
  const lockoutEnabled = configLockoutEnabled && !(isAdmin && bypassForAdmins);
660
+ const nowMs = Date.now();
214
661
  if (lockoutEnabled && existingUser?.lockoutUntil) {
215
- if (new Date(existingUser.lockoutUntil) > new Date()) {
662
+ if (new Date(existingUser.lockoutUntil) > new Date(nowMs)) {
216
663
  throw createAccountLockedError(new Date(existingUser.lockoutUntil));
217
664
  }
218
665
  // Lock window elapsed: clear it so the next failure starts from a fresh budget
@@ -220,36 +667,103 @@ export class IdentityService {
220
667
  await this.clearLockout(existingUser.id);
221
668
  existingUser = { ...existingUser, failedLoginAttempts: 0, lockoutUntil: null };
222
669
  }
670
+ if (lockoutEnabled &&
671
+ existingUser &&
672
+ hasFailedLoginWindowExpired(existingUser.lastFailedLoginAt, existingUser.lastLockoutAt, nowMs)) {
673
+ await this.resetLockoutTier(existingUser.id);
674
+ existingUser = {
675
+ ...existingUser,
676
+ failedLoginAttempts: 0,
677
+ lockoutUntil: null,
678
+ lockoutCount: 0,
679
+ lastLockoutAt: null,
680
+ lastFailedLoginAt: null,
681
+ };
682
+ }
683
+ let fakeLoginShadow;
684
+ if (lockoutEnabled && !existingUser) {
685
+ fakeLoginShadow = await this.loginShadowGet(loginShadowKey(email));
686
+ if (fakeLoginShadow?.lastFailedLoginAt) {
687
+ const lastFailedLoginAt = new Date(fakeLoginShadow.lastFailedLoginAt);
688
+ if (hasFailedLoginWindowExpired(lastFailedLoginAt, null, nowMs)) {
689
+ fakeLoginShadow = {
690
+ failedAttempts: 0,
691
+ lockoutUntil: null,
692
+ lockoutCount: 0,
693
+ lastLockoutAt: null,
694
+ lastFailedLoginAt: null,
695
+ };
696
+ }
697
+ }
698
+ if (fakeLoginShadow?.lockoutUntil) {
699
+ if (new Date(fakeLoginShadow.lockoutUntil) > new Date()) {
700
+ throw createAccountLockedError(new Date(fakeLoginShadow.lockoutUntil));
701
+ }
702
+ fakeLoginShadow = { ...fakeLoginShadow, failedAttempts: 0, lockoutUntil: null };
703
+ }
704
+ }
705
+ // better-auth honours its trust-device cookie on its own and offers no way to revoke
706
+ // one. The revocable half of a trusted device is the row this module keeps, so a login
707
+ // presenting the cookie without a live row has to fall back to the full challenge.
708
+ let signInHeaders = headers;
709
+ if (existingUser && this.trustedDevices && hasTrustDeviceCookie(headers)) {
710
+ // "Require 2FA every login" outranks the cookie outright, so no lookup is needed -
711
+ // how well this browser is trusted stops mattering while the preference holds.
712
+ const trusted = !existingUser.requireTwoFactorOnLogin &&
713
+ (await this.trustedDevices.isTrusted(existingUser.id, userAgent));
714
+ if (!trusted) {
715
+ signInHeaders = withoutTrustDeviceCookie(headers);
716
+ }
717
+ }
223
718
  try {
224
719
  const authResponse = await this.auth.api.signInEmail({
225
720
  body: { email, password: input.password, rememberMe: input.rememberMe },
226
- headers,
721
+ headers: signInHeaders,
227
722
  asResponse: true,
228
723
  });
229
724
  await ensureOk(authResponse);
230
- // RG login block, applied only AFTER credentials verify so a pre-auth probe can't
231
- // distinguish a restricted account from a wrong password. Kill the session
232
- // better-auth just issued and never forward its cookie. Cooling-off auto-expires
233
- // here once rgBlockedUntil elapses (no unblock job).
234
- if (existingUser && isRgBlocked(existingUser)) {
235
- await this.drizzle.db
236
- .update(session)
237
- .set({ expiresAt: new Date() })
238
- .where(eq(session.userId, existingUser.id));
239
- this.events.emit('rg.exclusion.login_blocked', { userId: existingUser.id, ip, userAgent });
240
- throw new ORPCError('FORBIDDEN', {
241
- message: 'Account access is currently restricted (responsible gambling).',
242
- });
243
- }
725
+ // RG and backoffice blocks, applied only AFTER credentials verify so a pre-auth
726
+ // probe can't distinguish a restricted account from a wrong password. Resolves
727
+ // playerId once, so the eventual login success event can carry it too.
728
+ const playerId = existingUser
729
+ ? await this.assertAccountNotBlocked(existingUser, { ip, userAgent })
730
+ : null;
244
731
  this.forwardCookies(authResponse, resHeaders);
245
732
  const body = (await authResponse.json());
246
733
  if (body.twoFactorRedirect || !body.user || !body.token) {
247
- return { twoFactorRedirect: true };
734
+ // The challenge screen has to know whether to ask for an authenticator code or
735
+ // to push one, and there is no session yet to read the account's method from.
736
+ // Naming it here reveals nothing the challenge would not show anyway. Same for
737
+ // the trust window: an operator's configured length is not account-specific.
738
+ return {
739
+ twoFactorRedirect: true,
740
+ trustedDeviceDays: this.trustedDevices?.getTrustedDeviceDays() ?? 0,
741
+ ...(existingUser
742
+ ? { twoFactorMethod: await this.resolveTwoFactorMethod(existingUser.id) }
743
+ : {}),
744
+ };
248
745
  }
249
746
  if (lockoutEnabled && existingUser) {
250
747
  await this.clearLockout(existingUser.id);
251
748
  }
252
- this.events.emit('identity.user.login', { userId: body.user.id, ip, userAgent });
749
+ await this.drizzle.db
750
+ .update(session)
751
+ .set({ ipAddress: ip, userAgent })
752
+ .where(eq(session.token, body.token));
753
+ this.events.emit('identity.user.login', {
754
+ userId: body.user.id,
755
+ playerId,
756
+ ip,
757
+ userAgent,
758
+ });
759
+ this.events.emit('identity.authentication.succeeded', {
760
+ userId: body.user.id,
761
+ playerId,
762
+ method: 'password',
763
+ ip,
764
+ userAgent,
765
+ });
766
+ await captureTimezone(this.playerProvisioning, body.user.id, input.timezone);
253
767
  const sessionDurationSeconds = this.auth.options.session?.expiresIn ?? SESSION_DURATION_IN_SECONDS;
254
768
  const expiresAt = body.session?.expiresAt
255
769
  ? toIso(body.session.expiresAt)
@@ -257,42 +771,89 @@ export class IdentityService {
257
771
  return {
258
772
  user: toUser(body.user),
259
773
  session: { token: body.token, expiresAt },
774
+ security: makeLoginSecurityState({
775
+ failedLoginAttempts: 0,
776
+ maxAttempts: this.options?.lockout?.maxAttempts ?? DEFAULT_MAX_LOGIN_ATTEMPTS,
777
+ lockoutUntil: null,
778
+ }),
260
779
  };
261
780
  }
262
781
  catch (error) {
263
782
  // An RG block is not a credential failure - surface it as-is, without touching the
264
- // lockout budget or emitting login.failed (the RG event was already emitted).
265
- if (error instanceof ORPCError && error.code === 'FORBIDDEN') {
783
+ // lockout budget or emitting login.failed (the RG event was already emitted). Match on
784
+ // the RG_BLOCKED marker, not the bare FORBIDDEN code - ensureOk also maps a banned-user
785
+ // 403 (better-auth's admin plugin) to FORBIDDEN, and that path must still fall through
786
+ // to the generic branch below to emit login.failed.
787
+ if (error instanceof ORPCError &&
788
+ error.code === 'FORBIDDEN' &&
789
+ (hasErrorCode(error, 'RG_BLOCKED') || hasErrorCode(error, 'ACCOUNT_SUSPENDED'))) {
266
790
  throw error;
267
791
  }
268
792
  // Only a genuine credential rejection counts toward lockout - a transient DB/network
269
793
  // error must never lock the account out.
270
- const isCredentialFailure = error instanceof ORPCError && error.code === 'UNAUTHORIZED';
794
+ const isAccountLocked = error instanceof ORPCError &&
795
+ error.code === 'UNAUTHORIZED' &&
796
+ hasErrorCode(error, 'ACCOUNT_LOCKED');
797
+ const isCredentialFailure = error instanceof ORPCError && error.code === 'UNAUTHORIZED' && !isAccountLocked;
798
+ let attemptsRemaining;
271
799
  if (lockoutEnabled && existingUser && isCredentialFailure) {
272
800
  const maxAttempts = this.options?.lockout?.maxAttempts ?? DEFAULT_MAX_LOGIN_ATTEMPTS;
273
- const durationMs = this.options?.lockout?.durationMs ?? DEFAULT_LOCKOUT_DURATION_MS;
801
+ const fallbackDurationMs = this.options?.lockout?.durationMs ?? DEFAULT_LOCKOUT_DURATION_MS;
274
802
  // Atomic increment: concurrent failures can't each read a stale count and slip past
275
803
  // the threshold (the read-modify-write this replaces was bypassable under load).
276
804
  const [row] = await this.drizzle.db
277
805
  .update(user)
278
- .set({ failedLoginAttempts: sql `${user.failedLoginAttempts} + 1` })
806
+ .set({
807
+ failedLoginAttempts: sql `${user.failedLoginAttempts} + 1`,
808
+ lastFailedLoginAt: new Date(),
809
+ })
279
810
  .where(eq(user.id, existingUser.id))
280
811
  .returning({ failedLoginAttempts: user.failedLoginAttempts });
281
812
  const newAttempts = row?.failedLoginAttempts ?? existingUser.failedLoginAttempts + 1;
282
- const { isLocking, lockoutUntil } = computeLockoutState({
813
+ attemptsRemaining = Math.max(maxAttempts - newAttempts, 0);
814
+ const { isLocking } = computeLockoutState({
283
815
  attempts: newAttempts,
284
816
  maxAttempts,
285
- durationMs,
817
+ durationMs: fallbackDurationMs,
286
818
  nowMs: Date.now(),
287
819
  });
288
- if (isLocking && lockoutUntil) {
289
- await this.drizzle.db
820
+ if (isLocking) {
821
+ const nowMs = Date.now();
822
+ // Escalate the lockout duration for repeat offenders inside the 24h window.
823
+ const { tier, durationMs } = computeLockoutTier({
824
+ lockoutCount: existingUser.lockoutCount ?? 0,
825
+ lastFailedLoginAt: existingUser.lastFailedLoginAt ?? null,
826
+ fallbackLastLockoutAt: existingUser.lastLockoutAt ?? null,
827
+ nowMs,
828
+ fallbackDurationMs,
829
+ });
830
+ const lockoutUntil = new Date(nowMs + durationMs);
831
+ const [lockoutRow] = await this.drizzle.db
290
832
  .update(user)
291
- .set({ lockoutUntil })
292
- .where(eq(user.id, existingUser.id));
833
+ .set({ lockoutUntil, lockoutCount: tier, lastLockoutAt: new Date(nowMs) })
834
+ // Only the first request that reaches the threshold creates the lockout.
835
+ // Other concurrent failures must observe and return the winner's lockout
836
+ // instead of overwriting its tier or emitting a duplicate event.
837
+ .where(and(eq(user.id, existingUser.id), isNull(user.lockoutUntil)))
838
+ .returning({ lockoutUntil: user.lockoutUntil });
839
+ if (!lockoutRow) {
840
+ const [current] = await this.drizzle.db
841
+ .select({ lockoutUntil: user.lockoutUntil })
842
+ .from(user)
843
+ .where(eq(user.id, existingUser.id))
844
+ .limit(1);
845
+ if (current?.lockoutUntil) {
846
+ throw createAccountLockedError(current.lockoutUntil);
847
+ }
848
+ throw new ORPCError('INTERNAL_SERVER_ERROR', {
849
+ message: 'Unable to establish account lockout.',
850
+ });
851
+ }
852
+ await this.limiter?.reset(makeLoginRateLimitKey(email));
293
853
  this.events.emit('identity.user.lockout.triggered', {
294
854
  userId: existingUser.id,
295
855
  email,
856
+ tier,
296
857
  lockoutUntil: lockoutUntil.toISOString(),
297
858
  ip,
298
859
  userAgent,
@@ -300,8 +861,69 @@ export class IdentityService {
300
861
  throw createAccountLockedError(lockoutUntil);
301
862
  }
302
863
  }
864
+ else if (lockoutEnabled && !existingUser && isCredentialFailure) {
865
+ const maxAttempts = this.options?.lockout?.maxAttempts ?? DEFAULT_MAX_LOGIN_ATTEMPTS;
866
+ const fallbackDurationMs = this.options?.lockout?.durationMs ?? DEFAULT_LOCKOUT_DURATION_MS;
867
+ const newAttempts = (fakeLoginShadow?.failedAttempts ?? 0) + 1;
868
+ attemptsRemaining = Math.max(maxAttempts - newAttempts, 0);
869
+ const { isLocking } = computeLockoutState({
870
+ attempts: newAttempts,
871
+ maxAttempts,
872
+ durationMs: fallbackDurationMs,
873
+ nowMs: Date.now(),
874
+ });
875
+ if (isLocking) {
876
+ const nowMs = Date.now();
877
+ const { tier, durationMs } = computeLockoutTier({
878
+ lockoutCount: fakeLoginShadow?.lockoutCount ?? 0,
879
+ lastFailedLoginAt: fakeLoginShadow?.lastFailedLoginAt
880
+ ? new Date(fakeLoginShadow.lastFailedLoginAt)
881
+ : null,
882
+ fallbackLastLockoutAt: fakeLoginShadow?.lastLockoutAt
883
+ ? new Date(fakeLoginShadow.lastLockoutAt)
884
+ : null,
885
+ nowMs,
886
+ fallbackDurationMs,
887
+ });
888
+ const lockoutUntil = new Date(nowMs + durationMs);
889
+ await this.loginShadowSet(loginShadowKey(email), {
890
+ failedAttempts: newAttempts,
891
+ lockoutUntil: lockoutUntil.toISOString(),
892
+ lockoutCount: tier,
893
+ lastLockoutAt: new Date(nowMs).toISOString(),
894
+ lastFailedLoginAt: new Date(nowMs).toISOString(),
895
+ });
896
+ await this.limiter?.reset(makeLoginRateLimitKey(email));
897
+ throw createAccountLockedError(lockoutUntil);
898
+ }
899
+ await this.loginShadowSet(loginShadowKey(email), {
900
+ failedAttempts: newAttempts,
901
+ lockoutUntil: null,
902
+ lockoutCount: fakeLoginShadow?.lockoutCount ?? 0,
903
+ lastLockoutAt: fakeLoginShadow?.lastLockoutAt ?? null,
904
+ lastFailedLoginAt: new Date().toISOString(),
905
+ });
906
+ }
303
907
  const reason = isCredentialFailure ? 'invalid_credentials' : 'error';
304
- this.events.emit('identity.user.login.failed', { email, reason, ip, userAgent });
908
+ this.events.emit('identity.user.login.failed', {
909
+ email,
910
+ reason,
911
+ ip,
912
+ userAgent,
913
+ ...(attemptsRemaining !== undefined ? { attemptsRemaining } : {}),
914
+ });
915
+ if (isCredentialFailure && error instanceof ORPCError && attemptsRemaining !== undefined) {
916
+ const maxAttempts = this.options?.lockout?.maxAttempts ?? DEFAULT_MAX_LOGIN_ATTEMPTS;
917
+ const security = makeLoginSecurityState({
918
+ failedLoginAttempts: attemptsRemaining === undefined ? 0 : maxAttempts - attemptsRemaining,
919
+ maxAttempts,
920
+ lockoutUntil: null,
921
+ });
922
+ throw new ORPCError('UNAUTHORIZED', {
923
+ message: error.message,
924
+ data: { ...error.data, ...security },
925
+ });
926
+ }
305
927
  throw error;
306
928
  }
307
929
  }
@@ -311,7 +933,95 @@ export class IdentityService {
311
933
  .set({ failedLoginAttempts: 0, lockoutUntil: null })
312
934
  .where(eq(user.id, userId));
313
935
  }
314
- async unlockUser(userId, actorId) {
936
+ resetLockoutTier(userId) {
937
+ return this.drizzle.db
938
+ .update(user)
939
+ .set({
940
+ failedLoginAttempts: 0,
941
+ lockoutUntil: null,
942
+ lockoutCount: 0,
943
+ lastLockoutAt: null,
944
+ lastFailedLoginAt: null,
945
+ })
946
+ .where(eq(user.id, userId));
947
+ }
948
+ async loginShadowGet(key) {
949
+ if (!this.cache) {
950
+ return undefined;
951
+ }
952
+ try {
953
+ return await this.cache.get(key);
954
+ }
955
+ catch (err) {
956
+ loginShadowLogger.warn({ key, err }, 'login shadow cache read failed');
957
+ return undefined;
958
+ }
959
+ }
960
+ async loginShadowSet(key, value) {
961
+ if (!this.cache) {
962
+ return;
963
+ }
964
+ try {
965
+ await this.cache.set(key, value, { ttlMs: FAKE_LOGIN_SHADOW_TTL_MS });
966
+ }
967
+ catch (err) {
968
+ loginShadowLogger.warn({ key, err }, 'login shadow cache write failed');
969
+ }
970
+ }
971
+ adminPasswordResetMarkerKey(email) {
972
+ return `admin-password-reset:${email.toLowerCase()}`;
973
+ }
974
+ async isAdminPasswordReset(email) {
975
+ if (!this.cache) {
976
+ return false;
977
+ }
978
+ const key = this.adminPasswordResetMarkerKey(email);
979
+ try {
980
+ const isAdmin = (await this.cache.get(key)) === true;
981
+ if (isAdmin) {
982
+ await this.cache.delete(key);
983
+ }
984
+ return isAdmin;
985
+ }
986
+ catch (err) {
987
+ identityLogger.warn({ err }, 'admin password reset marker cache read failed');
988
+ return false;
989
+ }
990
+ }
991
+ async adminRequestPasswordReset(userId, actorId, meta) {
992
+ const existingUser = findOneOrThrow(await this.drizzle.db
993
+ .select({ id: user.id, email: user.email })
994
+ .from(user)
995
+ .where(eq(user.id, userId))
996
+ .limit(1), new UserNotFoundError(userId));
997
+ const email = existingUser.email.toLowerCase();
998
+ try {
999
+ await this.cache?.set(this.adminPasswordResetMarkerKey(email), true, { ttlMs: 120_000 });
1000
+ }
1001
+ catch (err) {
1002
+ identityLogger.warn({ email, err }, 'admin password reset marker cache write failed');
1003
+ }
1004
+ // Mirrors requestPasswordReset - the send failure is swallowed the same way.
1005
+ try {
1006
+ await this.api.requestPasswordResetEmailOTP({
1007
+ body: { email },
1008
+ headers: new Headers(),
1009
+ asResponse: true,
1010
+ });
1011
+ }
1012
+ catch {
1013
+ // intentionally ignored
1014
+ }
1015
+ this.events.emit('identity.password.admin_reset_requested', {
1016
+ userId,
1017
+ email,
1018
+ actorId,
1019
+ ip: meta?.ip ?? null,
1020
+ userAgent: meta?.userAgent ?? null,
1021
+ });
1022
+ return SUCCESS;
1023
+ }
1024
+ async unlockUser(userId, actorId, meta) {
315
1025
  const existingUser = findOneOrThrow(await this.drizzle.db
316
1026
  .select({
317
1027
  id: user.id,
@@ -332,10 +1042,13 @@ export class IdentityService {
332
1042
  previousLockoutUntil: existingUser.lockoutUntil
333
1043
  ? existingUser.lockoutUntil.toISOString()
334
1044
  : null,
1045
+ ip: meta?.ip ?? null,
1046
+ userAgent: meta?.userAgent ?? null,
335
1047
  });
336
1048
  return SUCCESS;
337
1049
  }
338
1050
  async logout(reqHeaders, resHeaders) {
1051
+ const { ip, userAgent } = extractClientMeta(reqHeaders);
339
1052
  const headers = nodeHeadersToHeaders(reqHeaders);
340
1053
  // Resolve the user BEFORE signOut so the audit log can attribute the logout.
341
1054
  const session = await this.auth.api.getSession({ headers });
@@ -343,7 +1056,12 @@ export class IdentityService {
343
1056
  const authResponse = await this.auth.api.signOut({ headers, asResponse: true });
344
1057
  this.forwardCookies(authResponse, resHeaders);
345
1058
  if (userId) {
346
- this.events.emit('identity.user.logout', { userId });
1059
+ this.events.emit('identity.user.logout', {
1060
+ userId,
1061
+ playerId: await this.identityReader.getPlayerIdByUserIdSafe(userId),
1062
+ ip,
1063
+ userAgent,
1064
+ });
347
1065
  }
348
1066
  return SUCCESS;
349
1067
  }
@@ -355,10 +1073,39 @@ export class IdentityService {
355
1073
  }
356
1074
  return toUser(session.user);
357
1075
  }
1076
+ /**
1077
+ * Starts enrolment. All three methods share the one secret better-auth mints here;
1078
+ * `method` only decides how the code that activates it arrives, and is written
1079
+ * before the send so the delivery hook knows where to route. better-auth flips
1080
+ * `twoFactorEnabled` only once the first code clears, so abandoning a first
1081
+ * enrolment leaves the account unprotected exactly as it was.
1082
+ *
1083
+ * A transport failure on the first send throws (see `sendOtpForCurrentMethod`)
1084
+ * after `two_factor_method` is already written, but that write is inert on its
1085
+ * own: `twoFactorStatus` reports it only once `enabled` is true, and the CONFLICT
1086
+ * guard below only fires once it is. The caller recovers by retrying either
1087
+ * `sendTwoFactorOtp` (resend) or this route again - both read the method that was
1088
+ * already persisted, so neither loses the player's choice.
1089
+ */
358
1090
  async enableTwoFactor(input, reqHeaders, resHeaders) {
359
1091
  const headers = nodeHeadersToHeaders(reqHeaders);
360
1092
  const userId = await this.currentUserId(headers);
361
1093
  await assertRateLimit(this.limiter, `enable2fa:${userId ?? 'anonymous'}`, TWO_FACTOR_PASSWORD_RATE_LIMIT);
1094
+ if (!userId) {
1095
+ throw new ORPCError('UNAUTHORIZED', { message: 'Not signed in' });
1096
+ }
1097
+ await this.assertMethodAvailable(userId, input.method);
1098
+ // There is no switch-in-place: a player changes method by disabling and enrolling
1099
+ // again. better-auth's enable leg deletes and recreates the `twoFactor` row with a
1100
+ // fresh secret and fresh backup codes, and marks it verified straight away when one
1101
+ // was already verified - so re-running it on a live account destroys the working
1102
+ // authenticator the moment the call lands, and abandoning the step strands the
1103
+ // player on a secret they never scanned with `two_factor_enabled` still true.
1104
+ if (await this.isTwoFactorEnabled(userId)) {
1105
+ throw new ORPCError('CONFLICT', {
1106
+ message: 'Two-factor authentication is already enabled. Disable it first to change method.',
1107
+ });
1108
+ }
362
1109
  const res = await this.api.enableTwoFactor({
363
1110
  body: { password: input.password },
364
1111
  headers,
@@ -367,29 +1114,381 @@ export class IdentityService {
367
1114
  await ensureOk(res);
368
1115
  this.forwardCookies(res, resHeaders);
369
1116
  const body = (await res.json());
370
- return { totpUri: body.totpURI, backupCodes: body.backupCodes };
1117
+ await this.setTwoFactorMethod(userId, input.method);
1118
+ if (input.method === 'app') {
1119
+ return { totpUri: body.totpURI, backupCodes: body.backupCodes };
1120
+ }
1121
+ // The first code has to reach the player before they can activate the method, so
1122
+ // the send belongs to enrolment rather than a separate call the client must know
1123
+ // to make. "Resend code" then replays it through sendTwoFactorOtp.
1124
+ const masked = await this.sendOtpForCurrentMethod(userId, headers, resHeaders);
1125
+ return { backupCodes: body.backupCodes, maskedDestination: masked };
1126
+ }
1127
+ /**
1128
+ * Re-sends the one-time code for an account on the `email` or `sms` method - the
1129
+ * "Resend code" action during enrolment, and the send leg of a login challenge.
1130
+ * Resolves its subject from a live session first and the pending-challenge cookie
1131
+ * second, because at login there is no session yet.
1132
+ */
1133
+ async sendTwoFactorOtp(reqHeaders, resHeaders) {
1134
+ const headers = nodeHeadersToHeaders(reqHeaders);
1135
+ const pendingCookie = twoFactorPendingCookieValue(headers);
1136
+ const userId = (await this.currentUserId(headers)) ??
1137
+ (await this.twoFactorLockout?.resolvePendingUserId(pendingCookie));
1138
+ if (!userId) {
1139
+ throw new ORPCError('UNAUTHORIZED', { message: 'Not signed in' });
1140
+ }
1141
+ await assertRateLimit(this.limiter, `send2faOtp:${userId}`, SEND_2FA_OTP_RATE_LIMIT);
1142
+ // An account inside a lockout window cannot spend a code, so minting one only
1143
+ // hands out fresh guesses - and, on `sms`, bills the operator for them.
1144
+ await this.twoFactorLockout?.assertNotLocked(userId);
1145
+ return { maskedDestination: await this.sendOtpForCurrentMethod(userId, headers, resHeaders) };
1146
+ }
1147
+ /** Whether a second factor is active, which method it uses, and where a code can go. */
1148
+ async twoFactorStatus(reqHeaders) {
1149
+ const headers = nodeHeadersToHeaders(reqHeaders);
1150
+ const userId = await this.currentUserId(headers);
1151
+ if (!userId) {
1152
+ throw new ORPCError('UNAUTHORIZED', { message: 'Not signed in' });
1153
+ }
1154
+ const [row] = await this.drizzle.db
1155
+ .select({
1156
+ email: user.email,
1157
+ phoneNumber: user.phoneNumber,
1158
+ phoneVerified: user.phoneVerified,
1159
+ twoFactorEnabled: user.twoFactorEnabled,
1160
+ twoFactorMethod: user.twoFactorMethod,
1161
+ })
1162
+ .from(user)
1163
+ .where(eq(user.id, userId))
1164
+ .limit(1);
1165
+ if (!row) {
1166
+ throw new UserNotFoundError(userId);
1167
+ }
1168
+ const enabled = row.twoFactorEnabled ?? false;
1169
+ return {
1170
+ enabled,
1171
+ // The column outlives an abandoned enrolment, so an account that never cleared
1172
+ // its first code must still read as having no active method.
1173
+ method: enabled ? (row.twoFactorMethod ?? null) : null,
1174
+ maskedEmail: maskEmail(row.email),
1175
+ maskedPhone: row.phoneVerified && row.phoneNumber ? maskPhone(row.phoneNumber) : null,
1176
+ };
1177
+ }
1178
+ /**
1179
+ * Rejects a method the account cannot actually receive a code on. Enrolling into
1180
+ * `sms` without a verified phone would mint a secret the player can never clear,
1181
+ * locking them out of their own account at the next login.
1182
+ */
1183
+ async assertMethodAvailable(userId, method) {
1184
+ if (method === 'app') {
1185
+ return;
1186
+ }
1187
+ const [row] = await this.drizzle.db
1188
+ .select({
1189
+ emailVerified: user.emailVerified,
1190
+ phoneNumber: user.phoneNumber,
1191
+ phoneVerified: user.phoneVerified,
1192
+ })
1193
+ .from(user)
1194
+ .where(eq(user.id, userId))
1195
+ .limit(1);
1196
+ // A code can only guard the account if the address it goes to is one the account
1197
+ // has proven it holds. `registration.requireEmailVerification` is off by default,
1198
+ // so an unverified or mistyped address would otherwise enrol and lock the player
1199
+ // out at the next login - the same failure the phone check already prevents.
1200
+ if (method === 'email' && !row?.emailVerified) {
1201
+ throw new ORPCError('BAD_REQUEST', {
1202
+ message: 'Verify your email address before using email for two-factor authentication',
1203
+ });
1204
+ }
1205
+ if (method === 'sms' && (!row?.phoneNumber || !row.phoneVerified)) {
1206
+ throw new ORPCError('BAD_REQUEST', {
1207
+ message: 'Add and verify a phone number before using SMS for two-factor authentication',
1208
+ });
1209
+ }
1210
+ }
1211
+ /**
1212
+ * The account's delivery method, defaulting to `app`: an enrolment that predates the
1213
+ * column reads as null, and every one of those was an authenticator.
1214
+ */
1215
+ async resolveTwoFactorMethod(userId) {
1216
+ const [row] = await this.drizzle.db
1217
+ .select({ twoFactorMethod: user.twoFactorMethod })
1218
+ .from(user)
1219
+ .where(eq(user.id, userId))
1220
+ .limit(1);
1221
+ return row?.twoFactorMethod ?? 'app';
1222
+ }
1223
+ async isTwoFactorEnabled(userId) {
1224
+ const [row] = await this.drizzle.db
1225
+ .select({ twoFactorEnabled: user.twoFactorEnabled })
1226
+ .from(user)
1227
+ .where(eq(user.id, userId))
1228
+ .limit(1);
1229
+ return row?.twoFactorEnabled ?? false;
1230
+ }
1231
+ async setTwoFactorMethod(userId, method) {
1232
+ await this.drizzle.db.update(user).set({ twoFactorMethod: method }).where(eq(user.id, userId));
1233
+ }
1234
+ verifyChallengeCode(method, body, headers) {
1235
+ return verifyChallengeCode(this.api, method, body, headers);
1236
+ }
1237
+ async sendOtpForCurrentMethod(userId, headers, resHeaders) {
1238
+ const destination = await this.twoFactorDelivery.describeDestination(userId);
1239
+ if (!destination) {
1240
+ throw new ORPCError('BAD_REQUEST', {
1241
+ message: 'This account does not receive two-factor codes by email or SMS',
1242
+ });
1243
+ }
1244
+ const res = await this.api.sendTwoFactorOTP({ body: {}, headers, asResponse: true });
1245
+ await ensureOk(res);
1246
+ // A 200 here means the code was minted, not that it left the building: the send
1247
+ // hook is wrapped in `.catch(logger.error)` upstream. Telling the player a code is
1248
+ // on its way when the transport just failed strands them on a screen waiting for
1249
+ // something that is never coming.
1250
+ const failure = this.twoFactorDelivery.takeFailure(userId);
1251
+ if (failure) {
1252
+ throw new ORPCError('SERVICE_UNAVAILABLE', {
1253
+ message: 'Could not send your verification code. Please try again.',
1254
+ cause: failure,
1255
+ });
1256
+ }
1257
+ this.forwardCookies(res, resHeaders);
1258
+ return destination.masked;
1259
+ }
1260
+ /**
1261
+ * Whether the account insists on a second factor every login. Read off the row rather
1262
+ * than passed in: mid-challenge there is no session yet, so the only handle on the
1263
+ * account is the id the pending cookie resolved to.
1264
+ */
1265
+ async requiresTwoFactorEveryLogin(userId) {
1266
+ if (!userId) {
1267
+ return false;
1268
+ }
1269
+ const [row] = await this.drizzle.db
1270
+ .select({ requireTwoFactorOnLogin: user.requireTwoFactorOnLogin })
1271
+ .from(user)
1272
+ .where(eq(user.id, userId))
1273
+ .limit(1);
1274
+ return row?.requireTwoFactorOnLogin ?? false;
371
1275
  }
372
1276
  async verifyTwoFactor(input, reqHeaders, resHeaders) {
1277
+ const { ip, userAgent } = extractClientMeta(reqHeaders);
373
1278
  const headers = nodeHeadersToHeaders(reqHeaders);
374
- const twoFactorKey = (await this.currentUserId(headers)) ?? twoFactorPendingCookieValue(headers) ?? 'anonymous';
1279
+ const pendingCookie = twoFactorPendingCookieValue(headers);
1280
+ const sessionUserId = await this.currentUserId(headers);
1281
+ const twoFactorKey = sessionUserId ?? pendingCookie ?? 'anonymous';
375
1282
  await assertRateLimit(this.limiter, `verify2fa:${twoFactorKey}`, VERIFY_2FA_RATE_LIMIT);
376
- const res = await this.api.verifyTOTP({
377
- body: { code: input.code },
378
- headers,
379
- asResponse: true,
380
- });
1283
+ const challengedUserId = sessionUserId ?? (await this.twoFactorLockout?.resolvePendingUserId(pendingCookie));
1284
+ if (challengedUserId) {
1285
+ await this.twoFactorLockout?.assertNotLocked(challengedUserId);
1286
+ }
1287
+ // A backup code is a single-use recovery credential, not a second factor to bind a
1288
+ // browser to: it clears the challenge but never buys the trust window. A pushed
1289
+ // `otp` is a real factor and does, the same as a live authenticator code.
1290
+ const trustDevice = input.trustDevice &&
1291
+ input.method !== 'backup_code' &&
1292
+ this.trustedDevices !== undefined &&
1293
+ !(await this.requiresTwoFactorEveryLogin(challengedUserId));
1294
+ const body = { code: input.code, trustDevice };
1295
+ const res = await this.verifyChallengeCode(input.method, body, headers);
1296
+ if (!res.ok && challengedUserId) {
1297
+ await this.twoFactorLockout?.recordFailure(challengedUserId, { ip, userAgent });
1298
+ }
381
1299
  await ensureOk(res);
1300
+ if (challengedUserId) {
1301
+ await this.twoFactorLockout?.reset(challengedUserId);
1302
+ }
382
1303
  this.forwardCookies(res, resHeaders);
383
- const userId = await this.currentUserId(headers);
1304
+ // better-auth rotates the session on a successful challenge, so the request cookie is
1305
+ // already dead here - the actor is the identity resolved before the call.
1306
+ const userId = challengedUserId ?? (await this.currentUserId(headers));
1307
+ // Ground truth for the caller: `trustDevice` already reflects backup-code and
1308
+ // require-2fa-every-login refusals, but only actually buys the cookie below, and
1309
+ // only when `userId` resolved. The client asked to trust this device and deserves to
1310
+ // know whether that request was honoured rather than silently dropped.
1311
+ let trustGranted = false;
384
1312
  if (userId) {
385
- this.events.emit('identity.2fa.enabled', { userId });
1313
+ const playerId = await this.identityReader.getPlayerIdByUserIdSafe(userId);
1314
+ // A challenge answered from a live session is the enrolment step: better-auth only
1315
+ // flips twoFactorEnabled once the first code clears. Every later verification is a
1316
+ // sign-in, which carries the pending cookie instead and must not re-announce setup.
1317
+ if (sessionUserId) {
1318
+ this.events.emit('identity.2fa.enabled', {
1319
+ userId,
1320
+ playerId,
1321
+ method: input.method,
1322
+ ip,
1323
+ userAgent,
1324
+ });
1325
+ }
1326
+ this.events.emit('identity.2fa.verified', {
1327
+ userId,
1328
+ playerId,
1329
+ method: input.method,
1330
+ trustedDevice: trustDevice,
1331
+ ip,
1332
+ userAgent,
1333
+ });
1334
+ if (!sessionUserId) {
1335
+ this.events.emit('identity.authentication.succeeded', {
1336
+ userId,
1337
+ playerId,
1338
+ method: input.method,
1339
+ ip,
1340
+ userAgent,
1341
+ });
1342
+ }
1343
+ if (trustDevice) {
1344
+ await this.trustedDevices?.trust(userId, { ip, userAgent });
1345
+ trustGranted = true;
1346
+ }
1347
+ await captureTimezone(this.playerProvisioning, userId, input.timezone);
1348
+ }
1349
+ return { ...SUCCESS, trustGranted };
1350
+ }
1351
+ /**
1352
+ * Grants this browser its trust window without a sign-out. better-auth issues the
1353
+ * trust cookie only on the sign-in leg of a challenge, so the grant has to replay
1354
+ * that leg: the account proves its password and a fresh second factor, and the
1355
+ * cookies better-auth returns are the ones the browser keeps.
1356
+ */
1357
+ async trustCurrentDevice(input, reqHeaders, resHeaders) {
1358
+ const { ip, userAgent } = extractClientMeta(reqHeaders);
1359
+ const headers = nodeHeadersToHeaders(reqHeaders);
1360
+ const userId = await this.currentUserId(headers);
1361
+ if (!userId) {
1362
+ throw new ORPCError('UNAUTHORIZED', { message: 'Not signed in' });
1363
+ }
1364
+ await assertRateLimit(this.limiter, `trustDevice:${userId}`, TWO_FACTOR_PASSWORD_RATE_LIMIT);
1365
+ // Granting trust the login path is contractually going to ignore would leave the
1366
+ // player with a device listed as trusted that still gets challenged every time.
1367
+ if (await this.requiresTwoFactorEveryLogin(userId)) {
1368
+ throw new ORPCError('UNPROCESSABLE_CONTENT', {
1369
+ message: 'Turn off two-factor on every login before trusting this device.',
1370
+ });
1371
+ }
1372
+ const [account] = await this.drizzle.db
1373
+ .select({ email: user.email })
1374
+ .from(user)
1375
+ .where(eq(user.id, userId))
1376
+ .limit(1);
1377
+ if (!account) {
1378
+ throw new UserNotFoundError(userId);
1379
+ }
1380
+ const signIn = await this.auth.api.signInEmail({
1381
+ body: { email: account.email, password: input.password },
1382
+ headers: withoutTrustDeviceCookie(headers),
1383
+ asResponse: true,
1384
+ });
1385
+ await ensureOk(signIn);
1386
+ const signInBody = (await signIn.json());
1387
+ if (signInBody.twoFactorRedirect !== true) {
1388
+ throw new ORPCError('BAD_REQUEST', {
1389
+ message: 'Two-factor authentication is not enabled for this account',
1390
+ });
1391
+ }
1392
+ // Only the cookies the challenge just issued: leaving the live session cookie in
1393
+ // place makes better-auth treat the call as a settings change and skip the trust.
1394
+ const challengeHeaders = new Headers(headers);
1395
+ challengeHeaders.set('cookie', requestCookieHeader(signIn));
1396
+ await this.twoFactorLockout?.assertNotLocked(userId);
1397
+ // Authenticator accounts only. This route replays a fresh sign-in leg, and
1398
+ // better-auth keys a pushed code by the pending-challenge cookie that leg mints -
1399
+ // so an `email`/`sms` account has no code that can answer this challenge, and
1400
+ // letting the call through would only spend its lockout budget on a credential it
1401
+ // is impossible to present. Refusing says so instead of failing as a wrong code.
1402
+ const challengeMethod = await resolveChallengeMethod(this.drizzle, userId);
1403
+ if (challengeMethod !== 'totp') {
1404
+ throw new ORPCError('CONFLICT', {
1405
+ message: 'Trusting this device requires an authenticator app.',
1406
+ });
386
1407
  }
1408
+ const verified = await this.verifyChallengeCode(challengeMethod, { code: input.code, trustDevice: true }, challengeHeaders);
1409
+ if (!verified.ok) {
1410
+ await this.twoFactorLockout?.recordFailure(userId, { ip, userAgent });
1411
+ }
1412
+ await ensureOk(verified);
1413
+ await this.twoFactorLockout?.reset(userId);
1414
+ this.forwardCookies(verified, resHeaders);
1415
+ await this.trustedDevices?.trust(userId, { ip, userAgent });
1416
+ const playerId = await this.identityReader.getPlayerIdByUserIdSafe(userId);
1417
+ this.events.emit('identity.2fa.verified', {
1418
+ userId,
1419
+ playerId,
1420
+ method: challengeMethod,
1421
+ trustedDevice: true,
1422
+ ip,
1423
+ userAgent,
1424
+ });
1425
+ // The challenge leg above ran without a session cookie, so better-auth minted a new
1426
+ // session and this response carries it. That is a new authenticated session like any
1427
+ // other, and the security alert has to see it.
1428
+ this.events.emit('identity.authentication.succeeded', {
1429
+ userId,
1430
+ playerId,
1431
+ method: 'totp',
1432
+ ip,
1433
+ userAgent,
1434
+ });
387
1435
  return SUCCESS;
388
1436
  }
1437
+ /**
1438
+ * A step-up gate for the self-service routes that change standing 2FA state: the
1439
+ * caller has to clear a live authenticator code, not just the account password.
1440
+ * Routed through TwoFactorLockoutService so a hijacked session plus a reused
1441
+ * password cannot grind the second factor here the way the password-only paths let it.
1442
+ */
1443
+ async assertFreshSecondFactor(userId, headers, meta, code) {
1444
+ await this.twoFactorLockout?.assertNotLocked(userId);
1445
+ const res = await this.verifyChallengeCode(await resolveChallengeMethod(this.drizzle, userId), { code, trustDevice: false }, headers);
1446
+ if (!res.ok) {
1447
+ await this.twoFactorLockout?.recordFailure(userId, meta);
1448
+ }
1449
+ await ensureOk(res, { genericMessage: 'Invalid authenticator code' });
1450
+ await this.twoFactorLockout?.reset(userId);
1451
+ }
1452
+ async regenerateBackupCodes(input, reqHeaders, resHeaders) {
1453
+ const { ip, userAgent } = extractClientMeta(reqHeaders);
1454
+ const headers = nodeHeadersToHeaders(reqHeaders);
1455
+ const userId = await this.currentUserId(headers);
1456
+ await assertRateLimit(this.limiter, `backupCodes:${userId ?? 'anonymous'}`, TWO_FACTOR_PASSWORD_RATE_LIMIT);
1457
+ if (!userId) {
1458
+ throw new ORPCError('UNAUTHORIZED', { message: 'Not signed in' });
1459
+ }
1460
+ await this.assertFreshSecondFactor(userId, headers, { ip, userAgent }, input.code);
1461
+ const res = await this.api.generateBackupCodes({
1462
+ body: { password: input.password },
1463
+ headers,
1464
+ asResponse: true,
1465
+ });
1466
+ await ensureOk(res);
1467
+ this.forwardCookies(res, resHeaders);
1468
+ const body = (await res.json());
1469
+ // The old set is void the moment a new one is minted, so any device still trusted
1470
+ // off the old recovery flow re-verifies on its next login.
1471
+ await this.trustedDevices?.revokeAllForUser(userId, userId);
1472
+ this.events.emit('identity.2fa.backup_codes_regenerated', {
1473
+ userId,
1474
+ playerId: await this.identityReader.getPlayerIdByUserIdSafe(userId),
1475
+ ip,
1476
+ userAgent,
1477
+ });
1478
+ return { backupCodes: body.backupCodes };
1479
+ }
389
1480
  async disableTwoFactor(input, reqHeaders, resHeaders) {
1481
+ const { ip, userAgent } = extractClientMeta(reqHeaders);
390
1482
  const headers = nodeHeadersToHeaders(reqHeaders);
391
1483
  const userId = await this.currentUserId(headers);
392
1484
  await assertRateLimit(this.limiter, `disable2fa:${userId ?? 'anonymous'}`, TWO_FACTOR_PASSWORD_RATE_LIMIT);
1485
+ if (!userId) {
1486
+ throw new ORPCError('UNAUTHORIZED', { message: 'Not signed in' });
1487
+ }
1488
+ await this.assertFreshSecondFactor(userId, headers, { ip, userAgent }, input.code);
1489
+ // Read before the teardown clears it, so the audit trail records which method the
1490
+ // account was actually protected by rather than a blank.
1491
+ const disabledMethod = await resolveChallengeMethod(this.drizzle, userId);
393
1492
  const res = await this.api.disableTwoFactor({
394
1493
  body: { password: input.password },
395
1494
  headers,
@@ -397,19 +1496,37 @@ export class IdentityService {
397
1496
  });
398
1497
  await ensureOk(res);
399
1498
  this.forwardCookies(res, resHeaders);
400
- if (userId) {
401
- this.events.emit('identity.2fa.disabled', { userId });
402
- }
1499
+ await this.setTwoFactorMethod(userId, null);
1500
+ // Dropping the second factor takes every standing bypass with it, the same teardown
1501
+ // a Super Admin reset performs - a browser must not keep the access 2FA was guarding.
1502
+ await this.trustedDevices?.revokeAllForUser(userId, userId);
1503
+ await this.sessions?.revokeAllSessions(userId, userId, { ip, userAgent });
1504
+ // Must clear alongside the method: leaving it set strands the account with
1505
+ // `twoFactorEnabled: false, requireTwoFactorOnLogin: true` - a state `trustCurrentDevice`
1506
+ // reads as "still enforced" while `setRequireTwoFactorOnLogin` itself refuses to turn it
1507
+ // off without `twoFactorEnabled`, so nothing in the product could ever escape it again.
1508
+ await this.drizzle.db
1509
+ .update(user)
1510
+ .set({ requireTwoFactorOnLogin: false })
1511
+ .where(eq(user.id, userId));
1512
+ this.events.emit('identity.2fa.disabled', {
1513
+ userId,
1514
+ playerId: await this.identityReader.getPlayerIdByUserIdSafe(userId),
1515
+ method: disabledMethod,
1516
+ ip,
1517
+ userAgent,
1518
+ });
403
1519
  return SUCCESS;
404
1520
  }
405
1521
  async requestPasswordReset(input) {
406
- await assertRateLimit(this.limiter, `pwreset-req:${input.email.toLowerCase()}`, PASSWORD_RESET_REQUEST_RATE_LIMIT);
407
- // Always returns success - never reveal whether the email exists. The reset
408
- // email (if any) is delivered through the sendEmail hook -> notifications.
409
- // Any underlying error is swallowed for the same anti-enumeration reason.
1522
+ const email = input.email.toLowerCase();
1523
+ await assertRateLimit(this.limiter, makeRateLimitKey(RATE_LIMIT_KEYS.PASSWORD_RESET_REQUEST, email), PASSWORD_RESET_REQUEST_RATE_LIMIT);
1524
+ // Always returns success - never reveal whether the email exists. The reset OTP
1525
+ // (if any) is enqueued through better-auth's emailOTP hook -> MAIL_DISPATCH. Any
1526
+ // underlying error is swallowed for the same anti-enumeration reason.
410
1527
  try {
411
- await this.api.requestPasswordReset({
412
- body: { email: input.email, redirectTo: '/reset-password' },
1528
+ await this.api.requestPasswordResetEmailOTP({
1529
+ body: { email },
413
1530
  headers: new Headers(),
414
1531
  asResponse: true,
415
1532
  });
@@ -419,65 +1536,507 @@ export class IdentityService {
419
1536
  }
420
1537
  return SUCCESS;
421
1538
  }
1539
+ async verifyPasswordResetOtp(input) {
1540
+ const email = input.email.toLowerCase();
1541
+ await assertRateLimit(this.limiter, makeRateLimitKey(RATE_LIMIT_KEYS.PASSWORD_RESET_VERIFY, email), PASSWORD_RESET_VERIFY_RATE_LIMIT);
1542
+ const res = await this.api.checkVerificationOTP({
1543
+ body: { email, type: 'forget-password', otp: input.otp },
1544
+ headers: new Headers(),
1545
+ asResponse: true,
1546
+ });
1547
+ await ensureOk(res, { genericMessage: 'Invalid or expired verification code' });
1548
+ return SUCCESS;
1549
+ }
422
1550
  async resetPassword(input) {
423
- // Key on the token - the only identifier the input carries - to bound retries
424
- // against a single reset token.
425
- await assertRateLimit(this.limiter, `pwreset:${input.token}`, PASSWORD_RESET_RATE_LIMIT);
426
- const res = await this.api.resetPassword({
427
- body: { newPassword: input.newPassword, token: input.token },
1551
+ const email = input.email.toLowerCase();
1552
+ await assertRateLimit(this.limiter, makeRateLimitKey(RATE_LIMIT_KEYS.PASSWORD_RESET, email), PASSWORD_RESET_RATE_LIMIT);
1553
+ const res = await this.api.resetPasswordEmailOTP({
1554
+ body: { email, otp: input.otp, password: input.newPassword },
428
1555
  headers: new Headers(),
429
1556
  asResponse: true,
430
1557
  });
431
- await ensureOk(res);
432
- const body = (await res.json().catch(() => ({})));
433
- if (body.user?.id) {
434
- this.events.emit('identity.password.reset', { userId: body.user.id });
435
- // Password reset clears any lockout - the user has proven identity via email/phone.
436
- await this.clearLockout(body.user.id);
437
- }
1558
+ await ensureOk(res, { genericMessage: 'Invalid or expired verification code' });
1559
+ // better-auth's resetPasswordEmailOTP internally invokes the onPasswordReset hook
1560
+ // (wired in the constructor above), which emits `identity.password.reset` and
1561
+ // clears the lockout - do not duplicate that here (was double-emitting/double-
1562
+ // clearing on every real reset).
438
1563
  return SUCCESS;
439
1564
  }
440
- async changePassword(input, reqHeaders, resHeaders) {
1565
+ async changePassword(input, reqHeaders, resHeaders, caller) {
441
1566
  const headers = nodeHeadersToHeaders(reqHeaders);
442
- const userId = await this.currentUserId(headers);
443
- await assertRateLimit(this.limiter, `change-password:${userId ?? 'anonymous'}`, CHANGE_PASSWORD_RATE_LIMIT);
1567
+ const { userId, sessionId } = caller;
1568
+ await assertRateLimit(this.limiter, `change-password:${userId}`, CHANGE_PASSWORD_RATE_LIMIT);
444
1569
  const res = await this.api.changePassword({
445
- body: { currentPassword: input.currentPassword, newPassword: input.newPassword },
1570
+ // revokeOtherSessions: better-auth deletes every session for this user and
1571
+ // mints a fresh one for the caller; forwardCookies below ships that cookie.
1572
+ body: {
1573
+ currentPassword: input.currentPassword,
1574
+ newPassword: input.newPassword,
1575
+ revokeOtherSessions: true,
1576
+ },
446
1577
  headers,
447
1578
  asResponse: true,
448
1579
  });
449
1580
  await ensureOk(res);
450
1581
  this.forwardCookies(res, resHeaders);
1582
+ // Captured once the rotation is known committed - the deferred sweep below deletes
1583
+ // any session row created at or before this instant (i.e. one a concurrent
1584
+ // old-password sign-in raced in), sparing anything created afterwards.
1585
+ const sweepDeadline = new Date();
1586
+ // The token of the session better-auth just minted for the caller. `ensureOk` only
1587
+ // reads the body on failure, so this read is safe here.
1588
+ // Library boundary: `Response.json()` resolves to `any`, and better-auth publishes no
1589
+ // response type for this route, so its shape is asserted once here.
1590
+ const rotatedToken = (await res.json().catch(() => ({}))).token ?? null;
1591
+ // better-auth's response only carries the token, not the row id - look the row up
1592
+ // once here and reuse its id both to clamp the dontRememberMe TTL below and to
1593
+ // spare this (legitimate) session from the sweep's own revoke push further down.
1594
+ const rotated = rotatedToken
1595
+ ? (await this.drizzle.db
1596
+ .select({ id: session.id })
1597
+ .from(session)
1598
+ .where(eq(session.token, rotatedToken))
1599
+ .limit(1))[0]
1600
+ : undefined;
1601
+ // `revokeOtherSessions` makes better-auth mint the replacement session via
1602
+ // `createSession(userId)` with no `dontRememberMe` argument, so a caller who signed
1603
+ // in with `rememberMe: false` silently gets a full-TTL row. better-auth's own
1604
+ // `setSessionCookie` still honours the `dont_remember` cookie for the cookie maxAge,
1605
+ // but not the DB row - clamp it back to the non-remembered TTL to match.
1606
+ if (rotated && hasDontRememberCookie(headers)) {
1607
+ await this.drizzle.db
1608
+ .update(session)
1609
+ .set({ expiresAt: new Date(Date.now() + DONT_REMEMBER_SESSION_TTL_MS) })
1610
+ .where(eq(session.id, rotated.id));
1611
+ }
1612
+ const { ip, userAgent } = extractClientMeta(reqHeaders);
1613
+ // Independent of each other and of `rotated` - one round trip instead of two on a
1614
+ // user-facing endpoint. (The TTL clamp above does depend on `rotated`, so it stays
1615
+ // sequential.)
1616
+ const [, playerId] = await Promise.all([
1617
+ this.drizzle.db.update(user).set({ passwordMeetsPolicy: true }).where(eq(user.id, userId)),
1618
+ this.identityReader.getPlayerIdByUserIdSafe(userId),
1619
+ ]);
1620
+ // Dedicated, non-sensitive record that the login credential itself changed -
1621
+ // the audit mapper keys the action off the topic, so a plain
1622
+ // `identity.sessions.revoked_all` alone would read as "revoked all sessions",
1623
+ // not "changed password". Every state-changing credential action needs its own
1624
+ // accurately named audit record.
1625
+ this.events.emit('identity.password.changed', {
1626
+ userId,
1627
+ playerId,
1628
+ ip: ip ?? null,
1629
+ userAgent: userAgent ?? null,
1630
+ });
1631
+ // Same event the admin "revoke all sessions" path emits, so the streamSession
1632
+ // SSE handler pushes { type: 'revoked' } to this user's OTHER tabs.
1633
+ // exceptSessionId is the caller's PRE-rotation session id - it's the id the
1634
+ // caller's already-open streamSession connection captured at stream-open, and the
1635
+ // only value its SSE compare can ever match, so this is what spares the
1636
+ // initiating tab.
1637
+ this.events.emit('identity.sessions.revoked_all', {
1638
+ userId,
1639
+ playerId,
1640
+ actorId: userId,
1641
+ ip: ip ?? null,
1642
+ userAgent: userAgent ?? null,
1643
+ exceptSessionId: sessionId,
1644
+ });
1645
+ // better-auth rotates the password hash and deletes sessions in separate,
1646
+ // untransacted statements; a sign-in that verified the OLD password just before
1647
+ // the rotation can still insert its session row right after. Re-sweep shortly
1648
+ // after to delete it, sparing the caller's fresh session by token. Skipped when
1649
+ // the rotated token is unknown - without it the sweep cannot tell the caller's
1650
+ // own new session apart. Residual exposure: RACED_SESSION_SWEEP_DELAY_MS.
1651
+ if (rotatedToken) {
1652
+ const timer = setTimeout(() => {
1653
+ void sweepRacedSessionsAfterPasswordChange(this.drizzle.db, {
1654
+ userId,
1655
+ sparedToken: rotatedToken,
1656
+ deadline: sweepDeadline,
1657
+ })
1658
+ .then((deletedIds) => {
1659
+ // A session the sweep just force-deleted got no push and no audit record
1660
+ // otherwise: it raced in after the primary revoked_all above already
1661
+ // fired, so this is the only notice it gets of either.
1662
+ if (deletedIds.length === 0) {
1663
+ return;
1664
+ }
1665
+ this.events.emit('identity.sessions.revoked_all', {
1666
+ userId,
1667
+ playerId,
1668
+ actorId: userId,
1669
+ ip: ip ?? null,
1670
+ userAgent: userAgent ?? null,
1671
+ // The caller's PRE-rotation session id, same as the primary emit above -
1672
+ // it's what the initiating tab's already-open streamSession connection
1673
+ // captured at stream-open, and the only value its SSE compare can match.
1674
+ // `rotated.id` (the NEW row) can never match that, so using it here would
1675
+ // force-revoke the legitimate acting tab the moment the sweep actually
1676
+ // deletes a raced session.
1677
+ exceptSessionId: sessionId,
1678
+ });
1679
+ })
1680
+ .catch((err) => {
1681
+ identityLogger.warn({ err, userId }, 'post-password-change session sweep failed');
1682
+ });
1683
+ }, RACED_SESSION_SWEEP_DELAY_MS);
1684
+ timer.unref?.();
1685
+ }
451
1686
  return SUCCESS;
452
1687
  }
453
- async sendEmailVerification(reqHeaders) {
454
- const headers = nodeHeadersToHeaders(reqHeaders);
455
- const session = await this.auth.api.getSession({ headers });
456
- const email = session?.user?.email;
457
- if (email) {
458
- await assertRateLimit(this.limiter, `email-verify:${email.toLowerCase()}`, EMAIL_VERIFICATION_RATE_LIMIT);
459
- await this.api.sendVerificationEmail({ body: { email }, headers, asResponse: true });
1688
+ async getSecurityControls(reqHeaders) {
1689
+ const userId = await this.currentUserId(nodeHeadersToHeaders(reqHeaders));
1690
+ if (!userId) {
1691
+ throw new ORPCError('UNAUTHORIZED', { message: 'Not signed in.' });
1692
+ }
1693
+ return this.securityControlsFor(userId);
1694
+ }
1695
+ /**
1696
+ * Resolves the caller of a security-preference setter and refuses anyone who is not a
1697
+ * player. These setters reject before any shared guard runs, so a denial still owes the
1698
+ * audit log the same signal AdminGuard emits (docs/standards/audit.md) - `resource`
1699
+ * names which preference was attempted.
1700
+ */
1701
+ async assertPlayerPreferenceCaller(reqHeaders, resource) {
1702
+ const { ip, userAgent } = extractClientMeta(reqHeaders);
1703
+ const userId = await this.currentUserId(nodeHeadersToHeaders(reqHeaders));
1704
+ if (!userId) {
1705
+ throw new ORPCError('UNAUTHORIZED', { message: 'Not signed in.' });
1706
+ }
1707
+ const [caller] = await this.drizzle.db
1708
+ .select({ role: user.role })
1709
+ .from(user)
1710
+ .where(eq(user.id, userId))
1711
+ .limit(1);
1712
+ if (caller?.role !== 'player') {
1713
+ this.events.emit('identity.user.unauthorized_access', {
1714
+ userId,
1715
+ playerId: null,
1716
+ resource,
1717
+ action: 'set',
1718
+ ...(caller?.role ? { role: caller.role } : {}),
1719
+ ip,
1720
+ userAgent,
1721
+ });
1722
+ throw new ORPCError('FORBIDDEN', {
1723
+ message: 'Only players can set this preference.',
1724
+ });
1725
+ }
1726
+ return { userId, ip, userAgent };
1727
+ }
1728
+ async setLoginWithdrawalAlerts(input, reqHeaders) {
1729
+ const { userId, ip, userAgent } = await this.assertPlayerPreferenceCaller(reqHeaders, 'identity.security.login_withdrawal_alerts');
1730
+ const before = await this.securityControlsFor(userId);
1731
+ if (input.enabled && !before.emailVerified) {
1732
+ throw new ORPCError('UNPROCESSABLE_CONTENT', {
1733
+ message: 'Verify your email before enabling security alerts.',
1734
+ });
1735
+ }
1736
+ if (before.loginWithdrawalAlertsEnabled === input.enabled) {
1737
+ return before;
1738
+ }
1739
+ await this.drizzle.db
1740
+ .update(user)
1741
+ .set({ loginWithdrawalAlertsEnabled: input.enabled })
1742
+ .where(eq(user.id, userId));
1743
+ this.events.emit('identity.security.login_withdrawal_alerts.updated', {
1744
+ userId,
1745
+ playerId: await this.identityReader.getPlayerIdByUserIdSafe(userId),
1746
+ previousEnabled: before.loginWithdrawalAlertsEnabled,
1747
+ enabled: input.enabled,
1748
+ ip,
1749
+ userAgent,
1750
+ });
1751
+ return { ...before, loginWithdrawalAlertsEnabled: input.enabled };
1752
+ }
1753
+ async setAutoLogoutDuration(input, reqHeaders) {
1754
+ const { userId, ip, userAgent } = await this.assertPlayerPreferenceCaller(reqHeaders, 'identity.security.auto_logout');
1755
+ const before = await this.securityControlsFor(userId);
1756
+ if (before.autoLogoutDuration === input.duration) {
1757
+ return before;
1758
+ }
1759
+ await this.drizzle.db
1760
+ .update(user)
1761
+ .set({ autoLogoutDuration: input.duration })
1762
+ .where(eq(user.id, userId));
1763
+ this.events.emit('identity.security.auto_logout.updated', {
1764
+ userId,
1765
+ playerId: await this.identityReader.getPlayerIdByUserIdSafe(userId),
1766
+ previousDuration: before.autoLogoutDuration,
1767
+ duration: input.duration,
1768
+ ip,
1769
+ userAgent,
1770
+ });
1771
+ return { ...before, autoLogoutDuration: input.duration };
1772
+ }
1773
+ /**
1774
+ * Turning this on also tears down the devices already trusted: stripping the trust
1775
+ * cookie at login is enough to force the challenge, but leaving live rows behind would
1776
+ * show a player devices that no longer buy anything, and hand them straight back the
1777
+ * moment the toggle goes off again.
1778
+ */
1779
+ async setRequireTwoFactorOnLogin(input, reqHeaders) {
1780
+ const { userId, ip, userAgent } = await this.assertPlayerPreferenceCaller(reqHeaders, 'identity.security.require_two_factor');
1781
+ const before = await this.securityControlsFor(userId);
1782
+ if (input.enabled && !before.twoFactorEnabled) {
1783
+ throw new ORPCError('UNPROCESSABLE_CONTENT', {
1784
+ message: 'Enable two-factor authentication before requiring it on every login.',
1785
+ });
1786
+ }
1787
+ if (before.requireTwoFactorOnLogin === input.enabled) {
1788
+ return before;
1789
+ }
1790
+ await this.drizzle.db
1791
+ .update(user)
1792
+ .set({ requireTwoFactorOnLogin: input.enabled })
1793
+ .where(eq(user.id, userId));
1794
+ if (input.enabled) {
1795
+ await this.trustedDevices?.revokeAllForUser(userId, userId);
1796
+ }
1797
+ this.events.emit('identity.security.require_two_factor.updated', {
1798
+ userId,
1799
+ playerId: await this.identityReader.getPlayerIdByUserIdSafe(userId),
1800
+ previousEnabled: before.requireTwoFactorOnLogin,
1801
+ enabled: input.enabled,
1802
+ ip,
1803
+ userAgent,
1804
+ });
1805
+ return { ...before, requireTwoFactorOnLogin: input.enabled };
1806
+ }
1807
+ /**
1808
+ * Sets (or overwrites) the player's anti-phishing code: a free-text, case-sensitive
1809
+ * recognition phrase stamped into every outgoing platform email so the player can tell a
1810
+ * genuine email from a phishing attempt. Unlike the withdrawal PIN this authorizes nothing,
1811
+ * so - like `setLoginWithdrawalAlerts` - it takes no reauth and there is no remove route;
1812
+ * calling it again with a new value just changes the code.
1813
+ */
1814
+ async setAntiPhishingCode(input, reqHeaders) {
1815
+ const { ip, userAgent } = extractClientMeta(reqHeaders);
1816
+ const userId = await this.currentUserId(nodeHeadersToHeaders(reqHeaders));
1817
+ if (!userId) {
1818
+ throw new ORPCError('UNAUTHORIZED', { message: 'Not signed in.' });
1819
+ }
1820
+ const [caller] = await this.drizzle.db
1821
+ .select({ role: user.role, email: user.email, language: user.language })
1822
+ .from(user)
1823
+ .where(eq(user.id, userId))
1824
+ .limit(1);
1825
+ if (caller?.role !== 'player') {
1826
+ // A service-level denial still owes the audit log the same signal AdminGuard emits,
1827
+ // since this check rejects before any shared guard runs (docs/standards/audit.md).
1828
+ this.events.emit('identity.user.unauthorized_access', {
1829
+ userId,
1830
+ playerId: null,
1831
+ resource: 'identity.security.anti_phishing_code',
1832
+ action: 'set',
1833
+ ...(caller?.role ? { role: caller.role } : {}),
1834
+ ip,
1835
+ userAgent,
1836
+ });
1837
+ throw new ORPCError('FORBIDDEN', {
1838
+ message: 'Only players can set this preference.',
1839
+ });
1840
+ }
1841
+ const before = await this.securityControlsFor(userId);
1842
+ if (before.antiPhishingCode === input.code) {
1843
+ return before;
1844
+ }
1845
+ await assertRateLimit(this.limiter, makeRateLimitKey(RATE_LIMIT_KEYS.ANTI_PHISHING_CODE_MUTATION, userId), ANTI_PHISHING_CODE_RATE_LIMIT);
1846
+ await this.drizzle.db
1847
+ .update(user)
1848
+ .set({ antiPhishingCode: input.code })
1849
+ .where(eq(user.id, userId));
1850
+ this.events.emit('identity.security.anti_phishing_code.set', {
1851
+ userId,
1852
+ playerId: await this.identityReader.getPlayerIdByUserIdSafe(userId),
1853
+ wasAlreadySet: before.antiPhishingCode !== null,
1854
+ ip,
1855
+ userAgent,
1856
+ });
1857
+ // Deliberately address-only: resolving a user recipient later would stamp the email with
1858
+ // the replacement code. This notice instead carries the prior code, which lets the owner
1859
+ // recognise it even if a stolen session changed the current value.
1860
+ // The row is already committed, so a failed enqueue must not fail the mutation: the
1861
+ // caller would see an error for a change that landed, and retrying the same value exits
1862
+ // at the no-op branch above without ever re-sending the notice.
1863
+ try {
1864
+ await this.mailDispatch?.toAddress({
1865
+ email: caller.email,
1866
+ locale: caller.language,
1867
+ template: {
1868
+ key: 'securityAntiPhishingCodeChanged',
1869
+ data: { previousAntiPhishingCode: before.antiPhishingCode },
1870
+ },
1871
+ idempotencyKey: `anti-phishing-code-changed:${userId}:${randomUUID()}`,
1872
+ });
1873
+ }
1874
+ catch (err) {
1875
+ identityLogger.error({ err, userId }, 'anti-phishing code change notice enqueue failed');
1876
+ }
1877
+ return { ...before, antiPhishingCode: input.code };
1878
+ }
1879
+ /**
1880
+ * Resends the registration code. Unauthenticated by design - the player has no session
1881
+ * until the code is verified - so it answers SUCCESS for every address and only mails a
1882
+ * code to an account that exists and is still unverified. Verified accounts are skipped
1883
+ * deliberately: `verifyEmail` signs the code's bearer in, so resending to a verified
1884
+ * address would turn this into passwordless sign-in for anyone who can read that inbox.
1885
+ */
1886
+ async sendEmailVerification(input, reqHeaders) {
1887
+ const { ip } = extractClientMeta(reqHeaders);
1888
+ const email = input.email.toLowerCase();
1889
+ await assertRateLimit(this.limiter, `email-verify:${email}`, EMAIL_VERIFICATION_RATE_LIMIT);
1890
+ if (ip) {
1891
+ await assertRateLimit(this.limiter, `email-verify-ip:${ip}`, EMAIL_VERIFICATION_RATE_LIMIT);
1892
+ }
1893
+ const [row] = await this.drizzle.db
1894
+ .select({ emailVerified: user.emailVerified })
1895
+ .from(user)
1896
+ .where(eq(user.email, email))
1897
+ .limit(1);
1898
+ if (row && !row.emailVerified) {
1899
+ await this.api.sendVerificationOTP({
1900
+ body: { email, type: 'email-verification' },
1901
+ headers: nodeHeadersToHeaders(reqHeaders),
1902
+ asResponse: true,
1903
+ });
460
1904
  }
461
1905
  return SUCCESS;
462
1906
  }
463
- async verifyEmail(input, reqHeaders) {
1907
+ /**
1908
+ * Consumes the 6-digit code mailed by `register()` and signs the player in -
1909
+ * better-auth's `autoSignInAfterVerification` mints the session here rather than at
1910
+ * sign-up, which is what lets sign-up stay sessionless and therefore keep its
1911
+ * duplicate-email response indistinguishable. Same post-credential gates as `login`:
1912
+ * a code is proof of address ownership, not a bypass for an RG or backoffice block.
1913
+ */
1914
+ async verifyEmail(input, reqHeaders, resHeaders) {
1915
+ const { ip, userAgent } = extractClientMeta(reqHeaders);
464
1916
  const headers = nodeHeadersToHeaders(reqHeaders);
465
- const userId = await this.currentUserId(headers);
466
- await assertRateLimit(this.limiter, `verify-email:${userId ?? 'anonymous'}`, VERIFY_EMAIL_RATE_LIMIT);
467
- const res = await this.api.verifyEmail({
468
- query: { token: input.token },
1917
+ const email = input.email.toLowerCase();
1918
+ // Keyed on the address under attack (six digits are guessable) and on the caller, so
1919
+ // one client can neither grind a single account nor sweep many.
1920
+ await assertRateLimit(this.limiter, `verify-email:${email}`, VERIFY_EMAIL_RATE_LIMIT);
1921
+ // Only when the caller's IP is actually known: an `unknown` bucket would be shared by
1922
+ // every anonymous caller, letting one client stall everyone else's sign-up.
1923
+ if (ip) {
1924
+ await assertRateLimit(this.limiter, `verify-email-ip:${ip}`, VERIFY_EMAIL_RATE_LIMIT);
1925
+ }
1926
+ const res = await this.api.verifyEmailOTP({
1927
+ body: { email, otp: input.otp },
469
1928
  headers,
470
1929
  asResponse: true,
471
1930
  });
472
- await ensureOk(res);
473
- if (userId) {
474
- this.events.emit('identity.email.verified', { userId });
1931
+ await ensureOk(res, { genericMessage: 'Invalid or expired verification code' });
1932
+ const body = (await res.json());
1933
+ // better-auth has already committed `emailVerified` by now, so the audit record is
1934
+ // emitted before any gate below can throw - a state change that leaves no trail is a
1935
+ // compliance gap, see docs/standards/audit.md.
1936
+ const playerId = await this.identityReader.getPlayerIdByUserIdSafe(body.user.id);
1937
+ this.events.emit('identity.email.verified', { userId: body.user.id, playerId, ip, userAgent });
1938
+ const [account] = await this.drizzle.db
1939
+ .select({
1940
+ id: user.id,
1941
+ rgBlocked: user.rgBlocked,
1942
+ rgBlockedUntil: user.rgBlockedUntil,
1943
+ twoFactorEnabled: user.twoFactorEnabled,
1944
+ })
1945
+ .from(user)
1946
+ .where(eq(user.id, body.user.id))
1947
+ .limit(1);
1948
+ if (account) {
1949
+ await this.assertAccountNotBlocked(account, { ip, userAgent });
475
1950
  }
476
- return SUCCESS;
1951
+ // Before the 2FA branch below: that path ends the session it just minted, but the zone
1952
+ // the browser reported is good either way.
1953
+ await captureTimezone(this.playerProvisioning, body.user.id, input.timezone);
1954
+ // better-auth mints this session with `createSession`, which its twoFactor plugin only
1955
+ // hooks on the sign-in routes - so an enrolled account would get a full session from
1956
+ // the emailed code alone, bypassing its second factor. Verification still stands; the
1957
+ // session does not, and the player signs in through `login` to face the challenge.
1958
+ if (account?.twoFactorEnabled) {
1959
+ // Scoped to the token this call just minted: the player's other devices did nothing
1960
+ // wrong, and an unrelated sign-out here would be indistinguishable from a session
1961
+ // hijack. The RG/backoffice branch above is the one that revokes everything.
1962
+ if (body.token) {
1963
+ await this.drizzle.db
1964
+ .update(session)
1965
+ .set({ expiresAt: new Date() })
1966
+ .where(eq(session.token, body.token));
1967
+ }
1968
+ return { twoFactorRedirect: true };
1969
+ }
1970
+ if (!body.token) {
1971
+ throw new ORPCError('INTERNAL_SERVER_ERROR', { message: 'Verification did not sign you in' });
1972
+ }
1973
+ this.forwardCookies(res, resHeaders);
1974
+ await this.drizzle.db
1975
+ .update(session)
1976
+ .set({ ipAddress: ip, userAgent })
1977
+ .where(eq(session.token, body.token));
1978
+ this.events.emit('identity.user.login', { userId: body.user.id, playerId, ip, userAgent });
1979
+ this.events.emit('identity.authentication.succeeded', {
1980
+ userId: body.user.id,
1981
+ playerId,
1982
+ method: 'email_verification',
1983
+ ip,
1984
+ userAgent,
1985
+ });
1986
+ const sessionDurationSeconds = this.auth.options.session?.expiresIn ?? SESSION_DURATION_IN_SECONDS;
1987
+ return {
1988
+ user: toUser(body.user),
1989
+ session: {
1990
+ token: body.token,
1991
+ expiresAt: new Date(Date.now() + sessionDurationSeconds * 1000).toISOString(),
1992
+ },
1993
+ };
477
1994
  }
478
- async changeEmail(input, reqHeaders, resHeaders) {
1995
+ /**
1996
+ * Step 1 of the email change: better-auth mails a code to `newEmail` (type
1997
+ * `change-email`), answering success even when the address is already taken so this
1998
+ * never reveals whether an account exists. A live session is not proof enough on its
1999
+ * own for a change this sensitive, so it demands the same fresh password/2FA proof as
2000
+ * a withdrawal PIN or phone rebind (`assertFreshReauthentication`).
2001
+ */
2002
+ async requestEmailChange(input, reqHeaders, resHeaders) {
479
2003
  const headers = nodeHeadersToHeaders(reqHeaders);
480
- const res = await this.api.changeEmail({
2004
+ const meta = extractClientMeta(reqHeaders);
2005
+ const { ip } = meta;
2006
+ const userId = await this.currentUserId(headers);
2007
+ await assertRateLimit(this.limiter, `change-email:${userId ?? 'anonymous'}`, EMAIL_VERIFICATION_RATE_LIMIT);
2008
+ if (!userId) {
2009
+ throw new ORPCError('UNAUTHORIZED', { message: 'Not signed in.' });
2010
+ }
2011
+ const newEmail = input.newEmail.toLowerCase();
2012
+ // Keyed on the caller too, not just the target inbox: a target-only bucket lets any
2013
+ // signed-in account (no correct password needed - this runs before reauth) exhaust
2014
+ // a known address's budget and deny the real owner their own change for 15 minutes.
2015
+ // Per-(caller, target) still bounds how many codes one inbox gets from one caller.
2016
+ await assertRateLimit(this.limiter, `change-email-target:${userId}:${newEmail}`, EMAIL_VERIFICATION_RATE_LIMIT);
2017
+ if (ip) {
2018
+ await assertRateLimit(this.limiter, `change-email-ip:${ip}`, EMAIL_VERIFICATION_RATE_LIMIT);
2019
+ }
2020
+ const [caller] = await this.drizzle.db
2021
+ .select({ twoFactorEnabled: user.twoFactorEnabled })
2022
+ .from(user)
2023
+ .where(eq(user.id, userId))
2024
+ .limit(1);
2025
+ if (!caller) {
2026
+ throw new ORPCError('UNAUTHORIZED', { message: 'Not signed in.' });
2027
+ }
2028
+ await assertFreshReauthentication({
2029
+ drizzle: this.drizzle,
2030
+ auth: this.auth,
2031
+ twoFactorLockout: this.twoFactorLockout,
2032
+ userId,
2033
+ headers,
2034
+ currentPassword: input.currentPassword,
2035
+ totpCode: input.totpCode,
2036
+ twoFactorEnabled: caller.twoFactorEnabled ?? false,
2037
+ meta,
2038
+ });
2039
+ const res = await this.api.requestEmailChangeEmailOTP({
481
2040
  body: { newEmail: input.newEmail },
482
2041
  headers,
483
2042
  asResponse: true,
@@ -486,10 +2045,123 @@ export class IdentityService {
486
2045
  this.forwardCookies(res, resHeaders);
487
2046
  return SUCCESS;
488
2047
  }
2048
+ /**
2049
+ * Step 2: the code proves ownership of `newEmail`, so better-auth swaps the login email.
2050
+ * The old address is read first, since no row carries it afterwards, for the "changed"
2051
+ * notice and to reset the verified-email alert opt-in (made on the old inbox). Every
2052
+ * other session and trusted device is torn down too, the same as `disableTwoFactor`.
2053
+ */
2054
+ async confirmEmailChange(input, reqHeaders, resHeaders) {
2055
+ const headers = nodeHeadersToHeaders(reqHeaders);
2056
+ const meta = extractClientMeta(reqHeaders);
2057
+ const { ip, userAgent } = meta;
2058
+ const userId = await this.currentUserId(headers);
2059
+ await assertRateLimit(this.limiter, `confirm-email-change:${userId ?? 'anonymous'}`, VERIFY_EMAIL_RATE_LIMIT);
2060
+ if (!userId) {
2061
+ throw new ORPCError('UNAUTHORIZED', { message: 'Not signed in.' });
2062
+ }
2063
+ const newEmail = input.newEmail.toLowerCase();
2064
+ // Same actor-binding as requestEmailChange's target bucket: a bare-target key lets
2065
+ // any signed-in caller burn a known address's guess budget and lock the real
2066
+ // requester out of confirming their own pending change for 15 minutes.
2067
+ await assertRateLimit(this.limiter, `confirm-email-change-target:${userId}:${newEmail}`, VERIFY_EMAIL_RATE_LIMIT);
2068
+ if (ip) {
2069
+ await assertRateLimit(this.limiter, `confirm-email-change-ip:${ip}`, VERIFY_EMAIL_RATE_LIMIT);
2070
+ }
2071
+ const [before] = await this.drizzle.db
2072
+ .select({
2073
+ email: user.email,
2074
+ language: user.language,
2075
+ name: user.username,
2076
+ antiPhishingCode: user.antiPhishingCode,
2077
+ loginWithdrawalAlertsEnabled: user.loginWithdrawalAlertsEnabled,
2078
+ })
2079
+ .from(user)
2080
+ .where(eq(user.id, userId))
2081
+ .limit(1);
2082
+ const res = await this.api.changeEmailEmailOTP({
2083
+ body: { newEmail: input.newEmail, otp: input.otp },
2084
+ headers,
2085
+ asResponse: true,
2086
+ });
2087
+ await ensureOk(res, { genericMessage: 'Invalid or expired verification code' });
2088
+ this.forwardCookies(res, resHeaders);
2089
+ const changedAt = new Date().toISOString();
2090
+ if (before) {
2091
+ const playerId = await this.identityReader.getPlayerIdByUserIdSafe(userId);
2092
+ this.events.emit('identity.email.changed', {
2093
+ userId,
2094
+ playerId,
2095
+ previousEmail: before.email,
2096
+ newEmail,
2097
+ ip,
2098
+ userAgent,
2099
+ });
2100
+ // Both inboxes get told - fire-and-forget like `dispatchMail` in
2101
+ // notifications/plugin.ts, right after the emit and before the revocation calls
2102
+ // below: if either of those throws, the swap has already committed and both
2103
+ // owners still need their notice. `randomUUID()` keeps each key unique so the
2104
+ // queue's dedupe window can't swallow a repeat notice.
2105
+ //
2106
+ // To the OLD address - the row no longer holds it, so every field is read from
2107
+ // `before`. Carries the "was this you?" warning and a support CTA: this inbox
2108
+ // could belong to someone who never asked for the change.
2109
+ this.mailDispatch
2110
+ ?.toAddress({
2111
+ email: before.email,
2112
+ locale: before.language,
2113
+ antiPhishingCode: before.antiPhishingCode,
2114
+ recipientName: before.name,
2115
+ template: {
2116
+ key: 'emailChanged',
2117
+ data: { newEmail, occurredAt: changedAt, isNewAddress: false },
2118
+ },
2119
+ idempotencyKey: `email-change-notice-old:${userId}:${randomUUID()}`,
2120
+ })
2121
+ .catch((err) => identityLogger.error({ err, userId }, 'email-change notice (old address) enqueue failed'));
2122
+ // To the NEW address - `toAddress` with the fields already in hand from `before`
2123
+ // (name/locale/antiPhishingCode are account-level, unaffected by the swap), not
2124
+ // `toUser`: that reads the row live at delivery time, so a second change started
2125
+ // right after this one would relabel this "new" notice onto whatever address the
2126
+ // account holds by then. Plain confirmation, no warning: this inbox just proved
2127
+ // ownership with a live OTP, it didn't fall victim to one.
2128
+ this.mailDispatch
2129
+ ?.toAddress({
2130
+ email: newEmail,
2131
+ locale: before.language,
2132
+ antiPhishingCode: before.antiPhishingCode,
2133
+ recipientName: before.name,
2134
+ template: {
2135
+ key: 'emailChanged',
2136
+ data: { newEmail, occurredAt: changedAt, isNewAddress: true },
2137
+ },
2138
+ idempotencyKey: `email-change-notice-new:${userId}:${randomUUID()}`,
2139
+ })
2140
+ .catch((err) => identityLogger.error({ err, userId }, 'email-change notice (new address) enqueue failed'));
2141
+ await this.trustedDevices?.revokeAllForUser(userId, userId);
2142
+ await this.sessions?.revokeAllSessions(userId, userId, meta);
2143
+ if (before.loginWithdrawalAlertsEnabled) {
2144
+ await this.drizzle.db
2145
+ .update(user)
2146
+ .set({ loginWithdrawalAlertsEnabled: false })
2147
+ .where(eq(user.id, userId));
2148
+ this.events.emit('identity.security.login_withdrawal_alerts.updated', {
2149
+ userId,
2150
+ playerId,
2151
+ previousEnabled: true,
2152
+ enabled: false,
2153
+ ip,
2154
+ userAgent,
2155
+ });
2156
+ }
2157
+ }
2158
+ return SUCCESS;
2159
+ }
489
2160
  async updateProfile(input, reqHeaders, resHeaders) {
490
2161
  if (input.language !== undefined) {
491
2162
  assertSupportedLanguage(input.language, this.platformConfig);
492
2163
  }
2164
+ const { ip, userAgent } = extractClientMeta(reqHeaders);
493
2165
  const headers = nodeHeadersToHeaders(reqHeaders);
494
2166
  // better-auth's field parser and drizzle's mapUpdateSet both drop `undefined`
495
2167
  // values before the SQL SET clause, so omitted fields are safely no-ops here.
@@ -505,7 +2177,12 @@ export class IdentityService {
505
2177
  const session = await this.auth.api.getSession({ headers });
506
2178
  const current = session?.user;
507
2179
  if (current) {
508
- this.events.emit('identity.profile.updated', { userId: current.id });
2180
+ this.events.emit('identity.profile.updated', {
2181
+ userId: current.id,
2182
+ playerId: await this.identityReader.getPlayerIdByUserIdSafe(current.id),
2183
+ ip,
2184
+ userAgent,
2185
+ });
509
2186
  }
510
2187
  if (!current) {
511
2188
  throw new Error('Profile update succeeded but session could not be re-read');