@kalisio/kdk 2.1.7 → 2.1.8
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 +34 -34
- package/.nycrc +5 -5
- package/.travis.doc.sh +8 -8
- package/.travis.test.sh +40 -40
- package/CHANGELOG.md +727 -727
- package/LICENSE +21 -21
- package/README.md +32 -32
- package/core/api/application.js +591 -591
- package/core/api/authentication.js +203 -203
- package/core/api/db.js +226 -226
- package/core/api/hooks/hooks.authentication.js +73 -73
- package/core/api/hooks/hooks.authorisations.js +376 -376
- package/core/api/hooks/hooks.groups.js +48 -48
- package/core/api/hooks/hooks.logger.js +26 -26
- package/core/api/hooks/hooks.model.js +290 -290
- package/core/api/hooks/hooks.organisations.js +156 -156
- package/core/api/hooks/hooks.push.js +56 -56
- package/core/api/hooks/hooks.query.js +246 -246
- package/core/api/hooks/hooks.schemas.js +73 -73
- package/core/api/hooks/hooks.service.js +78 -78
- package/core/api/hooks/hooks.storage.js +36 -36
- package/core/api/hooks/hooks.users.js +261 -261
- package/core/api/hooks/index.js +12 -12
- package/core/api/index.js +21 -21
- package/core/api/marshall.js +90 -90
- package/core/api/models/groups.model.mongodb.js +8 -8
- package/core/api/models/organisations.model.mongodb.js +3 -3
- package/core/api/models/tags.model.mongodb.js +10 -10
- package/core/api/models/users.model.mongodb.js +10 -10
- package/core/api/services/account/account.hooks.js +37 -37
- package/core/api/services/account/account.service.js +117 -117
- package/core/api/services/authorisations/authorisations.hooks.js +33 -33
- package/core/api/services/authorisations/authorisations.service.js +139 -139
- package/core/api/services/databases/databases.hooks.js +36 -36
- package/core/api/services/databases/databases.service.js +5 -5
- package/core/api/services/groups/groups.hooks.js +31 -31
- package/core/api/services/index.js +126 -126
- package/core/api/services/mailer/mailer.hooks.js +35 -35
- package/core/api/services/mailer/mailer.service.js +11 -11
- package/core/api/services/organisations/organisations.hooks.js +31 -31
- package/core/api/services/organisations/organisations.service.js +86 -86
- package/core/api/services/push/push.hooks.js +35 -35
- package/core/api/services/push/push.service.js +12 -12
- package/core/api/services/storage/storage.hooks.js +35 -35
- package/core/api/services/storage/storage.service.js +29 -29
- package/core/api/services/tags/tags.hooks.js +31 -31
- package/core/api/services/users/users.hooks.js +75 -75
- package/core/api/utils.js +11 -11
- package/core/client/api.js +293 -293
- package/core/client/capabilities.js +22 -22
- package/core/client/components/KAction.vue +393 -393
- package/core/client/components/KAvatar.vue +129 -129
- package/core/client/components/KBlock.vue +67 -67
- package/core/client/components/KChip.vue +68 -68
- package/core/client/components/KChipsPane.vue +103 -103
- package/core/client/components/KContent.vue +105 -105
- package/core/client/components/KDialog.vue +160 -160
- package/core/client/components/KExpandable.vue +49 -49
- package/core/client/components/KLogo.vue +32 -32
- package/core/client/components/KModal.vue +173 -173
- package/core/client/components/KPanel.vue +64 -64
- package/core/client/components/KScrollArea.vue +88 -88
- package/core/client/components/KSponsor.vue +40 -40
- package/core/client/components/KStamp.vue +65 -65
- package/core/client/components/KStore.vue +102 -102
- package/core/client/components/KTextArea.vue +143 -143
- package/core/client/components/KTree.vue +31 -31
- package/core/client/components/KVersion.vue +19 -19
- package/core/client/components/account/KAccount.vue +68 -68
- package/core/client/components/account/KDeleteAccountManager.vue +62 -62
- package/core/client/components/account/KEmailManager.vue +128 -128
- package/core/client/components/account/KPasswordManager.vue +90 -90
- package/core/client/components/account/KProfile.vue +109 -109
- package/core/client/components/account/KResetPassword.vue +126 -120
- package/core/client/components/account/KSendResetPassword.vue +97 -97
- package/core/client/components/account/KSubscription.vue +71 -71
- package/core/client/components/account/KSubscriptionsManager.vue +46 -46
- package/core/client/components/account/KVerifyEmailManager.vue +105 -105
- package/core/client/components/account/index.js +7 -7
- package/core/client/components/app/KAbout.vue +98 -98
- package/core/client/components/app/KHome.vue +12 -12
- package/core/client/components/app/KPlatform.vue +55 -55
- package/core/client/components/app/KSettings.vue +42 -42
- package/core/client/components/app/KTerms.vue +41 -41
- package/core/client/components/app/KTour.vue +448 -448
- package/core/client/components/app/KWelcome.vue +133 -133
- package/core/client/components/app/index.js +11 -11
- package/core/client/components/chart/KChart.vue +197 -197
- package/core/client/components/chart/KDataTable.vue +183 -183
- package/core/client/components/chart/KStatisticsChart.vue +94 -94
- package/core/client/components/chart/KTimeSeriesChart.vue +431 -431
- package/core/client/components/chart/index.js +9 -9
- package/core/client/components/collection/KBoard.vue +65 -65
- package/core/client/components/collection/KCard.vue +196 -196
- package/core/client/components/collection/KCardSection.vue +52 -52
- package/core/client/components/collection/KColumn.vue +229 -229
- package/core/client/components/collection/KFilter.vue +158 -158
- package/core/client/components/collection/KGrid.vue +121 -121
- package/core/client/components/collection/KHistory.vue +118 -118
- package/core/client/components/collection/KHistoryEntry.vue +111 -111
- package/core/client/components/collection/KItem.vue +128 -128
- package/core/client/components/collection/KList.vue +135 -135
- package/core/client/components/collection/KSorter.vue +46 -46
- package/core/client/components/collection/KTable.vue +238 -238
- package/core/client/components/collection/index.js +19 -19
- package/core/client/components/editor/KEditor.vue +52 -52
- package/core/client/components/editor/KModalEditor.vue +96 -96
- package/core/client/components/editor/index.js +7 -7
- package/core/client/components/form/KChipsField.vue +162 -162
- package/core/client/components/form/KColorField.vue +69 -69
- package/core/client/components/form/KColorScaleField.vue +86 -86
- package/core/client/components/form/KDateTimeRangeField.vue +65 -65
- package/core/client/components/form/KDatetimeField.vue +70 -70
- package/core/client/components/form/KEmailField.vue +33 -33
- package/core/client/components/form/KFileField.vue +161 -161
- package/core/client/components/form/KForm.vue +247 -247
- package/core/client/components/form/KIconField.vue +101 -101
- package/core/client/components/form/KItemField.vue +123 -123
- package/core/client/components/form/KNumberField.vue +33 -33
- package/core/client/components/form/KOptionsField.vue +63 -63
- package/core/client/components/form/KPasswordField.vue +57 -57
- package/core/client/components/form/KPhoneField.vue +32 -32
- package/core/client/components/form/KPropertyItemField.vue +119 -119
- package/core/client/components/form/KRoleField.vue +60 -60
- package/core/client/components/form/KSelectField.vue +143 -143
- package/core/client/components/form/KTextField.vue +48 -48
- package/core/client/components/form/KTextareaField.vue +88 -88
- package/core/client/components/form/KToggleField.vue +46 -46
- package/core/client/components/form/KTokenField.vue +80 -80
- package/core/client/components/form/KUnitField.vue +57 -57
- package/core/client/components/form/KUrlField.vue +32 -32
- package/core/client/components/form/KView.vue +118 -118
- package/core/client/components/form/index.js +7 -7
- package/core/client/components/index.js +48 -48
- package/core/client/components/input/KColorChooser.vue +63 -63
- package/core/client/components/input/KIconChooser.vue +308 -308
- package/core/client/components/input/KOptionsChooser.vue +122 -122
- package/core/client/components/input/KPalette.vue +40 -40
- package/core/client/components/input/index.js +11 -11
- package/core/client/components/layout/KFab.vue +113 -113
- package/core/client/components/layout/KLayout.vue +64 -64
- package/core/client/components/layout/KOpener.vue +140 -140
- package/core/client/components/layout/KPage.vue +320 -320
- package/core/client/components/layout/KPageSticky.vue +53 -53
- package/core/client/components/layout/KWindow.vue +443 -443
- package/core/client/components/layout/index.js +13 -13
- package/core/client/components/media/KColorScale.vue +254 -254
- package/core/client/components/media/KImageViewer.vue +44 -44
- package/core/client/components/media/KMarkdownViewer.vue +55 -55
- package/core/client/components/media/KMediaBrowser.vue +301 -340
- package/core/client/components/media/KShape.vue +120 -120
- package/core/client/components/media/index.js +13 -13
- package/core/client/components/menu/KMenu.vue +147 -147
- package/core/client/components/menu/KRadialFab.vue +122 -122
- package/core/client/components/menu/KRadialFabItem.vue +73 -73
- package/core/client/components/menu/index.js +9 -9
- package/core/client/components/screen/KEndpointScreen.vue +80 -80
- package/core/client/components/screen/KErrorScreen.vue +24 -24
- package/core/client/components/screen/KLoginScreen.vue +84 -84
- package/core/client/components/screen/KLogoutScreen.vue +20 -20
- package/core/client/components/screen/KRegisterScreen.vue +114 -114
- package/core/client/components/screen/KScreen.vue +106 -106
- package/core/client/components/screen/KScreenFooter.vue +32 -32
- package/core/client/components/screen/KScreenHeader.vue +17 -17
- package/core/client/components/screen/index.js +5 -5
- package/core/client/components/team/KAddMember.vue +375 -375
- package/core/client/components/team/KAddTag.vue +121 -121
- package/core/client/components/team/KChangeRole.vue +118 -118
- package/core/client/components/team/KGroupCard.vue +110 -110
- package/core/client/components/team/KGroupsActivity.vue +66 -66
- package/core/client/components/team/KJoinGroup.vue +132 -132
- package/core/client/components/team/KMemberCard.vue +328 -328
- package/core/client/components/team/KMemberFilter.vue +49 -49
- package/core/client/components/team/KMembersActivity.vue +126 -126
- package/core/client/components/team/KOrganisationsActivity.vue +53 -53
- package/core/client/components/team/KTagCard.vue +72 -72
- package/core/client/components/team/KTagsActivity.vue +61 -61
- package/core/client/components/team/index.js +9 -9
- package/core/client/components/time/KAbsoluteTimeRange.vue +183 -183
- package/core/client/components/time/KDate.vue +75 -75
- package/core/client/components/time/KDateTime.vue +172 -172
- package/core/client/components/time/KDateTimeRange.vue +118 -118
- package/core/client/components/time/KRelativeTimeRanges.vue +193 -193
- package/core/client/components/time/KTime.vue +74 -74
- package/core/client/components/time/index.js +7 -7
- package/core/client/components/viewer/KModalViewer.vue +47 -47
- package/core/client/components/viewer/KViewer.vue +30 -30
- package/core/client/composables/activity.js +67 -67
- package/core/client/composables/collection.js +181 -181
- package/core/client/composables/index.js +8 -8
- package/core/client/composables/pwa.js +71 -71
- package/core/client/composables/schema.js +64 -64
- package/core/client/composables/selection.js +88 -88
- package/core/client/composables/session.js +172 -172
- package/core/client/composables/store.js +49 -49
- package/core/client/composables/version.js +47 -47
- package/core/client/events.js +3 -3
- package/core/client/filter.js +60 -60
- package/core/client/guards.js +101 -101
- package/core/client/hooks/hooks.events.js +7 -7
- package/core/client/hooks/hooks.logger.js +24 -24
- package/core/client/hooks/hooks.users.js +22 -22
- package/core/client/hooks/index.js +3 -3
- package/core/client/i18n/core_en.json +845 -845
- package/core/client/i18n/core_fr.json +843 -843
- package/core/client/i18n.js +88 -88
- package/core/client/index.js +84 -84
- package/core/client/layout.js +323 -323
- package/core/client/local-storage.js +28 -28
- package/core/client/mixins/index.js +12 -12
- package/core/client/mixins/mixin.account.js +61 -61
- package/core/client/mixins/mixin.base-activity.js +232 -232
- package/core/client/mixins/mixin.base-collection.js +162 -162
- package/core/client/mixins/mixin.base-context.js +54 -54
- package/core/client/mixins/mixin.base-editor.js +194 -194
- package/core/client/mixins/mixin.base-field.js +105 -105
- package/core/client/mixins/mixin.base-item.js +166 -166
- package/core/client/mixins/mixin.base-modal.js +36 -36
- package/core/client/mixins/mixin.base-viewer.js +43 -43
- package/core/client/mixins/mixin.object-proxy.js +46 -46
- package/core/client/mixins/mixin.schema-proxy.js +97 -97
- package/core/client/mixins/mixin.service.js +22 -22
- package/core/client/reader.js +65 -65
- package/core/client/readers/index.js +3 -3
- package/core/client/readers/reader.blob.js +39 -39
- package/core/client/readers/reader.csv.js +36 -36
- package/core/client/readers/reader.json.js +34 -34
- package/core/client/search.js +47 -47
- package/core/client/services/index.js +49 -49
- package/core/client/services/local-settings.service.js +67 -67
- package/core/client/sorter.js +31 -31
- package/core/client/storage.js +110 -102
- package/core/client/store.js +39 -39
- package/core/client/theme.js +40 -40
- package/core/client/time.js +167 -167
- package/core/client/units.js +218 -218
- package/core/client/utils/index.js +203 -203
- package/core/client/utils/utils.account.js +52 -52
- package/core/client/utils/utils.colors.js +36 -36
- package/core/client/utils/utils.content.js +185 -185
- package/core/client/utils/utils.locale.js +28 -28
- package/core/client/utils/utils.platform.js +11 -11
- package/core/client/utils/utils.push.js +53 -53
- package/core/client/utils/utils.pwa.js +62 -62
- package/core/client/utils/utils.session.js +89 -89
- package/core/common/errors.js +1 -1
- package/core/common/index.js +10 -10
- package/core/common/permissions.js +318 -318
- package/core/common/schema.js +35 -35
- package/core/common/schemas/groups.create.json +28 -28
- package/core/common/schemas/groups.update.json +28 -28
- package/core/common/schemas/organisations.create.json +28 -28
- package/core/common/schemas/organisations.update.json +49 -49
- package/core/common/schemas/settings.update.json +234 -234
- package/core/common/schemas/tags.create.json +35 -35
- package/core/common/schemas/tags.update.json +35 -35
- package/core/common/schemas/users.update-profile.json +33 -33
- package/core/common/utils.js +45 -45
- package/core.api.js +5 -5
- package/core.client.js +5 -5
- package/core.common.js +1 -1
- package/extras/css/core.variables.scss +38 -38
- package/extras/icons/center-on-feature.svg +315 -315
- package/extras/icons/json.svg +83 -83
- package/extras/icons/map-legend.svg +251 -251
- package/extras/icons/target.svg +37 -37
- package/extras/tours/core/account-profile.js +32 -32
- package/extras/tours/core/account.js +143 -143
- package/extras/tours/core/add-member.js +74 -74
- package/extras/tours/core/add-tag.js +12 -12
- package/extras/tours/core/create-group.js +19 -19
- package/extras/tours/core/create-organisation.js +19 -19
- package/extras/tours/core/create-tag.js +26 -26
- package/extras/tours/core/edit-member-role.js +13 -13
- package/extras/tours/core/groups.js +65 -65
- package/extras/tours/core/join-group.js +13 -13
- package/extras/tours/core/login.js +41 -41
- package/extras/tours/core/members.js +108 -108
- package/extras/tours/core/register.js +61 -61
- package/extras/tours/core/send-reset-password.js +14 -14
- package/extras/tours/core/tags.js +65 -65
- package/extras/tours/map/add-layer.js +28 -28
- package/extras/tours/map/catalog-categories.js +59 -59
- package/extras/tours/map/catalog-panel.js +112 -112
- package/extras/tours/map/connect-layer.js +39 -39
- package/extras/tours/map/create-layer.js +33 -33
- package/extras/tours/map/create-view.js +25 -25
- package/extras/tours/map/fab.js +26 -26
- package/extras/tours/map/import-layer.js +33 -33
- package/extras/tours/map/navigation-bar.js +185 -185
- package/extras/tours/map/side-nav.js +35 -35
- package/extras/tours/map/timeline.js +77 -77
- package/map/api/config/categories.cjs +42 -42
- package/map/api/config/layers.cjs +43 -43
- package/map/api/config/sublegends.cjs +42 -42
- package/map/api/hooks/hooks.catalog.js +85 -85
- package/map/api/hooks/hooks.features.js +84 -84
- package/map/api/hooks/hooks.query.js +361 -361
- package/map/api/hooks/index.js +3 -3
- package/map/api/index.js +18 -18
- package/map/api/marshall.js +31 -31
- package/map/api/models/alerts.model.mongodb.js +7 -7
- package/map/api/models/catalog.model.mongodb.js +14 -14
- package/map/api/models/features.model.mongodb.js +37 -37
- package/map/api/services/alerts/alerts.hooks.js +63 -63
- package/map/api/services/alerts/alerts.service.js +175 -175
- package/map/api/services/catalog/catalog.hooks.js +76 -76
- package/map/api/services/daptiles/daptiles.service.js +475 -475
- package/map/api/services/features/features.hooks.js +40 -40
- package/map/api/services/features/features.service.js +52 -52
- package/map/api/services/geocoder/geocoder.hooks.js +31 -31
- package/map/api/services/geocoder/geocoder.service.js +79 -79
- package/map/api/services/index.js +228 -228
- package/map/client/canvas-draw-context.js +16 -16
- package/map/client/cesium/utils.js +133 -133
- package/map/client/components/KCaptureToolbar.vue +155 -155
- package/map/client/components/KColorLegend.vue +349 -349
- package/map/client/components/KCompass.vue +143 -143
- package/map/client/components/KEditLayerData.vue +85 -85
- package/map/client/components/KFeatureActionButton.vue +119 -119
- package/map/client/components/KFeatureEditor.vue +92 -92
- package/map/client/components/KFeaturesChart.vue +285 -285
- package/map/client/components/KFeaturesFilter.vue +259 -259
- package/map/client/components/KFeaturesTable.vue +99 -99
- package/map/client/components/KLayerEditionToolbar.vue +54 -54
- package/map/client/components/KLayerEditor.vue +48 -48
- package/map/client/components/KLayerStyleEditor.vue +118 -118
- package/map/client/components/KLayerStyleForm.vue +906 -906
- package/map/client/components/KLevelSlider.vue +100 -100
- package/map/client/components/KMeasureTool.vue +568 -568
- package/map/client/components/KPositionIndicator.vue +90 -90
- package/map/client/components/KTimeline.vue +293 -293
- package/map/client/components/KTimezoneMap.vue +158 -158
- package/map/client/components/KUrlLegend.vue +122 -122
- package/map/client/components/catalog/KAddLayer.vue +66 -66
- package/map/client/components/catalog/KBaseLayersSelector.vue +114 -114
- package/map/client/components/catalog/KConnectLayer.vue +323 -323
- package/map/client/components/catalog/KCreateLayer.vue +184 -184
- package/map/client/components/catalog/KCreateView.vue +108 -108
- package/map/client/components/catalog/KFilteredLayerItem.vue +53 -53
- package/map/client/components/catalog/KImportLayer.vue +168 -168
- package/map/client/components/catalog/KLayerCategories.vue +274 -274
- package/map/client/components/catalog/KLayerItem.vue +70 -70
- package/map/client/components/catalog/KLayersPanel.vue +137 -137
- package/map/client/components/catalog/KLayersSelector.vue +78 -78
- package/map/client/components/catalog/KViewSelector.vue +46 -46
- package/map/client/components/catalog/KViewsPanel.vue +123 -123
- package/map/client/components/catalog/KWeatherLayersSelector.vue +129 -129
- package/map/client/components/form/KDirectionField.vue +113 -113
- package/map/client/components/form/KLayerCategoryField.vue +46 -46
- package/map/client/components/form/KLocationField.vue +189 -189
- package/map/client/components/form/KOwsLayerField.vue +130 -130
- package/map/client/components/form/KOwsServiceField.vue +238 -238
- package/map/client/components/form/KTimezoneField.vue +142 -142
- package/map/client/components/index.js +1 -1
- package/map/client/components/legend/KColorScaleLegend.vue +31 -31
- package/map/client/components/legend/KImageLegend.vue +52 -52
- package/map/client/components/legend/KLegend.vue +191 -191
- package/map/client/components/legend/KLegendRenderer.vue +20 -20
- package/map/client/components/legend/KSymbolsLegend.vue +101 -101
- package/map/client/components/location/KGeocodersFilter.vue +44 -44
- package/map/client/components/location/KLocationCardSection.vue +61 -61
- package/map/client/components/location/KLocationMap.vue +280 -280
- package/map/client/components/location/KLocationSearch.vue +144 -144
- package/map/client/components/location/KLocationTip.vue +29 -29
- package/map/client/components/tools/KGeolocateTool.vue +46 -46
- package/map/client/components/tools/KSearchTool.vue +93 -93
- package/map/client/components/widget/KElevationProfile.vue +454 -454
- package/map/client/components/widget/KInformationBox.vue +145 -145
- package/map/client/components/widget/KMapillaryViewer.vue +178 -178
- package/map/client/components/widget/KStackableTimeSeries.vue +214 -214
- package/map/client/components/widget/KTimeSeries.vue +500 -500
- package/map/client/composables/activity.js +88 -88
- package/map/client/composables/highlight.js +214 -214
- package/map/client/composables/index.js +7 -7
- package/map/client/composables/location.js +53 -53
- package/map/client/composables/measure.js +42 -42
- package/map/client/composables/probe.js +133 -133
- package/map/client/composables/selection.js +300 -300
- package/map/client/composables/weather.js +213 -213
- package/map/client/elevation-utils.js +258 -258
- package/map/client/geolocation.js +119 -119
- package/map/client/globe.js +13 -13
- package/map/client/i18n/map_en.json +645 -645
- package/map/client/i18n/map_fr.json +646 -646
- package/map/client/index.js +18 -18
- package/map/client/init.js +80 -80
- package/map/client/leaflet/GSMaPLayer.js +55 -55
- package/map/client/leaflet/GradientPath.js +180 -180
- package/map/client/leaflet/MaskLayer.js +57 -57
- package/map/client/leaflet/TiledFeatureLayer.js +572 -572
- package/map/client/leaflet/TiledMeshLayer.js +486 -486
- package/map/client/leaflet/TiledWindLayer.js +384 -384
- package/map/client/leaflet/utils.js +246 -246
- package/map/client/map.js +15 -15
- package/map/client/mixins/globe/index.js +8 -8
- package/map/client/mixins/globe/mixin.base-globe.js +462 -462
- package/map/client/mixins/globe/mixin.file-layers.js +40 -40
- package/map/client/mixins/globe/mixin.geojson-layers.js +314 -314
- package/map/client/mixins/globe/mixin.globe-activity.js +52 -52
- package/map/client/mixins/globe/mixin.opendap-layers.js +51 -51
- package/map/client/mixins/globe/mixin.popup.js +82 -82
- package/map/client/mixins/globe/mixin.style.js +110 -110
- package/map/client/mixins/globe/mixin.tooltip.js +101 -101
- package/map/client/mixins/index.js +9 -9
- package/map/client/mixins/map/index.js +16 -16
- package/map/client/mixins/map/mixin.base-map.js +592 -592
- package/map/client/mixins/map/mixin.canvas-layers.js +529 -529
- package/map/client/mixins/map/mixin.edit-layers.js +493 -474
- package/map/client/mixins/map/mixin.file-layers.js +49 -49
- package/map/client/mixins/map/mixin.forecast-layers.js +79 -79
- package/map/client/mixins/map/mixin.geojson-layers.js +557 -557
- package/map/client/mixins/map/mixin.georaster-layers.js +114 -114
- package/map/client/mixins/map/mixin.gsmap-layers.js +27 -27
- package/map/client/mixins/map/mixin.heatmap-layers.js +116 -116
- package/map/client/mixins/map/mixin.map-activity.js +38 -38
- package/map/client/mixins/map/mixin.mapillary-layers.js +45 -45
- package/map/client/mixins/map/mixin.popup.js +53 -53
- package/map/client/mixins/map/mixin.style.js +73 -73
- package/map/client/mixins/map/mixin.tiled-mesh-layers.js +120 -120
- package/map/client/mixins/map/mixin.tiled-wind-layers.js +126 -126
- package/map/client/mixins/map/mixin.tooltip.js +47 -47
- package/map/client/mixins/mixin.activity.js +477 -477
- package/map/client/mixins/mixin.catalog-panel.js +26 -26
- package/map/client/mixins/mixin.context.js +262 -262
- package/map/client/mixins/mixin.feature-selection.js +28 -28
- package/map/client/mixins/mixin.feature-service.js +403 -403
- package/map/client/mixins/mixin.infobox.js +29 -29
- package/map/client/mixins/mixin.levels.js +66 -66
- package/map/client/mixins/mixin.style.js +29 -29
- package/map/client/mixins/mixin.weacast.js +212 -212
- package/map/client/pixi-utils.js +256 -256
- package/map/client/readers/index.js +4 -4
- package/map/client/readers/reader.geojson.js +64 -64
- package/map/client/readers/reader.gpx.js +36 -36
- package/map/client/readers/reader.kml.js +36 -36
- package/map/client/readers/reader.shp.js +82 -82
- package/map/client/utils/index.js +3 -3
- package/map/client/utils/utils.js +228 -228
- package/map/client/utils/utils.location.js +45 -45
- package/map/client/utils/utils.schema.js +75 -75
- package/map/client/utils.all.js +3 -3
- package/map/client/utils.globe.js +2 -2
- package/map/client/utils.js +4 -4
- package/map/client/utils.map.js +2 -2
- package/map/common/dynamic-grid-source.js +127 -127
- package/map/common/errors.js +3 -3
- package/map/common/geotiff-grid-source.js +150 -150
- package/map/common/grid.js +509 -509
- package/map/common/index.js +29 -29
- package/map/common/meteo-model-grid-source.js +157 -157
- package/map/common/moment-utils.js +24 -24
- package/map/common/opendap-grid-source.js +261 -261
- package/map/common/opendap-utils.js +247 -247
- package/map/common/permissions.js +11 -11
- package/map/common/schemas/catalog.update.json +28 -28
- package/map/common/time-based-grid-source.js +111 -111
- package/map/common/tms-utils.js +63 -63
- package/map/common/wcs-grid-source.js +93 -93
- package/map/common/wcs-utils.js +167 -167
- package/map/common/weacast-grid-source.js +316 -316
- package/map/common/wfs-utils.js +163 -163
- package/map/common/wms-utils.js +117 -117
- package/map/common/wmts-utils.js +154 -154
- package/map.api.js +5 -5
- package/map.client.globe.js +5 -5
- package/map.client.js +5 -5
- package/map.client.map.js +5 -5
- package/map.common.js +1 -1
- package/map.config.cjs +9 -9
- package/package.json +161 -161
- package/test/api/core/account.test.js +485 -485
- package/test/api/core/client.test.js.skip +37 -37
- package/test/api/core/config/default.cjs +118 -118
- package/test/api/core/config/email-templates/confirmInvitation/html.ejs +18 -18
- package/test/api/core/config/email-templates/identityChange/html.ejs +14 -14
- package/test/api/core/config/email-templates/newDevice/html.ejs +7 -7
- package/test/api/core/config/email-templates/newSubscription/html.ejs +7 -7
- package/test/api/core/config/email-templates/passwordChange/html.ejs +5 -5
- package/test/api/core/config/email-templates/resendVerifySignup/html.ejs +12 -12
- package/test/api/core/config/email-templates/resetPwd/html.ejs +5 -5
- package/test/api/core/config/email-templates/sendResetPwd/html.ejs +12 -12
- package/test/api/core/config/email-templates/verifySignup/html.ejs +3 -3
- package/test/api/core/data/invalid-objects.json +59 -59
- package/test/api/core/data/schema.json +57 -57
- package/test/api/core/data/valid-objects.json +37 -37
- package/test/api/core/hooks.test.js +330 -330
- package/test/api/core/index.js +1 -1
- package/test/api/core/index.test.js +478 -478
- package/test/api/core/push.test.js +197 -197
- package/test/api/core/schemas.test.js +82 -82
- package/test/api/core/storage.test.js +153 -153
- package/test/api/core/team.test.js +670 -670
- package/test/api/core/utils.js +92 -92
- package/test/api/index.js +3 -3
- package/test/api/map/alerts.test.js +560 -560
- package/test/api/map/config/default.cjs +125 -125
- package/test/api/map/config/layers.json +38 -38
- package/test/api/map/data/DescribeCoverage.xml +54 -54
- package/test/api/map/data/adsb.observations.json +131 -131
- package/test/api/map/data/dataset.grb.das +55 -55
- package/test/api/map/data/dataset.grb.dds +17 -17
- package/test/api/map/data/vigicrues.observations.json +47041 -47041
- package/test/api/map/data/vigicrues.stations.json +15421 -15421
- package/test/api/map/data/zones.json +1227 -1227
- package/test/api/map/grid-sources.test.js +313 -313
- package/test/api/map/hooks.test.js +98 -98
- package/test/api/map/index.test.js +563 -563
- package/test/client/core/account.js +36 -36
- package/test/client/core/api.js +361 -361
- package/test/client/core/collection.js +64 -64
- package/test/client/core/index.js +8 -8
- package/test/client/core/layout.js +116 -116
- package/test/client/core/runner.js +224 -224
- package/test/client/core/screens.js +35 -35
- package/test/client/core/time.js +10 -10
- package/test/client/core/utils.js +260 -260
- package/test/client/index.js +3 -3
- package/test/client/map/catalog.js +193 -193
- package/test/client/map/controls.js +41 -41
- package/test/client/map/index.js +4 -4
- package/test/client/map/time.js +24 -24
- package/test/client/map/utils.js +27 -27
- package/coverage/base.css +0 -224
- package/coverage/block-navigation.js +0 -87
- package/coverage/core/api/application.js.html +0 -1789
- package/coverage/core/api/authentication.js.html +0 -694
- package/coverage/core/api/db.js.html +0 -751
- package/coverage/core/api/hooks/hooks.account.js.html +0 -169
- package/coverage/core/api/hooks/hooks.authentication.js.html +0 -274
- package/coverage/core/api/hooks/hooks.authorisations.js.html +0 -1201
- package/coverage/core/api/hooks/hooks.devices.js.html +0 -211
- package/coverage/core/api/hooks/hooks.groups.js.html +0 -229
- package/coverage/core/api/hooks/hooks.logger.js.html +0 -163
- package/coverage/core/api/hooks/hooks.model.js.html +0 -988
- package/coverage/core/api/hooks/hooks.organisations.js.html +0 -823
- package/coverage/core/api/hooks/hooks.pusher.js.html +0 -730
- package/coverage/core/api/hooks/hooks.query.js.html +0 -838
- package/coverage/core/api/hooks/hooks.schemas.js.html +0 -244
- package/coverage/core/api/hooks/hooks.service.js.html +0 -319
- package/coverage/core/api/hooks/hooks.storage.js.html +0 -193
- package/coverage/core/api/hooks/hooks.tags.js.html +0 -850
- package/coverage/core/api/hooks/hooks.users.js.html +0 -889
- package/coverage/core/api/hooks/index.html +0 -341
- package/coverage/core/api/hooks/index.js.html +0 -130
- package/coverage/core/api/index.html +0 -176
- package/coverage/core/api/index.js.html +0 -148
- package/coverage/core/api/marshall.js.html +0 -355
- package/coverage/core/api/models/groups.model.mongodb.js.html +0 -109
- package/coverage/core/api/models/index.html +0 -161
- package/coverage/core/api/models/organisations.model.mongodb.js.html +0 -94
- package/coverage/core/api/models/tags.model.mongodb.js.html +0 -115
- package/coverage/core/api/models/users.model.mongodb.js.html +0 -115
- package/coverage/core/api/oauth2-handler.js.html +0 -202
- package/coverage/core/api/oauth2-verifier.js.html +0 -355
- package/coverage/core/api/services/account/account.hooks.js.html +0 -196
- package/coverage/core/api/services/account/account.service.js.html +0 -448
- package/coverage/core/api/services/account/index.html +0 -131
- package/coverage/core/api/services/authorisations/authorisations.hooks.js.html +0 -184
- package/coverage/core/api/services/authorisations/authorisations.service.js.html +0 -502
- package/coverage/core/api/services/authorisations/index.html +0 -131
- package/coverage/core/api/services/databases/databases.hooks.js.html +0 -193
- package/coverage/core/api/services/databases/databases.service.js.html +0 -100
- package/coverage/core/api/services/databases/index.html +0 -131
- package/coverage/core/api/services/devices/devices.hooks.js.html +0 -190
- package/coverage/core/api/services/devices/devices.service.js.html +0 -382
- package/coverage/core/api/services/devices/index.html +0 -131
- package/coverage/core/api/services/groups/groups.hooks.js.html +0 -184
- package/coverage/core/api/services/groups/index.html +0 -116
- package/coverage/core/api/services/index.html +0 -116
- package/coverage/core/api/services/index.js.html +0 -472
- package/coverage/core/api/services/mailer/index.html +0 -131
- package/coverage/core/api/services/mailer/mailer.hooks.js.html +0 -190
- package/coverage/core/api/services/mailer/mailer.service.js.html +0 -118
- package/coverage/core/api/services/organisations/index.html +0 -131
- package/coverage/core/api/services/organisations/organisations.hooks.js.html +0 -178
- package/coverage/core/api/services/organisations/organisations.service.js.html +0 -319
- package/coverage/core/api/services/pusher/index.html +0 -146
- package/coverage/core/api/services/pusher/pusher.channels.js.html +0 -94
- package/coverage/core/api/services/pusher/pusher.hooks.js.html +0 -193
- package/coverage/core/api/services/pusher/pusher.service.js.html +0 -1420
- package/coverage/core/api/services/storage/index.html +0 -131
- package/coverage/core/api/services/storage/storage.hooks.js.html +0 -190
- package/coverage/core/api/services/storage/storage.service.js.html +0 -172
- package/coverage/core/api/services/tags/index.html +0 -116
- package/coverage/core/api/services/tags/tags.hooks.js.html +0 -220
- package/coverage/core/api/services/users/index.html +0 -116
- package/coverage/core/api/services/users/users.hooks.js.html +0 -313
- package/coverage/core/common/errors.js.html +0 -88
- package/coverage/core/common/index.html +0 -176
- package/coverage/core/common/index.js.html +0 -115
- package/coverage/core/common/permissions.js.html +0 -1015
- package/coverage/core/common/schema.js.html +0 -190
- package/coverage/core/common/utils.js.html +0 -220
- package/coverage/favicon.png +0 -0
- package/coverage/index.html +0 -491
- package/coverage/lcov-report/base.css +0 -224
- package/coverage/lcov-report/block-navigation.js +0 -87
- package/coverage/lcov-report/core/api/application.js.html +0 -1789
- package/coverage/lcov-report/core/api/authentication.js.html +0 -694
- package/coverage/lcov-report/core/api/db.js.html +0 -751
- package/coverage/lcov-report/core/api/hooks/hooks.account.js.html +0 -169
- package/coverage/lcov-report/core/api/hooks/hooks.authentication.js.html +0 -274
- package/coverage/lcov-report/core/api/hooks/hooks.authorisations.js.html +0 -1201
- package/coverage/lcov-report/core/api/hooks/hooks.devices.js.html +0 -211
- package/coverage/lcov-report/core/api/hooks/hooks.groups.js.html +0 -229
- package/coverage/lcov-report/core/api/hooks/hooks.logger.js.html +0 -163
- package/coverage/lcov-report/core/api/hooks/hooks.model.js.html +0 -988
- package/coverage/lcov-report/core/api/hooks/hooks.organisations.js.html +0 -823
- package/coverage/lcov-report/core/api/hooks/hooks.pusher.js.html +0 -730
- package/coverage/lcov-report/core/api/hooks/hooks.query.js.html +0 -838
- package/coverage/lcov-report/core/api/hooks/hooks.schemas.js.html +0 -244
- package/coverage/lcov-report/core/api/hooks/hooks.service.js.html +0 -319
- package/coverage/lcov-report/core/api/hooks/hooks.storage.js.html +0 -193
- package/coverage/lcov-report/core/api/hooks/hooks.tags.js.html +0 -850
- package/coverage/lcov-report/core/api/hooks/hooks.users.js.html +0 -889
- package/coverage/lcov-report/core/api/hooks/index.html +0 -341
- package/coverage/lcov-report/core/api/hooks/index.js.html +0 -130
- package/coverage/lcov-report/core/api/index.html +0 -176
- package/coverage/lcov-report/core/api/index.js.html +0 -148
- package/coverage/lcov-report/core/api/marshall.js.html +0 -355
- package/coverage/lcov-report/core/api/models/groups.model.mongodb.js.html +0 -109
- package/coverage/lcov-report/core/api/models/index.html +0 -161
- package/coverage/lcov-report/core/api/models/organisations.model.mongodb.js.html +0 -94
- package/coverage/lcov-report/core/api/models/tags.model.mongodb.js.html +0 -115
- package/coverage/lcov-report/core/api/models/users.model.mongodb.js.html +0 -115
- package/coverage/lcov-report/core/api/oauth2-handler.js.html +0 -202
- package/coverage/lcov-report/core/api/oauth2-verifier.js.html +0 -355
- package/coverage/lcov-report/core/api/services/account/account.hooks.js.html +0 -196
- package/coverage/lcov-report/core/api/services/account/account.service.js.html +0 -448
- package/coverage/lcov-report/core/api/services/account/index.html +0 -131
- package/coverage/lcov-report/core/api/services/authorisations/authorisations.hooks.js.html +0 -184
- package/coverage/lcov-report/core/api/services/authorisations/authorisations.service.js.html +0 -502
- package/coverage/lcov-report/core/api/services/authorisations/index.html +0 -131
- package/coverage/lcov-report/core/api/services/databases/databases.hooks.js.html +0 -193
- package/coverage/lcov-report/core/api/services/databases/databases.service.js.html +0 -100
- package/coverage/lcov-report/core/api/services/databases/index.html +0 -131
- package/coverage/lcov-report/core/api/services/devices/devices.hooks.js.html +0 -190
- package/coverage/lcov-report/core/api/services/devices/devices.service.js.html +0 -382
- package/coverage/lcov-report/core/api/services/devices/index.html +0 -131
- package/coverage/lcov-report/core/api/services/groups/groups.hooks.js.html +0 -184
- package/coverage/lcov-report/core/api/services/groups/index.html +0 -116
- package/coverage/lcov-report/core/api/services/index.html +0 -116
- package/coverage/lcov-report/core/api/services/index.js.html +0 -472
- package/coverage/lcov-report/core/api/services/mailer/index.html +0 -131
- package/coverage/lcov-report/core/api/services/mailer/mailer.hooks.js.html +0 -190
- package/coverage/lcov-report/core/api/services/mailer/mailer.service.js.html +0 -118
- package/coverage/lcov-report/core/api/services/organisations/index.html +0 -131
- package/coverage/lcov-report/core/api/services/organisations/organisations.hooks.js.html +0 -178
- package/coverage/lcov-report/core/api/services/organisations/organisations.service.js.html +0 -319
- package/coverage/lcov-report/core/api/services/pusher/index.html +0 -146
- package/coverage/lcov-report/core/api/services/pusher/pusher.channels.js.html +0 -94
- package/coverage/lcov-report/core/api/services/pusher/pusher.hooks.js.html +0 -193
- package/coverage/lcov-report/core/api/services/pusher/pusher.service.js.html +0 -1420
- package/coverage/lcov-report/core/api/services/storage/index.html +0 -131
- package/coverage/lcov-report/core/api/services/storage/storage.hooks.js.html +0 -190
- package/coverage/lcov-report/core/api/services/storage/storage.service.js.html +0 -172
- package/coverage/lcov-report/core/api/services/tags/index.html +0 -116
- package/coverage/lcov-report/core/api/services/tags/tags.hooks.js.html +0 -220
- package/coverage/lcov-report/core/api/services/users/index.html +0 -116
- package/coverage/lcov-report/core/api/services/users/users.hooks.js.html +0 -313
- package/coverage/lcov-report/core/common/errors.js.html +0 -88
- package/coverage/lcov-report/core/common/index.html +0 -176
- package/coverage/lcov-report/core/common/index.js.html +0 -115
- package/coverage/lcov-report/core/common/permissions.js.html +0 -1015
- package/coverage/lcov-report/core/common/schema.js.html +0 -190
- package/coverage/lcov-report/core/common/utils.js.html +0 -220
- package/coverage/lcov-report/favicon.png +0 -0
- package/coverage/lcov-report/index.html +0 -491
- package/coverage/lcov-report/map/api/hooks/hooks.catalog.js.html +0 -340
- package/coverage/lcov-report/map/api/hooks/hooks.features.js.html +0 -337
- package/coverage/lcov-report/map/api/hooks/hooks.query.js.html +0 -1162
- package/coverage/lcov-report/map/api/hooks/index.html +0 -161
- package/coverage/lcov-report/map/api/hooks/index.js.html +0 -94
- package/coverage/lcov-report/map/api/index.html +0 -131
- package/coverage/lcov-report/map/api/index.js.html +0 -139
- package/coverage/lcov-report/map/api/marshall.js.html +0 -178
- package/coverage/lcov-report/map/api/models/alerts.model.mongodb.js.html +0 -106
- package/coverage/lcov-report/map/api/models/catalog.model.mongodb.js.html +0 -127
- package/coverage/lcov-report/map/api/models/features.model.mongodb.js.html +0 -202
- package/coverage/lcov-report/map/api/models/index.html +0 -146
- package/coverage/lcov-report/map/api/services/alerts/alerts.hooks.js.html +0 -274
- package/coverage/lcov-report/map/api/services/alerts/alerts.service.js.html +0 -610
- package/coverage/lcov-report/map/api/services/alerts/index.html +0 -131
- package/coverage/lcov-report/map/api/services/catalog/catalog.hooks.js.html +0 -313
- package/coverage/lcov-report/map/api/services/catalog/index.html +0 -116
- package/coverage/lcov-report/map/api/services/daptiles/daptiles.service.js.html +0 -1510
- package/coverage/lcov-report/map/api/services/daptiles/index.html +0 -116
- package/coverage/lcov-report/map/api/services/features/features.hooks.js.html +0 -205
- package/coverage/lcov-report/map/api/services/features/features.service.js.html +0 -241
- package/coverage/lcov-report/map/api/services/features/index.html +0 -131
- package/coverage/lcov-report/map/api/services/geocoder/geocoder.hooks.js.html +0 -178
- package/coverage/lcov-report/map/api/services/geocoder/geocoder.service.js.html +0 -322
- package/coverage/lcov-report/map/api/services/geocoder/index.html +0 -131
- package/coverage/lcov-report/map/api/services/index.html +0 -116
- package/coverage/lcov-report/map/api/services/index.js.html +0 -760
- package/coverage/lcov-report/map/common/dynamic-grid-source.js.html +0 -466
- package/coverage/lcov-report/map/common/errors.js.html +0 -94
- package/coverage/lcov-report/map/common/geotiff-grid-source.js.html +0 -535
- package/coverage/lcov-report/map/common/grid.js.html +0 -1612
- package/coverage/lcov-report/map/common/index.html +0 -371
- package/coverage/lcov-report/map/common/index.js.html +0 -172
- package/coverage/lcov-report/map/common/meteo-model-grid-source.js.html +0 -556
- package/coverage/lcov-report/map/common/moment-utils.js.html +0 -157
- package/coverage/lcov-report/map/common/opendap-grid-source.js.html +0 -868
- package/coverage/lcov-report/map/common/opendap-utils.js.html +0 -826
- package/coverage/lcov-report/map/common/permissions.js.html +0 -118
- package/coverage/lcov-report/map/common/time-based-grid-source.js.html +0 -418
- package/coverage/lcov-report/map/common/tms-utils.js.html +0 -274
- package/coverage/lcov-report/map/common/wcs-grid-source.js.html +0 -364
- package/coverage/lcov-report/map/common/wcs-utils.js.html +0 -586
- package/coverage/lcov-report/map/common/weacast-grid-source.js.html +0 -1033
- package/coverage/lcov-report/map/common/wfs-utils.js.html +0 -574
- package/coverage/lcov-report/map/common/wms-utils.js.html +0 -436
- package/coverage/lcov-report/map/common/wmts-utils.js.html +0 -547
- package/coverage/lcov-report/prettify.css +0 -1
- package/coverage/lcov-report/prettify.js +0 -2
- package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
- package/coverage/lcov-report/sorter.js +0 -196
- package/coverage/lcov.info +0 -12501
- package/coverage/map/api/hooks/hooks.catalog.js.html +0 -340
- package/coverage/map/api/hooks/hooks.features.js.html +0 -337
- package/coverage/map/api/hooks/hooks.query.js.html +0 -1162
- package/coverage/map/api/hooks/index.html +0 -161
- package/coverage/map/api/hooks/index.js.html +0 -94
- package/coverage/map/api/index.html +0 -131
- package/coverage/map/api/index.js.html +0 -139
- package/coverage/map/api/marshall.js.html +0 -178
- package/coverage/map/api/models/alerts.model.mongodb.js.html +0 -106
- package/coverage/map/api/models/catalog.model.mongodb.js.html +0 -127
- package/coverage/map/api/models/features.model.mongodb.js.html +0 -202
- package/coverage/map/api/models/index.html +0 -146
- package/coverage/map/api/services/alerts/alerts.hooks.js.html +0 -274
- package/coverage/map/api/services/alerts/alerts.service.js.html +0 -610
- package/coverage/map/api/services/alerts/index.html +0 -131
- package/coverage/map/api/services/catalog/catalog.hooks.js.html +0 -313
- package/coverage/map/api/services/catalog/index.html +0 -116
- package/coverage/map/api/services/daptiles/daptiles.service.js.html +0 -1510
- package/coverage/map/api/services/daptiles/index.html +0 -116
- package/coverage/map/api/services/features/features.hooks.js.html +0 -205
- package/coverage/map/api/services/features/features.service.js.html +0 -241
- package/coverage/map/api/services/features/index.html +0 -131
- package/coverage/map/api/services/geocoder/geocoder.hooks.js.html +0 -178
- package/coverage/map/api/services/geocoder/geocoder.service.js.html +0 -322
- package/coverage/map/api/services/geocoder/index.html +0 -131
- package/coverage/map/api/services/index.html +0 -116
- package/coverage/map/api/services/index.js.html +0 -760
- package/coverage/map/common/dynamic-grid-source.js.html +0 -466
- package/coverage/map/common/errors.js.html +0 -94
- package/coverage/map/common/geotiff-grid-source.js.html +0 -535
- package/coverage/map/common/grid.js.html +0 -1612
- package/coverage/map/common/index.html +0 -371
- package/coverage/map/common/index.js.html +0 -172
- package/coverage/map/common/meteo-model-grid-source.js.html +0 -556
- package/coverage/map/common/moment-utils.js.html +0 -157
- package/coverage/map/common/opendap-grid-source.js.html +0 -868
- package/coverage/map/common/opendap-utils.js.html +0 -826
- package/coverage/map/common/permissions.js.html +0 -118
- package/coverage/map/common/time-based-grid-source.js.html +0 -418
- package/coverage/map/common/tms-utils.js.html +0 -274
- package/coverage/map/common/wcs-grid-source.js.html +0 -364
- package/coverage/map/common/wcs-utils.js.html +0 -586
- package/coverage/map/common/weacast-grid-source.js.html +0 -1033
- package/coverage/map/common/wfs-utils.js.html +0 -574
- package/coverage/map/common/wms-utils.js.html +0 -436
- package/coverage/map/common/wmts-utils.js.html +0 -547
- package/coverage/prettify.css +0 -1
- package/coverage/prettify.js +0 -2
- package/coverage/sort-arrow-sprite.png +0 -0
- package/coverage/sorter.js +0 -196
- package/coverage/tmp/coverage-19264-1684834146599-0.json +0 -1
- package/coverage/tmp/coverage-2508-1684834182408-0.json +0 -1
- package/coverage/tmp/coverage-25908-1684834189369-0.json +0 -1
- package/coverage/tmp/coverage-32364-1684834189420-0.json +0 -1
- package/coverage/tmp/coverage-36604-1684834189485-0.json +0 -1
- package/coverage/tmp/coverage-40652-1684834182272-0.json +0 -1
- package/coverage/tmp/coverage-48484-1684834182342-0.json +0 -1
- package/coverage/tmp/coverage-51652-1684834189584-0.json +0 -1
- package/coverage/tmp/coverage-9776-1684834189519-0.json +0 -1
- package/test/api/core/test-log-2023-06-05.log +0 -0
- package/test/api/map/test-log-2022-12-01.log +0 -19
- package/test/api/map/test-log-2023-01-05.log +0 -4
- package/test/api/map/test-log-2023-01-09.log +0 -3
- package/test/api/map/test-log-2023-02-05.log +0 -11
- package/test/api/map/test-log-2023-02-14.log +0 -82
- package/test/api/map/test-log-2023-02-28.log +0 -28
- package/test/api/map/test-log-2023-03-02.log +0 -11
- package/test/api/map/test-log-2023-03-06.log +0 -11
- package/test/api/map/test-log-2023-03-07.log +0 -61
- package/test/api/map/test-log-2023-03-31.log +0 -11
- package/test/api/map/test-log-2023-05-23.log +0 -11
- package/test/api/map/test-log-2023-05-24.log +0 -11
|
@@ -1,318 +1,318 @@
|
|
|
1
|
-
import _ from 'lodash'
|
|
2
|
-
import { AbilityBuilder, Ability, createAliasResolver } from '@casl/ability'
|
|
3
|
-
import { toMongoQuery } from '@casl/mongoose'
|
|
4
|
-
|
|
5
|
-
// Define some alias to simplify ability definitions
|
|
6
|
-
const resolveAction = createAliasResolver({
|
|
7
|
-
update: ['patch'],
|
|
8
|
-
read: ['get', 'find'],
|
|
9
|
-
remove: ['delete'],
|
|
10
|
-
all: ['read', 'create', 'update', 'remove']
|
|
11
|
-
})
|
|
12
|
-
|
|
13
|
-
export const Roles = {
|
|
14
|
-
member: 0,
|
|
15
|
-
manager: 1,
|
|
16
|
-
owner: 2
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export const RoleNames = [
|
|
20
|
-
'member',
|
|
21
|
-
'manager',
|
|
22
|
-
'owner'
|
|
23
|
-
]
|
|
24
|
-
|
|
25
|
-
// Hooks that can be added to customize abilities computation
|
|
26
|
-
let hooks = []
|
|
27
|
-
|
|
28
|
-
// Get the unique global symbol to store resource type / context on a resource object
|
|
29
|
-
export const RESOURCE_TYPE = 'type'
|
|
30
|
-
export const RESOURCE_TYPE_KEY = Symbol.for(RESOURCE_TYPE)
|
|
31
|
-
|
|
32
|
-
export function defineResourceRules (subject, resource, resourceService, can) {
|
|
33
|
-
const role = Roles[resource.permissions]
|
|
34
|
-
|
|
35
|
-
if (role >= Roles.member) {
|
|
36
|
-
can('read', resourceService, { _id: resource._id })
|
|
37
|
-
}
|
|
38
|
-
if (role >= Roles.manager) {
|
|
39
|
-
can('update', resourceService, { _id: resource._id })
|
|
40
|
-
can(['create', 'remove'], 'authorisations', { resource: resource._id })
|
|
41
|
-
}
|
|
42
|
-
if (role >= Roles.owner) {
|
|
43
|
-
can('remove', resourceService, { _id: resource._id })
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
// Hook computing default abilities for a given user
|
|
48
|
-
export function defineUserAbilities (subject, can, cannot) {
|
|
49
|
-
// Allow user registration
|
|
50
|
-
can('service', 'users')
|
|
51
|
-
can('create', 'users')
|
|
52
|
-
// Verification email, reset password, etc.
|
|
53
|
-
can('service', 'account')
|
|
54
|
-
can(['create', 'verifyEmail'], 'account')
|
|
55
|
-
// Allow push registration
|
|
56
|
-
can('service', 'push')
|
|
57
|
-
can('create', 'push')
|
|
58
|
-
if (subject && subject._id) {
|
|
59
|
-
// Read user profiles for authorizing
|
|
60
|
-
can('read', 'users')
|
|
61
|
-
// Update user profile and destroy it
|
|
62
|
-
can(['update', 'remove'], 'users', { _id: subject._id })
|
|
63
|
-
// Access authorisation service, then rights will be granted on a per-resource basis
|
|
64
|
-
can('service', 'authorisations')
|
|
65
|
-
// Access storage service, then rights will be granted on a per-resource basis
|
|
66
|
-
can('service', 'storage')
|
|
67
|
-
// This is for the user avatar
|
|
68
|
-
// take care that the storage service uses 'id' as input but produces _id as output
|
|
69
|
-
can('create', 'storage', { id: 'avatars/' + subject._id.toString() })
|
|
70
|
-
can('create', 'storage', { id: 'avatars/' + subject._id.toString() + '.thumbnail' })
|
|
71
|
-
can(['createMultipartUpload', 'completeMultipartUpload', 'uploadPart', 'putObject'], 'storage', { id: 'avatars/' + subject._id.toString() })
|
|
72
|
-
can(['createMultipartUpload', 'completeMultipartUpload', 'uploadPart', 'putObject'], 'storage', { id: 'avatars/' + subject._id.toString() + '.thumbnail' })
|
|
73
|
-
can('remove', 'storage', { _id: 'avatars/' + subject._id.toString() })
|
|
74
|
-
can('remove', 'storage', { _id: 'avatars/' + subject._id.toString() + '.thumbnail' })
|
|
75
|
-
// Avatar is part of user profiles so that they can be read by any
|
|
76
|
-
can('read', 'storage', { _id: { $regex: '^avatars/*' } })
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
// Compute abilities for a given user
|
|
81
|
-
export async function defineAbilities (subject, ...args) {
|
|
82
|
-
const { build, can, cannot } = new AbilityBuilder(Ability)
|
|
83
|
-
|
|
84
|
-
// Run registered hooks providing any additional arguments used to handle complex use cases
|
|
85
|
-
await Promise.all(hooks.map(async hook => {
|
|
86
|
-
await hook(subject, can, cannot, ...args)
|
|
87
|
-
}))
|
|
88
|
-
|
|
89
|
-
// CASL cannot infer the object type from the object itself so we need
|
|
90
|
-
// to tell it how he can find the object type, i.e. service name.
|
|
91
|
-
return build({
|
|
92
|
-
detectSubjectType: resource => {
|
|
93
|
-
if (!resource || typeof resource === 'string') {
|
|
94
|
-
return resource
|
|
95
|
-
}
|
|
96
|
-
return resource[RESOURCE_TYPE_KEY]
|
|
97
|
-
},
|
|
98
|
-
resolveAction
|
|
99
|
-
})
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
defineAbilities.registerHook = function (hook) {
|
|
103
|
-
if (!hooks.includes(hook)) {
|
|
104
|
-
hooks.push(hook)
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
defineAbilities.unregisterHook = function (hook) {
|
|
109
|
-
hooks = hooks.filter(registeredHook => registeredHook !== hook)
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
export function hasServiceAbilities (abilities, service) {
|
|
113
|
-
if (!abilities) return false
|
|
114
|
-
// The unique identifier of a service is its path not its name.
|
|
115
|
-
// Indeed we have for instance a 'groups' service in each organisation
|
|
116
|
-
// Take care that in client we have the service path while on server we have the actual object
|
|
117
|
-
const path = typeof service === 'string' ? service : service.getPath()
|
|
118
|
-
// */groups will allow to access any groups service in any context
|
|
119
|
-
return abilities.can('service', path) ||
|
|
120
|
-
abilities.can('service', `*/${path}`) ||
|
|
121
|
-
abilities.can('service', _.replace(path, /^.*\//, '*/'))
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
export function hasResourceAbilities (abilities, operation, resourceType, context, resource) {
|
|
125
|
-
if (!abilities) return false
|
|
126
|
-
// Create a shallow copy adding context and type
|
|
127
|
-
const object = Object.assign({}, resource)
|
|
128
|
-
object[RESOURCE_TYPE_KEY] = resourceType
|
|
129
|
-
// Add a virtual context to take it into account for object having no link to it
|
|
130
|
-
if (context) object.context = (typeof context === 'object' ? context._id.toString() : context.toString())
|
|
131
|
-
|
|
132
|
-
const result = abilities.can(operation, object)
|
|
133
|
-
|
|
134
|
-
return result
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
// Utility function used to remove the virtual context from query
|
|
138
|
-
export function removeContext (query) {
|
|
139
|
-
_.forOwn(query, (value, key) => {
|
|
140
|
-
// Process current attributes or recurse
|
|
141
|
-
// Take care to nested fields like 'field._id'
|
|
142
|
-
if (key === 'context') {
|
|
143
|
-
delete query.context
|
|
144
|
-
} else if (Array.isArray(value)) {
|
|
145
|
-
value.forEach(item => removeContext(item))
|
|
146
|
-
// Remove empty objects from array
|
|
147
|
-
// _.remove(value, item => _.isEmpty(item))
|
|
148
|
-
// Remove empty arrays from query
|
|
149
|
-
if (_.isEmpty(value)) delete query[key]
|
|
150
|
-
} else if (typeof value === 'object') {
|
|
151
|
-
removeContext(value)
|
|
152
|
-
// Remove empty objects from query
|
|
153
|
-
if (_.isEmpty(value)) delete query[key]
|
|
154
|
-
}
|
|
155
|
-
})
|
|
156
|
-
return query
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
// Get the query used to filter the objects according to given abilities
|
|
160
|
-
// A null query indicates that access should not be granted
|
|
161
|
-
export function getQueryForAbilities (abilities, operation, resourceType) {
|
|
162
|
-
if (!abilities) return null
|
|
163
|
-
|
|
164
|
-
const query = toMongoQuery(abilities, resourceType, operation)
|
|
165
|
-
// Remove any context to avoid taking it into account because it is not really stored on objects
|
|
166
|
-
// We clone the object here because of references to the abilities rules (see https://github.com/kalisio/kdk/issues/384)
|
|
167
|
-
return (query ? removeContext(_.cloneDeep(query)) : null)
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
function buildSubjectsQueryForResource (resourceScope, resourceId, role) {
|
|
171
|
-
const query = { [resourceScope]: { $elemMatch: { _id: resourceId } } }
|
|
172
|
-
if (role) {
|
|
173
|
-
_.set(query[resourceScope], '$elemMatch.permissions', (typeof role === 'string' ? role : RoleNames[role]))
|
|
174
|
-
}
|
|
175
|
-
return query
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
export function findSubjectsForResource (subjectService, resourceScope, resourceId, role) {
|
|
179
|
-
// Build the query
|
|
180
|
-
const query = buildSubjectsQueryForResource(resourceScope, resourceId, role)
|
|
181
|
-
// Execute the query
|
|
182
|
-
return subjectService.find({ query })
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
export function countSubjectsForResource (subjectService, resourceScope, resourceId, role) {
|
|
186
|
-
// Build the query
|
|
187
|
-
const query = buildSubjectsQueryForResource(resourceScope, resourceId, role)
|
|
188
|
-
// Indicate we'd only like to count
|
|
189
|
-
query.$limit = 0
|
|
190
|
-
// Execute the query
|
|
191
|
-
return subjectService.find({ query })
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
// Hook computing organisation abilities for a given user
|
|
195
|
-
export function defineOrganisationAbilities (subject, can, cannot) {
|
|
196
|
-
if (subject) {
|
|
197
|
-
// Create new organisations
|
|
198
|
-
can('service', 'organisations')
|
|
199
|
-
can('create', 'organisations')
|
|
200
|
-
|
|
201
|
-
if (subject.organisations) {
|
|
202
|
-
subject.organisations.forEach(organisation => {
|
|
203
|
-
if (organisation._id) {
|
|
204
|
-
// Generic rules for resources
|
|
205
|
-
defineResourceRules(subject, organisation, 'organisations', can)
|
|
206
|
-
// Specific rules for organisations
|
|
207
|
-
const role = Roles[organisation.permissions]
|
|
208
|
-
if (role >= Roles.member) {
|
|
209
|
-
// The unique identifier of a service is its path not its name.
|
|
210
|
-
// Indeed we have for instance a 'groups' service in each organisation.
|
|
211
|
-
can('service', organisation._id.toString() + '/members')
|
|
212
|
-
can('read', 'members', { context: organisation._id })
|
|
213
|
-
can('service', organisation._id.toString() + '/tags')
|
|
214
|
-
// Tags are public
|
|
215
|
-
can('read', 'tags', { context: organisation._id })
|
|
216
|
-
// Groups are private
|
|
217
|
-
can('service', organisation._id.toString() + '/groups')
|
|
218
|
-
can('service', organisation._id.toString() + '/storage')
|
|
219
|
-
can(['read', 'create', 'remove', 'createMultipartUpload', 'completeMultipartUpload', 'uploadPart', 'putObject'], 'storage', { context: organisation._id })
|
|
220
|
-
}
|
|
221
|
-
if (role >= Roles.manager) {
|
|
222
|
-
can('update', 'members', { context: organisation._id })
|
|
223
|
-
// Managers can manage all groups/tags
|
|
224
|
-
can('all', 'groups', { context: organisation._id })
|
|
225
|
-
can(['create', 'remove'], 'authorisations', { resourcesService: organisation._id.toString() + '/groups', scope: 'groups' })
|
|
226
|
-
can('all', 'tags', { context: organisation._id })
|
|
227
|
-
// Remove invited members
|
|
228
|
-
can(['remove'], 'users', { 'sponsor.organisationId': organisation._id })
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
})
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
// Hook computing group abilities for a given user
|
|
237
|
-
export function defineGroupAbilities (subject, can, cannot) {
|
|
238
|
-
if (subject) {
|
|
239
|
-
if (subject.groups) {
|
|
240
|
-
subject.groups.forEach(group => {
|
|
241
|
-
if (group._id) {
|
|
242
|
-
// Specific rules for groups
|
|
243
|
-
const role = Roles[group.permissions]
|
|
244
|
-
|
|
245
|
-
if (role >= Roles.member) {
|
|
246
|
-
can('read', 'groups', { _id: group._id })
|
|
247
|
-
}
|
|
248
|
-
if (role >= Roles.manager) {
|
|
249
|
-
can(['create', 'remove'], 'authorisations', { resource: group._id, permissions: 'member' })
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
})
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
// Helper functions to find the members of a given organisation
|
|
258
|
-
export function findMembersOfOrganisation (usersService, organisationId, role) {
|
|
259
|
-
return findSubjectsForResource(usersService, 'organisations', organisationId, role)
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
export function countMembersOfOrganisation (usersService, organisationId, role) {
|
|
263
|
-
return countSubjectsForResource(usersService, 'organisations', organisationId, role)
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
// Helper functions to find the members of a given group
|
|
267
|
-
export function findMembersOfGroup (membersService, groupId, role) {
|
|
268
|
-
return findSubjectsForResource(membersService, 'groups', groupId, role)
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
export function countMembersOfGroup (membersService, groupId, role) {
|
|
272
|
-
return countSubjectsForResource(membersService, 'groups', groupId, role)
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
// Helper functions to find the members with a given tag
|
|
276
|
-
export function findMembersWithTag (membersService, tagId) {
|
|
277
|
-
return findSubjectsForResource(membersService, 'tags', tagId)
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
export function countMembersWithTag (membersService, tagId) {
|
|
281
|
-
return countSubjectsForResource(membersService, 'tags', tagId)
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
export function getRoleForOrganisation (user, organisationId) {
|
|
285
|
-
const result = _.find(user.organisations, { _id: organisationId })
|
|
286
|
-
if (!_.isUndefined(result)) return result.permissions
|
|
287
|
-
return undefined
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
export function getRoleForGroup (user, organisationId, groupId) {
|
|
291
|
-
const result = _.find(user.groups, { context: organisationId, _id: groupId })
|
|
292
|
-
if (!_.isUndefined(result)) return result.permissions
|
|
293
|
-
return undefined
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
export function findGroupsWithRole (user, organisationId, role) {
|
|
297
|
-
return _.filter(user.groups || [], { context: organisationId, permissions: (typeof role === 'string' ? role : RoleNames[role]) })
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
export function isSeniorRole (roleName, juniorName) {
|
|
301
|
-
return Roles[roleName] >= Roles[juniorName]
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
export function isJuniorRole (roleName, seniorName) {
|
|
305
|
-
return Roles[roleName] < Roles[seniorName]
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
export function getSeniorRoles (roleName) {
|
|
309
|
-
const seniorRoles = []
|
|
310
|
-
_.forEach(Roles, role => { if (Roles[roleName] < role) seniorRoles.push(RoleNames[role]) })
|
|
311
|
-
return seniorRoles
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
export function getJuniorRoles (roleName) {
|
|
315
|
-
const juniorRoles = []
|
|
316
|
-
_.forEach(Roles, role => { if (Roles[roleName] >= role) juniorRoles.push(RoleNames[role]) })
|
|
317
|
-
return juniorRoles
|
|
318
|
-
}
|
|
1
|
+
import _ from 'lodash'
|
|
2
|
+
import { AbilityBuilder, Ability, createAliasResolver } from '@casl/ability'
|
|
3
|
+
import { toMongoQuery } from '@casl/mongoose'
|
|
4
|
+
|
|
5
|
+
// Define some alias to simplify ability definitions
|
|
6
|
+
const resolveAction = createAliasResolver({
|
|
7
|
+
update: ['patch'],
|
|
8
|
+
read: ['get', 'find'],
|
|
9
|
+
remove: ['delete'],
|
|
10
|
+
all: ['read', 'create', 'update', 'remove']
|
|
11
|
+
})
|
|
12
|
+
|
|
13
|
+
export const Roles = {
|
|
14
|
+
member: 0,
|
|
15
|
+
manager: 1,
|
|
16
|
+
owner: 2
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export const RoleNames = [
|
|
20
|
+
'member',
|
|
21
|
+
'manager',
|
|
22
|
+
'owner'
|
|
23
|
+
]
|
|
24
|
+
|
|
25
|
+
// Hooks that can be added to customize abilities computation
|
|
26
|
+
let hooks = []
|
|
27
|
+
|
|
28
|
+
// Get the unique global symbol to store resource type / context on a resource object
|
|
29
|
+
export const RESOURCE_TYPE = 'type'
|
|
30
|
+
export const RESOURCE_TYPE_KEY = Symbol.for(RESOURCE_TYPE)
|
|
31
|
+
|
|
32
|
+
export function defineResourceRules (subject, resource, resourceService, can) {
|
|
33
|
+
const role = Roles[resource.permissions]
|
|
34
|
+
|
|
35
|
+
if (role >= Roles.member) {
|
|
36
|
+
can('read', resourceService, { _id: resource._id })
|
|
37
|
+
}
|
|
38
|
+
if (role >= Roles.manager) {
|
|
39
|
+
can('update', resourceService, { _id: resource._id })
|
|
40
|
+
can(['create', 'remove'], 'authorisations', { resource: resource._id })
|
|
41
|
+
}
|
|
42
|
+
if (role >= Roles.owner) {
|
|
43
|
+
can('remove', resourceService, { _id: resource._id })
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Hook computing default abilities for a given user
|
|
48
|
+
export function defineUserAbilities (subject, can, cannot) {
|
|
49
|
+
// Allow user registration
|
|
50
|
+
can('service', 'users')
|
|
51
|
+
can('create', 'users')
|
|
52
|
+
// Verification email, reset password, etc.
|
|
53
|
+
can('service', 'account')
|
|
54
|
+
can(['create', 'verifyEmail'], 'account')
|
|
55
|
+
// Allow push registration
|
|
56
|
+
can('service', 'push')
|
|
57
|
+
can('create', 'push')
|
|
58
|
+
if (subject && subject._id) {
|
|
59
|
+
// Read user profiles for authorizing
|
|
60
|
+
can('read', 'users')
|
|
61
|
+
// Update user profile and destroy it
|
|
62
|
+
can(['update', 'remove'], 'users', { _id: subject._id })
|
|
63
|
+
// Access authorisation service, then rights will be granted on a per-resource basis
|
|
64
|
+
can('service', 'authorisations')
|
|
65
|
+
// Access storage service, then rights will be granted on a per-resource basis
|
|
66
|
+
can('service', 'storage')
|
|
67
|
+
// This is for the user avatar
|
|
68
|
+
// take care that the storage service uses 'id' as input but produces _id as output
|
|
69
|
+
can('create', 'storage', { id: 'avatars/' + subject._id.toString() })
|
|
70
|
+
can('create', 'storage', { id: 'avatars/' + subject._id.toString() + '.thumbnail' })
|
|
71
|
+
can(['createMultipartUpload', 'completeMultipartUpload', 'uploadPart', 'putObject'], 'storage', { id: 'avatars/' + subject._id.toString() })
|
|
72
|
+
can(['createMultipartUpload', 'completeMultipartUpload', 'uploadPart', 'putObject'], 'storage', { id: 'avatars/' + subject._id.toString() + '.thumbnail' })
|
|
73
|
+
can('remove', 'storage', { _id: 'avatars/' + subject._id.toString() })
|
|
74
|
+
can('remove', 'storage', { _id: 'avatars/' + subject._id.toString() + '.thumbnail' })
|
|
75
|
+
// Avatar is part of user profiles so that they can be read by any
|
|
76
|
+
can('read', 'storage', { _id: { $regex: '^avatars/*' } })
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// Compute abilities for a given user
|
|
81
|
+
export async function defineAbilities (subject, ...args) {
|
|
82
|
+
const { build, can, cannot } = new AbilityBuilder(Ability)
|
|
83
|
+
|
|
84
|
+
// Run registered hooks providing any additional arguments used to handle complex use cases
|
|
85
|
+
await Promise.all(hooks.map(async hook => {
|
|
86
|
+
await hook(subject, can, cannot, ...args)
|
|
87
|
+
}))
|
|
88
|
+
|
|
89
|
+
// CASL cannot infer the object type from the object itself so we need
|
|
90
|
+
// to tell it how he can find the object type, i.e. service name.
|
|
91
|
+
return build({
|
|
92
|
+
detectSubjectType: resource => {
|
|
93
|
+
if (!resource || typeof resource === 'string') {
|
|
94
|
+
return resource
|
|
95
|
+
}
|
|
96
|
+
return resource[RESOURCE_TYPE_KEY]
|
|
97
|
+
},
|
|
98
|
+
resolveAction
|
|
99
|
+
})
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
defineAbilities.registerHook = function (hook) {
|
|
103
|
+
if (!hooks.includes(hook)) {
|
|
104
|
+
hooks.push(hook)
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
defineAbilities.unregisterHook = function (hook) {
|
|
109
|
+
hooks = hooks.filter(registeredHook => registeredHook !== hook)
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export function hasServiceAbilities (abilities, service) {
|
|
113
|
+
if (!abilities) return false
|
|
114
|
+
// The unique identifier of a service is its path not its name.
|
|
115
|
+
// Indeed we have for instance a 'groups' service in each organisation
|
|
116
|
+
// Take care that in client we have the service path while on server we have the actual object
|
|
117
|
+
const path = typeof service === 'string' ? service : service.getPath()
|
|
118
|
+
// */groups will allow to access any groups service in any context
|
|
119
|
+
return abilities.can('service', path) ||
|
|
120
|
+
abilities.can('service', `*/${path}`) ||
|
|
121
|
+
abilities.can('service', _.replace(path, /^.*\//, '*/'))
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export function hasResourceAbilities (abilities, operation, resourceType, context, resource) {
|
|
125
|
+
if (!abilities) return false
|
|
126
|
+
// Create a shallow copy adding context and type
|
|
127
|
+
const object = Object.assign({}, resource)
|
|
128
|
+
object[RESOURCE_TYPE_KEY] = resourceType
|
|
129
|
+
// Add a virtual context to take it into account for object having no link to it
|
|
130
|
+
if (context) object.context = (typeof context === 'object' ? context._id.toString() : context.toString())
|
|
131
|
+
|
|
132
|
+
const result = abilities.can(operation, object)
|
|
133
|
+
|
|
134
|
+
return result
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// Utility function used to remove the virtual context from query
|
|
138
|
+
export function removeContext (query) {
|
|
139
|
+
_.forOwn(query, (value, key) => {
|
|
140
|
+
// Process current attributes or recurse
|
|
141
|
+
// Take care to nested fields like 'field._id'
|
|
142
|
+
if (key === 'context') {
|
|
143
|
+
delete query.context
|
|
144
|
+
} else if (Array.isArray(value)) {
|
|
145
|
+
value.forEach(item => removeContext(item))
|
|
146
|
+
// Remove empty objects from array
|
|
147
|
+
// _.remove(value, item => _.isEmpty(item))
|
|
148
|
+
// Remove empty arrays from query
|
|
149
|
+
if (_.isEmpty(value)) delete query[key]
|
|
150
|
+
} else if (typeof value === 'object') {
|
|
151
|
+
removeContext(value)
|
|
152
|
+
// Remove empty objects from query
|
|
153
|
+
if (_.isEmpty(value)) delete query[key]
|
|
154
|
+
}
|
|
155
|
+
})
|
|
156
|
+
return query
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// Get the query used to filter the objects according to given abilities
|
|
160
|
+
// A null query indicates that access should not be granted
|
|
161
|
+
export function getQueryForAbilities (abilities, operation, resourceType) {
|
|
162
|
+
if (!abilities) return null
|
|
163
|
+
|
|
164
|
+
const query = toMongoQuery(abilities, resourceType, operation)
|
|
165
|
+
// Remove any context to avoid taking it into account because it is not really stored on objects
|
|
166
|
+
// We clone the object here because of references to the abilities rules (see https://github.com/kalisio/kdk/issues/384)
|
|
167
|
+
return (query ? removeContext(_.cloneDeep(query)) : null)
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
function buildSubjectsQueryForResource (resourceScope, resourceId, role) {
|
|
171
|
+
const query = { [resourceScope]: { $elemMatch: { _id: resourceId } } }
|
|
172
|
+
if (role) {
|
|
173
|
+
_.set(query[resourceScope], '$elemMatch.permissions', (typeof role === 'string' ? role : RoleNames[role]))
|
|
174
|
+
}
|
|
175
|
+
return query
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
export function findSubjectsForResource (subjectService, resourceScope, resourceId, role) {
|
|
179
|
+
// Build the query
|
|
180
|
+
const query = buildSubjectsQueryForResource(resourceScope, resourceId, role)
|
|
181
|
+
// Execute the query
|
|
182
|
+
return subjectService.find({ query })
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
export function countSubjectsForResource (subjectService, resourceScope, resourceId, role) {
|
|
186
|
+
// Build the query
|
|
187
|
+
const query = buildSubjectsQueryForResource(resourceScope, resourceId, role)
|
|
188
|
+
// Indicate we'd only like to count
|
|
189
|
+
query.$limit = 0
|
|
190
|
+
// Execute the query
|
|
191
|
+
return subjectService.find({ query })
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
// Hook computing organisation abilities for a given user
|
|
195
|
+
export function defineOrganisationAbilities (subject, can, cannot) {
|
|
196
|
+
if (subject) {
|
|
197
|
+
// Create new organisations
|
|
198
|
+
can('service', 'organisations')
|
|
199
|
+
can('create', 'organisations')
|
|
200
|
+
|
|
201
|
+
if (subject.organisations) {
|
|
202
|
+
subject.organisations.forEach(organisation => {
|
|
203
|
+
if (organisation._id) {
|
|
204
|
+
// Generic rules for resources
|
|
205
|
+
defineResourceRules(subject, organisation, 'organisations', can)
|
|
206
|
+
// Specific rules for organisations
|
|
207
|
+
const role = Roles[organisation.permissions]
|
|
208
|
+
if (role >= Roles.member) {
|
|
209
|
+
// The unique identifier of a service is its path not its name.
|
|
210
|
+
// Indeed we have for instance a 'groups' service in each organisation.
|
|
211
|
+
can('service', organisation._id.toString() + '/members')
|
|
212
|
+
can('read', 'members', { context: organisation._id })
|
|
213
|
+
can('service', organisation._id.toString() + '/tags')
|
|
214
|
+
// Tags are public
|
|
215
|
+
can('read', 'tags', { context: organisation._id })
|
|
216
|
+
// Groups are private
|
|
217
|
+
can('service', organisation._id.toString() + '/groups')
|
|
218
|
+
can('service', organisation._id.toString() + '/storage')
|
|
219
|
+
can(['read', 'create', 'remove', 'createMultipartUpload', 'completeMultipartUpload', 'uploadPart', 'putObject'], 'storage', { context: organisation._id })
|
|
220
|
+
}
|
|
221
|
+
if (role >= Roles.manager) {
|
|
222
|
+
can('update', 'members', { context: organisation._id })
|
|
223
|
+
// Managers can manage all groups/tags
|
|
224
|
+
can('all', 'groups', { context: organisation._id })
|
|
225
|
+
can(['create', 'remove'], 'authorisations', { resourcesService: organisation._id.toString() + '/groups', scope: 'groups' })
|
|
226
|
+
can('all', 'tags', { context: organisation._id })
|
|
227
|
+
// Remove invited members
|
|
228
|
+
can(['remove'], 'users', { 'sponsor.organisationId': organisation._id })
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
})
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// Hook computing group abilities for a given user
|
|
237
|
+
export function defineGroupAbilities (subject, can, cannot) {
|
|
238
|
+
if (subject) {
|
|
239
|
+
if (subject.groups) {
|
|
240
|
+
subject.groups.forEach(group => {
|
|
241
|
+
if (group._id) {
|
|
242
|
+
// Specific rules for groups
|
|
243
|
+
const role = Roles[group.permissions]
|
|
244
|
+
|
|
245
|
+
if (role >= Roles.member) {
|
|
246
|
+
can('read', 'groups', { _id: group._id })
|
|
247
|
+
}
|
|
248
|
+
if (role >= Roles.manager) {
|
|
249
|
+
can(['create', 'remove'], 'authorisations', { resource: group._id, permissions: 'member' })
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
})
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
// Helper functions to find the members of a given organisation
|
|
258
|
+
export function findMembersOfOrganisation (usersService, organisationId, role) {
|
|
259
|
+
return findSubjectsForResource(usersService, 'organisations', organisationId, role)
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
export function countMembersOfOrganisation (usersService, organisationId, role) {
|
|
263
|
+
return countSubjectsForResource(usersService, 'organisations', organisationId, role)
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
// Helper functions to find the members of a given group
|
|
267
|
+
export function findMembersOfGroup (membersService, groupId, role) {
|
|
268
|
+
return findSubjectsForResource(membersService, 'groups', groupId, role)
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
export function countMembersOfGroup (membersService, groupId, role) {
|
|
272
|
+
return countSubjectsForResource(membersService, 'groups', groupId, role)
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
// Helper functions to find the members with a given tag
|
|
276
|
+
export function findMembersWithTag (membersService, tagId) {
|
|
277
|
+
return findSubjectsForResource(membersService, 'tags', tagId)
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
export function countMembersWithTag (membersService, tagId) {
|
|
281
|
+
return countSubjectsForResource(membersService, 'tags', tagId)
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
export function getRoleForOrganisation (user, organisationId) {
|
|
285
|
+
const result = _.find(user.organisations, { _id: organisationId })
|
|
286
|
+
if (!_.isUndefined(result)) return result.permissions
|
|
287
|
+
return undefined
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
export function getRoleForGroup (user, organisationId, groupId) {
|
|
291
|
+
const result = _.find(user.groups, { context: organisationId, _id: groupId })
|
|
292
|
+
if (!_.isUndefined(result)) return result.permissions
|
|
293
|
+
return undefined
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
export function findGroupsWithRole (user, organisationId, role) {
|
|
297
|
+
return _.filter(user.groups || [], { context: organisationId, permissions: (typeof role === 'string' ? role : RoleNames[role]) })
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
export function isSeniorRole (roleName, juniorName) {
|
|
301
|
+
return Roles[roleName] >= Roles[juniorName]
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
export function isJuniorRole (roleName, seniorName) {
|
|
305
|
+
return Roles[roleName] < Roles[seniorName]
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
export function getSeniorRoles (roleName) {
|
|
309
|
+
const seniorRoles = []
|
|
310
|
+
_.forEach(Roles, role => { if (Roles[roleName] < role) seniorRoles.push(RoleNames[role]) })
|
|
311
|
+
return seniorRoles
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
export function getJuniorRoles (roleName) {
|
|
315
|
+
const juniorRoles = []
|
|
316
|
+
_.forEach(Roles, role => { if (Roles[roleName] >= role) juniorRoles.push(RoleNames[role]) })
|
|
317
|
+
return juniorRoles
|
|
318
|
+
}
|