@hed-hog/core 0.0.398 → 0.0.400
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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 +4 -4
- package/dist/ai/ai.service.d.ts +35 -4
- package/dist/ai/ai.service.d.ts.map +1 -1
- package/dist/ai/ai.service.js +51 -137
- 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/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 +30 -6
- 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 +78 -4
- 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 +6 -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/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 +182 -6
- package/dist/file/file.service.d.ts.map +1 -1
- package/dist/file/file.service.js +385 -36
- 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 +75 -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 +17 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +17 -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 +7 -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/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 +5 -1
- package/dist/mcp/mcp.module.js.map +1 -1
- 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 +115 -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.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.map +1 -1
- package/dist/oauth/providers/microsoft-entra-id.provider.js +6 -0
- 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.controller.d.ts +9 -9
- package/dist/pairing/pairing.service.d.ts +15 -11
- package/dist/pairing/pairing.service.d.ts.map +1 -1
- 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/setting.controller.d.ts +5 -0
- package/dist/setting/setting.controller.d.ts.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 +46 -5
- 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 +6 -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 +140 -0
- package/hedhog/data/setting_group.yaml +137 -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 +183 -36
- package/hedhog/frontend/messages/pt.json +183 -36
- 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 +8 -6
- package/src/ai/ai-agent.sort.ts +21 -0
- package/src/ai/ai.service.spec.ts +173 -1
- package/src/ai/ai.service.ts +64 -193
- package/src/ai-instruction/ai-instruction.service.ts +32 -28
- package/src/ai-instruction/ai-instruction.sort.ts +32 -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 +6 -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/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 +94 -0
- package/src/file/file.service.ts +432 -30
- 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 +83 -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 +17 -0
- package/src/integration-profile/integration-profile.secrets.ts +7 -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/index.ts +2 -0
- package/src/integration-profile/testers/remaining.testers.spec.ts +79 -0
- package/src/integration-profile/testers/shipping.testers.ts +94 -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 +5 -1
- 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 +121 -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.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.ts +8 -1
- package/src/observability/monitored-cron.spec.ts +164 -31
- package/src/observability/monitored-cron.ts +154 -62
- 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/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 +112 -0
- package/src/whatsapp-sender/whatsapp-sender.service.ts +58 -5
|
@@ -3,6 +3,7 @@ import { Prisma, PrismaService, user_account_provider_52222e2ecb_enum } from '@h
|
|
|
3
3
|
import {
|
|
4
4
|
BadRequestException,
|
|
5
5
|
ConflictException,
|
|
6
|
+
HttpStatus,
|
|
6
7
|
Inject,
|
|
7
8
|
Injectable,
|
|
8
9
|
Logger,
|
|
@@ -45,7 +46,6 @@ type HandleCallbackProps = {
|
|
|
45
46
|
email?: string;
|
|
46
47
|
redirectUri?: string;
|
|
47
48
|
state?: string;
|
|
48
|
-
includeRefreshTokenInBody?: boolean;
|
|
49
49
|
/** Origin header of the request that hit the callback (used to bind web hub flows). */
|
|
50
50
|
requestOrigin?: string;
|
|
51
51
|
/** Referer header, used as a fallback when the Origin header is absent. */
|
|
@@ -250,7 +250,6 @@ export class OAuthService {
|
|
|
250
250
|
email,
|
|
251
251
|
redirectUri,
|
|
252
252
|
state,
|
|
253
|
-
includeRefreshTokenInBody,
|
|
254
253
|
requestOrigin,
|
|
255
254
|
requestReferer,
|
|
256
255
|
}: HandleCallbackProps) {
|
|
@@ -339,7 +338,6 @@ export class OAuthService {
|
|
|
339
338
|
type,
|
|
340
339
|
profile,
|
|
341
340
|
userId,
|
|
342
|
-
includeRefreshTokenInBody: true,
|
|
343
341
|
app: webState?.app,
|
|
344
342
|
});
|
|
345
343
|
})) as { accessToken: string; refreshToken?: string };
|
|
@@ -367,7 +365,6 @@ export class OAuthService {
|
|
|
367
365
|
type,
|
|
368
366
|
profile,
|
|
369
367
|
userId,
|
|
370
|
-
includeRefreshTokenInBody,
|
|
371
368
|
app: webState?.app,
|
|
372
369
|
});
|
|
373
370
|
|
|
@@ -728,7 +725,6 @@ export class OAuthService {
|
|
|
728
725
|
type: flow,
|
|
729
726
|
profile,
|
|
730
727
|
userId,
|
|
731
|
-
includeRefreshTokenInBody: false,
|
|
732
728
|
});
|
|
733
729
|
} catch (error) {
|
|
734
730
|
throw this.mapCallbackError(locale, provider, flow, error);
|
|
@@ -744,16 +740,15 @@ export class OAuthService {
|
|
|
744
740
|
type,
|
|
745
741
|
profile,
|
|
746
742
|
userId,
|
|
747
|
-
includeRefreshTokenInBody,
|
|
748
743
|
app,
|
|
749
744
|
}: Omit<HandleCallbackProps, 'code' | 'email' | 'redirectUri' | 'state'> & { profile: any }) {
|
|
750
745
|
switch (type) {
|
|
751
746
|
case 'login':
|
|
752
|
-
return this.handleLogin(res, locale, ipAddress, userAgent, provider, profile
|
|
747
|
+
return this.handleLogin(res, locale, ipAddress, userAgent, provider, profile);
|
|
753
748
|
case 'register':
|
|
754
|
-
return this.handleRegister(res, locale, ipAddress, userAgent, provider, profile,
|
|
749
|
+
return this.handleRegister(res, locale, ipAddress, userAgent, provider, profile, app);
|
|
755
750
|
case 'connect':
|
|
756
|
-
return this.handleConnect(res, locale, ipAddress, userAgent, provider, profile, userId
|
|
751
|
+
return this.handleConnect(res, locale, ipAddress, userAgent, provider, profile, userId);
|
|
757
752
|
default:
|
|
758
753
|
throw new BadRequestException(
|
|
759
754
|
getLocaleText('oauth.callback.invalidType', locale, 'Unsupported OAuth callback type.'),
|
|
@@ -761,16 +756,23 @@ export class OAuthService {
|
|
|
761
756
|
}
|
|
762
757
|
}
|
|
763
758
|
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
759
|
+
/**
|
|
760
|
+
* O corpo carrega SEMPRE o par, como `/auth/login` já faz.
|
|
761
|
+
*
|
|
762
|
+
* Antes só o app mobile recebia o refresh token aqui (`includeRefreshTokenInBody`
|
|
763
|
+
* valia `Boolean(redirectUri)`); o fluxo web ficava dependendo do cookie `rt`. Esse
|
|
764
|
+
* cookie sai com `domain` da setting `api-url` (`hub-api.hcode.com.br`), então ele
|
|
765
|
+
* só existe para quem fala DIRETO com a API — o admin. O Class fala por rewrite
|
|
766
|
+
* same-origin (`class.hcode.com.br/api`), e o browser descarta um `Set-Cookie` de
|
|
767
|
+
* domínio alheio: o aluno que entrava por OAuth ficava sem refresh token nenhum e
|
|
768
|
+
* era deslogado no minuto em que o access token vencia.
|
|
769
|
+
*
|
|
770
|
+
* Não é exposição nova: `/auth/login` devolve o refresh token no corpo desde sempre
|
|
771
|
+
* e todo app web já o guarda no localStorage. O cookie continua sendo emitido para
|
|
772
|
+
* quem o usa; ele deixa apenas de ser o único portador.
|
|
773
|
+
*/
|
|
774
|
+
private formatAuthResponse(accessToken: string, refreshToken: string) {
|
|
775
|
+
return { accessToken, refreshToken };
|
|
774
776
|
}
|
|
775
777
|
|
|
776
778
|
private resolveProfileScopes(provider: user_account_provider_52222e2ecb_enum, profile: any) {
|
|
@@ -798,10 +800,13 @@ export class OAuthService {
|
|
|
798
800
|
|
|
799
801
|
if (error instanceof OAuthCallbackAlreadyProcessedError) {
|
|
800
802
|
return new BadRequestException(
|
|
801
|
-
|
|
802
|
-
'
|
|
803
|
-
|
|
804
|
-
|
|
803
|
+
this.buildCallbackErrorBody(
|
|
804
|
+
'already_processed',
|
|
805
|
+
getLocaleText(
|
|
806
|
+
'oauth.callback.alreadyProcessed',
|
|
807
|
+
locale,
|
|
808
|
+
'This OAuth callback has already been processed. Start the sign-in flow again.',
|
|
809
|
+
),
|
|
805
810
|
),
|
|
806
811
|
);
|
|
807
812
|
}
|
|
@@ -818,7 +823,12 @@ export class OAuthService {
|
|
|
818
823
|
|
|
819
824
|
if (error instanceof OAuthProviderException) {
|
|
820
825
|
if (error.reason === 'callback_consumed' || error.reason === 'invalid_callback') {
|
|
821
|
-
return new BadRequestException(
|
|
826
|
+
return new BadRequestException(
|
|
827
|
+
this.buildCallbackErrorBody(
|
|
828
|
+
error.reason,
|
|
829
|
+
getLocaleText('oauth.callback.invalid', locale, error.message),
|
|
830
|
+
),
|
|
831
|
+
);
|
|
822
832
|
}
|
|
823
833
|
|
|
824
834
|
this.logger.warn(
|
|
@@ -831,11 +841,21 @@ export class OAuthService {
|
|
|
831
841
|
locale,
|
|
832
842
|
'Unable to complete OAuth authentication right now. Please try again.',
|
|
833
843
|
),
|
|
844
|
+
// `description` vai junto porque o Nest só aplica o default dela quando o
|
|
845
|
+
// segundo argumento é ausente ou string: passar apenas `{ cause }` deixaria
|
|
846
|
+
// o campo `error` do corpo como undefined.
|
|
847
|
+
{ cause: error, description: 'Service Unavailable' },
|
|
834
848
|
);
|
|
835
849
|
}
|
|
836
850
|
|
|
851
|
+
// Ramo de último recurso: um erro que ninguém classificou. Como a resposta ao
|
|
852
|
+
// usuário é genérica por definição, o log e a causa encadeada são o único
|
|
853
|
+
// rastro que sobra — sem eles o evento no Sentry chega sem status, sem corpo
|
|
854
|
+
// do provider e com o stack enraizado aqui, e não dá para agir.
|
|
855
|
+
const detail = error as any;
|
|
837
856
|
this.logger.error(
|
|
838
|
-
`Unexpected OAuth callback failure: provider=${provider} type=${type} error=${error instanceof Error ? error.message : 'unknown'}`,
|
|
857
|
+
`Unexpected OAuth callback failure: provider=${provider} type=${type} name=${detail?.name ?? 'unknown'} code=${detail?.code ?? 'n/a'} status=${detail?.response?.status ?? 'n/a'} error=${error instanceof Error ? error.message : 'unknown'}`,
|
|
858
|
+
error instanceof Error ? error.stack : undefined,
|
|
839
859
|
);
|
|
840
860
|
|
|
841
861
|
return new ServiceUnavailableException(
|
|
@@ -844,10 +864,27 @@ export class OAuthService {
|
|
|
844
864
|
locale,
|
|
845
865
|
'Unable to complete OAuth authentication right now. Please try again.',
|
|
846
866
|
),
|
|
867
|
+
{ cause: error, description: 'Service Unavailable' },
|
|
847
868
|
);
|
|
848
869
|
}
|
|
849
870
|
|
|
850
|
-
|
|
871
|
+
/**
|
|
872
|
+
* Corpo dos 400 de callback. O `oauthReason` é a chave estável que o frontend
|
|
873
|
+
* usa para reconhecer "código já consumido" — antes disso os apps casavam a
|
|
874
|
+
* substring "already processed", que só existe no texto em inglês e portanto
|
|
875
|
+
* nunca disparava para quem usa o Hub em pt-BR. O `error` vai explícito para o
|
|
876
|
+
* envelope da resposta continuar idêntico ao que o Nest monta sozinho.
|
|
877
|
+
*/
|
|
878
|
+
private buildCallbackErrorBody(oauthReason: string, message: string) {
|
|
879
|
+
return {
|
|
880
|
+
statusCode: HttpStatus.BAD_REQUEST,
|
|
881
|
+
message,
|
|
882
|
+
error: 'Bad Request',
|
|
883
|
+
oauthReason,
|
|
884
|
+
};
|
|
885
|
+
}
|
|
886
|
+
|
|
887
|
+
private async handleLogin(res: Response, locale: string, ipAddress: string, userAgent: string, provider: user_account_provider_52222e2ecb_enum, profile: any) {
|
|
851
888
|
const userAccount = await this.prisma.user_account.findFirst({
|
|
852
889
|
where: {
|
|
853
890
|
provider: String(provider).toLowerCase().replace(/-/g, '_') as user_account_provider_52222e2ecb_enum,
|
|
@@ -897,11 +934,11 @@ export class OAuthService {
|
|
|
897
934
|
);
|
|
898
935
|
|
|
899
936
|
await this.token.setRefreshTokenCookie(locale, res, refreshToken, session.expires_at);
|
|
900
|
-
return this.formatAuthResponse(accessToken, refreshToken
|
|
937
|
+
return this.formatAuthResponse(accessToken, refreshToken);
|
|
901
938
|
}
|
|
902
939
|
}
|
|
903
940
|
|
|
904
|
-
private async handleRegister(res: Response, locale: string, ipAddress: string, userAgent: string, provider: user_account_provider_52222e2ecb_enum, profile: any,
|
|
941
|
+
private async handleRegister(res: Response, locale: string, ipAddress: string, userAgent: string, provider: user_account_provider_52222e2ecb_enum, profile: any, app?: string) {
|
|
905
942
|
const existingUser = await this.prisma.user_identifier.findFirst({
|
|
906
943
|
where: {
|
|
907
944
|
type: 'email',
|
|
@@ -989,7 +1026,7 @@ export class OAuthService {
|
|
|
989
1026
|
userAgent
|
|
990
1027
|
);
|
|
991
1028
|
await this.token.setRefreshTokenCookie(locale, res, refreshToken, session.expires_at);
|
|
992
|
-
return this.formatAuthResponse(accessToken, refreshToken
|
|
1029
|
+
return this.formatAuthResponse(accessToken, refreshToken);
|
|
993
1030
|
}
|
|
994
1031
|
|
|
995
1032
|
private async handleConnect(
|
|
@@ -1000,7 +1037,6 @@ export class OAuthService {
|
|
|
1000
1037
|
provider: user_account_provider_52222e2ecb_enum,
|
|
1001
1038
|
profile: any,
|
|
1002
1039
|
userId: number,
|
|
1003
|
-
includeRefreshTokenInBody?: boolean,
|
|
1004
1040
|
) {
|
|
1005
1041
|
const existingAccount = await this.prisma.user_account.findFirst({
|
|
1006
1042
|
where: {
|
|
@@ -1057,7 +1093,7 @@ export class OAuthService {
|
|
|
1057
1093
|
await this.user.registerUserActivity(userId, 'oauth-connect');
|
|
1058
1094
|
const { accessToken, refreshToken, session } = await this.auth.getAuthenticationPayload(locale, user.id, ipAddress, userAgent);
|
|
1059
1095
|
await this.token.setRefreshTokenCookie(locale, res, refreshToken, session.expires_at);
|
|
1060
|
-
return this.formatAuthResponse(accessToken, refreshToken
|
|
1096
|
+
return this.formatAuthResponse(accessToken, refreshToken);
|
|
1061
1097
|
}
|
|
1062
1098
|
|
|
1063
1099
|
private async handleDisconnect(res: Response, locale: string, ipAddress: string, userAgent: string, provider: user_account_provider_52222e2ecb_enum, email: string) {
|
|
@@ -1080,7 +1116,10 @@ export class OAuthService {
|
|
|
1080
1116
|
await this.user.registerUserActivity(userAccount.user.id, 'oauth-disconnect');
|
|
1081
1117
|
const { accessToken, refreshToken, session } = await this.auth.getAuthenticationPayload(locale, userAccount.user.id, ipAddress, userAgent);
|
|
1082
1118
|
await this.token.setRefreshTokenCookie(locale, res, refreshToken, session.expires_at);
|
|
1083
|
-
|
|
1119
|
+
// Sessão NOVA (o `getAuthenticationPayload` acima cria uma), então o par vai
|
|
1120
|
+
// inteiro no corpo, como nos demais fluxos: devolver só o access token deixava
|
|
1121
|
+
// o cliente com um token de uma sessão e o refresh token de outra.
|
|
1122
|
+
return this.formatAuthResponse(accessToken, refreshToken);
|
|
1084
1123
|
}
|
|
1085
1124
|
|
|
1086
1125
|
private async downloadAndSaveProfilePicture(
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
import { describe, expect, it, jest } from '@jest/globals';
|
|
2
|
+
import { HttpService } from '@nestjs/axios';
|
|
3
|
+
import { of, throwError } from 'rxjs';
|
|
4
|
+
import { OAuthProviderException } from '../oauth.errors';
|
|
5
|
+
import { BaseOAuthProvider } from './abstract.provider';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Estes testes existem por causa do incidente API-6: os helpers da base deixavam
|
|
9
|
+
* o AxiosError cru subir, e como ele não é `OAuthProviderException` o
|
|
10
|
+
* `OAuthService.mapCallbackError` o jogava no ramo genérico — um `invalid_grant`
|
|
11
|
+
* (código reusado/expirado, o caso comum no Safari do iOS) respondia 503
|
|
12
|
+
* "tente novamente" em vez de 400 "refaça o login".
|
|
13
|
+
*/
|
|
14
|
+
class TestProvider extends BaseOAuthProvider {
|
|
15
|
+
getProviderType() {
|
|
16
|
+
return 'TEST';
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
async getAuthUrl() {
|
|
20
|
+
return 'https://example.test/authorize';
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
async getProfile() {
|
|
24
|
+
return {};
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// Os membros abaixo apenas expõem os protegidos da base para o teste.
|
|
28
|
+
callFetchToken() {
|
|
29
|
+
return this.fetchToken({
|
|
30
|
+
code: 'CODE',
|
|
31
|
+
url: 'https://example.test/token',
|
|
32
|
+
clientId: 'id',
|
|
33
|
+
clientSecret: 'secret',
|
|
34
|
+
redirectUri: 'https://example.test/callback',
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
callFetchProfile() {
|
|
39
|
+
return this.fetchProfile('ACCESS_TOKEN', 'https://example.test/me');
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
callMapProviderError(error: unknown) {
|
|
43
|
+
return this.mapProviderError('TEST', error);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const makeProvider = () => {
|
|
48
|
+
const http = { post: jest.fn(), get: jest.fn() };
|
|
49
|
+
return { provider: new TestProvider(http as unknown as HttpService), http };
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
/** Erro no formato que o axios entrega quando o provider responde com status de erro. */
|
|
53
|
+
const upstreamError = (status: number, data: unknown) =>
|
|
54
|
+
Object.assign(new Error(`Request failed with status code ${status}`), {
|
|
55
|
+
isAxiosError: true,
|
|
56
|
+
response: { status, data },
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
/** Erro de transporte: não chega a existir resposta, só o código do socket. */
|
|
60
|
+
const networkError = (code: string) =>
|
|
61
|
+
Object.assign(new Error(code), { isAxiosError: true, code });
|
|
62
|
+
|
|
63
|
+
describe('BaseOAuthProvider.fetchToken', () => {
|
|
64
|
+
it('devolve os dados quando a troca do código dá certo', async () => {
|
|
65
|
+
const { provider, http } = makeProvider();
|
|
66
|
+
http.post.mockReturnValue(of({ data: { access_token: 'AT' } }) as never);
|
|
67
|
+
|
|
68
|
+
await expect(provider.callFetchToken()).resolves.toEqual({ access_token: 'AT' });
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
it('traduz invalid_grant para invalid_callback (regressão do API-6)', async () => {
|
|
72
|
+
const { provider, http } = makeProvider();
|
|
73
|
+
const original = upstreamError(400, {
|
|
74
|
+
error: 'invalid_grant',
|
|
75
|
+
error_description: 'Code was already redeemed.',
|
|
76
|
+
});
|
|
77
|
+
http.post.mockReturnValue(throwError(() => original) as never);
|
|
78
|
+
|
|
79
|
+
const error = await provider.callFetchToken().catch((e) => e);
|
|
80
|
+
|
|
81
|
+
// Sem isto o erro sai cru e vira 503 lá no OAuthService.
|
|
82
|
+
expect(error).toBeInstanceOf(OAuthProviderException);
|
|
83
|
+
expect(error.reason).toBe('callback_consumed');
|
|
84
|
+
expect(error.status).toBe(400);
|
|
85
|
+
expect(error.providerError).toBe('invalid_grant');
|
|
86
|
+
expect(error.cause).toBe(original);
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
it('classifica invalid_grant sem "already redeemed" como invalid_callback', async () => {
|
|
90
|
+
const { provider, http } = makeProvider();
|
|
91
|
+
http.post.mockReturnValue(
|
|
92
|
+
throwError(() => upstreamError(400, { error: 'invalid_grant' })) as never,
|
|
93
|
+
);
|
|
94
|
+
|
|
95
|
+
const error = await provider.callFetchToken().catch((e) => e);
|
|
96
|
+
|
|
97
|
+
expect(error.reason).toBe('invalid_callback');
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
it('trata bad_verification_code do GitHub como código inválido', async () => {
|
|
101
|
+
const { provider, http } = makeProvider();
|
|
102
|
+
http.post.mockReturnValue(
|
|
103
|
+
throwError(() => upstreamError(200, { error: 'bad_verification_code' })) as never,
|
|
104
|
+
);
|
|
105
|
+
|
|
106
|
+
const error = await provider.callFetchToken().catch((e) => e);
|
|
107
|
+
|
|
108
|
+
expect(error.reason).toBe('invalid_callback');
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
it('classifica falha de transporte como upstream_failure preservando o código', async () => {
|
|
112
|
+
const { provider, http } = makeProvider();
|
|
113
|
+
const original = networkError('ECONNABORTED');
|
|
114
|
+
http.post.mockReturnValue(throwError(() => original) as never);
|
|
115
|
+
|
|
116
|
+
const error = await provider.callFetchToken().catch((e) => e);
|
|
117
|
+
|
|
118
|
+
expect(error).toBeInstanceOf(OAuthProviderException);
|
|
119
|
+
expect(error.reason).toBe('upstream_failure');
|
|
120
|
+
expect(error.status).toBeUndefined();
|
|
121
|
+
expect(error.providerError).toBe('ECONNABORTED');
|
|
122
|
+
expect(error.cause).toBe(original);
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
it('classifica erro do servidor do provider como upstream_failure', async () => {
|
|
126
|
+
const { provider, http } = makeProvider();
|
|
127
|
+
http.post.mockReturnValue(
|
|
128
|
+
throwError(() => upstreamError(503, { error: 'server_error' })) as never,
|
|
129
|
+
);
|
|
130
|
+
|
|
131
|
+
const error = await provider.callFetchToken().catch((e) => e);
|
|
132
|
+
|
|
133
|
+
expect(error.reason).toBe('upstream_failure');
|
|
134
|
+
expect(error.status).toBe(503);
|
|
135
|
+
});
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
describe('BaseOAuthProvider.fetchProfile', () => {
|
|
139
|
+
it('devolve os dados do perfil quando dá certo', async () => {
|
|
140
|
+
const { provider, http } = makeProvider();
|
|
141
|
+
http.get.mockReturnValue(of({ data: { email: 'a@b.c' } }) as never);
|
|
142
|
+
|
|
143
|
+
await expect(provider.callFetchProfile()).resolves.toEqual({ email: 'a@b.c' });
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
it('também traduz a falha, não só a troca do código', async () => {
|
|
147
|
+
const { provider, http } = makeProvider();
|
|
148
|
+
http.get.mockReturnValue(
|
|
149
|
+
throwError(() => upstreamError(401, { error: 'invalid_token' })) as never,
|
|
150
|
+
);
|
|
151
|
+
|
|
152
|
+
const error = await provider.callFetchProfile().catch((e) => e);
|
|
153
|
+
|
|
154
|
+
expect(error).toBeInstanceOf(OAuthProviderException);
|
|
155
|
+
expect(error.reason).toBe('upstream_failure');
|
|
156
|
+
expect(error.status).toBe(401);
|
|
157
|
+
});
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
describe('BaseOAuthProvider.mapProviderError', () => {
|
|
161
|
+
it('é idempotente: não reembrulha um erro já traduzido', () => {
|
|
162
|
+
const { provider } = makeProvider();
|
|
163
|
+
const mapped = new OAuthProviderException('TEST', 'invalid_callback', 'msg');
|
|
164
|
+
|
|
165
|
+
// O provider do Entra ID tem o próprio try/catch por cima dos helpers, que
|
|
166
|
+
// agora já mapeiam — sem a idempotência o motivo original seria perdido.
|
|
167
|
+
expect(provider.callMapProviderError(mapped)).toBe(mapped);
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
it('extrai o código AADSTS da descrição quando existe', () => {
|
|
171
|
+
const { provider } = makeProvider();
|
|
172
|
+
|
|
173
|
+
const error = provider.callMapProviderError(
|
|
174
|
+
upstreamError(400, {
|
|
175
|
+
error: 'invalid_grant',
|
|
176
|
+
error_description: 'AADSTS54005: OAuth2 Authorization code was already redeemed.',
|
|
177
|
+
}),
|
|
178
|
+
);
|
|
179
|
+
|
|
180
|
+
expect(error.reason).toBe('callback_consumed');
|
|
181
|
+
expect(error.providerErrorCode).toBe('AADSTS54005');
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
it('usa unknown_error quando não há nada aproveitável no erro', () => {
|
|
185
|
+
const { provider } = makeProvider();
|
|
186
|
+
|
|
187
|
+
const error = provider.callMapProviderError(new Error('boom'));
|
|
188
|
+
|
|
189
|
+
expect(error.reason).toBe('upstream_failure');
|
|
190
|
+
expect(error.providerError).toBe('unknown_error');
|
|
191
|
+
});
|
|
192
|
+
});
|
|
@@ -31,25 +31,47 @@ export abstract class BaseOAuthProvider implements OAuthProvider {
|
|
|
31
31
|
code,
|
|
32
32
|
}).toString();
|
|
33
33
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
34
|
+
try {
|
|
35
|
+
const response = await lastValueFrom(
|
|
36
|
+
this.http.post(url, body, {
|
|
37
|
+
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
38
|
+
}),
|
|
39
|
+
);
|
|
39
40
|
|
|
40
|
-
|
|
41
|
+
return response.data;
|
|
42
|
+
} catch (error) {
|
|
43
|
+
throw this.mapProviderError(this.getProviderType(), error);
|
|
44
|
+
}
|
|
41
45
|
}
|
|
42
46
|
|
|
43
47
|
protected async fetchProfile(accessToken: string, url: string) {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
48
|
+
try {
|
|
49
|
+
const response = await lastValueFrom(
|
|
50
|
+
this.http.get(url, {
|
|
51
|
+
headers: { Authorization: `Bearer ${accessToken}` },
|
|
52
|
+
}),
|
|
53
|
+
);
|
|
54
|
+
return response.data;
|
|
55
|
+
} catch (error) {
|
|
56
|
+
throw this.mapProviderError(this.getProviderType(), error);
|
|
57
|
+
}
|
|
50
58
|
}
|
|
51
59
|
|
|
52
|
-
|
|
60
|
+
/**
|
|
61
|
+
* Traduz a falha crua do provider (quase sempre um AxiosError) para o tipo que
|
|
62
|
+
* `OAuthService.mapCallbackError` sabe classificar. Sem isso o erro atravessa
|
|
63
|
+
* todos os ramos de lá e vira um 503 genérico — inclusive um `invalid_grant`,
|
|
64
|
+
* que é código reusado/expirado e deveria ser 400 "refaça o login".
|
|
65
|
+
*
|
|
66
|
+
* É idempotente de propósito: os helpers acima já mapeiam, então um provider
|
|
67
|
+
* que também tenha o próprio try/catch (Microsoft Entra ID) recebe aqui um
|
|
68
|
+
* erro já traduzido e não pode reembrulhá-lo.
|
|
69
|
+
*/
|
|
70
|
+
protected mapProviderError(provider: string, error: any): OAuthProviderException {
|
|
71
|
+
if (error instanceof OAuthProviderException) {
|
|
72
|
+
return error;
|
|
73
|
+
}
|
|
74
|
+
|
|
53
75
|
const providerError = this.extractProviderError(error);
|
|
54
76
|
const providerErrorCode = this.extractProviderErrorCode(error);
|
|
55
77
|
const status = error?.response?.status;
|
|
@@ -62,6 +84,7 @@ export abstract class BaseOAuthProvider implements OAuthProvider {
|
|
|
62
84
|
status,
|
|
63
85
|
providerError,
|
|
64
86
|
providerErrorCode,
|
|
87
|
+
error,
|
|
65
88
|
);
|
|
66
89
|
}
|
|
67
90
|
|
|
@@ -73,6 +96,7 @@ export abstract class BaseOAuthProvider implements OAuthProvider {
|
|
|
73
96
|
status,
|
|
74
97
|
providerError,
|
|
75
98
|
providerErrorCode,
|
|
99
|
+
error,
|
|
76
100
|
);
|
|
77
101
|
}
|
|
78
102
|
|
|
@@ -83,6 +107,7 @@ export abstract class BaseOAuthProvider implements OAuthProvider {
|
|
|
83
107
|
status,
|
|
84
108
|
providerError,
|
|
85
109
|
providerErrorCode,
|
|
110
|
+
error,
|
|
86
111
|
);
|
|
87
112
|
}
|
|
88
113
|
|
|
@@ -109,6 +134,13 @@ export abstract class BaseOAuthProvider implements OAuthProvider {
|
|
|
109
134
|
}
|
|
110
135
|
|
|
111
136
|
protected isInvalidAuthorizationCodeError(error: any) {
|
|
112
|
-
|
|
137
|
+
const providerError = this.extractProviderError(error);
|
|
138
|
+
|
|
139
|
+
// `bad_verification_code` é o `invalid_grant` do GitHub, que responde 200 com
|
|
140
|
+
// o erro no corpo em vez de status de erro.
|
|
141
|
+
return (
|
|
142
|
+
providerError === 'invalid_grant' ||
|
|
143
|
+
providerError === 'bad_verification_code'
|
|
144
|
+
);
|
|
113
145
|
}
|
|
114
146
|
}
|
|
@@ -76,52 +76,75 @@ export class GithubProvider extends BaseOAuthProvider {
|
|
|
76
76
|
const redirectURI = redirectUri?.trim()
|
|
77
77
|
? redirectUri.trim()
|
|
78
78
|
: new URL(fixedCallbackPath, apiUrl.replace(':3200', ':3100')).toString();
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
79
|
+
// Este provider não usa os helpers da base (fala com o axios direto), então
|
|
80
|
+
// precisa do mesmo tratamento de erro que eles aplicam — sem isso o AxiosError
|
|
81
|
+
// cru chega ao OAuthService e vira 503 genérico.
|
|
82
|
+
let tokenResponse: any;
|
|
83
|
+
try {
|
|
84
|
+
tokenResponse = await this.http.axiosRef.post(
|
|
85
|
+
'https://github.com/login/oauth/access_token',
|
|
86
|
+
{
|
|
87
|
+
client_id: clientId,
|
|
88
|
+
client_secret: clientSecret,
|
|
89
|
+
code,
|
|
90
|
+
redirect_uri: redirectURI,
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
headers: {
|
|
94
|
+
Accept: 'application/json',
|
|
95
|
+
},
|
|
90
96
|
},
|
|
91
|
-
},
|
|
92
|
-
);
|
|
93
|
-
|
|
94
|
-
const { access_token, error, error_description } = tokenResponse.data;
|
|
95
|
-
if (error || !access_token) {
|
|
96
|
-
throw new Error(
|
|
97
|
-
`GitHub OAuth error: ${error_description || error || 'No access token received'}`,
|
|
98
97
|
);
|
|
98
|
+
} catch (error) {
|
|
99
|
+
throw this.mapProviderError(this.getProviderType(), error);
|
|
99
100
|
}
|
|
100
101
|
|
|
101
|
-
const
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
102
|
+
const { access_token, error, error_description } = tokenResponse.data;
|
|
103
|
+
if (error || !access_token) {
|
|
104
|
+
// O GitHub responde 200 com o erro no corpo, então não há AxiosError para
|
|
105
|
+
// capturar: monta-se a mesma forma que o mapeador lê.
|
|
106
|
+
throw this.mapProviderError(this.getProviderType(), {
|
|
107
|
+
response: {
|
|
108
|
+
status: tokenResponse.status,
|
|
109
|
+
data: {
|
|
110
|
+
error: error || 'no_access_token',
|
|
111
|
+
error_description:
|
|
112
|
+
error_description || 'No access token received from GitHub.',
|
|
113
|
+
},
|
|
106
114
|
},
|
|
107
|
-
}
|
|
108
|
-
|
|
115
|
+
});
|
|
116
|
+
}
|
|
109
117
|
|
|
110
|
-
|
|
111
|
-
let email
|
|
112
|
-
|
|
113
|
-
const
|
|
114
|
-
'https://api.github.com/user
|
|
118
|
+
let profile: any;
|
|
119
|
+
let email: string | null;
|
|
120
|
+
try {
|
|
121
|
+
const profileResponse = await this.http.axiosRef.get(
|
|
122
|
+
'https://api.github.com/user',
|
|
115
123
|
{
|
|
116
124
|
headers: {
|
|
117
125
|
Authorization: `Bearer ${access_token}`,
|
|
118
126
|
},
|
|
119
127
|
},
|
|
120
128
|
);
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
129
|
+
|
|
130
|
+
profile = profileResponse.data;
|
|
131
|
+
email = profile.email;
|
|
132
|
+
if (!email) {
|
|
133
|
+
const emailResponse = await this.http.axiosRef.get(
|
|
134
|
+
'https://api.github.com/user/emails',
|
|
135
|
+
{
|
|
136
|
+
headers: {
|
|
137
|
+
Authorization: `Bearer ${access_token}`,
|
|
138
|
+
},
|
|
139
|
+
},
|
|
140
|
+
);
|
|
141
|
+
const primaryEmail = emailResponse.data.find(
|
|
142
|
+
(e: any) => e.primary && e.verified,
|
|
143
|
+
);
|
|
144
|
+
email = primaryEmail?.email || null;
|
|
145
|
+
}
|
|
146
|
+
} catch (error) {
|
|
147
|
+
throw this.mapProviderError(this.getProviderType(), error);
|
|
125
148
|
}
|
|
126
149
|
|
|
127
150
|
return {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { PrismaService } from '@hed-hog/api-prisma';
|
|
2
2
|
import { HttpService } from '@nestjs/axios';
|
|
3
|
-
import { BadRequestException, forwardRef, Inject, Injectable, Logger } from '@nestjs/common';
|
|
3
|
+
import { BadRequestException, forwardRef, HttpException, Inject, Injectable, Logger } from '@nestjs/common';
|
|
4
4
|
import { buildOAuthConfigFromIntegration } from '../../integration-profile/integration-profile.utils';
|
|
5
5
|
import { SettingService } from '../../setting/setting.service';
|
|
6
6
|
import { BaseOAuthProvider } from './abstract.provider';
|
|
@@ -174,6 +174,13 @@ export class MicrosoftEntraIdProvider extends BaseOAuthProvider {
|
|
|
174
174
|
},
|
|
175
175
|
};
|
|
176
176
|
} catch (error: any) {
|
|
177
|
+
// O try acima cobre também o `loadConfig`, que sinaliza perfil ausente com
|
|
178
|
+
// uma HttpException — mapeá-la transformaria um 400 de configuração em um
|
|
179
|
+
// 503 de indisponibilidade.
|
|
180
|
+
if (error instanceof HttpException) {
|
|
181
|
+
throw error;
|
|
182
|
+
}
|
|
183
|
+
|
|
177
184
|
const mappedError = this.mapProviderError('Microsoft Entra ID', error);
|
|
178
185
|
|
|
179
186
|
this.logger.warn(
|