@hed-hog/core 0.0.399 → 0.0.401
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.
- package/dist/ai/ai-agent.sort.d.ts +6 -0
- package/dist/ai/ai-agent.sort.d.ts.map +1 -0
- package/dist/ai/ai-agent.sort.js +21 -0
- package/dist/ai/ai-agent.sort.js.map +1 -0
- package/dist/ai/ai.controller.d.ts +6 -4
- package/dist/ai/ai.controller.d.ts.map +1 -1
- package/dist/ai/ai.service.d.ts +121 -6
- package/dist/ai/ai.service.d.ts.map +1 -1
- package/dist/ai/ai.service.js +355 -160
- package/dist/ai/ai.service.js.map +1 -1
- package/dist/ai-instruction/ai-instruction.service.d.ts.map +1 -1
- package/dist/ai-instruction/ai-instruction.service.js +26 -23
- package/dist/ai-instruction/ai-instruction.service.js.map +1 -1
- package/dist/ai-instruction/ai-instruction.sort.d.ts +16 -0
- package/dist/ai-instruction/ai-instruction.sort.d.ts.map +1 -0
- package/dist/ai-instruction/ai-instruction.sort.js +32 -0
- package/dist/ai-instruction/ai-instruction.sort.js.map +1 -0
- package/dist/ai-instruction/ai-prompt-resolver.service.d.ts +12 -0
- package/dist/ai-instruction/ai-prompt-resolver.service.d.ts.map +1 -1
- package/dist/ai-instruction/ai-prompt-resolver.service.js +26 -0
- package/dist/ai-instruction/ai-prompt-resolver.service.js.map +1 -1
- package/dist/auth/auth.controller.d.ts +24 -8
- package/dist/auth/auth.controller.d.ts.map +1 -1
- package/dist/auth/auth.module.d.ts.map +1 -1
- package/dist/auth/auth.module.js +8 -1
- package/dist/auth/auth.module.js.map +1 -1
- package/dist/auth/auth.service.d.ts +72 -25
- package/dist/auth/auth.service.d.ts.map +1 -1
- package/dist/auth/auth.service.js +41 -4
- package/dist/auth/auth.service.js.map +1 -1
- package/dist/auth/guards/auth.guard.d.ts +3 -1
- package/dist/auth/guards/auth.guard.d.ts.map +1 -1
- package/dist/auth/guards/auth.guard.js +12 -3
- package/dist/auth/guards/auth.guard.js.map +1 -1
- package/dist/authorize/authorize.controller.d.ts +29 -5
- package/dist/authorize/authorize.controller.d.ts.map +1 -1
- package/dist/authorize/authorize.controller.js +120 -13
- package/dist/authorize/authorize.controller.js.map +1 -1
- package/dist/authorize/authorize.errors.d.ts +34 -0
- package/dist/authorize/authorize.errors.d.ts.map +1 -0
- package/dist/authorize/authorize.errors.js +37 -0
- package/dist/authorize/authorize.errors.js.map +1 -0
- package/dist/authorize/authorize.module.d.ts.map +1 -1
- package/dist/authorize/authorize.module.js +6 -1
- package/dist/authorize/authorize.module.js.map +1 -1
- package/dist/authorize/authorize.service.d.ts +77 -3
- package/dist/authorize/authorize.service.d.ts.map +1 -1
- package/dist/authorize/authorize.service.js +212 -21
- package/dist/authorize/authorize.service.js.map +1 -1
- package/dist/authorize/dto/authorize-info.dto.d.ts +10 -1
- package/dist/authorize/dto/authorize-info.dto.d.ts.map +1 -1
- package/dist/authorize/dto/authorize-info.dto.js +16 -1
- package/dist/authorize/dto/authorize-info.dto.js.map +1 -1
- package/dist/authorize/dto/consent.dto.d.ts +10 -1
- package/dist/authorize/dto/consent.dto.d.ts.map +1 -1
- package/dist/authorize/dto/consent.dto.js +16 -1
- package/dist/authorize/dto/consent.dto.js.map +1 -1
- package/dist/authorize/dto/token.dto.d.ts +12 -0
- package/dist/authorize/dto/token.dto.d.ts.map +1 -1
- package/dist/authorize/dto/token.dto.js +21 -1
- package/dist/authorize/dto/token.dto.js.map +1 -1
- package/dist/authorize/oauth-exception.filter.d.ts +17 -0
- package/dist/authorize/oauth-exception.filter.d.ts.map +1 -0
- package/dist/authorize/oauth-exception.filter.js +54 -0
- package/dist/authorize/oauth-exception.filter.js.map +1 -0
- package/dist/authorize/oauth-metadata.service.d.ts +39 -0
- package/dist/authorize/oauth-metadata.service.d.ts.map +1 -0
- package/dist/authorize/oauth-metadata.service.js +81 -0
- package/dist/authorize/oauth-metadata.service.js.map +1 -0
- package/dist/authorize/well-known.controller.d.ts +67 -0
- package/dist/authorize/well-known.controller.d.ts.map +1 -0
- package/dist/authorize/well-known.controller.js +126 -0
- package/dist/authorize/well-known.controller.js.map +1 -0
- package/dist/captcha/captcha.service.d.ts +32 -2
- package/dist/captcha/captcha.service.d.ts.map +1 -1
- package/dist/captcha/captcha.service.js +85 -12
- package/dist/captcha/captcha.service.js.map +1 -1
- package/dist/challenge/challenge.service.d.ts +2 -2
- package/dist/core.module.d.ts.map +1 -1
- package/dist/core.module.js +9 -0
- package/dist/core.module.js.map +1 -1
- package/dist/dashboard/dashboard/dashboard.controller.d.ts +9 -9
- package/dist/dashboard/dashboard/dashboard.service.d.ts +9 -9
- package/dist/dashboard/dashboard-component/dashboard-component.controller.d.ts +3 -3
- package/dist/dashboard/dashboard-component/dashboard-component.service.d.ts +3 -3
- package/dist/dashboard/dashboard-component-role/dashboard-component-role.controller.d.ts +3 -3
- package/dist/dashboard/dashboard-component-role/dashboard-component-role.service.d.ts +3 -3
- package/dist/dashboard/dashboard-component-role/dashboard-component-role.service.d.ts.map +1 -1
- package/dist/dashboard/dashboard-component-role/dashboard-component-role.service.js +2 -4
- package/dist/dashboard/dashboard-component-role/dashboard-component-role.service.js.map +1 -1
- package/dist/dashboard/dashboard-component-role/dashboard-component-role.sort.d.ts +8 -0
- package/dist/dashboard/dashboard-component-role/dashboard-component-role.sort.d.ts.map +1 -0
- package/dist/dashboard/dashboard-component-role/dashboard-component-role.sort.js +18 -0
- package/dist/dashboard/dashboard-component-role/dashboard-component-role.sort.js.map +1 -0
- package/dist/dashboard/dashboard-item/dashboard-item.service.d.ts.map +1 -1
- package/dist/dashboard/dashboard-item/dashboard-item.service.js +2 -4
- package/dist/dashboard/dashboard-item/dashboard-item.service.js.map +1 -1
- package/dist/dashboard/dashboard-item/dashboard-item.sort.d.ts +9 -0
- package/dist/dashboard/dashboard-item/dashboard-item.sort.d.ts.map +1 -0
- package/dist/dashboard/dashboard-item/dashboard-item.sort.js +19 -0
- package/dist/dashboard/dashboard-item/dashboard-item.sort.js.map +1 -0
- package/dist/dashboard/dashboard-role/dashboard-role.controller.d.ts +3 -3
- package/dist/dashboard/dashboard-role/dashboard-role.service.d.ts +3 -3
- package/dist/dashboard/dashboard-role/dashboard-role.service.d.ts.map +1 -1
- package/dist/dashboard/dashboard-role/dashboard-role.service.js +2 -4
- package/dist/dashboard/dashboard-role/dashboard-role.service.js.map +1 -1
- package/dist/dashboard/dashboard-role/dashboard-role.sort.d.ts +8 -0
- package/dist/dashboard/dashboard-role/dashboard-role.sort.d.ts.map +1 -0
- package/dist/dashboard/dashboard-role/dashboard-role.sort.js +16 -0
- package/dist/dashboard/dashboard-role/dashboard-role.sort.js.map +1 -0
- package/dist/document-kit/document-kit.module.d.ts +3 -0
- package/dist/document-kit/document-kit.module.d.ts.map +1 -0
- package/dist/document-kit/document-kit.module.js +24 -0
- package/dist/document-kit/document-kit.module.js.map +1 -0
- package/dist/document-kit/document-kit.registry.d.ts +55 -0
- package/dist/document-kit/document-kit.registry.d.ts.map +1 -0
- package/dist/document-kit/document-kit.registry.js +91 -0
- package/dist/document-kit/document-kit.registry.js.map +1 -0
- package/dist/document-kit/document-kit.service.d.ts +49 -0
- package/dist/document-kit/document-kit.service.d.ts.map +1 -0
- package/dist/document-kit/document-kit.service.js +135 -0
- package/dist/document-kit/document-kit.service.js.map +1 -0
- package/dist/file/file-upload-ticket.service.d.ts +160 -0
- package/dist/file/file-upload-ticket.service.d.ts.map +1 -0
- package/dist/file/file-upload-ticket.service.js +382 -0
- package/dist/file/file-upload-ticket.service.js.map +1 -0
- package/dist/file/file.controller.d.ts +24 -1
- package/dist/file/file.controller.d.ts.map +1 -1
- package/dist/file/file.controller.js +63 -2
- package/dist/file/file.controller.js.map +1 -1
- package/dist/file/file.module.d.ts.map +1 -1
- package/dist/file/file.module.js +14 -2
- package/dist/file/file.module.js.map +1 -1
- package/dist/file/file.service.d.ts +197 -7
- package/dist/file/file.service.d.ts.map +1 -1
- package/dist/file/file.service.js +438 -78
- package/dist/file/file.service.js.map +1 -1
- package/dist/file/filename-encoding.util.d.ts +24 -0
- package/dist/file/filename-encoding.util.d.ts.map +1 -0
- package/dist/file/filename-encoding.util.js +63 -0
- package/dist/file/filename-encoding.util.js.map +1 -0
- package/dist/file/image-optimization.service.d.ts +27 -0
- package/dist/file/image-optimization.service.d.ts.map +1 -1
- package/dist/file/image-optimization.service.js +63 -14
- package/dist/file/image-optimization.service.js.map +1 -1
- package/dist/file/mcp-file-source.schema.d.ts +33 -0
- package/dist/file/mcp-file-source.schema.d.ts.map +1 -0
- package/dist/file/mcp-file-source.schema.js +78 -0
- package/dist/file/mcp-file-source.schema.js.map +1 -0
- package/dist/file/mcp-file-source.service.d.ts +124 -0
- package/dist/file/mcp-file-source.service.d.ts.map +1 -0
- package/dist/file/mcp-file-source.service.js +262 -0
- package/dist/file/mcp-file-source.service.js.map +1 -0
- package/dist/file/mimetype-sniff.util.d.ts +62 -0
- package/dist/file/mimetype-sniff.util.d.ts.map +1 -0
- package/dist/file/mimetype-sniff.util.js +226 -0
- package/dist/file/mimetype-sniff.util.js.map +1 -0
- package/dist/file/remote-fetch.util.d.ts +35 -0
- package/dist/file/remote-fetch.util.d.ts.map +1 -0
- package/dist/file/remote-fetch.util.js +236 -0
- package/dist/file/remote-fetch.util.js.map +1 -0
- package/dist/impersonation/dto/start-impersonation.dto.d.ts +4 -1
- package/dist/impersonation/dto/start-impersonation.dto.d.ts.map +1 -1
- package/dist/impersonation/dto/start-impersonation.dto.js +1 -1
- package/dist/impersonation/dto/start-impersonation.dto.js.map +1 -1
- package/dist/impersonation/impersonation.service.d.ts +8 -3
- package/dist/impersonation/impersonation.service.d.ts.map +1 -1
- package/dist/impersonation/impersonation.service.js +14 -4
- package/dist/impersonation/impersonation.service.js.map +1 -1
- package/dist/incident/incident.controller.d.ts +2 -1
- package/dist/incident/incident.controller.d.ts.map +1 -1
- package/dist/incident/incident.controller.js +10 -6
- package/dist/incident/incident.controller.js.map +1 -1
- package/dist/incident/incident.service.d.ts +2 -0
- package/dist/incident/incident.service.d.ts.map +1 -1
- package/dist/incident/incident.service.js +4 -0
- package/dist/incident/incident.service.js.map +1 -1
- package/dist/index.d.ts +22 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +22 -0
- package/dist/index.js.map +1 -1
- package/dist/integration-profile/integration-profile.secrets.d.ts.map +1 -1
- package/dist/integration-profile/integration-profile.secrets.js +28 -0
- package/dist/integration-profile/integration-profile.secrets.js.map +1 -1
- package/dist/integration-profile/integration-profile.service.d.ts +0 -13
- package/dist/integration-profile/integration-profile.service.d.ts.map +1 -1
- package/dist/integration-profile/integration-profile.service.js +5 -40
- package/dist/integration-profile/integration-profile.service.js.map +1 -1
- package/dist/integration-profile/integration-profile.utils.js +5 -5
- package/dist/integration-profile/integration-profile.utils.js.map +1 -1
- package/dist/integration-profile/testers/ai.testers.d.ts.map +1 -1
- package/dist/integration-profile/testers/ai.testers.js +46 -8
- package/dist/integration-profile/testers/ai.testers.js.map +1 -1
- package/dist/integration-profile/testers/index.d.ts.map +1 -1
- package/dist/integration-profile/testers/index.js +2 -0
- package/dist/integration-profile/testers/index.js.map +1 -1
- package/dist/integration-profile/testers/shipping.testers.d.ts +3 -0
- package/dist/integration-profile/testers/shipping.testers.d.ts.map +1 -0
- package/dist/integration-profile/testers/shipping.testers.js +71 -0
- package/dist/integration-profile/testers/shipping.testers.js.map +1 -0
- package/dist/locale/locale.controller.d.ts +1 -1
- package/dist/locale/locale.service.d.ts +1 -1
- package/dist/mail/dto/send.dto.d.ts +6 -1
- package/dist/mail/dto/send.dto.d.ts.map +1 -1
- package/dist/mail/dto/send.dto.js.map +1 -1
- package/dist/mail/mail.service.d.ts +9 -0
- package/dist/mail/mail.service.d.ts.map +1 -1
- package/dist/mail/mail.service.js +34 -14
- package/dist/mail/mail.service.js.map +1 -1
- package/dist/mail-sent/mail-sent.controller.d.ts +1 -1
- package/dist/mail-sent/mail-sent.service.d.ts +1 -1
- package/dist/mail-sent/mail-sent.service.d.ts.map +1 -1
- package/dist/mail-sent/mail-sent.service.js +2 -1
- package/dist/mail-sent/mail-sent.service.js.map +1 -1
- package/dist/mail-sent/mail-sent.sort.d.ts +9 -0
- package/dist/mail-sent/mail-sent.sort.d.ts.map +1 -0
- package/dist/mail-sent/mail-sent.sort.js +19 -0
- package/dist/mail-sent/mail-sent.sort.js.map +1 -0
- package/dist/mcp/filters/mcp-challenge.filter.d.ts +20 -0
- package/dist/mcp/filters/mcp-challenge.filter.d.ts.map +1 -0
- package/dist/mcp/filters/mcp-challenge.filter.js +69 -0
- package/dist/mcp/filters/mcp-challenge.filter.js.map +1 -0
- package/dist/mcp/guards/mcp-auth.guard.d.ts +4 -1
- package/dist/mcp/guards/mcp-auth.guard.d.ts.map +1 -1
- package/dist/mcp/guards/mcp-auth.guard.js +19 -5
- package/dist/mcp/guards/mcp-auth.guard.js.map +1 -1
- package/dist/mcp/guards/mcp-permission.guard.d.ts +25 -3
- package/dist/mcp/guards/mcp-permission.guard.d.ts.map +1 -1
- package/dist/mcp/guards/mcp-permission.guard.js +46 -26
- package/dist/mcp/guards/mcp-permission.guard.js.map +1 -1
- package/dist/mcp/mcp-audit.service.d.ts +17 -0
- package/dist/mcp/mcp-audit.service.d.ts.map +1 -1
- package/dist/mcp/mcp-audit.service.js +32 -3
- package/dist/mcp/mcp-audit.service.js.map +1 -1
- package/dist/mcp/mcp-permission.service.d.ts +64 -0
- package/dist/mcp/mcp-permission.service.d.ts.map +1 -0
- package/dist/mcp/mcp-permission.service.js +178 -0
- package/dist/mcp/mcp-permission.service.js.map +1 -0
- package/dist/mcp/mcp-server.service.d.ts +3 -1
- package/dist/mcp/mcp-server.service.d.ts.map +1 -1
- package/dist/mcp/mcp-server.service.js +36 -15
- package/dist/mcp/mcp-server.service.js.map +1 -1
- package/dist/mcp/mcp.controller.d.ts.map +1 -1
- package/dist/mcp/mcp.controller.js +10 -2
- package/dist/mcp/mcp.controller.js.map +1 -1
- package/dist/mcp/mcp.module.d.ts.map +1 -1
- package/dist/mcp/mcp.module.js +7 -1
- package/dist/mcp/mcp.module.js.map +1 -1
- package/dist/mcp/tools/core-access-log.mcp-tools.d.ts +17 -0
- package/dist/mcp/tools/core-access-log.mcp-tools.d.ts.map +1 -0
- package/dist/mcp/tools/core-access-log.mcp-tools.js +74 -0
- package/dist/mcp/tools/core-access-log.mcp-tools.js.map +1 -0
- package/dist/mcp/tools/core-ai.mcp-tools.js +2 -9
- package/dist/mcp/tools/core-ai.mcp-tools.js.map +1 -1
- package/dist/mcp/tools/core-dashboard-items.mcp-tools.js +1 -1
- package/dist/mcp/tools/core-dashboard-items.mcp-tools.js.map +1 -1
- package/dist/mcp/tools/core-dashboard.mcp-tools.js +2 -9
- package/dist/mcp/tools/core-dashboard.mcp-tools.js.map +1 -1
- package/dist/mcp/tools/core-event-webhooks.mcp-tools.d.ts.map +1 -1
- package/dist/mcp/tools/core-event-webhooks.mcp-tools.js +2 -10
- package/dist/mcp/tools/core-event-webhooks.mcp-tools.js.map +1 -1
- package/dist/mcp/tools/core-files.mcp-tools.d.ts +17 -5
- package/dist/mcp/tools/core-files.mcp-tools.d.ts.map +1 -1
- package/dist/mcp/tools/core-files.mcp-tools.js +186 -24
- package/dist/mcp/tools/core-files.mcp-tools.js.map +1 -1
- package/dist/mcp/tools/core-integration-events.mcp-tools.js +2 -9
- package/dist/mcp/tools/core-integration-events.mcp-tools.js.map +1 -1
- package/dist/mcp/tools/core-mail-sent.mcp-tools.js +2 -14
- package/dist/mcp/tools/core-mail-sent.mcp-tools.js.map +1 -1
- package/dist/mcp/tools/core-mail.mcp-tools.js +2 -9
- package/dist/mcp/tools/core-mail.mcp-tools.js.map +1 -1
- package/dist/mcp/tools/core-menus.mcp-tools.d.ts.map +1 -1
- package/dist/mcp/tools/core-menus.mcp-tools.js +2 -10
- package/dist/mcp/tools/core-menus.mcp-tools.js.map +1 -1
- package/dist/mcp/tools/core-notifications.mcp-tools.d.ts.map +1 -1
- package/dist/mcp/tools/core-notifications.mcp-tools.js +0 -1
- package/dist/mcp/tools/core-notifications.mcp-tools.js.map +1 -1
- package/dist/mcp/tools/core-roles.mcp-tools.d.ts.map +1 -1
- package/dist/mcp/tools/core-roles.mcp-tools.js +2 -13
- package/dist/mcp/tools/core-roles.mcp-tools.js.map +1 -1
- package/dist/mcp/tools/core-routes.mcp-tools.d.ts.map +1 -1
- package/dist/mcp/tools/core-routes.mcp-tools.js +2 -11
- package/dist/mcp/tools/core-routes.mcp-tools.js.map +1 -1
- package/dist/mcp/tools/core-screens.mcp-tools.d.ts.map +1 -1
- package/dist/mcp/tools/core-screens.mcp-tools.js +2 -11
- package/dist/mcp/tools/core-screens.mcp-tools.js.map +1 -1
- package/dist/mcp/tools/core-sessions.mcp-tools.d.ts.map +1 -1
- package/dist/mcp/tools/core-sessions.mcp-tools.js +0 -2
- package/dist/mcp/tools/core-sessions.mcp-tools.js.map +1 -1
- package/dist/mcp/tools/core-settings.mcp-tools.d.ts.map +1 -1
- package/dist/mcp/tools/core-settings.mcp-tools.js +2 -10
- package/dist/mcp/tools/core-settings.mcp-tools.js.map +1 -1
- package/dist/mcp/tools/core-users.mcp-tools.js +2 -9
- package/dist/mcp/tools/core-users.mcp-tools.js.map +1 -1
- package/dist/mcp/tools/core-webhooks.mcp-tools.d.ts.map +1 -1
- package/dist/mcp/tools/core-webhooks.mcp-tools.js +2 -10
- package/dist/mcp/tools/core-webhooks.mcp-tools.js.map +1 -1
- package/dist/mcp/types/mcp-context.type.d.ts +9 -0
- package/dist/mcp/types/mcp-context.type.d.ts.map +1 -1
- package/dist/mcp-chat/mcp-chat.service.d.ts.map +1 -1
- package/dist/mcp-chat/mcp-chat.service.js +8 -0
- package/dist/mcp-chat/mcp-chat.service.js.map +1 -1
- package/dist/meeting/meeting-provider.registry.d.ts +187 -0
- package/dist/meeting/meeting-provider.registry.d.ts.map +1 -1
- package/dist/meeting/meeting-provider.registry.js.map +1 -1
- package/dist/meeting/meeting.constants.d.ts +70 -0
- package/dist/meeting/meeting.constants.d.ts.map +1 -1
- package/dist/meeting/meeting.constants.js +9 -1
- package/dist/meeting/meeting.constants.js.map +1 -1
- package/dist/menu/menu.service.d.ts.map +1 -1
- package/dist/menu/menu.service.js +29 -9
- package/dist/menu/menu.service.js.map +1 -1
- package/dist/message-template/dto/update-message-template.dto.d.ts +18 -0
- package/dist/message-template/dto/update-message-template.dto.d.ts.map +1 -0
- package/dist/message-template/dto/update-message-template.dto.js +38 -0
- package/dist/message-template/dto/update-message-template.dto.js.map +1 -0
- package/dist/message-template/message-template-admin.service.d.ts +70 -0
- package/dist/message-template/message-template-admin.service.d.ts.map +1 -0
- package/dist/message-template/message-template-admin.service.js +226 -0
- package/dist/message-template/message-template-admin.service.js.map +1 -0
- package/dist/message-template/message-template.controller.d.ts +29 -0
- package/dist/message-template/message-template.controller.d.ts.map +1 -0
- package/dist/message-template/message-template.controller.js +101 -0
- package/dist/message-template/message-template.controller.js.map +1 -0
- package/dist/message-template/message-template.module.d.ts +10 -0
- package/dist/message-template/message-template.module.d.ts.map +1 -0
- package/dist/message-template/message-template.module.js +33 -0
- package/dist/message-template/message-template.module.js.map +1 -0
- package/dist/message-template/message-template.registry.d.ts +55 -0
- package/dist/message-template/message-template.registry.d.ts.map +1 -0
- package/dist/message-template/message-template.registry.js +64 -0
- package/dist/message-template/message-template.registry.js.map +1 -0
- package/dist/message-template/message-template.service.d.ts +59 -0
- package/dist/message-template/message-template.service.d.ts.map +1 -0
- package/dist/message-template/message-template.service.js +166 -0
- package/dist/message-template/message-template.service.js.map +1 -0
- package/dist/notification/notification.constants.d.ts +11 -0
- package/dist/notification/notification.constants.d.ts.map +1 -0
- package/dist/notification/notification.constants.js +14 -0
- package/dist/notification/notification.constants.js.map +1 -0
- package/dist/notification/notification.controller.d.ts +20 -20
- package/dist/notification/notification.module.d.ts.map +1 -1
- package/dist/notification/notification.module.js +3 -0
- package/dist/notification/notification.module.js.map +1 -1
- package/dist/notification/notification.service.d.ts +33 -21
- package/dist/notification/notification.service.d.ts.map +1 -1
- package/dist/notification/notification.service.js +36 -2
- package/dist/notification/notification.service.js.map +1 -1
- package/dist/oauth/oauth-token-broker.service.d.ts +50 -1
- package/dist/oauth/oauth-token-broker.service.d.ts.map +1 -1
- package/dist/oauth/oauth-token-broker.service.js +105 -3
- package/dist/oauth/oauth-token-broker.service.js.map +1 -1
- package/dist/oauth/oauth.controller.d.ts +4 -6
- package/dist/oauth/oauth.controller.d.ts.map +1 -1
- package/dist/oauth/oauth.controller.js +0 -1
- package/dist/oauth/oauth.controller.js.map +1 -1
- package/dist/oauth/oauth.errors.d.ts +15 -1
- package/dist/oauth/oauth.errors.d.ts.map +1 -1
- package/dist/oauth/oauth.errors.js +9 -1
- package/dist/oauth/oauth.errors.js.map +1 -1
- package/dist/oauth/oauth.module.d.ts.map +1 -1
- package/dist/oauth/oauth.module.js +6 -1
- package/dist/oauth/oauth.module.js.map +1 -1
- package/dist/oauth/oauth.service.d.ts +25 -5
- package/dist/oauth/oauth.service.d.ts.map +1 -1
- package/dist/oauth/oauth.service.js +63 -27
- package/dist/oauth/oauth.service.js.map +1 -1
- package/dist/oauth/providers/abstract.provider.d.ts +10 -0
- package/dist/oauth/providers/abstract.provider.d.ts.map +1 -1
- package/dist/oauth/providers/abstract.provider.js +39 -12
- package/dist/oauth/providers/abstract.provider.js.map +1 -1
- package/dist/oauth/providers/github.provider.d.ts +1 -1
- package/dist/oauth/providers/github.provider.d.ts.map +1 -1
- package/dist/oauth/providers/github.provider.js +48 -22
- package/dist/oauth/providers/github.provider.js.map +1 -1
- package/dist/oauth/providers/microsoft-entra-id.provider.d.ts +6 -0
- package/dist/oauth/providers/microsoft-entra-id.provider.d.ts.map +1 -1
- package/dist/oauth/providers/microsoft-entra-id.provider.js +36 -4
- package/dist/oauth/providers/microsoft-entra-id.provider.js.map +1 -1
- package/dist/observability/monitored-cron.d.ts +29 -12
- package/dist/observability/monitored-cron.d.ts.map +1 -1
- package/dist/observability/monitored-cron.js +131 -46
- package/dist/observability/monitored-cron.js.map +1 -1
- package/dist/pairing/pairing.service.d.ts +6 -2
- package/dist/pairing/pairing.service.d.ts.map +1 -1
- package/dist/pdf/document/charts/chart-bar.d.ts +24 -0
- package/dist/pdf/document/charts/chart-bar.d.ts.map +1 -0
- package/dist/pdf/document/charts/chart-bar.js +117 -0
- package/dist/pdf/document/charts/chart-bar.js.map +1 -0
- package/dist/pdf/document/charts/chart-donut.d.ts +16 -0
- package/dist/pdf/document/charts/chart-donut.d.ts.map +1 -0
- package/dist/pdf/document/charts/chart-donut.js +89 -0
- package/dist/pdf/document/charts/chart-donut.js.map +1 -0
- package/dist/pdf/document/charts/chart-gauge.d.ts +15 -0
- package/dist/pdf/document/charts/chart-gauge.d.ts.map +1 -0
- package/dist/pdf/document/charts/chart-gauge.js +60 -0
- package/dist/pdf/document/charts/chart-gauge.js.map +1 -0
- package/dist/pdf/document/charts/chart-line.d.ts +29 -0
- package/dist/pdf/document/charts/chart-line.d.ts.map +1 -0
- package/dist/pdf/document/charts/chart-line.js +89 -0
- package/dist/pdf/document/charts/chart-line.js.map +1 -0
- package/dist/pdf/document/charts/chart-primitives.d.ts +64 -0
- package/dist/pdf/document/charts/chart-primitives.d.ts.map +1 -0
- package/dist/pdf/document/charts/chart-primitives.js +110 -0
- package/dist/pdf/document/charts/chart-primitives.js.map +1 -0
- package/dist/pdf/document/charts/chart-radar.d.ts +13 -0
- package/dist/pdf/document/charts/chart-radar.d.ts.map +1 -0
- package/dist/pdf/document/charts/chart-radar.js +83 -0
- package/dist/pdf/document/charts/chart-radar.js.map +1 -0
- package/dist/pdf/document/charts/chart-scale.d.ts +39 -0
- package/dist/pdf/document/charts/chart-scale.d.ts.map +1 -0
- package/dist/pdf/document/charts/chart-scale.js +118 -0
- package/dist/pdf/document/charts/chart-scale.js.map +1 -0
- package/dist/pdf/document/charts/index.d.ts +8 -0
- package/dist/pdf/document/charts/index.d.ts.map +1 -0
- package/dist/pdf/document/charts/index.js +24 -0
- package/dist/pdf/document/charts/index.js.map +1 -0
- package/dist/pdf/document/index.d.ts +8 -0
- package/dist/pdf/document/index.d.ts.map +1 -0
- package/dist/pdf/document/index.js +24 -0
- package/dist/pdf/document/index.js.map +1 -0
- package/dist/pdf/document/pdf-document.chrome.d.ts +20 -0
- package/dist/pdf/document/pdf-document.chrome.d.ts.map +1 -0
- package/dist/pdf/document/pdf-document.chrome.js +36 -0
- package/dist/pdf/document/pdf-document.chrome.js.map +1 -0
- package/dist/pdf/document/pdf-document.css.d.ts +20 -0
- package/dist/pdf/document/pdf-document.css.d.ts.map +1 -0
- package/dist/pdf/document/pdf-document.css.js +239 -0
- package/dist/pdf/document/pdf-document.css.js.map +1 -0
- package/dist/pdf/document/pdf-document.renderer.d.ts +10 -0
- package/dist/pdf/document/pdf-document.renderer.d.ts.map +1 -0
- package/dist/pdf/document/pdf-document.renderer.js +153 -0
- package/dist/pdf/document/pdf-document.renderer.js.map +1 -0
- package/dist/pdf/document/pdf-document.service.d.ts +27 -0
- package/dist/pdf/document/pdf-document.service.d.ts.map +1 -0
- package/dist/pdf/document/pdf-document.service.js +81 -0
- package/dist/pdf/document/pdf-document.service.js.map +1 -0
- package/dist/pdf/document/pdf-document.theme.d.ts +41 -0
- package/dist/pdf/document/pdf-document.theme.d.ts.map +1 -0
- package/dist/pdf/document/pdf-document.theme.js +105 -0
- package/dist/pdf/document/pdf-document.theme.js.map +1 -0
- package/dist/pdf/document/pdf-document.types.d.ts +108 -0
- package/dist/pdf/document/pdf-document.types.d.ts.map +1 -0
- package/dist/pdf/document/pdf-document.types.js +18 -0
- package/dist/pdf/document/pdf-document.types.js.map +1 -0
- package/dist/pdf/pdf.module.d.ts.map +1 -1
- package/dist/pdf/pdf.module.js +3 -2
- package/dist/pdf/pdf.module.js.map +1 -1
- package/dist/pdf/pdf.service.d.ts +69 -1
- package/dist/pdf/pdf.service.d.ts.map +1 -1
- package/dist/pdf/pdf.service.js +164 -63
- package/dist/pdf/pdf.service.js.map +1 -1
- package/dist/pdf/templates/commercial-proposal.template.d.ts +96 -0
- package/dist/pdf/templates/commercial-proposal.template.d.ts.map +1 -0
- package/dist/pdf/templates/commercial-proposal.template.js +276 -0
- package/dist/pdf/templates/commercial-proposal.template.js.map +1 -0
- package/dist/profile/dto/change-password.dto.d.ts.map +1 -1
- package/dist/profile/dto/change-password.dto.js +4 -6
- package/dist/profile/dto/change-password.dto.js.map +1 -1
- package/dist/profile/profile.controller.d.ts +1 -1
- package/dist/profile/profile.service.d.ts +1 -1
- package/dist/profile/profile.service.d.ts.map +1 -1
- package/dist/profile/profile.service.js +9 -3
- package/dist/profile/profile.service.js.map +1 -1
- package/dist/realtime/realtime-tick.coalescer.d.ts +34 -0
- package/dist/realtime/realtime-tick.coalescer.d.ts.map +1 -0
- package/dist/realtime/realtime-tick.coalescer.js +60 -0
- package/dist/realtime/realtime-tick.coalescer.js.map +1 -0
- package/dist/realtime/realtime.service.d.ts +2 -0
- package/dist/realtime/realtime.service.d.ts.map +1 -1
- package/dist/realtime/realtime.service.js +22 -2
- package/dist/realtime/realtime.service.js.map +1 -1
- package/dist/redis/redis-kv.service.d.ts +90 -0
- package/dist/redis/redis-kv.service.d.ts.map +1 -0
- package/dist/redis/redis-kv.service.js +247 -0
- package/dist/redis/redis-kv.service.js.map +1 -0
- package/dist/redis/redis-master.d.ts +29 -0
- package/dist/redis/redis-master.d.ts.map +1 -0
- package/dist/redis/redis-master.js +81 -0
- package/dist/redis/redis-master.js.map +1 -0
- package/dist/redis/redis-pubsub.d.ts +12 -0
- package/dist/redis/redis-pubsub.d.ts.map +1 -1
- package/dist/redis/redis-pubsub.js +25 -2
- package/dist/redis/redis-pubsub.js.map +1 -1
- package/dist/redis/redis.module.d.ts +11 -0
- package/dist/redis/redis.module.d.ts.map +1 -0
- package/dist/redis/redis.module.js +30 -0
- package/dist/redis/redis.module.js.map +1 -0
- package/dist/session/session.controller.d.ts +6 -2
- package/dist/session/session.controller.d.ts.map +1 -1
- package/dist/session/session.service.d.ts +118 -15
- package/dist/session/session.service.d.ts.map +1 -1
- package/dist/session/session.service.js +251 -77
- package/dist/session/session.service.js.map +1 -1
- package/dist/setting/favicon.controller.d.ts +26 -0
- package/dist/setting/favicon.controller.d.ts.map +1 -0
- package/dist/setting/favicon.controller.js +130 -0
- package/dist/setting/favicon.controller.js.map +1 -0
- package/dist/setting/setting.controller.d.ts +5 -0
- package/dist/setting/setting.controller.d.ts.map +1 -1
- package/dist/setting/setting.module.d.ts.map +1 -1
- package/dist/setting/setting.module.js +2 -1
- package/dist/setting/setting.module.js.map +1 -1
- package/dist/setting/setting.service.d.ts +7 -0
- package/dist/setting/setting.service.d.ts.map +1 -1
- package/dist/setting/setting.service.js +38 -3
- package/dist/setting/setting.service.js.map +1 -1
- package/dist/task/task.service.d.ts +17 -0
- package/dist/task/task.service.d.ts.map +1 -1
- package/dist/task/task.service.js +48 -13
- package/dist/task/task.service.js.map +1 -1
- package/dist/token/token.service.d.ts +19 -1
- package/dist/token/token.service.d.ts.map +1 -1
- package/dist/token/token.service.js +39 -2
- package/dist/token/token.service.js.map +1 -1
- package/dist/user/user-credential.util.d.ts +10 -0
- package/dist/user/user-credential.util.d.ts.map +1 -1
- package/dist/user/user-credential.util.js +14 -1
- package/dist/user/user-credential.util.js.map +1 -1
- package/dist/user/user.service.d.ts +12 -4
- package/dist/user/user.service.d.ts.map +1 -1
- package/dist/user/user.service.js +2 -11
- package/dist/user/user.service.js.map +1 -1
- package/dist/user/user.sort.d.ts +16 -0
- package/dist/user/user.sort.d.ts.map +1 -0
- package/dist/user/user.sort.js +25 -0
- package/dist/user/user.sort.js.map +1 -0
- package/dist/utils/abbreviate-name.d.ts +13 -0
- package/dist/utils/abbreviate-name.d.ts.map +1 -0
- package/dist/utils/abbreviate-name.js +42 -0
- package/dist/utils/abbreviate-name.js.map +1 -0
- package/dist/utils/date-range-query.dto.d.ts +11 -0
- package/dist/utils/date-range-query.dto.d.ts.map +1 -0
- package/dist/utils/date-range-query.dto.js +63 -0
- package/dist/utils/date-range-query.dto.js.map +1 -0
- package/dist/utils/date-range.d.ts +96 -0
- package/dist/utils/date-range.d.ts.map +1 -0
- package/dist/utils/date-range.js +172 -0
- package/dist/utils/date-range.js.map +1 -0
- package/dist/webhook-integration/webhook-utils.d.ts.map +1 -1
- package/dist/webhook-integration/webhook-utils.js +24 -0
- package/dist/webhook-integration/webhook-utils.js.map +1 -1
- package/dist/whatsapp-sender/whatsapp-recipients.d.ts +49 -0
- package/dist/whatsapp-sender/whatsapp-recipients.d.ts.map +1 -0
- package/dist/whatsapp-sender/whatsapp-recipients.js +66 -0
- package/dist/whatsapp-sender/whatsapp-recipients.js.map +1 -0
- package/dist/whatsapp-sender/whatsapp-sender.service.d.ts +25 -0
- package/dist/whatsapp-sender/whatsapp-sender.service.d.ts.map +1 -1
- package/dist/whatsapp-sender/whatsapp-sender.service.js +71 -7
- package/dist/whatsapp-sender/whatsapp-sender.service.js.map +1 -1
- package/hedhog/data/integration_provider.yaml +9 -0
- package/hedhog/data/integration_type.yaml +12 -0
- package/hedhog/data/locale.yaml +0 -1
- package/hedhog/data/mail.yaml +2 -2
- package/hedhog/data/mail_layout.yaml +6 -3
- package/hedhog/data/menu.yaml +25 -5
- package/hedhog/data/route.yaml +148 -0
- package/hedhog/data/setting_group.yaml +189 -3
- package/hedhog/frontend/app/access-log/page.tsx.ejs +47 -53
- package/hedhog/frontend/app/account/components/active-sessions.tsx.ejs +33 -8
- package/hedhog/frontend/app/account/components/mcp-tokens.tsx.ejs +54 -13
- package/hedhog/frontend/app/account/components/mfa-method-card.tsx.ejs +7 -1
- package/hedhog/frontend/app/account/components/recovery-codes-dialog.tsx.ejs +1 -0
- package/hedhog/frontend/app/account/components/tokens.tsx.ejs +47 -17
- package/hedhog/frontend/app/ai_agent/page.tsx.ejs +46 -5
- package/hedhog/frontend/app/ai_instruction/_components/ai-instruction-form.tsx.ejs +101 -30
- package/hedhog/frontend/app/ai_instruction/_components/ai-instruction-versions.tsx.ejs +24 -8
- package/hedhog/frontend/app/ai_instruction/page.tsx.ejs +80 -15
- package/hedhog/frontend/app/configurations/[slug]/components/image-optimization-action.tsx.ejs +166 -0
- package/hedhog/frontend/app/configurations/[slug]/components/setting-field.test.tsx.ejs +145 -45
- package/hedhog/frontend/app/configurations/[slug]/components/setting-field.tsx.ejs +99 -219
- package/hedhog/frontend/app/configurations/[slug]/page.tsx.ejs +19 -1
- package/hedhog/frontend/app/configurations/layout.tsx.ejs +19 -5
- package/hedhog/frontend/app/dashboard/[slug]/widget-renderer.tsx.ejs +2 -8
- package/hedhog/frontend/app/dashboard/components/dynamic-widget.tsx.ejs +3 -0
- package/hedhog/frontend/app/dashboard/components/widget-wrapper.tsx.ejs +4 -0
- package/hedhog/frontend/app/dashboard/dashboard-home-tabs.tsx.ejs +43 -44
- package/hedhog/frontend/app/dashboard/management/tabs/component-roles-tab.tsx.ejs +41 -3
- package/hedhog/frontend/app/dashboard/management/tabs/components-tab.tsx.ejs +42 -2
- package/hedhog/frontend/app/dashboard/management/tabs/dashboard-roles-tab.tsx.ejs +41 -3
- package/hedhog/frontend/app/dashboard/management/tabs/dashboards-tab.tsx.ejs +39 -4
- package/hedhog/frontend/app/dashboard/management/tabs/items-tab.tsx.ejs +42 -3
- package/hedhog/frontend/app/incidents/page.tsx.ejs +60 -31
- package/hedhog/frontend/app/integration/profiles/page.tsx.ejs +45 -5
- package/hedhog/frontend/app/integrations-webhooks/page.tsx.ejs +92 -15
- package/hedhog/frontend/app/mail/log/page.tsx.ejs +109 -61
- package/hedhog/frontend/app/mail/template/page.tsx.ejs +125 -23
- package/hedhog/frontend/app/mcp_chat/chat-components.tsx.ejs +13 -15
- package/hedhog/frontend/app/mcp_chat/page.tsx.ejs +116 -110
- package/hedhog/frontend/app/message-templates/_components/message-template-sheet.tsx.ejs +245 -0
- package/hedhog/frontend/app/message-templates/_lib/types.ts.ejs +24 -0
- package/hedhog/frontend/app/message-templates/page.tsx.ejs +182 -0
- package/hedhog/frontend/app/pages/_components/page-wizard-sheet.tsx.ejs +1 -0
- package/hedhog/frontend/app/pages/page.tsx.ejs +94 -9
- package/hedhog/frontend/app/roles/menus.tsx.ejs +4 -4
- package/hedhog/frontend/app/roles/routes.tsx.ejs +4 -4
- package/hedhog/frontend/app/roles/users.tsx.ejs +4 -4
- package/hedhog/frontend/app/setting-list/page.tsx.ejs +71 -9
- package/hedhog/frontend/app/users/page.tsx.ejs +77 -67
- package/hedhog/frontend/messages/en.json +237 -37
- package/hedhog/frontend/messages/pt.json +237 -37
- package/hedhog/table/cron_lock.yaml +17 -0
- package/hedhog/table/file.yaml +13 -1
- package/hedhog/table/file_upload_chunk.yaml +23 -0
- package/hedhog/table/file_upload_ticket.yaml +67 -0
- package/hedhog/table/mcp_tool_call_log.yaml +30 -22
- package/hedhog/table/message_template.yaml +33 -0
- package/hedhog/table/setting.yaml +8 -0
- package/hedhog/table/user_session.yaml +36 -1
- package/package.json +5 -3
- package/src/ai/ai-agent.sort.ts +21 -0
- package/src/ai/ai-attachment.fragments.spec.ts +56 -3
- package/src/ai/ai.service.responses.spec.ts +429 -0
- package/src/ai/ai.service.spec.ts +173 -1
- package/src/ai/ai.service.ts +473 -220
- package/src/ai-instruction/ai-instruction.service.ts +32 -28
- package/src/ai-instruction/ai-instruction.sort.ts +32 -0
- package/src/ai-instruction/ai-prompt-resolver.service.spec.ts +44 -0
- package/src/ai-instruction/ai-prompt-resolver.service.ts +29 -0
- package/src/auth/auth.module.ts +8 -1
- package/src/auth/auth.service.spec.ts +108 -1
- package/src/auth/auth.service.ts +59 -5
- package/src/auth/guards/auth.guard.ts +9 -1
- package/src/authorize/authorize.controller.ts +126 -11
- package/src/authorize/authorize.errors.ts +55 -0
- package/src/authorize/authorize.module.ts +6 -1
- package/src/authorize/authorize.service.spec.ts +379 -7
- package/src/authorize/authorize.service.ts +309 -23
- package/src/authorize/dto/authorize-info.dto.ts +21 -3
- package/src/authorize/dto/consent.dto.ts +21 -3
- package/src/authorize/dto/token.dto.ts +24 -2
- package/src/authorize/oauth-exception.filter.ts +58 -0
- package/src/authorize/oauth-metadata.service.ts +67 -0
- package/src/authorize/well-known.controller.spec.ts +84 -0
- package/src/authorize/well-known.controller.ts +96 -0
- package/src/captcha/captcha.service.spec.ts +211 -4
- package/src/captcha/captcha.service.ts +127 -10
- package/src/core.module.ts +9 -0
- package/src/dashboard/dashboard-component-role/dashboard-component-role.service.ts +2 -3
- package/src/dashboard/dashboard-component-role/dashboard-component-role.sort.ts +18 -0
- package/src/dashboard/dashboard-item/dashboard-item.service.ts +2 -3
- package/src/dashboard/dashboard-item/dashboard-item.sort.ts +19 -0
- package/src/dashboard/dashboard-role/dashboard-role.service.ts +2 -3
- package/src/dashboard/dashboard-role/dashboard-role.sort.ts +16 -0
- package/src/document-kit/document-kit.module.ts +12 -0
- package/src/document-kit/document-kit.registry.ts +125 -0
- package/src/document-kit/document-kit.service.spec.ts +156 -0
- package/src/document-kit/document-kit.service.ts +173 -0
- package/src/file/file-upload-ticket.service.spec.ts +422 -0
- package/src/file/file-upload-ticket.service.ts +513 -0
- package/src/file/file.controller.ts +65 -0
- package/src/file/file.module.ts +14 -2
- package/src/file/file.service.spec.ts +262 -1
- package/src/file/file.service.ts +505 -87
- package/src/file/filename-encoding.util.spec.ts +54 -0
- package/src/file/filename-encoding.util.ts +67 -0
- package/src/file/image-optimization.service.spec.ts +156 -19
- package/src/file/image-optimization.service.ts +106 -21
- package/src/file/mcp-file-source.schema.ts +86 -0
- package/src/file/mcp-file-source.service.spec.ts +473 -0
- package/src/file/mcp-file-source.service.ts +445 -0
- package/src/file/mimetype-sniff.util.spec.ts +126 -0
- package/src/file/mimetype-sniff.util.ts +265 -0
- package/src/file/remote-fetch.util.spec.ts +117 -0
- package/src/file/remote-fetch.util.ts +330 -0
- package/src/impersonation/dto/start-impersonation.dto.ts +5 -2
- package/src/impersonation/impersonation.service.spec.ts +24 -1
- package/src/impersonation/impersonation.service.ts +14 -4
- package/src/incident/incident.controller.ts +9 -1
- package/src/incident/incident.service.ts +7 -0
- package/src/index.ts +23 -1
- package/src/integration-profile/integration-profile.secrets.ts +28 -0
- package/src/integration-profile/integration-profile.service.ts +7 -64
- package/src/integration-profile/integration-profile.utils.spec.ts +9 -0
- package/src/integration-profile/integration-profile.utils.ts +5 -5
- package/src/integration-profile/testers/ai.testers.ts +70 -5
- package/src/integration-profile/testers/index.ts +2 -0
- package/src/integration-profile/testers/remaining.testers.spec.ts +144 -1
- package/src/integration-profile/testers/shipping.testers.ts +94 -0
- package/src/integration-profile/testers/tester-coverage.spec.ts +10 -0
- package/src/mail/dto/send.dto.ts +6 -1
- package/src/mail/mail-template.spec.ts +58 -1
- package/src/mail/mail.service.spec.ts +112 -0
- package/src/mail/mail.service.ts +42 -4
- package/src/mail-sent/mail-sent.service.ts +3 -0
- package/src/mail-sent/mail-sent.sort.ts +19 -0
- package/src/mcp/filters/mcp-challenge.filter.spec.ts +76 -0
- package/src/mcp/filters/mcp-challenge.filter.ts +70 -0
- package/src/mcp/guards/mcp-auth.guard.spec.ts +51 -2
- package/src/mcp/guards/mcp-auth.guard.ts +24 -1
- package/src/mcp/guards/mcp-permission.guard.spec.ts +109 -15
- package/src/mcp/guards/mcp-permission.guard.ts +76 -51
- package/src/mcp/mcp-audit.service.spec.ts +107 -0
- package/src/mcp/mcp-audit.service.ts +37 -1
- package/src/mcp/mcp-permission.service.spec.ts +197 -0
- package/src/mcp/mcp-permission.service.ts +184 -0
- package/src/mcp/mcp-server.service.spec.ts +84 -2
- package/src/mcp/mcp-server.service.ts +111 -87
- package/src/mcp/mcp.controller.ts +8 -1
- package/src/mcp/mcp.module.ts +7 -1
- package/src/mcp/tools/core-access-log.mcp-tools.ts +66 -0
- package/src/mcp/tools/core-ai.mcp-tools.ts +1 -1
- package/src/mcp/tools/core-dashboard-items.mcp-tools.ts +1 -1
- package/src/mcp/tools/core-dashboard.mcp-tools.ts +1 -1
- package/src/mcp/tools/core-event-webhooks.mcp-tools.ts +1 -2
- package/src/mcp/tools/core-files.mcp-tools.ts +202 -22
- package/src/mcp/tools/core-integration-events.mcp-tools.ts +1 -1
- package/src/mcp/tools/core-mail-sent.mcp-tools.ts +1 -1
- package/src/mcp/tools/core-mail.mcp-tools.ts +1 -1
- package/src/mcp/tools/core-menus.mcp-tools.ts +1 -2
- package/src/mcp/tools/core-notifications.mcp-tools.ts +0 -1
- package/src/mcp/tools/core-roles.mcp-tools.ts +1 -5
- package/src/mcp/tools/core-routes.mcp-tools.ts +1 -3
- package/src/mcp/tools/core-screens.mcp-tools.ts +1 -3
- package/src/mcp/tools/core-sessions.mcp-tools.ts +0 -2
- package/src/mcp/tools/core-settings.mcp-tools.ts +1 -2
- package/src/mcp/tools/core-users.mcp-tools.ts +1 -1
- package/src/mcp/tools/core-webhooks.mcp-tools.ts +1 -2
- package/src/mcp/types/mcp-context.type.ts +15 -6
- package/src/mcp-chat/mcp-chat.service.ts +8 -0
- package/src/meeting/meeting-provider.registry.ts +201 -0
- package/src/meeting/meeting.constants.ts +74 -0
- package/src/menu/menu.service.spec.ts +89 -0
- package/src/menu/menu.service.ts +29 -11
- package/src/message-template/dto/update-message-template.dto.ts +22 -0
- package/src/message-template/message-template-admin.service.spec.ts +163 -0
- package/src/message-template/message-template-admin.service.ts +239 -0
- package/src/message-template/message-template.controller.ts +52 -0
- package/src/message-template/message-template.module.ts +21 -0
- package/src/message-template/message-template.registry.spec.ts +62 -0
- package/src/message-template/message-template.registry.ts +125 -0
- package/src/message-template/message-template.service.spec.ts +149 -0
- package/src/message-template/message-template.service.ts +149 -0
- package/src/notification/notification.constants.ts +10 -0
- package/src/notification/notification.module.ts +3 -0
- package/src/notification/notification.service.spec.ts +75 -1
- package/src/notification/notification.service.ts +39 -1
- package/src/oauth/oauth-token-broker.service.spec.ts +108 -0
- package/src/oauth/oauth-token-broker.service.ts +129 -2
- package/src/oauth/oauth.controller.ts +0 -1
- package/src/oauth/oauth.errors.ts +7 -0
- package/src/oauth/oauth.module.ts +6 -1
- package/src/oauth/oauth.service.spec.ts +58 -7
- package/src/oauth/oauth.service.ts +71 -32
- package/src/oauth/providers/abstract.provider.spec.ts +192 -0
- package/src/oauth/providers/abstract.provider.ts +46 -14
- package/src/oauth/providers/github.provider.ts +57 -34
- package/src/oauth/providers/microsoft-entra-id.provider.spec.ts +133 -0
- package/src/oauth/providers/microsoft-entra-id.provider.ts +37 -3
- package/src/observability/monitored-cron.spec.ts +164 -31
- package/src/observability/monitored-cron.ts +154 -62
- package/src/pdf/document/charts/chart-bar.ts +217 -0
- package/src/pdf/document/charts/chart-donut.ts +163 -0
- package/src/pdf/document/charts/chart-gauge.ts +94 -0
- package/src/pdf/document/charts/chart-line.ts +159 -0
- package/src/pdf/document/charts/chart-primitives.ts +188 -0
- package/src/pdf/document/charts/chart-radar.ts +136 -0
- package/src/pdf/document/charts/chart-scale.spec.ts +93 -0
- package/src/pdf/document/charts/chart-scale.ts +141 -0
- package/src/pdf/document/charts/charts.spec.ts +157 -0
- package/src/pdf/document/charts/index.ts +7 -0
- package/src/pdf/document/index.ts +7 -0
- package/src/pdf/document/pdf-document.chrome.ts +38 -0
- package/src/pdf/document/pdf-document.css.ts +238 -0
- package/src/pdf/document/pdf-document.renderer.spec.ts +129 -0
- package/src/pdf/document/pdf-document.renderer.ts +215 -0
- package/src/pdf/document/pdf-document.service.ts +77 -0
- package/src/pdf/document/pdf-document.theme.ts +146 -0
- package/src/pdf/document/pdf-document.types.ts +97 -0
- package/src/pdf/pdf.module.ts +3 -2
- package/src/pdf/pdf.service.spec.ts +131 -0
- package/src/pdf/pdf.service.ts +245 -82
- package/src/pdf/templates/commercial-proposal.template.spec.ts +177 -0
- package/src/pdf/templates/commercial-proposal.template.ts +400 -0
- package/src/profile/dto/change-password.dto.ts +25 -7
- package/src/profile/profile.service.spec.ts +97 -0
- package/src/profile/profile.service.ts +9 -3
- package/src/realtime/realtime-tick.coalescer.spec.ts +92 -0
- package/src/realtime/realtime-tick.coalescer.ts +60 -0
- package/src/realtime/realtime.service.spec.ts +33 -0
- package/src/realtime/realtime.service.ts +28 -2
- package/src/redis/redis-kv.service.ts +261 -0
- package/src/redis/redis-master.spec.ts +111 -0
- package/src/redis/redis-master.ts +86 -0
- package/src/redis/redis-pubsub.ts +27 -3
- package/src/redis/redis.module.ts +17 -0
- package/src/session/session.service.spec.ts +121 -42
- package/src/session/session.service.ts +279 -82
- package/src/setting/favicon.controller.spec.ts +92 -0
- package/src/setting/favicon.controller.ts +135 -0
- package/src/setting/setting.module.ts +2 -1
- package/src/setting/setting.service.ts +44 -3
- package/src/task/task.service.spec.ts +41 -0
- package/src/task/task.service.ts +53 -13
- package/src/token/token.service.spec.ts +90 -0
- package/src/token/token.service.ts +48 -2
- package/src/user/user-credential.util.ts +14 -5
- package/src/user/user.service.ts +2 -12
- package/src/user/user.sort.ts +25 -0
- package/src/utils/abbreviate-name.spec.ts +50 -0
- package/src/utils/abbreviate-name.ts +44 -0
- package/src/utils/date-range-query.dto.ts +56 -0
- package/src/utils/date-range.spec.ts +175 -0
- package/src/utils/date-range.ts +246 -0
- package/src/webhook-integration/webhook-utils.spec.ts +67 -0
- package/src/webhook-integration/webhook-utils.ts +26 -0
- package/src/whatsapp-sender/whatsapp-recipients.spec.ts +89 -0
- package/src/whatsapp-sender/whatsapp-recipients.ts +83 -0
- package/src/whatsapp-sender/whatsapp-sender.service.spec.ts +185 -0
- package/src/whatsapp-sender/whatsapp-sender.service.ts +90 -7
- package/hedhog/query/device_pairing_request.sql +0 -46
- package/hedhog/query/impersonation_grant.sql +0 -71
- package/hedhog/query/oauth_authorize_pkce.sql +0 -58
- package/hedhog/query/oauth_mobile_state_token.sql +0 -30
- package/hedhog/query/oauth_web_ref_token.sql +0 -25
|
@@ -82,11 +82,45 @@ describe('MailService', () => {
|
|
|
82
82
|
expect(call('A\r\nB', {})).toBe('A<br/>B');
|
|
83
83
|
});
|
|
84
84
|
|
|
85
|
+
it('preserva as quebras de linha de um documento HTML completo (não injeta <br/> dentro de <style>/<head>)', () => {
|
|
86
|
+
// Bug real: um HTML completo colado em Templates de e-mail (que
|
|
87
|
+
// funciona no preview cru de Campanhas) aparecia quebrado aqui porque
|
|
88
|
+
// toda quebra de linha virava "<br/>" literal mesmo dentro de <style>,
|
|
89
|
+
// invalidando o CSS antes de chegar em renderMailTemplate.
|
|
90
|
+
const fullHtml =
|
|
91
|
+
'<!DOCTYPE html>\n<html>\n<head>\n<style>\n.foo {\n color: red;\n}\n</style>\n</head>\n<body>{{name}}</body>\n</html>';
|
|
92
|
+
const result = call(fullHtml, { name: 'Bob' });
|
|
93
|
+
expect(result).not.toContain('<br/>');
|
|
94
|
+
expect(result).toContain('.foo {\n color: red;\n}');
|
|
95
|
+
expect(result).toContain('Bob');
|
|
96
|
+
});
|
|
97
|
+
|
|
85
98
|
it('lança BadRequestException em sintaxe inválida', () => {
|
|
86
99
|
expect(() => call('{{#if foo}}sem fechar', {})).toThrow(
|
|
87
100
|
BadRequestException,
|
|
88
101
|
);
|
|
89
102
|
});
|
|
103
|
+
|
|
104
|
+
// Bug real: o assunto e texto puro (vira o header `subject:` do e-mail),
|
|
105
|
+
// mas o Handlebars padrao escapa `& < > " ' `` `` como se fosse HTML —
|
|
106
|
+
// uma crase no titulo da tarefa saia como ``` cru na caixa de
|
|
107
|
+
// entrada, e escapava DE NOVO no `<h1>` do corpo (renderMailTemplate),
|
|
108
|
+
// virando `&#x60;`. `escapeHtml: false` e o que os call sites do
|
|
109
|
+
// assunto passam pra evitar isso.
|
|
110
|
+
it('com escapeHtml:false, nao escapa nada — usado no assunto (texto puro)', () => {
|
|
111
|
+
const src = 'Tarefa `{{title}}` & <urgente> "importante"';
|
|
112
|
+
const result = (makeService().service as any).interpolateTemplate(
|
|
113
|
+
src,
|
|
114
|
+
{ title: 'status' },
|
|
115
|
+
{ escapeHtml: false },
|
|
116
|
+
);
|
|
117
|
+
expect(result).toBe('Tarefa `status` & <urgente> "importante"');
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
it('por padrao (sem a opcao) continua escapando — usado no corpo, que e HTML de verdade', () => {
|
|
121
|
+
const result = call('Nome: {{name}}', { name: 'A & B <b>' });
|
|
122
|
+
expect(result).toBe('Nome: A & B <b>');
|
|
123
|
+
});
|
|
90
124
|
});
|
|
91
125
|
|
|
92
126
|
describe('isSettingEnabled', () => {
|
|
@@ -331,6 +365,54 @@ describe('MailService', () => {
|
|
|
331
365
|
).resolves.toEqual({ sent: true, providerMessageId: 'ses-abc' });
|
|
332
366
|
});
|
|
333
367
|
|
|
368
|
+
it('assunto com crase, & e aspas chega cru no e-mail — sem `/& vazando (corpo continua escapando)', async () => {
|
|
369
|
+
const { service, deps } = makeService();
|
|
370
|
+
deps.setting.getSettingValues.mockResolvedValue({
|
|
371
|
+
'configured-mail': 'true',
|
|
372
|
+
} as any);
|
|
373
|
+
// `resolveUserLocale` diferente de 'en' evita o fallback que chama
|
|
374
|
+
// `normalizeLocaleCode(callerLocale)` — sem relação com o bug desta
|
|
375
|
+
// task, só contorna o pacote @hed-hog/api-locale com dist desatualizado
|
|
376
|
+
// neste ambiente (falta o export, dist nao republicado).
|
|
377
|
+
deps.setting.resolveUserLocale.mockResolvedValue('pt');
|
|
378
|
+
jest
|
|
379
|
+
.spyOn(service, 'reloadConfig')
|
|
380
|
+
.mockResolvedValue({ success: true, provider: 'ses', from: 'a@b.com', config: {} });
|
|
381
|
+
deps.prismaService.locale.findUnique.mockResolvedValue({ id: 1, code: 'en' });
|
|
382
|
+
deps.prismaService.mail.findUnique.mockResolvedValue({
|
|
383
|
+
id: 7,
|
|
384
|
+
mail_locale: [
|
|
385
|
+
{
|
|
386
|
+
// A crase literal no template (fora de {{}}) nunca foi escapada
|
|
387
|
+
// pelo Handlebars — quem escapava era o VALOR interpolado da
|
|
388
|
+
// variavel. O bug real tinha a crase dentro do dado (nome da
|
|
389
|
+
// tarefa), entao o teste reproduz isso: a crase mora em `title`,
|
|
390
|
+
// nao no texto fixo do template.
|
|
391
|
+
subject: 'Você foi atribuído à tarefa {{title}} & "urgente"',
|
|
392
|
+
body: 'Título: {{title}}',
|
|
393
|
+
locale: { code: 'en' },
|
|
394
|
+
},
|
|
395
|
+
],
|
|
396
|
+
mail_var: [],
|
|
397
|
+
});
|
|
398
|
+
deps.mailMainService.send.mockResolvedValue({ result: { MessageId: 'ses-abc' } });
|
|
399
|
+
|
|
400
|
+
await service.sendTemplatedMail('en', {
|
|
401
|
+
email: 'a@b.com',
|
|
402
|
+
slug: 's',
|
|
403
|
+
variables: { title: '`status`' },
|
|
404
|
+
} as any);
|
|
405
|
+
|
|
406
|
+
const sentArgs = deps.mailMainService.send.mock.calls[0][0] as { subject: string; body: string };
|
|
407
|
+
expect(sentArgs.subject).toBe('Você foi atribuído à tarefa `status` & "urgente"');
|
|
408
|
+
expect(sentArgs.subject).not.toContain('`');
|
|
409
|
+
expect(sentArgs.subject).not.toContain('&');
|
|
410
|
+
// O corpo e HTML de verdade — a mesma crase, vinda do mesmo dado,
|
|
411
|
+
// continua escapando normalmente ali (nao é dupla checagem à toa: prova
|
|
412
|
+
// que `escapeHtml:false` ficou restrito ao assunto).
|
|
413
|
+
expect(sentArgs.body).toContain('`status`');
|
|
414
|
+
});
|
|
415
|
+
|
|
334
416
|
// O bug que originou esta mudanca: o e-mail saia no idioma do header (ou no
|
|
335
417
|
// `en` de quem nao manda header), ignorando a preferencia do destinatario.
|
|
336
418
|
describe('idioma do destinatario', () => {
|
|
@@ -579,6 +661,36 @@ describe('MailService', () => {
|
|
|
579
661
|
expect(html).toContain('lang="pt"');
|
|
580
662
|
});
|
|
581
663
|
|
|
664
|
+
// Regressao do bug real: assunto com crase saia como ``` cru no
|
|
665
|
+
// assunto do e-mail e `&#x60;` (escape duplo) no <h1> do corpo. O
|
|
666
|
+
// fluxo completo (interpolateTemplate -> renderMailTemplate) precisa
|
|
667
|
+
// produzir cada caractere especial escapado NO MAXIMO uma vez, e so pelo
|
|
668
|
+
// renderMailTemplate — sem o <script> escapando pra HTML executavel.
|
|
669
|
+
it('assunto com crase, &, aspas e <script> nao vaza entidade e nao escapa duas vezes no <h1>', async () => {
|
|
670
|
+
const { service } = makePreviewService();
|
|
671
|
+
|
|
672
|
+
const { html } = await service.preview('pt', {
|
|
673
|
+
subject: 'Tarefa `{{title}}` & "urgente" <script>alert(1)</script>',
|
|
674
|
+
body: '<p>Corpo</p>',
|
|
675
|
+
variables: { title: 'status' },
|
|
676
|
+
});
|
|
677
|
+
|
|
678
|
+
// Crase nunca vira entidade (renderMailTemplate/escapeHtml nem trata
|
|
679
|
+
// crase como caractere especial) — nem ` nem, pior, &#x60;.
|
|
680
|
+
expect(html).not.toContain('#x60;');
|
|
681
|
+
// & e " escapados exatamente uma vez (não &amp; / &quot;).
|
|
682
|
+
expect(html).toContain('&');
|
|
683
|
+
expect(html).not.toContain('&amp;');
|
|
684
|
+
expect(html).not.toContain('&quot;');
|
|
685
|
+
// <script> chega escapado, nunca como tag executável.
|
|
686
|
+
expect(html).not.toContain('<script>alert(1)</script>');
|
|
687
|
+
expect(html).toContain('<script>');
|
|
688
|
+
|
|
689
|
+
expect(html).toContain(
|
|
690
|
+
'<h1>Tarefa `status` & "urgente" <script>alert(1)</script></h1>',
|
|
691
|
+
);
|
|
692
|
+
});
|
|
693
|
+
|
|
582
694
|
it('produz exatamente o mesmo corpo que o envio real', async () => {
|
|
583
695
|
// Esta é a asserção que justifica o endpoint: o preview do admin não pode
|
|
584
696
|
// divergir do e-mail que sai. Os dois caminhos passam pelo mesmo
|
package/src/mail/mail.service.ts
CHANGED
|
@@ -8,9 +8,11 @@ import {
|
|
|
8
8
|
import {
|
|
9
9
|
DEFAULT_PRIMARY_COLOR,
|
|
10
10
|
DEFAULT_PRIMARY_FOREGROUND,
|
|
11
|
+
isFullHtmlDocument,
|
|
11
12
|
MailLayout,
|
|
12
13
|
MailService as MailMainService,
|
|
13
14
|
renderMailTemplate,
|
|
15
|
+
sanitizeAccentColor,
|
|
14
16
|
} from '@hed-hog/api-mail';
|
|
15
17
|
import { PaginationDTO } from '@hed-hog/api-pagination';
|
|
16
18
|
import { PrismaService } from '@hed-hog/api-prisma';
|
|
@@ -508,8 +510,14 @@ export class MailService implements OnModuleInit {
|
|
|
508
510
|
const brandName = await this.mailMainService.getBrandName(app, templateLocale);
|
|
509
511
|
const { primaryColor, primaryForeground } = await this.getThemeVariables();
|
|
510
512
|
const mergedVariables = { brandName, primaryColor, primaryForeground, ...variables };
|
|
511
|
-
const parsedSubject = this.interpolateTemplate(subject, mergedVariables);
|
|
513
|
+
const parsedSubject = this.interpolateTemplate(subject, mergedVariables, { escapeHtml: false });
|
|
512
514
|
const parsedBody = this.interpolateTemplate(body, mergedVariables);
|
|
515
|
+
// A cor da etapa vem do remetente (o commerce manda uma por slug) e chega
|
|
516
|
+
// ate o wrapper, que pinta a barra de destaque. `sanitizeAccentColor`
|
|
517
|
+
// descarta o que nao for `#rrggbb` porque o valor entra num bloco <style>.
|
|
518
|
+
const accentColor = sanitizeAccentColor(
|
|
519
|
+
typeof variables?.accentColor === 'string' ? variables.accentColor : undefined,
|
|
520
|
+
);
|
|
513
521
|
|
|
514
522
|
const sendResult: any = await this.mailMainService.send({
|
|
515
523
|
to: email,
|
|
@@ -517,6 +525,7 @@ export class MailService implements OnModuleInit {
|
|
|
517
525
|
...(resolvedReplyTo ? { replyTo: resolvedReplyTo } : {}),
|
|
518
526
|
subject: parsedSubject,
|
|
519
527
|
body: parsedBody,
|
|
528
|
+
...(accentColor ? { accentColor } : {}),
|
|
520
529
|
mail_id: mail.id,
|
|
521
530
|
// O layout (header/footer) e escolhido por este locale la no api-mail,
|
|
522
531
|
// entao tem que ser o do template escolhido, nao o cru do request.
|
|
@@ -662,12 +671,31 @@ export class MailService implements OnModuleInit {
|
|
|
662
671
|
return mail;
|
|
663
672
|
}
|
|
664
673
|
|
|
674
|
+
/**
|
|
675
|
+
* `escapeHtml` (default true) controla o escape padrao do Handlebars pra
|
|
676
|
+
* `&`, `<`, `>`, `"`, `'` e crase. O corpo e HTML de verdade e precisa dele;
|
|
677
|
+
* o assunto e texto puro (vira o header `subject:` do e-mail e, no corpo,
|
|
678
|
+
* passa de novo por `renderMailTemplate`/`escapeHtml` do `@hed-hog/api-mail`
|
|
679
|
+
* pra virar o `<h1>`) — escapar aqui tambem faria uma crase no assunto virar
|
|
680
|
+
* ``` cru na caixa de entrada, e depois `&#x60;` no `<h1>` (escape
|
|
681
|
+
* duplo). Quem chama pro assunto passa `{ escapeHtml: false }`.
|
|
682
|
+
*/
|
|
665
683
|
private interpolateTemplate(
|
|
666
684
|
source: string,
|
|
667
685
|
data: any,
|
|
686
|
+
{ escapeHtml = true }: { escapeHtml?: boolean } = {},
|
|
668
687
|
): string {
|
|
669
688
|
try {
|
|
670
|
-
|
|
689
|
+
// Um documento HTML completo (<style>/<head>/<script>) tem quebra de
|
|
690
|
+
// linha significativa dentro dessas tags — trocar por <br/> às cegas
|
|
691
|
+
// quebra o CSS/HTML (renderMailTemplate já pula o wrapper pra esse
|
|
692
|
+
// caso; aqui só espelhamos a mesma detecção pra não mutilar antes
|
|
693
|
+
// disso). Emails simples (sem <html>) continuam ganhando <br/> pra
|
|
694
|
+
// preservar quebras de linha digitadas pelo usuário.
|
|
695
|
+
const normalized = isFullHtmlDocument(source)
|
|
696
|
+
? source
|
|
697
|
+
: source.replace(/(\r\n|\n|\r)/g, '<br/>');
|
|
698
|
+
const template = Handlebars.compile(normalized, { noEscape: !escapeHtml });
|
|
671
699
|
return template(data);
|
|
672
700
|
} catch (error: any) {
|
|
673
701
|
this.logger.error('Handlebars template compilation error:', error);
|
|
@@ -741,7 +769,7 @@ export class MailService implements OnModuleInit {
|
|
|
741
769
|
? (await this.brandAsset.resolveAssetUrl(rawLogoUrl)) || undefined
|
|
742
770
|
: undefined;
|
|
743
771
|
const data = { brandName, primaryColor, primaryForeground, ...(variables || {}) };
|
|
744
|
-
const parsedSubject = subject ? this.interpolateTemplate(subject, data) : '';
|
|
772
|
+
const parsedSubject = subject ? this.interpolateTemplate(subject, data, { escapeHtml: false }) : '';
|
|
745
773
|
const parsedBody = body ? this.interpolateTemplate(body, data) : '';
|
|
746
774
|
|
|
747
775
|
let resolvedLayout: MailLayout | null = null;
|
|
@@ -765,6 +793,11 @@ export class MailService implements OnModuleInit {
|
|
|
765
793
|
brandName,
|
|
766
794
|
primaryColor,
|
|
767
795
|
primaryForeground,
|
|
796
|
+
// Mesma leitura do envio: sem isto a pre-visualizacao do admin mostraria a
|
|
797
|
+
// barra na cor da marca e o e-mail sairia na cor da etapa.
|
|
798
|
+
accentColor: sanitizeAccentColor(
|
|
799
|
+
typeof variables?.accentColor === 'string' ? variables.accentColor : undefined,
|
|
800
|
+
),
|
|
768
801
|
logoUrl,
|
|
769
802
|
lang: locale,
|
|
770
803
|
});
|
|
@@ -792,13 +825,18 @@ export class MailService implements OnModuleInit {
|
|
|
792
825
|
const brandName = await this.mailMainService.getBrandName(undefined, locale);
|
|
793
826
|
const { primaryColor, primaryForeground } = await this.getThemeVariables();
|
|
794
827
|
const mergedVariables = { brandName, primaryColor, primaryForeground, ...(variables || {}) };
|
|
795
|
-
const parsedSubject = this.interpolateTemplate(subject, mergedVariables);
|
|
828
|
+
const parsedSubject = this.interpolateTemplate(subject, mergedVariables, { escapeHtml: false });
|
|
796
829
|
const parsedBody = this.interpolateTemplate(body, mergedVariables);
|
|
797
830
|
|
|
831
|
+
const accentColor = sanitizeAccentColor(
|
|
832
|
+
typeof variables?.accentColor === 'string' ? variables.accentColor : undefined,
|
|
833
|
+
);
|
|
834
|
+
|
|
798
835
|
return this.mailMainService.send({
|
|
799
836
|
to: email,
|
|
800
837
|
subject: parsedSubject,
|
|
801
838
|
body: parsedBody,
|
|
839
|
+
...(accentColor ? { accentColor } : {}),
|
|
802
840
|
mail_id: mail.id,
|
|
803
841
|
from,
|
|
804
842
|
locale,
|
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
import { CreateDTO } from './dto/create.dto';
|
|
13
13
|
import { QueryMailSentListDTO } from './dto/query-mail-sent-list.dto';
|
|
14
14
|
import { UpdateDTO } from './dto/update.dto';
|
|
15
|
+
import { MAIL_SENT_SORT } from './mail-sent.sort';
|
|
15
16
|
|
|
16
17
|
type MailSentUserStatus = 'received' | 'read' | 'error';
|
|
17
18
|
|
|
@@ -186,6 +187,8 @@ export class MailSentService {
|
|
|
186
187
|
},
|
|
187
188
|
},
|
|
188
189
|
},
|
|
190
|
+
undefined,
|
|
191
|
+
{ sort: MAIL_SENT_SORT },
|
|
189
192
|
);
|
|
190
193
|
|
|
191
194
|
const data = (result.data as MailSentWithUsers[]).map((item) => {
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { defineSortable } from '@hed-hog/api-pagination';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Campos ordenáveis de `mail_sent`.
|
|
5
|
+
*
|
|
6
|
+
* "Delivery" (o badge exibido na listagem) fica de fora: é um resumo agregado
|
|
7
|
+
* calculado no service a partir de `mail_sent_user` (to-many), não uma coluna
|
|
8
|
+
* — o Prisma não tem como ordenar por ele.
|
|
9
|
+
*/
|
|
10
|
+
export const MAIL_SENT_SORT = defineSortable(
|
|
11
|
+
{
|
|
12
|
+
subject: true,
|
|
13
|
+
from: true,
|
|
14
|
+
to: true,
|
|
15
|
+
created_at: { initialOrder: 'desc' },
|
|
16
|
+
id: { initialOrder: 'desc' },
|
|
17
|
+
},
|
|
18
|
+
{ default: 'created_at', defaultOrder: 'desc' },
|
|
19
|
+
);
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { afterEach, describe, expect, it, jest } from '@jest/globals';
|
|
2
|
+
import {
|
|
3
|
+
ForbiddenException,
|
|
4
|
+
UnauthorizedException,
|
|
5
|
+
} from '@nestjs/common';
|
|
6
|
+
import { McpChallengeFilter } from './mcp-challenge.filter';
|
|
7
|
+
|
|
8
|
+
const ISSUER = 'https://hub-api.example.com';
|
|
9
|
+
const METADATA_URL = `${ISSUER}/.well-known/oauth-protected-resource/mcp`;
|
|
10
|
+
|
|
11
|
+
const makeFilter = () => {
|
|
12
|
+
const metadata = { getIssuer: jest.fn<any>().mockResolvedValue(ISSUER) };
|
|
13
|
+
const response: any = {
|
|
14
|
+
setHeader: jest.fn(),
|
|
15
|
+
status: jest.fn().mockReturnThis(),
|
|
16
|
+
json: jest.fn().mockReturnThis(),
|
|
17
|
+
};
|
|
18
|
+
const host: any = { switchToHttp: () => ({ getResponse: () => response }) };
|
|
19
|
+
return { filter: new McpChallengeFilter(metadata as any), response, host };
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
describe('McpChallengeFilter', () => {
|
|
23
|
+
afterEach(() => jest.clearAllMocks());
|
|
24
|
+
|
|
25
|
+
// O passo 1 de todo fluxo OAuth de cliente MCP: bater sem token e ler daqui
|
|
26
|
+
// onde estao os metadados do recurso.
|
|
27
|
+
it('desafia o 401 com resource_metadata', async () => {
|
|
28
|
+
const { filter, response, host } = makeFilter();
|
|
29
|
+
|
|
30
|
+
await filter.catch(new UnauthorizedException('Access denied.'), host);
|
|
31
|
+
|
|
32
|
+
expect(response.setHeader).toHaveBeenCalledWith(
|
|
33
|
+
'WWW-Authenticate',
|
|
34
|
+
`Bearer resource_metadata="${METADATA_URL}", error="invalid_token"`,
|
|
35
|
+
);
|
|
36
|
+
expect(response.status).toHaveBeenCalledWith(401);
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
it('pede reautorizacao quando falta o escopo mcp', async () => {
|
|
40
|
+
const { filter, response, host } = makeFilter();
|
|
41
|
+
|
|
42
|
+
await filter.catch(
|
|
43
|
+
new ForbiddenException("MCP: token is missing the 'mcp' scope"),
|
|
44
|
+
host,
|
|
45
|
+
);
|
|
46
|
+
|
|
47
|
+
const [, value] = response.setHeader.mock.calls[0];
|
|
48
|
+
expect(value).toContain('error="insufficient_scope"');
|
|
49
|
+
expect(value).toContain('scope="mcp"');
|
|
50
|
+
expect(response.status).toHaveBeenCalledWith(403);
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
// 403 por falta de papel numa tool nao se resolve reautorizando: mandar
|
|
54
|
+
// insufficient_scope poria o cliente num laco de reautorizacao sem fim.
|
|
55
|
+
it('nao desafia 403 de permissao de tool', async () => {
|
|
56
|
+
const { filter, response, host } = makeFilter();
|
|
57
|
+
|
|
58
|
+
await filter.catch(
|
|
59
|
+
new ForbiddenException("Access denied to MCP tool 'core.users.list'"),
|
|
60
|
+
host,
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
expect(response.setHeader).not.toHaveBeenCalled();
|
|
64
|
+
expect(response.status).toHaveBeenCalledWith(403);
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
it('preserva o corpo original da excecao', async () => {
|
|
68
|
+
const { filter, response, host } = makeFilter();
|
|
69
|
+
|
|
70
|
+
await filter.catch(new UnauthorizedException('Access denied.'), host);
|
|
71
|
+
|
|
72
|
+
expect(response.json).toHaveBeenCalledWith(
|
|
73
|
+
expect.objectContaining({ message: 'Access denied.' }),
|
|
74
|
+
);
|
|
75
|
+
});
|
|
76
|
+
});
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ArgumentsHost,
|
|
3
|
+
Catch,
|
|
4
|
+
ExceptionFilter,
|
|
5
|
+
HttpException,
|
|
6
|
+
HttpStatus,
|
|
7
|
+
} from '@nestjs/common';
|
|
8
|
+
import { Response } from 'express';
|
|
9
|
+
import { OAuthMetadataService } from '../../authorize/oauth-metadata.service';
|
|
10
|
+
import { MCP_SCOPE } from '../guards/mcp-auth.guard';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* O desafio `WWW-Authenticate` do /mcp — o primeiro passo de todo fluxo OAuth de
|
|
14
|
+
* um cliente MCP (RFC 9728 §5.1): ele bate sem token, lê deste cabeçalho onde
|
|
15
|
+
* estão os metadados do recurso, e só então sabe a quem pedir autorização.
|
|
16
|
+
*
|
|
17
|
+
* Precisa ser um ExceptionFilter, e não um trecho dentro do McpAuthGuard, porque
|
|
18
|
+
* o caso que mais importa nem chega ao McpAuthGuard: numa requisição SEM token,
|
|
19
|
+
* quem lança o 401 é o AuthGuard global, que roda antes. Um filtro declarado no
|
|
20
|
+
* controller captura tambem o que os guards lançam, e por isso cobre os dois.
|
|
21
|
+
*/
|
|
22
|
+
@Catch(HttpException)
|
|
23
|
+
export class McpChallengeFilter implements ExceptionFilter {
|
|
24
|
+
constructor(private readonly metadata: OAuthMetadataService) {}
|
|
25
|
+
|
|
26
|
+
async catch(exception: HttpException, host: ArgumentsHost): Promise<void> {
|
|
27
|
+
const ctx = host.switchToHttp();
|
|
28
|
+
const response = ctx.getResponse<Response>();
|
|
29
|
+
const status = exception.getStatus();
|
|
30
|
+
|
|
31
|
+
if (status === HttpStatus.UNAUTHORIZED) {
|
|
32
|
+
response.setHeader(
|
|
33
|
+
'WWW-Authenticate',
|
|
34
|
+
`Bearer resource_metadata="${await this.resourceMetadataUrl()}", error="invalid_token"`,
|
|
35
|
+
);
|
|
36
|
+
} else if (status === HttpStatus.FORBIDDEN) {
|
|
37
|
+
// 403 aqui pode ser falta de escopo (o token não foi autorizado para o MCP)
|
|
38
|
+
// ou falta de papel numa tool específica. Só o primeiro é recuperável por
|
|
39
|
+
// uma nova autorização, e é o único que ganha o desafio de escopo — mandar
|
|
40
|
+
// `insufficient_scope` no segundo caso faria o cliente entrar num laço de
|
|
41
|
+
// reautorização que nunca resolve.
|
|
42
|
+
if (this.isScopeError(exception)) {
|
|
43
|
+
response.setHeader(
|
|
44
|
+
'WWW-Authenticate',
|
|
45
|
+
`Bearer error="insufficient_scope", scope="${MCP_SCOPE}", resource_metadata="${await this.resourceMetadataUrl()}"`,
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const body = exception.getResponse();
|
|
51
|
+
response
|
|
52
|
+
.status(status)
|
|
53
|
+
.json(
|
|
54
|
+
typeof body === 'string'
|
|
55
|
+
? { statusCode: status, message: body }
|
|
56
|
+
: body,
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
private isScopeError(exception: HttpException): boolean {
|
|
61
|
+
const body = exception.getResponse() as any;
|
|
62
|
+
const message =
|
|
63
|
+
typeof body === 'string' ? body : String(body?.message ?? '');
|
|
64
|
+
return message.includes(`'${MCP_SCOPE}' scope`);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
private async resourceMetadataUrl(): Promise<string> {
|
|
68
|
+
return `${await this.metadata.getIssuer()}/.well-known/oauth-protected-resource/mcp`;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { describe, it, expect, beforeEach, afterEach, jest } from '@jest/globals';
|
|
2
|
-
import { UnauthorizedException } from '@nestjs/common';
|
|
2
|
+
import { ForbiddenException, UnauthorizedException } from '@nestjs/common';
|
|
3
3
|
import { McpAuthGuard } from './mcp-auth.guard';
|
|
4
4
|
|
|
5
5
|
const makeContext = (request: any) => ({
|
|
@@ -10,14 +10,20 @@ const makeDeps = () => {
|
|
|
10
10
|
const tokenService = { verify: jest.fn() };
|
|
11
11
|
const prisma = { mcp_api_key: { findFirst: jest.fn(), update: jest.fn() } };
|
|
12
12
|
const security = { hashWithPepper: jest.fn().mockReturnValue('hash') };
|
|
13
|
-
|
|
13
|
+
const oauthMetadata = {
|
|
14
|
+
getMcpResource: jest.fn<any>().mockResolvedValue(MCP_RESOURCE),
|
|
15
|
+
};
|
|
16
|
+
return { tokenService, prisma, security, oauthMetadata };
|
|
14
17
|
};
|
|
15
18
|
|
|
19
|
+
const MCP_RESOURCE = 'https://hub-api.example.com/mcp';
|
|
20
|
+
|
|
16
21
|
const makeService = (deps = makeDeps()) => ({
|
|
17
22
|
guard: new McpAuthGuard(
|
|
18
23
|
deps.tokenService as any,
|
|
19
24
|
deps.prisma as any,
|
|
20
25
|
deps.security as any,
|
|
26
|
+
deps.oauthMetadata as any,
|
|
21
27
|
),
|
|
22
28
|
deps,
|
|
23
29
|
});
|
|
@@ -40,6 +46,49 @@ describe('McpAuthGuard', () => {
|
|
|
40
46
|
true,
|
|
41
47
|
);
|
|
42
48
|
expect(request.auth).toEqual({ sub: 4 });
|
|
49
|
+
// O recurso e passado para o verify — e dele que sai a recusa de um token
|
|
50
|
+
// emitido para outra audiencia.
|
|
51
|
+
expect(deps.tokenService.verify).toHaveBeenCalledWith(
|
|
52
|
+
expect.anything(),
|
|
53
|
+
'tok',
|
|
54
|
+
MCP_RESOURCE,
|
|
55
|
+
);
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
it('aceita token OAuth que traz o escopo mcp', async () => {
|
|
59
|
+
const { guard, deps } = makeService();
|
|
60
|
+
deps.tokenService.verify.mockResolvedValue({
|
|
61
|
+
sub: 4,
|
|
62
|
+
aud: MCP_RESOURCE,
|
|
63
|
+
scope: 'mcp',
|
|
64
|
+
});
|
|
65
|
+
const request: any = { headers: { authorization: 'Bearer tok' } };
|
|
66
|
+
await expect(guard.canActivate(makeContext(request) as any)).resolves.toBe(
|
|
67
|
+
true,
|
|
68
|
+
);
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
it('nega token OAuth sem o escopo mcp', async () => {
|
|
72
|
+
const { guard, deps } = makeService();
|
|
73
|
+
deps.tokenService.verify.mockResolvedValue({
|
|
74
|
+
sub: 4,
|
|
75
|
+
aud: MCP_RESOURCE,
|
|
76
|
+
scope: 'profile',
|
|
77
|
+
});
|
|
78
|
+
const request: any = { headers: { authorization: 'Bearer tok' } };
|
|
79
|
+
await expect(
|
|
80
|
+
guard.canActivate(makeContext(request) as any),
|
|
81
|
+
).rejects.toThrow(ForbiddenException);
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
// O JWT de login nunca teve `scope`; exigi-lo quebraria o uso interno do /mcp.
|
|
85
|
+
it('nao exige escopo de token sem audiencia', async () => {
|
|
86
|
+
const { guard, deps } = makeService();
|
|
87
|
+
deps.tokenService.verify.mockResolvedValue({ sub: 4 });
|
|
88
|
+
const request: any = { headers: { authorization: 'Bearer tok' } };
|
|
89
|
+
await expect(guard.canActivate(makeContext(request) as any)).resolves.toBe(
|
|
90
|
+
true,
|
|
91
|
+
);
|
|
43
92
|
});
|
|
44
93
|
|
|
45
94
|
it('autentica com api key mcp válida', async () => {
|
|
@@ -2,19 +2,24 @@ import { PrismaService } from '@hed-hog/api-prisma';
|
|
|
2
2
|
import {
|
|
3
3
|
CanActivate,
|
|
4
4
|
ExecutionContext,
|
|
5
|
+
ForbiddenException,
|
|
5
6
|
Injectable,
|
|
6
7
|
UnauthorizedException,
|
|
7
8
|
} from '@nestjs/common';
|
|
8
9
|
import { Request } from 'express';
|
|
10
|
+
import { MCP_SCOPE, OAuthMetadataService } from '../../authorize/oauth-metadata.service';
|
|
9
11
|
import { SecurityService } from '../../security/security.service';
|
|
10
12
|
import { TokenService } from '../../token/token.service';
|
|
11
13
|
|
|
14
|
+
export { MCP_SCOPE };
|
|
15
|
+
|
|
12
16
|
@Injectable()
|
|
13
17
|
export class McpAuthGuard implements CanActivate {
|
|
14
18
|
constructor(
|
|
15
19
|
private readonly tokenService: TokenService,
|
|
16
20
|
private readonly prisma: PrismaService,
|
|
17
21
|
private readonly security: SecurityService,
|
|
22
|
+
private readonly oauthMetadata: OAuthMetadataService,
|
|
18
23
|
) {}
|
|
19
24
|
|
|
20
25
|
async canActivate(context: ExecutionContext): Promise<boolean> {
|
|
@@ -31,7 +36,25 @@ export class McpAuthGuard implements CanActivate {
|
|
|
31
36
|
return this.verifyApiKey(request, token);
|
|
32
37
|
}
|
|
33
38
|
|
|
34
|
-
|
|
39
|
+
const payload = await this.tokenService.verify(
|
|
40
|
+
locale,
|
|
41
|
+
token,
|
|
42
|
+
await this.oauthMetadata.getMcpResource(),
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
// Token emitido pelo fluxo OAuth carrega `scope`; o JWT de login, nao. So o
|
|
46
|
+
// primeiro precisa provar que o usuario consentiu com o acesso ao MCP — exigir
|
|
47
|
+
// escopo de um token de sessao quebraria o uso interno, que nunca teve escopo.
|
|
48
|
+
if (payload.aud !== undefined) {
|
|
49
|
+
const scopes = String(payload.scope ?? '').split(/\s+/).filter(Boolean);
|
|
50
|
+
if (!scopes.includes(MCP_SCOPE)) {
|
|
51
|
+
throw new ForbiddenException(
|
|
52
|
+
`MCP: token is missing the '${MCP_SCOPE}' scope`,
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
request['auth'] = payload;
|
|
35
58
|
return true;
|
|
36
59
|
}
|
|
37
60
|
|