@solidxai/core 0.1.13-beta.2 → 0.1.13-beta.20
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 +9517 -0
- 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 +65 -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 +2 -6
- package/dist/dtos/create-field-metadata.dto.d.ts.map +1 -1
- package/dist/dtos/create-field-metadata.dto.js +4 -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/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 +1 -0
- package/dist/helpers/field-crud-managers/MediaFieldCrudManager.d.ts.map +1 -1
- package/dist/helpers/field-crud-managers/MediaFieldCrudManager.js +18 -11
- 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 +15 -1
- package/dist/services/chatter-message.service.d.ts.map +1 -1
- package/dist/services/chatter-message.service.js +56 -4
- 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 +93 -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 +2 -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 +44 -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 +2 -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 +2 -1
- package/dist/services/setting.service.js.map +1 -1
- package/dist/services/settings/default-settings-provider.service.d.ts +228 -12
- package/dist/services/settings/default-settings-provider.service.d.ts.map +1 -1
- package/dist/services/settings/default-settings-provider.service.js +129 -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 +22 -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/postman/mpin.postman_collection.json +1045 -0
- 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 +127 -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 +4 -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/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 +26 -12
- 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 +124 -5
- package/src/services/crud-helper.service.ts +35 -50
- package/src/services/crud.service.ts +131 -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 +3 -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 +67 -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 +3 -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 +3 -1
- package/src/services/settings/default-settings-provider.service.ts +140 -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 +33 -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
|
@@ -3,10 +3,13 @@ import { SubCommand, CommandRunner, Option } from 'nest-commander';
|
|
|
3
3
|
import * as path from 'path';
|
|
4
4
|
import { ModuleMetadataHelperService } from 'src/helpers/module-metadata-helper.service';
|
|
5
5
|
import { ConsoleReporter } from 'src/testing/reporter/console-reporter';
|
|
6
|
+
import { ProgressReporter } from 'src/testing/reporter/progress-reporter';
|
|
6
7
|
import { WebhookReporter } from 'src/testing/reporter/webhook-reporter';
|
|
7
8
|
import { runFromMetadata } from 'src/testing/runner/run-from-metadata';
|
|
8
9
|
import type { TestingMetadata } from 'src/testing/contracts/testing-metadata.types';
|
|
9
10
|
import { SpecRegistry } from 'src/testing/core/spec-registry';
|
|
11
|
+
import { SettingService } from 'src/services/setting.service';
|
|
12
|
+
import type { SolidCoreSetting } from 'src/services/settings/default-settings-provider.service';
|
|
10
13
|
|
|
11
14
|
interface TestRunCommandOptions {
|
|
12
15
|
module?: string;
|
|
@@ -18,11 +21,14 @@ interface TestRunCommandOptions {
|
|
|
18
21
|
apiBaseUrl?: string;
|
|
19
22
|
uiBaseUrl?: string;
|
|
20
23
|
headless?: boolean;
|
|
24
|
+
uiTimeoutMs?: number;
|
|
25
|
+
uiNavigationTimeoutMs?: number;
|
|
21
26
|
timeoutMs?: number;
|
|
22
27
|
retries?: number;
|
|
23
28
|
listSpecs?: boolean;
|
|
24
29
|
printApiLogs?: boolean;
|
|
25
30
|
runName?: string;
|
|
31
|
+
progress?: boolean;
|
|
26
32
|
}
|
|
27
33
|
|
|
28
34
|
@SubCommand({
|
|
@@ -34,6 +40,7 @@ export class TestRunCommand extends CommandRunner {
|
|
|
34
40
|
|
|
35
41
|
constructor(
|
|
36
42
|
private readonly moduleMetadataHelperService: ModuleMetadataHelperService,
|
|
43
|
+
private readonly settingService: SettingService,
|
|
37
44
|
) {
|
|
38
45
|
super();
|
|
39
46
|
}
|
|
@@ -89,13 +96,24 @@ export class TestRunCommand extends CommandRunner {
|
|
|
89
96
|
const apiBaseUrl = options?.apiBaseUrl ?? process.env.BASE_URL;
|
|
90
97
|
const uiBaseUrl = options?.uiBaseUrl ?? process.env.FRONTEND_BASE_URL;
|
|
91
98
|
const headless = options?.headless ?? true;
|
|
99
|
+
const uiTimeoutMs =
|
|
100
|
+
options?.uiTimeoutMs
|
|
101
|
+
?? toPositiveNumber(process.env.UI_TIMEOUT_MS)
|
|
102
|
+
?? toPositiveNumber(this.settingService.getConfigValue<SolidCoreSetting>('uiTestDefaultTimeoutMs'));
|
|
103
|
+
const uiNavigationTimeoutMs =
|
|
104
|
+
options?.uiNavigationTimeoutMs
|
|
105
|
+
?? toPositiveNumber(process.env.UI_NAVIGATION_TIMEOUT_MS)
|
|
106
|
+
?? toPositiveNumber(this.settingService.getConfigValue<SolidCoreSetting>('uiTestNavigationTimeoutMs'));
|
|
92
107
|
const printApiLogs = options?.printApiLogs ?? false;
|
|
93
108
|
|
|
94
109
|
const webhookUrl = process.env.SOLIDCTL_WEBHOOK_URL;
|
|
95
110
|
const runName = options?.runName ?? `run-${Date.now()}`;
|
|
96
|
-
const
|
|
111
|
+
const baseReporter = webhookUrl
|
|
97
112
|
? new WebhookReporter(webhookUrl, runName)
|
|
98
113
|
: new ConsoleReporter();
|
|
114
|
+
const reporter = options?.progress === false
|
|
115
|
+
? baseReporter
|
|
116
|
+
: new ProgressReporter(baseReporter);
|
|
99
117
|
|
|
100
118
|
try {
|
|
101
119
|
await runFromMetadata({
|
|
@@ -105,7 +123,12 @@ export class TestRunCommand extends CommandRunner {
|
|
|
105
123
|
skipScenarioIds,
|
|
106
124
|
reporter,
|
|
107
125
|
api: apiBaseUrl ? { baseUrl: apiBaseUrl } : undefined,
|
|
108
|
-
ui: {
|
|
126
|
+
ui: {
|
|
127
|
+
baseUrl: uiBaseUrl,
|
|
128
|
+
headless,
|
|
129
|
+
defaultTimeoutMs: uiTimeoutMs,
|
|
130
|
+
navigationTimeoutMs: uiNavigationTimeoutMs,
|
|
131
|
+
},
|
|
109
132
|
defaults: {
|
|
110
133
|
timeoutMs: options?.timeoutMs,
|
|
111
134
|
retries: options?.retries,
|
|
@@ -120,8 +143,8 @@ export class TestRunCommand extends CommandRunner {
|
|
|
120
143
|
console.error('Run tests command failed');
|
|
121
144
|
process.exitCode = 1;
|
|
122
145
|
} finally {
|
|
123
|
-
if (
|
|
124
|
-
await
|
|
146
|
+
if (baseReporter instanceof WebhookReporter) {
|
|
147
|
+
await baseReporter.flush(Number(process.exitCode ?? 0));
|
|
125
148
|
}
|
|
126
149
|
}
|
|
127
150
|
return;
|
|
@@ -225,6 +248,26 @@ export class TestRunCommand extends CommandRunner {
|
|
|
225
248
|
return val === 'false' ? false : true;
|
|
226
249
|
}
|
|
227
250
|
|
|
251
|
+
@Option({
|
|
252
|
+
flags: '--ui-timeout-ms [number]',
|
|
253
|
+
description:
|
|
254
|
+
'Default timeout in ms for UI steps (waits, clicks, fills). Defaults to process.env.UI_TIMEOUT_MS, then the uiTestDefaultTimeoutMs setting, then 30000.',
|
|
255
|
+
required: false,
|
|
256
|
+
})
|
|
257
|
+
parseUiTimeoutMs(val: string): number {
|
|
258
|
+
return Number(val);
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
@Option({
|
|
262
|
+
flags: '--ui-navigation-timeout-ms [number]',
|
|
263
|
+
description:
|
|
264
|
+
'Default timeout in ms for ui.goto navigation. Defaults to process.env.UI_NAVIGATION_TIMEOUT_MS, then the uiTestNavigationTimeoutMs setting, then --ui-timeout-ms.',
|
|
265
|
+
required: false,
|
|
266
|
+
})
|
|
267
|
+
parseUiNavigationTimeoutMs(val: string): number {
|
|
268
|
+
return Number(val);
|
|
269
|
+
}
|
|
270
|
+
|
|
228
271
|
@Option({
|
|
229
272
|
flags: '--timeout-ms [number]',
|
|
230
273
|
description: 'Default scenario timeout in milliseconds.',
|
|
@@ -251,6 +294,15 @@ export class TestRunCommand extends CommandRunner {
|
|
|
251
294
|
parseRunName(val: string): string {
|
|
252
295
|
return val;
|
|
253
296
|
}
|
|
297
|
+
|
|
298
|
+
@Option({
|
|
299
|
+
flags: '--no-progress',
|
|
300
|
+
description: 'Disable the interactive test progress footer.',
|
|
301
|
+
required: false,
|
|
302
|
+
})
|
|
303
|
+
parseNoProgress(): boolean {
|
|
304
|
+
return false;
|
|
305
|
+
}
|
|
254
306
|
}
|
|
255
307
|
|
|
256
308
|
function splitCsv(value?: string): string[] | undefined {
|
|
@@ -262,6 +314,14 @@ function splitCsv(value?: string): string[] | undefined {
|
|
|
262
314
|
return items.length ? items : undefined;
|
|
263
315
|
}
|
|
264
316
|
|
|
317
|
+
// Accepts unknown because settings come back already parsed as numbers, while env
|
|
318
|
+
// vars arrive as strings.
|
|
319
|
+
function toPositiveNumber(value?: unknown): number | undefined {
|
|
320
|
+
if (value === null || value === undefined || value === '') return undefined;
|
|
321
|
+
const parsed = Number(value);
|
|
322
|
+
return Number.isFinite(parsed) && parsed > 0 ? parsed : undefined;
|
|
323
|
+
}
|
|
324
|
+
|
|
265
325
|
function resolveSpecPath(entry: string, metadataPath: string): string {
|
|
266
326
|
if (path.isAbsolute(entry)) {
|
|
267
327
|
return entry;
|
|
@@ -7,6 +7,7 @@ interface SeedCommandOptions {
|
|
|
7
7
|
seeder?: string;
|
|
8
8
|
modulesToSeed?: string;
|
|
9
9
|
prune?: boolean;
|
|
10
|
+
skipHooks?: boolean;
|
|
10
11
|
}
|
|
11
12
|
|
|
12
13
|
@Command({ name: 'seed', description: 'Install seed data for a given module' })
|
|
@@ -28,6 +29,7 @@ export class SeedCommand extends CommandRunner {
|
|
|
28
29
|
modulesToSeed,
|
|
29
30
|
pruneMetadata: false,
|
|
30
31
|
seedGlobalMetadata: true,
|
|
32
|
+
skipHooks: false,
|
|
31
33
|
};
|
|
32
34
|
this.logger.log(`Modules to seed: ${modulesToSeed.join(', ')}`);
|
|
33
35
|
} else {
|
|
@@ -39,10 +41,22 @@ export class SeedCommand extends CommandRunner {
|
|
|
39
41
|
modulesToSeed: null,
|
|
40
42
|
pruneMetadata: false,
|
|
41
43
|
seedGlobalMetadata: true,
|
|
44
|
+
skipHooks: false,
|
|
42
45
|
};
|
|
43
46
|
parsedConf.pruneMetadata = true;
|
|
44
47
|
}
|
|
45
48
|
|
|
49
|
+
if (options?.skipHooks) {
|
|
50
|
+
parsedConf = parsedConf ?? {
|
|
51
|
+
modulesToSeed: null,
|
|
52
|
+
pruneMetadata: false,
|
|
53
|
+
seedGlobalMetadata: true,
|
|
54
|
+
skipHooks: false,
|
|
55
|
+
};
|
|
56
|
+
parsedConf.skipHooks = true;
|
|
57
|
+
this.logger.log('Skipping pre-seed and post-seed hooks.');
|
|
58
|
+
}
|
|
59
|
+
|
|
46
60
|
const seeder = this.solidRegistry
|
|
47
61
|
.getSeeders()
|
|
48
62
|
.filter((seeder) => seeder.name === options.seeder)
|
|
@@ -74,4 +88,9 @@ export class SeedCommand extends CommandRunner {
|
|
|
74
88
|
parsePrune(): boolean {
|
|
75
89
|
return true;
|
|
76
90
|
}
|
|
91
|
+
|
|
92
|
+
@Option({ flags: '--skip-hooks', description: 'Skip emitting pre-seed and post-seed lifecycle hooks/events.' })
|
|
93
|
+
parseSkipHooks(): boolean {
|
|
94
|
+
return true;
|
|
95
|
+
}
|
|
77
96
|
}
|
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
import { CacheModuleAsyncOptions } from '@nestjs/cache-manager';
|
|
2
2
|
import { ConfigModule, ConfigService } from '@nestjs/config';
|
|
3
|
-
|
|
3
|
+
// cache-manager-redis-yet, not cache-manager-redis-store. The latter stops at
|
|
4
|
+
// 3.0.1 and implements the cache-manager v4 store contract: it expects an
|
|
5
|
+
// options object and reads `options.ttl` in seconds. cache-manager v5 calls
|
|
6
|
+
// `store.set(key, value, ttl)` with a bare number of milliseconds, so that
|
|
7
|
+
// store found no `.ttl`, fell back to an unset default, and issued a plain
|
|
8
|
+
// `SET` - silently discarding every TTL passed anywhere in the app and leaving
|
|
9
|
+
// Redis keys that never expire. redis-yet implements the v5 contract and
|
|
10
|
+
// writes with `PX`, so millisecond TTLs land correctly.
|
|
11
|
+
import { redisStore } from 'cache-manager-redis-yet';
|
|
4
12
|
import { isRedisConfigured } from 'src/helpers/environment.helper';
|
|
5
13
|
|
|
6
14
|
export const CacheManagerOptions: CacheModuleAsyncOptions = {
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { USER_SUMMARY_FIELDS } from 'src/constants/user.constants';
|
|
2
|
+
|
|
1
3
|
export const CHATTER_MESSAGE_TYPE = {
|
|
2
4
|
AUDIT: 'audit',
|
|
3
5
|
CUSTOM: 'custom',
|
|
@@ -16,3 +18,13 @@ export const CHATTER_MESSAGE_STATUS = {
|
|
|
16
18
|
PENDING: 'pending',
|
|
17
19
|
COMPLETED: 'completed',
|
|
18
20
|
} as const;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Columns of the message author exposed by the chatter APIs.
|
|
24
|
+
*
|
|
25
|
+
* The chatter panel renders `fullName` (name label + initials avatar) and uses `id`
|
|
26
|
+
* for the own-note edit check; the admin list/form/tree views display `fullName` via
|
|
27
|
+
* each view's `coModelFieldToDisplay`. That is exactly the platform-wide summary
|
|
28
|
+
* shape, so this is an alias rather than a second list to keep in step.
|
|
29
|
+
*/
|
|
30
|
+
export const CHATTER_MESSAGE_USER_FIELDS = USER_SUMMARY_FIELDS;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
// The versioning columns CommonEntity adds for draft/publish support. These don't exist on
|
|
2
|
+
// legacy tables (see LegacyCommonEntityWithExistingId) and don't carry over when a new draft
|
|
3
|
+
// version is copied from its source entity, so both of those call sites share this list rather
|
|
4
|
+
// than each hand-enumerating the same four names.
|
|
5
|
+
export const DRAFT_PUBLISH_VERSIONING_FIELD_NAMES = ['isPublished', 'isLatest', 'initialEntityVersionId', 'publishedTracker'] as const;
|
|
@@ -127,6 +127,20 @@ export const ERROR_MESSAGES = {
|
|
|
127
127
|
|
|
128
128
|
DEFAULT_REGEX_PATTERN_NOT_MATCHING_ERROR_MSG: 'Invalid regex pattern.',
|
|
129
129
|
|
|
130
|
+
// MPIN errors.
|
|
131
|
+
// MPIN_INVALID is deliberately shared by "wrong MPIN" and "unknown handle",
|
|
132
|
+
// so a failed sign-in never reveals whether the credential handle was real.
|
|
133
|
+
// MPIN_REVOKED is separate and is returned for any attempt against a
|
|
134
|
+
// deactivated credential - it discloses nothing useful, since a dead
|
|
135
|
+
// credential grants no capability, and it lets the client stop retrying.
|
|
136
|
+
MPIN_INVALID: 'Invalid MPIN.',
|
|
137
|
+
MPIN_LOCKED: 'MPIN sign-in is temporarily locked due to repeated failed attempts.',
|
|
138
|
+
MPIN_REVOKED: 'MPIN sign-in has been disabled for this device. Please sign in normally.',
|
|
139
|
+
MPIN_NOT_ENABLED: 'MPIN sign-in is not enabled.',
|
|
140
|
+
MPIN_FORMAT_INVALID: 'MPIN does not meet the required format.',
|
|
141
|
+
MPIN_TOO_PREDICTABLE: 'MPIN is too easy to guess. Avoid repeated or sequential digits.',
|
|
142
|
+
MPIN_CREDENTIAL_NOT_FOUND: 'MPIN device credential not found.',
|
|
143
|
+
|
|
130
144
|
PERMISSION_MESSAGES: {
|
|
131
145
|
insertMany: (model?: string) =>
|
|
132
146
|
`You do not have permission to import ${model ?? 'these'} records.`,
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
export type MediaCategory = 'image' | 'audio' | 'video' | 'file' | 'pdf';
|
|
2
2
|
|
|
3
|
+
export const MEDIA_CATEGORIES = ['image', 'audio', 'video', 'file', 'pdf'] as const;
|
|
4
|
+
|
|
3
5
|
const IMAGE_EXTENSIONS = ['png', 'jpg', 'jpeg', 'webp', 'gif', 'bmp', 'tiff', 'heic', 'heif'];
|
|
4
6
|
const AUDIO_EXTENSIONS = ['mp3', 'wav', 'ogg', 'aac', 'm4a', 'flac', 'webm'];
|
|
5
7
|
const VIDEO_EXTENSIONS = ['mp4', 'mov', 'avi', 'mkv', 'mpeg', 'mpg', '3gp', '3g2', 'webm', 'ogg'];
|
|
@@ -17,6 +19,131 @@ export const DANGEROUS_EXTENSIONS = new Set([
|
|
|
17
19
|
'exe', 'sh', 'bat', 'cmd', 'ps1', 'jar', 'dll',
|
|
18
20
|
]);
|
|
19
21
|
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Mimetypes that are never safe to accept, regardless of extension. These render as active
|
|
25
|
+
* content in a browser (svg can carry <script>), so they are rejected even when the filename
|
|
26
|
+
* looks harmless. Kept alongside DANGEROUS_EXTENSIONS so upload paths check both.
|
|
27
|
+
*/
|
|
28
|
+
export const DANGEROUS_MIME_TYPES = new Set([
|
|
29
|
+
'image/svg+xml', 'text/html', 'application/xhtml+xml',
|
|
30
|
+
]);
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Percent-decodes a filename, repeating a bounded number of times so a double-encoded payload
|
|
34
|
+
* (`%252e` -> `%2e` -> `.`) survives a single pass through a proxy/framework that already
|
|
35
|
+
* decoded once. Malformed escape sequences are left as-is rather than thrown, since this runs
|
|
36
|
+
* on attacker-controlled input and a literal `%` in a filename (`100%done.pdf`) is legal.
|
|
37
|
+
*/
|
|
38
|
+
function decodePercentEncodingSafely(name: string): string {
|
|
39
|
+
let decoded = name;
|
|
40
|
+
for (let i = 0; i < 3; i++) {
|
|
41
|
+
let next: string;
|
|
42
|
+
try {
|
|
43
|
+
next = decodeURIComponent(decoded);
|
|
44
|
+
} catch {
|
|
45
|
+
return decoded;
|
|
46
|
+
}
|
|
47
|
+
if (next === decoded) {
|
|
48
|
+
return decoded;
|
|
49
|
+
}
|
|
50
|
+
decoded = next;
|
|
51
|
+
}
|
|
52
|
+
return decoded;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Reduces a client-supplied name to the name that will actually be resolved on disk, so
|
|
57
|
+
* extension checks can't be dodged by decorating it. Each step defends a known bypass:
|
|
58
|
+
*
|
|
59
|
+
* - `evil.exe%2e` -> percent-encoding a trailing dot (or anything else) hides the real
|
|
60
|
+
* extension from naive string matching; decode before inspecting it.
|
|
61
|
+
* - `../../evil.exe` -> only the final path segment is the file name.
|
|
62
|
+
* - `evil.exe\0.png` -> a NUL truncates the name at the syscall/filesystem layer, so
|
|
63
|
+
* anything after it is invisible to the OS but visible to naive
|
|
64
|
+
* validation.
|
|
65
|
+
* - `evil.exe::$DATA` -> NTFS alternate data stream suffix; the file on disk is evil.exe.
|
|
66
|
+
* - `evil.exe.` / `.exe ` -> Windows silently strips trailing dots and spaces when resolving
|
|
67
|
+
* a path, so these land on disk as evil.exe.
|
|
68
|
+
*/
|
|
69
|
+
export function normalizeUploadedFileName(fileName?: string | null): string {
|
|
70
|
+
if (!fileName) {
|
|
71
|
+
return '';
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
let name = decodePercentEncodingSafely(String(fileName));
|
|
75
|
+
name = name.split(/[/\\]/).pop() ?? '';
|
|
76
|
+
|
|
77
|
+
const nulIndex = name.indexOf('\0');
|
|
78
|
+
if (nulIndex >= 0) {
|
|
79
|
+
name = name.slice(0, nulIndex);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const streamIndex = name.indexOf(':');
|
|
83
|
+
if (streamIndex >= 0) {
|
|
84
|
+
name = name.slice(0, streamIndex);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return name.replace(/[\s.]+$/, '');
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* The effective extension - what the OS/browser will treat the file as. Used for media
|
|
92
|
+
* category resolution and inline-safety decisions. Always normalizes first, so
|
|
93
|
+
* `evil.exe.` resolves to `exe` rather than to nothing.
|
|
94
|
+
*/
|
|
95
|
+
export function getLowercaseFileExtension(fileName?: string | null): string | undefined {
|
|
96
|
+
const name = normalizeUploadedFileName(fileName);
|
|
97
|
+
|
|
98
|
+
const lastDotIndex = name.lastIndexOf('.');
|
|
99
|
+
if (lastDotIndex < 0 || lastDotIndex === name.length - 1) {
|
|
100
|
+
return undefined;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
return name.slice(lastDotIndex + 1).toLowerCase();
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Every dot-delimited segment after the stem, lowercased. The danger check uses this rather
|
|
108
|
+
* than only the effective extension so a dangerous type buried in a double extension
|
|
109
|
+
* (`evil.exe.png`, `shell.php.jpg`) is still caught - several servers and browsers resolve
|
|
110
|
+
* such names by an earlier segment than the last one.
|
|
111
|
+
*
|
|
112
|
+
* The stem is skipped so an innocuous file that merely starts with a keyword (`exe.png`)
|
|
113
|
+
* isn't rejected.
|
|
114
|
+
*/
|
|
115
|
+
export function getLowercaseFileExtensionSegments(fileName?: string | null): string[] {
|
|
116
|
+
const segments = normalizeUploadedFileName(fileName).toLowerCase().split('.');
|
|
117
|
+
return segments.slice(1).filter(segment => segment.length > 0);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/** Minimal shape of an uploaded file, so this module stays free of framework imports. */
|
|
121
|
+
export interface UploadedFileLike {
|
|
122
|
+
mimetype?: string;
|
|
123
|
+
originalname?: string;
|
|
124
|
+
filename?: string;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/** originalname is the client-supplied name; filename is multer's on-disk name. */
|
|
128
|
+
export function getUploadedFileName(file?: UploadedFileLike | null): string {
|
|
129
|
+
return file?.originalname ?? file?.filename ?? '';
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Single predicate for "must never be stored". Shared by every upload entry point
|
|
134
|
+
* (MediaFieldCrudManager, chatter attachments) so the rules can't drift between them.
|
|
135
|
+
* Extensions are checked before mimetype so a spoofed Content-Type (e.g.
|
|
136
|
+
* application/octet-stream, or image/png, on an .html file) can't bypass it.
|
|
137
|
+
*/
|
|
138
|
+
export function isDangerousMediaFile(file?: UploadedFileLike | null): boolean {
|
|
139
|
+
const segments = getLowercaseFileExtensionSegments(getUploadedFileName(file));
|
|
140
|
+
if (segments.some(segment => DANGEROUS_EXTENSIONS.has(segment))) {
|
|
141
|
+
return true;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
return DANGEROUS_MIME_TYPES.has((file?.mimetype || '').toLowerCase().trim());
|
|
145
|
+
}
|
|
146
|
+
|
|
20
147
|
/**
|
|
21
148
|
* Single source of truth for extension -> coarse media category. Shared by upload-time
|
|
22
149
|
* validation (MediaFieldCrudManager) and serve-time header hardening (ServeStaticModule), so
|
|
@@ -6,6 +6,11 @@ export const SUCCESS_MESSAGES = {
|
|
|
6
6
|
LOGOUT_SUCCESS: 'Logged out successfully',
|
|
7
7
|
USER_REGISTERED: 'User registered successfully.',
|
|
8
8
|
|
|
9
|
+
// MPIN messages
|
|
10
|
+
MPIN_SETUP_SUCCESS: 'MPIN set up successfully.',
|
|
11
|
+
MPIN_CHANGED_SUCCESS: 'MPIN changed successfully.',
|
|
12
|
+
MPIN_DEVICE_REVOKED: 'MPIN sign-in removed for this device.',
|
|
13
|
+
|
|
9
14
|
// CRUD service messages
|
|
10
15
|
RECORD_RECOVERED: 'Record successfully recovered',
|
|
11
16
|
SELECTED_RECORDS_RECOVERED: 'Selected records successfully recovered',
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The columns of a `User` that are safe to embed in another entity's API response.
|
|
3
|
+
*
|
|
4
|
+
* Whenever a user is attached to a record the caller asked for - a `createdBy` /
|
|
5
|
+
* `updatedBy` populate, a chatter message author - the caller wants to display who it
|
|
6
|
+
* was, not to read their profile. Everything else on `User` is PII (email, mobile),
|
|
7
|
+
* authz metadata (roles, apiKeys) or secret, and the embedded user is frequently
|
|
8
|
+
* someone the viewer has no other visibility of.
|
|
9
|
+
*
|
|
10
|
+
* `fullName` is nullable; consumers that need a fallback should use the record's own
|
|
11
|
+
* context rather than widening this list.
|
|
12
|
+
*/
|
|
13
|
+
export const USER_SUMMARY_FIELDS = ['id', 'fullName'] as const;
|
|
@@ -107,8 +107,11 @@ export class AuthenticationController {
|
|
|
107
107
|
@Post('logout')
|
|
108
108
|
@Public()
|
|
109
109
|
@HttpCode(HttpStatus.OK)
|
|
110
|
-
async logout(
|
|
111
|
-
|
|
110
|
+
async logout(
|
|
111
|
+
@Body('refreshToken') refreshToken: string,
|
|
112
|
+
@Body('allDevices') allDevices?: boolean,
|
|
113
|
+
) {
|
|
114
|
+
return this.authService.logout(refreshToken, allDevices === true);
|
|
112
115
|
}
|
|
113
116
|
|
|
114
117
|
@ApiBearerAuth("jwt")
|
|
@@ -95,6 +95,14 @@ export class ChatterMessageController {
|
|
|
95
95
|
return this.service.find(query);
|
|
96
96
|
}
|
|
97
97
|
|
|
98
|
+
@ApiBearerAuth("jwt")
|
|
99
|
+
@ApiQuery({ name: 'search', required: false, type: String })
|
|
100
|
+
@ApiQuery({ name: 'limit', required: false, type: Number })
|
|
101
|
+
@Get('mentionable-users')
|
|
102
|
+
async getMentionableUsers(@Query() query: any) {
|
|
103
|
+
return this.service.getMentionableUsers(query?.search, query?.limit ? +query.limit : undefined);
|
|
104
|
+
}
|
|
105
|
+
|
|
98
106
|
@ApiBearerAuth("jwt")
|
|
99
107
|
@Get(':id')
|
|
100
108
|
async findOne(@Param('id') id: string, @Query() query: any) {
|
|
@@ -8,6 +8,7 @@ import { Response } from 'express';
|
|
|
8
8
|
import { StartExportSyncDto } from 'src/dtos/export.dto';
|
|
9
9
|
import { ActiveUser } from 'src/decorators/active-user.decorator';
|
|
10
10
|
import { ActiveUserData } from 'src/interfaces/active-user-data.interface';
|
|
11
|
+
import { setFileDownloadHeaders } from 'src/helpers/file-download.helper';
|
|
11
12
|
|
|
12
13
|
@ApiTags('Solid Core')
|
|
13
14
|
@Controller('export-template') //FIXME: Change this to the model plural name
|
|
@@ -91,9 +92,10 @@ export class ExportTemplateController {
|
|
|
91
92
|
throw new InternalServerErrorException("Export stream is null");
|
|
92
93
|
}
|
|
93
94
|
// ✅ Set response headers for streaming
|
|
94
|
-
res
|
|
95
|
-
|
|
96
|
-
|
|
95
|
+
setFileDownloadHeaders(res, {
|
|
96
|
+
fileName: exportFileInfo.fileName,
|
|
97
|
+
mimeType: exportFileInfo.mimeType,
|
|
98
|
+
});
|
|
97
99
|
// Pipe the strea to the response as an excel file
|
|
98
100
|
exportFileInfo.exportStream.pipe(res);
|
|
99
101
|
}
|
|
@@ -7,6 +7,7 @@ import { UpdateImportTransactionDto } from '../dtos/update-import-transaction.dt
|
|
|
7
7
|
import { Response } from 'express';
|
|
8
8
|
import { ActiveUser } from 'src/decorators/active-user.decorator';
|
|
9
9
|
import { ActiveUserData } from 'src/interfaces/active-user-data.interface';
|
|
10
|
+
import { setFileDownloadHeaders } from 'src/helpers/file-download.helper';
|
|
10
11
|
|
|
11
12
|
enum ShowSoftDeleted {
|
|
12
13
|
INCLUSIVE = "inclusive",
|
|
@@ -27,9 +28,10 @@ export class ImportTransactionController {
|
|
|
27
28
|
}
|
|
28
29
|
|
|
29
30
|
// ✅ Set response headers for streaming
|
|
30
|
-
res
|
|
31
|
-
|
|
32
|
-
|
|
31
|
+
setFileDownloadHeaders(res, {
|
|
32
|
+
fileName: importTemplateFileInfo.fileName,
|
|
33
|
+
mimeType: importTemplateFileInfo.mimeType,
|
|
34
|
+
});
|
|
33
35
|
// Pipe the stream to the response as an excel file
|
|
34
36
|
importTemplateFileInfo.stream.pipe(res);
|
|
35
37
|
}
|
|
@@ -117,9 +119,7 @@ export class ImportTransactionController {
|
|
|
117
119
|
throw new InternalServerErrorException("Failed records stream is null");
|
|
118
120
|
}
|
|
119
121
|
// ✅ Set response headers for streaming
|
|
120
|
-
res
|
|
121
|
-
res.setHeader('Content-Type', mimeType);
|
|
122
|
-
res.setHeader('Access-Control-Expose-Headers', 'Content-Disposition, Content-Type');
|
|
122
|
+
setFileDownloadHeaders(res, { fileName, mimeType });
|
|
123
123
|
// Pipe the strea to the response as an excel file
|
|
124
124
|
stream.pipe(res);
|
|
125
125
|
}
|
|
@@ -9,6 +9,8 @@ import { SolidRequestContextDto } from 'src/dtos/solid-request-context.dto';
|
|
|
9
9
|
import { UpdateMediaDto } from 'src/dtos/update-media.dto';
|
|
10
10
|
import { MediaService } from 'src/services/media.service';
|
|
11
11
|
import { Response } from 'express';
|
|
12
|
+
import { getLowercaseFileExtension, INLINE_SAFE_EXTENSIONS } from 'src/constants/media-file-types';
|
|
13
|
+
import { setFileDownloadHeaders } from 'src/helpers/file-download.helper';
|
|
12
14
|
|
|
13
15
|
enum ShowSoftDeleted {
|
|
14
16
|
INCLUSIVE = "inclusive",
|
|
@@ -91,17 +93,26 @@ export class MediaController {
|
|
|
91
93
|
|
|
92
94
|
@Auth(AuthType.MediaSignedUrl)
|
|
93
95
|
@ApiQuery({ name: 'token', required: true, type: String, description: "Short-lived signed token obtained from a private Media record's URL - not entered manually." })
|
|
94
|
-
@ApiQuery({ name: 'disposition', required: false, enum: ['inline', 'attachment'], description: "'inline' (default) renders/previews in the browser, matching public media. Pass 'attachment' to force a browser download (e.g. from a download button)." })
|
|
96
|
+
@ApiQuery({ name: 'disposition', required: false, enum: ['inline', 'attachment'], description: "'inline' (default) renders/previews in the browser, matching public media - it applies only to types safe to render inline (images, audio, video, pdf); anything else is always downloaded. Pass 'attachment' to force a browser download (e.g. from a download button)." })
|
|
95
97
|
@Get(':id/download')
|
|
96
98
|
async download(@Param('id') id: string, @Query('disposition') disposition: string, @Res() res: Response, @SolidRequestContextDecorator() solidRequestContext: SolidRequestContextDto) {
|
|
97
99
|
const media = await this.service.findOne(+id, {}, solidRequestContext);
|
|
98
100
|
const { stream, fileName, mimeType } = await this.service.fileDownloadStream(media);
|
|
99
101
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
102
|
+
// Mirror the static-serve hardening in SolidCoreModule: only a small allowlist of media
|
|
103
|
+
// types is ever safe to render inline. Anything else is forced to download rather than be
|
|
104
|
+
// displayed/executed, regardless of the mimetype the record was stored with - nosniff
|
|
105
|
+
// alone would not help here, since it faithfully honours a declared text/html.
|
|
106
|
+
const isInlineSafe = INLINE_SAFE_EXTENSIONS.has(getLowercaseFileExtension(fileName) ?? '');
|
|
107
|
+
const requestedInline = disposition !== 'attachment';
|
|
108
|
+
|
|
109
|
+
setFileDownloadHeaders(res, {
|
|
110
|
+
fileName,
|
|
111
|
+
mimeType: isInlineSafe ? mimeType : 'application/octet-stream',
|
|
112
|
+
disposition: requestedInline && isInlineSafe ? 'inline' : 'attachment',
|
|
113
|
+
crossOriginResourcePolicy: true,
|
|
114
|
+
});
|
|
115
|
+
|
|
105
116
|
stream.pipe(res);
|
|
106
117
|
}
|
|
107
118
|
|
|
@@ -13,6 +13,7 @@ import { ApiBearerAuth, ApiTags } from '@nestjs/swagger';
|
|
|
13
13
|
import { Response } from 'express';
|
|
14
14
|
import { ConfirmModulePackageImportDto } from 'src/dtos/confirm-module-package-import.dto';
|
|
15
15
|
import { RunModulePackageBuildDto } from 'src/dtos/run-module-package-build.dto';
|
|
16
|
+
import { setFileDownloadHeaders } from 'src/helpers/file-download.helper';
|
|
16
17
|
import { RunModulePackageSeedDto } from 'src/dtos/run-module-package-seed.dto';
|
|
17
18
|
import { ModulePackageService } from 'src/services/module-package.service';
|
|
18
19
|
|
|
@@ -39,9 +40,7 @@ export class ModulePackageController {
|
|
|
39
40
|
@Res() res: Response,
|
|
40
41
|
) {
|
|
41
42
|
const archive = await this.modulePackageService.exportModulePackage(moduleName);
|
|
42
|
-
res.
|
|
43
|
-
res.setHeader('Content-Type', archive.mimeType);
|
|
44
|
-
res.setHeader('Access-Control-Expose-Headers', 'Content-Disposition, Content-Type');
|
|
43
|
+
setFileDownloadHeaders(res, { fileName: archive.fileName, mimeType: archive.mimeType });
|
|
45
44
|
res.sendFile(archive.filePath);
|
|
46
45
|
}
|
|
47
46
|
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { Body, Controller, Delete, Get, HttpCode, HttpStatus, Param, ParseIntPipe, Post } from '@nestjs/common';
|
|
2
|
+
import { ApiBearerAuth, ApiTags } from '@nestjs/swagger';
|
|
3
|
+
import { ActiveUser } from '../decorators/active-user.decorator';
|
|
4
|
+
import { Public } from '../decorators/public.decorator';
|
|
5
|
+
import { ChangeMpinDto } from '../dtos/change-mpin.dto';
|
|
6
|
+
import { MpinLoginDto } from '../dtos/mpin-login.dto';
|
|
7
|
+
import { SetupMpinDto } from '../dtos/setup-mpin.dto';
|
|
8
|
+
import { ActiveUserData } from '../interfaces/active-user-data.interface';
|
|
9
|
+
import { MpinService } from '../services/mpin.service';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* There is deliberately no public "is MPIN set up for this identifier" route.
|
|
13
|
+
* That would reintroduce exactly the user-enumeration oracle the opaque
|
|
14
|
+
* credential handle removes. The client decides whether to show the MPIN
|
|
15
|
+
* screen from the presence of its own stored handle.
|
|
16
|
+
*/
|
|
17
|
+
@Controller('iam/mpin')
|
|
18
|
+
@ApiTags('Solid Core')
|
|
19
|
+
export class MpinAuthenticationController {
|
|
20
|
+
constructor(private readonly mpinService: MpinService) { }
|
|
21
|
+
|
|
22
|
+
@ApiBearerAuth('jwt')
|
|
23
|
+
@Post('setup')
|
|
24
|
+
@HttpCode(HttpStatus.OK)
|
|
25
|
+
setup(
|
|
26
|
+
@Body() setupMpinDto: SetupMpinDto,
|
|
27
|
+
@ActiveUser() activeUser: ActiveUserData,
|
|
28
|
+
) {
|
|
29
|
+
return this.mpinService.setupMpin(activeUser, setupMpinDto);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
@ApiBearerAuth('jwt')
|
|
33
|
+
@Post('change')
|
|
34
|
+
@HttpCode(HttpStatus.OK)
|
|
35
|
+
change(
|
|
36
|
+
@Body() changeMpinDto: ChangeMpinDto,
|
|
37
|
+
@ActiveUser() activeUser: ActiveUserData,
|
|
38
|
+
) {
|
|
39
|
+
return this.mpinService.changeMpin(activeUser, changeMpinDto);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Public by necessity - the caller has no session yet. The credential
|
|
43
|
+
// handle is unguessable, so this carries no enumeration surface.
|
|
44
|
+
@Public()
|
|
45
|
+
@Post('login')
|
|
46
|
+
@HttpCode(HttpStatus.OK)
|
|
47
|
+
login(@Body() mpinLoginDto: MpinLoginDto) {
|
|
48
|
+
return this.mpinService.loginWithMpin(mpinLoginDto);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
@ApiBearerAuth('jwt')
|
|
52
|
+
@Get('devices')
|
|
53
|
+
listDevices(@ActiveUser() activeUser: ActiveUserData) {
|
|
54
|
+
return this.mpinService.listDevices(activeUser);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// By row id, never by credential handle, so the management UI never has to
|
|
58
|
+
// hold the secret.
|
|
59
|
+
@ApiBearerAuth('jwt')
|
|
60
|
+
@Delete('devices/:id')
|
|
61
|
+
revokeDevice(
|
|
62
|
+
@Param('id', ParseIntPipe) id: number,
|
|
63
|
+
@ActiveUser() activeUser: ActiveUserData,
|
|
64
|
+
) {
|
|
65
|
+
return this.mpinService.revokeDevice(activeUser, id);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
@@ -60,10 +60,6 @@ export class BasicFilterDto extends PaginationQueryDto {
|
|
|
60
60
|
@ApiProperty({ description: "locale" })
|
|
61
61
|
readonly locale?: string;
|
|
62
62
|
|
|
63
|
-
@IsOptional()
|
|
64
|
-
@ApiProperty({ description: "status publish draft" })
|
|
65
|
-
readonly status?: string;
|
|
66
|
-
|
|
67
63
|
// @IsOptional()
|
|
68
64
|
// @ApiProperty({ description: "default locale id" })
|
|
69
65
|
// readonly defaultEntityLocaleId?: number;
|