@hed-hog/core 0.0.399 → 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 (668) 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 +29 -5
  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 +77 -3
  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 +386 -54
  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.service.d.ts +6 -2
  356. package/dist/pairing/pairing.service.d.ts.map +1 -1
  357. package/dist/profile/dto/change-password.dto.d.ts.map +1 -1
  358. package/dist/profile/dto/change-password.dto.js +4 -6
  359. package/dist/profile/dto/change-password.dto.js.map +1 -1
  360. package/dist/profile/profile.controller.d.ts +1 -1
  361. package/dist/profile/profile.service.d.ts +1 -1
  362. package/dist/profile/profile.service.d.ts.map +1 -1
  363. package/dist/profile/profile.service.js +9 -3
  364. package/dist/profile/profile.service.js.map +1 -1
  365. package/dist/realtime/realtime-tick.coalescer.d.ts +34 -0
  366. package/dist/realtime/realtime-tick.coalescer.d.ts.map +1 -0
  367. package/dist/realtime/realtime-tick.coalescer.js +60 -0
  368. package/dist/realtime/realtime-tick.coalescer.js.map +1 -0
  369. package/dist/realtime/realtime.service.d.ts +2 -0
  370. package/dist/realtime/realtime.service.d.ts.map +1 -1
  371. package/dist/realtime/realtime.service.js +22 -2
  372. package/dist/realtime/realtime.service.js.map +1 -1
  373. package/dist/redis/redis-kv.service.d.ts +90 -0
  374. package/dist/redis/redis-kv.service.d.ts.map +1 -0
  375. package/dist/redis/redis-kv.service.js +247 -0
  376. package/dist/redis/redis-kv.service.js.map +1 -0
  377. package/dist/redis/redis-master.d.ts +29 -0
  378. package/dist/redis/redis-master.d.ts.map +1 -0
  379. package/dist/redis/redis-master.js +81 -0
  380. package/dist/redis/redis-master.js.map +1 -0
  381. package/dist/redis/redis-pubsub.d.ts +12 -0
  382. package/dist/redis/redis-pubsub.d.ts.map +1 -1
  383. package/dist/redis/redis-pubsub.js +25 -2
  384. package/dist/redis/redis-pubsub.js.map +1 -1
  385. package/dist/redis/redis.module.d.ts +11 -0
  386. package/dist/redis/redis.module.d.ts.map +1 -0
  387. package/dist/redis/redis.module.js +30 -0
  388. package/dist/redis/redis.module.js.map +1 -0
  389. package/dist/session/session.controller.d.ts +6 -2
  390. package/dist/session/session.controller.d.ts.map +1 -1
  391. package/dist/session/session.service.d.ts +118 -15
  392. package/dist/session/session.service.d.ts.map +1 -1
  393. package/dist/session/session.service.js +251 -77
  394. package/dist/session/session.service.js.map +1 -1
  395. package/dist/setting/setting.controller.d.ts +5 -0
  396. package/dist/setting/setting.controller.d.ts.map +1 -1
  397. package/dist/setting/setting.service.d.ts +7 -0
  398. package/dist/setting/setting.service.d.ts.map +1 -1
  399. package/dist/setting/setting.service.js +38 -3
  400. package/dist/setting/setting.service.js.map +1 -1
  401. package/dist/task/task.service.d.ts +17 -0
  402. package/dist/task/task.service.d.ts.map +1 -1
  403. package/dist/task/task.service.js +48 -13
  404. package/dist/task/task.service.js.map +1 -1
  405. package/dist/token/token.service.d.ts +19 -1
  406. package/dist/token/token.service.d.ts.map +1 -1
  407. package/dist/token/token.service.js +39 -2
  408. package/dist/token/token.service.js.map +1 -1
  409. package/dist/user/user-credential.util.d.ts +10 -0
  410. package/dist/user/user-credential.util.d.ts.map +1 -1
  411. package/dist/user/user-credential.util.js +14 -1
  412. package/dist/user/user-credential.util.js.map +1 -1
  413. package/dist/user/user.service.d.ts +12 -4
  414. package/dist/user/user.service.d.ts.map +1 -1
  415. package/dist/user/user.service.js +2 -11
  416. package/dist/user/user.service.js.map +1 -1
  417. package/dist/user/user.sort.d.ts +16 -0
  418. package/dist/user/user.sort.d.ts.map +1 -0
  419. package/dist/user/user.sort.js +25 -0
  420. package/dist/user/user.sort.js.map +1 -0
  421. package/dist/utils/abbreviate-name.d.ts +13 -0
  422. package/dist/utils/abbreviate-name.d.ts.map +1 -0
  423. package/dist/utils/abbreviate-name.js +42 -0
  424. package/dist/utils/abbreviate-name.js.map +1 -0
  425. package/dist/utils/date-range-query.dto.d.ts +11 -0
  426. package/dist/utils/date-range-query.dto.d.ts.map +1 -0
  427. package/dist/utils/date-range-query.dto.js +63 -0
  428. package/dist/utils/date-range-query.dto.js.map +1 -0
  429. package/dist/utils/date-range.d.ts +96 -0
  430. package/dist/utils/date-range.d.ts.map +1 -0
  431. package/dist/utils/date-range.js +172 -0
  432. package/dist/utils/date-range.js.map +1 -0
  433. package/dist/webhook-integration/webhook-utils.d.ts.map +1 -1
  434. package/dist/webhook-integration/webhook-utils.js +24 -0
  435. package/dist/webhook-integration/webhook-utils.js.map +1 -1
  436. package/dist/whatsapp-sender/whatsapp-recipients.d.ts +49 -0
  437. package/dist/whatsapp-sender/whatsapp-recipients.d.ts.map +1 -0
  438. package/dist/whatsapp-sender/whatsapp-recipients.js +66 -0
  439. package/dist/whatsapp-sender/whatsapp-recipients.js.map +1 -0
  440. package/dist/whatsapp-sender/whatsapp-sender.service.d.ts +25 -0
  441. package/dist/whatsapp-sender/whatsapp-sender.service.d.ts.map +1 -1
  442. package/dist/whatsapp-sender/whatsapp-sender.service.js +46 -5
  443. package/dist/whatsapp-sender/whatsapp-sender.service.js.map +1 -1
  444. package/hedhog/data/integration_provider.yaml +9 -0
  445. package/hedhog/data/integration_type.yaml +6 -0
  446. package/hedhog/data/locale.yaml +0 -1
  447. package/hedhog/data/mail.yaml +2 -2
  448. package/hedhog/data/mail_layout.yaml +6 -3
  449. package/hedhog/data/menu.yaml +25 -5
  450. package/hedhog/data/route.yaml +140 -0
  451. package/hedhog/data/setting_group.yaml +137 -3
  452. package/hedhog/frontend/app/access-log/page.tsx.ejs +47 -53
  453. package/hedhog/frontend/app/account/components/active-sessions.tsx.ejs +33 -8
  454. package/hedhog/frontend/app/account/components/mcp-tokens.tsx.ejs +54 -13
  455. package/hedhog/frontend/app/account/components/mfa-method-card.tsx.ejs +7 -1
  456. package/hedhog/frontend/app/account/components/recovery-codes-dialog.tsx.ejs +1 -0
  457. package/hedhog/frontend/app/account/components/tokens.tsx.ejs +47 -17
  458. package/hedhog/frontend/app/ai_agent/page.tsx.ejs +46 -5
  459. package/hedhog/frontend/app/ai_instruction/_components/ai-instruction-form.tsx.ejs +101 -30
  460. package/hedhog/frontend/app/ai_instruction/_components/ai-instruction-versions.tsx.ejs +24 -8
  461. package/hedhog/frontend/app/ai_instruction/page.tsx.ejs +80 -15
  462. package/hedhog/frontend/app/configurations/[slug]/components/image-optimization-action.tsx.ejs +166 -0
  463. package/hedhog/frontend/app/configurations/[slug]/components/setting-field.test.tsx.ejs +145 -45
  464. package/hedhog/frontend/app/configurations/[slug]/components/setting-field.tsx.ejs +99 -219
  465. package/hedhog/frontend/app/configurations/[slug]/page.tsx.ejs +19 -1
  466. package/hedhog/frontend/app/configurations/layout.tsx.ejs +19 -5
  467. package/hedhog/frontend/app/dashboard/[slug]/widget-renderer.tsx.ejs +2 -8
  468. package/hedhog/frontend/app/dashboard/components/dynamic-widget.tsx.ejs +3 -0
  469. package/hedhog/frontend/app/dashboard/components/widget-wrapper.tsx.ejs +4 -0
  470. package/hedhog/frontend/app/dashboard/dashboard-home-tabs.tsx.ejs +43 -44
  471. package/hedhog/frontend/app/dashboard/management/tabs/component-roles-tab.tsx.ejs +41 -3
  472. package/hedhog/frontend/app/dashboard/management/tabs/components-tab.tsx.ejs +42 -2
  473. package/hedhog/frontend/app/dashboard/management/tabs/dashboard-roles-tab.tsx.ejs +41 -3
  474. package/hedhog/frontend/app/dashboard/management/tabs/dashboards-tab.tsx.ejs +39 -4
  475. package/hedhog/frontend/app/dashboard/management/tabs/items-tab.tsx.ejs +42 -3
  476. package/hedhog/frontend/app/incidents/page.tsx.ejs +60 -31
  477. package/hedhog/frontend/app/integration/profiles/page.tsx.ejs +45 -5
  478. package/hedhog/frontend/app/integrations-webhooks/page.tsx.ejs +92 -15
  479. package/hedhog/frontend/app/mail/log/page.tsx.ejs +109 -61
  480. package/hedhog/frontend/app/mail/template/page.tsx.ejs +125 -23
  481. package/hedhog/frontend/app/mcp_chat/chat-components.tsx.ejs +13 -15
  482. package/hedhog/frontend/app/mcp_chat/page.tsx.ejs +116 -110
  483. package/hedhog/frontend/app/message-templates/_components/message-template-sheet.tsx.ejs +245 -0
  484. package/hedhog/frontend/app/message-templates/_lib/types.ts.ejs +24 -0
  485. package/hedhog/frontend/app/message-templates/page.tsx.ejs +182 -0
  486. package/hedhog/frontend/app/pages/_components/page-wizard-sheet.tsx.ejs +1 -0
  487. package/hedhog/frontend/app/pages/page.tsx.ejs +94 -9
  488. package/hedhog/frontend/app/roles/menus.tsx.ejs +4 -4
  489. package/hedhog/frontend/app/roles/routes.tsx.ejs +4 -4
  490. package/hedhog/frontend/app/roles/users.tsx.ejs +4 -4
  491. package/hedhog/frontend/app/setting-list/page.tsx.ejs +71 -9
  492. package/hedhog/frontend/app/users/page.tsx.ejs +77 -67
  493. package/hedhog/frontend/messages/en.json +183 -36
  494. package/hedhog/frontend/messages/pt.json +183 -36
  495. package/hedhog/table/cron_lock.yaml +17 -0
  496. package/hedhog/table/file.yaml +13 -1
  497. package/hedhog/table/file_upload_chunk.yaml +23 -0
  498. package/hedhog/table/file_upload_ticket.yaml +67 -0
  499. package/hedhog/table/mcp_tool_call_log.yaml +30 -22
  500. package/hedhog/table/message_template.yaml +33 -0
  501. package/hedhog/table/setting.yaml +8 -0
  502. package/hedhog/table/user_session.yaml +36 -1
  503. package/package.json +7 -5
  504. package/src/ai/ai-agent.sort.ts +21 -0
  505. package/src/ai/ai.service.spec.ts +173 -1
  506. package/src/ai/ai.service.ts +64 -193
  507. package/src/ai-instruction/ai-instruction.service.ts +32 -28
  508. package/src/ai-instruction/ai-instruction.sort.ts +32 -0
  509. package/src/auth/auth.module.ts +8 -1
  510. package/src/auth/auth.service.spec.ts +108 -1
  511. package/src/auth/auth.service.ts +59 -5
  512. package/src/auth/guards/auth.guard.ts +9 -1
  513. package/src/authorize/authorize.controller.ts +126 -11
  514. package/src/authorize/authorize.errors.ts +55 -0
  515. package/src/authorize/authorize.module.ts +6 -1
  516. package/src/authorize/authorize.service.spec.ts +379 -7
  517. package/src/authorize/authorize.service.ts +309 -23
  518. package/src/authorize/dto/authorize-info.dto.ts +21 -3
  519. package/src/authorize/dto/consent.dto.ts +21 -3
  520. package/src/authorize/dto/token.dto.ts +24 -2
  521. package/src/authorize/oauth-exception.filter.ts +58 -0
  522. package/src/authorize/oauth-metadata.service.ts +67 -0
  523. package/src/authorize/well-known.controller.spec.ts +84 -0
  524. package/src/authorize/well-known.controller.ts +96 -0
  525. package/src/captcha/captcha.service.spec.ts +211 -4
  526. package/src/captcha/captcha.service.ts +127 -10
  527. package/src/core.module.ts +6 -0
  528. package/src/dashboard/dashboard-component-role/dashboard-component-role.service.ts +2 -3
  529. package/src/dashboard/dashboard-component-role/dashboard-component-role.sort.ts +18 -0
  530. package/src/dashboard/dashboard-item/dashboard-item.service.ts +2 -3
  531. package/src/dashboard/dashboard-item/dashboard-item.sort.ts +19 -0
  532. package/src/dashboard/dashboard-role/dashboard-role.service.ts +2 -3
  533. package/src/dashboard/dashboard-role/dashboard-role.sort.ts +16 -0
  534. package/src/file/file-upload-ticket.service.spec.ts +422 -0
  535. package/src/file/file-upload-ticket.service.ts +513 -0
  536. package/src/file/file.controller.ts +65 -0
  537. package/src/file/file.module.ts +14 -2
  538. package/src/file/file.service.spec.ts +94 -0
  539. package/src/file/file.service.ts +433 -53
  540. package/src/file/filename-encoding.util.spec.ts +54 -0
  541. package/src/file/filename-encoding.util.ts +67 -0
  542. package/src/file/image-optimization.service.spec.ts +156 -19
  543. package/src/file/image-optimization.service.ts +106 -21
  544. package/src/file/mcp-file-source.schema.ts +83 -0
  545. package/src/file/mcp-file-source.service.spec.ts +473 -0
  546. package/src/file/mcp-file-source.service.ts +445 -0
  547. package/src/file/mimetype-sniff.util.spec.ts +126 -0
  548. package/src/file/mimetype-sniff.util.ts +265 -0
  549. package/src/file/remote-fetch.util.spec.ts +117 -0
  550. package/src/file/remote-fetch.util.ts +330 -0
  551. package/src/impersonation/dto/start-impersonation.dto.ts +5 -2
  552. package/src/impersonation/impersonation.service.spec.ts +24 -1
  553. package/src/impersonation/impersonation.service.ts +14 -4
  554. package/src/incident/incident.controller.ts +9 -1
  555. package/src/incident/incident.service.ts +7 -0
  556. package/src/index.ts +17 -0
  557. package/src/integration-profile/integration-profile.secrets.ts +7 -0
  558. package/src/integration-profile/integration-profile.service.ts +7 -64
  559. package/src/integration-profile/integration-profile.utils.spec.ts +9 -0
  560. package/src/integration-profile/integration-profile.utils.ts +5 -5
  561. package/src/integration-profile/testers/index.ts +2 -0
  562. package/src/integration-profile/testers/remaining.testers.spec.ts +79 -0
  563. package/src/integration-profile/testers/shipping.testers.ts +94 -0
  564. package/src/mail/dto/send.dto.ts +6 -1
  565. package/src/mail/mail-template.spec.ts +58 -1
  566. package/src/mail/mail.service.spec.ts +112 -0
  567. package/src/mail/mail.service.ts +42 -4
  568. package/src/mail-sent/mail-sent.service.ts +3 -0
  569. package/src/mail-sent/mail-sent.sort.ts +19 -0
  570. package/src/mcp/filters/mcp-challenge.filter.spec.ts +76 -0
  571. package/src/mcp/filters/mcp-challenge.filter.ts +70 -0
  572. package/src/mcp/guards/mcp-auth.guard.spec.ts +51 -2
  573. package/src/mcp/guards/mcp-auth.guard.ts +24 -1
  574. package/src/mcp/guards/mcp-permission.guard.spec.ts +109 -15
  575. package/src/mcp/guards/mcp-permission.guard.ts +76 -51
  576. package/src/mcp/mcp-audit.service.spec.ts +107 -0
  577. package/src/mcp/mcp-audit.service.ts +37 -1
  578. package/src/mcp/mcp-permission.service.spec.ts +197 -0
  579. package/src/mcp/mcp-permission.service.ts +184 -0
  580. package/src/mcp/mcp-server.service.spec.ts +84 -2
  581. package/src/mcp/mcp-server.service.ts +111 -87
  582. package/src/mcp/mcp.controller.ts +8 -1
  583. package/src/mcp/mcp.module.ts +5 -1
  584. package/src/mcp/tools/core-ai.mcp-tools.ts +1 -1
  585. package/src/mcp/tools/core-dashboard-items.mcp-tools.ts +1 -1
  586. package/src/mcp/tools/core-dashboard.mcp-tools.ts +1 -1
  587. package/src/mcp/tools/core-event-webhooks.mcp-tools.ts +1 -2
  588. package/src/mcp/tools/core-files.mcp-tools.ts +202 -22
  589. package/src/mcp/tools/core-integration-events.mcp-tools.ts +1 -1
  590. package/src/mcp/tools/core-mail-sent.mcp-tools.ts +1 -1
  591. package/src/mcp/tools/core-mail.mcp-tools.ts +1 -1
  592. package/src/mcp/tools/core-menus.mcp-tools.ts +1 -2
  593. package/src/mcp/tools/core-notifications.mcp-tools.ts +0 -1
  594. package/src/mcp/tools/core-roles.mcp-tools.ts +1 -5
  595. package/src/mcp/tools/core-routes.mcp-tools.ts +1 -3
  596. package/src/mcp/tools/core-screens.mcp-tools.ts +1 -3
  597. package/src/mcp/tools/core-sessions.mcp-tools.ts +0 -2
  598. package/src/mcp/tools/core-settings.mcp-tools.ts +1 -2
  599. package/src/mcp/tools/core-users.mcp-tools.ts +1 -1
  600. package/src/mcp/tools/core-webhooks.mcp-tools.ts +1 -2
  601. package/src/mcp/types/mcp-context.type.ts +15 -6
  602. package/src/mcp-chat/mcp-chat.service.ts +8 -0
  603. package/src/meeting/meeting-provider.registry.ts +121 -0
  604. package/src/meeting/meeting.constants.ts +74 -0
  605. package/src/menu/menu.service.spec.ts +89 -0
  606. package/src/menu/menu.service.ts +29 -11
  607. package/src/message-template/dto/update-message-template.dto.ts +22 -0
  608. package/src/message-template/message-template-admin.service.spec.ts +163 -0
  609. package/src/message-template/message-template-admin.service.ts +239 -0
  610. package/src/message-template/message-template.controller.ts +52 -0
  611. package/src/message-template/message-template.module.ts +21 -0
  612. package/src/message-template/message-template.registry.spec.ts +62 -0
  613. package/src/message-template/message-template.registry.ts +125 -0
  614. package/src/message-template/message-template.service.spec.ts +149 -0
  615. package/src/message-template/message-template.service.ts +149 -0
  616. package/src/notification/notification.constants.ts +10 -0
  617. package/src/notification/notification.module.ts +3 -0
  618. package/src/notification/notification.service.spec.ts +75 -1
  619. package/src/notification/notification.service.ts +39 -1
  620. package/src/oauth/oauth.controller.ts +0 -1
  621. package/src/oauth/oauth.errors.ts +7 -0
  622. package/src/oauth/oauth.module.ts +6 -1
  623. package/src/oauth/oauth.service.spec.ts +58 -7
  624. package/src/oauth/oauth.service.ts +71 -32
  625. package/src/oauth/providers/abstract.provider.spec.ts +192 -0
  626. package/src/oauth/providers/abstract.provider.ts +46 -14
  627. package/src/oauth/providers/github.provider.ts +57 -34
  628. package/src/oauth/providers/microsoft-entra-id.provider.ts +8 -1
  629. package/src/observability/monitored-cron.spec.ts +164 -31
  630. package/src/observability/monitored-cron.ts +154 -62
  631. package/src/profile/dto/change-password.dto.ts +25 -7
  632. package/src/profile/profile.service.spec.ts +97 -0
  633. package/src/profile/profile.service.ts +9 -3
  634. package/src/realtime/realtime-tick.coalescer.spec.ts +92 -0
  635. package/src/realtime/realtime-tick.coalescer.ts +60 -0
  636. package/src/realtime/realtime.service.spec.ts +33 -0
  637. package/src/realtime/realtime.service.ts +28 -2
  638. package/src/redis/redis-kv.service.ts +261 -0
  639. package/src/redis/redis-master.spec.ts +111 -0
  640. package/src/redis/redis-master.ts +86 -0
  641. package/src/redis/redis-pubsub.ts +27 -3
  642. package/src/redis/redis.module.ts +17 -0
  643. package/src/session/session.service.spec.ts +121 -42
  644. package/src/session/session.service.ts +279 -82
  645. package/src/setting/setting.service.ts +44 -3
  646. package/src/task/task.service.spec.ts +41 -0
  647. package/src/task/task.service.ts +53 -13
  648. package/src/token/token.service.spec.ts +90 -0
  649. package/src/token/token.service.ts +48 -2
  650. package/src/user/user-credential.util.ts +14 -5
  651. package/src/user/user.service.ts +2 -12
  652. package/src/user/user.sort.ts +25 -0
  653. package/src/utils/abbreviate-name.spec.ts +50 -0
  654. package/src/utils/abbreviate-name.ts +44 -0
  655. package/src/utils/date-range-query.dto.ts +56 -0
  656. package/src/utils/date-range.spec.ts +175 -0
  657. package/src/utils/date-range.ts +246 -0
  658. package/src/webhook-integration/webhook-utils.spec.ts +67 -0
  659. package/src/webhook-integration/webhook-utils.ts +26 -0
  660. package/src/whatsapp-sender/whatsapp-recipients.spec.ts +89 -0
  661. package/src/whatsapp-sender/whatsapp-recipients.ts +83 -0
  662. package/src/whatsapp-sender/whatsapp-sender.service.spec.ts +112 -0
  663. package/src/whatsapp-sender/whatsapp-sender.service.ts +58 -5
  664. package/hedhog/query/device_pairing_request.sql +0 -46
  665. package/hedhog/query/impersonation_grant.sql +0 -71
  666. package/hedhog/query/oauth_authorize_pkce.sql +0 -58
  667. package/hedhog/query/oauth_mobile_state_token.sql +0 -30
  668. package/hedhog/query/oauth_web_ref_token.sql +0 -25
@@ -18,11 +18,25 @@ var __asyncValues = (this && this.__asyncValues) || function (o) {
18
18
  function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
19
19
  function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
20
20
  };
21
+ var __await = (this && this.__await) || function (v) { return this instanceof __await ? (this.v = v, this) : new __await(v); }
22
+ var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) {
23
+ if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
24
+ var g = generator.apply(thisArg, _arguments || []), i, q = [];
25
+ return i = Object.create((typeof AsyncIterator === "function" ? AsyncIterator : Object).prototype), verb("next"), verb("throw"), verb("return", awaitReturn), i[Symbol.asyncIterator] = function () { return this; }, i;
26
+ function awaitReturn(f) { return function (v) { return Promise.resolve(v).then(f, reject); }; }
27
+ function verb(n, f) { if (g[n]) { i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; if (f) i[n] = f(i[n]); } }
28
+ function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }
29
+ function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }
30
+ function fulfill(value) { resume("next", value); }
31
+ function reject(value) { resume("throw", value); }
32
+ function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }
33
+ };
21
34
  var _a;
22
35
  var FileService_1;
23
36
  Object.defineProperty(exports, "__esModule", { value: true });
24
37
  exports.FileService = void 0;
25
38
  const client_s3_1 = require("@aws-sdk/client-s3");
39
+ const s3_request_presigner_1 = require("@aws-sdk/s3-request-presigner");
26
40
  const client_lambda_1 = require("@aws-sdk/client-lambda");
27
41
  const client_sts_1 = require("@aws-sdk/client-sts");
28
42
  const api_locale_1 = require("@hed-hog/api-locale");
@@ -30,6 +44,7 @@ const api_pagination_1 = require("@hed-hog/api-pagination");
30
44
  const api_prisma_1 = require("@hed-hog/api-prisma");
31
45
  const common_1 = require("@nestjs/common");
32
46
  const jwt_1 = require("@nestjs/jwt");
47
+ const crypto_1 = require("crypto");
33
48
  const fs_1 = require("fs");
34
49
  const os_1 = require("os");
35
50
  const path_1 = require("path");
@@ -37,6 +52,8 @@ const promises_1 = require("stream/promises");
37
52
  const uuid_1 = require("uuid");
38
53
  const integration_profile_utils_1 = require("../integration-profile/integration-profile.utils");
39
54
  const setting_service_1 = require("../setting/setting.service");
55
+ const filename_encoding_util_1 = require("./filename-encoding.util");
56
+ const mimetype_sniff_util_1 = require("./mimetype-sniff.util");
40
57
  const image_optimization_service_1 = require("./image-optimization.service");
41
58
  const abstract_provider_1 = require("./provider/abstract.provider");
42
59
  const provider_factory_1 = require("./provider/provider.factory");
@@ -56,18 +73,13 @@ let FileService = FileService_1 = class FileService {
56
73
  }
57
74
  return `${file.location}/${file.path}`;
58
75
  }
59
- hasMojibake(value) {
60
- return /Ã.|Â.|â[\u0080-\u00BF]/.test(value);
61
- }
76
+ /**
77
+ * Nome que chegou com o encoding trocado (busboy entrega `originalname` em
78
+ * latin1, e a base ainda recebe nome importado com o mesmo defeito). A lógica
79
+ * mora no util porque a migration de backfill a reproduz em plpgsql.
80
+ */
62
81
  normalizeUploadedFilename(filename) {
63
- if (!filename) {
64
- return filename;
65
- }
66
- if (!this.hasMojibake(filename)) {
67
- return filename;
68
- }
69
- const decoded = Buffer.from(filename, 'latin1').toString('utf8');
70
- return this.hasMojibake(decoded) ? filename : decoded;
82
+ return filename ? (0, filename_encoding_util_1.fixMojibake)(filename) : filename;
71
83
  }
72
84
  constructor(prismaService, paginationService, settingService, jwtService, imageOptimizationService) {
73
85
  this.prismaService = prismaService;
@@ -79,6 +91,8 @@ let FileService = FileService_1 = class FileService {
79
91
  this.mimetypes = {};
80
92
  this.cachedProvider = null;
81
93
  this.providerResolution = null;
94
+ /** Cache curto de papéis, no mesmo espírito do McpPermissionService. */
95
+ this.fileAdminCache = new Map();
82
96
  }
83
97
  async onModuleInit() {
84
98
  try {
@@ -397,7 +411,7 @@ let FileService = FileService_1 = class FileService {
397
411
  // repassa este argumento, então não há como acioná-lo por HTTP.
398
412
  // `isPrivate` tira o arquivo das rotas que servem por id sem autenticação.
399
413
  options) {
400
- var _a;
414
+ var _a, _b;
401
415
  if (!fileBuffer) {
402
416
  throw new common_1.BadRequestException(`No file provided`);
403
417
  }
@@ -426,12 +440,13 @@ let FileService = FileService_1 = class FileService {
426
440
  mimetype_id: await this.getMimeType(optimized.mimetype),
427
441
  size: optimized.buffer.length,
428
442
  is_private: (_a = options === null || options === void 0 ? void 0 : options.isPrivate) !== null && _a !== void 0 ? _a : false,
443
+ created_by_user_id: (_b = options === null || options === void 0 ? void 0 : options.createdByUserId) !== null && _b !== void 0 ? _b : null,
429
444
  },
430
445
  });
431
446
  return file;
432
447
  }
433
448
  async uploadFromPath(destination, filePath, metadata) {
434
- var _a, _b, _c, _d, _e, _f, _g, _h;
449
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
435
450
  if (!filePath) {
436
451
  throw new common_1.BadRequestException(`No file path provided`);
437
452
  }
@@ -446,7 +461,14 @@ let FileService = FileService_1 = class FileService {
446
461
  const originalname = this.normalizeUploadedFilename((_c = (_b = metadata === null || metadata === void 0 ? void 0 : metadata.originalname) !== null && _b !== void 0 ? _b : metadata === null || metadata === void 0 ? void 0 : metadata.filename) !== null && _c !== void 0 ? _c : (0, path_1.basename)(filePath));
447
462
  // Recupera o tipo real quando o caller não informou o mimetype (default antigo era
448
463
  // application/octet-stream, que fazia imagens caírem fora da otimização e do serve).
449
- const mimetype = await this.resolveEffectiveMimetype(metadata === null || metadata === void 0 ? void 0 : metadata.mimetype, originalname);
464
+ // Diferente de `upload`, aqui só existe um caminho no disco — e ler o arquivo inteiro
465
+ // é justamente o que o branch de streaming abaixo evita para SCORM/vídeo de vários GB.
466
+ // Por isso o sniffing recebe só o cabeçalho, e apenas quando o caller não declarou um
467
+ // tipo concreto: sem isso, uma imagem enviada como application/octet-stream sem
468
+ // extensão no nome escapava da otimização e era gravada byte a byte.
469
+ const declaredMimetype = metadata === null || metadata === void 0 ? void 0 : metadata.mimetype;
470
+ const isGenericMimetype = !declaredMimetype || declaredMimetype === 'application/octet-stream';
471
+ const mimetype = await this.resolveEffectiveMimetype(declaredMimetype, originalname, isGenericMimetype ? await this.readFileHeader(filePath) : undefined);
450
472
  if (!(metadata === null || metadata === void 0 ? void 0 : metadata.skipMimeValidation) && !(await this.acceptMimetypes(mimetype))) {
451
473
  throw new common_1.BadRequestException(`Invalid file type: ${mimetype}`);
452
474
  }
@@ -473,19 +495,20 @@ let FileService = FileService_1 = class FileService {
473
495
  mimetype_id: await this.getMimeType(mimetype),
474
496
  size,
475
497
  is_private: (_d = metadata === null || metadata === void 0 ? void 0 : metadata.isPrivate) !== null && _d !== void 0 ? _d : false,
498
+ created_by_user_id: (_e = metadata === null || metadata === void 0 ? void 0 : metadata.createdByUserId) !== null && _e !== void 0 ? _e : null,
476
499
  },
477
500
  });
478
501
  }
479
502
  // Read buffer to allow image optimization regardless of provider support
480
503
  const rawBuffer = await fs_1.promises.readFile(filePath);
481
504
  const optimized = await this.imageOptimizationService.optimizeBuffer(rawBuffer, mimetype, originalname, {
482
- maxWidth: (_e = metadata === null || metadata === void 0 ? void 0 : metadata.resize) === null || _e === void 0 ? void 0 : _e.maxWidth,
483
- maxHeight: (_f = metadata === null || metadata === void 0 ? void 0 : metadata.resize) === null || _f === void 0 ? void 0 : _f.maxHeight,
505
+ maxWidth: (_f = metadata === null || metadata === void 0 ? void 0 : metadata.resize) === null || _f === void 0 ? void 0 : _f.maxWidth,
506
+ maxHeight: (_g = metadata === null || metadata === void 0 ? void 0 : metadata.resize) === null || _g === void 0 ? void 0 : _g.maxHeight,
484
507
  });
485
508
  const url = await provider.upload(destination, {
486
509
  fieldname: 'file',
487
510
  originalname: optimized.originalname,
488
- encoding: (_g = metadata === null || metadata === void 0 ? void 0 : metadata.encoding) !== null && _g !== void 0 ? _g : '7bit',
511
+ encoding: (_h = metadata === null || metadata === void 0 ? void 0 : metadata.encoding) !== null && _h !== void 0 ? _h : '7bit',
489
512
  mimetype: optimized.mimetype,
490
513
  size: optimized.buffer.length,
491
514
  destination: '',
@@ -501,19 +524,68 @@ let FileService = FileService_1 = class FileService {
501
524
  location: destination,
502
525
  mimetype_id: await this.getMimeType(optimized.mimetype),
503
526
  size: optimized.buffer.length,
504
- is_private: (_h = metadata === null || metadata === void 0 ? void 0 : metadata.isPrivate) !== null && _h !== void 0 ? _h : false,
527
+ is_private: (_j = metadata === null || metadata === void 0 ? void 0 : metadata.isPrivate) !== null && _j !== void 0 ? _j : false,
528
+ created_by_user_id: (_k = metadata === null || metadata === void 0 ? void 0 : metadata.createdByUserId) !== null && _k !== void 0 ? _k : null,
505
529
  },
506
530
  });
507
531
  return file;
508
532
  }
533
+ /**
534
+ * Lista as imagens armazenadas que valem uma passada por `reoptimizeFile`, para a
535
+ * operação em massa de reprocessamento do acervo.
536
+ *
537
+ * Devolve junto o total e a soma de bytes do filtro inteiro (não só da página), que é
538
+ * o que permite mostrar uma prévia antes de enfileirar dezenas de milhares de jobs.
539
+ * O core não conhece a fila — quem enfileira é a library `queue`, que depende deste
540
+ * pacote e não o contrário.
541
+ */
542
+ async findOptimizableImages(params) {
543
+ var _a, _b, _c;
544
+ const minSize = Math.max(0, Math.trunc(Number(params === null || params === void 0 ? void 0 : params.minSize) || 0));
545
+ const locations = ((_a = params === null || params === void 0 ? void 0 : params.locations) !== null && _a !== void 0 ? _a : [])
546
+ .map((location) => String(location).trim())
547
+ .filter(Boolean);
548
+ const where = {
549
+ size: { gte: minSize },
550
+ file_mimetype: {
551
+ name: {
552
+ startsWith: 'image/',
553
+ notIn: FileService_1.NON_OPTIMIZABLE_IMAGE_MIMETYPES,
554
+ },
555
+ },
556
+ };
557
+ if (locations.length) {
558
+ where.location = { in: locations };
559
+ }
560
+ const [aggregate, rows] = await Promise.all([
561
+ this.prismaService.file.aggregate({
562
+ where,
563
+ _count: { _all: true },
564
+ _sum: { size: true },
565
+ }),
566
+ this.prismaService.file.findMany({
567
+ where,
568
+ select: { id: true },
569
+ // Ordem estável para que o enfileiramento paginado não pule nem repita linhas.
570
+ orderBy: { id: 'asc' },
571
+ skip: Math.max(0, Math.trunc(Number(params === null || params === void 0 ? void 0 : params.offset) || 0)),
572
+ take: Math.min(5000, Math.max(1, Math.trunc(Number(params === null || params === void 0 ? void 0 : params.limit) || 1000))),
573
+ }),
574
+ ]);
575
+ return {
576
+ ids: rows.map((row) => row.id),
577
+ total: (_b = aggregate._count._all) !== null && _b !== void 0 ? _b : 0,
578
+ totalBytes: Number((_c = aggregate._sum.size) !== null && _c !== void 0 ? _c : 0),
579
+ };
580
+ }
509
581
  /**
510
582
  * Re-applies the current image-optimization settings to an already-stored file,
511
583
  * rewriting it in place: the `file` record keeps the same id, so every row that
512
584
  * references it (course_image, course_lesson_video_frame, ...) stays valid without
513
- * any FK juggling. Only replaces the stored object when the optimized result is
514
- * strictly smaller or the mimetype changed (e.g. PNG → WebP) — this keeps the
515
- * operation idempotent and avoids repeated lossy recompression. Non-image files are
516
- * left untouched.
585
+ * any FK juggling. Only replaces the stored object when the mimetype changed
586
+ * (e.g. PNG → WebP) or the result is smaller by a margin that justifies the rewrite —
587
+ * that margin is what actually makes the operation idempotent and avoids repeated
588
+ * lossy recompression. Non-image files are left untouched.
517
589
  */
518
590
  async reoptimizeFile(fileId) {
519
591
  var _a;
@@ -525,8 +597,13 @@ let FileService = FileService_1 = class FileService {
525
597
  }
526
598
  const optimized = await this.imageOptimizationService.optimizeBuffer(buffer, currentMimetype, file.filename);
527
599
  const mimetypeChanged = optimized.mimetype !== currentMimetype;
528
- const smaller = optimized.buffer.length < oldSize;
529
- if (!mimetypeChanged && !smaller) {
600
+ // Mudança de formato é o ganho principal (PNG → WebP) e vale por si; sem ela, só
601
+ // regrava quando a economia passa do limiar. `optimizeBuffer` já garante que o
602
+ // resultado nunca é maior que a entrada neste caminho (sem crop de alvo exato).
603
+ const worthRewriting = oldSize > 0 &&
604
+ (oldSize - optimized.buffer.length) / oldSize >=
605
+ FileService_1.REOPTIMIZE_MIN_GAIN_RATIO;
606
+ if (!mimetypeChanged && !worthRewriting) {
530
607
  return {
531
608
  changed: false,
532
609
  oldSize,
@@ -602,14 +679,181 @@ let FileService = FileService_1 = class FileService {
602
679
  }
603
680
  return files.map((file) => file.id);
604
681
  }
605
- async getFiles(paginationParams) {
682
+ /**
683
+ * `ownerUserId` restringe a listagem aos arquivos enviados por aquele usuário.
684
+ *
685
+ * Existe para as tools MCP: sem ele, `core.files.list` é um índice de tudo o que
686
+ * qualquer empresa já subiu, incluindo o que está gravado como `is_private`. O
687
+ * controller REST continua chamando sem o parâmetro, porque ali a rota já é `admin`
688
+ * e a tela de arquivos é justamente a visão global.
689
+ */
690
+ /**
691
+ * Grava um stream em disco medindo, hasheando e guardando o cabeçalho de uma vez só.
692
+ *
693
+ * O upload assinado recebe o binário cru no corpo do PUT, e nada garante que venha com
694
+ * `Content-Length` — sem o contador abaixo, um corpo aberto encheria o disco do pod. O
695
+ * corte é feito em pleno voo, antes de o excedente chegar ao arquivo.
696
+ *
697
+ * Passa o cabeçalho adiante porque conferir o tipo real é obrigatório nesse caminho, e
698
+ * reler o arquivo depois seria uma segunda passada por nada.
699
+ */
700
+ async writeStreamToPath(source, targetPath, maxBytes) {
701
+ const hash = (0, crypto_1.createHash)('sha256');
702
+ const headerChunks = [];
703
+ let headerLength = 0;
704
+ let bytes = 0;
705
+ const target = (0, fs_1.createWriteStream)(targetPath);
706
+ await (0, promises_1.pipeline)(source, function (chunks) {
707
+ return __asyncGenerator(this, arguments, function* () {
708
+ var _a, e_1, _b, _c;
709
+ try {
710
+ for (var _d = true, chunks_1 = __asyncValues(chunks), chunks_1_1; chunks_1_1 = yield __await(chunks_1.next()), _a = chunks_1_1.done, !_a; _d = true) {
711
+ _c = chunks_1_1.value;
712
+ _d = false;
713
+ const chunk = _c;
714
+ const buffer = Buffer.from(chunk);
715
+ bytes += buffer.length;
716
+ if (bytes > maxBytes) {
717
+ throw new common_1.BadRequestException(`Upload exceeds the declared size of ${maxBytes} bytes`);
718
+ }
719
+ hash.update(buffer);
720
+ if (headerLength < mimetype_sniff_util_1.MIMETYPE_SNIFF_BYTES) {
721
+ const slice = buffer.subarray(0, mimetype_sniff_util_1.MIMETYPE_SNIFF_BYTES - headerLength);
722
+ headerChunks.push(slice);
723
+ headerLength += slice.length;
724
+ }
725
+ yield yield __await(buffer);
726
+ }
727
+ }
728
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
729
+ finally {
730
+ try {
731
+ if (!_d && !_a && (_b = chunks_1.return)) yield __await(_b.call(chunks_1));
732
+ }
733
+ finally { if (e_1) throw e_1.error; }
734
+ }
735
+ });
736
+ }, target);
737
+ return {
738
+ bytes,
739
+ sha256: hash.digest('hex'),
740
+ header: Buffer.concat(headerChunks),
741
+ };
742
+ }
743
+ /**
744
+ * Conteúdo de um arquivo já armazenado, em memória.
745
+ *
746
+ * Existe para as tools que consomem os bytes sem persistir nada (importar extrato,
747
+ * extrair dados de uma nota com IA): elas recebem um `fileId` e precisam do arquivo,
748
+ * não de um stream. O teto evita que um `fileId` apontando para um SCORM de vários GB
749
+ * derrube o pod — quem serve arquivo grande usa `openReadStream` e não passa por aqui.
750
+ */
751
+ async bufferById(fileId, maxBytes) {
752
+ var _a, e_2, _b, _c;
753
+ var _d, _e;
754
+ const { stream } = await this.openReadStreamById(fileId);
755
+ const chunks = [];
756
+ let total = 0;
757
+ try {
758
+ for (var _f = true, _g = __asyncValues(stream), _h; _h = await _g.next(), _a = _h.done, !_a; _f = true) {
759
+ _c = _h.value;
760
+ _f = false;
761
+ const chunk = _c;
762
+ total += chunk.length;
763
+ if (total > maxBytes) {
764
+ (_e = (_d = stream).destroy) === null || _e === void 0 ? void 0 : _e.call(_d);
765
+ throw new common_1.BadRequestException(`File ${fileId} is larger than the ${maxBytes} bytes this operation can load`);
766
+ }
767
+ chunks.push(Buffer.from(chunk));
768
+ }
769
+ }
770
+ catch (e_2_1) { e_2 = { error: e_2_1 }; }
771
+ finally {
772
+ try {
773
+ if (!_f && !_a && (_b = _g.return)) await _b.call(_g);
774
+ }
775
+ finally { if (e_2) throw e_2.error; }
776
+ }
777
+ return Buffer.concat(chunks);
778
+ }
779
+ /**
780
+ * Nome do mimetype de um arquivo.
781
+ *
782
+ * `get()` e `upload()` devolvem a linha crua, sem a relação, e cada chamador que
783
+ * precisava do tipo vinha refazendo o `include` por conta. Como o cache de
784
+ * `getMimeType` é id-por-nome, este é o inverso dele e sai do mesmo mapa quando já
785
+ * tiver sido consultado.
786
+ */
787
+ async mimetypeNameById(mimetypeId) {
788
+ const cached = Object.entries(this.mimetypes).find(([, id]) => id === mimetypeId);
789
+ if (cached) {
790
+ return cached[0];
791
+ }
792
+ const row = await this.prismaService.file_mimetype.findUnique({
793
+ where: { id: mimetypeId },
794
+ select: { name: true },
795
+ });
796
+ if (row === null || row === void 0 ? void 0 : row.name) {
797
+ this.mimetypes[row.name] = mimetypeId;
798
+ return row.name;
799
+ }
800
+ return 'application/octet-stream';
801
+ }
802
+ async getFiles(paginationParams, ownerUserId) {
606
803
  const fields = ['filename', 'path'];
607
804
  const OR = this.prismaService.createInsensitiveSearch(fields, paginationParams);
608
805
  return this.paginationService.paginate(this.prismaService.file, paginationParams, {
806
+ where: Object.assign({ OR }, (ownerUserId ? { created_by_user_id: ownerUserId } : {})),
807
+ });
808
+ }
809
+ async isFileAdmin(userId) {
810
+ const cached = this.fileAdminCache.get(userId);
811
+ if (cached && Date.now() - cached.at < FileService_1.FILE_ADMIN_CACHE_TTL_MS) {
812
+ return cached.value;
813
+ }
814
+ const found = await this.prismaService.role_user.findFirst({
609
815
  where: {
610
- OR,
816
+ user_id: userId,
817
+ role: { slug: { in: FileService_1.FILE_ADMIN_ROLES } },
611
818
  },
819
+ select: { role_id: true },
820
+ });
821
+ const value = Boolean(found);
822
+ this.fileAdminCache.set(userId, { value, at: Date.now() });
823
+ return value;
824
+ }
825
+ /**
826
+ * Porteiro do `fileId` vindo de fora: só o dono usa um arquivo, e quem administra o
827
+ * acervo usa qualquer um.
828
+ *
829
+ * Sem isto, apontar um `fileId` numa tool seria enumerar — id de arquivo é sequencial,
830
+ * exatamente o motivo pelo qual `is_private` existe. Arquivo anterior a esta coluna
831
+ * (ou gravado por cron/seed/webhook) fica com dono nulo e só o admin alcança: não dá
832
+ * para provar de quem ele é, e adivinhar a favor do chamador seria abrir a porta que
833
+ * este método fecha.
834
+ */
835
+ async assertFileUsable(fileId, userId) {
836
+ if (!Number.isInteger(fileId) || fileId <= 0) {
837
+ throw new common_1.BadRequestException(`Invalid file id: ${fileId}`);
838
+ }
839
+ const file = await this.prismaService.file.findUnique({
840
+ where: { id: fileId },
841
+ include: { file_mimetype: true },
612
842
  });
843
+ // Mesma resposta para inexistente e para alheio seria o ideal contra enumeração, mas
844
+ // `get()` já responde 404 com o id, e divergir aqui só confundiria quem integra.
845
+ if (!file) {
846
+ throw new common_1.NotFoundException(`File not found: ${fileId}`);
847
+ }
848
+ if (file.created_by_user_id === userId) {
849
+ return file;
850
+ }
851
+ if (await this.isFileAdmin(userId)) {
852
+ return file;
853
+ }
854
+ throw new common_1.ForbiddenException(file.created_by_user_id === null
855
+ ? `File ${fileId} has no recorded owner and can only be used by an administrator`
856
+ : `File ${fileId} belongs to another user`);
613
857
  }
614
858
  async get(fileId) {
615
859
  const file = await this.prismaService.file.findUnique({
@@ -743,19 +987,44 @@ let FileService = FileService_1 = class FileService {
743
987
  }
744
988
  return undefined;
745
989
  }
990
+ /**
991
+ * Resolve o `file` cujo `resolveProviderPath` (location + path, ou path já combinado) bate com
992
+ * o `filepath` embutido no token de download — é o inverso de `resolveProviderPath`.
993
+ *
994
+ * Bug corrigido (relatado como "Token de download inválido ou expirado" no storage local):
995
+ * `tempURLById` assina o token com `resolveProviderPath(file)` (ex.:
996
+ * "class-assignment-tasks/abc123.pdf", já com o prefixo de `location`), mas o upload local/S3
997
+ * grava só o basename em `file.path` ("abc123.pdf") e o `location` separado em outra coluna.
998
+ * Um `findFirst({ where: { path: filepath } })` direto nunca batia para esses arquivos — sempre
999
+ * caía no `catch` abaixo e mostrava a mensagem genérica de token inválido, mesmo com o token
1000
+ * (e o arquivo) perfeitamente válidos. S3 mascarava isso porque `S3Provider.tempURL` devolve uma
1001
+ * URL assinada direto do bucket, sem passar por este método.
1002
+ */
1003
+ async findFileByResolvedPath(filepath) {
1004
+ const bySameValue = await this.prismaService.file.findFirst({
1005
+ where: { path: filepath },
1006
+ include: { file_mimetype: true },
1007
+ });
1008
+ if (bySameValue)
1009
+ return bySameValue;
1010
+ const slashIndex = filepath.lastIndexOf('/');
1011
+ if (slashIndex === -1)
1012
+ return null;
1013
+ return this.prismaService.file.findFirst({
1014
+ where: {
1015
+ location: filepath.slice(0, slashIndex),
1016
+ path: filepath.slice(slashIndex + 1),
1017
+ },
1018
+ include: { file_mimetype: true },
1019
+ });
1020
+ }
746
1021
  async download(locale, token) {
747
1022
  var _a;
748
1023
  try {
749
1024
  const { filepath } = this.jwtService.verify(token, {
750
1025
  secret: process.env.JWT_SECRET,
751
1026
  });
752
- // Buscar o arquivo no banco para pegar nome original e mimetype
753
- const file = await this.prismaService.file.findFirst({
754
- where: { path: filepath },
755
- include: {
756
- file_mimetype: true,
757
- },
758
- });
1027
+ const file = await this.findFileByResolvedPath(filepath);
759
1028
  if (!file) {
760
1029
  throw new common_1.NotFoundException((0, api_locale_1.getLocaleText)('file.download.not_found', locale, `Not found: ${filepath}`));
761
1030
  }
@@ -879,6 +1148,28 @@ let FileService = FileService_1 = class FileService {
879
1148
  };
880
1149
  return (_a = map[ext]) !== null && _a !== void 0 ? _a : null;
881
1150
  }
1151
+ /**
1152
+ * Lê só o começo do arquivo, o bastante para o sharp reconhecer o formato pelo
1153
+ * cabeçalho. Existe para o sniffing de `uploadFromPath`, que não pode chamar
1154
+ * `fs.readFile`: o mesmo caminho recebe pacotes SCORM e vídeos de vários GB, e
1155
+ * carregá-los inteiros estoura o limite de Buffer. Devolve `undefined` em qualquer
1156
+ * falha de leitura — quem chama já trata a ausência do buffer.
1157
+ */
1158
+ async readFileHeader(filePath, bytes = 64 * 1024) {
1159
+ let handle;
1160
+ try {
1161
+ handle = await fs_1.promises.open(filePath, 'r');
1162
+ const buffer = Buffer.alloc(bytes);
1163
+ const { bytesRead } = await handle.read(buffer, 0, bytes, 0);
1164
+ return bytesRead > 0 ? buffer.subarray(0, bytesRead) : undefined;
1165
+ }
1166
+ catch (_a) {
1167
+ return undefined;
1168
+ }
1169
+ finally {
1170
+ await (handle === null || handle === void 0 ? void 0 : handle.close().catch(() => undefined));
1171
+ }
1172
+ }
882
1173
  /**
883
1174
  * Resolves the MIME type to persist for an upload. When the incoming mimetype is
884
1175
  * generic (application/octet-stream or empty), recovers the real image type from
@@ -886,25 +1177,8 @@ let FileService = FileService_1 = class FileService {
886
1177
  * Concrete non-image types (video, pdf, ...) are returned unchanged.
887
1178
  */
888
1179
  async resolveEffectiveMimetype(mimetype, name, buffer) {
889
- if (mimetype && mimetype.startsWith('image/')) {
890
- // O mimetype que chega do navegador vem da EXTENSÃO do arquivo, não do
891
- // conteúdo: um PNG renomeado para `.svg` é anunciado como `image/svg+xml`.
892
- // Gravar isso faz o endpoint de imagem servir bytes PNG sob Content-Type
893
- // de SVG e, com o `nosniff` que a API envia, o navegador não corrige
894
- // sozinho — a imagem simplesmente não renderiza, sem erro nenhum.
895
- // Com os bytes em mãos, quem decide é a assinatura do arquivo.
896
- if (buffer) {
897
- const sniffed = await this.imageOptimizationService.detectImageMimetype(buffer);
898
- // Só sobrepõe quando o sniffing reconheceu o formato: um `null` significa
899
- // que o sharp não entendeu o buffer, e aí o declarado ainda é o melhor
900
- // palpite disponível.
901
- if (sniffed && sniffed !== mimetype) {
902
- this.logger.warn(`Upload "${name}" foi anunciado como ${mimetype}, mas os bytes são ${sniffed}. Persistindo o tipo real.`);
903
- return sniffed;
904
- }
905
- }
1180
+ if (mimetype && mimetype.startsWith('image/'))
906
1181
  return mimetype;
907
- }
908
1182
  // Tipos concretos não-imagem (video, pdf, ...) são mantidos como estão.
909
1183
  if (mimetype && mimetype !== 'application/octet-stream')
910
1184
  return mimetype;
@@ -1017,7 +1291,7 @@ let FileService = FileService_1 = class FileService {
1017
1291
  * which the storage layer does not normally do — cannot serve stale bytes.
1018
1292
  */
1019
1293
  async renderImageVariant(provider, providerPath, contentType, id, size, variant) {
1020
- var _a, e_1, _b, _c;
1294
+ var _a, e_3, _b, _c;
1021
1295
  var _d;
1022
1296
  const format = (_d = variant.format) !== null && _d !== void 0 ? _d : (contentType === 'image/png'
1023
1297
  ? 'png'
@@ -1045,12 +1319,12 @@ let FileService = FileService_1 = class FileService {
1045
1319
  chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
1046
1320
  }
1047
1321
  }
1048
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
1322
+ catch (e_3_1) { e_3 = { error: e_3_1 }; }
1049
1323
  finally {
1050
1324
  try {
1051
1325
  if (!_f && !_a && (_b = stream_1.return)) await _b.call(stream_1);
1052
1326
  }
1053
- finally { if (e_1) throw e_1.error; }
1327
+ finally { if (e_3) throw e_3.error; }
1054
1328
  }
1055
1329
  const original = Buffer.concat(chunks);
1056
1330
  const rendered = await this.imageOptimizationService.resizeBuffer(original, contentType, { width: variant.width, format: variant.format, quality: variant.quality });
@@ -1113,6 +1387,14 @@ let FileService = FileService_1 = class FileService {
1113
1387
  }
1114
1388
  return url;
1115
1389
  }
1390
+ /** Par de `tempURLById`, pela mesma razão: `path` cru resolve para NoSuchKey no S3. */
1391
+ async tempOpenURLById(fileId, expires = 3600) {
1392
+ const url = await this.tempURLById(fileId, expires);
1393
+ if (typeof url === 'string') {
1394
+ return url.replace('/file/download/', '/file/open/');
1395
+ }
1396
+ return url;
1397
+ }
1116
1398
  async getTemporaryCredentials(params) {
1117
1399
  const stsClient = new client_sts_1.STSClient({
1118
1400
  region: params.region,
@@ -1148,6 +1430,30 @@ let FileService = FileService_1 = class FileService {
1148
1430
  ETag: result.ETag,
1149
1431
  };
1150
1432
  }
1433
+ /**
1434
+ * URL assinada de um objeto em bucket avulso.
1435
+ *
1436
+ * O `getFileUrl` do provider resolve arquivos do acervo, que vivem no destino
1437
+ * ativo do core. Este metodo serve para os buckets que outras libraries
1438
+ * configuram por conta propria — o Studio grava no perfil de armazenamento
1439
+ * dele, que pode nao ser o mesmo — e por isso recebe as credenciais e o bucket
1440
+ * de fora, como o `headS3Object` ao lado.
1441
+ */
1442
+ async signS3Object(params) {
1443
+ var _a;
1444
+ const s3 = new client_s3_1.S3Client({
1445
+ region: params.region,
1446
+ credentials: Object.assign({ accessKeyId: params.accessKeyId, secretAccessKey: params.secretAccessKey }, (params.sessionToken ? { sessionToken: params.sessionToken } : {})),
1447
+ });
1448
+ const command = new client_s3_1.GetObjectCommand(Object.assign({ Bucket: params.bucket, Key: params.key }, (params.downloadFileName
1449
+ ? {
1450
+ ResponseContentDisposition: `attachment; filename="${params.downloadFileName.replace(/"/g, '')}"`,
1451
+ }
1452
+ : {})));
1453
+ return (0, s3_request_presigner_1.getSignedUrl)(s3, command, {
1454
+ expiresIn: (_a = params.expiresInSeconds) !== null && _a !== void 0 ? _a : 900,
1455
+ });
1456
+ }
1151
1457
  async headS3Bucket(params) {
1152
1458
  const s3 = new client_s3_1.S3Client({
1153
1459
  region: params.region,
@@ -1399,6 +1705,32 @@ let FileService = FileService_1 = class FileService {
1399
1705
  }
1400
1706
  };
1401
1707
  exports.FileService = FileService;
1708
+ /**
1709
+ * Mimetypes de imagem que `optimizeBuffer` devolve intactos por decisão de projeto
1710
+ * (vetor não vira bitmap, GIF animado não vira quadro único). Enfileirá-los para
1711
+ * reotimização seria custo de download e reprocessamento com resultado garantidamente
1712
+ * nulo, então ficam fora da varredura.
1713
+ */
1714
+ FileService.NON_OPTIMIZABLE_IMAGE_MIMETYPES = [
1715
+ 'image/svg+xml',
1716
+ 'image/gif',
1717
+ ];
1718
+ /**
1719
+ * Ganho mínimo para valer a regravação de um arquivo que já está no formato final.
1720
+ *
1721
+ * Recomprimir WebP sobre WebP sempre devolve alguns bytes a menos, então um limiar de
1722
+ * "estritamente menor" nunca converge: cada passada da varredura trocaria o arquivo
1723
+ * por um ganho irrisório e mais uma geração de perda de qualidade. Medido aqui, três
1724
+ * passadas seguidas rendiam 10926 → 10664 → 10662 bytes — a última custou uma
1725
+ * recompressão inteira para economizar 2 bytes.
1726
+ */
1727
+ FileService.REOPTIMIZE_MIN_GAIN_RATIO = 0.1;
1728
+ /**
1729
+ * Papéis que enxergam qualquer arquivo. Os mesmos que já governam as rotas de arquivo
1730
+ * em `route.yaml` — quem administra o acervo pela tela também o administra pelo MCP.
1731
+ */
1732
+ FileService.FILE_ADMIN_ROLES = ['admin', 'admin-access'];
1733
+ FileService.FILE_ADMIN_CACHE_TTL_MS = 30000;
1402
1734
  exports.FileService = FileService = FileService_1 = __decorate([
1403
1735
  (0, common_1.Injectable)(),
1404
1736
  __param(0, (0, common_1.Inject)((0, common_1.forwardRef)(() => api_prisma_1.PrismaService))),