@kalisio/kdk 2.6.3 → 2.7.0
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/core/api/application.js +2 -4
- package/core/api/authentication.js +2 -3
- package/core/api/db.js +10 -2
- package/core/api/hooks/hooks.authorisations.js +4 -2
- package/core/api/hooks/hooks.push.js +6 -2
- package/core/api/hooks/hooks.query.js +29 -12
- package/core/api/hooks/hooks.users.js +30 -17
- package/core/api/models/configurations.model.mongodb.js +4 -0
- package/core/api/services/authorisations/authorisations.service.js +1 -1
- package/core/api/services/configurations/configurations.hooks.js +33 -0
- package/core/api/services/index.js +41 -7
- package/core/api/services/messages/messages.hooks.js +9 -3
- package/core/client/api.js +14 -1
- package/core/client/capabilities.js +1 -6
- package/core/client/components/KAvatar.vue +24 -20
- package/core/client/components/account/KProfile.vue +10 -71
- package/core/client/components/account/index.js +0 -2
- package/core/client/components/app/KSettings.vue +1 -0
- package/core/client/components/collection/KBoard.vue +4 -3
- package/core/client/components/collection/KCardSection.vue +1 -0
- package/core/client/components/collection/KGrid.vue +2 -0
- package/core/client/components/collection/KTable.vue +5 -1
- package/core/client/components/collection/KTimeLine.vue +9 -1
- package/core/client/components/collection/index.js +0 -2
- package/core/client/components/form/KChipsField.vue +2 -1
- package/core/client/components/form/KEmailField.vue +1 -0
- package/core/client/components/form/KFileField.vue +22 -1
- package/core/client/components/form/KForm.vue +2 -0
- package/core/client/components/form/KItemField.vue +1 -0
- package/core/client/components/form/KNumberField.vue +1 -0
- package/core/client/components/form/KPasswordField.vue +1 -0
- package/core/client/components/form/KPhoneField.vue +1 -0
- package/core/client/components/form/KPropertyItemField.vue +1 -0
- package/core/client/components/form/KResolutionField.vue +1 -0
- package/core/client/components/form/KSelectField.vue +31 -0
- package/core/client/components/form/KTagField.vue +1 -0
- package/core/client/components/form/KTextField.vue +1 -0
- package/core/client/components/form/KTokenField.vue +1 -0
- package/core/client/components/form/KUnitField.vue +1 -0
- package/core/client/components/form/KUrlField.vue +1 -0
- package/core/client/components/graphics/KIcon.vue +3 -4
- package/core/client/components/layout/KPage.vue +1 -0
- package/core/client/components/layout/KWindow.vue +6 -3
- package/core/client/components/messages/KMessageComposer.vue +2 -1
- package/core/client/components/messages/KMessagesTimeLine.vue +1 -1
- package/core/client/components/time/KDate.vue +1 -2
- package/core/client/components/time/KDateTime.vue +11 -11
- package/core/client/components/time/KTime.vue +1 -1
- package/core/client/composables/collection.js +33 -8
- package/core/client/composables/errors.js +1 -1
- package/core/client/composables/layout.js +9 -9
- package/core/client/configurations.js +50 -0
- package/core/client/exporter.js +1 -1
- package/core/client/i18n/core_en.json +6 -39
- package/core/client/i18n/core_fr.json +6 -39
- package/core/client/index.js +2 -0
- package/core/client/layout.js +8 -8
- package/core/client/mixins/mixin.base-activity.js +5 -2
- package/core/client/mixins/mixin.base-field.js +3 -3
- package/core/client/search.js +2 -1
- package/core/client/utils/utils.collection.js +8 -8
- package/core/client/utils/utils.items.js +4 -0
- package/core/client/utils/utils.push.js +3 -3
- package/core/client/utils/utils.session.js +7 -5
- package/core/client/utils/utils.shapes.js +38 -7
- package/core/client/utils/utils.time.js +21 -22
- package/core/common/schemas/users.update-profile.json +3 -2
- package/coverage/core/api/application.js.html +1 -1
- package/coverage/core/api/authentication.js.html +1 -1
- package/coverage/core/api/db.js.html +1 -1
- package/coverage/core/api/hooks/hooks.authentication.js.html +1 -1
- package/coverage/core/api/hooks/hooks.authorisations.js.html +1 -1
- package/coverage/core/api/hooks/hooks.logger.js.html +1 -1
- package/coverage/core/api/hooks/hooks.model.js.html +1 -1
- package/coverage/core/api/hooks/hooks.push.js.html +22 -10
- package/coverage/core/api/hooks/hooks.query.js.html +33 -6
- package/coverage/core/api/hooks/hooks.schemas.js.html +1 -1
- package/coverage/core/api/hooks/hooks.service.js.html +1 -1
- package/coverage/core/api/hooks/hooks.storage.js.html +1 -1
- package/coverage/core/api/hooks/hooks.tags.js.html +1 -1
- package/coverage/core/api/hooks/hooks.users.js.html +4 -4
- package/coverage/core/api/hooks/index.html +23 -23
- package/coverage/core/api/hooks/index.js.html +1 -1
- package/coverage/core/api/index.html +1 -1
- package/coverage/core/api/index.js.html +1 -1
- package/coverage/core/api/marshall.js.html +1 -1
- package/coverage/core/api/models/configurations.model.mongodb.js.html +1 -1
- package/coverage/core/api/models/index.html +1 -1
- package/coverage/core/api/models/messages.model.mongodb.js.html +1 -1
- package/coverage/core/api/models/tags.model.mongodb.js.html +1 -1
- package/coverage/core/api/models/users.model.mongodb.js.html +1 -1
- package/coverage/core/api/services/account/account.hooks.js.html +1 -1
- package/coverage/core/api/services/account/account.service.js.html +1 -1
- package/coverage/core/api/services/account/index.html +1 -1
- package/coverage/core/api/services/authorisations/authorisations.hooks.js.html +1 -1
- package/coverage/core/api/services/authorisations/authorisations.service.js.html +1 -1
- package/coverage/core/api/services/authorisations/index.html +1 -1
- package/coverage/core/api/services/configurations/configurations.hooks.js.html +1 -1
- package/coverage/core/api/services/configurations/index.html +1 -1
- package/coverage/core/api/services/databases/databases.hooks.js.html +1 -1
- package/coverage/core/api/services/databases/databases.service.js.html +1 -1
- package/coverage/core/api/services/databases/index.html +1 -1
- package/coverage/core/api/services/import-export/import-export.hooks.js.html +1 -1
- package/coverage/core/api/services/import-export/import-export.service.js.html +1 -1
- package/coverage/core/api/services/import-export/index.html +1 -1
- package/coverage/core/api/services/index.html +1 -1
- package/coverage/core/api/services/index.js.html +1 -1
- package/coverage/core/api/services/mailer/index.html +1 -1
- package/coverage/core/api/services/mailer/mailer.hooks.js.html +1 -1
- package/coverage/core/api/services/mailer/mailer.service.js.html +1 -1
- package/coverage/core/api/services/messages/index.html +1 -1
- package/coverage/core/api/services/messages/messages.hooks.js.html +1 -1
- package/coverage/core/api/services/push/index.html +1 -1
- package/coverage/core/api/services/push/push.hooks.js.html +1 -1
- package/coverage/core/api/services/push/push.service.js.html +1 -1
- package/coverage/core/api/services/storage/index.html +1 -1
- package/coverage/core/api/services/storage/storage.hooks.js.html +1 -1
- package/coverage/core/api/services/storage/storage.service.js.html +1 -1
- package/coverage/core/api/services/tags/index.html +1 -1
- package/coverage/core/api/services/tags/tags.hooks.js.html +1 -1
- package/coverage/core/api/services/users/index.html +1 -1
- package/coverage/core/api/services/users/users.hooks.js.html +1 -1
- package/coverage/core/api/services/users/users.service.js.html +1 -1
- package/coverage/core/common/errors.js.html +1 -1
- package/coverage/core/common/index.html +1 -1
- package/coverage/core/common/index.js.html +1 -1
- package/coverage/core/common/permissions.js.html +1 -1
- package/coverage/core/common/schema.js.html +1 -1
- package/coverage/core/common/utils.js.html +1 -1
- package/coverage/core/common/utils.offline.js.html +1 -1
- package/coverage/index.html +17 -17
- package/coverage/lcov-report/core/api/application.js.html +1 -1
- package/coverage/lcov-report/core/api/authentication.js.html +1 -1
- package/coverage/lcov-report/core/api/db.js.html +1 -1
- package/coverage/lcov-report/core/api/hooks/hooks.authentication.js.html +1 -1
- package/coverage/lcov-report/core/api/hooks/hooks.authorisations.js.html +1 -1
- package/coverage/lcov-report/core/api/hooks/hooks.logger.js.html +1 -1
- package/coverage/lcov-report/core/api/hooks/hooks.model.js.html +1 -1
- package/coverage/lcov-report/core/api/hooks/hooks.push.js.html +22 -10
- package/coverage/lcov-report/core/api/hooks/hooks.query.js.html +33 -6
- package/coverage/lcov-report/core/api/hooks/hooks.schemas.js.html +1 -1
- package/coverage/lcov-report/core/api/hooks/hooks.service.js.html +1 -1
- package/coverage/lcov-report/core/api/hooks/hooks.storage.js.html +1 -1
- package/coverage/lcov-report/core/api/hooks/hooks.tags.js.html +1 -1
- package/coverage/lcov-report/core/api/hooks/hooks.users.js.html +4 -4
- package/coverage/lcov-report/core/api/hooks/index.html +23 -23
- package/coverage/lcov-report/core/api/hooks/index.js.html +1 -1
- package/coverage/lcov-report/core/api/index.html +1 -1
- package/coverage/lcov-report/core/api/index.js.html +1 -1
- package/coverage/lcov-report/core/api/marshall.js.html +1 -1
- package/coverage/lcov-report/core/api/models/configurations.model.mongodb.js.html +1 -1
- package/coverage/lcov-report/core/api/models/index.html +1 -1
- package/coverage/lcov-report/core/api/models/messages.model.mongodb.js.html +1 -1
- package/coverage/lcov-report/core/api/models/tags.model.mongodb.js.html +1 -1
- package/coverage/lcov-report/core/api/models/users.model.mongodb.js.html +1 -1
- package/coverage/lcov-report/core/api/services/account/account.hooks.js.html +1 -1
- package/coverage/lcov-report/core/api/services/account/account.service.js.html +1 -1
- package/coverage/lcov-report/core/api/services/account/index.html +1 -1
- package/coverage/lcov-report/core/api/services/authorisations/authorisations.hooks.js.html +1 -1
- package/coverage/lcov-report/core/api/services/authorisations/authorisations.service.js.html +1 -1
- package/coverage/lcov-report/core/api/services/authorisations/index.html +1 -1
- package/coverage/lcov-report/core/api/services/configurations/configurations.hooks.js.html +1 -1
- package/coverage/lcov-report/core/api/services/configurations/index.html +1 -1
- package/coverage/lcov-report/core/api/services/databases/databases.hooks.js.html +1 -1
- package/coverage/lcov-report/core/api/services/databases/databases.service.js.html +1 -1
- package/coverage/lcov-report/core/api/services/databases/index.html +1 -1
- package/coverage/lcov-report/core/api/services/import-export/import-export.hooks.js.html +1 -1
- package/coverage/lcov-report/core/api/services/import-export/import-export.service.js.html +1 -1
- package/coverage/lcov-report/core/api/services/import-export/index.html +1 -1
- package/coverage/lcov-report/core/api/services/index.html +1 -1
- package/coverage/lcov-report/core/api/services/index.js.html +1 -1
- package/coverage/lcov-report/core/api/services/mailer/index.html +1 -1
- package/coverage/lcov-report/core/api/services/mailer/mailer.hooks.js.html +1 -1
- package/coverage/lcov-report/core/api/services/mailer/mailer.service.js.html +1 -1
- package/coverage/lcov-report/core/api/services/messages/index.html +1 -1
- package/coverage/lcov-report/core/api/services/messages/messages.hooks.js.html +1 -1
- package/coverage/lcov-report/core/api/services/push/index.html +1 -1
- package/coverage/lcov-report/core/api/services/push/push.hooks.js.html +1 -1
- package/coverage/lcov-report/core/api/services/push/push.service.js.html +1 -1
- package/coverage/lcov-report/core/api/services/storage/index.html +1 -1
- package/coverage/lcov-report/core/api/services/storage/storage.hooks.js.html +1 -1
- package/coverage/lcov-report/core/api/services/storage/storage.service.js.html +1 -1
- package/coverage/lcov-report/core/api/services/tags/index.html +1 -1
- package/coverage/lcov-report/core/api/services/tags/tags.hooks.js.html +1 -1
- package/coverage/lcov-report/core/api/services/users/index.html +1 -1
- package/coverage/lcov-report/core/api/services/users/users.hooks.js.html +1 -1
- package/coverage/lcov-report/core/api/services/users/users.service.js.html +1 -1
- package/coverage/lcov-report/core/common/errors.js.html +1 -1
- package/coverage/lcov-report/core/common/index.html +1 -1
- package/coverage/lcov-report/core/common/index.js.html +1 -1
- package/coverage/lcov-report/core/common/permissions.js.html +1 -1
- package/coverage/lcov-report/core/common/schema.js.html +1 -1
- package/coverage/lcov-report/core/common/utils.js.html +1 -1
- package/coverage/lcov-report/core/common/utils.offline.js.html +1 -1
- package/coverage/lcov-report/index.html +17 -17
- package/coverage/lcov-report/map/api/hooks/hooks.catalog.js.html +1 -1
- package/coverage/lcov-report/map/api/hooks/hooks.features.js.html +1 -1
- package/coverage/lcov-report/map/api/hooks/hooks.query.js.html +184 -4
- package/coverage/lcov-report/map/api/hooks/index.html +5 -5
- package/coverage/lcov-report/map/api/hooks/index.js.html +1 -1
- package/coverage/lcov-report/map/api/index.html +1 -1
- package/coverage/lcov-report/map/api/index.js.html +1 -1
- package/coverage/lcov-report/map/api/marshall.js.html +1 -1
- package/coverage/lcov-report/map/api/models/alerts.model.mongodb.js.html +1 -1
- package/coverage/lcov-report/map/api/models/catalog.model.mongodb.js.html +1 -1
- package/coverage/lcov-report/map/api/models/features.model.mongodb.js.html +1 -1
- package/coverage/lcov-report/map/api/models/index.html +1 -1
- package/coverage/lcov-report/map/api/models/projects.model.mongodb.js.html +1 -1
- package/coverage/lcov-report/map/api/models/styles.model.mongodb.js.html +1 -1
- package/coverage/lcov-report/map/api/services/alerts/alerts.hooks.js.html +1 -1
- package/coverage/lcov-report/map/api/services/alerts/alerts.service.js.html +1 -1
- package/coverage/lcov-report/map/api/services/alerts/index.html +1 -1
- package/coverage/lcov-report/map/api/services/catalog/catalog.hooks.js.html +1 -1
- package/coverage/lcov-report/map/api/services/catalog/index.html +1 -1
- package/coverage/lcov-report/map/api/services/daptiles/daptiles.service.js.html +1 -1
- package/coverage/lcov-report/map/api/services/daptiles/index.html +1 -1
- package/coverage/lcov-report/map/api/services/features/features.hooks.js.html +1 -1
- package/coverage/lcov-report/map/api/services/features/features.service.js.html +1 -1
- package/coverage/lcov-report/map/api/services/features/index.html +1 -1
- package/coverage/lcov-report/map/api/services/index.html +1 -1
- package/coverage/lcov-report/map/api/services/index.js.html +1 -1
- package/coverage/lcov-report/map/api/services/projects/index.html +1 -1
- package/coverage/lcov-report/map/api/services/projects/projects.hooks.js.html +1 -1
- package/coverage/lcov-report/map/api/services/styles/index.html +1 -1
- package/coverage/lcov-report/map/api/services/styles/styles.hooks.js.html +1 -1
- package/coverage/lcov-report/map/common/dynamic-grid-source.js.html +1 -1
- package/coverage/lcov-report/map/common/errors.js.html +1 -1
- package/coverage/lcov-report/map/common/geotiff-grid-source.js.html +1 -1
- package/coverage/lcov-report/map/common/grid.js.html +1 -1
- package/coverage/lcov-report/map/common/index.html +1 -1
- package/coverage/lcov-report/map/common/index.js.html +1 -1
- package/coverage/lcov-report/map/common/meteo-model-grid-source.js.html +1 -1
- package/coverage/lcov-report/map/common/moment-utils.js.html +1 -1
- package/coverage/lcov-report/map/common/opendap-grid-source.js.html +1 -1
- package/coverage/lcov-report/map/common/opendap-utils.js.html +1 -1
- package/coverage/lcov-report/map/common/permissions.js.html +1 -1
- package/coverage/lcov-report/map/common/time-based-grid-source.js.html +1 -1
- package/coverage/lcov-report/map/common/tms-utils.js.html +1 -1
- package/coverage/lcov-report/map/common/wcs-grid-source.js.html +1 -1
- package/coverage/lcov-report/map/common/wcs-utils.js.html +1 -1
- package/coverage/lcov-report/map/common/weacast-grid-source.js.html +1 -1
- package/coverage/lcov-report/map/common/wfs-utils.js.html +1 -1
- package/coverage/lcov-report/map/common/wms-utils.js.html +1 -1
- package/coverage/lcov-report/map/common/wmts-utils.js.html +1 -1
- package/coverage/lcov.info +358 -280
- package/coverage/map/api/hooks/hooks.catalog.js.html +1 -1
- package/coverage/map/api/hooks/hooks.features.js.html +1 -1
- package/coverage/map/api/hooks/hooks.query.js.html +184 -4
- package/coverage/map/api/hooks/index.html +5 -5
- package/coverage/map/api/hooks/index.js.html +1 -1
- package/coverage/map/api/index.html +1 -1
- package/coverage/map/api/index.js.html +1 -1
- package/coverage/map/api/marshall.js.html +1 -1
- package/coverage/map/api/models/alerts.model.mongodb.js.html +1 -1
- package/coverage/map/api/models/catalog.model.mongodb.js.html +1 -1
- package/coverage/map/api/models/features.model.mongodb.js.html +1 -1
- package/coverage/map/api/models/index.html +1 -1
- package/coverage/map/api/models/projects.model.mongodb.js.html +1 -1
- package/coverage/map/api/models/styles.model.mongodb.js.html +1 -1
- package/coverage/map/api/services/alerts/alerts.hooks.js.html +1 -1
- package/coverage/map/api/services/alerts/alerts.service.js.html +1 -1
- package/coverage/map/api/services/alerts/index.html +1 -1
- package/coverage/map/api/services/catalog/catalog.hooks.js.html +1 -1
- package/coverage/map/api/services/catalog/index.html +1 -1
- package/coverage/map/api/services/daptiles/daptiles.service.js.html +1 -1
- package/coverage/map/api/services/daptiles/index.html +1 -1
- package/coverage/map/api/services/features/features.hooks.js.html +1 -1
- package/coverage/map/api/services/features/features.service.js.html +1 -1
- package/coverage/map/api/services/features/index.html +1 -1
- package/coverage/map/api/services/index.html +1 -1
- package/coverage/map/api/services/index.js.html +1 -1
- package/coverage/map/api/services/projects/index.html +1 -1
- package/coverage/map/api/services/projects/projects.hooks.js.html +1 -1
- package/coverage/map/api/services/styles/index.html +1 -1
- package/coverage/map/api/services/styles/styles.hooks.js.html +1 -1
- package/coverage/map/common/dynamic-grid-source.js.html +1 -1
- package/coverage/map/common/errors.js.html +1 -1
- package/coverage/map/common/geotiff-grid-source.js.html +1 -1
- package/coverage/map/common/grid.js.html +1 -1
- package/coverage/map/common/index.html +1 -1
- package/coverage/map/common/index.js.html +1 -1
- package/coverage/map/common/meteo-model-grid-source.js.html +1 -1
- package/coverage/map/common/moment-utils.js.html +1 -1
- package/coverage/map/common/opendap-grid-source.js.html +1 -1
- package/coverage/map/common/opendap-utils.js.html +1 -1
- package/coverage/map/common/permissions.js.html +1 -1
- package/coverage/map/common/time-based-grid-source.js.html +1 -1
- package/coverage/map/common/tms-utils.js.html +1 -1
- package/coverage/map/common/wcs-grid-source.js.html +1 -1
- package/coverage/map/common/wcs-utils.js.html +1 -1
- package/coverage/map/common/weacast-grid-source.js.html +1 -1
- package/coverage/map/common/wfs-utils.js.html +1 -1
- package/coverage/map/common/wms-utils.js.html +1 -1
- package/coverage/map/common/wmts-utils.js.html +1 -1
- package/coverage/tmp/coverage-1028514-1773134124472-0.json +1 -0
- package/coverage/tmp/coverage-1028526-1773134124448-0.json +1 -0
- package/coverage/tmp/coverage-1028537-1773134124431-0.json +1 -0
- package/coverage/tmp/coverage-1028549-1773134124401-0.json +1 -0
- package/coverage/tmp/{coverage-222566-1765963609278-0.json → coverage-1028556-1773134124353-0.json} +1 -1
- package/extras/configs/widgets.top.js +3 -3
- package/extras/tests/core/collection.mjs +2 -9
- package/map/api/hooks/hooks.catalog.js +18 -4
- package/map/api/services/catalog/catalog.hooks.js +3 -0
- package/map/api/services/features/features.hooks.js +3 -1
- package/map/api/services/index.js +2 -6
- package/map/api/services/styles/styles.hooks.js +6 -1
- package/map/client/components/KFeatureActionButton.vue +9 -3
- package/map/client/components/KFeaturesFilterManager.vue +5 -5
- package/map/client/components/KFilterCondition.vue +17 -10
- package/map/client/components/KLayerEditor.vue +49 -39
- package/map/client/components/KMeasureTool.vue +7 -1
- package/map/client/components/KTimezoneMap.vue +29 -9
- package/map/client/components/catalog/KLayersPanel.vue +26 -16
- package/map/client/components/catalog/KLayersSelector.vue +13 -2
- package/map/client/components/catalog/KViewsPanel.vue +5 -4
- package/map/client/components/form/KSelectLayersField.vue +28 -17
- package/map/client/components/form/KSelectViewsField.vue +18 -9
- package/map/client/components/form/KTimezoneField.vue +1 -2
- package/map/client/components/legend/KVariablesLegend.vue +10 -1
- package/map/client/components/location/KLocationCardSection.vue +7 -2
- package/map/client/components/location/KLocationMap.vue +31 -7
- package/map/client/components/selection/KSelectedLayerFeatures.vue +2 -2
- package/map/client/components/stickies/KZoomControl.vue +1 -1
- package/map/client/components/styles/KStyleManager.vue +4 -1
- package/map/client/components/widget/KTimeSeries.vue +174 -497
- package/map/client/components/widget/KTimeSeriesSelector.vue +72 -0
- package/map/client/components/widget/KTimeSeriesToolbar.vue +83 -0
- package/map/client/composables/catalog.js +6 -10
- package/map/client/composables/highlight.js +12 -9
- package/map/client/composables/project.js +1 -1
- package/map/client/composables/selection.js +8 -7
- package/map/client/composables/weather.js +9 -2
- package/map/client/geolocation.js +8 -5
- package/map/client/i18n/map_en.json +10 -8
- package/map/client/i18n/map_fr.json +9 -7
- package/map/client/leaflet/TiledFeatureLayer.js +85 -82
- package/map/client/leaflet/utils/utils.geojson.js +3 -3
- package/map/client/mixins/globe/mixin.base-globe.js +15 -6
- package/map/client/mixins/globe/mixin.geojson-layers.js +27 -18
- package/map/client/mixins/map/mixin.edit-layers.js +9 -1
- package/map/client/mixins/map/mixin.pmtiles-layers.js +118 -29
- package/map/client/mixins/map/mixin.tiled-mesh-layers.js +12 -5
- package/map/client/mixins/map/mixin.tiled-wind-layers.js +19 -10
- package/map/client/mixins/mixin.activity.js +23 -30
- package/map/client/mixins/mixin.feature-selection.js +41 -5
- package/map/client/planets.js +1 -1
- package/map/client/readers/reader.kml.js +2 -3
- package/map/client/utils/utils.catalog.js +36 -10
- package/map/client/utils/utils.layers.js +39 -8
- package/map/client/utils/utils.project.js +4 -0
- package/map/client/utils/utils.style.js +37 -7
- package/map/client/utils/utils.time-series.js +215 -6
- package/map/common/schemas/catalog.update.json +1 -1
- package/map/common/weacast-grid-source.js +1 -1
- package/package.json +3 -3
- package/scripts/kash/CHANGELOG.md +0 -4
- package/scripts/kash/README.md +0 -9
- package/scripts/kash/kash.sh +45 -40
- package/scripts/kash/scripts/run_tests.sh +1 -4
- package/test/api/core/authentication.test.js +9 -4
- package/test/api/core/config/default.cjs +1 -0
- package/test/api/core/hooks.test.js +6 -0
- package/test/api/core/index.test.js +43 -18
- package/test/api/core/push.test.js +8 -8
- package/test/api/core/test-log-2026-03-10.log +60 -0
- package/test/api/core/users.test.js +384 -0
- package/test/api/map/grid-sources.test.js +1 -1
- package/test/api/map/test-log-2026-03-10.log +56 -0
- package/vite/package.json +11 -2
- package/vite/test/core/composables.test.js +77 -0
- package/vite/vitest.config.js +13 -0
- package/vite/yarn.lock +1096 -18
- package/client/css/core.variables.scss +0 -72
- package/client/i18n/core_en.json +0 -744
- package/client/i18n/core_fr.json +0 -744
- package/client/i18n/map_en.json +0 -800
- package/client/i18n/map_fr.json +0 -800
- package/client/kdk.client.css +0 -47
- package/client/kdk.client.js +0 -41097
- package/client/kdk.client.map.css +0 -47
- package/client/kdk.client.map.js +0 -38182
- package/client/kdk.client.map.min.css +0 -1
- package/client/kdk.client.map.min.js +0 -27032
- package/client/kdk.client.min.css +0 -1
- package/client/kdk.client.min.js +0 -29074
- package/client/schemas/capture.create.json +0 -132
- package/client/schemas/catalog.update.json +0 -44
- package/client/schemas/messages.update.json +0 -16
- package/client/schemas/projects.create.json +0 -52
- package/client/schemas/projects.update.json +0 -52
- package/client/schemas/settings.update.json +0 -286
- package/client/schemas/tags.update.json +0 -35
- package/client/schemas/users.update-profile.json +0 -34
- package/core/client/components/account/KAccount.vue +0 -68
- package/core/client/components/account/KDeleteAccountManager.vue +0 -62
- package/core/client/components/account/KEmailManager.vue +0 -128
- package/core/client/components/account/KPasswordManager.vue +0 -90
- package/core/client/components/account/KVerifyEmailManager.vue +0 -105
- package/core/client/components/collection/KColumn.vue +0 -227
- package/core/client/components/collection/KHistory.vue +0 -113
- package/core/client/components/collection/KHistoryEntry.vue +0 -109
- package/coverage/tmp/coverage-222524-1765963609350-0.json +0 -1
- package/coverage/tmp/coverage-222536-1765963609335-0.json +0 -1
- package/coverage/tmp/coverage-222547-1765963609324-0.json +0 -1
- package/coverage/tmp/coverage-222559-1765963609309-0.json +0 -1
- package/scripts/kash/LICENSE +0 -21
- package/test/api/core/test-log-2025-07-31.log +0 -15
- package/test/api/core/test-log-2025-10-03.log +0 -18
- package/test/api/core/test-log-2025-11-10.log +0 -0
- package/test/api/core/test-log-2025-11-12.log +0 -117
- package/test/api/core/test-log-2025-11-27.log +0 -0
- package/test/api/core/test-log-2025-11-28.log +0 -17
- package/test/api/core/test-log-2025-12-09.log +0 -148
- package/test/api/core/test-log-2025-12-17.log +0 -58
- package/test/api/core/test-log-2026-01-29.log +0 -17
- package/test/api/map/test-log-2025-07-23.log +0 -1
- package/test/api/map/test-log-2025-11-28.log +0 -33
- package/test/api/map/test-log-2025-12-10.log +0 -2
- package/test/api/map/test-log-2026-01-06.log +0 -26
package/core/api/application.js
CHANGED
|
@@ -16,14 +16,12 @@ import configuration from '@feathersjs/configuration'
|
|
|
16
16
|
import errors from '@feathersjs/errors'
|
|
17
17
|
import express, { authenticate } from '@feathersjs/express'
|
|
18
18
|
import socketio from '@feathersjs/socketio'
|
|
19
|
-
import
|
|
20
|
-
import { Database, idToString } from './db.js'
|
|
19
|
+
import { Database, isObjectID, idToString } from './db.js'
|
|
21
20
|
import auth from './authentication.js'
|
|
22
21
|
|
|
23
22
|
const debug = makeDebug('kdk:core:application')
|
|
24
23
|
const debugLimiter = makeDebug('kdk:core:application:limiter')
|
|
25
24
|
const { TooManyRequests, Forbidden, BadRequest } = errors
|
|
26
|
-
const { ObjectID } = mongodb
|
|
27
25
|
const { rest } = express
|
|
28
26
|
const sift = siftModule.default
|
|
29
27
|
|
|
@@ -507,7 +505,7 @@ export function kdk (config = {}) {
|
|
|
507
505
|
return app.service(app.get('apiPath') + '/' + context + '/' + path)
|
|
508
506
|
} else if (context && typeof context === 'object') {
|
|
509
507
|
// Could be Object ID or raw object
|
|
510
|
-
if (
|
|
508
|
+
if (isObjectID(context)) return app.service(app.get('apiPath') + '/' + context.toString() + '/' + path)
|
|
511
509
|
else return app.service(app.get('apiPath') + '/' + context._id.toString() + '/' + path)
|
|
512
510
|
} else {
|
|
513
511
|
return app.service(app.get('apiPath') + '/' + path)
|
|
@@ -4,15 +4,14 @@ import qs from 'qs'
|
|
|
4
4
|
import 'winston-daily-rotate-file'
|
|
5
5
|
// import { RateLimiter } from 'limiter'
|
|
6
6
|
import HttpLimiter from 'express-rate-limit'
|
|
7
|
-
import mongodb from 'mongodb'
|
|
8
7
|
import errors from '@feathersjs/errors'
|
|
9
8
|
import { AuthenticationService, JWTStrategy } from '@feathersjs/authentication'
|
|
10
9
|
import { LocalStrategy } from '@feathersjs/authentication-local'
|
|
11
10
|
import OAuth from '@feathersjs/authentication-oauth'
|
|
12
11
|
import PasswordValidator from 'password-validator'
|
|
12
|
+
import { isValidObjectID } from './db.js'
|
|
13
13
|
|
|
14
14
|
const debug = makeDebug('kdk:core:authentication')
|
|
15
|
-
const { ObjectID } = mongodb
|
|
16
15
|
const { oauth, OAuthStrategy } = OAuth
|
|
17
16
|
const { NotAuthenticated } = errors
|
|
18
17
|
|
|
@@ -139,7 +138,7 @@ export class JWTAuthenticationStrategy extends JWTStrategy {
|
|
|
139
138
|
// Return basic information for a stateless token otherwise
|
|
140
139
|
if (payload.sub) {
|
|
141
140
|
// Check for a valid MongoDB ID
|
|
142
|
-
if (
|
|
141
|
+
if (isValidObjectID(payload.sub)) {
|
|
143
142
|
const entityId = await this.getEntityId(result, params)
|
|
144
143
|
const value = await this.getEntity(entityId, params)
|
|
145
144
|
|
package/core/api/db.js
CHANGED
|
@@ -12,13 +12,21 @@ Object.getPrototypeOf(moment()).toBSON = function () {
|
|
|
12
12
|
return this.toDate()
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
+
// Check if a given object is an instance of MongoDB ObjectID
|
|
15
16
|
export function isObjectID (id) {
|
|
16
17
|
return id && (typeof id.toHexString === 'function') && (typeof id.getTimestamp === 'function')
|
|
17
18
|
}
|
|
19
|
+
// Check if a given string is a valid MongoDB ObjectID
|
|
20
|
+
export function isValidObjectID (id) {
|
|
21
|
+
// We don't use ObjectID.isValid as it returns true for any string that contains 12 characters: https://jira.mongodb.org/browse/NODE-4912.
|
|
22
|
+
// Regular expression that checks for hex value
|
|
23
|
+
const checkForHexRegExp = /^[0-9a-fA-F]{24}$/
|
|
24
|
+
return (id && (id.length === 24) && checkForHexRegExp.test(id))
|
|
25
|
+
}
|
|
18
26
|
|
|
19
27
|
export function idToString (id) {
|
|
20
28
|
return (typeof id === 'object'
|
|
21
|
-
? (
|
|
29
|
+
? (isObjectID(id)
|
|
22
30
|
? id.toString()
|
|
23
31
|
: idToString(id._id))
|
|
24
32
|
: id)
|
|
@@ -28,7 +36,7 @@ export function createObjectID (id) {
|
|
|
28
36
|
// This ensure it works even if id is already an ObjectID
|
|
29
37
|
if (isObjectID(id)) return id
|
|
30
38
|
// Take care that numbers could be a valid object ID
|
|
31
|
-
else if ((typeof id === 'number') || !
|
|
39
|
+
else if ((typeof id === 'number') || !isValidObjectID(id)) return null
|
|
32
40
|
else {
|
|
33
41
|
const objectId = new ObjectID(id)
|
|
34
42
|
// It appears that ObjectID.isValid is not reliable in some driver versions, see eg https://jira.mongodb.org/browse/NODE-3760
|
|
@@ -187,11 +187,12 @@ export async function authorise (hook) {
|
|
|
187
187
|
const authorisationService = hook.app.getService('authorisations')
|
|
188
188
|
let subject = hook.params.user
|
|
189
189
|
const payload = _.get(hook.params, 'authentication.payload')
|
|
190
|
+
const subjectId = payload && (payload.sub || payload.appId)
|
|
190
191
|
if (payload) {
|
|
191
192
|
// If no user we allow for a stateless token with permissions inside, e.g.
|
|
192
193
|
// token targeting API gateway (sub = keyId) or app used through iframe (appId = keyId)
|
|
193
|
-
if (!subject &&
|
|
194
|
-
subject = Object.assign({ _id:
|
|
194
|
+
if (!subject && subjectId) {
|
|
195
|
+
subject = Object.assign({ _id: subjectId }, payload)
|
|
195
196
|
} else if (subject) { // Otherwise we allow to "extend" user abilities by providing additional information in the token
|
|
196
197
|
subject = Object.assign(subject, _.omit(payload, ['aud', 'iss', 'exp', 'sub', 'iat', 'jti', 'nbf']))
|
|
197
198
|
}
|
|
@@ -232,6 +233,7 @@ export async function authorise (hook) {
|
|
|
232
233
|
_.merge(hook.params.query, dbQuery)
|
|
233
234
|
} else {
|
|
234
235
|
if (operation === 'find') { // You don't have right to read any items but you have access to the service so the result is empty
|
|
236
|
+
debug('Service access granted but no resource allowed')
|
|
235
237
|
hook.result = (!_.get(hook, 'params.paginate', true) ? [] : { total: 0, skip: 0, data: [] })
|
|
236
238
|
} else { // You don't have the right to update/patch/remove any items so any tentative should throw
|
|
237
239
|
debug('Resource access not granted')
|
|
@@ -21,7 +21,11 @@ export async function sendNewSubscriptionEmail (hook) {
|
|
|
21
21
|
const currentUser = hook.result
|
|
22
22
|
const previousUser = hook.params.user
|
|
23
23
|
// If we can't compare abort, eg f-a-m might patch user to update tokens
|
|
24
|
-
if (!currentUser || !previousUser) return
|
|
24
|
+
if (!currentUser || !previousUser) return
|
|
25
|
+
// Or an app might allow a user to patch another for eg permissions management
|
|
26
|
+
const currentUserId = (currentUser._id ? currentUser._id.toString() : null)
|
|
27
|
+
const previousUserId = (previousUser._id ? previousUser._id.toString() : null)
|
|
28
|
+
if (!currentUserId || !previousUserId || (currentUserId !== previousUserId)) return
|
|
25
29
|
// Retrieve the last subscription
|
|
26
30
|
const lastSubscription = _.last(_.get(currentUser, 'subscriptions', []))
|
|
27
31
|
if (!lastSubscription) return
|
|
@@ -33,7 +37,7 @@ export async function sendNewSubscriptionEmail (hook) {
|
|
|
33
37
|
debug('Last subscription uses an existing fingerprint')
|
|
34
38
|
return
|
|
35
39
|
}
|
|
36
|
-
debug('Last subscription uses
|
|
40
|
+
debug('Last subscription uses a new fingerprint')
|
|
37
41
|
// Send an email to notify the user
|
|
38
42
|
const domainPath = app.get('domain') + '/#/'
|
|
39
43
|
const email = {
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import _ from 'lodash'
|
|
2
|
-
import { marshallComparisonFields, marshallTime, marshallBooleanFields, marshallNumberFields, marshallDateFields } from '../marshall.js'
|
|
3
2
|
import mongodb from 'mongodb'
|
|
4
3
|
import errors from '@feathersjs/errors'
|
|
5
4
|
import makeDebug from 'debug'
|
|
5
|
+
import { marshallComparisonFields, marshallTime, marshallBooleanFields, marshallNumberFields, marshallDateFields } from '../marshall.js'
|
|
6
|
+
import { isValidObjectID, isObjectID } from '../db.js'
|
|
6
7
|
import { makeDiacriticPattern } from '../../common/utils.js'
|
|
7
8
|
|
|
8
9
|
const { ObjectID } = mongodb
|
|
@@ -123,12 +124,12 @@ export function populateObject (options) {
|
|
|
123
124
|
// Set the retrieved service on the same field or given one in hook params
|
|
124
125
|
_.set(params, serviceProperty, service)
|
|
125
126
|
// Let it work with id/name string or real object
|
|
126
|
-
if (typeof id === 'string' ||
|
|
127
|
+
if (typeof id === 'string' || isObjectID(id)) {
|
|
127
128
|
const args = { user: hook.params.user }
|
|
128
129
|
let object
|
|
129
130
|
try {
|
|
130
131
|
// Get by ID or name ?
|
|
131
|
-
if (
|
|
132
|
+
if (isObjectID(id) || isValidObjectID(id)) {
|
|
132
133
|
object = await service.get(id.toString(), args)
|
|
133
134
|
} else {
|
|
134
135
|
Object.assign(args, { query: { name: id.toString() }, paginate: false })
|
|
@@ -219,11 +220,11 @@ export function populateObjects (options) {
|
|
|
219
220
|
} else {
|
|
220
221
|
debug(`Populating ${idProperty} with ID ${id}`)
|
|
221
222
|
// Let it work with id/name string or real object
|
|
222
|
-
if (typeof id === 'string' ||
|
|
223
|
+
if (typeof id === 'string' || isObjectID(id)) {
|
|
223
224
|
let object
|
|
224
225
|
try {
|
|
225
226
|
// Get by ID or name ?
|
|
226
|
-
if (
|
|
227
|
+
if (isObjectID(id) || isValidObjectID(id)) {
|
|
227
228
|
object = await service.get(id.toString(), { user: hook.params.user })
|
|
228
229
|
} else {
|
|
229
230
|
const results = await service.find({ query: { name: id.toString() }, paginate: false, user: hook.params.user })
|
|
@@ -254,15 +255,31 @@ export function unpopulateObjects (options) {
|
|
|
254
255
|
return unpopulateObject(options)
|
|
255
256
|
}
|
|
256
257
|
|
|
257
|
-
//
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
258
|
+
// Recursively transform any $regex on object to a new $regex managing diacritics.
|
|
259
|
+
// Will flag the regex items with a diacritic property in order to avoid do it twice.
|
|
260
|
+
export function toDiacriticRegex(object) {
|
|
261
|
+
if (Array.isArray(object)) {
|
|
262
|
+
object.forEach(toDiacriticRegex)
|
|
263
|
+
} else if (typeof object === 'object') {
|
|
264
|
+
_.forOwn(object, (value, key) => {
|
|
265
|
+
if (!value) return
|
|
266
|
+
// Check if applicable
|
|
267
|
+
if (value.$regex && !value.$regex.diacritic && value.$regex.source && !value.$diacriticSensitive) {
|
|
263
268
|
// Take care to support as well case sensitivity by keeping flags
|
|
264
|
-
|
|
269
|
+
value.$regex = new RegExp(makeDiacriticPattern(value.$regex.source), value.$regex.flags)
|
|
270
|
+
// Custom internal property to make the hook reentrant
|
|
271
|
+
value.$regex.diacritic = true
|
|
272
|
+
} else {
|
|
273
|
+
toDiacriticRegex(value)
|
|
265
274
|
}
|
|
266
275
|
})
|
|
267
276
|
}
|
|
268
277
|
}
|
|
278
|
+
|
|
279
|
+
// Used to manage diacritic insensitive fuzzy search
|
|
280
|
+
export function diacriticSearch (options = {}) {
|
|
281
|
+
return hook => {
|
|
282
|
+
const query = hook.params.query
|
|
283
|
+
if (query) toDiacriticRegex(query)
|
|
284
|
+
}
|
|
285
|
+
}
|
|
@@ -3,9 +3,8 @@ import makeDebug from 'debug'
|
|
|
3
3
|
import generateRandomPassword from 'password-generator'
|
|
4
4
|
import common from 'feathers-hooks-common'
|
|
5
5
|
import errors from '@feathersjs/errors'
|
|
6
|
-
import { Roles, RoleNames } from '../../common/permissions.js'
|
|
7
6
|
import authManagement from 'feathers-authentication-management'
|
|
8
|
-
|
|
7
|
+
import { createObjectID } from '../db.js'
|
|
9
8
|
const { Forbidden, BadRequest } = errors
|
|
10
9
|
const { getItems, replaceItems } = common
|
|
11
10
|
const verifyHooks = authManagement.hooks
|
|
@@ -21,23 +20,37 @@ export function allowLocalAuthentication (context) {
|
|
|
21
20
|
return _.get(context.app.get('authentication'), 'authStrategies', []).includes('local')
|
|
22
21
|
}
|
|
23
22
|
|
|
24
|
-
export function
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
if (context.type === 'before') {
|
|
29
|
-
if (context.method === 'find') {
|
|
30
|
-
context.params.query = {
|
|
31
|
-
...context.params.query,
|
|
32
|
-
_id: userId
|
|
33
|
-
}
|
|
34
|
-
return context
|
|
23
|
+
export function onlyMe (options = { throwOnMissingUser: true }) {
|
|
24
|
+
return function (context) {
|
|
25
|
+
if (context.type !== 'before') {
|
|
26
|
+
throw new Error('The \'onlyMe\' hook should only be used as a \'before\' hook.')
|
|
35
27
|
}
|
|
36
|
-
|
|
28
|
+
const userId = _.toString(_.get(context.params, 'user._id'))
|
|
29
|
+
if (userId) {
|
|
30
|
+
_.set(context.params, 'query._id', createObjectID(userId))
|
|
31
|
+
} else if (options.throwOnMissingUser) {
|
|
32
|
+
throw new Forbidden('This operation is subject to user identify check but none can be found')
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export function isNotMe (options = { throwOnMissingUser: false }) {
|
|
38
|
+
return function (context) {
|
|
39
|
+
const userId = _.get(context.params, 'user._id')
|
|
40
|
+
// As no user to compare with can't be me
|
|
41
|
+
if (_.isNil(userId)) {
|
|
42
|
+
if (options.throwOnMissingUser) throw new Forbidden('This operation is subject to user identify check but none can be found')
|
|
43
|
+
else return true
|
|
44
|
+
}
|
|
45
|
+
// Manage get/update/patch/remove before hook
|
|
46
|
+
if (context.id) return (_.toString(context.id) !== _.toString(userId))
|
|
47
|
+
// Manage after hook including multi-operations
|
|
48
|
+
let items = getItems(context)
|
|
49
|
+
if (!Array.isArray(items)) items = [items]
|
|
50
|
+
items = items.filter(item => _.toString(item._id) !== _.toString(userId))
|
|
51
|
+
// If any item not targetting myself
|
|
52
|
+
return items.length > 0
|
|
37
53
|
}
|
|
38
|
-
// After hook
|
|
39
|
-
const item = getItems(context)
|
|
40
|
-
return _.toString(item._id) !== userId
|
|
41
54
|
}
|
|
42
55
|
|
|
43
56
|
export function enforcePasswordPolicy (options = {}) {
|
|
@@ -60,7 +60,7 @@ export default {
|
|
|
60
60
|
let resources = _.remove(scope, resource => resource._id && (resource._id.toString() === id.toString()))
|
|
61
61
|
if (resources.length === 0) {
|
|
62
62
|
// Fallback as name
|
|
63
|
-
resources = _.remove(scope, resource => resource.name && (resource.name === id))
|
|
63
|
+
resources = _.remove(scope, resource => resource.name && (resource.name === id.toString()))
|
|
64
64
|
}
|
|
65
65
|
if (resources.length > 0) {
|
|
66
66
|
// This cover the case when we create the scope on the first auth,
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import commonHooks from 'feathers-hooks-common'
|
|
2
|
+
|
|
3
|
+
export default {
|
|
4
|
+
before: {
|
|
5
|
+
all: [],
|
|
6
|
+
find: [],
|
|
7
|
+
get: [],
|
|
8
|
+
create: [commonHooks.disallow('external')],
|
|
9
|
+
update: [commonHooks.disallow()],
|
|
10
|
+
patch: [],
|
|
11
|
+
remove: [commonHooks.disallow()]
|
|
12
|
+
},
|
|
13
|
+
|
|
14
|
+
after: {
|
|
15
|
+
all: [],
|
|
16
|
+
find: [],
|
|
17
|
+
get: [],
|
|
18
|
+
create: [],
|
|
19
|
+
update: [],
|
|
20
|
+
patch: [],
|
|
21
|
+
remove: []
|
|
22
|
+
},
|
|
23
|
+
|
|
24
|
+
error: {
|
|
25
|
+
all: [],
|
|
26
|
+
find: [],
|
|
27
|
+
get: [],
|
|
28
|
+
create: [],
|
|
29
|
+
update: [],
|
|
30
|
+
patch: [],
|
|
31
|
+
remove: []
|
|
32
|
+
}
|
|
33
|
+
}
|
|
@@ -3,6 +3,7 @@ import path from 'path'
|
|
|
3
3
|
import makeDebug from 'debug'
|
|
4
4
|
import { fileURLToPath } from 'url'
|
|
5
5
|
import mongodb from 'mongodb'
|
|
6
|
+
import { isValidObjectID } from '../db.js'
|
|
6
7
|
const { ObjectID } = mongodb
|
|
7
8
|
|
|
8
9
|
const __dirname = path.dirname(fileURLToPath(import.meta.url))
|
|
@@ -18,11 +19,8 @@ export function getServiceNameAndContext (servicePath) {
|
|
|
18
19
|
// Then without context if any
|
|
19
20
|
const lastSlash = name.lastIndexOf('/')
|
|
20
21
|
const contextId = (lastSlash >= 0 ? name.substring(0, lastSlash) : '')
|
|
21
|
-
// Check if
|
|
22
|
-
|
|
23
|
-
// Regular expression that checks for hex value
|
|
24
|
-
const checkForHexRegExp = /^[0-9a-fA-F]{24}$/
|
|
25
|
-
if (contextId && (contextId.length === 24) && checkForHexRegExp.test(contextId)) {
|
|
22
|
+
// Check if it is a valid MongoDB Object ID otherwise it is not a context string
|
|
23
|
+
if (isValidObjectID(contextId)) {
|
|
26
24
|
name = name.replace(contextId + '/', '')
|
|
27
25
|
return { name, contextId }
|
|
28
26
|
} else {
|
|
@@ -80,6 +78,36 @@ export function removeMessagesService (options = {}) {
|
|
|
80
78
|
return app.removeService(app.getService('messages', options.context))
|
|
81
79
|
}
|
|
82
80
|
|
|
81
|
+
export function createConfigurationsService (options = {}) {
|
|
82
|
+
const app = this
|
|
83
|
+
return app.createService('configurations', Object.assign({
|
|
84
|
+
servicesPath,
|
|
85
|
+
modelsPath
|
|
86
|
+
}, options))
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export async function createDefaultConfigurations (context) {
|
|
90
|
+
const app = this
|
|
91
|
+
const defaultConfigurations = app.get('defaultConfigurations')
|
|
92
|
+
if (!defaultConfigurations) return
|
|
93
|
+
const configurationsService = app.getService('configurations', context)
|
|
94
|
+
// Create default configurations if not already done
|
|
95
|
+
const configurations = await configurationsService.find({ paginate: false })
|
|
96
|
+
for (let i = 0; i < defaultConfigurations.length; i++) {
|
|
97
|
+
const defaultConfiguration = defaultConfigurations[i]
|
|
98
|
+
const createdConfiguration = _.find(configurations, { name: defaultConfiguration.name })
|
|
99
|
+
if (!createdConfiguration) {
|
|
100
|
+
app.logger.info('Initializing default configuration (name = ' + defaultConfiguration.name + ')')
|
|
101
|
+
await configurationsService.create(defaultConfiguration)
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export function removeConfigurationsService (options = {}) {
|
|
107
|
+
const app = this
|
|
108
|
+
return app.removeService(app.getService('configurations', options.context))
|
|
109
|
+
}
|
|
110
|
+
|
|
83
111
|
export function createDatabasesService (options = {}) {
|
|
84
112
|
const app = this
|
|
85
113
|
|
|
@@ -101,11 +129,11 @@ export function createTagsService (options = {}) {
|
|
|
101
129
|
}, options))
|
|
102
130
|
}
|
|
103
131
|
|
|
104
|
-
export async function createDefaultTags () {
|
|
132
|
+
export async function createDefaultTags (context) {
|
|
105
133
|
const app = this
|
|
106
134
|
const defaultTags = app.get('tags').defaultTags
|
|
107
135
|
if (!defaultTags) return
|
|
108
|
-
const tagsService = app.getService('tags')
|
|
136
|
+
const tagsService = app.getService('tags', context)
|
|
109
137
|
// Create default tags if not already done
|
|
110
138
|
const tags = await tagsService.find({ paginate: false })
|
|
111
139
|
for (let i = 0; i < defaultTags.length; i++) {
|
|
@@ -177,4 +205,10 @@ export default async function () {
|
|
|
177
205
|
await createTagsService.call(app, tagsConfig)
|
|
178
206
|
debug('\'tags\' service created')
|
|
179
207
|
}
|
|
208
|
+
|
|
209
|
+
const configurationsConfig = app.get('configurations')
|
|
210
|
+
if (configurationsConfig) {
|
|
211
|
+
await createConfigurationsService.call(app, configurationsConfig)
|
|
212
|
+
debug('\'configurations\' service created')
|
|
213
|
+
}
|
|
180
214
|
}
|
|
@@ -11,9 +11,15 @@ export default {
|
|
|
11
11
|
marshallComparisonQuery
|
|
12
12
|
],
|
|
13
13
|
get: [],
|
|
14
|
-
create: [commonHooks.setNow('createdAt')],
|
|
15
|
-
update: [
|
|
16
|
-
|
|
14
|
+
create: [commonHooks.setNow('createdAt', 'updatedAt')],
|
|
15
|
+
update: [
|
|
16
|
+
commonHooks.discard('createdAt', 'updatedAt'),
|
|
17
|
+
commonHooks.setNow('updatedAt')
|
|
18
|
+
],
|
|
19
|
+
patch: [
|
|
20
|
+
commonHooks.discard('createdAt', 'updatedAt'),
|
|
21
|
+
commonHooks.setNow('updatedAt')
|
|
22
|
+
],
|
|
17
23
|
remove: []
|
|
18
24
|
},
|
|
19
25
|
|
package/core/client/api.js
CHANGED
|
@@ -9,6 +9,7 @@ import { rx as reactive } from 'feathers-reactive'
|
|
|
9
9
|
import createOfflineService from '@kalisio/feathers-localforage'
|
|
10
10
|
import configuration from 'config'
|
|
11
11
|
import { permissions } from '../common/index.js'
|
|
12
|
+
import { Context } from './context.js'
|
|
12
13
|
import { Store } from './store.js'
|
|
13
14
|
import { LocalCache } from './local-cache.js'
|
|
14
15
|
import { Events } from './events.js'
|
|
@@ -103,10 +104,14 @@ export async function createClient (config) {
|
|
|
103
104
|
let service
|
|
104
105
|
// If a context is given use it
|
|
105
106
|
if (!_.isEmpty(context)) {
|
|
107
|
+
// The reserved 'global' context actually means no context.
|
|
108
|
+
// It can be used to force access to a global service even if a context is set in store
|
|
109
|
+
// as by default it will otherwise retrieve the contextual service if no context is provided
|
|
110
|
+
if (context === 'global') context = null
|
|
106
111
|
const servicePath = api.getServicePath(name, context)
|
|
107
112
|
service = (options.create ? api.service(servicePath) : api.services[servicePath])
|
|
108
113
|
} else { // Otherwise check for a potential current context to be used
|
|
109
|
-
const currentContext =
|
|
114
|
+
const currentContext = Context.get()
|
|
110
115
|
const contextualPath = api.getServicePath(name, currentContext)
|
|
111
116
|
const contextualService = api.services[contextualPath]
|
|
112
117
|
const globalPath = api.getServicePath(name)
|
|
@@ -152,6 +157,9 @@ export async function createClient (config) {
|
|
|
152
157
|
}
|
|
153
158
|
return service
|
|
154
159
|
}
|
|
160
|
+
api.hasService = function (name, context) {
|
|
161
|
+
return !_.isNil(api.getServiceInstance(name, context))
|
|
162
|
+
}
|
|
155
163
|
// Used to create a frontend only service with its options
|
|
156
164
|
api.createService = function (name, options = {}) {
|
|
157
165
|
const servicePath = api.getServicePath(name, options.context)
|
|
@@ -261,6 +269,11 @@ export async function createClient (config) {
|
|
|
261
269
|
let result
|
|
262
270
|
// If no service we have a single generic operation
|
|
263
271
|
if (service) {
|
|
272
|
+
if (!_.isEmpty(context)) {
|
|
273
|
+
if (context === 'global') context = null
|
|
274
|
+
} else if (context === undefined) {
|
|
275
|
+
context = Context.get()
|
|
276
|
+
}
|
|
264
277
|
// Check for access to service fisrt
|
|
265
278
|
const path = api.getServicePath(service, context, false)
|
|
266
279
|
result = permissions.hasServiceAbilities(abilities, path)
|
|
@@ -17,12 +17,7 @@ export const Capabilities = {
|
|
|
17
17
|
const capabilities = await window.fetch(api.getConfig('domain') + _.get(config, 'apiPath') + '/capabilities')
|
|
18
18
|
this.content = await capabilities.json()
|
|
19
19
|
// Store latest capabilities data for offline mode
|
|
20
|
-
|
|
21
|
-
try {
|
|
22
|
-
await LocalCache.setItem('capabilities', this.content)
|
|
23
|
-
} catch (error) {
|
|
24
|
-
logger.error(error)
|
|
25
|
-
}
|
|
20
|
+
await LocalCache.setItem('capabilities', this.content)
|
|
26
21
|
}
|
|
27
22
|
logger.debug('[KDK] Capabilities initialized with content:', this.content)
|
|
28
23
|
if (!this.content) return
|
|
@@ -1,21 +1,23 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<
|
|
3
|
-
<q-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
<q-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
2
|
+
<div>
|
|
3
|
+
<q-avatar v-if="avatar" :size="size">
|
|
4
|
+
<q-img :src="avatar" />
|
|
5
|
+
<q-tooltip v-if="tooltip">
|
|
6
|
+
{{ name }}
|
|
7
|
+
</q-tooltip>
|
|
8
|
+
</q-avatar>
|
|
9
|
+
<q-avatar v-else-if="icon" :size="size" :color="color" text-color="white" :icon="icon">
|
|
10
|
+
<q-tooltip v-if="tooltip">
|
|
11
|
+
{{ name }}
|
|
12
|
+
</q-tooltip>
|
|
13
|
+
</q-avatar>
|
|
14
|
+
<q-avatar v-else-if="initials" :size="size" color="primary" text-color="white">
|
|
15
|
+
{{ initials }}
|
|
16
|
+
<q-tooltip v-if="tooltip">
|
|
17
|
+
{{ name }}
|
|
18
|
+
</q-tooltip>
|
|
19
|
+
</q-avatar>
|
|
20
|
+
</div>
|
|
19
21
|
</template>
|
|
20
22
|
|
|
21
23
|
<script>
|
|
@@ -75,13 +77,15 @@ export default {
|
|
|
75
77
|
avatar.uri = data.uri
|
|
76
78
|
this.avatar = avatar.uri
|
|
77
79
|
*/
|
|
78
|
-
|
|
80
|
+
const options = {
|
|
79
81
|
file: _.get(avatar, 'name'),
|
|
80
82
|
key: avatarId,
|
|
81
83
|
query: {
|
|
82
84
|
timestamp: Date.now()
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
+
},
|
|
86
|
+
...(!_.isNil(_.get(this, 'options.context')) && { context: this.options.context })
|
|
87
|
+
}
|
|
88
|
+
this.avatar = await Storage.getObjectUrl(options)
|
|
85
89
|
return
|
|
86
90
|
}
|
|
87
91
|
this.avatar = null
|
|
@@ -1,18 +1,13 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div v-if="User" class="full-width column">
|
|
3
3
|
<!-- Header -->
|
|
4
|
-
<
|
|
5
|
-
id="profile-header"
|
|
6
|
-
:content="header"
|
|
7
|
-
:context="User"
|
|
8
|
-
class="q-py-sm full-width justify-end no-wrap"
|
|
9
|
-
@triggered="onTriggered"
|
|
10
|
-
/>
|
|
4
|
+
<component v-if="hasHeader" :is="computedHeaderComponent" class="q-py-sm full-width justify-end no-wrap" />
|
|
11
5
|
<!-- Avatar -->
|
|
12
6
|
<div v-if="avatar && userAvatar" class="q-py-sm column items-center">
|
|
13
7
|
<KAvatar
|
|
14
8
|
:subject="userAvatar"
|
|
15
9
|
size="5rem"
|
|
10
|
+
:options="options"
|
|
16
11
|
/>
|
|
17
12
|
</div>
|
|
18
13
|
<!-- Information -->
|
|
@@ -41,20 +36,13 @@
|
|
|
41
36
|
import _ from 'lodash'
|
|
42
37
|
import { computed } from 'vue'
|
|
43
38
|
import { useUser } from '../../composables'
|
|
39
|
+
import { loadComponent } from '../../utils/index.js'
|
|
40
|
+
import config from 'config'
|
|
44
41
|
import KAvatar from '../KAvatar.vue'
|
|
45
|
-
import KPanel from '../KPanel.vue'
|
|
46
42
|
import KChip from '../KChip.vue'
|
|
47
43
|
|
|
48
44
|
// Props
|
|
49
|
-
|
|
50
|
-
editable: {
|
|
51
|
-
type: Boolean,
|
|
52
|
-
default: true
|
|
53
|
-
},
|
|
54
|
-
manageable: {
|
|
55
|
-
type: Boolean,
|
|
56
|
-
default: true
|
|
57
|
-
},
|
|
45
|
+
defineProps({
|
|
58
46
|
avatar: {
|
|
59
47
|
type: Boolean,
|
|
60
48
|
default: true
|
|
@@ -69,63 +57,14 @@ const props = defineProps({
|
|
|
69
57
|
}
|
|
70
58
|
})
|
|
71
59
|
|
|
72
|
-
// Emit
|
|
73
|
-
const emit = defineEmits(['triggered'])
|
|
74
|
-
|
|
75
60
|
// Data
|
|
76
61
|
const { User, name: userName, description: userDescription, avatar: userAvatar, role: userRole } = useUser()
|
|
62
|
+
const headerComponent = _.get(config, 'profile.header')
|
|
63
|
+
const hasHeader = !_.isNil(headerComponent)
|
|
64
|
+
const options = { context: 'global' }
|
|
77
65
|
|
|
78
66
|
// Computed
|
|
79
|
-
const
|
|
80
|
-
|
|
81
|
-
if (props.editable) {
|
|
82
|
-
actions.push({
|
|
83
|
-
id: 'edit-profile',
|
|
84
|
-
icon: 'las la-edit',
|
|
85
|
-
size: '0.75rem',
|
|
86
|
-
tooltip: 'KProfile.EDIT_PROFILE',
|
|
87
|
-
dialog: {
|
|
88
|
-
component: 'editor/KEditor',
|
|
89
|
-
service: 'users',
|
|
90
|
-
objectId: User.value._id,
|
|
91
|
-
perspective: 'profile',
|
|
92
|
-
hideButtons: true,
|
|
93
|
-
cancelAction: 'CANCEL',
|
|
94
|
-
okAction: {
|
|
95
|
-
id: 'ok-button',
|
|
96
|
-
label: 'APPLY',
|
|
97
|
-
handler: 'apply'
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
})
|
|
101
|
-
}
|
|
102
|
-
if (props.manageable) {
|
|
103
|
-
const manageAccountAction = {
|
|
104
|
-
id: 'manage-account',
|
|
105
|
-
icon: 'las la-cog',
|
|
106
|
-
size: '0.75rem',
|
|
107
|
-
tooltip: 'KProfile.MANAGE_ACCOUNT',
|
|
108
|
-
dialog: {
|
|
109
|
-
component: 'account/KAccount',
|
|
110
|
-
okAction: 'CLOSE'
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
if (_.has(User.value, 'isVerified') && !User.value.isVerified) {
|
|
114
|
-
manageAccountAction.badge = {
|
|
115
|
-
rounded: true,
|
|
116
|
-
floating: true,
|
|
117
|
-
class: 'q-ma-sm',
|
|
118
|
-
color: 'red',
|
|
119
|
-
icon: { name: 'fas fa-exclamation', size: '8px' }
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
actions.push(manageAccountAction)
|
|
123
|
-
}
|
|
124
|
-
return actions
|
|
67
|
+
const computedHeaderComponent = computed(() => {
|
|
68
|
+
return loadComponent(headerComponent)
|
|
125
69
|
})
|
|
126
|
-
|
|
127
|
-
// Functions
|
|
128
|
-
function onTriggered (args) {
|
|
129
|
-
emit('triggered', args)
|
|
130
|
-
}
|
|
131
70
|
</script>
|