@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,135 @@
|
|
|
1
|
+
import { Public } from '@hed-hog/api';
|
|
2
|
+
import { Controller, Get, Logger, NotFoundException, Res } from '@nestjs/common';
|
|
3
|
+
import { Response } from 'express';
|
|
4
|
+
import { BrandAssetService } from './brand-asset.service';
|
|
5
|
+
import { SettingService } from './setting.service';
|
|
6
|
+
|
|
7
|
+
/** Timeout do fetch da imagem configurada. */
|
|
8
|
+
const FETCH_TIMEOUT_MS = 5_000;
|
|
9
|
+
|
|
10
|
+
/** Quanto tempo o binario baixado fica em memoria antes de buscar de novo. */
|
|
11
|
+
const CACHE_TTL_MS = 10 * 60_000;
|
|
12
|
+
|
|
13
|
+
type CachedIcon = {
|
|
14
|
+
url: string;
|
|
15
|
+
body: Buffer;
|
|
16
|
+
contentType: string;
|
|
17
|
+
expiresAt: number;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* `GET /favicon.ico` no host da API, com o icone do Branding (`icon-url`).
|
|
22
|
+
*
|
|
23
|
+
* Quem procura o favicon no dominio da API sao os clientes que so conhecem esse
|
|
24
|
+
* endereco - o conector MCP no claude.ai, por exemplo, mostra o icone do dominio
|
|
25
|
+
* do servidor ao lado do nome. Sem esta rota a resposta era o 404 JSON do Nest e
|
|
26
|
+
* o conector caia na letra inicial.
|
|
27
|
+
*
|
|
28
|
+
* O arquivo e servido daqui (e nao por redirect) porque nem todo coletor de
|
|
29
|
+
* favicon segue redirecionamento. O Content-Type e o da origem, entao um SVG
|
|
30
|
+
* configurado no Branding chega como SVG.
|
|
31
|
+
*/
|
|
32
|
+
@Controller()
|
|
33
|
+
export class FaviconController {
|
|
34
|
+
private readonly logger = new Logger(FaviconController.name);
|
|
35
|
+
private cache: CachedIcon | null = null;
|
|
36
|
+
|
|
37
|
+
constructor(
|
|
38
|
+
private readonly setting: SettingService,
|
|
39
|
+
private readonly brandAsset: BrandAssetService,
|
|
40
|
+
) {}
|
|
41
|
+
|
|
42
|
+
@Public()
|
|
43
|
+
@Get('favicon.ico')
|
|
44
|
+
async favicon(@Res() res: Response) {
|
|
45
|
+
const icon = await this.loadIcon();
|
|
46
|
+
|
|
47
|
+
if (!icon) {
|
|
48
|
+
throw new NotFoundException();
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
res.setHeader('Content-Type', icon.contentType);
|
|
52
|
+
res.setHeader('Cache-Control', 'public, max-age=3600');
|
|
53
|
+
res.send(icon.body);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
private async loadIcon(): Promise<CachedIcon | null> {
|
|
57
|
+
const settings = await this.setting.getSettingValues([
|
|
58
|
+
'icon-url',
|
|
59
|
+
'image-url',
|
|
60
|
+
]);
|
|
61
|
+
const value =
|
|
62
|
+
String(settings['icon-url'] ?? '').trim() ||
|
|
63
|
+
String(settings['image-url'] ?? '').trim();
|
|
64
|
+
const url = await this.brandAsset.resolveAssetUrl(value);
|
|
65
|
+
|
|
66
|
+
if (!url) {
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (
|
|
71
|
+
this.cache &&
|
|
72
|
+
this.cache.url === url &&
|
|
73
|
+
this.cache.expiresAt > Date.now()
|
|
74
|
+
) {
|
|
75
|
+
return this.cache;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const icon = await this.download(url);
|
|
79
|
+
|
|
80
|
+
if (icon) {
|
|
81
|
+
this.cache = icon;
|
|
82
|
+
return icon;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// Origem fora do ar: melhor o icone anterior do que nenhum.
|
|
86
|
+
return this.cache?.url === url ? this.cache : null;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
private async download(url: string): Promise<CachedIcon | null> {
|
|
90
|
+
const dataUri = /^data:([^;,]+)(;base64)?,([\s\S]*)$/i.exec(url);
|
|
91
|
+
|
|
92
|
+
if (dataUri) {
|
|
93
|
+
const [, contentType, base64, payload] = dataUri;
|
|
94
|
+
return {
|
|
95
|
+
url,
|
|
96
|
+
contentType,
|
|
97
|
+
body: base64
|
|
98
|
+
? Buffer.from(payload, 'base64')
|
|
99
|
+
: Buffer.from(decodeURIComponent(payload)),
|
|
100
|
+
expiresAt: Date.now() + CACHE_TTL_MS,
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
try {
|
|
105
|
+
const controller = new AbortController();
|
|
106
|
+
const timeout = setTimeout(() => controller.abort(), FETCH_TIMEOUT_MS);
|
|
107
|
+
const response = await globalThis
|
|
108
|
+
.fetch(url, { signal: controller.signal })
|
|
109
|
+
.finally(() => clearTimeout(timeout));
|
|
110
|
+
|
|
111
|
+
const contentType = response.headers.get('content-type') ?? '';
|
|
112
|
+
|
|
113
|
+
if (!response.ok || !contentType.startsWith('image/')) {
|
|
114
|
+
this.logger.warn(
|
|
115
|
+
`Favicon source ${url} answered ${response.status} ${contentType || '(no content-type)'}`,
|
|
116
|
+
);
|
|
117
|
+
return null;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
return {
|
|
121
|
+
url,
|
|
122
|
+
contentType,
|
|
123
|
+
body: Buffer.from(await response.arrayBuffer()),
|
|
124
|
+
expiresAt: Date.now() + CACHE_TTL_MS,
|
|
125
|
+
};
|
|
126
|
+
} catch (error) {
|
|
127
|
+
this.logger.warn(
|
|
128
|
+
`Could not fetch favicon source ${url}: ${
|
|
129
|
+
error instanceof Error ? error.message : String(error)
|
|
130
|
+
}`,
|
|
131
|
+
);
|
|
132
|
+
return null;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
@@ -5,6 +5,7 @@ import { Global, Module, forwardRef } from '@nestjs/common';
|
|
|
5
5
|
import { AuthModule } from '../auth/auth.module';
|
|
6
6
|
import { MailModule } from '../mail/mail.module';
|
|
7
7
|
import { BrandAssetService } from './brand-asset.service';
|
|
8
|
+
import { FaviconController } from './favicon.controller';
|
|
8
9
|
import { SettingsController } from './setting.controller';
|
|
9
10
|
import { SettingService } from './setting.service';
|
|
10
11
|
|
|
@@ -17,7 +18,7 @@ import { SettingService } from './setting.service';
|
|
|
17
18
|
forwardRef(() => LocaleModule),
|
|
18
19
|
forwardRef(() => MailModule),
|
|
19
20
|
],
|
|
20
|
-
controllers: [SettingsController],
|
|
21
|
+
controllers: [SettingsController, FaviconController],
|
|
21
22
|
providers: [SettingService, BrandAssetService],
|
|
22
23
|
exports: [SettingService, BrandAssetService],
|
|
23
24
|
})
|
|
@@ -67,6 +67,15 @@ export class SettingService implements OnModuleInit, OnModuleDestroy {
|
|
|
67
67
|
);
|
|
68
68
|
private lastRedisSubscriberErrorLogAt = 0;
|
|
69
69
|
private lastRedisPublisherErrorLogAt = 0;
|
|
70
|
+
// A `reconnectStrategy` que nunca devolve `false` faz `client.connect()` ficar
|
|
71
|
+
// retentando pra sempre quando o Redis está indisponível: a Promise nunca
|
|
72
|
+
// resolve nem rejeita, e `onModuleInit` trava o boot inteiro da API esperando
|
|
73
|
+
// por ela. Este teto bound só a tentativa inicial; a reconexão de um cliente
|
|
74
|
+
// já conectado continua indefinida.
|
|
75
|
+
private readonly redisConnectTimeoutMs = Math.max(
|
|
76
|
+
1000,
|
|
77
|
+
Number(process.env.REDIS_CONNECT_TIMEOUT_MS || 3000),
|
|
78
|
+
);
|
|
70
79
|
|
|
71
80
|
constructor(
|
|
72
81
|
@Inject(forwardRef(() => PrismaService))
|
|
@@ -140,6 +149,23 @@ export class SettingService implements OnModuleInit, OnModuleDestroy {
|
|
|
140
149
|
return String(error);
|
|
141
150
|
}
|
|
142
151
|
|
|
152
|
+
private async withConnectTimeout<T>(promise: Promise<T>, timeoutMs: number): Promise<T> {
|
|
153
|
+
let timer: NodeJS.Timeout;
|
|
154
|
+
try {
|
|
155
|
+
return await Promise.race([
|
|
156
|
+
promise,
|
|
157
|
+
new Promise<never>((_, reject) => {
|
|
158
|
+
timer = setTimeout(
|
|
159
|
+
() => reject(new Error(`Redis connection timed out after ${timeoutMs}ms`)),
|
|
160
|
+
timeoutMs,
|
|
161
|
+
);
|
|
162
|
+
}),
|
|
163
|
+
]);
|
|
164
|
+
} finally {
|
|
165
|
+
clearTimeout(timer!);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
143
169
|
private async initializeRedisSync() {
|
|
144
170
|
if (!this.redisUrl) {
|
|
145
171
|
this.logger.log(
|
|
@@ -169,8 +195,8 @@ export class SettingService implements OnModuleInit, OnModuleDestroy {
|
|
|
169
195
|
this.logRedisClientError('publisher', error);
|
|
170
196
|
});
|
|
171
197
|
|
|
172
|
-
await this.redisSubscriber.connect();
|
|
173
|
-
await this.redisPublisher.connect();
|
|
198
|
+
await this.withConnectTimeout(this.redisSubscriber.connect(), this.redisConnectTimeoutMs);
|
|
199
|
+
await this.withConnectTimeout(this.redisPublisher.connect(), this.redisConnectTimeoutMs);
|
|
174
200
|
await this.redisSubscriber.subscribe(this.redisChannel, async (message) => {
|
|
175
201
|
await this.handleRedisSettingsVersionMessage(message);
|
|
176
202
|
});
|
|
@@ -529,7 +555,22 @@ export class SettingService implements OnModuleInit, OnModuleDestroy {
|
|
|
529
555
|
'lms-video-frame-capture-interval-seconds',
|
|
530
556
|
'lms-error-modal-enabled',
|
|
531
557
|
'url',
|
|
532
|
-
'app-urls'
|
|
558
|
+
'app-urls',
|
|
559
|
+
// Hcode Store: liga/desliga a venda no frontend (o backend também
|
|
560
|
+
// recusa o checkout — isto é só para a UI mostrar "Em breve" cedo).
|
|
561
|
+
'commerce-store-sales-enabled',
|
|
562
|
+
// A loja lê esta para decidir se dispara o beacon de navegação. A irmã
|
|
563
|
+
// `-persist` NÃO entra aqui de propósito: é decisão de servidor (grava ou
|
|
564
|
+
// não IP e origem) e não tem por que chegar ao navegador.
|
|
565
|
+
'commerce-store-visitor-tracking',
|
|
566
|
+
// A partir de quantas unidades a loja mostra "Última unidade"/"Restam N".
|
|
567
|
+
// Só afeta o aviso na vitrine — a trava de quantidade é do backend e não
|
|
568
|
+
// depende deste valor chegar ao navegador.
|
|
569
|
+
'commerce-store-low-stock-threshold',
|
|
570
|
+
// Se a loja abre o stream de estoque ao vivo. Desligada, o frontend nem
|
|
571
|
+
// conecta — que é o ponto: sem isto aqui, cada visitante abriria uma
|
|
572
|
+
// conexão de longa duração para um recurso que está fora de uso.
|
|
573
|
+
'commerce-store-realtime-stock-enabled'
|
|
533
574
|
];
|
|
534
575
|
const setting = await this.getSettingValues(slugs);
|
|
535
576
|
return { locales, setting };
|
|
@@ -44,4 +44,45 @@ describe('TasksService', () => {
|
|
|
44
44
|
expect(values).toContain(500);
|
|
45
45
|
});
|
|
46
46
|
});
|
|
47
|
+
|
|
48
|
+
describe('clearOldAccessLogs', () => {
|
|
49
|
+
it('repete lotes ate drenar o acumulo', async () => {
|
|
50
|
+
// O bug: um unico lote por execucao diaria contra uma ingestao uma ordem
|
|
51
|
+
// de grandeza maior deixava a retencao inalcancavel.
|
|
52
|
+
const { service, deps } = makeService();
|
|
53
|
+
deps.settingService.getSettingValues.mockResolvedValue({
|
|
54
|
+
'cleanup-batch-limit': 100,
|
|
55
|
+
});
|
|
56
|
+
deps.prismaService.$executeRaw
|
|
57
|
+
.mockResolvedValueOnce(100)
|
|
58
|
+
.mockResolvedValueOnce(100)
|
|
59
|
+
.mockResolvedValueOnce(42);
|
|
60
|
+
|
|
61
|
+
await (service as any).clearOldAccessLogs();
|
|
62
|
+
|
|
63
|
+
expect(deps.prismaService.$executeRaw).toHaveBeenCalledTimes(3);
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
it('para no primeiro lote incompleto', async () => {
|
|
67
|
+
const { service, deps } = makeService();
|
|
68
|
+
deps.settingService.getSettingValues.mockResolvedValue({
|
|
69
|
+
'cleanup-batch-limit': 100,
|
|
70
|
+
});
|
|
71
|
+
deps.prismaService.$executeRaw.mockResolvedValue(0);
|
|
72
|
+
|
|
73
|
+
await (service as any).clearOldAccessLogs();
|
|
74
|
+
|
|
75
|
+
expect(deps.prismaService.$executeRaw).toHaveBeenCalledTimes(1);
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
it('usa os defaults de retencao e de lote quando as settings faltam', async () => {
|
|
79
|
+
const { service, deps } = makeService();
|
|
80
|
+
deps.settingService.getSettingValues.mockResolvedValue({});
|
|
81
|
+
|
|
82
|
+
await (service as any).clearOldAccessLogs();
|
|
83
|
+
|
|
84
|
+
const values = deps.prismaService.$executeRaw.mock.calls[0].slice(1);
|
|
85
|
+
expect(values).toContain(20000);
|
|
86
|
+
});
|
|
87
|
+
});
|
|
47
88
|
});
|
package/src/task/task.service.ts
CHANGED
|
@@ -3,6 +3,13 @@ import { Injectable, Logger } from '@nestjs/common';
|
|
|
3
3
|
import { Cron, CronExpression } from '@nestjs/schedule';
|
|
4
4
|
import { SettingService } from '../setting/setting.service';
|
|
5
5
|
|
|
6
|
+
/**
|
|
7
|
+
* Teto de tempo da limpeza do `access_log`. Existe para o caso da entrada
|
|
8
|
+
* superar a saída de novo: o laço para e devolve o resto para a execução
|
|
9
|
+
* seguinte, em vez de varrer a madrugada inteira disputando o banco.
|
|
10
|
+
*/
|
|
11
|
+
const ACCESS_LOG_CLEANUP_BUDGET_MS = 10 * 60 * 1000;
|
|
12
|
+
|
|
6
13
|
@Injectable()
|
|
7
14
|
export class TasksService {
|
|
8
15
|
private readonly logger = new Logger(TasksService.name);
|
|
@@ -270,6 +277,23 @@ export class TasksService {
|
|
|
270
277
|
);
|
|
271
278
|
}
|
|
272
279
|
|
|
280
|
+
/**
|
|
281
|
+
* Apaga os logs de acesso fora da janela de `access-log-retention-days`.
|
|
282
|
+
*
|
|
283
|
+
* Roda em lotes até drenar, e não em um lote só. O `access_log` recebe um
|
|
284
|
+
* INSERT por requisição — em produção, de 200 a 540 mil por dia — enquanto a
|
|
285
|
+
* limpeza apagava `cleanup-batch-limit` registros por execução diária. Com a
|
|
286
|
+
* entrada uma ordem de grandeza acima da saída, a retenção nunca era
|
|
287
|
+
* alcançada: a tabela chegou a 18,6 milhões de linhas e 4 GB, com 11,8
|
|
288
|
+
* milhões já vencidos e registros três meses mais velhos que a retenção de 30
|
|
289
|
+
* dias configurada.
|
|
290
|
+
*
|
|
291
|
+
* O `cleanup-batch-limit` passa a ser o tamanho de CADA lote — o papel que a
|
|
292
|
+
* própria descrição da setting sempre anunciou ("valores menores evitam locks
|
|
293
|
+
* prolongados mas aumentam a duração da limpeza"). O teto agora é de tempo,
|
|
294
|
+
* não de linhas: o laço para ao drenar a fila ou ao estourar o orçamento,
|
|
295
|
+
* para que a limpeza não avance madrugada adentro competindo com o tráfego.
|
|
296
|
+
*/
|
|
273
297
|
private async clearOldAccessLogs(): Promise<void> {
|
|
274
298
|
const settings = await this.settingService.getSettingValues([
|
|
275
299
|
'cleanup-batch-limit',
|
|
@@ -280,21 +304,37 @@ export class TasksService {
|
|
|
280
304
|
this.logger.verbose('Starting cleanup of old access logs');
|
|
281
305
|
const startAt = Date.now();
|
|
282
306
|
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
307
|
+
let deleted = 0;
|
|
308
|
+
let batches = 0;
|
|
309
|
+
for (;;) {
|
|
310
|
+
const removed = await this.prismaService.$executeRaw`
|
|
311
|
+
WITH del AS (
|
|
312
|
+
SELECT id
|
|
313
|
+
FROM access_log
|
|
314
|
+
WHERE created_at < (now() - ${Prisma.sql`INTERVAL '${Prisma.raw(String(retentionDays))} days'`})
|
|
315
|
+
ORDER BY id
|
|
316
|
+
LIMIT ${batchLimit}
|
|
317
|
+
)
|
|
318
|
+
DELETE FROM access_log al
|
|
319
|
+
USING del
|
|
320
|
+
WHERE al.id = del.id
|
|
321
|
+
`;
|
|
322
|
+
|
|
323
|
+
deleted += removed;
|
|
324
|
+
batches += 1;
|
|
325
|
+
|
|
326
|
+
if (removed < batchLimit) break;
|
|
327
|
+
|
|
328
|
+
if (Date.now() - startAt >= ACCESS_LOG_CLEANUP_BUDGET_MS) {
|
|
329
|
+
this.logger.warn(
|
|
330
|
+
`Access log cleanup hit the ${ACCESS_LOG_CLEANUP_BUDGET_MS}ms budget after ${deleted} rows; the remainder goes on the next run.`,
|
|
331
|
+
);
|
|
332
|
+
break;
|
|
333
|
+
}
|
|
334
|
+
}
|
|
295
335
|
|
|
296
336
|
this.logger.verbose(
|
|
297
|
-
`Old access logs cleaned up in ${Date.now() - startAt}ms`,
|
|
337
|
+
`Old access logs cleaned up in ${Date.now() - startAt}ms (${deleted} rows in ${batches} batches)`,
|
|
298
338
|
);
|
|
299
339
|
}
|
|
300
340
|
|
|
@@ -410,4 +410,94 @@ describe('TokenService', () => {
|
|
|
410
410
|
);
|
|
411
411
|
});
|
|
412
412
|
});
|
|
413
|
+
|
|
414
|
+
describe('verify - audiencia (audience binding)', () => {
|
|
415
|
+
const RESOURCE = 'https://hub-api.example.com/mcp';
|
|
416
|
+
const activeSession = {
|
|
417
|
+
revoked_at: null,
|
|
418
|
+
expires_at: new Date(Date.now() + 60_000),
|
|
419
|
+
};
|
|
420
|
+
|
|
421
|
+
// ESTE e o teste central do audience binding: sem ele, o token entregue ao
|
|
422
|
+
// conector do Claude valeria na API REST inteira.
|
|
423
|
+
it('recusa token COM aud numa rota que nao declara recurso', async () => {
|
|
424
|
+
const { service, deps } = makeService();
|
|
425
|
+
deps.jwt.verifyAsync.mockResolvedValue({ sub: 1, sessionId: 9, aud: RESOURCE });
|
|
426
|
+
|
|
427
|
+
await expect(service.verify('en', 'tok')).rejects.toThrow(
|
|
428
|
+
UnauthorizedException,
|
|
429
|
+
);
|
|
430
|
+
// Nem chega a consultar a sessao: a recusa e antes.
|
|
431
|
+
expect(deps.prisma.user_session.findUnique).not.toHaveBeenCalled();
|
|
432
|
+
});
|
|
433
|
+
|
|
434
|
+
it('recusa token cujo aud e de OUTRO recurso', async () => {
|
|
435
|
+
const { service, deps } = makeService();
|
|
436
|
+
deps.jwt.verifyAsync.mockResolvedValue({
|
|
437
|
+
sub: 1,
|
|
438
|
+
sessionId: 9,
|
|
439
|
+
aud: 'https://outro.example.com/mcp',
|
|
440
|
+
});
|
|
441
|
+
|
|
442
|
+
await expect(service.verify('en', 'tok', RESOURCE)).rejects.toThrow(
|
|
443
|
+
UnauthorizedException,
|
|
444
|
+
);
|
|
445
|
+
});
|
|
446
|
+
|
|
447
|
+
it('aceita token cujo aud casa exatamente com o recurso', async () => {
|
|
448
|
+
const { service, deps } = makeService();
|
|
449
|
+
deps.jwt.verifyAsync.mockResolvedValue({ sub: 1, sessionId: 9, aud: RESOURCE });
|
|
450
|
+
deps.prisma.user_session.findUnique.mockResolvedValue(activeSession);
|
|
451
|
+
|
|
452
|
+
await expect(service.verify('en', 'tok', RESOURCE)).resolves.toMatchObject({
|
|
453
|
+
sub: 1,
|
|
454
|
+
aud: RESOURCE,
|
|
455
|
+
});
|
|
456
|
+
});
|
|
457
|
+
|
|
458
|
+
// Comparacao por igualdade exata: barra final e outro recurso.
|
|
459
|
+
it('nao normaliza barra final ao comparar', async () => {
|
|
460
|
+
const { service, deps } = makeService();
|
|
461
|
+
deps.jwt.verifyAsync.mockResolvedValue({
|
|
462
|
+
sub: 1,
|
|
463
|
+
sessionId: 9,
|
|
464
|
+
aud: RESOURCE + '/',
|
|
465
|
+
});
|
|
466
|
+
|
|
467
|
+
await expect(service.verify('en', 'tok', RESOURCE)).rejects.toThrow(
|
|
468
|
+
UnauthorizedException,
|
|
469
|
+
);
|
|
470
|
+
});
|
|
471
|
+
|
|
472
|
+
// O login normal nao pode mudar de comportamento por causa disso.
|
|
473
|
+
it('aceita token SEM aud, com ou sem recurso declarado', async () => {
|
|
474
|
+
const { service, deps } = makeService();
|
|
475
|
+
deps.jwt.verifyAsync.mockResolvedValue({ sub: 1, sessionId: 9 });
|
|
476
|
+
deps.prisma.user_session.findUnique.mockResolvedValue(activeSession);
|
|
477
|
+
|
|
478
|
+
await expect(service.verify('en', 'tok')).resolves.toMatchObject({ sub: 1 });
|
|
479
|
+
await expect(service.verify('en', 'tok', RESOURCE)).resolves.toMatchObject({
|
|
480
|
+
sub: 1,
|
|
481
|
+
});
|
|
482
|
+
});
|
|
483
|
+
|
|
484
|
+
it('falha fechado em erro de banco quando o token e de recurso', async () => {
|
|
485
|
+
const { service, deps } = makeService();
|
|
486
|
+
deps.jwt.verifyAsync.mockResolvedValue({ sub: 1, sessionId: 9, aud: RESOURCE });
|
|
487
|
+
deps.prisma.user_session.findUnique.mockRejectedValue(new Error('db down'));
|
|
488
|
+
|
|
489
|
+
await expect(service.verify('en', 'tok', RESOURCE)).rejects.toThrow(
|
|
490
|
+
UnauthorizedException,
|
|
491
|
+
);
|
|
492
|
+
});
|
|
493
|
+
|
|
494
|
+
it('segue aberto em erro de banco para a sessao de login', async () => {
|
|
495
|
+
const { service, deps } = makeService();
|
|
496
|
+
deps.jwt.verifyAsync.mockResolvedValue({ sub: 1, sessionId: 9 });
|
|
497
|
+
deps.prisma.user_session.findUnique.mockRejectedValue(new Error('db down'));
|
|
498
|
+
|
|
499
|
+
await expect(service.verify('en', 'tok')).resolves.toMatchObject({ sub: 1 });
|
|
500
|
+
});
|
|
501
|
+
});
|
|
502
|
+
|
|
413
503
|
});
|
|
@@ -22,13 +22,46 @@ export class TokenService {
|
|
|
22
22
|
private readonly setting: SettingService,
|
|
23
23
|
) { }
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
/**
|
|
26
|
+
* `allowedAudience` declara qual recurso ESTA rota atende. A regra e de mao
|
|
27
|
+
* unica, e e essa assimetria que faz o modelo funcionar:
|
|
28
|
+
*
|
|
29
|
+
* - token SEM `aud` (o login normal) vale em qualquer lugar, com ou sem o
|
|
30
|
+
* parametro — nada muda para quem ja existe;
|
|
31
|
+
* - token COM `aud` so vale onde aquele exato recurso foi declarado. Em
|
|
32
|
+
* qualquer outra rota, 401.
|
|
33
|
+
*
|
|
34
|
+
* O AuthGuard global chama este metodo SEM o terceiro argumento, entao toda
|
|
35
|
+
* rota que ninguem marcou como recurso ja recusa um token de conector — por
|
|
36
|
+
* construcao, inclusive nas rotas que ainda nem foram escritas. Nao ha
|
|
37
|
+
* allowlist para alguem esquecer de atualizar.
|
|
38
|
+
*
|
|
39
|
+
* A comparacao e feita aqui, na mao, e nao pela opcao `audience` do
|
|
40
|
+
* jsonwebtoken: quando aquela opcao esta ausente, a lib simplesmente NAO OLHA o
|
|
41
|
+
* claim. E exatamente essa omissao que precisa virar rejeicao.
|
|
42
|
+
*/
|
|
43
|
+
async verify(locale: string, token: string, allowedAudience?: string) {
|
|
26
44
|
try {
|
|
27
45
|
|
|
28
46
|
const payload = await this.jwt.verifyAsync(token, {
|
|
29
47
|
secret: this.security.getJwtSecret(),
|
|
30
48
|
});
|
|
31
49
|
|
|
50
|
+
const audience = payload.aud;
|
|
51
|
+
const isResourceToken = audience !== undefined;
|
|
52
|
+
|
|
53
|
+
// Igualdade exata de string, sem parsear URL — normalizar abriria as mesmas
|
|
54
|
+
// brechas que a allowlist de redirect_uri ja evita (barra final, case do
|
|
55
|
+
// host, porta default).
|
|
56
|
+
if (isResourceToken && audience !== allowedAudience) {
|
|
57
|
+
this.logger.warn(
|
|
58
|
+
`[TokenVerify] sessionId=${payload.sessionId} userId=${payload.sub} token with aud=${audience} used outside its resource`,
|
|
59
|
+
);
|
|
60
|
+
throw new UnauthorizedException(
|
|
61
|
+
getLocaleText('accessDenied', locale, 'Access denied.'),
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
|
|
32
65
|
// Verify session is not revoked (only if prisma is available)
|
|
33
66
|
if (payload.sessionId && this.prisma) {
|
|
34
67
|
try {
|
|
@@ -62,8 +95,21 @@ export class TokenService {
|
|
|
62
95
|
if (sessionError instanceof UnauthorizedException) {
|
|
63
96
|
throw sessionError;
|
|
64
97
|
}
|
|
65
|
-
// DB error: log but allow auth to continue to avoid blocking on transient DB issues
|
|
66
98
|
this.logger.error(`[TokenVerify] DB error validating sessionId=${payload.sessionId} userId=${payload.sub}: ${(sessionError as any)?.message}`);
|
|
99
|
+
|
|
100
|
+
// Token de recurso nao ganha o beneficio da duvida. Para a sessao de
|
|
101
|
+
// login, seguir em frente numa falha transitoria de banco e a troca
|
|
102
|
+
// certa — derrubar todo mundo logado e pior que aceitar uma revogacao
|
|
103
|
+
// com atraso. Para um token entregue a um cliente externo, user_session
|
|
104
|
+
// e o UNICO jeito de revogar: continuar aqui faria uma revogacao valer
|
|
105
|
+
// so no vencimento do JWT. A decisao segue a natureza do TOKEN, nao a
|
|
106
|
+
// da rota.
|
|
107
|
+
if (isResourceToken) {
|
|
108
|
+
throw new UnauthorizedException(
|
|
109
|
+
getLocaleText('accessDenied', locale, 'Access denied.'),
|
|
110
|
+
);
|
|
111
|
+
}
|
|
112
|
+
// DB error: log but allow auth to continue to avoid blocking on transient DB issues
|
|
67
113
|
}
|
|
68
114
|
}
|
|
69
115
|
|
|
@@ -21,15 +21,24 @@ export function hasPendingPasswordReset(user: any): boolean {
|
|
|
21
21
|
);
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
+
/**
|
|
25
|
+
* Credencial de senha que ainda vale: do tipo password e não revogada.
|
|
26
|
+
*
|
|
27
|
+
* Existe para quem já tem as credenciais em memória e precisa do mesmo critério
|
|
28
|
+
* que as consultas de Prisma expressam com `revoked_at: null`. O login e a troca
|
|
29
|
+
* de e-mail filtravam só por `type`, então uma credencial revogada continuava
|
|
30
|
+
* autenticando — e a revogação é justamente o que o convite de acesso enterprise
|
|
31
|
+
* usa para transformar "autorize o acesso" em "crie sua conta e defina a senha".
|
|
32
|
+
*/
|
|
33
|
+
export function isActivePasswordCredential(credential: any): boolean {
|
|
34
|
+
return credential?.type === 'password' && !credential?.revoked_at;
|
|
35
|
+
}
|
|
36
|
+
|
|
24
37
|
/**
|
|
25
38
|
* Usuários criados/autenticados apenas via provedor externo (ex: Microsoft
|
|
26
39
|
* Entra ID) nunca têm uma credencial de senha ativa — não faz sentido
|
|
27
40
|
* oferecer o fluxo de "esqueci a senha" para eles.
|
|
28
41
|
*/
|
|
29
42
|
export function hasPasswordCredential(user: any): boolean {
|
|
30
|
-
return Boolean(
|
|
31
|
-
user?.user_credential?.some(
|
|
32
|
-
(credential) => credential?.type === 'password' && !credential?.revoked_at,
|
|
33
|
-
),
|
|
34
|
-
);
|
|
43
|
+
return Boolean(user?.user_credential?.some(isActivePasswordCredential));
|
|
35
44
|
}
|
package/src/user/user.service.ts
CHANGED
|
@@ -25,6 +25,7 @@ import {
|
|
|
25
25
|
PENDING_PASSWORD_RESET_WHERE,
|
|
26
26
|
hasPendingPasswordReset,
|
|
27
27
|
} from './user-credential.util';
|
|
28
|
+
import { USER_SORT } from './user.sort';
|
|
28
29
|
|
|
29
30
|
// Constants
|
|
30
31
|
const IDENTIFIER_TYPE = {
|
|
@@ -48,17 +49,6 @@ const PASSWORD_CHARSETS = {
|
|
|
48
49
|
symbols: '@#$%&*!?-_+',
|
|
49
50
|
} as const;
|
|
50
51
|
|
|
51
|
-
const USER_SORT_FIELDS = [
|
|
52
|
-
'id',
|
|
53
|
-
'name',
|
|
54
|
-
'photo_id',
|
|
55
|
-
'suspended_until',
|
|
56
|
-
'suspended_reason',
|
|
57
|
-
'deactivated_at',
|
|
58
|
-
'created_at',
|
|
59
|
-
'updated_at',
|
|
60
|
-
] as const;
|
|
61
|
-
|
|
62
52
|
type UserChangeLog = user_change_log;
|
|
63
53
|
type UserChangeLogActor = Prisma.userGetPayload<{
|
|
64
54
|
select: {
|
|
@@ -164,7 +154,7 @@ export class UserService {
|
|
|
164
154
|
this.prismaService.user,
|
|
165
155
|
{
|
|
166
156
|
...paginationParams,
|
|
167
|
-
|
|
157
|
+
sort: USER_SORT,
|
|
168
158
|
where: this.buildUserListWhere(filter, paginationParams?.search),
|
|
169
159
|
include: this.getUserIncludeClause(),
|
|
170
160
|
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { defineSortable } from '@hed-hog/api-pagination';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Campos ordenáveis de `user`.
|
|
5
|
+
*
|
|
6
|
+
* `email` fica de fora: mora em `user_identifier` (relação to-many filtrada
|
|
7
|
+
* por `type = 'email'`), sem coluna própria em `user` para o Prisma ordenar —
|
|
8
|
+
* mesma limitação documentada em `libraries/lms/src/instructor/instructor.sort.ts`
|
|
9
|
+
* para o e-mail do instrutor.
|
|
10
|
+
*
|
|
11
|
+
* `passwordReset` também fica de fora: é booleano calculado no service
|
|
12
|
+
* (`hasPendingPasswordReset`), não uma coluna.
|
|
13
|
+
*
|
|
14
|
+
* Sem ninguém pedir ordenação, o resultado continua igual ao de antes
|
|
15
|
+
* (`id` desc, o fallback do `paginatePrismaModel` quando não há `sortField`).
|
|
16
|
+
*/
|
|
17
|
+
export const USER_SORT = defineSortable(
|
|
18
|
+
{
|
|
19
|
+
name: true,
|
|
20
|
+
suspended_until: true,
|
|
21
|
+
last_login_at: true,
|
|
22
|
+
id: { initialOrder: 'desc' },
|
|
23
|
+
},
|
|
24
|
+
{ default: 'id', defaultOrder: 'desc' },
|
|
25
|
+
);
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { describe, it, expect } from '@jest/globals';
|
|
2
|
+
import { abbreviateName } from './abbreviate-name';
|
|
3
|
+
|
|
4
|
+
describe('abbreviateName', () => {
|
|
5
|
+
it('mantém primeiro nome e último sobrenome', () => {
|
|
6
|
+
expect(abbreviateName('João Henrique Cunha Rangel')).toBe('João Rangel');
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
it('ignora partículas (de/da/do/das/dos/e) ao escolher o último sobrenome', () => {
|
|
10
|
+
expect(abbreviateName('Maria de Souza')).toBe('Maria Souza');
|
|
11
|
+
expect(abbreviateName('Ana da Silva')).toBe('Ana Silva');
|
|
12
|
+
expect(abbreviateName('Pedro dos Santos')).toBe('Pedro Santos');
|
|
13
|
+
expect(abbreviateName('Carlos do Nascimento')).toBe('Carlos Nascimento');
|
|
14
|
+
expect(abbreviateName('José das Neves')).toBe('José Neves');
|
|
15
|
+
expect(abbreviateName('Silva e Souza Junior')).toBe('Silva Junior');
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
it('nome com duas palavras não muda', () => {
|
|
19
|
+
expect(abbreviateName('Ana Paula')).toBe('Ana Paula');
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it('nome com uma palavra só passa como está', () => {
|
|
23
|
+
expect(abbreviateName('Madonna')).toBe('Madonna');
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it('nome vazio ou só espaço devolve vazio', () => {
|
|
27
|
+
expect(abbreviateName('')).toBe('');
|
|
28
|
+
expect(abbreviateName(' ')).toBe('');
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
it('nome nulo/indefinido devolve vazio', () => {
|
|
32
|
+
expect(abbreviateName(null)).toBe('');
|
|
33
|
+
expect(abbreviateName(undefined)).toBe('');
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
it('normaliza espaços múltiplos entre palavras', () => {
|
|
37
|
+
expect(abbreviateName(' João Henrique Rangel ')).toBe('João Rangel');
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
it('cai no primeiro nome quando só sobra partícula depois dele', () => {
|
|
41
|
+
// Dado maltratado (ex.: sobrenome vazio salvo como "de") — não deve
|
|
42
|
+
// repetir o primeiro nome nem devolver a partícula sozinha.
|
|
43
|
+
expect(abbreviateName('João de')).toBe('João');
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it('fallback "Alguém"/"Someone" (sem atribuidor) passa direto, sem quebrar', () => {
|
|
47
|
+
expect(abbreviateName('Alguém')).toBe('Alguém');
|
|
48
|
+
expect(abbreviateName('Someone')).toBe('Someone');
|
|
49
|
+
});
|
|
50
|
+
});
|