@solidxai/core 0.1.13-beta.2 → 0.1.13-beta.21
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/CHANGELOG.md +10107 -0
- package/CLAUDE.md +5 -6
- package/README.md +19 -0
- package/dist/commands/run-tests.command.d.ts +9 -1
- package/dist/commands/run-tests.command.d.ts.map +1 -1
- package/dist/commands/run-tests.command.js +69 -6
- package/dist/commands/run-tests.command.js.map +1 -1
- package/dist/commands/seed.command.d.ts +2 -0
- package/dist/commands/seed.command.d.ts.map +1 -1
- package/dist/commands/seed.command.js +21 -0
- package/dist/commands/seed.command.js.map +1 -1
- package/dist/config/cache.options.d.ts.map +1 -1
- package/dist/config/cache.options.js +2 -2
- package/dist/config/cache.options.js.map +1 -1
- package/dist/constants/chatter-message.constants.d.ts +1 -0
- package/dist/constants/chatter-message.constants.d.ts.map +1 -1
- package/dist/constants/chatter-message.constants.js +3 -1
- package/dist/constants/chatter-message.constants.js.map +1 -1
- package/dist/constants/draft-publish-fields.d.ts +2 -0
- package/dist/constants/draft-publish-fields.d.ts.map +1 -0
- package/dist/constants/draft-publish-fields.js +5 -0
- package/dist/constants/draft-publish-fields.js.map +1 -0
- package/dist/constants/error-messages.d.ts +7 -0
- package/dist/constants/error-messages.d.ts.map +1 -1
- package/dist/constants/error-messages.js +7 -0
- package/dist/constants/error-messages.js.map +1 -1
- package/dist/constants/media-file-types.d.ts +12 -0
- package/dist/constants/media-file-types.d.ts.map +1 -1
- package/dist/constants/media-file-types.js +66 -1
- package/dist/constants/media-file-types.js.map +1 -1
- package/dist/constants/success-messages.d.ts +3 -0
- package/dist/constants/success-messages.d.ts.map +1 -1
- package/dist/constants/success-messages.js +3 -0
- package/dist/constants/success-messages.js.map +1 -1
- package/dist/constants/user.constants.d.ts +2 -0
- package/dist/constants/user.constants.d.ts.map +1 -0
- package/dist/constants/user.constants.js +5 -0
- package/dist/constants/user.constants.js.map +1 -0
- package/dist/controllers/action-metadata.controller.d.ts +1 -1
- package/dist/controllers/action-metadata.controller.js +1 -1
- package/dist/controllers/agent-event.controller.d.ts +1 -1
- package/dist/controllers/agent-event.controller.js +1 -1
- package/dist/controllers/agent-session.controller.d.ts +1 -1
- package/dist/controllers/agent-session.controller.js +1 -1
- package/dist/controllers/authentication.controller.d.ts +1 -1
- package/dist/controllers/authentication.controller.d.ts.map +1 -1
- package/dist/controllers/authentication.controller.js +4 -3
- package/dist/controllers/authentication.controller.js.map +1 -1
- package/dist/controllers/chatter-message.controller.d.ts +5 -0
- package/dist/controllers/chatter-message.controller.d.ts.map +1 -1
- package/dist/controllers/chatter-message.controller.js +14 -0
- package/dist/controllers/chatter-message.controller.js.map +1 -1
- package/dist/controllers/dashboard-user-layout.controller.d.ts +1 -1
- package/dist/controllers/dashboard-user-layout.controller.js +1 -1
- package/dist/controllers/email-template.controller.d.ts +1 -1
- package/dist/controllers/email-template.controller.js +1 -1
- package/dist/controllers/export-template.controller.d.ts +1 -1
- package/dist/controllers/export-template.controller.d.ts.map +1 -1
- package/dist/controllers/export-template.controller.js +6 -4
- package/dist/controllers/export-template.controller.js.map +1 -1
- package/dist/controllers/export-transaction.controller.d.ts +1 -1
- package/dist/controllers/export-transaction.controller.js +1 -1
- package/dist/controllers/field-metadata.controller.d.ts +2 -2
- package/dist/controllers/import-transaction-error-log.controller.d.ts +1 -1
- package/dist/controllers/import-transaction-error-log.controller.js +1 -1
- package/dist/controllers/import-transaction.controller.d.ts +1 -1
- package/dist/controllers/import-transaction.controller.d.ts.map +1 -1
- package/dist/controllers/import-transaction.controller.js +7 -7
- package/dist/controllers/import-transaction.controller.js.map +1 -1
- package/dist/controllers/list-of-values.controller.d.ts +1 -1
- package/dist/controllers/list-of-values.controller.js +1 -1
- package/dist/controllers/locale.controller.d.ts +1 -1
- package/dist/controllers/locale.controller.js +1 -1
- package/dist/controllers/mcp-audit-log.controller.d.ts +1 -1
- package/dist/controllers/mcp-audit-log.controller.js +1 -1
- package/dist/controllers/media.controller.d.ts +2 -2
- package/dist/controllers/media.controller.d.ts.map +1 -1
- package/dist/controllers/media.controller.js +13 -8
- package/dist/controllers/media.controller.js.map +1 -1
- package/dist/controllers/menu-item-metadata.controller.d.ts +1 -1
- package/dist/controllers/menu-item-metadata.controller.js +1 -1
- package/dist/controllers/model-sequence.controller.d.ts +1 -1
- package/dist/controllers/model-sequence.controller.js +1 -1
- package/dist/controllers/module-package.controller.d.ts.map +1 -1
- package/dist/controllers/module-package.controller.js +2 -3
- package/dist/controllers/module-package.controller.js.map +1 -1
- package/dist/controllers/mpin-authentication.controller.d.ts +44 -0
- package/dist/controllers/mpin-authentication.controller.d.ts.map +1 -0
- package/dist/controllers/mpin-authentication.controller.js +102 -0
- package/dist/controllers/mpin-authentication.controller.js.map +1 -0
- package/dist/controllers/mq-message-queue.controller.d.ts +1 -1
- package/dist/controllers/mq-message-queue.controller.js +1 -1
- package/dist/controllers/mq-message.controller.d.ts +1 -1
- package/dist/controllers/mq-message.controller.js +1 -1
- package/dist/controllers/permission-metadata.controller.d.ts +1 -1
- package/dist/controllers/permission-metadata.controller.js +1 -1
- package/dist/controllers/role-metadata.controller.d.ts +1 -1
- package/dist/controllers/role-metadata.controller.js +1 -1
- package/dist/controllers/saved-filters.controller.d.ts +1 -1
- package/dist/controllers/saved-filters.controller.js +1 -1
- package/dist/controllers/scheduled-job.controller.d.ts +1 -1
- package/dist/controllers/scheduled-job.controller.js +1 -1
- package/dist/controllers/security-rule.controller.d.ts +1 -1
- package/dist/controllers/security-rule.controller.js +1 -1
- package/dist/controllers/sms-template.controller.d.ts +1 -1
- package/dist/controllers/sms-template.controller.js +1 -1
- package/dist/controllers/user-activity-history.controller.d.ts +1 -1
- package/dist/controllers/user-activity-history.controller.js +1 -1
- package/dist/controllers/user-view-metadata.controller.d.ts +1 -1
- package/dist/controllers/user-view-metadata.controller.js +1 -1
- package/dist/controllers/user.controller.d.ts +2 -2
- package/dist/controllers/user.controller.js +2 -2
- package/dist/controllers/view-metadata.controller.d.ts +2 -2
- package/dist/controllers/view-metadata.controller.js +1 -1
- package/dist/controllers/workflow-definition.controller.d.ts +1 -1
- package/dist/controllers/workflow-definition.controller.js +1 -1
- package/dist/controllers/workflow-execution-artifact.controller.d.ts +1 -1
- package/dist/controllers/workflow-execution-artifact.controller.js +1 -1
- package/dist/controllers/workflow-execution-log.controller.d.ts +1 -1
- package/dist/controllers/workflow-execution-log.controller.js +1 -1
- package/dist/controllers/workflow-execution.controller.d.ts +1 -1
- package/dist/controllers/workflow-execution.controller.js +1 -1
- package/dist/controllers/workflow-secret.controller.d.ts +1 -1
- package/dist/controllers/workflow-secret.controller.js +1 -1
- package/dist/controllers/workflow-step-execution.controller.d.ts +1 -1
- package/dist/controllers/workflow-step-execution.controller.js +1 -1
- package/dist/controllers/workflow-trigger-execution.controller.d.ts +1 -1
- package/dist/controllers/workflow-trigger-execution.controller.js +1 -1
- package/dist/dtos/basic-filters.dto.d.ts +0 -1
- package/dist/dtos/basic-filters.dto.d.ts.map +1 -1
- package/dist/dtos/basic-filters.dto.js +1 -6
- package/dist/dtos/basic-filters.dto.js.map +1 -1
- package/dist/dtos/change-mpin.dto.d.ts +6 -0
- package/dist/dtos/change-mpin.dto.d.ts.map +1 -0
- package/dist/dtos/change-mpin.dto.js +39 -0
- package/dist/dtos/change-mpin.dto.js.map +1 -0
- package/dist/dtos/create-field-metadata.dto.d.ts +3 -6
- package/dist/dtos/create-field-metadata.dto.d.ts.map +1 -1
- package/dist/dtos/create-field-metadata.dto.js +15 -10
- package/dist/dtos/create-field-metadata.dto.js.map +1 -1
- package/dist/dtos/create-model-sequence.dto.d.ts +1 -1
- package/dist/dtos/create-model-sequence.dto.d.ts.map +1 -1
- package/dist/dtos/create-model-sequence.dto.js +1 -1
- package/dist/dtos/create-model-sequence.dto.js.map +1 -1
- package/dist/dtos/mpin-login.dto.d.ts +5 -0
- package/dist/dtos/mpin-login.dto.d.ts.map +1 -0
- package/dist/dtos/mpin-login.dto.js +33 -0
- package/dist/dtos/mpin-login.dto.js.map +1 -0
- package/dist/dtos/setup-mpin.dto.d.ts +7 -0
- package/dist/dtos/setup-mpin.dto.d.ts.map +1 -0
- package/dist/dtos/setup-mpin.dto.js +47 -0
- package/dist/dtos/setup-mpin.dto.js.map +1 -0
- package/dist/entities/common.entity.d.ts +4 -0
- package/dist/entities/common.entity.d.ts.map +1 -1
- package/dist/entities/common.entity.js +25 -1
- package/dist/entities/common.entity.js.map +1 -1
- package/dist/entities/dashboard-user-layout.entity.js +2 -2
- package/dist/entities/dashboard-user-layout.entity.js.map +1 -1
- package/dist/entities/field-metadata.entity.d.ts +1 -0
- package/dist/entities/field-metadata.entity.d.ts.map +1 -1
- package/dist/entities/field-metadata.entity.js +5 -1
- package/dist/entities/field-metadata.entity.js.map +1 -1
- package/dist/entities/saved-filters.entity.js +3 -3
- package/dist/entities/saved-filters.entity.js.map +1 -1
- package/dist/entities/user-device-credential.entity.d.ts +18 -0
- package/dist/entities/user-device-credential.entity.d.ts.map +1 -0
- package/dist/entities/user-device-credential.entity.js +91 -0
- package/dist/entities/user-device-credential.entity.js.map +1 -0
- package/dist/entities/user.entity.d.ts.map +1 -1
- package/dist/entities/user.entity.js +36 -0
- package/dist/entities/user.entity.js.map +1 -1
- package/dist/entities/view-metadata.entity.js.map +1 -1
- package/dist/entities/workflow-execution-artifact.entity.d.ts.map +1 -1
- package/dist/entities/workflow-execution-artifact.entity.js +4 -3
- package/dist/entities/workflow-execution-artifact.entity.js.map +1 -1
- package/dist/entities/workflow-execution-log.entity.d.ts.map +1 -1
- package/dist/entities/workflow-execution-log.entity.js +4 -3
- package/dist/entities/workflow-execution-log.entity.js.map +1 -1
- package/dist/entities/workflow-execution.entity.d.ts.map +1 -1
- package/dist/entities/workflow-execution.entity.js +3 -2
- package/dist/entities/workflow-execution.entity.js.map +1 -1
- package/dist/entities/workflow-secret.entity.d.ts.map +1 -1
- package/dist/entities/workflow-secret.entity.js +3 -2
- package/dist/entities/workflow-secret.entity.js.map +1 -1
- package/dist/entities/workflow-step-execution.entity.d.ts.map +1 -1
- package/dist/entities/workflow-step-execution.entity.js +3 -2
- package/dist/entities/workflow-step-execution.entity.js.map +1 -1
- package/dist/entities/workflow-trigger-execution.entity.d.ts.map +1 -1
- package/dist/entities/workflow-trigger-execution.entity.js +7 -6
- package/dist/entities/workflow-trigger-execution.entity.js.map +1 -1
- package/dist/factories/mail.factory.d.ts.map +1 -1
- package/dist/factories/mail.factory.js +4 -0
- package/dist/factories/mail.factory.js.map +1 -1
- package/dist/filters/http-exception.filter.d.ts.map +1 -1
- package/dist/filters/http-exception.filter.js +5 -1
- package/dist/filters/http-exception.filter.js.map +1 -1
- package/dist/helpers/bootstrap.helper.d.ts +5 -2
- package/dist/helpers/bootstrap.helper.d.ts.map +1 -1
- package/dist/helpers/bootstrap.helper.js +7 -3
- package/dist/helpers/bootstrap.helper.js.map +1 -1
- package/dist/helpers/field-crud-managers/MediaFieldCrudManager.d.ts +7 -0
- package/dist/helpers/field-crud-managers/MediaFieldCrudManager.d.ts.map +1 -1
- package/dist/helpers/field-crud-managers/MediaFieldCrudManager.js +66 -32
- package/dist/helpers/field-crud-managers/MediaFieldCrudManager.js.map +1 -1
- package/dist/helpers/file-download.helper.d.ts +9 -0
- package/dist/helpers/file-download.helper.d.ts.map +1 -0
- package/dist/helpers/file-download.helper.js +19 -0
- package/dist/helpers/file-download.helper.js.map +1 -0
- package/dist/helpers/model-metadata-helper.service.d.ts.map +1 -1
- package/dist/helpers/model-metadata-helper.service.js +30 -1
- package/dist/helpers/model-metadata-helper.service.js.map +1 -1
- package/dist/helpers/security.helper.d.ts +5 -1
- package/dist/helpers/security.helper.d.ts.map +1 -1
- package/dist/helpers/security.helper.js +15 -4
- package/dist/helpers/security.helper.js.map +1 -1
- package/dist/helpers/solid-core-error-codes-provider.service.d.ts.map +1 -1
- package/dist/helpers/solid-core-error-codes-provider.service.js +45 -0
- package/dist/helpers/solid-core-error-codes-provider.service.js.map +1 -1
- package/dist/helpers/solid-microservice-adapter.service.d.ts.map +1 -1
- package/dist/helpers/solid-microservice-adapter.service.js +1 -1
- package/dist/helpers/solid-microservice-adapter.service.js.map +1 -1
- package/dist/helpers/solid-registry.js +1 -1
- package/dist/helpers/solid-registry.js.map +1 -1
- package/dist/helpers/typeorm-db-helper.d.ts.map +1 -1
- package/dist/helpers/typeorm-db-helper.js +9 -0
- package/dist/helpers/typeorm-db-helper.js.map +1 -1
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -1
- package/dist/interfaces/active-user-data.interface.d.ts +1 -0
- package/dist/interfaces/active-user-data.interface.d.ts.map +1 -1
- package/dist/interfaces/active-user-data.interface.js.map +1 -1
- package/dist/interfaces.d.ts +1 -0
- package/dist/interfaces.d.ts.map +1 -1
- package/dist/interfaces.js.map +1 -1
- package/dist/repository/user-device-credential.repository.d.ts +12 -0
- package/dist/repository/user-device-credential.repository.d.ts.map +1 -0
- package/dist/repository/user-device-credential.repository.js +34 -0
- package/dist/repository/user-device-credential.repository.js.map +1 -0
- package/dist/seeders/module-metadata-seeder.service.d.ts.map +1 -1
- package/dist/seeders/module-metadata-seeder.service.js +51 -30
- package/dist/seeders/module-metadata-seeder.service.js.map +1 -1
- package/dist/seeders/module-test-data.service.d.ts +3 -1
- package/dist/seeders/module-test-data.service.d.ts.map +1 -1
- package/dist/seeders/module-test-data.service.js +8 -2
- package/dist/seeders/module-test-data.service.js.map +1 -1
- package/dist/seeders/seed-data/solid-core-metadata.json +290 -78
- package/dist/services/api-key.service.d.ts.map +1 -1
- package/dist/services/api-key.service.js +1 -1
- package/dist/services/api-key.service.js.map +1 -1
- package/dist/services/authentication.service.d.ts +9 -5
- package/dist/services/authentication.service.d.ts.map +1 -1
- package/dist/services/authentication.service.js +102 -23
- package/dist/services/authentication.service.js.map +1 -1
- package/dist/services/chatter-message.service.d.ts +16 -1
- package/dist/services/chatter-message.service.d.ts.map +1 -1
- package/dist/services/chatter-message.service.js +100 -16
- package/dist/services/chatter-message.service.js.map +1 -1
- package/dist/services/crud-helper.service.d.ts +6 -4
- package/dist/services/crud-helper.service.d.ts.map +1 -1
- package/dist/services/crud-helper.service.js +32 -48
- package/dist/services/crud-helper.service.js.map +1 -1
- package/dist/services/crud.service.d.ts +13 -1
- package/dist/services/crud.service.d.ts.map +1 -1
- package/dist/services/crud.service.js +94 -68
- package/dist/services/crud.service.js.map +1 -1
- package/dist/services/datasource-introspection.service.d.ts.map +1 -1
- package/dist/services/datasource-introspection.service.js.map +1 -1
- package/dist/services/draft-publish-helper.service.d.ts +53 -0
- package/dist/services/draft-publish-helper.service.d.ts.map +1 -0
- package/dist/services/draft-publish-helper.service.js +402 -0
- package/dist/services/draft-publish-helper.service.js.map +1 -0
- package/dist/services/field-metadata.service.d.ts +2 -2
- package/dist/services/field-metadata.service.d.ts.map +1 -1
- package/dist/services/field-metadata.service.js +4 -1
- package/dist/services/field-metadata.service.js.map +1 -1
- package/dist/services/internationalisation-helper.service.d.ts +19 -0
- package/dist/services/internationalisation-helper.service.d.ts.map +1 -0
- package/dist/services/internationalisation-helper.service.js +107 -0
- package/dist/services/internationalisation-helper.service.js.map +1 -0
- package/dist/services/locale.service.d.ts +1 -1
- package/dist/services/media-storage.utils.d.ts +1 -0
- package/dist/services/media-storage.utils.d.ts.map +1 -1
- package/dist/services/media-storage.utils.js +12 -1
- package/dist/services/media-storage.utils.js.map +1 -1
- package/dist/services/media.service.d.ts +3 -2
- package/dist/services/media.service.d.ts.map +1 -1
- package/dist/services/media.service.js +45 -29
- package/dist/services/media.service.js.map +1 -1
- package/dist/services/metadata-validation.service.d.ts +7 -0
- package/dist/services/metadata-validation.service.d.ts.map +1 -0
- package/dist/services/metadata-validation.service.js +42 -0
- package/dist/services/metadata-validation.service.js.map +1 -0
- package/dist/services/model-metadata.service.d.ts.map +1 -1
- package/dist/services/model-metadata.service.js +2 -1
- package/dist/services/model-metadata.service.js.map +1 -1
- package/dist/services/module-metadata.service.d.ts.map +1 -1
- package/dist/services/module-metadata.service.js +9 -1
- package/dist/services/module-metadata.service.js.map +1 -1
- package/dist/services/mpin.service.d.ts +67 -0
- package/dist/services/mpin.service.d.ts.map +1 -0
- package/dist/services/mpin.service.js +282 -0
- package/dist/services/mpin.service.js.map +1 -0
- package/dist/services/object.utils.d.ts +2 -0
- package/dist/services/object.utils.d.ts.map +1 -0
- package/dist/services/object.utils.js +11 -0
- package/dist/services/object.utils.js.map +1 -0
- package/dist/services/refresh-token-ids-storage.service.d.ts +25 -6
- package/dist/services/refresh-token-ids-storage.service.d.ts.map +1 -1
- package/dist/services/refresh-token-ids-storage.service.js +80 -42
- package/dist/services/refresh-token-ids-storage.service.js.map +1 -1
- package/dist/services/setting.service.d.ts.map +1 -1
- package/dist/services/setting.service.js +6 -1
- package/dist/services/setting.service.js.map +1 -1
- package/dist/services/settings/default-settings-provider.service.d.ts +248 -12
- package/dist/services/settings/default-settings-provider.service.d.ts.map +1 -1
- package/dist/services/settings/default-settings-provider.service.js +143 -6
- package/dist/services/settings/default-settings-provider.service.js.map +1 -1
- package/dist/services/user.service.d.ts +2 -2
- package/dist/services/user.service.d.ts.map +1 -1
- package/dist/services/user.service.js +9 -3
- package/dist/services/user.service.js.map +1 -1
- package/dist/services/view-metadata.service.d.ts +1 -2
- package/dist/services/view-metadata.service.d.ts.map +1 -1
- package/dist/services/view-metadata.service.js +3 -55
- package/dist/services/view-metadata.service.js.map +1 -1
- package/dist/services/workflow/nodes/execution-fail.node.d.ts +6 -0
- package/dist/services/workflow/nodes/execution-fail.node.d.ts.map +1 -0
- package/dist/services/workflow/nodes/execution-fail.node.js +81 -0
- package/dist/services/workflow/nodes/execution-fail.node.js.map +1 -0
- package/dist/services/workflow/nodes/for-each.node.d.ts +2 -0
- package/dist/services/workflow/nodes/for-each.node.d.ts.map +1 -1
- package/dist/services/workflow/nodes/for-each.node.js +114 -5
- package/dist/services/workflow/nodes/for-each.node.js.map +1 -1
- package/dist/services/workflow/nodes/if.node.d.ts.map +1 -1
- package/dist/services/workflow/nodes/if.node.js +7 -0
- package/dist/services/workflow/nodes/if.node.js.map +1 -1
- package/dist/services/workflow/nodes/log-write.node.d.ts.map +1 -1
- package/dist/services/workflow/nodes/log-write.node.js +2 -0
- package/dist/services/workflow/nodes/log-write.node.js.map +1 -1
- package/dist/services/workflow/nodes/loop-until.node.d.ts +12 -0
- package/dist/services/workflow/nodes/loop-until.node.d.ts.map +1 -0
- package/dist/services/workflow/nodes/loop-until.node.js +281 -0
- package/dist/services/workflow/nodes/loop-until.node.js.map +1 -0
- package/dist/services/workflow/nodes/parallel.node.d.ts.map +1 -1
- package/dist/services/workflow/nodes/parallel.node.js +7 -0
- package/dist/services/workflow/nodes/parallel.node.js.map +1 -1
- package/dist/services/workflow/nodes/sequential.node.d.ts.map +1 -1
- package/dist/services/workflow/nodes/sequential.node.js +7 -0
- package/dist/services/workflow/nodes/sequential.node.js.map +1 -1
- package/dist/services/workflow/nodes/switch.node.d.ts.map +1 -1
- package/dist/services/workflow/nodes/switch.node.js +7 -0
- package/dist/services/workflow/nodes/switch.node.js.map +1 -1
- package/dist/services/workflow/workflow-definition-validator.service.d.ts.map +1 -1
- package/dist/services/workflow/workflow-definition-validator.service.js +5 -2
- package/dist/services/workflow/workflow-definition-validator.service.js.map +1 -1
- package/dist/services/workflow/workflow-expression.service.d.ts.map +1 -1
- package/dist/services/workflow/workflow-expression.service.js +5 -0
- package/dist/services/workflow/workflow-expression.service.js.map +1 -1
- package/dist/services/workflow/workflow-node-registry.service.d.ts +2 -1
- package/dist/services/workflow/workflow-node-registry.service.d.ts.map +1 -1
- package/dist/services/workflow/workflow-node-registry.service.js +7 -0
- package/dist/services/workflow/workflow-node-registry.service.js.map +1 -1
- package/dist/services/workflow/workflow-runtime.service.d.ts +8 -0
- package/dist/services/workflow/workflow-runtime.service.d.ts.map +1 -1
- package/dist/services/workflow/workflow-runtime.service.js +197 -32
- package/dist/services/workflow/workflow-runtime.service.js.map +1 -1
- package/dist/services/workflow-definition.service.d.ts +1 -1
- package/dist/solid-core.module.d.ts +1 -3
- package/dist/solid-core.module.d.ts.map +1 -1
- package/dist/solid-core.module.js +28 -40
- package/dist/solid-core.module.js.map +1 -1
- package/dist/testing/adapters/ui/playwright-adapter.d.ts +5 -0
- package/dist/testing/adapters/ui/playwright-adapter.d.ts.map +1 -1
- package/dist/testing/adapters/ui/playwright-adapter.js +17 -1
- package/dist/testing/adapters/ui/playwright-adapter.js.map +1 -1
- package/dist/testing/adapters/ui/ui.types.d.ts +2 -0
- package/dist/testing/adapters/ui/ui.types.d.ts.map +1 -1
- package/dist/testing/adapters/ui/ui.types.js.map +1 -1
- package/dist/testing/reporter/console-reporter.d.ts +3 -0
- package/dist/testing/reporter/console-reporter.d.ts.map +1 -1
- package/dist/testing/reporter/console-reporter.js +2 -0
- package/dist/testing/reporter/console-reporter.js.map +1 -1
- package/dist/testing/reporter/progress-reporter.d.ts +64 -0
- package/dist/testing/reporter/progress-reporter.d.ts.map +1 -0
- package/dist/testing/reporter/progress-reporter.js +224 -0
- package/dist/testing/reporter/progress-reporter.js.map +1 -0
- package/dist/testing/reporter/reporter.types.d.ts +3 -0
- package/dist/testing/reporter/reporter.types.d.ts.map +1 -1
- package/dist/testing/reporter/reporter.types.js.map +1 -1
- package/dist/testing/runner/run-from-metadata.d.ts.map +1 -1
- package/dist/testing/runner/run-from-metadata.js +1 -0
- package/dist/testing/runner/run-from-metadata.js.map +1 -1
- package/dist/testing/steps/ui/actions.step.d.ts.map +1 -1
- package/dist/testing/steps/ui/actions.step.js +6 -2
- package/dist/testing/steps/ui/actions.step.js.map +1 -1
- package/dist/testing/steps/ui/assertions.step.d.ts.map +1 -1
- package/dist/testing/steps/ui/assertions.step.js +11 -3
- package/dist/testing/steps/ui/assertions.step.js.map +1 -1
- package/dist/testing/steps/ui/form.step.d.ts.map +1 -1
- package/dist/testing/steps/ui/form.step.js +9 -3
- package/dist/testing/steps/ui/form.step.js.map +1 -1
- package/dist/testing/steps/ui/manual.step.js +1 -1
- package/dist/testing/steps/ui/manual.step.js.map +1 -1
- package/dist/testing/steps/ui/navigation.step.d.ts.map +1 -1
- package/dist/testing/steps/ui/navigation.step.js +3 -1
- package/dist/testing/steps/ui/navigation.step.js.map +1 -1
- package/dist/theme/theme-registry.d.ts +14 -0
- package/dist/theme/theme-registry.d.ts.map +1 -0
- package/dist/theme/theme-registry.js +147 -0
- package/dist/theme/theme-registry.js.map +1 -0
- package/dist/types/workflow-dsl.types.d.ts +14 -0
- package/dist/types/workflow-dsl.types.d.ts.map +1 -1
- package/dist/types/workflow-dsl.types.js.map +1 -1
- package/package.json +2 -2
- package/src/commands/run-tests.command.ts +64 -4
- package/src/commands/seed.command.ts +19 -0
- package/src/config/cache.options.ts +9 -1
- package/src/constants/chatter-message.constants.ts +12 -0
- package/src/constants/draft-publish-fields.ts +5 -0
- package/src/constants/error-messages.ts +14 -0
- package/src/constants/media-file-types.ts +128 -0
- package/src/constants/success-messages.ts +5 -0
- package/src/constants/user.constants.ts +13 -0
- package/src/controllers/authentication.controller.ts +5 -2
- package/src/controllers/chatter-message.controller.ts +8 -0
- package/src/controllers/export-template.controller.ts +5 -3
- package/src/controllers/import-transaction.controller.ts +6 -6
- package/src/controllers/media.controller.ts +17 -6
- package/src/controllers/module-package.controller.ts +2 -3
- package/src/controllers/mpin-authentication.controller.ts +67 -0
- package/src/dtos/basic-filters.dto.ts +0 -4
- package/src/dtos/change-mpin.dto.ts +18 -0
- package/src/dtos/create-field-metadata.dto.ts +17 -9
- package/src/dtos/create-model-sequence.dto.ts +1 -1
- package/src/dtos/mpin-login.dto.ts +24 -0
- package/src/dtos/setup-mpin.dto.ts +51 -0
- package/src/entities/common.entity.ts +24 -0
- package/src/entities/dashboard-user-layout.entity.ts +2 -2
- package/src/entities/field-metadata.entity.ts +3 -0
- package/src/entities/saved-filters.entity.ts +3 -3
- package/src/entities/user-device-credential.entity.ts +130 -0
- package/src/entities/user.entity.ts +53 -36
- package/src/entities/view-metadata.entity.ts +2 -2
- package/src/entities/workflow-execution-artifact.entity.ts +4 -3
- package/src/entities/workflow-execution-log.entity.ts +4 -3
- package/src/entities/workflow-execution.entity.ts +3 -2
- package/src/entities/workflow-secret.entity.ts +3 -2
- package/src/entities/workflow-step-execution.entity.ts +3 -2
- package/src/entities/workflow-trigger-execution.entity.ts +7 -6
- package/src/factories/mail.factory.ts +7 -1
- package/src/filters/http-exception.filter.ts +11 -1
- package/src/helpers/bootstrap.helper.ts +43 -6
- package/src/helpers/field-crud-managers/MediaFieldCrudManager.ts +90 -37
- package/src/helpers/file-download.helper.ts +45 -0
- package/src/helpers/model-metadata-helper.service.ts +32 -1
- package/src/helpers/security.helper.ts +35 -8
- package/src/helpers/solid-core-error-codes-provider.service.ts +53 -0
- package/src/helpers/solid-microservice-adapter.service.ts +6 -1
- package/src/helpers/solid-registry.ts +1 -1
- package/src/helpers/typeorm-db-helper.ts +12 -1
- package/src/index.ts +10 -0
- package/src/interfaces/active-user-data.interface.ts +9 -0
- package/src/interfaces.ts +1 -0
- package/src/repository/user-device-credential.repository.ts +17 -0
- package/src/seeders/module-metadata-seeder.service.ts +61 -39
- package/src/seeders/module-test-data.service.ts +6 -0
- package/src/seeders/seed-data/solid-core-metadata.json +290 -78
- package/src/services/api-key.service.ts +13 -1
- package/src/services/authentication.service.ts +203 -41
- package/src/services/chatter-message.service.ts +180 -19
- package/src/services/crud-helper.service.ts +35 -50
- package/src/services/crud.service.ts +132 -105
- package/src/services/datasource-introspection.service.ts +5 -0
- package/src/services/draft-publish-helper.service.ts +581 -0
- package/src/services/field-metadata.service.ts +5 -2
- package/src/services/internationalisation-helper.service.ts +148 -0
- package/src/services/media-storage.utils.ts +26 -1
- package/src/services/media.service.ts +68 -36
- package/src/services/metadata-validation.service.ts +39 -0
- package/src/services/model-metadata.service.ts +4 -1
- package/src/services/module-metadata.service.ts +10 -1
- package/src/services/mpin.service.ts +447 -0
- package/src/services/object.utils.ts +10 -0
- package/src/services/refresh-token-ids-storage.service.ts +229 -90
- package/src/services/setting.service.ts +8 -1
- package/src/services/settings/default-settings-provider.service.ts +154 -6
- package/src/services/user.service.ts +18 -3
- package/src/services/view-metadata.service.ts +5 -145
- package/src/services/workflow/nodes/execution-fail.node.ts +82 -0
- package/src/services/workflow/nodes/for-each.node.ts +140 -6
- package/src/services/workflow/nodes/if.node.ts +7 -0
- package/src/services/workflow/nodes/log-write.node.ts +2 -0
- package/src/services/workflow/nodes/loop-until.node.ts +343 -0
- package/src/services/workflow/nodes/parallel.node.ts +7 -0
- package/src/services/workflow/nodes/sequential.node.ts +7 -0
- package/src/services/workflow/nodes/switch.node.ts +7 -0
- package/src/services/workflow/workflow-definition-validator.service.ts +5 -2
- package/src/services/workflow/workflow-expression.service.ts +5 -0
- package/src/services/workflow/workflow-node-registry.service.ts +11 -0
- package/src/services/workflow/workflow-runtime.service.ts +274 -39
- package/src/solid-core.module.ts +46 -15
- package/src/testing/README.md +75 -3
- package/src/testing/adapters/ui/playwright-adapter.ts +25 -0
- package/src/testing/adapters/ui/ui.types.ts +2 -0
- package/src/testing/reporter/console-reporter.ts +4 -0
- package/src/testing/reporter/progress-reporter.ts +251 -0
- package/src/testing/reporter/reporter.types.ts +3 -0
- package/src/testing/runner/run-from-metadata.ts +1 -0
- package/src/testing/steps/ui/actions.step.ts +8 -4
- package/src/testing/steps/ui/assertions.step.ts +18 -5
- package/src/testing/steps/ui/form.step.ts +16 -6
- package/src/testing/steps/ui/manual.step.ts +1 -1
- package/src/testing/steps/ui/navigation.step.ts +4 -2
- package/src/theme/theme-registry.ts +181 -0
- package/src/types/workflow-dsl.types.ts +43 -0
|
@@ -20,7 +20,7 @@ import { SUCCESS_MESSAGES } from "src/constants/success-messages";
|
|
|
20
20
|
import { CreateUserDto } from "src/dtos/create-user.dto";
|
|
21
21
|
import { MailFactory } from "src/factories/mail.factory";
|
|
22
22
|
import { UserRepository } from "src/repository/user.repository";
|
|
23
|
-
import { DataSource, DeepPartial, Repository } from "typeorm";
|
|
23
|
+
import { DataSource, DeepPartial, FindOptionsWhere, Repository } from "typeorm";
|
|
24
24
|
import { v4 as uuidv4 } from "uuid";
|
|
25
25
|
import {
|
|
26
26
|
ForgotPasswordSendVerificationTokenOn,
|
|
@@ -49,6 +49,7 @@ import { SsoCodeStorageService } from "./sso-code-storage.service";
|
|
|
49
49
|
import { RoleMetadataService } from "./role-metadata.service";
|
|
50
50
|
import { SettingService } from "./setting.service";
|
|
51
51
|
import { UserActivityHistoryService } from "./user-activity-history.service";
|
|
52
|
+
import { MetadataValidationService } from "./metadata-validation.service";
|
|
52
53
|
import { UserService } from "./user.service";
|
|
53
54
|
import { SmsFactory } from "src/factories/sms.factory";
|
|
54
55
|
import { WhatsAppFactory } from "src/factories/whatsapp.factory";
|
|
@@ -88,6 +89,7 @@ export class AuthenticationService {
|
|
|
88
89
|
private readonly roleMetadataService: RoleMetadataService,
|
|
89
90
|
private readonly userActivityHistoryService: UserActivityHistoryService,
|
|
90
91
|
private readonly ssoCodeStorage: SsoCodeStorageService,
|
|
92
|
+
private readonly metadataValidationService: MetadataValidationService,
|
|
91
93
|
|
|
92
94
|
@InjectDataSource()
|
|
93
95
|
private readonly dataSource: DataSource,
|
|
@@ -225,6 +227,9 @@ export class AuthenticationService {
|
|
|
225
227
|
preferEntityApiKeyFlag: boolean = false,
|
|
226
228
|
): Promise<T> {
|
|
227
229
|
try {
|
|
230
|
+
await this.assertUniqueSignupIdentifiers(signUpDto, repo);
|
|
231
|
+
await this.metadataValidationService.validateCreateDto("user", signUpDto);
|
|
232
|
+
|
|
228
233
|
const onForcePasswordChange =
|
|
229
234
|
this.settingService.getConfigValue<SolidCoreSetting>(
|
|
230
235
|
"forceChangePasswordOnFirstLogin",
|
|
@@ -276,6 +281,59 @@ export class AuthenticationService {
|
|
|
276
281
|
}
|
|
277
282
|
}
|
|
278
283
|
|
|
284
|
+
private async assertUniqueSignupIdentifiers<T extends User>(
|
|
285
|
+
signUpDto: SignUpDto,
|
|
286
|
+
repo: Repository<T>,
|
|
287
|
+
): Promise<void> {
|
|
288
|
+
const username = signUpDto.username?.trim();
|
|
289
|
+
const email = signUpDto.email?.trim();
|
|
290
|
+
const mobile = signUpDto.mobile?.trim();
|
|
291
|
+
|
|
292
|
+
const where: FindOptionsWhere<T>[] = [];
|
|
293
|
+
|
|
294
|
+
if (username) {
|
|
295
|
+
where.push({ username } as FindOptionsWhere<T>);
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
if (email) {
|
|
299
|
+
where.push({ email } as FindOptionsWhere<T>);
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
if (mobile) {
|
|
303
|
+
where.push({ mobile } as FindOptionsWhere<T>);
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
if (where.length === 0) {
|
|
307
|
+
return;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
const existingUser = await repo.findOne({ where });
|
|
311
|
+
|
|
312
|
+
if (!existingUser) {
|
|
313
|
+
return;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
if (email && existingUser.email === email) {
|
|
317
|
+
throw new ConflictException(
|
|
318
|
+
`A user with email address "${email}" already exists.`,
|
|
319
|
+
);
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
if (mobile && existingUser.mobile === mobile) {
|
|
323
|
+
throw new ConflictException(
|
|
324
|
+
`A user with mobile number "${mobile}" already exists.`,
|
|
325
|
+
);
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
if (username && existingUser.username === username) {
|
|
329
|
+
throw new ConflictException(
|
|
330
|
+
`A user with username "${username}" already exists.`,
|
|
331
|
+
);
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
throw new ConflictException(ERROR_MESSAGES.USER_ALREADY_EXISTS);
|
|
335
|
+
}
|
|
336
|
+
|
|
279
337
|
private async handlePasswordlessSignupOtp<T extends User>(
|
|
280
338
|
user: T,
|
|
281
339
|
signUpDto: SignUpDto,
|
|
@@ -400,11 +458,23 @@ export class AuthenticationService {
|
|
|
400
458
|
// if forcePasswordChange is true, then we trigger an email to the user to change the password, this needs to be done using a queue.
|
|
401
459
|
// Create a new method like notifyUserOnForcePasswordChange, create a new email template we can call it on-force-password-change this template to include the random password
|
|
402
460
|
if (user.forcePasswordChange && autoGeneratedPwd) {
|
|
403
|
-
|
|
461
|
+
try {
|
|
462
|
+
await this.notifyUserOnForcePasswordChange(user, autoGeneratedPwd);
|
|
463
|
+
} catch (error: any) {
|
|
464
|
+
this.logger.error(
|
|
465
|
+
`Failed to send force-password-change email for user ${user.id}: ${error?.message ?? error}`,
|
|
466
|
+
);
|
|
467
|
+
}
|
|
404
468
|
}
|
|
405
469
|
|
|
406
470
|
// Send welcome notifications (email/SMS) if enabled.
|
|
407
|
-
|
|
471
|
+
try {
|
|
472
|
+
await this.notifyUserOnSignup(user);
|
|
473
|
+
} catch (error: any) {
|
|
474
|
+
this.logger.error(
|
|
475
|
+
`Failed to send signup notifications for user ${user.id}: ${error?.message ?? error}`,
|
|
476
|
+
);
|
|
477
|
+
}
|
|
408
478
|
}
|
|
409
479
|
|
|
410
480
|
generatePassword(length: number = 8): string {
|
|
@@ -1578,7 +1648,7 @@ export class AuthenticationService {
|
|
|
1578
1648
|
// Assuming all users do not have mobile as mandatory.
|
|
1579
1649
|
if (
|
|
1580
1650
|
forgotPasswordSendVerificationTokenOn ==
|
|
1581
|
-
|
|
1651
|
+
ForgotPasswordSendVerificationTokenOn.MOBILE &&
|
|
1582
1652
|
user.mobile
|
|
1583
1653
|
) {
|
|
1584
1654
|
const smsService = this.smsFactory.getSmsService();
|
|
@@ -1702,7 +1772,7 @@ export class AuthenticationService {
|
|
|
1702
1772
|
// Assuming all users do not have mobile as mandatory.
|
|
1703
1773
|
if (
|
|
1704
1774
|
forgotPasswordSendVerificationTokenOn ==
|
|
1705
|
-
|
|
1775
|
+
ForgotPasswordSendVerificationTokenOn.MOBILE &&
|
|
1706
1776
|
user.mobile
|
|
1707
1777
|
) {
|
|
1708
1778
|
const smsService = this.smsFactory.getSmsService();
|
|
@@ -1723,7 +1793,13 @@ export class AuthenticationService {
|
|
|
1723
1793
|
}
|
|
1724
1794
|
}
|
|
1725
1795
|
|
|
1726
|
-
|
|
1796
|
+
/**
|
|
1797
|
+
* @param deviceId optional stable per-device identifier. Supplied by callers
|
|
1798
|
+
* that own a device credential; otherwise a key is minted per login so that
|
|
1799
|
+
* clients with no device concept (the web UI) still get their own bucket
|
|
1800
|
+
* instead of sharing - and evicting - one.
|
|
1801
|
+
*/
|
|
1802
|
+
async generateTokens(user: User, deviceId?: string) {
|
|
1727
1803
|
const sessionId = this.shouldPreventConcurrentLogins()
|
|
1728
1804
|
? randomUUID()
|
|
1729
1805
|
: undefined;
|
|
@@ -1732,9 +1808,17 @@ export class AuthenticationService {
|
|
|
1732
1808
|
} else {
|
|
1733
1809
|
await this.activeSessionStorage.clearActiveSession(user.id);
|
|
1734
1810
|
}
|
|
1811
|
+
|
|
1812
|
+
// Mutually exclusive with sessionId by construction: per-device buckets
|
|
1813
|
+
// exist only when preventConcurrentLogins is off, sessionId only when it
|
|
1814
|
+
// is on.
|
|
1815
|
+
const deviceKey = this.refreshTokenIdsStorage.areConcurrentLoginsAllowed()
|
|
1816
|
+
? deviceId ?? randomUUID()
|
|
1817
|
+
: undefined;
|
|
1818
|
+
|
|
1735
1819
|
const [accessToken, refreshToken] = await Promise.all([
|
|
1736
|
-
await this.generateAccessToken(user, sessionId),
|
|
1737
|
-
await this.generateRefreshToken(user),
|
|
1820
|
+
await this.generateAccessToken(user, sessionId, deviceKey),
|
|
1821
|
+
await this.generateRefreshToken(user, undefined, deviceKey),
|
|
1738
1822
|
]);
|
|
1739
1823
|
|
|
1740
1824
|
return {
|
|
@@ -1743,7 +1827,7 @@ export class AuthenticationService {
|
|
|
1743
1827
|
};
|
|
1744
1828
|
}
|
|
1745
1829
|
|
|
1746
|
-
async generateAccessToken(user: User, sessionId?: string) {
|
|
1830
|
+
async generateAccessToken(user: User, sessionId?: string, deviceKey?: string) {
|
|
1747
1831
|
// const userRoleNames = user.roles.map((role) => role.name).join(';')
|
|
1748
1832
|
const userRoleNames = user.roles.map((role) => role.name);
|
|
1749
1833
|
const resolvedSessionId = this.shouldPreventConcurrentLogins()
|
|
@@ -1760,18 +1844,36 @@ export class AuthenticationService {
|
|
|
1760
1844
|
email: user.email,
|
|
1761
1845
|
roles: userRoleNames,
|
|
1762
1846
|
...(resolvedSessionId ? { sessionId: resolvedSessionId } : {}),
|
|
1847
|
+
// Carried so that bearer-authenticated endpoints which need this
|
|
1848
|
+
// session's refresh token - generateSsoCode, me - can locate its
|
|
1849
|
+
// bucket. The refresh token is not available to them.
|
|
1850
|
+
...(deviceKey ? { deviceKey } : {}),
|
|
1763
1851
|
},
|
|
1764
1852
|
);
|
|
1765
1853
|
|
|
1766
1854
|
return accessToken;
|
|
1767
1855
|
}
|
|
1768
1856
|
|
|
1769
|
-
async generateRefreshToken(
|
|
1857
|
+
async generateRefreshToken(
|
|
1858
|
+
user: User,
|
|
1859
|
+
previousRefreshToken?: string,
|
|
1860
|
+
deviceKey?: string,
|
|
1861
|
+
) {
|
|
1770
1862
|
const refreshTokenId = randomUUID();
|
|
1771
1863
|
const refreshTokenTtl =
|
|
1772
1864
|
this.settingService.getConfigValue<SolidCoreSetting>("refreshTokenTtl");
|
|
1865
|
+
|
|
1866
|
+
// Only per-device tokens carry an epoch - it is what makes bulk
|
|
1867
|
+
// invalidation possible without enumerating buckets. Single-slot tokens
|
|
1868
|
+
// are invalidated by deleting their one key.
|
|
1869
|
+
const epoch = deviceKey
|
|
1870
|
+
? await this.refreshTokenIdsStorage.getEpoch(user.id)
|
|
1871
|
+
: undefined;
|
|
1872
|
+
|
|
1773
1873
|
const refreshToken = await this.signToken(user.id, refreshTokenTtl, {
|
|
1774
1874
|
refreshTokenId,
|
|
1875
|
+
...(deviceKey ? { deviceKey } : {}),
|
|
1876
|
+
...(epoch !== undefined ? { epoch } : {}),
|
|
1775
1877
|
});
|
|
1776
1878
|
|
|
1777
1879
|
// store the refresh token id in the redis storage.
|
|
@@ -1779,6 +1881,7 @@ export class AuthenticationService {
|
|
|
1779
1881
|
user.id,
|
|
1780
1882
|
refreshToken,
|
|
1781
1883
|
previousRefreshToken,
|
|
1884
|
+
deviceKey,
|
|
1782
1885
|
);
|
|
1783
1886
|
|
|
1784
1887
|
return refreshToken;
|
|
@@ -1793,8 +1896,16 @@ export class AuthenticationService {
|
|
|
1793
1896
|
const issuer =
|
|
1794
1897
|
this.settingService.getConfigValue<SolidCoreSetting>("issuer");
|
|
1795
1898
|
|
|
1796
|
-
|
|
1797
|
-
|
|
1899
|
+
// deviceKey/epoch are absent on tokens issued before per-device sessions,
|
|
1900
|
+
// and on tokens issued while preventConcurrentLogins is on. That absence
|
|
1901
|
+
// is the signal the storage layer branches on - no request-body change
|
|
1902
|
+
// and no client change is needed to carry it.
|
|
1903
|
+
const { sub, deviceKey, epoch } = await this.jwtService.verifyAsync<
|
|
1904
|
+
Pick<ActiveUserData, "sub"> & {
|
|
1905
|
+
refreshTokenId: string;
|
|
1906
|
+
deviceKey?: string;
|
|
1907
|
+
epoch?: number;
|
|
1908
|
+
}
|
|
1798
1909
|
>(refreshTokenDto.refreshToken, {
|
|
1799
1910
|
secret,
|
|
1800
1911
|
audience,
|
|
@@ -1822,17 +1933,24 @@ export class AuthenticationService {
|
|
|
1822
1933
|
// throw new Error('Refresh token is invalid');
|
|
1823
1934
|
// }
|
|
1824
1935
|
|
|
1825
|
-
const
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
|
|
1936
|
+
const rotated = await this.refreshTokenIdsStorage.validateAndRotate(
|
|
1937
|
+
user,
|
|
1938
|
+
refreshTokenDto.refreshToken,
|
|
1939
|
+
{ deviceKey, epoch },
|
|
1940
|
+
);
|
|
1830
1941
|
|
|
1831
1942
|
await this.userActivityHistoryService.logEvent("tokenRefreshed", user);
|
|
1832
1943
|
|
|
1833
1944
|
return {
|
|
1834
|
-
|
|
1835
|
-
|
|
1945
|
+
// The rotated key, not the incoming one: a session migrating out of the
|
|
1946
|
+
// pre-deploy single slot is assigned a bucket here, and the new access
|
|
1947
|
+
// token has to name the same one.
|
|
1948
|
+
accessToken: await this.generateAccessToken(
|
|
1949
|
+
user,
|
|
1950
|
+
undefined,
|
|
1951
|
+
rotated.deviceKey,
|
|
1952
|
+
),
|
|
1953
|
+
refreshToken: rotated.refreshToken,
|
|
1836
1954
|
};
|
|
1837
1955
|
} catch (err: any) {
|
|
1838
1956
|
if (err instanceof InvalidatedRefreshTokenError) {
|
|
@@ -2221,28 +2339,31 @@ export class AuthenticationService {
|
|
|
2221
2339
|
// // Invalidate the refresh token
|
|
2222
2340
|
// // await this.refreshTokenIdsStorage.invalidate(user.id);
|
|
2223
2341
|
// }
|
|
2224
|
-
async logout(refreshToken: string) {
|
|
2342
|
+
async logout(refreshToken: string, allDevices = false) {
|
|
2225
2343
|
try {
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
//
|
|
2229
|
-
//
|
|
2230
|
-
//
|
|
2231
|
-
//
|
|
2232
|
-
//
|
|
2233
|
-
//
|
|
2234
|
-
//
|
|
2235
|
-
|
|
2236
|
-
|
|
2237
|
-
|
|
2238
|
-
const payload = this.jwtService.decode(refreshToken) as any;
|
|
2239
|
-
|
|
2240
|
-
if (!payload || !payload.sub) {
|
|
2241
|
-
throw new UnauthorizedException(ERROR_MESSAGES.INVALID_REFRESH_TOKEN);
|
|
2344
|
+
const payload = await this.verifyRefreshTokenForLogout(refreshToken);
|
|
2345
|
+
|
|
2346
|
+
// Nothing verifiable to act on: forged, malformed, or signed with another
|
|
2347
|
+
// secret. Acting on an unauthenticated `sub` is exactly the hole this
|
|
2348
|
+
// closes - the route is @Public(), so a decoded-but-unverified token let
|
|
2349
|
+
// anyone log out an arbitrary user. Report success either way: logout
|
|
2350
|
+
// must be safe to call blindly from a client error path, and a 401/200
|
|
2351
|
+
// split here would leak whether a token string is genuine (RFC 7009 §2.2
|
|
2352
|
+
// takes the same position for revocation endpoints).
|
|
2353
|
+
if (!payload?.sub) {
|
|
2354
|
+
this.logger.warn("logout called with an unverifiable refresh token");
|
|
2355
|
+
return { message: SUCCESS_MESSAGES.LOGOUT_SUCCESS };
|
|
2242
2356
|
}
|
|
2243
2357
|
|
|
2244
2358
|
const userId = payload.sub;
|
|
2245
|
-
|
|
2359
|
+
if (allDevices) {
|
|
2360
|
+
await this.refreshTokenIdsStorage.invalidateAll(userId);
|
|
2361
|
+
} else {
|
|
2362
|
+
// Scoped to the bucket this token belongs to, so signing out on one
|
|
2363
|
+
// device leaves the others alive. A token with no deviceKey names the
|
|
2364
|
+
// single slot, which is the same key as before.
|
|
2365
|
+
await this.refreshTokenIdsStorage.invalidate(userId, payload.deviceKey);
|
|
2366
|
+
}
|
|
2246
2367
|
await this.activeSessionStorage.clearActiveSession(userId);
|
|
2247
2368
|
const user = await this.userRepository.findOne({
|
|
2248
2369
|
where: {
|
|
@@ -2250,10 +2371,15 @@ export class AuthenticationService {
|
|
|
2250
2371
|
},
|
|
2251
2372
|
});
|
|
2252
2373
|
// Log logout event
|
|
2253
|
-
|
|
2374
|
+
if (user) {
|
|
2375
|
+
await this.userActivityHistoryService.logEvent("logout", user);
|
|
2376
|
+
}
|
|
2254
2377
|
|
|
2255
2378
|
return { message: SUCCESS_MESSAGES.LOGOUT_SUCCESS };
|
|
2256
2379
|
} catch (err: any) {
|
|
2380
|
+
// JWT problems no longer reach here - verifyRefreshTokenForLogout
|
|
2381
|
+
// swallows them - so this is left for genuine infrastructure failures
|
|
2382
|
+
// (cache or database unavailable), where a 500 is the correct answer.
|
|
2257
2383
|
throw err instanceof UnauthorizedException ||
|
|
2258
2384
|
err instanceof InternalServerErrorException
|
|
2259
2385
|
? err
|
|
@@ -2261,6 +2387,31 @@ export class AuthenticationService {
|
|
|
2261
2387
|
}
|
|
2262
2388
|
}
|
|
2263
2389
|
|
|
2390
|
+
private async verifyRefreshTokenForLogout(
|
|
2391
|
+
refreshToken: string,
|
|
2392
|
+
): Promise<{ sub: number; deviceKey?: string } | null> {
|
|
2393
|
+
try {
|
|
2394
|
+
const payload = await this.jwtService.verifyAsync(refreshToken, {
|
|
2395
|
+
secret: this.settingService.getConfigValue<SolidCoreSetting>("secret"),
|
|
2396
|
+
audience:
|
|
2397
|
+
this.settingService.getConfigValue<SolidCoreSetting>("audience"),
|
|
2398
|
+
issuer: this.settingService.getConfigValue<SolidCoreSetting>("issuer"),
|
|
2399
|
+
// Signature, audience and issuer are still enforced; only `exp` is
|
|
2400
|
+
// tolerated. An expired session must still be able to log out - the
|
|
2401
|
+
// previous jwtService.decode() allowed that, and a plain verifyAsync
|
|
2402
|
+
// would throw TokenExpiredError, which the catch above would turn into
|
|
2403
|
+
// a 500 on an ordinary sign-out.
|
|
2404
|
+
ignoreExpiration: true,
|
|
2405
|
+
});
|
|
2406
|
+
|
|
2407
|
+
// Access and refresh tokens share secret, audience and issuer, so only
|
|
2408
|
+
// this claim distinguishes them. Reject an access token presented here.
|
|
2409
|
+
return payload?.refreshTokenId ? payload : null;
|
|
2410
|
+
} catch {
|
|
2411
|
+
return null; // bad signature or malformed
|
|
2412
|
+
}
|
|
2413
|
+
}
|
|
2414
|
+
|
|
2264
2415
|
async activateUser(userId: number) {
|
|
2265
2416
|
const user = await this.userService.findOne(userId, {});
|
|
2266
2417
|
if (!user) {
|
|
@@ -2282,9 +2433,14 @@ export class AuthenticationService {
|
|
|
2282
2433
|
|
|
2283
2434
|
// const tokens = await this.generateTokens(user);
|
|
2284
2435
|
|
|
2285
|
-
// Get the refresh token for a user from refresh token storage.
|
|
2436
|
+
// Get the refresh token for a user from refresh token storage. The bucket
|
|
2437
|
+
// is named by the access token's own deviceKey claim; absent for
|
|
2438
|
+
// single-slot sessions, which resolves to the same key as before.
|
|
2286
2439
|
const refreshTokenState =
|
|
2287
|
-
await this.refreshTokenIdsStorage.getCurrentRefreshTokenState(
|
|
2440
|
+
await this.refreshTokenIdsStorage.getCurrentRefreshTokenState(
|
|
2441
|
+
user.id,
|
|
2442
|
+
activeUser.deviceKey,
|
|
2443
|
+
);
|
|
2288
2444
|
|
|
2289
2445
|
const response = {
|
|
2290
2446
|
user: {
|
|
@@ -2295,7 +2451,11 @@ export class AuthenticationService {
|
|
|
2295
2451
|
id: user.id,
|
|
2296
2452
|
roles: user.roles.map((role) => role.name),
|
|
2297
2453
|
},
|
|
2298
|
-
|
|
2454
|
+
// Null-guarded because the cache entry now carries a TTL: once it
|
|
2455
|
+
// expires - or after a logout followed by a call with a still-valid
|
|
2456
|
+
// access token - there is no state to read. Matches the existing
|
|
2457
|
+
// handling in generateSsoCode.
|
|
2458
|
+
refreshToken: refreshTokenState?.currentRefreshToken ?? null,
|
|
2299
2459
|
// ...tokens
|
|
2300
2460
|
};
|
|
2301
2461
|
return response;
|
|
@@ -2308,6 +2468,7 @@ export class AuthenticationService {
|
|
|
2308
2468
|
const refreshTokenState =
|
|
2309
2469
|
await this.refreshTokenIdsStorage.getCurrentRefreshTokenState(
|
|
2310
2470
|
activeUser.sub,
|
|
2471
|
+
activeUser.deviceKey,
|
|
2311
2472
|
);
|
|
2312
2473
|
if (!refreshTokenState?.currentRefreshToken) {
|
|
2313
2474
|
throw new UnauthorizedException("No active session found");
|
|
@@ -2342,6 +2503,7 @@ function parseUniqueConstraintError(detail: string): string {
|
|
|
2342
2503
|
const fieldMap: Record<string, string> = {
|
|
2343
2504
|
username: "username",
|
|
2344
2505
|
email: "email address",
|
|
2506
|
+
mobile: "mobile number",
|
|
2345
2507
|
full_name_user_key: "full name",
|
|
2346
2508
|
};
|
|
2347
2509
|
const friendlyField = fieldMap[field] || field;
|