@hed-hog/core 0.0.387 → 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 (535) 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 +24 -9
  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 +33 -8
  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 +26 -0
  129. package/dist/index.d.ts.map +1 -1
  130. package/dist/index.js +30 -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 +9 -1
  146. package/dist/integration-profile/integration-profile.secrets.js.map +1 -1
  147. package/dist/integration-profile/integration-profile.service.d.ts +26 -7
  148. package/dist/integration-profile/integration-profile.service.d.ts.map +1 -1
  149. package/dist/integration-profile/integration-profile.service.js +94 -91
  150. package/dist/integration-profile/integration-profile.service.js.map +1 -1
  151. package/dist/integration-profile/integration-profile.utils.d.ts +13 -1
  152. package/dist/integration-profile/integration-profile.utils.d.ts.map +1 -1
  153. package/dist/integration-profile/integration-profile.utils.js +20 -5
  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 +21 -15
  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 +30 -18
  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/whatsapp-sender/whatsapp-sender.module.d.ts +3 -0
  361. package/dist/whatsapp-sender/whatsapp-sender.module.d.ts.map +1 -0
  362. package/dist/whatsapp-sender/whatsapp-sender.module.js +23 -0
  363. package/dist/whatsapp-sender/whatsapp-sender.module.js.map +1 -0
  364. package/dist/whatsapp-sender/whatsapp-sender.service.d.ts +50 -0
  365. package/dist/whatsapp-sender/whatsapp-sender.service.d.ts.map +1 -0
  366. package/dist/whatsapp-sender/whatsapp-sender.service.js +224 -0
  367. package/dist/whatsapp-sender/whatsapp-sender.service.js.map +1 -0
  368. package/hedhog/data/integration_provider.yaml +16 -0
  369. package/hedhog/data/mail.yaml +88 -61
  370. package/hedhog/data/mail_layout.yaml +188 -0
  371. package/hedhog/data/menu.yaml +67 -3
  372. package/hedhog/data/route.yaml +135 -0
  373. package/hedhog/data/setting_group.yaml +139 -1
  374. package/hedhog/frontend/app/account/components/mfa-setup-dialog.tsx.ejs +36 -0
  375. package/hedhog/frontend/app/account/components/two-factor-auth.tsx.ejs +2 -0
  376. package/hedhog/frontend/app/account/hooks/use-mfa-setup.ts.ejs +10 -7
  377. package/hedhog/frontend/app/ai_agent/page.tsx.ejs +7 -4
  378. package/hedhog/frontend/app/ai_instruction/_components/ai-instruction-form.tsx.ejs +580 -0
  379. package/hedhog/frontend/app/ai_instruction/_components/ai-instruction-preview.tsx.ejs +150 -0
  380. package/hedhog/frontend/app/ai_instruction/_components/ai-instruction-versions.tsx.ejs +199 -0
  381. package/hedhog/frontend/app/ai_instruction/_components/prompt-diff.tsx.ejs +63 -0
  382. package/hedhog/frontend/app/ai_instruction/_lib/line-diff.spec.ts.ejs +59 -0
  383. package/hedhog/frontend/app/ai_instruction/_lib/line-diff.ts.ejs +72 -0
  384. package/hedhog/frontend/app/ai_instruction/_lib/prompt-template.spec.ts.ejs +170 -0
  385. package/hedhog/frontend/app/ai_instruction/_lib/prompt-template.ts.ejs +167 -0
  386. package/hedhog/frontend/app/ai_instruction/_lib/types.ts.ejs +99 -0
  387. package/hedhog/frontend/app/ai_instruction/page.tsx.ejs +422 -0
  388. package/hedhog/frontend/app/configurations/[slug]/components/setting-field.tsx.ejs +51 -4
  389. package/hedhog/frontend/app/incidents/page.tsx.ejs +400 -0
  390. package/hedhog/frontend/app/integration/profiles/page.tsx.ejs +153 -84
  391. package/hedhog/frontend/app/mail/layout/page.tsx.ejs +344 -0
  392. package/hedhog/frontend/app/mail/template/page.tsx.ejs +155 -121
  393. package/hedhog/frontend/app/mcp_chat/page.tsx.ejs +129 -17
  394. package/hedhog/frontend/app/pages/_components/page-delete-dialog.tsx.ejs +343 -0
  395. package/hedhog/frontend/app/pages/_components/page-detail-sheet.tsx.ejs +438 -0
  396. package/hedhog/frontend/app/pages/_components/page-wizard-sheet.tsx.ejs +1009 -0
  397. package/hedhog/frontend/app/pages/_components/system-page-types.ts.ejs +56 -0
  398. package/hedhog/frontend/app/pages/_components/use-system-pages.ts.ejs +171 -0
  399. package/hedhog/frontend/app/pages/page.tsx.ejs +514 -0
  400. package/hedhog/frontend/app/users/page.tsx.ejs +119 -13
  401. package/hedhog/frontend/app/users/user-activity-timeline.tsx.ejs +231 -0
  402. package/hedhog/frontend/app/users/user-mails.tsx.ejs +399 -0
  403. package/hedhog/frontend/app/users/user-sheet.tsx.ejs +60 -75
  404. package/hedhog/frontend/messages/en.json +499 -3
  405. package/hedhog/frontend/messages/pt.json +499 -3
  406. package/hedhog/table/ai_agent.yaml +1 -0
  407. package/hedhog/table/ai_instruction.yaml +15 -0
  408. package/hedhog/table/leaked_password.yaml +18 -0
  409. package/hedhog/table/mail_layout.yaml +35 -0
  410. package/hedhog/table/mail_var.yaml +4 -0
  411. package/hedhog/table/setting.yaml +1 -0
  412. package/hedhog/table/system_incident.yaml +59 -0
  413. package/hedhog/table/user_presence.yaml +36 -0
  414. package/package.json +8 -4
  415. package/src/access-log/access-log.interceptor.ts +4 -2
  416. package/src/ai/ai-attachment.fragments.spec.ts +319 -0
  417. package/src/ai/ai-attachment.fragments.ts +35 -0
  418. package/src/ai/ai.prompts.ts +38 -0
  419. package/src/ai/ai.service.spec.ts +280 -0
  420. package/src/ai/ai.service.ts +338 -82
  421. package/src/ai/dto/chat.dto.ts +33 -3
  422. package/src/ai/dto/create-agent.dto.ts +2 -2
  423. package/src/ai/dto/update-agent.dto.ts +2 -2
  424. package/src/ai-instruction/ai-instruction.controller.ts +40 -9
  425. package/src/ai-instruction/ai-instruction.module.ts +13 -2
  426. package/src/ai-instruction/ai-instruction.service.spec.ts +658 -0
  427. package/src/ai-instruction/ai-instruction.service.ts +661 -62
  428. package/src/ai-instruction/ai-prompt-builder.service.ts +10 -1
  429. package/src/ai-instruction/ai-prompt-registry.ts +87 -0
  430. package/src/ai-instruction/ai-prompt-resolver.service.spec.ts +375 -0
  431. package/src/ai-instruction/ai-prompt-resolver.service.ts +295 -0
  432. package/src/ai-instruction/ai-prompt-template.util.spec.ts +162 -0
  433. package/src/ai-instruction/ai-prompt-template.util.ts +199 -0
  434. package/src/ai-instruction/dto/create-ai-instruction.dto.ts +39 -3
  435. package/src/ai-instruction/dto/preview-ai-instruction.dto.ts +26 -0
  436. package/src/ai-instruction/dto/update-ai-instruction.dto.ts +42 -1
  437. package/src/ai-instruction/types/ai-instruction.types.ts +24 -1
  438. package/src/auth/auth.controller.ts +31 -5
  439. package/src/auth/auth.service.spec.ts +3 -1
  440. package/src/auth/auth.service.ts +101 -36
  441. package/src/captcha/captcha.module.ts +10 -0
  442. package/src/captcha/captcha.service.spec.ts +210 -0
  443. package/src/captcha/captcha.service.ts +191 -0
  444. package/src/challenge/challenge.service.spec.ts +39 -4
  445. package/src/challenge/challenge.service.ts +72 -17
  446. package/src/core.module.ts +27 -1
  447. package/src/file/file.service.spec.ts +105 -0
  448. package/src/file/file.service.ts +60 -3
  449. package/src/incident/incident-notifier.service.spec.ts +205 -0
  450. package/src/incident/incident-notifier.service.ts +241 -0
  451. package/src/incident/incident.controller.ts +38 -0
  452. package/src/incident/incident.module.ts +19 -0
  453. package/src/incident/incident.service.spec.ts +150 -0
  454. package/src/incident/incident.service.ts +209 -0
  455. package/src/index.ts +37 -0
  456. package/src/integration-profile/dto/test.dto.ts +19 -0
  457. package/src/integration-profile/integration-profile.controller.ts +10 -1
  458. package/src/integration-profile/integration-profile.module.spec.ts +51 -0
  459. package/src/integration-profile/integration-profile.module.ts +23 -4
  460. package/src/integration-profile/integration-profile.secrets.ts +9 -1
  461. package/src/integration-profile/integration-profile.service.spec.ts +279 -0
  462. package/src/integration-profile/integration-profile.service.ts +120 -124
  463. package/src/integration-profile/integration-profile.utils.spec.ts +22 -0
  464. package/src/integration-profile/integration-profile.utils.ts +40 -3
  465. package/src/integration-profile/testers/ai.testers.ts +165 -0
  466. package/src/integration-profile/testers/captcha.testers.spec.ts +92 -0
  467. package/src/integration-profile/testers/captcha.testers.ts +139 -0
  468. package/src/integration-profile/testers/email.testers.ts +161 -0
  469. package/src/integration-profile/testers/http-probe.spec.ts +153 -0
  470. package/src/integration-profile/testers/http-probe.ts +171 -0
  471. package/src/integration-profile/testers/index.ts +30 -0
  472. package/src/integration-profile/testers/infrastructure.testers.ts +122 -0
  473. package/src/integration-profile/testers/integration-tester.registry.spec.ts +75 -0
  474. package/src/integration-profile/testers/integration-tester.registry.ts +43 -0
  475. package/src/integration-profile/testers/integration-tester.types.ts +61 -0
  476. package/src/integration-profile/testers/messaging.testers.ts +102 -0
  477. package/src/integration-profile/testers/oauth.testers.spec.ts +220 -0
  478. package/src/integration-profile/testers/oauth.testers.ts +305 -0
  479. package/src/integration-profile/testers/payment.testers.ts +185 -0
  480. package/src/integration-profile/testers/remaining.testers.spec.ts +401 -0
  481. package/src/integration-profile/testers/storage.testers.spec.ts +185 -0
  482. package/src/integration-profile/testers/storage.testers.ts +226 -0
  483. package/src/integration-profile/testers/tester-coverage.spec.ts +58 -0
  484. package/src/language/en.json +4 -2
  485. package/src/language/pt.json +4 -2
  486. package/src/leaked-password/README.md +83 -0
  487. package/src/leaked-password/leaked-password.controller.ts +52 -0
  488. package/src/leaked-password/leaked-password.module.ts +18 -0
  489. package/src/leaked-password/leaked-password.service.ts +242 -0
  490. package/src/leaked-password/seed/build-seed-sql.mjs +180 -0
  491. package/src/leaked-password/seed/common-passwords.txt +335 -0
  492. package/src/mail/dto/preview.dto.ts +50 -0
  493. package/src/mail/dto/send.dto.ts +14 -1
  494. package/src/mail/mail-template.spec.ts +197 -0
  495. package/src/mail/mail.controller.ts +9 -2
  496. package/src/mail/mail.service.spec.ts +116 -1
  497. package/src/mail/mail.service.ts +118 -12
  498. package/src/mail-layout/dto/update.dto.ts +19 -0
  499. package/src/mail-layout/mail-layout.controller.ts +47 -0
  500. package/src/mail-layout/mail-layout.module.ts +22 -0
  501. package/src/mail-layout/mail-layout.service.ts +94 -0
  502. package/src/mcp-chat/mcp-chat.service.spec.ts +236 -0
  503. package/src/mcp-chat/mcp-chat.service.ts +122 -26
  504. package/src/oauth/oauth-token-broker.service.spec.ts +172 -0
  505. package/src/oauth/oauth-token-broker.service.ts +363 -0
  506. package/src/oauth/oauth.module.ts +3 -1
  507. package/src/oauth/oauth.service.ts +8 -2
  508. package/src/pdf/pdf.service.ts +75 -0
  509. package/src/presence/presence.controller.ts +29 -0
  510. package/src/presence/presence.listener.ts +53 -0
  511. package/src/presence/presence.module.ts +19 -0
  512. package/src/presence/presence.service.spec.ts +97 -0
  513. package/src/presence/presence.service.ts +160 -0
  514. package/src/profile/dto/delete-account.dto.ts +11 -0
  515. package/src/profile/events/profile-account-deleted.event.ts +13 -0
  516. package/src/profile/profile.controller.ts +46 -34
  517. package/src/profile/profile.service.ts +138 -38
  518. package/src/realtime/realtime.gateway.ts +138 -0
  519. package/src/realtime/realtime.module.ts +16 -0
  520. package/src/realtime/realtime.service.spec.ts +50 -0
  521. package/src/realtime/realtime.service.ts +187 -0
  522. package/src/redis/redis-pubsub.ts +179 -0
  523. package/src/setting/dto/create.dto.ts +13 -2
  524. package/src/setting/setting.service.spec.ts +56 -0
  525. package/src/setting/setting.service.ts +29 -1
  526. package/src/user/dto/create-with-email-and-password.dto.ts +6 -1
  527. package/src/user/dto/query-user-mail-list.dto.ts +10 -0
  528. package/src/user/user-credential.util.ts +35 -0
  529. package/src/user/user.controller.ts +17 -2
  530. package/src/user/user.service.spec.ts +153 -0
  531. package/src/user/user.service.ts +255 -12
  532. package/src/validators/is-strong-password-with-settings.validator.ts +12 -0
  533. package/src/validators/service-locator.ts +15 -0
  534. package/src/whatsapp-sender/whatsapp-sender.module.ts +10 -0
  535. package/src/whatsapp-sender/whatsapp-sender.service.ts +313 -0
@@ -0,0 +1,226 @@
1
+ import { HeadBucketCommand, S3Client } from '@aws-sdk/client-s3';
2
+ import { BlobServiceClient, StorageSharedKeyCredential } from '@azure/storage-blob';
3
+ import { Storage } from '@google-cloud/storage';
4
+ import { access, constants } from 'node:fs/promises';
5
+ import { assertHttpUrl, fail, pass, requireFields, str } from './http-probe';
6
+ import { IntegrationTester, IntegrationTestOutcome } from './integration-tester.types';
7
+
8
+ /**
9
+ * Testadores dos providers de storage.
10
+ *
11
+ * Todos usam uma operação de LEITURA (HeadBucket, getMetadata, getProperties): provam
12
+ * credencial, existência do bucket/container e permissão sem escrever nada na conta
13
+ * do cliente.
14
+ */
15
+
16
+ /** Traduz o erro dos SDKs S3 em algo que o operador consiga agir. */
17
+ async function headS3Bucket(
18
+ client: S3Client,
19
+ bucket: string,
20
+ label: string,
21
+ signal: AbortSignal,
22
+ ): Promise<IntegrationTestOutcome> {
23
+ try {
24
+ await client.send(new HeadBucketCommand({ Bucket: bucket }), {
25
+ abortSignal: signal,
26
+ });
27
+ return pass(label);
28
+ } catch (error) {
29
+ const err = error as {
30
+ name?: string;
31
+ message?: string;
32
+ $metadata?: { httpStatusCode?: number };
33
+ };
34
+ const status = err?.$metadata?.httpStatusCode;
35
+ const name = String(err?.name ?? '');
36
+
37
+ if (name === 'InvalidAccessKeyId' || status === 401) {
38
+ return fail('Invalid access key ID.');
39
+ }
40
+ if (name === 'SignatureDoesNotMatch') {
41
+ return fail('Invalid secret access key.');
42
+ }
43
+ if (name === 'NotFound' || status === 404) {
44
+ return fail(`Bucket "${bucket}" was not found.`);
45
+ }
46
+ if (name === 'Forbidden' || status === 403) {
47
+ return fail(
48
+ `These credentials have no permission to access the bucket "${bucket}".`,
49
+ );
50
+ }
51
+ if (name === 'PermanentRedirect' || status === 301) {
52
+ return fail(`Bucket "${bucket}" lives in another region.`);
53
+ }
54
+ return fail(String(err?.message ?? 'Could not reach the bucket.'));
55
+ } finally {
56
+ client.destroy();
57
+ }
58
+ }
59
+
60
+ const localTester: IntegrationTester = {
61
+ providerSlug: 'local',
62
+ test: async (config) => {
63
+ const basePath = str(config, 'base_path') || 'storage';
64
+ try {
65
+ // Só checa permissão — escrever um arquivo de teste sujaria o storage do cliente.
66
+ await access(basePath, constants.R_OK | constants.W_OK);
67
+ return pass(basePath);
68
+ } catch (error) {
69
+ const code = String((error as { code?: string })?.code ?? '');
70
+ if (code === 'ENOENT') {
71
+ return fail(`The directory "${basePath}" does not exist.`);
72
+ }
73
+ if (code === 'EACCES' || code === 'EPERM') {
74
+ return fail(`No read/write permission on the directory "${basePath}".`);
75
+ }
76
+ return fail(`Could not access the directory "${basePath}".`);
77
+ }
78
+ },
79
+ };
80
+
81
+ const s3Tester: IntegrationTester = {
82
+ providerSlug: 's3',
83
+ test: async (config, ctx) => {
84
+ const missing = requireFields(config, [
85
+ ['access_key_id', 'Access key ID'],
86
+ ['secret_access_key', 'Secret access key'],
87
+ ['bucket', 'Bucket'],
88
+ ]);
89
+ if (missing) return missing;
90
+
91
+ const region = str(config, 'region') || 'us-east-1';
92
+ const bucket = str(config, 'bucket');
93
+ const sessionToken = String(config.session_token ?? '').trim();
94
+
95
+ const client = new S3Client({
96
+ region,
97
+ credentials: {
98
+ accessKeyId: str(config, 'access_key_id'),
99
+ secretAccessKey: String(config.secret_access_key ?? ''),
100
+ ...(sessionToken ? { sessionToken } : {}),
101
+ },
102
+ });
103
+
104
+ return headS3Bucket(client, bucket, `${bucket} (${region})`, ctx.signal);
105
+ },
106
+ };
107
+
108
+ const s3CompatibleTester: IntegrationTester = {
109
+ providerSlug: 's3-compatible',
110
+ test: async (config, ctx) => {
111
+ const missing = requireFields(config, [
112
+ ['endpoint', 'Endpoint'],
113
+ ['access_key_id', 'Access key ID'],
114
+ ['secret_access_key', 'Secret access key'],
115
+ ['bucket', 'Bucket'],
116
+ ]);
117
+ if (missing) return missing;
118
+
119
+ const endpoint = assertHttpUrl(str(config, 'endpoint'), 'Endpoint');
120
+ const bucket = str(config, 'bucket');
121
+ const region = str(config, 'region') || 'us-east-1';
122
+
123
+ const client = new S3Client({
124
+ region,
125
+ endpoint: endpoint.origin,
126
+ // Provedores compatíveis (MinIO, Ceph) raramente resolvem bucket por subdomínio.
127
+ forcePathStyle: true,
128
+ credentials: {
129
+ accessKeyId: str(config, 'access_key_id'),
130
+ secretAccessKey: String(config.secret_access_key ?? ''),
131
+ },
132
+ });
133
+
134
+ return headS3Bucket(client, bucket, `${bucket} @ ${endpoint.host}`, ctx.signal);
135
+ },
136
+ };
137
+
138
+ const gcsTester: IntegrationTester = {
139
+ providerSlug: 'gcs',
140
+ test: async (config) => {
141
+ const missing = requireFields(config, [
142
+ ['key_file_json', 'Service account JSON'],
143
+ ['bucket', 'Bucket'],
144
+ ]);
145
+ if (missing) return missing;
146
+
147
+ let credentials: { project_id?: string; client_email?: string };
148
+ try {
149
+ credentials = JSON.parse(String(config.key_file_json ?? ''));
150
+ } catch {
151
+ return fail('The service account JSON is not valid JSON.');
152
+ }
153
+ if (!credentials?.client_email) {
154
+ return fail('The service account JSON has no "client_email".');
155
+ }
156
+
157
+ const bucket = str(config, 'bucket');
158
+ try {
159
+ const storage = new Storage({
160
+ projectId: credentials.project_id,
161
+ credentials: credentials as Record<string, string>,
162
+ });
163
+ const [metadata] = await storage.bucket(bucket).getMetadata();
164
+ return pass(`${bucket}${metadata?.location ? ` (${metadata.location})` : ''}`);
165
+ } catch (error) {
166
+ const err = error as { code?: number; message?: string };
167
+ if (err?.code === 404) return fail(`Bucket "${bucket}" was not found.`);
168
+ if (err?.code === 403) {
169
+ return fail(
170
+ `The service account has no permission to access the bucket "${bucket}".`,
171
+ );
172
+ }
173
+ if (err?.code === 401) return fail('The service account key was rejected.');
174
+ return fail(String(err?.message ?? 'Could not reach the bucket.'));
175
+ }
176
+ },
177
+ };
178
+
179
+ const azureBlobTester: IntegrationTester = {
180
+ providerSlug: 'azure-blob',
181
+ test: async (config) => {
182
+ const missing = requireFields(config, [
183
+ ['account', 'Storage account'],
184
+ ['key', 'Access key'],
185
+ ['container', 'Container'],
186
+ ]);
187
+ if (missing) return missing;
188
+
189
+ const account = str(config, 'account');
190
+ const container = str(config, 'container');
191
+
192
+ let credential: StorageSharedKeyCredential;
193
+ try {
194
+ credential = new StorageSharedKeyCredential(account, String(config.key ?? ''));
195
+ } catch {
196
+ // O SDK decodifica a chave em base64 na construção.
197
+ return fail('The access key is not a valid Azure storage key.');
198
+ }
199
+
200
+ try {
201
+ const service = new BlobServiceClient(
202
+ `https://${account}.blob.core.windows.net`,
203
+ credential,
204
+ );
205
+ await service.getContainerClient(container).getProperties();
206
+ return pass(`${account}/${container}`);
207
+ } catch (error) {
208
+ const err = error as { statusCode?: number; code?: string; message?: string };
209
+ if (err?.statusCode === 403 || err?.code === 'AuthenticationFailed') {
210
+ return fail('The storage account or access key was rejected.');
211
+ }
212
+ if (err?.statusCode === 404 || err?.code === 'ContainerNotFound') {
213
+ return fail(`Container "${container}" was not found.`);
214
+ }
215
+ return fail(String(err?.message ?? 'Could not reach the container.'));
216
+ }
217
+ },
218
+ };
219
+
220
+ export const STORAGE_TESTERS: IntegrationTester[] = [
221
+ localTester,
222
+ s3Tester,
223
+ s3CompatibleTester,
224
+ gcsTester,
225
+ azureBlobTester,
226
+ ];
@@ -0,0 +1,58 @@
1
+ import { describe, expect, it } from '@jest/globals';
2
+ import { INTEGRATION_SECRET_KEYS } from '../integration-profile.secrets';
3
+ import { BUILTIN_INTEGRATION_TESTERS } from './index';
4
+
5
+ /**
6
+ * TRAVA ANTI-DRIFT, no mesmo espírito de integration-profile.secrets.spec.ts.
7
+ *
8
+ * Um provider novo entra no catálogo por YAML e ganha campos no form do admin. Sem
9
+ * este teste, o botão "Testar conexão" simplesmente responderia "não disponível para
10
+ * este provedor" — uma falha silenciosa, que só aparece quando alguém tenta usar.
11
+ */
12
+
13
+ /** Providers cujo tester vive em outra library (não pode ser embutido no core). */
14
+ const EXTERNAL_PROVIDERS = new Set([
15
+ // Abrir o certificado A1 é código do domínio fiscal: o tester se registra pelo
16
+ // NfseNationalModule (libraries/fiscal).
17
+ 'nfse-national',
18
+ ]);
19
+
20
+ /** Providers legítimos sem nenhum campo secreto. */
21
+ const PROVIDERS_WITHOUT_SECRETS = new Set([
22
+ // Storage no disco local: só um caminho, sem credencial.
23
+ 'local',
24
+ ]);
25
+
26
+ const registeredSlugs = new Set(
27
+ BUILTIN_INTEGRATION_TESTERS.map((tester) => tester.providerSlug),
28
+ );
29
+
30
+ describe('cobertura dos testers de conexão', () => {
31
+ it('todo provider com credenciais tem um tester (embutido ou de outra library)', () => {
32
+ const missing = Object.keys(INTEGRATION_SECRET_KEYS).filter(
33
+ (slug) => !registeredSlugs.has(slug) && !EXTERNAL_PROVIDERS.has(slug),
34
+ );
35
+
36
+ expect(missing).toEqual([]);
37
+ });
38
+
39
+ it('todo tester embutido corresponde a um provider conhecido', () => {
40
+ const unknown = [...registeredSlugs].filter(
41
+ (slug) =>
42
+ !(slug in INTEGRATION_SECRET_KEYS) && !PROVIDERS_WITHOUT_SECRETS.has(slug),
43
+ );
44
+
45
+ expect(unknown).toEqual([]);
46
+ });
47
+
48
+ it('não há dois testers para o mesmo provider', () => {
49
+ expect(registeredSlugs.size).toBe(BUILTIN_INTEGRATION_TESTERS.length);
50
+ });
51
+
52
+ it('todo tester expõe um providerSlug normalizado e uma função test', () => {
53
+ for (const tester of BUILTIN_INTEGRATION_TESTERS) {
54
+ expect(tester.providerSlug).toBe(tester.providerSlug.toLowerCase().trim());
55
+ expect(typeof tester.test).toBe('function');
56
+ }
57
+ });
58
+ });
@@ -26,7 +26,8 @@
26
26
  },
27
27
  "forgot": {
28
28
  "rateLimit": "Too many requests. Please try again later.",
29
- "userNotFound": "User not found."
29
+ "userNotFound": "User not found.",
30
+ "noPassword": "This account does not have a password set. Please sign in using your organization's login provider (e.g. Microsoft)."
30
31
  },
31
32
  "challenge": {
32
33
  "invalidOrExpired": "The provided code is invalid or has expired."
@@ -70,7 +71,8 @@
70
71
  "minLowercase": "Password must contain at least {minLowercase} lowercase letter(s).",
71
72
  "minUppercase": "Password must contain at least {minUppercase} uppercase letter(s).",
72
73
  "minNumbers": "Password must contain at least {minNumbers} number(s).",
73
- "minSymbols": "Password must contain at least {minSymbols} special character(s)."
74
+ "minSymbols": "Password must contain at least {minSymbols} special character(s).",
75
+ "leaked": "This password appears in known data breaches. Please choose another one."
74
76
  },
75
77
  "createUser": {
76
78
  "nameRequired": "Name is required."
@@ -26,7 +26,8 @@
26
26
  },
27
27
  "forgot": {
28
28
  "rateLimit": "Muitas solicitações. Por favor, tente novamente mais tarde.",
29
- "userNotFound": "Usuário não encontrado."
29
+ "userNotFound": "Usuário não encontrado.",
30
+ "noPassword": "Esta conta não possui senha cadastrada. Faça login utilizando o provedor de acesso da sua organização (ex: Microsoft)."
30
31
  },
31
32
  "challenge": {
32
33
  "invalidOrExpired": "O código informado é inválido ou expirou."
@@ -70,7 +71,8 @@
70
71
  "minLowercase": "A senha deve conter pelo menos {minLowercase} letra(s) minúscula(s).",
71
72
  "minUppercase": "A senha deve conter pelo menos {minUppercase} letra(s) maiúscula(s).",
72
73
  "minNumbers": "A senha deve conter pelo menos {minNumbers} número(s).",
73
- "minSymbols": "A senha deve conter pelo menos {minSymbols} caractere(s) especial(is)."
74
+ "minSymbols": "A senha deve conter pelo menos {minSymbols} caractere(s) especial(is).",
75
+ "leaked": "Esta senha aparece em vazamentos de dados conhecidos. Escolha outra."
74
76
  },
75
77
  "createUser": {
76
78
  "nameRequired": "Nome é obrigatório."
@@ -0,0 +1,83 @@
1
+ # Senhas vazadas conhecidas
2
+
3
+ Corpus de hashes SHA-1 de senhas que aparecem em vazamentos públicos, com duas
4
+ leituras bem diferentes.
5
+
6
+ ## Por que bloom filter, e não uma consulta
7
+
8
+ O cofre (`libraries/vaults`) é criptografado ponta a ponta: o servidor nunca vê
9
+ uma senha guardada. Isso descarta o desenho óbvio ("o cliente pergunta se a
10
+ senha X vazou") e também o modelo de k-anonimato do Pwned Passwords, em que o
11
+ cliente manda o prefixo do hash — com corpus pequeno, um prefixo já identifica
12
+ quase unicamente a senha.
13
+
14
+ Então o servidor entrega o corpus inteiro como bloom filter e o navegador
15
+ responde sozinho. Nada sobre a senha sai do cliente. O preço é a taxa de falso
16
+ positivo do filtro (0,1%): uma senha pode ser apontada como vazada sem estar no
17
+ corpus, nunca o contrário.
18
+
19
+ | Caminho | Quem usa | Como |
20
+ | --- | --- | --- |
21
+ | `GET /leaked-password/filter` | cofre, medidor de força do formulário | baixa o filtro, testa local |
22
+ | `LeakedPasswordService.isLeaked()` | validador de senha de **login** | consulta direta no banco |
23
+
24
+ A consulta direta só vale onde a senha em claro já passa pelo servidor de
25
+ qualquer forma (cadastro e troca de senha do sistema). Nunca use `isLeaked()`
26
+ com senha de cofre.
27
+
28
+ Tamanho do filtro: `-n·ln(p)/(ln2)²` bits. ~18 mil hashes ⇒ ~32KB; 1M ⇒ ~1,8MB.
29
+ Ele é montado sob demanda e fica em memória enquanto a versão do corpus não muda
30
+ (`count` + `created_at` mais recente), com `ETag` para o navegador revalidar de
31
+ graça.
32
+
33
+ ## O que já vem semeado
34
+
35
+ A migration `20260729180000_core_leaked_password` insere ~8,7 mil hashes gerados
36
+ de [`seed/common-passwords.txt`](./seed/common-passwords.txt) — as senhas
37
+ notórias de toda publicação anual de "senhas mais usadas", os equivalentes
38
+ brasileiros, e a expansão delas nos padrões que dominam vazamento (sufixo
39
+ numérico, ano, capitalização, leet).
40
+
41
+ **Isto é uma base curada, não o top-N do Have I Been Pwned.** Cobre o reuso
42
+ óbvio; cobertura real vem do import.
43
+
44
+ O SHA-1 do seed vai calculado em hex na migration porque o `pgcrypto` está
45
+ disponível mas não instalado no cluster, e `CREATE EXTENSION` exigiria
46
+ superusuário em produção.
47
+
48
+ Para regerar depois de mexer na lista base (criando uma migration nova — as
49
+ existentes nunca são reescritas):
50
+
51
+ ```bash
52
+ node libraries/core/src/leaked-password/seed/build-seed-sql.mjs --count # confere o tamanho
53
+ node libraries/core/src/leaked-password/seed/build-seed-sql.mjs > /tmp/seed.sql
54
+ ```
55
+
56
+ ## Ampliando o corpus
57
+
58
+ ```bash
59
+ # lista base completa (~120 mil, a expansão que não caberia numa migration)
60
+ node libraries/core/src/leaked-password/seed/build-seed-sql.mjs --full --plain > /tmp/base.txt
61
+ pnpm import:leaked-passwords /tmp/base.txt
62
+
63
+ # dump do Pwned Passwords, reduzido às N senhas mais frequentes
64
+ sort -t: -k2 -rn pwnedpasswords.txt | head -1000000 > top1m.txt
65
+ pnpm import:leaked-passwords top1m.txt
66
+
67
+ pnpm import:leaked-passwords arquivo.txt --dry-run # só relata
68
+ pnpm import:leaked-passwords arquivo.txt --limit 50000 # para em N linhas lidas
69
+ pnpm import:leaked-passwords arquivo.txt --min-occurrences 10
70
+ ```
71
+
72
+ O import é idempotente (o unique em `hash` + `skipDuplicates` absorvem
73
+ repetição), então reprocessar o mesmo arquivo não faz nada.
74
+
75
+ **Dimensione antes:** o dump completo do Pwned Passwords são ~850M hashes
76
+ (~40GB no Postgres) e não cabe no banco deste projeto. 1M hashes ⇒ ~80MB de
77
+ tabela e índice.
78
+
79
+ ## Desligando
80
+
81
+ A setting `password-block-leaked` (grupo de política de senha, padrão ligada)
82
+ controla as duas pontas: desligada, o validador de login para de recusar e o
83
+ cliente nem baixa o filtro.
@@ -0,0 +1,52 @@
1
+ import { Role } from '@hed-hog/api';
2
+ import { Controller, Get, Inject, Req, Res, forwardRef } from '@nestjs/common';
3
+ import type { Request, Response } from 'express';
4
+ import { LeakedPasswordService } from './leaked-password.service';
5
+
6
+ /**
7
+ * Entrega o bloom filter do corpus de senhas vazadas para o cliente testar as
8
+ * senhas do cofre localmente.
9
+ *
10
+ * É o desenho que mantém a criptografia ponta a ponta: em vez de o navegador
11
+ * perguntar "esta senha vazou?" (revelando a senha, ou pelo menos um prefixo do
12
+ * hash dela), ele baixa o filtro inteiro uma vez e responde sozinho.
13
+ *
14
+ * Autenticado de propósito: o conteúdo é público em essência, mas são MBs por
15
+ * download, e o `If-None-Match` faz o navegador revalidar de graça.
16
+ */
17
+ @Role()
18
+ @Controller('leaked-password')
19
+ export class LeakedPasswordController {
20
+ constructor(
21
+ @Inject(forwardRef(() => LeakedPasswordService))
22
+ private readonly leakedPasswordService: LeakedPasswordService,
23
+ ) {}
24
+
25
+ @Get('filter')
26
+ async filter(@Req() req: Request, @Res() res: Response): Promise<void> {
27
+ const filter = await this.leakedPasswordService.getFilter();
28
+
29
+ if (req.headers['if-none-match'] === filter.etag) {
30
+ res.status(304).end();
31
+ return;
32
+ }
33
+
34
+ res.set({
35
+ 'Content-Type': 'application/octet-stream',
36
+ 'Content-Length': String(filter.bytes.length),
37
+ ETag: filter.etag,
38
+ // `must-revalidate` com ETag: o navegador reusa o filtro sem baixar de novo,
39
+ // mas nunca serve corpus velho depois de um import.
40
+ 'Cache-Control': 'private, max-age=0, must-revalidate',
41
+ 'X-Leaked-Password-Count': String(filter.count),
42
+ });
43
+ res.end(filter.bytes);
44
+ }
45
+
46
+ /** Tamanho do corpus, para a tela de configuração mostrar o que está ativo. */
47
+ @Get('stats')
48
+ async stats() {
49
+ const version = await this.leakedPasswordService.getCorpusVersion();
50
+ return { count: version.count, lastUpdatedAt: version.lastCreatedAt };
51
+ }
52
+ }
@@ -0,0 +1,18 @@
1
+ import { PrismaModule } from '@hed-hog/api-prisma';
2
+ import { forwardRef, Global, Module } from '@nestjs/common';
3
+ import { LeakedPasswordController } from './leaked-password.controller';
4
+ import { LeakedPasswordService } from './leaked-password.service';
5
+
6
+ /**
7
+ * `@Global()` porque o validador de política de senha alcança este serviço pelo
8
+ * service locator, de fora da árvore de injeção normal (mesmo caminho do
9
+ * SettingService).
10
+ */
11
+ @Global()
12
+ @Module({
13
+ imports: [forwardRef(() => PrismaModule)],
14
+ controllers: [LeakedPasswordController],
15
+ providers: [LeakedPasswordService],
16
+ exports: [LeakedPasswordService],
17
+ })
18
+ export class LeakedPasswordModule {}