@kalisio/kdk 1.6.0 → 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.travis.test.sh +1 -1
- package/CHANGELOG.md +63 -13
- package/extras/tours/map/catalog-panel.js +61 -10
- package/extras/tours/map/create-view.js +25 -0
- package/extras/tours/map/fab.js +10 -1
- package/extras/tours/map/navigation-bar.js +7 -9
- package/lib/core/api/application.js +9 -1
- package/lib/core/api/application.js.map +1 -1
- package/lib/core/client/components/chart/KChart.vue +115 -0
- package/lib/core/client/components/chart/KStatsChart.vue +76 -0
- package/lib/core/client/components/chart/index.js +20 -0
- package/lib/core/client/components/chart/index.js.map +1 -0
- package/lib/core/client/components/collection/KFilter.vue +6 -0
- package/lib/core/client/components/collection/KHistoryEntry.vue +1 -1
- package/lib/core/client/components/collection/KItem.vue +4 -4
- package/lib/core/client/components/form/KChipsField.vue +4 -4
- package/lib/core/client/components/form/KView.vue +1 -1
- package/lib/core/client/components/frame/KAction.vue +40 -5
- package/lib/core/client/components/frame/KBlock.vue +7 -7
- package/lib/core/client/components/frame/KContent.vue +1 -1
- package/lib/core/client/components/frame/KOpener.vue +1 -1
- package/lib/core/client/components/frame/KPanel.vue +8 -7
- package/lib/core/client/components/frame/KPopupAction.vue +6 -0
- package/lib/core/client/components/frame/KScreen.vue +1 -1
- package/lib/core/client/components/frame/KStamp.vue +4 -2
- package/lib/core/client/components/frame/index.js +1 -6
- package/lib/core/client/components/frame/index.js.map +1 -1
- package/lib/core/client/components/input/KIconChooser.vue +5 -2
- package/lib/core/client/components/input/KPalette.vue +1 -1
- package/lib/core/client/components/input/index.js +14 -4
- package/lib/core/client/components/input/index.js.map +1 -1
- package/lib/core/client/components/layout/KFab.vue +1 -1
- package/lib/core/client/components/layout/KLayout.vue +10 -2
- package/lib/core/client/components/layout/KPage.vue +19 -18
- package/lib/core/client/components/layout/KTour.vue +5 -3
- package/lib/core/client/components/layout/KWindow.vue +211 -59
- package/lib/core/client/components/media/KMediaBrowser.vue +6 -6
- package/lib/core/client/components/menu/KMenu.vue +13 -5
- package/lib/core/client/components/menu/KRadialFab.vue +22 -24
- package/lib/core/client/components/menu/KRadialFabItem.vue +17 -18
- package/lib/core/client/components/team/KGroupsActivity.vue +1 -1
- package/lib/core/client/components/team/KJoinGroup.vue +2 -2
- package/lib/core/client/components/time/KAbsoluteTimeRange.vue +190 -0
- package/lib/core/client/components/time/KRelativeTimeRanges.vue +192 -0
- package/lib/core/client/components/time/index.js +20 -0
- package/lib/core/client/components/time/index.js.map +1 -0
- package/lib/core/client/i18n/core_en.json +35 -12
- package/lib/core/client/i18n/core_fr.json +36 -13
- package/lib/core/client/index.js +1 -1
- package/lib/core/client/index.js.map +1 -1
- package/lib/core/client/mixins/mixin.base-collection.js +11 -1
- package/lib/core/client/mixins/mixin.base-collection.js.map +1 -1
- package/lib/core/client/mixins/mixin.base-widget.js +25 -13
- package/lib/core/client/mixins/mixin.base-widget.js.map +1 -1
- package/lib/core/client/services/index.js +2 -1
- package/lib/core/client/services/index.js.map +1 -1
- package/lib/core/client/services/local-settings.service.js +4 -0
- package/lib/core/client/services/local-settings.service.js.map +1 -1
- package/lib/core/client/time.js +25 -15
- package/lib/core/client/time.js.map +1 -1
- package/lib/core/client/units.js +12 -0
- package/lib/core/client/units.js.map +1 -1
- package/lib/core/client/utils.js +11 -0
- package/lib/core/client/utils.js.map +1 -1
- package/lib/core/common/schemas/settings.update.json +14 -4
- package/lib/map/api/hooks/hooks.catalog.js +20 -0
- package/lib/map/api/hooks/hooks.catalog.js.map +1 -1
- package/lib/map/api/models/catalog.model.mongodb.js +6 -1
- package/lib/map/api/models/catalog.model.mongodb.js.map +1 -1
- package/lib/map/api/models/features.model.mongodb.js +5 -0
- package/lib/map/api/models/features.model.mongodb.js.map +1 -1
- package/lib/map/api/services/catalog/catalog.hooks.js +3 -1
- package/lib/map/api/services/catalog/catalog.hooks.js.map +1 -1
- package/lib/map/client/components/KColorLegend.vue +22 -21
- package/lib/map/client/components/KFeaturesChart.vue +81 -110
- package/lib/map/client/components/KLayerStyleForm.vue +119 -47
- package/lib/map/client/components/KLevelSlider.vue +30 -29
- package/lib/map/client/components/KLocationMap.vue +2 -2
- package/lib/map/client/components/KMeasureTool.vue +30 -6
- package/lib/map/client/components/KPositionIndicator.vue +4 -4
- package/lib/map/client/components/KTimeline.vue +25 -27
- package/lib/map/client/components/KTimezoneMap.vue +156 -0
- package/lib/map/client/components/KUrlLegend.vue +11 -10
- package/lib/map/client/components/catalog/KBaseLayersSelector.vue +1 -1
- package/lib/map/client/components/catalog/KCatalogLayersPanel.vue +56 -0
- package/lib/map/client/components/catalog/KCreateView.vue +91 -0
- package/lib/map/client/components/catalog/KLayerCategories.vue +2 -1
- package/lib/map/client/components/catalog/{KCatalog.vue → KLayersPanel.vue} +19 -37
- package/lib/map/client/components/catalog/KUserLayersPanel.vue +40 -0
- package/lib/map/client/components/catalog/KViewSelector.vue +46 -0
- package/lib/map/client/components/catalog/KViewsPanel.vue +110 -0
- package/lib/map/client/components/catalog/KWeatherLayersSelector.vue +4 -13
- package/lib/map/client/components/form/KTimezoneField.vue +135 -0
- package/lib/map/client/components/widget/KElevationProfile.vue +488 -0
- package/lib/map/client/components/widget/KInformationBox.vue +48 -23
- package/lib/map/client/components/widget/KMapillaryViewer.vue +26 -20
- package/lib/map/client/components/widget/KTimeSeries.vue +267 -347
- package/lib/map/client/i18n/map_en.json +63 -40
- package/lib/map/client/i18n/map_fr.json +65 -42
- package/lib/map/client/leaflet/GradientPath.js +40 -19
- package/lib/map/client/leaflet/GradientPath.js.map +1 -1
- package/lib/map/client/leaflet/TiledFeatureLayer.js +527 -93
- package/lib/map/client/leaflet/TiledFeatureLayer.js.map +1 -1
- package/lib/map/client/leaflet/TiledMeshLayer.js +58 -35
- package/lib/map/client/leaflet/TiledMeshLayer.js.map +1 -1
- package/lib/map/client/leaflet/utils.js +44 -3
- package/lib/map/client/leaflet/utils.js.map +1 -1
- package/lib/map/client/mixins/globe/mixin.base-globe.js +16 -1
- package/lib/map/client/mixins/globe/mixin.base-globe.js.map +1 -1
- package/lib/map/client/mixins/globe/mixin.file-layers.js +12 -2
- package/lib/map/client/mixins/globe/mixin.file-layers.js.map +1 -1
- package/lib/map/client/mixins/globe/mixin.geojson-layers.js +7 -6
- package/lib/map/client/mixins/globe/mixin.geojson-layers.js.map +1 -1
- package/lib/map/client/mixins/globe/mixin.popup.js +4 -2
- package/lib/map/client/mixins/globe/mixin.popup.js.map +1 -1
- package/lib/map/client/mixins/globe/mixin.style.js +8 -4
- package/lib/map/client/mixins/globe/mixin.style.js.map +1 -1
- package/lib/map/client/mixins/globe/mixin.tooltip.js +4 -2
- package/lib/map/client/mixins/globe/mixin.tooltip.js.map +1 -1
- package/lib/map/client/mixins/index.js +23 -18
- package/lib/map/client/mixins/index.js.map +1 -1
- package/lib/map/client/mixins/map/mixin.base-map.js +20 -2
- package/lib/map/client/mixins/map/mixin.base-map.js.map +1 -1
- package/lib/map/client/mixins/map/mixin.edit-layers.js +8 -4
- package/lib/map/client/mixins/map/mixin.edit-layers.js.map +1 -1
- package/lib/map/client/mixins/map/mixin.geojson-layers.js +27 -5
- package/lib/map/client/mixins/map/mixin.geojson-layers.js.map +1 -1
- package/lib/map/client/mixins/map/mixin.heatmap-layers.js +6 -1
- package/lib/map/client/mixins/map/mixin.heatmap-layers.js.map +1 -1
- package/lib/map/client/mixins/map/mixin.popup.js +1 -1
- package/lib/map/client/mixins/map/mixin.popup.js.map +1 -1
- package/lib/map/client/mixins/map/mixin.style.js +8 -4
- package/lib/map/client/mixins/map/mixin.style.js.map +1 -1
- package/lib/map/client/mixins/map/mixin.tiled-mesh-layers.js +4 -11
- package/lib/map/client/mixins/map/mixin.tiled-mesh-layers.js.map +1 -1
- package/lib/map/client/mixins/map/mixin.tiled-wind-layers.js +0 -11
- package/lib/map/client/mixins/map/mixin.tiled-wind-layers.js.map +1 -1
- package/lib/map/client/mixins/map/mixin.tooltip.js +1 -1
- package/lib/map/client/mixins/map/mixin.tooltip.js.map +1 -1
- package/lib/map/client/mixins/mixin.activity.js +150 -150
- package/lib/map/client/mixins/mixin.activity.js.map +1 -1
- package/lib/map/client/mixins/mixin.catalog-panel.js +36 -0
- package/lib/map/client/mixins/mixin.catalog-panel.js.map +1 -0
- package/lib/map/client/mixins/mixin.feature-selection.js +17 -8
- package/lib/map/client/mixins/mixin.feature-selection.js.map +1 -1
- package/lib/map/client/mixins/mixin.feature-service.js +36 -16
- package/lib/map/client/mixins/mixin.feature-service.js.map +1 -1
- package/lib/map/client/mixins/mixin.infobox.js +1 -1
- package/lib/map/client/mixins/mixin.infobox.js.map +1 -1
- package/lib/map/client/mixins/mixin.levels.js +26 -12
- package/lib/map/client/mixins/mixin.levels.js.map +1 -1
- package/lib/map/client/mixins/mixin.style.js +1 -0
- package/lib/map/client/mixins/mixin.style.js.map +1 -1
- package/lib/map/client/mixins/mixin.weacast.js +15 -23
- package/lib/map/client/mixins/mixin.weacast.js.map +1 -1
- package/lib/map/client/pixi-utils.js +8 -177
- package/lib/map/client/pixi-utils.js.map +1 -1
- package/lib/map/client/utils.js +1 -0
- package/lib/map/client/utils.js.map +1 -1
- package/lib/map/common/grid.js +131 -0
- package/lib/map/common/grid.js.map +1 -1
- package/lib/map/common/index.js +22 -11
- package/lib/map/common/index.js.map +1 -1
- package/lib/map/common/meteo-model-grid-source.js +5 -2
- package/lib/map/common/meteo-model-grid-source.js.map +1 -1
- package/lib/map/common/time-based-grid-source.js +5 -2
- package/lib/map/common/time-based-grid-source.js.map +1 -1
- package/lib/test/client/core/collection.js +31 -13
- package/lib/test/client/core/collection.js.map +1 -1
- package/lib/test/client/core/layout.js +137 -49
- package/lib/test/client/core/layout.js.map +1 -1
- package/lib/test/client/core/utils.js +89 -22
- package/lib/test/client/core/utils.js.map +1 -1
- package/lib/test/client/map/catalog.js +134 -41
- package/lib/test/client/map/catalog.js.map +1 -1
- package/lib/test/client/map/controls.js +7 -4
- package/lib/test/client/map/controls.js.map +1 -1
- package/lib/test/client/map/index.js +12 -0
- package/lib/test/client/map/index.js.map +1 -1
- package/lib/test/client/map/utils.js +67 -0
- package/lib/test/client/map/utils.js.map +1 -0
- package/package.json +5 -5
- package/extras/tours/map/favorite-views.js +0 -53
- package/lib/core/client/components/frame/KChart.vue +0 -60
- package/lib/core/client/components/input/KCodeInput.vue +0 -50
- package/lib/core/client/components/input/KTimeRangeChooser.vue +0 -109
- package/lib/core/client/components/time/KTimeRange.vue +0 -144
- package/lib/map/client/components/KFavoriteViews.vue +0 -217
package/.travis.test.sh
CHANGED
|
@@ -12,7 +12,7 @@ check_code()
|
|
|
12
12
|
echo -e "machine github.com\n login $GITHUB_TOKEN" > ~/.netrc
|
|
13
13
|
git clone https://github.com/kalisio/kdk-workspaces workspace
|
|
14
14
|
|
|
15
|
-
git clone https://github.com/kalisio/feathers-distributed && cd feathers-distributed && yarn install && yarn link && cd ..
|
|
15
|
+
git clone -b v1.0.5 https://github.com/kalisio/feathers-distributed && cd feathers-distributed && yarn install && yarn link && cd ..
|
|
16
16
|
yarn link @kalisio/feathers-distributed
|
|
17
17
|
|
|
18
18
|
git clone https://github.com/weacast/weacast-core && cd weacast-core && yarn install && yarn link && cd ..
|
package/CHANGELOG.md
CHANGED
|
@@ -1,13 +1,65 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [v1.6.0](https://github.com/kalisio/kdk/tree/v1.6.0) (2022-02-23)
|
|
4
|
+
|
|
5
|
+
[Full Changelog](https://github.com/kalisio/kdk/compare/v1.5.1...v1.6.0)
|
|
6
|
+
|
|
7
|
+
**Implemented enhancements:**
|
|
8
|
+
|
|
9
|
+
- Organisation managers should be able to manage all groups [\#548](https://github.com/kalisio/kdk/issues/548)
|
|
10
|
+
- Make timeline update interval configurable [\#543](https://github.com/kalisio/kdk/issues/543)
|
|
11
|
+
- Units management system [\#542](https://github.com/kalisio/kdk/issues/542)
|
|
12
|
+
- Allow to define TTL for service collection [\#539](https://github.com/kalisio/kdk/issues/539)
|
|
13
|
+
- Add shapefile support [\#538](https://github.com/kalisio/kdk/issues/538)
|
|
14
|
+
- Enhance timeseries widget to manage multiple forecasts [\#490](https://github.com/kalisio/kdk/issues/490)
|
|
15
|
+
|
|
16
|
+
**Fixed bugs:**
|
|
17
|
+
|
|
18
|
+
- filter is not refreshed when the focus is lost [\#551](https://github.com/kalisio/kdk/issues/551)
|
|
19
|
+
- Realtime layers with update interval not correctly updated when time changes [\#540](https://github.com/kalisio/kdk/issues/540)
|
|
20
|
+
- FeatureId generation does not handle any types of GeoJson [\#536](https://github.com/kalisio/kdk/issues/536)
|
|
21
|
+
|
|
22
|
+
**Closed issues:**
|
|
23
|
+
|
|
24
|
+
- Improve webhook with bearer token and processing functions [\#523](https://github.com/kalisio/kdk/issues/523)
|
|
25
|
+
|
|
26
|
+
**Merged pull requests:**
|
|
27
|
+
|
|
28
|
+
- chore\(deps\): bump follow-redirects from 1.14.7 to 1.14.8 in /docs [\#549](https://github.com/kalisio/kdk/pull/549) ([dependabot[bot]](https://github.com/apps/dependabot))
|
|
29
|
+
- chore\(deps\): bump ajv from 6.11.0 to 6.12.6 in /docs [\#547](https://github.com/kalisio/kdk/pull/547) ([dependabot[bot]](https://github.com/apps/dependabot))
|
|
30
|
+
- chore\(deps\): bump pathval from 1.1.0 to 1.1.1 [\#546](https://github.com/kalisio/kdk/pull/546) ([dependabot[bot]](https://github.com/apps/dependabot))
|
|
31
|
+
- chore\(deps\): bump node-fetch from 2.6.1 to 2.6.7 [\#537](https://github.com/kalisio/kdk/pull/537) ([dependabot[bot]](https://github.com/apps/dependabot))
|
|
32
|
+
- chore\(deps\): bump shelljs from 0.8.3 to 0.8.5 [\#517](https://github.com/kalisio/kdk/pull/517) ([dependabot[bot]](https://github.com/apps/dependabot))
|
|
33
|
+
- chore\(deps\): bump follow-redirects from 1.11.0 to 1.14.7 in /docs [\#514](https://github.com/kalisio/kdk/pull/514) ([dependabot[bot]](https://github.com/apps/dependabot))
|
|
34
|
+
|
|
3
35
|
## [v1.5.1](https://github.com/kalisio/kdk/tree/v1.5.1) (2022-01-27)
|
|
4
36
|
|
|
5
37
|
[Full Changelog](https://github.com/kalisio/kdk/compare/v1.5.0...v1.5.1)
|
|
6
38
|
|
|
39
|
+
**Implemented enhancements:**
|
|
40
|
+
|
|
41
|
+
- Provide a common ScrollArea component [\#526](https://github.com/kalisio/kdk/issues/526)
|
|
42
|
+
- Display a spinner when reading file [\#525](https://github.com/kalisio/kdk/issues/525)
|
|
43
|
+
- Allow to open the url of a text field [\#519](https://github.com/kalisio/kdk/issues/519)
|
|
44
|
+
- Allow authorisations to be set by name [\#516](https://github.com/kalisio/kdk/issues/516)
|
|
45
|
+
- Unify min/max zoom on tiled and non-tiled layers [\#249](https://github.com/kalisio/kdk/issues/249)
|
|
46
|
+
|
|
7
47
|
**Fixed bugs:**
|
|
8
48
|
|
|
9
|
-
-
|
|
49
|
+
- dropFileInput element is not removed when switching to another activity [\#535](https://github.com/kalisio/kdk/issues/535)
|
|
50
|
+
- Missing default background layer when capturing the screen [\#534](https://github.com/kalisio/kdk/issues/534)
|
|
51
|
+
- The computed url to access the Kapture service is incorrect [\#532](https://github.com/kalisio/kdk/issues/532)
|
|
52
|
+
- Impossible to remove min/max zoom levels once edited in the style [\#531](https://github.com/kalisio/kdk/issues/531)
|
|
53
|
+
- min/max zoom level does not work on internal feature layers [\#529](https://github.com/kalisio/kdk/issues/529)
|
|
54
|
+
- Authorise hook does not throw a forbidden error on find/patch/update/remove multiple items [\#528](https://github.com/kalisio/kdk/issues/528)
|
|
10
55
|
- Unable to install latest geoman version \(2.11.4\) [\#521](https://github.com/kalisio/kdk/issues/521)
|
|
56
|
+
- Mapillary widget is not resized when switching to fullscreen [\#520](https://github.com/kalisio/kdk/issues/520)
|
|
57
|
+
- Geojson import is failing if the linter found an old-style crs [\#518](https://github.com/kalisio/kdk/issues/518)
|
|
58
|
+
- Scale-dependent visibility can't be reset + spelling mistake [\#398](https://github.com/kalisio/kdk/issues/398)
|
|
59
|
+
|
|
60
|
+
**Closed issues:**
|
|
61
|
+
|
|
62
|
+
- Improve webhook with bearer token and processing functions [\#524](https://github.com/kalisio/kdk/issues/524)
|
|
11
63
|
|
|
12
64
|
## [v1.5.0](https://github.com/kalisio/kdk/tree/v1.5.0) (2022-01-07)
|
|
13
65
|
|
|
@@ -17,6 +69,7 @@
|
|
|
17
69
|
|
|
18
70
|
- The capture action should take into account the current activity \(map or globe\) [\#507](https://github.com/kalisio/kdk/issues/507)
|
|
19
71
|
- Handle the current time within the map context [\#503](https://github.com/kalisio/kdk/issues/503)
|
|
72
|
+
- Features filter should sort the list of values alphabetically to ease selection [\#405](https://github.com/kalisio/kdk/issues/405)
|
|
20
73
|
- Provide measurements capabilities [\#359](https://github.com/kalisio/kdk/issues/359)
|
|
21
74
|
|
|
22
75
|
**Fixed bugs:**
|
|
@@ -29,6 +82,7 @@
|
|
|
29
82
|
- Editing layer style : Marker color selector won't preselect the current color [\#502](https://github.com/kalisio/kdk/issues/502)
|
|
30
83
|
- Edit layer style : Adding space in Tooltip between text and drop menu [\#501](https://github.com/kalisio/kdk/issues/501)
|
|
31
84
|
- None of Popup, Tooltip and Information box display option working in style editor [\#499](https://github.com/kalisio/kdk/issues/499)
|
|
85
|
+
- Station properties lost when a measure is available [\#510](https://github.com/kalisio/kdk/issues/510)
|
|
32
86
|
|
|
33
87
|
**Merged pull requests:**
|
|
34
88
|
|
|
@@ -73,7 +127,7 @@
|
|
|
73
127
|
- Time range query should take into account a given field [\#479](https://github.com/kalisio/kdk/issues/479)
|
|
74
128
|
- Time range query is not initialized in Time.js [\#478](https://github.com/kalisio/kdk/issues/478)
|
|
75
129
|
- Saved user settings are erased by default values [\#477](https://github.com/kalisio/kdk/issues/477)
|
|
76
|
-
-
|
|
130
|
+
- PDF files cannot be selected in KUploader on a mobile application [\#101](https://github.com/kalisio/kdk/issues/101)
|
|
77
131
|
- OAuth2 does not work in mobile apps [\#85](https://github.com/kalisio/kdk/issues/85)
|
|
78
132
|
|
|
79
133
|
## [v1.4.0](https://github.com/kalisio/kdk/tree/v1.4.0) (2021-10-22)
|
|
@@ -100,7 +154,7 @@
|
|
|
100
154
|
- Close or cancel modal actions should be rendered using a form button [\#427](https://github.com/kalisio/kdk/issues/427)
|
|
101
155
|
- Support GetTile requests for WMTS layers [\#423](https://github.com/kalisio/kdk/issues/423)
|
|
102
156
|
- Homogenize team cards [\#417](https://github.com/kalisio/kdk/issues/417)
|
|
103
|
-
-
|
|
157
|
+
- Enhance time management [\#410](https://github.com/kalisio/kdk/issues/410)
|
|
104
158
|
- Use geoman instead of leaflet-draw in edit layer mixin [\#378](https://github.com/kalisio/kdk/issues/378)
|
|
105
159
|
- Mapillary v3 API has been retired, update mapillary widget/layer to use v4 API [\#300](https://github.com/kalisio/kdk/issues/300)
|
|
106
160
|
- Provide a kanban component [\#296](https://github.com/kalisio/kdk/issues/296)
|
|
@@ -152,18 +206,16 @@
|
|
|
152
206
|
**Implemented enhancements:**
|
|
153
207
|
|
|
154
208
|
- Provide helper function to check view/edit/remove ability on an item [\#422](https://github.com/kalisio/kdk/issues/422)
|
|
209
|
+
- Allow to define a path to the value in KChipsPane [\#416](https://github.com/kalisio/kdk/issues/416)
|
|
155
210
|
- Allow to filter a schema according a list of fields when building a form [\#415](https://github.com/kalisio/kdk/issues/415)
|
|
156
211
|
- Card rendering should support a dense mode [\#414](https://github.com/kalisio/kdk/issues/414)
|
|
157
212
|
- Make possible to use a template string for storage service name in uploader [\#413](https://github.com/kalisio/kdk/issues/413)
|
|
158
213
|
- Refactor KHistory to rely on KColumn [\#412](https://github.com/kalisio/kdk/issues/412)
|
|
159
214
|
- Provide a generic time range component [\#411](https://github.com/kalisio/kdk/issues/411)
|
|
160
|
-
- Enhance time management [\#410](https://github.com/kalisio/kdk/issues/410)
|
|
161
|
-
- Features filter should sort the list of values alphabetically to ease selection [\#405](https://github.com/kalisio/kdk/issues/405)
|
|
162
215
|
- Provide a way to observe the page content size [\#400](https://github.com/kalisio/kdk/issues/400)
|
|
163
216
|
- Make location field more user-friendly [\#399](https://github.com/kalisio/kdk/issues/399)
|
|
164
217
|
- Enhance the location field/map to manage any geometry type [\#397](https://github.com/kalisio/kdk/issues/397)
|
|
165
218
|
- Add ability to emit click events from canvas layer. [\#388](https://github.com/kalisio/kdk/issues/388)
|
|
166
|
-
- Enhance KMenu rendering with a dropdown icon [\#386](https://github.com/kalisio/kdk/issues/386)
|
|
167
219
|
- Provide a basic chart container [\#362](https://github.com/kalisio/kdk/issues/362)
|
|
168
220
|
- Provide a generic setttings component [\#317](https://github.com/kalisio/kdk/issues/317)
|
|
169
221
|
- Allow in-memory GeoJson be passed on GeoJson layer addition [\#94](https://github.com/kalisio/kdk/issues/94)
|
|
@@ -178,6 +230,7 @@
|
|
|
178
230
|
- List of values is incomplete when editing the features filter [\#404](https://github.com/kalisio/kdk/issues/404)
|
|
179
231
|
- FR version : data export generates .cvs instead of .csv [\#403](https://github.com/kalisio/kdk/issues/403)
|
|
180
232
|
- HistoryEntry card is not correclty aligned on the left side [\#401](https://github.com/kalisio/kdk/issues/401)
|
|
233
|
+
- Exclusive option not taken into account in user-defined categories [\#395](https://github.com/kalisio/kdk/issues/395)
|
|
181
234
|
|
|
182
235
|
## [v1.3.4](https://github.com/kalisio/kdk/tree/v1.3.4) (2021-06-08)
|
|
183
236
|
|
|
@@ -186,6 +239,7 @@
|
|
|
186
239
|
**Implemented enhancements:**
|
|
187
240
|
|
|
188
241
|
- Allow KChipsField to be used without icon edition [\#390](https://github.com/kalisio/kdk/issues/390)
|
|
242
|
+
- Enhance KMenu rendering with a dropdown icon [\#386](https://github.com/kalisio/kdk/issues/386)
|
|
189
243
|
- Allow to specify a schema name to an editor [\#381](https://github.com/kalisio/kdk/issues/381)
|
|
190
244
|
- Collections empty section should not be defined using an absolute position [\#377](https://github.com/kalisio/kdk/issues/377)
|
|
191
245
|
- Allow location map to be embedded in a card [\#373](https://github.com/kalisio/kdk/issues/373)
|
|
@@ -198,7 +252,6 @@
|
|
|
198
252
|
|
|
199
253
|
**Fixed bugs:**
|
|
200
254
|
|
|
201
|
-
- Exclusive option not taken into account in user-defined categories [\#395](https://github.com/kalisio/kdk/issues/395)
|
|
202
255
|
- Editing toast appear when removing a layer [\#394](https://github.com/kalisio/kdk/issues/394)
|
|
203
256
|
- KChangeRole no longer handle multiple resources [\#389](https://github.com/kalisio/kdk/issues/389)
|
|
204
257
|
- Select field must be clearable [\#387](https://github.com/kalisio/kdk/issues/387)
|
|
@@ -374,11 +427,13 @@
|
|
|
374
427
|
- Improve layer selector display [\#178](https://github.com/kalisio/kdk/issues/178)
|
|
375
428
|
- Allow to display an icon within a badge assigned to an action of KToolBar [\#176](https://github.com/kalisio/kdk/issues/176)
|
|
376
429
|
- Check unique hook should raise a specific error message [\#175](https://github.com/kalisio/kdk/issues/175)
|
|
430
|
+
- Provide a code input component [\#169](https://github.com/kalisio/kdk/issues/169)
|
|
377
431
|
- Tiled mesh/wind layers should support min zoom level [\#160](https://github.com/kalisio/kdk/issues/160)
|
|
378
432
|
- Zoom to layer action does not work on tiled layers in map [\#123](https://github.com/kalisio/kdk/issues/123)
|
|
379
433
|
- iOS build should rely on iOS SDK 13 [\#67](https://github.com/kalisio/kdk/issues/67)
|
|
380
434
|
- History component should provide infinite scroll [\#90](https://github.com/kalisio/kdk/issues/90)
|
|
381
435
|
- UIWebView API deprecation notice [\#47](https://github.com/kalisio/kdk/issues/47)
|
|
436
|
+
- Upgrade Mongo DB driver to v3 [\#44](https://github.com/kalisio/kdk/issues/44)
|
|
382
437
|
- Allow to directly take a picture when uploading a file [\#99](https://github.com/kalisio/kdk/issues/99)
|
|
383
438
|
- Extend pusher protocols for SMS/Emails [\#91](https://github.com/kalisio/kdk/issues/91)
|
|
384
439
|
|
|
@@ -441,10 +496,6 @@
|
|
|
441
496
|
|
|
442
497
|
[Full Changelog](https://github.com/kalisio/kdk/compare/v1.1.0...v1.1.1)
|
|
443
498
|
|
|
444
|
-
**Implemented enhancements:**
|
|
445
|
-
|
|
446
|
-
- Provide a code input component [\#169](https://github.com/kalisio/kdk/issues/169)
|
|
447
|
-
|
|
448
499
|
## [v1.1.0](https://github.com/kalisio/kdk/tree/v1.1.0) (2020-05-28)
|
|
449
500
|
|
|
450
501
|
[Full Changelog](https://github.com/kalisio/kdk/compare/v1.0.0...v1.1.0)
|
|
@@ -485,7 +536,6 @@
|
|
|
485
536
|
- Improve application webhook security [\#84](https://github.com/kalisio/kdk/issues/84)
|
|
486
537
|
- Upgrade to latest Node.js LTS [\#48](https://github.com/kalisio/kdk/issues/48)
|
|
487
538
|
- Allow to filter feature layers [\#89](https://github.com/kalisio/kdk/issues/89)
|
|
488
|
-
- Upgrade Mongo DB driver to v3 [\#44](https://github.com/kalisio/kdk/issues/44)
|
|
489
539
|
- Enhance e2e tests across the modules/apps [\#38](https://github.com/kalisio/kdk/issues/38)
|
|
490
540
|
- Optimize measure update for time-stamped features in globe [\#96](https://github.com/kalisio/kdk/issues/96)
|
|
491
541
|
- Create a component to provide styling options for feature layers in map [\#110](https://github.com/kalisio/kdk/issues/110)
|
|
@@ -512,12 +562,12 @@
|
|
|
512
562
|
- Error raised on clustered tile layers [\#140](https://github.com/kalisio/kdk/issues/140)
|
|
513
563
|
- Timeseries do not update correctly when changing time [\#139](https://github.com/kalisio/kdk/issues/139)
|
|
514
564
|
- Timeseries widget not synchronized when disabling/removing a layer [\#135](https://github.com/kalisio/kdk/issues/135)
|
|
565
|
+
- Mapillary viewer not synchronized correctly with coverage layer [\#133](https://github.com/kalisio/kdk/issues/133)
|
|
515
566
|
- Openers shoud be displayed only a component is assgined to the drawers or footer [\#131](https://github.com/kalisio/kdk/issues/131)
|
|
516
567
|
- min zoom level not correctly handled in tiled map layers [\#126](https://github.com/kalisio/kdk/issues/126)
|
|
517
568
|
- If a geocoder does not respond the geocoder service does not respond [\#125](https://github.com/kalisio/kdk/issues/125)
|
|
518
569
|
- Weacast grid source is missing some data when requesting a tile [\#77](https://github.com/kalisio/kdk/issues/77)
|
|
519
570
|
- KFab should be instanciated within a QPage [\#69](https://github.com/kalisio/kdk/issues/69)
|
|
520
|
-
- PDF files cannot be selected in KUploader on a mobile application [\#101](https://github.com/kalisio/kdk/issues/101)
|
|
521
571
|
|
|
522
572
|
**Closed issues:**
|
|
523
573
|
|
|
@@ -1,10 +1,70 @@
|
|
|
1
1
|
module.exports = [{
|
|
2
|
-
target: '#
|
|
2
|
+
target: '#catalog-tabbar',
|
|
3
3
|
title: 'tours.catalog-panel.CATALOG_LABEL',
|
|
4
|
+
params: {
|
|
5
|
+
placement: 'top'
|
|
6
|
+
}
|
|
7
|
+
}, {
|
|
8
|
+
target: '#user-layers-tab',
|
|
9
|
+
title: 'tours.catalog-panel.USER_LAYERS_LABEL',
|
|
4
10
|
content: 'tours.catalog-panel.CATEGORIES_LABEL',
|
|
5
11
|
params: {
|
|
6
12
|
placement: 'top'
|
|
7
13
|
}
|
|
14
|
+
}, {
|
|
15
|
+
target: '#manage-layer-categories',
|
|
16
|
+
title: 'tours.catalog-panel.MANAGE_LAYER_CATEGORIES_LABEL',
|
|
17
|
+
link: 'tours.catalog-panel.MANAGE_LAYER_CATEGORIES_LINK_LABEL',
|
|
18
|
+
params: {
|
|
19
|
+
placement: 'left',
|
|
20
|
+
clickOnLink: '#manage-layer-categories',
|
|
21
|
+
clickOnNext: '#user-views-tab',
|
|
22
|
+
nextDelay: 500
|
|
23
|
+
}
|
|
24
|
+
}, {
|
|
25
|
+
target: '#user-views-tab',
|
|
26
|
+
title: 'tours.catalog-panel.USER_VIEWS_LABEL',
|
|
27
|
+
link: 'tours.catalog-panel.USER_VIEWS_CREATE_LABEL',
|
|
28
|
+
params: {
|
|
29
|
+
placement: 'top',
|
|
30
|
+
hoverClickOnLink: 'div.q-fab__icon-holder',
|
|
31
|
+
tour: 'fab'
|
|
32
|
+
}
|
|
33
|
+
}, {
|
|
34
|
+
target: '#user-views-filter',
|
|
35
|
+
title: 'tours.catalog-panel.USER_VIEWS_FILTER_LABEL',
|
|
36
|
+
params: {
|
|
37
|
+
placement: 'top'
|
|
38
|
+
}
|
|
39
|
+
}, {
|
|
40
|
+
target: '#user-views-sorter',
|
|
41
|
+
title: 'tours.catalog-panel.USER_VIEWS_SORTER_LABEL',
|
|
42
|
+
params: {
|
|
43
|
+
placement: 'top',
|
|
44
|
+
blockOnMiss: 'div [component="catalog/KViewSelector"]'
|
|
45
|
+
}
|
|
46
|
+
}, {
|
|
47
|
+
target: 'div [component="catalog/KViewSelector"]',
|
|
48
|
+
title: 'tours.catalog-panel.USER_VIEWS_VIEW_LABEL',
|
|
49
|
+
params: {
|
|
50
|
+
placement: 'bottom'
|
|
51
|
+
}
|
|
52
|
+
}, {
|
|
53
|
+
target: 'div [component="catalog/KViewSelector"] #set-home-view',
|
|
54
|
+
title: 'tours.catalog-panel.USER_VIEWS_SET_HOME_VIEW_LABEL',
|
|
55
|
+
params: {
|
|
56
|
+
placement: 'bottom',
|
|
57
|
+
clickOnNext: 'div [component="catalog/KViewSelector"] #view-overflowmenu',
|
|
58
|
+
nextDelay: 500
|
|
59
|
+
}
|
|
60
|
+
}, {
|
|
61
|
+
target: '#remove-view',
|
|
62
|
+
title: 'tours.catalog-panel.USER_VIEWS_REMOVE_VIEW_LABEL',
|
|
63
|
+
params: {
|
|
64
|
+
placement: 'bottom',
|
|
65
|
+
clickOnNext: '#catalog-layers-tab',
|
|
66
|
+
nextDelay: 500
|
|
67
|
+
}
|
|
8
68
|
}, {
|
|
9
69
|
target: '#k-catalog-panel-base-layers',
|
|
10
70
|
title: 'tours.catalog-panel.CATEGORY_LABEL',
|
|
@@ -50,13 +110,4 @@ module.exports = [{
|
|
|
50
110
|
params: {
|
|
51
111
|
placement: 'top'
|
|
52
112
|
}
|
|
53
|
-
}, {
|
|
54
|
-
target: '#manage-layer-categories',
|
|
55
|
-
title: 'tours.catalog-panel.MANAGE_LAYER_CATEGORIES_LABEL',
|
|
56
|
-
link: 'tours.catalog-panel.MANAGE_LAYER_CATEGORIES_LINK_LABEL',
|
|
57
|
-
params: {
|
|
58
|
-
placement: 'left',
|
|
59
|
-
clickOnLink: '#manage-layer-categories',
|
|
60
|
-
nextDelay: 500
|
|
61
|
-
}
|
|
62
113
|
}]
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
module.exports = [{
|
|
2
|
+
target: '#name-field',
|
|
3
|
+
content: 'tours.create-view.NAME_FIELD_LABEL',
|
|
4
|
+
params: {
|
|
5
|
+
placement: 'bottom'
|
|
6
|
+
}
|
|
7
|
+
}, {
|
|
8
|
+
target: '#description-field',
|
|
9
|
+
content: 'tours.create-view.DESCRIPTION_FIELD_LABEL',
|
|
10
|
+
params: {
|
|
11
|
+
placement: 'bottom'
|
|
12
|
+
}
|
|
13
|
+
}, {
|
|
14
|
+
target: '#layers-field',
|
|
15
|
+
content: 'tours.create-view.LAYERS_FIELD_LABEL',
|
|
16
|
+
params: {
|
|
17
|
+
placement: 'bottom'
|
|
18
|
+
}
|
|
19
|
+
}, {
|
|
20
|
+
target: '#apply-button',
|
|
21
|
+
title: 'tours.create-view.APPLY_BUTTON_LABEL',
|
|
22
|
+
params: {
|
|
23
|
+
placement: 'bottom'
|
|
24
|
+
}
|
|
25
|
+
}]
|
package/extras/tours/map/fab.js
CHANGED
|
@@ -12,6 +12,15 @@ module.exports = [{
|
|
|
12
12
|
params: {
|
|
13
13
|
placement: 'left',
|
|
14
14
|
clickOnLink: '#add-layer',
|
|
15
|
-
|
|
15
|
+
tour: 'add-layer',
|
|
16
|
+
}
|
|
17
|
+
}, {
|
|
18
|
+
target: '#create-view',
|
|
19
|
+
title: 'tours.fab.CREATE_VIEW_LABEL',
|
|
20
|
+
link: 'tours.fab.CREATE_VIEW_LINK_LABEL',
|
|
21
|
+
params: {
|
|
22
|
+
placement: 'left',
|
|
23
|
+
clickOnLink: '#create-view',
|
|
24
|
+
tour: 'create-view',
|
|
16
25
|
}
|
|
17
26
|
}]
|
|
@@ -55,15 +55,6 @@ module.exports = [{
|
|
|
55
55
|
clickOnNext: '#back',
|
|
56
56
|
nextDelay: 500
|
|
57
57
|
}
|
|
58
|
-
}, {
|
|
59
|
-
target: '#manage-favorite-views',
|
|
60
|
-
title: 'tours.navigation-bar.FAVORITE_VIEWS_LABEL',
|
|
61
|
-
link: 'tours.navigation-bar.FAVORITE_VIEWS_LINK_LABEL',
|
|
62
|
-
params: {
|
|
63
|
-
placement: 'bottom',
|
|
64
|
-
clickOnLink: '#manage-favorite-views',
|
|
65
|
-
tour: 'favorite-views'
|
|
66
|
-
}
|
|
67
58
|
}, {
|
|
68
59
|
target: '#tools',
|
|
69
60
|
title: 'tours.navigation-bar.TOOLS_LABEL',
|
|
@@ -136,6 +127,13 @@ module.exports = [{
|
|
|
136
127
|
params: {
|
|
137
128
|
placement: 'bottom'
|
|
138
129
|
}
|
|
130
|
+
}, {
|
|
131
|
+
target: '#measure-feature',
|
|
132
|
+
title: 'tours.navigation-bar.MEASURE_FEATURE_LABEL',
|
|
133
|
+
content: 'tours.navigation-bar.MEASURE_FEATURE_DETAILS_LABEL',
|
|
134
|
+
params: {
|
|
135
|
+
placement: 'bottom'
|
|
136
|
+
}
|
|
139
137
|
}, {
|
|
140
138
|
target: '#clear-measurements',
|
|
141
139
|
title: 'tours.navigation-bar.CLEAR_MEASURE_LABEL',
|
|
@@ -520,6 +520,13 @@ function setupSockets(app) {
|
|
|
520
520
|
};
|
|
521
521
|
}
|
|
522
522
|
|
|
523
|
+
function setupHealthcheck(app) {
|
|
524
|
+
app.get('/healthcheck', (req, res) => {
|
|
525
|
+
res.set('Content-Type', 'application/json');
|
|
526
|
+
return res.status(200).json({ isRunning: true });
|
|
527
|
+
});
|
|
528
|
+
}
|
|
529
|
+
|
|
523
530
|
function kalisio() {
|
|
524
531
|
const app = (0, _express2.default)((0, _feathers2.default)());
|
|
525
532
|
// By default EventEmitters will print a warning if more than 10 listeners are added for a particular event.
|
|
@@ -527,8 +534,9 @@ function kalisio() {
|
|
|
527
534
|
app.setMaxListeners(0);
|
|
528
535
|
// Load app configuration first
|
|
529
536
|
app.configure((0, _configuration2.default)());
|
|
530
|
-
// Then setup logger
|
|
537
|
+
// Then setup logger, healthcheck, etc.
|
|
531
538
|
setupLogger(app);
|
|
539
|
+
setupHealthcheck(app);
|
|
532
540
|
|
|
533
541
|
// This retrieve corresponding service options from app config if any
|
|
534
542
|
app.getServiceOptions = function (name) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../core/api/application.js"],"names":["declareService","configureService","createProxyService","createService","createWebhook","kalisio","debug","debugLimiter","tooManyRequests","socket","message","key","error","TooManyRequests","translation","emit","setTimeout","disconnect","path","app","service","middlewares","feathersPath","get","feathersService","args","before","concat","push","after","use","apply","name","servicesPath","hooks","require","join","code","channels","_","forOwn","publisher","event","publish","options","targetService","proxyParams","params","proxiedParams","merge","proxyId","id","proxyData","data","proxyResult","result","find","create","update","patch","remove","createFeathersService","db","adapter","paginate","serviceOptions","Object","assign","disabled","undefined","fileName","dbService","modelsPath","configureModel","proxy","events","servicePath","contextId","context","serviceMixin","bind","mixin","getPath","withApiPrefix","getContextId","webhookPath","isAllowed","payload","filter","length","post","req","res","next","body","config","set","preprocessor","header","headers","authorization","accessToken","tokens","match","tokenPayload","passport","verifyJWT","user","getService","userId","checkAuthorisation","Forbidden","BadRequest","operation","operationsWithId","includes","has","operationsWithData","postprocessor","json","status","toJSON","setupLogger","logsConfig","logger","clear","console","logsTypes","getOwnPropertyNames","forEach","logType","level","process","env","NODE_ENV","add","transports","setupSockets","apiLimiter","connections","nbConnections","io","sockets","setMaxListeners","maxConnections","maxIpConnections","on","pid","conn","remoteAddress","reason","nbIpConnections","websocket","tokensPerInterval","interval","services","socketLimiter","SocketLimiter","packet","getTokensRemaining","tryRemoveTokens","configure","getServiceOptions","ObjectID","isValid","toString","_id","fn","call","http","handler","serviceUrl","url","URL","originalUrl","pathname","method","HttpLimiter","bodyParserConfig","bodyParser","urlencoded","extended","socketioConfig","auth","Database"],"mappings":"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","file":"application.js","sourcesContent":["import path from 'path'\r\nimport url from 'url'\r\nimport makeDebug from 'debug'\r\nimport logger from 'winston'\r\nimport _ from 'lodash'\r\nimport sift from 'sift'\r\nimport 'winston-daily-rotate-file'\r\nimport compress from 'compression'\r\nimport cors from 'cors'\r\nimport helmet from 'helmet'\r\nimport bodyParser from 'body-parser'\r\nimport { RateLimiter as SocketLimiter } from 'limiter'\r\nimport HttpLimiter from 'express-rate-limit'\r\nimport feathers from '@feathersjs/feathers'\r\nimport configuration from '@feathersjs/configuration'\r\nimport { TooManyRequests, Forbidden, BadRequest } from '@feathersjs/errors'\r\nimport express from '@feathersjs/express'\r\nimport rest from '@feathersjs/express/rest'\r\nimport socketio from '@feathersjs/socketio'\r\nimport { ObjectID } from 'mongodb'\r\nimport { Database, idToString } from './db'\r\nimport auth, { authSocket } from './authentication'\r\n\r\nconst debug = makeDebug('kdk:core:application')\r\nconst debugLimiter = makeDebug('kdk:core:application:limiter')\r\n\r\nfunction tooManyRequests (socket, message, key) {\r\n debug(message)\r\n const error = new TooManyRequests(message, { translation: { key } })\r\n socket.emit('rate-limit', error)\r\n // Add a timeout so that error message is correctly handled\r\n setTimeout(() => socket.disconnect(true), 3000)\r\n}\r\n\r\nexport function declareService (path, app, service, middlewares = {}) {\r\n const feathersPath = app.get('apiPath') + '/' + path\r\n const feathersService = app.service(feathersPath)\r\n // Some internal Feathers service might internally declare the service\r\n if (feathersService) {\r\n return feathersService\r\n }\r\n // Initialize our service by providing any middleware as well\r\n let args = [feathersPath]\r\n if (middlewares.before) args = args.concat(middlewares.before)\r\n args.push(service)\r\n if (middlewares.after) args = args.concat(middlewares.after)\r\n app.use.apply(app, args)\r\n debug('Service declared on path ' + feathersPath)\r\n // Return the Feathers service, ie base service + Feathers' internals\r\n return app.service(feathersPath)\r\n}\r\n\r\nexport function configureService (name, service, servicesPath) {\r\n try {\r\n const hooks = require(path.join(servicesPath, name, name + '.hooks'))\r\n service.hooks(hooks)\r\n debug(name + ' service hooks configured on path ' + servicesPath)\r\n } catch (error) {\r\n debug('No ' + name + ' service hooks configured on path ' + servicesPath)\r\n if (error.code !== 'MODULE_NOT_FOUND') {\r\n // Log error in this case as this might be linked to a syntax error in required file\r\n debug(error)\r\n }\r\n // As this is optionnal this require has to fail silently\r\n }\r\n\r\n try {\r\n const channels = require(path.join(servicesPath, name, name + '.channels'))\r\n _.forOwn(channels, (publisher, event) => {\r\n if (event === 'all') service.publish(publisher)\r\n else service.publish(event, publisher)\r\n })\r\n debug(name + ' service channels configured on path ' + servicesPath)\r\n } catch (error) {\r\n debug('No ' + name + ' service channels configured on path ' + servicesPath)\r\n if (error.code !== 'MODULE_NOT_FOUND') {\r\n // Log error in this case as this might be linked to a syntax error in required file\r\n debug(error)\r\n }\r\n // As this is optionnal this require has to fail silently\r\n }\r\n\r\n return service\r\n}\r\n\r\nexport function createProxyService (options) {\r\n const targetService = options.service\r\n function proxyParams (params) {\r\n if (options.params) {\r\n let proxiedParams\r\n if (typeof options.params === 'function') {\r\n proxiedParams = options.params(params)\r\n } else {\r\n proxiedParams = _.merge(params, options.params)\r\n }\r\n return proxiedParams\r\n } else return params\r\n }\r\n function proxyId (id) {\r\n if (options.id) return options.id(id)\r\n else return id\r\n }\r\n function proxyData (data) {\r\n if (options.data) return options.data(data)\r\n else return data\r\n }\r\n function proxyResult (data) {\r\n if (options.result) return options.result(data)\r\n else return data\r\n }\r\n return {\r\n async find (params) { return proxyResult(await targetService.find(proxyParams(params))) },\r\n async get (id, params) { return proxyResult(await targetService.get(proxyId(id), proxyParams(params))) },\r\n async create (data, params) { return proxyResult(await targetService.create(proxyData(data), proxyParams(params))) },\r\n async update (id, data, params) { return proxyResult(await targetService.update(proxyId(id), proxyData(data), proxyParams(params))) },\r\n async patch (id, data, params) { return proxyResult(await targetService.patch(proxyId(id), proxyData(data), proxyParams(params))) },\r\n async remove (id, params) { return proxyResult(await targetService.remove(proxyId(id), proxyParams(params))) }\r\n }\r\n}\r\n\r\nexport function createService (name, app, options = {}) {\r\n const createFeathersService = require('feathers-' + app.db.adapter)\r\n\r\n const paginate = app.get('paginate')\r\n const serviceOptions = Object.assign({\r\n name: name,\r\n paginate\r\n }, options)\r\n if (serviceOptions.disabled) return undefined\r\n // For DB services a model has to be provided\r\n const fileName = serviceOptions.fileName || name\r\n\r\n let dbService = false\r\n try {\r\n if (serviceOptions.modelsPath) {\r\n const configureModel = require(path.join(serviceOptions.modelsPath, fileName + '.model.' + app.db.adapter))\r\n configureModel(app, serviceOptions)\r\n dbService = true\r\n }\r\n } catch (error) {\r\n debug('No ' + fileName + ' service model configured on path ' + serviceOptions.modelsPath)\r\n if (error.code !== 'MODULE_NOT_FOUND') {\r\n // Log error in this case as this might be linked to a syntax error in required file\r\n debug(error)\r\n }\r\n // As this is optionnal this require has to fail silently\r\n }\r\n\r\n // Initialize our service with any options it requires\r\n let service\r\n if (dbService) {\r\n service = createFeathersService(serviceOptions)\r\n dbService = service\r\n } else if (serviceOptions.proxy) {\r\n service = createProxyService(serviceOptions.proxy)\r\n } else {\r\n // Otherwise we expect the service to be provided as a Feathers service interface\r\n service = require(path.join(serviceOptions.servicesPath, fileName, fileName + '.service'))\r\n // If we get a function try to call it assuming it will return the service object\r\n if (typeof service === 'function') {\r\n service = service(name, app, serviceOptions)\r\n }\r\n // Need to set this manually for services not using class inheritance or default adapters\r\n if (serviceOptions.events) service.events = serviceOptions.events\r\n }\r\n\r\n // Get our initialized service so that we can register hooks and filters\r\n let servicePath = serviceOptions.path || name\r\n let contextId\r\n if (serviceOptions.context) {\r\n contextId = idToString(serviceOptions.context)\r\n servicePath = contextId + '/' + servicePath\r\n }\r\n service = declareService(servicePath, app, service, serviceOptions.middlewares)\r\n // Register hooks and event filters\r\n service = configureService(fileName, service, serviceOptions.servicesPath)\r\n // Optionnally a specific service mixin can be provided, apply it\r\n if (dbService && serviceOptions.servicesPath) {\r\n try {\r\n let serviceMixin = require(path.join(serviceOptions.servicesPath, fileName, fileName + '.service'))\r\n // If we get a function try to call it assuming it will return the mixin object\r\n if (typeof serviceMixin === 'function') {\r\n serviceMixin = serviceMixin.bind(dbService)(fileName, app, serviceOptions)\r\n }\r\n service.mixin(serviceMixin)\r\n } catch (error) {\r\n debug('No ' + fileName + ' service mixin configured on path ' + serviceOptions.servicesPath)\r\n if (error.code !== 'MODULE_NOT_FOUND') {\r\n // Log error in this case as this might be linked to a syntax error in required file\r\n debug(error)\r\n }\r\n // As this is optionnal this require has to fail silently\r\n }\r\n }\r\n // Then configuration\r\n service.name = name\r\n service.app = app\r\n service.options = serviceOptions\r\n service.path = servicePath\r\n service.context = serviceOptions.context\r\n\r\n // Add some utility functions\r\n service.getPath = function (withApiPrefix) {\r\n let path = service.path\r\n if (withApiPrefix) {\r\n path = app.get('apiPath') + '/' + path\r\n }\r\n return path\r\n }\r\n service.getContextId = function () {\r\n return contextId // As string\r\n }\r\n\r\n debug(service.name + ' service registration completed')\r\n app.emit('service', service)\r\n\r\n return service\r\n}\r\n\r\nexport function createWebhook (path, app, options = {}) {\r\n let webhookPath = path\r\n if (options.context) {\r\n webhookPath = idToString(options.context) + '/' + webhookPath\r\n }\r\n const isAllowed = (payload) => {\r\n // Default is to expose all services/operations\r\n if (!options.filter) return true\r\n const result = [payload].filter(sift(options.filter))\r\n return result.length > 0\r\n }\r\n\r\n app.post(app.get('apiPath') + '/webhooks/' + webhookPath, async (req, res, next) => {\r\n const payload = req.body\r\n const config = app.get('authentication')\r\n res.set('content-type', 'application/json')\r\n const params = {}\r\n try {\r\n if (options.preprocessor) {\r\n await options.preprocessor(req, res, payload)\r\n }\r\n // Authenticate when required\r\n if (config) {\r\n try {\r\n // Token is in header or payload\r\n const header = req.headers.authorization\r\n let accessToken\r\n if (header) {\r\n // Should be of the form: 'Bearer xxx'\r\n const tokens = header.match(/(\\S+)\\s+(\\S+)/)\r\n if (tokens.length >= 2) accessToken = tokens[2]\r\n } else {\r\n accessToken = payload.accessToken\r\n }\r\n const tokenPayload = await app.passport.verifyJWT(accessToken, config)\r\n params.user = await app.getService('users').get(tokenPayload.userId)\r\n params.checkAuthorisation = true\r\n } catch (error) {\r\n throw new Forbidden('Could not verify webhook')\r\n }\r\n }\r\n if (req.headers['content-type'] !== 'application/json') {\r\n throw new BadRequest('Webhooks expect application/json content type')\r\n }\r\n if (!isAllowed(payload)) throw new Forbidden('Service or operation not allowed for webhook')\r\n const service = app.getService(payload.service, options.context || payload.context)\r\n if (!service) throw new BadRequest('Service could not be found')\r\n if (typeof service[payload.operation] !== 'function') throw new BadRequest('Service operation could not be found')\r\n const args = []\r\n // Get/Update/Patch/Remove\r\n const operationsWithId = ['get', 'update', 'patch', 'remove']\r\n if (operationsWithId.includes(payload.operation)) {\r\n if (!_.has(payload, 'id')) throw new BadRequest('Missing id for operation')\r\n args.push(_.get(payload, 'id'))\r\n }\r\n // Create/Update/Patch\r\n const operationsWithData = ['create', 'update', 'patch']\r\n if (operationsWithData.includes(payload.operation)) {\r\n if (!_.has(payload, 'data')) throw new BadRequest('Missing data for operation')\r\n args.push(_.get(payload, 'data'))\r\n }\r\n // Params\r\n args.push(params)\r\n if (options.postprocessor) {\r\n await options.postprocessor(service, args, payload)\r\n }\r\n try {\r\n const result = await service[payload.operation].apply(service, args)\r\n // Send back result\r\n res.json(result)\r\n } catch (error) {\r\n throw new BadRequest('Service operation could not be performed')\r\n }\r\n } catch (error) {\r\n // Send back error\r\n res.status(error.code).json(error.toJSON())\r\n }\r\n })\r\n\r\n debug(`Webhook ${webhookPath} registration completed`)\r\n}\r\n\r\nfunction setupLogger (app) {\r\n debug('Setup application loggers')\r\n const logsConfig = app.get('logs')\r\n // Use winston default logger\r\n app.logger = logger\r\n // Remove winston defaults\r\n try {\r\n logger.clear()\r\n } catch (error) {\r\n // Logger might be down, use console\r\n console.error('Could not remove default logger transport(s)', error)\r\n }\r\n // We have one entry per log type\r\n const logsTypes = logsConfig ? Object.getOwnPropertyNames(logsConfig) : []\r\n // Create corresponding winston transports with options\r\n logsTypes.forEach(logType => {\r\n const options = logsConfig[logType]\r\n // Setup default log level if not defined\r\n if (!options.level) {\r\n options.level = (process.env.NODE_ENV === 'development' ? 'debug' : 'info')\r\n }\r\n try {\r\n logger.add(new logger.transports[logType](options))\r\n } catch (error) {\r\n // Logger might be down, use console\r\n console.error('Could not setup default log levels', error)\r\n }\r\n })\r\n}\r\n\r\nfunction setupSockets (app) {\r\n const apiLimiter = app.get('apiLimiter')\r\n const connections = {}\r\n let nbConnections = 0\r\n\r\n return io => {\r\n // By default EventEmitters will print a warning if more than 10 listeners are added for a particular event.\r\n // The value can be set to Infinity (or 0) to indicate an unlimited number of listeners.\r\n io.sockets.setMaxListeners(0)\r\n const maxConnections = _.get(apiLimiter, 'websocket.maxConcurrency', 0)\r\n const maxIpConnections = _.get(apiLimiter, 'websocket.concurrency', 0)\r\n\r\n io.on('connection', socket => {\r\n nbConnections++\r\n debug(`New socket connection on server with pid ${process.pid}`, socket.id, socket.conn.remoteAddress, nbConnections)\r\n // Setup disconnect handler first\r\n socket.on('disconnect', (reason) => {\r\n nbConnections--\r\n debug(reason)\r\n debug(`Socket disconnection on server with pid ${process.pid}`, socket.id, socket.conn.remoteAddress, nbConnections)\r\n if (maxIpConnections > 0) {\r\n const nbIpConnections = _.get(connections, socket.conn.remoteAddress) - 1\r\n debug('Total number of connections for', socket.id, socket.conn.remoteAddress, nbIpConnections)\r\n _.set(connections, socket.conn.remoteAddress, nbIpConnections)\r\n }\r\n })\r\n if (maxConnections > 0) {\r\n if (nbConnections > maxConnections) {\r\n tooManyRequests(socket, 'Too many concurrent connections (rate limiting)', 'RATE_LIMITING_CONCURRENCY')\r\n return\r\n }\r\n }\r\n if (maxIpConnections > 0) {\r\n if (_.has(connections, socket.conn.remoteAddress)) {\r\n const nbIpConnections = _.get(connections, socket.conn.remoteAddress) + 1\r\n debug('Total number of connections for', socket.id, socket.conn.remoteAddress, nbConnections)\r\n _.set(connections, socket.conn.remoteAddress, nbIpConnections)\r\n if (nbIpConnections > maxIpConnections) {\r\n tooManyRequests(socket, 'Too many concurrent connections (rate limiting)', 'RATE_LIMITING_CONCURRENCY')\r\n return\r\n }\r\n } else {\r\n _.set(connections, socket.conn.remoteAddress, 1)\r\n }\r\n }\r\n /* For debug purpose: trace all data received\r\n socket.use((packet, next) => {\r\n console.log(packet)\r\n next()\r\n })\r\n */\r\n if (apiLimiter && apiLimiter.websocket) {\r\n const { tokensPerInterval, interval } = apiLimiter.websocket\r\n // Function used to filter whitelisted services, defaults to none\r\n const services = _.get(apiLimiter.websocket, 'services', (service) => false)\r\n socket.socketLimiter = new SocketLimiter(tokensPerInterval, interval)\r\n socket.use((packet, next) => {\r\n if (packet.length > 0) {\r\n // Packets are formatted according to service interface,\r\n // e.g. like [service_method, service_path, id or data, params]\r\n // Bypass rate limiting on whitelist\r\n if ((packet.length > 1) && (typeof packet[1] === 'string')) {\r\n const service = app.service(packet[1])\r\n if (service && services(service)) {\r\n debugLimiter('By-pass rate limiting on whitelisted service operation', socket.id, socket.conn.remoteAddress, packet[0], packet[1])\r\n next()\r\n return\r\n }\r\n }\r\n debugLimiter(socket.socketLimiter.getTokensRemaining() + ' remaining API token for socket', socket.id, socket.conn.remoteAddress)\r\n if (!socket.socketLimiter.tryRemoveTokens(1)) { // if exceeded\r\n tooManyRequests(socket, 'Too many requests in a given amount of time (rate limiting)', 'RATE_LIMITING')\r\n // FIXME: calling this causes a client timeout\r\n // next(error)\r\n // Need to normalize the error object as JSON\r\n // let result = {}\r\n // Object.getOwnPropertyNames(error).forEach(key => (result[key] = error[key]))\r\n // Trying to send error like in https://github.com/feathersjs/transport-commons/blob/auk/src/events.js#L103\r\n // does not work either (also generates a client timeout)\r\n // socket.emit(`${servicePath} error`, result)\r\n // socket.emit(result)\r\n return\r\n }\r\n }\r\n next()\r\n })\r\n }\r\n\r\n authSocket(app, socket)\r\n })\r\n }\r\n}\r\n\r\nexport function kalisio () {\r\n const app = express(feathers())\r\n // By default EventEmitters will print a warning if more than 10 listeners are added for a particular event.\r\n // The value can be set to Infinity (or 0) to indicate an unlimited number of listeners.\r\n app.setMaxListeners(0)\r\n // Load app configuration first\r\n app.configure(configuration())\r\n // Then setup logger\r\n setupLogger(app)\r\n\r\n // This retrieve corresponding service options from app config if any\r\n app.getServiceOptions = function (name) {\r\n const services = app.get('services')\r\n if (!services) return {}\r\n return _.get(services, name, {})\r\n }\r\n // This avoid managing the API path before each service name\r\n app.getService = function (path, context) {\r\n // Context is given as string ID\r\n if (context && typeof context === 'string') {\r\n return app.service(app.get('apiPath') + '/' + context + '/' + path)\r\n } else if (context && typeof context === 'object') {\r\n // Could be Object ID or raw object\r\n if (ObjectID.isValid(context)) return app.service(app.get('apiPath') + '/' + context.toString() + '/' + path)\r\n else return app.service(app.get('apiPath') + '/' + context._id.toString() + '/' + path)\r\n } else {\r\n return app.service(app.get('apiPath') + '/' + path)\r\n }\r\n }\r\n // This is used to add hooks/filters to services\r\n app.configureService = function (name, service, servicesPath) {\r\n return configureService(name, service, servicesPath)\r\n }\r\n // This is used to create standard services\r\n app.createService = function (name, options) {\r\n return createService(name, app, options)\r\n }\r\n // This is used to create webhooks\r\n app.createWebhook = function (path, options) {\r\n return createWebhook(path, app, options)\r\n }\r\n // Override Feathers configure that do not manage async operations,\r\n // here we also simply call the function given as parameter but await for it\r\n app.configure = async function (fn) {\r\n await fn.call(this, this)\r\n return this\r\n }\r\n const apiLimiter = app.get('apiLimiter')\r\n if (apiLimiter && apiLimiter.http) {\r\n // Function used to filter whitelisted services, defaults to none\r\n const services = _.get(apiLimiter.http, 'services', (service) => false)\r\n const handler = (req, res, next) => {\r\n // Bypass rate limiting on whitelist\r\n let service\r\n try {\r\n const serviceUrl = new url.URL(req.originalUrl)\r\n service = app.service(serviceUrl.pathname)\r\n } catch (error) {\r\n debugLimiter(error)\r\n }\r\n if (service && services(service)) {\r\n debugLimiter('By-pass rate limiting on whitelisted service operation', req.method, path)\r\n next()\r\n } else {\r\n const error = new TooManyRequests('Too many requests in a given amount of time (rate limiting)',\r\n { translation: { key: 'RATE_LIMITING' } })\r\n res.status(error.code)\r\n res.set('Content-Type', 'application/json')\r\n res.json(Object.assign({}, error.toJSON()))\r\n }\r\n }\r\n app.use(app.get('apiPath'), new HttpLimiter(Object.assign({ handler }, apiLimiter.http)))\r\n }\r\n\r\n // Enable CORS, security, compression, and body parsing\r\n app.use(cors(app.get('cors')))\r\n app.use(helmet(app.get('helmet')))\r\n app.use(compress(app.get('compression')))\r\n const bodyParserConfig = app.get('bodyParser')\r\n app.use(bodyParser.json(_.get(bodyParserConfig, 'json')))\r\n app.use(bodyParser.urlencoded(Object.assign({ extended: true }, _.get(bodyParserConfig, 'urlencoded'))))\r\n\r\n // Set up plugins and providers\r\n app.configure(rest())\r\n const socketioConfig = app.get('socketio') || {}\r\n app.configure(socketio(Object.assign({ path: app.get('apiPath') + 'ws' }, socketioConfig), setupSockets(app)))\r\n app.configure(auth)\r\n\r\n // Initialize DB\r\n app.db = Database.create(app)\r\n\r\n return app\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"sources":["../../../core/api/application.js"],"names":["declareService","configureService","createProxyService","createService","createWebhook","kalisio","debug","debugLimiter","tooManyRequests","socket","message","key","error","TooManyRequests","translation","emit","setTimeout","disconnect","path","app","service","middlewares","feathersPath","get","feathersService","args","before","concat","push","after","use","apply","name","servicesPath","hooks","require","join","code","channels","_","forOwn","publisher","event","publish","options","targetService","proxyParams","params","proxiedParams","merge","proxyId","id","proxyData","data","proxyResult","result","find","create","update","patch","remove","createFeathersService","db","adapter","paginate","serviceOptions","Object","assign","disabled","undefined","fileName","dbService","modelsPath","configureModel","proxy","events","servicePath","contextId","context","serviceMixin","bind","mixin","getPath","withApiPrefix","getContextId","webhookPath","isAllowed","payload","filter","length","post","req","res","next","body","config","set","preprocessor","header","headers","authorization","accessToken","tokens","match","tokenPayload","passport","verifyJWT","user","getService","userId","checkAuthorisation","Forbidden","BadRequest","operation","operationsWithId","includes","has","operationsWithData","postprocessor","json","status","toJSON","setupLogger","logsConfig","logger","clear","console","logsTypes","getOwnPropertyNames","forEach","logType","level","process","env","NODE_ENV","add","transports","setupSockets","apiLimiter","connections","nbConnections","io","sockets","setMaxListeners","maxConnections","maxIpConnections","on","pid","conn","remoteAddress","reason","nbIpConnections","websocket","tokensPerInterval","interval","services","socketLimiter","SocketLimiter","packet","getTokensRemaining","tryRemoveTokens","setupHealthcheck","isRunning","configure","getServiceOptions","ObjectID","isValid","toString","_id","fn","call","http","handler","serviceUrl","url","URL","originalUrl","pathname","method","HttpLimiter","bodyParserConfig","bodyParser","urlencoded","extended","socketioConfig","auth","Database"],"mappings":"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","file":"application.js","sourcesContent":["import path from 'path'\r\nimport url from 'url'\r\nimport makeDebug from 'debug'\r\nimport logger from 'winston'\r\nimport _ from 'lodash'\r\nimport sift from 'sift'\r\nimport 'winston-daily-rotate-file'\r\nimport compress from 'compression'\r\nimport cors from 'cors'\r\nimport helmet from 'helmet'\r\nimport bodyParser from 'body-parser'\r\nimport { RateLimiter as SocketLimiter } from 'limiter'\r\nimport HttpLimiter from 'express-rate-limit'\r\nimport feathers from '@feathersjs/feathers'\r\nimport configuration from '@feathersjs/configuration'\r\nimport { TooManyRequests, Forbidden, BadRequest } from '@feathersjs/errors'\r\nimport express from '@feathersjs/express'\r\nimport rest from '@feathersjs/express/rest'\r\nimport socketio from '@feathersjs/socketio'\r\nimport { ObjectID } from 'mongodb'\r\nimport { Database, idToString } from './db'\r\nimport auth, { authSocket } from './authentication'\r\n\r\nconst debug = makeDebug('kdk:core:application')\r\nconst debugLimiter = makeDebug('kdk:core:application:limiter')\r\n\r\nfunction tooManyRequests (socket, message, key) {\r\n debug(message)\r\n const error = new TooManyRequests(message, { translation: { key } })\r\n socket.emit('rate-limit', error)\r\n // Add a timeout so that error message is correctly handled\r\n setTimeout(() => socket.disconnect(true), 3000)\r\n}\r\n\r\nexport function declareService (path, app, service, middlewares = {}) {\r\n const feathersPath = app.get('apiPath') + '/' + path\r\n const feathersService = app.service(feathersPath)\r\n // Some internal Feathers service might internally declare the service\r\n if (feathersService) {\r\n return feathersService\r\n }\r\n // Initialize our service by providing any middleware as well\r\n let args = [feathersPath]\r\n if (middlewares.before) args = args.concat(middlewares.before)\r\n args.push(service)\r\n if (middlewares.after) args = args.concat(middlewares.after)\r\n app.use.apply(app, args)\r\n debug('Service declared on path ' + feathersPath)\r\n // Return the Feathers service, ie base service + Feathers' internals\r\n return app.service(feathersPath)\r\n}\r\n\r\nexport function configureService (name, service, servicesPath) {\r\n try {\r\n const hooks = require(path.join(servicesPath, name, name + '.hooks'))\r\n service.hooks(hooks)\r\n debug(name + ' service hooks configured on path ' + servicesPath)\r\n } catch (error) {\r\n debug('No ' + name + ' service hooks configured on path ' + servicesPath)\r\n if (error.code !== 'MODULE_NOT_FOUND') {\r\n // Log error in this case as this might be linked to a syntax error in required file\r\n debug(error)\r\n }\r\n // As this is optionnal this require has to fail silently\r\n }\r\n\r\n try {\r\n const channels = require(path.join(servicesPath, name, name + '.channels'))\r\n _.forOwn(channels, (publisher, event) => {\r\n if (event === 'all') service.publish(publisher)\r\n else service.publish(event, publisher)\r\n })\r\n debug(name + ' service channels configured on path ' + servicesPath)\r\n } catch (error) {\r\n debug('No ' + name + ' service channels configured on path ' + servicesPath)\r\n if (error.code !== 'MODULE_NOT_FOUND') {\r\n // Log error in this case as this might be linked to a syntax error in required file\r\n debug(error)\r\n }\r\n // As this is optionnal this require has to fail silently\r\n }\r\n\r\n return service\r\n}\r\n\r\nexport function createProxyService (options) {\r\n const targetService = options.service\r\n function proxyParams (params) {\r\n if (options.params) {\r\n let proxiedParams\r\n if (typeof options.params === 'function') {\r\n proxiedParams = options.params(params)\r\n } else {\r\n proxiedParams = _.merge(params, options.params)\r\n }\r\n return proxiedParams\r\n } else return params\r\n }\r\n function proxyId (id) {\r\n if (options.id) return options.id(id)\r\n else return id\r\n }\r\n function proxyData (data) {\r\n if (options.data) return options.data(data)\r\n else return data\r\n }\r\n function proxyResult (data) {\r\n if (options.result) return options.result(data)\r\n else return data\r\n }\r\n return {\r\n async find (params) { return proxyResult(await targetService.find(proxyParams(params))) },\r\n async get (id, params) { return proxyResult(await targetService.get(proxyId(id), proxyParams(params))) },\r\n async create (data, params) { return proxyResult(await targetService.create(proxyData(data), proxyParams(params))) },\r\n async update (id, data, params) { return proxyResult(await targetService.update(proxyId(id), proxyData(data), proxyParams(params))) },\r\n async patch (id, data, params) { return proxyResult(await targetService.patch(proxyId(id), proxyData(data), proxyParams(params))) },\r\n async remove (id, params) { return proxyResult(await targetService.remove(proxyId(id), proxyParams(params))) }\r\n }\r\n}\r\n\r\nexport function createService (name, app, options = {}) {\r\n const createFeathersService = require('feathers-' + app.db.adapter)\r\n\r\n const paginate = app.get('paginate')\r\n const serviceOptions = Object.assign({\r\n name: name,\r\n paginate\r\n }, options)\r\n if (serviceOptions.disabled) return undefined\r\n // For DB services a model has to be provided\r\n const fileName = serviceOptions.fileName || name\r\n\r\n let dbService = false\r\n try {\r\n if (serviceOptions.modelsPath) {\r\n const configureModel = require(path.join(serviceOptions.modelsPath, fileName + '.model.' + app.db.adapter))\r\n configureModel(app, serviceOptions)\r\n dbService = true\r\n }\r\n } catch (error) {\r\n debug('No ' + fileName + ' service model configured on path ' + serviceOptions.modelsPath)\r\n if (error.code !== 'MODULE_NOT_FOUND') {\r\n // Log error in this case as this might be linked to a syntax error in required file\r\n debug(error)\r\n }\r\n // As this is optionnal this require has to fail silently\r\n }\r\n\r\n // Initialize our service with any options it requires\r\n let service\r\n if (dbService) {\r\n service = createFeathersService(serviceOptions)\r\n dbService = service\r\n } else if (serviceOptions.proxy) {\r\n service = createProxyService(serviceOptions.proxy)\r\n } else {\r\n // Otherwise we expect the service to be provided as a Feathers service interface\r\n service = require(path.join(serviceOptions.servicesPath, fileName, fileName + '.service'))\r\n // If we get a function try to call it assuming it will return the service object\r\n if (typeof service === 'function') {\r\n service = service(name, app, serviceOptions)\r\n }\r\n // Need to set this manually for services not using class inheritance or default adapters\r\n if (serviceOptions.events) service.events = serviceOptions.events\r\n }\r\n\r\n // Get our initialized service so that we can register hooks and filters\r\n let servicePath = serviceOptions.path || name\r\n let contextId\r\n if (serviceOptions.context) {\r\n contextId = idToString(serviceOptions.context)\r\n servicePath = contextId + '/' + servicePath\r\n }\r\n service = declareService(servicePath, app, service, serviceOptions.middlewares)\r\n // Register hooks and event filters\r\n service = configureService(fileName, service, serviceOptions.servicesPath)\r\n // Optionnally a specific service mixin can be provided, apply it\r\n if (dbService && serviceOptions.servicesPath) {\r\n try {\r\n let serviceMixin = require(path.join(serviceOptions.servicesPath, fileName, fileName + '.service'))\r\n // If we get a function try to call it assuming it will return the mixin object\r\n if (typeof serviceMixin === 'function') {\r\n serviceMixin = serviceMixin.bind(dbService)(fileName, app, serviceOptions)\r\n }\r\n service.mixin(serviceMixin)\r\n } catch (error) {\r\n debug('No ' + fileName + ' service mixin configured on path ' + serviceOptions.servicesPath)\r\n if (error.code !== 'MODULE_NOT_FOUND') {\r\n // Log error in this case as this might be linked to a syntax error in required file\r\n debug(error)\r\n }\r\n // As this is optionnal this require has to fail silently\r\n }\r\n }\r\n // Then configuration\r\n service.name = name\r\n service.app = app\r\n service.options = serviceOptions\r\n service.path = servicePath\r\n service.context = serviceOptions.context\r\n\r\n // Add some utility functions\r\n service.getPath = function (withApiPrefix) {\r\n let path = service.path\r\n if (withApiPrefix) {\r\n path = app.get('apiPath') + '/' + path\r\n }\r\n return path\r\n }\r\n service.getContextId = function () {\r\n return contextId // As string\r\n }\r\n\r\n debug(service.name + ' service registration completed')\r\n app.emit('service', service)\r\n\r\n return service\r\n}\r\n\r\nexport function createWebhook (path, app, options = {}) {\r\n let webhookPath = path\r\n if (options.context) {\r\n webhookPath = idToString(options.context) + '/' + webhookPath\r\n }\r\n const isAllowed = (payload) => {\r\n // Default is to expose all services/operations\r\n if (!options.filter) return true\r\n const result = [payload].filter(sift(options.filter))\r\n return result.length > 0\r\n }\r\n\r\n app.post(app.get('apiPath') + '/webhooks/' + webhookPath, async (req, res, next) => {\r\n const payload = req.body\r\n const config = app.get('authentication')\r\n res.set('content-type', 'application/json')\r\n const params = {}\r\n try {\r\n if (options.preprocessor) {\r\n await options.preprocessor(req, res, payload)\r\n }\r\n // Authenticate when required\r\n if (config) {\r\n try {\r\n // Token is in header or payload\r\n const header = req.headers.authorization\r\n let accessToken\r\n if (header) {\r\n // Should be of the form: 'Bearer xxx'\r\n const tokens = header.match(/(\\S+)\\s+(\\S+)/)\r\n if (tokens.length >= 2) accessToken = tokens[2]\r\n } else {\r\n accessToken = payload.accessToken\r\n }\r\n const tokenPayload = await app.passport.verifyJWT(accessToken, config)\r\n params.user = await app.getService('users').get(tokenPayload.userId)\r\n params.checkAuthorisation = true\r\n } catch (error) {\r\n throw new Forbidden('Could not verify webhook')\r\n }\r\n }\r\n if (req.headers['content-type'] !== 'application/json') {\r\n throw new BadRequest('Webhooks expect application/json content type')\r\n }\r\n if (!isAllowed(payload)) throw new Forbidden('Service or operation not allowed for webhook')\r\n const service = app.getService(payload.service, options.context || payload.context)\r\n if (!service) throw new BadRequest('Service could not be found')\r\n if (typeof service[payload.operation] !== 'function') throw new BadRequest('Service operation could not be found')\r\n const args = []\r\n // Get/Update/Patch/Remove\r\n const operationsWithId = ['get', 'update', 'patch', 'remove']\r\n if (operationsWithId.includes(payload.operation)) {\r\n if (!_.has(payload, 'id')) throw new BadRequest('Missing id for operation')\r\n args.push(_.get(payload, 'id'))\r\n }\r\n // Create/Update/Patch\r\n const operationsWithData = ['create', 'update', 'patch']\r\n if (operationsWithData.includes(payload.operation)) {\r\n if (!_.has(payload, 'data')) throw new BadRequest('Missing data for operation')\r\n args.push(_.get(payload, 'data'))\r\n }\r\n // Params\r\n args.push(params)\r\n if (options.postprocessor) {\r\n await options.postprocessor(service, args, payload)\r\n }\r\n try {\r\n const result = await service[payload.operation].apply(service, args)\r\n // Send back result\r\n res.json(result)\r\n } catch (error) {\r\n throw new BadRequest('Service operation could not be performed')\r\n }\r\n } catch (error) {\r\n // Send back error\r\n res.status(error.code).json(error.toJSON())\r\n }\r\n })\r\n\r\n debug(`Webhook ${webhookPath} registration completed`)\r\n}\r\n\r\nfunction setupLogger (app) {\r\n debug('Setup application loggers')\r\n const logsConfig = app.get('logs')\r\n // Use winston default logger\r\n app.logger = logger\r\n // Remove winston defaults\r\n try {\r\n logger.clear()\r\n } catch (error) {\r\n // Logger might be down, use console\r\n console.error('Could not remove default logger transport(s)', error)\r\n }\r\n // We have one entry per log type\r\n const logsTypes = logsConfig ? Object.getOwnPropertyNames(logsConfig) : []\r\n // Create corresponding winston transports with options\r\n logsTypes.forEach(logType => {\r\n const options = logsConfig[logType]\r\n // Setup default log level if not defined\r\n if (!options.level) {\r\n options.level = (process.env.NODE_ENV === 'development' ? 'debug' : 'info')\r\n }\r\n try {\r\n logger.add(new logger.transports[logType](options))\r\n } catch (error) {\r\n // Logger might be down, use console\r\n console.error('Could not setup default log levels', error)\r\n }\r\n })\r\n}\r\n\r\nfunction setupSockets (app) {\r\n const apiLimiter = app.get('apiLimiter')\r\n const connections = {}\r\n let nbConnections = 0\r\n\r\n return io => {\r\n // By default EventEmitters will print a warning if more than 10 listeners are added for a particular event.\r\n // The value can be set to Infinity (or 0) to indicate an unlimited number of listeners.\r\n io.sockets.setMaxListeners(0)\r\n const maxConnections = _.get(apiLimiter, 'websocket.maxConcurrency', 0)\r\n const maxIpConnections = _.get(apiLimiter, 'websocket.concurrency', 0)\r\n\r\n io.on('connection', socket => {\r\n nbConnections++\r\n debug(`New socket connection on server with pid ${process.pid}`, socket.id, socket.conn.remoteAddress, nbConnections)\r\n // Setup disconnect handler first\r\n socket.on('disconnect', (reason) => {\r\n nbConnections--\r\n debug(reason)\r\n debug(`Socket disconnection on server with pid ${process.pid}`, socket.id, socket.conn.remoteAddress, nbConnections)\r\n if (maxIpConnections > 0) {\r\n const nbIpConnections = _.get(connections, socket.conn.remoteAddress) - 1\r\n debug('Total number of connections for', socket.id, socket.conn.remoteAddress, nbIpConnections)\r\n _.set(connections, socket.conn.remoteAddress, nbIpConnections)\r\n }\r\n })\r\n if (maxConnections > 0) {\r\n if (nbConnections > maxConnections) {\r\n tooManyRequests(socket, 'Too many concurrent connections (rate limiting)', 'RATE_LIMITING_CONCURRENCY')\r\n return\r\n }\r\n }\r\n if (maxIpConnections > 0) {\r\n if (_.has(connections, socket.conn.remoteAddress)) {\r\n const nbIpConnections = _.get(connections, socket.conn.remoteAddress) + 1\r\n debug('Total number of connections for', socket.id, socket.conn.remoteAddress, nbConnections)\r\n _.set(connections, socket.conn.remoteAddress, nbIpConnections)\r\n if (nbIpConnections > maxIpConnections) {\r\n tooManyRequests(socket, 'Too many concurrent connections (rate limiting)', 'RATE_LIMITING_CONCURRENCY')\r\n return\r\n }\r\n } else {\r\n _.set(connections, socket.conn.remoteAddress, 1)\r\n }\r\n }\r\n /* For debug purpose: trace all data received\r\n socket.use((packet, next) => {\r\n console.log(packet)\r\n next()\r\n })\r\n */\r\n if (apiLimiter && apiLimiter.websocket) {\r\n const { tokensPerInterval, interval } = apiLimiter.websocket\r\n // Function used to filter whitelisted services, defaults to none\r\n const services = _.get(apiLimiter.websocket, 'services', (service) => false)\r\n socket.socketLimiter = new SocketLimiter(tokensPerInterval, interval)\r\n socket.use((packet, next) => {\r\n if (packet.length > 0) {\r\n // Packets are formatted according to service interface,\r\n // e.g. like [service_method, service_path, id or data, params]\r\n // Bypass rate limiting on whitelist\r\n if ((packet.length > 1) && (typeof packet[1] === 'string')) {\r\n const service = app.service(packet[1])\r\n if (service && services(service)) {\r\n debugLimiter('By-pass rate limiting on whitelisted service operation', socket.id, socket.conn.remoteAddress, packet[0], packet[1])\r\n next()\r\n return\r\n }\r\n }\r\n debugLimiter(socket.socketLimiter.getTokensRemaining() + ' remaining API token for socket', socket.id, socket.conn.remoteAddress)\r\n if (!socket.socketLimiter.tryRemoveTokens(1)) { // if exceeded\r\n tooManyRequests(socket, 'Too many requests in a given amount of time (rate limiting)', 'RATE_LIMITING')\r\n // FIXME: calling this causes a client timeout\r\n // next(error)\r\n // Need to normalize the error object as JSON\r\n // let result = {}\r\n // Object.getOwnPropertyNames(error).forEach(key => (result[key] = error[key]))\r\n // Trying to send error like in https://github.com/feathersjs/transport-commons/blob/auk/src/events.js#L103\r\n // does not work either (also generates a client timeout)\r\n // socket.emit(`${servicePath} error`, result)\r\n // socket.emit(result)\r\n return\r\n }\r\n }\r\n next()\r\n })\r\n }\r\n\r\n authSocket(app, socket)\r\n })\r\n }\r\n}\r\n\r\nfunction setupHealthcheck (app) {\r\n app.get('/healthcheck', (req, res) => {\r\n res.set('Content-Type', 'application/json')\r\n return res.status(200).json({ isRunning: true })\r\n })\r\n}\r\n\r\nexport function kalisio () {\r\n const app = express(feathers())\r\n // By default EventEmitters will print a warning if more than 10 listeners are added for a particular event.\r\n // The value can be set to Infinity (or 0) to indicate an unlimited number of listeners.\r\n app.setMaxListeners(0)\r\n // Load app configuration first\r\n app.configure(configuration())\r\n // Then setup logger, healthcheck, etc.\r\n setupLogger(app)\r\n setupHealthcheck(app)\r\n\r\n // This retrieve corresponding service options from app config if any\r\n app.getServiceOptions = function (name) {\r\n const services = app.get('services')\r\n if (!services) return {}\r\n return _.get(services, name, {})\r\n }\r\n // This avoid managing the API path before each service name\r\n app.getService = function (path, context) {\r\n // Context is given as string ID\r\n if (context && typeof context === 'string') {\r\n return app.service(app.get('apiPath') + '/' + context + '/' + path)\r\n } else if (context && typeof context === 'object') {\r\n // Could be Object ID or raw object\r\n if (ObjectID.isValid(context)) return app.service(app.get('apiPath') + '/' + context.toString() + '/' + path)\r\n else return app.service(app.get('apiPath') + '/' + context._id.toString() + '/' + path)\r\n } else {\r\n return app.service(app.get('apiPath') + '/' + path)\r\n }\r\n }\r\n // This is used to add hooks/filters to services\r\n app.configureService = function (name, service, servicesPath) {\r\n return configureService(name, service, servicesPath)\r\n }\r\n // This is used to create standard services\r\n app.createService = function (name, options) {\r\n return createService(name, app, options)\r\n }\r\n // This is used to create webhooks\r\n app.createWebhook = function (path, options) {\r\n return createWebhook(path, app, options)\r\n }\r\n // Override Feathers configure that do not manage async operations,\r\n // here we also simply call the function given as parameter but await for it\r\n app.configure = async function (fn) {\r\n await fn.call(this, this)\r\n return this\r\n }\r\n const apiLimiter = app.get('apiLimiter')\r\n if (apiLimiter && apiLimiter.http) {\r\n // Function used to filter whitelisted services, defaults to none\r\n const services = _.get(apiLimiter.http, 'services', (service) => false)\r\n const handler = (req, res, next) => {\r\n // Bypass rate limiting on whitelist\r\n let service\r\n try {\r\n const serviceUrl = new url.URL(req.originalUrl)\r\n service = app.service(serviceUrl.pathname)\r\n } catch (error) {\r\n debugLimiter(error)\r\n }\r\n if (service && services(service)) {\r\n debugLimiter('By-pass rate limiting on whitelisted service operation', req.method, path)\r\n next()\r\n } else {\r\n const error = new TooManyRequests('Too many requests in a given amount of time (rate limiting)',\r\n { translation: { key: 'RATE_LIMITING' } })\r\n res.status(error.code)\r\n res.set('Content-Type', 'application/json')\r\n res.json(Object.assign({}, error.toJSON()))\r\n }\r\n }\r\n app.use(app.get('apiPath'), new HttpLimiter(Object.assign({ handler }, apiLimiter.http)))\r\n }\r\n\r\n // Enable CORS, security, compression, and body parsing\r\n app.use(cors(app.get('cors')))\r\n app.use(helmet(app.get('helmet')))\r\n app.use(compress(app.get('compression')))\r\n const bodyParserConfig = app.get('bodyParser')\r\n app.use(bodyParser.json(_.get(bodyParserConfig, 'json')))\r\n app.use(bodyParser.urlencoded(Object.assign({ extended: true }, _.get(bodyParserConfig, 'urlencoded'))))\r\n\r\n // Set up plugins and providers\r\n app.configure(rest())\r\n const socketioConfig = app.get('socketio') || {}\r\n app.configure(socketio(Object.assign({ path: app.get('apiPath') + 'ws' }, socketioConfig), setupSockets(app)))\r\n app.configure(auth)\r\n\r\n // Initialize DB\r\n app.db = Database.create(app)\r\n\r\n return app\r\n}\r\n"]}
|