@kalisio/kdk 2.6.3 → 2.6.4

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 (284) hide show
  1. package/.vscode/settings.json +5 -0
  2. package/coverage/core/api/application.js.html +398 -392
  3. package/coverage/core/api/authentication.js.html +187 -352
  4. package/coverage/core/api/db.js.html +126 -165
  5. package/coverage/core/api/hooks/hooks.authentication.js.html +196 -22
  6. package/coverage/core/api/hooks/hooks.authorisations.js.html +662 -383
  7. package/coverage/{lcov-report/core/api/hooks/hooks.tags.js.html → core/api/hooks/hooks.groups.js.html} +76 -100
  8. package/coverage/core/api/hooks/hooks.logger.js.html +41 -41
  9. package/coverage/core/api/hooks/hooks.model.js.html +101 -113
  10. package/coverage/core/api/hooks/hooks.organisations.js.html +541 -0
  11. package/coverage/core/api/hooks/hooks.push.js.html +97 -112
  12. package/coverage/core/api/hooks/hooks.query.js.html +222 -270
  13. package/coverage/core/api/hooks/hooks.schemas.js.html +123 -123
  14. package/coverage/core/api/hooks/hooks.service.js.html +1 -1
  15. package/coverage/core/api/hooks/hooks.storage.js.html +1 -1
  16. package/coverage/core/api/hooks/hooks.users.js.html +447 -255
  17. package/coverage/core/api/hooks/index.html +122 -107
  18. package/coverage/core/api/hooks/index.js.html +10 -4
  19. package/coverage/core/api/index.html +61 -46
  20. package/coverage/core/api/index.js.html +9 -9
  21. package/coverage/core/api/marshall.js.html +9 -9
  22. package/coverage/{lcov-report/map/api/models/styles.model.mongodb.js.html → core/api/models/groups.model.mongodb.js.html} +7 -10
  23. package/coverage/core/api/models/index.html +50 -35
  24. package/coverage/core/api/models/messages.model.mongodb.js.html +27 -39
  25. package/coverage/{lcov-report/core/api/models/configurations.model.mongodb.js.html → core/api/models/organisations.model.mongodb.js.html} +7 -10
  26. package/coverage/core/api/models/tags.model.mongodb.js.html +32 -26
  27. package/coverage/core/api/models/users.model.mongodb.js.html +10 -10
  28. package/coverage/core/api/services/account/account.hooks.js.html +5 -5
  29. package/coverage/core/api/services/account/account.service.js.html +127 -127
  30. package/coverage/core/api/services/account/index.html +22 -22
  31. package/coverage/core/api/services/authorisations/authorisations.hooks.js.html +1 -1
  32. package/coverage/core/api/services/authorisations/authorisations.service.js.html +222 -213
  33. package/coverage/core/api/services/authorisations/index.html +21 -21
  34. package/coverage/core/api/services/databases/databases.hooks.js.html +1 -1
  35. package/coverage/core/api/services/databases/databases.service.js.html +1 -1
  36. package/coverage/core/api/services/databases/index.html +1 -1
  37. package/coverage/{lcov-report/core/api/services/configurations/configurations.hooks.js.html → core/api/services/groups/groups.hooks.js.html} +10 -16
  38. package/coverage/core/api/services/{configurations → groups}/index.html +8 -8
  39. package/coverage/core/api/services/import-export/import-export.hooks.js.html +76 -76
  40. package/coverage/core/api/services/import-export/import-export.service.js.html +32 -32
  41. package/coverage/core/api/services/import-export/index.html +32 -32
  42. package/coverage/core/api/services/index.html +21 -21
  43. package/coverage/core/api/services/index.js.html +142 -313
  44. package/coverage/core/api/services/mailer/index.html +32 -32
  45. package/coverage/core/api/services/mailer/mailer.hooks.js.html +80 -80
  46. package/coverage/core/api/services/mailer/mailer.service.js.html +32 -32
  47. package/coverage/core/api/services/messages/index.html +21 -21
  48. package/coverage/core/api/services/messages/messages.hooks.js.html +76 -112
  49. package/coverage/{lcov-report/map/api/services/styles → core/api/services/organisations}/index.html +25 -10
  50. package/coverage/core/api/services/{configurations/configurations.hooks.js.html → organisations/organisations.hooks.js.html} +10 -16
  51. package/coverage/core/api/services/organisations/organisations.service.js.html +343 -0
  52. package/coverage/core/api/services/push/index.html +32 -32
  53. package/coverage/core/api/services/push/push.hooks.js.html +80 -80
  54. package/coverage/core/api/services/push/push.service.js.html +34 -34
  55. package/coverage/core/api/services/storage/index.html +29 -29
  56. package/coverage/core/api/services/storage/storage.hooks.js.html +80 -80
  57. package/coverage/core/api/services/storage/storage.service.js.html +29 -29
  58. package/coverage/core/api/services/tags/index.html +21 -21
  59. package/coverage/core/api/services/tags/tags.hooks.js.html +71 -119
  60. package/coverage/core/api/services/users/index.html +12 -27
  61. package/coverage/core/api/services/users/users.hooks.js.html +11 -14
  62. package/coverage/core/api/utils.js.html +118 -0
  63. package/coverage/core/common/errors.js.html +1 -1
  64. package/coverage/core/common/index.html +27 -42
  65. package/coverage/core/common/index.js.html +1 -1
  66. package/coverage/core/common/permissions.js.html +472 -166
  67. package/coverage/core/common/schema.js.html +4 -4
  68. package/coverage/core/common/utils.js.html +25 -31
  69. package/coverage/index.html +192 -192
  70. package/coverage/lcov-report/core/api/application.js.html +398 -392
  71. package/coverage/lcov-report/core/api/authentication.js.html +187 -352
  72. package/coverage/lcov-report/core/api/db.js.html +126 -165
  73. package/coverage/lcov-report/core/api/hooks/hooks.authentication.js.html +196 -22
  74. package/coverage/lcov-report/core/api/hooks/hooks.authorisations.js.html +662 -383
  75. package/coverage/{core/api/hooks/hooks.tags.js.html → lcov-report/core/api/hooks/hooks.groups.js.html} +76 -100
  76. package/coverage/lcov-report/core/api/hooks/hooks.logger.js.html +41 -41
  77. package/coverage/lcov-report/core/api/hooks/hooks.model.js.html +101 -113
  78. package/coverage/lcov-report/core/api/hooks/hooks.organisations.js.html +541 -0
  79. package/coverage/lcov-report/core/api/hooks/hooks.push.js.html +97 -112
  80. package/coverage/lcov-report/core/api/hooks/hooks.query.js.html +222 -270
  81. package/coverage/lcov-report/core/api/hooks/hooks.schemas.js.html +123 -123
  82. package/coverage/lcov-report/core/api/hooks/hooks.service.js.html +1 -1
  83. package/coverage/lcov-report/core/api/hooks/hooks.storage.js.html +1 -1
  84. package/coverage/lcov-report/core/api/hooks/hooks.users.js.html +447 -255
  85. package/coverage/lcov-report/core/api/hooks/index.html +122 -107
  86. package/coverage/lcov-report/core/api/hooks/index.js.html +10 -4
  87. package/coverage/lcov-report/core/api/index.html +61 -46
  88. package/coverage/lcov-report/core/api/index.js.html +9 -9
  89. package/coverage/lcov-report/core/api/marshall.js.html +9 -9
  90. package/coverage/{map/api/models/styles.model.mongodb.js.html → lcov-report/core/api/models/groups.model.mongodb.js.html} +7 -10
  91. package/coverage/lcov-report/core/api/models/index.html +50 -35
  92. package/coverage/lcov-report/core/api/models/messages.model.mongodb.js.html +27 -39
  93. package/coverage/{core/api/models/configurations.model.mongodb.js.html → lcov-report/core/api/models/organisations.model.mongodb.js.html} +7 -10
  94. package/coverage/lcov-report/core/api/models/tags.model.mongodb.js.html +32 -26
  95. package/coverage/lcov-report/core/api/models/users.model.mongodb.js.html +10 -10
  96. package/coverage/lcov-report/core/api/services/account/account.hooks.js.html +5 -5
  97. package/coverage/lcov-report/core/api/services/account/account.service.js.html +127 -127
  98. package/coverage/lcov-report/core/api/services/account/index.html +22 -22
  99. package/coverage/lcov-report/core/api/services/authorisations/authorisations.hooks.js.html +1 -1
  100. package/coverage/lcov-report/core/api/services/authorisations/authorisations.service.js.html +222 -213
  101. package/coverage/lcov-report/core/api/services/authorisations/index.html +21 -21
  102. package/coverage/lcov-report/core/api/services/databases/databases.hooks.js.html +1 -1
  103. package/coverage/lcov-report/core/api/services/databases/databases.service.js.html +1 -1
  104. package/coverage/lcov-report/core/api/services/databases/index.html +1 -1
  105. package/coverage/lcov-report/{map/api/services/styles/styles.hooks.js.html → core/api/services/groups/groups.hooks.js.html} +12 -45
  106. package/coverage/lcov-report/core/api/services/{configurations → groups}/index.html +8 -8
  107. package/coverage/lcov-report/core/api/services/import-export/import-export.hooks.js.html +76 -76
  108. package/coverage/lcov-report/core/api/services/import-export/import-export.service.js.html +32 -32
  109. package/coverage/lcov-report/core/api/services/import-export/index.html +32 -32
  110. package/coverage/lcov-report/core/api/services/index.html +21 -21
  111. package/coverage/lcov-report/core/api/services/index.js.html +142 -313
  112. package/coverage/lcov-report/core/api/services/mailer/index.html +32 -32
  113. package/coverage/lcov-report/core/api/services/mailer/mailer.hooks.js.html +80 -80
  114. package/coverage/lcov-report/core/api/services/mailer/mailer.service.js.html +32 -32
  115. package/coverage/lcov-report/core/api/services/messages/index.html +21 -21
  116. package/coverage/lcov-report/core/api/services/messages/messages.hooks.js.html +76 -112
  117. package/coverage/{map/api/services/styles → lcov-report/core/api/services/organisations}/index.html +25 -10
  118. package/coverage/{map/api/services/styles/styles.hooks.js.html → lcov-report/core/api/services/organisations/organisations.hooks.js.html} +12 -45
  119. package/coverage/lcov-report/core/api/services/organisations/organisations.service.js.html +343 -0
  120. package/coverage/lcov-report/core/api/services/push/index.html +32 -32
  121. package/coverage/lcov-report/core/api/services/push/push.hooks.js.html +80 -80
  122. package/coverage/lcov-report/core/api/services/push/push.service.js.html +34 -34
  123. package/coverage/lcov-report/core/api/services/storage/index.html +29 -29
  124. package/coverage/lcov-report/core/api/services/storage/storage.hooks.js.html +80 -80
  125. package/coverage/lcov-report/core/api/services/storage/storage.service.js.html +29 -29
  126. package/coverage/lcov-report/core/api/services/tags/index.html +21 -21
  127. package/coverage/lcov-report/core/api/services/tags/tags.hooks.js.html +71 -119
  128. package/coverage/lcov-report/core/api/services/users/index.html +12 -27
  129. package/coverage/lcov-report/core/api/services/users/users.hooks.js.html +11 -14
  130. package/coverage/lcov-report/core/api/utils.js.html +118 -0
  131. package/coverage/lcov-report/core/common/errors.js.html +1 -1
  132. package/coverage/lcov-report/core/common/index.html +27 -42
  133. package/coverage/lcov-report/core/common/index.js.html +1 -1
  134. package/coverage/lcov-report/core/common/permissions.js.html +472 -166
  135. package/coverage/lcov-report/core/common/schema.js.html +4 -4
  136. package/coverage/lcov-report/core/common/utils.js.html +25 -31
  137. package/coverage/lcov-report/index.html +192 -192
  138. package/coverage/lcov-report/map/api/hooks/hooks.catalog.js.html +31 -169
  139. package/coverage/lcov-report/map/api/hooks/hooks.features.js.html +1 -1
  140. package/coverage/lcov-report/map/api/hooks/hooks.query.js.html +32 -32
  141. package/coverage/lcov-report/map/api/hooks/index.html +5 -5
  142. package/coverage/lcov-report/map/api/hooks/index.js.html +1 -1
  143. package/coverage/lcov-report/map/api/index.html +1 -1
  144. package/coverage/lcov-report/map/api/index.js.html +1 -1
  145. package/coverage/lcov-report/map/api/marshall.js.html +1 -1
  146. package/coverage/lcov-report/map/api/models/alerts.model.mongodb.js.html +1 -1
  147. package/coverage/lcov-report/map/api/models/catalog.model.mongodb.js.html +7 -82
  148. package/coverage/lcov-report/map/api/models/features.model.mongodb.js.html +1 -1
  149. package/coverage/lcov-report/map/api/models/index.html +7 -22
  150. package/coverage/lcov-report/map/api/models/projects.model.mongodb.js.html +1 -1
  151. package/coverage/lcov-report/map/api/services/alerts/alerts.hooks.js.html +1 -1
  152. package/coverage/lcov-report/map/api/services/alerts/alerts.service.js.html +1 -1
  153. package/coverage/lcov-report/map/api/services/alerts/index.html +1 -1
  154. package/coverage/lcov-report/map/api/services/catalog/catalog.hooks.js.html +12 -39
  155. package/coverage/lcov-report/map/api/services/catalog/index.html +5 -5
  156. package/coverage/lcov-report/map/api/services/daptiles/daptiles.service.js.html +1 -1
  157. package/coverage/lcov-report/map/api/services/daptiles/index.html +1 -1
  158. package/coverage/lcov-report/map/api/services/features/features.hooks.js.html +11 -86
  159. package/coverage/lcov-report/map/api/services/features/features.service.js.html +4 -307
  160. package/coverage/lcov-report/map/api/services/features/index.html +7 -7
  161. package/coverage/lcov-report/map/api/services/index.html +5 -5
  162. package/coverage/lcov-report/map/api/services/index.js.html +50 -326
  163. package/coverage/lcov-report/map/api/services/projects/index.html +1 -1
  164. package/coverage/lcov-report/map/api/services/projects/projects.hooks.js.html +1 -1
  165. package/coverage/lcov-report/map/common/dynamic-grid-source.js.html +1 -1
  166. package/coverage/lcov-report/map/common/errors.js.html +1 -1
  167. package/coverage/lcov-report/map/common/geotiff-grid-source.js.html +10 -7
  168. package/coverage/lcov-report/map/common/grid.js.html +1 -1
  169. package/coverage/lcov-report/map/common/index.html +19 -19
  170. package/coverage/lcov-report/map/common/index.js.html +1 -1
  171. package/coverage/lcov-report/map/common/meteo-model-grid-source.js.html +1 -1
  172. package/coverage/lcov-report/map/common/moment-utils.js.html +1 -1
  173. package/coverage/lcov-report/map/common/opendap-grid-source.js.html +1 -1
  174. package/coverage/lcov-report/map/common/opendap-utils.js.html +7 -4
  175. package/coverage/lcov-report/map/common/permissions.js.html +4 -10
  176. package/coverage/lcov-report/map/common/time-based-grid-source.js.html +1 -1
  177. package/coverage/lcov-report/map/common/tms-utils.js.html +12 -9
  178. package/coverage/lcov-report/map/common/wcs-grid-source.js.html +3 -3
  179. package/coverage/lcov-report/map/common/wcs-utils.js.html +15 -12
  180. package/coverage/lcov-report/map/common/weacast-grid-source.js.html +2 -2
  181. package/coverage/lcov-report/map/common/wfs-utils.js.html +17 -14
  182. package/coverage/lcov-report/map/common/wms-utils.js.html +12 -30
  183. package/coverage/lcov-report/map/common/wmts-utils.js.html +13 -10
  184. package/coverage/lcov.info +4096 -4359
  185. package/coverage/map/api/hooks/hooks.catalog.js.html +31 -169
  186. package/coverage/map/api/hooks/hooks.features.js.html +1 -1
  187. package/coverage/map/api/hooks/hooks.query.js.html +32 -32
  188. package/coverage/map/api/hooks/index.html +5 -5
  189. package/coverage/map/api/hooks/index.js.html +1 -1
  190. package/coverage/map/api/index.html +1 -1
  191. package/coverage/map/api/index.js.html +1 -1
  192. package/coverage/map/api/marshall.js.html +1 -1
  193. package/coverage/map/api/models/alerts.model.mongodb.js.html +1 -1
  194. package/coverage/map/api/models/catalog.model.mongodb.js.html +7 -82
  195. package/coverage/map/api/models/features.model.mongodb.js.html +1 -1
  196. package/coverage/map/api/models/index.html +7 -22
  197. package/coverage/map/api/models/projects.model.mongodb.js.html +1 -1
  198. package/coverage/map/api/services/alerts/alerts.hooks.js.html +1 -1
  199. package/coverage/map/api/services/alerts/alerts.service.js.html +1 -1
  200. package/coverage/map/api/services/alerts/index.html +1 -1
  201. package/coverage/map/api/services/catalog/catalog.hooks.js.html +12 -39
  202. package/coverage/map/api/services/catalog/index.html +5 -5
  203. package/coverage/map/api/services/daptiles/daptiles.service.js.html +1 -1
  204. package/coverage/map/api/services/daptiles/index.html +1 -1
  205. package/coverage/map/api/services/features/features.hooks.js.html +11 -86
  206. package/coverage/map/api/services/features/features.service.js.html +4 -307
  207. package/coverage/map/api/services/features/index.html +7 -7
  208. package/coverage/map/api/services/index.html +5 -5
  209. package/coverage/map/api/services/index.js.html +50 -326
  210. package/coverage/map/api/services/projects/index.html +1 -1
  211. package/coverage/map/api/services/projects/projects.hooks.js.html +1 -1
  212. package/coverage/map/common/dynamic-grid-source.js.html +1 -1
  213. package/coverage/map/common/errors.js.html +1 -1
  214. package/coverage/map/common/geotiff-grid-source.js.html +10 -7
  215. package/coverage/map/common/grid.js.html +1 -1
  216. package/coverage/map/common/index.html +19 -19
  217. package/coverage/map/common/index.js.html +1 -1
  218. package/coverage/map/common/meteo-model-grid-source.js.html +1 -1
  219. package/coverage/map/common/moment-utils.js.html +1 -1
  220. package/coverage/map/common/opendap-grid-source.js.html +1 -1
  221. package/coverage/map/common/opendap-utils.js.html +7 -4
  222. package/coverage/map/common/permissions.js.html +4 -10
  223. package/coverage/map/common/time-based-grid-source.js.html +1 -1
  224. package/coverage/map/common/tms-utils.js.html +12 -9
  225. package/coverage/map/common/wcs-grid-source.js.html +3 -3
  226. package/coverage/map/common/wcs-utils.js.html +15 -12
  227. package/coverage/map/common/weacast-grid-source.js.html +2 -2
  228. package/coverage/map/common/wfs-utils.js.html +17 -14
  229. package/coverage/map/common/wms-utils.js.html +12 -30
  230. package/coverage/map/common/wmts-utils.js.html +13 -10
  231. package/coverage/tmp/coverage-151166-1723543324307-0.json +1 -0
  232. package/coverage/tmp/coverage-151178-1723543324283-0.json +1 -0
  233. package/coverage/tmp/coverage-151189-1723543324271-0.json +1 -0
  234. package/coverage/tmp/coverage-151201-1723543324248-0.json +1 -0
  235. package/coverage/tmp/coverage-151208-1723543324227-0.json +1 -0
  236. package/extras/tours/pane.top.js +9 -0
  237. package/map/client/i18n/map_en.json +2 -1
  238. package/map/client/i18n/map_fr.json +2 -1
  239. package/package.json +1 -1
  240. package/test/api/core/test-log-2024-04-22.log +84 -0
  241. package/test/api/core/{test-log-2025-10-03.log → test-log-2024-04-23.log} +9 -4
  242. package/test/api/core/test-log-2024-08-13.log +3 -0
  243. package/client/css/core.variables.scss +0 -72
  244. package/client/i18n/core_en.json +0 -744
  245. package/client/i18n/core_fr.json +0 -744
  246. package/client/i18n/map_en.json +0 -800
  247. package/client/i18n/map_fr.json +0 -800
  248. package/client/kdk.client.css +0 -47
  249. package/client/kdk.client.js +0 -41097
  250. package/client/kdk.client.map.css +0 -47
  251. package/client/kdk.client.map.js +0 -38182
  252. package/client/kdk.client.map.min.css +0 -1
  253. package/client/kdk.client.map.min.js +0 -27032
  254. package/client/kdk.client.min.css +0 -1
  255. package/client/kdk.client.min.js +0 -29074
  256. package/client/schemas/capture.create.json +0 -132
  257. package/client/schemas/catalog.update.json +0 -44
  258. package/client/schemas/messages.update.json +0 -16
  259. package/client/schemas/projects.create.json +0 -52
  260. package/client/schemas/projects.update.json +0 -52
  261. package/client/schemas/settings.update.json +0 -286
  262. package/client/schemas/tags.update.json +0 -35
  263. package/client/schemas/users.update-profile.json +0 -34
  264. package/coverage/core/api/services/users/users.service.js.html +0 -100
  265. package/coverage/core/common/utils.offline.js.html +0 -199
  266. package/coverage/lcov-report/core/api/services/users/users.service.js.html +0 -100
  267. package/coverage/lcov-report/core/common/utils.offline.js.html +0 -199
  268. package/coverage/tmp/coverage-222524-1765963609350-0.json +0 -1
  269. package/coverage/tmp/coverage-222536-1765963609335-0.json +0 -1
  270. package/coverage/tmp/coverage-222547-1765963609324-0.json +0 -1
  271. package/coverage/tmp/coverage-222559-1765963609309-0.json +0 -1
  272. package/coverage/tmp/coverage-222566-1765963609278-0.json +0 -1
  273. package/test/api/core/test-log-2025-07-31.log +0 -15
  274. package/test/api/core/test-log-2025-11-12.log +0 -117
  275. package/test/api/core/test-log-2025-11-27.log +0 -0
  276. package/test/api/core/test-log-2025-11-28.log +0 -17
  277. package/test/api/core/test-log-2025-12-09.log +0 -148
  278. package/test/api/core/test-log-2025-12-17.log +0 -58
  279. package/test/api/core/test-log-2026-01-29.log +0 -17
  280. package/test/api/map/test-log-2025-07-23.log +0 -1
  281. package/test/api/map/test-log-2025-11-28.log +0 -33
  282. package/test/api/map/test-log-2025-12-10.log +0 -2
  283. package/test/api/map/test-log-2026-01-06.log +0 -26
  284. /package/test/api/{core/test-log-2025-11-10.log → map/test-log-2025-03-08.log} +0 -0
@@ -23,30 +23,30 @@
23
23
  <div class='clearfix'>
24
24
 
25
25
  <div class='fl pad1y space-right2'>
26
- <span class="strong">87.3% </span>
26
+ <span class="strong">24.9% </span>
27
27
  <span class="quiet">Statements</span>
28
- <span class='fraction'>172/197</span>
28
+ <span class='fraction'>65/261</span>
29
29
  </div>
30
30
 
31
31
 
32
32
  <div class='fl pad1y space-right2'>
33
- <span class="strong">69.23% </span>
33
+ <span class="strong">50% </span>
34
34
  <span class="quiet">Branches</span>
35
- <span class='fraction'>36/52</span>
35
+ <span class='fraction'>5/10</span>
36
36
  </div>
37
37
 
38
38
 
39
39
  <div class='fl pad1y space-right2'>
40
- <span class="strong">100% </span>
40
+ <span class="strong">23.07% </span>
41
41
  <span class="quiet">Functions</span>
42
- <span class='fraction'>10/10</span>
42
+ <span class='fraction'>3/13</span>
43
43
  </div>
44
44
 
45
45
 
46
46
  <div class='fl pad1y space-right2'>
47
- <span class="strong">87.3% </span>
47
+ <span class="strong">24.9% </span>
48
48
  <span class="quiet">Lines</span>
49
- <span class='fraction'>172/197</span>
49
+ <span class='fraction'>65/261</span>
50
50
  </div>
51
51
 
52
52
 
@@ -61,7 +61,7 @@
61
61
  </div>
62
62
  </template>
63
63
  </div>
64
- <div class='status-line high'></div>
64
+ <div class='status-line low'></div>
65
65
  <pre><table class="coverage">
66
66
  <tr><td class="line-count quiet"><a name='L1'></a><a href='#L1'>1</a>
67
67
  <a name='L2'></a><a href='#L2'>2</a>
@@ -260,7 +260,71 @@
260
260
  <a name='L195'></a><a href='#L195'>195</a>
261
261
  <a name='L196'></a><a href='#L196'>196</a>
262
262
  <a name='L197'></a><a href='#L197'>197</a>
263
- <a name='L198'></a><a href='#L198'>198</a></td><td class="line-coverage quiet"><span class="cline-any cline-yes">1x</span>
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></td><td class="line-coverage quiet"><span class="cline-any cline-yes">1x</span>
264
328
  <span class="cline-any cline-yes">1x</span>
265
329
  <span class="cline-any cline-yes">1x</span>
266
330
  <span class="cline-any cline-yes">1x</span>
@@ -275,154 +339,92 @@
275
339
  <span class="cline-any cline-yes">1x</span>
276
340
  <span class="cline-any cline-yes">1x</span>
277
341
  <span class="cline-any cline-yes">1x</span>
278
- <span class="cline-any cline-yes">10x</span>
279
- <span class="cline-any cline-yes">10x</span>
280
342
  <span class="cline-any cline-yes">1x</span>
281
- <span class="cline-any cline-yes">1x</span>
282
- <span class="cline-any cline-yes">10x</span>
283
- <span class="cline-any cline-yes">10x</span>
284
- <span class="cline-any cline-yes">1x</span>
285
- <span class="cline-any cline-yes">1x</span>
286
- <span class="cline-any cline-yes">3x</span>
287
- <span class="cline-any cline-yes">15x</span>
288
343
  <span class="cline-any cline-no">&nbsp;</span>
289
344
  <span class="cline-any cline-no">&nbsp;</span>
290
- <span class="cline-any cline-yes">15x</span>
291
- <span class="cline-any cline-yes">15x</span>
292
- <span class="cline-any cline-yes">12x</span>
293
- <span class="cline-any cline-yes">15x</span>
294
- <span class="cline-any cline-yes">3x</span>
295
- <span class="cline-any cline-yes">3x</span>
296
- <span class="cline-any cline-yes">15x</span>
297
- <span class="cline-any cline-yes">3x</span>
298
345
  <span class="cline-any cline-yes">1x</span>
299
- <span class="cline-any cline-yes">1x</span>
300
- <span class="cline-any cline-yes">2x</span>
301
- <span class="cline-any cline-yes">22x</span>
302
- <span class="cline-any cline-yes">22x</span>
303
- <span class="cline-any cline-yes">22x</span>
304
- <span class="cline-any cline-yes">12x</span>
305
- <span class="cline-any cline-yes">12x</span>
306
- <span class="cline-any cline-yes">12x</span>
307
- <span class="cline-any cline-yes">10x</span>
308
- <span class="cline-any cline-yes">22x</span>
309
- <span class="cline-any cline-yes">3x</span>
310
- <span class="cline-any cline-yes">3x</span>
311
- <span class="cline-any cline-yes">22x</span>
312
- <span class="cline-any cline-yes">3x</span>
313
- <span class="cline-any cline-yes">3x</span>
314
- <span class="cline-any cline-yes">3x</span>
315
- <span class="cline-any cline-yes">22x</span>
316
- <span class="cline-any cline-yes">2x</span>
317
- <span class="cline-any cline-yes">1x</span>
318
- <span class="cline-any cline-yes">1x</span>
319
- <span class="cline-any cline-yes">2x</span>
320
- <span class="cline-any cline-yes">15x</span>
321
346
  <span class="cline-any cline-no">&nbsp;</span>
322
347
  <span class="cline-any cline-no">&nbsp;</span>
323
- <span class="cline-any cline-yes">15x</span>
324
- <span class="cline-any cline-yes">15x</span>
325
- <span class="cline-any cline-yes">15x</span>
326
- <span class="cline-any cline-yes">15x</span>
327
- <span class="cline-any cline-yes">15x</span>
328
- <span class="cline-any cline-yes">15x</span>
329
- <span class="cline-any cline-yes">15x</span>
330
- <span class="cline-any cline-yes">15x</span>
331
- <span class="cline-any cline-yes">15x</span>
332
- <span class="cline-any cline-yes">12x</span>
333
- <span class="cline-any cline-yes">12x</span>
334
- <span class="cline-any cline-yes">12x</span>
335
- <span class="cline-any cline-yes">12x</span>
336
- <span class="cline-any cline-yes">12x</span>
337
- <span class="cline-any cline-yes">12x</span>
338
- <span class="cline-any cline-yes">1x</span>
339
- <span class="cline-any cline-yes">1x</span>
340
- <span class="cline-any cline-yes">1x</span>
341
- <span class="cline-any cline-yes">1x</span>
342
- <span class="cline-any cline-yes">1x</span>
343
348
  <span class="cline-any cline-yes">1x</span>
344
349
  <span class="cline-any cline-no">&nbsp;</span>
345
350
  <span class="cline-any cline-no">&nbsp;</span>
346
- <span class="cline-any cline-yes">1x</span>
347
- <span class="cline-any cline-yes">12x</span>
348
- <span class="cline-any cline-yes">12x</span>
349
- <span class="cline-any cline-yes">5x</span>
350
- <span class="cline-any cline-yes">5x</span>
351
- <span class="cline-any cline-yes">5x</span>
352
- <span class="cline-any cline-yes">5x</span>
353
- <span class="cline-any cline-yes">5x</span>
354
- <span class="cline-any cline-yes">5x</span>
355
- <span class="cline-any cline-yes">5x</span>
356
- <span class="cline-any cline-yes">5x</span>
357
- <span class="cline-any cline-yes">12x</span>
358
- <span class="cline-any cline-yes">10x</span>
359
- <span class="cline-any cline-yes">15x</span>
360
- <span class="cline-any cline-yes">2x</span>
351
+ <span class="cline-any cline-no">&nbsp;</span>
352
+ <span class="cline-any cline-no">&nbsp;</span>
353
+ <span class="cline-any cline-no">&nbsp;</span>
361
354
  <span class="cline-any cline-yes">1x</span>
362
355
  <span class="cline-any cline-yes">1x</span>
363
356
  <span class="cline-any cline-yes">2x</span>
364
- <span class="cline-any cline-yes">3x</span>
365
- <span class="cline-any cline-no">&nbsp;</span>
366
- <span class="cline-any cline-no">&nbsp;</span>
367
- <span class="cline-any cline-yes">3x</span>
368
- <span class="cline-any cline-yes">3x</span>
369
- <span class="cline-any cline-yes">3x</span>
370
- <span class="cline-any cline-yes">3x</span>
371
- <span class="cline-any cline-yes">3x</span>
372
- <span class="cline-any cline-yes">3x</span>
373
- <span class="cline-any cline-yes">3x</span>
374
- <span class="cline-any cline-yes">3x</span>
375
- <span class="cline-any cline-yes">3x</span>
376
- <span class="cline-any cline-yes">3x</span>
377
- <span class="cline-any cline-yes">3x</span>
378
- <span class="cline-any cline-yes">3x</span>
379
- <span class="cline-any cline-yes">3x</span>
380
- <span class="cline-any cline-yes">3x</span>
381
- <span class="cline-any cline-yes">3x</span>
382
- <span class="cline-any cline-yes">3x</span>
383
- <span class="cline-any cline-yes">3x</span>
384
- <span class="cline-any cline-yes">3x</span>
385
- <span class="cline-any cline-yes">3x</span>
386
- <span class="cline-any cline-yes">3x</span>
387
- <span class="cline-any cline-yes">3x</span>
388
- <span class="cline-any cline-yes">3x</span>
357
+ <span class="cline-any cline-no">&nbsp;</span>
358
+ <span class="cline-any cline-no">&nbsp;</span>
359
+ <span class="cline-any cline-no">&nbsp;</span>
360
+ <span class="cline-any cline-no">&nbsp;</span>
361
+ <span class="cline-any cline-no">&nbsp;</span>
362
+ <span class="cline-any cline-no">&nbsp;</span>
363
+ <span class="cline-any cline-no">&nbsp;</span>
364
+ <span class="cline-any cline-no">&nbsp;</span>
365
+ <span class="cline-any cline-no">&nbsp;</span>
366
+ <span class="cline-any cline-no">&nbsp;</span>
367
+ <span class="cline-any cline-no">&nbsp;</span>
368
+ <span class="cline-any cline-no">&nbsp;</span>
369
+ <span class="cline-any cline-no">&nbsp;</span>
370
+ <span class="cline-any cline-no">&nbsp;</span>
371
+ <span class="cline-any cline-no">&nbsp;</span>
372
+ <span class="cline-any cline-no">&nbsp;</span>
373
+ <span class="cline-any cline-no">&nbsp;</span>
374
+ <span class="cline-any cline-no">&nbsp;</span>
375
+ <span class="cline-any cline-no">&nbsp;</span>
376
+ <span class="cline-any cline-no">&nbsp;</span>
377
+ <span class="cline-any cline-no">&nbsp;</span>
378
+ <span class="cline-any cline-no">&nbsp;</span>
379
+ <span class="cline-any cline-no">&nbsp;</span>
380
+ <span class="cline-any cline-no">&nbsp;</span>
381
+ <span class="cline-any cline-no">&nbsp;</span>
382
+ <span class="cline-any cline-no">&nbsp;</span>
383
+ <span class="cline-any cline-no">&nbsp;</span>
384
+ <span class="cline-any cline-no">&nbsp;</span>
385
+ <span class="cline-any cline-no">&nbsp;</span>
386
+ <span class="cline-any cline-no">&nbsp;</span>
387
+ <span class="cline-any cline-no">&nbsp;</span>
388
+ <span class="cline-any cline-no">&nbsp;</span>
389
+ <span class="cline-any cline-no">&nbsp;</span>
390
+ <span class="cline-any cline-no">&nbsp;</span>
391
+ <span class="cline-any cline-no">&nbsp;</span>
392
+ <span class="cline-any cline-no">&nbsp;</span>
393
+ <span class="cline-any cline-no">&nbsp;</span>
394
+ <span class="cline-any cline-no">&nbsp;</span>
395
+ <span class="cline-any cline-no">&nbsp;</span>
396
+ <span class="cline-any cline-no">&nbsp;</span>
389
397
  <span class="cline-any cline-yes">2x</span>
390
398
  <span class="cline-any cline-yes">1x</span>
391
399
  <span class="cline-any cline-yes">1x</span>
392
- <span class="cline-any cline-yes">3x</span>
393
400
  <span class="cline-any cline-yes">2x</span>
394
401
  <span class="cline-any cline-no">&nbsp;</span>
395
402
  <span class="cline-any cline-no">&nbsp;</span>
396
- <span class="cline-any cline-yes">2x</span>
397
- <span class="cline-any cline-yes">2x</span>
398
- <span class="cline-any cline-yes">2x</span>
399
- <span class="cline-any cline-yes">2x</span>
400
- <span class="cline-any cline-yes">2x</span>
401
- <span class="cline-any cline-yes">2x</span>
402
403
  <span class="cline-any cline-no">&nbsp;</span>
403
404
  <span class="cline-any cline-no">&nbsp;</span>
404
405
  <span class="cline-any cline-no">&nbsp;</span>
405
406
  <span class="cline-any cline-no">&nbsp;</span>
406
- <span class="cline-any cline-yes">2x</span>
407
- <span class="cline-any cline-yes">2x</span>
408
- <span class="cline-any cline-yes">2x</span>
409
- <span class="cline-any cline-yes">2x</span>
410
- <span class="cline-any cline-yes">2x</span>
411
- <span class="cline-any cline-yes">2x</span>
412
- <span class="cline-any cline-yes">2x</span>
413
- <span class="cline-any cline-yes">2x</span>
414
- <span class="cline-any cline-yes">8x</span>
415
- <span class="cline-any cline-yes">2x</span>
416
- <span class="cline-any cline-yes">2x</span>
417
- <span class="cline-any cline-yes">2x</span>
407
+ <span class="cline-any cline-no">&nbsp;</span>
408
+ <span class="cline-any cline-no">&nbsp;</span>
409
+ <span class="cline-any cline-no">&nbsp;</span>
410
+ <span class="cline-any cline-no">&nbsp;</span>
411
+ <span class="cline-any cline-no">&nbsp;</span>
412
+ <span class="cline-any cline-no">&nbsp;</span>
413
+ <span class="cline-any cline-no">&nbsp;</span>
414
+ <span class="cline-any cline-no">&nbsp;</span>
415
+ <span class="cline-any cline-no">&nbsp;</span>
416
+ <span class="cline-any cline-no">&nbsp;</span>
417
+ <span class="cline-any cline-no">&nbsp;</span>
418
+ <span class="cline-any cline-no">&nbsp;</span>
419
+ <span class="cline-any cline-no">&nbsp;</span>
420
+ <span class="cline-any cline-no">&nbsp;</span>
418
421
  <span class="cline-any cline-no">&nbsp;</span>
419
422
  <span class="cline-any cline-no">&nbsp;</span>
420
423
  <span class="cline-any cline-no">&nbsp;</span>
421
424
  <span class="cline-any cline-no">&nbsp;</span>
422
425
  <span class="cline-any cline-no">&nbsp;</span>
423
426
  <span class="cline-any cline-yes">2x</span>
424
- <span class="cline-any cline-yes">2x</span>
425
- <span class="cline-any cline-yes">3x</span>
427
+ <span class="cline-any cline-yes">1x</span>
426
428
  <span class="cline-any cline-yes">1x</span>
427
429
  <span class="cline-any cline-yes">1x</span>
428
430
  <span class="cline-any cline-yes">1x</span>
@@ -431,8 +433,16 @@
431
433
  <span class="cline-any cline-yes">1x</span>
432
434
  <span class="cline-any cline-yes">1x</span>
433
435
  <span class="cline-any cline-yes">1x</span>
436
+ <span class="cline-any cline-yes">1x</span>
437
+ <span class="cline-any cline-yes">1x</span>
438
+ <span class="cline-any cline-yes">1x</span>
439
+ <span class="cline-any cline-no">&nbsp;</span>
434
440
  <span class="cline-any cline-no">&nbsp;</span>
435
441
  <span class="cline-any cline-no">&nbsp;</span>
442
+ <span class="cline-any cline-no">&nbsp;</span>
443
+ <span class="cline-any cline-yes">1x</span>
444
+ <span class="cline-any cline-yes">1x</span>
445
+ <span class="cline-any cline-yes">1x</span>
436
446
  <span class="cline-any cline-yes">1x</span>
437
447
  <span class="cline-any cline-yes">1x</span>
438
448
  <span class="cline-any cline-yes">1x</span>
@@ -442,6 +452,11 @@
442
452
  <span class="cline-any cline-yes">1x</span>
443
453
  <span class="cline-any cline-yes">1x</span>
444
454
  <span class="cline-any cline-yes">1x</span>
455
+ <span class="cline-any cline-no">&nbsp;</span>
456
+ <span class="cline-any cline-no">&nbsp;</span>
457
+ <span class="cline-any cline-no">&nbsp;</span>
458
+ <span class="cline-any cline-no">&nbsp;</span>
459
+ <span class="cline-any cline-no">&nbsp;</span>
445
460
  <span class="cline-any cline-yes">1x</span>
446
461
  <span class="cline-any cline-yes">1x</span>
447
462
  <span class="cline-any cline-yes">1x</span>
@@ -449,21 +464,135 @@
449
464
  <span class="cline-any cline-yes">1x</span>
450
465
  <span class="cline-any cline-no">&nbsp;</span>
451
466
  <span class="cline-any cline-no">&nbsp;</span>
467
+ <span class="cline-any cline-no">&nbsp;</span>
468
+ <span class="cline-any cline-no">&nbsp;</span>
469
+ <span class="cline-any cline-no">&nbsp;</span>
470
+ <span class="cline-any cline-no">&nbsp;</span>
471
+ <span class="cline-any cline-no">&nbsp;</span>
472
+ <span class="cline-any cline-no">&nbsp;</span>
473
+ <span class="cline-any cline-no">&nbsp;</span>
474
+ <span class="cline-any cline-no">&nbsp;</span>
475
+ <span class="cline-any cline-no">&nbsp;</span>
476
+ <span class="cline-any cline-no">&nbsp;</span>
477
+ <span class="cline-any cline-no">&nbsp;</span>
478
+ <span class="cline-any cline-no">&nbsp;</span>
479
+ <span class="cline-any cline-no">&nbsp;</span>
480
+ <span class="cline-any cline-no">&nbsp;</span>
481
+ <span class="cline-any cline-no">&nbsp;</span>
482
+ <span class="cline-any cline-no">&nbsp;</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-no">&nbsp;</span>
486
+ <span class="cline-any cline-no">&nbsp;</span>
487
+ <span class="cline-any cline-no">&nbsp;</span>
488
+ <span class="cline-any cline-yes">1x</span>
489
+ <span class="cline-any cline-yes">1x</span>
490
+ <span class="cline-any cline-no">&nbsp;</span>
491
+ <span class="cline-any cline-no">&nbsp;</span>
492
+ <span class="cline-any cline-no">&nbsp;</span>
493
+ <span class="cline-any cline-no">&nbsp;</span>
494
+ <span class="cline-any cline-no">&nbsp;</span>
495
+ <span class="cline-any cline-no">&nbsp;</span>
496
+ <span class="cline-any cline-no">&nbsp;</span>
497
+ <span class="cline-any cline-no">&nbsp;</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-no">&nbsp;</span>
501
+ <span class="cline-any cline-no">&nbsp;</span>
502
+ <span class="cline-any cline-no">&nbsp;</span>
503
+ <span class="cline-any cline-no">&nbsp;</span>
504
+ <span class="cline-any cline-no">&nbsp;</span>
505
+ <span class="cline-any cline-no">&nbsp;</span>
506
+ <span class="cline-any cline-no">&nbsp;</span>
507
+ <span class="cline-any cline-no">&nbsp;</span>
508
+ <span class="cline-any cline-yes">1x</span>
509
+ <span class="cline-any cline-yes">1x</span>
510
+ <span class="cline-any cline-no">&nbsp;</span>
511
+ <span class="cline-any cline-no">&nbsp;</span>
512
+ <span class="cline-any cline-no">&nbsp;</span>
513
+ <span class="cline-any cline-no">&nbsp;</span>
514
+ <span class="cline-any cline-no">&nbsp;</span>
515
+ <span class="cline-any cline-no">&nbsp;</span>
516
+ <span class="cline-any cline-no">&nbsp;</span>
517
+ <span class="cline-any cline-no">&nbsp;</span>
518
+ <span class="cline-any cline-no">&nbsp;</span>
519
+ <span class="cline-any cline-no">&nbsp;</span>
520
+ <span class="cline-any cline-no">&nbsp;</span>
521
+ <span class="cline-any cline-no">&nbsp;</span>
522
+ <span class="cline-any cline-no">&nbsp;</span>
523
+ <span class="cline-any cline-no">&nbsp;</span>
524
+ <span class="cline-any cline-no">&nbsp;</span>
525
+ <span class="cline-any cline-no">&nbsp;</span>
526
+ <span class="cline-any cline-no">&nbsp;</span>
527
+ <span class="cline-any cline-no">&nbsp;</span>
528
+ <span class="cline-any cline-no">&nbsp;</span>
529
+ <span class="cline-any cline-no">&nbsp;</span>
530
+ <span class="cline-any cline-no">&nbsp;</span>
531
+ <span class="cline-any cline-no">&nbsp;</span>
532
+ <span class="cline-any cline-no">&nbsp;</span>
533
+ <span class="cline-any cline-no">&nbsp;</span>
534
+ <span class="cline-any cline-no">&nbsp;</span>
535
+ <span class="cline-any cline-no">&nbsp;</span>
536
+ <span class="cline-any cline-no">&nbsp;</span>
537
+ <span class="cline-any cline-no">&nbsp;</span>
538
+ <span class="cline-any cline-no">&nbsp;</span>
539
+ <span class="cline-any cline-no">&nbsp;</span>
540
+ <span class="cline-any cline-no">&nbsp;</span>
541
+ <span class="cline-any cline-no">&nbsp;</span>
542
+ <span class="cline-any cline-no">&nbsp;</span>
452
543
  <span class="cline-any cline-yes">1x</span>
453
544
  <span class="cline-any cline-yes">1x</span>
545
+ <span class="cline-any cline-no">&nbsp;</span>
546
+ <span class="cline-any cline-no">&nbsp;</span>
547
+ <span class="cline-any cline-no">&nbsp;</span>
548
+ <span class="cline-any cline-no">&nbsp;</span>
549
+ <span class="cline-any cline-no">&nbsp;</span>
550
+ <span class="cline-any cline-no">&nbsp;</span>
551
+ <span class="cline-any cline-no">&nbsp;</span>
552
+ <span class="cline-any cline-no">&nbsp;</span>
553
+ <span class="cline-any cline-no">&nbsp;</span>
554
+ <span class="cline-any cline-no">&nbsp;</span>
555
+ <span class="cline-any cline-no">&nbsp;</span>
556
+ <span class="cline-any cline-no">&nbsp;</span>
557
+ <span class="cline-any cline-no">&nbsp;</span>
454
558
  <span class="cline-any cline-yes">1x</span>
455
559
  <span class="cline-any cline-yes">1x</span>
560
+ <span class="cline-any cline-no">&nbsp;</span>
561
+ <span class="cline-any cline-no">&nbsp;</span>
562
+ <span class="cline-any cline-no">&nbsp;</span>
563
+ <span class="cline-any cline-no">&nbsp;</span>
564
+ <span class="cline-any cline-no">&nbsp;</span>
565
+ <span class="cline-any cline-no">&nbsp;</span>
566
+ <span class="cline-any cline-no">&nbsp;</span>
567
+ <span class="cline-any cline-no">&nbsp;</span>
568
+ <span class="cline-any cline-no">&nbsp;</span>
456
569
  <span class="cline-any cline-yes">1x</span>
457
570
  <span class="cline-any cline-yes">1x</span>
571
+ <span class="cline-any cline-no">&nbsp;</span>
572
+ <span class="cline-any cline-no">&nbsp;</span>
573
+ <span class="cline-any cline-no">&nbsp;</span>
574
+ <span class="cline-any cline-no">&nbsp;</span>
575
+ <span class="cline-any cline-no">&nbsp;</span>
576
+ <span class="cline-any cline-no">&nbsp;</span>
577
+ <span class="cline-any cline-no">&nbsp;</span>
578
+ <span class="cline-any cline-no">&nbsp;</span>
579
+ <span class="cline-any cline-no">&nbsp;</span>
580
+ <span class="cline-any cline-no">&nbsp;</span>
581
+ <span class="cline-any cline-no">&nbsp;</span>
582
+ <span class="cline-any cline-no">&nbsp;</span>
583
+ <span class="cline-any cline-no">&nbsp;</span>
458
584
  <span class="cline-any cline-yes">1x</span>
459
585
  <span class="cline-any cline-yes">1x</span>
586
+ <span class="cline-any cline-no">&nbsp;</span>
587
+ <span class="cline-any cline-no">&nbsp;</span>
460
588
  <span class="cline-any cline-neutral">&nbsp;</span></td><td class="text"><pre class="prettyprint lang-js">import _ from 'lodash'
461
589
  import makeDebug from 'debug'
462
590
  import generateRandomPassword from 'password-generator'
463
591
  import common from 'feathers-hooks-common'
464
592
  import errors from '@feathersjs/errors'
593
+ import { Roles, RoleNames } from '../../common/permissions.js'
465
594
  import authManagement from 'feathers-authentication-management'
466
- import { createObjectID } from '../db.js'
595
+ &nbsp;
467
596
  const { Forbidden, BadRequest } = errors
468
597
  const { getItems, replaceItems } = common
469
598
  const verifyHooks = authManagement.hooks
@@ -471,118 +600,90 @@ const verifyHooks = authManagement.hooks
471
600
  const debug = makeDebug('kdk:core:users:hooks')
472
601
  &nbsp;
473
602
  // Helper functions to be used in iff hooks
474
- export function disallowRegistration (context) {
475
- return _.get(context.app.get('authentication'), 'disallowRegistration')
476
- }
477
- &nbsp;
478
- export function allowLocalAuthentication (context) {
479
- return _.get(context.app.get('authentication'), 'authStrategies', []).includes('local')
480
- }
481
- &nbsp;
482
- export function onlyMe (options = { throwOnMissingUser: true }) {
483
- return function (context) {
484
- if (context.type !== 'before') <span class="branch-0 cbranch-no" title="branch not covered" >{</span>
485
- <span class="cstat-no" title="statement not covered" > throw new Error('The \'onlyMe\' hook should only be used as a \'before\' hook.')</span>
486
- <span class="cstat-no" title="statement not covered" > }</span>
487
- const userId = _.toString(_.get(context.params, 'user._id'))
488
- if (userId) {
489
- _.set(context.params, 'query._id', createObjectID(userId))
490
- } else if (options.throwOnMissingUser) {
491
- throw new Forbidden('This operation is subject to user identify check but none can be found')
492
- }
493
- }
494
- }
495
- &nbsp;
496
- export function isNotMe (options = { throwOnMissingUser: false }) {
497
- return function (context) {
498
- const userId = _.get(context.params, 'user._id')
499
- // As no user to compare with can't be me
500
- if (_.isNil(userId)) {
501
- if (options.throwOnMissingUser) <span class="branch-0 cbranch-no" title="branch not covered" >throw new Forbidden('This operation is subject to user identify check but none can be found')</span>
502
- else return true
503
- }
504
- // Manage get/update/patch/remove before hook
505
- if (context.id) return (_.toString(context.id) !== _.toString(userId))
506
- // Manage after hook including multi-operations
507
- let items = getItems(context)
508
- if (!Array.isArray(items)) <span class="branch-0 cbranch-no" title="branch not covered" >items = [items]</span>
509
- items = items.filter(item =&gt; _.toString(item._id) !== _.toString(userId))
510
- // If any item not targetting myself
511
- return items.length &gt; 0
512
- }
513
- }
603
+ export <span class="fstat-no" title="function not covered" >function disallowRegistration (hook) {</span>
604
+ <span class="cstat-no" title="statement not covered" > return _.get(hook.app.get('authentication'), 'disallowRegistration')</span>
605
+ <span class="cstat-no" title="statement not covered" >}</span>
606
+ export <span class="fstat-no" title="function not covered" >function allowLocalAuthentication (hook) {</span>
607
+ <span class="cstat-no" title="statement not covered" > return _.get(hook.app.get('authentication'), 'authStrategies', []).includes('local')</span>
608
+ <span class="cstat-no" title="statement not covered" >}</span>
609
+ export <span class="fstat-no" title="function not covered" >function isNotMe (hook) {</span>
610
+ <span class="cstat-no" title="statement not covered" > const userId = _.get(hook.params, 'user._id', '')</span>
611
+ <span class="cstat-no" title="statement not covered" > const item = getItems(hook)</span>
612
+ <span class="cstat-no" title="statement not covered" > const targetId = _.get(item, '_id', '')</span>
613
+ <span class="cstat-no" title="statement not covered" > return userId.toString() !== targetId.toString()</span>
614
+ <span class="cstat-no" title="statement not covered" >}</span>
514
615
  &nbsp;
515
616
  export function enforcePasswordPolicy (options = {}) {
516
617
  return async function (hook) {
517
- if (hook.type !== 'before') <span class="branch-0 cbranch-no" title="branch not covered" >{</span>
618
+ <span class="cstat-no" title="statement not covered" > if (hook.type !== 'before') {</span>
518
619
  <span class="cstat-no" title="statement not covered" > throw new Error('The \'enforePasswordPolicy\' hook should only be used as a \'before\' hook.')</span>
519
620
  <span class="cstat-no" title="statement not covered" > }</span>
520
- // By pass check ?
521
- if (hook.params.force) <span class="branch-0 cbranch-no" title="branch not covered" >return hook</span>
522
- const app = hook.app
523
- const item = getItems(hook)
524
- const user = options.userAsItem ? item : hook.params.user
525
- // Get both password(s) since some rules target one and some the other one(s)
526
- const clearPassword = _.get(item, options.passwordField || 'clearPassword')
527
- const hashedPasswords = _.get(user, options.previousPasswordsField || 'previousPasswords', [])
528
- if (clearPassword &amp;&amp; hashedPasswords &amp;&amp; app.getPasswordPolicy) {
529
- debug('Enforcing password policy on user', user)
530
- const validator = app.getPasswordPolicy()
531
- // First check the clear password
532
- const result = validator.validate(clearPassword, { list: true })
533
- // Then check for the last used passwords using password policy verifier
534
- for (let i = 0; i &lt; hashedPasswords.length; i++) {
535
- try {
536
- await validator.comparePassword({ password: hashedPasswords[i] }, clearPassword)
537
- // If we have found a similar password stop
538
- result.push('previous')
539
- break
540
- } <span class="branch-0 cbranch-no" title="branch not covered" >catch (error) {</span>
621
+ <span class="cstat-no" title="statement not covered" > // By pass check ?</span>
622
+ <span class="cstat-no" title="statement not covered" > if (hook.params.force) return hook</span>
623
+ <span class="cstat-no" title="statement not covered" > const app = hook.app</span>
624
+ <span class="cstat-no" title="statement not covered" > const item = getItems(hook)</span>
625
+ <span class="cstat-no" title="statement not covered" > const user = options.userAsItem ? item : hook.params.user</span>
626
+ <span class="cstat-no" title="statement not covered" > // Get both password(s) since some rules target one and some the other one(s)</span>
627
+ <span class="cstat-no" title="statement not covered" > const clearPassword = _.get(item, options.passwordField || 'clearPassword')</span>
628
+ <span class="cstat-no" title="statement not covered" > const hashedPasswords = _.get(user, options.previousPasswordsField || 'previousPasswords', [])</span>
629
+ <span class="cstat-no" title="statement not covered" > if (clearPassword &amp;&amp; hashedPasswords &amp;&amp; app.getPasswordPolicy) {</span>
630
+ <span class="cstat-no" title="statement not covered" > debug('Enforcing password policy on user', user)</span>
631
+ <span class="cstat-no" title="statement not covered" > const validator = app.getPasswordPolicy()</span>
632
+ <span class="cstat-no" title="statement not covered" > // First check the clear password</span>
633
+ <span class="cstat-no" title="statement not covered" > const result = validator.validate(clearPassword, { list: true })</span>
634
+ <span class="cstat-no" title="statement not covered" > // Then check for the last used passwords using password policy verifier</span>
635
+ <span class="cstat-no" title="statement not covered" > for (let i = 0; i &lt; hashedPasswords.length; i++) {</span>
636
+ <span class="cstat-no" title="statement not covered" > try {</span>
637
+ <span class="cstat-no" title="statement not covered" > await validator.comparePassword({ password: hashedPasswords[i] }, clearPassword)</span>
638
+ <span class="cstat-no" title="statement not covered" > // If we have found a similar password stop</span>
639
+ <span class="cstat-no" title="statement not covered" > result.push('previous')</span>
640
+ <span class="cstat-no" title="statement not covered" > break</span>
641
+ <span class="cstat-no" title="statement not covered" > } catch (error) {</span>
541
642
  <span class="cstat-no" title="statement not covered" > // Check next one</span>
542
643
  <span class="cstat-no" title="statement not covered" > }</span>
543
- }
544
- &nbsp;
545
- if (!_.isEmpty(result)) {
546
- throw new BadRequest('The provided password does not comply to the password policy', {
547
- translation: {
548
- key: 'WEAK_PASSWORD',
549
- keys: result.map(rule =&gt; 'WEAK_PASSWORD_' + rule.toUpperCase()),
550
- params: Object.assign({ failedRules: result }, _.omit(validator.options, ['prohibited']))
551
- }
552
- })
553
- }
554
- }
555
- return hook
556
- }
644
+ <span class="cstat-no" title="statement not covered" > }</span>
645
+ <span class="cstat-no" title="statement not covered" ></span>
646
+ <span class="cstat-no" title="statement not covered" > if (!_.isEmpty(result)) {</span>
647
+ <span class="cstat-no" title="statement not covered" > throw new BadRequest('The provided password does not comply to the password policy', {</span>
648
+ <span class="cstat-no" title="statement not covered" > translation: {</span>
649
+ <span class="cstat-no" title="statement not covered" > key: 'WEAK_PASSWORD',</span>
650
+ <span class="cstat-no" title="statement not covered" > keys: result.map(rule =&gt; 'WEAK_PASSWORD_' + rule.toUpperCase()),</span>
651
+ <span class="cstat-no" title="statement not covered" > params: Object.assign({ failedRules: result }, _.omit(validator.options, ['prohibited']))</span>
652
+ <span class="cstat-no" title="statement not covered" > }</span>
653
+ <span class="cstat-no" title="statement not covered" > })</span>
654
+ <span class="cstat-no" title="statement not covered" > }</span>
655
+ <span class="cstat-no" title="statement not covered" > }</span>
656
+ <span class="cstat-no" title="statement not covered" > return hook</span>
657
+ <span class="cstat-no" title="statement not covered" > }</span>
557
658
  }
558
659
  &nbsp;
559
660
  export function storePreviousPassword (options = {}) {
560
661
  return function (hook) {
561
- if (hook.type !== 'before') <span class="branch-0 cbranch-no" title="branch not covered" >{</span>
662
+ <span class="cstat-no" title="statement not covered" > if (hook.type !== 'before') {</span>
562
663
  <span class="cstat-no" title="statement not covered" > throw new Error('The \'storePreviousPassword\' hook should only be used as a \'before\' hook.')</span>
563
664
  <span class="cstat-no" title="statement not covered" > }</span>
564
- const app = hook.app
565
- const data = getItems(hook)
566
- if (app.getPasswordPolicy &amp;&amp; hook.params.previousItem) {
567
- const validator = app.getPasswordPolicy()
568
- // Based on previous password value
569
- const user = hook.params.previousItem
570
- const passwordField = options.passwordField || 'password'
571
- const password = _.get(user, passwordField)
572
- if (password) {
573
- const previousPasswordsField = options.previousPasswordsField || 'previousPasswords'
574
- const previousPasswords = _.get(user, previousPasswordsField, [])
575
- debug(`Moving previous password from field ${passwordField} in field ${previousPasswords} on user`, user)
576
- previousPasswords.push(password)
577
- // Pop oldest password when required
578
- const max = _.get(validator, 'options.history', 5)
579
- if (previousPasswords.length &gt; max) <span class="branch-0 cbranch-no" title="branch not covered" >previousPasswords.shift()</span>
580
- Object.assign(data, { [previousPasswordsField]: previousPasswords })
581
- replaceItems(hook, data)
582
- }
583
- }
584
- return hook
585
- }
665
+ <span class="cstat-no" title="statement not covered" > const app = hook.app</span>
666
+ <span class="cstat-no" title="statement not covered" > const data = getItems(hook)</span>
667
+ <span class="cstat-no" title="statement not covered" > if (app.getPasswordPolicy &amp;&amp; hook.params.previousItem) {</span>
668
+ <span class="cstat-no" title="statement not covered" > const validator = app.getPasswordPolicy()</span>
669
+ <span class="cstat-no" title="statement not covered" > // Based on previous password value</span>
670
+ <span class="cstat-no" title="statement not covered" > const user = hook.params.previousItem</span>
671
+ <span class="cstat-no" title="statement not covered" > const passwordField = options.passwordField || 'password'</span>
672
+ <span class="cstat-no" title="statement not covered" > const password = _.get(user, passwordField)</span>
673
+ <span class="cstat-no" title="statement not covered" > if (password) {</span>
674
+ <span class="cstat-no" title="statement not covered" > const previousPasswordsField = options.previousPasswordsField || 'previousPasswords'</span>
675
+ <span class="cstat-no" title="statement not covered" > const previousPasswords = _.get(user, previousPasswordsField, [])</span>
676
+ <span class="cstat-no" title="statement not covered" > debug(`Moving previous password from field ${passwordField} in field ${previousPasswords} on user`, user)</span>
677
+ <span class="cstat-no" title="statement not covered" > previousPasswords.push(password)</span>
678
+ <span class="cstat-no" title="statement not covered" > // Pop oldest password when required</span>
679
+ <span class="cstat-no" title="statement not covered" > const max = _.get(validator, 'options.history', 5)</span>
680
+ <span class="cstat-no" title="statement not covered" > if (previousPasswords.length &gt; max) previousPasswords.shift()</span>
681
+ <span class="cstat-no" title="statement not covered" > Object.assign(data, { [previousPasswordsField]: previousPasswords })</span>
682
+ <span class="cstat-no" title="statement not covered" > replaceItems(hook, data)</span>
683
+ <span class="cstat-no" title="statement not covered" > }</span>
684
+ <span class="cstat-no" title="statement not covered" > }</span>
685
+ <span class="cstat-no" title="statement not covered" > return hook</span>
686
+ <span class="cstat-no" title="statement not covered" > }</span>
586
687
  }
587
688
  &nbsp;
588
689
  export function generatePassword (options = {}) {
@@ -621,39 +722,130 @@ export function generatePassword (options = {}) {
621
722
  }
622
723
  }
623
724
  &nbsp;
624
- export async function sendVerificationEmail (hook) {
625
- if (hook.type !== 'after') <span class="branch-0 cbranch-no" title="branch not covered" >{</span>
626
- <span class="cstat-no" title="statement not covered" > throw new Error('The \'sendVerificationEmail\' hook should only be used as a \'after\' hook.')</span>
725
+ export <span class="fstat-no" title="function not covered" >function preventRemoveUser (hook) {</span>
726
+ <span class="cstat-no" title="statement not covered" > if (hook.type !== 'before') {</span>
727
+ <span class="cstat-no" title="statement not covered" > throw new Error('The \'preventRemoveUser\' hook should only be used as a \'before\' hook.')</span>
728
+ <span class="cstat-no" title="statement not covered" > }</span>
729
+ <span class="cstat-no" title="statement not covered" ></span>
730
+ <span class="cstat-no" title="statement not covered" > // By pass check ?</span>
731
+ <span class="cstat-no" title="statement not covered" > if (hook.params.force) return hook</span>
732
+ <span class="cstat-no" title="statement not covered" > const user = hook.params.user</span>
733
+ <span class="cstat-no" title="statement not covered" > // Check if the target is the current user</span>
734
+ <span class="cstat-no" title="statement not covered" > if ((user._id.toString() === hook.id.toString()) &amp;&amp; user.organisations) {</span>
735
+ <span class="cstat-no" title="statement not covered" > // We must ensure the user is no more a owner of an organisation</span>
736
+ <span class="cstat-no" title="statement not covered" > const owningOrganisations = _.filter(user.organisations, { permissions: RoleNames[Roles.owner] })</span>
737
+ <span class="cstat-no" title="statement not covered" > if (!_.isEmpty(owningOrganisations)) {</span>
738
+ <span class="cstat-no" title="statement not covered" > debug('Cannot remove the user: ', user)</span>
739
+ <span class="cstat-no" title="statement not covered" > throw new Forbidden('You are not allowed to delete the user ' + user.name, {</span>
740
+ <span class="cstat-no" title="statement not covered" > translation: {</span>
741
+ <span class="cstat-no" title="statement not covered" > key: 'CANNOT_REMOVE_USER',</span>
742
+ <span class="cstat-no" title="statement not covered" > params: { user: _.get(user, 'profile.name') }</span>
743
+ <span class="cstat-no" title="statement not covered" > }</span>
744
+ <span class="cstat-no" title="statement not covered" > })</span>
745
+ <span class="cstat-no" title="statement not covered" > }</span>
627
746
  <span class="cstat-no" title="statement not covered" > }</span>
747
+ <span class="cstat-no" title="statement not covered" > return hook</span>
748
+ <span class="cstat-no" title="statement not covered" >}</span>
628
749
  &nbsp;
629
- // Check for by-passing OAuth2 providers
630
- for (const provider of hook.app.authenticationProviders) <span class="branch-0 cbranch-no" title="branch not covered" >{</span>
631
- <span class="cstat-no" title="statement not covered" > if (hook.result[provider + 'Id']) return Promise.resolve(hook)</span>
750
+ export <span class="fstat-no" title="function not covered" >async function joinOrganisation (hook) {</span>
751
+ <span class="cstat-no" title="statement not covered" > const app = hook.app</span>
752
+ <span class="cstat-no" title="statement not covered" > const subject = getItems(hook)</span>
753
+ <span class="cstat-no" title="statement not covered" > const authorisationService = app.getService('authorisations')</span>
754
+ <span class="cstat-no" title="statement not covered" > const usersService = app.getService('users')</span>
755
+ <span class="cstat-no" title="statement not covered" ></span>
756
+ <span class="cstat-no" title="statement not covered" > // Set membership for the created user</span>
757
+ <span class="cstat-no" title="statement not covered" > await authorisationService.create({</span>
758
+ <span class="cstat-no" title="statement not covered" > scope: 'organisations',</span>
759
+ <span class="cstat-no" title="statement not covered" > permissions: subject.sponsor.roleGranted, // Member by default</span>
760
+ <span class="cstat-no" title="statement not covered" > resource: subject.sponsor.organisationId,</span>
761
+ <span class="cstat-no" title="statement not covered" > resourcesService: 'organisations'</span>
762
+ <span class="cstat-no" title="statement not covered" > }, {</span>
763
+ <span class="cstat-no" title="statement not covered" > subjectsService: usersService,</span>
764
+ <span class="cstat-no" title="statement not covered" > subjects: [subject]</span>
765
+ <span class="cstat-no" title="statement not covered" > })</span>
766
+ <span class="cstat-no" title="statement not covered" > debug('Organisation membership set for user ' + subject._id)</span>
767
+ <span class="cstat-no" title="statement not covered" > return hook</span>
768
+ <span class="cstat-no" title="statement not covered" >}</span>
769
+ &nbsp;
770
+ export <span class="fstat-no" title="function not covered" >function leaveOrganisations (options = { skipPrivate: true }) {</span>
771
+ <span class="cstat-no" title="statement not covered" > return async function (hook) {</span>
772
+ <span class="cstat-no" title="statement not covered" > if (hook.type !== 'after') {</span>
773
+ <span class="cstat-no" title="statement not covered" > throw new Error('The \'leaveOrganisations\' hook should only be used as a \'after\' hook.')</span>
774
+ <span class="cstat-no" title="statement not covered" > }</span>
775
+ <span class="cstat-no" title="statement not covered" ></span>
776
+ <span class="cstat-no" title="statement not covered" > const app = hook.app</span>
777
+ <span class="cstat-no" title="statement not covered" > const organisationsService = app.getService('organisations')</span>
778
+ <span class="cstat-no" title="statement not covered" > const authorisationService = app.getService('authorisations')</span>
779
+ <span class="cstat-no" title="statement not covered" > const usersService = app.getService('users')</span>
780
+ <span class="cstat-no" title="statement not covered" > const subject = getItems(hook)</span>
781
+ <span class="cstat-no" title="statement not covered" > const organisations = _.get(subject, 'organisations', [])</span>
782
+ <span class="cstat-no" title="statement not covered" ></span>
783
+ <span class="cstat-no" title="statement not covered" > await Promise.all(organisations.map(organisation =&gt; {</span>
784
+ <span class="cstat-no" title="statement not covered" > // Unset membership on org except private org if required</span>
785
+ <span class="cstat-no" title="statement not covered" > if (options.skipPrivate &amp;&amp; organisation._id.toString() === subject._id.toString()) return Promise.resolve()</span>
786
+ <span class="cstat-no" title="statement not covered" > return authorisationService.remove(organisation._id.toString(), {</span>
787
+ <span class="cstat-no" title="statement not covered" > query: {</span>
788
+ <span class="cstat-no" title="statement not covered" > scope: 'organisations'</span>
789
+ <span class="cstat-no" title="statement not covered" > },</span>
790
+ <span class="cstat-no" title="statement not covered" > user: hook.params.user,</span>
791
+ <span class="cstat-no" title="statement not covered" > // Because we already have resource set it as objects to avoid populating</span>
792
+ <span class="cstat-no" title="statement not covered" > // Moreover used as an after hook the subject might not already exist anymore</span>
793
+ <span class="cstat-no" title="statement not covered" > subjects: [subject],</span>
794
+ <span class="cstat-no" title="statement not covered" > subjectsService: usersService,</span>
795
+ <span class="cstat-no" title="statement not covered" > resource: organisation,</span>
796
+ <span class="cstat-no" title="statement not covered" > resourcesService: organisationsService</span>
797
+ <span class="cstat-no" title="statement not covered" > })</span>
798
+ <span class="cstat-no" title="statement not covered" > }))</span>
799
+ <span class="cstat-no" title="statement not covered" ></span>
800
+ <span class="cstat-no" title="statement not covered" > debug('Membership unset for all organisations on user ' + subject._id)</span>
801
+ <span class="cstat-no" title="statement not covered" > return hook</span>
632
802
  <span class="cstat-no" title="statement not covered" > }</span>
803
+ <span class="cstat-no" title="statement not covered" >}</span>
633
804
  &nbsp;
634
- const accountService = hook.app.getService('account')
635
- await accountService.options.notifier('resendVerifySignup', hook.result)
636
- return hook
637
- }
805
+ export <span class="fstat-no" title="function not covered" >async function sendVerificationEmail (hook) {</span>
806
+ <span class="cstat-no" title="statement not covered" > if (hook.type !== 'after') {</span>
807
+ <span class="cstat-no" title="statement not covered" > throw new Error('The \'sendVerificationEmail\' hook should only be used as a \'after\' hook.')</span>
808
+ <span class="cstat-no" title="statement not covered" > }</span>
809
+ <span class="cstat-no" title="statement not covered" ></span>
810
+ <span class="cstat-no" title="statement not covered" > // Check for by-passing OAuth2 providers</span>
811
+ <span class="cstat-no" title="statement not covered" > for (const provider of hook.app.authenticationProviders) {</span>
812
+ <span class="cstat-no" title="statement not covered" > if (hook.result[provider + 'Id']) return Promise.resolve(hook)</span>
813
+ <span class="cstat-no" title="statement not covered" > }</span>
814
+ <span class="cstat-no" title="statement not covered" ></span>
815
+ <span class="cstat-no" title="statement not covered" > const accountService = hook.app.getService('account')</span>
816
+ <span class="cstat-no" title="statement not covered" > await accountService.options.notifier('resendVerifySignup', hook.result)</span>
817
+ <span class="cstat-no" title="statement not covered" > return hook</span>
818
+ <span class="cstat-no" title="statement not covered" >}</span>
638
819
  &nbsp;
639
- export function addVerification (hook) {
640
- const accountService = hook.app.getService('account')
820
+ export <span class="fstat-no" title="function not covered" >async function sendInvitationEmail (hook) {</span>
821
+ <span class="cstat-no" title="statement not covered" > // Before because we need to send the clear password by email</span>
822
+ <span class="cstat-no" title="statement not covered" > if (hook.type !== 'before') {</span>
823
+ <span class="cstat-no" title="statement not covered" > throw new Error('The \'sendInvitationEmail\' hook should only be used as a \'before\' hook.')</span>
824
+ <span class="cstat-no" title="statement not covered" > }</span>
825
+ <span class="cstat-no" title="statement not covered" ></span>
826
+ <span class="cstat-no" title="statement not covered" > const accountService = hook.app.getService('account')</span>
827
+ <span class="cstat-no" title="statement not covered" > await accountService.options.notifier('sendInvitation', hook.data)</span>
828
+ <span class="cstat-no" title="statement not covered" > return hook</span>
829
+ <span class="cstat-no" title="statement not covered" >}</span>
641
830
  &nbsp;
642
- return verifyHooks.addVerification(accountService.getPath(true))(hook)
643
- .then(hook =&gt; {
644
- // Check for OAuth2 providers
645
- let isVerified = false
646
- for (const provider of hook.app.authenticationProviders) <span class="branch-0 cbranch-no" title="branch not covered" >{</span>
831
+ export <span class="fstat-no" title="function not covered" >function addVerification (hook) {</span>
832
+ <span class="cstat-no" title="statement not covered" > const accountService = hook.app.getService('account')</span>
833
+ <span class="cstat-no" title="statement not covered" ></span>
834
+ <span class="cstat-no" title="statement not covered" > return verifyHooks.addVerification(accountService.getPath(true))(hook)</span>
835
+ <span class="cstat-no" title="statement not covered" > .then(hook =&gt; {</span>
836
+ <span class="cstat-no" title="statement not covered" > // Check for OAuth2 providers</span>
837
+ <span class="cstat-no" title="statement not covered" > let isVerified = false</span>
838
+ <span class="cstat-no" title="statement not covered" > for (const provider of hook.app.authenticationProviders) {</span>
647
839
  <span class="cstat-no" title="statement not covered" > if (hook.data[provider + 'Id']) isVerified = true</span>
648
840
  <span class="cstat-no" title="statement not covered" > }</span>
649
- hook.data.isVerified = isVerified
650
- return hook
651
- })
652
- }
841
+ <span class="cstat-no" title="statement not covered" > hook.data.isVerified = isVerified</span>
842
+ <span class="cstat-no" title="statement not covered" > return hook</span>
843
+ <span class="cstat-no" title="statement not covered" > })</span>
844
+ <span class="cstat-no" title="statement not covered" >}</span>
653
845
  &nbsp;
654
- export function removeVerification (hook) {
655
- return verifyHooks.removeVerification()(hook)
656
- }
846
+ export <span class="fstat-no" title="function not covered" >function removeVerification (hook) {</span>
847
+ <span class="cstat-no" title="statement not covered" > return verifyHooks.removeVerification()(hook)</span>
848
+ <span class="cstat-no" title="statement not covered" >}</span>
657
849
  &nbsp;</pre></td></tr></table></pre>
658
850
 
659
851
  <div class='push'></div><!-- for sticky footer -->
@@ -661,7 +853,7 @@ export function removeVerification (hook) {
661
853
  <div class='footer quiet pad2 space-top1 center small'>
662
854
  Code coverage generated by
663
855
  <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
664
- at 2025-12-17T09:26:49.744Z
856
+ at 2024-08-13T10:02:04.843Z
665
857
  </div>
666
858
  <script src="../../../prettify.js"></script>
667
859
  <script>