@kalisio/kdk 2.0.0 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.codeclimate.yml +0 -1
- package/.travis.test.sh +3 -0
- package/core/api/application.js +591 -0
- package/core/api/authentication.js +203 -0
- package/core/api/db.js +226 -0
- package/core/api/hooks/hooks.authentication.js +74 -0
- package/core/api/hooks/hooks.authorisations.js +376 -0
- package/core/api/hooks/hooks.groups.js +48 -0
- package/core/api/hooks/hooks.logger.js +26 -0
- package/core/api/hooks/hooks.model.js +290 -0
- package/core/api/hooks/hooks.organisations.js +156 -0
- package/core/api/hooks/hooks.push.js +54 -0
- package/core/api/hooks/hooks.query.js +246 -0
- package/core/api/hooks/hooks.schemas.js +73 -0
- package/core/api/hooks/hooks.service.js +78 -0
- package/core/api/hooks/hooks.storage.js +36 -0
- package/core/api/hooks/hooks.users.js +261 -0
- package/core/api/hooks/index.js +12 -0
- package/core/api/index.js +21 -0
- package/core/api/marshall.js +90 -0
- package/core/api/models/groups.model.mongodb.js +8 -0
- package/core/api/models/organisations.model.mongodb.js +3 -0
- package/core/api/models/tags.model.mongodb.js +10 -0
- package/core/api/models/users.model.mongodb.js +10 -0
- package/core/api/services/account/account.hooks.js +37 -0
- package/core/api/services/account/account.service.js +120 -0
- package/core/api/services/authorisations/authorisations.hooks.js +33 -0
- package/core/api/services/authorisations/authorisations.service.js +139 -0
- package/core/api/services/databases/databases.hooks.js +36 -0
- package/core/api/services/databases/databases.service.js +5 -0
- package/core/api/services/groups/groups.hooks.js +31 -0
- package/core/api/services/index.js +126 -0
- package/core/api/services/mailer/mailer.hooks.js +35 -0
- package/core/api/services/mailer/mailer.service.js +11 -0
- package/core/api/services/organisations/organisations.hooks.js +31 -0
- package/core/api/services/organisations/organisations.service.js +86 -0
- package/core/api/services/push/push.hooks.js +35 -0
- package/core/api/services/push/push.service.js +12 -0
- package/core/api/services/storage/storage.hooks.js +35 -0
- package/core/api/services/storage/storage.service.js +29 -0
- package/core/api/services/tags/tags.hooks.js +31 -0
- package/core/api/services/users/users.hooks.js +75 -0
- package/core/api/utils.js +11 -0
- package/core/client/api.js +293 -0
- package/core/client/capabilities.js +22 -0
- package/core/client/components/KAction.vue +393 -0
- package/core/client/components/KAvatar.vue +129 -0
- package/core/client/components/KBlock.vue +67 -0
- package/core/client/components/KChip.vue +68 -0
- package/core/client/components/KChipsPane.vue +103 -0
- package/core/client/components/KContent.vue +105 -0
- package/core/client/components/KDialog.vue +160 -0
- package/core/client/components/KExpandable.vue +49 -0
- package/core/client/components/KLogo.vue +32 -0
- package/core/client/components/KModal.vue +173 -0
- package/core/client/components/KPanel.vue +64 -0
- package/core/client/components/KScrollArea.vue +88 -0
- package/core/client/components/KSponsor.vue +40 -0
- package/core/client/components/KStamp.vue +65 -0
- package/core/client/components/KStore.vue +102 -0
- package/core/client/components/KTextArea.vue +143 -0
- package/core/client/components/KTree.vue +31 -0
- package/core/client/components/KVersion.vue +19 -0
- package/core/client/components/account/KAccount.vue +68 -0
- package/core/client/components/account/KDeleteAccountManager.vue +62 -0
- package/core/client/components/account/KEmailManager.vue +128 -0
- package/core/client/components/account/KPasswordManager.vue +90 -0
- package/core/client/components/account/KProfile.vue +109 -0
- package/core/client/components/account/KResetPassword.vue +120 -0
- package/core/client/components/account/KSendResetPassword.vue +90 -0
- package/core/client/components/account/KSubscription.vue +71 -0
- package/core/client/components/account/KSubscriptionsManager.vue +46 -0
- package/core/client/components/account/KVerifyEmailManager.vue +105 -0
- package/core/client/components/account/index.js +7 -0
- package/core/client/components/app/KAbout.vue +98 -0
- package/core/client/components/app/KHome.vue +12 -0
- package/core/client/components/app/KPlatform.vue +55 -0
- package/core/client/components/app/KSettings.vue +43 -0
- package/core/client/components/app/KTerms.vue +41 -0
- package/core/client/components/app/KTour.vue +448 -0
- package/core/client/components/app/KWelcome.vue +133 -0
- package/core/client/components/app/index.js +11 -0
- package/core/client/components/chart/KChart.vue +197 -0
- package/core/client/components/chart/KDataTable.vue +183 -0
- package/core/client/components/chart/KStatisticsChart.vue +94 -0
- package/core/client/components/chart/KTimeSeriesChart.vue +431 -0
- package/core/client/components/chart/index.js +9 -0
- package/core/client/components/collection/KBoard.vue +65 -0
- package/core/client/components/collection/KCard.vue +196 -0
- package/core/client/components/collection/KCardSection.vue +52 -0
- package/core/client/components/collection/KColumn.vue +225 -0
- package/core/client/components/collection/KFilter.vue +158 -0
- package/core/client/components/collection/KGrid.vue +121 -0
- package/core/client/components/collection/KHistory.vue +112 -0
- package/core/client/components/collection/KHistoryEntry.vue +111 -0
- package/core/client/components/collection/KItem.vue +128 -0
- package/core/client/components/collection/KList.vue +135 -0
- package/core/client/components/collection/KSorter.vue +46 -0
- package/core/client/components/collection/KTable.vue +238 -0
- package/core/client/components/collection/index.js +19 -0
- package/core/client/components/editor/KEditor.vue +52 -0
- package/core/client/components/editor/KModalEditor.vue +96 -0
- package/core/client/components/editor/index.js +7 -0
- package/core/client/components/form/KChipsField.vue +162 -0
- package/core/client/components/form/KColorField.vue +69 -0
- package/core/client/components/form/KColorScaleField.vue +86 -0
- package/core/client/components/form/KDateTimeRangeField.vue +65 -0
- package/core/client/components/form/KDatetimeField.vue +70 -0
- package/core/client/components/form/KEmailField.vue +33 -0
- package/core/client/components/form/KFileField.vue +161 -0
- package/core/client/components/form/KForm.vue +247 -0
- package/core/client/components/form/KIconField.vue +101 -0
- package/core/client/components/form/KItemField.vue +123 -0
- package/core/client/components/form/KNumberField.vue +33 -0
- package/core/client/components/form/KOptionsField.vue +63 -0
- package/core/client/components/form/KPasswordField.vue +57 -0
- package/core/client/components/form/KPhoneField.vue +32 -0
- package/core/client/components/form/KPropertyItemField.vue +119 -0
- package/core/client/components/form/KRoleField.vue +60 -0
- package/core/client/components/form/KSelectField.vue +143 -0
- package/core/client/components/form/KTextField.vue +48 -0
- package/core/client/components/form/KTextareaField.vue +88 -0
- package/core/client/components/form/KToggleField.vue +46 -0
- package/core/client/components/form/KTokenField.vue +80 -0
- package/core/client/components/form/KUnitField.vue +57 -0
- package/core/client/components/form/KUrlField.vue +32 -0
- package/core/client/components/form/KView.vue +118 -0
- package/core/client/components/form/index.js +7 -0
- package/core/client/components/index.js +48 -0
- package/core/client/components/input/KColorChooser.vue +63 -0
- package/core/client/components/input/KIconChooser.vue +308 -0
- package/core/client/components/input/KOptionsChooser.vue +122 -0
- package/core/client/components/input/KPalette.vue +40 -0
- package/core/client/components/input/index.js +11 -0
- package/core/client/components/layout/KFab.vue +113 -0
- package/core/client/components/layout/KLayout.vue +64 -0
- package/core/client/components/layout/KOpener.vue +140 -0
- package/core/client/components/layout/KPage.vue +320 -0
- package/core/client/components/layout/KPageSticky.vue +53 -0
- package/core/client/components/layout/KWindow.vue +443 -0
- package/core/client/components/layout/index.js +13 -0
- package/core/client/components/media/KColorScale.vue +254 -0
- package/core/client/components/media/KImageViewer.vue +44 -0
- package/core/client/components/media/KMarkdownViewer.vue +55 -0
- package/core/client/components/media/KMediaBrowser.vue +340 -0
- package/core/client/components/media/KShape.vue +120 -0
- package/core/client/components/media/index.js +13 -0
- package/core/client/components/menu/KMenu.vue +147 -0
- package/core/client/components/menu/KRadialFab.vue +122 -0
- package/core/client/components/menu/KRadialFabItem.vue +73 -0
- package/core/client/components/menu/index.js +9 -0
- package/core/client/components/screen/KEndpointScreen.vue +80 -0
- package/core/client/components/screen/KErrorScreen.vue +24 -0
- package/core/client/components/screen/KLoginScreen.vue +79 -0
- package/core/client/components/screen/KLogoutScreen.vue +20 -0
- package/core/client/components/screen/KRegisterScreen.vue +114 -0
- package/core/client/components/screen/KScreen.vue +106 -0
- package/core/client/components/screen/KScreenFooter.vue +32 -0
- package/core/client/components/screen/KScreenHeader.vue +17 -0
- package/core/client/components/screen/index.js +5 -0
- package/core/client/components/team/KAddMember.vue +375 -0
- package/core/client/components/team/KAddTag.vue +121 -0
- package/core/client/components/team/KChangeRole.vue +118 -0
- package/core/client/components/team/KGroupCard.vue +110 -0
- package/core/client/components/team/KGroupsActivity.vue +66 -0
- package/core/client/components/team/KJoinGroup.vue +132 -0
- package/core/client/components/team/KMemberCard.vue +328 -0
- package/core/client/components/team/KMemberFilter.vue +49 -0
- package/core/client/components/team/KMembersActivity.vue +126 -0
- package/core/client/components/team/KOrganisationsActivity.vue +53 -0
- package/core/client/components/team/KTagCard.vue +72 -0
- package/core/client/components/team/KTagsActivity.vue +61 -0
- package/core/client/components/team/index.js +9 -0
- package/core/client/components/time/KAbsoluteTimeRange.vue +183 -0
- package/core/client/components/time/KDate.vue +75 -0
- package/core/client/components/time/KDateTime.vue +172 -0
- package/core/client/components/time/KDateTimeRange.vue +118 -0
- package/core/client/components/time/KRelativeTimeRanges.vue +193 -0
- package/core/client/components/time/KTime.vue +74 -0
- package/core/client/components/time/index.js +7 -0
- package/core/client/components/viewer/KModalViewer.vue +47 -0
- package/core/client/components/viewer/KViewer.vue +30 -0
- package/core/client/composables/activity.js +67 -0
- package/core/client/composables/collection.js +181 -0
- package/core/client/composables/index.js +8 -0
- package/core/client/composables/pwa.js +71 -0
- package/core/client/composables/schema.js +64 -0
- package/core/client/composables/selection.js +88 -0
- package/core/client/composables/session.js +150 -0
- package/core/client/composables/store.js +49 -0
- package/core/client/composables/version.js +47 -0
- package/core/client/events.js +3 -0
- package/core/client/filter.js +60 -0
- package/core/client/guards.js +101 -0
- package/core/client/hooks/hooks.events.js +7 -0
- package/core/client/hooks/hooks.logger.js +24 -0
- package/core/client/hooks/hooks.users.js +22 -0
- package/core/client/hooks/index.js +3 -0
- package/core/client/i18n/core_en.json +840 -0
- package/core/client/i18n/core_fr.json +838 -0
- package/core/client/i18n.js +88 -0
- package/core/client/index.js +84 -0
- package/core/client/layout.js +323 -0
- package/core/client/local-storage.js +28 -0
- package/core/client/mixins/index.js +12 -0
- package/core/client/mixins/mixin.account.js +61 -0
- package/core/client/mixins/mixin.base-activity.js +232 -0
- package/core/client/mixins/mixin.base-collection.js +162 -0
- package/core/client/mixins/mixin.base-context.js +54 -0
- package/core/client/mixins/mixin.base-editor.js +194 -0
- package/core/client/mixins/mixin.base-field.js +105 -0
- package/core/client/mixins/mixin.base-item.js +166 -0
- package/core/client/mixins/mixin.base-modal.js +36 -0
- package/core/client/mixins/mixin.base-viewer.js +43 -0
- package/core/client/mixins/mixin.object-proxy.js +46 -0
- package/core/client/mixins/mixin.schema-proxy.js +97 -0
- package/core/client/mixins/mixin.service.js +22 -0
- package/core/client/reader.js +65 -0
- package/core/client/readers/index.js +3 -0
- package/core/client/readers/reader.blob.js +39 -0
- package/core/client/readers/reader.csv.js +36 -0
- package/core/client/readers/reader.json.js +34 -0
- package/core/client/search.js +47 -0
- package/core/client/services/index.js +47 -0
- package/core/client/services/local-settings.service.js +67 -0
- package/core/client/sorter.js +31 -0
- package/core/client/storage.js +102 -0
- package/core/client/store.js +39 -0
- package/core/client/theme.js +40 -0
- package/core/client/time.js +167 -0
- package/core/client/units.js +218 -0
- package/core/client/utils/index.js +203 -0
- package/core/client/utils/utils.account.js +47 -0
- package/core/client/utils/utils.colors.js +36 -0
- package/core/client/utils/utils.content.js +185 -0
- package/core/client/utils/utils.locale.js +28 -0
- package/core/client/utils/utils.platform.js +11 -0
- package/core/client/utils/utils.push.js +53 -0
- package/core/client/utils/utils.pwa.js +63 -0
- package/core/client/utils/utils.session.js +89 -0
- package/core/common/errors.js +1 -0
- package/core/common/index.js +10 -0
- package/core/common/permissions.js +318 -0
- package/core/common/schema.js +35 -0
- package/core/common/schemas/groups.create.json +28 -0
- package/core/common/schemas/groups.update.json +28 -0
- package/core/common/schemas/organisations.create.json +28 -0
- package/core/common/schemas/organisations.update.json +49 -0
- package/core/common/schemas/settings.update.json +234 -0
- package/core/common/schemas/tags.create.json +35 -0
- package/core/common/schemas/tags.update.json +35 -0
- package/core/common/schemas/users.update-profile.json +33 -0
- package/core/common/utils.js +45 -0
- package/coverage/base.css +224 -0
- package/coverage/block-navigation.js +87 -0
- package/coverage/core/api/application.js.html +1849 -0
- package/coverage/core/api/authentication.js.html +694 -0
- package/coverage/core/api/db.js.html +763 -0
- package/coverage/core/api/hooks/hooks.account.js.html +169 -0
- package/coverage/core/api/hooks/hooks.authentication.js.html +274 -0
- package/coverage/core/api/hooks/hooks.authorisations.js.html +1213 -0
- package/coverage/core/api/hooks/hooks.groups.js.html +229 -0
- package/coverage/core/api/hooks/hooks.logger.js.html +163 -0
- package/coverage/core/api/hooks/hooks.model.js.html +994 -0
- package/coverage/core/api/hooks/hooks.organisations.js.html +553 -0
- package/coverage/core/api/hooks/hooks.push.js.html +232 -0
- package/coverage/core/api/hooks/hooks.query.js.html +838 -0
- package/coverage/core/api/hooks/hooks.schemas.js.html +304 -0
- package/coverage/core/api/hooks/hooks.service.js.html +319 -0
- package/coverage/core/api/hooks/hooks.storage.js.html +193 -0
- package/coverage/core/api/hooks/hooks.tags.js.html +850 -0
- package/coverage/core/api/hooks/hooks.users.js.html +826 -0
- package/coverage/core/api/hooks/index.html +296 -0
- package/coverage/core/api/hooks/index.js.html +121 -0
- package/coverage/core/api/index.html +191 -0
- package/coverage/core/api/index.js.html +148 -0
- package/coverage/core/api/marshall.js.html +355 -0
- package/coverage/core/api/models/groups.model.mongodb.js.html +109 -0
- package/coverage/core/api/models/index.html +161 -0
- package/coverage/core/api/models/organisations.model.mongodb.js.html +94 -0
- package/coverage/core/api/models/tags.model.mongodb.js.html +115 -0
- package/coverage/core/api/models/users.model.mongodb.js.html +115 -0
- package/coverage/core/api/services/account/account.hooks.js.html +196 -0
- package/coverage/core/api/services/account/account.service.js.html +445 -0
- package/coverage/core/api/services/account/index.html +131 -0
- package/coverage/core/api/services/authorisations/authorisations.hooks.js.html +184 -0
- package/coverage/core/api/services/authorisations/authorisations.service.js.html +502 -0
- package/coverage/core/api/services/authorisations/index.html +131 -0
- package/coverage/core/api/services/databases/databases.hooks.js.html +193 -0
- package/coverage/core/api/services/databases/databases.service.js.html +100 -0
- package/coverage/core/api/services/databases/index.html +131 -0
- package/coverage/core/api/services/groups/groups.hooks.js.html +178 -0
- package/coverage/core/api/services/groups/index.html +116 -0
- package/coverage/core/api/services/index.html +116 -0
- package/coverage/core/api/services/index.js.html +475 -0
- package/coverage/core/api/services/mailer/index.html +131 -0
- package/coverage/core/api/services/mailer/mailer.hooks.js.html +190 -0
- package/coverage/core/api/services/mailer/mailer.service.js.html +118 -0
- package/coverage/core/api/services/organisations/index.html +131 -0
- package/coverage/core/api/services/organisations/organisations.hooks.js.html +178 -0
- package/coverage/core/api/services/organisations/organisations.service.js.html +343 -0
- package/coverage/core/api/services/push/index.html +131 -0
- package/coverage/core/api/services/push/push.hooks.js.html +193 -0
- package/coverage/core/api/services/push/push.service.js.html +121 -0
- package/coverage/core/api/services/storage/index.html +131 -0
- package/coverage/core/api/services/storage/storage.hooks.js.html +190 -0
- package/coverage/core/api/services/storage/storage.service.js.html +172 -0
- package/coverage/core/api/services/tags/index.html +116 -0
- package/coverage/core/api/services/tags/tags.hooks.js.html +178 -0
- package/coverage/core/api/services/users/index.html +116 -0
- package/coverage/core/api/services/users/users.hooks.js.html +313 -0
- package/coverage/core/api/utils.js.html +118 -0
- package/coverage/core/common/errors.js.html +88 -0
- package/coverage/core/common/index.html +176 -0
- package/coverage/core/common/index.js.html +115 -0
- package/coverage/core/common/permissions.js.html +1039 -0
- package/coverage/core/common/schema.js.html +190 -0
- package/coverage/core/common/utils.js.html +220 -0
- package/coverage/favicon.png +0 -0
- package/coverage/index.html +476 -0
- package/coverage/lcov-report/base.css +224 -0
- package/coverage/lcov-report/block-navigation.js +87 -0
- package/coverage/lcov-report/core/api/application.js.html +1849 -0
- package/coverage/lcov-report/core/api/authentication.js.html +694 -0
- package/coverage/lcov-report/core/api/db.js.html +763 -0
- package/coverage/lcov-report/core/api/hooks/hooks.account.js.html +169 -0
- package/coverage/lcov-report/core/api/hooks/hooks.authentication.js.html +274 -0
- package/coverage/lcov-report/core/api/hooks/hooks.authorisations.js.html +1213 -0
- package/coverage/lcov-report/core/api/hooks/hooks.groups.js.html +229 -0
- package/coverage/lcov-report/core/api/hooks/hooks.logger.js.html +163 -0
- package/coverage/lcov-report/core/api/hooks/hooks.model.js.html +994 -0
- package/coverage/lcov-report/core/api/hooks/hooks.organisations.js.html +553 -0
- package/coverage/lcov-report/core/api/hooks/hooks.push.js.html +232 -0
- package/coverage/lcov-report/core/api/hooks/hooks.query.js.html +838 -0
- package/coverage/lcov-report/core/api/hooks/hooks.schemas.js.html +304 -0
- package/coverage/lcov-report/core/api/hooks/hooks.service.js.html +319 -0
- package/coverage/lcov-report/core/api/hooks/hooks.storage.js.html +193 -0
- package/coverage/lcov-report/core/api/hooks/hooks.tags.js.html +850 -0
- package/coverage/lcov-report/core/api/hooks/hooks.users.js.html +826 -0
- package/coverage/lcov-report/core/api/hooks/index.html +296 -0
- package/coverage/lcov-report/core/api/hooks/index.js.html +121 -0
- package/coverage/lcov-report/core/api/index.html +191 -0
- package/coverage/lcov-report/core/api/index.js.html +148 -0
- package/coverage/lcov-report/core/api/marshall.js.html +355 -0
- package/coverage/lcov-report/core/api/models/groups.model.mongodb.js.html +109 -0
- package/coverage/lcov-report/core/api/models/index.html +161 -0
- package/coverage/lcov-report/core/api/models/organisations.model.mongodb.js.html +94 -0
- package/coverage/lcov-report/core/api/models/tags.model.mongodb.js.html +115 -0
- package/coverage/lcov-report/core/api/models/users.model.mongodb.js.html +115 -0
- package/coverage/lcov-report/core/api/services/account/account.hooks.js.html +196 -0
- package/coverage/lcov-report/core/api/services/account/account.service.js.html +445 -0
- package/coverage/lcov-report/core/api/services/account/index.html +131 -0
- package/coverage/lcov-report/core/api/services/authorisations/authorisations.hooks.js.html +184 -0
- package/coverage/lcov-report/core/api/services/authorisations/authorisations.service.js.html +502 -0
- package/coverage/lcov-report/core/api/services/authorisations/index.html +131 -0
- package/coverage/lcov-report/core/api/services/databases/databases.hooks.js.html +193 -0
- package/coverage/lcov-report/core/api/services/databases/databases.service.js.html +100 -0
- package/coverage/lcov-report/core/api/services/databases/index.html +131 -0
- package/coverage/lcov-report/core/api/services/groups/groups.hooks.js.html +178 -0
- package/coverage/lcov-report/core/api/services/groups/index.html +116 -0
- package/coverage/lcov-report/core/api/services/index.html +116 -0
- package/coverage/lcov-report/core/api/services/index.js.html +475 -0
- package/coverage/lcov-report/core/api/services/mailer/index.html +131 -0
- package/coverage/lcov-report/core/api/services/mailer/mailer.hooks.js.html +190 -0
- package/coverage/lcov-report/core/api/services/mailer/mailer.service.js.html +118 -0
- package/coverage/lcov-report/core/api/services/organisations/index.html +131 -0
- package/coverage/lcov-report/core/api/services/organisations/organisations.hooks.js.html +178 -0
- package/coverage/lcov-report/core/api/services/organisations/organisations.service.js.html +343 -0
- package/coverage/lcov-report/core/api/services/push/index.html +131 -0
- package/coverage/lcov-report/core/api/services/push/push.hooks.js.html +193 -0
- package/coverage/lcov-report/core/api/services/push/push.service.js.html +121 -0
- package/coverage/lcov-report/core/api/services/storage/index.html +131 -0
- package/coverage/lcov-report/core/api/services/storage/storage.hooks.js.html +190 -0
- package/coverage/lcov-report/core/api/services/storage/storage.service.js.html +172 -0
- package/coverage/lcov-report/core/api/services/tags/index.html +116 -0
- package/coverage/lcov-report/core/api/services/tags/tags.hooks.js.html +178 -0
- package/coverage/lcov-report/core/api/services/users/index.html +116 -0
- package/coverage/lcov-report/core/api/services/users/users.hooks.js.html +313 -0
- package/coverage/lcov-report/core/api/utils.js.html +118 -0
- package/coverage/lcov-report/core/common/errors.js.html +88 -0
- package/coverage/lcov-report/core/common/index.html +176 -0
- package/coverage/lcov-report/core/common/index.js.html +115 -0
- package/coverage/lcov-report/core/common/permissions.js.html +1039 -0
- package/coverage/lcov-report/core/common/schema.js.html +190 -0
- package/coverage/lcov-report/core/common/utils.js.html +220 -0
- package/coverage/lcov-report/favicon.png +0 -0
- package/coverage/lcov-report/index.html +476 -0
- package/coverage/lcov-report/map/api/hooks/hooks.catalog.js.html +340 -0
- package/coverage/lcov-report/map/api/hooks/hooks.features.js.html +337 -0
- package/coverage/lcov-report/map/api/hooks/hooks.query.js.html +1168 -0
- package/coverage/lcov-report/map/api/hooks/index.html +161 -0
- package/coverage/lcov-report/map/api/hooks/index.js.html +94 -0
- package/coverage/lcov-report/map/api/index.html +131 -0
- package/coverage/lcov-report/map/api/index.js.html +139 -0
- package/coverage/lcov-report/map/api/marshall.js.html +178 -0
- package/coverage/lcov-report/map/api/models/alerts.model.mongodb.js.html +106 -0
- package/coverage/lcov-report/map/api/models/catalog.model.mongodb.js.html +127 -0
- package/coverage/lcov-report/map/api/models/features.model.mongodb.js.html +196 -0
- package/coverage/lcov-report/map/api/models/index.html +146 -0
- package/coverage/lcov-report/map/api/services/alerts/alerts.hooks.js.html +274 -0
- package/coverage/lcov-report/map/api/services/alerts/alerts.service.js.html +610 -0
- package/coverage/lcov-report/map/api/services/alerts/index.html +131 -0
- package/coverage/lcov-report/map/api/services/catalog/catalog.hooks.js.html +313 -0
- package/coverage/lcov-report/map/api/services/catalog/index.html +116 -0
- package/coverage/lcov-report/map/api/services/daptiles/daptiles.service.js.html +1510 -0
- package/coverage/lcov-report/map/api/services/daptiles/index.html +116 -0
- package/coverage/lcov-report/map/api/services/features/features.hooks.js.html +205 -0
- package/coverage/lcov-report/map/api/services/features/features.service.js.html +241 -0
- package/coverage/lcov-report/map/api/services/features/index.html +131 -0
- package/coverage/lcov-report/map/api/services/geocoder/geocoder.hooks.js.html +178 -0
- package/coverage/lcov-report/map/api/services/geocoder/geocoder.service.js.html +322 -0
- package/coverage/lcov-report/map/api/services/geocoder/index.html +131 -0
- package/coverage/lcov-report/map/api/services/index.html +116 -0
- package/coverage/lcov-report/map/api/services/index.js.html +769 -0
- package/coverage/lcov-report/map/common/dynamic-grid-source.js.html +466 -0
- package/coverage/lcov-report/map/common/errors.js.html +94 -0
- package/coverage/lcov-report/map/common/geotiff-grid-source.js.html +535 -0
- package/coverage/lcov-report/map/common/grid.js.html +1612 -0
- package/coverage/lcov-report/map/common/index.html +371 -0
- package/coverage/lcov-report/map/common/index.js.html +172 -0
- package/coverage/lcov-report/map/common/meteo-model-grid-source.js.html +556 -0
- package/coverage/lcov-report/map/common/moment-utils.js.html +157 -0
- package/coverage/lcov-report/map/common/opendap-grid-source.js.html +868 -0
- package/coverage/lcov-report/map/common/opendap-utils.js.html +826 -0
- package/coverage/lcov-report/map/common/permissions.js.html +118 -0
- package/coverage/lcov-report/map/common/time-based-grid-source.js.html +418 -0
- package/coverage/lcov-report/map/common/tms-utils.js.html +274 -0
- package/coverage/lcov-report/map/common/wcs-grid-source.js.html +364 -0
- package/coverage/lcov-report/map/common/wcs-utils.js.html +586 -0
- package/coverage/lcov-report/map/common/weacast-grid-source.js.html +1033 -0
- package/coverage/lcov-report/map/common/wfs-utils.js.html +574 -0
- package/coverage/lcov-report/map/common/wms-utils.js.html +436 -0
- package/coverage/lcov-report/map/common/wmts-utils.js.html +547 -0
- package/coverage/lcov-report/prettify.css +1 -0
- package/coverage/lcov-report/prettify.js +2 -0
- package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
- package/coverage/lcov-report/sorter.js +196 -0
- package/coverage/lcov.info +10742 -0
- package/coverage/map/api/hooks/hooks.catalog.js.html +340 -0
- package/coverage/map/api/hooks/hooks.features.js.html +337 -0
- package/coverage/map/api/hooks/hooks.query.js.html +1168 -0
- package/coverage/map/api/hooks/index.html +161 -0
- package/coverage/map/api/hooks/index.js.html +94 -0
- package/coverage/map/api/index.html +131 -0
- package/coverage/map/api/index.js.html +139 -0
- package/coverage/map/api/marshall.js.html +178 -0
- package/coverage/map/api/models/alerts.model.mongodb.js.html +106 -0
- package/coverage/map/api/models/catalog.model.mongodb.js.html +127 -0
- package/coverage/map/api/models/features.model.mongodb.js.html +196 -0
- package/coverage/map/api/models/index.html +146 -0
- package/coverage/map/api/services/alerts/alerts.hooks.js.html +274 -0
- package/coverage/map/api/services/alerts/alerts.service.js.html +610 -0
- package/coverage/map/api/services/alerts/index.html +131 -0
- package/coverage/map/api/services/catalog/catalog.hooks.js.html +313 -0
- package/coverage/map/api/services/catalog/index.html +116 -0
- package/coverage/map/api/services/daptiles/daptiles.service.js.html +1510 -0
- package/coverage/map/api/services/daptiles/index.html +116 -0
- package/coverage/map/api/services/features/features.hooks.js.html +205 -0
- package/coverage/map/api/services/features/features.service.js.html +241 -0
- package/coverage/map/api/services/features/index.html +131 -0
- package/coverage/map/api/services/geocoder/geocoder.hooks.js.html +178 -0
- package/coverage/map/api/services/geocoder/geocoder.service.js.html +322 -0
- package/coverage/map/api/services/geocoder/index.html +131 -0
- package/coverage/map/api/services/index.html +116 -0
- package/coverage/map/api/services/index.js.html +769 -0
- package/coverage/map/common/dynamic-grid-source.js.html +466 -0
- package/coverage/map/common/errors.js.html +94 -0
- package/coverage/map/common/geotiff-grid-source.js.html +535 -0
- package/coverage/map/common/grid.js.html +1612 -0
- package/coverage/map/common/index.html +371 -0
- package/coverage/map/common/index.js.html +172 -0
- package/coverage/map/common/meteo-model-grid-source.js.html +556 -0
- package/coverage/map/common/moment-utils.js.html +157 -0
- package/coverage/map/common/opendap-grid-source.js.html +868 -0
- package/coverage/map/common/opendap-utils.js.html +826 -0
- package/coverage/map/common/permissions.js.html +118 -0
- package/coverage/map/common/time-based-grid-source.js.html +418 -0
- package/coverage/map/common/tms-utils.js.html +274 -0
- package/coverage/map/common/wcs-grid-source.js.html +364 -0
- package/coverage/map/common/wcs-utils.js.html +586 -0
- package/coverage/map/common/weacast-grid-source.js.html +1033 -0
- package/coverage/map/common/wfs-utils.js.html +574 -0
- package/coverage/map/common/wms-utils.js.html +436 -0
- package/coverage/map/common/wmts-utils.js.html +547 -0
- package/coverage/prettify.css +1 -0
- package/coverage/prettify.js +2 -0
- package/coverage/sort-arrow-sprite.png +0 -0
- package/coverage/sorter.js +196 -0
- package/coverage/tmp/coverage-59096-1692631696256-0.json +1 -0
- package/coverage/tmp/coverage-59108-1692631696233-0.json +1 -0
- package/coverage/tmp/coverage-59119-1692631696222-0.json +1 -0
- package/coverage/tmp/coverage-59131-1692631696200-0.json +1 -0
- package/coverage/tmp/coverage-59138-1692631696175-0.json +1 -0
- package/extras/css/core.variables.scss +5 -1
- package/extras/tours/core/account-profile.js +14 -31
- package/extras/tours/core/account.js +143 -0
- package/extras/tours/core/add-member.js +7 -6
- package/extras/tours/core/add-tag.js +13 -0
- package/extras/tours/core/create-tag.js +26 -0
- package/extras/tours/core/edit-member-role.js +13 -0
- package/extras/tours/core/join-group.js +0 -12
- package/extras/tours/core/login.js +0 -7
- package/extras/tours/core/members.js +13 -26
- package/extras/tours/core/send-reset-password.js +1 -1
- package/extras/tours/core/tags.js +17 -4
- package/extras/tours/map/navigation-bar.js +1 -1
- package/extras/tours/map/side-nav.js +3 -2
- package/map/api/config/categories.cjs +42 -0
- package/map/api/config/layers.cjs +43 -0
- package/map/api/config/sublegends.cjs +42 -0
- package/map/api/hooks/hooks.catalog.js +85 -0
- package/map/api/hooks/hooks.features.js +84 -0
- package/map/api/hooks/hooks.query.js +361 -0
- package/map/api/hooks/index.js +3 -0
- package/map/api/index.js +18 -0
- package/map/api/marshall.js +31 -0
- package/map/api/models/alerts.model.mongodb.js +7 -0
- package/map/api/models/catalog.model.mongodb.js +14 -0
- package/map/api/models/features.model.mongodb.js +37 -0
- package/map/api/services/alerts/alerts.hooks.js +63 -0
- package/map/api/services/alerts/alerts.service.js +175 -0
- package/map/api/services/catalog/catalog.hooks.js +76 -0
- package/map/api/services/daptiles/daptiles.service.js +475 -0
- package/map/api/services/features/features.hooks.js +40 -0
- package/map/api/services/features/features.service.js +52 -0
- package/map/api/services/geocoder/geocoder.hooks.js +31 -0
- package/map/api/services/geocoder/geocoder.service.js +79 -0
- package/map/api/services/index.js +228 -0
- package/map/client/canvas-draw-context.js +16 -0
- package/map/client/cesium/utils.js +132 -0
- package/map/client/components/KCaptureToolbar.vue +155 -0
- package/map/client/components/KColorLegend.vue +349 -0
- package/map/client/components/KCompass.vue +143 -0
- package/map/client/components/KEditLayerData.vue +85 -0
- package/map/client/components/KFeatureActionButton.vue +119 -0
- package/map/client/components/KFeatureEditor.vue +92 -0
- package/map/client/components/KFeaturesChart.vue +285 -0
- package/map/client/components/KFeaturesFilter.vue +259 -0
- package/map/client/components/KFeaturesTable.vue +99 -0
- package/map/client/components/KLayerEditionToolbar.vue +54 -0
- package/map/client/components/KLayerEditor.vue +48 -0
- package/map/client/components/KLayerStyleEditor.vue +118 -0
- package/map/client/components/KLayerStyleForm.vue +906 -0
- package/map/client/components/KLevelSlider.vue +100 -0
- package/map/client/components/KMeasureTool.vue +568 -0
- package/map/client/components/KPositionIndicator.vue +90 -0
- package/map/client/components/KTimeline.vue +293 -0
- package/map/client/components/KTimezoneMap.vue +158 -0
- package/map/client/components/KUrlLegend.vue +122 -0
- package/map/client/components/catalog/KAddLayer.vue +66 -0
- package/map/client/components/catalog/KBaseLayersSelector.vue +114 -0
- package/map/client/components/catalog/KConnectLayer.vue +323 -0
- package/map/client/components/catalog/KCreateLayer.vue +184 -0
- package/map/client/components/catalog/KCreateView.vue +108 -0
- package/map/client/components/catalog/KFilteredLayerItem.vue +53 -0
- package/map/client/components/catalog/KImportLayer.vue +168 -0
- package/map/client/components/catalog/KLayerCategories.vue +274 -0
- package/map/client/components/catalog/KLayerItem.vue +71 -0
- package/map/client/components/catalog/KLayersPanel.vue +137 -0
- package/map/client/components/catalog/KLayersSelector.vue +73 -0
- package/map/client/components/catalog/KViewSelector.vue +46 -0
- package/map/client/components/catalog/KViewsPanel.vue +118 -0
- package/map/client/components/catalog/KWeatherLayersSelector.vue +129 -0
- package/map/client/components/form/KDirectionField.vue +113 -0
- package/map/client/components/form/KLayerCategoryField.vue +46 -0
- package/map/client/components/form/KLocationField.vue +189 -0
- package/map/client/components/form/KOwsLayerField.vue +130 -0
- package/map/client/components/form/KOwsServiceField.vue +238 -0
- package/map/client/components/form/KTimezoneField.vue +142 -0
- package/map/client/components/index.js +1 -0
- package/map/client/components/legend/KColorScaleLegend.vue +31 -0
- package/map/client/components/legend/KImageLegend.vue +52 -0
- package/map/client/components/legend/KLegend.vue +191 -0
- package/map/client/components/legend/KLegendRenderer.vue +20 -0
- package/map/client/components/legend/KSymbolsLegend.vue +101 -0
- package/map/client/components/location/KGeocodersFilter.vue +44 -0
- package/map/client/components/location/KLocationCardSection.vue +61 -0
- package/map/client/components/location/KLocationMap.vue +280 -0
- package/map/client/components/location/KLocationSearch.vue +144 -0
- package/map/client/components/location/KLocationTip.vue +29 -0
- package/map/client/components/tools/KGeolocateTool.vue +46 -0
- package/map/client/components/tools/KSearchTool.vue +93 -0
- package/map/client/components/widget/KElevationProfile.vue +454 -0
- package/map/client/components/widget/KInformationBox.vue +145 -0
- package/map/client/components/widget/KMapillaryViewer.vue +178 -0
- package/map/client/components/widget/KStackableTimeSeries.vue +214 -0
- package/map/client/components/widget/KTimeSeries.vue +500 -0
- package/map/client/composables/activity.js +88 -0
- package/map/client/composables/highlight.js +216 -0
- package/map/client/composables/index.js +7 -0
- package/map/client/composables/location.js +53 -0
- package/map/client/composables/measure.js +42 -0
- package/map/client/composables/probe.js +133 -0
- package/map/client/composables/selection.js +300 -0
- package/map/client/composables/weather.js +213 -0
- package/map/client/elevation-utils.js +258 -0
- package/map/client/geolocation.js +119 -0
- package/map/client/globe.js +13 -0
- package/map/client/i18n/map_en.json +645 -0
- package/map/client/i18n/map_fr.json +646 -0
- package/map/client/index.js +18 -0
- package/map/client/init.js +80 -0
- package/map/client/leaflet/BoxSelection.js +142 -0
- package/map/client/leaflet/GSMaPLayer.js +55 -0
- package/map/client/leaflet/GradientPath.js +180 -0
- package/map/client/leaflet/MaskLayer.js +57 -0
- package/map/client/leaflet/TiledFeatureLayer.js +572 -0
- package/map/client/leaflet/TiledMeshLayer.js +486 -0
- package/map/client/leaflet/TiledWindLayer.js +384 -0
- package/map/client/leaflet/utils.js +246 -0
- package/map/client/map.js +15 -0
- package/map/client/mixins/globe/index.js +8 -0
- package/map/client/mixins/globe/mixin.base-globe.js +462 -0
- package/map/client/mixins/globe/mixin.file-layers.js +40 -0
- package/map/client/mixins/globe/mixin.geojson-layers.js +314 -0
- package/map/client/mixins/globe/mixin.globe-activity.js +52 -0
- package/map/client/mixins/globe/mixin.opendap-layers.js +51 -0
- package/map/client/mixins/globe/mixin.popup.js +82 -0
- package/map/client/mixins/globe/mixin.style.js +110 -0
- package/map/client/mixins/globe/mixin.tooltip.js +101 -0
- package/map/client/mixins/index.js +9 -0
- package/map/client/mixins/map/index.js +16 -0
- package/map/client/mixins/map/mixin.base-map.js +592 -0
- package/map/client/mixins/map/mixin.canvas-layers.js +529 -0
- package/map/client/mixins/map/mixin.edit-layers.js +474 -0
- package/map/client/mixins/map/mixin.file-layers.js +49 -0
- package/map/client/mixins/map/mixin.forecast-layers.js +79 -0
- package/map/client/mixins/map/mixin.geojson-layers.js +557 -0
- package/map/client/mixins/map/mixin.georaster-layers.js +114 -0
- package/map/client/mixins/map/mixin.gsmap-layers.js +27 -0
- package/map/client/mixins/map/mixin.heatmap-layers.js +116 -0
- package/map/client/mixins/map/mixin.map-activity.js +38 -0
- package/map/client/mixins/map/mixin.mapillary-layers.js +45 -0
- package/map/client/mixins/map/mixin.popup.js +53 -0
- package/map/client/mixins/map/mixin.style.js +73 -0
- package/map/client/mixins/map/mixin.tiled-mesh-layers.js +120 -0
- package/map/client/mixins/map/mixin.tiled-wind-layers.js +126 -0
- package/map/client/mixins/map/mixin.tooltip.js +47 -0
- package/map/client/mixins/mixin.activity.js +477 -0
- package/map/client/mixins/mixin.catalog-panel.js +25 -0
- package/map/client/mixins/mixin.context.js +252 -0
- package/map/client/mixins/mixin.feature-selection.js +28 -0
- package/map/client/mixins/mixin.feature-service.js +403 -0
- package/map/client/mixins/mixin.infobox.js +29 -0
- package/map/client/mixins/mixin.levels.js +66 -0
- package/map/client/mixins/mixin.style.js +29 -0
- package/map/client/mixins/mixin.weacast.js +212 -0
- package/map/client/pixi-utils.js +256 -0
- package/map/client/readers/index.js +4 -0
- package/map/client/readers/reader.geojson.js +64 -0
- package/map/client/readers/reader.gpx.js +36 -0
- package/map/client/readers/reader.kml.js +36 -0
- package/map/client/readers/reader.shp.js +82 -0
- package/map/client/utils/utils.location.js +45 -0
- package/map/client/utils.js +303 -0
- package/map/common/dynamic-grid-source.js +127 -0
- package/map/common/errors.js +3 -0
- package/map/common/geotiff-grid-source.js +150 -0
- package/map/common/grid.js +509 -0
- package/map/common/index.js +29 -0
- package/map/common/meteo-model-grid-source.js +157 -0
- package/map/common/moment-utils.js +24 -0
- package/map/common/opendap-grid-source.js +261 -0
- package/map/common/opendap-utils.js +247 -0
- package/map/common/permissions.js +11 -0
- package/map/common/schemas/catalog.update.json +28 -0
- package/map/common/time-based-grid-source.js +111 -0
- package/map/common/tms-utils.js +63 -0
- package/map/common/wcs-grid-source.js +93 -0
- package/map/common/wcs-utils.js +167 -0
- package/map/common/weacast-grid-source.js +316 -0
- package/map/common/wfs-utils.js +163 -0
- package/map/common/wms-utils.js +117 -0
- package/map/common/wmts-utils.js +154 -0
- package/package.json +18 -15
- package/test/api/core/account.test.js +452 -0
- package/test/api/core/client.test.js.skip +37 -0
- package/test/api/core/config/default.cjs +115 -0
- package/test/api/core/config/email-templates/confirmInvitation/html.ejs +18 -0
- package/test/api/core/config/email-templates/identityChange/html.ejs +14 -0
- package/test/api/core/config/email-templates/newDevice/html.ejs +7 -0
- package/test/api/core/config/email-templates/newSubscription/html.ejs +7 -0
- package/test/api/core/config/email-templates/passwordChange/html.ejs +5 -0
- package/test/api/core/config/email-templates/resendVerifySignup/html.ejs +12 -0
- package/test/api/core/config/email-templates/resetPwd/html.ejs +5 -0
- package/test/api/core/config/email-templates/sendResetPwd/html.ejs +12 -0
- package/test/api/core/config/email-templates/verifySignup/html.ejs +3 -0
- package/test/api/core/data/10k_most_common_passwords.txt +10000 -0
- package/test/api/core/data/invalid-objects.json +60 -0
- package/test/api/core/data/logo.png +0 -0
- package/test/api/core/data/schema.json +57 -0
- package/test/api/core/data/valid-objects.json +38 -0
- package/test/api/core/hooks.test.js +330 -0
- package/test/api/core/index.js +1 -0
- package/test/api/core/index.test.js +478 -0
- package/test/api/core/push.test.js +191 -0
- package/test/api/core/schemas.test.js +82 -0
- package/test/api/core/storage.test.js +153 -0
- package/test/api/core/team.test.js +670 -0
- package/test/api/core/test-log-2023-07-04.log +0 -0
- package/test/api/core/test-log-2023-07-10.log +2 -0
- package/test/api/core/test-log-2023-07-12.log +0 -0
- package/test/api/core/test-log-2023-07-18.log +78 -0
- package/test/api/core/test-log-2023-07-19.log +44 -0
- package/test/api/core/test-log-2023-08-01.log +162 -0
- package/test/api/core/test-log-2023-08-21.log +66 -0
- package/test/api/core/test-log-2023-08-22.log +96 -0
- package/test/api/core/test-log-2023-08-23.log +22 -0
- package/test/api/core/test-log-2023-09-20.log +22 -0
- package/test/api/core/utils.js +83 -0
- package/test/api/index.js +4 -0
- package/test/api/map/alerts.test.js +560 -0
- package/test/api/map/config/default.cjs +125 -0
- package/test/api/map/config/layers.json +38 -0
- package/test/api/map/data/DescribeCoverage.xml +55 -0
- package/test/api/map/data/GetCoverage.tif +0 -0
- package/test/api/map/data/adsb.observations.json +132 -0
- package/test/api/map/data/dataset.grb.das +55 -0
- package/test/api/map/data/dataset.grb.dds +17 -0
- package/test/api/map/data/dataset.grb.dods +0 -0
- package/test/api/map/data/lat_lon_bounds.grb.dods +0 -0
- package/test/api/map/data/subdataset.grb.dods +0 -0
- package/test/api/map/data/vigicrues.observations.json +47042 -0
- package/test/api/map/data/vigicrues.stations.json +15422 -0
- package/test/api/map/data/zones.json +1228 -0
- package/test/api/map/grid-sources.test.js +313 -0
- package/test/api/map/hooks.test.js +98 -0
- package/test/api/map/index.js +0 -0
- package/test/api/map/index.test.js +563 -0
- package/test/api/map/test-log-2023-07-18.log +62 -0
- package/test/api/map/test-log-2023-07-19.log +13 -0
- package/test/api/map/test-log-2023-08-21.log +65 -0
- package/test/api/map/test-log-2023-09-20.log +60 -0
- package/test/client/core/account.js +36 -0
- package/test/client/core/api.js +361 -0
- package/test/client/core/collection.js +64 -0
- package/test/client/core/index.js +8 -0
- package/test/client/core/layout.js +116 -0
- package/test/client/core/runner.js +224 -0
- package/test/client/core/screens.js +35 -0
- package/test/client/core/time.js +10 -0
- package/test/client/core/utils.js +260 -0
- package/test/client/index.js +4 -0
- package/test/client/map/catalog.js +175 -0
- package/test/client/map/controls.js +41 -0
- package/test/client/map/index.js +4 -0
- package/test/client/map/time.js +24 -0
- package/test/client/map/utils.js +27 -0
- package/extras/tours/core/account-dz.js +0 -37
- package/extras/tours/core/account-security.js +0 -52
- package/extras/tours/core/change-password.js +0 -34
- package/extras/tours/core/edit-member-tags.js +0 -18
- package/extras/tours/core/send-change-identity.js +0 -28
package/.codeclimate.yml
CHANGED
package/.travis.test.sh
CHANGED
|
@@ -20,6 +20,9 @@ git clone https://github.com/kalisio/kdk-workspaces workspace
|
|
|
20
20
|
git clone https://github.com/kalisio/feathers-distributed && cd feathers-distributed && yarn install && yarn link && cd ..
|
|
21
21
|
yarn link @kalisio/feathers-distributed
|
|
22
22
|
|
|
23
|
+
git clone https://github.com/kalisio/feathers-webpush && cd feathers-webpush && yarn install && yarn link && cd ..
|
|
24
|
+
yarn link @kalisio/feathers-webpush
|
|
25
|
+
|
|
23
26
|
git clone https://github.com/weacast/weacast && cd weacast && yarn install && cd packages
|
|
24
27
|
cd core && yarn link && cd .. && cd gfs && yarn link && cd .. && cd probe && yarn link && cd ..
|
|
25
28
|
cd ../..
|
|
@@ -0,0 +1,591 @@
|
|
|
1
|
+
import path from 'path'
|
|
2
|
+
import url from 'url'
|
|
3
|
+
import fs from 'fs-extra'
|
|
4
|
+
import makeDebug from 'debug'
|
|
5
|
+
import winston from 'winston'
|
|
6
|
+
import _ from 'lodash'
|
|
7
|
+
import siftModule from 'sift'
|
|
8
|
+
import 'winston-daily-rotate-file'
|
|
9
|
+
import compress from 'compression'
|
|
10
|
+
import cors from 'cors'
|
|
11
|
+
import helmet from 'helmet'
|
|
12
|
+
import { RateLimiter as SocketLimiter } from 'limiter'
|
|
13
|
+
import HttpLimiter from 'express-rate-limit'
|
|
14
|
+
import feathers from '@feathersjs/feathers'
|
|
15
|
+
import configuration from '@feathersjs/configuration'
|
|
16
|
+
import errors from '@feathersjs/errors'
|
|
17
|
+
import express, { authenticate } from '@feathersjs/express'
|
|
18
|
+
import socketio from '@feathersjs/socketio'
|
|
19
|
+
import mongodb from 'mongodb'
|
|
20
|
+
import { Database, idToString } from './db.js'
|
|
21
|
+
import auth from './authentication.js'
|
|
22
|
+
|
|
23
|
+
const debug = makeDebug('kdk:core:application')
|
|
24
|
+
const debugLimiter = makeDebug('kdk:core:application:limiter')
|
|
25
|
+
const { TooManyRequests, Forbidden, BadRequest } = errors
|
|
26
|
+
const { ObjectID } = mongodb
|
|
27
|
+
const { rest } = express
|
|
28
|
+
const sift = siftModule.default
|
|
29
|
+
|
|
30
|
+
// Initialize debugger to be used in feathers
|
|
31
|
+
feathers.setDebug(makeDebug)
|
|
32
|
+
|
|
33
|
+
function tooManyRequests (socket, message, key) {
|
|
34
|
+
debug(message)
|
|
35
|
+
const error = new TooManyRequests(message, { translation: { key } })
|
|
36
|
+
socket.emit('rate-limit', error)
|
|
37
|
+
// Add a timeout so that error message is correctly handled
|
|
38
|
+
setTimeout(() => socket.disconnect(true), 3000)
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export function declareService (name, app, service, serviceOptions = {}) {
|
|
42
|
+
let servicePath = serviceOptions.path || name
|
|
43
|
+
let contextId
|
|
44
|
+
if (serviceOptions.context) {
|
|
45
|
+
contextId = idToString(serviceOptions.context)
|
|
46
|
+
servicePath = contextId + '/' + servicePath
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
let feathersPath = app.get('apiPath') + '/' + servicePath
|
|
50
|
+
if (feathersPath.startsWith('/')) feathersPath = feathersPath.substr(1)
|
|
51
|
+
|
|
52
|
+
try {
|
|
53
|
+
const feathersService = app.service(feathersPath)
|
|
54
|
+
// Some internal Feathers service might internally declare the service
|
|
55
|
+
return feathersService
|
|
56
|
+
} catch (error) {
|
|
57
|
+
// Initialize our service by providing any middleware as well
|
|
58
|
+
let args = [feathersPath]
|
|
59
|
+
if (_.has(serviceOptions, 'middlewares.before')) args = args.concat(_.get(serviceOptions, 'middlewares.before'))
|
|
60
|
+
args.push(service)
|
|
61
|
+
const options = _.pick(serviceOptions, ['methods', 'events'])
|
|
62
|
+
if (!_.isEmpty(options)) args = args.concat(options)
|
|
63
|
+
if (_.has(serviceOptions, 'middlewares.after')) args = args.concat(_.get(serviceOptions, 'middlewares.after'))
|
|
64
|
+
app.use.apply(app, args)
|
|
65
|
+
// Get the Feathers service, ie base service + Feathers' internals
|
|
66
|
+
service = app.service(feathersPath)
|
|
67
|
+
debug('Service declared on path ' + feathersPath)
|
|
68
|
+
// Then configuration
|
|
69
|
+
service.name = name
|
|
70
|
+
service.app = app
|
|
71
|
+
if (!service.options) service.options = serviceOptions
|
|
72
|
+
else Object.assign(service.options, serviceOptions)
|
|
73
|
+
service.path = servicePath
|
|
74
|
+
service.context = serviceOptions.context
|
|
75
|
+
|
|
76
|
+
// Add some utility functions
|
|
77
|
+
service.getPath = function (withApiPrefix) {
|
|
78
|
+
let path = service.path
|
|
79
|
+
if (withApiPrefix && !path.startsWith(app.get('apiPath'))) {
|
|
80
|
+
path = app.get('apiPath') + '/' + path
|
|
81
|
+
}
|
|
82
|
+
return path
|
|
83
|
+
}
|
|
84
|
+
service.getContextId = function () {
|
|
85
|
+
return contextId // As string
|
|
86
|
+
}
|
|
87
|
+
return service
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export async function configureService (name, service, servicesPath) {
|
|
92
|
+
let filepath = path.join(servicesPath, name, `${name}.hooks.js`)
|
|
93
|
+
try {
|
|
94
|
+
const fileExists = await fs.pathExists(filepath)
|
|
95
|
+
if (fileExists) {
|
|
96
|
+
const hooks = (await import(url.pathToFileURL(filepath))).default
|
|
97
|
+
service.hooks(hooks)
|
|
98
|
+
debug(name + ' service hooks configured on path ' + servicesPath)
|
|
99
|
+
}
|
|
100
|
+
} catch (error) {
|
|
101
|
+
debug('No ' + name + ' service hooks configured on path ' + servicesPath)
|
|
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
|
+
// As this is optionnal this require has to fail silently
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
filepath = path.join(servicesPath, name, `${name}.channels.js`)
|
|
110
|
+
try {
|
|
111
|
+
const fileExists = await fs.pathExists(filepath)
|
|
112
|
+
if (fileExists) {
|
|
113
|
+
const channels = (await import(url.pathToFileURL(filepath))).default
|
|
114
|
+
_.forOwn(channels, (publisher, event) => {
|
|
115
|
+
if (event === 'all') service.publish(publisher)
|
|
116
|
+
else service.publish(event, publisher)
|
|
117
|
+
})
|
|
118
|
+
debug(name + ' service channels configured on path ' + servicesPath)
|
|
119
|
+
}
|
|
120
|
+
} catch (error) {
|
|
121
|
+
debug('No ' + name + ' service channels configured on path ' + servicesPath)
|
|
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
|
+
// As this is optionnal this require has to fail silently
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
return service
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
export function createProxyService (options) {
|
|
133
|
+
const targetService = options.service
|
|
134
|
+
function proxyParams (params) {
|
|
135
|
+
if (options.params) {
|
|
136
|
+
let proxiedParams
|
|
137
|
+
if (typeof options.params === 'function') {
|
|
138
|
+
proxiedParams = options.params(params)
|
|
139
|
+
} else {
|
|
140
|
+
proxiedParams = _.merge(params, options.params)
|
|
141
|
+
}
|
|
142
|
+
return proxiedParams
|
|
143
|
+
} else return params
|
|
144
|
+
}
|
|
145
|
+
function proxyId (id) {
|
|
146
|
+
if (options.id) return options.id(id)
|
|
147
|
+
else return id
|
|
148
|
+
}
|
|
149
|
+
function proxyData (data) {
|
|
150
|
+
if (options.data) return options.data(data)
|
|
151
|
+
else return data
|
|
152
|
+
}
|
|
153
|
+
function proxyResult (data) {
|
|
154
|
+
if (options.result) return options.result(data)
|
|
155
|
+
else return data
|
|
156
|
+
}
|
|
157
|
+
return {
|
|
158
|
+
async find (params) { return proxyResult(await targetService.find(proxyParams(params))) },
|
|
159
|
+
async get (id, params) { return proxyResult(await targetService.get(proxyId(id), proxyParams(params))) },
|
|
160
|
+
async create (data, params) { return proxyResult(await targetService.create(proxyData(data), proxyParams(params))) },
|
|
161
|
+
async update (id, data, params) { return proxyResult(await targetService.update(proxyId(id), proxyData(data), proxyParams(params))) },
|
|
162
|
+
async patch (id, data, params) { return proxyResult(await targetService.patch(proxyId(id), proxyData(data), proxyParams(params))) },
|
|
163
|
+
async remove (id, params) { return proxyResult(await targetService.remove(proxyId(id), proxyParams(params))) }
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
async function createService (name, app, options = {}) {
|
|
168
|
+
debug(`Creating service ${name}`)
|
|
169
|
+
const createFeathersService = (await import('feathers-' + app.db.adapter)).default
|
|
170
|
+
|
|
171
|
+
const paginate = app.get('paginate')
|
|
172
|
+
const serviceOptions = Object.assign({
|
|
173
|
+
name,
|
|
174
|
+
paginate,
|
|
175
|
+
multi: true,
|
|
176
|
+
whitelist: [
|
|
177
|
+
'$exists', '$and', '$or', '$eq', '$elemMatch', '$distinct', '$groupBy', '$group', '$regex',
|
|
178
|
+
'$text', '$search', '$caseSensitive', '$language', '$diacriticSensitive',
|
|
179
|
+
'$aggregate', '$near', '$nearSphere', '$geoIntersects', '$geoWithin',
|
|
180
|
+
'$maxDistance', '$minDistance', '$geometry', '$box', '$polygon', '$center', '$centerSphere'
|
|
181
|
+
]
|
|
182
|
+
}, options)
|
|
183
|
+
if (serviceOptions.disabled) return undefined
|
|
184
|
+
// For DB services a model has to be provided
|
|
185
|
+
const fileName = serviceOptions.fileName || name
|
|
186
|
+
|
|
187
|
+
let dbService = false
|
|
188
|
+
try {
|
|
189
|
+
if (serviceOptions.modelsPath) {
|
|
190
|
+
const filepath = path.join(serviceOptions.modelsPath, `${fileName}.model.${app.db.adapter}.js`)
|
|
191
|
+
const fileExists = await fs.pathExists(filepath)
|
|
192
|
+
if (fileExists) {
|
|
193
|
+
const configureModel = (await import(url.pathToFileURL(filepath))).default
|
|
194
|
+
configureModel(app, serviceOptions)
|
|
195
|
+
debug(name + ' service model configured on path ' + serviceOptions.modelsPath)
|
|
196
|
+
dbService = true
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
} catch (error) {
|
|
200
|
+
debug('No ' + fileName + ' service model configured on path ' + serviceOptions.modelsPath)
|
|
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
|
+
// As this is optionnal this require has to fail silently
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// Initialize our service with any options it requires
|
|
209
|
+
let service
|
|
210
|
+
if (dbService) {
|
|
211
|
+
service = createFeathersService(serviceOptions)
|
|
212
|
+
dbService = service
|
|
213
|
+
} else if (serviceOptions.proxy) {
|
|
214
|
+
service = createProxyService(serviceOptions.proxy)
|
|
215
|
+
} else {
|
|
216
|
+
const filepath = path.join(serviceOptions.servicesPath, fileName, `${fileName}.service.js`)
|
|
217
|
+
// Otherwise we expect the service to be provided as a Feathers service interface
|
|
218
|
+
service = (await import(url.pathToFileURL(filepath))).default
|
|
219
|
+
// If we get a function try to call it assuming it will return the service object
|
|
220
|
+
if (typeof service === 'function') {
|
|
221
|
+
service = service(name, app, serviceOptions)
|
|
222
|
+
}
|
|
223
|
+
// Need to set this manually for services not using class inheritance or default adapters
|
|
224
|
+
if (serviceOptions.events) service.events = serviceOptions.events
|
|
225
|
+
}
|
|
226
|
+
// Optionnally a specific service mixin can be provided, apply it
|
|
227
|
+
if (dbService && serviceOptions.servicesPath) {
|
|
228
|
+
const filepath = path.join(serviceOptions.servicesPath, fileName, `${fileName}.service.js`)
|
|
229
|
+
try {
|
|
230
|
+
const fileExists = await fs.pathExists(filepath)
|
|
231
|
+
if (fileExists) {
|
|
232
|
+
let serviceMixin = (await import(url.pathToFileURL(filepath))).default
|
|
233
|
+
// If we get a function try to call it assuming it will return the mixin object
|
|
234
|
+
if (typeof serviceMixin === 'function') {
|
|
235
|
+
serviceMixin = await serviceMixin.bind(dbService)(fileName, app, serviceOptions)
|
|
236
|
+
}
|
|
237
|
+
Object.assign(service, serviceMixin)
|
|
238
|
+
debug(name + ' service mixin configured on path ' + serviceOptions.servicesPath)
|
|
239
|
+
}
|
|
240
|
+
} catch (error) {
|
|
241
|
+
debug('No ' + fileName + ' service mixin configured on path ' + serviceOptions.servicesPath)
|
|
242
|
+
// if (error.code !== 'ERR_MODULE_NOT_FOUND') {
|
|
243
|
+
// Log error in this case as this might be linked to a syntax error in required file
|
|
244
|
+
debug(filepath, error)
|
|
245
|
+
// }
|
|
246
|
+
// As this is optionnal this require has to fail silently
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
service = declareService(name, app, service, serviceOptions)
|
|
251
|
+
// Register hooks and event filters
|
|
252
|
+
service = await configureService(fileName, service, serviceOptions.servicesPath)
|
|
253
|
+
|
|
254
|
+
debug(service.name + ' service registration completed')
|
|
255
|
+
app.emit('service', service)
|
|
256
|
+
|
|
257
|
+
return service
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
async function removeService (service, app) {
|
|
261
|
+
// Often called like removeService(getService('xxx'))
|
|
262
|
+
// so that we don't want to crash if the service does not exist or has already been unregistered
|
|
263
|
+
if (!service) return
|
|
264
|
+
let feathersPath = app.get('apiPath') + '/' + service.path
|
|
265
|
+
if (feathersPath.startsWith('/')) feathersPath = feathersPath.substr(1)
|
|
266
|
+
|
|
267
|
+
app.unuse(feathersPath)
|
|
268
|
+
debug(service.name + ' service unregistration completed')
|
|
269
|
+
app.emit('service-removed', service)
|
|
270
|
+
|
|
271
|
+
return service
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
export function createWebhook (path, app, options = {}) {
|
|
275
|
+
let webhookPath = path
|
|
276
|
+
if (options.context) {
|
|
277
|
+
webhookPath = idToString(options.context) + '/' + webhookPath
|
|
278
|
+
}
|
|
279
|
+
const isAllowed = (payload) => {
|
|
280
|
+
// Default is to expose all services/operations
|
|
281
|
+
if (!options.filter) return true
|
|
282
|
+
const result = [payload].filter(sift(options.filter))
|
|
283
|
+
return result.length > 0
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
app.post(app.get('apiPath') + '/webhooks/' + webhookPath, authenticate('jwt'), async (req, res, next) => {
|
|
287
|
+
const payload = req.body
|
|
288
|
+
const config = app.get('authentication')
|
|
289
|
+
res.set('content-type', 'application/json')
|
|
290
|
+
const params = {}
|
|
291
|
+
try {
|
|
292
|
+
if (options.preprocessor) {
|
|
293
|
+
await options.preprocessor(req, res, payload)
|
|
294
|
+
}
|
|
295
|
+
// Authenticate when required
|
|
296
|
+
if (config) {
|
|
297
|
+
params.user = _.get(req, 'feathers.user')
|
|
298
|
+
params.checkAuthorisation = true
|
|
299
|
+
}
|
|
300
|
+
if (req.headers['content-type'] !== 'application/json') {
|
|
301
|
+
throw new BadRequest('Webhooks expect application/json content type')
|
|
302
|
+
}
|
|
303
|
+
if (!isAllowed(payload)) throw new Forbidden('Service or operation not allowed for webhook')
|
|
304
|
+
const service = app.getService(payload.service, options.context || payload.context)
|
|
305
|
+
if (!service) throw new BadRequest('Service could not be found')
|
|
306
|
+
if (typeof service[payload.operation] !== 'function') throw new BadRequest('Service operation could not be found')
|
|
307
|
+
const args = []
|
|
308
|
+
// Get/Update/Patch/Remove
|
|
309
|
+
const operationsWithId = ['get', 'update', 'patch', 'remove']
|
|
310
|
+
if (operationsWithId.includes(payload.operation)) {
|
|
311
|
+
if (!_.has(payload, 'id')) throw new BadRequest('Missing id for operation')
|
|
312
|
+
args.push(_.get(payload, 'id'))
|
|
313
|
+
}
|
|
314
|
+
// Create/Update/Patch
|
|
315
|
+
const operationsWithData = ['create', 'update', 'patch']
|
|
316
|
+
if (operationsWithData.includes(payload.operation)) {
|
|
317
|
+
if (!_.has(payload, 'data')) throw new BadRequest('Missing data for operation')
|
|
318
|
+
args.push(_.get(payload, 'data'))
|
|
319
|
+
}
|
|
320
|
+
// Params
|
|
321
|
+
args.push(params)
|
|
322
|
+
if (options.postprocessor) {
|
|
323
|
+
await options.postprocessor(service, args, payload)
|
|
324
|
+
}
|
|
325
|
+
try {
|
|
326
|
+
debug(`Performing ${payload.service} service ${payload.operation} operation through webhook ${webhookPath} with args:`, args)
|
|
327
|
+
const result = await service[payload.operation].apply(service, args)
|
|
328
|
+
// Send back result
|
|
329
|
+
res.json(result)
|
|
330
|
+
} catch (error) {
|
|
331
|
+
throw new BadRequest('Service operation could not be performed')
|
|
332
|
+
}
|
|
333
|
+
} catch (error) {
|
|
334
|
+
debug(`Webhook ${webhookPath} error:`, error)
|
|
335
|
+
// Send back error
|
|
336
|
+
res.status(error.code || 500).json(error.toJSON())
|
|
337
|
+
}
|
|
338
|
+
})
|
|
339
|
+
|
|
340
|
+
debug(`Webhook ${webhookPath} registration completed`)
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
function setupLogger (app) {
|
|
344
|
+
debug('Setup application loggers')
|
|
345
|
+
const logsConfig = Object.assign({ // Default logger erased by provided one if any
|
|
346
|
+
Console: {
|
|
347
|
+
format: winston.format.combine(winston.format.colorize(), winston.format.simple())
|
|
348
|
+
}
|
|
349
|
+
}, _.omit(app.get('logs'), ['level', 'format']))
|
|
350
|
+
// Remove winston defaults
|
|
351
|
+
try {
|
|
352
|
+
winston.clear()
|
|
353
|
+
} catch (error) {
|
|
354
|
+
// Logger might be down, use console
|
|
355
|
+
console.error('Could not remove default logger transport(s)', error)
|
|
356
|
+
}
|
|
357
|
+
// We have one entry per log type
|
|
358
|
+
const logsTypes = Object.getOwnPropertyNames(logsConfig)
|
|
359
|
+
// Create corresponding winston transports with options
|
|
360
|
+
const transports = []
|
|
361
|
+
logsTypes.forEach(logType => {
|
|
362
|
+
const logOptions = logsConfig[logType]
|
|
363
|
+
debug(`Setup ${logType} transport with options`, logOptions)
|
|
364
|
+
try {
|
|
365
|
+
transports.push(new winston.transports[logType](logOptions))
|
|
366
|
+
} catch (error) {
|
|
367
|
+
// Logger might be down, use console
|
|
368
|
+
console.error(`Could not setup logger ${logType}`, error)
|
|
369
|
+
}
|
|
370
|
+
})
|
|
371
|
+
app.logger = winston.createLogger(Object.assign({
|
|
372
|
+
level: (process.env.NODE_ENV === 'development' ? 'debug' : 'info'), transports
|
|
373
|
+
}, _.pick(logsConfig, ['level', 'format'])))
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
function setupSockets (app) {
|
|
377
|
+
const apiLimiter = app.get('apiLimiter')
|
|
378
|
+
const connections = {}
|
|
379
|
+
let nbConnections = 0
|
|
380
|
+
|
|
381
|
+
return io => {
|
|
382
|
+
// By default EventEmitters will print a warning if more than 10 listeners are added for a particular event.
|
|
383
|
+
// The value can be set to Infinity (or 0) to indicate an unlimited number of listeners.
|
|
384
|
+
io.sockets.setMaxListeners(0)
|
|
385
|
+
const maxConnections = _.get(apiLimiter, 'websocket.maxConcurrency', 0)
|
|
386
|
+
const maxIpConnections = _.get(apiLimiter, 'websocket.concurrency', 0)
|
|
387
|
+
|
|
388
|
+
io.on('connection', socket => {
|
|
389
|
+
nbConnections++
|
|
390
|
+
debug(`New socket connection on server with pid ${process.pid}`, socket.id, socket.conn.remoteAddress, nbConnections)
|
|
391
|
+
// Setup disconnect handler first
|
|
392
|
+
socket.on('disconnect', (reason) => {
|
|
393
|
+
nbConnections--
|
|
394
|
+
debug(reason)
|
|
395
|
+
debug(`Socket disconnection on server with pid ${process.pid}`, socket.id, socket.conn.remoteAddress, nbConnections)
|
|
396
|
+
if (maxIpConnections > 0) {
|
|
397
|
+
const nbIpConnections = _.get(connections, socket.conn.remoteAddress) - 1
|
|
398
|
+
debug('Total number of connections for', socket.id, socket.conn.remoteAddress, nbIpConnections)
|
|
399
|
+
_.set(connections, socket.conn.remoteAddress, nbIpConnections)
|
|
400
|
+
}
|
|
401
|
+
})
|
|
402
|
+
if (maxConnections > 0) {
|
|
403
|
+
if (nbConnections > maxConnections) {
|
|
404
|
+
tooManyRequests(socket, 'Too many concurrent connections (rate limiting)', 'RATE_LIMITING_CONCURRENCY')
|
|
405
|
+
return
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
if (maxIpConnections > 0) {
|
|
409
|
+
if (_.has(connections, socket.conn.remoteAddress)) {
|
|
410
|
+
const nbIpConnections = _.get(connections, socket.conn.remoteAddress) + 1
|
|
411
|
+
debug('Total number of connections for', socket.id, socket.conn.remoteAddress, nbConnections)
|
|
412
|
+
_.set(connections, socket.conn.remoteAddress, nbIpConnections)
|
|
413
|
+
if (nbIpConnections > maxIpConnections) {
|
|
414
|
+
tooManyRequests(socket, 'Too many concurrent connections (rate limiting)', 'RATE_LIMITING_CONCURRENCY')
|
|
415
|
+
return
|
|
416
|
+
}
|
|
417
|
+
} else {
|
|
418
|
+
_.set(connections, socket.conn.remoteAddress, 1)
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
/* For debug purpose: trace all data received
|
|
422
|
+
socket.use((packet, next) => {
|
|
423
|
+
console.log(packet)
|
|
424
|
+
next()
|
|
425
|
+
})
|
|
426
|
+
*/
|
|
427
|
+
if (apiLimiter && apiLimiter.websocket) {
|
|
428
|
+
const { tokensPerInterval, interval } = apiLimiter.websocket
|
|
429
|
+
// Function used to filter whitelisted services, defaults to none
|
|
430
|
+
const services = _.get(apiLimiter.websocket, 'services', (service) => false)
|
|
431
|
+
socket.socketLimiter = new SocketLimiter(tokensPerInterval, interval)
|
|
432
|
+
socket.use((packet, next) => {
|
|
433
|
+
if (packet.length > 0) {
|
|
434
|
+
// Packets are formatted according to service interface,
|
|
435
|
+
// e.g. like [service_method, service_path, id or data, params]
|
|
436
|
+
// Bypass rate limiting on whitelist
|
|
437
|
+
if ((packet.length > 1) && (typeof packet[1] === 'string')) {
|
|
438
|
+
// Service path includes API prefix (but without trailing /)
|
|
439
|
+
// Get name from service path without api prefix
|
|
440
|
+
const serviceName = packet[1].replace(app.get('apiPath').substring(1) + '/', '')
|
|
441
|
+
const service = app.getService(serviceName)
|
|
442
|
+
if (service && services(service)) {
|
|
443
|
+
debugLimiter('By-pass rate limiting on whitelisted service operation', socket.id, socket.conn.remoteAddress, packet[0], packet[1])
|
|
444
|
+
next()
|
|
445
|
+
return
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
debugLimiter(socket.socketLimiter.getTokensRemaining() + ' remaining API token for socket', socket.id, socket.conn.remoteAddress)
|
|
449
|
+
if (!socket.socketLimiter.tryRemoveTokens(1)) { // if exceeded
|
|
450
|
+
tooManyRequests(socket, 'Too many requests in a given amount of time (rate limiting)', 'RATE_LIMITING')
|
|
451
|
+
// FIXME: calling this causes a client timeout
|
|
452
|
+
// next(error)
|
|
453
|
+
// Need to normalize the error object as JSON
|
|
454
|
+
// let result = {}
|
|
455
|
+
// Object.getOwnPropertyNames(error).forEach(key => (result[key] = error[key]))
|
|
456
|
+
// Trying to send error like in https://github.com/feathersjs/transport-commons/blob/auk/src/events.js#L103
|
|
457
|
+
// does not work either (also generates a client timeout)
|
|
458
|
+
// socket.emit(`${servicePath} error`, result)
|
|
459
|
+
// socket.emit(result)
|
|
460
|
+
return
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
next()
|
|
464
|
+
})
|
|
465
|
+
}
|
|
466
|
+
})
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
function setupHealthcheck (app) {
|
|
471
|
+
app.get('/healthcheck', async (req, res) => {
|
|
472
|
+
res.set('Content-Type', 'application/json')
|
|
473
|
+
const result = await app.db.healthcheck()
|
|
474
|
+
const status = (result ? 200 : 500)
|
|
475
|
+
return res.status(status).json({ isRunning: true, isDatabaseRunning: result })
|
|
476
|
+
})
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
export function kdk (config = {}) {
|
|
480
|
+
const app = express(feathers())
|
|
481
|
+
// By default EventEmitters will print a warning if more than 10 listeners are added for a particular event.
|
|
482
|
+
// The value can be set to Infinity (or 0) to indicate an unlimited number of listeners.
|
|
483
|
+
app.setMaxListeners(0)
|
|
484
|
+
// Load app configuration first
|
|
485
|
+
app.configure(configuration())
|
|
486
|
+
// Then setup logger, healthcheck, etc.
|
|
487
|
+
setupLogger(app)
|
|
488
|
+
setupHealthcheck(app)
|
|
489
|
+
|
|
490
|
+
// Override config
|
|
491
|
+
Object.keys(config).forEach((name) => {
|
|
492
|
+
const value = config[name]
|
|
493
|
+
debug(`Setting ${name} configuration value to`, value)
|
|
494
|
+
app.set(name, value)
|
|
495
|
+
})
|
|
496
|
+
|
|
497
|
+
// This retrieve corresponding service options from app config if any
|
|
498
|
+
app.getServiceOptions = function (name) {
|
|
499
|
+
const services = app.get('services')
|
|
500
|
+
if (!services) return {}
|
|
501
|
+
return _.get(services, name, {})
|
|
502
|
+
}
|
|
503
|
+
// This avoid managing the API path before each service name
|
|
504
|
+
app.getService = function (path, context) {
|
|
505
|
+
try {
|
|
506
|
+
// Context is given as string ID
|
|
507
|
+
if (context && typeof context === 'string') {
|
|
508
|
+
return app.service(app.get('apiPath') + '/' + context + '/' + path)
|
|
509
|
+
} else if (context && typeof context === 'object') {
|
|
510
|
+
// Could be Object ID or raw object
|
|
511
|
+
if (ObjectID.isValid(context)) return app.service(app.get('apiPath') + '/' + context.toString() + '/' + path)
|
|
512
|
+
else return app.service(app.get('apiPath') + '/' + context._id.toString() + '/' + path)
|
|
513
|
+
} else {
|
|
514
|
+
return app.service(app.get('apiPath') + '/' + path)
|
|
515
|
+
}
|
|
516
|
+
} catch {
|
|
517
|
+
// We return a false-y value in case the service wasn't found
|
|
518
|
+
return null
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
// This is used to add hooks/filters to services
|
|
522
|
+
app.configureService = async function (name, service, servicesPath) {
|
|
523
|
+
service = await configureService(name, service, servicesPath)
|
|
524
|
+
return service
|
|
525
|
+
}
|
|
526
|
+
// This is used to create standard services
|
|
527
|
+
app.createService = async function (name, options) {
|
|
528
|
+
const service = await createService(name, app, options)
|
|
529
|
+
return service
|
|
530
|
+
}
|
|
531
|
+
// This is used to remove standard services
|
|
532
|
+
app.removeService = async function (service) {
|
|
533
|
+
service = await removeService(service, app)
|
|
534
|
+
return service
|
|
535
|
+
}
|
|
536
|
+
// This is used to create webhooks
|
|
537
|
+
app.createWebhook = function (path, options) {
|
|
538
|
+
return createWebhook(path, app, options)
|
|
539
|
+
}
|
|
540
|
+
// Override Feathers configure that do not manage async operations,
|
|
541
|
+
// here we also simply call the function given as parameter but await for it
|
|
542
|
+
app.configure = async function (fn) {
|
|
543
|
+
await fn.call(this, this)
|
|
544
|
+
return this
|
|
545
|
+
}
|
|
546
|
+
const apiLimiter = app.get('apiLimiter')
|
|
547
|
+
if (apiLimiter && apiLimiter.http) {
|
|
548
|
+
// Function used to filter whitelisted services, defaults to none
|
|
549
|
+
const services = _.get(apiLimiter.http, 'services', (service) => false)
|
|
550
|
+
const handler = (req, res, next) => {
|
|
551
|
+
// Bypass rate limiting on whitelist
|
|
552
|
+
let service
|
|
553
|
+
try {
|
|
554
|
+
const serviceUrl = new url.URL(req.originalUrl)
|
|
555
|
+
service = app.service(serviceUrl.pathname)
|
|
556
|
+
} catch (error) {
|
|
557
|
+
debugLimiter(error)
|
|
558
|
+
}
|
|
559
|
+
if (service && services(service)) {
|
|
560
|
+
debugLimiter('By-pass rate limiting on whitelisted service operation', req.method, path)
|
|
561
|
+
next()
|
|
562
|
+
} else {
|
|
563
|
+
const error = new TooManyRequests('Too many requests in a given amount of time (rate limiting)',
|
|
564
|
+
{ translation: { key: 'RATE_LIMITING' } })
|
|
565
|
+
res.status(error.code)
|
|
566
|
+
res.set('Content-Type', 'application/json')
|
|
567
|
+
res.json(Object.assign({}, error.toJSON()))
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
app.use(app.get('apiPath') || '/', new HttpLimiter(Object.assign({ handler }, apiLimiter.http)))
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
// Enable CORS, security, compression, and body parsing
|
|
574
|
+
app.use(cors(app.get('cors')))
|
|
575
|
+
app.use(helmet(app.get('helmet')))
|
|
576
|
+
app.use(compress(app.get('compression')))
|
|
577
|
+
const bodyParserConfig = app.get('bodyParser')
|
|
578
|
+
app.use(express.json(_.get(bodyParserConfig, 'json')))
|
|
579
|
+
app.use(express.urlencoded(Object.assign({ extended: true }, _.get(bodyParserConfig, 'urlencoded'))))
|
|
580
|
+
|
|
581
|
+
// Set up plugins and providers
|
|
582
|
+
app.configure(rest())
|
|
583
|
+
const socketioConfig = app.get('socketio') || {}
|
|
584
|
+
app.configure(socketio(Object.assign({ path: (app.get('apiPath') || '/') + 'ws' }, socketioConfig), setupSockets(app)))
|
|
585
|
+
app.configure(auth)
|
|
586
|
+
|
|
587
|
+
// Initialize DB
|
|
588
|
+
app.db = Database.create(app)
|
|
589
|
+
|
|
590
|
+
return app
|
|
591
|
+
}
|