@kalisio/kdk 2.1.9 → 2.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (272) hide show
  1. package/.travis.test.sh +42 -10
  2. package/README.md +2 -2
  3. package/core/api/application.js +7 -2
  4. package/core/api/authentication.js +17 -1
  5. package/core/api/db.js +7 -2
  6. package/core/api/hooks/hooks.authentication.js +4 -2
  7. package/core/api/hooks/hooks.authorisations.js +12 -2
  8. package/core/api/hooks/hooks.model.js +5 -5
  9. package/core/api/hooks/hooks.organisations.js +0 -4
  10. package/core/api/services/account/account.hooks.js +10 -6
  11. package/core/api/services/account/account.service.js +1 -1
  12. package/{map/api/services/geocoder/geocoder.hooks.js → core/api/services/import-export/import-export.hooks.js} +7 -5
  13. package/core/api/services/import-export/import-export.service.js +11 -0
  14. package/core/api/services/index.js +13 -1
  15. package/core/api/services/users/users.hooks.js +2 -3
  16. package/core/client/api.js +16 -14
  17. package/core/client/capabilities.js +6 -2
  18. package/core/client/components/KContent.vue +11 -1
  19. package/core/client/components/KDialog.vue +17 -15
  20. package/core/client/components/KModal.vue +1 -1
  21. package/core/client/components/KSponsor.vue +1 -1
  22. package/core/client/components/KTextArea.vue +5 -1
  23. package/core/client/components/app/KAbout.vue +1 -2
  24. package/core/client/components/app/KWelcome.vue +3 -5
  25. package/core/client/components/chart/KTimeSeriesChart.vue +24 -37
  26. package/core/client/components/collection/KColumn.vue +20 -17
  27. package/core/client/components/editor/KModalEditor.vue +0 -2
  28. package/core/client/components/form/KChipsField.vue +12 -2
  29. package/core/client/components/form/KColorField.vue +12 -2
  30. package/core/client/components/form/KColorScaleField.vue +12 -2
  31. package/core/client/components/form/KDateTimeRangeField.vue +12 -2
  32. package/core/client/components/form/KDatetimeField.vue +12 -2
  33. package/core/client/components/form/KEmailField.vue +12 -2
  34. package/core/client/components/form/KFileField.vue +12 -2
  35. package/core/client/components/form/KForm.vue +47 -9
  36. package/core/client/components/form/KIconField.vue +12 -2
  37. package/core/client/components/form/KItemField.vue +25 -4
  38. package/core/client/components/form/KNumberField.vue +12 -2
  39. package/core/client/components/form/KOptionsField.vue +12 -2
  40. package/core/client/components/form/KPasswordField.vue +12 -2
  41. package/core/client/components/form/KPhoneField.vue +13 -3
  42. package/core/client/components/form/KPropertyItemField.vue +12 -2
  43. package/core/client/components/form/KResolutionField.vue +126 -0
  44. package/core/client/components/form/KRoleField.vue +12 -2
  45. package/core/client/components/form/KSelectField.vue +14 -4
  46. package/core/client/components/form/KTextField.vue +12 -2
  47. package/core/client/components/form/KTextareaField.vue +13 -3
  48. package/core/client/components/form/KToggleField.vue +12 -2
  49. package/core/client/components/form/KTokenField.vue +12 -2
  50. package/core/client/components/form/KUnitField.vue +12 -2
  51. package/core/client/components/form/KUrlField.vue +12 -2
  52. package/core/client/components/input/KIconChooser.vue +10 -12
  53. package/core/client/components/input/KPalette.vue +2 -1
  54. package/core/client/components/layout/KPage.vue +5 -4
  55. package/core/client/components/layout/KWindow.vue +10 -10
  56. package/core/client/components/media/KColorScale.vue +25 -19
  57. package/core/client/components/media/KImageViewer.vue +57 -33
  58. package/core/client/components/media/KShape.vue +14 -103
  59. package/core/client/components/screen/KRegisterScreen.vue +0 -1
  60. package/core/client/components/screen/KScreenFooter.vue +0 -18
  61. package/core/client/components/team/KAddMember.vue +16 -22
  62. package/core/client/components/team/KGroupsActivity.vue +14 -0
  63. package/core/client/components/team/KMembersActivity.vue +12 -0
  64. package/core/client/components/team/KTagsActivity.vue +14 -0
  65. package/core/client/components/time/KDateTime.vue +23 -7
  66. package/core/client/components/time/KTimeControl.vue +142 -0
  67. package/core/client/components/tool/KExportTool.vue +57 -0
  68. package/core/client/composables/collection.js +0 -1
  69. package/core/client/composables/pwa.js +0 -1
  70. package/core/client/composables/schema.js +1 -1
  71. package/core/client/composables/session.js +30 -6
  72. package/core/client/exporter.js +147 -0
  73. package/core/client/i18n/core_en.json +91 -23
  74. package/core/client/i18n/core_fr.json +92 -23
  75. package/core/client/index.js +3 -0
  76. package/core/client/layout.js +34 -14
  77. package/core/client/local-storage.js +8 -6
  78. package/core/client/mixins/index.js +0 -1
  79. package/core/client/mixins/mixin.base-field.js +24 -2
  80. package/core/client/mixins/mixin.object-proxy.js +0 -1
  81. package/core/client/search.js +2 -1
  82. package/core/client/services/index.js +2 -1
  83. package/core/client/services/local-settings.service.js +4 -4
  84. package/core/client/theme.js +3 -3
  85. package/core/client/time.js +4 -0
  86. package/core/client/units.js +150 -5
  87. package/core/client/utils/index.js +13 -6
  88. package/core/client/utils/utils.account.js +1 -1
  89. package/core/client/utils/utils.colors.js +43 -0
  90. package/core/client/utils/utils.platform.js +0 -1
  91. package/core/client/utils/utils.pwa.js +14 -14
  92. package/core/client/utils/utils.session.js +1 -1
  93. package/core/client/utils/utils.shapes.js +270 -0
  94. package/core/client/utils/utils.time.js +37 -0
  95. package/core/common/permissions.js +3 -0
  96. package/core/common/schemas/settings.update.json +50 -29
  97. package/extras/css/core.variables.scss +3 -1
  98. package/extras/icons/wind-speed-0.svg +8 -0
  99. package/extras/icons/wind-speed-10.svg +8 -0
  100. package/extras/icons/wind-speed-100.svg +12 -0
  101. package/extras/icons/wind-speed-105.svg +13 -0
  102. package/extras/icons/wind-speed-15.svg +9 -0
  103. package/extras/icons/wind-speed-20.svg +9 -0
  104. package/extras/icons/wind-speed-25.svg +10 -0
  105. package/extras/icons/wind-speed-30.svg +10 -0
  106. package/extras/icons/wind-speed-35.svg +11 -0
  107. package/extras/icons/wind-speed-40.svg +11 -0
  108. package/extras/icons/wind-speed-45.svg +12 -0
  109. package/extras/icons/wind-speed-5.svg +9 -0
  110. package/extras/icons/wind-speed-50.svg +9 -0
  111. package/extras/icons/wind-speed-55.svg +10 -0
  112. package/extras/icons/wind-speed-60.svg +10 -0
  113. package/extras/icons/wind-speed-65.svg +11 -0
  114. package/extras/icons/wind-speed-70.svg +11 -0
  115. package/extras/icons/wind-speed-75.svg +12 -0
  116. package/extras/icons/wind-speed-80.svg +12 -0
  117. package/extras/icons/wind-speed-85.svg +13 -0
  118. package/extras/icons/wind-speed-90.svg +13 -0
  119. package/extras/icons/wind-speed-95.svg +14 -0
  120. package/extras/tours/map/navigation-bar.js +17 -15
  121. package/extras/tours/map/timeline.js +33 -33
  122. package/map/api/config/categories.cjs +4 -1
  123. package/map/api/hooks/hooks.catalog.js +39 -0
  124. package/map/api/hooks/hooks.features.js +23 -3
  125. package/map/api/hooks/hooks.query.js +65 -21
  126. package/map/api/models/projects.model.mongodb.js +8 -0
  127. package/map/api/services/catalog/catalog.hooks.js +5 -3
  128. package/map/api/services/features/features.hooks.js +18 -6
  129. package/map/api/services/index.js +22 -6
  130. package/map/api/services/projects/projects.hooks.js +118 -0
  131. package/map/client/capture.js +16 -0
  132. package/map/client/cesium/utils/index.js +4 -0
  133. package/map/client/cesium/utils/utils.events.js +30 -0
  134. package/map/client/cesium/utils/utils.features.js +8 -0
  135. package/map/client/cesium/utils/utils.popup.js +17 -0
  136. package/map/client/cesium/utils/utils.style.js +137 -0
  137. package/map/client/components/KCapture.vue +50 -0
  138. package/map/client/components/KCaptureTextArea.vue +53 -0
  139. package/map/client/components/KCompass.vue +2 -2
  140. package/map/client/components/KFeaturesChart.vue +1 -1
  141. package/map/client/components/KFeaturesFilter.vue +2 -2
  142. package/map/client/components/KLayerStyleForm.vue +288 -454
  143. package/map/client/components/KLevelSlider.vue +1 -1
  144. package/map/client/components/KNorth.vue +31 -0
  145. package/map/client/components/KProjectMenu.vue +88 -0
  146. package/map/client/components/KTimezoneMap.vue +36 -24
  147. package/map/client/components/catalog/KAddLayer.vue +3 -4
  148. package/map/client/components/catalog/KConnectLayer.vue +20 -4
  149. package/map/client/components/catalog/KCreateLayer.vue +1 -2
  150. package/map/client/components/catalog/KCreateProject.vue +100 -0
  151. package/map/client/components/catalog/KCreateView.vue +25 -2
  152. package/map/client/components/catalog/KLayersPanel.vue +24 -27
  153. package/map/client/components/catalog/KLayersSelector.vue +1 -1
  154. package/map/client/components/catalog/KProjectEditor.vue +91 -0
  155. package/map/client/components/catalog/KProjectManager.vue +60 -0
  156. package/map/client/components/catalog/KProjectSelector.vue +38 -0
  157. package/map/client/components/catalog/KProjectsPanel.vue +153 -0
  158. package/map/client/components/catalog/KSelectLayers.vue +96 -0
  159. package/map/client/components/catalog/KSelectViews.vue +96 -0
  160. package/map/client/components/catalog/KViewsPanel.vue +66 -30
  161. package/map/client/components/form/KDirectionField.vue +24 -5
  162. package/map/client/components/form/KLayerCategoryField.vue +12 -2
  163. package/map/client/components/form/KLocationField.vue +20 -5
  164. package/map/client/components/form/KOwsLayerField.vue +12 -2
  165. package/map/client/components/form/KOwsServiceField.vue +12 -2
  166. package/map/client/components/form/KSelectLayersField.vue +159 -0
  167. package/map/client/components/form/KSelectViewsField.vue +121 -0
  168. package/map/client/components/form/KTimezoneField.vue +24 -17
  169. package/map/client/components/legend/KColorScaleLegend.vue +6 -2
  170. package/map/client/components/legend/KLayerLegend.vue +71 -0
  171. package/map/client/components/legend/KLegend.vue +54 -51
  172. package/map/client/components/legend/KLegendRenderer.vue +5 -3
  173. package/map/client/components/legend/KSymbolsLegend.vue +12 -10
  174. package/map/client/components/legend/KVariablesLegend.vue +78 -0
  175. package/map/client/components/location/KGeocodersFilter.vue +2 -4
  176. package/map/client/components/location/KLocationCardSection.vue +8 -4
  177. package/map/client/components/location/KLocationMap.vue +48 -17
  178. package/map/client/components/location/KLocationSearch.vue +13 -3
  179. package/map/client/components/tools/KSearchTool.vue +17 -12
  180. package/map/client/components/widget/KElevationProfile.vue +16 -19
  181. package/map/client/components/widget/KMapillaryViewer.vue +21 -22
  182. package/map/client/components/widget/KTimeSeries.vue +35 -29
  183. package/map/client/composables/activity.js +15 -2
  184. package/map/client/composables/catalog.js +81 -0
  185. package/map/client/composables/highlight.js +45 -30
  186. package/map/client/composables/index.js +2 -0
  187. package/map/client/composables/location.js +25 -18
  188. package/map/client/composables/probe.js +4 -1
  189. package/map/client/composables/project.js +122 -0
  190. package/map/client/composables/weather.js +3 -3
  191. package/map/client/geolocation.js +1 -1
  192. package/map/client/globe.js +2 -0
  193. package/map/client/i18n/map_en.json +127 -76
  194. package/map/client/i18n/map_fr.json +128 -72
  195. package/map/client/index.js +3 -0
  196. package/map/client/init.js +17 -0
  197. package/map/client/leaflet/GSMaPLayer.js +16 -17
  198. package/map/client/leaflet/ShapeMarker.js +51 -0
  199. package/map/client/leaflet/TiledFeatureLayer.js +39 -9
  200. package/map/client/leaflet/TiledMeshLayer.js +13 -15
  201. package/map/client/leaflet/TiledWindLayer.js +6 -10
  202. package/map/client/leaflet/utils/index.js +4 -0
  203. package/map/client/leaflet/utils/utils.events.js +41 -0
  204. package/map/client/leaflet/utils/utils.popup.js +21 -0
  205. package/map/client/leaflet/utils/utils.style.js +195 -0
  206. package/map/client/leaflet/utils/utils.tiles.js +87 -0
  207. package/map/client/map.js +2 -0
  208. package/map/client/mixins/globe/mixin.base-globe.js +39 -18
  209. package/map/client/mixins/globe/mixin.geojson-layers.js +139 -69
  210. package/map/client/mixins/globe/mixin.popup.js +2 -1
  211. package/map/client/mixins/globe/mixin.style.js +6 -4
  212. package/map/client/mixins/globe/mixin.tooltip.js +8 -3
  213. package/map/client/mixins/map/mixin.base-map.js +53 -28
  214. package/map/client/mixins/map/mixin.edit-layers.js +15 -15
  215. package/map/client/mixins/map/mixin.forecast-layers.js +3 -1
  216. package/map/client/mixins/map/mixin.geojson-layers.js +60 -20
  217. package/map/client/mixins/map/mixin.georaster-layers.js +4 -11
  218. package/map/client/mixins/map/mixin.heatmap-layers.js +1 -1
  219. package/map/client/mixins/map/mixin.popup.js +2 -1
  220. package/map/client/mixins/map/mixin.style.js +4 -67
  221. package/map/client/mixins/map/mixin.tiled-mesh-layers.js +2 -1
  222. package/map/client/mixins/map/mixin.tiled-wind-layers.js +4 -2
  223. package/map/client/mixins/map/mixin.tooltip.js +2 -1
  224. package/map/client/mixins/mixin.activity.js +71 -192
  225. package/map/client/mixins/mixin.catalog-panel.js +6 -6
  226. package/map/client/mixins/mixin.context.js +12 -9
  227. package/map/client/mixins/mixin.feature-service.js +29 -300
  228. package/map/client/mixins/mixin.weacast.js +11 -17
  229. package/map/client/pixi-utils.js +1 -1
  230. package/map/client/planets.js +66 -0
  231. package/map/client/utils/index.js +6 -0
  232. package/map/client/utils/utils.capture.js +176 -0
  233. package/map/client/utils/utils.catalog.js +166 -0
  234. package/map/client/utils/utils.features.js +364 -0
  235. package/map/client/utils/utils.js +0 -151
  236. package/map/client/utils/utils.layers.js +175 -0
  237. package/map/client/utils/utils.location.js +91 -23
  238. package/map/client/utils/utils.project.js +8 -0
  239. package/map/client/utils/utils.schema.js +0 -1
  240. package/map/client/utils/utils.style.js +309 -0
  241. package/map/client/utils.all.js +2 -2
  242. package/map/client/utils.globe.js +1 -1
  243. package/map/client/utils.map.js +1 -1
  244. package/map/common/permissions.js +2 -0
  245. package/map/common/schemas/capture.create.json +132 -0
  246. package/map/common/schemas/projects.create.json +52 -0
  247. package/map/common/schemas/projects.update.json +52 -0
  248. package/map/common/wms-utils.js +8 -3
  249. package/package.json +6 -5
  250. package/test/api/core/account.test.js +20 -0
  251. package/test/api/core/config/default.cjs +16 -3
  252. package/test/api/core/import-export.test.js +86 -0
  253. package/test/api/core/test-log-2024-01-04.log +14 -0
  254. package/test/api/map/catalog.test.js +164 -0
  255. package/test/api/map/index.test.js +25 -61
  256. package/test/api/map/test-log-2024-01-04.log +2 -0
  257. package/test/api/map/test-log-2024-01-11.log +1 -0
  258. package/test/api/map/test-log-2024-01-25.log +19 -0
  259. package/test/client/core/layout.js +24 -5
  260. package/test/client/core/utils.js +7 -0
  261. package/test/client/map/catalog.js +78 -1
  262. package/test/client/map/time.js +2 -1
  263. package/core/client/components/screen/KEndpointScreen.vue +0 -80
  264. package/core/client/mixins/mixin.account.js +0 -61
  265. package/extras/icons/kdk.png +0 -0
  266. package/map/api/services/geocoder/geocoder.service.js +0 -79
  267. package/map/client/cesium/utils.js +0 -133
  268. package/map/client/components/KCaptureToolbar.vue +0 -155
  269. package/map/client/components/KColorLegend.vue +0 -349
  270. package/map/client/components/KTimeline.vue +0 -293
  271. package/map/client/components/KUrlLegend.vue +0 -122
  272. package/map/client/leaflet/utils.js +0 -246
package/.travis.test.sh CHANGED
@@ -3,23 +3,56 @@
3
3
  check_code()
4
4
  {
5
5
  if [ $1 -eq 1 ]; then
6
- echo "$2 has failed [error: $1]"
7
- exit 1
6
+ echo "$2 has failed [error: $1]"
7
+ exit 1
8
8
  fi
9
9
  }
10
10
 
11
+ AGE_VERSION=1.1.1
12
+ SOPS_VERSION=3.8.1
13
+ TMP_PATH="$(mktemp -d -p "${XDG_RUNTIME_DIR:-}" kalisio.XXXXXX)"
14
+
15
+ install_age() {
16
+ local DL_PATH="$TMP_PATH/age"
17
+ mkdir "$DL_PATH" && pushd "$DL_PATH" || exit
18
+ wget -q https://github.com/FiloSottile/age/releases/download/v${AGE_VERSION}/age-v${AGE_VERSION}-linux-amd64.tar.gz
19
+ # no checksum ...
20
+ tar xf age-v${AGE_VERSION}-linux-amd64.tar.gz
21
+ cp age/age "$HOME/.local/bin"
22
+ popd || exit
23
+ }
24
+
25
+ install_sops() {
26
+ local DL_PATH="$TMP_PATH/sops"
27
+ mkdir "$DL_PATH" && pushd "$DL_PATH" || exit
28
+ wget -q https://github.com/getsops/sops/releases/download/v${SOPS_VERSION}/sops-v${SOPS_VERSION}.linux.amd64
29
+ wget -q https://github.com/getsops/sops/releases/download/v${SOPS_VERSION}/sops-v${SOPS_VERSION}.checksums.txt
30
+ sha256sum --ignore-missing --quiet -c sops-v${SOPS_VERSION}.checksums.txt
31
+ cp sops-v${SOPS_VERSION}.linux.amd64 "$HOME/.local/bin/sops"
32
+ chmod a+x "$HOME/.local/bin/sops"
33
+ popd || exit
34
+ }
35
+
36
+ # Make sure that folder exists, with Travis CI it's already in the PATH
37
+ mkdir -p "$HOME/.local/bin"
38
+ install_age
39
+ install_sops
40
+
11
41
  echo -e "machine github.com\n login $GITHUB_TOKEN" > ~/.netrc
12
42
 
13
43
  # Setup KDK
14
44
  yarn install
15
45
 
16
- # Clone the workspace
17
- git clone https://github.com/kalisio/kdk-workspaces workspace
18
-
19
46
  # Clone others direct dependencies we'd like to use for testing
20
47
  git clone https://github.com/kalisio/feathers-distributed && cd feathers-distributed && yarn install && yarn link && cd ..
21
48
  yarn link @kalisio/feathers-distributed
22
49
 
50
+ git clone https://github.com/kalisio/feathers-s3 && cd feathers-s3 && yarn install && yarn link && cd ..
51
+ yarn link @kalisio/feathers-s3
52
+
53
+ git clone https://github.com/kalisio/feathers-import-export && cd feathers-import-export && yarn install && yarn link && yarn link @kalisio/feathers-s3 && cd ..
54
+ yarn link @kalisio/feathers-import-export
55
+
23
56
  git clone https://github.com/kalisio/feathers-webpush && cd feathers-webpush && yarn install && yarn link && cd ..
24
57
  yarn link @kalisio/feathers-webpush
25
58
 
@@ -30,11 +63,10 @@ yarn link @weacast/core
30
63
  yarn link @weacast/gfs
31
64
  yarn link @weacast/probe
32
65
 
33
- # Read extra environment variables (merges common and flavor env)
34
- cp workspace/.env .env
35
- set -a
36
- . .env
37
- set +a
66
+ # Clone the development project and configure the env
67
+ git clone https://oauth2:$GITHUB_TOKEN@github.com/kalisio/development.git "development"
68
+ source development/workspaces/libs/libs.sh kdk
38
69
 
70
+ # Run the test
39
71
  yarn test
40
72
  check_code $? "Running tests"
package/README.md CHANGED
@@ -1,10 +1,10 @@
1
- [![KDK](https://s3.eu-central-1.amazonaws.com/kalisioscope/kdk/kdk-logo-black-512x168.png)](https://kalisio.github.io/kdk/)
1
+ [![KDK](https://s3.eu-central-1.amazonaws.com/kalisioscope/kdk/kdk-logo-color-512x192.png)](https://kalisio.github.io/kdk/)
2
2
 
3
3
  [![Latest Release](https://img.shields.io/github/v/tag/kalisio/kdk?sort=semver&label=latest)](https://github.com/kalisio/kdk/releases)
4
4
  [![Build Status](https://app.travis-ci.com/kalisio/kdk.svg?branch=master)](https://app.travis-ci.com/kalisio/kdk)
5
5
  [![Code Climate](https://codeclimate.com/github/kalisio/kdk/badges/gpa.svg)](https://codeclimate.com/github/kalisio/kdk)
6
6
  [![Test Coverage](https://codeclimate.com/github/kalisio/kdk/badges/coverage.svg)](https://codeclimate.com/github/kalisio/kdk/coverage)
7
- [![Dependency Status](https://img.shields.io/david/kalisio/kdk.svg?style=flat-square)](https://david-dm.org/kalisio/kdk)
7
+ [![Dependency Status](https://img.shields.io/librariesio/github/kalisio/kdk?style=flat-square)](https://david-dm.org/kalisio/kdk)
8
8
  [![Documentation](https://img.shields.io/badge/documentation-available-brightgreen.svg)](https://kalisio.github.io/kdk/)
9
9
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
10
10
 
@@ -174,7 +174,7 @@ async function createService (name, app, options = {}) {
174
174
  paginate,
175
175
  multi: true,
176
176
  whitelist: [
177
- '$exists', '$and', '$or', '$eq', '$elemMatch', '$distinct', '$groupBy', '$group', '$regex',
177
+ '$exists', '$and', '$or', '$not', '$eq', '$elemMatch', '$distinct', '$groupBy', '$group', '$regex',
178
178
  '$text', '$search', '$caseSensitive', '$language', '$diacriticSensitive',
179
179
  '$aggregate', '$near', '$nearSphere', '$geoIntersects', '$geoWithin',
180
180
  '$maxDistance', '$minDistance', '$geometry', '$box', '$polygon', '$center', '$centerSphere'
@@ -182,7 +182,7 @@ async function createService (name, app, options = {}) {
182
182
  }, options)
183
183
  if (serviceOptions.disabled) return undefined
184
184
  // For DB services a model has to be provided
185
- const fileName = serviceOptions.fileName || name
185
+ const fileName = serviceOptions.modelName || name
186
186
 
187
187
  let dbService = false
188
188
  try {
@@ -523,6 +523,11 @@ export function kdk (config = {}) {
523
523
  service = await configureService(name, service, servicesPath)
524
524
  return service
525
525
  }
526
+ // This is used to declare existing service
527
+ app.declareService = function (name, service, serviceOptions) {
528
+ service = declareService(name, app, service, serviceOptions)
529
+ return service
530
+ }
526
531
  // This is used to create standard services
527
532
  app.createService = async function (name, options) {
528
533
  const service = await createService(name, app, options)
@@ -15,6 +15,22 @@ const { ObjectID } = mongodb
15
15
  const { oauth, OAuthStrategy } = OAuth
16
16
  const { NotAuthenticated } = errors
17
17
 
18
+ export class Authentication extends AuthenticationService {
19
+ // Feathers does not seem to take input payload into account when renewing the token,
20
+ // see https://github.com/feathersjs/feathers/issues/3419
21
+ async getPayload (authResult, params) {
22
+ // Params can override defaults
23
+ if (params.payload) {
24
+ return params.payload
25
+ } else if (authResult.authentication && authResult.authentication.payload) {
26
+ // Avoid conflicting with default token options added when generating a new token
27
+ return _.omit(authResult.authentication.payload, ['aud', 'iss', 'exp', 'sub', 'iat', 'jti', 'nbf'])
28
+ } else {
29
+ return {}
30
+ }
31
+ }
32
+ }
33
+
18
34
  export class AuthenticationProviderStrategy extends OAuthStrategy {
19
35
  async getEntityData (profile, entity) {
20
36
  const createEntity = _.isNil(entity)
@@ -151,7 +167,7 @@ export default function auth (app) {
151
167
  if (config.oauth) config.oauth = _.omitBy(config.oauth, _.isNil)
152
168
  app.set('authentication', config)
153
169
 
154
- const authentication = new AuthenticationService(app)
170
+ const authentication = new Authentication(app)
155
171
  const strategies = config.authStrategies || []
156
172
  if (strategies.includes('jwt')) authentication.register('jwt', new JWTAuthenticationStrategy())
157
173
  if (strategies.includes('local')) authentication.register('local', new LocalStrategy())
package/core/api/db.js CHANGED
@@ -72,8 +72,13 @@ export function objectifyIDs (object) {
72
72
  export function toObjectIDs (object, properties) {
73
73
  properties.forEach(property => {
74
74
  const value = _.get(object, property)
75
- const id = createObjectID(value)
76
- if (id) _.set(object, property, id)
75
+ if (Array.isArray(value)) {
76
+ const ids = value.map(id => createObjectID(id)).filter(id => id)
77
+ if (ids.length > 0) _.set(object, property, ids)
78
+ } else {
79
+ const id = createObjectID(value)
80
+ if (id) _.set(object, property, id)
81
+ }
77
82
  })
78
83
  }
79
84
 
@@ -14,6 +14,7 @@ export async function verifyGuest (hook) {
14
14
  }
15
15
  const app = hook.app
16
16
  const user = hook.result.user
17
+ if (!user) return hook
17
18
  debug('verifyGuest hook called on ', user._id)
18
19
 
19
20
  // Check whether the user has been inivted. If not, nothing to do
@@ -42,6 +43,7 @@ export async function consentGuest (hook) {
42
43
  }
43
44
  const app = hook.app
44
45
  const user = hook.result.user
46
+ if (!user) return hook
45
47
  debug('consentGuest hook called on ', user._id)
46
48
 
47
49
  // Check whether the user has been invited. If not, nothing to do
@@ -66,9 +68,9 @@ export async function consentGuest (hook) {
66
68
 
67
69
  export function discardAuthenticationProviders (hook) {
68
70
  const providers = hook.app.authenticationProviders || []
69
-
71
+
70
72
  // Iterate through known providers
71
73
  for (const provider of providers) {
72
74
  discard(provider)(hook)
73
75
  }
74
- }
76
+ }
@@ -186,9 +186,19 @@ export async function authorise (hook) {
186
186
  if (checkAuthorisation) {
187
187
  // Build ability for user
188
188
  const authorisationService = hook.app.getService('authorisations')
189
- const abilities = await authorisationService.getAbilities(hook.params.user)
189
+ // If no user we allow for a stateless token with permissions inside
190
+ let subject = hook.params.user
191
+ if (!subject) {
192
+ const payload = _.get(hook.params, 'authentication.payload')
193
+ // Token targeting API gateway (sub = keyId) or app used through iframe (appId = keyId)
194
+ if (payload && (payload.sub || payload.appId)) {
195
+ subject = Object.assign({ _id: (payload.sub || payload.appId) }, payload)
196
+ }
197
+ }
198
+ const abilities = await authorisationService.getAbilities(subject)
190
199
  hook.params.abilities = abilities
191
- debug('User abilities are', abilities.rules)
200
+ if (hook.params.user) debug('User abilities are', abilities.rules)
201
+ else debug('Stateless abilities are', abilities.rules)
192
202
 
193
203
  // Check for access to service fisrt
194
204
  if (!hasServiceAbilities(abilities, hook.service)) {
@@ -8,7 +8,7 @@ import common from 'feathers-hooks-common'
8
8
  import makeDebug from 'debug'
9
9
 
10
10
  const { Conflict, BadRequest } = errors
11
- const { discard, disallow, getItems, replaceItems } = common
11
+ const { getItems, replaceItems } = common
12
12
  const sift = siftModule.default
13
13
  const debug = makeDebug('kdk:core:model:hooks')
14
14
 
@@ -181,7 +181,7 @@ export async function populatePreviousObject (hook) {
181
181
  throw new Error('The \'populatePreviousObject\' hook should only be used as a \'before\' hook.')
182
182
  }
183
183
  const item = getItems(hook)
184
- const id = (hook.id ? hook.id : item._id)
184
+ const id = (hook.id ? hook.id : _.get(item, '_id'))
185
185
  // Retrieve previous version of the item and make it available to next hooks
186
186
  if (id) {
187
187
  hook.params.previousItem = await hook.service.get(id.toString())
@@ -264,20 +264,20 @@ export function checkUnique (options = {}) {
264
264
  // Prevent patch service calls from changing certain fields.
265
265
  // Based on https://hooks-common.feathersjs.com/hooks.html#preventchanges
266
266
  // but updated to handle dot notation
267
- export function preventChanges(ifThrow, fieldNames) {
267
+ export function preventChanges (ifThrow, fieldNames) {
268
268
  return (hook) => {
269
269
  if ((hook.type !== 'before') || (hook.method !== 'patch')) {
270
270
  throw new Error('The \'preventChanges\' hook should only be used as a \'before\' patch hook.')
271
271
  }
272
272
 
273
- let data = { ...hook.data }
273
+ const data = { ...hook.data }
274
274
  // Check all data fields
275
275
  _.forOwn(hook.data, (value, key) => {
276
276
  fieldNames.forEach(name => {
277
277
  // If a prevented field is found or dot notation with a prevented field is used
278
278
  if ((key === name) || key.startsWith(`${name}.`)) {
279
279
  if (ifThrow) {
280
- throw new BadRequest(`Field ${name} may not be patched. (preventChanges)`);
280
+ throw new BadRequest(`Field ${name} may not be patched. (preventChanges)`)
281
281
  }
282
282
  delete data[key]
283
283
  }
@@ -1,10 +1,7 @@
1
1
  import _ from 'lodash'
2
2
  import makeDebug from 'debug'
3
- import errors from '@feathersjs/errors'
4
3
  const debug = makeDebug('kdk:core:organisations:hooks')
5
4
 
6
- const { Forbidden } = errors
7
-
8
5
  export async function createOrganisationServices (hook) {
9
6
  if (hook.type !== 'after') {
10
7
  throw new Error('The \'createOrganisationServices\' hook should only be used as a \'after\' hook.')
@@ -153,4 +150,3 @@ export function removeOrganisationResources (resourceScope) {
153
150
  return hook
154
151
  }
155
152
  }
156
-
@@ -8,11 +8,15 @@ export default {
8
8
  all: [],
9
9
  find: [],
10
10
  get: [],
11
- create: [when(hook => hook.data.action === 'resetPwdShort' || hook.data.action === 'passwordChange',
12
- enforcePasswordPolicy({ userAsItem: false, passwordField: 'value.password' }))],
11
+ create: [
12
+ when(
13
+ (hook) => ['passwordChange', 'resetPwdShort', 'verifySignupSetPasswordLong', 'verifySignupSetPasswordShort'].includes(hook.data.action),
14
+ enforcePasswordPolicy({ userAsItem: false, passwordField: 'value.password' })
15
+ ),
16
+ ],
13
17
  update: [],
14
18
  patch: [],
15
- remove: []
19
+ remove: [],
16
20
  },
17
21
 
18
22
  after: {
@@ -22,7 +26,7 @@ export default {
22
26
  create: [],
23
27
  update: [],
24
28
  patch: [],
25
- remove: []
29
+ remove: [],
26
30
  },
27
31
 
28
32
  error: {
@@ -32,6 +36,6 @@ export default {
32
36
  create: [],
33
37
  update: [],
34
38
  patch: [],
35
- remove: []
36
- }
39
+ remove: [],
40
+ },
37
41
  }
@@ -103,7 +103,7 @@ export default function (name, app, options) {
103
103
 
104
104
  const servicePath = app.get('apiPath') + '/account'
105
105
  const userService = app.getService('users')
106
-
106
+
107
107
  return new AccountService(app, {
108
108
  // By default it is impossible to reset password if email is not verified
109
109
  // The problem is that if you loose your password before validating your email you are blocked,
@@ -1,12 +1,14 @@
1
+ import commonHooks from 'feathers-hooks-common'
2
+
1
3
  export default {
2
4
  before: {
3
5
  all: [],
4
- find: [],
5
- get: [],
6
+ find: [commonHooks.disallow()],
7
+ get: [commonHooks.disallow()],
6
8
  create: [],
7
- update: [],
8
- patch: [],
9
- remove: []
9
+ update: [commonHooks.disallow()],
10
+ patch: [commonHooks.disallow()],
11
+ remove: [commonHooks.disallow()]
10
12
  },
11
13
 
12
14
  after: {
@@ -0,0 +1,11 @@
1
+ import { Service } from '@kalisio/feathers-import-export'
2
+ import makeDebug from 'debug'
3
+
4
+ const debug = makeDebug('kdk:import-export:service')
5
+
6
+ export default function (name, app, options) {
7
+ const config = app.get('import-export')
8
+ debug('Creating import-export service with config ', config)
9
+ const s3ServicePath = app.get('apiPath') + '/' + (config.s3Service)
10
+ return new Service(Object.assign({ app }, config, { s3ServicePath }))
11
+ }
@@ -94,7 +94,10 @@ export default async function () {
94
94
  if (authConfig) {
95
95
  await app.createService('users', { modelsPath, servicesPath })
96
96
  debug('\'users\' service created')
97
- await app.createService('account', { servicesPath, methods: ['create', 'verifyEmail'] })
97
+ await app.createService('account', {
98
+ servicesPath,
99
+ methods: ['create', 'verifyEmail']
100
+ })
98
101
  debug('\'account\' service created')
99
102
  await app.createService('authorisations', { servicesPath })
100
103
  debug('\'authorisations\' service created')
@@ -106,6 +109,15 @@ export default async function () {
106
109
  debug('\'storage\' service created')
107
110
  }
108
111
 
112
+ const importExportConfig = app.get('import-export')
113
+ if (importExportConfig) {
114
+ await app.createService('import-export', {
115
+ servicesPath,
116
+ events: ['import-created', 'import-completed', 'export-created', 'export-completed']
117
+ }, app)
118
+ debug('\'import-export\' service created')
119
+ }
120
+
109
121
  const orgConfig = app.get('organisations')
110
122
  if (orgConfig) {
111
123
  await createOrganisationService.call(app)
@@ -1,4 +1,3 @@
1
- import _ from 'lodash'
2
1
  import {
3
2
  serialize, updateAbilities, populatePreviousObject, hashPassword, disallowRegistration, allowLocalAuthentication,
4
3
  discardAuthenticationProviders, enforcePasswordPolicy, storePreviousPassword, sendNewSubscriptionEmail
@@ -49,11 +48,11 @@ export default {
49
48
  commonHooks.when(hook => hook.params.provider,
50
49
  commonHooks.discard('password'),
51
50
  commonHooks.discard('previousPasswords'),
52
- discardAuthenticationProviders),
51
+ discardAuthenticationProviders)
53
52
  // Hide profile for external user as it may contain personal information
54
53
  // However, this causes an issue: https://github.com/feathersjs-ecosystem/feathers-reactive/issues/214
55
54
  // So let the application decide what to do
56
- //commonHooks.when(isNotMe, commonHooks.discard('profile'))
55
+ // commonHooks.when(isNotMe, commonHooks.discard('profile'))
57
56
  ],
58
57
  find: [],
59
58
  get: [],
@@ -7,10 +7,10 @@ import feathers from '@feathersjs/client'
7
7
  import { io } from 'socket.io-client'
8
8
  import reactive from 'feathers-reactive/dist/feathers-reactive.js'
9
9
  import configuration from 'config'
10
- import { Platform } from 'quasar'
11
10
  import { permissions } from '../common/index.js'
12
11
  import { Store } from './store.js'
13
12
  import { Events } from './events.js'
13
+ import { LocalStorage } from './local-storage.js'
14
14
 
15
15
  // Setup log level
16
16
  if (_.get(configuration, 'logs.level')) {
@@ -22,10 +22,7 @@ if (_.get(configuration, 'logs.level')) {
22
22
  export function createClient (config) {
23
23
  // Initiate the client
24
24
  const api = feathers()
25
-
26
- function getBaseUrlStorageKey () {
27
- return config.appName.toLowerCase() + '-baseUrl'
28
- }
25
+ const baseUrlStorageKey = 'baseUrl'
29
26
 
30
27
  // Matchers that can be added to customize route guards
31
28
  let matchers = []
@@ -142,7 +139,7 @@ export function createClient (config) {
142
139
  }
143
140
  // Change the base URL/domain to be used (useful for mobile apps)
144
141
  api.setBaseUrl = function (baseUrl) {
145
- window.localStorage.setItem(getBaseUrlStorageKey(), baseUrl)
142
+ LocalStorage.set(baseUrlStorageKey, baseUrl)
146
143
  // Updating this setting live does not seem to work well in Feathers
147
144
  // For now the caller should simply "reload" the app
148
145
  /*
@@ -162,15 +159,19 @@ export function createClient (config) {
162
159
  }
163
160
  */
164
161
  }
165
-
162
+ // Get the base URL/domain to be used (useful for mobile apps)
166
163
  api.getBaseUrl = function () {
167
- // In case we are not in a mobile platform we can override the default app origin anyway
168
- let origin = (Platform.is.cordova ? config.domain : config.origin || window.location.origin)
164
+ // We can override the default app origin anyway
165
+ const origin = config.origin || window.location.origin
169
166
  // Check for registered custom base Url if any
170
- if (window.localStorage.getItem(getBaseUrlStorageKey())) {
171
- origin = window.localStorage.getItem(getBaseUrlStorageKey())
172
- }
173
- return origin
167
+ return LocalStorage.get(baseUrlStorageKey, origin)
168
+ }
169
+ // Helper fonctions to access/alter config used at creation time
170
+ api.getConfig = function (path) {
171
+ return (path ? _.get(config, path) : config)
172
+ }
173
+ api.setConfig = function (path, value) {
174
+ _.set(config, path, value)
174
175
  }
175
176
 
176
177
  api.can = function () {
@@ -287,7 +288,8 @@ export function createClient (config) {
287
288
  // eg it might be imported before another one updating the config.
288
289
  // It is up to the application to instanciate the client when required.
289
290
  export let api
290
- export function initializeApi () {
291
+ export function initializeApi (fn) {
291
292
  api = createClient(configuration)
293
+ if (fn) fn.call(api, configuration)
292
294
  return api
293
295
  }
@@ -11,12 +11,16 @@ export const Capabilities = {
11
11
  const content = await capabilities.json()
12
12
  logger.debug('[KDK] fetched capabilities:', JSON.stringify(content, null, 4))
13
13
  this.content = content
14
+ // Backend might override some defaults in client config
15
+ _.forOwn(_.pick(content, ['gateway']), (value, key) => {
16
+ api.setConfig(key, value)
17
+ })
14
18
  // Used to ensure backward compatibility
15
19
  Store.set('capabilities.api', content)
16
20
  Store.set('capabilities.client', _.pick(config, ['version', 'buildNumber']))
17
21
  },
18
- get (key) {
22
+ get (key, defaultValue) {
19
23
  if (!this.content) logger.error(new Error('Capabilities must be initialized first'))
20
- else return _.get(this.content, key)
24
+ else return _.get(this.content, key, defaultValue)
21
25
  }
22
26
  }
@@ -1,7 +1,17 @@
1
1
  <template>
2
2
  <div>
3
3
  <template v-for="component in avaiableComponents" :key="component.uid">
4
- <component
4
+ <Suspense v-if="component.suspense">
5
+ <component
6
+ v-if="component.isVisible && !component.isHidden"
7
+ :is="component.instance"
8
+ :context="context"
9
+ :renderer="component.renderer ? component.renderer: actionRenderer"
10
+ v-bind="component"
11
+ v-on="component.on ? { [component.on.event]: component.on.listener } : {}"
12
+ @triggered="onTriggered" />
13
+ </Suspense>
14
+ <component v-else
5
15
  v-if="component.isVisible && !component.isHidden"
6
16
  :is="component.instance"
7
17
  :context="context"
@@ -7,21 +7,23 @@
7
7
  :toolbar="toolbar"
8
8
  :width-policy="widthPolicy"
9
9
  >
10
- <!-- component with v-model -->
11
- <component
12
- v-if="_.has(attrs, 'v-model')"
13
- ref="componentRef"
14
- :is="computedComponent"
15
- v-model="computedModel"
16
- v-bind="computedProps"
17
- />
18
- <!-- component without v-model -->
19
- <component
20
- v-else
21
- ref="componentRef"
22
- :is="computedComponent"
23
- v-bind="computedProps"
24
- />
10
+ <Suspense>
11
+ <!-- component with v-model -->
12
+ <component
13
+ v-if="_.has(attrs, 'v-model')"
14
+ ref="componentRef"
15
+ :is="computedComponent"
16
+ v-model="computedModel"
17
+ v-bind="computedProps"
18
+ />
19
+ <!-- component without v-model -->
20
+ <component
21
+ v-else
22
+ ref="componentRef"
23
+ :is="computedComponent"
24
+ v-bind="computedProps"
25
+ />
26
+ </Suspense>
25
27
  </KModal>
26
28
  </template>
27
29
 
@@ -112,7 +112,7 @@ const xlMinWidths = { wide: 90, medium: 55, narrow: 25 }
112
112
  const computedStyle = computed(() => {
113
113
  // compute the modal max height
114
114
  const screenHeight = $q.screen.height
115
- const modalMaxHeight = props.maximized ? screenHeight : 0.8 * screenHeight
115
+ const modalMaxHeight = props.maximized ? screenHeight : 0.9 * screenHeight
116
116
  // compute the scroll area max height
117
117
  // take into account the header and footer height
118
118
  let contentMaxHeight = modalMaxHeight - headerHeight.value
@@ -2,7 +2,7 @@
2
2
  <div class="column items-center">
3
3
  <!-- KDK attribution -->
4
4
  <div class="row justify-center items-center">
5
- <div>
5
+ <div class="text-caption">
6
6
  {{ $t('KSponsor.KDK_POWERED') }}
7
7
  </div>
8
8
  <KAction
@@ -63,6 +63,10 @@ const props = defineProps({
63
63
  dense: {
64
64
  type: Boolean,
65
65
  default: false
66
+ },
67
+ isExpanded: {
68
+ type: Boolean,
69
+ default: false
66
70
  }
67
71
  })
68
72
 
@@ -70,7 +74,7 @@ const props = defineProps({
70
74
  const scrollArea = ref(null)
71
75
  const scrollAreaKey = ref(0)
72
76
  const isExpandable = ref(false)
73
- const isExpanded = ref(false)
77
+ const isExpanded = ref(props.isExpanded)
74
78
  const isScrollable = ref(false)
75
79
 
76
80
  // computed
@@ -74,8 +74,7 @@ const defaultActions = [{
74
74
  okAction: 'CLOSE',
75
75
  widthPolicy: 'narrow'
76
76
  }
77
- }
78
- ]
77
+ }]
79
78
  if (!_.isNil(bugReport.address)) {
80
79
  defaultActions.unshift({
81
80
  id: 'report-bug',
@@ -78,6 +78,7 @@ import { ref, computed, onBeforeUnmount } from 'vue'
78
78
  import { openURL, useQuasar } from 'quasar'
79
79
  import { Store, api } from '../..'
80
80
  import { loadComponent } from '../../utils'
81
+ import { LocalStorage } from '../../local-storage.js'
81
82
  import KAction from '../KAction.vue'
82
83
 
83
84
  // Data
@@ -94,11 +95,8 @@ const dense = computed(() => {
94
95
  })
95
96
 
96
97
  // functions
97
- function getWelcomeKey () {
98
- return _.get(config, 'appName').toLowerCase() + '-welcome'
99
- }
100
98
  function show () {
101
- const canShow = window.localStorage.getItem(getWelcomeKey())
99
+ const canShow = LocalStorage.get('welcome')
102
100
  // Introduction is only for logged users
103
101
  showWelcome.value = (_.isNil(canShow) ? _.get(config, 'layout.welcome', true) : JSON.parse(canShow))
104
102
  }
@@ -106,7 +104,7 @@ function hide () {
106
104
  showWelcome.value = false
107
105
  }
108
106
  function onToggleIntroduction (toggle) {
109
- window.localStorage.setItem(getWelcomeKey(), JSON.stringify(!toggle))
107
+ LocalStorage.set('welcome', !toggle)
110
108
  }
111
109
  function onOnlineHelp () {
112
110
  const onlineHelp = _.get(config, 'appOnlineHelp')