@kalisio/kdk 2.4.1 → 2.5.2

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 (638) hide show
  1. package/core/api/application.js +12 -12
  2. package/core/api/authentication.js +51 -7
  3. package/core/api/hooks/hooks.authentication.js +1 -59
  4. package/core/api/hooks/hooks.authorisations.js +9 -104
  5. package/core/api/hooks/hooks.model.js +4 -0
  6. package/core/api/hooks/hooks.push.js +18 -14
  7. package/core/api/hooks/hooks.users.js +0 -91
  8. package/core/api/hooks/index.js +0 -2
  9. package/core/api/services/account/account.service.js +1 -1
  10. package/core/api/services/authorisations/authorisations.service.js +28 -31
  11. package/core/api/services/index.js +42 -50
  12. package/core/api/services/messages/messages.hooks.js +4 -3
  13. package/core/api/services/users/users.hooks.js +4 -3
  14. package/core/api/services/users/users.service.js +5 -0
  15. package/core/client/api.js +182 -71
  16. package/core/client/broadcaster.js +20 -0
  17. package/core/client/capabilities.js +17 -7
  18. package/core/client/components/KActivity.vue +29 -34
  19. package/core/client/components/KAvatar.vue +0 -6
  20. package/core/client/components/KChip.vue +142 -39
  21. package/core/client/components/KContent.vue +13 -32
  22. package/core/client/components/KDialog.vue +29 -8
  23. package/core/client/components/KEditor.vue +120 -0
  24. package/core/client/components/KFollower.vue +75 -0
  25. package/core/client/components/KLogo.vue +2 -3
  26. package/core/client/components/KModal.vue +30 -10
  27. package/core/client/components/KSponsor.vue +1 -1
  28. package/core/client/components/KTextArea.vue +2 -5
  29. package/core/client/components/account/KDeleteAccountManager.vue +1 -1
  30. package/core/client/components/account/KProfile.vue +52 -14
  31. package/core/client/components/account/KSubscription.vue +19 -9
  32. package/core/client/components/account/KSubscriptionsManager.vue +10 -11
  33. package/core/client/components/action/KAction.vue +44 -24
  34. package/core/client/components/action/KBugReportAction.vue +4 -5
  35. package/core/client/components/action/KToggleStickyVisibility.vue +41 -0
  36. package/core/client/components/action/KToggleWidgetVisibility.vue +41 -0
  37. package/core/client/components/app/KPlatform.vue +122 -35
  38. package/core/client/components/app/KRequestProgressBar.vue +59 -0
  39. package/core/client/components/app/KSettings.vue +13 -2
  40. package/core/client/components/app/KTour.vue +2 -2
  41. package/core/client/components/chart/KTimeSeriesChart.vue +11 -3
  42. package/core/client/components/collection/KCard.vue +27 -33
  43. package/core/client/components/collection/KCardSection.vue +3 -23
  44. package/core/client/components/collection/KColumn.vue +0 -5
  45. package/core/client/components/collection/KDescriptionCardSection.vue +10 -5
  46. package/core/client/components/collection/KFilterView.vue +15 -0
  47. package/core/client/components/collection/KGrid.vue +4 -9
  48. package/core/client/components/collection/KHistory.vue +0 -5
  49. package/core/client/components/collection/KHistoryEntry.vue +0 -2
  50. package/core/client/components/collection/KItem.vue +1 -2
  51. package/core/client/components/collection/KSearchFilterControl.vue +139 -0
  52. package/core/client/components/collection/KTable.vue +1 -4
  53. package/core/client/components/collection/KTagsFilterControl.vue +70 -0
  54. package/core/client/components/collection/KTagsFilterView.vue +61 -0
  55. package/core/client/components/collection/KTimeFilterControl.vue +40 -0
  56. package/core/client/components/collection/KTimeFilterView.vue +106 -0
  57. package/core/client/components/collection/KTimeLine.vue +18 -11
  58. package/core/client/components/document/KBrowser.vue +283 -0
  59. package/core/client/components/document/KCsv.vue +52 -0
  60. package/core/client/components/document/KDocument.vue +19 -5
  61. package/core/client/components/document/KImage.vue +50 -19
  62. package/core/client/components/document/KMarkdown.vue +10 -2
  63. package/core/client/components/document/KUploader.vue +126 -0
  64. package/core/client/components/document/KVideo.vue +39 -0
  65. package/core/client/components/form/KDateField.vue +70 -0
  66. package/core/client/components/form/KDateTimeRangeField.vue +6 -17
  67. package/core/client/components/form/KDatetimeField.vue +6 -13
  68. package/core/client/components/form/KForm.vue +8 -8
  69. package/core/client/components/form/KOptionsField.vue +2 -0
  70. package/core/client/components/form/KResolutionField.vue +54 -52
  71. package/core/client/components/form/KSelectField.vue +27 -13
  72. package/core/client/components/form/KTextareaField.vue +23 -5
  73. package/core/client/components/graphics/KIcon.vue +64 -0
  74. package/core/client/components/index.js +1 -3
  75. package/core/client/components/input/KColorPicker.vue +70 -0
  76. package/core/client/components/input/KIconPicker.vue +188 -0
  77. package/core/client/components/input/KShapePicker.vue +81 -0
  78. package/core/client/components/input/index.js +7 -1
  79. package/core/client/components/layout/KFab.vue +1 -1
  80. package/core/client/components/layout/KLayout.vue +14 -2
  81. package/core/client/components/layout/KOpener.vue +9 -11
  82. package/core/client/components/layout/KPage.vue +31 -17
  83. package/core/client/components/layout/KWindow.vue +34 -18
  84. package/core/client/components/menu/KMenu.vue +52 -36
  85. package/core/client/components/menu/KSubMenu.vue +105 -0
  86. package/core/client/components/messages/KMessageCard.vue +207 -0
  87. package/core/client/components/messages/KMessageComposer.vue +199 -0
  88. package/core/client/components/messages/KMessagesTimeLine.vue +137 -0
  89. package/core/client/components/messages/index.js +7 -0
  90. package/core/client/components/screen/KErrorScreen.vue +2 -3
  91. package/core/client/components/screen/KLogoutScreen.vue +3 -1
  92. package/core/client/components/screen/KOAuthLoginScreen.vue +15 -0
  93. package/core/client/components/screen/KOAuthLogoutScreen.vue +33 -0
  94. package/core/client/components/screen/KUnauthorizedScreen.vue +16 -0
  95. package/core/client/components/time/KAbsoluteTimeRange.vue +7 -14
  96. package/core/client/components/time/KDate.vue +55 -28
  97. package/core/client/components/time/KDateTime.vue +93 -37
  98. package/core/client/components/time/KDateTimeRange.vue +197 -52
  99. package/core/client/components/time/KTime.vue +55 -27
  100. package/core/client/composables/activity.js +40 -30
  101. package/core/client/composables/{counter.js → collection-counter.js} +2 -4
  102. package/core/client/composables/collection-filter.js +111 -0
  103. package/core/client/composables/collection-timerange.js +56 -0
  104. package/core/client/composables/collection.js +13 -11
  105. package/core/client/composables/context.js +92 -0
  106. package/core/client/composables/errors.js +83 -0
  107. package/core/client/composables/index.js +5 -1
  108. package/core/client/composables/layout.js +14 -11
  109. package/core/client/composables/messages.js +4 -4
  110. package/core/client/composables/pwa.js +20 -27
  111. package/core/client/composables/schema.js +1 -1
  112. package/core/client/composables/screen.js +21 -9
  113. package/core/client/composables/selection.js +16 -4
  114. package/core/client/composables/session.js +13 -7
  115. package/core/client/composables/store.js +2 -1
  116. package/core/client/context.js +38 -0
  117. package/core/client/directives/v-hover.js +7 -4
  118. package/core/client/document.js +43 -15
  119. package/core/client/events.js +2 -2
  120. package/core/client/exporter.js +5 -4
  121. package/core/client/filter.js +1 -8
  122. package/core/client/guards.js +3 -3
  123. package/core/client/hooks/hooks.logger.js +1 -1
  124. package/core/client/hooks/hooks.offline.js +32 -0
  125. package/core/client/hooks/index.js +2 -1
  126. package/core/client/i18n/core_en.json +95 -268
  127. package/core/client/i18n/core_fr.json +181 -353
  128. package/core/client/index.js +22 -8
  129. package/core/client/layout.js +64 -25
  130. package/core/client/local-cache.js +67 -0
  131. package/core/client/local-storage.js +6 -2
  132. package/core/client/mixins/index.js +0 -1
  133. package/core/client/mixins/mixin.base-activity.js +22 -10
  134. package/core/client/mixins/mixin.base-editor.js +1 -1
  135. package/core/client/mixins/mixin.base-field.js +10 -1
  136. package/core/client/mixins/mixin.base-item.js +14 -11
  137. package/core/client/mixins/mixin.service.js +1 -5
  138. package/core/client/platform.js +44 -0
  139. package/core/client/readers/reader.blob.js +3 -3
  140. package/core/client/readers/reader.csv.js +2 -2
  141. package/core/client/readers/reader.json.js +2 -2
  142. package/core/client/services/index.js +7 -11
  143. package/core/client/storage.js +43 -8
  144. package/core/client/template-context.js +14 -14
  145. package/core/client/time.js +2 -2
  146. package/core/client/units.js +7 -4
  147. package/core/client/utils/index.js +7 -5
  148. package/core/client/utils/utils.collection.js +71 -0
  149. package/core/client/utils/utils.colors.js +29 -8
  150. package/core/client/utils/utils.content.js +14 -14
  151. package/core/client/utils/utils.files.js +17 -0
  152. package/core/client/utils/utils.items.js +4 -0
  153. package/core/client/utils/utils.math.js +18 -1
  154. package/core/client/utils/utils.push.js +22 -13
  155. package/core/client/utils/utils.screen.js +6 -2
  156. package/core/client/utils/utils.services.js +42 -0
  157. package/core/client/utils/utils.session.js +48 -12
  158. package/core/client/utils/utils.shapes.js +15 -11
  159. package/core/common/permissions.js +3 -108
  160. package/core/common/schemas/messages.update.json +16 -0
  161. package/core/common/schemas/settings.update.json +27 -8
  162. package/core/common/utils.js +2 -0
  163. package/core/common/utils.offline.js +38 -0
  164. package/coverage/core/api/application.js.html +296 -296
  165. package/coverage/core/api/authentication.js.html +206 -74
  166. package/coverage/core/api/db.js.html +61 -61
  167. package/coverage/core/api/hooks/hooks.authentication.js.html +15 -189
  168. package/coverage/core/api/hooks/hooks.authorisations.js.html +172 -460
  169. package/coverage/core/api/hooks/hooks.groups.js.html +1 -1
  170. package/coverage/core/api/hooks/hooks.logger.js.html +16 -16
  171. package/coverage/core/api/hooks/hooks.model.js.html +52 -52
  172. package/coverage/core/api/hooks/hooks.organisations.js.html +1 -1
  173. package/coverage/core/api/hooks/hooks.push.js.html +58 -46
  174. package/coverage/core/api/hooks/hooks.query.js.html +136 -136
  175. package/coverage/core/api/hooks/hooks.schemas.js.html +1 -1
  176. package/coverage/core/api/hooks/hooks.service.js.html +1 -1
  177. package/coverage/core/api/hooks/hooks.storage.js.html +1 -1
  178. package/coverage/core/api/hooks/hooks.users.js.html +55 -328
  179. package/coverage/core/api/hooks/index.html +58 -88
  180. package/coverage/core/api/hooks/index.js.html +4 -10
  181. package/coverage/core/api/index.html +39 -54
  182. package/coverage/core/api/index.js.html +1 -1
  183. package/coverage/core/api/marshall.js.html +1 -1
  184. package/coverage/core/api/models/groups.model.mongodb.js.html +1 -1
  185. package/coverage/core/api/models/index.html +13 -58
  186. package/coverage/core/api/models/messages.model.mongodb.js.html +35 -35
  187. package/coverage/core/api/models/organisations.model.mongodb.js.html +3 -3
  188. package/coverage/core/api/models/tags.model.mongodb.js.html +1 -1
  189. package/coverage/core/api/models/users.model.mongodb.js.html +1 -1
  190. package/coverage/core/api/services/account/account.hooks.js.html +1 -1
  191. package/coverage/core/api/services/account/account.service.js.html +67 -67
  192. package/coverage/core/api/services/account/index.html +16 -16
  193. package/coverage/core/api/services/authorisations/authorisations.hooks.js.html +1 -1
  194. package/coverage/core/api/services/authorisations/authorisations.service.js.html +120 -117
  195. package/coverage/core/api/services/authorisations/index.html +15 -15
  196. package/coverage/core/api/services/databases/databases.hooks.js.html +82 -82
  197. package/coverage/core/api/services/databases/databases.service.js.html +20 -20
  198. package/coverage/core/api/services/databases/index.html +32 -32
  199. package/coverage/core/api/services/groups/groups.hooks.js.html +1 -1
  200. package/coverage/core/api/services/groups/index.html +1 -1
  201. package/coverage/core/api/services/import-export/import-export.hooks.js.html +1 -1
  202. package/coverage/core/api/services/import-export/import-export.service.js.html +1 -1
  203. package/coverage/core/api/services/import-export/index.html +1 -1
  204. package/coverage/core/api/services/index.html +21 -21
  205. package/coverage/core/api/services/index.js.html +118 -154
  206. package/coverage/core/api/services/mailer/index.html +1 -1
  207. package/coverage/core/api/services/mailer/mailer.hooks.js.html +1 -1
  208. package/coverage/core/api/services/mailer/mailer.service.js.html +1 -1
  209. package/coverage/core/api/services/messages/index.html +21 -21
  210. package/coverage/core/api/services/messages/messages.hooks.js.html +86 -86
  211. package/coverage/core/api/services/organisations/index.html +1 -1
  212. package/coverage/core/api/services/organisations/organisations.hooks.js.html +1 -1
  213. package/coverage/core/api/services/organisations/organisations.service.js.html +23 -23
  214. package/coverage/core/api/services/push/index.html +1 -1
  215. package/coverage/core/api/services/push/push.hooks.js.html +1 -1
  216. package/coverage/core/api/services/push/push.service.js.html +1 -1
  217. package/coverage/core/api/services/storage/index.html +5 -5
  218. package/coverage/core/api/services/storage/storage.hooks.js.html +1 -1
  219. package/coverage/core/api/services/storage/storage.service.js.html +27 -27
  220. package/coverage/core/api/services/tags/index.html +1 -1
  221. package/coverage/core/api/services/tags/tags.hooks.js.html +1 -1
  222. package/coverage/core/api/services/users/index.html +23 -8
  223. package/coverage/core/api/services/users/users.hooks.js.html +1 -1
  224. package/coverage/core/api/services/users/users.service.js.html +100 -0
  225. package/coverage/core/api/utils.js.html +1 -1
  226. package/coverage/core/common/errors.js.html +1 -1
  227. package/coverage/core/common/index.html +42 -27
  228. package/coverage/core/common/index.js.html +1 -1
  229. package/coverage/core/common/permissions.js.html +195 -510
  230. package/coverage/core/common/schema.js.html +1 -1
  231. package/coverage/core/common/utils.js.html +12 -6
  232. package/coverage/core/common/utils.offline.js.html +199 -0
  233. package/coverage/index.html +121 -166
  234. package/coverage/lcov-report/core/api/application.js.html +296 -296
  235. package/coverage/lcov-report/core/api/authentication.js.html +206 -74
  236. package/coverage/lcov-report/core/api/db.js.html +61 -61
  237. package/coverage/lcov-report/core/api/hooks/hooks.authentication.js.html +15 -189
  238. package/coverage/lcov-report/core/api/hooks/hooks.authorisations.js.html +172 -460
  239. package/coverage/lcov-report/core/api/hooks/hooks.groups.js.html +1 -1
  240. package/coverage/lcov-report/core/api/hooks/hooks.logger.js.html +16 -16
  241. package/coverage/lcov-report/core/api/hooks/hooks.model.js.html +52 -52
  242. package/coverage/lcov-report/core/api/hooks/hooks.organisations.js.html +1 -1
  243. package/coverage/lcov-report/core/api/hooks/hooks.push.js.html +58 -46
  244. package/coverage/lcov-report/core/api/hooks/hooks.query.js.html +136 -136
  245. package/coverage/lcov-report/core/api/hooks/hooks.schemas.js.html +1 -1
  246. package/coverage/lcov-report/core/api/hooks/hooks.service.js.html +1 -1
  247. package/coverage/lcov-report/core/api/hooks/hooks.storage.js.html +1 -1
  248. package/coverage/lcov-report/core/api/hooks/hooks.users.js.html +55 -328
  249. package/coverage/lcov-report/core/api/hooks/index.html +58 -88
  250. package/coverage/lcov-report/core/api/hooks/index.js.html +4 -10
  251. package/coverage/lcov-report/core/api/index.html +39 -54
  252. package/coverage/lcov-report/core/api/index.js.html +1 -1
  253. package/coverage/lcov-report/core/api/marshall.js.html +1 -1
  254. package/coverage/lcov-report/core/api/models/groups.model.mongodb.js.html +1 -1
  255. package/coverage/lcov-report/core/api/models/index.html +13 -58
  256. package/coverage/lcov-report/core/api/models/messages.model.mongodb.js.html +35 -35
  257. package/coverage/lcov-report/core/api/models/organisations.model.mongodb.js.html +3 -3
  258. package/coverage/lcov-report/core/api/models/tags.model.mongodb.js.html +1 -1
  259. package/coverage/lcov-report/core/api/models/users.model.mongodb.js.html +1 -1
  260. package/coverage/lcov-report/core/api/services/account/account.hooks.js.html +1 -1
  261. package/coverage/lcov-report/core/api/services/account/account.service.js.html +67 -67
  262. package/coverage/lcov-report/core/api/services/account/index.html +16 -16
  263. package/coverage/lcov-report/core/api/services/authorisations/authorisations.hooks.js.html +1 -1
  264. package/coverage/lcov-report/core/api/services/authorisations/authorisations.service.js.html +120 -117
  265. package/coverage/lcov-report/core/api/services/authorisations/index.html +15 -15
  266. package/coverage/lcov-report/core/api/services/databases/databases.hooks.js.html +82 -82
  267. package/coverage/lcov-report/core/api/services/databases/databases.service.js.html +20 -20
  268. package/coverage/lcov-report/core/api/services/databases/index.html +32 -32
  269. package/coverage/lcov-report/core/api/services/groups/groups.hooks.js.html +1 -1
  270. package/coverage/lcov-report/core/api/services/groups/index.html +1 -1
  271. package/coverage/lcov-report/core/api/services/import-export/import-export.hooks.js.html +1 -1
  272. package/coverage/lcov-report/core/api/services/import-export/import-export.service.js.html +1 -1
  273. package/coverage/lcov-report/core/api/services/import-export/index.html +1 -1
  274. package/coverage/lcov-report/core/api/services/index.html +21 -21
  275. package/coverage/lcov-report/core/api/services/index.js.html +118 -154
  276. package/coverage/lcov-report/core/api/services/mailer/index.html +1 -1
  277. package/coverage/lcov-report/core/api/services/mailer/mailer.hooks.js.html +1 -1
  278. package/coverage/lcov-report/core/api/services/mailer/mailer.service.js.html +1 -1
  279. package/coverage/lcov-report/core/api/services/messages/index.html +21 -21
  280. package/coverage/lcov-report/core/api/services/messages/messages.hooks.js.html +86 -86
  281. package/coverage/lcov-report/core/api/services/organisations/index.html +1 -1
  282. package/coverage/lcov-report/core/api/services/organisations/organisations.hooks.js.html +1 -1
  283. package/coverage/lcov-report/core/api/services/organisations/organisations.service.js.html +23 -23
  284. package/coverage/lcov-report/core/api/services/push/index.html +1 -1
  285. package/coverage/lcov-report/core/api/services/push/push.hooks.js.html +1 -1
  286. package/coverage/lcov-report/core/api/services/push/push.service.js.html +1 -1
  287. package/coverage/lcov-report/core/api/services/storage/index.html +5 -5
  288. package/coverage/lcov-report/core/api/services/storage/storage.hooks.js.html +1 -1
  289. package/coverage/lcov-report/core/api/services/storage/storage.service.js.html +27 -27
  290. package/coverage/lcov-report/core/api/services/tags/index.html +1 -1
  291. package/coverage/lcov-report/core/api/services/tags/tags.hooks.js.html +1 -1
  292. package/coverage/lcov-report/core/api/services/users/index.html +23 -8
  293. package/coverage/lcov-report/core/api/services/users/users.hooks.js.html +1 -1
  294. package/coverage/lcov-report/core/api/services/users/users.service.js.html +100 -0
  295. package/coverage/lcov-report/core/api/utils.js.html +1 -1
  296. package/coverage/lcov-report/core/common/errors.js.html +1 -1
  297. package/coverage/lcov-report/core/common/index.html +42 -27
  298. package/coverage/lcov-report/core/common/index.js.html +1 -1
  299. package/coverage/lcov-report/core/common/permissions.js.html +195 -510
  300. package/coverage/lcov-report/core/common/schema.js.html +1 -1
  301. package/coverage/lcov-report/core/common/utils.js.html +12 -6
  302. package/coverage/lcov-report/core/common/utils.offline.js.html +199 -0
  303. package/coverage/lcov-report/index.html +121 -166
  304. package/coverage/lcov-report/map/api/hooks/hooks.catalog.js.html +33 -27
  305. package/coverage/lcov-report/map/api/hooks/hooks.features.js.html +1 -1
  306. package/coverage/lcov-report/map/api/hooks/hooks.query.js.html +4 -4
  307. package/coverage/lcov-report/map/api/hooks/index.html +5 -5
  308. package/coverage/lcov-report/map/api/hooks/index.js.html +1 -1
  309. package/coverage/lcov-report/map/api/index.html +1 -1
  310. package/coverage/lcov-report/map/api/index.js.html +1 -1
  311. package/coverage/lcov-report/map/api/marshall.js.html +1 -1
  312. package/coverage/lcov-report/map/api/models/alerts.model.mongodb.js.html +1 -1
  313. package/coverage/lcov-report/map/api/models/catalog.model.mongodb.js.html +1 -1
  314. package/coverage/lcov-report/map/api/models/features.model.mongodb.js.html +1 -1
  315. package/coverage/lcov-report/map/api/models/index.html +1 -1
  316. package/coverage/lcov-report/map/api/models/projects.model.mongodb.js.html +1 -1
  317. package/coverage/lcov-report/map/api/services/alerts/alerts.hooks.js.html +1 -1
  318. package/coverage/lcov-report/map/api/services/alerts/alerts.service.js.html +1 -1
  319. package/coverage/lcov-report/map/api/services/alerts/index.html +1 -1
  320. package/coverage/lcov-report/map/api/services/catalog/catalog.hooks.js.html +10 -7
  321. package/coverage/lcov-report/map/api/services/catalog/index.html +5 -5
  322. package/coverage/lcov-report/map/api/services/daptiles/daptiles.service.js.html +1 -1
  323. package/coverage/lcov-report/map/api/services/daptiles/index.html +1 -1
  324. package/coverage/lcov-report/map/api/services/features/features.hooks.js.html +78 -9
  325. package/coverage/lcov-report/map/api/services/features/features.service.js.html +307 -4
  326. package/coverage/lcov-report/map/api/services/features/index.html +7 -7
  327. package/coverage/lcov-report/map/api/services/index.html +5 -5
  328. package/coverage/lcov-report/map/api/services/index.js.html +171 -42
  329. package/coverage/lcov-report/map/api/services/projects/index.html +1 -1
  330. package/coverage/lcov-report/map/api/services/projects/projects.hooks.js.html +1 -1
  331. package/coverage/lcov-report/map/common/dynamic-grid-source.js.html +1 -1
  332. package/coverage/lcov-report/map/common/errors.js.html +1 -1
  333. package/coverage/lcov-report/map/common/geotiff-grid-source.js.html +8 -5
  334. package/coverage/lcov-report/map/common/grid.js.html +1 -1
  335. package/coverage/lcov-report/map/common/index.html +5 -5
  336. package/coverage/lcov-report/map/common/index.js.html +1 -1
  337. package/coverage/lcov-report/map/common/meteo-model-grid-source.js.html +1 -1
  338. package/coverage/lcov-report/map/common/moment-utils.js.html +1 -1
  339. package/coverage/lcov-report/map/common/opendap-grid-source.js.html +1 -1
  340. package/coverage/lcov-report/map/common/opendap-utils.js.html +1 -1
  341. package/coverage/lcov-report/map/common/permissions.js.html +1 -1
  342. package/coverage/lcov-report/map/common/time-based-grid-source.js.html +1 -1
  343. package/coverage/lcov-report/map/common/tms-utils.js.html +1 -1
  344. package/coverage/lcov-report/map/common/wcs-grid-source.js.html +1 -1
  345. package/coverage/lcov-report/map/common/wcs-utils.js.html +1 -1
  346. package/coverage/lcov-report/map/common/weacast-grid-source.js.html +1 -1
  347. package/coverage/lcov-report/map/common/wfs-utils.js.html +1 -1
  348. package/coverage/lcov-report/map/common/wms-utils.js.html +1 -1
  349. package/coverage/lcov-report/map/common/wmts-utils.js.html +1 -1
  350. package/coverage/lcov.info +2314 -3167
  351. package/coverage/map/api/hooks/hooks.catalog.js.html +33 -27
  352. package/coverage/map/api/hooks/hooks.features.js.html +1 -1
  353. package/coverage/map/api/hooks/hooks.query.js.html +4 -4
  354. package/coverage/map/api/hooks/index.html +5 -5
  355. package/coverage/map/api/hooks/index.js.html +1 -1
  356. package/coverage/map/api/index.html +1 -1
  357. package/coverage/map/api/index.js.html +1 -1
  358. package/coverage/map/api/marshall.js.html +1 -1
  359. package/coverage/map/api/models/alerts.model.mongodb.js.html +1 -1
  360. package/coverage/map/api/models/catalog.model.mongodb.js.html +1 -1
  361. package/coverage/map/api/models/features.model.mongodb.js.html +1 -1
  362. package/coverage/map/api/models/index.html +1 -1
  363. package/coverage/map/api/models/projects.model.mongodb.js.html +1 -1
  364. package/coverage/map/api/services/alerts/alerts.hooks.js.html +1 -1
  365. package/coverage/map/api/services/alerts/alerts.service.js.html +1 -1
  366. package/coverage/map/api/services/alerts/index.html +1 -1
  367. package/coverage/map/api/services/catalog/catalog.hooks.js.html +10 -7
  368. package/coverage/map/api/services/catalog/index.html +5 -5
  369. package/coverage/map/api/services/daptiles/daptiles.service.js.html +1 -1
  370. package/coverage/map/api/services/daptiles/index.html +1 -1
  371. package/coverage/map/api/services/features/features.hooks.js.html +78 -9
  372. package/coverage/map/api/services/features/features.service.js.html +307 -4
  373. package/coverage/map/api/services/features/index.html +7 -7
  374. package/coverage/map/api/services/index.html +5 -5
  375. package/coverage/map/api/services/index.js.html +171 -42
  376. package/coverage/map/api/services/projects/index.html +1 -1
  377. package/coverage/map/api/services/projects/projects.hooks.js.html +1 -1
  378. package/coverage/map/common/dynamic-grid-source.js.html +1 -1
  379. package/coverage/map/common/errors.js.html +1 -1
  380. package/coverage/map/common/geotiff-grid-source.js.html +8 -5
  381. package/coverage/map/common/grid.js.html +1 -1
  382. package/coverage/map/common/index.html +5 -5
  383. package/coverage/map/common/index.js.html +1 -1
  384. package/coverage/map/common/meteo-model-grid-source.js.html +1 -1
  385. package/coverage/map/common/moment-utils.js.html +1 -1
  386. package/coverage/map/common/opendap-grid-source.js.html +1 -1
  387. package/coverage/map/common/opendap-utils.js.html +1 -1
  388. package/coverage/map/common/permissions.js.html +1 -1
  389. package/coverage/map/common/time-based-grid-source.js.html +1 -1
  390. package/coverage/map/common/tms-utils.js.html +1 -1
  391. package/coverage/map/common/wcs-grid-source.js.html +1 -1
  392. package/coverage/map/common/wcs-utils.js.html +1 -1
  393. package/coverage/map/common/weacast-grid-source.js.html +1 -1
  394. package/coverage/map/common/wfs-utils.js.html +1 -1
  395. package/coverage/map/common/wms-utils.js.html +1 -1
  396. package/coverage/map/common/wmts-utils.js.html +1 -1
  397. package/coverage/tmp/{coverage-280506-1731704745613-0.json → coverage-122123-1739872365211-0.json} +1 -1
  398. package/coverage/tmp/{coverage-280518-1731704745599-0.json → coverage-122135-1739872365196-0.json} +1 -1
  399. package/coverage/tmp/{coverage-280529-1731704745588-0.json → coverage-122146-1739872365184-0.json} +1 -1
  400. package/coverage/tmp/{coverage-280541-1731704745574-0.json → coverage-122158-1739872365169-0.json} +1 -1
  401. package/coverage/tmp/{coverage-280548-1731704745545-0.json → coverage-122165-1739872365141-0.json} +1 -1
  402. package/extras/configs/helpers.js +78 -0
  403. package/extras/configs/panes.left.js +118 -0
  404. package/extras/configs/panes.top.js +222 -0
  405. package/extras/configs/stickies.js +57 -0
  406. package/extras/configs/widgets.left.js +23 -0
  407. package/extras/configs/widgets.top.js +73 -0
  408. package/extras/css/core.variables.scss +8 -0
  409. package/extras/images/north.svg +3 -0
  410. package/extras/tours/map/side-nav.js +3 -3
  411. package/map/api/hooks/hooks.catalog.js +56 -23
  412. package/map/api/hooks/hooks.query.js +19 -24
  413. package/map/api/models/catalog.model.mongodb.js +16 -2
  414. package/{core/api/models/groups.model.mongodb.js → map/api/models/styles.model.mongodb.js} +2 -1
  415. package/map/api/services/catalog/catalog.hooks.js +13 -7
  416. package/map/api/services/features/features.hooks.js +28 -5
  417. package/map/api/services/features/features.service.js +101 -0
  418. package/map/api/services/index.js +125 -46
  419. package/map/api/services/styles/styles.hooks.js +37 -0
  420. package/map/client/cesium/utils/index.js +1 -0
  421. package/map/client/cesium/utils/utils.cesium.js +397 -0
  422. package/map/client/cesium/utils/utils.features.js +8 -0
  423. package/map/client/cesium/utils/utils.geojson.js +59 -0
  424. package/map/client/cesium/utils/utils.style.js +134 -17
  425. package/map/client/components/KEditLayerData.vue +17 -79
  426. package/map/client/components/KFeatureEditor.vue +2 -7
  427. package/map/client/components/KFeaturesChart.vue +2 -6
  428. package/map/client/components/KFeaturesFilterEditor.vue +300 -0
  429. package/map/client/components/KFeaturesFilterManager.vue +196 -0
  430. package/map/client/components/KFeaturesTable.vue +0 -5
  431. package/map/client/components/KFilterCondition.vue +303 -0
  432. package/map/client/components/KLayerEditionToolbar.vue +4 -3
  433. package/map/client/components/KLayerEditor.vue +451 -36
  434. package/map/client/components/KMeasureTool.vue +36 -9
  435. package/map/client/components/KProjectMenu.vue +14 -8
  436. package/map/client/components/catalog/KAddLayer.vue +0 -4
  437. package/map/client/components/catalog/KBaseLayersSelector.vue +42 -46
  438. package/map/client/components/catalog/KConnectLayer.vue +295 -291
  439. package/map/client/components/catalog/KCreateLayer.vue +141 -146
  440. package/map/client/components/catalog/KCreateOfflineView.vue +100 -0
  441. package/map/client/components/catalog/KCreateView.vue +2 -8
  442. package/map/client/components/catalog/KFilteredLayerItem.vue +72 -25
  443. package/map/client/components/catalog/KImportLayer.vue +121 -129
  444. package/map/client/components/catalog/KLayerItem.vue +44 -32
  445. package/map/client/components/catalog/KLayersPanel.vue +45 -17
  446. package/map/client/components/catalog/KLayersSelector.vue +51 -50
  447. package/map/client/components/catalog/KProjectManager.vue +4 -8
  448. package/map/client/components/catalog/KProjectSelector.vue +33 -2
  449. package/map/client/components/catalog/KProjectsPanel.vue +84 -106
  450. package/map/client/components/catalog/KSelectLayers.vue +56 -69
  451. package/map/client/components/catalog/KSelectViews.vue +56 -69
  452. package/map/client/components/catalog/KViewSelector.vue +32 -2
  453. package/map/client/components/catalog/KViewsPanel.vue +178 -110
  454. package/map/client/components/catalog/KWeatherLayersSelector.vue +77 -85
  455. package/map/client/components/form/KLocationField.vue +21 -2
  456. package/map/client/components/form/KOwsLayerField.vue +1 -1
  457. package/map/client/components/form/KOwsServiceField.vue +102 -63
  458. package/map/client/components/form/KSelectLayersField.vue +1 -1
  459. package/map/client/components/form/KSelectViewsField.vue +1 -1
  460. package/map/client/components/form/KTimezoneField.vue +0 -1
  461. package/map/client/components/legend/KLegend.vue +4 -4
  462. package/map/client/components/location/KLocationCardSection.vue +16 -0
  463. package/map/client/components/location/KLocationMap.vue +3 -2
  464. package/map/client/components/location/KLocationSearch.vue +46 -8
  465. package/map/client/components/location/KLocationTimeLineCard.vue +25 -3
  466. package/map/client/components/location/KLocationTip.vue +57 -10
  467. package/map/client/components/selection/KFeaturesSelection.vue +71 -0
  468. package/map/client/components/selection/KSelectedLayerFeatures.vue +343 -0
  469. package/map/client/components/stickies/KAttribution.vue +115 -0
  470. package/map/client/components/stickies/KLevelSlider.vue +114 -0
  471. package/map/client/components/stickies/KNorthArrow.vue +26 -0
  472. package/map/client/components/stickies/KPosition.vue +103 -0
  473. package/map/client/components/stickies/KTarget.vue +34 -0
  474. package/map/client/components/styles/KLayerStyleAction.vue +58 -0
  475. package/map/client/components/styles/KStyleEditor.vue +273 -0
  476. package/map/client/components/styles/KStyleEditorSection.vue +79 -0
  477. package/map/client/components/styles/KStyleManager.vue +183 -0
  478. package/map/client/components/styles/KStylePreview.vue +64 -0
  479. package/map/client/components/styles/KStylePreviewItem.vue +68 -0
  480. package/map/client/components/styles/KStylePropertiesGroup.vue +76 -0
  481. package/map/client/components/styles/KStyleProperty.vue +136 -0
  482. package/map/client/components/styles/KStyleTip.vue +118 -0
  483. package/map/client/components/tools/KGeolocateTool.vue +3 -2
  484. package/map/client/components/tools/KSearchTool.vue +34 -6
  485. package/map/client/components/widget/KMapillaryViewer.vue +1 -1
  486. package/map/client/components/widget/KStackableTimeSeries.vue +8 -5
  487. package/map/client/composables/activity.js +29 -43
  488. package/map/client/composables/catalog.js +1 -1
  489. package/map/client/composables/highlight.js +117 -57
  490. package/map/client/composables/location.js +33 -14
  491. package/map/client/composables/project.js +9 -10
  492. package/map/client/composables/selection.js +136 -23
  493. package/map/client/geocoder.js +104 -0
  494. package/map/client/geolocation.js +1 -1
  495. package/map/client/globe.js +3 -0
  496. package/map/client/hooks/hooks.offline.js +95 -0
  497. package/map/client/hooks/index.js +1 -0
  498. package/map/client/i18n/map_en.json +159 -94
  499. package/map/client/i18n/map_fr.json +187 -128
  500. package/map/client/index.js +3 -0
  501. package/map/client/init.js +44 -8
  502. package/map/client/leaflet/BoxSelection.js +2 -2
  503. package/map/client/leaflet/GradientPath.js +84 -4
  504. package/map/client/leaflet/WindBarb.js +323 -0
  505. package/map/client/leaflet/utils/index.js +1 -0
  506. package/map/client/leaflet/utils/utils.events.js +8 -3
  507. package/map/client/leaflet/utils/utils.geojson.js +222 -0
  508. package/map/client/leaflet/utils/utils.style.js +10 -9
  509. package/map/client/map.js +3 -0
  510. package/map/client/mixins/globe/mixin.base-globe.js +151 -19
  511. package/map/client/mixins/globe/mixin.geojson-layers.js +208 -86
  512. package/map/client/mixins/globe/mixin.popup.js +3 -2
  513. package/map/client/mixins/globe/mixin.style.js +3 -1
  514. package/map/client/mixins/globe/mixin.tooltip.js +3 -2
  515. package/map/client/mixins/map/index.js +1 -3
  516. package/map/client/mixins/map/mixin.base-map.js +267 -79
  517. package/map/client/mixins/map/mixin.canvas-layers.js +44 -10
  518. package/map/client/mixins/map/mixin.edit-layers.js +142 -57
  519. package/map/client/mixins/map/mixin.geojson-layers.js +127 -204
  520. package/map/client/mixins/map/mixin.pmtiles-layers.js +24 -11
  521. package/map/client/mixins/map/mixin.tiled-mesh-layers.js +1 -2
  522. package/map/client/mixins/map/mixin.tiled-wind-layers.js +2 -1
  523. package/map/client/mixins/mixin.activity.js +61 -41
  524. package/map/client/mixins/mixin.context.js +19 -14
  525. package/map/client/mixins/mixin.feature-selection.js +0 -1
  526. package/map/client/mixins/mixin.feature-service.js +41 -59
  527. package/map/client/mixins/mixin.weacast.js +1 -1
  528. package/map/client/navigator.js +38 -0
  529. package/map/client/pixi-utils.js +1 -1
  530. package/map/client/planets.js +1 -1
  531. package/map/client/readers/reader.kml.js +57 -1
  532. package/map/client/utils/index.js +1 -0
  533. package/map/client/utils/utils.capture.js +10 -7
  534. package/map/client/utils/utils.catalog.js +2 -2
  535. package/map/client/utils/utils.features.js +193 -39
  536. package/map/client/utils/utils.js +0 -21
  537. package/map/client/utils/utils.layers.js +381 -4
  538. package/map/client/utils/utils.location.js +39 -74
  539. package/map/client/utils/utils.offline.js +89 -0
  540. package/map/client/utils/utils.style.js +133 -80
  541. package/map/common/geotiff-grid-source.js +2 -1
  542. package/map/common/permissions.js +2 -0
  543. package/map/common/schemas/capture.create.json +4 -4
  544. package/map/common/schemas/catalog.update.json +18 -2
  545. package/map/common/schemas/projects.create.json +2 -2
  546. package/map/common/schemas/projects.update.json +2 -2
  547. package/map/common/tms-utils.js +5 -5
  548. package/map/common/wcs-grid-source.js +2 -2
  549. package/map/common/wcs-utils.js +8 -8
  550. package/map/common/wfs-utils.js +10 -10
  551. package/map/common/wms-utils.js +7 -7
  552. package/map/common/wmts-utils.js +6 -6
  553. package/package.json +7 -4
  554. package/test/api/core/account.test.js +0 -72
  555. package/test/api/core/authentication.test.js +184 -0
  556. package/test/api/core/config/default.cjs +1 -3
  557. package/test/api/core/index.test.js +77 -151
  558. package/test/api/core/offline.test.js +55 -0
  559. package/test/api/core/push.test.js +3 -3
  560. package/test/api/core/{test-log-2024-11-05.log → test-log-2025-05-26.log} +1 -9
  561. package/test/api/map/alerts.test.js +1 -1
  562. package/test/api/map/config/default.cjs +2 -1
  563. package/test/api/map/data/vigicrues.observations.Q.json +47042 -0
  564. package/test/api/map/index.test.js +113 -9
  565. package/test/api/map/style.test.js +62 -0
  566. package/test/api/map/{test-log-2024-10-28.log → test-log-2025-05-26.log} +4 -3
  567. package/test/client/core/layout.js +2 -2
  568. package/test/client/core/runner.js +1 -1
  569. package/test/client/core/utils.js +52 -0
  570. package/test/client/map/catalog.js +1 -0
  571. package/core/api/hooks/hooks.groups.js +0 -48
  572. package/core/api/hooks/hooks.organisations.js +0 -152
  573. package/core/api/models/organisations.model.mongodb.js +0 -3
  574. package/core/api/models/tags.model.mongodb.js +0 -10
  575. package/core/api/services/groups/groups.hooks.js +0 -31
  576. package/core/api/services/organisations/organisations.hooks.js +0 -31
  577. package/core/api/services/organisations/organisations.service.js +0 -86
  578. package/core/api/services/tags/tags.hooks.js +0 -31
  579. package/core/api/utils.js +0 -11
  580. package/core/client/components/KChipsPane.vue +0 -103
  581. package/core/client/components/document/index.js +0 -9
  582. package/core/client/components/team/KAddMember.vue +0 -378
  583. package/core/client/components/team/KAddTag.vue +0 -121
  584. package/core/client/components/team/KChangeRole.vue +0 -118
  585. package/core/client/components/team/KGroupCard.vue +0 -110
  586. package/core/client/components/team/KGroupsActivity.vue +0 -78
  587. package/core/client/components/team/KJoinGroup.vue +0 -132
  588. package/core/client/components/team/KMemberCard.vue +0 -328
  589. package/core/client/components/team/KMemberFilter.vue +0 -49
  590. package/core/client/components/team/KMembersActivity.vue +0 -136
  591. package/core/client/components/team/KOrganisationsActivity.vue +0 -51
  592. package/core/client/components/team/KTagCard.vue +0 -72
  593. package/core/client/components/team/KTagsActivity.vue +0 -73
  594. package/core/client/components/team/index.js +0 -9
  595. package/core/client/mixins/mixin.base-context.js +0 -54
  596. package/core/client/utils/utils.platform.js +0 -12
  597. package/core/common/schemas/groups.create.json +0 -28
  598. package/core/common/schemas/groups.update.json +0 -28
  599. package/core/common/schemas/organisations.create.json +0 -28
  600. package/core/common/schemas/organisations.update.json +0 -49
  601. package/core/common/schemas/tags.create.json +0 -35
  602. package/core/common/schemas/tags.update.json +0 -35
  603. package/map/client/components/KAttribution.vue +0 -108
  604. package/map/client/components/KFeaturesFilter.vue +0 -259
  605. package/map/client/components/KLayerStyleEditor.vue +0 -118
  606. package/map/client/components/KLayerStyleForm.vue +0 -740
  607. package/map/client/components/KLevelSlider.vue +0 -100
  608. package/map/client/components/KNorth.vue +0 -31
  609. package/map/client/components/KPositionIndicator.vue +0 -83
  610. package/map/client/components/catalog/KCreateProject.vue +0 -100
  611. package/map/client/mixins/map/mixin.forecast-layers.js +0 -81
  612. package/map/client/mixins/map/mixin.georaster-layers.js +0 -107
  613. package/test/api/core/team.test.js +0 -670
  614. package/test/api/core/test-log-2023-12-19.log +0 -7
  615. package/test/api/core/test-log-2024-01-04.log +0 -14
  616. package/test/api/core/test-log-2024-05-14.log +0 -6
  617. package/test/api/core/test-log-2024-06-06.log +0 -23
  618. package/test/api/core/test-log-2024-06-26.log +0 -25
  619. package/test/api/core/test-log-2024-06-28.log +0 -2
  620. package/test/api/core/test-log-2024-07-09.log +0 -0
  621. package/test/api/core/test-log-2024-08-13.log +0 -69
  622. package/test/api/core/test-log-2024-10-28.log +0 -53
  623. package/test/api/core/test-log-2024-11-15.log +0 -23
  624. package/test/api/core/test-log-2024-11-18.log +0 -0
  625. package/test/api/core/test-log-2024-12-03.log +0 -30
  626. package/test/api/map/test-log-2023-11-24.log +0 -121
  627. package/test/api/map/test-log-2023-12-12.log +0 -29
  628. package/test/api/map/test-log-2023-12-13.log +0 -5
  629. package/test/api/map/test-log-2024-01-04.log +0 -2
  630. package/test/api/map/test-log-2024-01-11.log +0 -1
  631. package/test/api/map/test-log-2024-01-25.log +0 -19
  632. package/test/api/map/test-log-2024-06-06.log +0 -39
  633. package/test/api/map/test-log-2024-08-13.log +0 -13
  634. package/test/api/map/test-log-2024-08-20.log +0 -55
  635. package/test/api/map/test-log-2024-09-09.log +0 -92
  636. /package/extras/{logos → images}/kalisio.png +0 -0
  637. /package/extras/{icons → images}/target.svg +0 -0
  638. /package/test/api/map/data/{vigicrues.observations.json → vigicrues.observations.H.json} +0 -0
@@ -99,10 +99,10 @@ export async function configureService (name, service, servicesPath) {
99
99
  }
100
100
  } catch (error) {
101
101
  debug('No ' + name + ' service hooks configured on path ' + servicesPath)
102
- if (error.code !== 'ERR_MODULE_NOT_FOUND') {
103
- // Log error in this case as this might be linked to a syntax error in required file
104
- debug(filepath, error)
105
- }
102
+ // if (error.code !== 'ERR_MODULE_NOT_FOUND') {
103
+ // Log error in this case as this might be linked to a syntax error in required file
104
+ debug(filepath, error)
105
+ // }
106
106
  // As this is optionnal this require has to fail silently
107
107
  }
108
108
 
@@ -119,10 +119,10 @@ export async function configureService (name, service, servicesPath) {
119
119
  }
120
120
  } catch (error) {
121
121
  debug('No ' + name + ' service channels configured on path ' + servicesPath)
122
- if (error.code !== 'ERR_MODULE_NOT_FOUND') {
123
- // Log error in this case as this might be linked to a syntax error in required file
124
- debug(filepath, error)
125
- }
122
+ // if (error.code !== 'ERR_MODULE_NOT_FOUND') {
123
+ // Log error in this case as this might be linked to a syntax error in required file
124
+ debug(filepath, error)
125
+ // }
126
126
  // As this is optionnal this require has to fail silently
127
127
  }
128
128
 
@@ -198,10 +198,10 @@ async function createService (name, app, options = {}) {
198
198
  }
199
199
  } catch (error) {
200
200
  debug('No ' + fileName + ' service model configured on path ' + serviceOptions.modelsPath)
201
- if (error.code !== 'ERR_MODULE_NOT_FOUND') {
202
- // Log error in this case as this might be linked to a syntax error in required file
203
- debug(fileName, error)
204
- }
201
+ // if (error.code !== 'ERR_MODULE_NOT_FOUND') {
202
+ // Log error in this case as this might be linked to a syntax error in required file
203
+ debug(fileName, error)
204
+ // }
205
205
  // As this is optionnal this require has to fail silently
206
206
  }
207
207
 
@@ -1,5 +1,6 @@
1
1
  import makeDebug from 'debug'
2
2
  import _ from 'lodash'
3
+ import qs from 'qs'
3
4
  import 'winston-daily-rotate-file'
4
5
  // import { RateLimiter } from 'limiter'
5
6
  import HttpLimiter from 'express-rate-limit'
@@ -32,6 +33,23 @@ export class Authentication extends AuthenticationService {
32
33
  }
33
34
 
34
35
  export class AuthenticationProviderStrategy extends OAuthStrategy {
36
+ setAuthentication (auth) {
37
+ super.setAuthentication(auth)
38
+ const authConfig = this.authentication.configuration
39
+ const { oauth } = authConfig
40
+ // Single logout supported ?
41
+ const { logout_url: logoutUrl, post_logout_url: postLogoutUrl, key } = this.configuration
42
+ if (logoutUrl && key) {
43
+ // Cannot use oauth/:provider/logout route as oauth/:provider is already intercepted by feathers and this causes an error
44
+ this.app.get(`/oauth-logout/${this.name}`, (req, res) => {
45
+ return res.redirect(logoutUrl + '?' + qs.stringify({
46
+ post_logout_redirect_uri: postLogoutUrl || oauth.redirect,
47
+ client_id: key
48
+ }))
49
+ })
50
+ }
51
+ }
52
+
35
53
  async getEntityData (profile, entity) {
36
54
  const createEntity = _.isNil(entity)
37
55
  // Add provider Id
@@ -50,6 +68,13 @@ export class AuthenticationProviderStrategy extends OAuthStrategy {
50
68
  }
51
69
 
52
70
  async getEntityQuery (profile) {
71
+ // Ensure the profile is right before requesting based on it
72
+ // as when an error is raised the profile will not contain any ID or email
73
+ // and we might build a request retrieving any user
74
+ if (!_.has(profile, 'id') && !_.has(profile, 'sub') && !_.has(profile, this.emailFieldInProfile || 'email')) {
75
+ // This ensure no user will be retrieved
76
+ return { $limit: 0 }
77
+ }
53
78
  const query = {
54
79
  $or: [
55
80
  { [`${this.name}Id`]: profile.id || profile.sub },
@@ -76,6 +101,8 @@ export class AuthenticationProviderStrategy extends OAuthStrategy {
76
101
  export class JWTAuthenticationStrategy extends JWTStrategy {
77
102
  async authenticate (authentication, params) {
78
103
  const { accessToken } = authentication
104
+ const authConfig = this.authentication.configuration
105
+ const { identityFields } = authConfig
79
106
  const { entity } = this.configuration
80
107
  const renewJwt = _.get(this.configuration, 'renewJwt', true)
81
108
 
@@ -99,14 +126,31 @@ export class JWTAuthenticationStrategy extends JWTStrategy {
99
126
  // Second key trick
100
127
  // Return user attached to the token if any
101
128
  // Return basic information for a stateless token otherwise
102
- // As we only target MongoDB now, check for a valid ID otherwise assume a stateless token as well
103
- if (payload.sub && ObjectID.isValid(payload.sub)) {
104
- const entityId = await this.getEntityId(result, params)
105
- const value = await this.getEntity(entityId, params)
129
+ if (payload.sub) {
130
+ // Check for a valid MongoDB ID
131
+ if (ObjectID.isValid(payload.sub)) {
132
+ const entityId = await this.getEntityId(result, params)
133
+ const value = await this.getEntity(entityId, params)
106
134
 
107
- return {
108
- ...result,
109
- [entity]: value
135
+ return {
136
+ ...result,
137
+ [entity]: value
138
+ }
139
+ } else if (identityFields) {
140
+ // Otherwise use others fields to identify the user if defined
141
+ const query = {
142
+ $or: _.reduce(identityFields, (or, field) => or.concat([{ [field]: payload.sub }]), []),
143
+ $limit: 1
144
+ }
145
+ const response = await this.entityService.find({ ...params, query })
146
+ const [value = null] = response.data ? response.data : response
147
+ // Otherwise assume a stateless token
148
+ if (value) {
149
+ return {
150
+ ...result,
151
+ [entity]: value
152
+ }
153
+ }
110
154
  }
111
155
  }
112
156
 
@@ -5,67 +5,9 @@ import local from '@feathersjs/authentication-local'
5
5
  const debug = makeDebug('kdk:core:authentication:hooks')
6
6
  const { discard } = common
7
7
 
8
- // Make it more easy to acces
8
+ // Make it more easy to access
9
9
  export const hashPassword = local.hooks.hashPassword
10
10
 
11
- export async function verifyGuest (hook) {
12
- if (hook.type !== 'after') {
13
- throw new Error('The \'verifyGuest\' hook should only be used as a \'after\' hook.')
14
- }
15
- const app = hook.app
16
- const user = hook.result.user
17
- if (!user) return hook
18
- debug('verifyGuest hook called on ', user._id)
19
-
20
- // Check whether the user has been inivted. If not, nothing to do
21
- if (!user.sponsor) {
22
- debug('Logged user is not a guest')
23
- return hook
24
- }
25
-
26
- // Check whether has been already verified. If yes, nothing to do
27
- if (user.isVerified) {
28
- debug('Logged guest is already verified')
29
- return hook
30
- }
31
-
32
- // The user is a guest and need to be verified
33
- debug('Verifying logged guest')
34
- const userService = app.getService('users')
35
- await userService.patch(user._id, { isVerified: true })
36
-
37
- return hook
38
- }
39
-
40
- export async function consentGuest (hook) {
41
- if (hook.type !== 'after') {
42
- throw new Error('The \'consentGuest\' hook should only be used as a \'after\' hook.')
43
- }
44
- const app = hook.app
45
- const user = hook.result.user
46
- if (!user) return hook
47
- debug('consentGuest hook called on ', user._id)
48
-
49
- // Check whether the user has been invited. If not, nothing to do
50
- if (!user.sponsor) {
51
- debug('Logged user is not a guest')
52
- return hook
53
- }
54
-
55
- // Check whether consent has been already checked. If yes, nothing to do
56
- if (user.consentTerms) {
57
- debug('Logged guest is already verified')
58
- return hook
59
- }
60
-
61
- // The user is a guest and need to be consent
62
- debug('Consenting logged guest')
63
- const userService = app.getService('users')
64
- await userService.patch(user._id, { consentTerms: true, expireAt: null })
65
-
66
- return hook
67
- }
68
-
69
11
  export function discardAuthenticationProviders (hook) {
70
12
  const providers = hook.app.authenticationProviders || []
71
13
 
@@ -8,7 +8,6 @@ import {
8
8
  hasServiceAbilities, hasResourceAbilities, getQueryForAbilities,
9
9
  Roles, RoleNames, countSubjectsForResource
10
10
  } from '../../common/permissions.js'
11
- import { isTagEqual } from '../utils.js'
12
11
 
13
12
  const { getItems, replaceItems } = common
14
13
  const { Forbidden } = errors
@@ -25,7 +24,7 @@ export function createJWT (options = {}) {
25
24
  const accessTokens = await Promise.all(items.map(item => hook.app.getService('authentication').createAccessToken(
26
25
  // Provided function can be used to pick or omit properties in JWT payload
27
26
  (typeof options.payload === 'function' ? options.payload(user) : {}),
28
- // Provided function can be used for custom options cdepending on the user,
27
+ // Provided function can be used for custom options depending on the user,
29
28
  // then we merge with default auth options for global properties like aud, iss, etc.
30
29
  _.merge({}, defaults, (typeof options.jwt === 'function' ? options.jwt(user) : options)))
31
30
  ))
@@ -186,13 +185,15 @@ export async function authorise (hook) {
186
185
  if (checkAuthorisation) {
187
186
  // Build ability for user
188
187
  const authorisationService = hook.app.getService('authorisations')
189
- // If no user we allow for a stateless token with permissions inside
190
188
  let subject = hook.params.user
191
- 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)) {
189
+ const payload = _.get(hook.params, 'authentication.payload')
190
+ if (payload) {
191
+ // If no user we allow for a stateless token with permissions inside, e.g.
192
+ // token targeting API gateway (sub = keyId) or app used through iframe (appId = keyId)
193
+ if (!subject && (payload.sub || payload.appId)) {
195
194
  subject = Object.assign({ _id: (payload.sub || payload.appId) }, payload)
195
+ } else if (subject) { // Otherwise we allow to "extend" user abilities by providing additional information in the token
196
+ subject = Object.assign(subject, _.omit(payload, ['aud', 'iss', 'exp', 'sub', 'iat', 'jti', 'nbf']))
196
197
  }
197
198
  }
198
199
  const abilities = await authorisationService.getAbilities(subject)
@@ -283,104 +284,8 @@ export function updateAbilities (options = {}) {
283
284
  if (options.fetchSubject) {
284
285
  subject = await app.getService('users').get(subject._id.toString())
285
286
  }
286
- const abilities = await authorisationService.updateAbilities(subject)
287
- debug('Abilities updated on subject', subject, abilities.rules)
287
+ await authorisationService.updateAbilities(subject)
288
288
  return hook
289
289
  }
290
290
  }
291
291
 
292
- export function preventRemovingLastOwner (resourceScope) {
293
- return async function (hook) {
294
- // By pass check ?
295
- if (hook.params.force) return hook
296
- const params = hook.params
297
- const data = hook.data || {}
298
- const query = params.query || {}
299
- const scope = data.scope || query.scope
300
- const grantedPermissions = data.permissions || query.permissions
301
- const grantedRole = (grantedPermissions ? Roles[grantedPermissions] : undefined)
302
- const resource = hook.params.resource
303
- const subjects = hook.params.subjects
304
- const subjectService = hook.params.subjectsService
305
- // On create check if we try to downgrade permissions otherwise let pass through
306
- if (!_.isUndefined(grantedRole) && (grantedRole === Roles.owner)) return hook
307
-
308
- if ((scope === resourceScope) && resource && resource._id) {
309
- // Count existing owners
310
- const owners = await countSubjectsForResource(subjectService, resourceScope, resource._id, Roles.owner)
311
- // Now count owners we change/remove permissions on
312
- const removedOwners = subjects.reduce((count, subject) => {
313
- const resources = _.get(subject, resourceScope, [])
314
- const ownedResource = _.find(resources, { _id: resource._id, permissions: RoleNames[Roles.owner] })
315
- return (ownedResource ? count + 1 : count)
316
- }, 0)
317
- // If none remains stop
318
- if (removedOwners >= owners.total) {
319
- debug('Cannot remove the last owner of resource ', resource)
320
- const resourceName = resource.name ? resource.name : resource._id.toString()
321
- throw new Forbidden('You are not allowed to remove the last owner of resource ' + resourceName, {
322
- translation: {
323
- key: 'CANNOT_REMOVE_LAST_OWNER',
324
- params: { resource: resourceName }
325
- }
326
- })
327
- }
328
- }
329
- return hook
330
- }
331
- }
332
-
333
- export async function removeOrganisationGroupsAuthorisations (hook) {
334
- const app = hook.app
335
- const authorisationService = app.getService('authorisations')
336
- const org = hook.params.resource
337
- const user = hook.params.user
338
- // Unset membership for the all org groups
339
- const orgGroupService = app.getService('groups', org)
340
- const groups = await orgGroupService.find({ paginate: false })
341
- await Promise.all(groups.map(group => {
342
- // Unset membership on group for the all org users
343
- return authorisationService.remove(group._id.toString(), {
344
- query: {
345
- scope: 'groups'
346
- },
347
- user,
348
- force: hook.params.force,
349
- // Because we already have resource set it as objects to avoid populating
350
- // Moreover used as an after hook the resource might not already exist anymore
351
- subjects: hook.params.subjects,
352
- subjectsService: hook.params.subjectsService,
353
- resource: group,
354
- resourcesService: orgGroupService
355
- })
356
- }))
357
- debug('Authorisations unset on groups for organisation ' + org._id)
358
- return hook
359
- }
360
-
361
- export async function removeOrganisationTagsAuthorisations (hook) {
362
- const app = hook.app
363
- const org = hook.params.resource
364
- const subjectService = hook.params.subjectsService
365
- const orgTagsService = app.getService('tags', org)
366
- const subjects = hook.params.subjects || []
367
- if (subjects.length === 0) return hook
368
- // Retrieve org tags
369
- const orgTags = await orgTagsService.find({ paginate: false })
370
- const promises = []
371
- subjects.forEach(subject => {
372
- const tags = subject.tags || []
373
- // Find tags from org
374
- const fromOrg = _.intersectionWith(tags, orgTags, isTagEqual)
375
- // Clear removed tags
376
- const notFromOrg = _.differenceWith(tags, orgTags, isTagEqual)
377
- // Update subject if required
378
- if (fromOrg.length > 0) {
379
- promises.push(subjectService.patch(subject._id.toString(), { tags: notFromOrg }))
380
- }
381
- })
382
- // Perform subject updates in parallel
383
- await Promise.all(promises)
384
- debug(`Tags unset on ${promises.length} subjects for organisation ` + org._id)
385
- return hook
386
- }
@@ -233,6 +233,10 @@ export async function distinct (hook) {
233
233
  // Check for already existing object according to given service/id field
234
234
  export function checkUnique (options = {}) {
235
235
  return async (hook) => {
236
+ if (hook.app) {
237
+ const serviceConfig = hook.app.get(hook.service.name)
238
+ if (serviceConfig && serviceConfig.checkUnique) options = serviceConfig.checkUnique
239
+ }
236
240
  const service = (options.service ? hook.app.getService(options.service) : hook.service)
237
241
  const field = options.field || 'name'
238
242
  const id = _.get(hook, `data.${field}`)
@@ -14,35 +14,41 @@ export async function sendNewSubscriptionEmail (hook) {
14
14
  if (hook.type !== 'after') {
15
15
  throw new Error('The \'sendNewSubscriptionEmail\' hook should only be used as a \'after\' hook.')
16
16
  }
17
-
18
17
  // Check for a new subscription if any
19
- const updatedUser = hook.result
18
+ const currentUser = hook.result
20
19
  const previousUser = hook.params.user
21
20
  // If we can't compare abort, eg f-a-m might patch user to update tokens
22
- if (!updatedUser || !previousUser) return hook
23
- const newSubscription = _.differenceBy(_.get(updatedUser, 'subscriptions', []), _.get(previousUser, 'subscriptions', []), 'endpoint')
24
- if (_.size(newSubscription) !== 1) return
25
-
26
- // Data
21
+ if (!currentUser || !previousUser) return
22
+ // Retrieve the last subscription
23
+ const lastSubscription = _.last(_.get(currentUser, 'subscriptions', []))
24
+ if (!lastSubscription) return
25
+ // Check whether the subscription has an existing fingerprint
26
+ const existingSubscription = _.find(_.get(previousUser, 'subscriptions', []), subscription => {
27
+ return _.isEqual(subscription.fingerprint, lastSubscription.fingerprint)
28
+ })
29
+ if (existingSubscription) {
30
+ debug('Last subscription uses an existing fingerprint')
31
+ return
32
+ }
33
+ debug('Last subscription uses uses a new fingerprint')
34
+ // Send an email to notify the user
27
35
  const app = hook.app
28
36
  const mailerService = app.getService('mailer')
29
37
  const domainPath = app.get('domain') + '/#/'
30
38
  const email = {
31
39
  subject: 'Security alert - new browser detected',
32
- from: mailerService.options.auth.user,
33
- // When changing email send to the new one so that it can be verified
34
- to: updatedUser.email,
40
+ from: mailerService.options.from || mailerService.options.auth.user,
41
+ to: currentUser.email,
35
42
  link: domainPath,
36
43
  domainPath
37
44
  }
38
-
39
45
  // Build the subject & link to the app to perform the different actions
40
46
  const templateDir = path.join(mailerService.options.templateDir, 'newSubscription')
41
47
  const template = new emails.EmailTemplate(templateDir)
42
48
  // Errors does not seem to be correctly catched by the caller
43
49
  // so we catch them here to avoid any problem
44
50
  try {
45
- const emailContent = await template.render({ email, user: updatedUser, subscription: _.first(newSubscription) }, updatedUser.locale || 'en-us')
51
+ const emailContent = await template.render({ email, user: currentUser, subscription: lastSubscription }, currentUser.locale || 'en-us')
46
52
  // Update compiled content
47
53
  email.html = emailContent.html
48
54
  debug('Sending email ', email)
@@ -51,6 +57,4 @@ export async function sendNewSubscriptionEmail (hook) {
51
57
  debug('Sending email failed', error)
52
58
  app.logger.error(error)
53
59
  }
54
-
55
- return hook
56
60
  }
@@ -135,86 +135,6 @@ export function generatePassword (options = {}) {
135
135
  }
136
136
  }
137
137
 
138
- export function preventRemoveUser (hook) {
139
- if (hook.type !== 'before') {
140
- throw new Error('The \'preventRemoveUser\' hook should only be used as a \'before\' hook.')
141
- }
142
-
143
- // By pass check ?
144
- if (hook.params.force) return hook
145
- const user = hook.params.user
146
- // Check if the target is the current user
147
- if ((user._id.toString() === hook.id.toString()) && user.organisations) {
148
- // We must ensure the user is no more a owner of an organisation
149
- const owningOrganisations = _.filter(user.organisations, { permissions: RoleNames[Roles.owner] })
150
- if (!_.isEmpty(owningOrganisations)) {
151
- debug('Cannot remove the user: ', user)
152
- throw new Forbidden('You are not allowed to delete the user ' + user.name, {
153
- translation: {
154
- key: 'CANNOT_REMOVE_USER',
155
- params: { user: _.get(user, 'profile.name') }
156
- }
157
- })
158
- }
159
- }
160
- return hook
161
- }
162
-
163
- export async function joinOrganisation (hook) {
164
- const app = hook.app
165
- const subject = getItems(hook)
166
- const authorisationService = app.getService('authorisations')
167
- const usersService = app.getService('users')
168
-
169
- // Set membership for the created user
170
- await authorisationService.create({
171
- scope: 'organisations',
172
- permissions: subject.sponsor.roleGranted, // Member by default
173
- resource: subject.sponsor.organisationId,
174
- resourcesService: 'organisations'
175
- }, {
176
- subjectsService: usersService,
177
- subjects: [subject]
178
- })
179
- debug('Organisation membership set for user ' + subject._id)
180
- return hook
181
- }
182
-
183
- export function leaveOrganisations (options = { skipPrivate: true }) {
184
- return async function (hook) {
185
- if (hook.type !== 'after') {
186
- throw new Error('The \'leaveOrganisations\' hook should only be used as a \'after\' hook.')
187
- }
188
-
189
- const app = hook.app
190
- const organisationsService = app.getService('organisations')
191
- const authorisationService = app.getService('authorisations')
192
- const usersService = app.getService('users')
193
- const subject = getItems(hook)
194
- const organisations = _.get(subject, 'organisations', [])
195
-
196
- await Promise.all(organisations.map(organisation => {
197
- // Unset membership on org except private org if required
198
- if (options.skipPrivate && organisation._id.toString() === subject._id.toString()) return Promise.resolve()
199
- return authorisationService.remove(organisation._id.toString(), {
200
- query: {
201
- scope: 'organisations'
202
- },
203
- user: hook.params.user,
204
- // Because we already have resource set it as objects to avoid populating
205
- // Moreover used as an after hook the subject might not already exist anymore
206
- subjects: [subject],
207
- subjectsService: usersService,
208
- resource: organisation,
209
- resourcesService: organisationsService
210
- })
211
- }))
212
-
213
- debug('Membership unset for all organisations on user ' + subject._id)
214
- return hook
215
- }
216
- }
217
-
218
138
  export async function sendVerificationEmail (hook) {
219
139
  if (hook.type !== 'after') {
220
140
  throw new Error('The \'sendVerificationEmail\' hook should only be used as a \'after\' hook.')
@@ -230,17 +150,6 @@ export async function sendVerificationEmail (hook) {
230
150
  return hook
231
151
  }
232
152
 
233
- export async function sendInvitationEmail (hook) {
234
- // Before because we need to send the clear password by email
235
- if (hook.type !== 'before') {
236
- throw new Error('The \'sendInvitationEmail\' hook should only be used as a \'before\' hook.')
237
- }
238
-
239
- const accountService = hook.app.getService('account')
240
- await accountService.options.notifier('sendInvitation', hook.data)
241
- return hook
242
- }
243
-
244
153
  export function addVerification (hook) {
245
154
  const accountService = hook.app.getService('account')
246
155
 
@@ -1,9 +1,7 @@
1
1
  export * from './hooks.authentication.js'
2
2
  export * from './hooks.authorisations.js'
3
- export * from './hooks.groups.js'
4
3
  export * from './hooks.logger.js'
5
4
  export * from './hooks.model.js'
6
- export * from './hooks.organisations.js'
7
5
  export * from './hooks.query.js'
8
6
  export * from './hooks.schemas.js'
9
7
  export * from './hooks.service.js'
@@ -42,7 +42,7 @@ export default function (name, app, options) {
42
42
  const mailerService = app.getService('mailer')
43
43
  const domainPath = app.get('domain') + '/#/'
44
44
  const email = {
45
- from: mailerService.options.auth.user,
45
+ from: mailerService.options.from || mailerService.options.auth.user,
46
46
  // When changing email send to the new one so that it can be verified
47
47
  to: (type === 'identityChange' ? user.verifyChanges.email : user.email),
48
48
  domainPath
@@ -22,10 +22,6 @@ export default {
22
22
  const scope = _.get(subject, scopeName, [])
23
23
  // Then the target resource
24
24
  let resource = _.find(scope, resource => resource._id && (resource._id.toString() === params.resource._id.toString()))
25
- if (!resource) {
26
- // Fallback as name
27
- resource = _.find(scope, resource => resource.name && (resource.name === params.resource.name))
28
- }
29
25
  // On first authorisation create the resource in scope
30
26
  if (!resource) {
31
27
  resource = Object.assign({}, params.resource)
@@ -46,7 +42,6 @@ export default {
46
42
  }, {
47
43
  user: params.user
48
44
  })
49
- await this.updateAbilities(subject)
50
45
  debug('Authorisation ' + data.permissions + ' set for subject ' + subject._id + ' on resource ' + params.resource._id + ' with scope ' + scopeName)
51
46
  return subject
52
47
  }))
@@ -79,7 +74,6 @@ export default {
79
74
  }, {
80
75
  user: params.user
81
76
  })
82
- await this.updateAbilities(subject)
83
77
  debug('Authorisation unset for subject ' + subject._id + ' on resource ' + id + ' with scope ' + scopeName)
84
78
  return subject
85
79
  }
@@ -91,37 +85,40 @@ export default {
91
85
  setup (app) {
92
86
  const config = app.get('authorisation')
93
87
  if (config && config.cache) {
88
+ this.cacheConfig = config.cache
94
89
  // Store abilities of the N most active users in LRU cache (defaults to 1000)
95
- const max = config.cache.maxUsers || 1000
90
+ const max = this.cacheConfig.maxUsers || 1000
96
91
  // LRU cache lib switched from positional parameters to options object at some point
97
92
  // so that now we directly pass the options to it while before we used the max argument
98
- if (!config.cache.max && !config.cache.ttl && !config.cache.maxSize) config.cache.max = max
99
- this.cache = new LRUCache(config.cache)
93
+ if (!this.cacheConfig.max && !this.cacheConfig.ttl && !this.cacheConfig.maxSize) this.cacheConfig.max = max
94
+ this.cache = new LRUCache(this.cacheConfig)
100
95
  debug('Using LRU cache for user abilities')
101
96
  } else {
102
97
  debug('Do not use LRU cache for user abilities')
103
98
  }
104
99
  },
105
100
 
101
+ getCacheKey (subject) {
102
+ if (!this.cache) return null
103
+ let cacheKey
104
+ // Compute cache key based on provided function or user ID
105
+ if (typeof this.cacheConfig.key === 'function') cacheKey = this.cacheConfig.key(subject)
106
+ if (!cacheKey && subject && subject._id) cacheKey = subject._id.toString()
107
+ return cacheKey || ANONYMOUS_USER
108
+ },
109
+
106
110
  // Compute abilities for a given user and set it in cache the first time
107
111
  // or get it from cache if found
108
112
  async getAbilities (subject) {
109
- if (this.cache) {
110
- if (subject && subject._id) {
111
- if (this.cache.has(subject._id.toString())) return this.cache.get(subject._id.toString())
112
- } else {
113
- if (this.cache.has(ANONYMOUS_USER)) return this.cache.get(ANONYMOUS_USER)
114
- }
115
- }
113
+ const cacheKey = this.getCacheKey(subject)
114
+ if (cacheKey && this.cache.has(cacheKey)) return this.cache.get(cacheKey)
115
+
116
116
  // Provide app for any complex use case requiring to make requests
117
117
  const abilities = await defineAbilities(subject, this.app)
118
118
 
119
- if (this.cache) {
120
- if (subject && subject._id) {
121
- this.cache.set(subject._id.toString(), abilities)
122
- } else {
123
- this.cache.set(ANONYMOUS_USER, abilities)
124
- }
119
+ if (cacheKey) {
120
+ debug('Updating abilities of subject ' + (subject ? subject._id : ANONYMOUS_USER) + ' with cache key ' + cacheKey)
121
+ this.cache.set(cacheKey, abilities)
125
122
  }
126
123
 
127
124
  return abilities
@@ -129,20 +126,20 @@ export default {
129
126
 
130
127
  // Compute abilities for a given user and update it in cache
131
128
  async updateAbilities (subject) {
132
- if (this.cache) {
133
- if (subject && subject._id) {
134
- this.cache.delete(subject._id.toString())
135
- } else {
136
- this.cache.delete(ANONYMOUS_USER)
137
- }
138
- }
139
-
129
+ const cacheKey = this.getCacheKey(subject)
130
+
131
+ // Remove abilities from cache so that next call will populate it again
132
+ if (cacheKey && this.cache.has(cacheKey)) this.cache.delete(cacheKey)
133
+
140
134
  const abilities = await this.getAbilities(subject)
141
135
  return abilities
142
136
  },
143
137
 
144
138
  // Clear abilities
145
139
  clearAbilities() {
146
- if (this.cache) this.cache.clear()
140
+ if (this.cache) {
141
+ debug('Clearing user abilities cache')
142
+ this.cache.clear()
143
+ }
147
144
  }
148
145
  }