@kalisio/kdk 2.2.2 → 2.3.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 (388) hide show
  1. package/.eslintignore +1 -0
  2. package/.github/workflows/main.yaml +67 -0
  3. package/.gitmodules +3 -0
  4. package/README.md +1 -2
  5. package/core/api/hooks/hooks.query.js +15 -2
  6. package/core/api/marshall.js +35 -4
  7. package/core/client/api.js +1 -1
  8. package/core/client/components/KActivity.vue +73 -0
  9. package/core/client/components/KContent.vue +1 -1
  10. package/core/client/components/KSponsor.vue +2 -13
  11. package/core/client/components/account/KDeleteAccountManager.vue +1 -1
  12. package/core/client/components/account/KPasswordManager.vue +1 -1
  13. package/core/client/components/action/KAction.vue +294 -0
  14. package/core/client/components/action/KBugReportAction.vue +37 -0
  15. package/core/client/components/action/index.js +7 -0
  16. package/core/client/components/app/KAbout.vue +16 -63
  17. package/core/client/components/app/KPlatform.vue +1 -1
  18. package/core/client/components/app/KSettings.vue +14 -14
  19. package/core/client/components/app/KTour.vue +6 -8
  20. package/core/client/components/app/KWelcome.vue +1 -1
  21. package/core/client/components/app/index.js +4 -0
  22. package/core/client/components/chart/KDataTable.vue +40 -25
  23. package/core/client/components/chart/KTimeSeriesChart.vue +20 -12
  24. package/core/client/components/collection/KCard.vue +1 -1
  25. package/core/client/components/collection/KCardSection.vue +3 -2
  26. package/core/client/components/collection/KColumn.vue +1 -1
  27. package/core/client/components/collection/KFilter.vue +6 -1
  28. package/core/client/components/document/KDocument.vue +83 -0
  29. package/core/client/components/document/KHtml.vue +23 -0
  30. package/core/client/components/document/KMarkdown.vue +37 -0
  31. package/core/client/components/document/index.js +9 -0
  32. package/core/client/components/form/KForm.vue +6 -2
  33. package/core/client/components/form/KSelectField.vue +1 -1
  34. package/core/client/components/index.js +1 -4
  35. package/core/client/components/input/KOptionsChooser.vue +1 -1
  36. package/core/client/components/layout/KFab.vue +1 -1
  37. package/core/client/components/layout/KPage.vue +3 -2
  38. package/core/client/components/layout/KWindow.vue +1 -1
  39. package/core/client/components/media/KColorScale.vue +16 -6
  40. package/core/client/components/screen/KLoginScreen.vue +1 -1
  41. package/core/client/components/screen/KRegisterScreen.vue +1 -1
  42. package/core/client/components/team/KAddMember.vue +7 -7
  43. package/core/client/components/team/KGroupCard.vue +1 -1
  44. package/core/client/components/team/KMemberFilter.vue +1 -1
  45. package/core/client/components/team/KTagCard.vue +1 -1
  46. package/core/client/components/time/KRelativeTimeRanges.vue +16 -1
  47. package/core/client/components/time/KTimeControl.vue +1 -0
  48. package/core/client/components/tool/KExportTool.vue +1 -1
  49. package/core/client/composables/collection.js +1 -1
  50. package/core/client/composables/index.js +1 -0
  51. package/core/client/composables/layout.js +50 -0
  52. package/core/client/composables/session.js +6 -0
  53. package/core/client/filter.js +9 -6
  54. package/core/client/guards.js +29 -6
  55. package/core/client/i18n/core_en.json +4 -1
  56. package/core/client/i18n/core_fr.json +8 -5
  57. package/core/client/i18n.js +14 -0
  58. package/core/client/layout.js +25 -14
  59. package/core/client/mixins/mixin.base-activity.js +16 -0
  60. package/core/client/services/index.js +27 -26
  61. package/core/client/services/local-settings.service.js +2 -3
  62. package/core/client/units.js +6 -1
  63. package/core/client/utils/index.js +3 -0
  64. package/core/client/utils/utils.actions.js +93 -0
  65. package/core/client/utils/utils.colors.js +1 -1
  66. package/core/client/utils/utils.data.js +22 -0
  67. package/core/client/utils/utils.shapes.js +16 -6
  68. package/coverage/base.css +224 -0
  69. package/coverage/block-navigation.js +87 -0
  70. package/coverage/core/api/application.js.html +1870 -0
  71. package/coverage/core/api/authentication.js.html +742 -0
  72. package/coverage/core/api/db.js.html +778 -0
  73. package/coverage/core/api/hooks/hooks.authentication.js.html +313 -0
  74. package/coverage/core/api/hooks/hooks.authorisations.js.html +1243 -0
  75. package/coverage/core/api/hooks/hooks.groups.js.html +229 -0
  76. package/coverage/core/api/hooks/hooks.logger.js.html +163 -0
  77. package/coverage/core/api/hooks/hooks.model.js.html +955 -0
  78. package/coverage/core/api/hooks/hooks.organisations.js.html +541 -0
  79. package/coverage/core/api/hooks/hooks.push.js.html +253 -0
  80. package/coverage/core/api/hooks/hooks.query.js.html +862 -0
  81. package/coverage/core/api/hooks/hooks.schemas.js.html +304 -0
  82. package/coverage/core/api/hooks/hooks.service.js.html +319 -0
  83. package/coverage/core/api/hooks/hooks.storage.js.html +193 -0
  84. package/coverage/core/api/hooks/hooks.users.js.html +868 -0
  85. package/coverage/core/api/hooks/index.html +296 -0
  86. package/coverage/core/api/hooks/index.js.html +121 -0
  87. package/coverage/core/api/index.html +191 -0
  88. package/coverage/core/api/index.js.html +148 -0
  89. package/coverage/core/api/marshall.js.html +448 -0
  90. package/coverage/core/api/models/groups.model.mongodb.js.html +109 -0
  91. package/coverage/core/api/models/index.html +161 -0
  92. package/coverage/core/api/models/organisations.model.mongodb.js.html +94 -0
  93. package/coverage/core/api/models/tags.model.mongodb.js.html +115 -0
  94. package/coverage/core/api/models/users.model.mongodb.js.html +115 -0
  95. package/coverage/core/api/services/account/account.hooks.js.html +208 -0
  96. package/coverage/core/api/services/account/account.service.js.html +436 -0
  97. package/coverage/core/api/services/account/index.html +131 -0
  98. package/coverage/core/api/services/authorisations/authorisations.hooks.js.html +184 -0
  99. package/coverage/core/api/services/authorisations/authorisations.service.js.html +502 -0
  100. package/coverage/core/api/services/authorisations/index.html +131 -0
  101. package/coverage/core/api/services/databases/databases.hooks.js.html +193 -0
  102. package/coverage/core/api/services/databases/databases.service.js.html +100 -0
  103. package/coverage/core/api/services/databases/index.html +131 -0
  104. package/coverage/core/api/services/groups/groups.hooks.js.html +178 -0
  105. package/coverage/core/api/services/groups/index.html +116 -0
  106. package/coverage/core/api/services/import-export/import-export.hooks.js.html +184 -0
  107. package/coverage/core/api/services/import-export/import-export.service.js.html +118 -0
  108. package/coverage/core/api/services/import-export/index.html +131 -0
  109. package/coverage/core/api/services/index.html +116 -0
  110. package/coverage/core/api/services/index.js.html +499 -0
  111. package/coverage/core/api/services/mailer/index.html +131 -0
  112. package/coverage/core/api/services/mailer/mailer.hooks.js.html +190 -0
  113. package/coverage/core/api/services/mailer/mailer.service.js.html +118 -0
  114. package/coverage/core/api/services/organisations/index.html +131 -0
  115. package/coverage/core/api/services/organisations/organisations.hooks.js.html +178 -0
  116. package/coverage/core/api/services/organisations/organisations.service.js.html +343 -0
  117. package/coverage/core/api/services/push/index.html +131 -0
  118. package/coverage/core/api/services/push/push.hooks.js.html +190 -0
  119. package/coverage/core/api/services/push/push.service.js.html +121 -0
  120. package/coverage/core/api/services/storage/index.html +131 -0
  121. package/coverage/core/api/services/storage/storage.hooks.js.html +190 -0
  122. package/coverage/core/api/services/storage/storage.service.js.html +172 -0
  123. package/coverage/core/api/services/tags/index.html +116 -0
  124. package/coverage/core/api/services/tags/tags.hooks.js.html +178 -0
  125. package/coverage/core/api/services/users/index.html +116 -0
  126. package/coverage/core/api/services/users/users.hooks.js.html +307 -0
  127. package/coverage/core/api/utils.js.html +118 -0
  128. package/coverage/core/common/errors.js.html +88 -0
  129. package/coverage/core/common/index.html +176 -0
  130. package/coverage/core/common/index.js.html +115 -0
  131. package/coverage/core/common/permissions.js.html +1048 -0
  132. package/coverage/core/common/schema.js.html +190 -0
  133. package/coverage/core/common/utils.js.html +220 -0
  134. package/coverage/favicon.png +0 -0
  135. package/coverage/index.html +491 -0
  136. package/coverage/lcov-report/base.css +224 -0
  137. package/coverage/lcov-report/block-navigation.js +87 -0
  138. package/coverage/lcov-report/core/api/application.js.html +1870 -0
  139. package/coverage/lcov-report/core/api/authentication.js.html +742 -0
  140. package/coverage/lcov-report/core/api/db.js.html +778 -0
  141. package/coverage/lcov-report/core/api/hooks/hooks.authentication.js.html +313 -0
  142. package/coverage/lcov-report/core/api/hooks/hooks.authorisations.js.html +1243 -0
  143. package/coverage/lcov-report/core/api/hooks/hooks.groups.js.html +229 -0
  144. package/coverage/lcov-report/core/api/hooks/hooks.logger.js.html +163 -0
  145. package/coverage/lcov-report/core/api/hooks/hooks.model.js.html +955 -0
  146. package/coverage/lcov-report/core/api/hooks/hooks.organisations.js.html +541 -0
  147. package/coverage/lcov-report/core/api/hooks/hooks.push.js.html +253 -0
  148. package/coverage/lcov-report/core/api/hooks/hooks.query.js.html +862 -0
  149. package/coverage/lcov-report/core/api/hooks/hooks.schemas.js.html +304 -0
  150. package/coverage/lcov-report/core/api/hooks/hooks.service.js.html +319 -0
  151. package/coverage/lcov-report/core/api/hooks/hooks.storage.js.html +193 -0
  152. package/coverage/lcov-report/core/api/hooks/hooks.users.js.html +868 -0
  153. package/coverage/lcov-report/core/api/hooks/index.html +296 -0
  154. package/coverage/lcov-report/core/api/hooks/index.js.html +121 -0
  155. package/coverage/lcov-report/core/api/index.html +191 -0
  156. package/coverage/lcov-report/core/api/index.js.html +148 -0
  157. package/coverage/lcov-report/core/api/marshall.js.html +448 -0
  158. package/coverage/lcov-report/core/api/models/groups.model.mongodb.js.html +109 -0
  159. package/coverage/lcov-report/core/api/models/index.html +161 -0
  160. package/coverage/lcov-report/core/api/models/organisations.model.mongodb.js.html +94 -0
  161. package/coverage/lcov-report/core/api/models/tags.model.mongodb.js.html +115 -0
  162. package/coverage/lcov-report/core/api/models/users.model.mongodb.js.html +115 -0
  163. package/coverage/lcov-report/core/api/services/account/account.hooks.js.html +208 -0
  164. package/coverage/lcov-report/core/api/services/account/account.service.js.html +436 -0
  165. package/coverage/lcov-report/core/api/services/account/index.html +131 -0
  166. package/coverage/lcov-report/core/api/services/authorisations/authorisations.hooks.js.html +184 -0
  167. package/coverage/lcov-report/core/api/services/authorisations/authorisations.service.js.html +502 -0
  168. package/coverage/lcov-report/core/api/services/authorisations/index.html +131 -0
  169. package/coverage/lcov-report/core/api/services/databases/databases.hooks.js.html +193 -0
  170. package/coverage/lcov-report/core/api/services/databases/databases.service.js.html +100 -0
  171. package/coverage/lcov-report/core/api/services/databases/index.html +131 -0
  172. package/coverage/lcov-report/core/api/services/groups/groups.hooks.js.html +178 -0
  173. package/coverage/lcov-report/core/api/services/groups/index.html +116 -0
  174. package/coverage/lcov-report/core/api/services/import-export/import-export.hooks.js.html +184 -0
  175. package/coverage/lcov-report/core/api/services/import-export/import-export.service.js.html +118 -0
  176. package/coverage/lcov-report/core/api/services/import-export/index.html +131 -0
  177. package/coverage/lcov-report/core/api/services/index.html +116 -0
  178. package/coverage/lcov-report/core/api/services/index.js.html +499 -0
  179. package/coverage/lcov-report/core/api/services/mailer/index.html +131 -0
  180. package/coverage/lcov-report/core/api/services/mailer/mailer.hooks.js.html +190 -0
  181. package/coverage/lcov-report/core/api/services/mailer/mailer.service.js.html +118 -0
  182. package/coverage/lcov-report/core/api/services/organisations/index.html +131 -0
  183. package/coverage/lcov-report/core/api/services/organisations/organisations.hooks.js.html +178 -0
  184. package/coverage/lcov-report/core/api/services/organisations/organisations.service.js.html +343 -0
  185. package/coverage/lcov-report/core/api/services/push/index.html +131 -0
  186. package/coverage/lcov-report/core/api/services/push/push.hooks.js.html +190 -0
  187. package/coverage/lcov-report/core/api/services/push/push.service.js.html +121 -0
  188. package/coverage/lcov-report/core/api/services/storage/index.html +131 -0
  189. package/coverage/lcov-report/core/api/services/storage/storage.hooks.js.html +190 -0
  190. package/coverage/lcov-report/core/api/services/storage/storage.service.js.html +172 -0
  191. package/coverage/lcov-report/core/api/services/tags/index.html +116 -0
  192. package/coverage/lcov-report/core/api/services/tags/tags.hooks.js.html +178 -0
  193. package/coverage/lcov-report/core/api/services/users/index.html +116 -0
  194. package/coverage/lcov-report/core/api/services/users/users.hooks.js.html +307 -0
  195. package/coverage/lcov-report/core/api/utils.js.html +118 -0
  196. package/coverage/lcov-report/core/common/errors.js.html +88 -0
  197. package/coverage/lcov-report/core/common/index.html +176 -0
  198. package/coverage/lcov-report/core/common/index.js.html +115 -0
  199. package/coverage/lcov-report/core/common/permissions.js.html +1048 -0
  200. package/coverage/lcov-report/core/common/schema.js.html +190 -0
  201. package/coverage/lcov-report/core/common/utils.js.html +220 -0
  202. package/coverage/lcov-report/favicon.png +0 -0
  203. package/coverage/lcov-report/index.html +491 -0
  204. package/coverage/lcov-report/map/api/hooks/hooks.catalog.js.html +457 -0
  205. package/coverage/lcov-report/map/api/hooks/hooks.features.js.html +397 -0
  206. package/coverage/lcov-report/map/api/hooks/hooks.query.js.html +1309 -0
  207. package/coverage/lcov-report/map/api/hooks/index.html +161 -0
  208. package/coverage/lcov-report/map/api/hooks/index.js.html +94 -0
  209. package/coverage/lcov-report/map/api/index.html +131 -0
  210. package/coverage/lcov-report/map/api/index.js.html +139 -0
  211. package/coverage/lcov-report/map/api/marshall.js.html +178 -0
  212. package/coverage/lcov-report/map/api/models/alerts.model.mongodb.js.html +106 -0
  213. package/coverage/lcov-report/map/api/models/catalog.model.mongodb.js.html +127 -0
  214. package/coverage/lcov-report/map/api/models/features.model.mongodb.js.html +196 -0
  215. package/coverage/lcov-report/map/api/models/index.html +161 -0
  216. package/coverage/lcov-report/map/api/models/projects.model.mongodb.js.html +109 -0
  217. package/coverage/lcov-report/map/api/services/alerts/alerts.hooks.js.html +274 -0
  218. package/coverage/lcov-report/map/api/services/alerts/alerts.service.js.html +610 -0
  219. package/coverage/lcov-report/map/api/services/alerts/index.html +131 -0
  220. package/coverage/lcov-report/map/api/services/catalog/catalog.hooks.js.html +316 -0
  221. package/coverage/lcov-report/map/api/services/catalog/index.html +116 -0
  222. package/coverage/lcov-report/map/api/services/daptiles/daptiles.service.js.html +1510 -0
  223. package/coverage/lcov-report/map/api/services/daptiles/index.html +116 -0
  224. package/coverage/lcov-report/map/api/services/features/features.hooks.js.html +241 -0
  225. package/coverage/lcov-report/map/api/services/features/features.service.js.html +241 -0
  226. package/coverage/lcov-report/map/api/services/features/index.html +131 -0
  227. package/coverage/lcov-report/map/api/services/index.html +116 -0
  228. package/coverage/lcov-report/map/api/services/index.js.html +817 -0
  229. package/coverage/lcov-report/map/api/services/projects/index.html +116 -0
  230. package/coverage/lcov-report/map/api/services/projects/projects.hooks.js.html +439 -0
  231. package/coverage/lcov-report/map/common/dynamic-grid-source.js.html +466 -0
  232. package/coverage/lcov-report/map/common/errors.js.html +94 -0
  233. package/coverage/lcov-report/map/common/geotiff-grid-source.js.html +541 -0
  234. package/coverage/lcov-report/map/common/grid.js.html +1612 -0
  235. package/coverage/lcov-report/map/common/index.html +371 -0
  236. package/coverage/lcov-report/map/common/index.js.html +172 -0
  237. package/coverage/lcov-report/map/common/meteo-model-grid-source.js.html +556 -0
  238. package/coverage/lcov-report/map/common/moment-utils.js.html +157 -0
  239. package/coverage/lcov-report/map/common/opendap-grid-source.js.html +868 -0
  240. package/coverage/lcov-report/map/common/opendap-utils.js.html +826 -0
  241. package/coverage/lcov-report/map/common/permissions.js.html +124 -0
  242. package/coverage/lcov-report/map/common/time-based-grid-source.js.html +418 -0
  243. package/coverage/lcov-report/map/common/tms-utils.js.html +274 -0
  244. package/coverage/lcov-report/map/common/wcs-grid-source.js.html +364 -0
  245. package/coverage/lcov-report/map/common/wcs-utils.js.html +586 -0
  246. package/coverage/lcov-report/map/common/weacast-grid-source.js.html +1033 -0
  247. package/coverage/lcov-report/map/common/wfs-utils.js.html +574 -0
  248. package/coverage/lcov-report/map/common/wms-utils.js.html +451 -0
  249. package/coverage/lcov-report/map/common/wmts-utils.js.html +547 -0
  250. package/coverage/lcov-report/prettify.css +1 -0
  251. package/coverage/lcov-report/prettify.js +2 -0
  252. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  253. package/coverage/lcov-report/sorter.js +196 -0
  254. package/coverage/lcov.info +11128 -0
  255. package/coverage/map/api/hooks/hooks.catalog.js.html +457 -0
  256. package/coverage/map/api/hooks/hooks.features.js.html +397 -0
  257. package/coverage/map/api/hooks/hooks.query.js.html +1309 -0
  258. package/coverage/map/api/hooks/index.html +161 -0
  259. package/coverage/map/api/hooks/index.js.html +94 -0
  260. package/coverage/map/api/index.html +131 -0
  261. package/coverage/map/api/index.js.html +139 -0
  262. package/coverage/map/api/marshall.js.html +178 -0
  263. package/coverage/map/api/models/alerts.model.mongodb.js.html +106 -0
  264. package/coverage/map/api/models/catalog.model.mongodb.js.html +127 -0
  265. package/coverage/map/api/models/features.model.mongodb.js.html +196 -0
  266. package/coverage/map/api/models/index.html +161 -0
  267. package/coverage/map/api/models/projects.model.mongodb.js.html +109 -0
  268. package/coverage/map/api/services/alerts/alerts.hooks.js.html +274 -0
  269. package/coverage/map/api/services/alerts/alerts.service.js.html +610 -0
  270. package/coverage/map/api/services/alerts/index.html +131 -0
  271. package/coverage/map/api/services/catalog/catalog.hooks.js.html +316 -0
  272. package/coverage/map/api/services/catalog/index.html +116 -0
  273. package/coverage/map/api/services/daptiles/daptiles.service.js.html +1510 -0
  274. package/coverage/map/api/services/daptiles/index.html +116 -0
  275. package/coverage/map/api/services/features/features.hooks.js.html +241 -0
  276. package/coverage/map/api/services/features/features.service.js.html +241 -0
  277. package/coverage/map/api/services/features/index.html +131 -0
  278. package/coverage/map/api/services/index.html +116 -0
  279. package/coverage/map/api/services/index.js.html +817 -0
  280. package/coverage/map/api/services/projects/index.html +116 -0
  281. package/coverage/map/api/services/projects/projects.hooks.js.html +439 -0
  282. package/coverage/map/common/dynamic-grid-source.js.html +466 -0
  283. package/coverage/map/common/errors.js.html +94 -0
  284. package/coverage/map/common/geotiff-grid-source.js.html +541 -0
  285. package/coverage/map/common/grid.js.html +1612 -0
  286. package/coverage/map/common/index.html +371 -0
  287. package/coverage/map/common/index.js.html +172 -0
  288. package/coverage/map/common/meteo-model-grid-source.js.html +556 -0
  289. package/coverage/map/common/moment-utils.js.html +157 -0
  290. package/coverage/map/common/opendap-grid-source.js.html +868 -0
  291. package/coverage/map/common/opendap-utils.js.html +826 -0
  292. package/coverage/map/common/permissions.js.html +124 -0
  293. package/coverage/map/common/time-based-grid-source.js.html +418 -0
  294. package/coverage/map/common/tms-utils.js.html +274 -0
  295. package/coverage/map/common/wcs-grid-source.js.html +364 -0
  296. package/coverage/map/common/wcs-utils.js.html +586 -0
  297. package/coverage/map/common/weacast-grid-source.js.html +1033 -0
  298. package/coverage/map/common/wfs-utils.js.html +574 -0
  299. package/coverage/map/common/wms-utils.js.html +451 -0
  300. package/coverage/map/common/wmts-utils.js.html +547 -0
  301. package/coverage/prettify.css +1 -0
  302. package/coverage/prettify.js +2 -0
  303. package/coverage/sort-arrow-sprite.png +0 -0
  304. package/coverage/sorter.js +196 -0
  305. package/coverage/tmp/coverage-137435-1719398750767-0.json +1 -0
  306. package/coverage/tmp/coverage-137447-1719398750752-0.json +1 -0
  307. package/coverage/tmp/coverage-137458-1719398750740-0.json +1 -0
  308. package/coverage/tmp/coverage-137470-1719398750728-0.json +1 -0
  309. package/coverage/tmp/coverage-137477-1719398750691-0.json +1 -0
  310. package/map/api/hooks/hooks.query.js +5 -2
  311. package/map/api/services/catalog/catalog.hooks.js +4 -5
  312. package/map/client/cesium/utils/index.js +2 -1
  313. package/map/client/cesium/utils/utils.cesium.js +8 -0
  314. package/map/client/cesium/utils/utils.features.js +2 -2
  315. package/map/client/cesium/utils/utils.style.js +19 -17
  316. package/map/client/components/KCompass.vue +25 -3
  317. package/map/client/components/KEditLayerData.vue +1 -1
  318. package/map/client/components/KPositionIndicator.vue +1 -1
  319. package/map/client/components/catalog/KConnectLayer.vue +2 -2
  320. package/map/client/components/catalog/KCreateView.vue +2 -2
  321. package/map/client/components/form/KDirectionField.vue +4 -0
  322. package/map/client/components/form/KOwsLayerField.vue +4 -4
  323. package/map/client/components/form/KOwsServiceField.vue +3 -4
  324. package/map/client/components/legend/KLegend.vue +13 -15
  325. package/map/client/components/tools/KGeolocateTool.vue +1 -1
  326. package/map/client/components/widget/KStackableTimeSeries.vue +3 -0
  327. package/map/client/composables/highlight.js +4 -1
  328. package/map/client/elevation-utils.js +2 -2
  329. package/map/client/i18n/map_en.json +3 -1
  330. package/map/client/i18n/map_fr.json +3 -1
  331. package/map/client/mixins/globe/mixin.base-globe.js +121 -80
  332. package/map/client/mixins/globe/mixin.file-layers.js +2 -2
  333. package/map/client/mixins/globe/mixin.geojson-layers.js +24 -19
  334. package/map/client/mixins/globe/mixin.globe-activity.js +3 -3
  335. package/map/client/mixins/globe/mixin.opendap-layers.js +3 -3
  336. package/map/client/mixins/globe/mixin.style.js +5 -5
  337. package/map/client/mixins/globe/mixin.tooltip.js +5 -3
  338. package/map/client/mixins/map/mixin.base-map.js +42 -4
  339. package/map/client/mixins/map/mixin.canvas-layers.js +0 -1
  340. package/map/client/mixins/map/mixin.geojson-layers.js +10 -5
  341. package/map/client/mixins/mixin.activity.js +2 -2
  342. package/map/client/mixins/mixin.feature-selection.js +7 -5
  343. package/map/client/mixins/mixin.levels.js +1 -1
  344. package/map/client/utils/utils.catalog.js +15 -0
  345. package/map/client/utils/utils.location.js +2 -1
  346. package/map/client/utils/utils.style.js +1 -1
  347. package/map/common/geotiff-grid-source.js +5 -3
  348. package/map/common/grid.js +2 -2
  349. package/map/common/meteo-model-grid-source.js +1 -1
  350. package/map/common/time-based-grid-source.js +1 -1
  351. package/map/common/wmts-utils.js +11 -11
  352. package/package.json +12 -8
  353. package/scripts/build_docs.sh +37 -0
  354. package/scripts/init_runner.sh +30 -0
  355. package/scripts/kash/.github/workflows/run_tests.yaml +33 -0
  356. package/scripts/kash/README.md +2 -0
  357. package/scripts/kash/kash.sh +1657 -0
  358. package/scripts/kash/scripts/run_tests.sh +151 -0
  359. package/scripts/run_tests.sh +48 -0
  360. package/scripts/setup_workspace.sh +42 -0
  361. package/test/api/core/hooks.test.js +31 -0
  362. package/test/api/core/test-log-2023-12-19.log +7 -0
  363. package/test/api/core/test-log-2024-01-04.log +14 -0
  364. package/test/api/core/test-log-2024-05-14.log +6 -0
  365. package/test/api/core/test-log-2024-06-06.log +23 -0
  366. package/test/api/core/test-log-2024-06-26.log +25 -0
  367. package/test/api/core/test-log-2024-06-28.log +2 -0
  368. package/test/api/map/grid-sources.test.js +3 -1
  369. package/test/api/map/hooks.test.js +58 -12
  370. package/test/api/map/test-log-2023-11-24.log +121 -0
  371. package/test/api/map/test-log-2023-12-12.log +29 -0
  372. package/test/api/map/test-log-2023-12-13.log +5 -0
  373. package/test/api/map/test-log-2024-01-04.log +2 -0
  374. package/test/api/map/test-log-2024-01-11.log +1 -0
  375. package/test/api/map/test-log-2024-01-25.log +19 -0
  376. package/test/api/map/test-log-2024-06-06.log +39 -0
  377. package/test/client/core/collection.js +2 -2
  378. package/test/client/core/dialogs.js +13 -0
  379. package/test/client/core/index.js +6 -5
  380. package/test/client/core/layout.js +1 -13
  381. package/test/client/core/runner.js +41 -20
  382. package/test/client/core/screens.js +6 -0
  383. package/test/client/core/utils.js +23 -19
  384. package/.travis.doc.sh +0 -8
  385. package/.travis.test.sh +0 -72
  386. package/core/client/components/KAction.vue +0 -393
  387. package/core/client/components/KBlock.vue +0 -67
  388. package/core/client/components/app/KTerms.vue +0 -41
@@ -0,0 +1,1048 @@
1
+
2
+ <!doctype html>
3
+ <html lang="en">
4
+
5
+ <head>
6
+ <title>Code coverage report for core/common/permissions.js</title>
7
+ <meta charset="utf-8" />
8
+ <link rel="stylesheet" href="../../prettify.css" />
9
+ <link rel="stylesheet" href="../../base.css" />
10
+ <link rel="shortcut icon" type="image/x-icon" href="../../favicon.png" />
11
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
12
+ <style type='text/css'>
13
+ .coverage-summary .sorter {
14
+ background-image: url(../../sort-arrow-sprite.png);
15
+ }
16
+ </style>
17
+ </head>
18
+
19
+ <body>
20
+ <div class='wrapper'>
21
+ <div class='pad1'>
22
+ <h1><a href="../../index.html">All files</a> / <a href="index.html">core/common</a> permissions.js</h1>
23
+ <div class='clearfix'>
24
+
25
+ <div class='fl pad1y space-right2'>
26
+ <span class="strong">88.78% </span>
27
+ <span class="quiet">Statements</span>
28
+ <span class='fraction'>285/321</span>
29
+ </div>
30
+
31
+
32
+ <div class='fl pad1y space-right2'>
33
+ <span class="strong">82.35% </span>
34
+ <span class="quiet">Branches</span>
35
+ <span class='fraction'>42/51</span>
36
+ </div>
37
+
38
+
39
+ <div class='fl pad1y space-right2'>
40
+ <span class="strong">53.57% </span>
41
+ <span class="quiet">Functions</span>
42
+ <span class='fraction'>15/28</span>
43
+ </div>
44
+
45
+
46
+ <div class='fl pad1y space-right2'>
47
+ <span class="strong">88.78% </span>
48
+ <span class="quiet">Lines</span>
49
+ <span class='fraction'>285/321</span>
50
+ </div>
51
+
52
+
53
+ </div>
54
+ <p class="quiet">
55
+ Press <em>n</em> or <em>j</em> to go to the next uncovered block, <em>b</em>, <em>p</em> or <em>k</em> for the previous block.
56
+ </p>
57
+ <template id="filterTemplate">
58
+ <div class="quiet">
59
+ Filter:
60
+ <input oninput="onInput()" type="search" id="fileSearch">
61
+ </div>
62
+ </template>
63
+ </div>
64
+ <div class='status-line high'></div>
65
+ <pre><table class="coverage">
66
+ <tr><td class="line-count quiet"><a name='L1'></a><a href='#L1'>1</a>
67
+ <a name='L2'></a><a href='#L2'>2</a>
68
+ <a name='L3'></a><a href='#L3'>3</a>
69
+ <a name='L4'></a><a href='#L4'>4</a>
70
+ <a name='L5'></a><a href='#L5'>5</a>
71
+ <a name='L6'></a><a href='#L6'>6</a>
72
+ <a name='L7'></a><a href='#L7'>7</a>
73
+ <a name='L8'></a><a href='#L8'>8</a>
74
+ <a name='L9'></a><a href='#L9'>9</a>
75
+ <a name='L10'></a><a href='#L10'>10</a>
76
+ <a name='L11'></a><a href='#L11'>11</a>
77
+ <a name='L12'></a><a href='#L12'>12</a>
78
+ <a name='L13'></a><a href='#L13'>13</a>
79
+ <a name='L14'></a><a href='#L14'>14</a>
80
+ <a name='L15'></a><a href='#L15'>15</a>
81
+ <a name='L16'></a><a href='#L16'>16</a>
82
+ <a name='L17'></a><a href='#L17'>17</a>
83
+ <a name='L18'></a><a href='#L18'>18</a>
84
+ <a name='L19'></a><a href='#L19'>19</a>
85
+ <a name='L20'></a><a href='#L20'>20</a>
86
+ <a name='L21'></a><a href='#L21'>21</a>
87
+ <a name='L22'></a><a href='#L22'>22</a>
88
+ <a name='L23'></a><a href='#L23'>23</a>
89
+ <a name='L24'></a><a href='#L24'>24</a>
90
+ <a name='L25'></a><a href='#L25'>25</a>
91
+ <a name='L26'></a><a href='#L26'>26</a>
92
+ <a name='L27'></a><a href='#L27'>27</a>
93
+ <a name='L28'></a><a href='#L28'>28</a>
94
+ <a name='L29'></a><a href='#L29'>29</a>
95
+ <a name='L30'></a><a href='#L30'>30</a>
96
+ <a name='L31'></a><a href='#L31'>31</a>
97
+ <a name='L32'></a><a href='#L32'>32</a>
98
+ <a name='L33'></a><a href='#L33'>33</a>
99
+ <a name='L34'></a><a href='#L34'>34</a>
100
+ <a name='L35'></a><a href='#L35'>35</a>
101
+ <a name='L36'></a><a href='#L36'>36</a>
102
+ <a name='L37'></a><a href='#L37'>37</a>
103
+ <a name='L38'></a><a href='#L38'>38</a>
104
+ <a name='L39'></a><a href='#L39'>39</a>
105
+ <a name='L40'></a><a href='#L40'>40</a>
106
+ <a name='L41'></a><a href='#L41'>41</a>
107
+ <a name='L42'></a><a href='#L42'>42</a>
108
+ <a name='L43'></a><a href='#L43'>43</a>
109
+ <a name='L44'></a><a href='#L44'>44</a>
110
+ <a name='L45'></a><a href='#L45'>45</a>
111
+ <a name='L46'></a><a href='#L46'>46</a>
112
+ <a name='L47'></a><a href='#L47'>47</a>
113
+ <a name='L48'></a><a href='#L48'>48</a>
114
+ <a name='L49'></a><a href='#L49'>49</a>
115
+ <a name='L50'></a><a href='#L50'>50</a>
116
+ <a name='L51'></a><a href='#L51'>51</a>
117
+ <a name='L52'></a><a href='#L52'>52</a>
118
+ <a name='L53'></a><a href='#L53'>53</a>
119
+ <a name='L54'></a><a href='#L54'>54</a>
120
+ <a name='L55'></a><a href='#L55'>55</a>
121
+ <a name='L56'></a><a href='#L56'>56</a>
122
+ <a name='L57'></a><a href='#L57'>57</a>
123
+ <a name='L58'></a><a href='#L58'>58</a>
124
+ <a name='L59'></a><a href='#L59'>59</a>
125
+ <a name='L60'></a><a href='#L60'>60</a>
126
+ <a name='L61'></a><a href='#L61'>61</a>
127
+ <a name='L62'></a><a href='#L62'>62</a>
128
+ <a name='L63'></a><a href='#L63'>63</a>
129
+ <a name='L64'></a><a href='#L64'>64</a>
130
+ <a name='L65'></a><a href='#L65'>65</a>
131
+ <a name='L66'></a><a href='#L66'>66</a>
132
+ <a name='L67'></a><a href='#L67'>67</a>
133
+ <a name='L68'></a><a href='#L68'>68</a>
134
+ <a name='L69'></a><a href='#L69'>69</a>
135
+ <a name='L70'></a><a href='#L70'>70</a>
136
+ <a name='L71'></a><a href='#L71'>71</a>
137
+ <a name='L72'></a><a href='#L72'>72</a>
138
+ <a name='L73'></a><a href='#L73'>73</a>
139
+ <a name='L74'></a><a href='#L74'>74</a>
140
+ <a name='L75'></a><a href='#L75'>75</a>
141
+ <a name='L76'></a><a href='#L76'>76</a>
142
+ <a name='L77'></a><a href='#L77'>77</a>
143
+ <a name='L78'></a><a href='#L78'>78</a>
144
+ <a name='L79'></a><a href='#L79'>79</a>
145
+ <a name='L80'></a><a href='#L80'>80</a>
146
+ <a name='L81'></a><a href='#L81'>81</a>
147
+ <a name='L82'></a><a href='#L82'>82</a>
148
+ <a name='L83'></a><a href='#L83'>83</a>
149
+ <a name='L84'></a><a href='#L84'>84</a>
150
+ <a name='L85'></a><a href='#L85'>85</a>
151
+ <a name='L86'></a><a href='#L86'>86</a>
152
+ <a name='L87'></a><a href='#L87'>87</a>
153
+ <a name='L88'></a><a href='#L88'>88</a>
154
+ <a name='L89'></a><a href='#L89'>89</a>
155
+ <a name='L90'></a><a href='#L90'>90</a>
156
+ <a name='L91'></a><a href='#L91'>91</a>
157
+ <a name='L92'></a><a href='#L92'>92</a>
158
+ <a name='L93'></a><a href='#L93'>93</a>
159
+ <a name='L94'></a><a href='#L94'>94</a>
160
+ <a name='L95'></a><a href='#L95'>95</a>
161
+ <a name='L96'></a><a href='#L96'>96</a>
162
+ <a name='L97'></a><a href='#L97'>97</a>
163
+ <a name='L98'></a><a href='#L98'>98</a>
164
+ <a name='L99'></a><a href='#L99'>99</a>
165
+ <a name='L100'></a><a href='#L100'>100</a>
166
+ <a name='L101'></a><a href='#L101'>101</a>
167
+ <a name='L102'></a><a href='#L102'>102</a>
168
+ <a name='L103'></a><a href='#L103'>103</a>
169
+ <a name='L104'></a><a href='#L104'>104</a>
170
+ <a name='L105'></a><a href='#L105'>105</a>
171
+ <a name='L106'></a><a href='#L106'>106</a>
172
+ <a name='L107'></a><a href='#L107'>107</a>
173
+ <a name='L108'></a><a href='#L108'>108</a>
174
+ <a name='L109'></a><a href='#L109'>109</a>
175
+ <a name='L110'></a><a href='#L110'>110</a>
176
+ <a name='L111'></a><a href='#L111'>111</a>
177
+ <a name='L112'></a><a href='#L112'>112</a>
178
+ <a name='L113'></a><a href='#L113'>113</a>
179
+ <a name='L114'></a><a href='#L114'>114</a>
180
+ <a name='L115'></a><a href='#L115'>115</a>
181
+ <a name='L116'></a><a href='#L116'>116</a>
182
+ <a name='L117'></a><a href='#L117'>117</a>
183
+ <a name='L118'></a><a href='#L118'>118</a>
184
+ <a name='L119'></a><a href='#L119'>119</a>
185
+ <a name='L120'></a><a href='#L120'>120</a>
186
+ <a name='L121'></a><a href='#L121'>121</a>
187
+ <a name='L122'></a><a href='#L122'>122</a>
188
+ <a name='L123'></a><a href='#L123'>123</a>
189
+ <a name='L124'></a><a href='#L124'>124</a>
190
+ <a name='L125'></a><a href='#L125'>125</a>
191
+ <a name='L126'></a><a href='#L126'>126</a>
192
+ <a name='L127'></a><a href='#L127'>127</a>
193
+ <a name='L128'></a><a href='#L128'>128</a>
194
+ <a name='L129'></a><a href='#L129'>129</a>
195
+ <a name='L130'></a><a href='#L130'>130</a>
196
+ <a name='L131'></a><a href='#L131'>131</a>
197
+ <a name='L132'></a><a href='#L132'>132</a>
198
+ <a name='L133'></a><a href='#L133'>133</a>
199
+ <a name='L134'></a><a href='#L134'>134</a>
200
+ <a name='L135'></a><a href='#L135'>135</a>
201
+ <a name='L136'></a><a href='#L136'>136</a>
202
+ <a name='L137'></a><a href='#L137'>137</a>
203
+ <a name='L138'></a><a href='#L138'>138</a>
204
+ <a name='L139'></a><a href='#L139'>139</a>
205
+ <a name='L140'></a><a href='#L140'>140</a>
206
+ <a name='L141'></a><a href='#L141'>141</a>
207
+ <a name='L142'></a><a href='#L142'>142</a>
208
+ <a name='L143'></a><a href='#L143'>143</a>
209
+ <a name='L144'></a><a href='#L144'>144</a>
210
+ <a name='L145'></a><a href='#L145'>145</a>
211
+ <a name='L146'></a><a href='#L146'>146</a>
212
+ <a name='L147'></a><a href='#L147'>147</a>
213
+ <a name='L148'></a><a href='#L148'>148</a>
214
+ <a name='L149'></a><a href='#L149'>149</a>
215
+ <a name='L150'></a><a href='#L150'>150</a>
216
+ <a name='L151'></a><a href='#L151'>151</a>
217
+ <a name='L152'></a><a href='#L152'>152</a>
218
+ <a name='L153'></a><a href='#L153'>153</a>
219
+ <a name='L154'></a><a href='#L154'>154</a>
220
+ <a name='L155'></a><a href='#L155'>155</a>
221
+ <a name='L156'></a><a href='#L156'>156</a>
222
+ <a name='L157'></a><a href='#L157'>157</a>
223
+ <a name='L158'></a><a href='#L158'>158</a>
224
+ <a name='L159'></a><a href='#L159'>159</a>
225
+ <a name='L160'></a><a href='#L160'>160</a>
226
+ <a name='L161'></a><a href='#L161'>161</a>
227
+ <a name='L162'></a><a href='#L162'>162</a>
228
+ <a name='L163'></a><a href='#L163'>163</a>
229
+ <a name='L164'></a><a href='#L164'>164</a>
230
+ <a name='L165'></a><a href='#L165'>165</a>
231
+ <a name='L166'></a><a href='#L166'>166</a>
232
+ <a name='L167'></a><a href='#L167'>167</a>
233
+ <a name='L168'></a><a href='#L168'>168</a>
234
+ <a name='L169'></a><a href='#L169'>169</a>
235
+ <a name='L170'></a><a href='#L170'>170</a>
236
+ <a name='L171'></a><a href='#L171'>171</a>
237
+ <a name='L172'></a><a href='#L172'>172</a>
238
+ <a name='L173'></a><a href='#L173'>173</a>
239
+ <a name='L174'></a><a href='#L174'>174</a>
240
+ <a name='L175'></a><a href='#L175'>175</a>
241
+ <a name='L176'></a><a href='#L176'>176</a>
242
+ <a name='L177'></a><a href='#L177'>177</a>
243
+ <a name='L178'></a><a href='#L178'>178</a>
244
+ <a name='L179'></a><a href='#L179'>179</a>
245
+ <a name='L180'></a><a href='#L180'>180</a>
246
+ <a name='L181'></a><a href='#L181'>181</a>
247
+ <a name='L182'></a><a href='#L182'>182</a>
248
+ <a name='L183'></a><a href='#L183'>183</a>
249
+ <a name='L184'></a><a href='#L184'>184</a>
250
+ <a name='L185'></a><a href='#L185'>185</a>
251
+ <a name='L186'></a><a href='#L186'>186</a>
252
+ <a name='L187'></a><a href='#L187'>187</a>
253
+ <a name='L188'></a><a href='#L188'>188</a>
254
+ <a name='L189'></a><a href='#L189'>189</a>
255
+ <a name='L190'></a><a href='#L190'>190</a>
256
+ <a name='L191'></a><a href='#L191'>191</a>
257
+ <a name='L192'></a><a href='#L192'>192</a>
258
+ <a name='L193'></a><a href='#L193'>193</a>
259
+ <a name='L194'></a><a href='#L194'>194</a>
260
+ <a name='L195'></a><a href='#L195'>195</a>
261
+ <a name='L196'></a><a href='#L196'>196</a>
262
+ <a name='L197'></a><a href='#L197'>197</a>
263
+ <a name='L198'></a><a href='#L198'>198</a>
264
+ <a name='L199'></a><a href='#L199'>199</a>
265
+ <a name='L200'></a><a href='#L200'>200</a>
266
+ <a name='L201'></a><a href='#L201'>201</a>
267
+ <a name='L202'></a><a href='#L202'>202</a>
268
+ <a name='L203'></a><a href='#L203'>203</a>
269
+ <a name='L204'></a><a href='#L204'>204</a>
270
+ <a name='L205'></a><a href='#L205'>205</a>
271
+ <a name='L206'></a><a href='#L206'>206</a>
272
+ <a name='L207'></a><a href='#L207'>207</a>
273
+ <a name='L208'></a><a href='#L208'>208</a>
274
+ <a name='L209'></a><a href='#L209'>209</a>
275
+ <a name='L210'></a><a href='#L210'>210</a>
276
+ <a name='L211'></a><a href='#L211'>211</a>
277
+ <a name='L212'></a><a href='#L212'>212</a>
278
+ <a name='L213'></a><a href='#L213'>213</a>
279
+ <a name='L214'></a><a href='#L214'>214</a>
280
+ <a name='L215'></a><a href='#L215'>215</a>
281
+ <a name='L216'></a><a href='#L216'>216</a>
282
+ <a name='L217'></a><a href='#L217'>217</a>
283
+ <a name='L218'></a><a href='#L218'>218</a>
284
+ <a name='L219'></a><a href='#L219'>219</a>
285
+ <a name='L220'></a><a href='#L220'>220</a>
286
+ <a name='L221'></a><a href='#L221'>221</a>
287
+ <a name='L222'></a><a href='#L222'>222</a>
288
+ <a name='L223'></a><a href='#L223'>223</a>
289
+ <a name='L224'></a><a href='#L224'>224</a>
290
+ <a name='L225'></a><a href='#L225'>225</a>
291
+ <a name='L226'></a><a href='#L226'>226</a>
292
+ <a name='L227'></a><a href='#L227'>227</a>
293
+ <a name='L228'></a><a href='#L228'>228</a>
294
+ <a name='L229'></a><a href='#L229'>229</a>
295
+ <a name='L230'></a><a href='#L230'>230</a>
296
+ <a name='L231'></a><a href='#L231'>231</a>
297
+ <a name='L232'></a><a href='#L232'>232</a>
298
+ <a name='L233'></a><a href='#L233'>233</a>
299
+ <a name='L234'></a><a href='#L234'>234</a>
300
+ <a name='L235'></a><a href='#L235'>235</a>
301
+ <a name='L236'></a><a href='#L236'>236</a>
302
+ <a name='L237'></a><a href='#L237'>237</a>
303
+ <a name='L238'></a><a href='#L238'>238</a>
304
+ <a name='L239'></a><a href='#L239'>239</a>
305
+ <a name='L240'></a><a href='#L240'>240</a>
306
+ <a name='L241'></a><a href='#L241'>241</a>
307
+ <a name='L242'></a><a href='#L242'>242</a>
308
+ <a name='L243'></a><a href='#L243'>243</a>
309
+ <a name='L244'></a><a href='#L244'>244</a>
310
+ <a name='L245'></a><a href='#L245'>245</a>
311
+ <a name='L246'></a><a href='#L246'>246</a>
312
+ <a name='L247'></a><a href='#L247'>247</a>
313
+ <a name='L248'></a><a href='#L248'>248</a>
314
+ <a name='L249'></a><a href='#L249'>249</a>
315
+ <a name='L250'></a><a href='#L250'>250</a>
316
+ <a name='L251'></a><a href='#L251'>251</a>
317
+ <a name='L252'></a><a href='#L252'>252</a>
318
+ <a name='L253'></a><a href='#L253'>253</a>
319
+ <a name='L254'></a><a href='#L254'>254</a>
320
+ <a name='L255'></a><a href='#L255'>255</a>
321
+ <a name='L256'></a><a href='#L256'>256</a>
322
+ <a name='L257'></a><a href='#L257'>257</a>
323
+ <a name='L258'></a><a href='#L258'>258</a>
324
+ <a name='L259'></a><a href='#L259'>259</a>
325
+ <a name='L260'></a><a href='#L260'>260</a>
326
+ <a name='L261'></a><a href='#L261'>261</a>
327
+ <a name='L262'></a><a href='#L262'>262</a>
328
+ <a name='L263'></a><a href='#L263'>263</a>
329
+ <a name='L264'></a><a href='#L264'>264</a>
330
+ <a name='L265'></a><a href='#L265'>265</a>
331
+ <a name='L266'></a><a href='#L266'>266</a>
332
+ <a name='L267'></a><a href='#L267'>267</a>
333
+ <a name='L268'></a><a href='#L268'>268</a>
334
+ <a name='L269'></a><a href='#L269'>269</a>
335
+ <a name='L270'></a><a href='#L270'>270</a>
336
+ <a name='L271'></a><a href='#L271'>271</a>
337
+ <a name='L272'></a><a href='#L272'>272</a>
338
+ <a name='L273'></a><a href='#L273'>273</a>
339
+ <a name='L274'></a><a href='#L274'>274</a>
340
+ <a name='L275'></a><a href='#L275'>275</a>
341
+ <a name='L276'></a><a href='#L276'>276</a>
342
+ <a name='L277'></a><a href='#L277'>277</a>
343
+ <a name='L278'></a><a href='#L278'>278</a>
344
+ <a name='L279'></a><a href='#L279'>279</a>
345
+ <a name='L280'></a><a href='#L280'>280</a>
346
+ <a name='L281'></a><a href='#L281'>281</a>
347
+ <a name='L282'></a><a href='#L282'>282</a>
348
+ <a name='L283'></a><a href='#L283'>283</a>
349
+ <a name='L284'></a><a href='#L284'>284</a>
350
+ <a name='L285'></a><a href='#L285'>285</a>
351
+ <a name='L286'></a><a href='#L286'>286</a>
352
+ <a name='L287'></a><a href='#L287'>287</a>
353
+ <a name='L288'></a><a href='#L288'>288</a>
354
+ <a name='L289'></a><a href='#L289'>289</a>
355
+ <a name='L290'></a><a href='#L290'>290</a>
356
+ <a name='L291'></a><a href='#L291'>291</a>
357
+ <a name='L292'></a><a href='#L292'>292</a>
358
+ <a name='L293'></a><a href='#L293'>293</a>
359
+ <a name='L294'></a><a href='#L294'>294</a>
360
+ <a name='L295'></a><a href='#L295'>295</a>
361
+ <a name='L296'></a><a href='#L296'>296</a>
362
+ <a name='L297'></a><a href='#L297'>297</a>
363
+ <a name='L298'></a><a href='#L298'>298</a>
364
+ <a name='L299'></a><a href='#L299'>299</a>
365
+ <a name='L300'></a><a href='#L300'>300</a>
366
+ <a name='L301'></a><a href='#L301'>301</a>
367
+ <a name='L302'></a><a href='#L302'>302</a>
368
+ <a name='L303'></a><a href='#L303'>303</a>
369
+ <a name='L304'></a><a href='#L304'>304</a>
370
+ <a name='L305'></a><a href='#L305'>305</a>
371
+ <a name='L306'></a><a href='#L306'>306</a>
372
+ <a name='L307'></a><a href='#L307'>307</a>
373
+ <a name='L308'></a><a href='#L308'>308</a>
374
+ <a name='L309'></a><a href='#L309'>309</a>
375
+ <a name='L310'></a><a href='#L310'>310</a>
376
+ <a name='L311'></a><a href='#L311'>311</a>
377
+ <a name='L312'></a><a href='#L312'>312</a>
378
+ <a name='L313'></a><a href='#L313'>313</a>
379
+ <a name='L314'></a><a href='#L314'>314</a>
380
+ <a name='L315'></a><a href='#L315'>315</a>
381
+ <a name='L316'></a><a href='#L316'>316</a>
382
+ <a name='L317'></a><a href='#L317'>317</a>
383
+ <a name='L318'></a><a href='#L318'>318</a>
384
+ <a name='L319'></a><a href='#L319'>319</a>
385
+ <a name='L320'></a><a href='#L320'>320</a>
386
+ <a name='L321'></a><a href='#L321'>321</a>
387
+ <a name='L322'></a><a href='#L322'>322</a></td><td class="line-coverage quiet"><span class="cline-any cline-yes">1x</span>
388
+ <span class="cline-any cline-yes">1x</span>
389
+ <span class="cline-any cline-yes">1x</span>
390
+ <span class="cline-any cline-yes">1x</span>
391
+ <span class="cline-any cline-yes">1x</span>
392
+ <span class="cline-any cline-yes">1x</span>
393
+ <span class="cline-any cline-yes">1x</span>
394
+ <span class="cline-any cline-yes">1x</span>
395
+ <span class="cline-any cline-yes">1x</span>
396
+ <span class="cline-any cline-yes">1x</span>
397
+ <span class="cline-any cline-yes">1x</span>
398
+ <span class="cline-any cline-yes">1x</span>
399
+ <span class="cline-any cline-yes">1x</span>
400
+ <span class="cline-any cline-yes">1x</span>
401
+ <span class="cline-any cline-yes">1x</span>
402
+ <span class="cline-any cline-yes">1x</span>
403
+ <span class="cline-any cline-yes">1x</span>
404
+ <span class="cline-any cline-yes">1x</span>
405
+ <span class="cline-any cline-yes">1x</span>
406
+ <span class="cline-any cline-yes">1x</span>
407
+ <span class="cline-any cline-yes">1x</span>
408
+ <span class="cline-any cline-yes">1x</span>
409
+ <span class="cline-any cline-yes">1x</span>
410
+ <span class="cline-any cline-yes">1x</span>
411
+ <span class="cline-any cline-yes">1x</span>
412
+ <span class="cline-any cline-yes">1x</span>
413
+ <span class="cline-any cline-yes">1x</span>
414
+ <span class="cline-any cline-yes">1x</span>
415
+ <span class="cline-any cline-yes">1x</span>
416
+ <span class="cline-any cline-yes">1x</span>
417
+ <span class="cline-any cline-yes">1x</span>
418
+ <span class="cline-any cline-yes">1x</span>
419
+ <span class="cline-any cline-yes">44x</span>
420
+ <span class="cline-any cline-yes">44x</span>
421
+ <span class="cline-any cline-yes">44x</span>
422
+ <span class="cline-any cline-yes">44x</span>
423
+ <span class="cline-any cline-yes">44x</span>
424
+ <span class="cline-any cline-yes">44x</span>
425
+ <span class="cline-any cline-yes">24x</span>
426
+ <span class="cline-any cline-yes">24x</span>
427
+ <span class="cline-any cline-yes">24x</span>
428
+ <span class="cline-any cline-yes">44x</span>
429
+ <span class="cline-any cline-yes">16x</span>
430
+ <span class="cline-any cline-yes">16x</span>
431
+ <span class="cline-any cline-yes">44x</span>
432
+ <span class="cline-any cline-yes">1x</span>
433
+ <span class="cline-any cline-yes">1x</span>
434
+ <span class="cline-any cline-yes">1x</span>
435
+ <span class="cline-any cline-yes">49x</span>
436
+ <span class="cline-any cline-yes">49x</span>
437
+ <span class="cline-any cline-yes">49x</span>
438
+ <span class="cline-any cline-yes">49x</span>
439
+ <span class="cline-any cline-yes">49x</span>
440
+ <span class="cline-any cline-yes">49x</span>
441
+ <span class="cline-any cline-yes">49x</span>
442
+ <span class="cline-any cline-yes">49x</span>
443
+ <span class="cline-any cline-yes">49x</span>
444
+ <span class="cline-any cline-yes">49x</span>
445
+ <span class="cline-any cline-yes">49x</span>
446
+ <span class="cline-any cline-yes">49x</span>
447
+ <span class="cline-any cline-yes">49x</span>
448
+ <span class="cline-any cline-yes">39x</span>
449
+ <span class="cline-any cline-yes">39x</span>
450
+ <span class="cline-any cline-yes">39x</span>
451
+ <span class="cline-any cline-yes">39x</span>
452
+ <span class="cline-any cline-yes">39x</span>
453
+ <span class="cline-any cline-yes">39x</span>
454
+ <span class="cline-any cline-yes">39x</span>
455
+ <span class="cline-any cline-yes">39x</span>
456
+ <span class="cline-any cline-yes">39x</span>
457
+ <span class="cline-any cline-yes">39x</span>
458
+ <span class="cline-any cline-yes">39x</span>
459
+ <span class="cline-any cline-yes">39x</span>
460
+ <span class="cline-any cline-yes">39x</span>
461
+ <span class="cline-any cline-yes">39x</span>
462
+ <span class="cline-any cline-yes">39x</span>
463
+ <span class="cline-any cline-yes">39x</span>
464
+ <span class="cline-any cline-yes">39x</span>
465
+ <span class="cline-any cline-yes">39x</span>
466
+ <span class="cline-any cline-yes">39x</span>
467
+ <span class="cline-any cline-yes">49x</span>
468
+ <span class="cline-any cline-yes">1x</span>
469
+ <span class="cline-any cline-yes">1x</span>
470
+ <span class="cline-any cline-yes">1x</span>
471
+ <span class="cline-any cline-yes">49x</span>
472
+ <span class="cline-any cline-yes">49x</span>
473
+ <span class="cline-any cline-yes">49x</span>
474
+ <span class="cline-any cline-yes">49x</span>
475
+ <span class="cline-any cline-yes">125x</span>
476
+ <span class="cline-any cline-yes">49x</span>
477
+ <span class="cline-any cline-yes">49x</span>
478
+ <span class="cline-any cline-yes">49x</span>
479
+ <span class="cline-any cline-yes">49x</span>
480
+ <span class="cline-any cline-yes">49x</span>
481
+ <span class="cline-any cline-yes">49x</span>
482
+ <span class="cline-any cline-yes">33x</span>
483
+ <span class="cline-any cline-no">&nbsp;</span>
484
+ <span class="cline-any cline-no">&nbsp;</span>
485
+ <span class="cline-any cline-yes">33x</span>
486
+ <span class="cline-any cline-yes">49x</span>
487
+ <span class="cline-any cline-yes">49x</span>
488
+ <span class="cline-any cline-yes">49x</span>
489
+ <span class="cline-any cline-yes">49x</span>
490
+ <span class="cline-any cline-yes">1x</span>
491
+ <span class="cline-any cline-yes">1x</span>
492
+ <span class="cline-any cline-yes">8x</span>
493
+ <span class="cline-any cline-yes">3x</span>
494
+ <span class="cline-any cline-yes">3x</span>
495
+ <span class="cline-any cline-yes">8x</span>
496
+ <span class="cline-any cline-yes">1x</span>
497
+ <span class="cline-any cline-yes">1x</span>
498
+ <span class="cline-any cline-no">&nbsp;</span>
499
+ <span class="cline-any cline-no">&nbsp;</span>
500
+ <span class="cline-any cline-yes">1x</span>
501
+ <span class="cline-any cline-yes">1x</span>
502
+ <span class="cline-any cline-yes">63x</span>
503
+ <span class="cline-any cline-yes">63x</span>
504
+ <span class="cline-any cline-yes">63x</span>
505
+ <span class="cline-any cline-yes">63x</span>
506
+ <span class="cline-any cline-yes">63x</span>
507
+ <span class="cline-any cline-yes">63x</span>
508
+ <span class="cline-any cline-yes">63x</span>
509
+ <span class="cline-any cline-yes">63x</span>
510
+ <span class="cline-any cline-yes">3x</span>
511
+ <span class="cline-any cline-yes">63x</span>
512
+ <span class="cline-any cline-yes">1x</span>
513
+ <span class="cline-any cline-yes">1x</span>
514
+ <span class="cline-any cline-yes">33x</span>
515
+ <span class="cline-any cline-yes">33x</span>
516
+ <span class="cline-any cline-yes">33x</span>
517
+ <span class="cline-any cline-yes">33x</span>
518
+ <span class="cline-any cline-yes">33x</span>
519
+ <span class="cline-any cline-yes">33x</span>
520
+ <span class="cline-any cline-yes">33x</span>
521
+ <span class="cline-any cline-yes">33x</span>
522
+ <span class="cline-any cline-yes">33x</span>
523
+ <span class="cline-any cline-yes">33x</span>
524
+ <span class="cline-any cline-yes">33x</span>
525
+ <span class="cline-any cline-yes">1x</span>
526
+ <span class="cline-any cline-yes">1x</span>
527
+ <span class="cline-any cline-yes">1x</span>
528
+ <span class="cline-any cline-yes">42x</span>
529
+ <span class="cline-any cline-yes">63x</span>
530
+ <span class="cline-any cline-yes">63x</span>
531
+ <span class="cline-any cline-yes">63x</span>
532
+ <span class="cline-any cline-yes">9x</span>
533
+ <span class="cline-any cline-yes">63x</span>
534
+ <span class="cline-any cline-yes">9x</span>
535
+ <span class="cline-any cline-yes">9x</span>
536
+ <span class="cline-any cline-yes">9x</span>
537
+ <span class="cline-any cline-yes">9x</span>
538
+ <span class="cline-any cline-yes">9x</span>
539
+ <span class="cline-any cline-yes">54x</span>
540
+ <span class="cline-any cline-yes">6x</span>
541
+ <span class="cline-any cline-yes">6x</span>
542
+ <span class="cline-any cline-yes">6x</span>
543
+ <span class="cline-any cline-yes">6x</span>
544
+ <span class="cline-any cline-yes">42x</span>
545
+ <span class="cline-any cline-yes">42x</span>
546
+ <span class="cline-any cline-yes">42x</span>
547
+ <span class="cline-any cline-yes">1x</span>
548
+ <span class="cline-any cline-yes">1x</span>
549
+ <span class="cline-any cline-yes">1x</span>
550
+ <span class="cline-any cline-yes">1x</span>
551
+ <span class="cline-any cline-yes">25x</span>
552
+ <span class="cline-any cline-yes">25x</span>
553
+ <span class="cline-any cline-yes">25x</span>
554
+ <span class="cline-any cline-yes">25x</span>
555
+ <span class="cline-any cline-yes">25x</span>
556
+ <span class="cline-any cline-yes">25x</span>
557
+ <span class="cline-any cline-yes">25x</span>
558
+ <span class="cline-any cline-yes">1x</span>
559
+ <span class="cline-any cline-yes">6x</span>
560
+ <span class="cline-any cline-yes">6x</span>
561
+ <span class="cline-any cline-yes">6x</span>
562
+ <span class="cline-any cline-yes">6x</span>
563
+ <span class="cline-any cline-yes">6x</span>
564
+ <span class="cline-any cline-yes">6x</span>
565
+ <span class="cline-any cline-yes">6x</span>
566
+ <span class="cline-any cline-yes">1x</span>
567
+ <span class="cline-any cline-yes">1x</span>
568
+ <span class="cline-any cline-yes">1x</span>
569
+ <span class="cline-any cline-yes">1x</span>
570
+ <span class="cline-any cline-yes">1x</span>
571
+ <span class="cline-any cline-yes">1x</span>
572
+ <span class="cline-any cline-yes">1x</span>
573
+ <span class="cline-any cline-yes">1x</span>
574
+ <span class="cline-any cline-yes">1x</span>
575
+ <span class="cline-any cline-yes">5x</span>
576
+ <span class="cline-any cline-yes">5x</span>
577
+ <span class="cline-any cline-yes">5x</span>
578
+ <span class="cline-any cline-yes">5x</span>
579
+ <span class="cline-any cline-yes">5x</span>
580
+ <span class="cline-any cline-yes">5x</span>
581
+ <span class="cline-any cline-yes">5x</span>
582
+ <span class="cline-any cline-yes">1x</span>
583
+ <span class="cline-any cline-yes">1x</span>
584
+ <span class="cline-any cline-yes">1x</span>
585
+ <span class="cline-any cline-yes">38x</span>
586
+ <span class="cline-any cline-yes">34x</span>
587
+ <span class="cline-any cline-yes">34x</span>
588
+ <span class="cline-any cline-yes">34x</span>
589
+ <span class="cline-any cline-yes">34x</span>
590
+ <span class="cline-any cline-yes">34x</span>
591
+ <span class="cline-any cline-yes">32x</span>
592
+ <span class="cline-any cline-yes">44x</span>
593
+ <span class="cline-any cline-yes">44x</span>
594
+ <span class="cline-any cline-yes">44x</span>
595
+ <span class="cline-any cline-yes">44x</span>
596
+ <span class="cline-any cline-yes">44x</span>
597
+ <span class="cline-any cline-yes">44x</span>
598
+ <span class="cline-any cline-yes">44x</span>
599
+ <span class="cline-any cline-yes">44x</span>
600
+ <span class="cline-any cline-yes">44x</span>
601
+ <span class="cline-any cline-yes">44x</span>
602
+ <span class="cline-any cline-yes">44x</span>
603
+ <span class="cline-any cline-yes">44x</span>
604
+ <span class="cline-any cline-yes">44x</span>
605
+ <span class="cline-any cline-yes">44x</span>
606
+ <span class="cline-any cline-yes">44x</span>
607
+ <span class="cline-any cline-yes">44x</span>
608
+ <span class="cline-any cline-yes">44x</span>
609
+ <span class="cline-any cline-yes">44x</span>
610
+ <span class="cline-any cline-yes">44x</span>
611
+ <span class="cline-any cline-yes">24x</span>
612
+ <span class="cline-any cline-yes">24x</span>
613
+ <span class="cline-any cline-yes">24x</span>
614
+ <span class="cline-any cline-yes">24x</span>
615
+ <span class="cline-any cline-yes">24x</span>
616
+ <span class="cline-any cline-yes">24x</span>
617
+ <span class="cline-any cline-yes">24x</span>
618
+ <span class="cline-any cline-yes">24x</span>
619
+ <span class="cline-any cline-yes">44x</span>
620
+ <span class="cline-any cline-yes">32x</span>
621
+ <span class="cline-any cline-yes">32x</span>
622
+ <span class="cline-any cline-yes">34x</span>
623
+ <span class="cline-any cline-yes">38x</span>
624
+ <span class="cline-any cline-yes">1x</span>
625
+ <span class="cline-any cline-yes">1x</span>
626
+ <span class="cline-any cline-yes">1x</span>
627
+ <span class="cline-any cline-yes">38x</span>
628
+ <span class="cline-any cline-yes">34x</span>
629
+ <span class="cline-any cline-yes">20x</span>
630
+ <span class="cline-any cline-yes">10x</span>
631
+ <span class="cline-any cline-yes">10x</span>
632
+ <span class="cline-any cline-yes">10x</span>
633
+ <span class="cline-any cline-yes">10x</span>
634
+ <span class="cline-any cline-yes">10x</span>
635
+ <span class="cline-any cline-yes">10x</span>
636
+ <span class="cline-any cline-yes">10x</span>
637
+ <span class="cline-any cline-yes">10x</span>
638
+ <span class="cline-any cline-yes">2x</span>
639
+ <span class="cline-any cline-yes">2x</span>
640
+ <span class="cline-any cline-yes">10x</span>
641
+ <span class="cline-any cline-yes">20x</span>
642
+ <span class="cline-any cline-yes">20x</span>
643
+ <span class="cline-any cline-yes">34x</span>
644
+ <span class="cline-any cline-yes">38x</span>
645
+ <span class="cline-any cline-yes">1x</span>
646
+ <span class="cline-any cline-yes">1x</span>
647
+ <span class="cline-any cline-yes">1x</span>
648
+ <span class="cline-any cline-yes">1x</span>
649
+ <span class="cline-any cline-yes">1x</span>
650
+ <span class="cline-any cline-yes">1x</span>
651
+ <span class="cline-any cline-yes">1x</span>
652
+ <span class="cline-any cline-no">&nbsp;</span>
653
+ <span class="cline-any cline-no">&nbsp;</span>
654
+ <span class="cline-any cline-yes">1x</span>
655
+ <span class="cline-any cline-yes">1x</span>
656
+ <span class="cline-any cline-yes">1x</span>
657
+ <span class="cline-any cline-no">&nbsp;</span>
658
+ <span class="cline-any cline-no">&nbsp;</span>
659
+ <span class="cline-any cline-yes">1x</span>
660
+ <span class="cline-any cline-yes">1x</span>
661
+ <span class="cline-any cline-no">&nbsp;</span>
662
+ <span class="cline-any cline-no">&nbsp;</span>
663
+ <span class="cline-any cline-yes">1x</span>
664
+ <span class="cline-any cline-yes">1x</span>
665
+ <span class="cline-any cline-yes">1x</span>
666
+ <span class="cline-any cline-no">&nbsp;</span>
667
+ <span class="cline-any cline-no">&nbsp;</span>
668
+ <span class="cline-any cline-yes">1x</span>
669
+ <span class="cline-any cline-yes">1x</span>
670
+ <span class="cline-any cline-no">&nbsp;</span>
671
+ <span class="cline-any cline-no">&nbsp;</span>
672
+ <span class="cline-any cline-yes">1x</span>
673
+ <span class="cline-any cline-yes">1x</span>
674
+ <span class="cline-any cline-no">&nbsp;</span>
675
+ <span class="cline-any cline-no">&nbsp;</span>
676
+ <span class="cline-any cline-no">&nbsp;</span>
677
+ <span class="cline-any cline-no">&nbsp;</span>
678
+ <span class="cline-any cline-yes">1x</span>
679
+ <span class="cline-any cline-yes">1x</span>
680
+ <span class="cline-any cline-no">&nbsp;</span>
681
+ <span class="cline-any cline-no">&nbsp;</span>
682
+ <span class="cline-any cline-no">&nbsp;</span>
683
+ <span class="cline-any cline-no">&nbsp;</span>
684
+ <span class="cline-any cline-yes">1x</span>
685
+ <span class="cline-any cline-yes">1x</span>
686
+ <span class="cline-any cline-no">&nbsp;</span>
687
+ <span class="cline-any cline-no">&nbsp;</span>
688
+ <span class="cline-any cline-yes">1x</span>
689
+ <span class="cline-any cline-yes">1x</span>
690
+ <span class="cline-any cline-no">&nbsp;</span>
691
+ <span class="cline-any cline-no">&nbsp;</span>
692
+ <span class="cline-any cline-yes">1x</span>
693
+ <span class="cline-any cline-yes">1x</span>
694
+ <span class="cline-any cline-no">&nbsp;</span>
695
+ <span class="cline-any cline-no">&nbsp;</span>
696
+ <span class="cline-any cline-yes">1x</span>
697
+ <span class="cline-any cline-yes">1x</span>
698
+ <span class="cline-any cline-no">&nbsp;</span>
699
+ <span class="cline-any cline-no">&nbsp;</span>
700
+ <span class="cline-any cline-no">&nbsp;</span>
701
+ <span class="cline-any cline-no">&nbsp;</span>
702
+ <span class="cline-any cline-yes">1x</span>
703
+ <span class="cline-any cline-yes">1x</span>
704
+ <span class="cline-any cline-no">&nbsp;</span>
705
+ <span class="cline-any cline-no">&nbsp;</span>
706
+ <span class="cline-any cline-no">&nbsp;</span>
707
+ <span class="cline-any cline-no">&nbsp;</span>
708
+ <span class="cline-any cline-neutral">&nbsp;</span></td><td class="text"><pre class="prettyprint lang-js">import _ from 'lodash'
709
+ import { AbilityBuilder, Ability, createAliasResolver } from '@casl/ability'
710
+ import { toMongoQuery } from '@casl/mongoose'
711
+ &nbsp;
712
+ // Define some alias to simplify ability definitions
713
+ const resolveAction = createAliasResolver({
714
+ update: ['patch'],
715
+ read: ['get', 'find'],
716
+ remove: ['delete'],
717
+ all: ['read', 'create', 'update', 'remove']
718
+ })
719
+ &nbsp;
720
+ export const Roles = {
721
+ member: 0,
722
+ manager: 1,
723
+ owner: 2
724
+ }
725
+ &nbsp;
726
+ export const RoleNames = [
727
+ 'member',
728
+ 'manager',
729
+ 'owner'
730
+ ]
731
+ &nbsp;
732
+ // Hooks that can be added to customize abilities computation
733
+ let hooks = []
734
+ &nbsp;
735
+ // Get the unique global symbol to store resource type / context on a resource object
736
+ export const RESOURCE_TYPE = 'type'
737
+ export const RESOURCE_TYPE_KEY = Symbol.for(RESOURCE_TYPE)
738
+ &nbsp;
739
+ export function defineResourceRules (subject, resource, resourceService, can) {
740
+ const role = Roles[resource.permissions]
741
+ &nbsp;
742
+ if (role &gt;= Roles.member) {
743
+ can('read', resourceService, { _id: resource._id })
744
+ }
745
+ if (role &gt;= Roles.manager) {
746
+ can('update', resourceService, { _id: resource._id })
747
+ can(['create', 'remove'], 'authorisations', { resource: resource._id })
748
+ }
749
+ if (role &gt;= Roles.owner) {
750
+ can('remove', resourceService, { _id: resource._id })
751
+ }
752
+ }
753
+ &nbsp;
754
+ // Hook computing default abilities for a given user
755
+ export function defineUserAbilities (subject, can, cannot) {
756
+ // Allow user registration
757
+ can('service', 'users')
758
+ can('create', 'users')
759
+ // Verification email, reset password, etc.
760
+ can('service', 'account')
761
+ can(['create', 'verifyEmail'], 'account')
762
+ // Allow import/export
763
+ can('service', 'import-export')
764
+ can('create', 'import-export')
765
+ // Allow push registration
766
+ can('service', 'push')
767
+ can('create', 'push')
768
+ if (subject &amp;&amp; subject._id) {
769
+ // Read user profiles for authorizing
770
+ can('read', 'users')
771
+ // Update user profile and destroy it
772
+ can(['update', 'remove'], 'users', { _id: subject._id })
773
+ // Access authorisation service, then rights will be granted on a per-resource basis
774
+ can('service', 'authorisations')
775
+ // Access storage service, then rights will be granted on a per-resource basis
776
+ can('service', 'storage')
777
+ // This is for the user avatar
778
+ // take care that the storage service uses 'id' as input but produces _id as output
779
+ can('create', 'storage', { id: 'avatars/' + subject._id.toString() })
780
+ can('create', 'storage', { id: 'avatars/' + subject._id.toString() + '.thumbnail' })
781
+ can(['createMultipartUpload', 'completeMultipartUpload', 'uploadPart', 'putObject'], 'storage', { id: 'avatars/' + subject._id.toString() })
782
+ can(['createMultipartUpload', 'completeMultipartUpload', 'uploadPart', 'putObject'], 'storage', { id: 'avatars/' + subject._id.toString() + '.thumbnail' })
783
+ can('remove', 'storage', { _id: 'avatars/' + subject._id.toString() })
784
+ can('remove', 'storage', { _id: 'avatars/' + subject._id.toString() + '.thumbnail' })
785
+ // Avatar is part of user profiles so that they can be read by any
786
+ can('read', 'storage', { _id: { $regex: '^avatars/*' } })
787
+ }
788
+ }
789
+ &nbsp;
790
+ // Compute abilities for a given user
791
+ export async function defineAbilities (subject, ...args) {
792
+ const { build, can, cannot } = new AbilityBuilder(Ability)
793
+ &nbsp;
794
+ // Run registered hooks providing any additional arguments used to handle complex use cases
795
+ await Promise.all(hooks.map(async hook =&gt; {
796
+ await hook(subject, can, cannot, ...args)
797
+ }))
798
+ &nbsp;
799
+ // CASL cannot infer the object type from the object itself so we need
800
+ // to tell it how he can find the object type, i.e. service name.
801
+ return build({
802
+ detectSubjectType: resource =&gt; {
803
+ if (!resource || typeof resource === 'string') <span class="branch-0 cbranch-no" title="branch not covered" >{</span>
804
+ <span class="cstat-no" title="statement not covered" > return resource</span>
805
+ <span class="cstat-no" title="statement not covered" > }</span>
806
+ return resource[RESOURCE_TYPE_KEY]
807
+ },
808
+ resolveAction
809
+ })
810
+ }
811
+ &nbsp;
812
+ defineAbilities.registerHook = function (hook) {
813
+ if (!hooks.includes(hook)) {
814
+ hooks.push(hook)
815
+ }
816
+ }
817
+ &nbsp;
818
+ defineAbilities.unregisterHook = <span class="fstat-no" title="function not covered" >function (hook) {</span>
819
+ <span class="cstat-no" title="statement not covered" > hooks = hooks.filter(registeredHook =&gt; registeredHook !== hook)</span>
820
+ <span class="cstat-no" title="statement not covered" >}</span>
821
+ &nbsp;
822
+ export function hasServiceAbilities (abilities, service) {
823
+ if (!abilities) <span class="branch-0 cbranch-no" title="branch not covered" >return false</span>
824
+ // The unique identifier of a service is its path not its name.
825
+ // Indeed we have for instance a 'groups' service in each organisation
826
+ // Take care that in client we have the service path while on server we have the actual object
827
+ const path = typeof service === 'string' <span class="branch-0 cbranch-no" title="branch not covered" >? service </span>: service.getPath()
828
+ // */groups will allow to access any groups service in any context
829
+ return abilities.can('service', path) ||
830
+ abilities.can('service', `*/${path}`) ||
831
+ abilities.can('service', _.replace(path, /^.*\//, '*/'))
832
+ }
833
+ &nbsp;
834
+ export function hasResourceAbilities (abilities, operation, resourceType, context, resource) {
835
+ if (!abilities) <span class="branch-0 cbranch-no" title="branch not covered" >return false</span>
836
+ // Create a shallow copy adding context and type
837
+ const object = Object.assign({}, resource)
838
+ object[RESOURCE_TYPE_KEY] = resourceType
839
+ // Add a virtual context to take it into account for object having no link to it
840
+ if (context) object.context = (typeof context === 'object' ? context._id.toString() <span class="branch-0 cbranch-no" title="branch not covered" >: context.toString())</span>
841
+ &nbsp;
842
+ const result = abilities.can(operation, object)
843
+ &nbsp;
844
+ return result
845
+ }
846
+ &nbsp;
847
+ // Utility function used to remove the virtual context from query
848
+ export function removeContext (query) {
849
+ _.forOwn(query, (value, key) =&gt; {
850
+ // Process current attributes or recurse
851
+ // Take care to nested fields like 'field._id'
852
+ if (key === 'context') {
853
+ delete query.context
854
+ } else if (Array.isArray(value)) {
855
+ value.forEach(item =&gt; removeContext(item))
856
+ // Remove empty objects from array
857
+ // _.remove(value, item =&gt; _.isEmpty(item))
858
+ // Remove empty arrays from query
859
+ if (_.isEmpty(value)) <span class="branch-0 cbranch-no" title="branch not covered" >delete query[key]</span>
860
+ } else if (typeof value === 'object') {
861
+ removeContext(value)
862
+ // Remove empty objects from query
863
+ if (_.isEmpty(value)) <span class="branch-0 cbranch-no" title="branch not covered" >delete query[key]</span>
864
+ }
865
+ })
866
+ return query
867
+ }
868
+ &nbsp;
869
+ // Get the query used to filter the objects according to given abilities
870
+ // A null query indicates that access should not be granted
871
+ export function getQueryForAbilities (abilities, operation, resourceType) {
872
+ if (!abilities) <span class="branch-0 cbranch-no" title="branch not covered" >return null</span>
873
+ &nbsp;
874
+ const query = toMongoQuery(abilities, resourceType, operation)
875
+ // Remove any context to avoid taking it into account because it is not really stored on objects
876
+ // We clone the object here because of references to the abilities rules (see https://github.com/kalisio/kdk/issues/384)
877
+ return (query ? removeContext(_.cloneDeep(query)) : null)
878
+ }
879
+ &nbsp;
880
+ function buildSubjectsQueryForResource (resourceScope, resourceId, role) {
881
+ const query = { [resourceScope]: { $elemMatch: { _id: resourceId } } }
882
+ if (role) {
883
+ _.set(query[resourceScope], '$elemMatch.permissions', (typeof role === 'string' <span class="branch-0 cbranch-no" title="branch not covered" >? role </span>: RoleNames[role]))
884
+ }
885
+ return query
886
+ }
887
+ &nbsp;
888
+ export function findSubjectsForResource (subjectService, resourceScope, resourceId, role) {
889
+ // Build the query
890
+ const query = buildSubjectsQueryForResource(resourceScope, resourceId, role)
891
+ // Execute the query
892
+ return subjectService.find({ query })
893
+ }
894
+ &nbsp;
895
+ export function countSubjectsForResource (subjectService, resourceScope, resourceId, role) {
896
+ // Build the query
897
+ const query = buildSubjectsQueryForResource(resourceScope, resourceId, role)
898
+ // Indicate we'd only like to count
899
+ query.$limit = 0
900
+ // Execute the query
901
+ return subjectService.find({ query })
902
+ }
903
+ &nbsp;
904
+ // Hook computing organisation abilities for a given user
905
+ export function defineOrganisationAbilities (subject, can, cannot) {
906
+ if (subject) {
907
+ // Create new organisations
908
+ can('service', 'organisations')
909
+ can('create', 'organisations')
910
+ &nbsp;
911
+ if (subject.organisations) {
912
+ subject.organisations.forEach(organisation =&gt; {
913
+ if (organisation._id) {
914
+ // Generic rules for resources
915
+ defineResourceRules(subject, organisation, 'organisations', can)
916
+ // Specific rules for organisations
917
+ const role = Roles[organisation.permissions]
918
+ if (role &gt;= Roles.member) {
919
+ // The unique identifier of a service is its path not its name.
920
+ // Indeed we have for instance a 'groups' service in each organisation.
921
+ can('service', organisation._id.toString() + '/members')
922
+ can('read', 'members', { context: organisation._id })
923
+ can('service', organisation._id.toString() + '/tags')
924
+ // Tags are public
925
+ can('read', 'tags', { context: organisation._id })
926
+ // Groups are private
927
+ can('service', organisation._id.toString() + '/groups')
928
+ can('service', organisation._id.toString() + '/storage')
929
+ can(['read', 'create', 'remove', 'createMultipartUpload', 'completeMultipartUpload', 'uploadPart', 'putObject'], 'storage', { context: organisation._id })
930
+ }
931
+ if (role &gt;= Roles.manager) {
932
+ can('update', 'members', { context: organisation._id })
933
+ // Managers can manage all groups/tags
934
+ can('all', 'groups', { context: organisation._id })
935
+ can(['create', 'remove'], 'authorisations', { resourcesService: organisation._id.toString() + '/groups', scope: 'groups' })
936
+ can('all', 'tags', { context: organisation._id })
937
+ // Remove invited members
938
+ can(['remove'], 'users', { 'sponsor.organisationId': organisation._id })
939
+ }
940
+ }
941
+ })
942
+ }
943
+ }
944
+ }
945
+ &nbsp;
946
+ // Hook computing group abilities for a given user
947
+ export function defineGroupAbilities (subject, can, cannot) {
948
+ if (subject) {
949
+ if (subject.groups) {
950
+ subject.groups.forEach(group =&gt; {
951
+ if (group._id) {
952
+ // Specific rules for groups
953
+ const role = Roles[group.permissions]
954
+ &nbsp;
955
+ if (role &gt;= Roles.member) {
956
+ can('read', 'groups', { _id: group._id })
957
+ }
958
+ if (role &gt;= Roles.manager) {
959
+ can(['create', 'remove'], 'authorisations', { resource: group._id, permissions: 'member' })
960
+ }
961
+ }
962
+ })
963
+ }
964
+ }
965
+ }
966
+ &nbsp;
967
+ // Helper functions to find the members of a given organisation
968
+ export function findMembersOfOrganisation (usersService, organisationId, role) {
969
+ return findSubjectsForResource(usersService, 'organisations', organisationId, role)
970
+ }
971
+ &nbsp;
972
+ export <span class="fstat-no" title="function not covered" >function countMembersOfOrganisation (usersService, organisationId, role) {</span>
973
+ <span class="cstat-no" title="statement not covered" > return countSubjectsForResource(usersService, 'organisations', organisationId, role)</span>
974
+ <span class="cstat-no" title="statement not covered" >}</span>
975
+ &nbsp;
976
+ // Helper functions to find the members of a given group
977
+ export <span class="fstat-no" title="function not covered" >function findMembersOfGroup (membersService, groupId, role) {</span>
978
+ <span class="cstat-no" title="statement not covered" > return findSubjectsForResource(membersService, 'groups', groupId, role)</span>
979
+ <span class="cstat-no" title="statement not covered" >}</span>
980
+ &nbsp;
981
+ export <span class="fstat-no" title="function not covered" >function countMembersOfGroup (membersService, groupId, role) {</span>
982
+ <span class="cstat-no" title="statement not covered" > return countSubjectsForResource(membersService, 'groups', groupId, role)</span>
983
+ <span class="cstat-no" title="statement not covered" >}</span>
984
+ &nbsp;
985
+ // Helper functions to find the members with a given tag
986
+ export <span class="fstat-no" title="function not covered" >function findMembersWithTag (membersService, tagId) {</span>
987
+ <span class="cstat-no" title="statement not covered" > return findSubjectsForResource(membersService, 'tags', tagId)</span>
988
+ <span class="cstat-no" title="statement not covered" >}</span>
989
+ &nbsp;
990
+ export <span class="fstat-no" title="function not covered" >function countMembersWithTag (membersService, tagId) {</span>
991
+ <span class="cstat-no" title="statement not covered" > return countSubjectsForResource(membersService, 'tags', tagId)</span>
992
+ <span class="cstat-no" title="statement not covered" >}</span>
993
+ &nbsp;
994
+ export <span class="fstat-no" title="function not covered" >function getRoleForOrganisation (user, organisationId) {</span>
995
+ <span class="cstat-no" title="statement not covered" > const result = _.find(user.organisations, { _id: organisationId })</span>
996
+ <span class="cstat-no" title="statement not covered" > if (!_.isUndefined(result)) return result.permissions</span>
997
+ <span class="cstat-no" title="statement not covered" > return undefined</span>
998
+ <span class="cstat-no" title="statement not covered" >}</span>
999
+ &nbsp;
1000
+ export <span class="fstat-no" title="function not covered" >function getRoleForGroup (user, organisationId, groupId) {</span>
1001
+ <span class="cstat-no" title="statement not covered" > const result = _.find(user.groups, { context: organisationId, _id: groupId })</span>
1002
+ <span class="cstat-no" title="statement not covered" > if (!_.isUndefined(result)) return result.permissions</span>
1003
+ <span class="cstat-no" title="statement not covered" > return undefined</span>
1004
+ <span class="cstat-no" title="statement not covered" >}</span>
1005
+ &nbsp;
1006
+ export <span class="fstat-no" title="function not covered" >function findGroupsWithRole (user, organisationId, role) {</span>
1007
+ <span class="cstat-no" title="statement not covered" > return _.filter(user.groups || [], { context: organisationId, permissions: (typeof role === 'string' ? role : RoleNames[role]) })</span>
1008
+ <span class="cstat-no" title="statement not covered" >}</span>
1009
+ &nbsp;
1010
+ export <span class="fstat-no" title="function not covered" >function isSeniorRole (roleName, juniorName) {</span>
1011
+ <span class="cstat-no" title="statement not covered" > return Roles[roleName] &gt;= Roles[juniorName]</span>
1012
+ <span class="cstat-no" title="statement not covered" >}</span>
1013
+ &nbsp;
1014
+ export <span class="fstat-no" title="function not covered" >function isJuniorRole (roleName, seniorName) {</span>
1015
+ <span class="cstat-no" title="statement not covered" > return Roles[roleName] &lt; Roles[seniorName]</span>
1016
+ <span class="cstat-no" title="statement not covered" >}</span>
1017
+ &nbsp;
1018
+ export <span class="fstat-no" title="function not covered" >function getSeniorRoles (roleName) {</span>
1019
+ <span class="cstat-no" title="statement not covered" > const seniorRoles = []</span>
1020
+ <span class="cstat-no" title="statement not covered" > _.forEach(Roles, role =&gt; { if (Roles[roleName] &lt; role) seniorRoles.push(RoleNames[role]) })</span>
1021
+ <span class="cstat-no" title="statement not covered" > return seniorRoles</span>
1022
+ <span class="cstat-no" title="statement not covered" >}</span>
1023
+ &nbsp;
1024
+ export <span class="fstat-no" title="function not covered" >function getJuniorRoles (roleName) {</span>
1025
+ <span class="cstat-no" title="statement not covered" > const juniorRoles = []</span>
1026
+ <span class="cstat-no" title="statement not covered" > _.forEach(Roles, role =&gt; { if (Roles[roleName] &gt;= role) juniorRoles.push(RoleNames[role]) })</span>
1027
+ <span class="cstat-no" title="statement not covered" > return juniorRoles</span>
1028
+ <span class="cstat-no" title="statement not covered" >}</span>
1029
+ &nbsp;</pre></td></tr></table></pre>
1030
+
1031
+ <div class='push'></div><!-- for sticky footer -->
1032
+ </div><!-- /wrapper -->
1033
+ <div class='footer quiet pad2 space-top1 center small'>
1034
+ Code coverage generated by
1035
+ <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
1036
+ at 2024-06-26T10:45:51.147Z
1037
+ </div>
1038
+ <script src="../../prettify.js"></script>
1039
+ <script>
1040
+ window.onload = function () {
1041
+ prettyPrint();
1042
+ };
1043
+ </script>
1044
+ <script src="../../sorter.js"></script>
1045
+ <script src="../../block-navigation.js"></script>
1046
+ </body>
1047
+ </html>
1048
+