@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
@@ -7,10 +7,15 @@ import {
7
7
  Inject,
8
8
  Injectable,
9
9
  Logger,
10
+ UnauthorizedException,
10
11
  forwardRef,
11
12
  } from '@nestjs/common';
12
13
  import { timingSafeEqual } from 'crypto';
13
14
  import { AuthService } from '../auth/auth.service';
15
+ import { SessionService } from '../session/session.service';
16
+ import { TokenService } from '../token/token.service';
17
+ import { OAuthError } from './authorize.errors';
18
+ import { MCP_SCOPE, OAuthMetadataService } from './oauth-metadata.service';
14
19
  import { SecurityService } from '../security/security.service';
15
20
 
16
21
  /**
@@ -38,15 +43,26 @@ export class AuthorizeService {
38
43
  private readonly security: SecurityService,
39
44
  @Inject(forwardRef(() => AuthService))
40
45
  private readonly auth: AuthService,
46
+ @Inject(forwardRef(() => SessionService))
47
+ private readonly session: SessionService,
48
+ @Inject(forwardRef(() => TokenService))
49
+ private readonly token: TokenService,
50
+ @Inject(forwardRef(() => OAuthMetadataService))
51
+ private readonly metadata: OAuthMetadataService,
41
52
  ) {}
42
53
 
54
+
55
+
43
56
  private async getClient(clientId: string) {
44
57
  const client = await this.prisma.oauth_app_client.findUnique({
45
58
  where: { client_id: clientId },
46
59
  });
47
60
 
48
61
  if (!client || !client.enabled) {
49
- throw new BadRequestException('Aplicativo desconhecido ou desabilitado.');
62
+ // NAO redirecionavel: sem client valido nao ha redirect_uri de confianca
63
+ // para onde mandar o erro (RFC 6749 4.1.2.1).
64
+ this.logger.warn(`[AuthorizeService] client desconhecido ou desabilitado: ${clientId}`);
65
+ throw new OAuthError('invalid_client', 'Aplicativo desconhecido ou desabilitado.');
50
66
  }
51
67
 
52
68
  return client;
@@ -57,26 +73,102 @@ export class AuthorizeService {
57
73
  * normalizar/parsear abriria espaço para bypass (barra final, case do host,
58
74
  * userinfo, `origin` valendo "null" em esquemas não-http).
59
75
  */
60
- private assertRedirectUri(client: { redirect_uris: string }, redirectUri: string) {
76
+ private assertRedirectUri(
77
+ client: { redirect_uris: string; client_id?: string },
78
+ redirectUri: string,
79
+ ) {
61
80
  const allowed = client.redirect_uris
62
81
  .split('\n')
63
82
  .map((uri) => uri.trim())
64
83
  .filter(Boolean);
65
84
 
66
85
  if (!allowed.includes(redirectUri)) {
67
- throw new BadRequestException('redirect_uri não registrado para este aplicativo.');
86
+ // O valor rejeitado vai para o log de proposito: e por ele que se descobre
87
+ // o callback real de um cliente novo (o do Claude, por exemplo) sem ter que
88
+ // adivinhar. Nao e segredo — quem mandou ja o conhece.
89
+ this.logger.warn(
90
+ `[AuthorizeService] redirect_uri recusado client=${(client as any).client_id ?? '?'} uri=${redirectUri}`,
91
+ );
92
+ throw new OAuthError(
93
+ 'invalid_request',
94
+ 'redirect_uri não registrado para este aplicativo.',
95
+ );
68
96
  }
69
97
  }
70
98
 
71
- private assertScope(client: { scopes: string }, scope: string) {
99
+ /**
100
+ * Devolve o escopo efetivo. `scope` ausente assume o que o client tem
101
+ * registrado — um cliente OAuth padrao pode simplesmente nao mandar o
102
+ * parametro, e recusa-lo seria recusar o fluxo inteiro por nada.
103
+ */
104
+ private assertScope(client: { scopes: string }, scope?: string): string {
72
105
  const granted = new Set(client.scopes.split(/[\s,]+/).filter(Boolean));
73
- const requested = scope.split(/[\s,]+/).filter(Boolean);
106
+ const requested = (scope ?? '').split(/[\s,]+/).filter(Boolean);
74
107
 
75
108
  if (requested.length === 0) {
76
- throw new BadRequestException('scope é obrigatório.');
109
+ return [...granted].join(' ');
77
110
  }
78
111
  if (!requested.every((s) => granted.has(s))) {
79
- throw new BadRequestException('scope não autorizado para este aplicativo.');
112
+ throw new OAuthError(
113
+ 'invalid_scope',
114
+ 'scope não autorizado para este aplicativo.',
115
+ true,
116
+ );
117
+ }
118
+ return requested.join(' ');
119
+ }
120
+
121
+ /**
122
+ * `resource` (RFC 8707) é uma allowlist de um item só: o /mcp deste servidor.
123
+ * Igualdade exata — o middleware de compatibilidade do main.ts faz `/api/mcp`
124
+ * responder no mesmo lugar, e comparar por prefixo deixaria nascer um token com
125
+ * audiência paralela que o TokenService nunca reconheceria.
126
+ *
127
+ * E ele é OBRIGATÓRIO quando a concessão inclui o escopo `mcp`. Sem essa regra
128
+ * o confinamento seria opt-in pela parte que ele restringe: bastava o cliente
129
+ * omitir o parâmetro para receber um token sem `aud` — válido na API REST
130
+ * inteira, com o TTL longo de login e renovável pelo /auth/refresh. Um cliente
131
+ * de MCP nunca deve conseguir uma sessão de propósito geral.
132
+ */
133
+ private async assertResource(
134
+ scope: string,
135
+ resource?: string,
136
+ ): Promise<string | null> {
137
+ const confinedToMcp = scope
138
+ .split(/[\s,]+/)
139
+ .filter(Boolean)
140
+ .includes(MCP_SCOPE);
141
+
142
+ if (!resource) {
143
+ if (confinedToMcp) {
144
+ throw new OAuthError(
145
+ 'invalid_target',
146
+ `resource é obrigatório para o escopo '${MCP_SCOPE}'.`,
147
+ true,
148
+ );
149
+ }
150
+ return null;
151
+ }
152
+
153
+ const mcpResource = await this.metadata.getMcpResource();
154
+ if (resource !== mcpResource) {
155
+ throw new OAuthError(
156
+ 'invalid_target',
157
+ 'resource não reconhecido por este servidor.',
158
+ true,
159
+ );
160
+ }
161
+ return mcpResource;
162
+ }
163
+
164
+ /** RFC 6749: só `code`. Ausente, assume `code` — nenhum client atual manda. */
165
+ private assertResponseType(responseType?: string) {
166
+ if (responseType && responseType !== 'code') {
167
+ throw new OAuthError(
168
+ 'unsupported_response_type',
169
+ 'Apenas response_type=code é suportado.',
170
+ true,
171
+ );
80
172
  }
81
173
  }
82
174
 
@@ -84,18 +176,30 @@ export class AuthorizeService {
84
176
  async getAuthorizationInfo(params: {
85
177
  clientId: string;
86
178
  redirectUri: string;
87
- scope: string;
179
+ scope?: string;
88
180
  codeChallenge: string;
89
181
  codeChallengeMethod: string;
182
+ responseType?: string;
183
+ resource?: string;
90
184
  }) {
185
+ // A ordem importa: primeiro o que NAO pode redirecionar (client, redirect),
186
+ // so depois o que pode. Invertida, um erro de escopo tentaria redirecionar
187
+ // para um redirect_uri ainda nao validado.
91
188
  const client = await this.getClient(params.clientId);
92
189
  this.assertRedirectUri(client, params.redirectUri);
93
- this.assertScope(client, params.scope);
190
+
191
+ this.assertResponseType(params.responseType);
192
+ const scope = this.assertScope(client, params.scope);
94
193
  this.assertPkce(params.codeChallenge, params.codeChallengeMethod);
194
+ await this.assertResource(scope, params.resource);
95
195
 
96
196
  return {
97
197
  clientName: client.name,
98
- scopes: params.scope.split(/[\s,]+/).filter(Boolean),
198
+ scopes: scope.split(/[\s,]+/).filter(Boolean),
199
+ // A tela precisa devolver `iss` no redirect (RFC 9207), e anunciamos
200
+ // `authorization_response_iss_parameter_supported`. Mandar daqui evita mais
201
+ // uma variavel de ambiente no admin e garante que os dois concordem.
202
+ issuer: await this.metadata.getIssuer(),
99
203
  };
100
204
  }
101
205
 
@@ -105,7 +209,11 @@ export class AuthorizeService {
105
209
  */
106
210
  private assertPkce(codeChallenge: string, method: string) {
107
211
  if (method !== 'S256') {
108
- throw new BadRequestException('code_challenge_method deve ser S256.');
212
+ throw new OAuthError(
213
+ 'invalid_request',
214
+ 'code_challenge_method deve ser S256.',
215
+ true,
216
+ );
109
217
  }
110
218
  if (
111
219
  !codeChallenge ||
@@ -113,7 +221,7 @@ export class AuthorizeService {
113
221
  codeChallenge.length > 128 ||
114
222
  !/^[A-Za-z0-9\-._~]+$/.test(codeChallenge)
115
223
  ) {
116
- throw new BadRequestException('code_challenge inválido.');
224
+ throw new OAuthError('invalid_request', 'code_challenge inválido.', true);
117
225
  }
118
226
  }
119
227
 
@@ -122,14 +230,18 @@ export class AuthorizeService {
122
230
  userId: number;
123
231
  clientId: string;
124
232
  redirectUri: string;
125
- scope: string;
233
+ scope?: string;
126
234
  codeChallenge: string;
127
235
  codeChallengeMethod: string;
236
+ responseType?: string;
237
+ resource?: string;
128
238
  }): Promise<string> {
129
239
  const client = await this.getClient(params.clientId);
130
240
  this.assertRedirectUri(client, params.redirectUri);
131
- this.assertScope(client, params.scope);
241
+ this.assertResponseType(params.responseType);
242
+ const scope = this.assertScope(client, params.scope);
132
243
  this.assertPkce(params.codeChallenge, params.codeChallengeMethod);
244
+ const resource = await this.assertResource(scope, params.resource);
133
245
 
134
246
  const code = this.security.randomOpaque(32);
135
247
  const codeHash = this.security.hashSha256(code);
@@ -141,10 +253,13 @@ export class AuthorizeService {
141
253
  client_id: params.clientId,
142
254
  user_id: params.userId,
143
255
  redirect_uri: params.redirectUri,
144
- scope: params.scope,
256
+ scope,
145
257
  code_challenge: params.codeChallenge,
146
258
  code_challenge_method: 'S256',
147
259
  expires_at: expiresAt,
260
+ // Guardado para a troca do code exigir o MESMO recurso. Sem isso um
261
+ // cliente autorizaria para um recurso e pegaria token para outro.
262
+ resource,
148
263
  },
149
264
  });
150
265
 
@@ -165,6 +280,7 @@ export class AuthorizeService {
165
280
  codeVerifier: string;
166
281
  clientId: string;
167
282
  redirectUri: string;
283
+ resource?: string;
168
284
  locale: string;
169
285
  ipAddress: string;
170
286
  userAgent: string;
@@ -179,13 +295,16 @@ export class AuthorizeService {
179
295
  const client = await this.getClient(params.clientId);
180
296
 
181
297
  if (client.client_type !== 'public') {
182
- throw new BadRequestException('Fluxo indisponível para este aplicativo.');
298
+ throw new OAuthError(
299
+ 'unauthorized_client',
300
+ 'Fluxo indisponível para este aplicativo.',
301
+ );
183
302
  }
184
303
 
185
304
  const codeHash = this.security.hashSha256(params.code);
186
305
 
187
306
  const rows = await this.prisma.$queryRaw<
188
- Array<{ user_id: number; code_challenge: string; scope: string }>
307
+ Array<{ user_id: number; code_challenge: string; scope: string; resource: string | null }>
189
308
  >(
190
309
  Prisma.sql`
191
310
  UPDATE oauth_authorization_code
@@ -195,13 +314,14 @@ export class AuthorizeService {
195
314
  AND redirect_uri = ${params.redirectUri}
196
315
  AND expires_at > NOW()
197
316
  AND consumed_at IS NULL
198
- RETURNING user_id, code_challenge, scope
317
+ RETURNING user_id, code_challenge, scope, resource
199
318
  `,
200
319
  );
201
320
 
202
321
  const row = rows[0];
203
322
  if (!row) {
204
- throw new BadRequestException(
323
+ throw new OAuthError(
324
+ 'invalid_grant',
205
325
  'Código inválido, expirado ou já utilizado. Refaça a autorização.',
206
326
  );
207
327
  }
@@ -211,27 +331,193 @@ export class AuthorizeService {
211
331
  this.logger.warn(
212
332
  `[AuthorizeService] PKCE falhou client=${params.clientId} userId=${row.user_id}`,
213
333
  );
214
- throw new BadRequestException('code_verifier inválido.');
334
+ throw new OAuthError('invalid_grant', 'code_verifier inválido.');
215
335
  }
216
336
 
337
+ // O recurso pedido agora tem que ser o mesmo pedido na autorizacao. Divergir
338
+ // aqui seria autorizar para um recurso e receber token para outro.
339
+ if ((params.resource ?? null) !== (row.resource ?? null)) {
340
+ throw new OAuthError(
341
+ 'invalid_target',
342
+ 'resource não confere com o da autorização.',
343
+ );
344
+ }
345
+
346
+ const oauth = row.resource
347
+ ? {
348
+ audience: row.resource,
349
+ scope: row.scope,
350
+ clientId: params.clientId,
351
+ issuer: await this.metadata.getIssuer(),
352
+ ttlMinutes: SessionService.CONNECTOR_SESSION_TTL_MINUTES,
353
+ }
354
+ : undefined;
355
+
217
356
  const { accessToken, refreshToken } = await this.auth.getAuthenticationPayload(
218
357
  params.locale,
219
358
  row.user_id,
220
359
  params.ipAddress,
221
360
  params.userAgent,
222
361
  params.browserId,
362
+ oauth,
223
363
  );
224
364
 
365
+ return this.buildTokenResponse(accessToken, refreshToken, row.scope);
366
+ }
367
+
368
+ /**
369
+ * Renovacao do cliente OAuth externo.
370
+ *
371
+ * Existe separado do POST /auth/refresh porque aquele devolve um token SEM
372
+ * `aud` — e por isso mesmo recusa sessao de conector. Aqui o `aud` e reaplicado
373
+ * a partir da propria sessao, que e a unica coisa que sobrevive a rotacao do
374
+ * refresh token (que e opaco).
375
+ */
376
+ async exchangeRefreshToken(params: {
377
+ refreshToken: string;
378
+ clientId: string;
379
+ resource?: string;
380
+ locale: string;
381
+ ipAddress: string;
382
+ userAgent: string;
383
+ browserId?: string | null;
384
+ }) {
385
+ const client = await this.getClient(params.clientId);
386
+
387
+ if (client.client_type !== 'public') {
388
+ throw new OAuthError(
389
+ 'unauthorized_client',
390
+ 'Fluxo indisponível para este aplicativo.',
391
+ );
392
+ }
393
+
394
+ // TUDO o que pode recusar acontece ANTES de girar.
395
+ //
396
+ // `session.refresh()` commita o compare-and-swap na hora: o token que o
397
+ // cliente tem passa a valer por mais 30s (a janela de graca) e o substituto
398
+ // so existe se a chamada chegar ao fim. Validar depois dela transformava
399
+ // qualquer recusa — client errado, resource divergente — na destruicao da
400
+ // sessao do cliente, em vez da negacao de um pedido.
401
+ const existing = await this.session.peekByRefreshToken(params.refreshToken);
402
+
403
+ if (!existing || existing.revoked_at !== null || existing.expires_at <= new Date()) {
404
+ throw new OAuthError(
405
+ 'invalid_grant',
406
+ 'refresh_token inválido, expirado ou revogado.',
407
+ );
408
+ }
409
+
410
+ // A sessao tem que ser deste client. Sem esta checagem, o refresh token de um
411
+ // cliente valeria apresentado por outro.
412
+ if (existing.oauth_client_id && existing.oauth_client_id !== params.clientId) {
413
+ throw new OAuthError(
414
+ 'invalid_grant',
415
+ 'refresh_token não pertence a este aplicativo.',
416
+ );
417
+ }
418
+
419
+ const audience = existing.audience ?? null;
420
+ if ((params.resource ?? null) !== audience) {
421
+ throw new OAuthError(
422
+ 'invalid_target',
423
+ 'resource não confere com o da sessão.',
424
+ );
425
+ }
426
+
427
+ // O escopo sai do que o client tem REGISTRADO, nunca de um literal. Fixar
428
+ // 'mcp' aqui promovia a cliente de MCP qualquer client que chegasse a este
429
+ // endpoint — inclusive os que so tem 'profile' ou 'vaults'.
430
+ const scope = this.assertScope(client);
431
+
432
+ // Uma sessao de recurso so pode ser renovada por um client que ainda tenha o
433
+ // escopo correspondente. Se o registro do client mudou no meio do caminho, a
434
+ // renovacao para aqui em vez de emitir um token que o McpAuthGuard recusaria.
435
+ if (audience && !scope.split(/[\s,]+/).filter(Boolean).includes(MCP_SCOPE)) {
436
+ throw new OAuthError(
437
+ 'invalid_scope',
438
+ `Este aplicativo não tem mais o escopo '${MCP_SCOPE}'.`,
439
+ );
440
+ }
441
+
442
+ let session: any;
443
+ let token: string;
444
+ try {
445
+ ({ session, token } = await this.session.refresh(
446
+ params.locale,
447
+ params.refreshToken,
448
+ params.ipAddress,
449
+ params.userAgent,
450
+ params.browserId ?? null,
451
+ ));
452
+ } catch (error) {
453
+ // So o que o SessionService classifica como credencial invalida vira
454
+ // invalid_grant. Erro de infraestrutura (timeout, pool esgotado) NAO pode:
455
+ // pelo RFC 6749 5.2 esse codigo manda o cliente descartar o refresh token,
456
+ // entao um soluco de banco desconectaria todo mundo de forma permanente.
457
+ if (error instanceof UnauthorizedException) {
458
+ throw new OAuthError(
459
+ 'invalid_grant',
460
+ 'refresh_token inválido, expirado ou revogado.',
461
+ );
462
+ }
463
+ throw error;
464
+ }
465
+
466
+ const payload = audience
467
+ ? {
468
+ sub: session.user_id,
469
+ sessionId: session.id,
470
+ aud: audience,
471
+ iss: await this.metadata.getIssuer(),
472
+ scope,
473
+ cid: params.clientId,
474
+ }
475
+ : { sub: session.user_id, sessionId: session.id };
476
+
477
+ const accessToken = await this.token.createAccessToken(payload);
478
+
479
+ return this.buildTokenResponse(accessToken, token, scope);
480
+ }
481
+
482
+ /**
483
+ * `expires_in` sai do `exp` do proprio JWT recem-assinado, e nao da setting: o
484
+ * JwtModule le `access-token-expiration-minutes` uma UNICA vez, no boot, entao a
485
+ * setting e o token podem divergir ate o proximo deploy. O token e a verdade.
486
+ *
487
+ * A resposta traz snake_case e camelCase ao mesmo tempo. O RFC 6749 5.1 permite
488
+ * membros extras, e os cinco clientes ja registrados leem camelCase — passar so
489
+ * a snake_case quebraria todos de uma vez.
490
+ */
491
+ private buildTokenResponse(accessToken: string, refreshToken: string, scope: string) {
492
+ const expiresIn = this.expiresInFromJwt(accessToken);
493
+
225
494
  return {
495
+ access_token: accessToken,
226
496
  accessToken,
497
+ refresh_token: refreshToken,
227
498
  refreshToken,
499
+ token_type: 'Bearer',
228
500
  tokenType: 'Bearer',
229
- // Informativo para o cliente agendar refresh; a verdade é o exp do JWT.
230
- expiresIn: 3600,
231
- scope: row.scope,
501
+ expires_in: expiresIn,
502
+ expiresIn,
503
+ scope,
232
504
  };
233
505
  }
234
506
 
507
+ private expiresInFromJwt(accessToken: string): number {
508
+ try {
509
+ const claims = JSON.parse(
510
+ Buffer.from(accessToken.split('.')[1], 'base64url').toString('utf8'),
511
+ );
512
+ const seconds = Number(claims?.exp) - Math.floor(Date.now() / 1000);
513
+ return seconds > 0 ? seconds : 0;
514
+ } catch {
515
+ // Token sem exp legivel nao deve derrubar a resposta; o cliente reage ao
516
+ // 401 de qualquer forma.
517
+ return 0;
518
+ }
519
+ }
520
+
235
521
  /** base64url(sha256(verifier)) === challenge, em tempo constante. */
236
522
  private verifyPkce(codeVerifier: string, codeChallenge: string): boolean {
237
523
  if (!codeVerifier || codeVerifier.length < 43 || codeVerifier.length > 128) {
@@ -1,4 +1,4 @@
1
- import { IsNotEmpty, IsString } from 'class-validator';
1
+ import { IsNotEmpty, IsOptional, IsString } from 'class-validator';
2
2
 
3
3
  export class AuthorizeInfoDTO {
4
4
  @IsString()
@@ -9,9 +9,10 @@ export class AuthorizeInfoDTO {
9
9
  @IsNotEmpty()
10
10
  redirect_uri: string;
11
11
 
12
+ /** Ausente, assume os escopos registrados do client. */
13
+ @IsOptional()
12
14
  @IsString()
13
- @IsNotEmpty()
14
- scope: string;
15
+ scope?: string;
15
16
 
16
17
  @IsString()
17
18
  @IsNotEmpty()
@@ -20,4 +21,21 @@ export class AuthorizeInfoDTO {
20
21
  @IsString()
21
22
  @IsNotEmpty()
22
23
  code_challenge_method: string;
24
+
25
+ /**
26
+ * Opcionais porque os cinco clientes ja registrados nao os mandam. Quando
27
+ * ausentes, o comportamento e byte a byte o de hoje; quando presentes e
28
+ * invalidos, a requisicao e recusada.
29
+ */
30
+ @IsOptional()
31
+ @IsString()
32
+ response_type?: string;
33
+
34
+ @IsOptional()
35
+ @IsString()
36
+ resource?: string;
37
+
38
+ @IsOptional()
39
+ @IsString()
40
+ state?: string;
23
41
  }
@@ -1,4 +1,4 @@
1
- import { IsNotEmpty, IsString } from 'class-validator';
1
+ import { IsNotEmpty, IsOptional, IsString } from 'class-validator';
2
2
 
3
3
  export class ConsentDTO {
4
4
  @IsString()
@@ -9,9 +9,10 @@ export class ConsentDTO {
9
9
  @IsNotEmpty()
10
10
  redirect_uri: string;
11
11
 
12
+ /** Ausente, assume os escopos registrados do client. */
13
+ @IsOptional()
12
14
  @IsString()
13
- @IsNotEmpty()
14
- scope: string;
15
+ scope?: string;
15
16
 
16
17
  @IsString()
17
18
  @IsNotEmpty()
@@ -20,4 +21,21 @@ export class ConsentDTO {
20
21
  @IsString()
21
22
  @IsNotEmpty()
22
23
  code_challenge_method: string;
24
+
25
+ /**
26
+ * Opcionais porque os cinco clientes ja registrados nao os mandam. Quando
27
+ * ausentes, o comportamento e byte a byte o de hoje; quando presentes e
28
+ * invalidos, a requisicao e recusada.
29
+ */
30
+ @IsOptional()
31
+ @IsString()
32
+ response_type?: string;
33
+
34
+ @IsOptional()
35
+ @IsString()
36
+ resource?: string;
37
+
38
+ @IsOptional()
39
+ @IsString()
40
+ state?: string;
23
41
  }
@@ -1,14 +1,22 @@
1
- import { IsIn, IsNotEmpty, IsString } from 'class-validator';
1
+ import { IsIn, IsNotEmpty, IsOptional, IsString, ValidateIf } from 'class-validator';
2
2
 
3
+ /**
4
+ * Os campos obrigatórios dependem do grant. `authorization_code` continua
5
+ * exigindo exatamente o que exigia; `refresh_token` só existe para o cliente
6
+ * OAuth externo renovar sem passar pelo `/auth/refresh` — que devolve token sem
7
+ * audiência e por isso recusa sessão de conector.
8
+ */
3
9
  export class TokenDTO {
4
10
  @IsString()
5
- @IsIn(['authorization_code'])
11
+ @IsIn(['authorization_code', 'refresh_token'])
6
12
  grant_type: string;
7
13
 
14
+ @ValidateIf((o) => o.grant_type !== 'refresh_token')
8
15
  @IsString()
9
16
  @IsNotEmpty()
10
17
  code: string;
11
18
 
19
+ @ValidateIf((o) => o.grant_type !== 'refresh_token')
12
20
  @IsString()
13
21
  @IsNotEmpty()
14
22
  code_verifier: string;
@@ -17,7 +25,21 @@ export class TokenDTO {
17
25
  @IsNotEmpty()
18
26
  client_id: string;
19
27
 
28
+ @ValidateIf((o) => o.grant_type !== 'refresh_token')
20
29
  @IsString()
21
30
  @IsNotEmpty()
22
31
  redirect_uri: string;
32
+
33
+ @ValidateIf((o) => o.grant_type === 'refresh_token')
34
+ @IsString()
35
+ @IsNotEmpty()
36
+ refresh_token: string;
37
+
38
+ /**
39
+ * RFC 8707. Opcional: sem ele o token sai sem `aud` e o comportamento é o de
40
+ * hoje — que é o que os cinco clientes já registrados esperam.
41
+ */
42
+ @IsOptional()
43
+ @IsString()
44
+ resource?: string;
23
45
  }
@@ -0,0 +1,58 @@
1
+ import {
2
+ ArgumentsHost,
3
+ Catch,
4
+ ExceptionFilter,
5
+ HttpException,
6
+ } from '@nestjs/common';
7
+ import { Response } from 'express';
8
+ import { OAuthError } from './authorize.errors';
9
+
10
+ /**
11
+ * Traduz o que sai dos endpoints OAuth para o formato do RFC 6749 §5.2:
12
+ * `{ error, error_description }`, sempre `no-store`.
13
+ *
14
+ * Existe porque o `HttpExceptionFilter` global quase serve, mas não nos dois
15
+ * casos que importam: ele acrescenta `statusCode`/`timestamp`/`path` ao corpo, e
16
+ * uma falha do `ValidationPipe` sai como `{ message: { campo: [...] } }`, que não
17
+ * é um erro OAuth e nenhum cliente sabe ler.
18
+ *
19
+ * O campo `message` é preservado de propósito — os cinco clientes já registrados
20
+ * leem ele nas respostas de erro de hoje.
21
+ */
22
+ @Catch(HttpException)
23
+ export class OAuthExceptionFilter implements ExceptionFilter {
24
+ catch(exception: HttpException, host: ArgumentsHost): void {
25
+ const response = host.switchToHttp().getResponse<Response>();
26
+ const status = exception.getStatus();
27
+ const body = exception.getResponse() as any;
28
+
29
+ response.setHeader('Cache-Control', 'no-store');
30
+ response.setHeader('Pragma', 'no-cache');
31
+
32
+ if (exception instanceof OAuthError) {
33
+ response.status(status).json({
34
+ error: body.error,
35
+ error_description: body.error_description,
36
+ ...(body.redirectable ? { redirectable: true } : {}),
37
+ ...(body.issuer ? { issuer: body.issuer } : {}),
38
+ message: body.message,
39
+ });
40
+ return;
41
+ }
42
+
43
+ // Falha de validação de DTO: vira invalid_request, com a mensagem original
44
+ // preservada para quem estiver depurando.
45
+ const description =
46
+ typeof body === 'string'
47
+ ? body
48
+ : typeof body?.message === 'string'
49
+ ? body.message
50
+ : JSON.stringify(body?.message ?? 'Invalid request.');
51
+
52
+ response.status(status).json({
53
+ error: status === 400 ? 'invalid_request' : 'server_error',
54
+ error_description: description,
55
+ message: body?.message ?? description,
56
+ });
57
+ }
58
+ }