@hed-hog/core 0.0.398 → 0.0.400

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 (664) hide show
  1. package/dist/ai/ai-agent.sort.d.ts +6 -0
  2. package/dist/ai/ai-agent.sort.d.ts.map +1 -0
  3. package/dist/ai/ai-agent.sort.js +21 -0
  4. package/dist/ai/ai-agent.sort.js.map +1 -0
  5. package/dist/ai/ai.controller.d.ts +4 -4
  6. package/dist/ai/ai.service.d.ts +35 -4
  7. package/dist/ai/ai.service.d.ts.map +1 -1
  8. package/dist/ai/ai.service.js +51 -137
  9. package/dist/ai/ai.service.js.map +1 -1
  10. package/dist/ai-instruction/ai-instruction.service.d.ts.map +1 -1
  11. package/dist/ai-instruction/ai-instruction.service.js +26 -23
  12. package/dist/ai-instruction/ai-instruction.service.js.map +1 -1
  13. package/dist/ai-instruction/ai-instruction.sort.d.ts +16 -0
  14. package/dist/ai-instruction/ai-instruction.sort.d.ts.map +1 -0
  15. package/dist/ai-instruction/ai-instruction.sort.js +32 -0
  16. package/dist/ai-instruction/ai-instruction.sort.js.map +1 -0
  17. package/dist/auth/auth.controller.d.ts +24 -8
  18. package/dist/auth/auth.controller.d.ts.map +1 -1
  19. package/dist/auth/auth.module.d.ts.map +1 -1
  20. package/dist/auth/auth.module.js +8 -1
  21. package/dist/auth/auth.module.js.map +1 -1
  22. package/dist/auth/auth.service.d.ts +72 -25
  23. package/dist/auth/auth.service.d.ts.map +1 -1
  24. package/dist/auth/auth.service.js +41 -4
  25. package/dist/auth/auth.service.js.map +1 -1
  26. package/dist/auth/guards/auth.guard.d.ts +3 -1
  27. package/dist/auth/guards/auth.guard.d.ts.map +1 -1
  28. package/dist/auth/guards/auth.guard.js +12 -3
  29. package/dist/auth/guards/auth.guard.js.map +1 -1
  30. package/dist/authorize/authorize.controller.d.ts +30 -6
  31. package/dist/authorize/authorize.controller.d.ts.map +1 -1
  32. package/dist/authorize/authorize.controller.js +120 -13
  33. package/dist/authorize/authorize.controller.js.map +1 -1
  34. package/dist/authorize/authorize.errors.d.ts +34 -0
  35. package/dist/authorize/authorize.errors.d.ts.map +1 -0
  36. package/dist/authorize/authorize.errors.js +37 -0
  37. package/dist/authorize/authorize.errors.js.map +1 -0
  38. package/dist/authorize/authorize.module.d.ts.map +1 -1
  39. package/dist/authorize/authorize.module.js +6 -1
  40. package/dist/authorize/authorize.module.js.map +1 -1
  41. package/dist/authorize/authorize.service.d.ts +78 -4
  42. package/dist/authorize/authorize.service.d.ts.map +1 -1
  43. package/dist/authorize/authorize.service.js +212 -21
  44. package/dist/authorize/authorize.service.js.map +1 -1
  45. package/dist/authorize/dto/authorize-info.dto.d.ts +10 -1
  46. package/dist/authorize/dto/authorize-info.dto.d.ts.map +1 -1
  47. package/dist/authorize/dto/authorize-info.dto.js +16 -1
  48. package/dist/authorize/dto/authorize-info.dto.js.map +1 -1
  49. package/dist/authorize/dto/consent.dto.d.ts +10 -1
  50. package/dist/authorize/dto/consent.dto.d.ts.map +1 -1
  51. package/dist/authorize/dto/consent.dto.js +16 -1
  52. package/dist/authorize/dto/consent.dto.js.map +1 -1
  53. package/dist/authorize/dto/token.dto.d.ts +12 -0
  54. package/dist/authorize/dto/token.dto.d.ts.map +1 -1
  55. package/dist/authorize/dto/token.dto.js +21 -1
  56. package/dist/authorize/dto/token.dto.js.map +1 -1
  57. package/dist/authorize/oauth-exception.filter.d.ts +17 -0
  58. package/dist/authorize/oauth-exception.filter.d.ts.map +1 -0
  59. package/dist/authorize/oauth-exception.filter.js +54 -0
  60. package/dist/authorize/oauth-exception.filter.js.map +1 -0
  61. package/dist/authorize/oauth-metadata.service.d.ts +39 -0
  62. package/dist/authorize/oauth-metadata.service.d.ts.map +1 -0
  63. package/dist/authorize/oauth-metadata.service.js +81 -0
  64. package/dist/authorize/oauth-metadata.service.js.map +1 -0
  65. package/dist/authorize/well-known.controller.d.ts +67 -0
  66. package/dist/authorize/well-known.controller.d.ts.map +1 -0
  67. package/dist/authorize/well-known.controller.js +126 -0
  68. package/dist/authorize/well-known.controller.js.map +1 -0
  69. package/dist/captcha/captcha.service.d.ts +32 -2
  70. package/dist/captcha/captcha.service.d.ts.map +1 -1
  71. package/dist/captcha/captcha.service.js +85 -12
  72. package/dist/captcha/captcha.service.js.map +1 -1
  73. package/dist/challenge/challenge.service.d.ts +2 -2
  74. package/dist/core.module.d.ts.map +1 -1
  75. package/dist/core.module.js +6 -0
  76. package/dist/core.module.js.map +1 -1
  77. package/dist/dashboard/dashboard/dashboard.controller.d.ts +9 -9
  78. package/dist/dashboard/dashboard/dashboard.service.d.ts +9 -9
  79. package/dist/dashboard/dashboard-component/dashboard-component.controller.d.ts +3 -3
  80. package/dist/dashboard/dashboard-component/dashboard-component.service.d.ts +3 -3
  81. package/dist/dashboard/dashboard-component-role/dashboard-component-role.controller.d.ts +3 -3
  82. package/dist/dashboard/dashboard-component-role/dashboard-component-role.service.d.ts +3 -3
  83. package/dist/dashboard/dashboard-component-role/dashboard-component-role.service.d.ts.map +1 -1
  84. package/dist/dashboard/dashboard-component-role/dashboard-component-role.service.js +2 -4
  85. package/dist/dashboard/dashboard-component-role/dashboard-component-role.service.js.map +1 -1
  86. package/dist/dashboard/dashboard-component-role/dashboard-component-role.sort.d.ts +8 -0
  87. package/dist/dashboard/dashboard-component-role/dashboard-component-role.sort.d.ts.map +1 -0
  88. package/dist/dashboard/dashboard-component-role/dashboard-component-role.sort.js +18 -0
  89. package/dist/dashboard/dashboard-component-role/dashboard-component-role.sort.js.map +1 -0
  90. package/dist/dashboard/dashboard-item/dashboard-item.service.d.ts.map +1 -1
  91. package/dist/dashboard/dashboard-item/dashboard-item.service.js +2 -4
  92. package/dist/dashboard/dashboard-item/dashboard-item.service.js.map +1 -1
  93. package/dist/dashboard/dashboard-item/dashboard-item.sort.d.ts +9 -0
  94. package/dist/dashboard/dashboard-item/dashboard-item.sort.d.ts.map +1 -0
  95. package/dist/dashboard/dashboard-item/dashboard-item.sort.js +19 -0
  96. package/dist/dashboard/dashboard-item/dashboard-item.sort.js.map +1 -0
  97. package/dist/dashboard/dashboard-role/dashboard-role.controller.d.ts +3 -3
  98. package/dist/dashboard/dashboard-role/dashboard-role.service.d.ts +3 -3
  99. package/dist/dashboard/dashboard-role/dashboard-role.service.d.ts.map +1 -1
  100. package/dist/dashboard/dashboard-role/dashboard-role.service.js +2 -4
  101. package/dist/dashboard/dashboard-role/dashboard-role.service.js.map +1 -1
  102. package/dist/dashboard/dashboard-role/dashboard-role.sort.d.ts +8 -0
  103. package/dist/dashboard/dashboard-role/dashboard-role.sort.d.ts.map +1 -0
  104. package/dist/dashboard/dashboard-role/dashboard-role.sort.js +16 -0
  105. package/dist/dashboard/dashboard-role/dashboard-role.sort.js.map +1 -0
  106. package/dist/file/file-upload-ticket.service.d.ts +160 -0
  107. package/dist/file/file-upload-ticket.service.d.ts.map +1 -0
  108. package/dist/file/file-upload-ticket.service.js +382 -0
  109. package/dist/file/file-upload-ticket.service.js.map +1 -0
  110. package/dist/file/file.controller.d.ts +24 -1
  111. package/dist/file/file.controller.d.ts.map +1 -1
  112. package/dist/file/file.controller.js +63 -2
  113. package/dist/file/file.controller.js.map +1 -1
  114. package/dist/file/file.module.d.ts.map +1 -1
  115. package/dist/file/file.module.js +14 -2
  116. package/dist/file/file.module.js.map +1 -1
  117. package/dist/file/file.service.d.ts +182 -6
  118. package/dist/file/file.service.d.ts.map +1 -1
  119. package/dist/file/file.service.js +385 -36
  120. package/dist/file/file.service.js.map +1 -1
  121. package/dist/file/filename-encoding.util.d.ts +24 -0
  122. package/dist/file/filename-encoding.util.d.ts.map +1 -0
  123. package/dist/file/filename-encoding.util.js +63 -0
  124. package/dist/file/filename-encoding.util.js.map +1 -0
  125. package/dist/file/image-optimization.service.d.ts +27 -0
  126. package/dist/file/image-optimization.service.d.ts.map +1 -1
  127. package/dist/file/image-optimization.service.js +63 -14
  128. package/dist/file/image-optimization.service.js.map +1 -1
  129. package/dist/file/mcp-file-source.schema.d.ts +33 -0
  130. package/dist/file/mcp-file-source.schema.d.ts.map +1 -0
  131. package/dist/file/mcp-file-source.schema.js +75 -0
  132. package/dist/file/mcp-file-source.schema.js.map +1 -0
  133. package/dist/file/mcp-file-source.service.d.ts +124 -0
  134. package/dist/file/mcp-file-source.service.d.ts.map +1 -0
  135. package/dist/file/mcp-file-source.service.js +262 -0
  136. package/dist/file/mcp-file-source.service.js.map +1 -0
  137. package/dist/file/mimetype-sniff.util.d.ts +62 -0
  138. package/dist/file/mimetype-sniff.util.d.ts.map +1 -0
  139. package/dist/file/mimetype-sniff.util.js +226 -0
  140. package/dist/file/mimetype-sniff.util.js.map +1 -0
  141. package/dist/file/remote-fetch.util.d.ts +35 -0
  142. package/dist/file/remote-fetch.util.d.ts.map +1 -0
  143. package/dist/file/remote-fetch.util.js +236 -0
  144. package/dist/file/remote-fetch.util.js.map +1 -0
  145. package/dist/impersonation/dto/start-impersonation.dto.d.ts +4 -1
  146. package/dist/impersonation/dto/start-impersonation.dto.d.ts.map +1 -1
  147. package/dist/impersonation/dto/start-impersonation.dto.js +1 -1
  148. package/dist/impersonation/dto/start-impersonation.dto.js.map +1 -1
  149. package/dist/impersonation/impersonation.service.d.ts +8 -3
  150. package/dist/impersonation/impersonation.service.d.ts.map +1 -1
  151. package/dist/impersonation/impersonation.service.js +14 -4
  152. package/dist/impersonation/impersonation.service.js.map +1 -1
  153. package/dist/incident/incident.controller.d.ts +2 -1
  154. package/dist/incident/incident.controller.d.ts.map +1 -1
  155. package/dist/incident/incident.controller.js +10 -6
  156. package/dist/incident/incident.controller.js.map +1 -1
  157. package/dist/incident/incident.service.d.ts +2 -0
  158. package/dist/incident/incident.service.d.ts.map +1 -1
  159. package/dist/incident/incident.service.js +4 -0
  160. package/dist/incident/incident.service.js.map +1 -1
  161. package/dist/index.d.ts +17 -0
  162. package/dist/index.d.ts.map +1 -1
  163. package/dist/index.js +17 -0
  164. package/dist/index.js.map +1 -1
  165. package/dist/integration-profile/integration-profile.secrets.d.ts.map +1 -1
  166. package/dist/integration-profile/integration-profile.secrets.js +7 -0
  167. package/dist/integration-profile/integration-profile.secrets.js.map +1 -1
  168. package/dist/integration-profile/integration-profile.service.d.ts +0 -13
  169. package/dist/integration-profile/integration-profile.service.d.ts.map +1 -1
  170. package/dist/integration-profile/integration-profile.service.js +5 -40
  171. package/dist/integration-profile/integration-profile.service.js.map +1 -1
  172. package/dist/integration-profile/integration-profile.utils.js +5 -5
  173. package/dist/integration-profile/integration-profile.utils.js.map +1 -1
  174. package/dist/integration-profile/testers/index.d.ts.map +1 -1
  175. package/dist/integration-profile/testers/index.js +2 -0
  176. package/dist/integration-profile/testers/index.js.map +1 -1
  177. package/dist/integration-profile/testers/shipping.testers.d.ts +3 -0
  178. package/dist/integration-profile/testers/shipping.testers.d.ts.map +1 -0
  179. package/dist/integration-profile/testers/shipping.testers.js +71 -0
  180. package/dist/integration-profile/testers/shipping.testers.js.map +1 -0
  181. package/dist/locale/locale.controller.d.ts +1 -1
  182. package/dist/locale/locale.service.d.ts +1 -1
  183. package/dist/mail/dto/send.dto.d.ts +6 -1
  184. package/dist/mail/dto/send.dto.d.ts.map +1 -1
  185. package/dist/mail/dto/send.dto.js.map +1 -1
  186. package/dist/mail/mail.service.d.ts +9 -0
  187. package/dist/mail/mail.service.d.ts.map +1 -1
  188. package/dist/mail/mail.service.js +34 -14
  189. package/dist/mail/mail.service.js.map +1 -1
  190. package/dist/mail-sent/mail-sent.controller.d.ts +1 -1
  191. package/dist/mail-sent/mail-sent.service.d.ts +1 -1
  192. package/dist/mail-sent/mail-sent.service.d.ts.map +1 -1
  193. package/dist/mail-sent/mail-sent.service.js +2 -1
  194. package/dist/mail-sent/mail-sent.service.js.map +1 -1
  195. package/dist/mail-sent/mail-sent.sort.d.ts +9 -0
  196. package/dist/mail-sent/mail-sent.sort.d.ts.map +1 -0
  197. package/dist/mail-sent/mail-sent.sort.js +19 -0
  198. package/dist/mail-sent/mail-sent.sort.js.map +1 -0
  199. package/dist/mcp/filters/mcp-challenge.filter.d.ts +20 -0
  200. package/dist/mcp/filters/mcp-challenge.filter.d.ts.map +1 -0
  201. package/dist/mcp/filters/mcp-challenge.filter.js +69 -0
  202. package/dist/mcp/filters/mcp-challenge.filter.js.map +1 -0
  203. package/dist/mcp/guards/mcp-auth.guard.d.ts +4 -1
  204. package/dist/mcp/guards/mcp-auth.guard.d.ts.map +1 -1
  205. package/dist/mcp/guards/mcp-auth.guard.js +19 -5
  206. package/dist/mcp/guards/mcp-auth.guard.js.map +1 -1
  207. package/dist/mcp/guards/mcp-permission.guard.d.ts +25 -3
  208. package/dist/mcp/guards/mcp-permission.guard.d.ts.map +1 -1
  209. package/dist/mcp/guards/mcp-permission.guard.js +46 -26
  210. package/dist/mcp/guards/mcp-permission.guard.js.map +1 -1
  211. package/dist/mcp/mcp-audit.service.d.ts +17 -0
  212. package/dist/mcp/mcp-audit.service.d.ts.map +1 -1
  213. package/dist/mcp/mcp-audit.service.js +32 -3
  214. package/dist/mcp/mcp-audit.service.js.map +1 -1
  215. package/dist/mcp/mcp-permission.service.d.ts +64 -0
  216. package/dist/mcp/mcp-permission.service.d.ts.map +1 -0
  217. package/dist/mcp/mcp-permission.service.js +178 -0
  218. package/dist/mcp/mcp-permission.service.js.map +1 -0
  219. package/dist/mcp/mcp-server.service.d.ts +3 -1
  220. package/dist/mcp/mcp-server.service.d.ts.map +1 -1
  221. package/dist/mcp/mcp-server.service.js +36 -15
  222. package/dist/mcp/mcp-server.service.js.map +1 -1
  223. package/dist/mcp/mcp.controller.d.ts.map +1 -1
  224. package/dist/mcp/mcp.controller.js +10 -2
  225. package/dist/mcp/mcp.controller.js.map +1 -1
  226. package/dist/mcp/mcp.module.d.ts.map +1 -1
  227. package/dist/mcp/mcp.module.js +5 -1
  228. package/dist/mcp/mcp.module.js.map +1 -1
  229. package/dist/mcp/tools/core-ai.mcp-tools.js +2 -9
  230. package/dist/mcp/tools/core-ai.mcp-tools.js.map +1 -1
  231. package/dist/mcp/tools/core-dashboard-items.mcp-tools.js +1 -1
  232. package/dist/mcp/tools/core-dashboard-items.mcp-tools.js.map +1 -1
  233. package/dist/mcp/tools/core-dashboard.mcp-tools.js +2 -9
  234. package/dist/mcp/tools/core-dashboard.mcp-tools.js.map +1 -1
  235. package/dist/mcp/tools/core-event-webhooks.mcp-tools.d.ts.map +1 -1
  236. package/dist/mcp/tools/core-event-webhooks.mcp-tools.js +2 -10
  237. package/dist/mcp/tools/core-event-webhooks.mcp-tools.js.map +1 -1
  238. package/dist/mcp/tools/core-files.mcp-tools.d.ts +17 -5
  239. package/dist/mcp/tools/core-files.mcp-tools.d.ts.map +1 -1
  240. package/dist/mcp/tools/core-files.mcp-tools.js +186 -24
  241. package/dist/mcp/tools/core-files.mcp-tools.js.map +1 -1
  242. package/dist/mcp/tools/core-integration-events.mcp-tools.js +2 -9
  243. package/dist/mcp/tools/core-integration-events.mcp-tools.js.map +1 -1
  244. package/dist/mcp/tools/core-mail-sent.mcp-tools.js +2 -14
  245. package/dist/mcp/tools/core-mail-sent.mcp-tools.js.map +1 -1
  246. package/dist/mcp/tools/core-mail.mcp-tools.js +2 -9
  247. package/dist/mcp/tools/core-mail.mcp-tools.js.map +1 -1
  248. package/dist/mcp/tools/core-menus.mcp-tools.d.ts.map +1 -1
  249. package/dist/mcp/tools/core-menus.mcp-tools.js +2 -10
  250. package/dist/mcp/tools/core-menus.mcp-tools.js.map +1 -1
  251. package/dist/mcp/tools/core-notifications.mcp-tools.d.ts.map +1 -1
  252. package/dist/mcp/tools/core-notifications.mcp-tools.js +0 -1
  253. package/dist/mcp/tools/core-notifications.mcp-tools.js.map +1 -1
  254. package/dist/mcp/tools/core-roles.mcp-tools.d.ts.map +1 -1
  255. package/dist/mcp/tools/core-roles.mcp-tools.js +2 -13
  256. package/dist/mcp/tools/core-roles.mcp-tools.js.map +1 -1
  257. package/dist/mcp/tools/core-routes.mcp-tools.d.ts.map +1 -1
  258. package/dist/mcp/tools/core-routes.mcp-tools.js +2 -11
  259. package/dist/mcp/tools/core-routes.mcp-tools.js.map +1 -1
  260. package/dist/mcp/tools/core-screens.mcp-tools.d.ts.map +1 -1
  261. package/dist/mcp/tools/core-screens.mcp-tools.js +2 -11
  262. package/dist/mcp/tools/core-screens.mcp-tools.js.map +1 -1
  263. package/dist/mcp/tools/core-sessions.mcp-tools.d.ts.map +1 -1
  264. package/dist/mcp/tools/core-sessions.mcp-tools.js +0 -2
  265. package/dist/mcp/tools/core-sessions.mcp-tools.js.map +1 -1
  266. package/dist/mcp/tools/core-settings.mcp-tools.d.ts.map +1 -1
  267. package/dist/mcp/tools/core-settings.mcp-tools.js +2 -10
  268. package/dist/mcp/tools/core-settings.mcp-tools.js.map +1 -1
  269. package/dist/mcp/tools/core-users.mcp-tools.js +2 -9
  270. package/dist/mcp/tools/core-users.mcp-tools.js.map +1 -1
  271. package/dist/mcp/tools/core-webhooks.mcp-tools.d.ts.map +1 -1
  272. package/dist/mcp/tools/core-webhooks.mcp-tools.js +2 -10
  273. package/dist/mcp/tools/core-webhooks.mcp-tools.js.map +1 -1
  274. package/dist/mcp/types/mcp-context.type.d.ts +9 -0
  275. package/dist/mcp/types/mcp-context.type.d.ts.map +1 -1
  276. package/dist/mcp-chat/mcp-chat.service.d.ts.map +1 -1
  277. package/dist/mcp-chat/mcp-chat.service.js +8 -0
  278. package/dist/mcp-chat/mcp-chat.service.js.map +1 -1
  279. package/dist/meeting/meeting-provider.registry.d.ts +115 -0
  280. package/dist/meeting/meeting-provider.registry.d.ts.map +1 -1
  281. package/dist/meeting/meeting-provider.registry.js.map +1 -1
  282. package/dist/meeting/meeting.constants.d.ts +70 -0
  283. package/dist/meeting/meeting.constants.d.ts.map +1 -1
  284. package/dist/meeting/meeting.constants.js +9 -1
  285. package/dist/meeting/meeting.constants.js.map +1 -1
  286. package/dist/menu/menu.service.d.ts.map +1 -1
  287. package/dist/menu/menu.service.js +29 -9
  288. package/dist/menu/menu.service.js.map +1 -1
  289. package/dist/message-template/dto/update-message-template.dto.d.ts +18 -0
  290. package/dist/message-template/dto/update-message-template.dto.d.ts.map +1 -0
  291. package/dist/message-template/dto/update-message-template.dto.js +38 -0
  292. package/dist/message-template/dto/update-message-template.dto.js.map +1 -0
  293. package/dist/message-template/message-template-admin.service.d.ts +70 -0
  294. package/dist/message-template/message-template-admin.service.d.ts.map +1 -0
  295. package/dist/message-template/message-template-admin.service.js +226 -0
  296. package/dist/message-template/message-template-admin.service.js.map +1 -0
  297. package/dist/message-template/message-template.controller.d.ts +29 -0
  298. package/dist/message-template/message-template.controller.d.ts.map +1 -0
  299. package/dist/message-template/message-template.controller.js +101 -0
  300. package/dist/message-template/message-template.controller.js.map +1 -0
  301. package/dist/message-template/message-template.module.d.ts +10 -0
  302. package/dist/message-template/message-template.module.d.ts.map +1 -0
  303. package/dist/message-template/message-template.module.js +33 -0
  304. package/dist/message-template/message-template.module.js.map +1 -0
  305. package/dist/message-template/message-template.registry.d.ts +55 -0
  306. package/dist/message-template/message-template.registry.d.ts.map +1 -0
  307. package/dist/message-template/message-template.registry.js +64 -0
  308. package/dist/message-template/message-template.registry.js.map +1 -0
  309. package/dist/message-template/message-template.service.d.ts +59 -0
  310. package/dist/message-template/message-template.service.d.ts.map +1 -0
  311. package/dist/message-template/message-template.service.js +166 -0
  312. package/dist/message-template/message-template.service.js.map +1 -0
  313. package/dist/notification/notification.constants.d.ts +11 -0
  314. package/dist/notification/notification.constants.d.ts.map +1 -0
  315. package/dist/notification/notification.constants.js +14 -0
  316. package/dist/notification/notification.constants.js.map +1 -0
  317. package/dist/notification/notification.controller.d.ts +20 -20
  318. package/dist/notification/notification.module.d.ts.map +1 -1
  319. package/dist/notification/notification.module.js +3 -0
  320. package/dist/notification/notification.module.js.map +1 -1
  321. package/dist/notification/notification.service.d.ts +33 -21
  322. package/dist/notification/notification.service.d.ts.map +1 -1
  323. package/dist/notification/notification.service.js +36 -2
  324. package/dist/notification/notification.service.js.map +1 -1
  325. package/dist/oauth/oauth.controller.d.ts +4 -6
  326. package/dist/oauth/oauth.controller.d.ts.map +1 -1
  327. package/dist/oauth/oauth.controller.js +0 -1
  328. package/dist/oauth/oauth.controller.js.map +1 -1
  329. package/dist/oauth/oauth.errors.d.ts +15 -1
  330. package/dist/oauth/oauth.errors.d.ts.map +1 -1
  331. package/dist/oauth/oauth.errors.js +9 -1
  332. package/dist/oauth/oauth.errors.js.map +1 -1
  333. package/dist/oauth/oauth.module.d.ts.map +1 -1
  334. package/dist/oauth/oauth.module.js +6 -1
  335. package/dist/oauth/oauth.module.js.map +1 -1
  336. package/dist/oauth/oauth.service.d.ts +25 -5
  337. package/dist/oauth/oauth.service.d.ts.map +1 -1
  338. package/dist/oauth/oauth.service.js +63 -27
  339. package/dist/oauth/oauth.service.js.map +1 -1
  340. package/dist/oauth/providers/abstract.provider.d.ts +10 -0
  341. package/dist/oauth/providers/abstract.provider.d.ts.map +1 -1
  342. package/dist/oauth/providers/abstract.provider.js +39 -12
  343. package/dist/oauth/providers/abstract.provider.js.map +1 -1
  344. package/dist/oauth/providers/github.provider.d.ts +1 -1
  345. package/dist/oauth/providers/github.provider.d.ts.map +1 -1
  346. package/dist/oauth/providers/github.provider.js +48 -22
  347. package/dist/oauth/providers/github.provider.js.map +1 -1
  348. package/dist/oauth/providers/microsoft-entra-id.provider.d.ts.map +1 -1
  349. package/dist/oauth/providers/microsoft-entra-id.provider.js +6 -0
  350. package/dist/oauth/providers/microsoft-entra-id.provider.js.map +1 -1
  351. package/dist/observability/monitored-cron.d.ts +29 -12
  352. package/dist/observability/monitored-cron.d.ts.map +1 -1
  353. package/dist/observability/monitored-cron.js +131 -46
  354. package/dist/observability/monitored-cron.js.map +1 -1
  355. package/dist/pairing/pairing.controller.d.ts +9 -9
  356. package/dist/pairing/pairing.service.d.ts +15 -11
  357. package/dist/pairing/pairing.service.d.ts.map +1 -1
  358. package/dist/profile/dto/change-password.dto.d.ts.map +1 -1
  359. package/dist/profile/dto/change-password.dto.js +4 -6
  360. package/dist/profile/dto/change-password.dto.js.map +1 -1
  361. package/dist/profile/profile.controller.d.ts +1 -1
  362. package/dist/profile/profile.service.d.ts +1 -1
  363. package/dist/profile/profile.service.d.ts.map +1 -1
  364. package/dist/profile/profile.service.js +9 -3
  365. package/dist/profile/profile.service.js.map +1 -1
  366. package/dist/realtime/realtime-tick.coalescer.d.ts +34 -0
  367. package/dist/realtime/realtime-tick.coalescer.d.ts.map +1 -0
  368. package/dist/realtime/realtime-tick.coalescer.js +60 -0
  369. package/dist/realtime/realtime-tick.coalescer.js.map +1 -0
  370. package/dist/realtime/realtime.service.d.ts +2 -0
  371. package/dist/realtime/realtime.service.d.ts.map +1 -1
  372. package/dist/realtime/realtime.service.js +22 -2
  373. package/dist/realtime/realtime.service.js.map +1 -1
  374. package/dist/redis/redis-kv.service.d.ts +90 -0
  375. package/dist/redis/redis-kv.service.d.ts.map +1 -0
  376. package/dist/redis/redis-kv.service.js +247 -0
  377. package/dist/redis/redis-kv.service.js.map +1 -0
  378. package/dist/redis/redis-master.d.ts +29 -0
  379. package/dist/redis/redis-master.d.ts.map +1 -0
  380. package/dist/redis/redis-master.js +81 -0
  381. package/dist/redis/redis-master.js.map +1 -0
  382. package/dist/redis/redis-pubsub.d.ts +12 -0
  383. package/dist/redis/redis-pubsub.d.ts.map +1 -1
  384. package/dist/redis/redis-pubsub.js +25 -2
  385. package/dist/redis/redis-pubsub.js.map +1 -1
  386. package/dist/redis/redis.module.d.ts +11 -0
  387. package/dist/redis/redis.module.d.ts.map +1 -0
  388. package/dist/redis/redis.module.js +30 -0
  389. package/dist/redis/redis.module.js.map +1 -0
  390. package/dist/session/session.controller.d.ts +6 -2
  391. package/dist/session/session.controller.d.ts.map +1 -1
  392. package/dist/session/session.service.d.ts +118 -15
  393. package/dist/session/session.service.d.ts.map +1 -1
  394. package/dist/session/session.service.js +251 -77
  395. package/dist/session/session.service.js.map +1 -1
  396. package/dist/setting/setting.controller.d.ts +5 -0
  397. package/dist/setting/setting.controller.d.ts.map +1 -1
  398. package/dist/setting/setting.service.d.ts +7 -0
  399. package/dist/setting/setting.service.d.ts.map +1 -1
  400. package/dist/setting/setting.service.js +38 -3
  401. package/dist/setting/setting.service.js.map +1 -1
  402. package/dist/task/task.service.d.ts +17 -0
  403. package/dist/task/task.service.d.ts.map +1 -1
  404. package/dist/task/task.service.js +48 -13
  405. package/dist/task/task.service.js.map +1 -1
  406. package/dist/token/token.service.d.ts +19 -1
  407. package/dist/token/token.service.d.ts.map +1 -1
  408. package/dist/token/token.service.js +39 -2
  409. package/dist/token/token.service.js.map +1 -1
  410. package/dist/user/user-credential.util.d.ts +10 -0
  411. package/dist/user/user-credential.util.d.ts.map +1 -1
  412. package/dist/user/user-credential.util.js +14 -1
  413. package/dist/user/user-credential.util.js.map +1 -1
  414. package/dist/user/user.service.d.ts +12 -4
  415. package/dist/user/user.service.d.ts.map +1 -1
  416. package/dist/user/user.service.js +2 -11
  417. package/dist/user/user.service.js.map +1 -1
  418. package/dist/user/user.sort.d.ts +16 -0
  419. package/dist/user/user.sort.d.ts.map +1 -0
  420. package/dist/user/user.sort.js +25 -0
  421. package/dist/user/user.sort.js.map +1 -0
  422. package/dist/utils/abbreviate-name.d.ts +13 -0
  423. package/dist/utils/abbreviate-name.d.ts.map +1 -0
  424. package/dist/utils/abbreviate-name.js +42 -0
  425. package/dist/utils/abbreviate-name.js.map +1 -0
  426. package/dist/utils/date-range-query.dto.d.ts +11 -0
  427. package/dist/utils/date-range-query.dto.d.ts.map +1 -0
  428. package/dist/utils/date-range-query.dto.js +63 -0
  429. package/dist/utils/date-range-query.dto.js.map +1 -0
  430. package/dist/utils/date-range.d.ts +96 -0
  431. package/dist/utils/date-range.d.ts.map +1 -0
  432. package/dist/utils/date-range.js +172 -0
  433. package/dist/utils/date-range.js.map +1 -0
  434. package/dist/webhook-integration/webhook-utils.d.ts.map +1 -1
  435. package/dist/webhook-integration/webhook-utils.js +24 -0
  436. package/dist/webhook-integration/webhook-utils.js.map +1 -1
  437. package/dist/whatsapp-sender/whatsapp-recipients.d.ts +49 -0
  438. package/dist/whatsapp-sender/whatsapp-recipients.d.ts.map +1 -0
  439. package/dist/whatsapp-sender/whatsapp-recipients.js +66 -0
  440. package/dist/whatsapp-sender/whatsapp-recipients.js.map +1 -0
  441. package/dist/whatsapp-sender/whatsapp-sender.service.d.ts +25 -0
  442. package/dist/whatsapp-sender/whatsapp-sender.service.d.ts.map +1 -1
  443. package/dist/whatsapp-sender/whatsapp-sender.service.js +46 -5
  444. package/dist/whatsapp-sender/whatsapp-sender.service.js.map +1 -1
  445. package/hedhog/data/integration_provider.yaml +9 -0
  446. package/hedhog/data/integration_type.yaml +6 -0
  447. package/hedhog/data/locale.yaml +0 -1
  448. package/hedhog/data/mail.yaml +2 -2
  449. package/hedhog/data/mail_layout.yaml +6 -3
  450. package/hedhog/data/menu.yaml +25 -5
  451. package/hedhog/data/route.yaml +140 -0
  452. package/hedhog/data/setting_group.yaml +137 -3
  453. package/hedhog/frontend/app/access-log/page.tsx.ejs +47 -53
  454. package/hedhog/frontend/app/account/components/active-sessions.tsx.ejs +33 -8
  455. package/hedhog/frontend/app/account/components/mcp-tokens.tsx.ejs +54 -13
  456. package/hedhog/frontend/app/account/components/mfa-method-card.tsx.ejs +7 -1
  457. package/hedhog/frontend/app/account/components/recovery-codes-dialog.tsx.ejs +1 -0
  458. package/hedhog/frontend/app/account/components/tokens.tsx.ejs +47 -17
  459. package/hedhog/frontend/app/ai_agent/page.tsx.ejs +46 -5
  460. package/hedhog/frontend/app/ai_instruction/_components/ai-instruction-form.tsx.ejs +101 -30
  461. package/hedhog/frontend/app/ai_instruction/_components/ai-instruction-versions.tsx.ejs +24 -8
  462. package/hedhog/frontend/app/ai_instruction/page.tsx.ejs +80 -15
  463. package/hedhog/frontend/app/configurations/[slug]/components/image-optimization-action.tsx.ejs +166 -0
  464. package/hedhog/frontend/app/configurations/[slug]/components/setting-field.test.tsx.ejs +145 -45
  465. package/hedhog/frontend/app/configurations/[slug]/components/setting-field.tsx.ejs +99 -219
  466. package/hedhog/frontend/app/configurations/[slug]/page.tsx.ejs +19 -1
  467. package/hedhog/frontend/app/configurations/layout.tsx.ejs +19 -5
  468. package/hedhog/frontend/app/dashboard/[slug]/widget-renderer.tsx.ejs +2 -8
  469. package/hedhog/frontend/app/dashboard/components/dynamic-widget.tsx.ejs +3 -0
  470. package/hedhog/frontend/app/dashboard/components/widget-wrapper.tsx.ejs +4 -0
  471. package/hedhog/frontend/app/dashboard/dashboard-home-tabs.tsx.ejs +43 -44
  472. package/hedhog/frontend/app/dashboard/management/tabs/component-roles-tab.tsx.ejs +41 -3
  473. package/hedhog/frontend/app/dashboard/management/tabs/components-tab.tsx.ejs +42 -2
  474. package/hedhog/frontend/app/dashboard/management/tabs/dashboard-roles-tab.tsx.ejs +41 -3
  475. package/hedhog/frontend/app/dashboard/management/tabs/dashboards-tab.tsx.ejs +39 -4
  476. package/hedhog/frontend/app/dashboard/management/tabs/items-tab.tsx.ejs +42 -3
  477. package/hedhog/frontend/app/incidents/page.tsx.ejs +60 -31
  478. package/hedhog/frontend/app/integration/profiles/page.tsx.ejs +45 -5
  479. package/hedhog/frontend/app/integrations-webhooks/page.tsx.ejs +92 -15
  480. package/hedhog/frontend/app/mail/log/page.tsx.ejs +109 -61
  481. package/hedhog/frontend/app/mail/template/page.tsx.ejs +125 -23
  482. package/hedhog/frontend/app/mcp_chat/chat-components.tsx.ejs +13 -15
  483. package/hedhog/frontend/app/mcp_chat/page.tsx.ejs +116 -110
  484. package/hedhog/frontend/app/message-templates/_components/message-template-sheet.tsx.ejs +245 -0
  485. package/hedhog/frontend/app/message-templates/_lib/types.ts.ejs +24 -0
  486. package/hedhog/frontend/app/message-templates/page.tsx.ejs +182 -0
  487. package/hedhog/frontend/app/pages/_components/page-wizard-sheet.tsx.ejs +1 -0
  488. package/hedhog/frontend/app/pages/page.tsx.ejs +94 -9
  489. package/hedhog/frontend/app/roles/menus.tsx.ejs +4 -4
  490. package/hedhog/frontend/app/roles/routes.tsx.ejs +4 -4
  491. package/hedhog/frontend/app/roles/users.tsx.ejs +4 -4
  492. package/hedhog/frontend/app/setting-list/page.tsx.ejs +71 -9
  493. package/hedhog/frontend/app/users/page.tsx.ejs +77 -67
  494. package/hedhog/frontend/messages/en.json +183 -36
  495. package/hedhog/frontend/messages/pt.json +183 -36
  496. package/hedhog/table/cron_lock.yaml +17 -0
  497. package/hedhog/table/file.yaml +13 -1
  498. package/hedhog/table/file_upload_chunk.yaml +23 -0
  499. package/hedhog/table/file_upload_ticket.yaml +67 -0
  500. package/hedhog/table/mcp_tool_call_log.yaml +30 -22
  501. package/hedhog/table/message_template.yaml +33 -0
  502. package/hedhog/table/setting.yaml +8 -0
  503. package/hedhog/table/user_session.yaml +36 -1
  504. package/package.json +8 -6
  505. package/src/ai/ai-agent.sort.ts +21 -0
  506. package/src/ai/ai.service.spec.ts +173 -1
  507. package/src/ai/ai.service.ts +64 -193
  508. package/src/ai-instruction/ai-instruction.service.ts +32 -28
  509. package/src/ai-instruction/ai-instruction.sort.ts +32 -0
  510. package/src/auth/auth.module.ts +8 -1
  511. package/src/auth/auth.service.spec.ts +108 -1
  512. package/src/auth/auth.service.ts +59 -5
  513. package/src/auth/guards/auth.guard.ts +9 -1
  514. package/src/authorize/authorize.controller.ts +126 -11
  515. package/src/authorize/authorize.errors.ts +55 -0
  516. package/src/authorize/authorize.module.ts +6 -1
  517. package/src/authorize/authorize.service.spec.ts +379 -7
  518. package/src/authorize/authorize.service.ts +309 -23
  519. package/src/authorize/dto/authorize-info.dto.ts +21 -3
  520. package/src/authorize/dto/consent.dto.ts +21 -3
  521. package/src/authorize/dto/token.dto.ts +24 -2
  522. package/src/authorize/oauth-exception.filter.ts +58 -0
  523. package/src/authorize/oauth-metadata.service.ts +67 -0
  524. package/src/authorize/well-known.controller.spec.ts +84 -0
  525. package/src/authorize/well-known.controller.ts +96 -0
  526. package/src/captcha/captcha.service.spec.ts +211 -4
  527. package/src/captcha/captcha.service.ts +127 -10
  528. package/src/core.module.ts +6 -0
  529. package/src/dashboard/dashboard-component-role/dashboard-component-role.service.ts +2 -3
  530. package/src/dashboard/dashboard-component-role/dashboard-component-role.sort.ts +18 -0
  531. package/src/dashboard/dashboard-item/dashboard-item.service.ts +2 -3
  532. package/src/dashboard/dashboard-item/dashboard-item.sort.ts +19 -0
  533. package/src/dashboard/dashboard-role/dashboard-role.service.ts +2 -3
  534. package/src/dashboard/dashboard-role/dashboard-role.sort.ts +16 -0
  535. package/src/file/file-upload-ticket.service.spec.ts +422 -0
  536. package/src/file/file-upload-ticket.service.ts +513 -0
  537. package/src/file/file.controller.ts +65 -0
  538. package/src/file/file.module.ts +14 -2
  539. package/src/file/file.service.spec.ts +94 -0
  540. package/src/file/file.service.ts +432 -30
  541. package/src/file/filename-encoding.util.spec.ts +54 -0
  542. package/src/file/filename-encoding.util.ts +67 -0
  543. package/src/file/image-optimization.service.spec.ts +156 -19
  544. package/src/file/image-optimization.service.ts +106 -21
  545. package/src/file/mcp-file-source.schema.ts +83 -0
  546. package/src/file/mcp-file-source.service.spec.ts +473 -0
  547. package/src/file/mcp-file-source.service.ts +445 -0
  548. package/src/file/mimetype-sniff.util.spec.ts +126 -0
  549. package/src/file/mimetype-sniff.util.ts +265 -0
  550. package/src/file/remote-fetch.util.spec.ts +117 -0
  551. package/src/file/remote-fetch.util.ts +330 -0
  552. package/src/impersonation/dto/start-impersonation.dto.ts +5 -2
  553. package/src/impersonation/impersonation.service.spec.ts +24 -1
  554. package/src/impersonation/impersonation.service.ts +14 -4
  555. package/src/incident/incident.controller.ts +9 -1
  556. package/src/incident/incident.service.ts +7 -0
  557. package/src/index.ts +17 -0
  558. package/src/integration-profile/integration-profile.secrets.ts +7 -0
  559. package/src/integration-profile/integration-profile.service.ts +7 -64
  560. package/src/integration-profile/integration-profile.utils.spec.ts +9 -0
  561. package/src/integration-profile/integration-profile.utils.ts +5 -5
  562. package/src/integration-profile/testers/index.ts +2 -0
  563. package/src/integration-profile/testers/remaining.testers.spec.ts +79 -0
  564. package/src/integration-profile/testers/shipping.testers.ts +94 -0
  565. package/src/mail/dto/send.dto.ts +6 -1
  566. package/src/mail/mail-template.spec.ts +58 -1
  567. package/src/mail/mail.service.spec.ts +112 -0
  568. package/src/mail/mail.service.ts +42 -4
  569. package/src/mail-sent/mail-sent.service.ts +3 -0
  570. package/src/mail-sent/mail-sent.sort.ts +19 -0
  571. package/src/mcp/filters/mcp-challenge.filter.spec.ts +76 -0
  572. package/src/mcp/filters/mcp-challenge.filter.ts +70 -0
  573. package/src/mcp/guards/mcp-auth.guard.spec.ts +51 -2
  574. package/src/mcp/guards/mcp-auth.guard.ts +24 -1
  575. package/src/mcp/guards/mcp-permission.guard.spec.ts +109 -15
  576. package/src/mcp/guards/mcp-permission.guard.ts +76 -51
  577. package/src/mcp/mcp-audit.service.spec.ts +107 -0
  578. package/src/mcp/mcp-audit.service.ts +37 -1
  579. package/src/mcp/mcp-permission.service.spec.ts +197 -0
  580. package/src/mcp/mcp-permission.service.ts +184 -0
  581. package/src/mcp/mcp-server.service.spec.ts +84 -2
  582. package/src/mcp/mcp-server.service.ts +111 -87
  583. package/src/mcp/mcp.controller.ts +8 -1
  584. package/src/mcp/mcp.module.ts +5 -1
  585. package/src/mcp/tools/core-ai.mcp-tools.ts +1 -1
  586. package/src/mcp/tools/core-dashboard-items.mcp-tools.ts +1 -1
  587. package/src/mcp/tools/core-dashboard.mcp-tools.ts +1 -1
  588. package/src/mcp/tools/core-event-webhooks.mcp-tools.ts +1 -2
  589. package/src/mcp/tools/core-files.mcp-tools.ts +202 -22
  590. package/src/mcp/tools/core-integration-events.mcp-tools.ts +1 -1
  591. package/src/mcp/tools/core-mail-sent.mcp-tools.ts +1 -1
  592. package/src/mcp/tools/core-mail.mcp-tools.ts +1 -1
  593. package/src/mcp/tools/core-menus.mcp-tools.ts +1 -2
  594. package/src/mcp/tools/core-notifications.mcp-tools.ts +0 -1
  595. package/src/mcp/tools/core-roles.mcp-tools.ts +1 -5
  596. package/src/mcp/tools/core-routes.mcp-tools.ts +1 -3
  597. package/src/mcp/tools/core-screens.mcp-tools.ts +1 -3
  598. package/src/mcp/tools/core-sessions.mcp-tools.ts +0 -2
  599. package/src/mcp/tools/core-settings.mcp-tools.ts +1 -2
  600. package/src/mcp/tools/core-users.mcp-tools.ts +1 -1
  601. package/src/mcp/tools/core-webhooks.mcp-tools.ts +1 -2
  602. package/src/mcp/types/mcp-context.type.ts +15 -6
  603. package/src/mcp-chat/mcp-chat.service.ts +8 -0
  604. package/src/meeting/meeting-provider.registry.ts +121 -0
  605. package/src/meeting/meeting.constants.ts +74 -0
  606. package/src/menu/menu.service.spec.ts +89 -0
  607. package/src/menu/menu.service.ts +29 -11
  608. package/src/message-template/dto/update-message-template.dto.ts +22 -0
  609. package/src/message-template/message-template-admin.service.spec.ts +163 -0
  610. package/src/message-template/message-template-admin.service.ts +239 -0
  611. package/src/message-template/message-template.controller.ts +52 -0
  612. package/src/message-template/message-template.module.ts +21 -0
  613. package/src/message-template/message-template.registry.spec.ts +62 -0
  614. package/src/message-template/message-template.registry.ts +125 -0
  615. package/src/message-template/message-template.service.spec.ts +149 -0
  616. package/src/message-template/message-template.service.ts +149 -0
  617. package/src/notification/notification.constants.ts +10 -0
  618. package/src/notification/notification.module.ts +3 -0
  619. package/src/notification/notification.service.spec.ts +75 -1
  620. package/src/notification/notification.service.ts +39 -1
  621. package/src/oauth/oauth.controller.ts +0 -1
  622. package/src/oauth/oauth.errors.ts +7 -0
  623. package/src/oauth/oauth.module.ts +6 -1
  624. package/src/oauth/oauth.service.spec.ts +58 -7
  625. package/src/oauth/oauth.service.ts +71 -32
  626. package/src/oauth/providers/abstract.provider.spec.ts +192 -0
  627. package/src/oauth/providers/abstract.provider.ts +46 -14
  628. package/src/oauth/providers/github.provider.ts +57 -34
  629. package/src/oauth/providers/microsoft-entra-id.provider.ts +8 -1
  630. package/src/observability/monitored-cron.spec.ts +164 -31
  631. package/src/observability/monitored-cron.ts +154 -62
  632. package/src/profile/dto/change-password.dto.ts +25 -7
  633. package/src/profile/profile.service.spec.ts +97 -0
  634. package/src/profile/profile.service.ts +9 -3
  635. package/src/realtime/realtime-tick.coalescer.spec.ts +92 -0
  636. package/src/realtime/realtime-tick.coalescer.ts +60 -0
  637. package/src/realtime/realtime.service.spec.ts +33 -0
  638. package/src/realtime/realtime.service.ts +28 -2
  639. package/src/redis/redis-kv.service.ts +261 -0
  640. package/src/redis/redis-master.spec.ts +111 -0
  641. package/src/redis/redis-master.ts +86 -0
  642. package/src/redis/redis-pubsub.ts +27 -3
  643. package/src/redis/redis.module.ts +17 -0
  644. package/src/session/session.service.spec.ts +121 -42
  645. package/src/session/session.service.ts +279 -82
  646. package/src/setting/setting.service.ts +44 -3
  647. package/src/task/task.service.spec.ts +41 -0
  648. package/src/task/task.service.ts +53 -13
  649. package/src/token/token.service.spec.ts +90 -0
  650. package/src/token/token.service.ts +48 -2
  651. package/src/user/user-credential.util.ts +14 -5
  652. package/src/user/user.service.ts +2 -12
  653. package/src/user/user.sort.ts +25 -0
  654. package/src/utils/abbreviate-name.spec.ts +50 -0
  655. package/src/utils/abbreviate-name.ts +44 -0
  656. package/src/utils/date-range-query.dto.ts +56 -0
  657. package/src/utils/date-range.spec.ts +175 -0
  658. package/src/utils/date-range.ts +246 -0
  659. package/src/webhook-integration/webhook-utils.spec.ts +67 -0
  660. package/src/webhook-integration/webhook-utils.ts +26 -0
  661. package/src/whatsapp-sender/whatsapp-recipients.spec.ts +89 -0
  662. package/src/whatsapp-sender/whatsapp-recipients.ts +83 -0
  663. package/src/whatsapp-sender/whatsapp-sender.service.spec.ts +112 -0
  664. package/src/whatsapp-sender/whatsapp-sender.service.ts +58 -5
@@ -0,0 +1,330 @@
1
+ import { BadRequestException } from '@nestjs/common';
2
+ import { Agent as HttpAgent } from 'http';
3
+ import { Agent as HttpsAgent } from 'https';
4
+ import { isIP } from 'net';
5
+ import { lookup as dnsLookup } from 'dns';
6
+ import axios from 'axios';
7
+
8
+ /**
9
+ * Download de URL informada por quem chama a tool (`fileUrl`).
10
+ *
11
+ * É a única superfície do sistema em que um endereço escolhido pelo usuário vira uma
12
+ * requisição saindo de dentro do cluster, então a guarda de SSRF mora aqui. O repositório
13
+ * não tinha nada equivalente: a única util de URL existente (`assertHttpUrl`, em
14
+ * `integration-profile/testers/http-probe.ts`) **libera faixas privadas de propósito**,
15
+ * porque serve para Evolution e k8s auto-hospedados — usá-la aqui seria o oposto do que
16
+ * se precisa.
17
+ *
18
+ * O ponto não óbvio é *quando* validar o IP. Resolver o nome, aprovar e só então deixar o
19
+ * axios conectar abre uma janela: entre a checagem e a conexão o DNS pode responder outra
20
+ * coisa (rebinding), e quem conecta é o agente, não nós. Por isso a validação é instalada
21
+ * como o `lookup` do agente — ela roda no momento em que o socket é aberto, sobre o mesmo
22
+ * endereço que será usado. Cada redirect repete tudo, porque o destino muda.
23
+ */
24
+
25
+ const PRIVATE_IPV4_RULES: Array<{ cidr: string; reason: string }> = [
26
+ { cidr: '0.0.0.0/8', reason: 'this-network' },
27
+ { cidr: '10.0.0.0/8', reason: 'private' },
28
+ { cidr: '100.64.0.0/10', reason: 'carrier-grade NAT' },
29
+ { cidr: '127.0.0.0/8', reason: 'loopback' },
30
+ { cidr: '169.254.0.0/16', reason: 'link-local / cloud metadata' },
31
+ { cidr: '172.16.0.0/12', reason: 'private' },
32
+ { cidr: '192.0.0.0/24', reason: 'IETF protocol assignments' },
33
+ { cidr: '192.0.2.0/24', reason: 'documentation' },
34
+ { cidr: '192.168.0.0/16', reason: 'private' },
35
+ { cidr: '198.18.0.0/15', reason: 'benchmarking' },
36
+ { cidr: '198.51.100.0/24', reason: 'documentation' },
37
+ { cidr: '203.0.113.0/24', reason: 'documentation' },
38
+ { cidr: '224.0.0.0/4', reason: 'multicast' },
39
+ { cidr: '240.0.0.0/4', reason: 'reserved' },
40
+ ];
41
+
42
+ const ipv4ToInt = (ip: string): number =>
43
+ ip.split('.').reduce((acc, part) => (acc << 8) + Number(part), 0) >>> 0;
44
+
45
+ const matchesCidr = (ip: string, cidr: string): boolean => {
46
+ const [range, bitsRaw] = cidr.split('/');
47
+ const bits = Number(bitsRaw);
48
+ const mask = bits === 0 ? 0 : (0xffffffff << (32 - bits)) >>> 0;
49
+ return (ipv4ToInt(ip) & mask) === (ipv4ToInt(range) & mask);
50
+ };
51
+
52
+ /**
53
+ * Motivo da recusa, ou `null` quando o endereço é público.
54
+ *
55
+ * IPv6 mapeado (`::ffff:169.254.169.254`) é desempacotado antes do cotejo: sem isso, o
56
+ * endpoint de metadados volta a ser alcançável pela notação de seis grupos.
57
+ */
58
+ export function describeBlockedAddress(address: string): string | null {
59
+ const value = String(address || '').trim().toLowerCase();
60
+
61
+ if (!value) {
62
+ return 'empty address';
63
+ }
64
+
65
+ const mapped = value.match(/^::ffff:(\d+\.\d+\.\d+\.\d+)$/);
66
+ const candidate = mapped ? mapped[1] : value;
67
+ const version = isIP(candidate);
68
+
69
+ if (version === 4) {
70
+ const rule = PRIVATE_IPV4_RULES.find((entry) => matchesCidr(candidate, entry.cidr));
71
+ return rule ? `${rule.reason} address (${candidate})` : null;
72
+ }
73
+
74
+ if (version === 6) {
75
+ if (candidate === '::' || candidate === '::1') {
76
+ return `loopback address (${candidate})`;
77
+ }
78
+
79
+ // fc00::/7 (unique local) e fe80::/10 (link-local, onde vive fe80::a9fe:a9fe).
80
+ if (/^f[cd]/.test(candidate)) {
81
+ return `unique local address (${candidate})`;
82
+ }
83
+
84
+ if (/^fe[89ab]/.test(candidate)) {
85
+ return `link-local address (${candidate})`;
86
+ }
87
+
88
+ if (/^ff/.test(candidate)) {
89
+ return `multicast address (${candidate})`;
90
+ }
91
+
92
+ return null;
93
+ }
94
+
95
+ return `unresolvable address (${address})`;
96
+ }
97
+
98
+ /**
99
+ * `lookup` compatível com o do Node que recusa antes de devolver o endereço ao agente.
100
+ *
101
+ * O agente chama isto para cada conexão, então é aqui que a decisão vale — e não numa
102
+ * checagem prévia que o DNS poderia contradizer depois.
103
+ */
104
+ const guardedLookup = (
105
+ hostname: string,
106
+ options: any,
107
+ callback: (err: NodeJS.ErrnoException | null, address?: any, family?: number) => void,
108
+ ): void => {
109
+ const done = typeof options === 'function' ? options : callback;
110
+ const opts = typeof options === 'function' ? {} : options;
111
+
112
+ dnsLookup(hostname, { ...opts, all: true } as any, (err, addresses: any) => {
113
+ if (err) {
114
+ done(err);
115
+ return;
116
+ }
117
+
118
+ const list = Array.isArray(addresses) ? addresses : [addresses];
119
+
120
+ if (list.length === 0) {
121
+ done(Object.assign(new Error(`Host did not resolve: ${hostname}`), { code: 'ENOTFOUND' }));
122
+ return;
123
+ }
124
+
125
+ // Basta um endereço proibido para recusar o host inteiro: aceitar os "bons" deixaria
126
+ // o resultado na mão de qual entrada o resolvedor devolve primeiro.
127
+ for (const entry of list) {
128
+ const blocked = describeBlockedAddress(entry.address);
129
+ if (blocked) {
130
+ done(
131
+ Object.assign(new Error(`Blocked ${blocked} for host ${hostname}`), {
132
+ code: 'EBLOCKED',
133
+ }),
134
+ );
135
+ return;
136
+ }
137
+ }
138
+
139
+ const first = list[0];
140
+
141
+ if (opts?.all) {
142
+ done(null, list as any);
143
+ return;
144
+ }
145
+
146
+ done(null, first.address, first.family);
147
+ });
148
+ };
149
+
150
+ export interface RemoteFetchOptions {
151
+ /** Teto de bytes; o download aborta assim que o passa, sem bufferizar o resto. */
152
+ maxBytes: number;
153
+ /** Hosts liberados. Vazio (o default) = qualquer host público. */
154
+ allowedHosts?: string[];
155
+ timeoutMs?: number;
156
+ maxRedirects?: number;
157
+ }
158
+
159
+ export interface RemoteFetchResult {
160
+ buffer: Buffer;
161
+ /** `Content-Type` da resposta, sem parâmetros. Informativo: quem manda é o conteúdo. */
162
+ contentType: string | null;
163
+ /** Host de onde o conteúdo veio de fato, depois de seguidos os redirects. */
164
+ finalHost: string;
165
+ finalUrl: string;
166
+ }
167
+
168
+ const DEFAULT_TIMEOUT_MS = 15000;
169
+ const DEFAULT_MAX_REDIRECTS = 3;
170
+
171
+ /** Valida esquema, credenciais e allowlist. Separada para poder ser testada sozinha. */
172
+ export function assertFetchableUrl(raw: string, allowedHosts?: string[]): URL {
173
+ let url: URL;
174
+
175
+ try {
176
+ url = new URL(String(raw || '').trim());
177
+ } catch {
178
+ throw new BadRequestException(`fileUrl is not a valid URL`);
179
+ }
180
+
181
+ if (url.protocol !== 'http:' && url.protocol !== 'https:') {
182
+ throw new BadRequestException(
183
+ `fileUrl must use http or https, got ${url.protocol.replace(':', '') || 'none'}`,
184
+ );
185
+ }
186
+
187
+ // Credencial na URL viraria header de autenticação para um destino escolhido por quem
188
+ // chama — e apareceria no log de auditoria junto com o resto da entrada.
189
+ if (url.username || url.password) {
190
+ throw new BadRequestException(`fileUrl must not carry credentials`);
191
+ }
192
+
193
+ const allow = (allowedHosts || []).map((h) => h.trim().toLowerCase()).filter(Boolean);
194
+
195
+ if (allow.length > 0) {
196
+ const host = url.hostname.toLowerCase();
197
+ const permitted = allow.some(
198
+ (entry) => host === entry || host.endsWith(`.${entry}`),
199
+ );
200
+
201
+ if (!permitted) {
202
+ throw new BadRequestException(
203
+ `fileUrl host is not allowed: ${host}. Allowed hosts come from the mcp-file-url-allowed-hosts setting.`,
204
+ );
205
+ }
206
+ }
207
+
208
+ return url;
209
+ }
210
+
211
+ /**
212
+ * Baixa a URL para memória, recusando destino privado e conteúdo acima do teto.
213
+ *
214
+ * Os redirects são seguidos à mão (`maxRedirects: 0` no axios) porque cada salto é um
215
+ * destino novo que precisa passar pela mesma validação — deixar o axios seguir sozinho
216
+ * entregaria o segundo salto sem conferência, que é justamente como se contorna uma
217
+ * allowlist que só olha a URL inicial.
218
+ */
219
+ export async function fetchRemoteFile(
220
+ rawUrl: string,
221
+ options: RemoteFetchOptions,
222
+ ): Promise<RemoteFetchResult> {
223
+ const maxRedirects = options.maxRedirects ?? DEFAULT_MAX_REDIRECTS;
224
+ const timeout = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
225
+
226
+ let current = assertFetchableUrl(rawUrl, options.allowedHosts);
227
+
228
+ for (let hop = 0; hop <= maxRedirects; hop += 1) {
229
+ const isHttps = current.protocol === 'https:';
230
+ const AgentCtor = isHttps ? HttpsAgent : HttpAgent;
231
+ const agent = new AgentCtor({ lookup: guardedLookup as any });
232
+
233
+ let response: any;
234
+
235
+ try {
236
+ response = await axios.get(current.toString(), {
237
+ responseType: 'stream',
238
+ timeout,
239
+ maxRedirects: 0,
240
+ // Teto redundante com o contador abaixo, mas ele corta antes de o axios montar
241
+ // qualquer buffer quando o servidor declara o tamanho.
242
+ maxContentLength: options.maxBytes,
243
+ maxBodyLength: options.maxBytes,
244
+ decompress: true,
245
+ validateStatus: (status: number) => status < 400,
246
+ ...(isHttps ? { httpsAgent: agent } : { httpAgent: agent }),
247
+ });
248
+ } catch (error: any) {
249
+ if (error?.code === 'EBLOCKED') {
250
+ throw new BadRequestException(`fileUrl rejected: ${error.message}`);
251
+ }
252
+
253
+ if (error?.response?.status) {
254
+ throw new BadRequestException(
255
+ `fileUrl responded with HTTP ${error.response.status}`,
256
+ );
257
+ }
258
+
259
+ throw new BadRequestException(`fileUrl download failed: ${error?.message || error}`);
260
+ }
261
+
262
+ const status = Number(response.status);
263
+
264
+ if (status >= 300 && status < 400) {
265
+ const location = response.headers?.location;
266
+ response.data?.destroy?.();
267
+
268
+ if (!location) {
269
+ throw new BadRequestException(`fileUrl redirected without a location header`);
270
+ }
271
+
272
+ if (hop === maxRedirects) {
273
+ throw new BadRequestException(
274
+ `fileUrl exceeded the redirect limit of ${maxRedirects}`,
275
+ );
276
+ }
277
+
278
+ current = assertFetchableUrl(
279
+ new URL(location, current).toString(),
280
+ options.allowedHosts,
281
+ );
282
+ continue;
283
+ }
284
+
285
+ const buffer = await readStreamWithLimit(response.data, options.maxBytes);
286
+
287
+ return {
288
+ buffer,
289
+ contentType: String(response.headers?.['content-type'] || '').split(';')[0] || null,
290
+ finalHost: current.hostname,
291
+ finalUrl: current.toString(),
292
+ };
293
+ }
294
+
295
+ throw new BadRequestException(`fileUrl exceeded the redirect limit of ${maxRedirects}`);
296
+ }
297
+
298
+ /**
299
+ * Acumula o stream até o teto e aborta na primeira parte que o ultrapassa.
300
+ *
301
+ * `maxContentLength` do axios só vale quando o servidor declara `Content-Length`; sem o
302
+ * contador, uma resposta sem tamanho declarado encheria a memória do pod.
303
+ */
304
+ function readStreamWithLimit(stream: any, maxBytes: number): Promise<Buffer> {
305
+ return new Promise((resolve, reject) => {
306
+ const chunks: Buffer[] = [];
307
+ let total = 0;
308
+
309
+ stream.on('data', (chunk: Buffer) => {
310
+ total += chunk.length;
311
+
312
+ if (total > maxBytes) {
313
+ stream.destroy();
314
+ reject(
315
+ new BadRequestException(
316
+ `fileUrl content exceeds the maximum of ${maxBytes} bytes`,
317
+ ),
318
+ );
319
+ return;
320
+ }
321
+
322
+ chunks.push(Buffer.from(chunk));
323
+ });
324
+
325
+ stream.on('end', () => resolve(Buffer.concat(chunks)));
326
+ stream.on('error', (error: any) =>
327
+ reject(new BadRequestException(`fileUrl download failed: ${error?.message || error}`)),
328
+ );
329
+ });
330
+ }
@@ -1,8 +1,11 @@
1
1
  import { IsIn, IsOptional, IsString, MaxLength } from 'class-validator';
2
2
 
3
3
  export class StartImpersonationDTO {
4
- /** Chave do app de destino em `app-urls`. */
5
- @IsIn(['admin', 'class', 'partners'])
4
+ /**
5
+ * Chave do app de destino em `app-urls`. Espelha
6
+ * `ImpersonationService.REDEEMABLE_APPS`: app novo entra nos dois lugares.
7
+ */
8
+ @IsIn(['admin', 'class', 'partners', 'training'])
6
9
  app: string;
7
10
 
8
11
  /** Justificativa livre do operador; vai para a trilha de auditoria. */
@@ -188,10 +188,23 @@ describe('ImpersonationService', () => {
188
188
 
189
189
  it('recusa app sem tela de resgate', async () => {
190
190
  await expect(
191
- service.start(startParams({ app: 'training' }) as never),
191
+ service.start(startParams({ app: 'site' }) as never),
192
192
  ).rejects.toThrow(BadRequestException);
193
193
  });
194
194
 
195
+ it('aceita o training, que tem tela de resgate própria', async () => {
196
+ deps.setting.getSettingValues.mockResolvedValue({
197
+ 'app-urls': ['training=https://hcode.training'],
198
+ 'impersonation-session-minutes': 30,
199
+ } as never);
200
+
201
+ await expect(
202
+ service.start(startParams({ app: 'training' }) as never),
203
+ ).resolves.toMatchObject({
204
+ url: expect.stringContaining('https://hcode.training/simulacao#code='),
205
+ });
206
+ });
207
+
195
208
  it('recusa app sem URL configurada em app-urls', async () => {
196
209
  await expect(
197
210
  service.start(startParams({ app: 'partners' }) as never),
@@ -423,5 +436,15 @@ describe('ImpersonationService', () => {
423
436
  { key: 'class', url: 'https://class.example.com' },
424
437
  ]);
425
438
  });
439
+
440
+ it('lista o training quando ele está em app-urls', async () => {
441
+ deps.setting.getSettingValues.mockResolvedValue({
442
+ 'app-urls': ['training=https://hcode.training', 'site=https://hcode.com.br'],
443
+ } as never);
444
+
445
+ await expect(service.listRedeemableApps()).resolves.toEqual([
446
+ { key: 'training', url: 'https://hcode.training' },
447
+ ]);
448
+ });
426
449
  });
427
450
  });
@@ -68,7 +68,7 @@ export class ImpersonationService {
68
68
  /** Curto: o codigo so precisa sobreviver ao carregamento da aba nova. */
69
69
  private readonly codeTtlMs = 60_000;
70
70
 
71
- /** Caminho da tela de resgate, igual nos tres apps. */
71
+ /** Caminho da tela de resgate, igual em todos os apps. */
72
72
  static readonly REDEEM_PATH = '/simulacao';
73
73
 
74
74
  /**
@@ -78,10 +78,20 @@ export class ImpersonationService {
78
78
  private static readonly BLOCKED_TARGET_ROLES = ['admin', 'admin-impersonation'];
79
79
 
80
80
  /**
81
- * Apps com tela de resgate. `training` tem autenticacao propria e nao usa o
82
- * @hed-hog/next-app-provider, entao ficou fora desta fase.
81
+ * Apps com tela de resgate em `/simulacao`. `training` nao usa o
82
+ * @hed-hog/next-app-provider — tem AuthProvider proprio —, entao a tela de
83
+ * resgate, a faixa e a trava de refresh dele sao codigo do proprio app.
84
+ *
85
+ * Esta lista e a que alimenta o select do operador; quem valida a entrada do
86
+ * `start` e o `@IsIn` do StartImpersonationDTO. As duas precisam andar juntas:
87
+ * so aqui, o app aparece no select e o `start` responde 400.
83
88
  */
84
- private static readonly REDEEMABLE_APPS = ['admin', 'class', 'partners'];
89
+ private static readonly REDEEMABLE_APPS = [
90
+ 'admin',
91
+ 'class',
92
+ 'partners',
93
+ 'training',
94
+ ];
85
95
 
86
96
  constructor(
87
97
  @Inject(forwardRef(() => PrismaService))
@@ -1,5 +1,6 @@
1
1
  import { Role, User } from '@hed-hog/api';
2
2
  import { Pagination } from '@hed-hog/api-pagination';
3
+ import { DateRangeQueryDTO } from '../utils/date-range-query.dto';
3
4
  import { Controller, Get, Inject, Param, Patch, Query, forwardRef } from '@nestjs/common';
4
5
  import { IncidentService, type IncidentSeverity } from './incident.service';
5
6
 
@@ -14,11 +15,18 @@ export class IncidentController {
14
15
  @Get()
15
16
  async list(
16
17
  @Pagination() paginationParams,
18
+ @Query() range: DateRangeQueryDTO,
17
19
  @Query('source') source?: string,
18
20
  @Query('severity') severity?: IncidentSeverity,
19
21
  @Query('status') status?: 'open' | 'resolved' | 'all',
20
22
  ) {
21
- return this.incidentService.list({ ...paginationParams, source, severity, status });
23
+ return this.incidentService.list({
24
+ ...paginationParams,
25
+ ...range,
26
+ source,
27
+ severity,
28
+ status,
29
+ });
22
30
  }
23
31
 
24
32
  @Get('summary')
@@ -1,4 +1,5 @@
1
1
  import { PageOrderDirection, PaginationService } from '@hed-hog/api-pagination';
2
+ import { dateRangeWhere } from '../utils/date-range';
2
3
  import { PrismaService } from '@hed-hog/api-prisma';
3
4
  import { forwardRef, Inject, Injectable, Logger } from '@nestjs/common';
4
5
  import { createHash } from 'crypto';
@@ -33,6 +34,8 @@ export interface IncidentListParams {
33
34
  source?: string;
34
35
  severity?: IncidentSeverity;
35
36
  status?: 'open' | 'resolved' | 'all';
37
+ from?: string;
38
+ to?: string;
36
39
  }
37
40
 
38
41
  const MAX_MESSAGE_LENGTH = 2000;
@@ -141,6 +144,10 @@ export class IncidentService {
141
144
  if (params.source) where.source = params.source;
142
145
  if (params.severity) where.severity = params.severity;
143
146
 
147
+ // Recorte pela última ocorrência, que é também a ordenação da tela:
148
+ // "o que apareceu na semana passada" é a pergunta de quem investiga.
149
+ Object.assign(where, dateRangeWhere('last_seen_at', params.from, params.to));
150
+
144
151
  // Aberto é o default: a tela existe para mostrar o que precisa de ação.
145
152
  if (params.status !== 'all') {
146
153
  where.resolved_at = params.status === 'resolved' ? { not: null } : null;
package/src/index.ts CHANGED
@@ -30,6 +30,9 @@ export * from './leaked-password/leaked-password.service';
30
30
 
31
31
  export * from './mail-layout/mail-layout.module';
32
32
  export * from './mail-layout/mail-layout.service';
33
+ export * from './message-template/message-template.module';
34
+ export * from './message-template/message-template.registry';
35
+ export * from './message-template/message-template.service';
33
36
  export * from './mail/mail.module';
34
37
  export * from './mail/mail.service';
35
38
 
@@ -41,11 +44,18 @@ export * from './integration-profile/integration-credential-crypto.service';
41
44
  export * from './integration-profile/testers/integration-tester.types';
42
45
  export * from './integration-profile/testers/integration-tester.registry';
43
46
 
47
+ export * from './whatsapp-sender/whatsapp-recipients';
44
48
  export * from './whatsapp-sender/whatsapp-sender.module';
45
49
  export * from './whatsapp-sender/whatsapp-sender.service';
46
50
 
47
51
  export * from './file/file.module';
48
52
  export * from './file/file.service';
53
+ export * from './file/filename-encoding.util';
54
+ export * from './file/file-upload-ticket.service';
55
+ export * from './file/mcp-file-source.service';
56
+ export * from './file/mcp-file-source.schema';
57
+ export * from './file/mimetype-sniff.util';
58
+ export * from './file/remote-fetch.util';
49
59
 
50
60
  export * from './pdf/pdf.module';
51
61
  export * from './pdf/pdf.service';
@@ -122,10 +132,14 @@ export * from './utils/locale-context';
122
132
  export * from './utils/geo-ip';
123
133
  export * from './utils/user-agent';
124
134
  export * from './utils/security-event-vars';
135
+ export * from './utils/abbreviate-name';
136
+ export * from './utils/date-range';
137
+ export * from './utils/date-range-query.dto';
125
138
 
126
139
 
127
140
  // Notification Module
128
141
  export * from './notification/dto/create-notification.dto';
142
+ export * from './notification/notification.constants';
129
143
  export * from './notification/notification.module';
130
144
  export * from './notification/notification.service';
131
145
 
@@ -133,6 +147,9 @@ export * from './notification/notification.service';
133
147
  export * from './realtime/realtime.module';
134
148
  export * from './realtime/realtime.service';
135
149
  export * from './realtime/realtime.gateway';
150
+ export * from './realtime/realtime-tick.coalescer';
151
+ export * from './redis/redis-kv.service';
152
+ export * from './redis/redis.module';
136
153
 
137
154
  // Presence Module
138
155
  export * from './presence/presence.module';
@@ -69,6 +69,13 @@ export const INTEGRATION_SECRET_KEYS: Record<string, string[]> = {
69
69
  // O certificado A1 é a chave privada da empresa: quem tem o PFX + a senha
70
70
  // emite nota em nome dela. Os dois DEVEM estar aqui.
71
71
  'nfse-national': ['certificate_pfx_base64', 'certificate_password'],
72
+ // Frete
73
+ // O token do Melhor Envio compra etiqueta na carteira da conta, não só cota
74
+ // frete: vale como credencial de pagamento. `refresh_token` vale ainda mais —
75
+ // ele gera tokens novos indefinidamente —, e o OAuth deles o ROTACIONA a cada
76
+ // uso, então ele é reescrito no perfil a cada renovação: se não estiver aqui,
77
+ // cada renovação grava a credencial em texto puro no banco.
78
+ 'melhor-envio': ['access_token', 'client_secret', 'refresh_token'],
72
79
  };
73
80
 
74
81
  /** Chaves sensíveis de um provider (vazio se desconhecido). */
@@ -165,30 +165,18 @@ export class IntegrationProfileService {
165
165
  const items = Array.isArray(result.data) ? result.data : [];
166
166
  if (items.length > 0) {
167
167
  const ids = items.map((p: any) => p.id as number);
168
- const usageTables = await this.getExistingUsageTables();
169
-
170
- const counts =
171
- usageTables.length === 0
172
- ? []
173
- : await this.prismaService.$queryRawUnsafe<
174
- { id: number; uses_count: bigint }[]
175
- >(
176
- `
168
+ const counts = await this.prismaService.$queryRaw<
169
+ { id: number; uses_count: bigint }[]
170
+ >`
177
171
  SELECT
178
172
  ip.id,
179
173
  (
180
- ${usageTables
181
- .map(
182
- (table) =>
183
- `COALESCE((SELECT COUNT(*)::int FROM ${table} WHERE integration_profile_id = ip.id), 0)`,
184
- )
185
- .join(' + ')}
174
+ COALESCE((SELECT COUNT(*)::int FROM campaign WHERE integration_profile_id = ip.id), 0) +
175
+ COALESCE((SELECT COUNT(*)::int FROM webhook_action WHERE integration_profile_id = ip.id), 0)
186
176
  ) AS uses_count
187
177
  FROM integration_profile ip
188
- WHERE ip.id = ANY($1::int[])
189
- `,
190
- ids,
191
- );
178
+ WHERE ip.id = ANY(${ids}::int[])
179
+ `;
192
180
 
193
181
  const countMap = new Map(
194
182
  counts.map((r) => [r.id, Number(r.uses_count)]),
@@ -208,51 +196,6 @@ export class IntegrationProfileService {
208
196
  return result;
209
197
  }
210
198
 
211
- /**
212
- * Tabelas que referenciam um perfil de integração, para o contador `uses_count`.
213
- *
214
- * Nem toda instalação tem todas: `campaign` vem de uma library de marketing que
215
- * pode não estar instalada, enquanto `webhook_action` é do core. O Postgres
216
- * valida os nomes de relação ao analisar a query, então citar uma tabela ausente
217
- * não devolve zero — derruba o `$queryRaw` inteiro com 42P01 e, com ele, toda a
218
- * listagem de perfis (500, sem nenhum perfil visível na tela).
219
- */
220
- private static readonly USAGE_TABLES = ['campaign', 'webhook_action'];
221
-
222
- /** Cacheado: o conjunto de tabelas só muda com migration, não entre requests. */
223
- private existingUsageTables: string[] | null = null;
224
-
225
- private async getExistingUsageTables(): Promise<string[]> {
226
- if (this.existingUsageTables) return this.existingUsageTables;
227
-
228
- const rows = await this.prismaService.$queryRaw<{ table_name: string }[]>`
229
- SELECT table_name
230
- FROM information_schema.tables
231
- WHERE table_schema = 'public'
232
- AND table_name = ANY(${IntegrationProfileService.USAGE_TABLES}::text[])
233
- `;
234
-
235
- const found = new Set(rows.map((r) => r.table_name));
236
-
237
- // Filtrar a constante (em vez de usar o retorno do banco direto) mantém os
238
- // nomes interpolados na query restritos a esta lista fixa.
239
- this.existingUsageTables = IntegrationProfileService.USAGE_TABLES.filter(
240
- (table) => found.has(table),
241
- );
242
-
243
- const missing = IntegrationProfileService.USAGE_TABLES.filter(
244
- (table) => !found.has(table),
245
- );
246
-
247
- if (missing.length > 0) {
248
- this.logger.log(
249
- `uses_count ignora tabela(s) ausente(s) nesta instalação: ${missing.join(', ')}.`,
250
- );
251
- }
252
-
253
- return this.existingUsageTables;
254
- }
255
-
256
199
  /**
257
200
  * Resolve o config do perfil de integração ATIVO para um par tipo/provider — uso
258
201
  * server-side por serviços que precisam das credenciais (ex.: InfraScaler do
@@ -111,6 +111,15 @@ describe('integration-profile.utils', () => {
111
111
  it('trata config null', () => {
112
112
  expect(getFromAddress(null)).toBe('');
113
113
  });
114
+
115
+ // Espaco sobrando no perfil virava `Alice < a@b.com>` e o SES recusava o
116
+ // Source inteiro, do mesmo jeito que recusa um destinatario sujo.
117
+ it('apara espaco no email e no nome, como o getReplyToAddress ja fazia', () => {
118
+ expect(
119
+ getFromAddress({ from_email: ' a@b.com ', from_name: ' Alice ' }),
120
+ ).toBe('Alice <a@b.com>');
121
+ expect(getFromAddress({ from_email: ' a@b.com ' })).toBe('a@b.com');
122
+ });
114
123
  });
115
124
 
116
125
  describe('getReplyToAddress', () => {