@hed-hog/core 0.0.387 → 0.0.393
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/README.md +51 -11
- package/dist/access-log/access-log.controller.d.ts.map +1 -1
- package/dist/access-log/access-log.controller.js +1 -1
- package/dist/access-log/access-log.controller.js.map +1 -1
- package/dist/access-log/access-log.interceptor.d.ts.map +1 -1
- package/dist/access-log/access-log.interceptor.js +11 -6
- package/dist/access-log/access-log.interceptor.js.map +1 -1
- package/dist/access-log/access-log.service.d.ts +4 -0
- package/dist/access-log/access-log.service.d.ts.map +1 -1
- package/dist/access-log/access-log.service.js +31 -4
- package/dist/access-log/access-log.service.js.map +1 -1
- package/dist/access-log/dto/query-access-log.dto.d.ts +2 -0
- package/dist/access-log/dto/query-access-log.dto.d.ts.map +1 -1
- package/dist/access-log/dto/query-access-log.dto.js +5 -0
- package/dist/access-log/dto/query-access-log.dto.js.map +1 -1
- package/dist/ai/ai-attachment.fragments.d.ts +23 -0
- package/dist/ai/ai-attachment.fragments.d.ts.map +1 -0
- package/dist/ai/ai-attachment.fragments.js +34 -0
- package/dist/ai/ai-attachment.fragments.js.map +1 -0
- package/dist/ai/ai.controller.d.ts +12 -17
- package/dist/ai/ai.controller.d.ts.map +1 -1
- package/dist/ai/ai.controller.js +17 -2
- package/dist/ai/ai.controller.js.map +1 -1
- package/dist/ai/ai.module.d.ts.map +1 -1
- package/dist/ai/ai.module.js +3 -2
- package/dist/ai/ai.module.js.map +1 -1
- package/dist/ai/ai.prompts.d.ts +16 -0
- package/dist/ai/ai.prompts.d.ts.map +1 -0
- package/dist/ai/ai.prompts.js +37 -0
- package/dist/ai/ai.prompts.js.map +1 -0
- package/dist/ai/ai.service.d.ts +92 -12
- package/dist/ai/ai.service.d.ts.map +1 -1
- package/dist/ai/ai.service.js +309 -88
- package/dist/ai/ai.service.js.map +1 -1
- package/dist/ai/dto/chat.dto.d.ts +4 -1
- package/dist/ai/dto/chat.dto.d.ts.map +1 -1
- package/dist/ai/dto/chat.dto.js +23 -1
- package/dist/ai/dto/chat.dto.js.map +1 -1
- package/dist/ai/dto/create-agent.dto.d.ts +1 -1
- package/dist/ai/dto/create-agent.dto.d.ts.map +1 -1
- package/dist/ai/dto/create-agent.dto.js +1 -1
- package/dist/ai/dto/create-agent.dto.js.map +1 -1
- package/dist/ai/dto/richtext-edit-html.dto.d.ts +5 -0
- package/dist/ai/dto/richtext-edit-html.dto.d.ts.map +1 -0
- package/dist/ai/dto/richtext-edit-html.dto.js +27 -0
- package/dist/ai/dto/richtext-edit-html.dto.js.map +1 -0
- package/dist/ai/dto/update-agent.dto.d.ts +1 -1
- package/dist/ai/dto/update-agent.dto.d.ts.map +1 -1
- package/dist/ai/dto/update-agent.dto.js +1 -1
- package/dist/ai/dto/update-agent.dto.js.map +1 -1
- package/dist/ai/richtext-ai.prompts.d.ts +5 -0
- package/dist/ai/richtext-ai.prompts.d.ts.map +1 -0
- package/dist/ai/richtext-ai.prompts.js +57 -0
- package/dist/ai/richtext-ai.prompts.js.map +1 -0
- package/dist/ai/richtext-ai.service.d.ts +34 -0
- package/dist/ai/richtext-ai.service.d.ts.map +1 -0
- package/dist/ai/richtext-ai.service.js +95 -0
- package/dist/ai/richtext-ai.service.js.map +1 -0
- package/dist/ai-instruction/ai-instruction.controller.d.ts +59 -5
- package/dist/ai-instruction/ai-instruction.controller.d.ts.map +1 -1
- package/dist/ai-instruction/ai-instruction.controller.js +63 -20
- package/dist/ai-instruction/ai-instruction.controller.js.map +1 -1
- package/dist/ai-instruction/ai-instruction.module.d.ts.map +1 -1
- package/dist/ai-instruction/ai-instruction.module.js +13 -2
- package/dist/ai-instruction/ai-instruction.module.js.map +1 -1
- package/dist/ai-instruction/ai-instruction.service.d.ts +131 -6
- package/dist/ai-instruction/ai-instruction.service.d.ts.map +1 -1
- package/dist/ai-instruction/ai-instruction.service.js +533 -60
- package/dist/ai-instruction/ai-instruction.service.js.map +1 -1
- package/dist/ai-instruction/ai-prompt-builder.service.d.ts +8 -0
- package/dist/ai-instruction/ai-prompt-builder.service.d.ts.map +1 -1
- package/dist/ai-instruction/ai-prompt-builder.service.js +10 -1
- package/dist/ai-instruction/ai-prompt-builder.service.js.map +1 -1
- package/dist/ai-instruction/ai-prompt-registry.d.ts +45 -0
- package/dist/ai-instruction/ai-prompt-registry.d.ts.map +1 -0
- package/dist/ai-instruction/ai-prompt-registry.js +49 -0
- package/dist/ai-instruction/ai-prompt-registry.js.map +1 -0
- package/dist/ai-instruction/ai-prompt-resolver.service.d.ts +89 -0
- package/dist/ai-instruction/ai-prompt-resolver.service.d.ts.map +1 -0
- package/dist/ai-instruction/ai-prompt-resolver.service.js +222 -0
- package/dist/ai-instruction/ai-prompt-resolver.service.js.map +1 -0
- package/dist/ai-instruction/ai-prompt-template.util.d.ts +70 -0
- package/dist/ai-instruction/ai-prompt-template.util.d.ts.map +1 -0
- package/dist/ai-instruction/ai-prompt-template.util.js +154 -0
- package/dist/ai-instruction/ai-prompt-template.util.js.map +1 -0
- package/dist/ai-instruction/dto/create-ai-instruction.dto.d.ts +5 -0
- package/dist/ai-instruction/dto/create-ai-instruction.dto.d.ts.map +1 -1
- package/dist/ai-instruction/dto/create-ai-instruction.dto.js +27 -1
- package/dist/ai-instruction/dto/create-ai-instruction.dto.js.map +1 -1
- package/dist/ai-instruction/dto/preview-ai-instruction.dto.d.ts +14 -0
- package/dist/ai-instruction/dto/preview-ai-instruction.dto.d.ts.map +1 -0
- package/dist/ai-instruction/dto/preview-ai-instruction.dto.js +42 -0
- package/dist/ai-instruction/dto/preview-ai-instruction.dto.js.map +1 -0
- package/dist/ai-instruction/dto/update-ai-instruction.dto.d.ts +11 -0
- package/dist/ai-instruction/dto/update-ai-instruction.dto.d.ts.map +1 -1
- package/dist/ai-instruction/dto/update-ai-instruction.dto.js +34 -0
- package/dist/ai-instruction/dto/update-ai-instruction.dto.js.map +1 -1
- package/dist/ai-instruction/types/ai-instruction.types.d.ts +13 -1
- package/dist/ai-instruction/types/ai-instruction.types.d.ts.map +1 -1
- package/dist/ai-instruction/types/ai-instruction.types.js +10 -0
- package/dist/ai-instruction/types/ai-instruction.types.js.map +1 -1
- package/dist/auth/auth.controller.d.ts +89 -15
- package/dist/auth/auth.controller.d.ts.map +1 -1
- package/dist/auth/auth.controller.js +116 -44
- package/dist/auth/auth.controller.js.map +1 -1
- package/dist/auth/auth.module.d.ts.map +1 -1
- package/dist/auth/auth.module.js +2 -0
- package/dist/auth/auth.module.js.map +1 -1
- package/dist/auth/auth.service.d.ts +169 -12
- package/dist/auth/auth.service.d.ts.map +1 -1
- package/dist/auth/auth.service.js +314 -67
- package/dist/auth/auth.service.js.map +1 -1
- package/dist/auth/dto/confirm-email.dto.d.ts +4 -0
- package/dist/auth/dto/confirm-email.dto.d.ts.map +1 -0
- package/dist/auth/dto/confirm-email.dto.js +22 -0
- package/dist/auth/dto/confirm-email.dto.js.map +1 -0
- package/dist/auth/dto/resend-confirmation.dto.d.ts +8 -0
- package/dist/auth/dto/resend-confirmation.dto.d.ts.map +1 -0
- package/dist/auth/dto/resend-confirmation.dto.js +36 -0
- package/dist/auth/dto/resend-confirmation.dto.js.map +1 -0
- package/dist/authorize/authorize.controller.d.ts +1 -1
- package/dist/authorize/authorize.controller.d.ts.map +1 -1
- package/dist/authorize/authorize.controller.js +4 -2
- package/dist/authorize/authorize.controller.js.map +1 -1
- package/dist/authorize/authorize.service.d.ts +7 -0
- package/dist/authorize/authorize.service.d.ts.map +1 -1
- package/dist/authorize/authorize.service.js +1 -1
- package/dist/authorize/authorize.service.js.map +1 -1
- package/dist/captcha/captcha.module.d.ts +3 -0
- package/dist/captcha/captcha.module.d.ts.map +1 -0
- package/dist/captcha/captcha.module.js +23 -0
- package/dist/captcha/captcha.module.js.map +1 -0
- package/dist/captcha/captcha.service.d.ts +38 -0
- package/dist/captcha/captcha.service.d.ts.map +1 -0
- package/dist/captcha/captcha.service.js +144 -0
- package/dist/captcha/captcha.service.js.map +1 -0
- package/dist/challenge/challenge.service.d.ts +31 -9
- package/dist/challenge/challenge.service.d.ts.map +1 -1
- package/dist/challenge/challenge.service.js +111 -16
- package/dist/challenge/challenge.service.js.map +1 -1
- package/dist/core.module.d.ts +3 -1
- package/dist/core.module.d.ts.map +1 -1
- package/dist/core.module.js +46 -2
- package/dist/core.module.js.map +1 -1
- package/dist/dashboard/dashboard/dashboard.controller.d.ts +21 -21
- package/dist/dashboard/dashboard/dashboard.service.d.ts +21 -21
- package/dist/dashboard/dashboard-component/dashboard-component.controller.d.ts +10 -10
- package/dist/dashboard/dashboard-component/dashboard-component.service.d.ts +10 -10
- package/dist/dashboard/dashboard-component-role/dashboard-component-role.controller.d.ts +20 -20
- package/dist/dashboard/dashboard-component-role/dashboard-component-role.service.d.ts +20 -20
- package/dist/dashboard/dashboard-core/dashboard-core.controller.d.ts +3 -3
- package/dist/dashboard/dashboard-core/dashboard-core.service.d.ts +3 -3
- package/dist/dashboard/dashboard-item/dashboard-item.controller.d.ts +2 -2
- package/dist/dashboard/dashboard-item/dashboard-item.service.d.ts +2 -2
- package/dist/dashboard/dashboard-role/dashboard-role.controller.d.ts +13 -13
- package/dist/dashboard/dashboard-role/dashboard-role.service.d.ts +13 -13
- package/dist/file/file.controller.d.ts +8 -1
- package/dist/file/file.controller.d.ts.map +1 -1
- package/dist/file/file.controller.js +45 -7
- package/dist/file/file.controller.js.map +1 -1
- package/dist/file/file.service.d.ts +134 -1
- package/dist/file/file.service.d.ts.map +1 -1
- package/dist/file/file.service.js +363 -12
- package/dist/file/file.service.js.map +1 -1
- package/dist/file/image-optimization.service.d.ts +43 -0
- package/dist/file/image-optimization.service.d.ts.map +1 -1
- package/dist/file/image-optimization.service.js +154 -0
- package/dist/file/image-optimization.service.js.map +1 -1
- package/dist/file/provider/abstract.provider.d.ts +16 -0
- package/dist/file/provider/abstract.provider.d.ts.map +1 -1
- package/dist/file/provider/abstract.provider.js +4 -0
- package/dist/file/provider/abstract.provider.js.map +1 -1
- package/dist/file/provider/gcs.provider.d.ts +2 -0
- package/dist/file/provider/gcs.provider.d.ts.map +1 -1
- package/dist/file/provider/gcs.provider.js +10 -0
- package/dist/file/provider/gcs.provider.js.map +1 -1
- package/dist/file/provider/local.provider.d.ts +1 -0
- package/dist/file/provider/local.provider.d.ts.map +1 -1
- package/dist/file/provider/local.provider.js +13 -0
- package/dist/file/provider/local.provider.js.map +1 -1
- package/dist/file/provider/s3.provider.d.ts +5 -0
- package/dist/file/provider/s3.provider.d.ts.map +1 -1
- package/dist/file/provider/s3.provider.js +15 -0
- package/dist/file/provider/s3.provider.js.map +1 -1
- package/dist/file/provider/spaces.provider.d.ts +5 -0
- package/dist/file/provider/spaces.provider.d.ts.map +1 -1
- package/dist/file/provider/spaces.provider.js +16 -0
- package/dist/file/provider/spaces.provider.js.map +1 -1
- package/dist/impersonation/dto/redeem-impersonation.dto.d.ts +4 -0
- package/dist/impersonation/dto/redeem-impersonation.dto.d.ts.map +1 -0
- package/dist/impersonation/dto/redeem-impersonation.dto.js +23 -0
- package/dist/impersonation/dto/redeem-impersonation.dto.js.map +1 -0
- package/dist/impersonation/dto/start-impersonation.dto.d.ts +7 -0
- package/dist/impersonation/dto/start-impersonation.dto.d.ts.map +1 -0
- package/dist/impersonation/dto/start-impersonation.dto.js +27 -0
- package/dist/impersonation/dto/start-impersonation.dto.js.map +1 -0
- package/dist/impersonation/impersonation-restrictions.d.ts +26 -0
- package/dist/impersonation/impersonation-restrictions.d.ts.map +1 -0
- package/dist/impersonation/impersonation-restrictions.js +76 -0
- package/dist/impersonation/impersonation-restrictions.js.map +1 -0
- package/dist/impersonation/impersonation.controller.d.ts +90 -0
- package/dist/impersonation/impersonation.controller.d.ts.map +1 -0
- package/dist/impersonation/impersonation.controller.js +135 -0
- package/dist/impersonation/impersonation.controller.js.map +1 -0
- package/dist/impersonation/impersonation.module.d.ts +8 -0
- package/dist/impersonation/impersonation.module.d.ts.map +1 -0
- package/dist/impersonation/impersonation.module.js +44 -0
- package/dist/impersonation/impersonation.module.js.map +1 -0
- package/dist/impersonation/impersonation.service.d.ts +164 -0
- package/dist/impersonation/impersonation.service.d.ts.map +1 -0
- package/dist/impersonation/impersonation.service.js +408 -0
- package/dist/impersonation/impersonation.service.js.map +1 -0
- package/dist/incident/incident-notifier.service.d.ts +36 -0
- package/dist/incident/incident-notifier.service.d.ts.map +1 -0
- package/dist/incident/incident-notifier.service.js +208 -0
- package/dist/incident/incident-notifier.service.js.map +1 -0
- package/dist/incident/incident.controller.d.ts +23 -0
- package/dist/incident/incident.controller.d.ts.map +1 -0
- package/dist/incident/incident.controller.js +75 -0
- package/dist/incident/incident.controller.js.map +1 -0
- package/dist/incident/incident.module.d.ts +7 -0
- package/dist/incident/incident.module.d.ts.map +1 -0
- package/dist/incident/incident.module.js +32 -0
- package/dist/incident/incident.module.js.map +1 -0
- package/dist/incident/incident.service.d.ts +72 -0
- package/dist/incident/incident.service.d.ts.map +1 -0
- package/dist/incident/incident.service.js +184 -0
- package/dist/incident/incident.service.js.map +1 -0
- package/dist/index.d.ts +43 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +49 -0
- package/dist/index.js.map +1 -1
- package/dist/integration/services/outbox-polling.coordinator.d.ts +2 -0
- package/dist/integration/services/outbox-polling.coordinator.d.ts.map +1 -1
- package/dist/integration/services/outbox-polling.coordinator.js +50 -30
- package/dist/integration/services/outbox-polling.coordinator.js.map +1 -1
- package/dist/integration/services/outbox.service.d.ts.map +1 -1
- package/dist/integration/services/outbox.service.js +5 -1
- package/dist/integration/services/outbox.service.js.map +1 -1
- package/dist/integration-profile/dto/test.dto.d.ts +13 -0
- package/dist/integration-profile/dto/test.dto.d.ts.map +1 -0
- package/dist/integration-profile/dto/test.dto.js +26 -0
- package/dist/integration-profile/dto/test.dto.js.map +1 -0
- package/dist/integration-profile/integration-profile.controller.d.ts +12 -1
- package/dist/integration-profile/integration-profile.controller.d.ts.map +1 -1
- package/dist/integration-profile/integration-profile.controller.js +9 -1
- package/dist/integration-profile/integration-profile.controller.js.map +1 -1
- package/dist/integration-profile/integration-profile.module.d.ts +6 -1
- package/dist/integration-profile/integration-profile.module.d.ts.map +1 -1
- package/dist/integration-profile/integration-profile.module.js +26 -3
- package/dist/integration-profile/integration-profile.module.js.map +1 -1
- package/dist/integration-profile/integration-profile.secrets.d.ts.map +1 -1
- package/dist/integration-profile/integration-profile.secrets.js +12 -1
- package/dist/integration-profile/integration-profile.secrets.js.map +1 -1
- package/dist/integration-profile/integration-profile.service.d.ts +26 -7
- package/dist/integration-profile/integration-profile.service.d.ts.map +1 -1
- package/dist/integration-profile/integration-profile.service.js +94 -91
- package/dist/integration-profile/integration-profile.service.js.map +1 -1
- package/dist/integration-profile/integration-profile.utils.d.ts +27 -1
- package/dist/integration-profile/integration-profile.utils.d.ts.map +1 -1
- package/dist/integration-profile/integration-profile.utils.js +46 -5
- package/dist/integration-profile/integration-profile.utils.js.map +1 -1
- package/dist/integration-profile/testers/ai.testers.d.ts +3 -0
- package/dist/integration-profile/testers/ai.testers.d.ts.map +1 -0
- package/dist/integration-profile/testers/ai.testers.js +125 -0
- package/dist/integration-profile/testers/ai.testers.js.map +1 -0
- package/dist/integration-profile/testers/captcha.testers.d.ts +3 -0
- package/dist/integration-profile/testers/captcha.testers.d.ts.map +1 -0
- package/dist/integration-profile/testers/captcha.testers.js +121 -0
- package/dist/integration-profile/testers/captcha.testers.js.map +1 -0
- package/dist/integration-profile/testers/email.testers.d.ts +3 -0
- package/dist/integration-profile/testers/email.testers.d.ts.map +1 -0
- package/dist/integration-profile/testers/email.testers.js +156 -0
- package/dist/integration-profile/testers/email.testers.js.map +1 -0
- package/dist/integration-profile/testers/http-probe.d.ts +57 -0
- package/dist/integration-profile/testers/http-probe.d.ts.map +1 -0
- package/dist/integration-profile/testers/http-probe.js +140 -0
- package/dist/integration-profile/testers/http-probe.js.map +1 -0
- package/dist/integration-profile/testers/index.d.ts +12 -0
- package/dist/integration-profile/testers/index.d.ts.map +1 -0
- package/dist/integration-profile/testers/index.js +45 -0
- package/dist/integration-profile/testers/index.js.map +1 -0
- package/dist/integration-profile/testers/infrastructure.testers.d.ts +3 -0
- package/dist/integration-profile/testers/infrastructure.testers.d.ts.map +1 -0
- package/dist/integration-profile/testers/infrastructure.testers.js +105 -0
- package/dist/integration-profile/testers/infrastructure.testers.js.map +1 -0
- package/dist/integration-profile/testers/integration-tester.registry.d.ts +17 -0
- package/dist/integration-profile/testers/integration-tester.registry.d.ts.map +1 -0
- package/dist/integration-profile/testers/integration-tester.registry.js +52 -0
- package/dist/integration-profile/testers/integration-tester.registry.js.map +1 -0
- package/dist/integration-profile/testers/integration-tester.types.d.ts +55 -0
- package/dist/integration-profile/testers/integration-tester.types.d.ts.map +1 -0
- package/dist/integration-profile/testers/integration-tester.types.js +16 -0
- package/dist/integration-profile/testers/integration-tester.types.js.map +1 -0
- package/dist/integration-profile/testers/messaging.testers.d.ts +3 -0
- package/dist/integration-profile/testers/messaging.testers.d.ts.map +1 -0
- package/dist/integration-profile/testers/messaging.testers.js +70 -0
- package/dist/integration-profile/testers/messaging.testers.js.map +1 -0
- package/dist/integration-profile/testers/oauth.testers.d.ts +3 -0
- package/dist/integration-profile/testers/oauth.testers.d.ts.map +1 -0
- package/dist/integration-profile/testers/oauth.testers.js +285 -0
- package/dist/integration-profile/testers/oauth.testers.js.map +1 -0
- package/dist/integration-profile/testers/payment.testers.d.ts +3 -0
- package/dist/integration-profile/testers/payment.testers.d.ts.map +1 -0
- package/dist/integration-profile/testers/payment.testers.js +169 -0
- package/dist/integration-profile/testers/payment.testers.js.map +1 -0
- package/dist/integration-profile/testers/storage.testers.d.ts +3 -0
- package/dist/integration-profile/testers/storage.testers.d.ts.map +1 -0
- package/dist/integration-profile/testers/storage.testers.js +208 -0
- package/dist/integration-profile/testers/storage.testers.js.map +1 -0
- package/dist/language/en.json +15 -2
- package/dist/language/pt.json +15 -2
- package/dist/leaked-password/leaked-password.controller.d.ts +24 -0
- package/dist/leaked-password/leaked-password.controller.d.ts.map +1 -0
- package/dist/leaked-password/leaked-password.controller.js +78 -0
- package/dist/leaked-password/leaked-password.controller.js.map +1 -0
- package/dist/leaked-password/leaked-password.module.d.ts +8 -0
- package/dist/leaked-password/leaked-password.module.d.ts.map +1 -0
- package/dist/leaked-password/leaked-password.module.js +31 -0
- package/dist/leaked-password/leaked-password.module.js.map +1 -0
- package/dist/leaked-password/leaked-password.service.d.ts +64 -0
- package/dist/leaked-password/leaked-password.service.d.ts.map +1 -0
- package/dist/leaked-password/leaked-password.service.js +218 -0
- package/dist/leaked-password/leaked-password.service.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/preview.dto.d.ts +18 -0
- package/dist/mail/dto/preview.dto.d.ts.map +1 -0
- package/dist/mail/dto/preview.dto.js +66 -0
- package/dist/mail/dto/preview.dto.js.map +1 -0
- package/dist/mail/dto/send.dto.d.ts +44 -0
- package/dist/mail/dto/send.dto.d.ts.map +1 -1
- package/dist/mail/dto/send.dto.js +20 -0
- package/dist/mail/dto/send.dto.js.map +1 -1
- package/dist/mail/mail.controller.d.ts +5 -0
- package/dist/mail/mail.controller.d.ts.map +1 -1
- package/dist/mail/mail.controller.js +16 -2
- package/dist/mail/mail.controller.js.map +1 -1
- package/dist/mail/mail.module.d.ts.map +1 -1
- package/dist/mail/mail.module.js +2 -0
- package/dist/mail/mail.module.js.map +1 -1
- package/dist/mail/mail.service.d.ts +69 -4
- package/dist/mail/mail.service.d.ts.map +1 -1
- package/dist/mail/mail.service.js +278 -37
- package/dist/mail/mail.service.js.map +1 -1
- package/dist/mail-delivery/mail-delivery-provision.service.d.ts +21 -0
- package/dist/mail-delivery/mail-delivery-provision.service.d.ts.map +1 -0
- package/dist/mail-delivery/mail-delivery-provision.service.js +64 -0
- package/dist/mail-delivery/mail-delivery-provision.service.js.map +1 -0
- package/dist/mail-delivery/mail-delivery.constants.d.ts +17 -0
- package/dist/mail-delivery/mail-delivery.constants.d.ts.map +1 -0
- package/dist/mail-delivery/mail-delivery.constants.js +31 -0
- package/dist/mail-delivery/mail-delivery.constants.js.map +1 -0
- package/dist/mail-delivery/mail-delivery.controller.d.ts +19 -0
- package/dist/mail-delivery/mail-delivery.controller.d.ts.map +1 -0
- package/dist/mail-delivery/mail-delivery.controller.js +53 -0
- package/dist/mail-delivery/mail-delivery.controller.js.map +1 -0
- package/dist/mail-delivery/mail-delivery.module.d.ts +7 -0
- package/dist/mail-delivery/mail-delivery.module.d.ts.map +1 -0
- package/dist/mail-delivery/mail-delivery.module.js +36 -0
- package/dist/mail-delivery/mail-delivery.module.js.map +1 -0
- package/dist/mail-delivery/mail-delivery.service.d.ts +38 -0
- package/dist/mail-delivery/mail-delivery.service.d.ts.map +1 -0
- package/dist/mail-delivery/mail-delivery.service.js +140 -0
- package/dist/mail-delivery/mail-delivery.service.js.map +1 -0
- package/dist/mail-delivery/ses-event.parser.d.ts +27 -0
- package/dist/mail-delivery/ses-event.parser.d.ts.map +1 -0
- package/dist/mail-delivery/ses-event.parser.js +131 -0
- package/dist/mail-delivery/ses-event.parser.js.map +1 -0
- package/dist/mail-delivery/ses-webhook.service.d.ts +58 -0
- package/dist/mail-delivery/ses-webhook.service.d.ts.map +1 -0
- package/dist/mail-delivery/ses-webhook.service.js +214 -0
- package/dist/mail-delivery/ses-webhook.service.js.map +1 -0
- package/dist/mail-delivery/sns-message.util.d.ts +38 -0
- package/dist/mail-delivery/sns-message.util.d.ts.map +1 -0
- package/dist/mail-delivery/sns-message.util.js +109 -0
- package/dist/mail-delivery/sns-message.util.js.map +1 -0
- package/dist/mail-layout/dto/update.dto.d.ts +17 -0
- package/dist/mail-layout/dto/update.dto.d.ts.map +1 -0
- package/dist/mail-layout/dto/update.dto.js +27 -0
- package/dist/mail-layout/dto/update.dto.js.map +1 -0
- package/dist/mail-layout/mail-layout.controller.d.ts +15 -0
- package/dist/mail-layout/mail-layout.controller.d.ts.map +1 -0
- package/dist/mail-layout/mail-layout.controller.js +71 -0
- package/dist/mail-layout/mail-layout.controller.js.map +1 -0
- package/dist/mail-layout/mail-layout.module.d.ts +3 -0
- package/dist/mail-layout/mail-layout.module.d.ts.map +1 -0
- package/dist/mail-layout/mail-layout.module.js +35 -0
- package/dist/mail-layout/mail-layout.module.js.map +1 -0
- package/dist/mail-layout/mail-layout.service.d.ts +27 -0
- package/dist/mail-layout/mail-layout.service.d.ts.map +1 -0
- package/dist/mail-layout/mail-layout.service.js +80 -0
- package/dist/mail-layout/mail-layout.service.js.map +1 -0
- package/dist/mail-sent/dto/query-mail-sent-list.dto.d.ts +5 -0
- package/dist/mail-sent/dto/query-mail-sent-list.dto.d.ts.map +1 -1
- package/dist/mail-sent/dto/query-mail-sent-list.dto.js +6 -0
- package/dist/mail-sent/dto/query-mail-sent-list.dto.js.map +1 -1
- package/dist/mail-sent/mail-sent.controller.d.ts +39 -0
- package/dist/mail-sent/mail-sent.controller.d.ts.map +1 -1
- package/dist/mail-sent/mail-sent.service.d.ts +39 -0
- package/dist/mail-sent/mail-sent.service.d.ts.map +1 -1
- package/dist/mail-sent/mail-sent.service.js +45 -4
- package/dist/mail-sent/mail-sent.service.js.map +1 -1
- package/dist/mailbox/mailbox-fetcher.registry.d.ts +100 -0
- package/dist/mailbox/mailbox-fetcher.registry.d.ts.map +1 -0
- package/dist/mailbox/mailbox-fetcher.registry.js +59 -0
- package/dist/mailbox/mailbox-fetcher.registry.js.map +1 -0
- package/dist/mailbox/mailbox.module.d.ts +8 -0
- package/dist/mailbox/mailbox.module.d.ts.map +1 -0
- package/dist/mailbox/mailbox.module.js +27 -0
- package/dist/mailbox/mailbox.module.js.map +1 -0
- package/dist/mcp-chat/mcp-chat.controller.d.ts +2 -2
- package/dist/mcp-chat/mcp-chat.service.d.ts +24 -2
- package/dist/mcp-chat/mcp-chat.service.d.ts.map +1 -1
- package/dist/mcp-chat/mcp-chat.service.js +80 -24
- package/dist/mcp-chat/mcp-chat.service.js.map +1 -1
- package/dist/meeting/meeting-provider.registry.d.ts +155 -0
- package/dist/meeting/meeting-provider.registry.d.ts.map +1 -0
- package/dist/meeting/meeting-provider.registry.js +53 -0
- package/dist/meeting/meeting-provider.registry.js.map +1 -0
- package/dist/meeting/meeting.constants.d.ts +47 -0
- package/dist/meeting/meeting.constants.d.ts.map +1 -0
- package/dist/meeting/meeting.constants.js +21 -0
- package/dist/meeting/meeting.constants.js.map +1 -0
- package/dist/meeting/meeting.module.d.ts +7 -0
- package/dist/meeting/meeting.module.d.ts.map +1 -0
- package/dist/meeting/meeting.module.js +26 -0
- package/dist/meeting/meeting.module.js.map +1 -0
- package/dist/menu/menu.controller.d.ts +3 -3
- package/dist/menu/menu.service.d.ts +3 -3
- package/dist/middlewares/locale-injection.middleware.d.ts +12 -0
- package/dist/middlewares/locale-injection.middleware.d.ts.map +1 -1
- package/dist/middlewares/locale-injection.middleware.js +20 -4
- package/dist/middlewares/locale-injection.middleware.js.map +1 -1
- package/dist/notification/notification.controller.d.ts +12 -12
- package/dist/notification/notification.service.d.ts +12 -12
- package/dist/oauth/oauth-token-broker.service.d.ts +72 -0
- package/dist/oauth/oauth-token-broker.service.d.ts.map +1 -0
- package/dist/oauth/oauth-token-broker.service.js +258 -0
- package/dist/oauth/oauth-token-broker.service.js.map +1 -0
- package/dist/oauth/oauth.module.d.ts.map +1 -1
- package/dist/oauth/oauth.module.js +3 -1
- package/dist/oauth/oauth.module.js.map +1 -1
- package/dist/oauth/oauth.service.d.ts +2 -0
- package/dist/oauth/oauth.service.d.ts.map +1 -1
- package/dist/oauth/oauth.service.js +6 -3
- package/dist/oauth/oauth.service.js.map +1 -1
- package/dist/oauth/providers/google.provider.d.ts +7 -0
- package/dist/oauth/providers/google.provider.d.ts.map +1 -1
- package/dist/oauth/providers/google.provider.js +43 -13
- package/dist/oauth/providers/google.provider.js.map +1 -1
- package/dist/observability/monitored-cron.d.ts +34 -0
- package/dist/observability/monitored-cron.d.ts.map +1 -0
- package/dist/observability/monitored-cron.js +118 -0
- package/dist/observability/monitored-cron.js.map +1 -0
- package/dist/pairing/dto/approve-reverse-pairing.dto.d.ts +12 -0
- package/dist/pairing/dto/approve-reverse-pairing.dto.d.ts.map +1 -0
- package/dist/pairing/dto/approve-reverse-pairing.dto.js +30 -0
- package/dist/pairing/dto/approve-reverse-pairing.dto.js.map +1 -0
- package/dist/pairing/dto/claim-pairing.dto.d.ts +11 -0
- package/dist/pairing/dto/claim-pairing.dto.d.ts.map +1 -0
- package/dist/pairing/dto/claim-pairing.dto.js +35 -0
- package/dist/pairing/dto/claim-pairing.dto.js.map +1 -0
- package/dist/pairing/dto/confirm-pairing.dto.d.ts +10 -0
- package/dist/pairing/dto/confirm-pairing.dto.d.ts.map +1 -0
- package/dist/pairing/dto/confirm-pairing.dto.js +24 -0
- package/dist/pairing/dto/confirm-pairing.dto.js.map +1 -0
- package/dist/pairing/dto/poll-reverse-pairing.dto.d.ts +5 -0
- package/dist/pairing/dto/poll-reverse-pairing.dto.d.ts.map +1 -0
- package/dist/pairing/dto/poll-reverse-pairing.dto.js +24 -0
- package/dist/pairing/dto/poll-reverse-pairing.dto.js.map +1 -0
- package/dist/pairing/dto/start-pairing.dto.d.ts +11 -0
- package/dist/pairing/dto/start-pairing.dto.d.ts.map +1 -0
- package/dist/pairing/dto/start-pairing.dto.js +30 -0
- package/dist/pairing/dto/start-pairing.dto.js.map +1 -0
- package/dist/pairing/dto/start-reverse-pairing.dto.d.ts +24 -0
- package/dist/pairing/dto/start-reverse-pairing.dto.d.ts.map +1 -0
- package/dist/pairing/dto/start-reverse-pairing.dto.js +47 -0
- package/dist/pairing/dto/start-reverse-pairing.dto.js.map +1 -0
- package/dist/pairing/pairing.controller.d.ts +118 -0
- package/dist/pairing/pairing.controller.d.ts.map +1 -0
- package/dist/pairing/pairing.controller.js +296 -0
- package/dist/pairing/pairing.controller.js.map +1 -0
- package/dist/pairing/pairing.module.d.ts +10 -0
- package/dist/pairing/pairing.module.d.ts.map +1 -0
- package/dist/pairing/pairing.module.js +40 -0
- package/dist/pairing/pairing.module.js.map +1 -0
- package/dist/pairing/pairing.service.d.ts +238 -0
- package/dist/pairing/pairing.service.d.ts.map +1 -0
- package/dist/pairing/pairing.service.js +495 -0
- package/dist/pairing/pairing.service.js.map +1 -0
- package/dist/pdf/pdf.service.d.ts +11 -6
- package/dist/pdf/pdf.service.d.ts.map +1 -1
- package/dist/pdf/pdf.service.js +60 -20
- package/dist/pdf/pdf.service.js.map +1 -1
- package/dist/presence/presence.controller.d.ts +16 -0
- package/dist/presence/presence.controller.d.ts.map +1 -0
- package/dist/presence/presence.controller.js +60 -0
- package/dist/presence/presence.controller.js.map +1 -0
- package/dist/presence/presence.listener.d.ts +29 -0
- package/dist/presence/presence.listener.d.ts.map +1 -0
- package/dist/presence/presence.listener.js +82 -0
- package/dist/presence/presence.listener.js.map +1 -0
- package/dist/presence/presence.module.d.ts +3 -0
- package/dist/presence/presence.module.d.ts.map +1 -0
- package/dist/presence/presence.module.js +32 -0
- package/dist/presence/presence.module.js.map +1 -0
- package/dist/presence/presence.service.d.ts +42 -0
- package/dist/presence/presence.service.d.ts.map +1 -0
- package/dist/presence/presence.service.js +147 -0
- package/dist/presence/presence.service.js.map +1 -0
- package/dist/profile/dto/delete-account.dto.d.ts +8 -0
- package/dist/profile/dto/delete-account.dto.d.ts.map +1 -0
- package/dist/profile/dto/delete-account.dto.js +22 -0
- package/dist/profile/dto/delete-account.dto.js.map +1 -0
- package/dist/profile/events/profile-account-deleted.event.d.ts +12 -0
- package/dist/profile/events/profile-account-deleted.event.d.ts.map +1 -0
- package/dist/profile/events/profile-account-deleted.event.js +17 -0
- package/dist/profile/events/profile-account-deleted.event.js.map +1 -0
- package/dist/profile/profile.controller.d.ts +32 -15
- package/dist/profile/profile.controller.d.ts.map +1 -1
- package/dist/profile/profile.controller.js +75 -46
- package/dist/profile/profile.controller.js.map +1 -1
- package/dist/profile/profile.service.d.ts +41 -18
- package/dist/profile/profile.service.d.ts.map +1 -1
- package/dist/profile/profile.service.js +133 -48
- package/dist/profile/profile.service.js.map +1 -1
- package/dist/realtime/realtime.gateway.d.ts +48 -0
- package/dist/realtime/realtime.gateway.d.ts.map +1 -0
- package/dist/realtime/realtime.gateway.js +156 -0
- package/dist/realtime/realtime.gateway.js.map +1 -0
- package/dist/realtime/realtime.module.d.ts +8 -0
- package/dist/realtime/realtime.module.d.ts.map +1 -0
- package/dist/realtime/realtime.module.js +29 -0
- package/dist/realtime/realtime.module.js.map +1 -0
- package/dist/realtime/realtime.service.d.ts +51 -0
- package/dist/realtime/realtime.service.d.ts.map +1 -0
- package/dist/realtime/realtime.service.js +177 -0
- package/dist/realtime/realtime.service.js.map +1 -0
- package/dist/redis/redis-pubsub.d.ts +27 -0
- package/dist/redis/redis-pubsub.d.ts.map +1 -0
- package/dist/redis/redis-pubsub.js +184 -0
- package/dist/redis/redis-pubsub.js.map +1 -0
- package/dist/role/guards/role.guard.d.ts +5 -0
- package/dist/role/guards/role.guard.d.ts.map +1 -1
- package/dist/role/guards/role.guard.js +41 -39
- package/dist/role/guards/role.guard.js.map +1 -1
- package/dist/role/role.controller.d.ts +3 -3
- package/dist/role/role.service.d.ts +3 -3
- package/dist/session/session.controller.d.ts +2 -0
- package/dist/session/session.controller.d.ts.map +1 -1
- package/dist/session/session.service.d.ts +39 -0
- package/dist/session/session.service.d.ts.map +1 -1
- package/dist/session/session.service.js +91 -8
- package/dist/session/session.service.js.map +1 -1
- package/dist/setting/brand-asset.service.d.ts +48 -0
- package/dist/setting/brand-asset.service.d.ts.map +1 -0
- package/dist/setting/brand-asset.service.js +130 -0
- package/dist/setting/brand-asset.service.js.map +1 -0
- package/dist/setting/dto/create.dto.d.ts.map +1 -1
- package/dist/setting/dto/create.dto.js +9 -2
- package/dist/setting/dto/create.dto.js.map +1 -1
- package/dist/setting/setting.controller.d.ts +5 -5
- package/dist/setting/setting.module.d.ts.map +1 -1
- package/dist/setting/setting.module.js +3 -2
- package/dist/setting/setting.module.js.map +1 -1
- package/dist/setting/setting.service.d.ts +41 -5
- package/dist/setting/setting.service.d.ts.map +1 -1
- package/dist/setting/setting.service.js +113 -1
- package/dist/setting/setting.service.js.map +1 -1
- package/dist/token/token.service.d.ts +23 -2
- package/dist/token/token.service.d.ts.map +1 -1
- package/dist/token/token.service.js +39 -4
- package/dist/token/token.service.js.map +1 -1
- package/dist/user/dto/create-with-email-and-password.dto.d.ts +2 -0
- package/dist/user/dto/create-with-email-and-password.dto.d.ts.map +1 -1
- package/dist/user/dto/create-with-email-and-password.dto.js +5 -0
- package/dist/user/dto/create-with-email-and-password.dto.js.map +1 -1
- package/dist/user/dto/query-user-mail-list.dto.d.ts +5 -0
- package/dist/user/dto/query-user-mail-list.dto.d.ts.map +1 -0
- package/dist/user/dto/query-user-mail-list.dto.js +25 -0
- package/dist/user/dto/query-user-mail-list.dto.js.map +1 -0
- package/dist/user/user-credential.util.d.ts +19 -0
- package/dist/user/user-credential.util.d.ts.map +1 -0
- package/dist/user/user-credential.util.js +32 -0
- package/dist/user/user-credential.util.js.map +1 -0
- package/dist/user/user.controller.d.ts +24 -26
- package/dist/user/user.controller.d.ts.map +1 -1
- package/dist/user/user.controller.js +18 -3
- package/dist/user/user.controller.js.map +1 -1
- package/dist/user/user.service.d.ts +71 -29
- package/dist/user/user.service.d.ts.map +1 -1
- package/dist/user/user.service.js +291 -17
- package/dist/user/user.service.js.map +1 -1
- package/dist/user-device/user-device.controller.d.ts +54 -0
- package/dist/user-device/user-device.controller.d.ts.map +1 -0
- package/dist/user-device/user-device.controller.js +103 -0
- package/dist/user-device/user-device.controller.js.map +1 -0
- package/dist/user-device/user-device.module.d.ts +3 -0
- package/dist/user-device/user-device.module.d.ts.map +1 -0
- package/dist/user-device/user-device.module.js +26 -0
- package/dist/user-device/user-device.module.js.map +1 -0
- package/dist/user-device/user-device.service.d.ts +71 -0
- package/dist/user-device/user-device.service.d.ts.map +1 -0
- package/dist/user-device/user-device.service.js +158 -0
- package/dist/user-device/user-device.service.js.map +1 -0
- package/dist/utils/device-key.d.ts +23 -0
- package/dist/utils/device-key.d.ts.map +1 -0
- package/dist/utils/device-key.js +31 -0
- package/dist/utils/device-key.js.map +1 -0
- package/dist/utils/geo-ip.d.ts +38 -0
- package/dist/utils/geo-ip.d.ts.map +1 -0
- package/dist/utils/geo-ip.js +122 -0
- package/dist/utils/geo-ip.js.map +1 -0
- package/dist/utils/locale-context.d.ts +10 -7
- package/dist/utils/locale-context.d.ts.map +1 -1
- package/dist/utils/locale-context.js +14 -8
- package/dist/utils/locale-context.js.map +1 -1
- package/dist/utils/security-event-vars.d.ts +56 -0
- package/dist/utils/security-event-vars.d.ts.map +1 -0
- package/dist/utils/security-event-vars.js +109 -0
- package/dist/utils/security-event-vars.js.map +1 -0
- package/dist/utils/user-agent.d.ts +19 -0
- package/dist/utils/user-agent.d.ts.map +1 -0
- package/dist/utils/user-agent.js +36 -0
- package/dist/utils/user-agent.js.map +1 -0
- package/dist/validators/is-strong-password-with-settings.validator.d.ts.map +1 -1
- package/dist/validators/is-strong-password-with-settings.validator.js +11 -0
- package/dist/validators/is-strong-password-with-settings.validator.js.map +1 -1
- package/dist/validators/service-locator.d.ts +9 -0
- package/dist/validators/service-locator.d.ts.map +1 -1
- package/dist/validators/service-locator.js +12 -0
- package/dist/validators/service-locator.js.map +1 -1
- package/dist/webhook-integration/webhook-integration.service.d.ts +5 -0
- package/dist/webhook-integration/webhook-integration.service.d.ts.map +1 -1
- package/dist/webhook-integration/webhook-integration.service.js +50 -4
- package/dist/webhook-integration/webhook-integration.service.js.map +1 -1
- package/dist/webhook-integration/webhook-protocol.registry.d.ts +6 -0
- package/dist/webhook-integration/webhook-protocol.registry.d.ts.map +1 -1
- package/dist/webhook-integration/webhook-protocol.registry.js.map +1 -1
- package/dist/whatsapp-sender/whatsapp-sender.module.d.ts +3 -0
- package/dist/whatsapp-sender/whatsapp-sender.module.d.ts.map +1 -0
- package/dist/whatsapp-sender/whatsapp-sender.module.js +23 -0
- package/dist/whatsapp-sender/whatsapp-sender.module.js.map +1 -0
- package/dist/whatsapp-sender/whatsapp-sender.service.d.ts +50 -0
- package/dist/whatsapp-sender/whatsapp-sender.service.d.ts.map +1 -0
- package/dist/whatsapp-sender/whatsapp-sender.service.js +224 -0
- package/dist/whatsapp-sender/whatsapp-sender.service.js.map +1 -0
- package/hedhog/data/integration_provider.yaml +25 -0
- package/hedhog/data/mail.yaml +275 -112
- package/hedhog/data/mail_layout.yaml +198 -0
- package/hedhog/data/menu.yaml +69 -3
- package/hedhog/data/role.yaml +16 -0
- package/hedhog/data/route.yaml +307 -3
- package/hedhog/data/setting_group.yaml +315 -1
- package/hedhog/data/setting_subgroup.yaml +8 -0
- package/hedhog/frontend/app/_lib/hooks/use-core-access.test.tsx.ejs +125 -0
- package/hedhog/frontend/app/_lib/hooks/use-core-access.ts.ejs +29 -0
- package/hedhog/frontend/app/_lib/hooks/use-impersonation-access.test.ts.ejs +71 -0
- package/hedhog/frontend/app/_lib/hooks/use-impersonation-access.ts.ejs +32 -0
- package/hedhog/frontend/app/access-log/page.tsx.ejs +96 -22
- package/hedhog/frontend/app/account/components/active-sessions.tsx.ejs +17 -1
- package/hedhog/frontend/app/account/components/known-devices.tsx.ejs +89 -0
- package/hedhog/frontend/app/account/components/mfa-setup-dialog.tsx.ejs +36 -0
- package/hedhog/frontend/app/account/components/profile-form.tsx.ejs +2 -1
- package/hedhog/frontend/app/account/components/two-factor-auth.tsx.ejs +2 -0
- package/hedhog/frontend/app/account/components/user-devices-list.tsx.ejs +186 -0
- package/hedhog/frontend/app/account/devices/page.tsx.ejs +5 -0
- package/hedhog/frontend/app/account/hooks/use-mfa-setup.ts.ejs +10 -7
- package/hedhog/frontend/app/account/layout.tsx.ejs +2 -0
- package/hedhog/frontend/app/ai_agent/page.tsx.ejs +7 -4
- package/hedhog/frontend/app/ai_instruction/_components/ai-instruction-form.tsx.ejs +580 -0
- package/hedhog/frontend/app/ai_instruction/_components/ai-instruction-preview.tsx.ejs +150 -0
- package/hedhog/frontend/app/ai_instruction/_components/ai-instruction-versions.tsx.ejs +199 -0
- package/hedhog/frontend/app/ai_instruction/_components/prompt-diff.tsx.ejs +63 -0
- package/hedhog/frontend/app/ai_instruction/_lib/line-diff.spec.ts.ejs +59 -0
- package/hedhog/frontend/app/ai_instruction/_lib/line-diff.ts.ejs +72 -0
- package/hedhog/frontend/app/ai_instruction/_lib/prompt-template.spec.ts.ejs +170 -0
- package/hedhog/frontend/app/ai_instruction/_lib/prompt-template.ts.ejs +167 -0
- package/hedhog/frontend/app/ai_instruction/_lib/types.ts.ejs +99 -0
- package/hedhog/frontend/app/ai_instruction/page.tsx.ejs +422 -0
- package/hedhog/frontend/app/configurations/[slug]/components/setting-field.test.tsx.ejs +298 -0
- package/hedhog/frontend/app/configurations/[slug]/components/setting-field.tsx.ejs +410 -1223
- package/hedhog/frontend/app/incidents/page.tsx.ejs +400 -0
- package/hedhog/frontend/app/integration/profiles/page.tsx.ejs +153 -84
- package/hedhog/frontend/app/mail/layout/page.tsx.ejs +344 -0
- package/hedhog/frontend/app/mail/log/page.tsx.ejs +210 -3
- package/hedhog/frontend/app/mail/template/page.tsx.ejs +292 -200
- package/hedhog/frontend/app/mcp_chat/page.tsx.ejs +129 -17
- package/hedhog/frontend/app/pages/_components/page-delete-dialog.tsx.ejs +343 -0
- package/hedhog/frontend/app/pages/_components/page-detail-sheet.tsx.ejs +438 -0
- package/hedhog/frontend/app/pages/_components/page-wizard-sheet.tsx.ejs +1009 -0
- package/hedhog/frontend/app/pages/_components/system-page-types.ts.ejs +56 -0
- package/hedhog/frontend/app/pages/_components/use-system-pages.ts.ejs +171 -0
- package/hedhog/frontend/app/pages/page.tsx.ejs +514 -0
- package/hedhog/frontend/app/users/active-session.tsx.ejs +58 -11
- package/hedhog/frontend/app/users/page.tsx.ejs +186 -21
- package/hedhog/frontend/app/users/simulate-access-dialog.test.tsx.ejs +202 -0
- package/hedhog/frontend/app/users/simulate-access-dialog.tsx.ejs +170 -0
- package/hedhog/frontend/app/users/user-activity-timeline.tsx.ejs +250 -0
- package/hedhog/frontend/app/users/user-devices.tsx.ejs +89 -0
- package/hedhog/frontend/app/users/user-logs.tsx.ejs +13 -1
- package/hedhog/frontend/app/users/user-mails.tsx.ejs +399 -0
- package/hedhog/frontend/app/users/user-sheet.tsx.ejs +106 -99
- package/hedhog/frontend/messages/en.json +643 -49
- package/hedhog/frontend/messages/pt.json +643 -49
- package/hedhog/table/access_log.yaml +7 -0
- package/hedhog/table/ai_agent.yaml +1 -0
- package/hedhog/table/ai_instruction.yaml +15 -0
- package/hedhog/table/file.yaml +8 -0
- package/hedhog/table/leaked_password.yaml +18 -0
- package/hedhog/table/mail_delivery_event.yaml +76 -0
- package/hedhog/table/mail_layout.yaml +35 -0
- package/hedhog/table/mail_sent.yaml +23 -0
- package/hedhog/table/mail_var.yaml +4 -0
- package/hedhog/table/setting.yaml +1 -0
- package/hedhog/table/system_incident.yaml +59 -0
- package/hedhog/table/user_activity.yaml +9 -0
- package/hedhog/table/user_device.yaml +52 -0
- package/hedhog/table/user_presence.yaml +36 -0
- package/hedhog/table/user_session.yaml +20 -1
- package/package.json +7 -2
- package/src/access-log/access-log.controller.ts +1 -0
- package/src/access-log/access-log.interceptor.ts +9 -3
- package/src/access-log/access-log.service.spec.ts +33 -2
- package/src/access-log/access-log.service.ts +38 -0
- package/src/access-log/dto/query-access-log.dto.ts +5 -0
- package/src/ai/ai-attachment.fragments.spec.ts +319 -0
- package/src/ai/ai-attachment.fragments.ts +35 -0
- package/src/ai/ai.controller.ts +9 -0
- package/src/ai/ai.module.ts +3 -2
- package/src/ai/ai.prompts.ts +38 -0
- package/src/ai/ai.service.spec.ts +280 -0
- package/src/ai/ai.service.ts +475 -82
- package/src/ai/dto/chat.dto.ts +33 -3
- package/src/ai/dto/create-agent.dto.ts +2 -2
- package/src/ai/dto/richtext-edit-html.dto.ts +11 -0
- package/src/ai/dto/update-agent.dto.ts +2 -2
- package/src/ai/richtext-ai.prompts.ts +57 -0
- package/src/ai/richtext-ai.service.ts +109 -0
- package/src/ai-instruction/ai-instruction.controller.ts +40 -9
- package/src/ai-instruction/ai-instruction.module.ts +13 -2
- package/src/ai-instruction/ai-instruction.service.spec.ts +658 -0
- package/src/ai-instruction/ai-instruction.service.ts +661 -62
- package/src/ai-instruction/ai-prompt-builder.service.ts +10 -1
- package/src/ai-instruction/ai-prompt-registry.ts +87 -0
- package/src/ai-instruction/ai-prompt-resolver.service.spec.ts +375 -0
- package/src/ai-instruction/ai-prompt-resolver.service.ts +295 -0
- package/src/ai-instruction/ai-prompt-template.util.spec.ts +162 -0
- package/src/ai-instruction/ai-prompt-template.util.ts +199 -0
- package/src/ai-instruction/dto/create-ai-instruction.dto.ts +39 -3
- package/src/ai-instruction/dto/preview-ai-instruction.dto.ts +26 -0
- package/src/ai-instruction/dto/update-ai-instruction.dto.ts +42 -1
- package/src/ai-instruction/types/ai-instruction.types.ts +24 -1
- package/src/auth/auth.controller.ts +78 -13
- package/src/auth/auth.module.ts +2 -0
- package/src/auth/auth.service.spec.ts +386 -7
- package/src/auth/auth.service.ts +435 -81
- package/src/auth/dto/confirm-email.dto.ts +7 -0
- package/src/auth/dto/resend-confirmation.dto.ts +20 -0
- package/src/authorize/authorize.controller.ts +2 -0
- package/src/authorize/authorize.service.spec.ts +23 -0
- package/src/authorize/authorize.service.ts +8 -0
- package/src/captcha/captcha.module.ts +10 -0
- package/src/captcha/captcha.service.spec.ts +210 -0
- package/src/captcha/captcha.service.ts +191 -0
- package/src/challenge/challenge.service.spec.ts +112 -4
- package/src/challenge/challenge.service.ts +131 -17
- package/src/core.module.ts +46 -1
- package/src/file/file.controller.ts +54 -4
- package/src/file/file.service.spec.ts +275 -0
- package/src/file/file.service.ts +468 -16
- package/src/file/image-optimization.service.spec.ts +92 -0
- package/src/file/image-optimization.service.ts +202 -0
- package/src/file/provider/abstract.provider.ts +23 -0
- package/src/file/provider/gcs.provider.ts +17 -0
- package/src/file/provider/local.provider.ts +21 -0
- package/src/file/provider/s3.provider.ts +25 -0
- package/src/file/provider/spaces.provider.ts +26 -0
- package/src/impersonation/dto/redeem-impersonation.dto.ts +8 -0
- package/src/impersonation/dto/start-impersonation.dto.ts +13 -0
- package/src/impersonation/impersonation-restrictions.ts +84 -0
- package/src/impersonation/impersonation.controller.ts +109 -0
- package/src/impersonation/impersonation.module.ts +31 -0
- package/src/impersonation/impersonation.service.spec.ts +427 -0
- package/src/impersonation/impersonation.service.ts +577 -0
- package/src/incident/incident-notifier.service.spec.ts +205 -0
- package/src/incident/incident-notifier.service.ts +241 -0
- package/src/incident/incident.controller.ts +38 -0
- package/src/incident/incident.module.ts +19 -0
- package/src/incident/incident.service.spec.ts +150 -0
- package/src/incident/incident.service.ts +209 -0
- package/src/index.ts +58 -0
- package/src/integration/services/outbox-polling.coordinator.spec.ts +90 -0
- package/src/integration/services/outbox-polling.coordinator.ts +62 -40
- package/src/integration/services/outbox.service.spec.ts +8 -0
- package/src/integration/services/outbox.service.ts +19 -13
- package/src/integration-profile/dto/test.dto.ts +19 -0
- package/src/integration-profile/integration-profile.controller.ts +10 -1
- package/src/integration-profile/integration-profile.module.spec.ts +51 -0
- package/src/integration-profile/integration-profile.module.ts +23 -4
- package/src/integration-profile/integration-profile.secrets.ts +12 -1
- package/src/integration-profile/integration-profile.service.spec.ts +279 -0
- package/src/integration-profile/integration-profile.service.ts +120 -124
- package/src/integration-profile/integration-profile.utils.spec.ts +22 -0
- package/src/integration-profile/integration-profile.utils.ts +78 -3
- package/src/integration-profile/testers/ai.testers.ts +165 -0
- package/src/integration-profile/testers/captcha.testers.spec.ts +92 -0
- package/src/integration-profile/testers/captcha.testers.ts +139 -0
- package/src/integration-profile/testers/email.testers.ts +194 -0
- package/src/integration-profile/testers/http-probe.spec.ts +153 -0
- package/src/integration-profile/testers/http-probe.ts +171 -0
- package/src/integration-profile/testers/index.ts +30 -0
- package/src/integration-profile/testers/infrastructure.testers.ts +122 -0
- package/src/integration-profile/testers/integration-tester.registry.spec.ts +75 -0
- package/src/integration-profile/testers/integration-tester.registry.ts +43 -0
- package/src/integration-profile/testers/integration-tester.types.ts +61 -0
- package/src/integration-profile/testers/messaging.testers.ts +102 -0
- package/src/integration-profile/testers/oauth.testers.spec.ts +220 -0
- package/src/integration-profile/testers/oauth.testers.ts +305 -0
- package/src/integration-profile/testers/payment.testers.ts +185 -0
- package/src/integration-profile/testers/remaining.testers.spec.ts +401 -0
- package/src/integration-profile/testers/storage.testers.spec.ts +185 -0
- package/src/integration-profile/testers/storage.testers.ts +226 -0
- package/src/integration-profile/testers/tester-coverage.spec.ts +58 -0
- package/src/language/en.json +15 -2
- package/src/language/pt.json +15 -2
- package/src/leaked-password/README.md +83 -0
- package/src/leaked-password/leaked-password.controller.ts +52 -0
- package/src/leaked-password/leaked-password.module.ts +18 -0
- package/src/leaked-password/leaked-password.service.ts +242 -0
- package/src/leaked-password/seed/build-seed-sql.mjs +180 -0
- package/src/leaked-password/seed/common-passwords.txt +335 -0
- package/src/mail/dto/preview.dto.ts +50 -0
- package/src/mail/dto/send.dto.ts +58 -1
- package/src/mail/mail-template.spec.ts +274 -0
- package/src/mail/mail.controller.ts +9 -2
- package/src/mail/mail.module.ts +2 -0
- package/src/mail/mail.service.spec.ts +422 -6
- package/src/mail/mail.service.ts +337 -34
- package/src/mail-delivery/mail-delivery-provision.service.ts +66 -0
- package/src/mail-delivery/mail-delivery.constants.ts +31 -0
- package/src/mail-delivery/mail-delivery.controller.ts +38 -0
- package/src/mail-delivery/mail-delivery.module.ts +23 -0
- package/src/mail-delivery/mail-delivery.service.spec.ts +136 -0
- package/src/mail-delivery/mail-delivery.service.ts +152 -0
- package/src/mail-delivery/ses-event.parser.spec.ts +140 -0
- package/src/mail-delivery/ses-event.parser.ts +191 -0
- package/src/mail-delivery/ses-webhook.service.spec.ts +170 -0
- package/src/mail-delivery/ses-webhook.service.ts +240 -0
- package/src/mail-delivery/sns-message.util.spec.ts +163 -0
- package/src/mail-delivery/sns-message.util.ts +125 -0
- package/src/mail-layout/dto/update.dto.ts +19 -0
- package/src/mail-layout/mail-layout.controller.ts +47 -0
- package/src/mail-layout/mail-layout.module.ts +22 -0
- package/src/mail-layout/mail-layout.service.ts +94 -0
- package/src/mail-sent/dto/query-mail-sent-list.dto.ts +15 -0
- package/src/mail-sent/mail-sent.service.ts +46 -2
- package/src/mailbox/mailbox-fetcher.registry.ts +132 -0
- package/src/mailbox/mailbox.module.ts +14 -0
- package/src/mcp-chat/mcp-chat.service.spec.ts +236 -0
- package/src/mcp-chat/mcp-chat.service.ts +122 -26
- package/src/meeting/meeting-provider.registry.ts +193 -0
- package/src/meeting/meeting.constants.ts +53 -0
- package/src/meeting/meeting.module.ts +13 -0
- package/src/middlewares/locale-injection.middleware.ts +25 -6
- package/src/oauth/oauth-token-broker.service.spec.ts +172 -0
- package/src/oauth/oauth-token-broker.service.ts +363 -0
- package/src/oauth/oauth.module.ts +3 -1
- package/src/oauth/oauth.service.ts +8 -2
- package/src/oauth/providers/google.provider.ts +49 -15
- package/src/observability/monitored-cron.spec.ts +102 -0
- package/src/observability/monitored-cron.ts +110 -0
- package/src/pairing/dto/approve-reverse-pairing.dto.ts +20 -0
- package/src/pairing/dto/claim-pairing.dto.ts +19 -0
- package/src/pairing/dto/confirm-pairing.dto.ts +14 -0
- package/src/pairing/dto/poll-reverse-pairing.dto.ts +9 -0
- package/src/pairing/dto/start-pairing.dto.ts +19 -0
- package/src/pairing/dto/start-reverse-pairing.dto.ts +45 -0
- package/src/pairing/pairing.controller.ts +246 -0
- package/src/pairing/pairing.module.ts +27 -0
- package/src/pairing/pairing.service.spec.ts +462 -0
- package/src/pairing/pairing.service.ts +614 -0
- package/src/pdf/pdf.service.ts +81 -24
- package/src/presence/presence.controller.ts +29 -0
- package/src/presence/presence.listener.ts +53 -0
- package/src/presence/presence.module.ts +19 -0
- package/src/presence/presence.service.spec.ts +97 -0
- package/src/presence/presence.service.ts +160 -0
- package/src/profile/dto/delete-account.dto.ts +11 -0
- package/src/profile/events/profile-account-deleted.event.ts +13 -0
- package/src/profile/profile.controller.ts +46 -34
- package/src/profile/profile.service.ts +164 -46
- package/src/realtime/realtime.gateway.ts +138 -0
- package/src/realtime/realtime.module.ts +16 -0
- package/src/realtime/realtime.service.spec.ts +50 -0
- package/src/realtime/realtime.service.ts +187 -0
- package/src/redis/redis-pubsub.ts +190 -0
- package/src/role/guards/role.guard.spec.ts +75 -0
- package/src/role/guards/role.guard.ts +64 -46
- package/src/session/session.service.spec.ts +81 -0
- package/src/session/session.service.ts +93 -6
- package/src/setting/brand-asset.service.ts +137 -0
- package/src/setting/dto/create.dto.ts +13 -2
- package/src/setting/setting.module.ts +3 -2
- package/src/setting/setting.service.spec.ts +135 -1
- package/src/setting/setting.service.ts +138 -2
- package/src/token/token.service.spec.ts +62 -0
- package/src/token/token.service.ts +57 -3
- package/src/user/dto/create-with-email-and-password.dto.ts +6 -1
- package/src/user/dto/query-user-mail-list.dto.ts +10 -0
- package/src/user/user-credential.util.ts +35 -0
- package/src/user/user.controller.ts +17 -2
- package/src/user/user.service.spec.ts +186 -2
- package/src/user/user.service.ts +361 -16
- package/src/user-device/user-device.controller.ts +77 -0
- package/src/user-device/user-device.module.ts +13 -0
- package/src/user-device/user-device.service.spec.ts +234 -0
- package/src/user-device/user-device.service.ts +168 -0
- package/src/utils/device-key.spec.ts +57 -0
- package/src/utils/device-key.ts +32 -0
- package/src/utils/geo-ip.spec.ts +134 -0
- package/src/utils/geo-ip.ts +93 -0
- package/src/utils/locale-context.spec.ts +27 -1
- package/src/utils/locale-context.ts +15 -12
- package/src/utils/security-event-vars.spec.ts +161 -0
- package/src/utils/security-event-vars.ts +153 -0
- package/src/utils/user-agent.spec.ts +37 -0
- package/src/utils/user-agent.ts +46 -0
- package/src/validators/is-strong-password-with-settings.validator.ts +12 -0
- package/src/validators/service-locator.ts +15 -0
- package/src/webhook-integration/webhook-integration.service.ts +57 -3
- package/src/webhook-integration/webhook-protocol.registry.ts +6 -0
- package/src/whatsapp-sender/whatsapp-sender.module.ts +10 -0
- package/src/whatsapp-sender/whatsapp-sender.service.ts +313 -0
package/src/auth/auth.service.ts
CHANGED
|
@@ -1,9 +1,15 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
getLocaleFromContext,
|
|
3
|
+
getLocaleText,
|
|
4
|
+
isLocaleDetectedFromContext,
|
|
5
|
+
normalizeLocaleCode,
|
|
6
|
+
} from '@hed-hog/api-locale';
|
|
2
7
|
import { PrismaService } from '@hed-hog/api-prisma';
|
|
3
8
|
import { User } from '@hed-hog/api-types';
|
|
4
9
|
import type { PublicKeyCredentialRequestOptionsJSON } from '@simplewebauthn/server';
|
|
5
10
|
import {
|
|
6
11
|
BadRequestException,
|
|
12
|
+
ForbiddenException,
|
|
7
13
|
forwardRef,
|
|
8
14
|
Inject,
|
|
9
15
|
Injectable,
|
|
@@ -17,7 +23,11 @@ import { SecurityService } from '../security/security.service';
|
|
|
17
23
|
import { SessionService } from '../session/session.service';
|
|
18
24
|
import { SettingService } from '../setting/setting.service';
|
|
19
25
|
import { TokenService } from '../token/token.service';
|
|
26
|
+
import { UserDeviceService } from '../user-device/user-device.service';
|
|
27
|
+
import { hasPendingPasswordReset } from '../user/user-credential.util';
|
|
28
|
+
import { CreateWithEmailAndPasswordDTO } from '../user/dto/create-with-email-and-password.dto';
|
|
20
29
|
import { UserService } from '../user/user.service';
|
|
30
|
+
import { buildSecurityEventVars } from '../utils/security-event-vars';
|
|
21
31
|
import { resolveWebAuthnOrigin } from '../utils/webauthn-origin';
|
|
22
32
|
import { ForgetDTO } from './dto/forget.dto';
|
|
23
33
|
import { LoginDTO } from './dto/login.dto';
|
|
@@ -43,6 +53,8 @@ export class AuthService {
|
|
|
43
53
|
private readonly user: UserService,
|
|
44
54
|
@Inject(forwardRef(() => ChallengeService))
|
|
45
55
|
private readonly challenge: ChallengeService,
|
|
56
|
+
@Inject(forwardRef(() => UserDeviceService))
|
|
57
|
+
private readonly userDevice: UserDeviceService,
|
|
46
58
|
) { }
|
|
47
59
|
|
|
48
60
|
async getAuthenticationPayload(locale: string, userId: number, ipAddress: string, userAgent: string, browserId?: string | null) {
|
|
@@ -50,6 +62,18 @@ export class AuthService {
|
|
|
50
62
|
const payload = { sub: userId, sessionId: session.id };
|
|
51
63
|
const accessToken = await this.token.createAccessToken(payload);
|
|
52
64
|
await this.prisma.user.update({ where: { id: userId }, data: { last_login_at: new Date() } });
|
|
65
|
+
|
|
66
|
+
// Unico ponto por onde todo caminho de autenticacao passa (senha, MFA,
|
|
67
|
+
// WebAuthn, recovery code, OAuth, pairing), entao e aqui que o dispositivo
|
|
68
|
+
// e aprendido. Quem checa `isNewDevice` faz isso antes de chegar aqui.
|
|
69
|
+
await this.userDevice.remember(userId, { userAgent, browserId, ipAddress });
|
|
70
|
+
|
|
71
|
+
// O idioma e aprendido junto com o dispositivo, e pelo mesmo motivo: e o
|
|
72
|
+
// unico momento em que o cliente se apresenta. Fica antes do alerta de
|
|
73
|
+
// dispositivo desconhecido (disparado por quem chamou este metodo), entao o
|
|
74
|
+
// proprio e-mail do primeiro login ja sai traduzido.
|
|
75
|
+
await this.persistDetectedLanguage(locale, userId);
|
|
76
|
+
|
|
53
77
|
this.logger.debug(`[AuthService] Session created userId=${userId} sessionId=${session.id}`);
|
|
54
78
|
|
|
55
79
|
return {
|
|
@@ -60,20 +84,72 @@ export class AuthService {
|
|
|
60
84
|
|
|
61
85
|
}
|
|
62
86
|
|
|
63
|
-
|
|
87
|
+
/**
|
|
88
|
+
* Adota o idioma do cliente como preferencia do usuario - uma unica vez.
|
|
89
|
+
*
|
|
90
|
+
* Escrita write-once de proposito: sobrescrever a cada login faria um acesso
|
|
91
|
+
* de aparelho emprestado, ou de um navegador em outro idioma, apagar a
|
|
92
|
+
* escolha que o usuario fez na tela de preferencias.
|
|
93
|
+
*
|
|
94
|
+
* Nunca lanca. Idioma e acabamento; login que falha por causa dele seria uma
|
|
95
|
+
* troca pessima.
|
|
96
|
+
*/
|
|
97
|
+
private async persistDetectedLanguage(locale: string, userId: number) {
|
|
98
|
+
try {
|
|
99
|
+
// `detected` distingue a escolha do cliente do default do middleware.
|
|
100
|
+
// Sem isso, todo cliente que nao manda `Accept-Language` congelaria `en`.
|
|
101
|
+
if (!isLocaleDetectedFromContext()) {
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
const code = normalizeLocaleCode(getLocaleFromContext());
|
|
106
|
+
|
|
107
|
+
if (!code) {
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// `setSettingUserValue` valida que a setting aceita override, mas nao o
|
|
112
|
+
// valor. Sem esta checagem um navegador em `de-DE` gravaria `de`, e todo
|
|
113
|
+
// e-mail seguinte procuraria um template inexistente.
|
|
114
|
+
const allowed = await this.setting.getSettingListValues('language');
|
|
115
|
+
|
|
116
|
+
if (allowed.length && !allowed.includes(code)) {
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
if (await this.setting.getUserSettingValue(userId, 'language')) {
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
await this.setting.setSettingUserValue(locale, userId, 'language', code);
|
|
125
|
+
} catch (error) {
|
|
126
|
+
this.logger.warn(
|
|
127
|
+
`[AuthService] Could not persist detected language for userId=${userId}: ${error}`,
|
|
128
|
+
);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
async issueDesktopToken(locale: string, userId: number, ipAddress: string, userAgent: string, isImpersonating = false) {
|
|
133
|
+
// Aqui o `userId` vem de @User(), que numa simulacao e o ALVO — sem esta
|
|
134
|
+
// guarda, o operador cunharia para ele uma sessao completa, RENOVAVEL e de
|
|
135
|
+
// 30 dias, furando o teto da simulacao e saindo da trilha de auditoria. O
|
|
136
|
+
// RoleGuard ja bloqueia a rota; isto e a segunda barreira.
|
|
137
|
+
if (isImpersonating) {
|
|
138
|
+
throw new ForbiddenException(
|
|
139
|
+
getLocaleText(
|
|
140
|
+
'impersonation.restrictedRoute',
|
|
141
|
+
locale,
|
|
142
|
+
'This action is not available during an access simulation.',
|
|
143
|
+
),
|
|
144
|
+
);
|
|
145
|
+
}
|
|
146
|
+
|
|
64
147
|
const { accessToken, refreshToken } = await this.getAuthenticationPayload(locale, userId, ipAddress, userAgent);
|
|
65
148
|
return { accessToken, refreshToken };
|
|
66
149
|
}
|
|
67
150
|
|
|
68
151
|
private hasPendingPasswordReset(user: User | any) {
|
|
69
|
-
return
|
|
70
|
-
user?.user_credential?.some(
|
|
71
|
-
(credential) =>
|
|
72
|
-
credential.type === 'password' &&
|
|
73
|
-
credential.requires_reset === true &&
|
|
74
|
-
!credential.revoked_at,
|
|
75
|
-
),
|
|
76
|
-
);
|
|
152
|
+
return hasPendingPasswordReset(user);
|
|
77
153
|
}
|
|
78
154
|
|
|
79
155
|
private async getRequiresPasswordResetByUserId(userId: number) {
|
|
@@ -90,7 +166,7 @@ export class AuthService {
|
|
|
90
166
|
return Boolean(credential?.id);
|
|
91
167
|
}
|
|
92
168
|
|
|
93
|
-
async requiresMfaForLogin(locale: string, email: string, user: any) {
|
|
169
|
+
async requiresMfaForLogin(locale: string, email: string, user: any, origin?: string) {
|
|
94
170
|
|
|
95
171
|
const settings = await this.setting.getSettingValues([
|
|
96
172
|
'require-mfa',
|
|
@@ -160,7 +236,8 @@ export class AuthService {
|
|
|
160
236
|
variables: {
|
|
161
237
|
code,
|
|
162
238
|
name: user.name,
|
|
163
|
-
}
|
|
239
|
+
},
|
|
240
|
+
app: await this.challenge.resolveAppKeyFromOrigin(origin),
|
|
164
241
|
}
|
|
165
242
|
);
|
|
166
243
|
|
|
@@ -173,7 +250,7 @@ export class AuthService {
|
|
|
173
250
|
}
|
|
174
251
|
}
|
|
175
252
|
|
|
176
|
-
async requiresEmailVerificationForLogin(locale: string, email: string, user: any) {
|
|
253
|
+
async requiresEmailVerificationForLogin(locale: string, email: string, user: any, origin?: string) {
|
|
177
254
|
|
|
178
255
|
const settings = await this.setting.getSettingValues([
|
|
179
256
|
'require-mfa',
|
|
@@ -217,7 +294,8 @@ export class AuthService {
|
|
|
217
294
|
variables: {
|
|
218
295
|
code,
|
|
219
296
|
name: user.name,
|
|
220
|
-
}
|
|
297
|
+
},
|
|
298
|
+
app: await this.challenge.resolveAppKeyFromOrigin(origin),
|
|
221
299
|
}
|
|
222
300
|
);
|
|
223
301
|
|
|
@@ -231,7 +309,7 @@ export class AuthService {
|
|
|
231
309
|
|
|
232
310
|
}
|
|
233
311
|
|
|
234
|
-
async emailVerificationLoginResend(locale: string, token: string) {
|
|
312
|
+
async emailVerificationLoginResend(locale: string, token: string, origin?: string) {
|
|
235
313
|
|
|
236
314
|
try {
|
|
237
315
|
const payload = await this.token.verify(locale, token);
|
|
@@ -253,25 +331,25 @@ export class AuthService {
|
|
|
253
331
|
|
|
254
332
|
const user = await this.user.findUserById(locale, challenge.user_identifier.user_id);
|
|
255
333
|
|
|
256
|
-
return await this.requiresEmailVerificationForLogin(locale, payload.email, user);
|
|
334
|
+
return await this.requiresEmailVerificationForLogin(locale, payload.email, user, origin);
|
|
257
335
|
|
|
258
336
|
} catch (error: any) {
|
|
259
337
|
if (error.message?.includes('jwt expired') || error.name === 'TokenExpiredError') {
|
|
260
|
-
|
|
338
|
+
|
|
261
339
|
const expiredPayload = await this.token.decodeExpiredToken(token);
|
|
262
340
|
const newToken = await this.token.createAccessToken({
|
|
263
341
|
challengeIdentifierId: expiredPayload.challengeIdentifierId,
|
|
264
342
|
email: expiredPayload.email
|
|
265
343
|
});
|
|
266
344
|
|
|
267
|
-
return this.emailVerificationLoginResend(locale, newToken);
|
|
345
|
+
return this.emailVerificationLoginResend(locale, newToken, origin);
|
|
268
346
|
}
|
|
269
|
-
|
|
347
|
+
|
|
270
348
|
throw error;
|
|
271
349
|
}
|
|
272
350
|
}
|
|
273
351
|
|
|
274
|
-
async emailVerificationLogin(locale: string, token: string, code: string, ipAddress: string, userAgent: string, res: any, browserId?: string | null) {
|
|
352
|
+
async emailVerificationLogin(locale: string, token: string, code: string, ipAddress: string, userAgent: string, res: any, browserId?: string | null, origin?: string) {
|
|
275
353
|
|
|
276
354
|
try {
|
|
277
355
|
const payload = await this.token.verify(locale, token);
|
|
@@ -283,7 +361,10 @@ export class AuthService {
|
|
|
283
361
|
user_identifier_id: true,
|
|
284
362
|
user_identifier: {
|
|
285
363
|
select: {
|
|
286
|
-
user_id: true
|
|
364
|
+
user_id: true,
|
|
365
|
+
// Destinatario do alerta de dispositivo novo: o endereco que o
|
|
366
|
+
// usuario de fato verificou para entrar.
|
|
367
|
+
value: true
|
|
287
368
|
}
|
|
288
369
|
}
|
|
289
370
|
}
|
|
@@ -324,14 +405,65 @@ export class AuthService {
|
|
|
324
405
|
|
|
325
406
|
const user = await this.user.findUserById(locale, challenge.user_identifier.user_id);
|
|
326
407
|
|
|
327
|
-
return this.login(locale, user as unknown as User, ipAddress, userAgent, res, browserId);
|
|
408
|
+
return this.login(locale, user as unknown as User, ipAddress, userAgent, res, browserId, origin, challenge.user_identifier.value);
|
|
328
409
|
|
|
329
410
|
} catch (error) {
|
|
330
411
|
throw error;
|
|
331
412
|
}
|
|
332
413
|
}
|
|
333
414
|
|
|
334
|
-
|
|
415
|
+
/**
|
|
416
|
+
* Dispara o alerta de acesso de dispositivo desconhecido.
|
|
417
|
+
*
|
|
418
|
+
* O `await` aqui cobre so a resolucao do app (leitura de setting memoizada);
|
|
419
|
+
* o envio em si continua sem await de proposito, para nao somar a latencia do
|
|
420
|
+
* SMTP ao tempo de resposta do login.
|
|
421
|
+
*/
|
|
422
|
+
private async sendNewDeviceLoginMail(
|
|
423
|
+
locale: string,
|
|
424
|
+
user: { name?: string } | null | undefined,
|
|
425
|
+
email: string | null | undefined,
|
|
426
|
+
ipAddress: string,
|
|
427
|
+
userAgent: string,
|
|
428
|
+
origin?: string,
|
|
429
|
+
): Promise<void> {
|
|
430
|
+
// Tokens de desafio emitidos antes de o `email` passar a ser gravado no
|
|
431
|
+
// payload chegam aqui sem destinatario; alertar ninguem e melhor do que
|
|
432
|
+
// deixar o envio explodir dentro do fluxo de login.
|
|
433
|
+
if (!email) {
|
|
434
|
+
return;
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
const app = await this.challenge.resolveAppKeyFromOrigin(origin);
|
|
438
|
+
|
|
439
|
+
// As variaveis sao formatadas aqui (data e nome do pais saem do `Intl`),
|
|
440
|
+
// entao o idioma do destinatario tem que ser resolvido ANTES do envio -
|
|
441
|
+
// senao o corpo sai em portugues com a data em ingles.
|
|
442
|
+
const recipientLocale = await this.mail.resolveRecipientLocale(email, locale);
|
|
443
|
+
|
|
444
|
+
this.mail.sendTemplatedMail(recipientLocale, {
|
|
445
|
+
email,
|
|
446
|
+
slug: 'auth-login-new-device',
|
|
447
|
+
variables: {
|
|
448
|
+
name: user?.name ?? '',
|
|
449
|
+
...buildSecurityEventVars({ ipAddress, userAgent, locale: recipientLocale }),
|
|
450
|
+
},
|
|
451
|
+
app,
|
|
452
|
+
});
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
private async login(locale: string, user: User, ipAddress: string, userAgent: string, res: any, browserId?: string | null, origin?: string, loginEmail?: string) {
|
|
456
|
+
|
|
457
|
+
// Conta excluída pelo próprio usuário: os identificadores já foram
|
|
458
|
+
// anonimizados, mas a checagem fecha qualquer caminho remanescente.
|
|
459
|
+
const account = await this.prisma.user.findUnique({
|
|
460
|
+
where: { id: user.id },
|
|
461
|
+
select: { deactivated_at: true },
|
|
462
|
+
});
|
|
463
|
+
|
|
464
|
+
if (account?.deactivated_at) {
|
|
465
|
+
throw new BadRequestException(getLocaleText('accessDenied', locale, 'Access denied.'));
|
|
466
|
+
}
|
|
335
467
|
|
|
336
468
|
const emails = await this.prisma.user_identifier.findMany({
|
|
337
469
|
where: {
|
|
@@ -345,6 +477,8 @@ export class AuthService {
|
|
|
345
477
|
throw new BadRequestException(getLocaleText('accessDenied', locale, 'Access denied.'));
|
|
346
478
|
}
|
|
347
479
|
|
|
480
|
+
const newDevice = await this.userDevice.isNewDevice(user.id, userAgent, browserId);
|
|
481
|
+
|
|
348
482
|
const { accessToken, refreshToken, session } = await this.getAuthenticationPayload(
|
|
349
483
|
locale,
|
|
350
484
|
user.id,
|
|
@@ -353,23 +487,16 @@ export class AuthService {
|
|
|
353
487
|
browserId,
|
|
354
488
|
);
|
|
355
489
|
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
variables: {
|
|
364
|
-
name: user.name,
|
|
365
|
-
ipAddress,
|
|
366
|
-
userAgent,
|
|
367
|
-
location: 'Unknown',
|
|
368
|
-
}
|
|
369
|
-
}
|
|
370
|
-
);
|
|
490
|
+
if (newDevice) {
|
|
491
|
+
// So o endereco usado para entrar. Avisar todos os identificadores
|
|
492
|
+
// contava, para um e-mail secundario, que o principal tinha sido usado.
|
|
493
|
+
const wanted = (loginEmail ?? '').trim().toLowerCase();
|
|
494
|
+
const recipient =
|
|
495
|
+
emails.find((e) => e.value?.toLowerCase() === wanted)?.value ??
|
|
496
|
+
emails[0].value;
|
|
371
497
|
|
|
372
|
-
|
|
498
|
+
await this.sendNewDeviceLoginMail(locale, user, recipient, ipAddress, userAgent, origin);
|
|
499
|
+
}
|
|
373
500
|
|
|
374
501
|
await this.user.registerUserActivity(user.id, "login")
|
|
375
502
|
|
|
@@ -391,6 +518,7 @@ export class AuthService {
|
|
|
391
518
|
userAgent: string,
|
|
392
519
|
{ email, password }: LoginDTO,
|
|
393
520
|
browserId?: string | null,
|
|
521
|
+
origin?: string,
|
|
394
522
|
) {
|
|
395
523
|
|
|
396
524
|
const user = await this.user.findUserByEmail(locale, email);
|
|
@@ -428,11 +556,11 @@ export class AuthService {
|
|
|
428
556
|
|
|
429
557
|
if (emailMfas.length > 0) {
|
|
430
558
|
const emails = emailMfas.map(mfa => mfa.user_mfa_email[0].email);
|
|
431
|
-
await this.challenge.sendMfaCodeToMultipleEmails(locale, user.id, emails);
|
|
559
|
+
await this.challenge.sendMfaCodeToMultipleEmails(locale, user.id, emails, origin);
|
|
432
560
|
}
|
|
433
561
|
|
|
434
|
-
return {
|
|
435
|
-
requiresMfa: true,
|
|
562
|
+
return {
|
|
563
|
+
requiresMfa: true,
|
|
436
564
|
mfaToken,
|
|
437
565
|
mfaMethods: mfaMethods.map(m => ({ type: m.type, id: m.id }))
|
|
438
566
|
};
|
|
@@ -447,15 +575,63 @@ export class AuthService {
|
|
|
447
575
|
|
|
448
576
|
if (settings['require-mfa'] === true && mfaMethods.length === 0) {
|
|
449
577
|
|
|
450
|
-
return this.requiresMfaForLogin(locale, email, user);
|
|
578
|
+
return this.requiresMfaForLogin(locale, email, user, origin);
|
|
451
579
|
|
|
452
580
|
} else if (settings['require-email-verification'] === true && identifier?.verified_at === null) {
|
|
453
581
|
|
|
454
|
-
return this.requiresEmailVerificationForLogin(locale, email, user);
|
|
582
|
+
return this.requiresEmailVerificationForLogin(locale, email, user, origin);
|
|
583
|
+
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
return this.login(locale, user as unknown as User, ipAddress, userAgent, res, browserId, origin, email);
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
/**
|
|
590
|
+
* Cadastro por e-mail e senha.
|
|
591
|
+
*
|
|
592
|
+
* Com `require-email-verification` desligada (o default), a conta já nasce
|
|
593
|
+
* utilizável e o e-mail de confirmação é apenas informativo — devolver a
|
|
594
|
+
* pessoa para a tela de login só a obrigaria a digitar de novo o que acabou
|
|
595
|
+
* de digitar, então o cadastro já termina com a sessão emitida.
|
|
596
|
+
*
|
|
597
|
+
* Com a setting ligada, `loginWithEmailAndPassword` barraria o acesso logo em
|
|
598
|
+
* seguida; nesse caso não emitimos sessão e devolvemos `hasChallenge` para o
|
|
599
|
+
* app mandar a pessoa confirmar o endereço antes.
|
|
600
|
+
*/
|
|
601
|
+
async signupWithEmailAndPassword(
|
|
602
|
+
res: any,
|
|
603
|
+
locale: string,
|
|
604
|
+
ipAddress: string,
|
|
605
|
+
userAgent: string,
|
|
606
|
+
data: CreateWithEmailAndPasswordDTO,
|
|
607
|
+
browserId?: string | null,
|
|
608
|
+
origin?: string,
|
|
609
|
+
) {
|
|
610
|
+
const { user } = await this.user.createWithEmailAndPassword(locale, data);
|
|
611
|
+
|
|
612
|
+
const settings = await this.setting.getSettingValues([
|
|
613
|
+
'require-email-verification',
|
|
614
|
+
]);
|
|
455
615
|
|
|
616
|
+
if (settings['require-email-verification'] === true) {
|
|
617
|
+
return { user, hasChallenge: true };
|
|
456
618
|
}
|
|
457
619
|
|
|
458
|
-
|
|
620
|
+
// `isNewDevice` retorna false quando o usuário ainda não tem dispositivo
|
|
621
|
+
// nenhum, então o auto-login não dispara o alerta de "novo acesso" — que
|
|
622
|
+
// logo após o cadastro pareceria um aviso de invasão.
|
|
623
|
+
const session = await this.login(
|
|
624
|
+
locale,
|
|
625
|
+
user as unknown as User,
|
|
626
|
+
ipAddress,
|
|
627
|
+
userAgent,
|
|
628
|
+
res,
|
|
629
|
+
browserId,
|
|
630
|
+
origin,
|
|
631
|
+
data.email,
|
|
632
|
+
);
|
|
633
|
+
|
|
634
|
+
return { user, hasChallenge: false, ...session };
|
|
459
635
|
}
|
|
460
636
|
|
|
461
637
|
async verifyRoles(_locale: string, userId: number) {
|
|
@@ -473,13 +649,46 @@ export class AuthService {
|
|
|
473
649
|
})
|
|
474
650
|
}
|
|
475
651
|
|
|
476
|
-
async verifyUser(locale: string, userId: number) {
|
|
652
|
+
async verifyUser(locale: string, userId: number, sessionId?: number | null) {
|
|
477
653
|
const user = await this.user.findUserById(locale, userId);
|
|
478
654
|
const requiresPasswordReset = this.hasPendingPasswordReset(user);
|
|
479
655
|
delete user.user_credential;
|
|
480
656
|
return {
|
|
481
657
|
...user,
|
|
482
658
|
requires_password_reset: requiresPasswordReset,
|
|
659
|
+
// Fonte de verdade do banner de simulacao no cliente: a sessionStorage do
|
|
660
|
+
// navegador e so cache e e gravavel por quem estiver na aba.
|
|
661
|
+
impersonation: await this.describeImpersonation(sessionId),
|
|
662
|
+
};
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
private async describeImpersonation(sessionId?: number | null) {
|
|
666
|
+
if (!sessionId) {
|
|
667
|
+
return null;
|
|
668
|
+
}
|
|
669
|
+
|
|
670
|
+
const session = await this.prisma.user_session.findUnique({
|
|
671
|
+
where: { id: sessionId },
|
|
672
|
+
select: {
|
|
673
|
+
impersonator_user_id: true,
|
|
674
|
+
impersonation_reason: true,
|
|
675
|
+
expires_at: true,
|
|
676
|
+
},
|
|
677
|
+
});
|
|
678
|
+
|
|
679
|
+
if (!session?.impersonator_user_id) {
|
|
680
|
+
return null;
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
const operator = await this.prisma.user.findUnique({
|
|
684
|
+
where: { id: session.impersonator_user_id },
|
|
685
|
+
select: { id: true, name: true },
|
|
686
|
+
});
|
|
687
|
+
|
|
688
|
+
return {
|
|
689
|
+
by: operator ?? { id: session.impersonator_user_id, name: '' },
|
|
690
|
+
reason: session.impersonation_reason,
|
|
691
|
+
expires_at: session.expires_at.toISOString(),
|
|
483
692
|
};
|
|
484
693
|
}
|
|
485
694
|
|
|
@@ -520,6 +729,17 @@ export class AuthService {
|
|
|
520
729
|
}
|
|
521
730
|
|
|
522
731
|
async logout(res, req, refreshToken: string) {
|
|
732
|
+
// Numa sessao simulada o cookie `rt` da mesma origem e o do OPERADOR: limpar
|
|
733
|
+
// e revogar por hash aqui derrubaria a sessao real dele. O RoleGuard ja
|
|
734
|
+
// bloqueia esta rota durante uma simulacao (impersonation-restrictions.ts);
|
|
735
|
+
// isto e a segunda barreira, no caso de a rota ser alcancada por outro
|
|
736
|
+
// caminho. Sair de uma simulacao e POST /impersonation/stop.
|
|
737
|
+
if (req?.auth?.imp === true) {
|
|
738
|
+
throw new ForbiddenException(
|
|
739
|
+
'This action is not available during an access simulation.',
|
|
740
|
+
);
|
|
741
|
+
}
|
|
742
|
+
|
|
523
743
|
const result = await this.session.deleteRefreshTokenCookie(res, refreshToken);
|
|
524
744
|
const logoutUserId = req.auth?.sub ?? result?.userId ?? null;
|
|
525
745
|
|
|
@@ -530,7 +750,7 @@ export class AuthService {
|
|
|
530
750
|
return { success: true };
|
|
531
751
|
}
|
|
532
752
|
|
|
533
|
-
async forgotResetPassword(locale: string, password: string, code: string, ipAddress: string, userAgent: string) {
|
|
753
|
+
async forgotResetPassword(locale: string, password: string, code: string, ipAddress: string, userAgent: string, origin?: string) {
|
|
534
754
|
const challenge = await this.challenge.verifyCodePassword(locale, code);
|
|
535
755
|
const userIdentifier = challenge.user_identifier;
|
|
536
756
|
const passwordHash = await this.security.hashArgon2(password);
|
|
@@ -550,12 +770,13 @@ export class AuthService {
|
|
|
550
770
|
slug: 'auth-forget-password-confirmation',
|
|
551
771
|
variables: {
|
|
552
772
|
name: userIdentifier.user.name,
|
|
553
|
-
}
|
|
773
|
+
},
|
|
774
|
+
app: await this.challenge.resolveAppKeyFromOrigin(origin),
|
|
554
775
|
}
|
|
555
776
|
);
|
|
556
777
|
|
|
557
778
|
const { accessToken, refreshToken, session } = await this.getAuthenticationPayload(locale, userIdentifier.user_id, ipAddress, userAgent);
|
|
558
|
-
await this.user.registerUserActivity(userIdentifier.
|
|
779
|
+
await this.user.registerUserActivity(userIdentifier.user_id, "resetPassword")
|
|
559
780
|
return { accessToken, refreshToken, session }
|
|
560
781
|
}
|
|
561
782
|
|
|
@@ -616,19 +837,160 @@ export class AuthService {
|
|
|
616
837
|
return { userId: targetUserId, token, hasPassword: passwordCount > 0 };
|
|
617
838
|
}
|
|
618
839
|
|
|
840
|
+
/**
|
|
841
|
+
* Confirma o e-mail a partir do link enviado no cadastro. Não emite sessão: o
|
|
842
|
+
* link só prova o controle da caixa, quem quiser entrar passa pelo login.
|
|
843
|
+
*
|
|
844
|
+
* Idempotente de propósito — clientes de e-mail fazem pré-fetch do link e o
|
|
845
|
+
* usuário costuma clicar de novo depois, e nesses casos ver "link inválido"
|
|
846
|
+
* assusta mais do que ajuda.
|
|
847
|
+
*/
|
|
848
|
+
async confirmEmail(locale: string, token: string) {
|
|
849
|
+
const { userIdentifierId } = await this.token.verifyEmailConfirmationToken(
|
|
850
|
+
locale,
|
|
851
|
+
token,
|
|
852
|
+
);
|
|
853
|
+
|
|
854
|
+
const identifier = await this.prisma.user_identifier.findUnique({
|
|
855
|
+
where: { id: userIdentifierId },
|
|
856
|
+
include: { user: { select: { id: true, name: true } } },
|
|
857
|
+
});
|
|
858
|
+
|
|
859
|
+
if (!identifier) {
|
|
860
|
+
throw new BadRequestException(
|
|
861
|
+
getLocaleText(
|
|
862
|
+
'confirmEmail.invalidOrExpired',
|
|
863
|
+
locale,
|
|
864
|
+
'This confirmation link is invalid or has expired.',
|
|
865
|
+
),
|
|
866
|
+
);
|
|
867
|
+
}
|
|
868
|
+
|
|
869
|
+
if (identifier.verified_at) {
|
|
870
|
+
return {
|
|
871
|
+
confirmed: true,
|
|
872
|
+
alreadyConfirmed: true,
|
|
873
|
+
email: identifier.value,
|
|
874
|
+
name: identifier.user?.name ?? null,
|
|
875
|
+
};
|
|
876
|
+
}
|
|
877
|
+
|
|
878
|
+
await this.prisma.user_identifier.update({
|
|
879
|
+
where: { id: identifier.id },
|
|
880
|
+
data: { verified_at: new Date(), enabled: true },
|
|
881
|
+
});
|
|
882
|
+
|
|
883
|
+
await this.user.registerUserActivity(identifier.user_id, 'confirmEmail');
|
|
884
|
+
|
|
885
|
+
return {
|
|
886
|
+
confirmed: true,
|
|
887
|
+
alreadyConfirmed: false,
|
|
888
|
+
email: identifier.value,
|
|
889
|
+
name: identifier.user?.name ?? null,
|
|
890
|
+
};
|
|
891
|
+
}
|
|
892
|
+
|
|
893
|
+
/**
|
|
894
|
+
* Reenvia o link de confirmação do cadastro.
|
|
895
|
+
*
|
|
896
|
+
* Responde `{ sent: true }` mesmo quando o e-mail não existe ou já está
|
|
897
|
+
* confirmado: qualquer diferença na resposta transformaria a rota num
|
|
898
|
+
* oráculo para descobrir quais endereços têm conta.
|
|
899
|
+
*/
|
|
900
|
+
async resendEmailConfirmation(
|
|
901
|
+
locale: string,
|
|
902
|
+
email: string,
|
|
903
|
+
app?: string,
|
|
904
|
+
origin?: string,
|
|
905
|
+
) {
|
|
906
|
+
try {
|
|
907
|
+
const user = await this.user.findUserByEmail(locale, email);
|
|
908
|
+
|
|
909
|
+
if (user) {
|
|
910
|
+
await this.challenge.sendEmailConfirmationLink(
|
|
911
|
+
locale,
|
|
912
|
+
user.id,
|
|
913
|
+
email,
|
|
914
|
+
app,
|
|
915
|
+
origin,
|
|
916
|
+
);
|
|
917
|
+
}
|
|
918
|
+
} catch (error: any) {
|
|
919
|
+
// `sendEmailConfirmationLink` lança NotFound quando o endereço já está
|
|
920
|
+
// verificado — e uma falha de envio não pode virar erro para o cliente,
|
|
921
|
+
// sob pena de vazar a existência da conta.
|
|
922
|
+
this.logger.warn(
|
|
923
|
+
'Resend of signup confirmation email failed: ' + (error?.message ?? error),
|
|
924
|
+
);
|
|
925
|
+
}
|
|
926
|
+
|
|
927
|
+
return { sent: true };
|
|
928
|
+
}
|
|
929
|
+
|
|
619
930
|
/**
|
|
620
931
|
* Valida (sem consumir) um token de convite de criação de conta e retorna os
|
|
621
932
|
* dados básicos para pré-preencher o formulário no app de treinamentos.
|
|
933
|
+
* `hasAccount` diz se esse usuário já tem um jeito de entrar (senha ativa ou
|
|
934
|
+
* provedor externo vinculado) — usado pelo app para decidir entre mostrar o
|
|
935
|
+
* formulário de criação de conta ou uma tela de autorização de acesso.
|
|
622
936
|
*/
|
|
623
937
|
async verifyAccountInvite(locale: string, code: string) {
|
|
624
938
|
const challenge = await this.challenge.verifyCodePassword(locale, code);
|
|
939
|
+
const userId = challenge.user_identifier.user_id;
|
|
940
|
+
|
|
941
|
+
const [passwordCount, oauthCount] = await Promise.all([
|
|
942
|
+
this.prisma.user_credential.count({
|
|
943
|
+
where: { user_id: userId, type: 'password', revoked_at: null },
|
|
944
|
+
}),
|
|
945
|
+
this.prisma.user_account.count({ where: { user_id: userId } }),
|
|
946
|
+
]);
|
|
947
|
+
|
|
625
948
|
return {
|
|
626
949
|
valid: true,
|
|
627
950
|
name: challenge.user_identifier.user?.name ?? null,
|
|
628
951
|
email: challenge.user_identifier.value,
|
|
952
|
+
hasAccount: passwordCount > 0 || oauthCount > 0,
|
|
629
953
|
};
|
|
630
954
|
}
|
|
631
955
|
|
|
956
|
+
/**
|
|
957
|
+
* Conclui um convite de acesso para quem já tem conta (senha ou provedor
|
|
958
|
+
* externo): não define senha nenhuma, só prova controle do e-mail (mesmo
|
|
959
|
+
* nível de confiança do link de reset de senha) e autentica o usuário.
|
|
960
|
+
*/
|
|
961
|
+
async authorizeAccountInvite(
|
|
962
|
+
locale: string,
|
|
963
|
+
code: string,
|
|
964
|
+
ipAddress: string,
|
|
965
|
+
userAgent: string,
|
|
966
|
+
) {
|
|
967
|
+
const challenge = await this.challenge.verifyCodePassword(locale, code);
|
|
968
|
+
const userIdentifier = challenge.user_identifier;
|
|
969
|
+
|
|
970
|
+
if (!userIdentifier.verified_at || !userIdentifier.enabled) {
|
|
971
|
+
await this.prisma.user_identifier.update({
|
|
972
|
+
where: { id: userIdentifier.id },
|
|
973
|
+
data: { verified_at: userIdentifier.verified_at ?? new Date(), enabled: true },
|
|
974
|
+
});
|
|
975
|
+
}
|
|
976
|
+
|
|
977
|
+
// Consome o challenge para impedir reuso do link.
|
|
978
|
+
await this.prisma.user_identifier_challenge.updateMany({
|
|
979
|
+
where: { id: challenge.id },
|
|
980
|
+
data: { verified_at: new Date(), expires_at: new Date() },
|
|
981
|
+
});
|
|
982
|
+
|
|
983
|
+
const { accessToken, refreshToken, session } =
|
|
984
|
+
await this.getAuthenticationPayload(
|
|
985
|
+
locale,
|
|
986
|
+
userIdentifier.user_id,
|
|
987
|
+
ipAddress,
|
|
988
|
+
userAgent,
|
|
989
|
+
);
|
|
990
|
+
await this.user.registerUserActivity(userIdentifier.user_id, 'authorizeAccountInvite');
|
|
991
|
+
return { accessToken, refreshToken, session };
|
|
992
|
+
}
|
|
993
|
+
|
|
632
994
|
/**
|
|
633
995
|
* Conclui a criação de conta a partir de um token de convite: cria/atualiza a
|
|
634
996
|
* credencial de senha, marca o identificador como verificado, atualiza o nome
|
|
@@ -688,11 +1050,11 @@ export class AuthService {
|
|
|
688
1050
|
ipAddress,
|
|
689
1051
|
userAgent,
|
|
690
1052
|
);
|
|
691
|
-
await this.user.registerUserActivity(userIdentifier.
|
|
1053
|
+
await this.user.registerUserActivity(userIdentifier.user_id, 'completeAccount');
|
|
692
1054
|
return { accessToken, refreshToken, session };
|
|
693
1055
|
}
|
|
694
1056
|
|
|
695
|
-
async verifyMfaCode(locale: string, mfaToken: string, code: string, ipAddress: string, userAgent: string, methodType?: 'totp' | 'email' | 'recovery', browserId?: string | null) {
|
|
1057
|
+
async verifyMfaCode(locale: string, mfaToken: string, code: string, ipAddress: string, userAgent: string, methodType?: 'totp' | 'email' | 'recovery', browserId?: string | null, origin?: string) {
|
|
696
1058
|
const payload = await this.token.verifyMfaChallengeToken(mfaToken);
|
|
697
1059
|
const user = await this.prisma.user.findUnique({
|
|
698
1060
|
where: { id: payload.userId },
|
|
@@ -788,6 +1150,8 @@ export class AuthService {
|
|
|
788
1150
|
throw new BadRequestException(getLocaleText('invalidMfaCode', locale, 'Invalid MFA code.'));
|
|
789
1151
|
}
|
|
790
1152
|
|
|
1153
|
+
const newDevice = await this.userDevice.isNewDevice(user.id, userAgent, browserId);
|
|
1154
|
+
|
|
791
1155
|
const { accessToken, refreshToken, session } = await this.getAuthenticationPayload(
|
|
792
1156
|
locale,
|
|
793
1157
|
user.id,
|
|
@@ -796,19 +1160,9 @@ export class AuthService {
|
|
|
796
1160
|
browserId,
|
|
797
1161
|
);
|
|
798
1162
|
|
|
799
|
-
|
|
800
|
-
locale,
|
|
801
|
-
|
|
802
|
-
email: payload.email,
|
|
803
|
-
slug: 'auth-login-new-device',
|
|
804
|
-
variables: {
|
|
805
|
-
name: user.name,
|
|
806
|
-
ipAddress,
|
|
807
|
-
userAgent,
|
|
808
|
-
location: 'Unknown',
|
|
809
|
-
}
|
|
810
|
-
}
|
|
811
|
-
);
|
|
1163
|
+
if (newDevice) {
|
|
1164
|
+
await this.sendNewDeviceLoginMail(locale, user, payload.email, ipAddress, userAgent, origin);
|
|
1165
|
+
}
|
|
812
1166
|
|
|
813
1167
|
await this.user.registerUserActivity(user.id, "login");
|
|
814
1168
|
const requiresPasswordReset = await this.getRequiresPasswordResetByUserId(
|
|
@@ -817,7 +1171,7 @@ export class AuthService {
|
|
|
817
1171
|
return { accessToken, refreshToken, session, requiresPasswordReset };
|
|
818
1172
|
}
|
|
819
1173
|
|
|
820
|
-
async verifyMfaRecoveryCode(locale: string, mfaToken: string, recoveryCode: string, ipAddress: string, userAgent: string, browserId?: string | null) {
|
|
1174
|
+
async verifyMfaRecoveryCode(locale: string, mfaToken: string, recoveryCode: string, ipAddress: string, userAgent: string, browserId?: string | null, origin?: string) {
|
|
821
1175
|
const payload = await this.token.verifyMfaChallengeToken(mfaToken);
|
|
822
1176
|
const user = await this.prisma.user.findUnique({
|
|
823
1177
|
where: { id: payload.userId },
|
|
@@ -845,6 +1199,8 @@ export class AuthService {
|
|
|
845
1199
|
throw new BadRequestException(getLocaleText('invalidRecoveryCode', locale, 'Invalid recovery code.'));
|
|
846
1200
|
}
|
|
847
1201
|
|
|
1202
|
+
const newDevice = await this.userDevice.isNewDevice(user.id, userAgent, browserId);
|
|
1203
|
+
|
|
848
1204
|
const { accessToken, refreshToken, session } = await this.getAuthenticationPayload(
|
|
849
1205
|
locale,
|
|
850
1206
|
user.id,
|
|
@@ -853,6 +1209,12 @@ export class AuthService {
|
|
|
853
1209
|
browserId,
|
|
854
1210
|
);
|
|
855
1211
|
|
|
1212
|
+
// Entrar por codigo de recuperacao e o caminho mais sensivel dos tres, e era
|
|
1213
|
+
// justamente o unico que nao avisava ninguem.
|
|
1214
|
+
if (newDevice) {
|
|
1215
|
+
await this.sendNewDeviceLoginMail(locale, user, payload.email, ipAddress, userAgent, origin);
|
|
1216
|
+
}
|
|
1217
|
+
|
|
856
1218
|
await this.user.registerUserActivity(user.id, "login");
|
|
857
1219
|
const requiresPasswordReset = await this.getRequiresPasswordResetByUserId(
|
|
858
1220
|
user.id,
|
|
@@ -860,7 +1222,7 @@ export class AuthService {
|
|
|
860
1222
|
return { accessToken, refreshToken, session, requiresPasswordReset };
|
|
861
1223
|
}
|
|
862
1224
|
|
|
863
|
-
async resendMfaCode(locale: string, mfaToken: string) {
|
|
1225
|
+
async resendMfaCode(locale: string, mfaToken: string, origin?: string) {
|
|
864
1226
|
const payload = await this.token.verifyMfaChallengeToken(mfaToken);
|
|
865
1227
|
|
|
866
1228
|
const mfaMethods = await this.prisma.user_mfa.findMany({
|
|
@@ -883,7 +1245,7 @@ export class AuthService {
|
|
|
883
1245
|
throw new BadRequestException(getLocaleText('noEmailMfaFound', locale, 'No email MFA method found for this user.'));
|
|
884
1246
|
}
|
|
885
1247
|
|
|
886
|
-
await this.challenge.sendMfaCodeByEmail(locale, payload.userId, emailMfa.user_mfa_email[0].email);
|
|
1248
|
+
await this.challenge.sendMfaCodeByEmail(locale, payload.userId, emailMfa.user_mfa_email[0].email, origin);
|
|
887
1249
|
|
|
888
1250
|
return {
|
|
889
1251
|
success: true,
|
|
@@ -994,6 +1356,8 @@ export class AuthService {
|
|
|
994
1356
|
data: { verified_at: new Date() }
|
|
995
1357
|
});
|
|
996
1358
|
|
|
1359
|
+
const newDevice = await this.userDevice.isNewDevice(userId, userAgent, browserId);
|
|
1360
|
+
|
|
997
1361
|
const { accessToken, refreshToken, session } = await this.getAuthenticationPayload(
|
|
998
1362
|
locale,
|
|
999
1363
|
userId,
|
|
@@ -1002,20 +1366,10 @@ export class AuthService {
|
|
|
1002
1366
|
browserId,
|
|
1003
1367
|
);
|
|
1004
1368
|
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
locale,
|
|
1008
|
-
|
|
1009
|
-
email: payload.email,
|
|
1010
|
-
slug: 'auth-login-new-device',
|
|
1011
|
-
variables: {
|
|
1012
|
-
name: user.name,
|
|
1013
|
-
ipAddress,
|
|
1014
|
-
userAgent,
|
|
1015
|
-
location: 'Unknown',
|
|
1016
|
-
}
|
|
1017
|
-
}
|
|
1018
|
-
);
|
|
1369
|
+
if (newDevice) {
|
|
1370
|
+
const user = await this.prisma.user.findFirst({ where: { id: userId } });
|
|
1371
|
+
await this.sendNewDeviceLoginMail(locale, user, payload.email, ipAddress, userAgent, requestOrigin);
|
|
1372
|
+
}
|
|
1019
1373
|
|
|
1020
1374
|
await this.user.registerUserActivity(userId, 'login');
|
|
1021
1375
|
const requiresPasswordReset = await this.getRequiresPasswordResetByUserId(
|