@kalisio/kdk 2.0.1 → 2.1.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/.codeclimate.yml +0 -1
- package/.travis.test.sh +3 -0
- package/core/api/application.js +13 -9
- package/core/api/db.js +34 -30
- package/core/api/hooks/hooks.authentication.js +11 -0
- package/core/api/hooks/hooks.authorisations.js +7 -3
- package/core/api/hooks/hooks.model.js +32 -43
- package/core/api/hooks/hooks.organisations.js +26 -116
- package/core/api/hooks/{hooks.devices.js → hooks.push.js} +22 -10
- package/core/api/hooks/hooks.query.js +0 -5
- package/core/api/hooks/hooks.schemas.js +23 -3
- package/core/api/hooks/hooks.users.js +15 -22
- package/core/api/hooks/index.js +1 -4
- package/core/api/services/account/account.hooks.js +3 -3
- package/core/api/services/account/account.service.js +5 -6
- package/core/api/services/groups/groups.hooks.js +2 -4
- package/core/api/services/index.js +11 -16
- package/core/api/services/{devices/devices.hooks.js → push/push.hooks.js} +5 -5
- package/core/api/services/push/push.service.js +12 -0
- package/core/api/services/tags/tags.hooks.js +6 -20
- package/core/api/services/users/users.hooks.js +12 -13
- package/core/api/utils.js +11 -0
- package/core/client/api.js +6 -0
- package/core/client/capabilities.js +8 -12
- package/core/client/components/KAction.vue +10 -3
- package/core/client/components/KAvatar.vue +31 -35
- package/core/client/components/KChipsPane.vue +23 -0
- package/core/client/components/account/KAccount.vue +68 -0
- package/core/client/components/account/KDeleteAccountManager.vue +62 -0
- package/core/client/components/account/KEmailManager.vue +128 -0
- package/core/client/components/account/KPasswordManager.vue +90 -0
- package/core/client/components/account/KProfile.vue +109 -0
- package/core/client/components/account/KResetPassword.vue +100 -111
- package/core/client/components/account/KSendResetPassword.vue +71 -87
- package/core/client/components/account/KSubscription.vue +71 -0
- package/core/client/components/account/KSubscriptionsManager.vue +46 -0
- package/core/client/components/account/KVerifyEmailManager.vue +105 -0
- package/core/client/components/account/index.js +4 -2
- package/core/client/components/app/KAbout.vue +27 -14
- package/core/client/components/app/KPlatform.vue +2 -2
- package/core/client/components/app/KWelcome.vue +71 -45
- package/core/client/components/collection/KBoard.vue +50 -40
- package/core/client/components/collection/KCard.vue +16 -7
- package/core/client/components/collection/KColumn.vue +146 -111
- package/core/client/components/collection/KGrid.vue +77 -58
- package/core/client/components/collection/KHistory.vue +19 -3
- package/core/client/components/collection/KItem.vue +5 -1
- package/core/client/components/collection/KList.vue +80 -56
- package/core/client/components/collection/KTable.vue +181 -142
- package/core/client/components/editor/KEditor.vue +10 -3
- package/core/client/components/form/KFileField.vue +22 -8
- package/core/client/components/form/KForm.vue +27 -14
- package/core/client/components/form/KItemField.vue +2 -2
- package/core/client/components/form/KOptionsField.vue +11 -2
- package/core/client/components/form/KSelectField.vue +12 -3
- package/core/client/components/form/KTextField.vue +6 -0
- package/core/client/components/form/KTokenField.vue +80 -0
- package/core/client/components/layout/KOpener.vue +8 -8
- package/core/client/components/layout/KPage.vue +8 -4
- package/core/client/components/layout/KWindow.vue +172 -141
- package/core/client/components/media/KMediaBrowser.vue +28 -12
- package/core/client/components/media/KShape.vue +58 -56
- package/core/client/components/menu/KMenu.vue +22 -13
- package/core/client/components/menu/KRadialFab.vue +83 -56
- package/core/client/components/menu/KRadialFabItem.vue +39 -19
- package/core/client/components/screen/KLoginScreen.vue +0 -17
- package/core/client/components/screen/KScreen.vue +3 -3
- package/core/client/components/screen/KScreenFooter.vue +0 -3
- package/core/client/components/team/KAddMember.vue +1 -1
- package/core/client/components/team/KAddTag.vue +121 -0
- package/core/client/components/team/KMemberCard.vue +42 -13
- package/core/client/components/team/KMembersActivity.vue +9 -3
- package/core/client/components/team/KTagCard.vue +16 -1
- package/core/client/composables/collection.js +181 -0
- package/core/client/composables/index.js +2 -0
- package/core/client/composables/pwa.js +71 -0
- package/core/client/composables/session.js +6 -9
- package/core/client/composables/version.js +1 -22
- package/core/client/i18n/core_en.json +124 -153
- package/core/client/i18n/core_fr.json +124 -155
- package/core/client/index.js +37 -110
- package/core/client/layout.js +37 -14
- package/core/client/local-storage.js +4 -3
- package/core/client/mixins/mixin.account.js +9 -5
- package/core/client/mixins/mixin.base-editor.js +19 -3
- package/core/client/mixins/mixin.base-item.js +3 -3
- package/core/client/mixins/mixin.base-viewer.js +14 -0
- package/core/client/mixins/mixin.object-proxy.js +2 -21
- package/core/client/services/index.js +0 -1
- package/core/client/storage.js +19 -16
- package/core/client/theme.js +11 -5
- package/core/client/utils/index.js +5 -13
- package/core/client/utils/utils.account.js +47 -0
- package/core/client/utils/utils.colors.js +6 -2
- package/core/client/utils/utils.content.js +7 -5
- package/core/client/utils/utils.platform.js +1 -20
- package/core/client/utils/utils.push.js +53 -0
- package/core/client/utils/utils.pwa.js +63 -0
- package/core/client/utils/utils.session.js +27 -12
- package/core/common/permissions.js +12 -4
- package/core/common/schemas/tags.create.json +35 -0
- package/core/common/schemas/users.update-profile.json +1 -1
- package/coverage/base.css +224 -0
- package/coverage/block-navigation.js +87 -0
- package/coverage/core/api/application.js.html +1849 -0
- package/coverage/core/api/authentication.js.html +694 -0
- package/coverage/core/api/db.js.html +763 -0
- package/coverage/core/api/hooks/hooks.account.js.html +169 -0
- package/coverage/core/api/hooks/hooks.authentication.js.html +274 -0
- package/coverage/core/api/hooks/hooks.authorisations.js.html +1213 -0
- package/coverage/core/api/hooks/hooks.groups.js.html +229 -0
- package/coverage/core/api/hooks/hooks.logger.js.html +163 -0
- package/coverage/core/api/hooks/hooks.model.js.html +994 -0
- package/coverage/core/api/hooks/hooks.organisations.js.html +553 -0
- package/coverage/core/api/hooks/hooks.push.js.html +232 -0
- package/coverage/core/api/hooks/hooks.query.js.html +838 -0
- package/coverage/core/api/hooks/hooks.schemas.js.html +304 -0
- package/coverage/core/api/hooks/hooks.service.js.html +319 -0
- package/coverage/core/api/hooks/hooks.storage.js.html +193 -0
- package/coverage/core/api/hooks/hooks.tags.js.html +850 -0
- package/coverage/core/api/hooks/hooks.users.js.html +826 -0
- package/coverage/core/api/hooks/index.html +296 -0
- package/coverage/core/api/hooks/index.js.html +121 -0
- package/coverage/core/api/index.html +191 -0
- package/coverage/core/api/index.js.html +148 -0
- package/coverage/core/api/marshall.js.html +355 -0
- package/coverage/core/api/models/groups.model.mongodb.js.html +109 -0
- package/coverage/core/api/models/index.html +161 -0
- package/coverage/core/api/models/organisations.model.mongodb.js.html +94 -0
- package/coverage/core/api/models/tags.model.mongodb.js.html +115 -0
- package/coverage/core/api/models/users.model.mongodb.js.html +115 -0
- package/coverage/core/api/services/account/account.hooks.js.html +196 -0
- package/coverage/core/api/services/account/account.service.js.html +445 -0
- package/coverage/core/api/services/account/index.html +131 -0
- package/coverage/core/api/services/authorisations/authorisations.hooks.js.html +184 -0
- package/coverage/core/api/services/authorisations/authorisations.service.js.html +502 -0
- package/coverage/core/api/services/authorisations/index.html +131 -0
- package/coverage/core/api/services/databases/databases.hooks.js.html +193 -0
- package/coverage/core/api/services/databases/databases.service.js.html +100 -0
- package/coverage/core/api/services/databases/index.html +131 -0
- package/coverage/core/api/services/groups/groups.hooks.js.html +178 -0
- package/coverage/core/api/services/groups/index.html +116 -0
- package/coverage/core/api/services/index.html +116 -0
- package/coverage/core/api/services/index.js.html +475 -0
- package/coverage/core/api/services/mailer/index.html +131 -0
- package/coverage/core/api/services/mailer/mailer.hooks.js.html +190 -0
- package/coverage/core/api/services/mailer/mailer.service.js.html +118 -0
- package/coverage/core/api/services/organisations/index.html +131 -0
- package/coverage/core/api/services/organisations/organisations.hooks.js.html +178 -0
- package/coverage/core/api/services/organisations/organisations.service.js.html +343 -0
- package/coverage/core/api/services/push/index.html +131 -0
- package/coverage/core/api/services/push/push.hooks.js.html +193 -0
- package/coverage/core/api/services/push/push.service.js.html +121 -0
- package/coverage/core/api/services/storage/index.html +131 -0
- package/coverage/core/api/services/storage/storage.hooks.js.html +190 -0
- package/coverage/core/api/services/storage/storage.service.js.html +172 -0
- package/coverage/core/api/services/tags/index.html +116 -0
- package/coverage/core/api/services/tags/tags.hooks.js.html +178 -0
- package/coverage/core/api/services/users/index.html +116 -0
- package/coverage/core/api/services/users/users.hooks.js.html +313 -0
- package/coverage/core/api/utils.js.html +118 -0
- package/coverage/core/common/errors.js.html +88 -0
- package/coverage/core/common/index.html +176 -0
- package/coverage/core/common/index.js.html +115 -0
- package/coverage/core/common/permissions.js.html +1039 -0
- package/coverage/core/common/schema.js.html +190 -0
- package/coverage/core/common/utils.js.html +220 -0
- package/coverage/favicon.png +0 -0
- package/coverage/index.html +476 -0
- package/coverage/lcov-report/base.css +224 -0
- package/coverage/lcov-report/block-navigation.js +87 -0
- package/coverage/lcov-report/core/api/application.js.html +1849 -0
- package/coverage/lcov-report/core/api/authentication.js.html +694 -0
- package/coverage/lcov-report/core/api/db.js.html +763 -0
- package/coverage/lcov-report/core/api/hooks/hooks.account.js.html +169 -0
- package/coverage/lcov-report/core/api/hooks/hooks.authentication.js.html +274 -0
- package/coverage/lcov-report/core/api/hooks/hooks.authorisations.js.html +1213 -0
- package/coverage/lcov-report/core/api/hooks/hooks.groups.js.html +229 -0
- package/coverage/lcov-report/core/api/hooks/hooks.logger.js.html +163 -0
- package/coverage/lcov-report/core/api/hooks/hooks.model.js.html +994 -0
- package/coverage/lcov-report/core/api/hooks/hooks.organisations.js.html +553 -0
- package/coverage/lcov-report/core/api/hooks/hooks.push.js.html +232 -0
- package/coverage/lcov-report/core/api/hooks/hooks.query.js.html +838 -0
- package/coverage/lcov-report/core/api/hooks/hooks.schemas.js.html +304 -0
- package/coverage/lcov-report/core/api/hooks/hooks.service.js.html +319 -0
- package/coverage/lcov-report/core/api/hooks/hooks.storage.js.html +193 -0
- package/coverage/lcov-report/core/api/hooks/hooks.tags.js.html +850 -0
- package/coverage/lcov-report/core/api/hooks/hooks.users.js.html +826 -0
- package/coverage/lcov-report/core/api/hooks/index.html +296 -0
- package/coverage/lcov-report/core/api/hooks/index.js.html +121 -0
- package/coverage/lcov-report/core/api/index.html +191 -0
- package/coverage/lcov-report/core/api/index.js.html +148 -0
- package/coverage/lcov-report/core/api/marshall.js.html +355 -0
- package/coverage/lcov-report/core/api/models/groups.model.mongodb.js.html +109 -0
- package/coverage/lcov-report/core/api/models/index.html +161 -0
- package/coverage/lcov-report/core/api/models/organisations.model.mongodb.js.html +94 -0
- package/coverage/lcov-report/core/api/models/tags.model.mongodb.js.html +115 -0
- package/coverage/lcov-report/core/api/models/users.model.mongodb.js.html +115 -0
- package/coverage/lcov-report/core/api/services/account/account.hooks.js.html +196 -0
- package/coverage/lcov-report/core/api/services/account/account.service.js.html +445 -0
- package/coverage/lcov-report/core/api/services/account/index.html +131 -0
- package/coverage/lcov-report/core/api/services/authorisations/authorisations.hooks.js.html +184 -0
- package/coverage/lcov-report/core/api/services/authorisations/authorisations.service.js.html +502 -0
- package/coverage/lcov-report/core/api/services/authorisations/index.html +131 -0
- package/coverage/lcov-report/core/api/services/databases/databases.hooks.js.html +193 -0
- package/coverage/lcov-report/core/api/services/databases/databases.service.js.html +100 -0
- package/coverage/lcov-report/core/api/services/databases/index.html +131 -0
- package/coverage/lcov-report/core/api/services/groups/groups.hooks.js.html +178 -0
- package/coverage/lcov-report/core/api/services/groups/index.html +116 -0
- package/coverage/lcov-report/core/api/services/index.html +116 -0
- package/coverage/lcov-report/core/api/services/index.js.html +475 -0
- package/coverage/lcov-report/core/api/services/mailer/index.html +131 -0
- package/coverage/lcov-report/core/api/services/mailer/mailer.hooks.js.html +190 -0
- package/coverage/lcov-report/core/api/services/mailer/mailer.service.js.html +118 -0
- package/coverage/lcov-report/core/api/services/organisations/index.html +131 -0
- package/coverage/lcov-report/core/api/services/organisations/organisations.hooks.js.html +178 -0
- package/coverage/lcov-report/core/api/services/organisations/organisations.service.js.html +343 -0
- package/coverage/lcov-report/core/api/services/push/index.html +131 -0
- package/coverage/lcov-report/core/api/services/push/push.hooks.js.html +193 -0
- package/coverage/lcov-report/core/api/services/push/push.service.js.html +121 -0
- package/coverage/lcov-report/core/api/services/storage/index.html +131 -0
- package/coverage/lcov-report/core/api/services/storage/storage.hooks.js.html +190 -0
- package/coverage/lcov-report/core/api/services/storage/storage.service.js.html +172 -0
- package/coverage/lcov-report/core/api/services/tags/index.html +116 -0
- package/coverage/lcov-report/core/api/services/tags/tags.hooks.js.html +178 -0
- package/coverage/lcov-report/core/api/services/users/index.html +116 -0
- package/coverage/lcov-report/core/api/services/users/users.hooks.js.html +313 -0
- package/coverage/lcov-report/core/api/utils.js.html +118 -0
- package/coverage/lcov-report/core/common/errors.js.html +88 -0
- package/coverage/lcov-report/core/common/index.html +176 -0
- package/coverage/lcov-report/core/common/index.js.html +115 -0
- package/coverage/lcov-report/core/common/permissions.js.html +1039 -0
- package/coverage/lcov-report/core/common/schema.js.html +190 -0
- package/coverage/lcov-report/core/common/utils.js.html +220 -0
- package/coverage/lcov-report/favicon.png +0 -0
- package/coverage/lcov-report/index.html +476 -0
- package/coverage/lcov-report/map/api/hooks/hooks.catalog.js.html +340 -0
- package/coverage/lcov-report/map/api/hooks/hooks.features.js.html +337 -0
- package/coverage/lcov-report/map/api/hooks/hooks.query.js.html +1168 -0
- package/coverage/lcov-report/map/api/hooks/index.html +161 -0
- package/coverage/lcov-report/map/api/hooks/index.js.html +94 -0
- package/coverage/lcov-report/map/api/index.html +131 -0
- package/coverage/lcov-report/map/api/index.js.html +139 -0
- package/coverage/lcov-report/map/api/marshall.js.html +178 -0
- package/coverage/lcov-report/map/api/models/alerts.model.mongodb.js.html +106 -0
- package/coverage/lcov-report/map/api/models/catalog.model.mongodb.js.html +127 -0
- package/coverage/lcov-report/map/api/models/features.model.mongodb.js.html +196 -0
- package/coverage/lcov-report/map/api/models/index.html +146 -0
- package/coverage/lcov-report/map/api/services/alerts/alerts.hooks.js.html +274 -0
- package/coverage/lcov-report/map/api/services/alerts/alerts.service.js.html +610 -0
- package/coverage/lcov-report/map/api/services/alerts/index.html +131 -0
- package/coverage/lcov-report/map/api/services/catalog/catalog.hooks.js.html +313 -0
- package/coverage/lcov-report/map/api/services/catalog/index.html +116 -0
- package/coverage/lcov-report/map/api/services/daptiles/daptiles.service.js.html +1510 -0
- package/coverage/lcov-report/map/api/services/daptiles/index.html +116 -0
- package/coverage/lcov-report/map/api/services/features/features.hooks.js.html +205 -0
- package/coverage/lcov-report/map/api/services/features/features.service.js.html +241 -0
- package/coverage/lcov-report/map/api/services/features/index.html +131 -0
- package/coverage/lcov-report/map/api/services/geocoder/geocoder.hooks.js.html +178 -0
- package/coverage/lcov-report/map/api/services/geocoder/geocoder.service.js.html +322 -0
- package/coverage/lcov-report/map/api/services/geocoder/index.html +131 -0
- package/coverage/lcov-report/map/api/services/index.html +116 -0
- package/coverage/lcov-report/map/api/services/index.js.html +769 -0
- package/coverage/lcov-report/map/common/dynamic-grid-source.js.html +466 -0
- package/coverage/lcov-report/map/common/errors.js.html +94 -0
- package/coverage/lcov-report/map/common/geotiff-grid-source.js.html +535 -0
- package/coverage/lcov-report/map/common/grid.js.html +1612 -0
- package/coverage/lcov-report/map/common/index.html +371 -0
- package/coverage/lcov-report/map/common/index.js.html +172 -0
- package/coverage/lcov-report/map/common/meteo-model-grid-source.js.html +556 -0
- package/coverage/lcov-report/map/common/moment-utils.js.html +157 -0
- package/coverage/lcov-report/map/common/opendap-grid-source.js.html +868 -0
- package/coverage/lcov-report/map/common/opendap-utils.js.html +826 -0
- package/coverage/lcov-report/map/common/permissions.js.html +118 -0
- package/coverage/lcov-report/map/common/time-based-grid-source.js.html +418 -0
- package/coverage/lcov-report/map/common/tms-utils.js.html +274 -0
- package/coverage/lcov-report/map/common/wcs-grid-source.js.html +364 -0
- package/coverage/lcov-report/map/common/wcs-utils.js.html +586 -0
- package/coverage/lcov-report/map/common/weacast-grid-source.js.html +1033 -0
- package/coverage/lcov-report/map/common/wfs-utils.js.html +574 -0
- package/coverage/lcov-report/map/common/wms-utils.js.html +436 -0
- package/coverage/lcov-report/map/common/wmts-utils.js.html +547 -0
- package/coverage/lcov-report/prettify.css +1 -0
- package/coverage/lcov-report/prettify.js +2 -0
- package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
- package/coverage/lcov-report/sorter.js +196 -0
- package/coverage/lcov.info +10742 -0
- package/coverage/map/api/hooks/hooks.catalog.js.html +340 -0
- package/coverage/map/api/hooks/hooks.features.js.html +337 -0
- package/coverage/map/api/hooks/hooks.query.js.html +1168 -0
- package/coverage/map/api/hooks/index.html +161 -0
- package/coverage/map/api/hooks/index.js.html +94 -0
- package/coverage/map/api/index.html +131 -0
- package/coverage/map/api/index.js.html +139 -0
- package/coverage/map/api/marshall.js.html +178 -0
- package/coverage/map/api/models/alerts.model.mongodb.js.html +106 -0
- package/coverage/map/api/models/catalog.model.mongodb.js.html +127 -0
- package/coverage/map/api/models/features.model.mongodb.js.html +196 -0
- package/coverage/map/api/models/index.html +146 -0
- package/coverage/map/api/services/alerts/alerts.hooks.js.html +274 -0
- package/coverage/map/api/services/alerts/alerts.service.js.html +610 -0
- package/coverage/map/api/services/alerts/index.html +131 -0
- package/coverage/map/api/services/catalog/catalog.hooks.js.html +313 -0
- package/coverage/map/api/services/catalog/index.html +116 -0
- package/coverage/map/api/services/daptiles/daptiles.service.js.html +1510 -0
- package/coverage/map/api/services/daptiles/index.html +116 -0
- package/coverage/map/api/services/features/features.hooks.js.html +205 -0
- package/coverage/map/api/services/features/features.service.js.html +241 -0
- package/coverage/map/api/services/features/index.html +131 -0
- package/coverage/map/api/services/geocoder/geocoder.hooks.js.html +178 -0
- package/coverage/map/api/services/geocoder/geocoder.service.js.html +322 -0
- package/coverage/map/api/services/geocoder/index.html +131 -0
- package/coverage/map/api/services/index.html +116 -0
- package/coverage/map/api/services/index.js.html +769 -0
- package/coverage/map/common/dynamic-grid-source.js.html +466 -0
- package/coverage/map/common/errors.js.html +94 -0
- package/coverage/map/common/geotiff-grid-source.js.html +535 -0
- package/coverage/map/common/grid.js.html +1612 -0
- package/coverage/map/common/index.html +371 -0
- package/coverage/map/common/index.js.html +172 -0
- package/coverage/map/common/meteo-model-grid-source.js.html +556 -0
- package/coverage/map/common/moment-utils.js.html +157 -0
- package/coverage/map/common/opendap-grid-source.js.html +868 -0
- package/coverage/map/common/opendap-utils.js.html +826 -0
- package/coverage/map/common/permissions.js.html +118 -0
- package/coverage/map/common/time-based-grid-source.js.html +418 -0
- package/coverage/map/common/tms-utils.js.html +274 -0
- package/coverage/map/common/wcs-grid-source.js.html +364 -0
- package/coverage/map/common/wcs-utils.js.html +586 -0
- package/coverage/map/common/weacast-grid-source.js.html +1033 -0
- package/coverage/map/common/wfs-utils.js.html +574 -0
- package/coverage/map/common/wms-utils.js.html +436 -0
- package/coverage/map/common/wmts-utils.js.html +547 -0
- package/coverage/prettify.css +1 -0
- package/coverage/prettify.js +2 -0
- package/coverage/sort-arrow-sprite.png +0 -0
- package/coverage/sorter.js +196 -0
- package/coverage/tmp/coverage-59096-1692631696256-0.json +1 -0
- package/coverage/tmp/coverage-59108-1692631696233-0.json +1 -0
- package/coverage/tmp/coverage-59119-1692631696222-0.json +1 -0
- package/coverage/tmp/coverage-59131-1692631696200-0.json +1 -0
- package/coverage/tmp/coverage-59138-1692631696175-0.json +1 -0
- package/extras/css/core.variables.scss +5 -1
- package/extras/tours/core/account-profile.js +14 -31
- package/extras/tours/core/account.js +143 -0
- package/extras/tours/core/add-member.js +7 -6
- package/extras/tours/core/add-tag.js +13 -0
- package/extras/tours/core/create-tag.js +26 -0
- package/extras/tours/core/edit-member-role.js +13 -0
- package/extras/tours/core/join-group.js +0 -12
- package/extras/tours/core/login.js +0 -7
- package/extras/tours/core/members.js +13 -26
- package/extras/tours/core/send-reset-password.js +1 -1
- package/extras/tours/core/tags.js +17 -4
- package/extras/tours/map/navigation-bar.js +1 -1
- package/extras/tours/map/side-nav.js +3 -2
- package/map/api/hooks/hooks.query.js +5 -3
- package/map/client/cesium/utils.js +68 -0
- package/map/client/components/KFeatureActionButton.vue +27 -27
- package/map/client/components/KFeaturesChart.vue +1 -1
- package/map/client/components/KFeaturesTable.vue +2 -2
- package/map/client/components/KLayerEditionToolbar.vue +1 -0
- package/map/client/components/KPositionIndicator.vue +1 -1
- package/map/client/components/catalog/KViewSelector.vue +1 -2
- package/map/client/components/catalog/KViewsPanel.vue +17 -15
- package/map/client/components/form/KDirectionField.vue +0 -1
- package/map/client/components/form/KLocationField.vue +16 -29
- package/map/client/components/legend/KSymbolsLegend.vue +2 -1
- package/map/client/components/location/KLocationCardSection.vue +61 -0
- package/map/client/components/location/KLocationMap.vue +24 -13
- package/map/client/components/location/KLocationSearch.vue +144 -0
- package/map/client/components/location/KLocationTip.vue +29 -0
- package/map/client/components/tools/KGeolocateTool.vue +46 -0
- package/map/client/components/tools/KSearchTool.vue +93 -0
- package/map/client/components/widget/KElevationProfile.vue +2 -2
- package/map/client/components/widget/KInformationBox.vue +3 -3
- package/map/client/composables/location.js +35 -43
- package/map/client/geolocation.js +65 -8
- package/map/client/i18n/map_en.json +15 -13
- package/map/client/i18n/map_fr.json +15 -13
- package/map/client/init.js +10 -18
- package/map/client/leaflet/GradientPath.js +2 -1
- package/map/client/leaflet/utils.js +61 -0
- package/map/client/mixins/globe/mixin.base-globe.js +6 -5
- package/map/client/mixins/globe/mixin.popup.js +3 -0
- package/map/client/mixins/globe/mixin.style.js +9 -64
- package/map/client/mixins/globe/mixin.tooltip.js +3 -0
- package/map/client/mixins/index.js +0 -1
- package/map/client/mixins/map/mixin.base-map.js +13 -9
- package/map/client/mixins/map/mixin.edit-layers.js +82 -15
- package/map/client/mixins/map/mixin.geojson-layers.js +8 -1
- package/map/client/mixins/map/mixin.style.js +8 -56
- package/map/client/mixins/mixin.activity.js +20 -12
- package/map/client/mixins/mixin.feature-service.js +34 -1
- package/map/client/readers/reader.geojson.js +1 -1
- package/map/client/utils/utils.location.js +45 -0
- package/package.json +13 -14
- package/test/api/core/account.test.js +112 -126
- package/test/api/core/config/default.cjs +7 -11
- package/test/api/core/config/email-templates/confirmInvitation/html.ejs +1 -1
- package/test/api/core/config/email-templates/identityChange/html.ejs +6 -4
- package/test/api/core/config/email-templates/newDevice/html.ejs +1 -1
- package/test/api/core/config/email-templates/newSubscription/html.ejs +7 -0
- package/test/api/core/config/email-templates/passwordChange/html.ejs +1 -1
- package/test/api/core/config/email-templates/resendVerifySignup/html.ejs +6 -4
- package/test/api/core/config/email-templates/resetPwd/html.ejs +1 -1
- package/test/api/core/config/email-templates/sendResetPwd/html.ejs +8 -4
- package/test/api/core/hooks.test.js +166 -18
- package/test/api/core/index.test.js +32 -70
- package/test/api/core/push.test.js +191 -0
- package/test/api/core/team.test.js +38 -32
- package/test/api/core/test-log-2023-07-04.log +0 -0
- package/test/api/core/test-log-2023-07-10.log +2 -0
- package/test/api/core/test-log-2023-07-12.log +0 -0
- package/test/api/core/test-log-2023-07-18.log +78 -0
- package/test/api/core/test-log-2023-07-19.log +44 -0
- package/test/api/core/test-log-2023-08-01.log +162 -0
- package/test/api/core/test-log-2023-08-21.log +66 -0
- package/test/api/core/test-log-2023-08-22.log +96 -0
- package/test/api/core/test-log-2023-08-23.log +22 -0
- package/test/api/core/test-log-2023-09-20.log +22 -0
- package/test/api/map/alerts.test.js +1 -1
- package/test/api/map/test-log-2023-07-18.log +62 -0
- package/test/api/map/test-log-2023-07-19.log +13 -0
- package/test/api/map/test-log-2023-08-21.log +65 -0
- package/test/api/map/test-log-2023-09-20.log +60 -0
- package/test/client/core/account.js +15 -32
- package/test/client/core/api.js +99 -44
- package/test/client/core/layout.js +4 -0
- package/test/client/core/runner.js +66 -14
- package/test/client/core/time.js +1 -1
- package/test/client/map/controls.js +17 -3
- package/core/api/hooks/hooks.account.js +0 -28
- package/core/api/hooks/hooks.pusher.js +0 -215
- package/core/api/hooks/hooks.tags.js +0 -255
- package/core/api/services/devices/devices.service.js +0 -99
- package/core/api/services/pusher/pusher.channels.js +0 -3
- package/core/api/services/pusher/pusher.hooks.js +0 -36
- package/core/api/services/pusher/pusher.service.js +0 -449
- package/core/client/components/KInstallApp.vue +0 -43
- package/core/client/components/account/KAccountActivity.vue +0 -58
- package/core/client/components/account/KAccountDZ.vue +0 -66
- package/core/client/components/account/KAccountDevices.vue +0 -56
- package/core/client/components/account/KAccountSecurity.vue +0 -87
- package/core/client/components/account/KChangeIdentity.vue +0 -102
- package/core/client/components/account/KChangePassword.vue +0 -132
- package/core/client/components/account/KDeviceCard.vue +0 -75
- package/core/client/components/account/KIdentityPanel.vue +0 -34
- package/core/client/components/account/KResendVerifySignup.vue +0 -108
- package/core/client/components/account/KSendChangeIdentity.vue +0 -115
- package/core/client/components/account/KSignupAlert.vue +0 -63
- package/core/client/components/account/KVerifySignup.vue +0 -102
- package/core/client/components/form/KTagField.vue +0 -148
- package/core/common/schemas/members.update.json +0 -18
- package/extras/tours/core/account-dz.js +0 -37
- package/extras/tours/core/account-security.js +0 -52
- package/extras/tours/core/change-password.js +0 -34
- package/extras/tours/core/edit-member-tags.js +0 -18
- package/extras/tours/core/send-change-identity.js +0 -28
- package/map/client/components/KLocateUser.vue +0 -36
- package/map/client/components/KLocationInput.vue +0 -217
- package/map/client/components/KLocationMap.vue +0 -301
- package/map/client/components/KSearchLocation.vue +0 -88
- package/map/client/components/input/KPlaceChooser.vue +0 -78
- package/map/client/components/location/KLocation.vue +0 -24
- package/map/client/mixins/mixin.navigator.js +0 -36
- package/test/api/core/notifications.test.js +0 -502
package/.codeclimate.yml
CHANGED
package/.travis.test.sh
CHANGED
|
@@ -20,6 +20,9 @@ git clone https://github.com/kalisio/kdk-workspaces workspace
|
|
|
20
20
|
git clone https://github.com/kalisio/feathers-distributed && cd feathers-distributed && yarn install && yarn link && cd ..
|
|
21
21
|
yarn link @kalisio/feathers-distributed
|
|
22
22
|
|
|
23
|
+
git clone https://github.com/kalisio/feathers-webpush && cd feathers-webpush && yarn install && yarn link && cd ..
|
|
24
|
+
yarn link @kalisio/feathers-webpush
|
|
25
|
+
|
|
23
26
|
git clone https://github.com/weacast/weacast && cd weacast && yarn install && cd packages
|
|
24
27
|
cd core && yarn link && cd .. && cd gfs && yarn link && cd .. && cd probe && yarn link && cd ..
|
|
25
28
|
cd ../..
|
package/core/api/application.js
CHANGED
|
@@ -89,8 +89,8 @@ export function declareService (name, app, service, serviceOptions = {}) {
|
|
|
89
89
|
}
|
|
90
90
|
|
|
91
91
|
export async function configureService (name, service, servicesPath) {
|
|
92
|
+
let filepath = path.join(servicesPath, name, `${name}.hooks.js`)
|
|
92
93
|
try {
|
|
93
|
-
const filepath = path.join(servicesPath, name, `${name}.hooks.js`)
|
|
94
94
|
const fileExists = await fs.pathExists(filepath)
|
|
95
95
|
if (fileExists) {
|
|
96
96
|
const hooks = (await import(url.pathToFileURL(filepath))).default
|
|
@@ -101,13 +101,13 @@ export async function configureService (name, service, servicesPath) {
|
|
|
101
101
|
debug('No ' + name + ' service hooks configured on path ' + servicesPath)
|
|
102
102
|
if (error.code !== 'ERR_MODULE_NOT_FOUND') {
|
|
103
103
|
// Log error in this case as this might be linked to a syntax error in required file
|
|
104
|
-
debug(error)
|
|
104
|
+
debug(filepath, error)
|
|
105
105
|
}
|
|
106
106
|
// As this is optionnal this require has to fail silently
|
|
107
107
|
}
|
|
108
108
|
|
|
109
|
+
filepath = path.join(servicesPath, name, `${name}.channels.js`)
|
|
109
110
|
try {
|
|
110
|
-
const filepath = path.join(servicesPath, name, `${name}.channels.js`)
|
|
111
111
|
const fileExists = await fs.pathExists(filepath)
|
|
112
112
|
if (fileExists) {
|
|
113
113
|
const channels = (await import(url.pathToFileURL(filepath))).default
|
|
@@ -121,7 +121,7 @@ export async function configureService (name, service, servicesPath) {
|
|
|
121
121
|
debug('No ' + name + ' service channels configured on path ' + servicesPath)
|
|
122
122
|
if (error.code !== 'ERR_MODULE_NOT_FOUND') {
|
|
123
123
|
// Log error in this case as this might be linked to a syntax error in required file
|
|
124
|
-
debug(error)
|
|
124
|
+
debug(filepath, error)
|
|
125
125
|
}
|
|
126
126
|
// As this is optionnal this require has to fail silently
|
|
127
127
|
}
|
|
@@ -176,7 +176,8 @@ async function createService (name, app, options = {}) {
|
|
|
176
176
|
whitelist: [
|
|
177
177
|
'$exists', '$and', '$or', '$eq', '$elemMatch', '$distinct', '$groupBy', '$group', '$regex',
|
|
178
178
|
'$text', '$search', '$caseSensitive', '$language', '$diacriticSensitive',
|
|
179
|
-
'$aggregate', '$near', '$
|
|
179
|
+
'$aggregate', '$near', '$nearSphere', '$geoIntersects', '$geoWithin',
|
|
180
|
+
'$maxDistance', '$minDistance', '$geometry', '$box', '$polygon', '$center', '$centerSphere'
|
|
180
181
|
]
|
|
181
182
|
}, options)
|
|
182
183
|
if (serviceOptions.disabled) return undefined
|
|
@@ -199,7 +200,7 @@ async function createService (name, app, options = {}) {
|
|
|
199
200
|
debug('No ' + fileName + ' service model configured on path ' + serviceOptions.modelsPath)
|
|
200
201
|
if (error.code !== 'ERR_MODULE_NOT_FOUND') {
|
|
201
202
|
// Log error in this case as this might be linked to a syntax error in required file
|
|
202
|
-
debug(error)
|
|
203
|
+
debug(fileName, error)
|
|
203
204
|
}
|
|
204
205
|
// As this is optionnal this require has to fail silently
|
|
205
206
|
}
|
|
@@ -224,8 +225,8 @@ async function createService (name, app, options = {}) {
|
|
|
224
225
|
}
|
|
225
226
|
// Optionnally a specific service mixin can be provided, apply it
|
|
226
227
|
if (dbService && serviceOptions.servicesPath) {
|
|
228
|
+
const filepath = path.join(serviceOptions.servicesPath, fileName, `${fileName}.service.js`)
|
|
227
229
|
try {
|
|
228
|
-
const filepath = path.join(serviceOptions.servicesPath, fileName, `${fileName}.service.js`)
|
|
229
230
|
const fileExists = await fs.pathExists(filepath)
|
|
230
231
|
if (fileExists) {
|
|
231
232
|
let serviceMixin = (await import(url.pathToFileURL(filepath))).default
|
|
@@ -240,7 +241,7 @@ async function createService (name, app, options = {}) {
|
|
|
240
241
|
debug('No ' + fileName + ' service mixin configured on path ' + serviceOptions.servicesPath)
|
|
241
242
|
// if (error.code !== 'ERR_MODULE_NOT_FOUND') {
|
|
242
243
|
// Log error in this case as this might be linked to a syntax error in required file
|
|
243
|
-
debug(error)
|
|
244
|
+
debug(filepath, error)
|
|
244
245
|
// }
|
|
245
246
|
// As this is optionnal this require has to fail silently
|
|
246
247
|
}
|
|
@@ -434,7 +435,10 @@ function setupSockets (app) {
|
|
|
434
435
|
// e.g. like [service_method, service_path, id or data, params]
|
|
435
436
|
// Bypass rate limiting on whitelist
|
|
436
437
|
if ((packet.length > 1) && (typeof packet[1] === 'string')) {
|
|
437
|
-
|
|
438
|
+
// Service path includes API prefix (but without trailing /)
|
|
439
|
+
// Get name from service path without api prefix
|
|
440
|
+
const serviceName = packet[1].replace(app.get('apiPath').substring(1) + '/', '')
|
|
441
|
+
const service = app.getService(serviceName)
|
|
438
442
|
if (service && services(service)) {
|
|
439
443
|
debugLimiter('By-pass rate limiting on whitelisted service operation', socket.id, socket.conn.remoteAddress, packet[0], packet[1])
|
|
440
444
|
next()
|
package/core/api/db.js
CHANGED
|
@@ -33,43 +33,47 @@ export function createObjectID (id) {
|
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
// Utility function used to convert from string to MongoDB IDs as required eg by queries
|
|
36
|
+
// It only processes _id properties or operators (eg $ne, $in) to be converted
|
|
37
|
+
// If you have others properties to be converted use toObjectIDs
|
|
36
38
|
export function objectifyIDs (object) {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
39
|
+
// Avoid destructuring already transformed Date, ObjectID or arrays
|
|
40
|
+
if (_.isPlainObject(object)) {
|
|
41
|
+
_.forOwn(object, (value, key) => {
|
|
42
|
+
// Process current attributes or recurse
|
|
43
|
+
// Take care to nested fields like 'field._id'
|
|
44
|
+
if (key === '_id' || key.endsWith('._id') || key === '$ne') {
|
|
45
|
+
if (typeof value === 'string') {
|
|
46
|
+
const id = createObjectID(value)
|
|
47
|
+
if (id) {
|
|
48
|
+
object[key] = id
|
|
49
|
+
}
|
|
50
|
+
debug('Objectify ID ' + key, id)
|
|
51
|
+
} else if (Array.isArray(value)) {
|
|
52
|
+
debug('Objectify ID array ' + key)
|
|
53
|
+
object[key] = value.map(id => createObjectID(id)).filter(id => id)
|
|
54
|
+
} else objectifyIDs(value)
|
|
55
|
+
} else if (['$in', '$nin'].includes(key)) {
|
|
48
56
|
debug('Objectify ID array ' + key)
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
objectifyIDs(value)
|
|
61
|
-
}
|
|
62
|
-
})
|
|
57
|
+
const ids = value.map(id => createObjectID(id)).filter(id => id)
|
|
58
|
+
// Take care that $in/$nin can be used for others types than Object IDs so conversion might fail
|
|
59
|
+
if (ids.length > 0) object[key] = ids
|
|
60
|
+
} else if ((key === '$or') || (key === '$and')) {
|
|
61
|
+
value.forEach(entry => objectifyIDs(entry))
|
|
62
|
+
} else {
|
|
63
|
+
if (!Array.isArray(value)) objectifyIDs(value)
|
|
64
|
+
else value.forEach(entry => objectifyIDs(entry))
|
|
65
|
+
}
|
|
66
|
+
})
|
|
67
|
+
}
|
|
63
68
|
return object
|
|
64
69
|
}
|
|
65
70
|
|
|
66
|
-
// Utility function used to convert
|
|
71
|
+
// Utility function used to convert a fixed set of properties on a given object from string to MongoDB IDs
|
|
67
72
|
export function toObjectIDs (object, properties) {
|
|
68
73
|
properties.forEach(property => {
|
|
69
|
-
const
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
}
|
|
74
|
+
const value = _.get(object, property)
|
|
75
|
+
const id = createObjectID(value)
|
|
76
|
+
if (id) _.set(object, property, id)
|
|
73
77
|
})
|
|
74
78
|
}
|
|
75
79
|
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import makeDebug from 'debug'
|
|
2
|
+
import common from 'feathers-hooks-common'
|
|
2
3
|
import local from '@feathersjs/authentication-local'
|
|
3
4
|
|
|
4
5
|
const debug = makeDebug('kdk:core:authentication:hooks')
|
|
6
|
+
const { discard } = common
|
|
5
7
|
|
|
6
8
|
// Make it more easy to acces
|
|
7
9
|
export const hashPassword = local.hooks.hashPassword
|
|
@@ -61,3 +63,12 @@ export async function consentGuest (hook) {
|
|
|
61
63
|
|
|
62
64
|
return hook
|
|
63
65
|
}
|
|
66
|
+
|
|
67
|
+
export function discardAuthenticationProviders (hook) {
|
|
68
|
+
const providers = hook.app.authenticationProviders || []
|
|
69
|
+
|
|
70
|
+
// Iterate through known providers
|
|
71
|
+
for (const provider of providers) {
|
|
72
|
+
discard(provider)(hook)
|
|
73
|
+
}
|
|
74
|
+
}
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
hasServiceAbilities, hasResourceAbilities, getQueryForAbilities,
|
|
9
9
|
Roles, RoleNames, countSubjectsForResource
|
|
10
10
|
} from '../../common/permissions.js'
|
|
11
|
-
import { isTagEqual } from '
|
|
11
|
+
import { isTagEqual } from '../utils.js'
|
|
12
12
|
|
|
13
13
|
const { getItems, replaceItems } = common
|
|
14
14
|
const { Forbidden } = errors
|
|
@@ -233,7 +233,11 @@ export async function authorise (hook) {
|
|
|
233
233
|
// this has to be implemented by the service itself
|
|
234
234
|
} else if (typeof hook.service.get === 'function') {
|
|
235
235
|
// In this case (single get/update/patch/remove) we need to fetch the item first
|
|
236
|
-
|
|
236
|
+
// Take care we might have additional query parameters to be "catched" by before hooks,
|
|
237
|
+
// however at this stage these query parameters might cause get to fail
|
|
238
|
+
const params = Object.assign({ checkAuthorisation: false }, hook.params)
|
|
239
|
+
_.unset(params, 'query')
|
|
240
|
+
const resource = await hook.service.get(hook.id, params)
|
|
237
241
|
debug('Target resource is', resource)
|
|
238
242
|
// Then check against the object we'd like to manage
|
|
239
243
|
if (!hasResourceAbilities(abilities, operation, resourceType, context, resource)) {
|
|
@@ -362,7 +366,7 @@ export async function removeOrganisationTagsAuthorisations (hook) {
|
|
|
362
366
|
const notFromOrg = _.differenceWith(tags, orgTags, isTagEqual)
|
|
363
367
|
// Update subject if required
|
|
364
368
|
if (fromOrg.length > 0) {
|
|
365
|
-
promises.push(subjectService.patch(subject._id.toString(), { tags: notFromOrg
|
|
369
|
+
promises.push(subjectService.patch(subject._id.toString(), { tags: notFromOrg }))
|
|
366
370
|
}
|
|
367
371
|
})
|
|
368
372
|
// Perform subject updates in parallel
|
|
@@ -7,7 +7,7 @@ import { marshallTimes, unmarshallTimes } from '../marshall.js'
|
|
|
7
7
|
import common from 'feathers-hooks-common'
|
|
8
8
|
import makeDebug from 'debug'
|
|
9
9
|
|
|
10
|
-
const { Conflict } = errors
|
|
10
|
+
const { Conflict, BadRequest } = errors
|
|
11
11
|
const { discard, disallow, getItems, replaceItems } = common
|
|
12
12
|
const sift = siftModule.default
|
|
13
13
|
const debug = makeDebug('kdk:core:model:hooks')
|
|
@@ -36,47 +36,6 @@ export function unprocessTimes (properties) {
|
|
|
36
36
|
}
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
export function processPerspectives (hook) {
|
|
40
|
-
const params = hook.params
|
|
41
|
-
const query = params.query
|
|
42
|
-
const service = hook.service
|
|
43
|
-
|
|
44
|
-
// Test if some perspectives are defined on the model
|
|
45
|
-
if (!service.options || !service.options.perspectives) return
|
|
46
|
-
|
|
47
|
-
// Iterate through known perspectives of the model
|
|
48
|
-
service.options.perspectives.forEach(perspective => {
|
|
49
|
-
// Only discard if not explicitely asked by $select
|
|
50
|
-
let filterPerspective = true
|
|
51
|
-
if (!_.isNil(query) && !_.isNil(query.$select)) {
|
|
52
|
-
// Transform to array to unify processing
|
|
53
|
-
const selectedFields = (typeof query.$select === 'string' ? [query.$select] : query.$select)
|
|
54
|
-
if (Array.isArray(selectedFields)) {
|
|
55
|
-
selectedFields.forEach(field => {
|
|
56
|
-
// Take care that we might only ask for a subset of perspective fields like ['perspective.fieldName']
|
|
57
|
-
if ((field === perspective) || field.startsWith(perspective + '.')) {
|
|
58
|
-
filterPerspective = false
|
|
59
|
-
}
|
|
60
|
-
})
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
if (filterPerspective) {
|
|
64
|
-
discard(perspective)(hook)
|
|
65
|
-
}
|
|
66
|
-
})
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
// When perspectives are present we disallow update in order to avoid erase them.
|
|
70
|
-
// Indeed when requesting an object they are not retrieved by default
|
|
71
|
-
export function preventUpdatePerspectives (hook) {
|
|
72
|
-
const service = hook.service
|
|
73
|
-
|
|
74
|
-
// Test if some perspectives are defined on the model
|
|
75
|
-
if (!service.options || !service.options.perspectives) return
|
|
76
|
-
|
|
77
|
-
disallow()(hook)
|
|
78
|
-
}
|
|
79
|
-
|
|
80
39
|
// The hook serialize allows to copy/move some properties within the objects holded by the hook
|
|
81
40
|
// It applies an array of rules defined by:
|
|
82
41
|
// - source: the path to the property to be copied
|
|
@@ -108,8 +67,10 @@ export function serialize (rules, options = {}) {
|
|
|
108
67
|
}
|
|
109
68
|
}
|
|
110
69
|
|
|
111
|
-
//
|
|
70
|
+
// This hook allows to transform the values bound to '_id' like keys or
|
|
71
|
+
// operators (eg $ne, $in) provided as strings into Mongo ObjectIds
|
|
112
72
|
// It inspects hook data as well as query data
|
|
73
|
+
// If you have others properties to be converted use convertObjectIDs
|
|
113
74
|
export function processObjectIDs (hook) {
|
|
114
75
|
let items = getItems(hook)
|
|
115
76
|
const isArray = Array.isArray(items)
|
|
@@ -299,3 +260,31 @@ export function checkUnique (options = {}) {
|
|
|
299
260
|
return hook
|
|
300
261
|
}
|
|
301
262
|
}
|
|
263
|
+
|
|
264
|
+
// Prevent patch service calls from changing certain fields.
|
|
265
|
+
// Based on https://hooks-common.feathersjs.com/hooks.html#preventchanges
|
|
266
|
+
// but updated to handle dot notation
|
|
267
|
+
export function preventChanges(ifThrow, fieldNames) {
|
|
268
|
+
return (hook) => {
|
|
269
|
+
if ((hook.type !== 'before') || (hook.method !== 'patch')) {
|
|
270
|
+
throw new Error('The \'preventChanges\' hook should only be used as a \'before\' patch hook.')
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
let data = { ...hook.data }
|
|
274
|
+
// Check all data fields
|
|
275
|
+
_.forOwn(hook.data, (value, key) => {
|
|
276
|
+
fieldNames.forEach(name => {
|
|
277
|
+
// If a prevented field is found or dot notation with a prevented field is used
|
|
278
|
+
if ((key === name) || key.startsWith(`${name}.`)) {
|
|
279
|
+
if (ifThrow) {
|
|
280
|
+
throw new BadRequest(`Field ${name} may not be patched. (preventChanges)`);
|
|
281
|
+
}
|
|
282
|
+
delete data[key]
|
|
283
|
+
}
|
|
284
|
+
})
|
|
285
|
+
})
|
|
286
|
+
hook.data = data
|
|
287
|
+
|
|
288
|
+
return hook
|
|
289
|
+
}
|
|
290
|
+
}
|
|
@@ -5,21 +5,6 @@ const debug = makeDebug('kdk:core:organisations:hooks')
|
|
|
5
5
|
|
|
6
6
|
const { Forbidden } = errors
|
|
7
7
|
|
|
8
|
-
export function addOrganisationPlan (hook) {
|
|
9
|
-
if (hook.type !== 'before') {
|
|
10
|
-
throw new Error('The \'addOrganisationPlan\' hook should only be used as a \'before\' hook.')
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
const plans = _.keys(hook.app.get('plans') || {})
|
|
14
|
-
const plan = _.get(hook.data, 'billing.plan')
|
|
15
|
-
if (!plan && (plans.length > 0)) {
|
|
16
|
-
// Add defaul plan
|
|
17
|
-
_.set(hook.data, 'billing.plan', plans[0])
|
|
18
|
-
debug('Added default plan to organisation: ', hook.data)
|
|
19
|
-
}
|
|
20
|
-
return hook
|
|
21
|
-
}
|
|
22
|
-
|
|
23
8
|
export async function createOrganisationServices (hook) {
|
|
24
9
|
if (hook.type !== 'after') {
|
|
25
10
|
throw new Error('The \'createOrganisationServices\' hook should only be used as a \'after\' hook.')
|
|
@@ -119,10 +104,14 @@ export function updateOrganisationResource (resourceScope) {
|
|
|
119
104
|
if (hook.type !== 'after') {
|
|
120
105
|
throw new Error('The \'updateOrganisationResource\' hook should only be used as a \'after\' hook.')
|
|
121
106
|
}
|
|
107
|
+
// Only applicable to update/remove operations
|
|
108
|
+
if ((hook.method === 'get' || hook.method === 'find' || hook.method === 'create')) return hook
|
|
122
109
|
|
|
123
110
|
const app = hook.app
|
|
124
111
|
// Retrieve the list of members
|
|
125
|
-
const
|
|
112
|
+
const context = hook.service.getContextId()
|
|
113
|
+
// Use members service if any or global users service
|
|
114
|
+
const orgMembersService = (context ? app.getService('members', context) : app.getService('users'))
|
|
126
115
|
const members = await orgMembersService.find({
|
|
127
116
|
query: { [resourceScope]: { $elemMatch: { _id: hook.result._id } } },
|
|
128
117
|
paginate: false
|
|
@@ -130,13 +119,15 @@ export function updateOrganisationResource (resourceScope) {
|
|
|
130
119
|
// Update each members
|
|
131
120
|
await Promise.all(members.map(member => {
|
|
132
121
|
const resources = _.get(member, resourceScope, [])
|
|
133
|
-
const resource = _.find(resources,
|
|
134
|
-
if (resource)
|
|
135
|
-
|
|
136
|
-
|
|
122
|
+
const resource = _.find(resources, item => item._id.toString() === hook.result._id.toString())
|
|
123
|
+
if (!resource) return Promise.resolve()
|
|
124
|
+
// Check for removal or update
|
|
125
|
+
if (hook.method === 'remove') {
|
|
126
|
+
_.remove(resources, item => resource._id.toString() === item._id.toString())
|
|
137
127
|
} else {
|
|
138
|
-
|
|
128
|
+
Object.assign(resource, hook.result)
|
|
139
129
|
}
|
|
130
|
+
return orgMembersService.patch(member._id, { [resourceScope]: resources })
|
|
140
131
|
}))
|
|
141
132
|
|
|
142
133
|
debug(`Updated resource ${hook.result._id} on scope ${resourceScope} for members of organisation ` + hook.result._id)
|
|
@@ -144,103 +135,22 @@ export function updateOrganisationResource (resourceScope) {
|
|
|
144
135
|
}
|
|
145
136
|
}
|
|
146
137
|
|
|
147
|
-
export function
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
const app = hook.app
|
|
153
|
-
const orgGroupService = app.getService('groups', hook.result)
|
|
154
|
-
return orgGroupService.find({ paginate: false })
|
|
155
|
-
.then(groups => {
|
|
156
|
-
return Promise.all(groups.map(group => {
|
|
157
|
-
return orgGroupService.remove(group._id.toString(), {
|
|
158
|
-
user: hook.params.user
|
|
159
|
-
})
|
|
160
|
-
}))
|
|
161
|
-
})
|
|
162
|
-
.then(groups => {
|
|
163
|
-
debug('Removed groups for organisation ' + hook.result._id)
|
|
164
|
-
return hook
|
|
165
|
-
})
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
export async function removeOrganisationTags (hook) {
|
|
169
|
-
if (hook.type !== 'after') {
|
|
170
|
-
throw new Error('The \'removeOrganisationTags\' hook should only be used as a \'after\' hook.')
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
const app = hook.app
|
|
174
|
-
// Retrieve the list of tags
|
|
175
|
-
const orgTagsService = app.getService('tags', hook.result)
|
|
176
|
-
const tags = await orgTagsService.find({ paginate: false })
|
|
177
|
-
// Retrieve the list of members
|
|
178
|
-
const orgMembersService = app.getService('members', hook.result)
|
|
179
|
-
const members = await orgMembersService.find({ paginate: false })
|
|
180
|
-
// Update each members
|
|
181
|
-
for (const i in members) {
|
|
182
|
-
const member = members[i]
|
|
183
|
-
if (member.tags) {
|
|
184
|
-
const filteredTagsMember = _.filter(member.tags, (tag) => {
|
|
185
|
-
return _.findIndex(tags, { _id: tag._id }) === -1
|
|
186
|
-
})
|
|
187
|
-
await orgMembersService.patch(member._id, { tags: filteredTagsMember })
|
|
138
|
+
export function removeOrganisationResources (resourceScope) {
|
|
139
|
+
return async function (hook) {
|
|
140
|
+
if (hook.type !== 'after') {
|
|
141
|
+
throw new Error('The \'removeOrganisationResources\' hook should only be used as a \'after\' hook.')
|
|
188
142
|
}
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
debug('Removed tags from organisation ' + hook.result._id)
|
|
192
|
-
return hook
|
|
193
|
-
}
|
|
194
143
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
name: hook.result.profile.name // Same name as user
|
|
206
|
-
}, {
|
|
207
|
-
user: hook.result
|
|
208
|
-
})
|
|
209
|
-
|
|
210
|
-
debug('Private organisation created for user ' + hook.result._id)
|
|
211
|
-
return hook
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
export async function removePrivateOrganisation (hook) {
|
|
215
|
-
if (hook.type !== 'after') {
|
|
216
|
-
throw new Error('The \'removePrivateOrganisation\' hook should only be used as a \'after\' hook.')
|
|
144
|
+
const app = hook.app
|
|
145
|
+
const orgResourceService = app.getService(resourceScope, hook.result)
|
|
146
|
+
const resources = await orgResourceService.find({ paginate: false })
|
|
147
|
+
await Promise.all(resources.map(resource => {
|
|
148
|
+
return orgResourceService.remove(resource._id.toString(), {
|
|
149
|
+
user: hook.params.user
|
|
150
|
+
})
|
|
151
|
+
}))
|
|
152
|
+
debug(`Removed ${resourceScope} for organisation ` + hook.result._id)
|
|
153
|
+
return hook
|
|
217
154
|
}
|
|
218
|
-
|
|
219
|
-
const app = hook.app
|
|
220
|
-
const organisationService = app.getService('organisations')
|
|
221
|
-
// Remove the private user's organisation
|
|
222
|
-
await organisationService.remove(hook.result._id.toString(), {
|
|
223
|
-
user: hook.result
|
|
224
|
-
})
|
|
225
|
-
|
|
226
|
-
debug('Private organisation removed for user ' + hook.result._id)
|
|
227
|
-
return hook
|
|
228
155
|
}
|
|
229
156
|
|
|
230
|
-
export async function preventRemoveOrganisation (hook) {
|
|
231
|
-
if (hook.type !== 'before') {
|
|
232
|
-
throw new Error('The \'preventRemoveOrganisations\' hook should only be used as a \'before\' hook.')
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
// By pass check ?
|
|
236
|
-
if (hook.params.force) return hook
|
|
237
|
-
const app = hook.app
|
|
238
|
-
const orgGroupService = app.getService('groups', hook.id)
|
|
239
|
-
const result = await orgGroupService.find({ $limit: 0 })
|
|
240
|
-
if (result.total > 0) {
|
|
241
|
-
throw new Forbidden('You are not allowed to delete the organisation', {
|
|
242
|
-
translation: { key: 'CANNOT_REMOVE_ORGANISATION' }
|
|
243
|
-
})
|
|
244
|
-
}
|
|
245
|
-
return hook
|
|
246
|
-
}
|
|
@@ -1,34 +1,46 @@
|
|
|
1
1
|
import emails from 'email-templates'
|
|
2
2
|
import path from 'path'
|
|
3
3
|
import makeDebug from 'debug'
|
|
4
|
+
import _ from 'lodash'
|
|
4
5
|
|
|
5
|
-
const debug = makeDebug('kdk:core:
|
|
6
|
+
const debug = makeDebug('kdk:core:push:hooks')
|
|
6
7
|
|
|
7
|
-
|
|
8
|
+
// Helper functions to be used in iff hooks
|
|
9
|
+
export function disallowExternalPush (hook) {
|
|
10
|
+
return _.get(hook.app.get('push'), 'disallowExternalPush', true)
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export async function sendNewSubscriptionEmail (hook) {
|
|
8
14
|
if (hook.type !== 'after') {
|
|
9
|
-
throw new Error('The \'
|
|
15
|
+
throw new Error('The \'sendNewSubscriptionEmail\' hook should only be used as a \'after\' hook.')
|
|
10
16
|
}
|
|
11
17
|
|
|
18
|
+
// Check for a new subscription
|
|
19
|
+
const updatedUser = hook.result
|
|
20
|
+
const previousUser = hook.params.user
|
|
21
|
+
const newSubscription = _.differenceBy(_.get(updatedUser, 'subscriptions', []), _.get(previousUser, 'subscriptions', []), 'endpoint')
|
|
22
|
+
if (_.size(newSubscription) !== 1) return
|
|
23
|
+
|
|
24
|
+
// Data
|
|
12
25
|
const app = hook.app
|
|
13
|
-
const user = hook.params.user
|
|
14
26
|
const mailerService = app.getService('mailer')
|
|
15
27
|
const domainPath = app.get('domain') + '/#/'
|
|
16
28
|
const email = {
|
|
17
|
-
subject: 'Security alert - new
|
|
29
|
+
subject: 'Security alert - new browser detected',
|
|
18
30
|
from: mailerService.options.auth.user,
|
|
19
31
|
// When changing email send to the new one so that it can be verified
|
|
20
|
-
to:
|
|
21
|
-
link: domainPath
|
|
32
|
+
to: updatedUser.email,
|
|
33
|
+
link: domainPath,
|
|
22
34
|
domainPath
|
|
23
35
|
}
|
|
24
|
-
|
|
36
|
+
|
|
25
37
|
// Build the subject & link to the app to perform the different actions
|
|
26
|
-
const templateDir = path.join(mailerService.options.templateDir, '
|
|
38
|
+
const templateDir = path.join(mailerService.options.templateDir, 'newSubscription')
|
|
27
39
|
const template = new emails.EmailTemplate(templateDir)
|
|
28
40
|
// Errors does not seem to be correctly catched by the caller
|
|
29
41
|
// so we catch them here to avoid any problem
|
|
30
42
|
try {
|
|
31
|
-
const emailContent = await template.render({ email,
|
|
43
|
+
const emailContent = await template.render({ email, user: updatedUser, subscription: _.first(newSubscription) }, updatedUser.locale || 'en-us')
|
|
32
44
|
// Update compiled content
|
|
33
45
|
email.html = emailContent.html
|
|
34
46
|
debug('Sending email ', email)
|
|
@@ -97,9 +97,6 @@ export function populateObject (options) {
|
|
|
97
97
|
if (options.throwOnNotFound) throw new Error(`Cannot find the ${options.idField} to dynamically populate.`)
|
|
98
98
|
else return hook
|
|
99
99
|
}
|
|
100
|
-
// Then the perspective if any
|
|
101
|
-
const perspective = _.get(data, options.perspectiveField) || _.get(query, options.perspectiveField)
|
|
102
|
-
|
|
103
100
|
debug(`Populating ${idProperty} with ID ${id}`)
|
|
104
101
|
// Set the retrieved service on the same field or given one in hook params
|
|
105
102
|
_.set(params, serviceProperty, service)
|
|
@@ -110,11 +107,9 @@ export function populateObject (options) {
|
|
|
110
107
|
try {
|
|
111
108
|
// Get by ID or name ?
|
|
112
109
|
if (ObjectID.isValid(id)) {
|
|
113
|
-
if (perspective) Object.assign(args, { query: { $select: [perspective] } })
|
|
114
110
|
object = await service.get(id.toString(), args)
|
|
115
111
|
} else {
|
|
116
112
|
Object.assign(args, { query: { name: id.toString() }, paginate: false })
|
|
117
|
-
if (perspective) Object.assign(args.query, { $select: [perspective] })
|
|
118
113
|
const results = await service.find(args)
|
|
119
114
|
if (results.length >= 0) object = results[0]
|
|
120
115
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import _ from 'lodash'
|
|
1
2
|
import makeDebug from 'debug'
|
|
2
3
|
import errors from '@feathersjs/errors'
|
|
3
4
|
import commonHooks from 'feathers-hooks-common'
|
|
@@ -24,9 +25,27 @@ export function validateData (schema) {
|
|
|
24
25
|
items = await Promise.allSettled(items.map((item) => schema.validate(item)))
|
|
25
26
|
// Keep track of validation errors, even if invalid data will be filtered this ensure
|
|
26
27
|
// original data with validation error will be "tagged"
|
|
27
|
-
|
|
28
|
+
|
|
29
|
+
items.forEach((item, index) => {
|
|
28
30
|
if (item.status === 'rejected') {
|
|
29
|
-
|
|
31
|
+
console.log(item.reason)
|
|
32
|
+
item.validationError = {
|
|
33
|
+
message: item.reason.message,
|
|
34
|
+
data: item.reason.data.map(error => {
|
|
35
|
+
// retrieve the data corresponding to the item
|
|
36
|
+
const data = isArray ? hook.data[index] : hook.data
|
|
37
|
+
// compute the property path
|
|
38
|
+
let propertyPath = error.instancePath
|
|
39
|
+
if (_.startsWith(propertyPath, '/')) propertyPath = propertyPath.substring(1)
|
|
40
|
+
propertyPath = propertyPath.replace('/', '.')
|
|
41
|
+
// return the error
|
|
42
|
+
return {
|
|
43
|
+
message: error.message,
|
|
44
|
+
propertyPath: error.instancePath,
|
|
45
|
+
propertyValue: _.get(data, propertyPath)
|
|
46
|
+
}
|
|
47
|
+
})
|
|
48
|
+
}
|
|
30
49
|
}
|
|
31
50
|
})
|
|
32
51
|
// Filter errors/valid data
|
|
@@ -39,8 +58,9 @@ export function validateData (schema) {
|
|
|
39
58
|
const hasError = (errors.length > 0)
|
|
40
59
|
if (hasError) {
|
|
41
60
|
const firstError = errors[0]
|
|
61
|
+
console.log(firstError)
|
|
42
62
|
// Single item case => raise the error
|
|
43
|
-
if (!isArray) throw firstError
|
|
63
|
+
if (!isArray) throw new BadRequest(firstError.message, firstError.data)
|
|
44
64
|
// Multiple items case => raise if no valid data found
|
|
45
65
|
else if (!hasValidData) {
|
|
46
66
|
// Keep track of all errors
|