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