@sync-in/server 1.5.2 → 1.6.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 (355) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/README.md +2 -1
  3. package/environment/environment.dist.min.yaml +1 -0
  4. package/environment/environment.dist.yaml +88 -30
  5. package/migrations/0002_sleepy_korath.sql +1 -0
  6. package/migrations/meta/0002_snapshot.json +2424 -0
  7. package/migrations/meta/_journal.json +7 -0
  8. package/package.json +14 -12
  9. package/server/app.bootstrap.js +1 -1
  10. package/server/app.bootstrap.js.map +1 -1
  11. package/server/applications/files/services/files-manager.service.js +1 -2
  12. package/server/applications/files/services/files-manager.service.js.map +1 -1
  13. package/server/applications/files/services/files-only-office-manager.service.js +5 -6
  14. package/server/applications/files/services/files-only-office-manager.service.js.map +1 -1
  15. package/server/applications/files/utils/files.js +6 -4
  16. package/server/applications/files/utils/files.js.map +1 -1
  17. package/server/applications/links/links.controller.js +2 -2
  18. package/server/applications/links/links.controller.js.map +1 -1
  19. package/server/applications/links/services/links-manager.service.js +2 -1
  20. package/server/applications/links/services/links-manager.service.js.map +1 -1
  21. package/server/applications/links/services/links-manager.service.spec.js +6 -3
  22. package/server/applications/links/services/links-manager.service.spec.js.map +1 -1
  23. package/server/applications/notifications/constants/notifications.js +9 -0
  24. package/server/applications/notifications/constants/notifications.js.map +1 -1
  25. package/server/applications/notifications/i18n/fr.js +10 -1
  26. package/server/applications/notifications/i18n/fr.js.map +1 -1
  27. package/server/applications/notifications/interfaces/notification-properties.interface.js.map +1 -1
  28. package/server/applications/notifications/mails/models.js +41 -3
  29. package/server/applications/notifications/mails/models.js.map +1 -1
  30. package/server/applications/notifications/mails/templates.js +1 -1
  31. package/server/applications/notifications/mails/templates.js.map +1 -1
  32. package/server/applications/notifications/schemas/notifications.schema.js +2 -1
  33. package/server/applications/notifications/schemas/notifications.schema.js.map +1 -1
  34. package/server/applications/notifications/services/notifications-manager.service.js +16 -13
  35. package/server/applications/notifications/services/notifications-manager.service.js.map +1 -1
  36. package/server/applications/notifications/services/notifications-manager.service.spec.js +9 -8
  37. package/server/applications/notifications/services/notifications-manager.service.spec.js.map +1 -1
  38. package/server/applications/notifications/services/notifications-queries.service.js +1 -1
  39. package/server/applications/notifications/services/notifications-queries.service.js.map +1 -1
  40. package/server/applications/shares/services/shares-manager.service.js +3 -2
  41. package/server/applications/shares/services/shares-manager.service.js.map +1 -1
  42. package/server/applications/sync/constants/auth.js +2 -2
  43. package/server/applications/sync/constants/auth.js.map +1 -1
  44. package/server/applications/sync/dtos/sync-client-registration.dto.js +5 -0
  45. package/server/applications/sync/dtos/sync-client-registration.dto.js.map +1 -1
  46. package/server/applications/sync/dtos/sync-operations.dto.js +1 -2
  47. package/server/applications/sync/dtos/sync-operations.dto.js.map +1 -1
  48. package/server/applications/sync/schemas/sync-clients.schema.js +2 -1
  49. package/server/applications/sync/schemas/sync-clients.schema.js.map +1 -1
  50. package/server/applications/sync/schemas/sync-paths.schema.js +2 -1
  51. package/server/applications/sync/schemas/sync-paths.schema.js.map +1 -1
  52. package/server/applications/sync/services/sync-clients-manager.service.js +28 -20
  53. package/server/applications/sync/services/sync-clients-manager.service.js.map +1 -1
  54. package/server/applications/sync/services/sync-clients-manager.service.spec.js +24 -18
  55. package/server/applications/sync/services/sync-clients-manager.service.spec.js.map +1 -1
  56. package/server/applications/sync/services/sync-queries.service.js +5 -5
  57. package/server/applications/sync/services/sync-queries.service.js.map +1 -1
  58. package/server/applications/users/admin-users.controller.js +48 -37
  59. package/server/applications/users/admin-users.controller.js.map +1 -1
  60. package/server/applications/users/admin-users.controller.spec.js +15 -0
  61. package/server/applications/users/admin-users.controller.spec.js.map +1 -1
  62. package/server/applications/users/constants/routes.js +5 -0
  63. package/server/applications/users/constants/routes.js.map +1 -1
  64. package/server/applications/users/constants/user.js +8 -0
  65. package/server/applications/users/constants/user.js.map +1 -1
  66. package/server/applications/users/dto/delete-user.dto.js +5 -23
  67. package/server/applications/users/dto/delete-user.dto.js.map +1 -1
  68. package/server/applications/users/dto/user-properties.dto.js +38 -3
  69. package/server/applications/users/dto/user-properties.dto.js.map +1 -1
  70. package/server/applications/users/interfaces/admin-user.interface.js.map +1 -1
  71. package/server/applications/users/interfaces/user-secrets.interface.js +10 -0
  72. package/server/applications/users/interfaces/user-secrets.interface.js.map +1 -0
  73. package/server/applications/users/models/user.model.js +84 -50
  74. package/server/applications/users/models/user.model.js.map +1 -1
  75. package/server/applications/users/schemas/user.interface.js.map +1 -1
  76. package/server/applications/users/schemas/users.schema.js +2 -0
  77. package/server/applications/users/schemas/users.schema.js.map +1 -1
  78. package/server/applications/users/services/admin-users-manager.service.js +7 -19
  79. package/server/applications/users/services/admin-users-manager.service.js.map +1 -1
  80. package/server/applications/users/services/admin-users-manager.service.spec.js +7 -26
  81. package/server/applications/users/services/admin-users-manager.service.spec.js.map +1 -1
  82. package/server/applications/users/services/admin-users-queries.service.js +1 -0
  83. package/server/applications/users/services/admin-users-queries.service.js.map +1 -1
  84. package/server/applications/users/services/users-manager.service.js +138 -28
  85. package/server/applications/users/services/users-manager.service.js.map +1 -1
  86. package/server/applications/users/services/users-manager.service.spec.js +11 -9
  87. package/server/applications/users/services/users-manager.service.spec.js.map +1 -1
  88. package/server/applications/users/services/users-queries.service.js +63 -57
  89. package/server/applications/users/services/users-queries.service.js.map +1 -1
  90. package/server/applications/users/users.controller.js +48 -1
  91. package/server/applications/users/users.controller.js.map +1 -1
  92. package/server/applications/users/users.controller.spec.js +8 -1
  93. package/server/applications/users/users.controller.spec.js.map +1 -1
  94. package/server/applications/users/users.e2e-spec.js +2 -1
  95. package/server/applications/users/users.e2e-spec.js.map +1 -1
  96. package/server/applications/users/utils/avatar.js +48 -0
  97. package/server/applications/users/utils/avatar.js.map +1 -0
  98. package/server/authentication/auth.config.js +89 -26
  99. package/server/authentication/auth.config.js.map +1 -1
  100. package/server/authentication/auth.controller.js +117 -9
  101. package/server/authentication/auth.controller.js.map +1 -1
  102. package/server/authentication/auth.controller.spec.js +16 -1
  103. package/server/authentication/auth.controller.spec.js.map +1 -1
  104. package/server/authentication/auth.e2e-spec.js +4 -3
  105. package/server/authentication/auth.e2e-spec.js.map +1 -1
  106. package/server/authentication/auth.module.js +4 -1
  107. package/server/authentication/auth.module.js.map +1 -1
  108. package/server/authentication/constants/auth-ldap.js +44 -0
  109. package/server/authentication/constants/auth-ldap.js.map +1 -0
  110. package/server/authentication/constants/auth.js +37 -4
  111. package/server/authentication/constants/auth.js.map +1 -1
  112. package/server/authentication/constants/routes.js +21 -0
  113. package/server/authentication/constants/routes.js.map +1 -1
  114. package/server/authentication/constants/scope.js +20 -0
  115. package/server/authentication/constants/scope.js.map +1 -0
  116. package/server/authentication/dto/login-response.dto.js +27 -4
  117. package/server/authentication/dto/login-response.dto.js.map +1 -1
  118. package/server/authentication/dto/token-response.dto.js +5 -0
  119. package/server/authentication/dto/token-response.dto.js.map +1 -1
  120. package/server/{applications/users/dto/user-password.dto.js → authentication/dto/two-fa-verify.dto.js} +27 -9
  121. package/server/authentication/dto/two-fa-verify.dto.js.map +1 -0
  122. package/server/authentication/guards/auth-basic.strategy.js +6 -5
  123. package/server/authentication/guards/auth-basic.strategy.js.map +1 -1
  124. package/server/authentication/guards/auth-token-access.strategy.js +3 -2
  125. package/server/authentication/guards/auth-token-access.strategy.js.map +1 -1
  126. package/server/authentication/guards/auth-token-refresh.strategy.js +3 -2
  127. package/server/authentication/guards/auth-token-refresh.strategy.js.map +1 -1
  128. package/server/authentication/guards/auth-two-fa-guard.js +81 -0
  129. package/server/authentication/guards/auth-two-fa-guard.js.map +1 -0
  130. package/server/authentication/interfaces/jwt-payload.interface.js +5 -0
  131. package/server/authentication/interfaces/jwt-payload.interface.js.map +1 -1
  132. package/server/authentication/interfaces/token.interface.js +2 -0
  133. package/server/authentication/interfaces/token.interface.js.map +1 -1
  134. package/server/authentication/interfaces/two-fa-setup.interface.js +10 -0
  135. package/server/authentication/interfaces/two-fa-setup.interface.js.map +1 -0
  136. package/server/authentication/models/auth-method.js.map +1 -1
  137. package/server/authentication/services/auth-manager.service.js +72 -49
  138. package/server/authentication/services/auth-manager.service.js.map +1 -1
  139. package/server/authentication/services/auth-methods/auth-method-database.service.js +3 -3
  140. package/server/authentication/services/auth-methods/auth-method-database.service.js.map +1 -1
  141. package/server/authentication/services/auth-methods/auth-method-database.service.spec.js +5 -0
  142. package/server/authentication/services/auth-methods/auth-method-database.service.spec.js.map +1 -1
  143. package/server/authentication/services/auth-methods/auth-method-ldap.service.js +151 -66
  144. package/server/authentication/services/auth-methods/auth-method-ldap.service.js.map +1 -1
  145. package/server/authentication/services/auth-methods/auth-method-ldap.service.spec.js +52 -50
  146. package/server/authentication/services/auth-methods/auth-method-ldap.service.spec.js.map +1 -1
  147. package/server/authentication/services/auth-methods/auth-method-two-fa.service.js +251 -0
  148. package/server/authentication/services/auth-methods/auth-method-two-fa.service.js.map +1 -0
  149. package/server/authentication/services/auth-methods/auth-method-two-fa.service.spec.js +41 -0
  150. package/server/authentication/services/auth-methods/auth-method-two-fa.service.spec.js.map +1 -0
  151. package/server/authentication/utils/crypt-secret.js +68 -0
  152. package/server/authentication/utils/crypt-secret.js.map +1 -0
  153. package/server/common/functions.js +18 -2
  154. package/server/common/functions.js.map +1 -1
  155. package/server/common/qrcode.js +34 -0
  156. package/server/common/qrcode.js.map +1 -0
  157. package/server/common/shared.js +18 -0
  158. package/server/common/shared.js.map +1 -1
  159. package/server/configuration/config.environment.js +23 -6
  160. package/server/configuration/config.environment.js.map +1 -1
  161. package/server/configuration/config.interfaces.js +10 -0
  162. package/server/configuration/config.interfaces.js.map +1 -0
  163. package/server/configuration/config.loader.js.map +1 -1
  164. package/server/configuration/config.validation.js +13 -13
  165. package/server/configuration/config.validation.js.map +1 -1
  166. package/server/infrastructure/cache/adapters/mysql-cache.adapter.js +6 -6
  167. package/server/infrastructure/cache/adapters/mysql-cache.adapter.js.map +1 -1
  168. package/server/infrastructure/cache/schemas/mysql-cache.schema.js +2 -1
  169. package/server/infrastructure/cache/schemas/mysql-cache.schema.js.map +1 -1
  170. package/server/infrastructure/cache/services/cache.service.js.map +1 -1
  171. package/server/infrastructure/database/columns.js +39 -0
  172. package/server/infrastructure/database/columns.js.map +1 -0
  173. package/server/infrastructure/database/database.config.js +0 -1
  174. package/server/infrastructure/database/database.config.js.map +1 -1
  175. package/server/infrastructure/mailer/interfaces/mail.interface.js.map +1 -1
  176. package/server/infrastructure/mailer/mailer.config.js +12 -0
  177. package/server/infrastructure/mailer/mailer.config.js.map +1 -1
  178. package/server/infrastructure/mailer/mailer.service.js +2 -1
  179. package/server/infrastructure/mailer/mailer.service.js.map +1 -1
  180. package/static/assets/mimes/text-x-c.svg +1 -0
  181. package/static/assets/pdfjs/build/pdf.mjs +2522 -914
  182. package/static/assets/pdfjs/build/pdf.mjs.map +1 -1
  183. package/static/assets/pdfjs/build/pdf.sandbox.mjs +2 -2
  184. package/static/assets/pdfjs/build/pdf.worker.mjs +1024 -566
  185. package/static/assets/pdfjs/build/pdf.worker.mjs.map +1 -1
  186. package/static/assets/pdfjs/version +1 -1
  187. package/static/assets/pdfjs/web/debugger.mjs +116 -37
  188. package/static/assets/pdfjs/web/images/comment-popup-editButton.svg +5 -0
  189. package/static/assets/pdfjs/web/locale/ach/viewer.ftl +0 -12
  190. package/static/assets/pdfjs/web/locale/af/viewer.ftl +0 -12
  191. package/static/assets/pdfjs/web/locale/an/viewer.ftl +0 -16
  192. package/static/assets/pdfjs/web/locale/ar/viewer.ftl +0 -32
  193. package/static/assets/pdfjs/web/locale/ast/viewer.ftl +0 -19
  194. package/static/assets/pdfjs/web/locale/az/viewer.ftl +0 -16
  195. package/static/assets/pdfjs/web/locale/be/viewer.ftl +0 -32
  196. package/static/assets/pdfjs/web/locale/bg/viewer.ftl +0 -32
  197. package/static/assets/pdfjs/web/locale/bn/viewer.ftl +0 -16
  198. package/static/assets/pdfjs/web/locale/bo/viewer.ftl +0 -12
  199. package/static/assets/pdfjs/web/locale/br/viewer.ftl +0 -22
  200. package/static/assets/pdfjs/web/locale/brx/viewer.ftl +0 -16
  201. package/static/assets/pdfjs/web/locale/bs/viewer.ftl +0 -32
  202. package/static/assets/pdfjs/web/locale/ca/viewer.ftl +12 -23
  203. package/static/assets/pdfjs/web/locale/cak/viewer.ftl +0 -23
  204. package/static/assets/pdfjs/web/locale/ckb/viewer.ftl +0 -16
  205. package/static/assets/pdfjs/web/locale/cs/viewer.ftl +0 -32
  206. package/static/assets/pdfjs/web/locale/cy/viewer.ftl +0 -32
  207. package/static/assets/pdfjs/web/locale/da/viewer.ftl +3 -35
  208. package/static/assets/pdfjs/web/locale/de/viewer.ftl +0 -32
  209. package/static/assets/pdfjs/web/locale/dsb/viewer.ftl +0 -32
  210. package/static/assets/pdfjs/web/locale/el/viewer.ftl +0 -32
  211. package/static/assets/pdfjs/web/locale/en-CA/viewer.ftl +0 -32
  212. package/static/assets/pdfjs/web/locale/en-GB/viewer.ftl +0 -32
  213. package/static/assets/pdfjs/web/locale/en-US/viewer.ftl +25 -13
  214. package/static/assets/pdfjs/web/locale/eo/viewer.ftl +0 -32
  215. package/static/assets/pdfjs/web/locale/es-AR/viewer.ftl +0 -32
  216. package/static/assets/pdfjs/web/locale/es-CL/viewer.ftl +0 -32
  217. package/static/assets/pdfjs/web/locale/es-ES/viewer.ftl +5 -32
  218. package/static/assets/pdfjs/web/locale/es-MX/viewer.ftl +0 -32
  219. package/static/assets/pdfjs/web/locale/et/viewer.ftl +0 -16
  220. package/static/assets/pdfjs/web/locale/eu/viewer.ftl +38 -32
  221. package/static/assets/pdfjs/web/locale/fa/viewer.ftl +0 -19
  222. package/static/assets/pdfjs/web/locale/ff/viewer.ftl +0 -12
  223. package/static/assets/pdfjs/web/locale/fi/viewer.ftl +0 -32
  224. package/static/assets/pdfjs/web/locale/fr/viewer.ftl +0 -32
  225. package/static/assets/pdfjs/web/locale/fur/viewer.ftl +0 -32
  226. package/static/assets/pdfjs/web/locale/fy-NL/viewer.ftl +0 -32
  227. package/static/assets/pdfjs/web/locale/ga-IE/viewer.ftl +0 -12
  228. package/static/assets/pdfjs/web/locale/gd/viewer.ftl +0 -23
  229. package/static/assets/pdfjs/web/locale/gl/viewer.ftl +0 -32
  230. package/static/assets/pdfjs/web/locale/gn/viewer.ftl +0 -32
  231. package/static/assets/pdfjs/web/locale/gu-IN/viewer.ftl +0 -12
  232. package/static/assets/pdfjs/web/locale/he/viewer.ftl +0 -32
  233. package/static/assets/pdfjs/web/locale/hi-IN/viewer.ftl +0 -16
  234. package/static/assets/pdfjs/web/locale/hr/viewer.ftl +0 -32
  235. package/static/assets/pdfjs/web/locale/hsb/viewer.ftl +0 -32
  236. package/static/assets/pdfjs/web/locale/hu/viewer.ftl +0 -32
  237. package/static/assets/pdfjs/web/locale/hy-AM/viewer.ftl +372 -16
  238. package/static/assets/pdfjs/web/locale/hye/viewer.ftl +0 -16
  239. package/static/assets/pdfjs/web/locale/ia/viewer.ftl +0 -32
  240. package/static/assets/pdfjs/web/locale/id/viewer.ftl +38 -32
  241. package/static/assets/pdfjs/web/locale/is/viewer.ftl +27 -32
  242. package/static/assets/pdfjs/web/locale/it/viewer.ftl +0 -33
  243. package/static/assets/pdfjs/web/locale/ja/viewer.ftl +31 -33
  244. package/static/assets/pdfjs/web/locale/ka/viewer.ftl +0 -32
  245. package/static/assets/pdfjs/web/locale/kab/viewer.ftl +0 -32
  246. package/static/assets/pdfjs/web/locale/kk/viewer.ftl +31 -32
  247. package/static/assets/pdfjs/web/locale/km/viewer.ftl +0 -12
  248. package/static/assets/pdfjs/web/locale/kn/viewer.ftl +0 -12
  249. package/static/assets/pdfjs/web/locale/ko/viewer.ftl +0 -32
  250. package/static/assets/pdfjs/web/locale/lij/viewer.ftl +0 -12
  251. package/static/assets/pdfjs/web/locale/lo/viewer.ftl +0 -23
  252. package/static/assets/pdfjs/web/locale/lt/viewer.ftl +0 -16
  253. package/static/assets/pdfjs/web/locale/ltg/viewer.ftl +0 -12
  254. package/static/assets/pdfjs/web/locale/lv/viewer.ftl +0 -12
  255. package/static/assets/pdfjs/web/locale/meh/viewer.ftl +0 -14
  256. package/static/assets/pdfjs/web/locale/mk/viewer.ftl +0 -19
  257. package/static/assets/pdfjs/web/locale/ml/viewer.ftl +0 -31
  258. package/static/assets/pdfjs/web/locale/mr/viewer.ftl +0 -16
  259. package/static/assets/pdfjs/web/locale/ms/viewer.ftl +0 -12
  260. package/static/assets/pdfjs/web/locale/my/viewer.ftl +0 -12
  261. package/static/assets/pdfjs/web/locale/nb-NO/viewer.ftl +0 -32
  262. package/static/assets/pdfjs/web/locale/ne-NP/viewer.ftl +0 -12
  263. package/static/assets/pdfjs/web/locale/nl/viewer.ftl +0 -32
  264. package/static/assets/pdfjs/web/locale/nn-NO/viewer.ftl +0 -32
  265. package/static/assets/pdfjs/web/locale/oc/viewer.ftl +0 -24
  266. package/static/assets/pdfjs/web/locale/pa-IN/viewer.ftl +0 -32
  267. package/static/assets/pdfjs/web/locale/pl/viewer.ftl +0 -32
  268. package/static/assets/pdfjs/web/locale/pt-BR/viewer.ftl +0 -32
  269. package/static/assets/pdfjs/web/locale/pt-PT/viewer.ftl +0 -32
  270. package/static/assets/pdfjs/web/locale/rm/viewer.ftl +0 -32
  271. package/static/assets/pdfjs/web/locale/ro/viewer.ftl +5 -37
  272. package/static/assets/pdfjs/web/locale/ru/viewer.ftl +0 -32
  273. package/static/assets/pdfjs/web/locale/sat/viewer.ftl +0 -23
  274. package/static/assets/pdfjs/web/locale/sc/viewer.ftl +8 -27
  275. package/static/assets/pdfjs/web/locale/sco/viewer.ftl +0 -16
  276. package/static/assets/pdfjs/web/locale/si/viewer.ftl +0 -22
  277. package/static/assets/pdfjs/web/locale/sk/viewer.ftl +0 -32
  278. package/static/assets/pdfjs/web/locale/skr/viewer.ftl +0 -32
  279. package/static/assets/pdfjs/web/locale/sl/viewer.ftl +30 -32
  280. package/static/assets/pdfjs/web/locale/son/viewer.ftl +0 -12
  281. package/static/assets/pdfjs/web/locale/sq/viewer.ftl +0 -32
  282. package/static/assets/pdfjs/web/locale/sr/viewer.ftl +0 -32
  283. package/static/assets/pdfjs/web/locale/sv-SE/viewer.ftl +0 -32
  284. package/static/assets/pdfjs/web/locale/szl/viewer.ftl +0 -16
  285. package/static/assets/pdfjs/web/locale/ta/viewer.ftl +0 -12
  286. package/static/assets/pdfjs/web/locale/te/viewer.ftl +0 -16
  287. package/static/assets/pdfjs/web/locale/tg/viewer.ftl +0 -32
  288. package/static/assets/pdfjs/web/locale/th/viewer.ftl +38 -32
  289. package/static/assets/pdfjs/web/locale/tl/viewer.ftl +0 -16
  290. package/static/assets/pdfjs/web/locale/tr/viewer.ftl +0 -32
  291. package/static/assets/pdfjs/web/locale/trs/viewer.ftl +0 -12
  292. package/static/assets/pdfjs/web/locale/uk/viewer.ftl +0 -32
  293. package/static/assets/pdfjs/web/locale/ur/viewer.ftl +0 -16
  294. package/static/assets/pdfjs/web/locale/uz/viewer.ftl +0 -12
  295. package/static/assets/pdfjs/web/locale/vi/viewer.ftl +0 -32
  296. package/static/assets/pdfjs/web/locale/xh/viewer.ftl +0 -12
  297. package/static/assets/pdfjs/web/locale/zh-CN/viewer.ftl +0 -32
  298. package/static/assets/pdfjs/web/locale/zh-TW/viewer.ftl +0 -32
  299. package/static/assets/pdfjs/web/viewer.css +586 -437
  300. package/static/assets/pdfjs/web/viewer.html +12 -23
  301. package/static/assets/pdfjs/web/viewer.mjs +955 -514
  302. package/static/assets/pdfjs/web/viewer.mjs.map +1 -1
  303. package/static/assets/pdfjs/web/wasm/openjpeg.wasm +0 -0
  304. package/static/assets/pdfjs/web/wasm/openjpeg_nowasm_fallback.js +10 -22
  305. package/static/{chunk-SPTF6FSM.js → chunk-27YQB3TE.js} +1 -1
  306. package/static/chunk-2I4CUFUA.js +1 -0
  307. package/static/chunk-2MTM6SWN.js +4 -0
  308. package/static/{chunk-7VRUZRJG.js → chunk-34MKICK5.js} +2 -2
  309. package/static/chunk-5O3DIUU3.js +1 -0
  310. package/static/{chunk-VJRTMDEJ.js → chunk-6NMVZIIT.js} +1 -1
  311. package/static/{chunk-L6MU6S2V.js → chunk-7DN7ZAPU.js} +1 -1
  312. package/static/{chunk-MVO4WZLK.js → chunk-7FUM3JGM.js} +1 -1
  313. package/static/{chunk-RSS6GYNE.js → chunk-7ITZXYYJ.js} +1 -1
  314. package/static/chunk-7P27WBGC.js +4 -0
  315. package/static/chunk-ATP3BFHV.js +562 -0
  316. package/static/chunk-AWQ2YTVC.js +1 -0
  317. package/static/chunk-DSOE3FEP.js +1 -0
  318. package/static/{chunk-2R6HHGUR.js → chunk-EFKMBLRE.js} +1 -1
  319. package/static/chunk-FUFKVHPU.js +1 -0
  320. package/static/{chunk-MRSWNAVB.js → chunk-HCDLWTMW.js} +1 -1
  321. package/static/chunk-IPAC4VAF.js +1 -0
  322. package/static/{chunk-ZC5NIT55.js → chunk-IQOALFYU.js} +1 -1
  323. package/static/chunk-JASU3CIH.js +1 -0
  324. package/static/{chunk-6OJZWYRZ.js → chunk-JQ5FTO2M.js} +1 -1
  325. package/static/chunk-JUNZFADM.js +1 -0
  326. package/static/{chunk-LLWSLOSX.js → chunk-LJUKI4SQ.js} +1 -1
  327. package/static/{chunk-WI7FOANP.js → chunk-LUWQFIWR.js} +1 -1
  328. package/static/{chunk-BIUNUYZ5.js → chunk-ORMRCEGT.js} +1 -1
  329. package/static/{chunk-IZL7JPTS.js → chunk-Q7D6RN4N.js} +1 -1
  330. package/static/{chunk-JYXLQRHG.js → chunk-QJX6ITLW.js} +1 -1
  331. package/static/{chunk-YJMN3B4N.js → chunk-QQ6UQQBR.js} +1 -1
  332. package/static/chunk-S2HDY3OL.js +1 -0
  333. package/static/{chunk-NE4NDO45.js → chunk-S75P2FFI.js} +1 -1
  334. package/static/{chunk-CRQNEHTX.js → chunk-T3EYFSVZ.js} +1 -1
  335. package/static/{chunk-MCLQFZ3S.js → chunk-U34OZUZ7.js} +1 -1
  336. package/static/chunk-Y7EH7G5K.js +1 -0
  337. package/static/{chunk-MGGT6MIJ.js → chunk-ZQQPUYLU.js} +1 -1
  338. package/static/index.html +2 -2
  339. package/static/main-7SQDDVMD.js +9 -0
  340. package/static/{styles-FYUSO6OJ.css → styles-A5VYX3CE.css} +1 -1
  341. package/server/applications/users/dto/user-password.dto.js.map +0 -1
  342. package/static/chunk-4U5A2DEP.js +0 -4
  343. package/static/chunk-54EAZ2UD.js +0 -1
  344. package/static/chunk-7ZRXJONB.js +0 -1
  345. package/static/chunk-F2J2IIJE.js +0 -1
  346. package/static/chunk-FNFGUIQH.js +0 -4
  347. package/static/chunk-GGLK52CG.js +0 -1
  348. package/static/chunk-HW2H3ISM.js +0 -559
  349. package/static/chunk-HX6BBYVD.js +0 -1
  350. package/static/chunk-JF7S3UYQ.js +0 -1
  351. package/static/chunk-KSHPKI4G.js +0 -1
  352. package/static/chunk-VPJ2V27B.js +0 -1
  353. package/static/chunk-VUI3KV7V.js +0 -1
  354. package/static/chunk-ZXS4V7J2.js +0 -1
  355. package/static/main-FFIWFD2F.js +0 -7
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../backend/src/applications/users/services/admin-users-manager.service.ts"],"sourcesContent":["/*\n * Copyright (C) 2012-2025 Johan Legrand <johan.legrand@sync-in.com>\n * This file is part of Sync-in | The open source file sync and share solution\n * See the LICENSE file for licensing details\n */\n\nimport { HttpException, HttpStatus, Injectable, Logger } from '@nestjs/common'\nimport { FastifyReply } from 'fastify'\nimport { LoginResponseDto } from '../../../authentication/dto/login-response.dto'\nimport { AuthManager } from '../../../authentication/services/auth-manager.service'\nimport { anonymizePassword, hashPassword } from '../../../common/functions'\nimport { isPathExists, moveFiles, removeFiles } from '../../files/utils/files'\nimport { GROUP_TYPE } from '../constants/group'\nimport { USER_ROLE } from '../constants/user'\nimport type { CreateOrUpdateGroupDto } from '../dto/create-or-update-group.dto'\nimport { CreateUserDto, UpdateUserDto, UpdateUserFromGroupDto } from '../dto/create-or-update-user.dto'\nimport type { AdminDeleteUserDto, DeleteUserDto } from '../dto/delete-user.dto'\nimport type { SearchMembersDto } from '../dto/search-members.dto'\nimport type { UserPasswordDto } from '../dto/user-password.dto'\nimport type { AdminGroup } from '../interfaces/admin-group.interface'\nimport type { AdminUser } from '../interfaces/admin-user.interface'\nimport type { GroupBrowse } from '../interfaces/group-browse.interface'\nimport type { GuestUser } from '../interfaces/guest-user.interface'\nimport type { Member } from '../interfaces/member.interface'\nimport { UserModel } from '../models/user.model'\nimport type { Group } from '../schemas/group.interface'\nimport type { User } from '../schemas/user.interface'\nimport { AdminUsersQueries } from './admin-users-queries.service'\n\n@Injectable()\nexport class AdminUsersManager {\n private readonly logger = new Logger(AdminUsersManager.name)\n\n constructor(\n private readonly authManager: AuthManager,\n private readonly adminQueries: AdminUsersQueries\n ) {}\n\n listUsers(): Promise<AdminUser[]> {\n return this.adminQueries.listUsers()\n }\n\n async getUser(userId: number): Promise<AdminUser> {\n const user: AdminUser = await this.adminQueries.listUsers(userId)\n this.checkUser(user, true)\n return user\n }\n\n async getGuest(guestId: number): Promise<GuestUser> {\n const user: GuestUser = await this.adminQueries.usersQueries.listGuests(guestId, 0, true)\n this.checkUser(user, true)\n return user\n }\n\n async createUserOrGuest(createUserDto: CreateUserDto, userRole: USER_ROLE.GUEST, asAdmin: boolean): Promise<GuestUser>\n async createUserOrGuest(createUserDto: CreateUserDto, userRole: USER_ROLE, asAdmin: true): Promise<AdminUser | GuestUser>\n async createUserOrGuest(createUserDto: CreateUserDto, userRole: USER_ROLE, asAdmin?: false): Promise<UserModel>\n async createUserOrGuest(\n createUserDto: CreateUserDto,\n userRole: USER_ROLE = USER_ROLE.USER,\n asAdmin = false\n ): Promise<UserModel | AdminUser | GuestUser> {\n await this.loginOrEmailAlreadyUsed(createUserDto.login, createUserDto.email)\n try {\n createUserDto.password = await hashPassword(createUserDto.password)\n const userId: number = await this.adminQueries.usersQueries.createUserOrGuest(createUserDto, userRole)\n const user = new UserModel({ ...createUserDto, id: userId, role: userRole })\n this.logger.log(\n `${this.createUserOrGuest.name} - ${USER_ROLE[userRole]} (${userId}) was created : ${JSON.stringify(anonymizePassword(createUserDto))}`\n )\n await user.makePaths()\n if (userRole <= USER_ROLE.USER) {\n return asAdmin ? this.getUser(user.id) : user\n } else {\n return asAdmin ? this.getGuest(user.id) : user\n }\n } catch (e) {\n this.logger.error(`${this.createUserOrGuest.name} - unable to create user *${createUserDto.login}* : ${e}`)\n throw new HttpException('Unable to create user', HttpStatus.INTERNAL_SERVER_ERROR)\n }\n }\n\n async updateUserOrGuest(userId: number, updateUserDto: UpdateUserDto): Promise<AdminUser>\n async updateUserOrGuest(userId: number, updateUserDto: UpdateUserDto, userRole: USER_ROLE.GUEST): Promise<GuestUser>\n async updateUserOrGuest(\n userId: number,\n updateUserDto: UpdateUserDto,\n userRole: USER_ROLE.USER | USER_ROLE.GUEST = USER_ROLE.USER\n ): Promise<AdminUser | GuestUser> {\n const user: AdminUser & GuestUser = userRole === USER_ROLE.USER ? await this.getUser(userId) : await this.getGuest(userId)\n const updateUser: Partial<User> = {}\n const updateUserGroups: { add: number[]; delete: number[] } = { add: [], delete: [] }\n const updateGuestManagers: { add: number[]; delete: number[] } = { add: [], delete: [] }\n for (const [k, v] of Object.entries(updateUserDto)) {\n switch (k as keyof UpdateUserDto) {\n case 'login':\n if (user.login === v) {\n break\n }\n if (await this.adminQueries.usersQueries.checkUserExists(v)) {\n throw new HttpException('Login already used', HttpStatus.FORBIDDEN)\n }\n if (!(await this.renameUserSpace(user.login, v))) {\n throw new HttpException('Unable to rename user space', HttpStatus.INTERNAL_SERVER_ERROR)\n }\n updateUser.login = v\n break\n case 'email':\n if (user.email === v) {\n break\n }\n if (await this.adminQueries.usersQueries.checkUserExists(null, v)) {\n throw new HttpException('Email already used', HttpStatus.FORBIDDEN)\n }\n updateUser.email = v\n break\n case 'isActive':\n updateUser.isActive = v\n if (v) {\n updateUser.passwordAttempts = 0\n }\n break\n case 'password':\n updateUser.password = await hashPassword(updateUserDto.password)\n break\n case 'groups':\n if (userRole === USER_ROLE.USER) {\n const currentGroups: number[] = user.groups?.length ? user.groups.map((g) => g.id) : []\n updateUserGroups.add = v.filter((id: number) => currentGroups.indexOf(id) === -1)\n updateUserGroups.delete = currentGroups.filter((id: number) => v.indexOf(id) === -1)\n }\n break\n case 'managers':\n if (userRole === USER_ROLE.GUEST) {\n const currentManagers: number[] = user.managers?.length ? user.managers.map((m) => m.id) : []\n updateGuestManagers.add = v.filter((id: number) => currentManagers.indexOf(id) === -1)\n updateGuestManagers.delete = currentManagers.filter((id: number) => v.indexOf(id) === -1)\n }\n break\n default:\n updateUser[k] = v\n }\n }\n if (Object.keys(updateUser).length) {\n // force the type for security reason\n const forceRole = userRole === USER_ROLE.GUEST ? USER_ROLE.GUEST : undefined\n if (!(await this.adminQueries.usersQueries.updateUserOrGuest(user.id, updateUser, forceRole))) {\n throw new HttpException('Unable to update user', HttpStatus.INTERNAL_SERVER_ERROR)\n }\n }\n if (userRole === USER_ROLE.USER) {\n if (updateUserGroups.add.length || updateUserGroups.delete.length) {\n try {\n await this.adminQueries.updateUserGroups(user.id, updateUserGroups)\n } catch {\n throw new HttpException('Unable to update user groups', HttpStatus.INTERNAL_SERVER_ERROR)\n }\n }\n return this.getUser(userId)\n } else {\n if (updateGuestManagers.add.length || updateGuestManagers.delete.length) {\n try {\n await this.adminQueries.updateGuestManagers(user.id, updateGuestManagers)\n } catch {\n throw new HttpException('Unable to update guest managers', HttpStatus.INTERNAL_SERVER_ERROR)\n }\n }\n return this.getGuest(userId)\n }\n }\n\n async deleteUserOrGuest(userId: number, userLogin: string, deleteUserDto: DeleteUserDto): Promise<void> {\n try {\n if (await this.adminQueries.deleteUser(userId, userLogin)) {\n this.logger.log(`${this.deleteUserOrGuest.name} - *${userLogin}* (${userId}) was deleted`)\n } else {\n this.logger.error(`${this.deleteUserOrGuest.name} - *${userLogin}* (${userId}) was not deleted : not found`)\n }\n if (deleteUserDto.deleteSpace) {\n await this.deleteUserSpace(userLogin, deleteUserDto.isGuest)\n }\n } catch (e) {\n this.logger.error(`${this.deleteUserOrGuest.name} - unable to delete *${userLogin}* (${userId}) : ${e}`)\n throw new HttpException('Unable to delete user', HttpStatus.INTERNAL_SERVER_ERROR)\n }\n }\n\n async deleteUserFromAdmin(admin: UserModel, userId: number, adminDeleteUserDto: AdminDeleteUserDto): Promise<void> {\n // check admin password\n if (!(await this.adminQueries.usersQueries.compareUserPassword(admin.id, adminDeleteUserDto.adminPassword))) {\n throw new HttpException('Bad password', HttpStatus.BAD_REQUEST)\n }\n const userToDelete: UserModel = this.checkUser(await this.adminQueries.usersQueries.from(userId))\n await this.deleteUserOrGuest(userToDelete.id, userToDelete.login, {\n deleteSpace: adminDeleteUserDto.deleteSpace\n } satisfies DeleteUserDto)\n }\n\n listGuests(): Promise<AdminUser[]> {\n return this.adminQueries.usersQueries.listGuests(null, null, true)\n }\n\n createGuest(user: UserModel, createGuestDto: CreateUserDto): Promise<GuestUser> {\n if (!createGuestDto.managers.length) {\n createGuestDto.managers.push(user.id)\n }\n return this.createUserOrGuest(createGuestDto, USER_ROLE.GUEST, true)\n }\n\n updateGuest(guestId: number, updateGuestDto: UpdateUserDto): Promise<GuestUser> {\n if (!Object.keys(updateGuestDto).length) {\n throw new HttpException('No changes to update', HttpStatus.BAD_REQUEST)\n }\n if (updateGuestDto.managers && !updateGuestDto.managers.length) {\n throw new HttpException('Guest must have at least one manager', HttpStatus.BAD_REQUEST)\n }\n return this.updateUserOrGuest(guestId, updateGuestDto, USER_ROLE.GUEST)\n }\n\n async deleteGuest(guestId: number): Promise<void> {\n // guest has no space but a temporary directory\n const guest: GuestUser = await this.getGuest(guestId)\n return this.deleteUserOrGuest(guest.id, guest.login, { deleteSpace: true, isGuest: true })\n }\n\n async browseGroups(name?: string, type: GROUP_TYPE = GROUP_TYPE.USER): Promise<GroupBrowse> {\n if (name) {\n const group: Pick<Group, 'id' | 'name' | 'type'> = await this.adminQueries.groupFromName(name)\n if (!group) {\n throw new HttpException('Group not found', HttpStatus.NOT_FOUND)\n }\n return { parentGroup: group, members: await this.adminQueries.browseGroupMembers(group.id, type) }\n }\n return { parentGroup: undefined, members: await this.adminQueries.browseRootGroupMembers(type) }\n }\n\n async getGroup(groupId: number): Promise<AdminGroup> {\n const group = await this.adminQueries.groupFromId(groupId)\n if (!group) {\n throw new HttpException('Group not found', HttpStatus.NOT_FOUND)\n }\n return group\n }\n\n async createGroup(createGroupDto: CreateOrUpdateGroupDto): Promise<AdminGroup> {\n if (!createGroupDto.name) {\n this.logger.error(`${this.createGroup.name} - missing group name : ${JSON.stringify(createGroupDto)}`)\n throw new HttpException('Group name is missing', HttpStatus.BAD_REQUEST)\n }\n await this.checkGroupNameExists(createGroupDto.name)\n try {\n const groupId: number = await this.adminQueries.createGroup(createGroupDto)\n this.logger.log(`${this.createGroup.name} - group (${groupId}) was created : ${JSON.stringify(createGroupDto)}`)\n return this.adminQueries.groupFromId(groupId)\n } catch (e) {\n this.logger.error(`${this.createGroup.name} - group was not created : ${JSON.stringify(createGroupDto)} : ${e}`)\n throw new HttpException('Unable to create group', HttpStatus.INTERNAL_SERVER_ERROR)\n }\n }\n\n async updateGroup(groupId: number, updateGroupDto: CreateOrUpdateGroupDto): Promise<AdminGroup> {\n if (updateGroupDto.name) {\n await this.checkGroupNameExists(updateGroupDto.name)\n }\n if (!(await this.adminQueries.updateGroup(groupId, updateGroupDto))) {\n throw new HttpException('Unable to update group', HttpStatus.INTERNAL_SERVER_ERROR)\n }\n return this.adminQueries.groupFromId(groupId)\n }\n\n async deleteGroup(groupId: number): Promise<void> {\n if (await this.adminQueries.deleteGroup(groupId)) {\n this.logger.log(`${this.deleteGroup.name} - group (${groupId}) was deleted`)\n } else {\n this.logger.warn(`${this.deleteGroup.name} - group (${groupId}) does not exist`)\n throw new HttpException('Unable to delete group', HttpStatus.BAD_REQUEST)\n }\n }\n\n async addUsersToGroup(groupId: number, userIds: number[]): Promise<void> {\n const group: AdminGroup = await this.adminQueries.groupFromId(groupId)\n if (!group) {\n throw new HttpException('Group not found', HttpStatus.NOT_FOUND)\n }\n try {\n await this.adminQueries.addUsersToGroup(groupId, userIds, group.type === GROUP_TYPE.USER ? USER_ROLE.USER : undefined)\n } catch (e) {\n throw new HttpException(e.message, HttpStatus.BAD_REQUEST)\n }\n }\n\n async updateUserFromGroup(groupId: number, userId: number, updateUserFromGroupDto: UpdateUserFromGroupDto): Promise<void> {\n try {\n await this.adminQueries.updateUserFromGroup(groupId, userId, updateUserFromGroupDto.role)\n } catch (e) {\n throw new HttpException(e.message, HttpStatus.BAD_REQUEST)\n }\n }\n\n async removeUserFromGroup(groupId: number, userId: number): Promise<void> {\n try {\n await this.adminQueries.removeUserFromGroup(groupId, userId)\n } catch (e) {\n throw new HttpException(e.message, HttpStatus.BAD_REQUEST)\n }\n }\n\n searchMembers(searchMembersDto: SearchMembersDto): Promise<Member[]> {\n return this.adminQueries.usersQueries.searchUsersOrGroups(searchMembersDto)\n }\n\n async impersonateUser(admin: UserModel, userId: number, adminPassword: UserPasswordDto, res: FastifyReply): Promise<LoginResponseDto> {\n // check admin password\n if (admin.id === userId) {\n throw new HttpException('You are already logged in', HttpStatus.BAD_REQUEST)\n }\n if (!(await this.adminQueries.usersQueries.compareUserPassword(admin.id, adminPassword.password))) {\n throw new HttpException('Bad password', HttpStatus.BAD_REQUEST)\n }\n const user: UserModel = this.checkUser(await this.adminQueries.usersQueries.from(userId))\n user.impersonatedFromId = admin.id\n user.impersonatedClientId = admin.clientId\n return this.authManager.setCookies(user, res)\n }\n\n async logoutImpersonateUser(user: UserModel, res: FastifyReply): Promise<LoginResponseDto> {\n if (!user.impersonatedFromId) {\n throw new HttpException('You are not allowed to do this action', HttpStatus.FORBIDDEN)\n }\n const admin: UserModel = this.checkUser(await this.adminQueries.usersQueries.from(user.impersonatedFromId))\n if (!admin.isAdmin) {\n throw new HttpException('You are not allowed to do this action', HttpStatus.FORBIDDEN)\n }\n admin.clientId = user.impersonatedClientId\n return this.authManager.setCookies(admin, res)\n }\n\n async deleteUserSpace(userLogin: string, isGuest = false): Promise<void> {\n const userSpace: string = UserModel.getHomePath(userLogin, isGuest)\n try {\n if (await isPathExists(userSpace)) {\n await removeFiles(userSpace)\n this.logger.log(`${this.deleteUserSpace.name} - user space *${userLogin}* was deleted`)\n } else {\n this.logger.warn(`${this.deleteUserSpace.name} - user space *${userLogin}* does not exist : ${userSpace}`)\n }\n } catch (e) {\n this.logger.warn(`${this.deleteUserSpace.name} - user space *${userLogin}* (${userSpace}) was not deleted : ${e}`)\n throw new HttpException('Unable to delete user space', HttpStatus.INTERNAL_SERVER_ERROR)\n }\n }\n\n checkUser(user: User | AdminUser | GuestUser, checkOnly: true): void\n checkUser(user: User | AdminUser | GuestUser, checkOnly?: false): UserModel\n checkUser(user: User | AdminUser | GuestUser, checkOnly = false): UserModel | void {\n if (!user) {\n throw new HttpException('User not found', HttpStatus.NOT_FOUND)\n }\n if (!checkOnly) {\n return new UserModel(user, true)\n }\n }\n\n private async renameUserSpace(oldLogin: string, newLogin: string): Promise<boolean> {\n const currentUserSpace: string = UserModel.getHomePath(oldLogin)\n if (!(await isPathExists(currentUserSpace))) {\n this.logger.warn(`${this.renameUserSpace.name} - user space *${oldLogin}* does not exist : ${currentUserSpace}`)\n return false\n }\n const newUserSpace: string = UserModel.getHomePath(newLogin)\n if (await isPathExists(newUserSpace)) {\n this.logger.warn(`${this.renameUserSpace.name} - user space *${newLogin}* already exists : ${newUserSpace}`)\n return false\n }\n try {\n await moveFiles(currentUserSpace, newUserSpace)\n return true\n } catch (e) {\n // try to restore\n await moveFiles(newUserSpace, currentUserSpace, true)\n this.logger.error(`${this.renameUserSpace.name} - unable to rename user space from *${currentUserSpace}* to *${newUserSpace}* : ${e}`)\n return false\n }\n }\n\n private async checkGroupNameExists(groupName: string): Promise<void> {\n if (await this.adminQueries.usersQueries.checkGroupNameExists(groupName)) {\n throw new HttpException('Name already used', HttpStatus.BAD_REQUEST)\n }\n }\n\n private async loginOrEmailAlreadyUsed(login: string, email: string) {\n const exists = await this.adminQueries.usersQueries.checkUserExists(login, email)\n if (exists) {\n throw new HttpException(`${exists.login === login ? 'Login' : 'Email'} already used`, HttpStatus.BAD_REQUEST)\n }\n }\n}\n"],"names":["AdminUsersManager","listUsers","adminQueries","getUser","userId","user","checkUser","getGuest","guestId","usersQueries","listGuests","createUserOrGuest","createUserDto","userRole","USER_ROLE","USER","asAdmin","loginOrEmailAlreadyUsed","login","email","password","hashPassword","UserModel","id","role","logger","log","name","JSON","stringify","anonymizePassword","makePaths","e","error","HttpException","HttpStatus","INTERNAL_SERVER_ERROR","updateUserOrGuest","updateUserDto","updateUser","updateUserGroups","add","delete","updateGuestManagers","k","v","Object","entries","checkUserExists","FORBIDDEN","renameUserSpace","isActive","passwordAttempts","currentGroups","groups","length","map","g","filter","indexOf","GUEST","currentManagers","managers","m","keys","forceRole","undefined","deleteUserOrGuest","userLogin","deleteUserDto","deleteUser","deleteSpace","deleteUserSpace","isGuest","deleteUserFromAdmin","admin","adminDeleteUserDto","compareUserPassword","adminPassword","BAD_REQUEST","userToDelete","from","createGuest","createGuestDto","push","updateGuest","updateGuestDto","deleteGuest","guest","browseGroups","type","GROUP_TYPE","group","groupFromName","NOT_FOUND","parentGroup","members","browseGroupMembers","browseRootGroupMembers","getGroup","groupId","groupFromId","createGroup","createGroupDto","checkGroupNameExists","updateGroup","updateGroupDto","deleteGroup","warn","addUsersToGroup","userIds","message","updateUserFromGroup","updateUserFromGroupDto","removeUserFromGroup","searchMembers","searchMembersDto","searchUsersOrGroups","impersonateUser","res","impersonatedFromId","impersonatedClientId","clientId","authManager","setCookies","logoutImpersonateUser","isAdmin","userSpace","getHomePath","isPathExists","removeFiles","checkOnly","oldLogin","newLogin","currentUserSpace","newUserSpace","moveFiles","groupName","exists","Logger"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../../backend/src/applications/users/services/admin-users-manager.service.ts"],"sourcesContent":["/*\n * Copyright (C) 2012-2025 Johan Legrand <johan.legrand@sync-in.com>\n * This file is part of Sync-in | The open source file sync and share solution\n * See the LICENSE file for licensing details\n */\n\nimport { HttpException, HttpStatus, Injectable, Logger } from '@nestjs/common'\nimport { FastifyReply } from 'fastify'\nimport { LoginResponseDto } from '../../../authentication/dto/login-response.dto'\nimport { AuthManager } from '../../../authentication/services/auth-manager.service'\nimport { anonymizePassword, hashPassword } from '../../../common/functions'\nimport { isPathExists, moveFiles, removeFiles } from '../../files/utils/files'\nimport { GROUP_TYPE } from '../constants/group'\nimport { USER_ROLE } from '../constants/user'\nimport type { CreateOrUpdateGroupDto } from '../dto/create-or-update-group.dto'\nimport type { CreateUserDto, UpdateUserDto, UpdateUserFromGroupDto } from '../dto/create-or-update-user.dto'\nimport type { DeleteUserDto } from '../dto/delete-user.dto'\nimport type { SearchMembersDto } from '../dto/search-members.dto'\nimport type { AdminGroup } from '../interfaces/admin-group.interface'\nimport type { AdminUser } from '../interfaces/admin-user.interface'\nimport type { GroupBrowse } from '../interfaces/group-browse.interface'\nimport type { GuestUser } from '../interfaces/guest-user.interface'\nimport type { Member } from '../interfaces/member.interface'\nimport { UserModel } from '../models/user.model'\nimport type { Group } from '../schemas/group.interface'\nimport type { User } from '../schemas/user.interface'\nimport { AdminUsersQueries } from './admin-users-queries.service'\n\n@Injectable()\nexport class AdminUsersManager {\n private readonly logger = new Logger(AdminUsersManager.name)\n\n constructor(\n private readonly authManager: AuthManager,\n private readonly adminQueries: AdminUsersQueries\n ) {}\n\n listUsers(): Promise<AdminUser[]> {\n return this.adminQueries.listUsers()\n }\n\n async getUser(userId: number): Promise<AdminUser> {\n const user: AdminUser = await this.adminQueries.listUsers(userId)\n this.checkUser(user, true)\n return user\n }\n\n async getGuest(guestId: number): Promise<GuestUser> {\n const user: GuestUser = await this.adminQueries.usersQueries.listGuests(guestId, 0, true)\n this.checkUser(user, true)\n return user\n }\n\n async createUserOrGuest(createUserDto: CreateUserDto, userRole: USER_ROLE.GUEST, asAdmin: boolean): Promise<GuestUser>\n async createUserOrGuest(createUserDto: CreateUserDto, userRole: USER_ROLE, asAdmin: true): Promise<AdminUser | GuestUser>\n async createUserOrGuest(createUserDto: CreateUserDto, userRole: USER_ROLE, asAdmin?: false): Promise<UserModel>\n async createUserOrGuest(\n createUserDto: CreateUserDto,\n userRole: USER_ROLE = USER_ROLE.USER,\n asAdmin = false\n ): Promise<UserModel | AdminUser | GuestUser> {\n await this.loginOrEmailAlreadyUsed(createUserDto.login, createUserDto.email)\n try {\n createUserDto.password = await hashPassword(createUserDto.password)\n const userId: number = await this.adminQueries.usersQueries.createUserOrGuest(createUserDto, userRole)\n const user = new UserModel({ ...createUserDto, id: userId, role: userRole })\n this.logger.log(\n `${this.createUserOrGuest.name} - ${USER_ROLE[userRole]} (${userId}) was created : ${JSON.stringify(anonymizePassword(createUserDto))}`\n )\n await user.makePaths()\n if (userRole <= USER_ROLE.USER) {\n return asAdmin ? this.getUser(user.id) : user\n } else {\n return asAdmin ? this.getGuest(user.id) : user\n }\n } catch (e) {\n this.logger.error(`${this.createUserOrGuest.name} - unable to create user *${createUserDto.login}* : ${e}`)\n throw new HttpException('Unable to create user', HttpStatus.INTERNAL_SERVER_ERROR)\n }\n }\n\n async updateUserOrGuest(userId: number, updateUserDto: UpdateUserDto): Promise<AdminUser>\n async updateUserOrGuest(userId: number, updateUserDto: UpdateUserDto, userRole: USER_ROLE.GUEST): Promise<GuestUser>\n async updateUserOrGuest(\n userId: number,\n updateUserDto: UpdateUserDto,\n userRole: USER_ROLE.USER | USER_ROLE.GUEST = USER_ROLE.USER\n ): Promise<AdminUser | GuestUser> {\n const user: AdminUser & GuestUser = userRole === USER_ROLE.USER ? await this.getUser(userId) : await this.getGuest(userId)\n const updateUser: Partial<User> = {}\n const updateUserGroups: { add: number[]; delete: number[] } = { add: [], delete: [] }\n const updateGuestManagers: { add: number[]; delete: number[] } = { add: [], delete: [] }\n for (const [k, v] of Object.entries(updateUserDto)) {\n switch (k as keyof UpdateUserDto) {\n case 'login':\n if (user.login === v) {\n break\n }\n if (await this.adminQueries.usersQueries.checkUserExists(v)) {\n throw new HttpException('Login already used', HttpStatus.FORBIDDEN)\n }\n if (!(await this.renameUserSpace(user.login, v))) {\n throw new HttpException('Unable to rename user space', HttpStatus.INTERNAL_SERVER_ERROR)\n }\n updateUser.login = v\n break\n case 'email':\n if (user.email === v) {\n break\n }\n if (await this.adminQueries.usersQueries.checkUserExists(null, v)) {\n throw new HttpException('Email already used', HttpStatus.FORBIDDEN)\n }\n updateUser.email = v\n break\n case 'isActive':\n updateUser.isActive = v\n if (v) {\n updateUser.passwordAttempts = 0\n }\n break\n case 'password':\n updateUser.password = await hashPassword(updateUserDto.password)\n break\n case 'groups':\n if (userRole === USER_ROLE.USER) {\n const currentGroups: number[] = user.groups?.length ? user.groups.map((g) => g.id) : []\n updateUserGroups.add = v.filter((id: number) => currentGroups.indexOf(id) === -1)\n updateUserGroups.delete = currentGroups.filter((id: number) => v.indexOf(id) === -1)\n }\n break\n case 'managers':\n if (userRole === USER_ROLE.GUEST) {\n const currentManagers: number[] = user.managers?.length ? user.managers.map((m) => m.id) : []\n updateGuestManagers.add = v.filter((id: number) => currentManagers.indexOf(id) === -1)\n updateGuestManagers.delete = currentManagers.filter((id: number) => v.indexOf(id) === -1)\n }\n break\n default:\n updateUser[k] = v\n }\n }\n if (Object.keys(updateUser).length) {\n // force the type for security reason\n const forceRole = userRole === USER_ROLE.GUEST ? USER_ROLE.GUEST : undefined\n if (!(await this.adminQueries.usersQueries.updateUserOrGuest(user.id, updateUser, forceRole))) {\n throw new HttpException('Unable to update user', HttpStatus.INTERNAL_SERVER_ERROR)\n }\n }\n if (userRole === USER_ROLE.USER) {\n if (updateUserGroups.add.length || updateUserGroups.delete.length) {\n try {\n await this.adminQueries.updateUserGroups(user.id, updateUserGroups)\n } catch {\n throw new HttpException('Unable to update user groups', HttpStatus.INTERNAL_SERVER_ERROR)\n }\n }\n return this.getUser(userId)\n } else {\n if (updateGuestManagers.add.length || updateGuestManagers.delete.length) {\n try {\n await this.adminQueries.updateGuestManagers(user.id, updateGuestManagers)\n } catch {\n throw new HttpException('Unable to update guest managers', HttpStatus.INTERNAL_SERVER_ERROR)\n }\n }\n return this.getGuest(userId)\n }\n }\n\n async deleteUserOrGuest(userId: number, userLogin: string, deleteUserDto: DeleteUserDto): Promise<void> {\n try {\n if (await this.adminQueries.deleteUser(userId, userLogin)) {\n this.logger.log(`${this.deleteUserOrGuest.name} - *${userLogin}* (${userId}) was deleted`)\n } else {\n this.logger.error(`${this.deleteUserOrGuest.name} - *${userLogin}* (${userId}) was not deleted : not found`)\n }\n if (deleteUserDto.deleteSpace) {\n await this.deleteUserSpace(userLogin, deleteUserDto.isGuest)\n }\n } catch (e) {\n this.logger.error(`${this.deleteUserOrGuest.name} - unable to delete *${userLogin}* (${userId}) : ${e}`)\n throw new HttpException('Unable to delete user', HttpStatus.INTERNAL_SERVER_ERROR)\n }\n }\n\n async deleteUserOrGuestFromAdmin(userId: number, deleteUserDto: DeleteUserDto): Promise<void> {\n const userToDelete: UserModel = this.checkUser(await this.adminQueries.usersQueries.from(userId))\n if (userToDelete.isGuest !== deleteUserDto.isGuest) {\n throw new HttpException('User mismatch', HttpStatus.BAD_REQUEST)\n }\n await this.deleteUserOrGuest(userToDelete.id, userToDelete.login, {\n deleteSpace: deleteUserDto.isGuest ? true : deleteUserDto.deleteSpace,\n isGuest: deleteUserDto.isGuest\n } satisfies DeleteUserDto)\n }\n\n listGuests(): Promise<AdminUser[]> {\n return this.adminQueries.usersQueries.listGuests(null, null, true)\n }\n\n createGuest(user: UserModel, createGuestDto: CreateUserDto): Promise<GuestUser> {\n if (!createGuestDto.managers.length) {\n createGuestDto.managers.push(user.id)\n }\n return this.createUserOrGuest(createGuestDto, USER_ROLE.GUEST, true)\n }\n\n updateGuest(guestId: number, updateGuestDto: UpdateUserDto): Promise<GuestUser> {\n if (!Object.keys(updateGuestDto).length) {\n throw new HttpException('No changes to update', HttpStatus.BAD_REQUEST)\n }\n if (updateGuestDto.managers && !updateGuestDto.managers.length) {\n throw new HttpException('Guest must have at least one manager', HttpStatus.BAD_REQUEST)\n }\n return this.updateUserOrGuest(guestId, updateGuestDto, USER_ROLE.GUEST)\n }\n\n async browseGroups(name?: string, type: GROUP_TYPE = GROUP_TYPE.USER): Promise<GroupBrowse> {\n if (name) {\n const group: Pick<Group, 'id' | 'name' | 'type'> = await this.adminQueries.groupFromName(name)\n if (!group) {\n throw new HttpException('Group not found', HttpStatus.NOT_FOUND)\n }\n return { parentGroup: group, members: await this.adminQueries.browseGroupMembers(group.id, type) }\n }\n return { parentGroup: undefined, members: await this.adminQueries.browseRootGroupMembers(type) }\n }\n\n async getGroup(groupId: number): Promise<AdminGroup> {\n const group = await this.adminQueries.groupFromId(groupId)\n if (!group) {\n throw new HttpException('Group not found', HttpStatus.NOT_FOUND)\n }\n return group\n }\n\n async createGroup(createGroupDto: CreateOrUpdateGroupDto): Promise<AdminGroup> {\n if (!createGroupDto.name) {\n this.logger.error(`${this.createGroup.name} - missing group name : ${JSON.stringify(createGroupDto)}`)\n throw new HttpException('Group name is missing', HttpStatus.BAD_REQUEST)\n }\n await this.checkGroupNameExists(createGroupDto.name)\n try {\n const groupId: number = await this.adminQueries.createGroup(createGroupDto)\n this.logger.log(`${this.createGroup.name} - group (${groupId}) was created : ${JSON.stringify(createGroupDto)}`)\n return this.adminQueries.groupFromId(groupId)\n } catch (e) {\n this.logger.error(`${this.createGroup.name} - group was not created : ${JSON.stringify(createGroupDto)} : ${e}`)\n throw new HttpException('Unable to create group', HttpStatus.INTERNAL_SERVER_ERROR)\n }\n }\n\n async updateGroup(groupId: number, updateGroupDto: CreateOrUpdateGroupDto): Promise<AdminGroup> {\n if (updateGroupDto.name) {\n await this.checkGroupNameExists(updateGroupDto.name)\n }\n if (!(await this.adminQueries.updateGroup(groupId, updateGroupDto))) {\n throw new HttpException('Unable to update group', HttpStatus.INTERNAL_SERVER_ERROR)\n }\n return this.adminQueries.groupFromId(groupId)\n }\n\n async deleteGroup(groupId: number): Promise<void> {\n if (await this.adminQueries.deleteGroup(groupId)) {\n this.logger.log(`${this.deleteGroup.name} - group (${groupId}) was deleted`)\n } else {\n this.logger.warn(`${this.deleteGroup.name} - group (${groupId}) does not exist`)\n throw new HttpException('Unable to delete group', HttpStatus.BAD_REQUEST)\n }\n }\n\n async addUsersToGroup(groupId: number, userIds: number[]): Promise<void> {\n const group: AdminGroup = await this.adminQueries.groupFromId(groupId)\n if (!group) {\n throw new HttpException('Group not found', HttpStatus.NOT_FOUND)\n }\n try {\n await this.adminQueries.addUsersToGroup(groupId, userIds, group.type === GROUP_TYPE.USER ? USER_ROLE.USER : undefined)\n } catch (e) {\n throw new HttpException(e.message, HttpStatus.BAD_REQUEST)\n }\n }\n\n async updateUserFromGroup(groupId: number, userId: number, updateUserFromGroupDto: UpdateUserFromGroupDto): Promise<void> {\n try {\n await this.adminQueries.updateUserFromGroup(groupId, userId, updateUserFromGroupDto.role)\n } catch (e) {\n throw new HttpException(e.message, HttpStatus.BAD_REQUEST)\n }\n }\n\n async removeUserFromGroup(groupId: number, userId: number): Promise<void> {\n try {\n await this.adminQueries.removeUserFromGroup(groupId, userId)\n } catch (e) {\n throw new HttpException(e.message, HttpStatus.BAD_REQUEST)\n }\n }\n\n searchMembers(searchMembersDto: SearchMembersDto): Promise<Member[]> {\n return this.adminQueries.usersQueries.searchUsersOrGroups(searchMembersDto)\n }\n\n async impersonateUser(admin: UserModel, userId: number, res: FastifyReply): Promise<LoginResponseDto> {\n if (admin.id === userId) {\n throw new HttpException('You are already logged in', HttpStatus.BAD_REQUEST)\n }\n const user: UserModel = this.checkUser(await this.adminQueries.usersQueries.from(userId))\n user.impersonatedFromId = admin.id\n user.impersonatedClientId = admin.clientId\n return this.authManager.setCookies(user, res)\n }\n\n async logoutImpersonateUser(user: UserModel, res: FastifyReply): Promise<LoginResponseDto> {\n if (!user.impersonatedFromId) {\n throw new HttpException('You are not allowed to do this action', HttpStatus.FORBIDDEN)\n }\n const admin: UserModel = this.checkUser(await this.adminQueries.usersQueries.from(user.impersonatedFromId))\n if (!admin.isAdmin) {\n throw new HttpException('You are not allowed to do this action', HttpStatus.FORBIDDEN)\n }\n admin.clientId = user.impersonatedClientId\n return this.authManager.setCookies(admin, res)\n }\n\n async deleteUserSpace(userLogin: string, isGuest = false): Promise<void> {\n const userSpace: string = UserModel.getHomePath(userLogin, isGuest)\n try {\n if (await isPathExists(userSpace)) {\n await removeFiles(userSpace)\n this.logger.log(`${this.deleteUserSpace.name} - user space *${userLogin}* was deleted`)\n } else {\n this.logger.warn(`${this.deleteUserSpace.name} - user space *${userLogin}* does not exist : ${userSpace}`)\n }\n } catch (e) {\n this.logger.warn(`${this.deleteUserSpace.name} - user space *${userLogin}* (${userSpace}) was not deleted : ${e}`)\n throw new HttpException('Unable to delete user space', HttpStatus.INTERNAL_SERVER_ERROR)\n }\n }\n\n checkUser(user: User | AdminUser | GuestUser, checkOnly: true): void\n checkUser(user: User | AdminUser | GuestUser, checkOnly?: false): UserModel\n checkUser(user: User | AdminUser | GuestUser, checkOnly = false): UserModel | void {\n if (!user) {\n throw new HttpException('User not found', HttpStatus.NOT_FOUND)\n }\n if (!checkOnly) {\n return new UserModel(user, true)\n }\n }\n\n private async renameUserSpace(oldLogin: string, newLogin: string): Promise<boolean> {\n const currentUserSpace: string = UserModel.getHomePath(oldLogin)\n if (!(await isPathExists(currentUserSpace))) {\n this.logger.warn(`${this.renameUserSpace.name} - user space *${oldLogin}* does not exist : ${currentUserSpace}`)\n return false\n }\n const newUserSpace: string = UserModel.getHomePath(newLogin)\n if (await isPathExists(newUserSpace)) {\n this.logger.warn(`${this.renameUserSpace.name} - user space *${newLogin}* already exists : ${newUserSpace}`)\n return false\n }\n try {\n await moveFiles(currentUserSpace, newUserSpace)\n return true\n } catch (e) {\n // try to restore\n await moveFiles(newUserSpace, currentUserSpace, true)\n this.logger.error(`${this.renameUserSpace.name} - unable to rename user space from *${currentUserSpace}* to *${newUserSpace}* : ${e}`)\n return false\n }\n }\n\n private async checkGroupNameExists(groupName: string): Promise<void> {\n if (await this.adminQueries.usersQueries.checkGroupNameExists(groupName)) {\n throw new HttpException('Name already used', HttpStatus.BAD_REQUEST)\n }\n }\n\n private async loginOrEmailAlreadyUsed(login: string, email: string) {\n const exists = await this.adminQueries.usersQueries.checkUserExists(login, email)\n if (exists) {\n throw new HttpException(`${exists.login === login ? 'Login' : 'Email'} already used`, HttpStatus.BAD_REQUEST)\n }\n }\n}\n"],"names":["AdminUsersManager","listUsers","adminQueries","getUser","userId","user","checkUser","getGuest","guestId","usersQueries","listGuests","createUserOrGuest","createUserDto","userRole","USER_ROLE","USER","asAdmin","loginOrEmailAlreadyUsed","login","email","password","hashPassword","UserModel","id","role","logger","log","name","JSON","stringify","anonymizePassword","makePaths","e","error","HttpException","HttpStatus","INTERNAL_SERVER_ERROR","updateUserOrGuest","updateUserDto","updateUser","updateUserGroups","add","delete","updateGuestManagers","k","v","Object","entries","checkUserExists","FORBIDDEN","renameUserSpace","isActive","passwordAttempts","currentGroups","groups","length","map","g","filter","indexOf","GUEST","currentManagers","managers","m","keys","forceRole","undefined","deleteUserOrGuest","userLogin","deleteUserDto","deleteUser","deleteSpace","deleteUserSpace","isGuest","deleteUserOrGuestFromAdmin","userToDelete","from","BAD_REQUEST","createGuest","createGuestDto","push","updateGuest","updateGuestDto","browseGroups","type","GROUP_TYPE","group","groupFromName","NOT_FOUND","parentGroup","members","browseGroupMembers","browseRootGroupMembers","getGroup","groupId","groupFromId","createGroup","createGroupDto","checkGroupNameExists","updateGroup","updateGroupDto","deleteGroup","warn","addUsersToGroup","userIds","message","updateUserFromGroup","updateUserFromGroupDto","removeUserFromGroup","searchMembers","searchMembersDto","searchUsersOrGroups","impersonateUser","admin","res","impersonatedFromId","impersonatedClientId","clientId","authManager","setCookies","logoutImpersonateUser","isAdmin","userSpace","getHomePath","isPathExists","removeFiles","checkOnly","oldLogin","newLogin","currentUserSpace","newUserSpace","moveFiles","groupName","exists","Logger"],"mappings":"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"}
@@ -455,25 +455,12 @@ describe(_adminusersmanagerservice.AdminUsersManager.name, ()=>{
455
455
  deleteSpace: false
456
456
  }));
457
457
  });
458
- it('deleteGuest -> getGuest then delete', async ()=>{
459
- setGuest({
460
- id: 77,
461
- login: 'g77'
462
- });
463
- adminQueriesMock.deleteUser.mockResolvedValueOnce(true);
464
- fs.isPathExists.mockResolvedValueOnce(false);
465
- await expect(service.deleteGuest(77)).resolves.toBeUndefined();
466
- expect(adminQueriesMock.deleteUser).toHaveBeenCalledWith(77, 'g77');
467
- });
468
458
  });
469
459
  describe('deleteUserFromAdmin', ()=>{
470
460
  it('admin password incorrect / deletion ok', async ()=>{
471
- const admin = new _usermodel.UserModel({
472
- id: 1
473
- }, true);
474
461
  adminQueriesMock.usersQueries.compareUserPassword.mockResolvedValueOnce(false);
475
- await expectHttp(service.deleteUserFromAdmin(admin, 10, {
476
- adminPassword: 'bad'
462
+ await expectHttp(service.deleteUserOrGuestFromAdmin(10, {
463
+ isGuest: false
477
464
  }));
478
465
  adminQueriesMock.usersQueries.compareUserPassword.mockResolvedValueOnce(true);
479
466
  adminQueriesMock.usersQueries.from.mockResolvedValueOnce({
@@ -481,8 +468,8 @@ describe(_adminusersmanagerservice.AdminUsersManager.name, ()=>{
481
468
  login: 'to-del'
482
469
  });
483
470
  adminQueriesMock.deleteUser.mockResolvedValueOnce(true);
484
- await service.deleteUserFromAdmin(admin, 10, {
485
- adminPassword: 'ok',
471
+ await service.deleteUserOrGuestFromAdmin(10, {
472
+ isGuest: false,
486
473
  deleteSpace: true
487
474
  });
488
475
  expect(adminQueriesMock.deleteUser).toHaveBeenCalledWith(10, 'to-del');
@@ -628,13 +615,9 @@ describe(_adminusersmanagerservice.AdminUsersManager.name, ()=>{
628
615
  const admin = new _usermodel.UserModel({
629
616
  id: 5
630
617
  }, true);
631
- await expectHttp(service.impersonateUser(admin, 5, {
632
- password: 'x'
633
- }, res));
618
+ await expectHttp(service.impersonateUser(admin, 5, res));
634
619
  adminQueriesMock.usersQueries.compareUserPassword.mockResolvedValueOnce(false);
635
- await expectHttp(service.impersonateUser(admin, 6, {
636
- password: 'bad'
637
- }, res));
620
+ await expectHttp(service.impersonateUser(admin, 6, res));
638
621
  const admin2 = new _usermodel.UserModel({
639
622
  id: 5,
640
623
  clientId: 'c1'
@@ -647,9 +630,7 @@ describe(_adminusersmanagerservice.AdminUsersManager.name, ()=>{
647
630
  authManagerMock.setCookies.mockResolvedValueOnce({
648
631
  accessToken: 't'
649
632
  });
650
- expect(await service.impersonateUser(admin2, 6, {
651
- password: 'ok'
652
- }, res)).toEqual({
633
+ expect(await service.impersonateUser(admin2, 6, res)).toEqual({
653
634
  accessToken: 't'
654
635
  });
655
636
  const notImpersonated = new _usermodel.UserModel({
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../backend/src/applications/users/services/admin-users-manager.service.spec.ts"],"sourcesContent":["/*\n * Copyright (C) 2012-2025 Johan Legrand <johan.legrand@sync-in.com>\n * This file is part of Sync-in | The open source file sync and share solution\n * See the LICENSE file for licensing details\n */\n\nimport { HttpException } from '@nestjs/common'\nimport { Test, TestingModule } from '@nestjs/testing'\nimport { AuthManager } from '../../../authentication/services/auth-manager.service'\nimport { GROUP_TYPE } from '../constants/group'\nimport { USER_GROUP_ROLE, USER_ROLE } from '../constants/user'\nimport type { CreateOrUpdateGroupDto } from '../dto/create-or-update-group.dto'\nimport { CreateUserDto, UpdateUserDto, UpdateUserFromGroupDto } from '../dto/create-or-update-user.dto'\nimport type { AdminDeleteUserDto } from '../dto/delete-user.dto'\nimport type { SearchMembersDto } from '../dto/search-members.dto'\nimport type { UserPasswordDto } from '../dto/user-password.dto'\nimport { UserModel } from '../models/user.model'\nimport { AdminUsersManager } from './admin-users-manager.service'\nimport { AdminUsersQueries } from './admin-users-queries.service'\n\n// mock file utils used by the service (delete/rename user space)\njest.mock('../../files/utils/files', () => ({\n isPathExists: jest.fn(),\n moveFiles: jest.fn(),\n removeFiles: jest.fn()\n}))\n\n// mock hash/anonymize utilities (preserve other module exports)\njest.mock('../../../common/functions', () => {\n const actual = jest.requireActual('../../../common/functions')\n return {\n ...actual,\n hashPassword: jest.fn(async (pwd: string) => `hashed:${pwd}`),\n anonymizePassword: jest.fn((dto: any) => ({ ...dto, password: '***' }))\n }\n})\n\n// Alias FS mocks (avoid repetitions)\nconst fs = jest.requireMock('../../files/utils/files') as { isPathExists: jest.Mock; moveFiles: jest.Mock; removeFiles: jest.Mock }\n\n// Helper utilities\nconst expectHttp = async (p: Promise<any>) => expect(p).rejects.toBeInstanceOf(HttpException)\nconst spyMakePaths = () => jest.spyOn(UserModel.prototype, 'makePaths').mockResolvedValueOnce(undefined)\n\ndescribe(AdminUsersManager.name, () => {\n let service: AdminUsersManager\n\n // deep mocks\n let authManagerMock: { setCookies: jest.Mock }\n let adminQueriesMock: {\n listUsers: jest.Mock\n usersQueries: {\n listGuests: jest.Mock\n from: jest.Mock\n createUserOrGuest: jest.Mock\n updateUserOrGuest: jest.Mock\n deleteUser: jest.Mock\n compareUserPassword: jest.Mock\n checkGroupNameExists: jest.Mock\n checkUserExists: jest.Mock\n searchUsersOrGroups: jest.Mock\n }\n updateUserGroups: jest.Mock\n updateGuestManagers: jest.Mock\n deleteUser: jest.Mock\n groupFromName: jest.Mock\n browseGroupMembers: jest.Mock\n browseRootGroupMembers: jest.Mock\n groupFromId: jest.Mock\n createGroup: jest.Mock\n updateGroup: jest.Mock\n deleteGroup: jest.Mock\n addUsersToGroup: jest.Mock\n updateUserFromGroup: jest.Mock\n removeUserFromGroup: jest.Mock\n }\n\n const setUser = (u: any) => adminQueriesMock.listUsers.mockResolvedValueOnce(u)\n const setGuest = (g: any) => adminQueriesMock.usersQueries.listGuests.mockResolvedValueOnce(g)\n\n const baseUser = {\n id: 10,\n login: 'john',\n email: 'john@example.com',\n isActive: true,\n role: USER_ROLE.USER,\n groups: [{ id: 1 }, { id: 3 }]\n } as any\n\n beforeAll(async () => {\n authManagerMock = { setCookies: jest.fn() }\n\n adminQueriesMock = {\n listUsers: jest.fn(),\n usersQueries: {\n listGuests: jest.fn(),\n from: jest.fn(),\n createUserOrGuest: jest.fn(),\n updateUserOrGuest: jest.fn(),\n deleteUser: jest.fn(),\n compareUserPassword: jest.fn(),\n checkGroupNameExists: jest.fn(),\n checkUserExists: jest.fn(),\n searchUsersOrGroups: jest.fn()\n },\n updateUserGroups: jest.fn(),\n updateGuestManagers: jest.fn(),\n deleteUser: jest.fn(),\n groupFromName: jest.fn(),\n browseGroupMembers: jest.fn(),\n browseRootGroupMembers: jest.fn(),\n groupFromId: jest.fn(),\n createGroup: jest.fn(),\n updateGroup: jest.fn(),\n deleteGroup: jest.fn(),\n addUsersToGroup: jest.fn(),\n updateUserFromGroup: jest.fn(),\n removeUserFromGroup: jest.fn()\n }\n\n const module: TestingModule = await Test.createTestingModule({\n providers: [AdminUsersManager, { provide: AuthManager, useValue: authManagerMock }, { provide: AdminUsersQueries, useValue: adminQueriesMock }]\n }).compile()\n\n module.useLogger(['fatal'])\n service = module.get<AdminUsersManager>(AdminUsersManager)\n })\n\n beforeEach(() => {\n jest.clearAllMocks()\n })\n\n it('should be defined', () => {\n expect(service).toBeDefined()\n })\n\n describe('getUser / getGuest', () => {\n it('user ok + not found + guest ok', async () => {\n setUser(baseUser)\n expect(await service.getUser(10)).toEqual(baseUser)\n expect(adminQueriesMock.listUsers).toHaveBeenCalledWith(10)\n\n setUser(null)\n await expectHttp(service.getUser(999))\n\n const guest = { id: 22, login: 'guest', email: 'g@x', managers: [], role: USER_ROLE.GUEST }\n setGuest(guest as any)\n expect(await service.getGuest(22)).toEqual(guest)\n expect(adminQueriesMock.usersQueries.listGuests).toHaveBeenCalledWith(22, 0, true)\n })\n })\n\n describe('createUserOrGuest', () => {\n it.each([\n { role: USER_ROLE.USER, asAdmin: false, id: 101, exp: 'UserModel' },\n { role: USER_ROLE.GUEST, asAdmin: true, id: 202, exp: 'AdminGuest' },\n { role: USER_ROLE.USER, asAdmin: true, id: 707, exp: 'AdminUser' },\n { role: USER_ROLE.GUEST, asAdmin: false, id: 808, exp: 'UserModel' }\n ])('creation matrix ($role / asAdmin=$asAdmin)', async ({ role, asAdmin, id, exp }) => {\n const dto: CreateUserDto = { login: 'alice', email: 'a@x', password: 'pwd', managers: role === USER_ROLE.GUEST ? [1] : [] } as any\n adminQueriesMock.usersQueries.checkUserExists.mockResolvedValueOnce(false)\n adminQueriesMock.usersQueries.createUserOrGuest.mockResolvedValueOnce(id)\n spyMakePaths()\n\n if (exp === 'AdminUser') setUser({ id, login: 'alice', role })\n if (exp === 'AdminGuest') setGuest({ id, login: 'alice', role } as any)\n\n const res = await (service as any).createUserOrGuest(dto, role, asAdmin)\n\n if (exp === 'UserModel') {\n expect(res).toBeInstanceOf(UserModel)\n expect((res as any).id).toBe(id)\n } else if (exp === 'AdminUser') {\n expect(adminQueriesMock.listUsers).toHaveBeenCalledWith(id)\n } else {\n expect(adminQueriesMock.usersQueries.listGuests).toHaveBeenCalledWith(id, 0, true)\n }\n expect(adminQueriesMock.usersQueries.createUserOrGuest).toHaveBeenCalledWith(\n expect.objectContaining({ login: 'alice', email: 'a@x', password: 'hashed:pwd' }),\n role\n )\n })\n\n it('creation errors: duplication and DB error', async () => {\n adminQueriesMock.usersQueries.checkUserExists.mockResolvedValueOnce({ login: 'dup', email: 'dup@x' })\n await expectHttp(service.createUserOrGuest({ login: 'dup', email: 'dup@x', password: 'p', managers: [] } as any, USER_ROLE.USER, false))\n\n adminQueriesMock.usersQueries.checkUserExists.mockResolvedValueOnce(false)\n adminQueriesMock.usersQueries.createUserOrGuest.mockRejectedValueOnce(new Error('db fail'))\n await expectHttp(service.createUserOrGuest({ login: 'bob', email: 'b@x', password: 'p', managers: [] } as any, USER_ROLE.USER, false))\n })\n })\n\n describe('updateUserOrGuest - USER branch', () => {\n it('full update + FS rename + groups diff', async () => {\n const current = { ...baseUser, groups: [{ id: 1 }, { id: 3 }] }\n setUser(current)\n const updated = { ...current, login: 'johnny', email: 'j@new' }\n setUser(updated)\n\n adminQueriesMock.usersQueries.checkUserExists.mockResolvedValueOnce(false)\n adminQueriesMock.usersQueries.checkUserExists.mockResolvedValueOnce(false)\n fs.isPathExists.mockResolvedValueOnce(true)\n fs.isPathExists.mockResolvedValueOnce(false)\n fs.moveFiles.mockResolvedValueOnce(undefined)\n adminQueriesMock.usersQueries.updateUserOrGuest.mockResolvedValueOnce(true)\n adminQueriesMock.updateUserGroups.mockResolvedValueOnce(undefined)\n\n const dto: UpdateUserDto = { login: 'johnny', email: 'j@new', isActive: true, password: 'newpwd', groups: [3, 5] }\n const res = await service.updateUserOrGuest(current.id, dto)\n\n expect(adminQueriesMock.usersQueries.updateUserOrGuest).toHaveBeenCalledWith(\n current.id,\n expect.objectContaining({ login: 'johnny', email: 'j@new', isActive: true, passwordAttempts: 0, password: 'hashed:newpwd' }),\n undefined\n )\n expect(adminQueriesMock.updateUserGroups).toHaveBeenCalledWith(current.id, { add: [5], delete: [1] })\n expect(res).toEqual(updated)\n })\n\n it('login/email conflict', async () => {\n const current = { ...baseUser }\n setUser(current)\n adminQueriesMock.usersQueries.checkUserExists.mockResolvedValueOnce(true)\n await expectHttp(service.updateUserOrGuest(current.id, { login: 'taken' } as any))\n\n setUser(current)\n adminQueriesMock.usersQueries.checkUserExists.mockResolvedValueOnce(true)\n await expectHttp(service.updateUserOrGuest(current.id, { email: 'dup@x' } as any))\n expect(adminQueriesMock.usersQueries.updateUserOrGuest).not.toHaveBeenCalled()\n })\n\n it('renameUserSpace impossible (new space exists)', async () => {\n const current = { ...baseUser }\n setUser(current)\n adminQueriesMock.usersQueries.checkUserExists.mockResolvedValueOnce(false)\n fs.isPathExists.mockResolvedValueOnce(true) // current\n fs.isPathExists.mockResolvedValueOnce(true) // new already exists\n fs.moveFiles.mockResolvedValue(undefined)\n await expectHttp(service.updateUserOrGuest(current.id, { login: 'new' } as any))\n })\n\n it('DB update false => INTERNAL_SERVER_ERROR', async () => {\n const current = { ...baseUser }\n setUser(current)\n adminQueriesMock.usersQueries.updateUserOrGuest.mockResolvedValueOnce(false)\n await expectHttp(service.updateUserOrGuest(current.id, { email: 'e@x' } as any))\n })\n\n it('updateUserGroups fails', async () => {\n const current = { ...baseUser, groups: [{ id: 1 }] }\n setUser(current)\n adminQueriesMock.usersQueries.updateUserOrGuest.mockResolvedValueOnce(true)\n adminQueriesMock.updateUserGroups.mockRejectedValueOnce(new Error('group error'))\n await expectHttp(service.updateUserOrGuest(current.id, { groups: [2] } as any))\n })\n\n it('no change when login or email unchanged', async () => {\n const current = { ...baseUser }\n setUser(current)\n setUser(current)\n expect(await service.updateUserOrGuest(current.id, { login: current.login } as any)).toEqual(current)\n expect(adminQueriesMock.usersQueries.checkUserExists).not.toHaveBeenCalled()\n\n setUser(current)\n setUser(current)\n expect(await service.updateUserOrGuest(current.id, { email: current.email } as any)).toEqual(current)\n expect(adminQueriesMock.usersQueries.updateUserOrGuest).not.toHaveBeenCalled()\n })\n\n it('default branch (unknown field)', async () => {\n const current = { ...baseUser }\n setUser(current)\n adminQueriesMock.usersQueries.updateUserOrGuest.mockResolvedValueOnce(true)\n const updated = { ...current, language: 'fr' } as any\n setUser(updated)\n\n const res = await service.updateUserOrGuest(current.id, { language: 'fr' } as any)\n expect(adminQueriesMock.usersQueries.updateUserOrGuest).toHaveBeenCalledWith(current.id, expect.objectContaining({ language: 'fr' }), undefined)\n expect(res).toEqual(updated)\n })\n })\n\n describe('updateUserOrGuest - GUEST branch', () => {\n it('update guest + managers diff', async () => {\n const guest = { id: 33, login: 'g', email: 'g@x', managers: [{ id: 2 }, { id: 7 }], role: USER_ROLE.GUEST }\n setGuest(guest as any)\n const updatedGuest = { ...guest, email: 'new@x' }\n setGuest(updatedGuest as any)\n\n adminQueriesMock.usersQueries.updateUserOrGuest.mockResolvedValueOnce(true)\n adminQueriesMock.updateGuestManagers.mockResolvedValueOnce(undefined)\n\n const res = await service.updateUserOrGuest(guest.id, { email: 'new@x', managers: [7, 9] } as UpdateUserDto, USER_ROLE.GUEST)\n expect(adminQueriesMock.usersQueries.updateUserOrGuest).toHaveBeenCalledWith(guest.id, { email: 'new@x' }, USER_ROLE.GUEST)\n expect(adminQueriesMock.updateGuestManagers).toHaveBeenCalledWith(guest.id, { add: [9], delete: [2] })\n expect(res).toEqual(updatedGuest)\n })\n\n it('validations updateGuest', async () => {\n expect(() => service.updateGuest(1, {} as any)).toThrow(/no changes to update/i)\n expect(() => service.updateGuest(1, { managers: [] } as any)).toThrow(/guest must have at least one manager/i)\n })\n\n it('updateGuestManagers échoue', async () => {\n const guest = { id: 33, login: 'g', email: 'g@x', managers: [{ id: 2 }], role: USER_ROLE.GUEST }\n setGuest(guest as any)\n adminQueriesMock.usersQueries.updateUserOrGuest.mockResolvedValueOnce(true)\n adminQueriesMock.updateGuestManagers.mockRejectedValueOnce(new Error('mgr error'))\n await expectHttp(service.updateUserOrGuest(guest.id, { managers: [3] } as any, USER_ROLE.GUEST))\n })\n })\n\n describe('deleteUserOrGuest / deleteGuest', () => {\n it('delete user + optional space and errors', async () => {\n adminQueriesMock.deleteUser.mockResolvedValueOnce(true)\n fs.isPathExists.mockResolvedValueOnce(true)\n fs.removeFiles.mockResolvedValueOnce(undefined)\n await expect(service.deleteUserOrGuest(10, 'john', { deleteSpace: true, isGuest: false })).resolves.toBeUndefined()\n expect(adminQueriesMock.deleteUser).toHaveBeenCalledWith(10, 'john')\n expect(fs.isPathExists).toHaveBeenCalled()\n expect(fs.removeFiles).toHaveBeenCalled()\n\n adminQueriesMock.deleteUser.mockRejectedValueOnce(new Error('db crash'))\n await expectHttp(service.deleteUserOrGuest(10, 'john', { deleteSpace: false } as any))\n })\n\n it('deleteGuest -> getGuest then delete', async () => {\n setGuest({ id: 77, login: 'g77' } as any)\n adminQueriesMock.deleteUser.mockResolvedValueOnce(true)\n fs.isPathExists.mockResolvedValueOnce(false)\n await expect(service.deleteGuest(77)).resolves.toBeUndefined()\n expect(adminQueriesMock.deleteUser).toHaveBeenCalledWith(77, 'g77')\n })\n })\n\n describe('deleteUserFromAdmin', () => {\n it('admin password incorrect / deletion ok', async () => {\n const admin = new UserModel({ id: 1 } as any, true)\n adminQueriesMock.usersQueries.compareUserPassword.mockResolvedValueOnce(false)\n await expectHttp(service.deleteUserFromAdmin(admin, 10, { adminPassword: 'bad' } as AdminDeleteUserDto))\n\n adminQueriesMock.usersQueries.compareUserPassword.mockResolvedValueOnce(true)\n adminQueriesMock.usersQueries.from.mockResolvedValueOnce({ id: 10, login: 'to-del' } as any)\n adminQueriesMock.deleteUser.mockResolvedValueOnce(true)\n await service.deleteUserFromAdmin(admin, 10, { adminPassword: 'ok', deleteSpace: true } as any)\n expect(adminQueriesMock.deleteUser).toHaveBeenCalledWith(10, 'to-del')\n })\n })\n\n describe('groups', () => {\n it('browseGroups with/without name + NOT_FOUND', async () => {\n adminQueriesMock.groupFromName.mockResolvedValueOnce({ id: 5, name: 'dev', type: GROUP_TYPE.USER })\n adminQueriesMock.browseGroupMembers.mockResolvedValueOnce([{ id: 1 }, { id: 2 }])\n const withName = await service.browseGroups('dev', GROUP_TYPE.USER)\n expect(withName.parentGroup).toEqual({ id: 5, name: 'dev', type: GROUP_TYPE.USER })\n expect(withName.members).toHaveLength(2)\n\n adminQueriesMock.browseRootGroupMembers.mockResolvedValueOnce([{ id: 3 }])\n const root = await service.browseGroups(undefined, GROUP_TYPE.USER)\n expect(root.parentGroup).toBeUndefined()\n expect(root.members).toEqual([{ id: 3 }])\n\n adminQueriesMock.groupFromName.mockResolvedValueOnce(null)\n await expectHttp(service.browseGroups('unknown'))\n })\n\n it('getGroup OK / NOT_FOUND', async () => {\n adminQueriesMock.groupFromId.mockResolvedValueOnce({ id: 9 })\n expect(await service.getGroup(9)).toEqual({ id: 9 })\n adminQueriesMock.groupFromId.mockResolvedValueOnce(null)\n await expectHttp(service.getGroup(999))\n })\n\n it('createGroup OK + validations + creation error', async () => {\n const dto: CreateOrUpdateGroupDto = { name: 'team', type: GROUP_TYPE.USER } as any\n adminQueriesMock.usersQueries.checkGroupNameExists.mockResolvedValueOnce(false)\n adminQueriesMock.createGroup.mockResolvedValueOnce(123)\n adminQueriesMock.groupFromId.mockResolvedValueOnce({ id: 123, name: 'team' })\n expect(await service.createGroup(dto)).toEqual({ id: 123, name: 'team' })\n\n await expectHttp(service.createGroup({} as any))\n\n adminQueriesMock.usersQueries.checkGroupNameExists.mockResolvedValueOnce(true)\n await expectHttp(service.createGroup(dto))\n expect(adminQueriesMock.createGroup).toHaveBeenCalledTimes(1) // only the first one OK\n\n adminQueriesMock.usersQueries.checkGroupNameExists.mockResolvedValueOnce(false)\n adminQueriesMock.createGroup.mockRejectedValueOnce(new Error('db err'))\n await expectHttp(service.createGroup(dto))\n })\n\n it('updateGroup success / failure', async () => {\n adminQueriesMock.usersQueries.checkGroupNameExists.mockResolvedValueOnce(false)\n adminQueriesMock.updateGroup.mockResolvedValueOnce(true)\n adminQueriesMock.groupFromId.mockResolvedValueOnce({ id: 5, name: 'new' })\n expect(await service.updateGroup(5, { name: 'new' } as any)).toEqual({ id: 5, name: 'new' })\n\n adminQueriesMock.updateGroup.mockResolvedValueOnce(false)\n await expectHttp(service.updateGroup(5, {} as any))\n })\n\n it('deleteGroup success / fail', async () => {\n adminQueriesMock.deleteGroup.mockResolvedValueOnce(true)\n await expect(service.deleteGroup(5)).resolves.toBeUndefined()\n adminQueriesMock.deleteGroup.mockResolvedValueOnce(false)\n await expectHttp(service.deleteGroup(6))\n })\n\n it('addUsersToGroup: NOT_FOUND + error', async () => {\n adminQueriesMock.groupFromId.mockResolvedValueOnce(null)\n await expectHttp(service.addUsersToGroup(1, [2, 3]))\n\n adminQueriesMock.groupFromId.mockResolvedValueOnce({ id: 1, type: GROUP_TYPE.USER })\n adminQueriesMock.addUsersToGroup.mockRejectedValueOnce(new Error('bad users'))\n await expectHttp(service.addUsersToGroup(1, [2]))\n })\n\n it('updateUserFromGroup / removeUserFromGroup BAD_REQUEST errors', async () => {\n adminQueriesMock.updateUserFromGroup.mockRejectedValueOnce(new Error('bad role'))\n await expectHttp(service.updateUserFromGroup(1, 2, { role: USER_GROUP_ROLE.MEMBER } as UpdateUserFromGroupDto))\n\n adminQueriesMock.removeUserFromGroup.mockRejectedValueOnce(new Error('not member'))\n await expectHttp(service.removeUserFromGroup(1, 2))\n })\n })\n\n describe('searchMembers', () => {\n it('forwards to usersQueries.searchUsersOrGroups', async () => {\n const dto = { search: 'jo' } as SearchMembersDto\n adminQueriesMock.usersQueries.searchUsersOrGroups.mockResolvedValueOnce([{ id: 1 }])\n expect(await service.searchMembers(dto)).toEqual([{ id: 1 }])\n expect(adminQueriesMock.usersQueries.searchUsersOrGroups).toHaveBeenCalledWith(dto)\n })\n })\n\n describe('impersonation', () => {\n const res: any = {}\n it('self / bad password / ok + logout (guard + non-admin + admin)', async () => {\n const admin = new UserModel({ id: 5 } as any, true)\n await expectHttp(service.impersonateUser(admin, 5, { password: 'x' } as UserPasswordDto, res))\n\n adminQueriesMock.usersQueries.compareUserPassword.mockResolvedValueOnce(false)\n await expectHttp(service.impersonateUser(admin, 6, { password: 'bad' } as any, res))\n\n const admin2 = new UserModel({ id: 5, clientId: 'c1' } as any, true)\n adminQueriesMock.usersQueries.compareUserPassword.mockResolvedValueOnce(true)\n adminQueriesMock.usersQueries.from.mockResolvedValueOnce({ id: 6, login: 'user' } as any)\n authManagerMock.setCookies.mockResolvedValueOnce({ accessToken: 't' })\n expect(await service.impersonateUser(admin2, 6, { password: 'ok' } as any, res)).toEqual({ accessToken: 't' })\n\n const notImpersonated = new UserModel({ id: 1 } as any, true)\n await expectHttp(service.logoutImpersonateUser(notImpersonated, res))\n\n const impersonated = new UserModel({ id: 2, impersonatedFromId: 9, impersonatedClientId: 'X' } as any, true)\n adminQueriesMock.usersQueries.from.mockResolvedValueOnce({ id: 9, role: USER_ROLE.USER } as any)\n await expectHttp(service.logoutImpersonateUser(impersonated, res))\n\n adminQueriesMock.usersQueries.from.mockResolvedValueOnce({ id: 9, role: USER_ROLE.ADMINISTRATOR } as any)\n authManagerMock.setCookies.mockResolvedValueOnce({ accessToken: 'admin' })\n expect(await service.logoutImpersonateUser(impersonated, res)).toEqual({ accessToken: 'admin' })\n })\n })\n\n describe('listing', () => {\n it('forwards listUsers and listGuests', async () => {\n const users = [{ id: 1 }]\n adminQueriesMock.listUsers.mockResolvedValueOnce(users as any)\n expect(await service.listUsers()).toEqual(users)\n expect(adminQueriesMock.listUsers).toHaveBeenCalledWith()\n\n const guests = [{ id: 2 }]\n adminQueriesMock.usersQueries.listGuests.mockResolvedValueOnce(guests as any)\n expect(await service.listGuests()).toEqual(guests)\n expect(adminQueriesMock.usersQueries.listGuests).toHaveBeenCalledWith(null, null, true)\n })\n })\n\n describe('createGuest', () => {\n it('adds the creator as default manager and returns admin guest', async () => {\n const creator = new UserModel({ id: 88 } as any, true)\n const dto: CreateUserDto = { login: 'gg', email: 'g@x', password: 'pwd', managers: [] } as any\n adminQueriesMock.usersQueries.checkUserExists.mockResolvedValueOnce(false)\n adminQueriesMock.usersQueries.createUserOrGuest.mockResolvedValueOnce(505)\n spyMakePaths()\n const expectedGuest = { id: 505, login: 'gg', role: USER_ROLE.GUEST }\n setGuest(expectedGuest as any)\n\n expect(await service.createGuest(creator, dto)).toEqual(expectedGuest)\n expect(adminQueriesMock.usersQueries.createUserOrGuest).toHaveBeenCalledWith(\n expect.objectContaining({ login: 'gg', email: 'g@x', managers: [88] }),\n USER_ROLE.GUEST\n )\n })\n })\n\n describe('updateGuest wrapper', () => {\n it('updateGuest() -> success', async () => {\n const guest = { id: 33, login: 'g', email: 'g@x', managers: [{ id: 2 }], role: USER_ROLE.GUEST }\n const updatedGuest = { ...guest, email: 'new@x' }\n setGuest(guest as any)\n adminQueriesMock.usersQueries.updateUserOrGuest.mockResolvedValueOnce(true)\n setGuest(updatedGuest as any)\n expect(await service.updateGuest(guest.id, { email: 'new@x' } as any)).toEqual(updatedGuest)\n })\n })\n\n describe('deleteUserSpace', () => {\n it('space not existing / removeFiles failure', async () => {\n fs.isPathExists.mockResolvedValueOnce(false)\n await expect(service.deleteUserSpace('nobody')).resolves.toBeUndefined()\n\n fs.isPathExists.mockResolvedValueOnce(true)\n fs.removeFiles.mockRejectedValueOnce(new Error('fs error'))\n await expectHttp(service.deleteUserSpace('bob'))\n })\n })\n\n describe('renameUserSpace error handling', () => {\n it('moveFiles throws then restore', async () => {\n const current = { ...baseUser }\n setUser(current)\n adminQueriesMock.usersQueries.checkUserExists.mockResolvedValueOnce(false)\n fs.isPathExists.mockResolvedValueOnce(true)\n fs.isPathExists.mockResolvedValueOnce(false)\n fs.moveFiles.mockRejectedValueOnce(new Error('io error'))\n fs.moveFiles.mockResolvedValueOnce(undefined)\n await expectHttp(service.updateUserOrGuest(current.id, { login: 'new-login' } as any))\n expect(fs.moveFiles).toHaveBeenCalledTimes(2)\n })\n\n it('current space missing -> early return', async () => {\n const current = { ...baseUser }\n setUser(current)\n adminQueriesMock.usersQueries.checkUserExists.mockResolvedValueOnce(false)\n fs.isPathExists.mockResolvedValueOnce(false)\n await expectHttp(service.updateUserOrGuest(current.id, { login: 'new-login' } as any))\n expect(fs.moveFiles).not.toHaveBeenCalled()\n })\n })\n})\n"],"names":["jest","mock","isPathExists","fn","moveFiles","removeFiles","actual","requireActual","hashPassword","pwd","anonymizePassword","dto","password","fs","requireMock","expectHttp","p","expect","rejects","toBeInstanceOf","HttpException","spyMakePaths","spyOn","UserModel","prototype","mockResolvedValueOnce","undefined","describe","AdminUsersManager","name","service","authManagerMock","adminQueriesMock","setUser","u","listUsers","setGuest","g","usersQueries","listGuests","baseUser","id","login","email","isActive","role","USER_ROLE","USER","groups","beforeAll","setCookies","from","createUserOrGuest","updateUserOrGuest","deleteUser","compareUserPassword","checkGroupNameExists","checkUserExists","searchUsersOrGroups","updateUserGroups","updateGuestManagers","groupFromName","browseGroupMembers","browseRootGroupMembers","groupFromId","createGroup","updateGroup","deleteGroup","addUsersToGroup","updateUserFromGroup","removeUserFromGroup","module","Test","createTestingModule","providers","provide","AuthManager","useValue","AdminUsersQueries","compile","useLogger","get","beforeEach","clearAllMocks","it","toBeDefined","getUser","toEqual","toHaveBeenCalledWith","guest","managers","GUEST","getGuest","each","asAdmin","exp","res","toBe","objectContaining","mockRejectedValueOnce","Error","current","updated","passwordAttempts","add","delete","not","toHaveBeenCalled","mockResolvedValue","language","updatedGuest","updateGuest","toThrow","deleteUserOrGuest","deleteSpace","isGuest","resolves","toBeUndefined","deleteGuest","admin","deleteUserFromAdmin","adminPassword","type","GROUP_TYPE","withName","browseGroups","parentGroup","members","toHaveLength","root","getGroup","toHaveBeenCalledTimes","USER_GROUP_ROLE","MEMBER","search","searchMembers","impersonateUser","admin2","clientId","accessToken","notImpersonated","logoutImpersonateUser","impersonated","impersonatedFromId","impersonatedClientId","ADMINISTRATOR","users","guests","creator","expectedGuest","createGuest","deleteUserSpace"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../../backend/src/applications/users/services/admin-users-manager.service.spec.ts"],"sourcesContent":["/*\n * Copyright (C) 2012-2025 Johan Legrand <johan.legrand@sync-in.com>\n * This file is part of Sync-in | The open source file sync and share solution\n * See the LICENSE file for licensing details\n */\n\nimport { HttpException } from '@nestjs/common'\nimport { Test, TestingModule } from '@nestjs/testing'\nimport { AuthManager } from '../../../authentication/services/auth-manager.service'\nimport { GROUP_TYPE } from '../constants/group'\nimport { USER_GROUP_ROLE, USER_ROLE } from '../constants/user'\nimport type { CreateOrUpdateGroupDto } from '../dto/create-or-update-group.dto'\nimport type { CreateUserDto, UpdateUserDto, UpdateUserFromGroupDto } from '../dto/create-or-update-user.dto'\nimport type { DeleteUserDto } from '../dto/delete-user.dto'\nimport type { SearchMembersDto } from '../dto/search-members.dto'\nimport { UserModel } from '../models/user.model'\nimport { AdminUsersManager } from './admin-users-manager.service'\nimport { AdminUsersQueries } from './admin-users-queries.service'\n\n// mock file utils used by the service (delete/rename user space)\njest.mock('../../files/utils/files', () => ({\n isPathExists: jest.fn(),\n moveFiles: jest.fn(),\n removeFiles: jest.fn()\n}))\n\n// mock hash/anonymize utilities (preserve other module exports)\njest.mock('../../../common/functions', () => {\n const actual = jest.requireActual('../../../common/functions')\n return {\n ...actual,\n hashPassword: jest.fn(async (pwd: string) => `hashed:${pwd}`),\n anonymizePassword: jest.fn((dto: any) => ({ ...dto, password: '***' }))\n }\n})\n\n// Alias FS mocks (avoid repetitions)\nconst fs = jest.requireMock('../../files/utils/files') as { isPathExists: jest.Mock; moveFiles: jest.Mock; removeFiles: jest.Mock }\n\n// Helper utilities\nconst expectHttp = async (p: Promise<any>) => expect(p).rejects.toBeInstanceOf(HttpException)\nconst spyMakePaths = () => jest.spyOn(UserModel.prototype, 'makePaths').mockResolvedValueOnce(undefined)\n\ndescribe(AdminUsersManager.name, () => {\n let service: AdminUsersManager\n\n // deep mocks\n let authManagerMock: { setCookies: jest.Mock }\n let adminQueriesMock: {\n listUsers: jest.Mock\n usersQueries: {\n listGuests: jest.Mock\n from: jest.Mock\n createUserOrGuest: jest.Mock\n updateUserOrGuest: jest.Mock\n deleteUser: jest.Mock\n compareUserPassword: jest.Mock\n checkGroupNameExists: jest.Mock\n checkUserExists: jest.Mock\n searchUsersOrGroups: jest.Mock\n }\n updateUserGroups: jest.Mock\n updateGuestManagers: jest.Mock\n deleteUser: jest.Mock\n groupFromName: jest.Mock\n browseGroupMembers: jest.Mock\n browseRootGroupMembers: jest.Mock\n groupFromId: jest.Mock\n createGroup: jest.Mock\n updateGroup: jest.Mock\n deleteGroup: jest.Mock\n addUsersToGroup: jest.Mock\n updateUserFromGroup: jest.Mock\n removeUserFromGroup: jest.Mock\n }\n\n const setUser = (u: any) => adminQueriesMock.listUsers.mockResolvedValueOnce(u)\n const setGuest = (g: any) => adminQueriesMock.usersQueries.listGuests.mockResolvedValueOnce(g)\n\n const baseUser = {\n id: 10,\n login: 'john',\n email: 'john@example.com',\n isActive: true,\n role: USER_ROLE.USER,\n groups: [{ id: 1 }, { id: 3 }]\n } as any\n\n beforeAll(async () => {\n authManagerMock = { setCookies: jest.fn() }\n\n adminQueriesMock = {\n listUsers: jest.fn(),\n usersQueries: {\n listGuests: jest.fn(),\n from: jest.fn(),\n createUserOrGuest: jest.fn(),\n updateUserOrGuest: jest.fn(),\n deleteUser: jest.fn(),\n compareUserPassword: jest.fn(),\n checkGroupNameExists: jest.fn(),\n checkUserExists: jest.fn(),\n searchUsersOrGroups: jest.fn()\n },\n updateUserGroups: jest.fn(),\n updateGuestManagers: jest.fn(),\n deleteUser: jest.fn(),\n groupFromName: jest.fn(),\n browseGroupMembers: jest.fn(),\n browseRootGroupMembers: jest.fn(),\n groupFromId: jest.fn(),\n createGroup: jest.fn(),\n updateGroup: jest.fn(),\n deleteGroup: jest.fn(),\n addUsersToGroup: jest.fn(),\n updateUserFromGroup: jest.fn(),\n removeUserFromGroup: jest.fn()\n }\n\n const module: TestingModule = await Test.createTestingModule({\n providers: [AdminUsersManager, { provide: AuthManager, useValue: authManagerMock }, { provide: AdminUsersQueries, useValue: adminQueriesMock }]\n }).compile()\n\n module.useLogger(['fatal'])\n service = module.get<AdminUsersManager>(AdminUsersManager)\n })\n\n beforeEach(() => {\n jest.clearAllMocks()\n })\n\n it('should be defined', () => {\n expect(service).toBeDefined()\n })\n\n describe('getUser / getGuest', () => {\n it('user ok + not found + guest ok', async () => {\n setUser(baseUser)\n expect(await service.getUser(10)).toEqual(baseUser)\n expect(adminQueriesMock.listUsers).toHaveBeenCalledWith(10)\n\n setUser(null)\n await expectHttp(service.getUser(999))\n\n const guest = { id: 22, login: 'guest', email: 'g@x', managers: [], role: USER_ROLE.GUEST }\n setGuest(guest as any)\n expect(await service.getGuest(22)).toEqual(guest)\n expect(adminQueriesMock.usersQueries.listGuests).toHaveBeenCalledWith(22, 0, true)\n })\n })\n\n describe('createUserOrGuest', () => {\n it.each([\n { role: USER_ROLE.USER, asAdmin: false, id: 101, exp: 'UserModel' },\n { role: USER_ROLE.GUEST, asAdmin: true, id: 202, exp: 'AdminGuest' },\n { role: USER_ROLE.USER, asAdmin: true, id: 707, exp: 'AdminUser' },\n { role: USER_ROLE.GUEST, asAdmin: false, id: 808, exp: 'UserModel' }\n ])('creation matrix ($role / asAdmin=$asAdmin)', async ({ role, asAdmin, id, exp }) => {\n const dto: CreateUserDto = { login: 'alice', email: 'a@x', password: 'pwd', managers: role === USER_ROLE.GUEST ? [1] : [] } as any\n adminQueriesMock.usersQueries.checkUserExists.mockResolvedValueOnce(false)\n adminQueriesMock.usersQueries.createUserOrGuest.mockResolvedValueOnce(id)\n spyMakePaths()\n\n if (exp === 'AdminUser') setUser({ id, login: 'alice', role })\n if (exp === 'AdminGuest') setGuest({ id, login: 'alice', role } as any)\n\n const res = await (service as any).createUserOrGuest(dto, role, asAdmin)\n\n if (exp === 'UserModel') {\n expect(res).toBeInstanceOf(UserModel)\n expect((res as any).id).toBe(id)\n } else if (exp === 'AdminUser') {\n expect(adminQueriesMock.listUsers).toHaveBeenCalledWith(id)\n } else {\n expect(adminQueriesMock.usersQueries.listGuests).toHaveBeenCalledWith(id, 0, true)\n }\n expect(adminQueriesMock.usersQueries.createUserOrGuest).toHaveBeenCalledWith(\n expect.objectContaining({ login: 'alice', email: 'a@x', password: 'hashed:pwd' }),\n role\n )\n })\n\n it('creation errors: duplication and DB error', async () => {\n adminQueriesMock.usersQueries.checkUserExists.mockResolvedValueOnce({ login: 'dup', email: 'dup@x' })\n await expectHttp(service.createUserOrGuest({ login: 'dup', email: 'dup@x', password: 'p', managers: [] } as any, USER_ROLE.USER, false))\n\n adminQueriesMock.usersQueries.checkUserExists.mockResolvedValueOnce(false)\n adminQueriesMock.usersQueries.createUserOrGuest.mockRejectedValueOnce(new Error('db fail'))\n await expectHttp(service.createUserOrGuest({ login: 'bob', email: 'b@x', password: 'p', managers: [] } as any, USER_ROLE.USER, false))\n })\n })\n\n describe('updateUserOrGuest - USER branch', () => {\n it('full update + FS rename + groups diff', async () => {\n const current = { ...baseUser, groups: [{ id: 1 }, { id: 3 }] }\n setUser(current)\n const updated = { ...current, login: 'johnny', email: 'j@new' }\n setUser(updated)\n\n adminQueriesMock.usersQueries.checkUserExists.mockResolvedValueOnce(false)\n adminQueriesMock.usersQueries.checkUserExists.mockResolvedValueOnce(false)\n fs.isPathExists.mockResolvedValueOnce(true)\n fs.isPathExists.mockResolvedValueOnce(false)\n fs.moveFiles.mockResolvedValueOnce(undefined)\n adminQueriesMock.usersQueries.updateUserOrGuest.mockResolvedValueOnce(true)\n adminQueriesMock.updateUserGroups.mockResolvedValueOnce(undefined)\n\n const dto: UpdateUserDto = { login: 'johnny', email: 'j@new', isActive: true, password: 'newpwd', groups: [3, 5] }\n const res = await service.updateUserOrGuest(current.id, dto)\n\n expect(adminQueriesMock.usersQueries.updateUserOrGuest).toHaveBeenCalledWith(\n current.id,\n expect.objectContaining({ login: 'johnny', email: 'j@new', isActive: true, passwordAttempts: 0, password: 'hashed:newpwd' }),\n undefined\n )\n expect(adminQueriesMock.updateUserGroups).toHaveBeenCalledWith(current.id, { add: [5], delete: [1] })\n expect(res).toEqual(updated)\n })\n\n it('login/email conflict', async () => {\n const current = { ...baseUser }\n setUser(current)\n adminQueriesMock.usersQueries.checkUserExists.mockResolvedValueOnce(true)\n await expectHttp(service.updateUserOrGuest(current.id, { login: 'taken' } as any))\n\n setUser(current)\n adminQueriesMock.usersQueries.checkUserExists.mockResolvedValueOnce(true)\n await expectHttp(service.updateUserOrGuest(current.id, { email: 'dup@x' } as any))\n expect(adminQueriesMock.usersQueries.updateUserOrGuest).not.toHaveBeenCalled()\n })\n\n it('renameUserSpace impossible (new space exists)', async () => {\n const current = { ...baseUser }\n setUser(current)\n adminQueriesMock.usersQueries.checkUserExists.mockResolvedValueOnce(false)\n fs.isPathExists.mockResolvedValueOnce(true) // current\n fs.isPathExists.mockResolvedValueOnce(true) // new already exists\n fs.moveFiles.mockResolvedValue(undefined)\n await expectHttp(service.updateUserOrGuest(current.id, { login: 'new' } as any))\n })\n\n it('DB update false => INTERNAL_SERVER_ERROR', async () => {\n const current = { ...baseUser }\n setUser(current)\n adminQueriesMock.usersQueries.updateUserOrGuest.mockResolvedValueOnce(false)\n await expectHttp(service.updateUserOrGuest(current.id, { email: 'e@x' } as any))\n })\n\n it('updateUserGroups fails', async () => {\n const current = { ...baseUser, groups: [{ id: 1 }] }\n setUser(current)\n adminQueriesMock.usersQueries.updateUserOrGuest.mockResolvedValueOnce(true)\n adminQueriesMock.updateUserGroups.mockRejectedValueOnce(new Error('group error'))\n await expectHttp(service.updateUserOrGuest(current.id, { groups: [2] } as any))\n })\n\n it('no change when login or email unchanged', async () => {\n const current = { ...baseUser }\n setUser(current)\n setUser(current)\n expect(await service.updateUserOrGuest(current.id, { login: current.login } as any)).toEqual(current)\n expect(adminQueriesMock.usersQueries.checkUserExists).not.toHaveBeenCalled()\n\n setUser(current)\n setUser(current)\n expect(await service.updateUserOrGuest(current.id, { email: current.email } as any)).toEqual(current)\n expect(adminQueriesMock.usersQueries.updateUserOrGuest).not.toHaveBeenCalled()\n })\n\n it('default branch (unknown field)', async () => {\n const current = { ...baseUser }\n setUser(current)\n adminQueriesMock.usersQueries.updateUserOrGuest.mockResolvedValueOnce(true)\n const updated = { ...current, language: 'fr' } as any\n setUser(updated)\n\n const res = await service.updateUserOrGuest(current.id, { language: 'fr' } as any)\n expect(adminQueriesMock.usersQueries.updateUserOrGuest).toHaveBeenCalledWith(current.id, expect.objectContaining({ language: 'fr' }), undefined)\n expect(res).toEqual(updated)\n })\n })\n\n describe('updateUserOrGuest - GUEST branch', () => {\n it('update guest + managers diff', async () => {\n const guest = { id: 33, login: 'g', email: 'g@x', managers: [{ id: 2 }, { id: 7 }], role: USER_ROLE.GUEST }\n setGuest(guest as any)\n const updatedGuest = { ...guest, email: 'new@x' }\n setGuest(updatedGuest as any)\n\n adminQueriesMock.usersQueries.updateUserOrGuest.mockResolvedValueOnce(true)\n adminQueriesMock.updateGuestManagers.mockResolvedValueOnce(undefined)\n\n const res = await service.updateUserOrGuest(guest.id, { email: 'new@x', managers: [7, 9] } as UpdateUserDto, USER_ROLE.GUEST)\n expect(adminQueriesMock.usersQueries.updateUserOrGuest).toHaveBeenCalledWith(guest.id, { email: 'new@x' }, USER_ROLE.GUEST)\n expect(adminQueriesMock.updateGuestManagers).toHaveBeenCalledWith(guest.id, { add: [9], delete: [2] })\n expect(res).toEqual(updatedGuest)\n })\n\n it('validations updateGuest', async () => {\n expect(() => service.updateGuest(1, {} as any)).toThrow(/no changes to update/i)\n expect(() => service.updateGuest(1, { managers: [] } as any)).toThrow(/guest must have at least one manager/i)\n })\n\n it('updateGuestManagers échoue', async () => {\n const guest = { id: 33, login: 'g', email: 'g@x', managers: [{ id: 2 }], role: USER_ROLE.GUEST }\n setGuest(guest as any)\n adminQueriesMock.usersQueries.updateUserOrGuest.mockResolvedValueOnce(true)\n adminQueriesMock.updateGuestManagers.mockRejectedValueOnce(new Error('mgr error'))\n await expectHttp(service.updateUserOrGuest(guest.id, { managers: [3] } as any, USER_ROLE.GUEST))\n })\n })\n\n describe('deleteUserOrGuest / deleteGuest', () => {\n it('delete user + optional space and errors', async () => {\n adminQueriesMock.deleteUser.mockResolvedValueOnce(true)\n fs.isPathExists.mockResolvedValueOnce(true)\n fs.removeFiles.mockResolvedValueOnce(undefined)\n await expect(service.deleteUserOrGuest(10, 'john', { deleteSpace: true, isGuest: false })).resolves.toBeUndefined()\n expect(adminQueriesMock.deleteUser).toHaveBeenCalledWith(10, 'john')\n expect(fs.isPathExists).toHaveBeenCalled()\n expect(fs.removeFiles).toHaveBeenCalled()\n\n adminQueriesMock.deleteUser.mockRejectedValueOnce(new Error('db crash'))\n await expectHttp(service.deleteUserOrGuest(10, 'john', { deleteSpace: false } as any))\n })\n })\n\n describe('deleteUserFromAdmin', () => {\n it('admin password incorrect / deletion ok', async () => {\n adminQueriesMock.usersQueries.compareUserPassword.mockResolvedValueOnce(false)\n await expectHttp(service.deleteUserOrGuestFromAdmin(10, { isGuest: false } as DeleteUserDto))\n\n adminQueriesMock.usersQueries.compareUserPassword.mockResolvedValueOnce(true)\n adminQueriesMock.usersQueries.from.mockResolvedValueOnce({ id: 10, login: 'to-del' } as any)\n adminQueriesMock.deleteUser.mockResolvedValueOnce(true)\n await service.deleteUserOrGuestFromAdmin(10, { isGuest: false, deleteSpace: true } as DeleteUserDto)\n expect(adminQueriesMock.deleteUser).toHaveBeenCalledWith(10, 'to-del')\n })\n })\n\n describe('groups', () => {\n it('browseGroups with/without name + NOT_FOUND', async () => {\n adminQueriesMock.groupFromName.mockResolvedValueOnce({ id: 5, name: 'dev', type: GROUP_TYPE.USER })\n adminQueriesMock.browseGroupMembers.mockResolvedValueOnce([{ id: 1 }, { id: 2 }])\n const withName = await service.browseGroups('dev', GROUP_TYPE.USER)\n expect(withName.parentGroup).toEqual({ id: 5, name: 'dev', type: GROUP_TYPE.USER })\n expect(withName.members).toHaveLength(2)\n\n adminQueriesMock.browseRootGroupMembers.mockResolvedValueOnce([{ id: 3 }])\n const root = await service.browseGroups(undefined, GROUP_TYPE.USER)\n expect(root.parentGroup).toBeUndefined()\n expect(root.members).toEqual([{ id: 3 }])\n\n adminQueriesMock.groupFromName.mockResolvedValueOnce(null)\n await expectHttp(service.browseGroups('unknown'))\n })\n\n it('getGroup OK / NOT_FOUND', async () => {\n adminQueriesMock.groupFromId.mockResolvedValueOnce({ id: 9 })\n expect(await service.getGroup(9)).toEqual({ id: 9 })\n adminQueriesMock.groupFromId.mockResolvedValueOnce(null)\n await expectHttp(service.getGroup(999))\n })\n\n it('createGroup OK + validations + creation error', async () => {\n const dto: CreateOrUpdateGroupDto = { name: 'team', type: GROUP_TYPE.USER } as any\n adminQueriesMock.usersQueries.checkGroupNameExists.mockResolvedValueOnce(false)\n adminQueriesMock.createGroup.mockResolvedValueOnce(123)\n adminQueriesMock.groupFromId.mockResolvedValueOnce({ id: 123, name: 'team' })\n expect(await service.createGroup(dto)).toEqual({ id: 123, name: 'team' })\n\n await expectHttp(service.createGroup({} as any))\n\n adminQueriesMock.usersQueries.checkGroupNameExists.mockResolvedValueOnce(true)\n await expectHttp(service.createGroup(dto))\n expect(adminQueriesMock.createGroup).toHaveBeenCalledTimes(1) // only the first one OK\n\n adminQueriesMock.usersQueries.checkGroupNameExists.mockResolvedValueOnce(false)\n adminQueriesMock.createGroup.mockRejectedValueOnce(new Error('db err'))\n await expectHttp(service.createGroup(dto))\n })\n\n it('updateGroup success / failure', async () => {\n adminQueriesMock.usersQueries.checkGroupNameExists.mockResolvedValueOnce(false)\n adminQueriesMock.updateGroup.mockResolvedValueOnce(true)\n adminQueriesMock.groupFromId.mockResolvedValueOnce({ id: 5, name: 'new' })\n expect(await service.updateGroup(5, { name: 'new' } as any)).toEqual({ id: 5, name: 'new' })\n\n adminQueriesMock.updateGroup.mockResolvedValueOnce(false)\n await expectHttp(service.updateGroup(5, {} as any))\n })\n\n it('deleteGroup success / fail', async () => {\n adminQueriesMock.deleteGroup.mockResolvedValueOnce(true)\n await expect(service.deleteGroup(5)).resolves.toBeUndefined()\n adminQueriesMock.deleteGroup.mockResolvedValueOnce(false)\n await expectHttp(service.deleteGroup(6))\n })\n\n it('addUsersToGroup: NOT_FOUND + error', async () => {\n adminQueriesMock.groupFromId.mockResolvedValueOnce(null)\n await expectHttp(service.addUsersToGroup(1, [2, 3]))\n\n adminQueriesMock.groupFromId.mockResolvedValueOnce({ id: 1, type: GROUP_TYPE.USER })\n adminQueriesMock.addUsersToGroup.mockRejectedValueOnce(new Error('bad users'))\n await expectHttp(service.addUsersToGroup(1, [2]))\n })\n\n it('updateUserFromGroup / removeUserFromGroup BAD_REQUEST errors', async () => {\n adminQueriesMock.updateUserFromGroup.mockRejectedValueOnce(new Error('bad role'))\n await expectHttp(service.updateUserFromGroup(1, 2, { role: USER_GROUP_ROLE.MEMBER } as UpdateUserFromGroupDto))\n\n adminQueriesMock.removeUserFromGroup.mockRejectedValueOnce(new Error('not member'))\n await expectHttp(service.removeUserFromGroup(1, 2))\n })\n })\n\n describe('searchMembers', () => {\n it('forwards to usersQueries.searchUsersOrGroups', async () => {\n const dto = { search: 'jo' } as SearchMembersDto\n adminQueriesMock.usersQueries.searchUsersOrGroups.mockResolvedValueOnce([{ id: 1 }])\n expect(await service.searchMembers(dto)).toEqual([{ id: 1 }])\n expect(adminQueriesMock.usersQueries.searchUsersOrGroups).toHaveBeenCalledWith(dto)\n })\n })\n\n describe('impersonation', () => {\n const res: any = {}\n it('self / bad password / ok + logout (guard + non-admin + admin)', async () => {\n const admin = new UserModel({ id: 5 } as any, true)\n await expectHttp(service.impersonateUser(admin, 5, res))\n\n adminQueriesMock.usersQueries.compareUserPassword.mockResolvedValueOnce(false)\n await expectHttp(service.impersonateUser(admin, 6, res))\n\n const admin2 = new UserModel({ id: 5, clientId: 'c1' } as any, true)\n adminQueriesMock.usersQueries.compareUserPassword.mockResolvedValueOnce(true)\n adminQueriesMock.usersQueries.from.mockResolvedValueOnce({ id: 6, login: 'user' } as any)\n authManagerMock.setCookies.mockResolvedValueOnce({ accessToken: 't' })\n expect(await service.impersonateUser(admin2, 6, res)).toEqual({ accessToken: 't' })\n\n const notImpersonated = new UserModel({ id: 1 } as any, true)\n await expectHttp(service.logoutImpersonateUser(notImpersonated, res))\n\n const impersonated = new UserModel({ id: 2, impersonatedFromId: 9, impersonatedClientId: 'X' } as any, true)\n adminQueriesMock.usersQueries.from.mockResolvedValueOnce({ id: 9, role: USER_ROLE.USER } as any)\n await expectHttp(service.logoutImpersonateUser(impersonated, res))\n\n adminQueriesMock.usersQueries.from.mockResolvedValueOnce({ id: 9, role: USER_ROLE.ADMINISTRATOR } as any)\n authManagerMock.setCookies.mockResolvedValueOnce({ accessToken: 'admin' })\n expect(await service.logoutImpersonateUser(impersonated, res)).toEqual({ accessToken: 'admin' })\n })\n })\n\n describe('listing', () => {\n it('forwards listUsers and listGuests', async () => {\n const users = [{ id: 1 }]\n adminQueriesMock.listUsers.mockResolvedValueOnce(users as any)\n expect(await service.listUsers()).toEqual(users)\n expect(adminQueriesMock.listUsers).toHaveBeenCalledWith()\n\n const guests = [{ id: 2 }]\n adminQueriesMock.usersQueries.listGuests.mockResolvedValueOnce(guests as any)\n expect(await service.listGuests()).toEqual(guests)\n expect(adminQueriesMock.usersQueries.listGuests).toHaveBeenCalledWith(null, null, true)\n })\n })\n\n describe('createGuest', () => {\n it('adds the creator as default manager and returns admin guest', async () => {\n const creator = new UserModel({ id: 88 } as any, true)\n const dto: CreateUserDto = { login: 'gg', email: 'g@x', password: 'pwd', managers: [] } as any\n adminQueriesMock.usersQueries.checkUserExists.mockResolvedValueOnce(false)\n adminQueriesMock.usersQueries.createUserOrGuest.mockResolvedValueOnce(505)\n spyMakePaths()\n const expectedGuest = { id: 505, login: 'gg', role: USER_ROLE.GUEST }\n setGuest(expectedGuest as any)\n\n expect(await service.createGuest(creator, dto)).toEqual(expectedGuest)\n expect(adminQueriesMock.usersQueries.createUserOrGuest).toHaveBeenCalledWith(\n expect.objectContaining({ login: 'gg', email: 'g@x', managers: [88] }),\n USER_ROLE.GUEST\n )\n })\n })\n\n describe('updateGuest wrapper', () => {\n it('updateGuest() -> success', async () => {\n const guest = { id: 33, login: 'g', email: 'g@x', managers: [{ id: 2 }], role: USER_ROLE.GUEST }\n const updatedGuest = { ...guest, email: 'new@x' }\n setGuest(guest as any)\n adminQueriesMock.usersQueries.updateUserOrGuest.mockResolvedValueOnce(true)\n setGuest(updatedGuest as any)\n expect(await service.updateGuest(guest.id, { email: 'new@x' } as any)).toEqual(updatedGuest)\n })\n })\n\n describe('deleteUserSpace', () => {\n it('space not existing / removeFiles failure', async () => {\n fs.isPathExists.mockResolvedValueOnce(false)\n await expect(service.deleteUserSpace('nobody')).resolves.toBeUndefined()\n\n fs.isPathExists.mockResolvedValueOnce(true)\n fs.removeFiles.mockRejectedValueOnce(new Error('fs error'))\n await expectHttp(service.deleteUserSpace('bob'))\n })\n })\n\n describe('renameUserSpace error handling', () => {\n it('moveFiles throws then restore', async () => {\n const current = { ...baseUser }\n setUser(current)\n adminQueriesMock.usersQueries.checkUserExists.mockResolvedValueOnce(false)\n fs.isPathExists.mockResolvedValueOnce(true)\n fs.isPathExists.mockResolvedValueOnce(false)\n fs.moveFiles.mockRejectedValueOnce(new Error('io error'))\n fs.moveFiles.mockResolvedValueOnce(undefined)\n await expectHttp(service.updateUserOrGuest(current.id, { login: 'new-login' } as any))\n expect(fs.moveFiles).toHaveBeenCalledTimes(2)\n })\n\n it('current space missing -> early return', async () => {\n const current = { ...baseUser }\n setUser(current)\n adminQueriesMock.usersQueries.checkUserExists.mockResolvedValueOnce(false)\n fs.isPathExists.mockResolvedValueOnce(false)\n await expectHttp(service.updateUserOrGuest(current.id, { login: 'new-login' } as any))\n expect(fs.moveFiles).not.toHaveBeenCalled()\n })\n })\n})\n"],"names":["jest","mock","isPathExists","fn","moveFiles","removeFiles","actual","requireActual","hashPassword","pwd","anonymizePassword","dto","password","fs","requireMock","expectHttp","p","expect","rejects","toBeInstanceOf","HttpException","spyMakePaths","spyOn","UserModel","prototype","mockResolvedValueOnce","undefined","describe","AdminUsersManager","name","service","authManagerMock","adminQueriesMock","setUser","u","listUsers","setGuest","g","usersQueries","listGuests","baseUser","id","login","email","isActive","role","USER_ROLE","USER","groups","beforeAll","setCookies","from","createUserOrGuest","updateUserOrGuest","deleteUser","compareUserPassword","checkGroupNameExists","checkUserExists","searchUsersOrGroups","updateUserGroups","updateGuestManagers","groupFromName","browseGroupMembers","browseRootGroupMembers","groupFromId","createGroup","updateGroup","deleteGroup","addUsersToGroup","updateUserFromGroup","removeUserFromGroup","module","Test","createTestingModule","providers","provide","AuthManager","useValue","AdminUsersQueries","compile","useLogger","get","beforeEach","clearAllMocks","it","toBeDefined","getUser","toEqual","toHaveBeenCalledWith","guest","managers","GUEST","getGuest","each","asAdmin","exp","res","toBe","objectContaining","mockRejectedValueOnce","Error","current","updated","passwordAttempts","add","delete","not","toHaveBeenCalled","mockResolvedValue","language","updatedGuest","updateGuest","toThrow","deleteUserOrGuest","deleteSpace","isGuest","resolves","toBeUndefined","deleteUserOrGuestFromAdmin","type","GROUP_TYPE","withName","browseGroups","parentGroup","members","toHaveLength","root","getGroup","toHaveBeenCalledTimes","USER_GROUP_ROLE","MEMBER","search","searchMembers","admin","impersonateUser","admin2","clientId","accessToken","notImpersonated","logoutImpersonateUser","impersonated","impersonatedFromId","impersonatedClientId","ADMINISTRATOR","users","guests","creator","expectedGuest","createGuest","deleteUserSpace"],"mappings":"AAAA;;;;CAIC;;;;wBAE6B;yBACM;oCACR;uBACD;sBACgB;2BAKjB;0CACQ;0CACA;AAElC,iEAAiE;AACjEA,KAAKC,IAAI,CAAC,2BAA2B,IAAO,CAAA;QAC1CC,cAAcF,KAAKG,EAAE;QACrBC,WAAWJ,KAAKG,EAAE;QAClBE,aAAaL,KAAKG,EAAE;IACtB,CAAA;AAEA,gEAAgE;AAChEH,KAAKC,IAAI,CAAC,6BAA6B;IACrC,MAAMK,SAASN,KAAKO,aAAa,CAAC;IAClC,OAAO;QACL,GAAGD,MAAM;QACTE,cAAcR,KAAKG,EAAE,CAAC,OAAOM,MAAgB,CAAC,OAAO,EAAEA,KAAK;QAC5DC,mBAAmBV,KAAKG,EAAE,CAAC,CAACQ,MAAc,CAAA;gBAAE,GAAGA,GAAG;gBAAEC,UAAU;YAAM,CAAA;IACtE;AACF;AAEA,qCAAqC;AACrC,MAAMC,KAAKb,KAAKc,WAAW,CAAC;AAE5B,mBAAmB;AACnB,MAAMC,aAAa,OAAOC,IAAoBC,OAAOD,GAAGE,OAAO,CAACC,cAAc,CAACC,qBAAa;AAC5F,MAAMC,eAAe,IAAMrB,KAAKsB,KAAK,CAACC,oBAAS,CAACC,SAAS,EAAE,aAAaC,qBAAqB,CAACC;AAE9FC,SAASC,2CAAiB,CAACC,IAAI,EAAE;IAC/B,IAAIC;IAEJ,aAAa;IACb,IAAIC;IACJ,IAAIC;IA4BJ,MAAMC,UAAU,CAACC,IAAWF,iBAAiBG,SAAS,CAACV,qBAAqB,CAACS;IAC7E,MAAME,WAAW,CAACC,IAAWL,iBAAiBM,YAAY,CAACC,UAAU,CAACd,qBAAqB,CAACY;IAE5F,MAAMG,WAAW;QACfC,IAAI;QACJC,OAAO;QACPC,OAAO;QACPC,UAAU;QACVC,MAAMC,eAAS,CAACC,IAAI;QACpBC,QAAQ;YAAC;gBAAEP,IAAI;YAAE;YAAG;gBAAEA,IAAI;YAAE;SAAE;IAChC;IAEAQ,UAAU;QACRlB,kBAAkB;YAAEmB,YAAYlD,KAAKG,EAAE;QAAG;QAE1C6B,mBAAmB;YACjBG,WAAWnC,KAAKG,EAAE;YAClBmC,cAAc;gBACZC,YAAYvC,KAAKG,EAAE;gBACnBgD,MAAMnD,KAAKG,EAAE;gBACbiD,mBAAmBpD,KAAKG,EAAE;gBAC1BkD,mBAAmBrD,KAAKG,EAAE;gBAC1BmD,YAAYtD,KAAKG,EAAE;gBACnBoD,qBAAqBvD,KAAKG,EAAE;gBAC5BqD,sBAAsBxD,KAAKG,EAAE;gBAC7BsD,iBAAiBzD,KAAKG,EAAE;gBACxBuD,qBAAqB1D,KAAKG,EAAE;YAC9B;YACAwD,kBAAkB3D,KAAKG,EAAE;YACzByD,qBAAqB5D,KAAKG,EAAE;YAC5BmD,YAAYtD,KAAKG,EAAE;YACnB0D,eAAe7D,KAAKG,EAAE;YACtB2D,oBAAoB9D,KAAKG,EAAE;YAC3B4D,wBAAwB/D,KAAKG,EAAE;YAC/B6D,aAAahE,KAAKG,EAAE;YACpB8D,aAAajE,KAAKG,EAAE;YACpB+D,aAAalE,KAAKG,EAAE;YACpBgE,aAAanE,KAAKG,EAAE;YACpBiE,iBAAiBpE,KAAKG,EAAE;YACxBkE,qBAAqBrE,KAAKG,EAAE;YAC5BmE,qBAAqBtE,KAAKG,EAAE;QAC9B;QAEA,MAAMoE,SAAwB,MAAMC,aAAI,CAACC,mBAAmB,CAAC;YAC3DC,WAAW;gBAAC9C,2CAAiB;gBAAE;oBAAE+C,SAASC,+BAAW;oBAAEC,UAAU9C;gBAAgB;gBAAG;oBAAE4C,SAASG,2CAAiB;oBAAED,UAAU7C;gBAAiB;aAAE;QACjJ,GAAG+C,OAAO;QAEVR,OAAOS,SAAS,CAAC;YAAC;SAAQ;QAC1BlD,UAAUyC,OAAOU,GAAG,CAAoBrD,2CAAiB;IAC3D;IAEAsD,WAAW;QACTlF,KAAKmF,aAAa;IACpB;IAEAC,GAAG,qBAAqB;QACtBnE,OAAOa,SAASuD,WAAW;IAC7B;IAEA1D,SAAS,sBAAsB;QAC7ByD,GAAG,kCAAkC;YACnCnD,QAAQO;YACRvB,OAAO,MAAMa,QAAQwD,OAAO,CAAC,KAAKC,OAAO,CAAC/C;YAC1CvB,OAAOe,iBAAiBG,SAAS,EAAEqD,oBAAoB,CAAC;YAExDvD,QAAQ;YACR,MAAMlB,WAAWe,QAAQwD,OAAO,CAAC;YAEjC,MAAMG,QAAQ;gBAAEhD,IAAI;gBAAIC,OAAO;gBAASC,OAAO;gBAAO+C,UAAU,EAAE;gBAAE7C,MAAMC,eAAS,CAAC6C,KAAK;YAAC;YAC1FvD,SAASqD;YACTxE,OAAO,MAAMa,QAAQ8D,QAAQ,CAAC,KAAKL,OAAO,CAACE;YAC3CxE,OAAOe,iBAAiBM,YAAY,CAACC,UAAU,EAAEiD,oBAAoB,CAAC,IAAI,GAAG;QAC/E;IACF;IAEA7D,SAAS,qBAAqB;QAC5ByD,GAAGS,IAAI,CAAC;YACN;gBAAEhD,MAAMC,eAAS,CAACC,IAAI;gBAAE+C,SAAS;gBAAOrD,IAAI;gBAAKsD,KAAK;YAAY;YAClE;gBAAElD,MAAMC,eAAS,CAAC6C,KAAK;gBAAEG,SAAS;gBAAMrD,IAAI;gBAAKsD,KAAK;YAAa;YACnE;gBAAElD,MAAMC,eAAS,CAACC,IAAI;gBAAE+C,SAAS;gBAAMrD,IAAI;gBAAKsD,KAAK;YAAY;YACjE;gBAAElD,MAAMC,eAAS,CAAC6C,KAAK;gBAAEG,SAAS;gBAAOrD,IAAI;gBAAKsD,KAAK;YAAY;SACpE,EAAE,8CAA8C,OAAO,EAAElD,IAAI,EAAEiD,OAAO,EAAErD,EAAE,EAAEsD,GAAG,EAAE;YAChF,MAAMpF,MAAqB;gBAAE+B,OAAO;gBAASC,OAAO;gBAAO/B,UAAU;gBAAO8E,UAAU7C,SAASC,eAAS,CAAC6C,KAAK,GAAG;oBAAC;iBAAE,GAAG,EAAE;YAAC;YAC1H3D,iBAAiBM,YAAY,CAACmB,eAAe,CAAChC,qBAAqB,CAAC;YACpEO,iBAAiBM,YAAY,CAACc,iBAAiB,CAAC3B,qBAAqB,CAACgB;YACtEpB;YAEA,IAAI0E,QAAQ,aAAa9D,QAAQ;gBAAEQ;gBAAIC,OAAO;gBAASG;YAAK;YAC5D,IAAIkD,QAAQ,cAAc3D,SAAS;gBAAEK;gBAAIC,OAAO;gBAASG;YAAK;YAE9D,MAAMmD,MAAM,MAAM,AAAClE,QAAgBsB,iBAAiB,CAACzC,KAAKkC,MAAMiD;YAEhE,IAAIC,QAAQ,aAAa;gBACvB9E,OAAO+E,KAAK7E,cAAc,CAACI,oBAAS;gBACpCN,OAAO,AAAC+E,IAAYvD,EAAE,EAAEwD,IAAI,CAACxD;YAC/B,OAAO,IAAIsD,QAAQ,aAAa;gBAC9B9E,OAAOe,iBAAiBG,SAAS,EAAEqD,oBAAoB,CAAC/C;YAC1D,OAAO;gBACLxB,OAAOe,iBAAiBM,YAAY,CAACC,UAAU,EAAEiD,oBAAoB,CAAC/C,IAAI,GAAG;YAC/E;YACAxB,OAAOe,iBAAiBM,YAAY,CAACc,iBAAiB,EAAEoC,oBAAoB,CAC1EvE,OAAOiF,gBAAgB,CAAC;gBAAExD,OAAO;gBAASC,OAAO;gBAAO/B,UAAU;YAAa,IAC/EiC;QAEJ;QAEAuC,GAAG,6CAA6C;YAC9CpD,iBAAiBM,YAAY,CAACmB,eAAe,CAAChC,qBAAqB,CAAC;gBAAEiB,OAAO;gBAAOC,OAAO;YAAQ;YACnG,MAAM5B,WAAWe,QAAQsB,iBAAiB,CAAC;gBAAEV,OAAO;gBAAOC,OAAO;gBAAS/B,UAAU;gBAAK8E,UAAU,EAAE;YAAC,GAAU5C,eAAS,CAACC,IAAI,EAAE;YAEjIf,iBAAiBM,YAAY,CAACmB,eAAe,CAAChC,qBAAqB,CAAC;YACpEO,iBAAiBM,YAAY,CAACc,iBAAiB,CAAC+C,qBAAqB,CAAC,IAAIC,MAAM;YAChF,MAAMrF,WAAWe,QAAQsB,iBAAiB,CAAC;gBAAEV,OAAO;gBAAOC,OAAO;gBAAO/B,UAAU;gBAAK8E,UAAU,EAAE;YAAC,GAAU5C,eAAS,CAACC,IAAI,EAAE;QACjI;IACF;IAEApB,SAAS,mCAAmC;QAC1CyD,GAAG,yCAAyC;YAC1C,MAAMiB,UAAU;gBAAE,GAAG7D,QAAQ;gBAAEQ,QAAQ;oBAAC;wBAAEP,IAAI;oBAAE;oBAAG;wBAAEA,IAAI;oBAAE;iBAAE;YAAC;YAC9DR,QAAQoE;YACR,MAAMC,UAAU;gBAAE,GAAGD,OAAO;gBAAE3D,OAAO;gBAAUC,OAAO;YAAQ;YAC9DV,QAAQqE;YAERtE,iBAAiBM,YAAY,CAACmB,eAAe,CAAChC,qBAAqB,CAAC;YACpEO,iBAAiBM,YAAY,CAACmB,eAAe,CAAChC,qBAAqB,CAAC;YACpEZ,GAAGX,YAAY,CAACuB,qBAAqB,CAAC;YACtCZ,GAAGX,YAAY,CAACuB,qBAAqB,CAAC;YACtCZ,GAAGT,SAAS,CAACqB,qBAAqB,CAACC;YACnCM,iBAAiBM,YAAY,CAACe,iBAAiB,CAAC5B,qBAAqB,CAAC;YACtEO,iBAAiB2B,gBAAgB,CAAClC,qBAAqB,CAACC;YAExD,MAAMf,MAAqB;gBAAE+B,OAAO;gBAAUC,OAAO;gBAASC,UAAU;gBAAMhC,UAAU;gBAAUoC,QAAQ;oBAAC;oBAAG;iBAAE;YAAC;YACjH,MAAMgD,MAAM,MAAMlE,QAAQuB,iBAAiB,CAACgD,QAAQ5D,EAAE,EAAE9B;YAExDM,OAAOe,iBAAiBM,YAAY,CAACe,iBAAiB,EAAEmC,oBAAoB,CAC1Ea,QAAQ5D,EAAE,EACVxB,OAAOiF,gBAAgB,CAAC;gBAAExD,OAAO;gBAAUC,OAAO;gBAASC,UAAU;gBAAM2D,kBAAkB;gBAAG3F,UAAU;YAAgB,IAC1Hc;YAEFT,OAAOe,iBAAiB2B,gBAAgB,EAAE6B,oBAAoB,CAACa,QAAQ5D,EAAE,EAAE;gBAAE+D,KAAK;oBAAC;iBAAE;gBAAEC,QAAQ;oBAAC;iBAAE;YAAC;YACnGxF,OAAO+E,KAAKT,OAAO,CAACe;QACtB;QAEAlB,GAAG,wBAAwB;YACzB,MAAMiB,UAAU;gBAAE,GAAG7D,QAAQ;YAAC;YAC9BP,QAAQoE;YACRrE,iBAAiBM,YAAY,CAACmB,eAAe,CAAChC,qBAAqB,CAAC;YACpE,MAAMV,WAAWe,QAAQuB,iBAAiB,CAACgD,QAAQ5D,EAAE,EAAE;gBAAEC,OAAO;YAAQ;YAExET,QAAQoE;YACRrE,iBAAiBM,YAAY,CAACmB,eAAe,CAAChC,qBAAqB,CAAC;YACpE,MAAMV,WAAWe,QAAQuB,iBAAiB,CAACgD,QAAQ5D,EAAE,EAAE;gBAAEE,OAAO;YAAQ;YACxE1B,OAAOe,iBAAiBM,YAAY,CAACe,iBAAiB,EAAEqD,GAAG,CAACC,gBAAgB;QAC9E;QAEAvB,GAAG,iDAAiD;YAClD,MAAMiB,UAAU;gBAAE,GAAG7D,QAAQ;YAAC;YAC9BP,QAAQoE;YACRrE,iBAAiBM,YAAY,CAACmB,eAAe,CAAChC,qBAAqB,CAAC;YACpEZ,GAAGX,YAAY,CAACuB,qBAAqB,CAAC,OAAM,UAAU;YACtDZ,GAAGX,YAAY,CAACuB,qBAAqB,CAAC,OAAM,qBAAqB;YACjEZ,GAAGT,SAAS,CAACwG,iBAAiB,CAAClF;YAC/B,MAAMX,WAAWe,QAAQuB,iBAAiB,CAACgD,QAAQ5D,EAAE,EAAE;gBAAEC,OAAO;YAAM;QACxE;QAEA0C,GAAG,4CAA4C;YAC7C,MAAMiB,UAAU;gBAAE,GAAG7D,QAAQ;YAAC;YAC9BP,QAAQoE;YACRrE,iBAAiBM,YAAY,CAACe,iBAAiB,CAAC5B,qBAAqB,CAAC;YACtE,MAAMV,WAAWe,QAAQuB,iBAAiB,CAACgD,QAAQ5D,EAAE,EAAE;gBAAEE,OAAO;YAAM;QACxE;QAEAyC,GAAG,0BAA0B;YAC3B,MAAMiB,UAAU;gBAAE,GAAG7D,QAAQ;gBAAEQ,QAAQ;oBAAC;wBAAEP,IAAI;oBAAE;iBAAE;YAAC;YACnDR,QAAQoE;YACRrE,iBAAiBM,YAAY,CAACe,iBAAiB,CAAC5B,qBAAqB,CAAC;YACtEO,iBAAiB2B,gBAAgB,CAACwC,qBAAqB,CAAC,IAAIC,MAAM;YAClE,MAAMrF,WAAWe,QAAQuB,iBAAiB,CAACgD,QAAQ5D,EAAE,EAAE;gBAAEO,QAAQ;oBAAC;iBAAE;YAAC;QACvE;QAEAoC,GAAG,2CAA2C;YAC5C,MAAMiB,UAAU;gBAAE,GAAG7D,QAAQ;YAAC;YAC9BP,QAAQoE;YACRpE,QAAQoE;YACRpF,OAAO,MAAMa,QAAQuB,iBAAiB,CAACgD,QAAQ5D,EAAE,EAAE;gBAAEC,OAAO2D,QAAQ3D,KAAK;YAAC,IAAW6C,OAAO,CAACc;YAC7FpF,OAAOe,iBAAiBM,YAAY,CAACmB,eAAe,EAAEiD,GAAG,CAACC,gBAAgB;YAE1E1E,QAAQoE;YACRpE,QAAQoE;YACRpF,OAAO,MAAMa,QAAQuB,iBAAiB,CAACgD,QAAQ5D,EAAE,EAAE;gBAAEE,OAAO0D,QAAQ1D,KAAK;YAAC,IAAW4C,OAAO,CAACc;YAC7FpF,OAAOe,iBAAiBM,YAAY,CAACe,iBAAiB,EAAEqD,GAAG,CAACC,gBAAgB;QAC9E;QAEAvB,GAAG,kCAAkC;YACnC,MAAMiB,UAAU;gBAAE,GAAG7D,QAAQ;YAAC;YAC9BP,QAAQoE;YACRrE,iBAAiBM,YAAY,CAACe,iBAAiB,CAAC5B,qBAAqB,CAAC;YACtE,MAAM6E,UAAU;gBAAE,GAAGD,OAAO;gBAAEQ,UAAU;YAAK;YAC7C5E,QAAQqE;YAER,MAAMN,MAAM,MAAMlE,QAAQuB,iBAAiB,CAACgD,QAAQ5D,EAAE,EAAE;gBAAEoE,UAAU;YAAK;YACzE5F,OAAOe,iBAAiBM,YAAY,CAACe,iBAAiB,EAAEmC,oBAAoB,CAACa,QAAQ5D,EAAE,EAAExB,OAAOiF,gBAAgB,CAAC;gBAAEW,UAAU;YAAK,IAAInF;YACtIT,OAAO+E,KAAKT,OAAO,CAACe;QACtB;IACF;IAEA3E,SAAS,oCAAoC;QAC3CyD,GAAG,gCAAgC;YACjC,MAAMK,QAAQ;gBAAEhD,IAAI;gBAAIC,OAAO;gBAAKC,OAAO;gBAAO+C,UAAU;oBAAC;wBAAEjD,IAAI;oBAAE;oBAAG;wBAAEA,IAAI;oBAAE;iBAAE;gBAAEI,MAAMC,eAAS,CAAC6C,KAAK;YAAC;YAC1GvD,SAASqD;YACT,MAAMqB,eAAe;gBAAE,GAAGrB,KAAK;gBAAE9C,OAAO;YAAQ;YAChDP,SAAS0E;YAET9E,iBAAiBM,YAAY,CAACe,iBAAiB,CAAC5B,qBAAqB,CAAC;YACtEO,iBAAiB4B,mBAAmB,CAACnC,qBAAqB,CAACC;YAE3D,MAAMsE,MAAM,MAAMlE,QAAQuB,iBAAiB,CAACoC,MAAMhD,EAAE,EAAE;gBAAEE,OAAO;gBAAS+C,UAAU;oBAAC;oBAAG;iBAAE;YAAC,GAAoB5C,eAAS,CAAC6C,KAAK;YAC5H1E,OAAOe,iBAAiBM,YAAY,CAACe,iBAAiB,EAAEmC,oBAAoB,CAACC,MAAMhD,EAAE,EAAE;gBAAEE,OAAO;YAAQ,GAAGG,eAAS,CAAC6C,KAAK;YAC1H1E,OAAOe,iBAAiB4B,mBAAmB,EAAE4B,oBAAoB,CAACC,MAAMhD,EAAE,EAAE;gBAAE+D,KAAK;oBAAC;iBAAE;gBAAEC,QAAQ;oBAAC;iBAAE;YAAC;YACpGxF,OAAO+E,KAAKT,OAAO,CAACuB;QACtB;QAEA1B,GAAG,2BAA2B;YAC5BnE,OAAO,IAAMa,QAAQiF,WAAW,CAAC,GAAG,CAAC,IAAWC,OAAO,CAAC;YACxD/F,OAAO,IAAMa,QAAQiF,WAAW,CAAC,GAAG;oBAAErB,UAAU,EAAE;gBAAC,IAAWsB,OAAO,CAAC;QACxE;QAEA5B,GAAG,8BAA8B;YAC/B,MAAMK,QAAQ;gBAAEhD,IAAI;gBAAIC,OAAO;gBAAKC,OAAO;gBAAO+C,UAAU;oBAAC;wBAAEjD,IAAI;oBAAE;iBAAE;gBAAEI,MAAMC,eAAS,CAAC6C,KAAK;YAAC;YAC/FvD,SAASqD;YACTzD,iBAAiBM,YAAY,CAACe,iBAAiB,CAAC5B,qBAAqB,CAAC;YACtEO,iBAAiB4B,mBAAmB,CAACuC,qBAAqB,CAAC,IAAIC,MAAM;YACrE,MAAMrF,WAAWe,QAAQuB,iBAAiB,CAACoC,MAAMhD,EAAE,EAAE;gBAAEiD,UAAU;oBAAC;iBAAE;YAAC,GAAU5C,eAAS,CAAC6C,KAAK;QAChG;IACF;IAEAhE,SAAS,mCAAmC;QAC1CyD,GAAG,2CAA2C;YAC5CpD,iBAAiBsB,UAAU,CAAC7B,qBAAqB,CAAC;YAClDZ,GAAGX,YAAY,CAACuB,qBAAqB,CAAC;YACtCZ,GAAGR,WAAW,CAACoB,qBAAqB,CAACC;YACrC,MAAMT,OAAOa,QAAQmF,iBAAiB,CAAC,IAAI,QAAQ;gBAAEC,aAAa;gBAAMC,SAAS;YAAM,IAAIC,QAAQ,CAACC,aAAa;YACjHpG,OAAOe,iBAAiBsB,UAAU,EAAEkC,oBAAoB,CAAC,IAAI;YAC7DvE,OAAOJ,GAAGX,YAAY,EAAEyG,gBAAgB;YACxC1F,OAAOJ,GAAGR,WAAW,EAAEsG,gBAAgB;YAEvC3E,iBAAiBsB,UAAU,CAAC6C,qBAAqB,CAAC,IAAIC,MAAM;YAC5D,MAAMrF,WAAWe,QAAQmF,iBAAiB,CAAC,IAAI,QAAQ;gBAAEC,aAAa;YAAM;QAC9E;IACF;IAEAvF,SAAS,uBAAuB;QAC9ByD,GAAG,0CAA0C;YAC3CpD,iBAAiBM,YAAY,CAACiB,mBAAmB,CAAC9B,qBAAqB,CAAC;YACxE,MAAMV,WAAWe,QAAQwF,0BAA0B,CAAC,IAAI;gBAAEH,SAAS;YAAM;YAEzEnF,iBAAiBM,YAAY,CAACiB,mBAAmB,CAAC9B,qBAAqB,CAAC;YACxEO,iBAAiBM,YAAY,CAACa,IAAI,CAAC1B,qBAAqB,CAAC;gBAAEgB,IAAI;gBAAIC,OAAO;YAAS;YACnFV,iBAAiBsB,UAAU,CAAC7B,qBAAqB,CAAC;YAClD,MAAMK,QAAQwF,0BAA0B,CAAC,IAAI;gBAAEH,SAAS;gBAAOD,aAAa;YAAK;YACjFjG,OAAOe,iBAAiBsB,UAAU,EAAEkC,oBAAoB,CAAC,IAAI;QAC/D;IACF;IAEA7D,SAAS,UAAU;QACjByD,GAAG,8CAA8C;YAC/CpD,iBAAiB6B,aAAa,CAACpC,qBAAqB,CAAC;gBAAEgB,IAAI;gBAAGZ,MAAM;gBAAO0F,MAAMC,iBAAU,CAACzE,IAAI;YAAC;YACjGf,iBAAiB8B,kBAAkB,CAACrC,qBAAqB,CAAC;gBAAC;oBAAEgB,IAAI;gBAAE;gBAAG;oBAAEA,IAAI;gBAAE;aAAE;YAChF,MAAMgF,WAAW,MAAM3F,QAAQ4F,YAAY,CAAC,OAAOF,iBAAU,CAACzE,IAAI;YAClE9B,OAAOwG,SAASE,WAAW,EAAEpC,OAAO,CAAC;gBAAE9C,IAAI;gBAAGZ,MAAM;gBAAO0F,MAAMC,iBAAU,CAACzE,IAAI;YAAC;YACjF9B,OAAOwG,SAASG,OAAO,EAAEC,YAAY,CAAC;YAEtC7F,iBAAiB+B,sBAAsB,CAACtC,qBAAqB,CAAC;gBAAC;oBAAEgB,IAAI;gBAAE;aAAE;YACzE,MAAMqF,OAAO,MAAMhG,QAAQ4F,YAAY,CAAChG,WAAW8F,iBAAU,CAACzE,IAAI;YAClE9B,OAAO6G,KAAKH,WAAW,EAAEN,aAAa;YACtCpG,OAAO6G,KAAKF,OAAO,EAAErC,OAAO,CAAC;gBAAC;oBAAE9C,IAAI;gBAAE;aAAE;YAExCT,iBAAiB6B,aAAa,CAACpC,qBAAqB,CAAC;YACrD,MAAMV,WAAWe,QAAQ4F,YAAY,CAAC;QACxC;QAEAtC,GAAG,2BAA2B;YAC5BpD,iBAAiBgC,WAAW,CAACvC,qBAAqB,CAAC;gBAAEgB,IAAI;YAAE;YAC3DxB,OAAO,MAAMa,QAAQiG,QAAQ,CAAC,IAAIxC,OAAO,CAAC;gBAAE9C,IAAI;YAAE;YAClDT,iBAAiBgC,WAAW,CAACvC,qBAAqB,CAAC;YACnD,MAAMV,WAAWe,QAAQiG,QAAQ,CAAC;QACpC;QAEA3C,GAAG,iDAAiD;YAClD,MAAMzE,MAA8B;gBAAEkB,MAAM;gBAAQ0F,MAAMC,iBAAU,CAACzE,IAAI;YAAC;YAC1Ef,iBAAiBM,YAAY,CAACkB,oBAAoB,CAAC/B,qBAAqB,CAAC;YACzEO,iBAAiBiC,WAAW,CAACxC,qBAAqB,CAAC;YACnDO,iBAAiBgC,WAAW,CAACvC,qBAAqB,CAAC;gBAAEgB,IAAI;gBAAKZ,MAAM;YAAO;YAC3EZ,OAAO,MAAMa,QAAQmC,WAAW,CAACtD,MAAM4E,OAAO,CAAC;gBAAE9C,IAAI;gBAAKZ,MAAM;YAAO;YAEvE,MAAMd,WAAWe,QAAQmC,WAAW,CAAC,CAAC;YAEtCjC,iBAAiBM,YAAY,CAACkB,oBAAoB,CAAC/B,qBAAqB,CAAC;YACzE,MAAMV,WAAWe,QAAQmC,WAAW,CAACtD;YACrCM,OAAOe,iBAAiBiC,WAAW,EAAE+D,qBAAqB,CAAC,IAAG,wBAAwB;YAEtFhG,iBAAiBM,YAAY,CAACkB,oBAAoB,CAAC/B,qBAAqB,CAAC;YACzEO,iBAAiBiC,WAAW,CAACkC,qBAAqB,CAAC,IAAIC,MAAM;YAC7D,MAAMrF,WAAWe,QAAQmC,WAAW,CAACtD;QACvC;QAEAyE,GAAG,iCAAiC;YAClCpD,iBAAiBM,YAAY,CAACkB,oBAAoB,CAAC/B,qBAAqB,CAAC;YACzEO,iBAAiBkC,WAAW,CAACzC,qBAAqB,CAAC;YACnDO,iBAAiBgC,WAAW,CAACvC,qBAAqB,CAAC;gBAAEgB,IAAI;gBAAGZ,MAAM;YAAM;YACxEZ,OAAO,MAAMa,QAAQoC,WAAW,CAAC,GAAG;gBAAErC,MAAM;YAAM,IAAW0D,OAAO,CAAC;gBAAE9C,IAAI;gBAAGZ,MAAM;YAAM;YAE1FG,iBAAiBkC,WAAW,CAACzC,qBAAqB,CAAC;YACnD,MAAMV,WAAWe,QAAQoC,WAAW,CAAC,GAAG,CAAC;QAC3C;QAEAkB,GAAG,8BAA8B;YAC/BpD,iBAAiBmC,WAAW,CAAC1C,qBAAqB,CAAC;YACnD,MAAMR,OAAOa,QAAQqC,WAAW,CAAC,IAAIiD,QAAQ,CAACC,aAAa;YAC3DrF,iBAAiBmC,WAAW,CAAC1C,qBAAqB,CAAC;YACnD,MAAMV,WAAWe,QAAQqC,WAAW,CAAC;QACvC;QAEAiB,GAAG,sCAAsC;YACvCpD,iBAAiBgC,WAAW,CAACvC,qBAAqB,CAAC;YACnD,MAAMV,WAAWe,QAAQsC,eAAe,CAAC,GAAG;gBAAC;gBAAG;aAAE;YAElDpC,iBAAiBgC,WAAW,CAACvC,qBAAqB,CAAC;gBAAEgB,IAAI;gBAAG8E,MAAMC,iBAAU,CAACzE,IAAI;YAAC;YAClFf,iBAAiBoC,eAAe,CAAC+B,qBAAqB,CAAC,IAAIC,MAAM;YACjE,MAAMrF,WAAWe,QAAQsC,eAAe,CAAC,GAAG;gBAAC;aAAE;QACjD;QAEAgB,GAAG,gEAAgE;YACjEpD,iBAAiBqC,mBAAmB,CAAC8B,qBAAqB,CAAC,IAAIC,MAAM;YACrE,MAAMrF,WAAWe,QAAQuC,mBAAmB,CAAC,GAAG,GAAG;gBAAExB,MAAMoF,qBAAe,CAACC,MAAM;YAAC;YAElFlG,iBAAiBsC,mBAAmB,CAAC6B,qBAAqB,CAAC,IAAIC,MAAM;YACrE,MAAMrF,WAAWe,QAAQwC,mBAAmB,CAAC,GAAG;QAClD;IACF;IAEA3C,SAAS,iBAAiB;QACxByD,GAAG,gDAAgD;YACjD,MAAMzE,MAAM;gBAAEwH,QAAQ;YAAK;YAC3BnG,iBAAiBM,YAAY,CAACoB,mBAAmB,CAACjC,qBAAqB,CAAC;gBAAC;oBAAEgB,IAAI;gBAAE;aAAE;YACnFxB,OAAO,MAAMa,QAAQsG,aAAa,CAACzH,MAAM4E,OAAO,CAAC;gBAAC;oBAAE9C,IAAI;gBAAE;aAAE;YAC5DxB,OAAOe,iBAAiBM,YAAY,CAACoB,mBAAmB,EAAE8B,oBAAoB,CAAC7E;QACjF;IACF;IAEAgB,SAAS,iBAAiB;QACxB,MAAMqE,MAAW,CAAC;QAClBZ,GAAG,iEAAiE;YAClE,MAAMiD,QAAQ,IAAI9G,oBAAS,CAAC;gBAAEkB,IAAI;YAAE,GAAU;YAC9C,MAAM1B,WAAWe,QAAQwG,eAAe,CAACD,OAAO,GAAGrC;YAEnDhE,iBAAiBM,YAAY,CAACiB,mBAAmB,CAAC9B,qBAAqB,CAAC;YACxE,MAAMV,WAAWe,QAAQwG,eAAe,CAACD,OAAO,GAAGrC;YAEnD,MAAMuC,SAAS,IAAIhH,oBAAS,CAAC;gBAAEkB,IAAI;gBAAG+F,UAAU;YAAK,GAAU;YAC/DxG,iBAAiBM,YAAY,CAACiB,mBAAmB,CAAC9B,qBAAqB,CAAC;YACxEO,iBAAiBM,YAAY,CAACa,IAAI,CAAC1B,qBAAqB,CAAC;gBAAEgB,IAAI;gBAAGC,OAAO;YAAO;YAChFX,gBAAgBmB,UAAU,CAACzB,qBAAqB,CAAC;gBAAEgH,aAAa;YAAI;YACpExH,OAAO,MAAMa,QAAQwG,eAAe,CAACC,QAAQ,GAAGvC,MAAMT,OAAO,CAAC;gBAAEkD,aAAa;YAAI;YAEjF,MAAMC,kBAAkB,IAAInH,oBAAS,CAAC;gBAAEkB,IAAI;YAAE,GAAU;YACxD,MAAM1B,WAAWe,QAAQ6G,qBAAqB,CAACD,iBAAiB1C;YAEhE,MAAM4C,eAAe,IAAIrH,oBAAS,CAAC;gBAAEkB,IAAI;gBAAGoG,oBAAoB;gBAAGC,sBAAsB;YAAI,GAAU;YACvG9G,iBAAiBM,YAAY,CAACa,IAAI,CAAC1B,qBAAqB,CAAC;gBAAEgB,IAAI;gBAAGI,MAAMC,eAAS,CAACC,IAAI;YAAC;YACvF,MAAMhC,WAAWe,QAAQ6G,qBAAqB,CAACC,cAAc5C;YAE7DhE,iBAAiBM,YAAY,CAACa,IAAI,CAAC1B,qBAAqB,CAAC;gBAAEgB,IAAI;gBAAGI,MAAMC,eAAS,CAACiG,aAAa;YAAC;YAChGhH,gBAAgBmB,UAAU,CAACzB,qBAAqB,CAAC;gBAAEgH,aAAa;YAAQ;YACxExH,OAAO,MAAMa,QAAQ6G,qBAAqB,CAACC,cAAc5C,MAAMT,OAAO,CAAC;gBAAEkD,aAAa;YAAQ;QAChG;IACF;IAEA9G,SAAS,WAAW;QAClByD,GAAG,qCAAqC;YACtC,MAAM4D,QAAQ;gBAAC;oBAAEvG,IAAI;gBAAE;aAAE;YACzBT,iBAAiBG,SAAS,CAACV,qBAAqB,CAACuH;YACjD/H,OAAO,MAAMa,QAAQK,SAAS,IAAIoD,OAAO,CAACyD;YAC1C/H,OAAOe,iBAAiBG,SAAS,EAAEqD,oBAAoB;YAEvD,MAAMyD,SAAS;gBAAC;oBAAExG,IAAI;gBAAE;aAAE;YAC1BT,iBAAiBM,YAAY,CAACC,UAAU,CAACd,qBAAqB,CAACwH;YAC/DhI,OAAO,MAAMa,QAAQS,UAAU,IAAIgD,OAAO,CAAC0D;YAC3ChI,OAAOe,iBAAiBM,YAAY,CAACC,UAAU,EAAEiD,oBAAoB,CAAC,MAAM,MAAM;QACpF;IACF;IAEA7D,SAAS,eAAe;QACtByD,GAAG,+DAA+D;YAChE,MAAM8D,UAAU,IAAI3H,oBAAS,CAAC;gBAAEkB,IAAI;YAAG,GAAU;YACjD,MAAM9B,MAAqB;gBAAE+B,OAAO;gBAAMC,OAAO;gBAAO/B,UAAU;gBAAO8E,UAAU,EAAE;YAAC;YACtF1D,iBAAiBM,YAAY,CAACmB,eAAe,CAAChC,qBAAqB,CAAC;YACpEO,iBAAiBM,YAAY,CAACc,iBAAiB,CAAC3B,qBAAqB,CAAC;YACtEJ;YACA,MAAM8H,gBAAgB;gBAAE1G,IAAI;gBAAKC,OAAO;gBAAMG,MAAMC,eAAS,CAAC6C,KAAK;YAAC;YACpEvD,SAAS+G;YAETlI,OAAO,MAAMa,QAAQsH,WAAW,CAACF,SAASvI,MAAM4E,OAAO,CAAC4D;YACxDlI,OAAOe,iBAAiBM,YAAY,CAACc,iBAAiB,EAAEoC,oBAAoB,CAC1EvE,OAAOiF,gBAAgB,CAAC;gBAAExD,OAAO;gBAAMC,OAAO;gBAAO+C,UAAU;oBAAC;iBAAG;YAAC,IACpE5C,eAAS,CAAC6C,KAAK;QAEnB;IACF;IAEAhE,SAAS,uBAAuB;QAC9ByD,GAAG,4BAA4B;YAC7B,MAAMK,QAAQ;gBAAEhD,IAAI;gBAAIC,OAAO;gBAAKC,OAAO;gBAAO+C,UAAU;oBAAC;wBAAEjD,IAAI;oBAAE;iBAAE;gBAAEI,MAAMC,eAAS,CAAC6C,KAAK;YAAC;YAC/F,MAAMmB,eAAe;gBAAE,GAAGrB,KAAK;gBAAE9C,OAAO;YAAQ;YAChDP,SAASqD;YACTzD,iBAAiBM,YAAY,CAACe,iBAAiB,CAAC5B,qBAAqB,CAAC;YACtEW,SAAS0E;YACT7F,OAAO,MAAMa,QAAQiF,WAAW,CAACtB,MAAMhD,EAAE,EAAE;gBAAEE,OAAO;YAAQ,IAAW4C,OAAO,CAACuB;QACjF;IACF;IAEAnF,SAAS,mBAAmB;QAC1ByD,GAAG,4CAA4C;YAC7CvE,GAAGX,YAAY,CAACuB,qBAAqB,CAAC;YACtC,MAAMR,OAAOa,QAAQuH,eAAe,CAAC,WAAWjC,QAAQ,CAACC,aAAa;YAEtExG,GAAGX,YAAY,CAACuB,qBAAqB,CAAC;YACtCZ,GAAGR,WAAW,CAAC8F,qBAAqB,CAAC,IAAIC,MAAM;YAC/C,MAAMrF,WAAWe,QAAQuH,eAAe,CAAC;QAC3C;IACF;IAEA1H,SAAS,kCAAkC;QACzCyD,GAAG,iCAAiC;YAClC,MAAMiB,UAAU;gBAAE,GAAG7D,QAAQ;YAAC;YAC9BP,QAAQoE;YACRrE,iBAAiBM,YAAY,CAACmB,eAAe,CAAChC,qBAAqB,CAAC;YACpEZ,GAAGX,YAAY,CAACuB,qBAAqB,CAAC;YACtCZ,GAAGX,YAAY,CAACuB,qBAAqB,CAAC;YACtCZ,GAAGT,SAAS,CAAC+F,qBAAqB,CAAC,IAAIC,MAAM;YAC7CvF,GAAGT,SAAS,CAACqB,qBAAqB,CAACC;YACnC,MAAMX,WAAWe,QAAQuB,iBAAiB,CAACgD,QAAQ5D,EAAE,EAAE;gBAAEC,OAAO;YAAY;YAC5EzB,OAAOJ,GAAGT,SAAS,EAAE4H,qBAAqB,CAAC;QAC7C;QAEA5C,GAAG,yCAAyC;YAC1C,MAAMiB,UAAU;gBAAE,GAAG7D,QAAQ;YAAC;YAC9BP,QAAQoE;YACRrE,iBAAiBM,YAAY,CAACmB,eAAe,CAAChC,qBAAqB,CAAC;YACpEZ,GAAGX,YAAY,CAACuB,qBAAqB,CAAC;YACtC,MAAMV,WAAWe,QAAQuB,iBAAiB,CAACgD,QAAQ5D,EAAE,EAAE;gBAAEC,OAAO;YAAY;YAC5EzB,OAAOJ,GAAGT,SAAS,EAAEsG,GAAG,CAACC,gBAAgB;QAC3C;IACF;AACF"}
@@ -60,6 +60,7 @@ let AdminUsersQueries = class AdminUsersQueries {
60
60
  lastName: _usersschema.users.lastName,
61
61
  notification: _usersschema.users.notification,
62
62
  permissions: _usersschema.users.permissions,
63
+ twoFaEnabled: (0, _drizzleorm.sql)`JSON_UNQUOTE(JSON_EXTRACT(${_usersschema.users.secrets}, ${_drizzleorm.sql.raw(`'$.${_user.USER_SECRET.TWO_FA_SECRET}'`)})) IS NOT NULL`.mapWith(Boolean),
63
64
  groups: (0, _utils.concatDistinctObjectsInArray)(_groupsschema.groups.id, {
64
65
  id: _groupsschema.groups.id,
65
66
  name: _groupsschema.groups.name,