@hed-hog/core 0.0.386 → 0.0.390

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 (556) hide show
  1. package/README.md +12 -11
  2. package/dist/access-log/access-log.interceptor.d.ts.map +1 -1
  3. package/dist/access-log/access-log.interceptor.js +4 -2
  4. package/dist/access-log/access-log.interceptor.js.map +1 -1
  5. package/dist/ai/ai-attachment.fragments.d.ts +23 -0
  6. package/dist/ai/ai-attachment.fragments.d.ts.map +1 -0
  7. package/dist/ai/ai-attachment.fragments.js +34 -0
  8. package/dist/ai/ai-attachment.fragments.js.map +1 -0
  9. package/dist/ai/ai.controller.d.ts +7 -16
  10. package/dist/ai/ai.controller.d.ts.map +1 -1
  11. package/dist/ai/ai.prompts.d.ts +16 -0
  12. package/dist/ai/ai.prompts.d.ts.map +1 -0
  13. package/dist/ai/ai.prompts.js +37 -0
  14. package/dist/ai/ai.prompts.js.map +1 -0
  15. package/dist/ai/ai.service.d.ts +63 -12
  16. package/dist/ai/ai.service.d.ts.map +1 -1
  17. package/dist/ai/ai.service.js +215 -88
  18. package/dist/ai/ai.service.js.map +1 -1
  19. package/dist/ai/dto/chat.dto.d.ts +4 -1
  20. package/dist/ai/dto/chat.dto.d.ts.map +1 -1
  21. package/dist/ai/dto/chat.dto.js +23 -1
  22. package/dist/ai/dto/chat.dto.js.map +1 -1
  23. package/dist/ai/dto/create-agent.dto.d.ts +1 -1
  24. package/dist/ai/dto/create-agent.dto.d.ts.map +1 -1
  25. package/dist/ai/dto/create-agent.dto.js +1 -1
  26. package/dist/ai/dto/create-agent.dto.js.map +1 -1
  27. package/dist/ai/dto/update-agent.dto.d.ts +1 -1
  28. package/dist/ai/dto/update-agent.dto.d.ts.map +1 -1
  29. package/dist/ai/dto/update-agent.dto.js +1 -1
  30. package/dist/ai/dto/update-agent.dto.js.map +1 -1
  31. package/dist/ai-instruction/ai-instruction.controller.d.ts +61 -7
  32. package/dist/ai-instruction/ai-instruction.controller.d.ts.map +1 -1
  33. package/dist/ai-instruction/ai-instruction.controller.js +63 -20
  34. package/dist/ai-instruction/ai-instruction.controller.js.map +1 -1
  35. package/dist/ai-instruction/ai-instruction.module.d.ts.map +1 -1
  36. package/dist/ai-instruction/ai-instruction.module.js +13 -2
  37. package/dist/ai-instruction/ai-instruction.module.js.map +1 -1
  38. package/dist/ai-instruction/ai-instruction.service.d.ts +131 -6
  39. package/dist/ai-instruction/ai-instruction.service.d.ts.map +1 -1
  40. package/dist/ai-instruction/ai-instruction.service.js +533 -60
  41. package/dist/ai-instruction/ai-instruction.service.js.map +1 -1
  42. package/dist/ai-instruction/ai-prompt-builder.service.d.ts +8 -0
  43. package/dist/ai-instruction/ai-prompt-builder.service.d.ts.map +1 -1
  44. package/dist/ai-instruction/ai-prompt-builder.service.js +10 -1
  45. package/dist/ai-instruction/ai-prompt-builder.service.js.map +1 -1
  46. package/dist/ai-instruction/ai-prompt-registry.d.ts +45 -0
  47. package/dist/ai-instruction/ai-prompt-registry.d.ts.map +1 -0
  48. package/dist/ai-instruction/ai-prompt-registry.js +49 -0
  49. package/dist/ai-instruction/ai-prompt-registry.js.map +1 -0
  50. package/dist/ai-instruction/ai-prompt-resolver.service.d.ts +89 -0
  51. package/dist/ai-instruction/ai-prompt-resolver.service.d.ts.map +1 -0
  52. package/dist/ai-instruction/ai-prompt-resolver.service.js +222 -0
  53. package/dist/ai-instruction/ai-prompt-resolver.service.js.map +1 -0
  54. package/dist/ai-instruction/ai-prompt-template.util.d.ts +70 -0
  55. package/dist/ai-instruction/ai-prompt-template.util.d.ts.map +1 -0
  56. package/dist/ai-instruction/ai-prompt-template.util.js +154 -0
  57. package/dist/ai-instruction/ai-prompt-template.util.js.map +1 -0
  58. package/dist/ai-instruction/dto/create-ai-instruction.dto.d.ts +5 -0
  59. package/dist/ai-instruction/dto/create-ai-instruction.dto.d.ts.map +1 -1
  60. package/dist/ai-instruction/dto/create-ai-instruction.dto.js +27 -1
  61. package/dist/ai-instruction/dto/create-ai-instruction.dto.js.map +1 -1
  62. package/dist/ai-instruction/dto/preview-ai-instruction.dto.d.ts +14 -0
  63. package/dist/ai-instruction/dto/preview-ai-instruction.dto.d.ts.map +1 -0
  64. package/dist/ai-instruction/dto/preview-ai-instruction.dto.js +42 -0
  65. package/dist/ai-instruction/dto/preview-ai-instruction.dto.js.map +1 -0
  66. package/dist/ai-instruction/dto/update-ai-instruction.dto.d.ts +11 -0
  67. package/dist/ai-instruction/dto/update-ai-instruction.dto.d.ts.map +1 -1
  68. package/dist/ai-instruction/dto/update-ai-instruction.dto.js +34 -0
  69. package/dist/ai-instruction/dto/update-ai-instruction.dto.js.map +1 -1
  70. package/dist/ai-instruction/types/ai-instruction.types.d.ts +13 -1
  71. package/dist/ai-instruction/types/ai-instruction.types.d.ts.map +1 -1
  72. package/dist/ai-instruction/types/ai-instruction.types.js +10 -0
  73. package/dist/ai-instruction/types/ai-instruction.types.js.map +1 -1
  74. package/dist/auth/auth.controller.d.ts +26 -10
  75. package/dist/auth/auth.controller.d.ts.map +1 -1
  76. package/dist/auth/auth.controller.js +49 -21
  77. package/dist/auth/auth.controller.js.map +1 -1
  78. package/dist/auth/auth.service.d.ts +35 -9
  79. package/dist/auth/auth.service.d.ts.map +1 -1
  80. package/dist/auth/auth.service.js +78 -29
  81. package/dist/auth/auth.service.js.map +1 -1
  82. package/dist/captcha/captcha.module.d.ts +3 -0
  83. package/dist/captcha/captcha.module.d.ts.map +1 -0
  84. package/dist/captcha/captcha.module.js +23 -0
  85. package/dist/captcha/captcha.module.js.map +1 -0
  86. package/dist/captcha/captcha.service.d.ts +38 -0
  87. package/dist/captcha/captcha.service.d.ts.map +1 -0
  88. package/dist/captcha/captcha.service.js +144 -0
  89. package/dist/captcha/captcha.service.js.map +1 -0
  90. package/dist/challenge/challenge.service.d.ts +16 -7
  91. package/dist/challenge/challenge.service.d.ts.map +1 -1
  92. package/dist/challenge/challenge.service.js +64 -16
  93. package/dist/challenge/challenge.service.js.map +1 -1
  94. package/dist/core.module.d.ts +3 -1
  95. package/dist/core.module.d.ts.map +1 -1
  96. package/dist/core.module.js +29 -2
  97. package/dist/core.module.js.map +1 -1
  98. package/dist/dashboard/dashboard/dashboard.controller.d.ts +15 -15
  99. package/dist/dashboard/dashboard/dashboard.service.d.ts +15 -15
  100. package/dist/dashboard/dashboard-component/dashboard-component.controller.d.ts +6 -6
  101. package/dist/dashboard/dashboard-component/dashboard-component.service.d.ts +6 -6
  102. package/dist/dashboard/dashboard-component-role/dashboard-component-role.controller.d.ts +20 -20
  103. package/dist/dashboard/dashboard-component-role/dashboard-component-role.service.d.ts +20 -20
  104. package/dist/dashboard/dashboard-core/dashboard-core.controller.d.ts +1 -1
  105. package/dist/dashboard/dashboard-core/dashboard-core.service.d.ts +1 -1
  106. package/dist/dashboard/dashboard-role/dashboard-role.controller.d.ts +13 -13
  107. package/dist/dashboard/dashboard-role/dashboard-role.service.d.ts +13 -13
  108. package/dist/file/file.service.d.ts +6 -0
  109. package/dist/file/file.service.d.ts.map +1 -1
  110. package/dist/file/file.service.js +44 -4
  111. package/dist/file/file.service.js.map +1 -1
  112. package/dist/incident/incident-notifier.service.d.ts +36 -0
  113. package/dist/incident/incident-notifier.service.d.ts.map +1 -0
  114. package/dist/incident/incident-notifier.service.js +208 -0
  115. package/dist/incident/incident-notifier.service.js.map +1 -0
  116. package/dist/incident/incident.controller.d.ts +23 -0
  117. package/dist/incident/incident.controller.d.ts.map +1 -0
  118. package/dist/incident/incident.controller.js +75 -0
  119. package/dist/incident/incident.controller.js.map +1 -0
  120. package/dist/incident/incident.module.d.ts +7 -0
  121. package/dist/incident/incident.module.d.ts.map +1 -0
  122. package/dist/incident/incident.module.js +32 -0
  123. package/dist/incident/incident.module.js.map +1 -0
  124. package/dist/incident/incident.service.d.ts +72 -0
  125. package/dist/incident/incident.service.d.ts.map +1 -0
  126. package/dist/incident/incident.service.js +184 -0
  127. package/dist/incident/incident.service.js.map +1 -0
  128. package/dist/index.d.ts +27 -0
  129. package/dist/index.d.ts.map +1 -1
  130. package/dist/index.js +31 -0
  131. package/dist/index.js.map +1 -1
  132. package/dist/integration-profile/dto/test.dto.d.ts +13 -0
  133. package/dist/integration-profile/dto/test.dto.d.ts.map +1 -0
  134. package/dist/integration-profile/dto/test.dto.js +26 -0
  135. package/dist/integration-profile/dto/test.dto.js.map +1 -0
  136. package/dist/integration-profile/integration-profile.controller.d.ts +12 -1
  137. package/dist/integration-profile/integration-profile.controller.d.ts.map +1 -1
  138. package/dist/integration-profile/integration-profile.controller.js +9 -1
  139. package/dist/integration-profile/integration-profile.controller.js.map +1 -1
  140. package/dist/integration-profile/integration-profile.module.d.ts +6 -1
  141. package/dist/integration-profile/integration-profile.module.d.ts.map +1 -1
  142. package/dist/integration-profile/integration-profile.module.js +26 -3
  143. package/dist/integration-profile/integration-profile.module.js.map +1 -1
  144. package/dist/integration-profile/integration-profile.secrets.d.ts.map +1 -1
  145. package/dist/integration-profile/integration-profile.secrets.js +12 -2
  146. package/dist/integration-profile/integration-profile.secrets.js.map +1 -1
  147. package/dist/integration-profile/integration-profile.service.d.ts +28 -2
  148. package/dist/integration-profile/integration-profile.service.d.ts.map +1 -1
  149. package/dist/integration-profile/integration-profile.service.js +105 -31
  150. package/dist/integration-profile/integration-profile.service.js.map +1 -1
  151. package/dist/integration-profile/integration-profile.utils.d.ts +31 -1
  152. package/dist/integration-profile/integration-profile.utils.d.ts.map +1 -1
  153. package/dist/integration-profile/integration-profile.utils.js +35 -4
  154. package/dist/integration-profile/integration-profile.utils.js.map +1 -1
  155. package/dist/integration-profile/testers/ai.testers.d.ts +3 -0
  156. package/dist/integration-profile/testers/ai.testers.d.ts.map +1 -0
  157. package/dist/integration-profile/testers/ai.testers.js +125 -0
  158. package/dist/integration-profile/testers/ai.testers.js.map +1 -0
  159. package/dist/integration-profile/testers/captcha.testers.d.ts +3 -0
  160. package/dist/integration-profile/testers/captcha.testers.d.ts.map +1 -0
  161. package/dist/integration-profile/testers/captcha.testers.js +121 -0
  162. package/dist/integration-profile/testers/captcha.testers.js.map +1 -0
  163. package/dist/integration-profile/testers/email.testers.d.ts +3 -0
  164. package/dist/integration-profile/testers/email.testers.d.ts.map +1 -0
  165. package/dist/integration-profile/testers/email.testers.js +128 -0
  166. package/dist/integration-profile/testers/email.testers.js.map +1 -0
  167. package/dist/integration-profile/testers/http-probe.d.ts +57 -0
  168. package/dist/integration-profile/testers/http-probe.d.ts.map +1 -0
  169. package/dist/integration-profile/testers/http-probe.js +140 -0
  170. package/dist/integration-profile/testers/http-probe.js.map +1 -0
  171. package/dist/integration-profile/testers/index.d.ts +12 -0
  172. package/dist/integration-profile/testers/index.d.ts.map +1 -0
  173. package/dist/integration-profile/testers/index.js +45 -0
  174. package/dist/integration-profile/testers/index.js.map +1 -0
  175. package/dist/integration-profile/testers/infrastructure.testers.d.ts +3 -0
  176. package/dist/integration-profile/testers/infrastructure.testers.d.ts.map +1 -0
  177. package/dist/integration-profile/testers/infrastructure.testers.js +105 -0
  178. package/dist/integration-profile/testers/infrastructure.testers.js.map +1 -0
  179. package/dist/integration-profile/testers/integration-tester.registry.d.ts +17 -0
  180. package/dist/integration-profile/testers/integration-tester.registry.d.ts.map +1 -0
  181. package/dist/integration-profile/testers/integration-tester.registry.js +52 -0
  182. package/dist/integration-profile/testers/integration-tester.registry.js.map +1 -0
  183. package/dist/integration-profile/testers/integration-tester.types.d.ts +55 -0
  184. package/dist/integration-profile/testers/integration-tester.types.d.ts.map +1 -0
  185. package/dist/integration-profile/testers/integration-tester.types.js +16 -0
  186. package/dist/integration-profile/testers/integration-tester.types.js.map +1 -0
  187. package/dist/integration-profile/testers/messaging.testers.d.ts +3 -0
  188. package/dist/integration-profile/testers/messaging.testers.d.ts.map +1 -0
  189. package/dist/integration-profile/testers/messaging.testers.js +70 -0
  190. package/dist/integration-profile/testers/messaging.testers.js.map +1 -0
  191. package/dist/integration-profile/testers/oauth.testers.d.ts +3 -0
  192. package/dist/integration-profile/testers/oauth.testers.d.ts.map +1 -0
  193. package/dist/integration-profile/testers/oauth.testers.js +285 -0
  194. package/dist/integration-profile/testers/oauth.testers.js.map +1 -0
  195. package/dist/integration-profile/testers/payment.testers.d.ts +3 -0
  196. package/dist/integration-profile/testers/payment.testers.d.ts.map +1 -0
  197. package/dist/integration-profile/testers/payment.testers.js +169 -0
  198. package/dist/integration-profile/testers/payment.testers.js.map +1 -0
  199. package/dist/integration-profile/testers/storage.testers.d.ts +3 -0
  200. package/dist/integration-profile/testers/storage.testers.d.ts.map +1 -0
  201. package/dist/integration-profile/testers/storage.testers.js +208 -0
  202. package/dist/integration-profile/testers/storage.testers.js.map +1 -0
  203. package/dist/language/en.json +4 -2
  204. package/dist/language/pt.json +4 -2
  205. package/dist/leaked-password/leaked-password.controller.d.ts +24 -0
  206. package/dist/leaked-password/leaked-password.controller.d.ts.map +1 -0
  207. package/dist/leaked-password/leaked-password.controller.js +78 -0
  208. package/dist/leaked-password/leaked-password.controller.js.map +1 -0
  209. package/dist/leaked-password/leaked-password.module.d.ts +8 -0
  210. package/dist/leaked-password/leaked-password.module.d.ts.map +1 -0
  211. package/dist/leaked-password/leaked-password.module.js +31 -0
  212. package/dist/leaked-password/leaked-password.module.js.map +1 -0
  213. package/dist/leaked-password/leaked-password.service.d.ts +64 -0
  214. package/dist/leaked-password/leaked-password.service.d.ts.map +1 -0
  215. package/dist/leaked-password/leaked-password.service.js +218 -0
  216. package/dist/leaked-password/leaked-password.service.js.map +1 -0
  217. package/dist/locale/locale.controller.d.ts +1 -1
  218. package/dist/locale/locale.service.d.ts +1 -1
  219. package/dist/mail/dto/preview.dto.d.ts +18 -0
  220. package/dist/mail/dto/preview.dto.d.ts.map +1 -0
  221. package/dist/mail/dto/preview.dto.js +66 -0
  222. package/dist/mail/dto/preview.dto.js.map +1 -0
  223. package/dist/mail/dto/send.dto.d.ts +7 -0
  224. package/dist/mail/dto/send.dto.d.ts.map +1 -1
  225. package/dist/mail/dto/send.dto.js +10 -0
  226. package/dist/mail/dto/send.dto.js.map +1 -1
  227. package/dist/mail/mail.controller.d.ts +4 -0
  228. package/dist/mail/mail.controller.d.ts.map +1 -1
  229. package/dist/mail/mail.controller.js +16 -2
  230. package/dist/mail/mail.controller.js.map +1 -1
  231. package/dist/mail/mail.service.d.ts +23 -2
  232. package/dist/mail/mail.service.d.ts.map +1 -1
  233. package/dist/mail/mail.service.js +102 -13
  234. package/dist/mail/mail.service.js.map +1 -1
  235. package/dist/mail-layout/dto/update.dto.d.ts +17 -0
  236. package/dist/mail-layout/dto/update.dto.d.ts.map +1 -0
  237. package/dist/mail-layout/dto/update.dto.js +27 -0
  238. package/dist/mail-layout/dto/update.dto.js.map +1 -0
  239. package/dist/mail-layout/mail-layout.controller.d.ts +15 -0
  240. package/dist/mail-layout/mail-layout.controller.d.ts.map +1 -0
  241. package/dist/mail-layout/mail-layout.controller.js +71 -0
  242. package/dist/mail-layout/mail-layout.controller.js.map +1 -0
  243. package/dist/mail-layout/mail-layout.module.d.ts +3 -0
  244. package/dist/mail-layout/mail-layout.module.d.ts.map +1 -0
  245. package/dist/mail-layout/mail-layout.module.js +35 -0
  246. package/dist/mail-layout/mail-layout.module.js.map +1 -0
  247. package/dist/mail-layout/mail-layout.service.d.ts +27 -0
  248. package/dist/mail-layout/mail-layout.service.d.ts.map +1 -0
  249. package/dist/mail-layout/mail-layout.service.js +80 -0
  250. package/dist/mail-layout/mail-layout.service.js.map +1 -0
  251. package/dist/mcp-chat/mcp-chat.controller.d.ts +2 -2
  252. package/dist/mcp-chat/mcp-chat.service.d.ts +24 -2
  253. package/dist/mcp-chat/mcp-chat.service.d.ts.map +1 -1
  254. package/dist/mcp-chat/mcp-chat.service.js +80 -24
  255. package/dist/mcp-chat/mcp-chat.service.js.map +1 -1
  256. package/dist/menu/menu.controller.d.ts +3 -3
  257. package/dist/menu/menu.service.d.ts +3 -3
  258. package/dist/notification/notification.controller.d.ts +12 -12
  259. package/dist/notification/notification.service.d.ts +12 -12
  260. package/dist/oauth/oauth-token-broker.service.d.ts +72 -0
  261. package/dist/oauth/oauth-token-broker.service.d.ts.map +1 -0
  262. package/dist/oauth/oauth-token-broker.service.js +258 -0
  263. package/dist/oauth/oauth-token-broker.service.js.map +1 -0
  264. package/dist/oauth/oauth.module.d.ts.map +1 -1
  265. package/dist/oauth/oauth.module.js +3 -1
  266. package/dist/oauth/oauth.module.js.map +1 -1
  267. package/dist/oauth/oauth.service.d.ts +2 -0
  268. package/dist/oauth/oauth.service.d.ts.map +1 -1
  269. package/dist/oauth/oauth.service.js +6 -3
  270. package/dist/oauth/oauth.service.js.map +1 -1
  271. package/dist/pdf/pdf.service.d.ts +8 -0
  272. package/dist/pdf/pdf.service.d.ts.map +1 -1
  273. package/dist/pdf/pdf.service.js +52 -0
  274. package/dist/pdf/pdf.service.js.map +1 -1
  275. package/dist/presence/presence.controller.d.ts +16 -0
  276. package/dist/presence/presence.controller.d.ts.map +1 -0
  277. package/dist/presence/presence.controller.js +60 -0
  278. package/dist/presence/presence.controller.js.map +1 -0
  279. package/dist/presence/presence.listener.d.ts +29 -0
  280. package/dist/presence/presence.listener.d.ts.map +1 -0
  281. package/dist/presence/presence.listener.js +82 -0
  282. package/dist/presence/presence.listener.js.map +1 -0
  283. package/dist/presence/presence.module.d.ts +3 -0
  284. package/dist/presence/presence.module.d.ts.map +1 -0
  285. package/dist/presence/presence.module.js +32 -0
  286. package/dist/presence/presence.module.js.map +1 -0
  287. package/dist/presence/presence.service.d.ts +42 -0
  288. package/dist/presence/presence.service.d.ts.map +1 -0
  289. package/dist/presence/presence.service.js +147 -0
  290. package/dist/presence/presence.service.js.map +1 -0
  291. package/dist/profile/dto/delete-account.dto.d.ts +8 -0
  292. package/dist/profile/dto/delete-account.dto.d.ts.map +1 -0
  293. package/dist/profile/dto/delete-account.dto.js +22 -0
  294. package/dist/profile/dto/delete-account.dto.js.map +1 -0
  295. package/dist/profile/events/profile-account-deleted.event.d.ts +12 -0
  296. package/dist/profile/events/profile-account-deleted.event.d.ts.map +1 -0
  297. package/dist/profile/events/profile-account-deleted.event.js +17 -0
  298. package/dist/profile/events/profile-account-deleted.event.js.map +1 -0
  299. package/dist/profile/profile.controller.d.ts +24 -17
  300. package/dist/profile/profile.controller.d.ts.map +1 -1
  301. package/dist/profile/profile.controller.js +75 -46
  302. package/dist/profile/profile.controller.js.map +1 -1
  303. package/dist/profile/profile.service.d.ts +34 -21
  304. package/dist/profile/profile.service.d.ts.map +1 -1
  305. package/dist/profile/profile.service.js +113 -37
  306. package/dist/profile/profile.service.js.map +1 -1
  307. package/dist/realtime/realtime.gateway.d.ts +48 -0
  308. package/dist/realtime/realtime.gateway.d.ts.map +1 -0
  309. package/dist/realtime/realtime.gateway.js +156 -0
  310. package/dist/realtime/realtime.gateway.js.map +1 -0
  311. package/dist/realtime/realtime.module.d.ts +8 -0
  312. package/dist/realtime/realtime.module.d.ts.map +1 -0
  313. package/dist/realtime/realtime.module.js +29 -0
  314. package/dist/realtime/realtime.module.js.map +1 -0
  315. package/dist/realtime/realtime.service.d.ts +51 -0
  316. package/dist/realtime/realtime.service.d.ts.map +1 -0
  317. package/dist/realtime/realtime.service.js +177 -0
  318. package/dist/realtime/realtime.service.js.map +1 -0
  319. package/dist/redis/redis-pubsub.d.ts +27 -0
  320. package/dist/redis/redis-pubsub.d.ts.map +1 -0
  321. package/dist/redis/redis-pubsub.js +140 -0
  322. package/dist/redis/redis-pubsub.js.map +1 -0
  323. package/dist/role/role.controller.d.ts +3 -3
  324. package/dist/role/role.service.d.ts +3 -3
  325. package/dist/setting/dto/create.dto.d.ts.map +1 -1
  326. package/dist/setting/dto/create.dto.js +9 -2
  327. package/dist/setting/dto/create.dto.js.map +1 -1
  328. package/dist/setting/setting.controller.d.ts +5 -5
  329. package/dist/setting/setting.service.d.ts +8 -5
  330. package/dist/setting/setting.service.d.ts.map +1 -1
  331. package/dist/setting/setting.service.js +25 -1
  332. package/dist/setting/setting.service.js.map +1 -1
  333. package/dist/user/dto/create-with-email-and-password.dto.d.ts +2 -0
  334. package/dist/user/dto/create-with-email-and-password.dto.d.ts.map +1 -1
  335. package/dist/user/dto/create-with-email-and-password.dto.js +5 -0
  336. package/dist/user/dto/create-with-email-and-password.dto.js.map +1 -1
  337. package/dist/user/dto/query-user-mail-list.dto.d.ts +5 -0
  338. package/dist/user/dto/query-user-mail-list.dto.d.ts.map +1 -0
  339. package/dist/user/dto/query-user-mail-list.dto.js +25 -0
  340. package/dist/user/dto/query-user-mail-list.dto.js.map +1 -0
  341. package/dist/user/user-credential.util.d.ts +19 -0
  342. package/dist/user/user-credential.util.d.ts.map +1 -0
  343. package/dist/user/user-credential.util.js +32 -0
  344. package/dist/user/user-credential.util.js.map +1 -0
  345. package/dist/user/user.controller.d.ts +17 -5
  346. package/dist/user/user.controller.d.ts.map +1 -1
  347. package/dist/user/user.controller.js +18 -3
  348. package/dist/user/user.controller.js.map +1 -1
  349. package/dist/user/user.service.d.ts +28 -6
  350. package/dist/user/user.service.d.ts.map +1 -1
  351. package/dist/user/user.service.js +204 -13
  352. package/dist/user/user.service.js.map +1 -1
  353. package/dist/validators/is-strong-password-with-settings.validator.d.ts.map +1 -1
  354. package/dist/validators/is-strong-password-with-settings.validator.js +11 -0
  355. package/dist/validators/is-strong-password-with-settings.validator.js.map +1 -1
  356. package/dist/validators/service-locator.d.ts +9 -0
  357. package/dist/validators/service-locator.d.ts.map +1 -1
  358. package/dist/validators/service-locator.js +12 -0
  359. package/dist/validators/service-locator.js.map +1 -1
  360. package/dist/webhook-integration/webhook-integration.controller.d.ts +5 -8
  361. package/dist/webhook-integration/webhook-integration.controller.d.ts.map +1 -1
  362. package/dist/webhook-integration/webhook-integration.controller.js +31 -8
  363. package/dist/webhook-integration/webhook-integration.controller.js.map +1 -1
  364. package/dist/webhook-integration/webhook-integration.module.d.ts.map +1 -1
  365. package/dist/webhook-integration/webhook-integration.module.js +5 -0
  366. package/dist/webhook-integration/webhook-integration.module.js.map +1 -1
  367. package/dist/webhook-integration/webhook-integration.service.d.ts +33 -1
  368. package/dist/webhook-integration/webhook-integration.service.d.ts.map +1 -1
  369. package/dist/webhook-integration/webhook-integration.service.js +109 -4
  370. package/dist/webhook-integration/webhook-integration.service.js.map +1 -1
  371. package/dist/webhook-integration/webhook-protocol.registry.d.ts +63 -0
  372. package/dist/webhook-integration/webhook-protocol.registry.d.ts.map +1 -0
  373. package/dist/webhook-integration/webhook-protocol.registry.js +51 -0
  374. package/dist/webhook-integration/webhook-protocol.registry.js.map +1 -0
  375. package/dist/whatsapp-sender/whatsapp-sender.module.d.ts +3 -0
  376. package/dist/whatsapp-sender/whatsapp-sender.module.d.ts.map +1 -0
  377. package/dist/whatsapp-sender/whatsapp-sender.module.js +23 -0
  378. package/dist/whatsapp-sender/whatsapp-sender.module.js.map +1 -0
  379. package/dist/whatsapp-sender/whatsapp-sender.service.d.ts +50 -0
  380. package/dist/whatsapp-sender/whatsapp-sender.service.d.ts.map +1 -0
  381. package/dist/whatsapp-sender/whatsapp-sender.service.js +224 -0
  382. package/dist/whatsapp-sender/whatsapp-sender.service.js.map +1 -0
  383. package/hedhog/data/integration_provider.yaml +16 -0
  384. package/hedhog/data/mail.yaml +88 -61
  385. package/hedhog/data/mail_layout.yaml +188 -0
  386. package/hedhog/data/menu.yaml +67 -3
  387. package/hedhog/data/route.yaml +135 -0
  388. package/hedhog/data/setting_group.yaml +139 -1
  389. package/hedhog/frontend/app/account/components/mfa-setup-dialog.tsx.ejs +36 -0
  390. package/hedhog/frontend/app/account/components/two-factor-auth.tsx.ejs +2 -0
  391. package/hedhog/frontend/app/account/hooks/use-mfa-setup.ts.ejs +10 -7
  392. package/hedhog/frontend/app/ai_agent/page.tsx.ejs +7 -4
  393. package/hedhog/frontend/app/ai_instruction/_components/ai-instruction-form.tsx.ejs +580 -0
  394. package/hedhog/frontend/app/ai_instruction/_components/ai-instruction-preview.tsx.ejs +150 -0
  395. package/hedhog/frontend/app/ai_instruction/_components/ai-instruction-versions.tsx.ejs +199 -0
  396. package/hedhog/frontend/app/ai_instruction/_components/prompt-diff.tsx.ejs +63 -0
  397. package/hedhog/frontend/app/ai_instruction/_lib/line-diff.spec.ts.ejs +59 -0
  398. package/hedhog/frontend/app/ai_instruction/_lib/line-diff.ts.ejs +72 -0
  399. package/hedhog/frontend/app/ai_instruction/_lib/prompt-template.spec.ts.ejs +170 -0
  400. package/hedhog/frontend/app/ai_instruction/_lib/prompt-template.ts.ejs +167 -0
  401. package/hedhog/frontend/app/ai_instruction/_lib/types.ts.ejs +99 -0
  402. package/hedhog/frontend/app/ai_instruction/page.tsx.ejs +422 -0
  403. package/hedhog/frontend/app/configurations/[slug]/components/setting-field.tsx.ejs +51 -4
  404. package/hedhog/frontend/app/incidents/page.tsx.ejs +400 -0
  405. package/hedhog/frontend/app/integration/profiles/page.tsx.ejs +169 -92
  406. package/hedhog/frontend/app/mail/layout/page.tsx.ejs +344 -0
  407. package/hedhog/frontend/app/mail/template/page.tsx.ejs +155 -121
  408. package/hedhog/frontend/app/mcp_chat/page.tsx.ejs +129 -17
  409. package/hedhog/frontend/app/pages/_components/page-delete-dialog.tsx.ejs +343 -0
  410. package/hedhog/frontend/app/pages/_components/page-detail-sheet.tsx.ejs +438 -0
  411. package/hedhog/frontend/app/pages/_components/page-wizard-sheet.tsx.ejs +1009 -0
  412. package/hedhog/frontend/app/pages/_components/system-page-types.ts.ejs +56 -0
  413. package/hedhog/frontend/app/pages/_components/use-system-pages.ts.ejs +171 -0
  414. package/hedhog/frontend/app/pages/page.tsx.ejs +514 -0
  415. package/hedhog/frontend/app/users/page.tsx.ejs +119 -13
  416. package/hedhog/frontend/app/users/user-activity-timeline.tsx.ejs +231 -0
  417. package/hedhog/frontend/app/users/user-mails.tsx.ejs +399 -0
  418. package/hedhog/frontend/app/users/user-sheet.tsx.ejs +60 -75
  419. package/hedhog/frontend/messages/en.json +521 -3
  420. package/hedhog/frontend/messages/pt.json +521 -3
  421. package/hedhog/table/ai_agent.yaml +1 -0
  422. package/hedhog/table/ai_instruction.yaml +15 -0
  423. package/hedhog/table/leaked_password.yaml +18 -0
  424. package/hedhog/table/mail_layout.yaml +35 -0
  425. package/hedhog/table/mail_var.yaml +4 -0
  426. package/hedhog/table/setting.yaml +1 -0
  427. package/hedhog/table/system_incident.yaml +59 -0
  428. package/hedhog/table/user_presence.yaml +36 -0
  429. package/hedhog/table/webhook_integration.yaml +64 -43
  430. package/package.json +8 -4
  431. package/src/access-log/access-log.interceptor.ts +4 -2
  432. package/src/ai/ai-attachment.fragments.spec.ts +319 -0
  433. package/src/ai/ai-attachment.fragments.ts +35 -0
  434. package/src/ai/ai.prompts.ts +38 -0
  435. package/src/ai/ai.service.spec.ts +280 -0
  436. package/src/ai/ai.service.ts +338 -82
  437. package/src/ai/dto/chat.dto.ts +33 -3
  438. package/src/ai/dto/create-agent.dto.ts +2 -2
  439. package/src/ai/dto/update-agent.dto.ts +2 -2
  440. package/src/ai-instruction/ai-instruction.controller.ts +40 -9
  441. package/src/ai-instruction/ai-instruction.module.ts +13 -2
  442. package/src/ai-instruction/ai-instruction.service.spec.ts +658 -0
  443. package/src/ai-instruction/ai-instruction.service.ts +661 -62
  444. package/src/ai-instruction/ai-prompt-builder.service.ts +10 -1
  445. package/src/ai-instruction/ai-prompt-registry.ts +87 -0
  446. package/src/ai-instruction/ai-prompt-resolver.service.spec.ts +375 -0
  447. package/src/ai-instruction/ai-prompt-resolver.service.ts +295 -0
  448. package/src/ai-instruction/ai-prompt-template.util.spec.ts +162 -0
  449. package/src/ai-instruction/ai-prompt-template.util.ts +199 -0
  450. package/src/ai-instruction/dto/create-ai-instruction.dto.ts +39 -3
  451. package/src/ai-instruction/dto/preview-ai-instruction.dto.ts +26 -0
  452. package/src/ai-instruction/dto/update-ai-instruction.dto.ts +42 -1
  453. package/src/ai-instruction/types/ai-instruction.types.ts +24 -1
  454. package/src/auth/auth.controller.ts +33 -6
  455. package/src/auth/auth.service.spec.ts +3 -1
  456. package/src/auth/auth.service.ts +103 -37
  457. package/src/captcha/captcha.module.ts +10 -0
  458. package/src/captcha/captcha.service.spec.ts +210 -0
  459. package/src/captcha/captcha.service.ts +191 -0
  460. package/src/challenge/challenge.service.spec.ts +39 -4
  461. package/src/challenge/challenge.service.ts +72 -17
  462. package/src/core.module.ts +27 -1
  463. package/src/file/file.service.spec.ts +105 -0
  464. package/src/file/file.service.ts +60 -3
  465. package/src/incident/incident-notifier.service.spec.ts +205 -0
  466. package/src/incident/incident-notifier.service.ts +241 -0
  467. package/src/incident/incident.controller.ts +38 -0
  468. package/src/incident/incident.module.ts +19 -0
  469. package/src/incident/incident.service.spec.ts +150 -0
  470. package/src/incident/incident.service.ts +209 -0
  471. package/src/index.ts +38 -0
  472. package/src/integration-profile/dto/test.dto.ts +19 -0
  473. package/src/integration-profile/integration-profile.controller.ts +10 -1
  474. package/src/integration-profile/integration-profile.module.spec.ts +51 -0
  475. package/src/integration-profile/integration-profile.module.ts +23 -4
  476. package/src/integration-profile/integration-profile.secrets.ts +12 -2
  477. package/src/integration-profile/integration-profile.service.spec.ts +279 -0
  478. package/src/integration-profile/integration-profile.service.ts +132 -29
  479. package/src/integration-profile/integration-profile.utils.spec.ts +97 -0
  480. package/src/integration-profile/integration-profile.utils.ts +79 -3
  481. package/src/integration-profile/testers/ai.testers.ts +165 -0
  482. package/src/integration-profile/testers/captcha.testers.spec.ts +92 -0
  483. package/src/integration-profile/testers/captcha.testers.ts +139 -0
  484. package/src/integration-profile/testers/email.testers.ts +161 -0
  485. package/src/integration-profile/testers/http-probe.spec.ts +153 -0
  486. package/src/integration-profile/testers/http-probe.ts +171 -0
  487. package/src/integration-profile/testers/index.ts +30 -0
  488. package/src/integration-profile/testers/infrastructure.testers.ts +122 -0
  489. package/src/integration-profile/testers/integration-tester.registry.spec.ts +75 -0
  490. package/src/integration-profile/testers/integration-tester.registry.ts +43 -0
  491. package/src/integration-profile/testers/integration-tester.types.ts +61 -0
  492. package/src/integration-profile/testers/messaging.testers.ts +102 -0
  493. package/src/integration-profile/testers/oauth.testers.spec.ts +220 -0
  494. package/src/integration-profile/testers/oauth.testers.ts +305 -0
  495. package/src/integration-profile/testers/payment.testers.ts +185 -0
  496. package/src/integration-profile/testers/remaining.testers.spec.ts +401 -0
  497. package/src/integration-profile/testers/storage.testers.spec.ts +185 -0
  498. package/src/integration-profile/testers/storage.testers.ts +226 -0
  499. package/src/integration-profile/testers/tester-coverage.spec.ts +58 -0
  500. package/src/language/en.json +4 -2
  501. package/src/language/pt.json +4 -2
  502. package/src/leaked-password/README.md +83 -0
  503. package/src/leaked-password/leaked-password.controller.ts +52 -0
  504. package/src/leaked-password/leaked-password.module.ts +18 -0
  505. package/src/leaked-password/leaked-password.service.ts +242 -0
  506. package/src/leaked-password/seed/build-seed-sql.mjs +180 -0
  507. package/src/leaked-password/seed/common-passwords.txt +335 -0
  508. package/src/mail/dto/preview.dto.ts +50 -0
  509. package/src/mail/dto/send.dto.ts +14 -1
  510. package/src/mail/mail-template.spec.ts +197 -0
  511. package/src/mail/mail.controller.ts +9 -2
  512. package/src/mail/mail.service.spec.ts +116 -1
  513. package/src/mail/mail.service.ts +118 -12
  514. package/src/mail-layout/dto/update.dto.ts +19 -0
  515. package/src/mail-layout/mail-layout.controller.ts +47 -0
  516. package/src/mail-layout/mail-layout.module.ts +22 -0
  517. package/src/mail-layout/mail-layout.service.ts +94 -0
  518. package/src/mcp-chat/mcp-chat.service.spec.ts +236 -0
  519. package/src/mcp-chat/mcp-chat.service.ts +122 -26
  520. package/src/oauth/oauth-token-broker.service.spec.ts +172 -0
  521. package/src/oauth/oauth-token-broker.service.ts +363 -0
  522. package/src/oauth/oauth.module.ts +3 -1
  523. package/src/oauth/oauth.service.ts +8 -2
  524. package/src/pdf/pdf.service.ts +75 -0
  525. package/src/presence/presence.controller.ts +29 -0
  526. package/src/presence/presence.listener.ts +53 -0
  527. package/src/presence/presence.module.ts +19 -0
  528. package/src/presence/presence.service.spec.ts +97 -0
  529. package/src/presence/presence.service.ts +160 -0
  530. package/src/profile/dto/delete-account.dto.ts +11 -0
  531. package/src/profile/events/profile-account-deleted.event.ts +13 -0
  532. package/src/profile/profile.controller.ts +52 -36
  533. package/src/profile/profile.service.ts +143 -41
  534. package/src/realtime/realtime.gateway.ts +138 -0
  535. package/src/realtime/realtime.module.ts +16 -0
  536. package/src/realtime/realtime.service.spec.ts +50 -0
  537. package/src/realtime/realtime.service.ts +187 -0
  538. package/src/redis/redis-pubsub.ts +179 -0
  539. package/src/setting/dto/create.dto.ts +13 -2
  540. package/src/setting/setting.service.spec.ts +56 -0
  541. package/src/setting/setting.service.ts +29 -1
  542. package/src/user/dto/create-with-email-and-password.dto.ts +6 -1
  543. package/src/user/dto/query-user-mail-list.dto.ts +10 -0
  544. package/src/user/user-credential.util.ts +35 -0
  545. package/src/user/user.controller.ts +17 -2
  546. package/src/user/user.service.spec.ts +153 -0
  547. package/src/user/user.service.ts +255 -12
  548. package/src/validators/is-strong-password-with-settings.validator.ts +12 -0
  549. package/src/validators/service-locator.ts +15 -0
  550. package/src/webhook-integration/webhook-integration.controller.ts +40 -2
  551. package/src/webhook-integration/webhook-integration.module.ts +5 -0
  552. package/src/webhook-integration/webhook-integration.service.ts +133 -0
  553. package/src/webhook-integration/webhook-protocol.registry.spec.ts +70 -0
  554. package/src/webhook-integration/webhook-protocol.registry.ts +93 -0
  555. package/src/whatsapp-sender/whatsapp-sender.module.ts +10 -0
  556. package/src/whatsapp-sender/whatsapp-sender.service.ts +313 -0
@@ -1,12 +1,26 @@
1
- import { IsBoolean, IsEnum, IsObject, IsOptional, IsString, MaxLength } from 'class-validator';
2
- import { AiInstructionLayer } from '../types/ai-instruction.types';
1
+ import {
2
+ IsBoolean,
3
+ IsIn,
4
+ IsInt,
5
+ IsNumber,
6
+ IsObject,
7
+ IsOptional,
8
+ IsString,
9
+ Max,
10
+ MaxLength,
11
+ Min,
12
+ } from 'class-validator';
13
+ import {
14
+ AI_INSTRUCTION_LAYERS,
15
+ AiInstructionLayer,
16
+ } from '../types/ai-instruction.types';
3
17
 
4
18
  export class CreateAiInstructionDTO {
5
19
  @IsString()
6
20
  @MaxLength(255)
7
21
  slug: string;
8
22
 
9
- @IsEnum(['system', 'product', 'module', 'agent', 'tool', 'output'])
23
+ @IsIn(AI_INSTRUCTION_LAYERS)
10
24
  layer: AiInstructionLayer;
11
25
 
12
26
  @IsString()
@@ -33,4 +47,26 @@ export class CreateAiInstructionDTO {
33
47
  @IsOptional()
34
48
  @IsBoolean()
35
49
  is_active?: boolean;
50
+
51
+ @IsOptional()
52
+ @IsString()
53
+ @MaxLength(100)
54
+ model?: string | null;
55
+
56
+ @IsOptional()
57
+ @IsNumber()
58
+ @Min(0)
59
+ @Max(2)
60
+ temperature?: number | null;
61
+
62
+ @IsOptional()
63
+ @IsInt()
64
+ @Min(1)
65
+ @Max(200000)
66
+ max_tokens?: number | null;
67
+
68
+ /** Save even when required variables are missing from the content. */
69
+ @IsOptional()
70
+ @IsBoolean()
71
+ allow_missing_variables?: boolean;
36
72
  }
@@ -0,0 +1,26 @@
1
+ import { IsObject, IsOptional, IsString, MaxLength } from 'class-validator';
2
+
3
+ /**
4
+ * Stateless render of a draft. The admin sends the content currently in the
5
+ * textarea — unsaved — so the editor can see the interpolated result before
6
+ * committing to it.
7
+ */
8
+ export class PreviewAiInstructionDTO {
9
+ @IsString()
10
+ content: string;
11
+
12
+ /** Only used to look up the registry definition (guard phrases, variables). */
13
+ @IsOptional()
14
+ @IsString()
15
+ @MaxLength(255)
16
+ slug?: string;
17
+
18
+ /** Fallback when the slug is not registered in code. */
19
+ @IsOptional()
20
+ @IsObject()
21
+ variables_schema?: Record<string, any>;
22
+
23
+ @IsOptional()
24
+ @IsObject()
25
+ variables?: Record<string, string | number | boolean>;
26
+ }
@@ -1,5 +1,19 @@
1
- import { IsBoolean, IsObject, IsOptional, IsString, MaxLength } from 'class-validator';
1
+ import {
2
+ IsBoolean,
3
+ IsInt,
4
+ IsNumber,
5
+ IsObject,
6
+ IsOptional,
7
+ IsString,
8
+ Max,
9
+ MaxLength,
10
+ Min,
11
+ } from 'class-validator';
2
12
 
13
+ /**
14
+ * `slug` and `layer` are intentionally absent — they are immutable after
15
+ * creation, since the calling code resolves prompts by slug.
16
+ */
3
17
  export class UpdateAiInstructionDTO {
4
18
  @IsOptional()
5
19
  @IsString()
@@ -32,4 +46,31 @@ export class UpdateAiInstructionDTO {
32
46
  @IsString()
33
47
  @MaxLength(500)
34
48
  change_note?: string;
49
+
50
+ @IsOptional()
51
+ @IsString()
52
+ @MaxLength(100)
53
+ model?: string | null;
54
+
55
+ @IsOptional()
56
+ @IsNumber()
57
+ @Min(0)
58
+ @Max(2)
59
+ temperature?: number | null;
60
+
61
+ @IsOptional()
62
+ @IsInt()
63
+ @Min(1)
64
+ @Max(200000)
65
+ max_tokens?: number | null;
66
+
67
+ /** Save even when required variables are missing from the content. */
68
+ @IsOptional()
69
+ @IsBoolean()
70
+ allow_missing_variables?: boolean;
71
+
72
+ /** Required to edit a record flagged `is_locked` (security-sensitive prompt). */
73
+ @IsOptional()
74
+ @IsBoolean()
75
+ acknowledge_security_review?: boolean;
35
76
  }
@@ -4,7 +4,18 @@ export type AiInstructionLayer =
4
4
  | 'module'
5
5
  | 'agent'
6
6
  | 'tool'
7
- | 'output';
7
+ | 'output'
8
+ | 'task';
9
+
10
+ export const AI_INSTRUCTION_LAYERS: AiInstructionLayer[] = [
11
+ 'system',
12
+ 'product',
13
+ 'module',
14
+ 'agent',
15
+ 'tool',
16
+ 'output',
17
+ 'task',
18
+ ];
8
19
 
9
20
  export type AiInstructionRecord = {
10
21
  id: number;
@@ -17,10 +28,22 @@ export type AiInstructionRecord = {
17
28
  module_slug: string | null;
18
29
  is_active: boolean;
19
30
  version: number;
31
+ /** NULL means "keep whatever the calling code already uses". */
32
+ model: string | null;
33
+ temperature: number | null;
34
+ max_tokens: number | null;
35
+ /** Editing requires an explicit acknowledgement (security-sensitive prompt). */
36
+ is_locked: boolean;
20
37
  created_at: Date;
21
38
  updated_at: Date;
22
39
  };
23
40
 
41
+ export type AiInstructionListFilters = {
42
+ layer?: AiInstructionLayer;
43
+ module_slug?: string;
44
+ is_active?: boolean;
45
+ };
46
+
24
47
  export type AiExecutionTrigger = 'manual' | 'webhook' | 'schedule' | 'tool' | 'api';
25
48
  export type AiExecutionStatus = 'running' | 'completed' | 'failed' | 'cancelled';
26
49
  export type AiExecutionStepType = 'prompt' | 'tool_call' | 'tool_result' | 'output' | 'error';
@@ -16,6 +16,7 @@ import {
16
16
  UseGuards
17
17
  } from '@nestjs/common';
18
18
  import { Throttle, ThrottlerGuard } from '@nestjs/throttler';
19
+ import type { PublicKeyCredentialRequestOptionsJSON } from '@simplewebauthn/server';
19
20
  import { TokenService } from '../token/token.service';
20
21
  import { CreateWithEmailAndPasswordDTO } from '../user/dto/create-with-email-and-password.dto';
21
22
  import { UserService } from '../user/user.service';
@@ -102,9 +103,10 @@ export class AuthController {
102
103
  @Ip() ipAddress: string,
103
104
  @Headers('user-agent') userAgent: string,
104
105
  @Headers('x-browser-id') browserId: string,
106
+ @Headers('origin') origin: string,
105
107
  @Res({ passthrough: true }) res,
106
108
  ) {
107
- return this.service.loginWithEmailAndPassword(res, locale, ipAddress, userAgent, data, browserId || null);
109
+ return this.service.loginWithEmailAndPassword(res, locale, ipAddress, userAgent, data, browserId || null, origin);
108
110
  }
109
111
 
110
112
  @Public()
@@ -117,18 +119,22 @@ export class AuthController {
117
119
  @Ip() ipAddress: string,
118
120
  @Headers('user-agent') userAgent: string,
119
121
  @Headers('x-browser-id') browserId: string,
122
+ @Headers('origin') origin: string,
120
123
  @Res({ passthrough: true }) res,
121
124
  ) {
122
- return this.service.emailVerificationLogin(locale, token, code, ipAddress, userAgent, res, browserId || null);
125
+ return this.service.emailVerificationLogin(locale, token, code, ipAddress, userAgent, res, browserId || null, origin);
123
126
  }
124
127
 
125
128
  @Public()
129
+ @UseGuards(ThrottlerGuard)
130
+ @Throttle({ default: { limit: 10, ttl: 60_000 } })
126
131
  @Post('login-email-verification-resend')
127
132
  async emailVerificationLoginResend(
128
133
  @Locale() locale: string,
129
134
  @Body() {token}: LoginEmailVerificationResendDTO,
135
+ @Headers('origin') origin: string,
130
136
  ) {
131
- return this.service.emailVerificationLoginResend(locale, token);
137
+ return this.service.emailVerificationLoginResend(locale, token, origin);
132
138
  }
133
139
 
134
140
  @Public()
@@ -150,6 +156,7 @@ export class AuthController {
150
156
  @Ip() ipAddress: string,
151
157
  @Headers('user-agent') userAgent: string,
152
158
  @Headers('x-browser-id') browserId: string,
159
+ @Headers('origin') origin: string,
153
160
  @Res({ passthrough: true }) res,
154
161
  ) {
155
162
  const { accessToken, refreshToken, session, requiresPasswordReset } = await this.service.verifyMfaCode(
@@ -160,6 +167,7 @@ export class AuthController {
160
167
  userAgent,
161
168
  methodType,
162
169
  browserId || null,
170
+ origin,
163
171
  );
164
172
 
165
173
  await this.token.setRefreshTokenCookie(locale, res, refreshToken, session.expires_at);
@@ -192,25 +200,32 @@ export class AuthController {
192
200
  }
193
201
 
194
202
  @Public()
203
+ @UseGuards(ThrottlerGuard)
204
+ @Throttle({ default: { limit: 10, ttl: 60_000 } })
195
205
  @Post('resend-mfa-code')
196
206
  async resendMfaCode(
197
207
  @Locale() locale: string,
198
208
  @Body() { token }: ResendMfaCodeDTO,
209
+ @Headers('origin') origin: string,
199
210
  ) {
200
- return this.service.resendMfaCode(locale, token);
211
+ return this.service.resendMfaCode(locale, token, origin);
201
212
  }
202
213
 
203
214
  @Public()
215
+ @UseGuards(ThrottlerGuard)
216
+ @Throttle({ default: { limit: 10, ttl: 60_000 } })
204
217
  @Post('webauthn/generate')
205
218
  async generateWebAuthnOptions(
206
219
  @Locale() locale: string,
207
220
  @Body() { mfaToken }: { mfaToken: string },
208
221
  @Headers('origin') origin: string
209
- ) {
222
+ ): Promise<PublicKeyCredentialRequestOptionsJSON> {
210
223
  return this.service.generateWebAuthnAuthenticationOptions(locale, mfaToken, origin);
211
224
  }
212
225
 
213
226
  @Public()
227
+ @UseGuards(ThrottlerGuard)
228
+ @Throttle({ default: { limit: 10, ttl: 60_000 } })
214
229
  @Post('webauthn/verify')
215
230
  async verifyWebAuthn(
216
231
  @Locale() locale: string,
@@ -267,8 +282,9 @@ export class AuthController {
267
282
  @Body() { password, code }: ResetDTO,
268
283
  @Ip() ipAddress: string,
269
284
  @Headers('user-agent') userAgent: string,
285
+ @Headers('origin') origin: string,
270
286
  ) {
271
- return this.service.forgotResetPassword(locale, password, code, ipAddress, userAgent);
287
+ return this.service.forgotResetPassword(locale, password, code, ipAddress, userAgent, origin);
272
288
  }
273
289
 
274
290
  @Public()
@@ -290,4 +306,15 @@ export class AuthController {
290
306
  ) {
291
307
  return this.service.completeAccount(locale, { password, code, name }, ipAddress, userAgent);
292
308
  }
309
+
310
+ @Public()
311
+ @Post('complete-account/authorize')
312
+ async authorizeAccountInvite(
313
+ @Locale() locale: string,
314
+ @Body() { code }: VerifyAccountInviteDTO,
315
+ @Ip() ipAddress: string,
316
+ @Headers('user-agent') userAgent: string,
317
+ ) {
318
+ return this.service.authorizeAccountInvite(locale, code, ipAddress, userAgent);
319
+ }
293
320
  }
@@ -62,6 +62,7 @@ const makeDeps = () => {
62
62
  forgotEmail: jest.fn(),
63
63
  verifyCodePassword: jest.fn(),
64
64
  verifyMfaEmailCode: jest.fn(),
65
+ resolveAppKeyFromOrigin: jest.fn().mockResolvedValue(undefined),
65
66
  };
66
67
  return { prisma, mail, setting, security, token, session, user, challenge };
67
68
  };
@@ -203,6 +204,7 @@ describe('AuthService', () => {
203
204
  'pt-BR',
204
205
  1,
205
206
  ['mfa@b.com'],
207
+ undefined,
206
208
  );
207
209
  expect(result).toEqual({
208
210
  requiresMfa: true,
@@ -655,7 +657,7 @@ describe('AuthService', () => {
655
657
 
656
658
  const result = await service.resendMfaCode('pt-BR', 'mfa-token');
657
659
 
658
- expect(deps.challenge.sendMfaCodeByEmail).toHaveBeenCalledWith('pt-BR', 1, 'a@b.com');
660
+ expect(deps.challenge.sendMfaCodeByEmail).toHaveBeenCalledWith('pt-BR', 1, 'a@b.com', undefined);
659
661
  expect(result).toEqual({ success: true, hasEmailMfa: true });
660
662
  });
661
663
  });
@@ -1,6 +1,7 @@
1
1
  import { getLocaleText } from '@hed-hog/api-locale';
2
2
  import { PrismaService } from '@hed-hog/api-prisma';
3
3
  import { User } from '@hed-hog/api-types';
4
+ import type { PublicKeyCredentialRequestOptionsJSON } from '@simplewebauthn/server';
4
5
  import {
5
6
  BadRequestException,
6
7
  forwardRef,
@@ -16,6 +17,7 @@ import { SecurityService } from '../security/security.service';
16
17
  import { SessionService } from '../session/session.service';
17
18
  import { SettingService } from '../setting/setting.service';
18
19
  import { TokenService } from '../token/token.service';
20
+ import { hasPendingPasswordReset } from '../user/user-credential.util';
19
21
  import { UserService } from '../user/user.service';
20
22
  import { resolveWebAuthnOrigin } from '../utils/webauthn-origin';
21
23
  import { ForgetDTO } from './dto/forget.dto';
@@ -65,14 +67,7 @@ export class AuthService {
65
67
  }
66
68
 
67
69
  private hasPendingPasswordReset(user: User | any) {
68
- return Boolean(
69
- user?.user_credential?.some(
70
- (credential) =>
71
- credential.type === 'password' &&
72
- credential.requires_reset === true &&
73
- !credential.revoked_at,
74
- ),
75
- );
70
+ return hasPendingPasswordReset(user);
76
71
  }
77
72
 
78
73
  private async getRequiresPasswordResetByUserId(userId: number) {
@@ -89,7 +84,7 @@ export class AuthService {
89
84
  return Boolean(credential?.id);
90
85
  }
91
86
 
92
- async requiresMfaForLogin(locale: string, email: string, user: any) {
87
+ async requiresMfaForLogin(locale: string, email: string, user: any, origin?: string) {
93
88
 
94
89
  const settings = await this.setting.getSettingValues([
95
90
  'require-mfa',
@@ -159,7 +154,8 @@ export class AuthService {
159
154
  variables: {
160
155
  code,
161
156
  name: user.name,
162
- }
157
+ },
158
+ app: await this.challenge.resolveAppKeyFromOrigin(origin),
163
159
  }
164
160
  );
165
161
 
@@ -172,7 +168,7 @@ export class AuthService {
172
168
  }
173
169
  }
174
170
 
175
- async requiresEmailVerificationForLogin(locale: string, email: string, user: any) {
171
+ async requiresEmailVerificationForLogin(locale: string, email: string, user: any, origin?: string) {
176
172
 
177
173
  const settings = await this.setting.getSettingValues([
178
174
  'require-mfa',
@@ -216,7 +212,8 @@ export class AuthService {
216
212
  variables: {
217
213
  code,
218
214
  name: user.name,
219
- }
215
+ },
216
+ app: await this.challenge.resolveAppKeyFromOrigin(origin),
220
217
  }
221
218
  );
222
219
 
@@ -230,7 +227,7 @@ export class AuthService {
230
227
 
231
228
  }
232
229
 
233
- async emailVerificationLoginResend(locale: string, token: string) {
230
+ async emailVerificationLoginResend(locale: string, token: string, origin?: string) {
234
231
 
235
232
  try {
236
233
  const payload = await this.token.verify(locale, token);
@@ -252,25 +249,25 @@ export class AuthService {
252
249
 
253
250
  const user = await this.user.findUserById(locale, challenge.user_identifier.user_id);
254
251
 
255
- return await this.requiresEmailVerificationForLogin(locale, payload.email, user);
252
+ return await this.requiresEmailVerificationForLogin(locale, payload.email, user, origin);
256
253
 
257
254
  } catch (error: any) {
258
255
  if (error.message?.includes('jwt expired') || error.name === 'TokenExpiredError') {
259
-
256
+
260
257
  const expiredPayload = await this.token.decodeExpiredToken(token);
261
258
  const newToken = await this.token.createAccessToken({
262
259
  challengeIdentifierId: expiredPayload.challengeIdentifierId,
263
260
  email: expiredPayload.email
264
261
  });
265
262
 
266
- return this.emailVerificationLoginResend(locale, newToken);
263
+ return this.emailVerificationLoginResend(locale, newToken, origin);
267
264
  }
268
-
265
+
269
266
  throw error;
270
267
  }
271
268
  }
272
269
 
273
- async emailVerificationLogin(locale: string, token: string, code: string, ipAddress: string, userAgent: string, res: any, browserId?: string | null) {
270
+ async emailVerificationLogin(locale: string, token: string, code: string, ipAddress: string, userAgent: string, res: any, browserId?: string | null, origin?: string) {
274
271
 
275
272
  try {
276
273
  const payload = await this.token.verify(locale, token);
@@ -323,14 +320,25 @@ export class AuthService {
323
320
 
324
321
  const user = await this.user.findUserById(locale, challenge.user_identifier.user_id);
325
322
 
326
- return this.login(locale, user as unknown as User, ipAddress, userAgent, res, browserId);
323
+ return this.login(locale, user as unknown as User, ipAddress, userAgent, res, browserId, origin);
327
324
 
328
325
  } catch (error) {
329
326
  throw error;
330
327
  }
331
328
  }
332
329
 
333
- private async login(locale: string, user: User, ipAddress: string, userAgent: string, res: any, browserId?: string | null) {
330
+ private async login(locale: string, user: User, ipAddress: string, userAgent: string, res: any, browserId?: string | null, origin?: string) {
331
+
332
+ // Conta excluída pelo próprio usuário: os identificadores já foram
333
+ // anonimizados, mas a checagem fecha qualquer caminho remanescente.
334
+ const account = await this.prisma.user.findUnique({
335
+ where: { id: user.id },
336
+ select: { deactivated_at: true },
337
+ });
338
+
339
+ if (account?.deactivated_at) {
340
+ throw new BadRequestException(getLocaleText('accessDenied', locale, 'Access denied.'));
341
+ }
334
342
 
335
343
  const emails = await this.prisma.user_identifier.findMany({
336
344
  where: {
@@ -352,6 +360,8 @@ export class AuthService {
352
360
  browserId,
353
361
  );
354
362
 
363
+ const app = await this.challenge.resolveAppKeyFromOrigin(origin);
364
+
355
365
  for (const emailObj of emails) {
356
366
 
357
367
  this.mail.sendTemplatedMail(
@@ -364,7 +374,8 @@ export class AuthService {
364
374
  ipAddress,
365
375
  userAgent,
366
376
  location: 'Unknown',
367
- }
377
+ },
378
+ app,
368
379
  }
369
380
  );
370
381
 
@@ -390,6 +401,7 @@ export class AuthService {
390
401
  userAgent: string,
391
402
  { email, password }: LoginDTO,
392
403
  browserId?: string | null,
404
+ origin?: string,
393
405
  ) {
394
406
 
395
407
  const user = await this.user.findUserByEmail(locale, email);
@@ -427,11 +439,11 @@ export class AuthService {
427
439
 
428
440
  if (emailMfas.length > 0) {
429
441
  const emails = emailMfas.map(mfa => mfa.user_mfa_email[0].email);
430
- await this.challenge.sendMfaCodeToMultipleEmails(locale, user.id, emails);
442
+ await this.challenge.sendMfaCodeToMultipleEmails(locale, user.id, emails, origin);
431
443
  }
432
444
 
433
- return {
434
- requiresMfa: true,
445
+ return {
446
+ requiresMfa: true,
435
447
  mfaToken,
436
448
  mfaMethods: mfaMethods.map(m => ({ type: m.type, id: m.id }))
437
449
  };
@@ -446,15 +458,15 @@ export class AuthService {
446
458
 
447
459
  if (settings['require-mfa'] === true && mfaMethods.length === 0) {
448
460
 
449
- return this.requiresMfaForLogin(locale, email, user);
461
+ return this.requiresMfaForLogin(locale, email, user, origin);
450
462
 
451
463
  } else if (settings['require-email-verification'] === true && identifier?.verified_at === null) {
452
464
 
453
- return this.requiresEmailVerificationForLogin(locale, email, user);
465
+ return this.requiresEmailVerificationForLogin(locale, email, user, origin);
454
466
 
455
467
  }
456
468
 
457
- return this.login(locale, user as unknown as User, ipAddress, userAgent, res, browserId);
469
+ return this.login(locale, user as unknown as User, ipAddress, userAgent, res, browserId, origin);
458
470
  }
459
471
 
460
472
  async verifyRoles(_locale: string, userId: number) {
@@ -529,7 +541,7 @@ export class AuthService {
529
541
  return { success: true };
530
542
  }
531
543
 
532
- async forgotResetPassword(locale: string, password: string, code: string, ipAddress: string, userAgent: string) {
544
+ async forgotResetPassword(locale: string, password: string, code: string, ipAddress: string, userAgent: string, origin?: string) {
533
545
  const challenge = await this.challenge.verifyCodePassword(locale, code);
534
546
  const userIdentifier = challenge.user_identifier;
535
547
  const passwordHash = await this.security.hashArgon2(password);
@@ -549,12 +561,13 @@ export class AuthService {
549
561
  slug: 'auth-forget-password-confirmation',
550
562
  variables: {
551
563
  name: userIdentifier.user.name,
552
- }
564
+ },
565
+ app: await this.challenge.resolveAppKeyFromOrigin(origin),
553
566
  }
554
567
  );
555
568
 
556
569
  const { accessToken, refreshToken, session } = await this.getAuthenticationPayload(locale, userIdentifier.user_id, ipAddress, userAgent);
557
- await this.user.registerUserActivity(userIdentifier.id, "resetPassword")
570
+ await this.user.registerUserActivity(userIdentifier.user_id, "resetPassword")
558
571
  return { accessToken, refreshToken, session }
559
572
  }
560
573
 
@@ -618,16 +631,67 @@ export class AuthService {
618
631
  /**
619
632
  * Valida (sem consumir) um token de convite de criação de conta e retorna os
620
633
  * dados básicos para pré-preencher o formulário no app de treinamentos.
634
+ * `hasAccount` diz se esse usuário já tem um jeito de entrar (senha ativa ou
635
+ * provedor externo vinculado) — usado pelo app para decidir entre mostrar o
636
+ * formulário de criação de conta ou uma tela de autorização de acesso.
621
637
  */
622
638
  async verifyAccountInvite(locale: string, code: string) {
623
639
  const challenge = await this.challenge.verifyCodePassword(locale, code);
640
+ const userId = challenge.user_identifier.user_id;
641
+
642
+ const [passwordCount, oauthCount] = await Promise.all([
643
+ this.prisma.user_credential.count({
644
+ where: { user_id: userId, type: 'password', revoked_at: null },
645
+ }),
646
+ this.prisma.user_account.count({ where: { user_id: userId } }),
647
+ ]);
648
+
624
649
  return {
625
650
  valid: true,
626
651
  name: challenge.user_identifier.user?.name ?? null,
627
652
  email: challenge.user_identifier.value,
653
+ hasAccount: passwordCount > 0 || oauthCount > 0,
628
654
  };
629
655
  }
630
656
 
657
+ /**
658
+ * Conclui um convite de acesso para quem já tem conta (senha ou provedor
659
+ * externo): não define senha nenhuma, só prova controle do e-mail (mesmo
660
+ * nível de confiança do link de reset de senha) e autentica o usuário.
661
+ */
662
+ async authorizeAccountInvite(
663
+ locale: string,
664
+ code: string,
665
+ ipAddress: string,
666
+ userAgent: string,
667
+ ) {
668
+ const challenge = await this.challenge.verifyCodePassword(locale, code);
669
+ const userIdentifier = challenge.user_identifier;
670
+
671
+ if (!userIdentifier.verified_at || !userIdentifier.enabled) {
672
+ await this.prisma.user_identifier.update({
673
+ where: { id: userIdentifier.id },
674
+ data: { verified_at: userIdentifier.verified_at ?? new Date(), enabled: true },
675
+ });
676
+ }
677
+
678
+ // Consome o challenge para impedir reuso do link.
679
+ await this.prisma.user_identifier_challenge.updateMany({
680
+ where: { id: challenge.id },
681
+ data: { verified_at: new Date(), expires_at: new Date() },
682
+ });
683
+
684
+ const { accessToken, refreshToken, session } =
685
+ await this.getAuthenticationPayload(
686
+ locale,
687
+ userIdentifier.user_id,
688
+ ipAddress,
689
+ userAgent,
690
+ );
691
+ await this.user.registerUserActivity(userIdentifier.user_id, 'authorizeAccountInvite');
692
+ return { accessToken, refreshToken, session };
693
+ }
694
+
631
695
  /**
632
696
  * Conclui a criação de conta a partir de um token de convite: cria/atualiza a
633
697
  * credencial de senha, marca o identificador como verificado, atualiza o nome
@@ -687,11 +751,11 @@ export class AuthService {
687
751
  ipAddress,
688
752
  userAgent,
689
753
  );
690
- await this.user.registerUserActivity(userIdentifier.id, 'completeAccount');
754
+ await this.user.registerUserActivity(userIdentifier.user_id, 'completeAccount');
691
755
  return { accessToken, refreshToken, session };
692
756
  }
693
757
 
694
- async verifyMfaCode(locale: string, mfaToken: string, code: string, ipAddress: string, userAgent: string, methodType?: 'totp' | 'email' | 'recovery', browserId?: string | null) {
758
+ async verifyMfaCode(locale: string, mfaToken: string, code: string, ipAddress: string, userAgent: string, methodType?: 'totp' | 'email' | 'recovery', browserId?: string | null, origin?: string) {
695
759
  const payload = await this.token.verifyMfaChallengeToken(mfaToken);
696
760
  const user = await this.prisma.user.findUnique({
697
761
  where: { id: payload.userId },
@@ -805,7 +869,8 @@ export class AuthService {
805
869
  ipAddress,
806
870
  userAgent,
807
871
  location: 'Unknown',
808
- }
872
+ },
873
+ app: await this.challenge.resolveAppKeyFromOrigin(origin),
809
874
  }
810
875
  );
811
876
 
@@ -859,7 +924,7 @@ export class AuthService {
859
924
  return { accessToken, refreshToken, session, requiresPasswordReset };
860
925
  }
861
926
 
862
- async resendMfaCode(locale: string, mfaToken: string) {
927
+ async resendMfaCode(locale: string, mfaToken: string, origin?: string) {
863
928
  const payload = await this.token.verifyMfaChallengeToken(mfaToken);
864
929
 
865
930
  const mfaMethods = await this.prisma.user_mfa.findMany({
@@ -882,7 +947,7 @@ export class AuthService {
882
947
  throw new BadRequestException(getLocaleText('noEmailMfaFound', locale, 'No email MFA method found for this user.'));
883
948
  }
884
949
 
885
- await this.challenge.sendMfaCodeByEmail(locale, payload.userId, emailMfa.user_mfa_email[0].email);
950
+ await this.challenge.sendMfaCodeByEmail(locale, payload.userId, emailMfa.user_mfa_email[0].email, origin);
886
951
 
887
952
  return {
888
953
  success: true,
@@ -890,7 +955,7 @@ export class AuthService {
890
955
  };
891
956
  }
892
957
 
893
- async generateWebAuthnAuthenticationOptions(locale: string, mfaToken: string, requestOrigin?: string) {
958
+ async generateWebAuthnAuthenticationOptions(locale: string, mfaToken: string, requestOrigin?: string): Promise<PublicKeyCredentialRequestOptionsJSON> {
894
959
  const { generateAuthenticationOptions } = await import('@simplewebauthn/server');
895
960
  const payload = await this.token.verifyMfaChallengeToken(mfaToken);
896
961
 
@@ -1012,7 +1077,8 @@ export class AuthService {
1012
1077
  ipAddress,
1013
1078
  userAgent,
1014
1079
  location: 'Unknown',
1015
- }
1080
+ },
1081
+ app: await this.challenge.resolveAppKeyFromOrigin(requestOrigin),
1016
1082
  }
1017
1083
  );
1018
1084
 
@@ -0,0 +1,10 @@
1
+ import { PrismaModule } from '@hed-hog/api-prisma';
2
+ import { Module, forwardRef } from '@nestjs/common';
3
+ import { CaptchaService } from './captcha.service';
4
+
5
+ @Module({
6
+ imports: [forwardRef(() => PrismaModule)],
7
+ providers: [CaptchaService],
8
+ exports: [CaptchaService],
9
+ })
10
+ export class CaptchaModule {}