@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
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { parseWhatsappRecipients, toWhatsappGroupJid } from './whatsapp-recipients';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* O que este parser decide é para ONDE um aviso interno vai. Errar aqui não dá
|
|
5
|
+
* erro: entrega em outro número, ou some em silêncio — os dois modos de falha
|
|
6
|
+
* que o canal existe para evitar.
|
|
7
|
+
*/
|
|
8
|
+
describe('toWhatsappGroupJid', () => {
|
|
9
|
+
it('aceita a forma atual, só dígitos com sufixo', () => {
|
|
10
|
+
expect(toWhatsappGroupJid('120363430651137530@g.us')).toBe(
|
|
11
|
+
'120363430651137530@g.us',
|
|
12
|
+
);
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
it('aceita a forma antiga, derivada de quem criou o grupo', () => {
|
|
16
|
+
expect(toWhatsappGroupJid('5511992662104-1564082267@g.us')).toBe(
|
|
17
|
+
'5511992662104-1564082267@g.us',
|
|
18
|
+
);
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
it('completa o sufixo de um id colado sem ele', () => {
|
|
22
|
+
expect(toWhatsappGroupJid('120363430651137530')).toBe(
|
|
23
|
+
'120363430651137530@g.us',
|
|
24
|
+
);
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
it('não confunde telefone com grupo', () => {
|
|
28
|
+
expect(toWhatsappGroupJid('5511999998888')).toBeNull();
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
it('descarta a colagem de dois telefones grudados', () => {
|
|
32
|
+
expect(toWhatsappGroupJid('5511999998888551199999777')).toBeNull();
|
|
33
|
+
});
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
describe('parseWhatsappRecipients', () => {
|
|
37
|
+
it('devolve lista vazia para configuração ausente', () => {
|
|
38
|
+
expect(parseWhatsappRecipients(null)).toEqual([]);
|
|
39
|
+
expect(parseWhatsappRecipients('')).toEqual([]);
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
it('completa o DDI 55 de um número nacional com máscara', () => {
|
|
43
|
+
expect(parseWhatsappRecipients('(11) 99999-8888')).toEqual([
|
|
44
|
+
{ to: '5511999998888', targetType: 'phone' },
|
|
45
|
+
]);
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
it('não acrescenta DDI a quem já veio com um', () => {
|
|
49
|
+
expect(parseWhatsappRecipients('5511999998888')).toEqual([
|
|
50
|
+
{ to: '5511999998888', targetType: 'phone' },
|
|
51
|
+
]);
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it('separa por vírgula, ponto-e-vírgula e quebra de linha, nunca por espaço', () => {
|
|
55
|
+
// Espaço faz parte da máscara: quebrar ali produziria `+55`, `(11)` e
|
|
56
|
+
// `3333-4444`, todos descartados, e a lista sumiria em silêncio.
|
|
57
|
+
expect(
|
|
58
|
+
parseWhatsappRecipients(
|
|
59
|
+
'+55 (11) 3333-4444, 5511999998888;\n120363430651137530@g.us',
|
|
60
|
+
),
|
|
61
|
+
).toEqual([
|
|
62
|
+
{ to: '551133334444', targetType: 'phone' },
|
|
63
|
+
{ to: '5511999998888', targetType: 'phone' },
|
|
64
|
+
{ to: '120363430651137530@g.us', targetType: 'group' },
|
|
65
|
+
]);
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
it('conta uma vez só o mesmo destino escrito de duas formas', () => {
|
|
69
|
+
expect(
|
|
70
|
+
parseWhatsappRecipients('(11) 99999-8888, 5511999998888'),
|
|
71
|
+
).toHaveLength(1);
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
it('descarta o que não é telefone nem grupo', () => {
|
|
75
|
+
// Menos de 10 dígitos não tem DDD, e acima de 20 nem grupo é: a faixa entre
|
|
76
|
+
// 16 e 20 pertence ao id de grupo colado sem o sufixo `@g.us`.
|
|
77
|
+
expect(
|
|
78
|
+
parseWhatsappRecipients('123, abc, 123456789012345678901'),
|
|
79
|
+
).toEqual([]);
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
it('16 a 20 dígitos é id de grupo, não telefone longo demais', () => {
|
|
83
|
+
// O descarte silencioso por "longo demais" é justamente o modo de falha que
|
|
84
|
+
// este canal combate: quem cola o id do painel da Evolution não recebe erro.
|
|
85
|
+
expect(parseWhatsappRecipients('1203634306511375')).toEqual([
|
|
86
|
+
{ to: '1203634306511375@g.us', targetType: 'group' },
|
|
87
|
+
]);
|
|
88
|
+
});
|
|
89
|
+
});
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { WhatsappTargetType } from './whatsapp-sender.service';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Destino de um aviso interno por WhatsApp: celular ou grupo.
|
|
5
|
+
*
|
|
6
|
+
* Mora no core, e nao na library que avisa, porque ja sao duas a ler a mesma
|
|
7
|
+
* lista digitada a mao — o SAC, para o grupo do atendimento, e o commerce, para
|
|
8
|
+
* os grupos de venda. Reconhecedor de JID de grupo duplicado e como as duas
|
|
9
|
+
* divergem: uma passa a aceitar o id sem sufixo e a outra nao, e o destino some
|
|
10
|
+
* em silencio no modulo que ficou para tras.
|
|
11
|
+
*/
|
|
12
|
+
export type WhatsappRecipient = {
|
|
13
|
+
to: string;
|
|
14
|
+
targetType: WhatsappTargetType;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Id de grupo do WhatsApp (`...@g.us`), ou null quando o item nao e grupo.
|
|
19
|
+
*
|
|
20
|
+
* Grupo tem duas formas: a atual, so digitos (`120363...@g.us`), e a antiga,
|
|
21
|
+
* derivada de quem criou o grupo (`5511999998888-1564082267@g.us`). As duas
|
|
22
|
+
* saem do painel da Evolution ja com o sufixo.
|
|
23
|
+
*
|
|
24
|
+
* Sem sufixo tambem vale: um id colado do painel tem 18 digitos, e acima do teto
|
|
25
|
+
* do E.164 (15) nao existe telefone — a alternativa seria o descarte silencioso
|
|
26
|
+
* por "longo demais", que e o modo de falha que este canal combate. O corte em
|
|
27
|
+
* 20 digitos deixa de fora a colagem de dois telefones grudados, que nao e
|
|
28
|
+
* destino nenhum.
|
|
29
|
+
*/
|
|
30
|
+
export function toWhatsappGroupJid(value: string): string | null {
|
|
31
|
+
const match = /^(\d{5,}(?:-\d{5,})?)@g\.us$/i.exec(value);
|
|
32
|
+
if (match) return `${match[1]}@g.us`;
|
|
33
|
+
|
|
34
|
+
return /^\d{16,20}$/.test(value) ? `${value}@g.us` : null;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Destinos de WhatsApp de uma lista digitada a mao: celulares e grupos.
|
|
39
|
+
*
|
|
40
|
+
* Nao da para reusar um `split` de e-mail: `WhatsappSenderService.normalizeTarget`
|
|
41
|
+
* apenas remove os nao-digitos e **nao acrescenta DDI**. Um `(11) 99999-8888`
|
|
42
|
+
* digitado no admin viraria `11999998888`, um numero que o provedor aceita e
|
|
43
|
+
* entrega em outro lugar — falha silenciosa, que e exatamente o que este canal
|
|
44
|
+
* existe para evitar. Por isso o DDI 55 e completado aqui quando o que sobrou
|
|
45
|
+
* tem cara de numero nacional (DDD + 8 ou 9 digitos).
|
|
46
|
+
*
|
|
47
|
+
* A separacao e so por virgula, ponto-e-virgula e quebra de linha — nao por
|
|
48
|
+
* espaco. Espaco faz parte da mascara de um telefone (`+55 (11) 3333-4444`), e
|
|
49
|
+
* quebrar ali produziria os fragmentos `+55`, `(11)` e `3333-4444`, todos
|
|
50
|
+
* descartados: a lista inteira sumiria em silencio.
|
|
51
|
+
*
|
|
52
|
+
* Menos de 10 digitos nao e telefone com DDD, e mais de 15 nao e telefone nenhum
|
|
53
|
+
* (o teto do E.164) — normalmente sao dois numeros que alguem separou so com
|
|
54
|
+
* espaco. Descartar e melhor que enviar para um numero inventado.
|
|
55
|
+
*/
|
|
56
|
+
export function parseWhatsappRecipients(
|
|
57
|
+
raw: string | null | undefined,
|
|
58
|
+
): WhatsappRecipient[] {
|
|
59
|
+
if (!raw) return [];
|
|
60
|
+
|
|
61
|
+
// Map, e nao Set: o mesmo destino escrito de duas formas continua contando uma
|
|
62
|
+
// vez so, e o tipo precisa vir junto do valor.
|
|
63
|
+
const seen = new Map<string, WhatsappRecipient>();
|
|
64
|
+
|
|
65
|
+
for (const item of raw.split(/[,;\n]+/)) {
|
|
66
|
+
const value = item.trim();
|
|
67
|
+
if (!value) continue;
|
|
68
|
+
|
|
69
|
+
const group = toWhatsappGroupJid(value);
|
|
70
|
+
|
|
71
|
+
if (group) {
|
|
72
|
+
seen.set(group, { to: group, targetType: 'group' });
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const digits = value.replace(/\D+/g, '');
|
|
77
|
+
if (digits.length < 10 || digits.length > 15) continue;
|
|
78
|
+
const phone = digits.length <= 11 ? `55${digits}` : digits;
|
|
79
|
+
seen.set(phone, { to: phone, targetType: 'phone' });
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return [...seen.values()];
|
|
83
|
+
}
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
import {
|
|
2
|
+
WhatsappSendError,
|
|
3
|
+
WhatsappSenderService,
|
|
4
|
+
} from './whatsapp-sender.service';
|
|
5
|
+
|
|
6
|
+
describe('WhatsappSenderService', () => {
|
|
7
|
+
const buildService = (providerSlug: string) => {
|
|
8
|
+
const prisma = {
|
|
9
|
+
integration_profile: {
|
|
10
|
+
findUnique: jest.fn().mockResolvedValue({
|
|
11
|
+
id: 7,
|
|
12
|
+
slug: 'whatsapp-api-hcode',
|
|
13
|
+
config: { access_token: 'token', phone_number_id: '109371452' },
|
|
14
|
+
integration_provider: { slug: providerSlug },
|
|
15
|
+
integration_type: { slug: 'whatsapp' },
|
|
16
|
+
}),
|
|
17
|
+
findFirst: jest.fn(),
|
|
18
|
+
},
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
return { prisma, service: new WhatsappSenderService(prisma as any) };
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
describe('normalizeTarget', () => {
|
|
25
|
+
it('preserva o sufixo do grupo, que um strip de digitos destruiria', () => {
|
|
26
|
+
const { service } = buildService('evolution-api');
|
|
27
|
+
|
|
28
|
+
expect(
|
|
29
|
+
service.normalizeTarget('120363430651137530@g.us', 'group'),
|
|
30
|
+
).toBe('120363430651137530@g.us');
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
it('reduz o telefone a digitos', () => {
|
|
34
|
+
const { service } = buildService('evolution-api');
|
|
35
|
+
|
|
36
|
+
expect(service.normalizeTarget('+55 (11) 3333-4444')).toBe(
|
|
37
|
+
'551133334444',
|
|
38
|
+
);
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
// A Cloud API nao tem endpoint de grupo. Sem a guarda, o destino seria
|
|
43
|
+
// reduzido a digitos e a Graph API receberia o id do grupo como telefone.
|
|
44
|
+
describe('grupo no provider oficial', () => {
|
|
45
|
+
let fetchSpy: jest.SpyInstance;
|
|
46
|
+
|
|
47
|
+
beforeEach(() => {
|
|
48
|
+
fetchSpy = jest
|
|
49
|
+
.spyOn(global, 'fetch' as any)
|
|
50
|
+
.mockResolvedValue({ ok: true, json: async () => ({}) } as any);
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
afterEach(() => fetchSpy.mockRestore());
|
|
54
|
+
|
|
55
|
+
it('recusa o envio sem chamar a Graph API', async () => {
|
|
56
|
+
const { service } = buildService('whatsapp-official');
|
|
57
|
+
|
|
58
|
+
await expect(
|
|
59
|
+
service.send({
|
|
60
|
+
profileSlug: 'whatsapp-api-hcode',
|
|
61
|
+
to: '120363430651137530@g.us',
|
|
62
|
+
targetType: 'group',
|
|
63
|
+
text: 'Novo chamado',
|
|
64
|
+
}),
|
|
65
|
+
).rejects.toThrow(/não envia mensagem para grupo/);
|
|
66
|
+
|
|
67
|
+
expect(fetchSpy).not.toHaveBeenCalled();
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
it('marca a recusa como permanente, para o job nao insistir', async () => {
|
|
71
|
+
const { service } = buildService('whatsapp-official');
|
|
72
|
+
|
|
73
|
+
const error = await service
|
|
74
|
+
.send({
|
|
75
|
+
profileSlug: 'whatsapp-api-hcode',
|
|
76
|
+
to: '120363430651137530@g.us',
|
|
77
|
+
targetType: 'group',
|
|
78
|
+
text: 'Novo chamado',
|
|
79
|
+
})
|
|
80
|
+
.catch((thrown) => thrown);
|
|
81
|
+
|
|
82
|
+
expect(error).toBeInstanceOf(WhatsappSendError);
|
|
83
|
+
expect((error as WhatsappSendError).retryable).toBe(false);
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
it('a Evolution continua entregando no grupo', async () => {
|
|
87
|
+
const { prisma, service } = buildService('evolution-api');
|
|
88
|
+
prisma.integration_profile.findUnique.mockResolvedValue({
|
|
89
|
+
id: 2,
|
|
90
|
+
slug: 'hcode',
|
|
91
|
+
config: {
|
|
92
|
+
host: 'https://evolution.hcode.com.br',
|
|
93
|
+
token: 'apikey',
|
|
94
|
+
instance_name: 'hcode',
|
|
95
|
+
},
|
|
96
|
+
integration_provider: { slug: 'evolution-api' },
|
|
97
|
+
integration_type: { slug: 'whatsapp' },
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
await service.send({
|
|
101
|
+
profileSlug: 'hcode',
|
|
102
|
+
to: '120363430651137530@g.us',
|
|
103
|
+
targetType: 'group',
|
|
104
|
+
text: 'Novo chamado',
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
const [url, init] = fetchSpy.mock.calls[0];
|
|
108
|
+
expect(url).toBe('https://evolution.hcode.com.br/message/sendText/hcode');
|
|
109
|
+
expect(JSON.parse(init.body).number).toBe('120363430651137530@g.us');
|
|
110
|
+
});
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
// O worker so insiste quando a recusa pode mudar; numero sem WhatsApp e dado
|
|
114
|
+
// de cadastro e reprocessaria o job tres vezes a toa.
|
|
115
|
+
describe('recusa da Evolution', () => {
|
|
116
|
+
let fetchSpy: jest.SpyInstance;
|
|
117
|
+
|
|
118
|
+
const buildEvolution = () => {
|
|
119
|
+
const built = buildService('evolution-api');
|
|
120
|
+
built.prisma.integration_profile.findUnique.mockResolvedValue({
|
|
121
|
+
id: 2,
|
|
122
|
+
slug: 'hcode',
|
|
123
|
+
config: {
|
|
124
|
+
host: 'https://evolution.hcode.com.br',
|
|
125
|
+
token: 'apikey',
|
|
126
|
+
instance_name: 'hcode',
|
|
127
|
+
},
|
|
128
|
+
integration_provider: { slug: 'evolution-api' },
|
|
129
|
+
integration_type: { slug: 'whatsapp' },
|
|
130
|
+
});
|
|
131
|
+
return built.service;
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
const respond = (status: number, body: unknown) =>
|
|
135
|
+
fetchSpy.mockResolvedValue({
|
|
136
|
+
ok: false,
|
|
137
|
+
status,
|
|
138
|
+
text: async () => JSON.stringify(body),
|
|
139
|
+
} as any);
|
|
140
|
+
|
|
141
|
+
const sendAndCatch = () =>
|
|
142
|
+
buildEvolution()
|
|
143
|
+
.send({ profileSlug: 'hcode', to: '5515991103304', text: 'Oi' })
|
|
144
|
+
.catch((thrown) => thrown);
|
|
145
|
+
|
|
146
|
+
beforeEach(() => {
|
|
147
|
+
fetchSpy = jest.spyOn(global, 'fetch' as any);
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
afterEach(() => fetchSpy.mockRestore());
|
|
151
|
+
|
|
152
|
+
it('numero sem WhatsApp e recusa permanente com mensagem legivel', async () => {
|
|
153
|
+
respond(400, {
|
|
154
|
+
status: 400,
|
|
155
|
+
error: 'Bad Request',
|
|
156
|
+
response: {
|
|
157
|
+
message: [{ jid: '5515991103304@s.whatsapp.net', exists: false, number: '5515991103304' }],
|
|
158
|
+
},
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
const error = await sendAndCatch();
|
|
162
|
+
|
|
163
|
+
expect(error).toBeInstanceOf(WhatsappSendError);
|
|
164
|
+
expect(error.retryable).toBe(false);
|
|
165
|
+
expect(error.message).toMatch(/5515991103304 não tem WhatsApp/);
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
it('outro 4xx tambem e permanente', async () => {
|
|
169
|
+
respond(400, { response: { message: ['text is required'] } });
|
|
170
|
+
|
|
171
|
+
const error = await sendAndCatch();
|
|
172
|
+
|
|
173
|
+
expect(error.retryable).toBe(false);
|
|
174
|
+
expect(error.message).toMatch(/HTTP 400/);
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
it('5xx e 429 podem ser tentados de novo', async () => {
|
|
178
|
+
respond(502, {});
|
|
179
|
+
expect((await sendAndCatch()).retryable).toBe(true);
|
|
180
|
+
|
|
181
|
+
respond(429, {});
|
|
182
|
+
expect((await sendAndCatch()).retryable).toBe(true);
|
|
183
|
+
});
|
|
184
|
+
});
|
|
185
|
+
});
|
|
@@ -35,11 +35,27 @@ export type WhatsappSendInput = {
|
|
|
35
35
|
};
|
|
36
36
|
|
|
37
37
|
type ResolvedProfile = {
|
|
38
|
+
id: number;
|
|
38
39
|
slug: string;
|
|
39
40
|
providerSlug: string;
|
|
40
41
|
config: Record<string, unknown>;
|
|
41
42
|
};
|
|
42
43
|
|
|
44
|
+
/**
|
|
45
|
+
* Erro de envio classificado: `retryable` diz se tentar de novo pode dar
|
|
46
|
+
* resultado diferente. Um HTTP 4xx da Graph API (id inexistente, sem
|
|
47
|
+
* permissão, token ruim) não muda em cinco minutos; um 5xx ou falha de rede
|
|
48
|
+
* pode ser uma instabilidade passageira do provedor.
|
|
49
|
+
*/
|
|
50
|
+
export class WhatsappSendError extends BadRequestException {
|
|
51
|
+
constructor(
|
|
52
|
+
message: string,
|
|
53
|
+
public readonly retryable: boolean,
|
|
54
|
+
) {
|
|
55
|
+
super(message);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
43
59
|
/**
|
|
44
60
|
* Envio de WhatsApp usando um perfil de integração escolhido pelo usuário.
|
|
45
61
|
*
|
|
@@ -92,6 +108,22 @@ export class WhatsappSenderService {
|
|
|
92
108
|
}
|
|
93
109
|
}
|
|
94
110
|
|
|
111
|
+
/**
|
|
112
|
+
* Identidade do perfil que o `send` usaria, sem o `config`.
|
|
113
|
+
*
|
|
114
|
+
* Quem envia pelo provider oficial precisa dizer por qual número a mensagem
|
|
115
|
+
* sai, e cada módulo guarda esse id no próprio cadastro. Para achar o cadastro
|
|
116
|
+
* certo é preciso saber qual perfil foi resolvido — inclusive quando o slug
|
|
117
|
+
* veio vazio e a escolha coube a este serviço. O `config` fica de fora de
|
|
118
|
+
* propósito: é onde moram `access_token` e `app_secret`.
|
|
119
|
+
*/
|
|
120
|
+
async describeProfile(
|
|
121
|
+
profileSlug?: string,
|
|
122
|
+
): Promise<{ id: number; slug: string; providerSlug: string }> {
|
|
123
|
+
const { id, slug, providerSlug } = await this.resolveProfile(profileSlug);
|
|
124
|
+
return { id, slug, providerSlug };
|
|
125
|
+
}
|
|
126
|
+
|
|
95
127
|
/**
|
|
96
128
|
* Normaliza o destino: número vira só dígitos, id de grupo passa intacto
|
|
97
129
|
* (grupos do WhatsApp têm sufixo `@g.us`, que seria destruído por um strip).
|
|
@@ -153,6 +185,7 @@ export class WhatsappSenderService {
|
|
|
153
185
|
}
|
|
154
186
|
|
|
155
187
|
return {
|
|
188
|
+
id: profile.id,
|
|
156
189
|
slug: profile.slug,
|
|
157
190
|
providerSlug: String((profile as any).integration_provider?.slug ?? ''),
|
|
158
191
|
config: ((profile.config ?? {}) as Record<string, unknown>),
|
|
@@ -209,13 +242,27 @@ export class WhatsappSenderService {
|
|
|
209
242
|
const detail = await response.text().catch(() => '');
|
|
210
243
|
|
|
211
244
|
if (response.status === 401) {
|
|
212
|
-
throw new
|
|
245
|
+
throw new WhatsappSendError(
|
|
213
246
|
`Credenciais do WhatsApp inválidas (401). Verifique o token do perfil "${profile.slug}".`,
|
|
247
|
+
false,
|
|
214
248
|
);
|
|
215
249
|
}
|
|
216
250
|
|
|
217
|
-
|
|
251
|
+
// Número sem conta no WhatsApp: a Evolution responde 400 com
|
|
252
|
+
// `exists: false`. É dado do cadastro, não instabilidade — reenviar não
|
|
253
|
+
// muda nada, e o chamador precisa saber disso para não insistir.
|
|
254
|
+
if (isEvolutionNumberMissing(detail)) {
|
|
255
|
+
throw new WhatsappSendError(
|
|
256
|
+
`O número ${target} não tem WhatsApp (Evolution: exists=false).`,
|
|
257
|
+
false,
|
|
258
|
+
);
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
// Mesmo critério do provider oficial: 4xx é recusa estrutural, 5xx e
|
|
262
|
+
// 429 podem passar numa próxima tentativa.
|
|
263
|
+
throw new WhatsappSendError(
|
|
218
264
|
`Evolution API recusou o envio (HTTP ${response.status}): ${detail.slice(0, 300)}`,
|
|
265
|
+
response.status >= 500 || response.status === 429,
|
|
219
266
|
);
|
|
220
267
|
}
|
|
221
268
|
}
|
|
@@ -226,6 +273,19 @@ export class WhatsappSenderService {
|
|
|
226
273
|
): Promise<void> {
|
|
227
274
|
const cfg = buildWhatsappOfficialConfigFromIntegration(profile.config);
|
|
228
275
|
|
|
276
|
+
// A Cloud API da Meta não envia para grupo — não há endpoint para isso. Sem
|
|
277
|
+
// esta guarda o `normalizeTarget(..., 'phone')` logo abaixo arrancaria o
|
|
278
|
+
// sufixo `@g.us` e a Graph API receberia o id do grupo como se fosse um
|
|
279
|
+
// telefone: ou erro genérico de número inválido, ou (pior) entrega a um
|
|
280
|
+
// número que por acaso exista. `retryable: false` porque trocar de provider
|
|
281
|
+
// é decisão de configuração, não instabilidade.
|
|
282
|
+
if (input.targetType === 'group') {
|
|
283
|
+
throw new WhatsappSendError(
|
|
284
|
+
`Perfil de integração "${profile.slug}" usa a Cloud API oficial da Meta, que não envia mensagem para grupo. Use um perfil evolution-api para esse destino.`,
|
|
285
|
+
false,
|
|
286
|
+
);
|
|
287
|
+
}
|
|
288
|
+
|
|
229
289
|
if (!cfg.accessToken) {
|
|
230
290
|
throw new BadRequestException(
|
|
231
291
|
`Perfil de WhatsApp "${profile.slug}" está sem access_token.`,
|
|
@@ -290,22 +350,45 @@ export class WhatsappSenderService {
|
|
|
290
350
|
|
|
291
351
|
if (!response.ok) {
|
|
292
352
|
const payload = (await response.json().catch(() => ({}))) as {
|
|
293
|
-
error?: { message?: string };
|
|
353
|
+
error?: { message?: string; code?: number };
|
|
294
354
|
};
|
|
295
355
|
|
|
296
|
-
|
|
356
|
+
// Código documentado pela Meta para "business-initiated message fora da
|
|
357
|
+
// janela de 24h sem template" (re-engagement). Outros 4xx (id inválido,
|
|
358
|
+
// sem permissão, token ruim) não têm nada a ver com template e não
|
|
359
|
+
// devem exibir essa dica.
|
|
360
|
+
const isReengagementWindowError = payload?.error?.code === 131047;
|
|
361
|
+
|
|
362
|
+
throw new WhatsappSendError(
|
|
297
363
|
`WhatsApp recusou o envio (HTTP ${response.status}): ${
|
|
298
364
|
payload?.error?.message ?? 'sem detalhe'
|
|
299
365
|
}${
|
|
300
|
-
input.template?.name
|
|
301
|
-
? ''
|
|
302
|
-
: '
|
|
366
|
+
!input.template?.name && isReengagementWindowError
|
|
367
|
+
? ' — sem template configurado, a entrega só funciona na janela de 24h'
|
|
368
|
+
: ''
|
|
303
369
|
}`,
|
|
370
|
+
response.status >= 500,
|
|
304
371
|
);
|
|
305
372
|
}
|
|
306
373
|
}
|
|
307
374
|
}
|
|
308
375
|
|
|
376
|
+
/**
|
|
377
|
+
* Reconhece o 400 da Evolution para destino inexistente:
|
|
378
|
+
* `{"response":{"message":[{"exists":false,"number":"55..."}]}}`.
|
|
379
|
+
*/
|
|
380
|
+
function isEvolutionNumberMissing(detail: string): boolean {
|
|
381
|
+
try {
|
|
382
|
+
const messages = JSON.parse(detail)?.response?.message;
|
|
383
|
+
return (
|
|
384
|
+
Array.isArray(messages) &&
|
|
385
|
+
messages.some((item) => item && typeof item === 'object' && item.exists === false)
|
|
386
|
+
);
|
|
387
|
+
} catch {
|
|
388
|
+
return false;
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
|
|
309
392
|
/** Evolution espera base64 puro; um data URL vindo do chamador quebraria o envio. */
|
|
310
393
|
function stripDataUrlPrefix(image: string): string {
|
|
311
394
|
const match = /^data:[^;]+;base64,(.*)$/i.exec(image);
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
-- Pareamento de dispositivo (QR entre celular e navegador).
|
|
2
|
-
--
|
|
3
|
-
-- Tabela de infra de auth: vive so aqui, sem YAML em hedhog/table (ver
|
|
4
|
-
-- oauth_mobile_state_token.sql).
|
|
5
|
-
--
|
|
6
|
-
-- Usada por libraries/core/src/pairing/pairing.service.ts. A FK para "user"
|
|
7
|
-
-- resolve porque os arquivos de hedhog/query sao anexados DEPOIS de todos os
|
|
8
|
-
-- CREATE TABLE (ver docs/YAML-SPEC.md secao 7).
|
|
9
|
-
CREATE TABLE IF NOT EXISTS device_pairing_request (
|
|
10
|
-
id BIGSERIAL PRIMARY KEY,
|
|
11
|
-
direction VARCHAR(20) NOT NULL,
|
|
12
|
-
-- Só o hash do token de resgate/poll: um dump do banco não permite reivindicar
|
|
13
|
-
-- nem consumir pareamento nenhum.
|
|
14
|
-
auth_hash VARCHAR(255) NOT NULL UNIQUE,
|
|
15
|
-
-- NULL em 'device-to-browser' até a aprovação: o navegador que pede ainda não
|
|
16
|
-
-- é ninguém. Preenchido pelo aparelho que aprova.
|
|
17
|
-
user_id INTEGER NULL REFERENCES "user"(id) ON DELETE CASCADE,
|
|
18
|
-
client_id VARCHAR(100) NOT NULL,
|
|
19
|
-
purpose VARCHAR(50) NOT NULL DEFAULT 'vaults',
|
|
20
|
-
-- 'device-to-browser': ponto EC não comprimido (65 bytes) em base64. É a chave
|
|
21
|
-
-- para a qual o celular cifra; a privada correspondente nunca sai da aba.
|
|
22
|
-
eph_public_key TEXT NULL,
|
|
23
|
-
-- 'device-to-browser': o navegador também precisa de sessão (computador novo,
|
|
24
|
-
-- ninguém logado) ou só das chaves do cofre (sessão já existe, cofre travado).
|
|
25
|
-
want_session BOOLEAN NOT NULL DEFAULT TRUE,
|
|
26
|
-
-- OPACO para o servidor: AES-256-GCM feito no cliente com uma chave que nunca
|
|
27
|
-
-- chega aqui (fragmento do QR ou par efêmero da aba). Fica NULL até a
|
|
28
|
-
-- aprovação, então um pareamento não aprovado nunca guarda material de chave.
|
|
29
|
-
payload_enc TEXT NULL,
|
|
30
|
-
issued_ip VARCHAR(64) NULL,
|
|
31
|
-
issued_user_agent TEXT NULL,
|
|
32
|
-
claimed_at TIMESTAMPTZ NULL,
|
|
33
|
-
claim_ip VARCHAR(64) NULL,
|
|
34
|
-
claim_user_agent TEXT NULL,
|
|
35
|
-
confirmed_at TIMESTAMPTZ NULL,
|
|
36
|
-
cancelled_at TIMESTAMPTZ NULL,
|
|
37
|
-
consumed_at TIMESTAMPTZ NULL,
|
|
38
|
-
expires_at TIMESTAMPTZ NOT NULL,
|
|
39
|
-
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
40
|
-
);
|
|
41
|
-
|
|
42
|
-
CREATE INDEX IF NOT EXISTS idx_device_pairing_request_expires_at
|
|
43
|
-
ON device_pairing_request (expires_at);
|
|
44
|
-
|
|
45
|
-
CREATE INDEX IF NOT EXISTS idx_device_pairing_request_user
|
|
46
|
-
ON device_pairing_request (user_id, created_at DESC);
|
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
-- Simulacao de acesso ("simular login"): um operador abre uma sessao curta,
|
|
2
|
-
-- auditada e nao renovavel como outro usuario.
|
|
3
|
-
--
|
|
4
|
-
-- Tabela de infra de auth: vive so aqui, sem YAML em hedhog/table (ver
|
|
5
|
-
-- oauth_mobile_state_token.sql).
|
|
6
|
-
--
|
|
7
|
-
-- Usada por libraries/core/src/impersonation/impersonation.service.ts.
|
|
8
|
-
--
|
|
9
|
-
-- POR QUE impersonator_user_id E target_user_id SAO INTEGER SEM FOREIGN KEY:
|
|
10
|
-
-- as tabelas marcadas mais abaixo ja tem uma FK para "user". Uma segunda FK faz
|
|
11
|
-
-- o `prisma db pull` desambiguar os nomes das relacoes NOS DOIS LADOS, o que
|
|
12
|
-
-- renomearia `user.user_session`, `user.access_log` e `user.user_activity` e
|
|
13
|
-
-- quebraria UserService, packages/api-types e a tela de sessoes do admin. O nome
|
|
14
|
-
-- do operador e resolvido por uma segunda consulta.
|
|
15
|
-
CREATE TABLE IF NOT EXISTS impersonation_grant (
|
|
16
|
-
id SERIAL PRIMARY KEY,
|
|
17
|
-
code_hash VARCHAR(255) NOT NULL UNIQUE,
|
|
18
|
-
-- Sem FK de proposito — ver a nota no topo do arquivo.
|
|
19
|
-
impersonator_user_id INTEGER NOT NULL,
|
|
20
|
-
target_user_id INTEGER NOT NULL,
|
|
21
|
-
-- Chave do app de destino ('admin', 'class', 'partners'), resolvida contra a
|
|
22
|
-
-- setting app-urls.
|
|
23
|
-
app VARCHAR(50) NOT NULL,
|
|
24
|
-
reason VARCHAR(255) NULL,
|
|
25
|
-
-- Preenchido no resgate: aponta para a user_session simulada que nasceu daqui.
|
|
26
|
-
session_id INTEGER NULL,
|
|
27
|
-
issued_ip VARCHAR(64) NULL,
|
|
28
|
-
issued_user_agent TEXT NULL,
|
|
29
|
-
redeemed_ip VARCHAR(64) NULL,
|
|
30
|
-
redeemed_user_agent TEXT NULL,
|
|
31
|
-
consumed_at TIMESTAMPTZ NULL,
|
|
32
|
-
ended_at TIMESTAMPTZ NULL,
|
|
33
|
-
expires_at TIMESTAMPTZ NOT NULL,
|
|
34
|
-
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
35
|
-
);
|
|
36
|
-
|
|
37
|
-
CREATE INDEX IF NOT EXISTS idx_impersonation_grant_impersonator
|
|
38
|
-
ON impersonation_grant (impersonator_user_id, created_at DESC);
|
|
39
|
-
|
|
40
|
-
CREATE INDEX IF NOT EXISTS idx_impersonation_grant_target
|
|
41
|
-
ON impersonation_grant (target_user_id, created_at DESC);
|
|
42
|
-
|
|
43
|
-
CREATE INDEX IF NOT EXISTS idx_impersonation_grant_expires
|
|
44
|
-
ON impersonation_grant (expires_at);
|
|
45
|
-
|
|
46
|
-
CREATE INDEX IF NOT EXISTS idx_impersonation_grant_session
|
|
47
|
-
ON impersonation_grant (session_id)
|
|
48
|
-
WHERE session_id IS NOT NULL;
|
|
49
|
-
|
|
50
|
-
-- ---------------------------------------------------------------------------
|
|
51
|
-
-- Indices das colunas de simulacao nas tabelas que TEM YAML.
|
|
52
|
-
--
|
|
53
|
-
-- As colunas em si vem de hedhog/table/{user_session,access_log,user_activity}.yaml
|
|
54
|
-
-- e o CLI as cria; os indices NAO — o gerador nao emite indice para elas, e a
|
|
55
|
-
-- semantica parcial (WHERE ... IS NOT NULL) nao e exprimivel em YAML.
|
|
56
|
-
--
|
|
57
|
-
-- Parciais de proposito: a esmagadora maioria das linhas nao tem simulacao
|
|
58
|
-
-- nenhuma, entao um indice cheio numa coluna quase toda NULL seria bem maior sem
|
|
59
|
-
-- servir a nenhuma consulta.
|
|
60
|
-
-- ---------------------------------------------------------------------------
|
|
61
|
-
CREATE INDEX IF NOT EXISTS "user_session_impersonator_user_id_idx"
|
|
62
|
-
ON "user_session" ("impersonator_user_id")
|
|
63
|
-
WHERE "impersonator_user_id" IS NOT NULL;
|
|
64
|
-
|
|
65
|
-
CREATE INDEX IF NOT EXISTS "access_log_impersonator_user_id_idx"
|
|
66
|
-
ON "access_log" ("impersonator_user_id")
|
|
67
|
-
WHERE "impersonator_user_id" IS NOT NULL;
|
|
68
|
-
|
|
69
|
-
CREATE INDEX IF NOT EXISTS "user_activity_actor_user_id_idx"
|
|
70
|
-
ON "user_activity" ("actor_user_id")
|
|
71
|
-
WHERE "actor_user_id" IS NOT NULL;
|