@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
|
@@ -5,8 +5,10 @@ import { InjectEntityManager } from '@nestjs/typeorm';
|
|
|
5
5
|
import { Brackets, EntityManager, EntityMetadata, In } from 'typeorm';
|
|
6
6
|
|
|
7
7
|
import { classify } from '@angular-devkit/core/src/utils/strings';
|
|
8
|
-
import { CHATTER_MESSAGE_STATUS, CHATTER_MESSAGE_SUBTYPE, CHATTER_MESSAGE_TYPE } from 'src/constants/chatter-message.constants';
|
|
8
|
+
import { CHATTER_MESSAGE_STATUS, CHATTER_MESSAGE_SUBTYPE, CHATTER_MESSAGE_TYPE, CHATTER_MESSAGE_USER_FIELDS } from 'src/constants/chatter-message.constants';
|
|
9
|
+
import { isDangerousMediaFile } from 'src/constants/media-file-types';
|
|
9
10
|
import { ERROR_MESSAGES } from 'src/constants/error-messages';
|
|
11
|
+
import { MediaFieldCrudManager, SolidMediaType } from 'src/helpers/field-crud-managers/MediaFieldCrudManager';
|
|
10
12
|
import { PostChatterMessageDto } from 'src/dtos/post-chatter-message.dto';
|
|
11
13
|
import { UpdateChatterNoteMessageDto } from 'src/dtos/update-chatter-note-message.dto';
|
|
12
14
|
import { ModelMetadataHelperService } from 'src/helpers/model-metadata-helper.service';
|
|
@@ -18,9 +20,11 @@ import { FieldMetadataRepository } from 'src/repository/field-metadata.repositor
|
|
|
18
20
|
import { MediaRepository } from 'src/repository/media.repository';
|
|
19
21
|
import { ModelMetadataRepository } from 'src/repository/model-metadata.repository';
|
|
20
22
|
import { CRUDService } from 'src/services/crud.service';
|
|
23
|
+
import { BasicFilterDto } from '../dtos/basic-filters.dto';
|
|
21
24
|
import { MediaStorageProviderType } from '../dtos/create-media-storage-provider-metadata.dto';
|
|
22
25
|
import { ChatterMessageDetails } from '../entities/chatter-message-details.entity';
|
|
23
26
|
import { ChatterMessage } from '../entities/chatter-message.entity';
|
|
27
|
+
import { User } from '../entities/user.entity';
|
|
24
28
|
import { getMediaStorageProvider } from './mediaStorageProviders';
|
|
25
29
|
import { RequestContextService } from './request-context.service';
|
|
26
30
|
import { Logger } from '@nestjs/common';
|
|
@@ -34,6 +38,16 @@ interface ChatterMention {
|
|
|
34
38
|
id?: string | number;
|
|
35
39
|
}
|
|
36
40
|
|
|
41
|
+
/**
|
|
42
|
+
* Server-side-only overrides for `postMessage`. Not part of `PostChatterMessageDto`, so
|
|
43
|
+
* nothing here is settable over HTTP - only in-process callers such as migration or
|
|
44
|
+
* back-fill services can supply it.
|
|
45
|
+
*/
|
|
46
|
+
export interface PostChatterMessageOptions {
|
|
47
|
+
/** Backdate the message instead of stamping it with the current time. */
|
|
48
|
+
createdAt?: Date;
|
|
49
|
+
}
|
|
50
|
+
|
|
37
51
|
@Injectable()
|
|
38
52
|
export class ChatterMessageService extends CRUDService<ChatterMessage> {
|
|
39
53
|
private readonly _logger = new Logger(ChatterMessageService.name);
|
|
@@ -101,6 +115,44 @@ export class ChatterMessageService extends CRUDService<ChatterMessage> {
|
|
|
101
115
|
chatterMessage.updatedBy = resolvedUserId;
|
|
102
116
|
}
|
|
103
117
|
|
|
118
|
+
/**
|
|
119
|
+
* Reduce a message's hydrated `user` relation to CHATTER_MESSAGE_USER_FIELDS.
|
|
120
|
+
*
|
|
121
|
+
* `getChatterMessages` restricts the columns in the query itself, which is preferable.
|
|
122
|
+
* The generic CRUD paths below build their query from find-options and hand `populate`
|
|
123
|
+
* straight to TypeORM, so they are trimmed after the fact instead. (`createdBy` /
|
|
124
|
+
* `updatedBy` need nothing here - CRUDService.handlePopulateUserIdFields already selects
|
|
125
|
+
* only USER_SUMMARY_FIELDS when a caller populates them.)
|
|
126
|
+
*/
|
|
127
|
+
private trimMessageUser<M extends ChatterMessage>(message: M): M {
|
|
128
|
+
if (message?.user) {
|
|
129
|
+
message.user = this.toUserSummary(message.user) as User;
|
|
130
|
+
}
|
|
131
|
+
return message;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
private trimMessageUsers(messages: ChatterMessage[] | undefined) {
|
|
135
|
+
messages?.forEach(message => this.trimMessageUser(message));
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* `GET /chatter-message?populate[]=user` would otherwise be a way around the column
|
|
140
|
+
* allowlist applied by getChatterMessages.
|
|
141
|
+
*/
|
|
142
|
+
async find(basicFilterDto: BasicFilterDto, solidRequestContext: any = {}): Promise<any> {
|
|
143
|
+
const result = await super.find(basicFilterDto, solidRequestContext);
|
|
144
|
+
this.trimMessageUsers(result?.records);
|
|
145
|
+
// A grouped find (populateGroup) nests its entities one level deeper.
|
|
146
|
+
for (const groupRecord of result?.groupRecords ?? []) {
|
|
147
|
+
this.trimMessageUsers(groupRecord?.groupData?.records);
|
|
148
|
+
}
|
|
149
|
+
return result;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
async findOne(id: number, query: any = {}, solidRequestContext: any = {}) {
|
|
153
|
+
return this.trimMessageUser(await super.findOne(id, query, solidRequestContext));
|
|
154
|
+
}
|
|
155
|
+
|
|
104
156
|
private isEditableCustomNoteMessage(message: ChatterMessage): boolean {
|
|
105
157
|
if (message.messageType !== CHATTER_MESSAGE_TYPE.CUSTOM) {
|
|
106
158
|
return false;
|
|
@@ -134,6 +186,45 @@ export class ChatterMessageService extends CRUDService<ChatterMessage> {
|
|
|
134
186
|
}, messageBody || '');
|
|
135
187
|
}
|
|
136
188
|
|
|
189
|
+
/**
|
|
190
|
+
* Chatter attachments bypass MediaFieldCrudManager - they go straight to
|
|
191
|
+
* storageProvider.store() - so the shared predicate is applied here directly. The rules
|
|
192
|
+
* themselves live in media-file-types so upload paths can't drift apart.
|
|
193
|
+
*/
|
|
194
|
+
private validateChatterMediaFiles(files: Express.Multer.File[] = []) {
|
|
195
|
+
if (Array.isArray(files) && files.some(file => isDangerousMediaFile(file))) {
|
|
196
|
+
throw new BadRequestException('Dangerous file types are not allowed in chatter attachments.');
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* Validates newly-uploaded attachments against each declared media field's real config
|
|
202
|
+
* (mediaTypes/mediaMaxSizeKb/mediaAllowedExtensions), grouped by fieldname - the same rules
|
|
203
|
+
* MediaFieldCrudManager already enforces everywhere else. Shared between postMessage and
|
|
204
|
+
* updateCustomNoteMessage so the two entry points can't drift apart; isUpdate is the only
|
|
205
|
+
* thing that differs between them.
|
|
206
|
+
*/
|
|
207
|
+
private validateChatterAttachmentsForFields(files: Express.Multer.File[], mediaFields: any[], isUpdate: boolean): void {
|
|
208
|
+
for (const mediaField of mediaFields) {
|
|
209
|
+
const media = files.filter(multerFile => multerFile.fieldname === mediaField.name);
|
|
210
|
+
if (media.length === 0) continue;
|
|
211
|
+
|
|
212
|
+
const validator = new MediaFieldCrudManager({
|
|
213
|
+
type: mediaField.type as SolidMediaType,
|
|
214
|
+
required: mediaField.required,
|
|
215
|
+
fieldName: mediaField.name,
|
|
216
|
+
mediaMaxSizeKb: mediaField.mediaMaxSizeKb,
|
|
217
|
+
mediaTypes: mediaField.mediaTypes,
|
|
218
|
+
mediaAllowedExtensions: mediaField.mediaAllowedExtensions,
|
|
219
|
+
isUpdate,
|
|
220
|
+
});
|
|
221
|
+
const validationErrors = validator.validate({}, media);
|
|
222
|
+
if (validationErrors.length > 0) {
|
|
223
|
+
throw new BadRequestException(validationErrors.map(error => error.error).join(', '));
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
|
|
137
228
|
private async publishChatterMentionNotifications(message: ChatterMessage, model: any) {
|
|
138
229
|
if (message.messageType !== CHATTER_MESSAGE_TYPE.CUSTOM || message.messageSubType !== CHATTER_MESSAGE_SUBTYPE.NOTE) {
|
|
139
230
|
return;
|
|
@@ -188,6 +279,31 @@ export class ChatterMessageService extends CRUDService<ChatterMessage> {
|
|
|
188
279
|
}
|
|
189
280
|
}
|
|
190
281
|
|
|
282
|
+
// Deliberately bypasses UserRepository's security-rule filtering: the mention picker
|
|
283
|
+
// needs id/username/fullName for any active user regardless of the caller's row-level
|
|
284
|
+
// access to the User model, same as the getChatterMessages one-to-many lookup below.
|
|
285
|
+
async getMentionableUsers(search?: string, limit: number = 8): Promise<Array<{ id: number; username: string; fullName: string }>> {
|
|
286
|
+
const normalizedLimit = Number.isInteger(limit) && limit > 0 && limit <= 50 ? limit : 8;
|
|
287
|
+
const userRepository = this.entityManager.getRepository(User);
|
|
288
|
+
|
|
289
|
+
const qb = userRepository
|
|
290
|
+
.createQueryBuilder('user')
|
|
291
|
+
.select(['user.id', 'user.username', 'user.fullName'])
|
|
292
|
+
.where('user.active = :active', { active: true });
|
|
293
|
+
|
|
294
|
+
const trimmedSearch = (search ?? '').trim();
|
|
295
|
+
if (trimmedSearch) {
|
|
296
|
+
qb.andWhere('(LOWER(user.username) LIKE :search OR LOWER(user.fullName) LIKE :search)', {
|
|
297
|
+
search: `%${trimmedSearch.toLowerCase()}%`,
|
|
298
|
+
});
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
qb.orderBy('user.username', 'ASC').take(normalizedLimit);
|
|
302
|
+
|
|
303
|
+
const users = await qb.getMany();
|
|
304
|
+
return users.map(user => ({ id: user.id, username: user.username, fullName: user.fullName }));
|
|
305
|
+
}
|
|
306
|
+
|
|
191
307
|
async markCompleted(id: number) {
|
|
192
308
|
const activeUser = this.requestContextService.getActiveUser();
|
|
193
309
|
if (!activeUser) {
|
|
@@ -240,6 +356,26 @@ export class ChatterMessageService extends CRUDService<ChatterMessage> {
|
|
|
240
356
|
throw new BadRequestException('Message body cannot be empty.');
|
|
241
357
|
}
|
|
242
358
|
|
|
359
|
+
this.validateChatterMediaFiles(files);
|
|
360
|
+
|
|
361
|
+
let chatterModel: any = null;
|
|
362
|
+
let mediaFields: any[] = [];
|
|
363
|
+
if (removeAttachmentIds.length > 0 || hasNewFiles) {
|
|
364
|
+
chatterModel = await this.modelMetadataService.findOneBySingularName('chatterMessage', {
|
|
365
|
+
fields: {
|
|
366
|
+
model: true,
|
|
367
|
+
mediaStorageProvider: true,
|
|
368
|
+
},
|
|
369
|
+
module: true,
|
|
370
|
+
});
|
|
371
|
+
|
|
372
|
+
mediaFields = chatterModel.fields.filter(field => field.type === 'mediaSingle' || field.type === 'mediaMultiple');
|
|
373
|
+
|
|
374
|
+
if (hasNewFiles) {
|
|
375
|
+
this.validateChatterAttachmentsForFields(files, mediaFields, true);
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
|
|
243
379
|
if (hasMessageBody) {
|
|
244
380
|
message.messageBody = trimmedMessageBody;
|
|
245
381
|
}
|
|
@@ -256,15 +392,6 @@ export class ChatterMessageService extends CRUDService<ChatterMessage> {
|
|
|
256
392
|
const savedMessage = await this.repo.save(message);
|
|
257
393
|
|
|
258
394
|
if (removeAttachmentIds.length > 0 || hasNewFiles) {
|
|
259
|
-
const model = await this.modelMetadataService.findOneBySingularName('chatterMessage', {
|
|
260
|
-
fields: {
|
|
261
|
-
model: true,
|
|
262
|
-
mediaStorageProvider: true,
|
|
263
|
-
},
|
|
264
|
-
module: true,
|
|
265
|
-
});
|
|
266
|
-
|
|
267
|
-
const mediaFields = model.fields.filter(field => field.type === 'mediaSingle' || field.type === 'mediaMultiple');
|
|
268
395
|
const attachmentFieldIds = mediaFields.map(field => field.id);
|
|
269
396
|
|
|
270
397
|
if (removeAttachmentIds.length > 0 && attachmentFieldIds.length > 0) {
|
|
@@ -272,7 +399,7 @@ export class ChatterMessageService extends CRUDService<ChatterMessage> {
|
|
|
272
399
|
where: {
|
|
273
400
|
id: In(removeAttachmentIds),
|
|
274
401
|
entityId: savedMessage.id,
|
|
275
|
-
modelMetadata: { id:
|
|
402
|
+
modelMetadata: { id: chatterModel.id },
|
|
276
403
|
fieldMetadata: { id: In(attachmentFieldIds) },
|
|
277
404
|
},
|
|
278
405
|
relations: {
|
|
@@ -306,13 +433,23 @@ export class ChatterMessageService extends CRUDService<ChatterMessage> {
|
|
|
306
433
|
|
|
307
434
|
await this.publishChatterMentionNotifications(savedMessage, model);
|
|
308
435
|
|
|
309
|
-
return
|
|
436
|
+
// The `user` relation was loaded for the ownership check above; don't return all of it.
|
|
437
|
+
return this.trimMessageUser(savedMessage);
|
|
310
438
|
}
|
|
311
439
|
|
|
312
|
-
|
|
440
|
+
/**
|
|
441
|
+
* Post a chatter message.
|
|
442
|
+
*
|
|
443
|
+
* `options` is deliberately kept out of `PostChatterMessageDto` so it can only be supplied
|
|
444
|
+
* by server-side callers (migrations, back-fills). The controller binds the DTO alone, so
|
|
445
|
+
* an API client has no way to backdate a message.
|
|
446
|
+
*/
|
|
447
|
+
async postMessage(postDto: PostChatterMessageDto, files: Express.Multer.File[] = [], options: PostChatterMessageOptions = {}) {
|
|
313
448
|
const coModelName = lowerFirst(postDto.coModelName);
|
|
314
449
|
await this.assertRecordAccess(coModelName, postDto.coModelEntityId);
|
|
315
450
|
|
|
451
|
+
this.validateChatterMediaFiles(files);
|
|
452
|
+
|
|
316
453
|
const chatterMessage = new ChatterMessage();
|
|
317
454
|
chatterMessage.messageType = CHATTER_MESSAGE_TYPE.CUSTOM;
|
|
318
455
|
chatterMessage.messageSubType = postDto.messageSubType || CHATTER_MESSAGE_SUBTYPE.CUSTOM;
|
|
@@ -322,6 +459,10 @@ export class ChatterMessageService extends CRUDService<ChatterMessage> {
|
|
|
322
459
|
chatterMessage.coModelEntityId = postDto.coModelEntityId;
|
|
323
460
|
chatterMessage.coModelName = coModelName;
|
|
324
461
|
chatterMessage.modelUserKey = postDto.modelUserKey ?? null;
|
|
462
|
+
// Left unset otherwise, so the @CreateDateColumn default still applies.
|
|
463
|
+
if (options.createdAt) {
|
|
464
|
+
chatterMessage.createdAt = options.createdAt;
|
|
465
|
+
}
|
|
325
466
|
|
|
326
467
|
const model = await this.modelMetadataRepo.findOne({
|
|
327
468
|
where: { singularName: coModelName },
|
|
@@ -331,10 +472,9 @@ export class ChatterMessageService extends CRUDService<ChatterMessage> {
|
|
|
331
472
|
|
|
332
473
|
this.stampMessageAuditFields(chatterMessage);
|
|
333
474
|
|
|
334
|
-
|
|
335
|
-
|
|
475
|
+
let mediaFields: any[] = [];
|
|
336
476
|
if (files && files.length > 0) {
|
|
337
|
-
const
|
|
477
|
+
const chatterModel = await this.modelMetadataService.findOneBySingularName('chatterMessage', {
|
|
338
478
|
fields: {
|
|
339
479
|
model: true,
|
|
340
480
|
mediaStorageProvider: true,
|
|
@@ -342,8 +482,13 @@ export class ChatterMessageService extends CRUDService<ChatterMessage> {
|
|
|
342
482
|
module: true,
|
|
343
483
|
});
|
|
344
484
|
|
|
345
|
-
|
|
485
|
+
mediaFields = chatterModel.fields.filter(field => field.type === 'mediaSingle' || field.type === 'mediaMultiple');
|
|
486
|
+
this.validateChatterAttachmentsForFields(files, mediaFields, false);
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
const savedMessage = await this.repo.save(chatterMessage);
|
|
346
490
|
|
|
491
|
+
if (files && files.length > 0) {
|
|
347
492
|
for (const mediaField of mediaFields) {
|
|
348
493
|
const media = files.filter(multerFile => multerFile.fieldname === mediaField.name);
|
|
349
494
|
if (media.length > 0) {
|
|
@@ -891,16 +1036,25 @@ export class ChatterMessageService extends CRUDService<ChatterMessage> {
|
|
|
891
1036
|
qb.where(orConditions.join(' OR '), parameters);
|
|
892
1037
|
}));
|
|
893
1038
|
|
|
894
|
-
const relations = ['chatterMessageDetails'
|
|
1039
|
+
const relations = ['chatterMessageDetails'];
|
|
895
1040
|
if (populate && populate.length > 0) {
|
|
896
1041
|
const normalizedPopulate = this.crudHelperService.normalize(populate);
|
|
897
|
-
|
|
1042
|
+
// SECURITY: 'user' is joined below with an explicit column allowlist. A client-supplied
|
|
1043
|
+
// populate[]=user must not be able to turn it back into a full-entity join (the chatter
|
|
1044
|
+
// panel does send exactly that).
|
|
1045
|
+
relations.push(...normalizedPopulate.filter(rel => rel !== 'user' && !relations.includes(rel)));
|
|
898
1046
|
}
|
|
899
1047
|
|
|
900
1048
|
relations.forEach(relation => {
|
|
901
1049
|
qb.leftJoinAndSelect(`entity.${relation}`, relation);
|
|
902
1050
|
});
|
|
903
1051
|
|
|
1052
|
+
// Only the author's id and display name leave this endpoint - see CHATTER_MESSAGE_USER_FIELDS.
|
|
1053
|
+
// This join must stay before applyFilters below: it lets filters[user][fullName] reuse this
|
|
1054
|
+
// alias instead of adding a second join of its own.
|
|
1055
|
+
qb.leftJoin('entity.user', 'user');
|
|
1056
|
+
qb.addSelect(CHATTER_MESSAGE_USER_FIELDS.map(field => `user.${field}`));
|
|
1057
|
+
|
|
904
1058
|
if (filters) {
|
|
905
1059
|
qb.andWhere(new Brackets(whereQb => {
|
|
906
1060
|
this.crudHelperService.applyFilters(whereQb, filters, 'entity', qb);
|
|
@@ -914,6 +1068,13 @@ export class ChatterMessageService extends CRUDService<ChatterMessage> {
|
|
|
914
1068
|
const [entities, count] = await qb.getManyAndCount();
|
|
915
1069
|
this.logHeapUsed('getChatterMessages-entitiesLoaded');
|
|
916
1070
|
|
|
1071
|
+
// The join above only selects the allowlisted columns, but TypeORM still hydrates the
|
|
1072
|
+
// author with `new User()`, which leaves every initialiser-backed property (active,
|
|
1073
|
+
// forcePasswordChange, ...) sitting on the instance holding its default rather than a
|
|
1074
|
+
// value read from the database. Replace it with a plain object of exactly the
|
|
1075
|
+
// allowlisted keys so the response cannot report fabricated defaults as data.
|
|
1076
|
+
this.trimMessageUsers(entities);
|
|
1077
|
+
|
|
917
1078
|
// Convert date strings in message details to ISO format for consistent handling on the frontend
|
|
918
1079
|
const DATE_FIELD_TYPES = ['date', 'datetime', 'time'];
|
|
919
1080
|
for (const entity of entities) {
|
|
@@ -3,9 +3,12 @@ import { BasicFilterDto } from "../dtos/basic-filters.dto";
|
|
|
3
3
|
import { classify } from '../helpers/string.helper';
|
|
4
4
|
import { ActiveUserData } from "src/interfaces/active-user-data.interface";
|
|
5
5
|
import { SolidRegistry } from "src/helpers/solid-registry";
|
|
6
|
-
import { BadRequestException, Logger } from "@nestjs/common";
|
|
6
|
+
import { BadRequestException, Injectable, Logger } from "@nestjs/common";
|
|
7
7
|
import { ERROR_MESSAGES } from "src/constants/error-messages";
|
|
8
8
|
import { buildCastToText } from "src/helpers/typeorm-db-helper";
|
|
9
|
+
import { DraftPublishHelperService } from "./draft-publish-helper.service";
|
|
10
|
+
import { InternationalisationHelperService } from "./internationalisation-helper.service";
|
|
11
|
+
import { normalizeObjectKeys } from "./object.utils";
|
|
9
12
|
|
|
10
13
|
export enum FilterCombinator {
|
|
11
14
|
AND = '$and',
|
|
@@ -36,10 +39,14 @@ export interface ResolvedFieldPath {
|
|
|
36
39
|
leafIsRelation: boolean;
|
|
37
40
|
}
|
|
38
41
|
|
|
42
|
+
@Injectable()
|
|
39
43
|
export class CrudHelperService {
|
|
44
|
+
private readonly logger = new Logger(CrudHelperService.name);
|
|
45
|
+
|
|
40
46
|
constructor(
|
|
47
|
+
private readonly draftPublishHelperService: DraftPublishHelperService,
|
|
48
|
+
private readonly internationalisationHelperService: InternationalisationHelperService,
|
|
41
49
|
) { }
|
|
42
|
-
private readonly logger = new Logger(CrudHelperService.name);
|
|
43
50
|
|
|
44
51
|
/**
|
|
45
52
|
* Resolve a user-supplied dotted path (e.g. "customer.name") against real TypeORM metadata.
|
|
@@ -163,7 +170,7 @@ export class CrudHelperService {
|
|
|
163
170
|
}
|
|
164
171
|
|
|
165
172
|
applyFilters(qb: WhereExpressionBuilder, filters: any, alias: string = 'entity', selectQb: SelectQueryBuilder<any>) {
|
|
166
|
-
const normalizedFilters =
|
|
173
|
+
const normalizedFilters = normalizeObjectKeys(filters);
|
|
167
174
|
if (normalizedFilters.$and) {
|
|
168
175
|
normalizedFilters.$and.forEach((andFilter: any) => {
|
|
169
176
|
qb.andWhere(
|
|
@@ -182,7 +189,7 @@ export class CrudHelperService {
|
|
|
182
189
|
// For individual conditions
|
|
183
190
|
Object.keys(normalizedFilters).forEach(key => {
|
|
184
191
|
const primaryFilterObj = normalizedFilters[key];
|
|
185
|
-
const normalizedPrimaryFilterObj =
|
|
192
|
+
const normalizedPrimaryFilterObj = normalizeObjectKeys(primaryFilterObj);
|
|
186
193
|
|
|
187
194
|
const [rawField, funcAlias] = key.split(':');
|
|
188
195
|
|
|
@@ -312,17 +319,6 @@ export class CrudHelperService {
|
|
|
312
319
|
}
|
|
313
320
|
}
|
|
314
321
|
|
|
315
|
-
// Normalize the primary operator object by removing the surrounding brackets in the keys e.g [$eq] => $eq
|
|
316
|
-
private normalizeObjectKeys(obj: any): any {
|
|
317
|
-
return Object.keys(obj).reduce((acc, key) => {
|
|
318
|
-
// Transform the key by removing surrounding brackets
|
|
319
|
-
const newKey = key.replace(/^\[(.*)\]$/, '$1');
|
|
320
|
-
// Assign the value to the transformed key in the accumulator object
|
|
321
|
-
acc[newKey] = obj[key];
|
|
322
|
-
return acc;
|
|
323
|
-
}, {});
|
|
324
|
-
}
|
|
325
|
-
|
|
326
322
|
normalize(value: string | string[]): string[] {
|
|
327
323
|
if (!value) return []; // if the value is nullish, then return an empty array
|
|
328
324
|
return Array.isArray(value) ? value : [value]; // if the value is an array, return it as is, otherwise return it as an array
|
|
@@ -359,7 +355,7 @@ export class CrudHelperService {
|
|
|
359
355
|
applySorting: boolean = true
|
|
360
356
|
): SelectQueryBuilder<any> { // TODO : Check how to pass a type to SelectQueryBuilder instead of any
|
|
361
357
|
let { limit, offset, showSoftDeleted, filters } = basicFilterDto;
|
|
362
|
-
const { fields, sort, populate = [], populateMedia = [], locale
|
|
358
|
+
const { fields, sort, populate = [], populateMedia = [], locale } = basicFilterDto;
|
|
363
359
|
|
|
364
360
|
// Normalize the fields, sort, groupBy and populate options i.e (since they can be either a string or an array of strings, when coming from the request)
|
|
365
361
|
const normalizedFields = this.normalize(fields);
|
|
@@ -390,28 +386,14 @@ export class CrudHelperService {
|
|
|
390
386
|
}
|
|
391
387
|
}
|
|
392
388
|
|
|
393
|
-
let finalLocale = locale
|
|
394
389
|
if (internationalisation) {
|
|
395
|
-
// If locale is not provided in the filter dto, then assume it is the default locale to be used.
|
|
396
|
-
|
|
397
|
-
//Get default locale from registry
|
|
398
|
-
const solidRegistry = moduleRef.get(SolidRegistry, { strict: false });
|
|
399
|
-
const defaultLocale = solidRegistry.getDefaultLocale();
|
|
400
|
-
if(defaultLocale){
|
|
401
|
-
finalLocale = defaultLocale.locale;
|
|
402
|
-
}else{
|
|
403
|
-
finalLocale = 'en';
|
|
404
|
-
}
|
|
405
|
-
}
|
|
390
|
+
// If locale is not provided in the filter dto, then assume it is the default locale to be used.
|
|
391
|
+
const finalLocale = locale || this.internationalisationHelperService.resolveDefaultLocaleName(moduleRef.get(SolidRegistry, { strict: false }));
|
|
406
392
|
qb.andWhere(`${entityAlias}.localeName = :locale`, { locale: finalLocale });
|
|
407
393
|
}
|
|
408
394
|
|
|
409
|
-
if (draftPublishWorkflow
|
|
410
|
-
|
|
411
|
-
qb.andWhere(`${entityAlias}.publishedAt IS NOT NULL`);
|
|
412
|
-
} else if (basicFilterDto.status === 'draft') {
|
|
413
|
-
qb.andWhere(`${entityAlias}.publishedAt IS NULL`);
|
|
414
|
-
}
|
|
395
|
+
if (draftPublishWorkflow) {
|
|
396
|
+
this.draftPublishHelperService.applyDraftPublishFilterDefaults(qb, filters, entityAlias);
|
|
415
397
|
}
|
|
416
398
|
// Depending upon the select option, apply the select clause
|
|
417
399
|
if (normalizedFields && normalizedFields.length) {
|
|
@@ -907,25 +889,25 @@ export class CrudHelperService {
|
|
|
907
889
|
};
|
|
908
890
|
}
|
|
909
891
|
|
|
910
|
-
async countGroupedRecords(qb: SelectQueryBuilder<any>, basicFilterDto: BasicFilterDto, entityAlias: string) { //TODO : Check how to pass a type to SelectQueryBuilder instead of any
|
|
911
|
-
|
|
912
|
-
|
|
892
|
+
// async countGroupedRecords(qb: SelectQueryBuilder<any>, basicFilterDto: BasicFilterDto, entityAlias: string, internationalisation?: boolean, draftPublishWorkflow?: boolean, moduleRef?: any) { //TODO : Check how to pass a type to SelectQueryBuilder instead of any
|
|
893
|
+
// const { limit, offset, ...rest } = basicFilterDto;
|
|
894
|
+
// const filteredDto = { ...rest, limit: undefined, offset: undefined };
|
|
913
895
|
|
|
914
|
-
|
|
896
|
+
// const filteredQB = this.buildFilterQuery(qb, filteredDto as BasicFilterDto, entityAlias, internationalisation, draftPublishWorkflow, moduleRef, FilterCombinator.AND, false, false);
|
|
915
897
|
|
|
916
|
-
|
|
898
|
+
// const groupByFields = this.normalize(filteredDto.groupBy);
|
|
917
899
|
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
900
|
+
// if (!groupByFields || groupByFields.length === 0) {
|
|
901
|
+
// throw new Error(ERROR_MESSAGES.INVALID_GROUP_BY_COUNT);
|
|
902
|
+
// }
|
|
921
903
|
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
904
|
+
// this.applyGroupBySelections(filteredQB, groupByFields, entityAlias);
|
|
905
|
+
// this.applyAggregates(filteredQB, ['count'], entityAlias);
|
|
906
|
+
// filteredQB.limit(undefined).offset(undefined).take(undefined).skip(undefined);
|
|
925
907
|
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
}
|
|
908
|
+
// const rawResults = await filteredQB.getRawMany();
|
|
909
|
+
// return rawResults.length;
|
|
910
|
+
// }
|
|
929
911
|
|
|
930
912
|
hasReadPermissionOnModel = (activeUser: ActiveUserData, modelName: string) => {
|
|
931
913
|
const permissionNames = [`${classify(modelName)}Controller.findOne`, `${classify(modelName)}Controller.findMany`];
|
|
@@ -998,7 +980,10 @@ export class CrudHelperService {
|
|
|
998
980
|
basicFilterDto: BasicFilterDto,
|
|
999
981
|
alias: string,
|
|
1000
982
|
createQbFn: () => Promise<SelectQueryBuilder<T>>,
|
|
1001
|
-
postProcessEntities?: (entities: T[]) => Promise<void
|
|
983
|
+
postProcessEntities?: (entities: T[]) => Promise<void>,
|
|
984
|
+
internationalisation?: boolean,
|
|
985
|
+
draftPublishWorkflow?: boolean,
|
|
986
|
+
moduleRef?: any
|
|
1002
987
|
): Promise<{ meta: { totalRecords: number }; groupMeta: any[]; groupRecords: any[] }> {
|
|
1003
988
|
const groupByFields = this.normalize(basicFilterDto.groupBy);
|
|
1004
989
|
if (!groupByFields.length) throw new BadRequestException(ERROR_MESSAGES.INVALID_GROUP_BY_COUNT);
|
|
@@ -1033,7 +1018,7 @@ export class CrudHelperService {
|
|
|
1033
1018
|
aggregates: undefined,
|
|
1034
1019
|
sort: basicFilterDto.groupFilter?.sort,
|
|
1035
1020
|
};
|
|
1036
|
-
groupQb = this.buildFilterQuery(groupQb, groupFilterDto, alias);
|
|
1021
|
+
groupQb = this.buildFilterQuery(groupQb, groupFilterDto, alias, internationalisation, draftPublishWorkflow, moduleRef);
|
|
1037
1022
|
groupQb = this.buildGroupByRecordsQuery(groupQb, group, alias, groupAliasMap, aggregateAliasMap, groupExpressionMap);
|
|
1038
1023
|
const [entities, count] = await groupQb.getManyAndCount();
|
|
1039
1024
|
if (postProcessEntities) await postProcessEntities(entities);
|