@kalisio/kdk 2.4.0 → 2.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/core/api/application.js +12 -12
- package/core/api/authentication.js +51 -7
- package/core/api/hooks/hooks.authentication.js +1 -59
- package/core/api/hooks/hooks.authorisations.js +8 -102
- package/core/api/hooks/hooks.model.js +4 -0
- package/core/api/hooks/hooks.push.js +18 -14
- package/core/api/hooks/hooks.users.js +0 -91
- package/core/api/hooks/index.js +0 -2
- package/core/api/services/account/account.service.js +1 -1
- package/core/api/services/authorisations/authorisations.service.js +28 -29
- package/core/api/services/index.js +38 -50
- package/core/api/services/messages/messages.hooks.js +4 -3
- package/core/api/services/users/users.service.js +5 -0
- package/core/client/api.js +182 -71
- package/core/client/broadcaster.js +20 -0
- package/core/client/capabilities.js +17 -7
- package/core/client/components/KActivity.vue +29 -34
- package/core/client/components/KAvatar.vue +0 -6
- package/core/client/components/KChip.vue +142 -39
- package/core/client/components/KContent.vue +13 -32
- package/core/client/components/KDialog.vue +29 -8
- package/core/client/components/KEditor.vue +120 -0
- package/core/client/components/KFollower.vue +75 -0
- package/core/client/components/KLogo.vue +2 -3
- package/core/client/components/KModal.vue +30 -10
- package/core/client/components/KSponsor.vue +1 -1
- package/core/client/components/KTextArea.vue +2 -5
- package/core/client/components/account/KDeleteAccountManager.vue +1 -1
- package/core/client/components/account/KProfile.vue +52 -14
- package/core/client/components/account/KSubscription.vue +19 -9
- package/core/client/components/account/KSubscriptionsManager.vue +10 -11
- package/core/client/components/action/KAction.vue +44 -24
- package/core/client/components/action/KBugReportAction.vue +4 -5
- package/core/client/components/action/KToggleStickyVisibility.vue +41 -0
- package/core/client/components/action/KToggleWidgetVisibility.vue +41 -0
- package/core/client/components/app/KPlatform.vue +122 -35
- package/core/client/components/app/KRequestProgressBar.vue +59 -0
- package/core/client/components/app/KSettings.vue +13 -2
- package/core/client/components/app/KTour.vue +2 -2
- package/core/client/components/chart/KTimeSeriesChart.vue +11 -3
- package/core/client/components/collection/KCard.vue +27 -33
- package/core/client/components/collection/KCardSection.vue +3 -23
- package/core/client/components/collection/KColumn.vue +0 -5
- package/core/client/components/collection/KDescriptionCardSection.vue +10 -5
- package/core/client/components/collection/KFilterView.vue +15 -0
- package/core/client/components/collection/KGrid.vue +4 -9
- package/core/client/components/collection/KHistory.vue +0 -5
- package/core/client/components/collection/KHistoryEntry.vue +0 -2
- package/core/client/components/collection/KItem.vue +1 -2
- package/core/client/components/collection/KSearchFilterControl.vue +139 -0
- package/core/client/components/collection/KTable.vue +1 -4
- package/core/client/components/collection/KTagsFilterControl.vue +70 -0
- package/core/client/components/collection/KTagsFilterView.vue +61 -0
- package/core/client/components/collection/KTimeFilterControl.vue +40 -0
- package/core/client/components/collection/KTimeFilterView.vue +106 -0
- package/core/client/components/collection/KTimeLine.vue +18 -11
- package/core/client/components/document/KBrowser.vue +283 -0
- package/core/client/components/document/KCsv.vue +52 -0
- package/core/client/components/document/KDocument.vue +19 -5
- package/core/client/components/document/KImage.vue +50 -19
- package/core/client/components/document/KMarkdown.vue +10 -2
- package/core/client/components/document/KUploader.vue +126 -0
- package/core/client/components/document/KVideo.vue +39 -0
- package/core/client/components/form/KDateField.vue +70 -0
- package/core/client/components/form/KDateTimeRangeField.vue +6 -17
- package/core/client/components/form/KDatetimeField.vue +6 -13
- package/core/client/components/form/KForm.vue +8 -8
- package/core/client/components/form/KOptionsField.vue +2 -0
- package/core/client/components/form/KResolutionField.vue +54 -52
- package/core/client/components/form/KSelectField.vue +27 -13
- package/core/client/components/form/KTextareaField.vue +23 -5
- package/core/client/components/graphics/KIcon.vue +64 -0
- package/core/client/components/index.js +1 -3
- package/core/client/components/input/KColorPicker.vue +70 -0
- package/core/client/components/input/KIconPicker.vue +188 -0
- package/core/client/components/input/KShapePicker.vue +81 -0
- package/core/client/components/input/index.js +7 -1
- package/core/client/components/layout/KFab.vue +1 -1
- package/core/client/components/layout/KLayout.vue +14 -2
- package/core/client/components/layout/KOpener.vue +9 -11
- package/core/client/components/layout/KPage.vue +31 -17
- package/core/client/components/layout/KWindow.vue +34 -18
- package/core/client/components/menu/KMenu.vue +52 -36
- package/core/client/components/menu/KSubMenu.vue +105 -0
- package/core/client/components/messages/KMessageCard.vue +207 -0
- package/core/client/components/messages/KMessageComposer.vue +199 -0
- package/core/client/components/messages/KMessagesTimeLine.vue +137 -0
- package/core/client/components/messages/index.js +7 -0
- package/core/client/components/screen/KErrorScreen.vue +2 -3
- package/core/client/components/screen/KLogoutScreen.vue +3 -1
- package/core/client/components/screen/KOAuthLoginScreen.vue +15 -0
- package/core/client/components/screen/KOAuthLogoutScreen.vue +33 -0
- package/core/client/components/screen/KUnauthorizedScreen.vue +16 -0
- package/core/client/components/time/KAbsoluteTimeRange.vue +7 -14
- package/core/client/components/time/KDate.vue +56 -26
- package/core/client/components/time/KDateTime.vue +93 -37
- package/core/client/components/time/KDateTimeRange.vue +197 -52
- package/core/client/components/time/KTime.vue +56 -26
- package/core/client/composables/activity.js +40 -30
- package/core/client/composables/{counter.js → collection-counter.js} +2 -4
- package/core/client/composables/collection-filter.js +111 -0
- package/core/client/composables/collection-timerange.js +56 -0
- package/core/client/composables/collection.js +13 -11
- package/core/client/composables/context.js +92 -0
- package/core/client/composables/errors.js +83 -0
- package/core/client/composables/index.js +5 -1
- package/core/client/composables/layout.js +14 -11
- package/core/client/composables/messages.js +4 -4
- package/core/client/composables/pwa.js +20 -27
- package/core/client/composables/schema.js +1 -1
- package/core/client/composables/screen.js +21 -9
- package/core/client/composables/selection.js +16 -4
- package/core/client/composables/session.js +13 -7
- package/core/client/composables/store.js +2 -1
- package/core/client/context.js +38 -0
- package/core/client/directives/v-hover.js +7 -4
- package/core/client/document.js +43 -15
- package/core/client/events.js +2 -2
- package/core/client/exporter.js +5 -4
- package/core/client/filter.js +1 -8
- package/core/client/guards.js +3 -3
- package/core/client/hooks/hooks.logger.js +1 -1
- package/core/client/hooks/hooks.offline.js +32 -0
- package/core/client/hooks/index.js +2 -1
- package/core/client/i18n/core_en.json +95 -268
- package/core/client/i18n/core_fr.json +181 -353
- package/core/client/index.js +22 -8
- package/core/client/layout.js +64 -25
- package/core/client/local-cache.js +67 -0
- package/core/client/local-storage.js +6 -2
- package/core/client/mixins/index.js +0 -1
- package/core/client/mixins/mixin.base-activity.js +22 -10
- package/core/client/mixins/mixin.base-editor.js +1 -1
- package/core/client/mixins/mixin.base-field.js +10 -1
- package/core/client/mixins/mixin.base-item.js +14 -11
- package/core/client/mixins/mixin.service.js +1 -5
- package/core/client/platform.js +44 -0
- package/core/client/readers/reader.blob.js +3 -3
- package/core/client/readers/reader.csv.js +2 -2
- package/core/client/readers/reader.json.js +2 -2
- package/core/client/services/index.js +7 -11
- package/core/client/storage.js +43 -8
- package/core/client/template-context.js +14 -14
- package/core/client/time.js +3 -3
- package/core/client/units.js +7 -4
- package/core/client/utils/index.js +6 -5
- package/core/client/utils/utils.collection.js +71 -0
- package/core/client/utils/utils.colors.js +29 -8
- package/core/client/utils/utils.content.js +14 -14
- package/core/client/utils/utils.files.js +17 -0
- package/core/client/utils/utils.items.js +4 -0
- package/core/client/utils/utils.math.js +18 -1
- package/core/client/utils/utils.push.js +22 -13
- package/core/client/utils/utils.screen.js +6 -2
- package/core/client/utils/utils.services.js +42 -0
- package/core/client/utils/utils.session.js +48 -12
- package/core/client/utils/utils.shapes.js +15 -11
- package/core/common/permissions.js +3 -108
- package/core/common/schemas/messages.update.json +16 -0
- package/core/common/schemas/settings.update.json +27 -8
- package/core/common/utils.js +2 -0
- package/core/common/utils.offline.js +38 -0
- package/coverage/core/api/application.js.html +296 -296
- package/coverage/core/api/authentication.js.html +206 -74
- package/coverage/core/api/db.js.html +61 -61
- package/coverage/core/api/hooks/hooks.authentication.js.html +15 -189
- package/coverage/core/api/hooks/hooks.authorisations.js.html +180 -462
- package/coverage/core/api/hooks/hooks.groups.js.html +1 -1
- package/coverage/core/api/hooks/hooks.logger.js.html +16 -16
- package/coverage/core/api/hooks/hooks.model.js.html +69 -57
- package/coverage/core/api/hooks/hooks.organisations.js.html +1 -1
- package/coverage/core/api/hooks/hooks.push.js.html +58 -46
- package/coverage/core/api/hooks/hooks.query.js.html +142 -142
- package/coverage/core/api/hooks/hooks.schemas.js.html +1 -1
- package/coverage/core/api/hooks/hooks.service.js.html +1 -1
- package/coverage/core/api/hooks/hooks.storage.js.html +1 -1
- package/coverage/core/api/hooks/hooks.users.js.html +54 -327
- package/coverage/core/api/hooks/index.html +64 -94
- package/coverage/core/api/hooks/index.js.html +4 -10
- package/coverage/core/api/index.html +41 -56
- package/coverage/core/api/index.js.html +1 -1
- package/coverage/core/api/marshall.js.html +9 -9
- package/coverage/core/api/models/groups.model.mongodb.js.html +1 -1
- package/coverage/core/api/models/index.html +13 -58
- package/coverage/core/api/models/messages.model.mongodb.js.html +35 -35
- package/coverage/core/api/models/organisations.model.mongodb.js.html +3 -3
- package/coverage/core/api/models/tags.model.mongodb.js.html +1 -1
- package/coverage/core/api/models/users.model.mongodb.js.html +1 -1
- package/coverage/core/api/services/account/account.hooks.js.html +1 -1
- package/coverage/core/api/services/account/account.service.js.html +67 -67
- package/coverage/core/api/services/account/index.html +16 -16
- package/coverage/core/api/services/authorisations/authorisations.hooks.js.html +1 -1
- package/coverage/core/api/services/authorisations/authorisations.service.js.html +141 -144
- package/coverage/core/api/services/authorisations/index.html +19 -19
- package/coverage/core/api/services/databases/databases.hooks.js.html +82 -82
- package/coverage/core/api/services/databases/databases.service.js.html +20 -20
- package/coverage/core/api/services/databases/index.html +32 -32
- package/coverage/core/api/services/groups/groups.hooks.js.html +1 -1
- package/coverage/core/api/services/groups/index.html +1 -1
- package/coverage/core/api/services/import-export/import-export.hooks.js.html +1 -1
- package/coverage/core/api/services/import-export/import-export.service.js.html +1 -1
- package/coverage/core/api/services/import-export/index.html +1 -1
- package/coverage/core/api/services/index.html +21 -21
- package/coverage/core/api/services/index.js.html +118 -154
- package/coverage/core/api/services/mailer/index.html +1 -1
- package/coverage/core/api/services/mailer/mailer.hooks.js.html +1 -1
- package/coverage/core/api/services/mailer/mailer.service.js.html +1 -1
- package/coverage/core/api/services/messages/index.html +21 -21
- package/coverage/core/api/services/messages/messages.hooks.js.html +89 -86
- package/coverage/core/api/services/organisations/index.html +1 -1
- package/coverage/core/api/services/organisations/organisations.hooks.js.html +1 -1
- package/coverage/core/api/services/organisations/organisations.service.js.html +23 -23
- package/coverage/core/api/services/push/index.html +1 -1
- package/coverage/core/api/services/push/push.hooks.js.html +1 -1
- package/coverage/core/api/services/push/push.service.js.html +1 -1
- package/coverage/core/api/services/storage/index.html +5 -5
- package/coverage/core/api/services/storage/storage.hooks.js.html +1 -1
- package/coverage/core/api/services/storage/storage.service.js.html +27 -27
- package/coverage/core/api/services/tags/index.html +1 -1
- package/coverage/core/api/services/tags/tags.hooks.js.html +1 -1
- package/coverage/core/api/services/users/index.html +23 -8
- package/coverage/core/api/services/users/users.hooks.js.html +1 -1
- package/coverage/core/api/services/users/users.service.js.html +100 -0
- package/coverage/core/api/utils.js.html +1 -1
- package/coverage/core/common/errors.js.html +1 -1
- package/coverage/core/common/index.html +42 -27
- package/coverage/core/common/index.js.html +1 -1
- package/coverage/core/common/permissions.js.html +195 -510
- package/coverage/core/common/schema.js.html +1 -1
- package/coverage/core/common/utils.js.html +12 -6
- package/coverage/core/common/utils.offline.js.html +199 -0
- package/coverage/index.html +142 -172
- package/coverage/lcov-report/core/api/application.js.html +296 -296
- package/coverage/lcov-report/core/api/authentication.js.html +206 -74
- package/coverage/lcov-report/core/api/db.js.html +61 -61
- package/coverage/lcov-report/core/api/hooks/hooks.authentication.js.html +15 -189
- package/coverage/lcov-report/core/api/hooks/hooks.authorisations.js.html +180 -462
- package/coverage/lcov-report/core/api/hooks/hooks.groups.js.html +1 -1
- package/coverage/lcov-report/core/api/hooks/hooks.logger.js.html +16 -16
- package/coverage/lcov-report/core/api/hooks/hooks.model.js.html +69 -57
- package/coverage/lcov-report/core/api/hooks/hooks.organisations.js.html +1 -1
- package/coverage/lcov-report/core/api/hooks/hooks.push.js.html +58 -46
- package/coverage/lcov-report/core/api/hooks/hooks.query.js.html +142 -142
- package/coverage/lcov-report/core/api/hooks/hooks.schemas.js.html +1 -1
- package/coverage/lcov-report/core/api/hooks/hooks.service.js.html +1 -1
- package/coverage/lcov-report/core/api/hooks/hooks.storage.js.html +1 -1
- package/coverage/lcov-report/core/api/hooks/hooks.users.js.html +54 -327
- package/coverage/lcov-report/core/api/hooks/index.html +64 -94
- package/coverage/lcov-report/core/api/hooks/index.js.html +4 -10
- package/coverage/lcov-report/core/api/index.html +41 -56
- package/coverage/lcov-report/core/api/index.js.html +1 -1
- package/coverage/lcov-report/core/api/marshall.js.html +9 -9
- package/coverage/lcov-report/core/api/models/groups.model.mongodb.js.html +1 -1
- package/coverage/lcov-report/core/api/models/index.html +13 -58
- package/coverage/lcov-report/core/api/models/messages.model.mongodb.js.html +35 -35
- package/coverage/lcov-report/core/api/models/organisations.model.mongodb.js.html +3 -3
- package/coverage/lcov-report/core/api/models/tags.model.mongodb.js.html +1 -1
- package/coverage/lcov-report/core/api/models/users.model.mongodb.js.html +1 -1
- package/coverage/lcov-report/core/api/services/account/account.hooks.js.html +1 -1
- package/coverage/lcov-report/core/api/services/account/account.service.js.html +67 -67
- package/coverage/lcov-report/core/api/services/account/index.html +16 -16
- package/coverage/lcov-report/core/api/services/authorisations/authorisations.hooks.js.html +1 -1
- package/coverage/lcov-report/core/api/services/authorisations/authorisations.service.js.html +141 -144
- package/coverage/lcov-report/core/api/services/authorisations/index.html +19 -19
- package/coverage/lcov-report/core/api/services/databases/databases.hooks.js.html +82 -82
- package/coverage/lcov-report/core/api/services/databases/databases.service.js.html +20 -20
- package/coverage/lcov-report/core/api/services/databases/index.html +32 -32
- package/coverage/lcov-report/core/api/services/groups/groups.hooks.js.html +1 -1
- package/coverage/lcov-report/core/api/services/groups/index.html +1 -1
- package/coverage/lcov-report/core/api/services/import-export/import-export.hooks.js.html +1 -1
- package/coverage/lcov-report/core/api/services/import-export/import-export.service.js.html +1 -1
- package/coverage/lcov-report/core/api/services/import-export/index.html +1 -1
- package/coverage/lcov-report/core/api/services/index.html +21 -21
- package/coverage/lcov-report/core/api/services/index.js.html +118 -154
- package/coverage/lcov-report/core/api/services/mailer/index.html +1 -1
- package/coverage/lcov-report/core/api/services/mailer/mailer.hooks.js.html +1 -1
- package/coverage/lcov-report/core/api/services/mailer/mailer.service.js.html +1 -1
- package/coverage/lcov-report/core/api/services/messages/index.html +21 -21
- package/coverage/lcov-report/core/api/services/messages/messages.hooks.js.html +89 -86
- package/coverage/lcov-report/core/api/services/organisations/index.html +1 -1
- package/coverage/lcov-report/core/api/services/organisations/organisations.hooks.js.html +1 -1
- package/coverage/lcov-report/core/api/services/organisations/organisations.service.js.html +23 -23
- package/coverage/lcov-report/core/api/services/push/index.html +1 -1
- package/coverage/lcov-report/core/api/services/push/push.hooks.js.html +1 -1
- package/coverage/lcov-report/core/api/services/push/push.service.js.html +1 -1
- package/coverage/lcov-report/core/api/services/storage/index.html +5 -5
- package/coverage/lcov-report/core/api/services/storage/storage.hooks.js.html +1 -1
- package/coverage/lcov-report/core/api/services/storage/storage.service.js.html +27 -27
- package/coverage/lcov-report/core/api/services/tags/index.html +1 -1
- package/coverage/lcov-report/core/api/services/tags/tags.hooks.js.html +1 -1
- package/coverage/lcov-report/core/api/services/users/index.html +23 -8
- package/coverage/lcov-report/core/api/services/users/users.hooks.js.html +1 -1
- package/coverage/lcov-report/core/api/services/users/users.service.js.html +100 -0
- package/coverage/lcov-report/core/api/utils.js.html +1 -1
- package/coverage/lcov-report/core/common/errors.js.html +1 -1
- package/coverage/lcov-report/core/common/index.html +42 -27
- package/coverage/lcov-report/core/common/index.js.html +1 -1
- package/coverage/lcov-report/core/common/permissions.js.html +195 -510
- package/coverage/lcov-report/core/common/schema.js.html +1 -1
- package/coverage/lcov-report/core/common/utils.js.html +12 -6
- package/coverage/lcov-report/core/common/utils.offline.js.html +199 -0
- package/coverage/lcov-report/index.html +142 -172
- package/coverage/lcov-report/map/api/hooks/hooks.catalog.js.html +125 -29
- package/coverage/lcov-report/map/api/hooks/hooks.features.js.html +1 -1
- package/coverage/lcov-report/map/api/hooks/hooks.query.js.html +20 -44
- package/coverage/lcov-report/map/api/hooks/index.html +7 -7
- package/coverage/lcov-report/map/api/hooks/index.js.html +1 -1
- package/coverage/lcov-report/map/api/index.html +1 -1
- package/coverage/lcov-report/map/api/index.js.html +1 -1
- package/coverage/lcov-report/map/api/marshall.js.html +1 -1
- package/coverage/lcov-report/map/api/models/alerts.model.mongodb.js.html +1 -1
- package/coverage/lcov-report/map/api/models/catalog.model.mongodb.js.html +49 -7
- package/coverage/lcov-report/map/api/models/features.model.mongodb.js.html +1 -1
- package/coverage/lcov-report/map/api/models/index.html +22 -7
- package/coverage/lcov-report/map/api/models/projects.model.mongodb.js.html +1 -1
- package/coverage/lcov-report/map/api/models/styles.model.mongodb.js.html +112 -0
- package/coverage/lcov-report/map/api/services/alerts/alerts.hooks.js.html +1 -1
- package/coverage/lcov-report/map/api/services/alerts/alerts.service.js.html +1 -1
- package/coverage/lcov-report/map/api/services/alerts/index.html +1 -1
- package/coverage/lcov-report/map/api/services/catalog/catalog.hooks.js.html +29 -11
- package/coverage/lcov-report/map/api/services/catalog/index.html +5 -5
- package/coverage/lcov-report/map/api/services/daptiles/daptiles.service.js.html +1 -1
- package/coverage/lcov-report/map/api/services/daptiles/index.html +1 -1
- package/coverage/lcov-report/map/api/services/features/features.hooks.js.html +78 -9
- package/coverage/lcov-report/map/api/services/features/features.service.js.html +307 -4
- package/coverage/lcov-report/map/api/services/features/index.html +7 -7
- package/coverage/lcov-report/map/api/services/index.html +5 -5
- package/coverage/lcov-report/map/api/services/index.js.html +287 -50
- package/coverage/lcov-report/map/api/services/projects/index.html +1 -1
- package/coverage/lcov-report/map/api/services/projects/projects.hooks.js.html +1 -1
- package/coverage/lcov-report/map/api/services/styles/index.html +116 -0
- package/coverage/lcov-report/map/api/services/styles/styles.hooks.js.html +196 -0
- package/coverage/lcov-report/map/common/dynamic-grid-source.js.html +1 -1
- package/coverage/lcov-report/map/common/errors.js.html +1 -1
- package/coverage/lcov-report/map/common/geotiff-grid-source.js.html +8 -5
- package/coverage/lcov-report/map/common/grid.js.html +1 -1
- package/coverage/lcov-report/map/common/index.html +7 -7
- package/coverage/lcov-report/map/common/index.js.html +1 -1
- package/coverage/lcov-report/map/common/meteo-model-grid-source.js.html +1 -1
- package/coverage/lcov-report/map/common/moment-utils.js.html +1 -1
- package/coverage/lcov-report/map/common/opendap-grid-source.js.html +1 -1
- package/coverage/lcov-report/map/common/opendap-utils.js.html +1 -1
- package/coverage/lcov-report/map/common/permissions.js.html +10 -4
- package/coverage/lcov-report/map/common/time-based-grid-source.js.html +1 -1
- package/coverage/lcov-report/map/common/tms-utils.js.html +6 -6
- package/coverage/lcov-report/map/common/wcs-grid-source.js.html +3 -3
- package/coverage/lcov-report/map/common/wcs-utils.js.html +9 -9
- package/coverage/lcov-report/map/common/weacast-grid-source.js.html +1 -1
- package/coverage/lcov-report/map/common/wfs-utils.js.html +11 -11
- package/coverage/lcov-report/map/common/wms-utils.js.html +8 -8
- package/coverage/lcov-report/map/common/wmts-utils.js.html +7 -7
- package/coverage/lcov.info +2581 -3278
- package/coverage/map/api/hooks/hooks.catalog.js.html +125 -29
- package/coverage/map/api/hooks/hooks.features.js.html +1 -1
- package/coverage/map/api/hooks/hooks.query.js.html +20 -44
- package/coverage/map/api/hooks/index.html +7 -7
- package/coverage/map/api/hooks/index.js.html +1 -1
- package/coverage/map/api/index.html +1 -1
- package/coverage/map/api/index.js.html +1 -1
- package/coverage/map/api/marshall.js.html +1 -1
- package/coverage/map/api/models/alerts.model.mongodb.js.html +1 -1
- package/coverage/map/api/models/catalog.model.mongodb.js.html +49 -7
- package/coverage/map/api/models/features.model.mongodb.js.html +1 -1
- package/coverage/map/api/models/index.html +22 -7
- package/coverage/map/api/models/projects.model.mongodb.js.html +1 -1
- package/coverage/map/api/models/styles.model.mongodb.js.html +112 -0
- package/coverage/map/api/services/alerts/alerts.hooks.js.html +1 -1
- package/coverage/map/api/services/alerts/alerts.service.js.html +1 -1
- package/coverage/map/api/services/alerts/index.html +1 -1
- package/coverage/map/api/services/catalog/catalog.hooks.js.html +29 -11
- package/coverage/map/api/services/catalog/index.html +5 -5
- package/coverage/map/api/services/daptiles/daptiles.service.js.html +1 -1
- package/coverage/map/api/services/daptiles/index.html +1 -1
- package/coverage/map/api/services/features/features.hooks.js.html +78 -9
- package/coverage/map/api/services/features/features.service.js.html +307 -4
- package/coverage/map/api/services/features/index.html +7 -7
- package/coverage/map/api/services/index.html +5 -5
- package/coverage/map/api/services/index.js.html +287 -50
- package/coverage/map/api/services/projects/index.html +1 -1
- package/coverage/map/api/services/projects/projects.hooks.js.html +1 -1
- package/coverage/map/api/services/styles/index.html +116 -0
- package/coverage/map/api/services/styles/styles.hooks.js.html +196 -0
- package/coverage/map/common/dynamic-grid-source.js.html +1 -1
- package/coverage/map/common/errors.js.html +1 -1
- package/coverage/map/common/geotiff-grid-source.js.html +8 -5
- package/coverage/map/common/grid.js.html +1 -1
- package/coverage/map/common/index.html +7 -7
- package/coverage/map/common/index.js.html +1 -1
- package/coverage/map/common/meteo-model-grid-source.js.html +1 -1
- package/coverage/map/common/moment-utils.js.html +1 -1
- package/coverage/map/common/opendap-grid-source.js.html +1 -1
- package/coverage/map/common/opendap-utils.js.html +1 -1
- package/coverage/map/common/permissions.js.html +10 -4
- package/coverage/map/common/time-based-grid-source.js.html +1 -1
- package/coverage/map/common/tms-utils.js.html +6 -6
- package/coverage/map/common/wcs-grid-source.js.html +3 -3
- package/coverage/map/common/wcs-utils.js.html +9 -9
- package/coverage/map/common/weacast-grid-source.js.html +1 -1
- package/coverage/map/common/wfs-utils.js.html +11 -11
- package/coverage/map/common/wms-utils.js.html +8 -8
- package/coverage/map/common/wmts-utils.js.html +7 -7
- package/coverage/tmp/coverage-323534-1747828879483-0.json +1 -0
- package/coverage/tmp/coverage-323546-1747828879453-0.json +1 -0
- package/coverage/tmp/coverage-323557-1747828879439-0.json +1 -0
- package/coverage/tmp/coverage-323569-1747828879416-0.json +1 -0
- package/coverage/tmp/coverage-323576-1747828879390-0.json +1 -0
- package/extras/configs/helpers.js +78 -0
- package/extras/configs/panes.left.js +118 -0
- package/extras/configs/panes.top.js +222 -0
- package/extras/configs/stickies.js +57 -0
- package/extras/configs/widgets.left.js +23 -0
- package/extras/configs/widgets.top.js +73 -0
- package/extras/css/core.variables.scss +8 -0
- package/extras/images/north.svg +3 -0
- package/extras/tours/map/side-nav.js +3 -3
- package/map/api/hooks/hooks.catalog.js +56 -23
- package/map/api/hooks/hooks.query.js +16 -24
- package/map/api/models/catalog.model.mongodb.js +16 -2
- package/{core/api/models/groups.model.mongodb.js → map/api/models/styles.model.mongodb.js} +2 -1
- package/map/api/services/catalog/catalog.hooks.js +13 -7
- package/map/api/services/features/features.hooks.js +28 -5
- package/map/api/services/features/features.service.js +101 -0
- package/map/api/services/index.js +125 -46
- package/map/api/services/styles/styles.hooks.js +37 -0
- package/map/client/cesium/utils/index.js +1 -0
- package/map/client/cesium/utils/utils.cesium.js +397 -0
- package/map/client/cesium/utils/utils.features.js +8 -0
- package/map/client/cesium/utils/utils.geojson.js +59 -0
- package/map/client/cesium/utils/utils.style.js +134 -17
- package/map/client/components/KEditLayerData.vue +17 -79
- package/map/client/components/KFeatureEditor.vue +2 -7
- package/map/client/components/KFeaturesChart.vue +2 -6
- package/map/client/components/KFeaturesFilterEditor.vue +300 -0
- package/map/client/components/KFeaturesFilterManager.vue +196 -0
- package/map/client/components/KFeaturesTable.vue +0 -5
- package/map/client/components/KFilterCondition.vue +303 -0
- package/map/client/components/KLayerEditionToolbar.vue +4 -3
- package/map/client/components/KLayerEditor.vue +451 -36
- package/map/client/components/KMeasureTool.vue +36 -9
- package/map/client/components/KProjectMenu.vue +14 -8
- package/map/client/components/catalog/KAddLayer.vue +0 -4
- package/map/client/components/catalog/KBaseLayersSelector.vue +42 -46
- package/map/client/components/catalog/KConnectLayer.vue +295 -291
- package/map/client/components/catalog/KCreateLayer.vue +141 -146
- package/map/client/components/catalog/KCreateOfflineView.vue +100 -0
- package/map/client/components/catalog/KCreateView.vue +2 -8
- package/map/client/components/catalog/KFilteredLayerItem.vue +72 -25
- package/map/client/components/catalog/KImportLayer.vue +121 -129
- package/map/client/components/catalog/KLayerItem.vue +44 -32
- package/map/client/components/catalog/KLayersPanel.vue +45 -17
- package/map/client/components/catalog/KLayersSelector.vue +51 -50
- package/map/client/components/catalog/KProjectManager.vue +4 -8
- package/map/client/components/catalog/KProjectSelector.vue +33 -2
- package/map/client/components/catalog/KProjectsPanel.vue +84 -106
- package/map/client/components/catalog/KSelectLayers.vue +56 -69
- package/map/client/components/catalog/KSelectViews.vue +56 -69
- package/map/client/components/catalog/KViewSelector.vue +32 -2
- package/map/client/components/catalog/KViewsPanel.vue +178 -110
- package/map/client/components/catalog/KWeatherLayersSelector.vue +77 -85
- package/map/client/components/form/KLocationField.vue +21 -2
- package/map/client/components/form/KOwsLayerField.vue +1 -1
- package/map/client/components/form/KOwsServiceField.vue +102 -63
- package/map/client/components/form/KSelectLayersField.vue +1 -1
- package/map/client/components/form/KSelectViewsField.vue +1 -1
- package/map/client/components/form/KTimezoneField.vue +0 -1
- package/map/client/components/legend/KLegend.vue +4 -4
- package/map/client/components/location/KLocationCardSection.vue +16 -0
- package/map/client/components/location/KLocationMap.vue +3 -2
- package/map/client/components/location/KLocationSearch.vue +46 -8
- package/map/client/components/location/KLocationTimeLineCard.vue +25 -3
- package/map/client/components/location/KLocationTip.vue +57 -10
- package/map/client/components/selection/KFeaturesSelection.vue +71 -0
- package/map/client/components/selection/KSelectedLayerFeatures.vue +343 -0
- package/map/client/components/{KAttribution.vue → stickies/KAttribution.vue} +39 -33
- package/map/client/components/stickies/KLevelSlider.vue +114 -0
- package/map/client/components/stickies/KNorthArrow.vue +26 -0
- package/map/client/components/stickies/KPosition.vue +103 -0
- package/map/client/components/stickies/KTarget.vue +34 -0
- package/map/client/components/styles/KLayerStyleAction.vue +58 -0
- package/map/client/components/styles/KStyleEditor.vue +273 -0
- package/map/client/components/styles/KStyleEditorSection.vue +79 -0
- package/map/client/components/styles/KStyleManager.vue +183 -0
- package/map/client/components/styles/KStylePreview.vue +64 -0
- package/map/client/components/styles/KStylePreviewItem.vue +68 -0
- package/map/client/components/styles/KStylePropertiesGroup.vue +76 -0
- package/map/client/components/styles/KStyleProperty.vue +136 -0
- package/map/client/components/styles/KStyleTip.vue +118 -0
- package/map/client/components/tools/KGeolocateTool.vue +3 -2
- package/map/client/components/tools/KSearchTool.vue +34 -6
- package/map/client/components/widget/KMapillaryViewer.vue +1 -1
- package/map/client/components/widget/KStackableTimeSeries.vue +8 -5
- package/map/client/composables/activity.js +29 -43
- package/map/client/composables/catalog.js +1 -1
- package/map/client/composables/highlight.js +117 -57
- package/map/client/composables/location.js +33 -14
- package/map/client/composables/project.js +9 -10
- package/map/client/composables/selection.js +136 -23
- package/map/client/geocoder.js +104 -0
- package/map/client/geolocation.js +1 -1
- package/map/client/globe.js +3 -0
- package/map/client/hooks/hooks.offline.js +95 -0
- package/map/client/hooks/index.js +1 -0
- package/map/client/i18n/map_en.json +159 -94
- package/map/client/i18n/map_fr.json +186 -127
- package/map/client/index.js +3 -0
- package/map/client/init.js +44 -8
- package/map/client/leaflet/BoxSelection.js +2 -2
- package/map/client/leaflet/GradientPath.js +84 -4
- package/map/client/leaflet/TiledFeatureLayer.js +2 -3
- package/map/client/leaflet/WindBarb.js +323 -0
- package/map/client/leaflet/utils/index.js +1 -0
- package/map/client/leaflet/utils/utils.events.js +8 -3
- package/map/client/leaflet/utils/utils.geojson.js +221 -0
- package/map/client/leaflet/utils/utils.style.js +10 -9
- package/map/client/map.js +3 -0
- package/map/client/mixins/globe/mixin.base-globe.js +151 -19
- package/map/client/mixins/globe/mixin.geojson-layers.js +208 -86
- package/map/client/mixins/globe/mixin.popup.js +3 -2
- package/map/client/mixins/globe/mixin.style.js +3 -1
- package/map/client/mixins/globe/mixin.tooltip.js +3 -2
- package/map/client/mixins/map/index.js +1 -3
- package/map/client/mixins/map/mixin.base-map.js +267 -79
- package/map/client/mixins/map/mixin.canvas-layers.js +44 -10
- package/map/client/mixins/map/mixin.edit-layers.js +142 -57
- package/map/client/mixins/map/mixin.geojson-layers.js +129 -205
- package/map/client/mixins/map/mixin.pmtiles-layers.js +24 -11
- package/map/client/mixins/map/mixin.tiled-mesh-layers.js +1 -2
- package/map/client/mixins/map/mixin.tiled-wind-layers.js +2 -1
- package/map/client/mixins/mixin.activity.js +61 -41
- package/map/client/mixins/mixin.context.js +19 -14
- package/map/client/mixins/mixin.feature-selection.js +0 -1
- package/map/client/mixins/mixin.feature-service.js +41 -59
- package/map/client/mixins/mixin.weacast.js +1 -1
- package/map/client/navigator.js +38 -0
- package/map/client/pixi-utils.js +1 -1
- package/map/client/planets.js +1 -1
- package/map/client/readers/reader.kml.js +57 -1
- package/map/client/utils/index.js +1 -0
- package/map/client/utils/utils.capture.js +10 -7
- package/map/client/utils/utils.catalog.js +2 -2
- package/map/client/utils/utils.features.js +193 -39
- package/map/client/utils/utils.js +8 -19
- package/map/client/utils/utils.layers.js +381 -4
- package/map/client/utils/utils.location.js +39 -74
- package/map/client/utils/utils.offline.js +89 -0
- package/map/client/utils/utils.style.js +133 -80
- package/map/client/utils/utils.time-series.js +99 -25
- package/map/common/geotiff-grid-source.js +2 -1
- package/map/common/permissions.js +2 -0
- package/map/common/schemas/capture.create.json +4 -4
- package/map/common/schemas/catalog.update.json +18 -2
- package/map/common/schemas/projects.create.json +2 -2
- package/map/common/schemas/projects.update.json +2 -2
- package/map/common/tms-utils.js +5 -5
- package/map/common/wcs-grid-source.js +2 -2
- package/map/common/wcs-utils.js +8 -8
- package/map/common/wfs-utils.js +10 -10
- package/map/common/wms-utils.js +7 -7
- package/map/common/wmts-utils.js +6 -6
- package/package.json +7 -4
- package/test/api/core/account.test.js +0 -72
- package/test/api/core/authentication.test.js +184 -0
- package/test/api/core/config/default.cjs +1 -3
- package/test/api/core/index.test.js +33 -96
- package/test/api/core/offline.test.js +55 -0
- package/test/api/core/push.test.js +3 -3
- package/test/api/core/{test-log-2024-06-06.log → test-log-2025-02-05.log} +3 -3
- package/test/api/core/{test-log-2024-11-15.log → test-log-2025-05-21.log} +1 -9
- package/test/api/map/alerts.test.js +1 -1
- package/test/api/map/config/default.cjs +2 -1
- package/test/api/map/data/vigicrues.observations.Q.json +47042 -0
- package/test/api/map/index.test.js +113 -9
- package/test/api/map/style.test.js +62 -0
- package/test/client/core/layout.js +2 -2
- package/test/client/core/runner.js +1 -1
- package/test/client/core/utils.js +52 -0
- package/test/client/map/catalog.js +1 -0
- package/core/api/hooks/hooks.groups.js +0 -48
- package/core/api/hooks/hooks.organisations.js +0 -152
- package/core/api/models/organisations.model.mongodb.js +0 -3
- package/core/api/models/tags.model.mongodb.js +0 -10
- package/core/api/services/groups/groups.hooks.js +0 -31
- package/core/api/services/organisations/organisations.hooks.js +0 -31
- package/core/api/services/organisations/organisations.service.js +0 -86
- package/core/api/services/tags/tags.hooks.js +0 -31
- package/core/api/utils.js +0 -11
- package/core/client/components/KChipsPane.vue +0 -103
- package/core/client/components/document/index.js +0 -9
- package/core/client/components/team/KAddMember.vue +0 -378
- package/core/client/components/team/KAddTag.vue +0 -121
- package/core/client/components/team/KChangeRole.vue +0 -118
- package/core/client/components/team/KGroupCard.vue +0 -110
- package/core/client/components/team/KGroupsActivity.vue +0 -78
- package/core/client/components/team/KJoinGroup.vue +0 -132
- package/core/client/components/team/KMemberCard.vue +0 -328
- package/core/client/components/team/KMemberFilter.vue +0 -49
- package/core/client/components/team/KMembersActivity.vue +0 -136
- package/core/client/components/team/KOrganisationsActivity.vue +0 -51
- package/core/client/components/team/KTagCard.vue +0 -72
- package/core/client/components/team/KTagsActivity.vue +0 -73
- package/core/client/components/team/index.js +0 -9
- package/core/client/mixins/mixin.base-context.js +0 -54
- package/core/client/utils/utils.platform.js +0 -12
- package/core/common/schemas/groups.create.json +0 -28
- package/core/common/schemas/groups.update.json +0 -28
- package/core/common/schemas/organisations.create.json +0 -28
- package/core/common/schemas/organisations.update.json +0 -49
- package/core/common/schemas/tags.create.json +0 -35
- package/core/common/schemas/tags.update.json +0 -35
- package/coverage/tmp/coverage-280506-1731704745613-0.json +0 -1
- package/coverage/tmp/coverage-280518-1731704745599-0.json +0 -1
- package/coverage/tmp/coverage-280529-1731704745588-0.json +0 -1
- package/coverage/tmp/coverage-280541-1731704745574-0.json +0 -1
- package/coverage/tmp/coverage-280548-1731704745545-0.json +0 -1
- package/map/client/components/KFeaturesFilter.vue +0 -259
- package/map/client/components/KLayerStyleEditor.vue +0 -118
- package/map/client/components/KLayerStyleForm.vue +0 -740
- package/map/client/components/KLevelSlider.vue +0 -100
- package/map/client/components/KNorth.vue +0 -31
- package/map/client/components/KPositionIndicator.vue +0 -83
- package/map/client/components/catalog/KCreateProject.vue +0 -100
- package/map/client/mixins/map/mixin.forecast-layers.js +0 -81
- package/map/client/mixins/map/mixin.georaster-layers.js +0 -107
- package/test/api/core/team.test.js +0 -670
- package/test/api/core/test-log-2023-12-19.log +0 -7
- package/test/api/core/test-log-2024-01-04.log +0 -14
- package/test/api/core/test-log-2024-05-14.log +0 -6
- package/test/api/core/test-log-2024-06-26.log +0 -25
- package/test/api/core/test-log-2024-06-28.log +0 -2
- package/test/api/core/test-log-2024-07-09.log +0 -0
- package/test/api/core/test-log-2024-08-13.log +0 -69
- package/test/api/core/test-log-2024-10-28.log +0 -53
- package/test/api/core/test-log-2024-11-05.log +0 -30
- package/test/api/map/test-log-2023-11-24.log +0 -121
- package/test/api/map/test-log-2023-12-12.log +0 -29
- package/test/api/map/test-log-2023-12-13.log +0 -5
- package/test/api/map/test-log-2024-01-04.log +0 -2
- package/test/api/map/test-log-2024-01-11.log +0 -1
- package/test/api/map/test-log-2024-01-25.log +0 -19
- package/test/api/map/test-log-2024-06-06.log +0 -39
- package/test/api/map/test-log-2024-08-13.log +0 -13
- package/test/api/map/test-log-2024-08-20.log +0 -55
- package/test/api/map/test-log-2024-09-09.log +0 -92
- package/test/api/map/test-log-2024-10-28.log +0 -11
- /package/extras/{logos → images}/kalisio.png +0 -0
- /package/extras/{icons → images}/target.svg +0 -0
- /package/test/api/map/data/{vigicrues.observations.json → vigicrues.observations.H.json} +0 -0
package/core/api/application.js
CHANGED
|
@@ -99,10 +99,10 @@ export async function configureService (name, service, servicesPath) {
|
|
|
99
99
|
}
|
|
100
100
|
} catch (error) {
|
|
101
101
|
debug('No ' + name + ' service hooks configured on path ' + servicesPath)
|
|
102
|
-
if (error.code !== 'ERR_MODULE_NOT_FOUND') {
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
}
|
|
102
|
+
// if (error.code !== 'ERR_MODULE_NOT_FOUND') {
|
|
103
|
+
// Log error in this case as this might be linked to a syntax error in required file
|
|
104
|
+
debug(filepath, error)
|
|
105
|
+
// }
|
|
106
106
|
// As this is optionnal this require has to fail silently
|
|
107
107
|
}
|
|
108
108
|
|
|
@@ -119,10 +119,10 @@ export async function configureService (name, service, servicesPath) {
|
|
|
119
119
|
}
|
|
120
120
|
} catch (error) {
|
|
121
121
|
debug('No ' + name + ' service channels configured on path ' + servicesPath)
|
|
122
|
-
if (error.code !== 'ERR_MODULE_NOT_FOUND') {
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
}
|
|
122
|
+
// if (error.code !== 'ERR_MODULE_NOT_FOUND') {
|
|
123
|
+
// Log error in this case as this might be linked to a syntax error in required file
|
|
124
|
+
debug(filepath, error)
|
|
125
|
+
// }
|
|
126
126
|
// As this is optionnal this require has to fail silently
|
|
127
127
|
}
|
|
128
128
|
|
|
@@ -198,10 +198,10 @@ async function createService (name, app, options = {}) {
|
|
|
198
198
|
}
|
|
199
199
|
} catch (error) {
|
|
200
200
|
debug('No ' + fileName + ' service model configured on path ' + serviceOptions.modelsPath)
|
|
201
|
-
if (error.code !== 'ERR_MODULE_NOT_FOUND') {
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
}
|
|
201
|
+
// if (error.code !== 'ERR_MODULE_NOT_FOUND') {
|
|
202
|
+
// Log error in this case as this might be linked to a syntax error in required file
|
|
203
|
+
debug(fileName, error)
|
|
204
|
+
// }
|
|
205
205
|
// As this is optionnal this require has to fail silently
|
|
206
206
|
}
|
|
207
207
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import makeDebug from 'debug'
|
|
2
2
|
import _ from 'lodash'
|
|
3
|
+
import qs from 'qs'
|
|
3
4
|
import 'winston-daily-rotate-file'
|
|
4
5
|
// import { RateLimiter } from 'limiter'
|
|
5
6
|
import HttpLimiter from 'express-rate-limit'
|
|
@@ -32,6 +33,23 @@ export class Authentication extends AuthenticationService {
|
|
|
32
33
|
}
|
|
33
34
|
|
|
34
35
|
export class AuthenticationProviderStrategy extends OAuthStrategy {
|
|
36
|
+
setAuthentication (auth) {
|
|
37
|
+
super.setAuthentication(auth)
|
|
38
|
+
const authConfig = this.authentication.configuration
|
|
39
|
+
const { oauth } = authConfig
|
|
40
|
+
// Single logout supported ?
|
|
41
|
+
const { logout_url: logoutUrl, post_logout_url: postLogoutUrl, key } = this.configuration
|
|
42
|
+
if (logoutUrl && key) {
|
|
43
|
+
// Cannot use oauth/:provider/logout route as oauth/:provider is already intercepted by feathers and this causes an error
|
|
44
|
+
this.app.get(`/oauth-logout/${this.name}`, (req, res) => {
|
|
45
|
+
return res.redirect(logoutUrl + '?' + qs.stringify({
|
|
46
|
+
post_logout_redirect_uri: postLogoutUrl || oauth.redirect,
|
|
47
|
+
client_id: key
|
|
48
|
+
}))
|
|
49
|
+
})
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
35
53
|
async getEntityData (profile, entity) {
|
|
36
54
|
const createEntity = _.isNil(entity)
|
|
37
55
|
// Add provider Id
|
|
@@ -50,6 +68,13 @@ export class AuthenticationProviderStrategy extends OAuthStrategy {
|
|
|
50
68
|
}
|
|
51
69
|
|
|
52
70
|
async getEntityQuery (profile) {
|
|
71
|
+
// Ensure the profile is right before requesting based on it
|
|
72
|
+
// as when an error is raised the profile will not contain any ID or email
|
|
73
|
+
// and we might build a request retrieving any user
|
|
74
|
+
if (!_.has(profile, 'id') && !_.has(profile, 'sub') && !_.has(profile, this.emailFieldInProfile || 'email')) {
|
|
75
|
+
// This ensure no user will be retrieved
|
|
76
|
+
return { $limit: 0 }
|
|
77
|
+
}
|
|
53
78
|
const query = {
|
|
54
79
|
$or: [
|
|
55
80
|
{ [`${this.name}Id`]: profile.id || profile.sub },
|
|
@@ -76,6 +101,8 @@ export class AuthenticationProviderStrategy extends OAuthStrategy {
|
|
|
76
101
|
export class JWTAuthenticationStrategy extends JWTStrategy {
|
|
77
102
|
async authenticate (authentication, params) {
|
|
78
103
|
const { accessToken } = authentication
|
|
104
|
+
const authConfig = this.authentication.configuration
|
|
105
|
+
const { identityFields } = authConfig
|
|
79
106
|
const { entity } = this.configuration
|
|
80
107
|
const renewJwt = _.get(this.configuration, 'renewJwt', true)
|
|
81
108
|
|
|
@@ -99,14 +126,31 @@ export class JWTAuthenticationStrategy extends JWTStrategy {
|
|
|
99
126
|
// Second key trick
|
|
100
127
|
// Return user attached to the token if any
|
|
101
128
|
// Return basic information for a stateless token otherwise
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
129
|
+
if (payload.sub) {
|
|
130
|
+
// Check for a valid MongoDB ID
|
|
131
|
+
if (ObjectID.isValid(payload.sub)) {
|
|
132
|
+
const entityId = await this.getEntityId(result, params)
|
|
133
|
+
const value = await this.getEntity(entityId, params)
|
|
106
134
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
135
|
+
return {
|
|
136
|
+
...result,
|
|
137
|
+
[entity]: value
|
|
138
|
+
}
|
|
139
|
+
} else if (identityFields) {
|
|
140
|
+
// Otherwise use others fields to identify the user if defined
|
|
141
|
+
const query = {
|
|
142
|
+
$or: _.reduce(identityFields, (or, field) => or.concat([{ [field]: payload.sub }]), []),
|
|
143
|
+
$limit: 1
|
|
144
|
+
}
|
|
145
|
+
const response = await this.entityService.find({ ...params, query })
|
|
146
|
+
const [value = null] = response.data ? response.data : response
|
|
147
|
+
// Otherwise assume a stateless token
|
|
148
|
+
if (value) {
|
|
149
|
+
return {
|
|
150
|
+
...result,
|
|
151
|
+
[entity]: value
|
|
152
|
+
}
|
|
153
|
+
}
|
|
110
154
|
}
|
|
111
155
|
}
|
|
112
156
|
|
|
@@ -5,67 +5,9 @@ import local from '@feathersjs/authentication-local'
|
|
|
5
5
|
const debug = makeDebug('kdk:core:authentication:hooks')
|
|
6
6
|
const { discard } = common
|
|
7
7
|
|
|
8
|
-
// Make it more easy to
|
|
8
|
+
// Make it more easy to access
|
|
9
9
|
export const hashPassword = local.hooks.hashPassword
|
|
10
10
|
|
|
11
|
-
export async function verifyGuest (hook) {
|
|
12
|
-
if (hook.type !== 'after') {
|
|
13
|
-
throw new Error('The \'verifyGuest\' hook should only be used as a \'after\' hook.')
|
|
14
|
-
}
|
|
15
|
-
const app = hook.app
|
|
16
|
-
const user = hook.result.user
|
|
17
|
-
if (!user) return hook
|
|
18
|
-
debug('verifyGuest hook called on ', user._id)
|
|
19
|
-
|
|
20
|
-
// Check whether the user has been inivted. If not, nothing to do
|
|
21
|
-
if (!user.sponsor) {
|
|
22
|
-
debug('Logged user is not a guest')
|
|
23
|
-
return hook
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
// Check whether has been already verified. If yes, nothing to do
|
|
27
|
-
if (user.isVerified) {
|
|
28
|
-
debug('Logged guest is already verified')
|
|
29
|
-
return hook
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
// The user is a guest and need to be verified
|
|
33
|
-
debug('Verifying logged guest')
|
|
34
|
-
const userService = app.getService('users')
|
|
35
|
-
await userService.patch(user._id, { isVerified: true })
|
|
36
|
-
|
|
37
|
-
return hook
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
export async function consentGuest (hook) {
|
|
41
|
-
if (hook.type !== 'after') {
|
|
42
|
-
throw new Error('The \'consentGuest\' hook should only be used as a \'after\' hook.')
|
|
43
|
-
}
|
|
44
|
-
const app = hook.app
|
|
45
|
-
const user = hook.result.user
|
|
46
|
-
if (!user) return hook
|
|
47
|
-
debug('consentGuest hook called on ', user._id)
|
|
48
|
-
|
|
49
|
-
// Check whether the user has been invited. If not, nothing to do
|
|
50
|
-
if (!user.sponsor) {
|
|
51
|
-
debug('Logged user is not a guest')
|
|
52
|
-
return hook
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
// Check whether consent has been already checked. If yes, nothing to do
|
|
56
|
-
if (user.consentTerms) {
|
|
57
|
-
debug('Logged guest is already verified')
|
|
58
|
-
return hook
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
// The user is a guest and need to be consent
|
|
62
|
-
debug('Consenting logged guest')
|
|
63
|
-
const userService = app.getService('users')
|
|
64
|
-
await userService.patch(user._id, { consentTerms: true, expireAt: null })
|
|
65
|
-
|
|
66
|
-
return hook
|
|
67
|
-
}
|
|
68
|
-
|
|
69
11
|
export function discardAuthenticationProviders (hook) {
|
|
70
12
|
const providers = hook.app.authenticationProviders || []
|
|
71
13
|
|
|
@@ -8,7 +8,6 @@ import {
|
|
|
8
8
|
hasServiceAbilities, hasResourceAbilities, getQueryForAbilities,
|
|
9
9
|
Roles, RoleNames, countSubjectsForResource
|
|
10
10
|
} from '../../common/permissions.js'
|
|
11
|
-
import { isTagEqual } from '../utils.js'
|
|
12
11
|
|
|
13
12
|
const { getItems, replaceItems } = common
|
|
14
13
|
const { Forbidden } = errors
|
|
@@ -25,7 +24,7 @@ export function createJWT (options = {}) {
|
|
|
25
24
|
const accessTokens = await Promise.all(items.map(item => hook.app.getService('authentication').createAccessToken(
|
|
26
25
|
// Provided function can be used to pick or omit properties in JWT payload
|
|
27
26
|
(typeof options.payload === 'function' ? options.payload(user) : {}),
|
|
28
|
-
// Provided function can be used for custom options
|
|
27
|
+
// Provided function can be used for custom options depending on the user,
|
|
29
28
|
// then we merge with default auth options for global properties like aud, iss, etc.
|
|
30
29
|
_.merge({}, defaults, (typeof options.jwt === 'function' ? options.jwt(user) : options)))
|
|
31
30
|
))
|
|
@@ -186,13 +185,15 @@ export async function authorise (hook) {
|
|
|
186
185
|
if (checkAuthorisation) {
|
|
187
186
|
// Build ability for user
|
|
188
187
|
const authorisationService = hook.app.getService('authorisations')
|
|
189
|
-
// If no user we allow for a stateless token with permissions inside
|
|
190
188
|
let subject = hook.params.user
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
//
|
|
194
|
-
|
|
189
|
+
const payload = _.get(hook.params, 'authentication.payload')
|
|
190
|
+
if (payload) {
|
|
191
|
+
// If no user we allow for a stateless token with permissions inside, e.g.
|
|
192
|
+
// token targeting API gateway (sub = keyId) or app used through iframe (appId = keyId)
|
|
193
|
+
if (!subject && (payload.sub || payload.appId)) {
|
|
195
194
|
subject = Object.assign({ _id: (payload.sub || payload.appId) }, payload)
|
|
195
|
+
} else if (subject) { // Otherwise we allow to "extend" user abilities by providing additional information in the token
|
|
196
|
+
subject = Object.assign(subject, _.omit(payload, ['aud', 'iss', 'exp', 'sub', 'iat', 'jti', 'nbf']))
|
|
196
197
|
}
|
|
197
198
|
}
|
|
198
199
|
const abilities = await authorisationService.getAbilities(subject)
|
|
@@ -289,98 +290,3 @@ export function updateAbilities (options = {}) {
|
|
|
289
290
|
}
|
|
290
291
|
}
|
|
291
292
|
|
|
292
|
-
export function preventRemovingLastOwner (resourceScope) {
|
|
293
|
-
return async function (hook) {
|
|
294
|
-
// By pass check ?
|
|
295
|
-
if (hook.params.force) return hook
|
|
296
|
-
const params = hook.params
|
|
297
|
-
const data = hook.data || {}
|
|
298
|
-
const query = params.query || {}
|
|
299
|
-
const scope = data.scope || query.scope
|
|
300
|
-
const grantedPermissions = data.permissions || query.permissions
|
|
301
|
-
const grantedRole = (grantedPermissions ? Roles[grantedPermissions] : undefined)
|
|
302
|
-
const resource = hook.params.resource
|
|
303
|
-
const subjects = hook.params.subjects
|
|
304
|
-
const subjectService = hook.params.subjectsService
|
|
305
|
-
// On create check if we try to downgrade permissions otherwise let pass through
|
|
306
|
-
if (!_.isUndefined(grantedRole) && (grantedRole === Roles.owner)) return hook
|
|
307
|
-
|
|
308
|
-
if ((scope === resourceScope) && resource && resource._id) {
|
|
309
|
-
// Count existing owners
|
|
310
|
-
const owners = await countSubjectsForResource(subjectService, resourceScope, resource._id, Roles.owner)
|
|
311
|
-
// Now count owners we change/remove permissions on
|
|
312
|
-
const removedOwners = subjects.reduce((count, subject) => {
|
|
313
|
-
const resources = _.get(subject, resourceScope, [])
|
|
314
|
-
const ownedResource = _.find(resources, { _id: resource._id, permissions: RoleNames[Roles.owner] })
|
|
315
|
-
return (ownedResource ? count + 1 : count)
|
|
316
|
-
}, 0)
|
|
317
|
-
// If none remains stop
|
|
318
|
-
if (removedOwners >= owners.total) {
|
|
319
|
-
debug('Cannot remove the last owner of resource ', resource)
|
|
320
|
-
const resourceName = resource.name ? resource.name : resource._id.toString()
|
|
321
|
-
throw new Forbidden('You are not allowed to remove the last owner of resource ' + resourceName, {
|
|
322
|
-
translation: {
|
|
323
|
-
key: 'CANNOT_REMOVE_LAST_OWNER',
|
|
324
|
-
params: { resource: resourceName }
|
|
325
|
-
}
|
|
326
|
-
})
|
|
327
|
-
}
|
|
328
|
-
}
|
|
329
|
-
return hook
|
|
330
|
-
}
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
export async function removeOrganisationGroupsAuthorisations (hook) {
|
|
334
|
-
const app = hook.app
|
|
335
|
-
const authorisationService = app.getService('authorisations')
|
|
336
|
-
const org = hook.params.resource
|
|
337
|
-
const user = hook.params.user
|
|
338
|
-
// Unset membership for the all org groups
|
|
339
|
-
const orgGroupService = app.getService('groups', org)
|
|
340
|
-
const groups = await orgGroupService.find({ paginate: false })
|
|
341
|
-
await Promise.all(groups.map(group => {
|
|
342
|
-
// Unset membership on group for the all org users
|
|
343
|
-
return authorisationService.remove(group._id.toString(), {
|
|
344
|
-
query: {
|
|
345
|
-
scope: 'groups'
|
|
346
|
-
},
|
|
347
|
-
user,
|
|
348
|
-
force: hook.params.force,
|
|
349
|
-
// Because we already have resource set it as objects to avoid populating
|
|
350
|
-
// Moreover used as an after hook the resource might not already exist anymore
|
|
351
|
-
subjects: hook.params.subjects,
|
|
352
|
-
subjectsService: hook.params.subjectsService,
|
|
353
|
-
resource: group,
|
|
354
|
-
resourcesService: orgGroupService
|
|
355
|
-
})
|
|
356
|
-
}))
|
|
357
|
-
debug('Authorisations unset on groups for organisation ' + org._id)
|
|
358
|
-
return hook
|
|
359
|
-
}
|
|
360
|
-
|
|
361
|
-
export async function removeOrganisationTagsAuthorisations (hook) {
|
|
362
|
-
const app = hook.app
|
|
363
|
-
const org = hook.params.resource
|
|
364
|
-
const subjectService = hook.params.subjectsService
|
|
365
|
-
const orgTagsService = app.getService('tags', org)
|
|
366
|
-
const subjects = hook.params.subjects || []
|
|
367
|
-
if (subjects.length === 0) return hook
|
|
368
|
-
// Retrieve org tags
|
|
369
|
-
const orgTags = await orgTagsService.find({ paginate: false })
|
|
370
|
-
const promises = []
|
|
371
|
-
subjects.forEach(subject => {
|
|
372
|
-
const tags = subject.tags || []
|
|
373
|
-
// Find tags from org
|
|
374
|
-
const fromOrg = _.intersectionWith(tags, orgTags, isTagEqual)
|
|
375
|
-
// Clear removed tags
|
|
376
|
-
const notFromOrg = _.differenceWith(tags, orgTags, isTagEqual)
|
|
377
|
-
// Update subject if required
|
|
378
|
-
if (fromOrg.length > 0) {
|
|
379
|
-
promises.push(subjectService.patch(subject._id.toString(), { tags: notFromOrg }))
|
|
380
|
-
}
|
|
381
|
-
})
|
|
382
|
-
// Perform subject updates in parallel
|
|
383
|
-
await Promise.all(promises)
|
|
384
|
-
debug(`Tags unset on ${promises.length} subjects for organisation ` + org._id)
|
|
385
|
-
return hook
|
|
386
|
-
}
|
|
@@ -233,6 +233,10 @@ export async function distinct (hook) {
|
|
|
233
233
|
// Check for already existing object according to given service/id field
|
|
234
234
|
export function checkUnique (options = {}) {
|
|
235
235
|
return async (hook) => {
|
|
236
|
+
if (hook.app) {
|
|
237
|
+
const serviceConfig = hook.app.get(hook.service.name)
|
|
238
|
+
if (serviceConfig && serviceConfig.checkUnique) options = serviceConfig.checkUnique
|
|
239
|
+
}
|
|
236
240
|
const service = (options.service ? hook.app.getService(options.service) : hook.service)
|
|
237
241
|
const field = options.field || 'name'
|
|
238
242
|
const id = _.get(hook, `data.${field}`)
|
|
@@ -14,35 +14,41 @@ export async function sendNewSubscriptionEmail (hook) {
|
|
|
14
14
|
if (hook.type !== 'after') {
|
|
15
15
|
throw new Error('The \'sendNewSubscriptionEmail\' hook should only be used as a \'after\' hook.')
|
|
16
16
|
}
|
|
17
|
-
|
|
18
17
|
// Check for a new subscription if any
|
|
19
|
-
const
|
|
18
|
+
const currentUser = hook.result
|
|
20
19
|
const previousUser = hook.params.user
|
|
21
20
|
// If we can't compare abort, eg f-a-m might patch user to update tokens
|
|
22
|
-
if (!
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
//
|
|
21
|
+
if (!currentUser || !previousUser) return
|
|
22
|
+
// Retrieve the last subscription
|
|
23
|
+
const lastSubscription = _.last(_.get(currentUser, 'subscriptions', []))
|
|
24
|
+
if (!lastSubscription) return
|
|
25
|
+
// Check whether the subscription has an existing fingerprint
|
|
26
|
+
const existingSubscription = _.find(_.get(previousUser, 'subscriptions', []), subscription => {
|
|
27
|
+
return _.isEqual(subscription.fingerprint, lastSubscription.fingerprint)
|
|
28
|
+
})
|
|
29
|
+
if (existingSubscription) {
|
|
30
|
+
debug('Last subscription uses an existing fingerprint')
|
|
31
|
+
return
|
|
32
|
+
}
|
|
33
|
+
debug('Last subscription uses uses a new fingerprint')
|
|
34
|
+
// Send an email to notify the user
|
|
27
35
|
const app = hook.app
|
|
28
36
|
const mailerService = app.getService('mailer')
|
|
29
37
|
const domainPath = app.get('domain') + '/#/'
|
|
30
38
|
const email = {
|
|
31
39
|
subject: 'Security alert - new browser detected',
|
|
32
|
-
from: mailerService.options.auth.user,
|
|
33
|
-
|
|
34
|
-
to: updatedUser.email,
|
|
40
|
+
from: mailerService.options.from || mailerService.options.auth.user,
|
|
41
|
+
to: currentUser.email,
|
|
35
42
|
link: domainPath,
|
|
36
43
|
domainPath
|
|
37
44
|
}
|
|
38
|
-
|
|
39
45
|
// Build the subject & link to the app to perform the different actions
|
|
40
46
|
const templateDir = path.join(mailerService.options.templateDir, 'newSubscription')
|
|
41
47
|
const template = new emails.EmailTemplate(templateDir)
|
|
42
48
|
// Errors does not seem to be correctly catched by the caller
|
|
43
49
|
// so we catch them here to avoid any problem
|
|
44
50
|
try {
|
|
45
|
-
const emailContent = await template.render({ email, user:
|
|
51
|
+
const emailContent = await template.render({ email, user: currentUser, subscription: lastSubscription }, currentUser.locale || 'en-us')
|
|
46
52
|
// Update compiled content
|
|
47
53
|
email.html = emailContent.html
|
|
48
54
|
debug('Sending email ', email)
|
|
@@ -51,6 +57,4 @@ export async function sendNewSubscriptionEmail (hook) {
|
|
|
51
57
|
debug('Sending email failed', error)
|
|
52
58
|
app.logger.error(error)
|
|
53
59
|
}
|
|
54
|
-
|
|
55
|
-
return hook
|
|
56
60
|
}
|
|
@@ -135,86 +135,6 @@ export function generatePassword (options = {}) {
|
|
|
135
135
|
}
|
|
136
136
|
}
|
|
137
137
|
|
|
138
|
-
export function preventRemoveUser (hook) {
|
|
139
|
-
if (hook.type !== 'before') {
|
|
140
|
-
throw new Error('The \'preventRemoveUser\' hook should only be used as a \'before\' hook.')
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
// By pass check ?
|
|
144
|
-
if (hook.params.force) return hook
|
|
145
|
-
const user = hook.params.user
|
|
146
|
-
// Check if the target is the current user
|
|
147
|
-
if ((user._id.toString() === hook.id.toString()) && user.organisations) {
|
|
148
|
-
// We must ensure the user is no more a owner of an organisation
|
|
149
|
-
const owningOrganisations = _.filter(user.organisations, { permissions: RoleNames[Roles.owner] })
|
|
150
|
-
if (!_.isEmpty(owningOrganisations)) {
|
|
151
|
-
debug('Cannot remove the user: ', user)
|
|
152
|
-
throw new Forbidden('You are not allowed to delete the user ' + user.name, {
|
|
153
|
-
translation: {
|
|
154
|
-
key: 'CANNOT_REMOVE_USER',
|
|
155
|
-
params: { user: _.get(user, 'profile.name') }
|
|
156
|
-
}
|
|
157
|
-
})
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
return hook
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
export async function joinOrganisation (hook) {
|
|
164
|
-
const app = hook.app
|
|
165
|
-
const subject = getItems(hook)
|
|
166
|
-
const authorisationService = app.getService('authorisations')
|
|
167
|
-
const usersService = app.getService('users')
|
|
168
|
-
|
|
169
|
-
// Set membership for the created user
|
|
170
|
-
await authorisationService.create({
|
|
171
|
-
scope: 'organisations',
|
|
172
|
-
permissions: subject.sponsor.roleGranted, // Member by default
|
|
173
|
-
resource: subject.sponsor.organisationId,
|
|
174
|
-
resourcesService: 'organisations'
|
|
175
|
-
}, {
|
|
176
|
-
subjectsService: usersService,
|
|
177
|
-
subjects: [subject]
|
|
178
|
-
})
|
|
179
|
-
debug('Organisation membership set for user ' + subject._id)
|
|
180
|
-
return hook
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
export function leaveOrganisations (options = { skipPrivate: true }) {
|
|
184
|
-
return async function (hook) {
|
|
185
|
-
if (hook.type !== 'after') {
|
|
186
|
-
throw new Error('The \'leaveOrganisations\' hook should only be used as a \'after\' hook.')
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
const app = hook.app
|
|
190
|
-
const organisationsService = app.getService('organisations')
|
|
191
|
-
const authorisationService = app.getService('authorisations')
|
|
192
|
-
const usersService = app.getService('users')
|
|
193
|
-
const subject = getItems(hook)
|
|
194
|
-
const organisations = _.get(subject, 'organisations', [])
|
|
195
|
-
|
|
196
|
-
await Promise.all(organisations.map(organisation => {
|
|
197
|
-
// Unset membership on org except private org if required
|
|
198
|
-
if (options.skipPrivate && organisation._id.toString() === subject._id.toString()) return Promise.resolve()
|
|
199
|
-
return authorisationService.remove(organisation._id.toString(), {
|
|
200
|
-
query: {
|
|
201
|
-
scope: 'organisations'
|
|
202
|
-
},
|
|
203
|
-
user: hook.params.user,
|
|
204
|
-
// Because we already have resource set it as objects to avoid populating
|
|
205
|
-
// Moreover used as an after hook the subject might not already exist anymore
|
|
206
|
-
subjects: [subject],
|
|
207
|
-
subjectsService: usersService,
|
|
208
|
-
resource: organisation,
|
|
209
|
-
resourcesService: organisationsService
|
|
210
|
-
})
|
|
211
|
-
}))
|
|
212
|
-
|
|
213
|
-
debug('Membership unset for all organisations on user ' + subject._id)
|
|
214
|
-
return hook
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
|
|
218
138
|
export async function sendVerificationEmail (hook) {
|
|
219
139
|
if (hook.type !== 'after') {
|
|
220
140
|
throw new Error('The \'sendVerificationEmail\' hook should only be used as a \'after\' hook.')
|
|
@@ -230,17 +150,6 @@ export async function sendVerificationEmail (hook) {
|
|
|
230
150
|
return hook
|
|
231
151
|
}
|
|
232
152
|
|
|
233
|
-
export async function sendInvitationEmail (hook) {
|
|
234
|
-
// Before because we need to send the clear password by email
|
|
235
|
-
if (hook.type !== 'before') {
|
|
236
|
-
throw new Error('The \'sendInvitationEmail\' hook should only be used as a \'before\' hook.')
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
const accountService = hook.app.getService('account')
|
|
240
|
-
await accountService.options.notifier('sendInvitation', hook.data)
|
|
241
|
-
return hook
|
|
242
|
-
}
|
|
243
|
-
|
|
244
153
|
export function addVerification (hook) {
|
|
245
154
|
const accountService = hook.app.getService('account')
|
|
246
155
|
|
package/core/api/hooks/index.js
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
export * from './hooks.authentication.js'
|
|
2
2
|
export * from './hooks.authorisations.js'
|
|
3
|
-
export * from './hooks.groups.js'
|
|
4
3
|
export * from './hooks.logger.js'
|
|
5
4
|
export * from './hooks.model.js'
|
|
6
|
-
export * from './hooks.organisations.js'
|
|
7
5
|
export * from './hooks.query.js'
|
|
8
6
|
export * from './hooks.schemas.js'
|
|
9
7
|
export * from './hooks.service.js'
|
|
@@ -42,7 +42,7 @@ export default function (name, app, options) {
|
|
|
42
42
|
const mailerService = app.getService('mailer')
|
|
43
43
|
const domainPath = app.get('domain') + '/#/'
|
|
44
44
|
const email = {
|
|
45
|
-
from: mailerService.options.auth.user,
|
|
45
|
+
from: mailerService.options.from || mailerService.options.auth.user,
|
|
46
46
|
// When changing email send to the new one so that it can be verified
|
|
47
47
|
to: (type === 'identityChange' ? user.verifyChanges.email : user.email),
|
|
48
48
|
domainPath
|
|
@@ -22,10 +22,6 @@ export default {
|
|
|
22
22
|
const scope = _.get(subject, scopeName, [])
|
|
23
23
|
// Then the target resource
|
|
24
24
|
let resource = _.find(scope, resource => resource._id && (resource._id.toString() === params.resource._id.toString()))
|
|
25
|
-
if (!resource) {
|
|
26
|
-
// Fallback as name
|
|
27
|
-
resource = _.find(scope, resource => resource.name && (resource.name === params.resource.name))
|
|
28
|
-
}
|
|
29
25
|
// On first authorisation create the resource in scope
|
|
30
26
|
if (!resource) {
|
|
31
27
|
resource = Object.assign({}, params.resource)
|
|
@@ -91,37 +87,40 @@ export default {
|
|
|
91
87
|
setup (app) {
|
|
92
88
|
const config = app.get('authorisation')
|
|
93
89
|
if (config && config.cache) {
|
|
90
|
+
this.cacheConfig = config.cache
|
|
94
91
|
// Store abilities of the N most active users in LRU cache (defaults to 1000)
|
|
95
|
-
const max =
|
|
92
|
+
const max = this.cacheConfig.maxUsers || 1000
|
|
96
93
|
// LRU cache lib switched from positional parameters to options object at some point
|
|
97
94
|
// so that now we directly pass the options to it while before we used the max argument
|
|
98
|
-
if (!
|
|
99
|
-
this.cache = new LRUCache(
|
|
95
|
+
if (!this.cacheConfig.max && !this.cacheConfig.ttl && !this.cacheConfig.maxSize) this.cacheConfig.max = max
|
|
96
|
+
this.cache = new LRUCache(this.cacheConfig)
|
|
100
97
|
debug('Using LRU cache for user abilities')
|
|
101
98
|
} else {
|
|
102
99
|
debug('Do not use LRU cache for user abilities')
|
|
103
100
|
}
|
|
104
101
|
},
|
|
105
102
|
|
|
103
|
+
getCacheKey (subject) {
|
|
104
|
+
if (!this.cache) return null
|
|
105
|
+
let cacheKey
|
|
106
|
+
// Compute cache key based on provided function or user ID
|
|
107
|
+
if (typeof this.cacheConfig.key === 'function') cacheKey = this.cacheConfig.key(subject)
|
|
108
|
+
if (!cacheKey && subject && subject._id) cacheKey = subject._id.toString()
|
|
109
|
+
return cacheKey || ANONYMOUS_USER
|
|
110
|
+
},
|
|
111
|
+
|
|
106
112
|
// Compute abilities for a given user and set it in cache the first time
|
|
107
113
|
// or get it from cache if found
|
|
108
114
|
async getAbilities (subject) {
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
} else {
|
|
113
|
-
if (this.cache.has(ANONYMOUS_USER)) return this.cache.get(ANONYMOUS_USER)
|
|
114
|
-
}
|
|
115
|
-
}
|
|
115
|
+
const cacheKey = this.getCacheKey(subject)
|
|
116
|
+
if (cacheKey && this.cache.has(cacheKey)) return this.cache.get(cacheKey)
|
|
117
|
+
|
|
116
118
|
// Provide app for any complex use case requiring to make requests
|
|
117
119
|
const abilities = await defineAbilities(subject, this.app)
|
|
118
120
|
|
|
119
|
-
if (
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
} else {
|
|
123
|
-
this.cache.set(ANONYMOUS_USER, abilities)
|
|
124
|
-
}
|
|
121
|
+
if (cacheKey) {
|
|
122
|
+
debug('Updating user abilities of subject ' + (subject ? subject._id : ANONYMOUS_USER) + ' with cache key ' + cacheKey)
|
|
123
|
+
this.cache.set(cacheKey, abilities)
|
|
125
124
|
}
|
|
126
125
|
|
|
127
126
|
return abilities
|
|
@@ -129,20 +128,20 @@ export default {
|
|
|
129
128
|
|
|
130
129
|
// Compute abilities for a given user and update it in cache
|
|
131
130
|
async updateAbilities (subject) {
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
|
|
131
|
+
const cacheKey = this.getCacheKey(subject)
|
|
132
|
+
|
|
133
|
+
// Remove abilities from cache so that next call will populate it again
|
|
134
|
+
if (cacheKey && this.cache.has(cacheKey)) this.cache.delete(cacheKey)
|
|
135
|
+
|
|
140
136
|
const abilities = await this.getAbilities(subject)
|
|
141
137
|
return abilities
|
|
142
138
|
},
|
|
143
139
|
|
|
144
140
|
// Clear abilities
|
|
145
141
|
clearAbilities() {
|
|
146
|
-
if (this.cache)
|
|
142
|
+
if (this.cache) {
|
|
143
|
+
debug('Clearing user abilities cache')
|
|
144
|
+
this.cache.clear()
|
|
145
|
+
}
|
|
147
146
|
}
|
|
148
147
|
}
|