@sync-in/server 1.9.3 → 1.10.0

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 (349) hide show
  1. package/CHANGELOG.md +41 -4
  2. package/environment/environment.dist.yaml +15 -5
  3. package/package.json +18 -19
  4. package/server/app.bootstrap.js +1 -1
  5. package/server/app.bootstrap.js.map +1 -1
  6. package/server/app.constants.js +3 -2
  7. package/server/app.constants.js.map +1 -1
  8. package/server/applications/files/constants/cache.js +2 -5
  9. package/server/applications/files/constants/cache.js.map +1 -1
  10. package/server/applications/files/constants/files.js +4 -0
  11. package/server/applications/files/constants/files.js.map +1 -1
  12. package/server/applications/files/constants/operations.js +4 -0
  13. package/server/applications/files/constants/operations.js.map +1 -1
  14. package/server/applications/files/constants/routes.js +1 -26
  15. package/server/applications/files/constants/routes.js.map +1 -1
  16. package/server/applications/files/files.config.js +15 -39
  17. package/server/applications/files/files.config.js.map +1 -1
  18. package/server/applications/files/files.controller.js +4 -4
  19. package/server/applications/files/files.controller.js.map +1 -1
  20. package/server/applications/files/files.module.js +12 -9
  21. package/server/applications/files/files.module.js.map +1 -1
  22. package/server/applications/files/interfaces/file-lock.interface.js.map +1 -1
  23. package/server/applications/files/interfaces/file-props.interface.js.map +1 -1
  24. package/server/applications/files/modules/collabora-online/collabora-online-environment.decorator.js +32 -0
  25. package/server/applications/files/modules/collabora-online/collabora-online-environment.decorator.js.map +1 -0
  26. package/server/applications/files/modules/collabora-online/collabora-online-manager.service.js +280 -0
  27. package/server/applications/files/modules/collabora-online/collabora-online-manager.service.js.map +1 -0
  28. package/server/applications/files/modules/collabora-online/collabora-online-manager.service.spec.js +552 -0
  29. package/server/applications/files/modules/collabora-online/collabora-online-manager.service.spec.js.map +1 -0
  30. package/server/applications/files/modules/collabora-online/collabora-online.config.js +40 -0
  31. package/server/applications/files/modules/collabora-online/collabora-online.config.js.map +1 -0
  32. package/server/applications/files/modules/collabora-online/collabora-online.constants.js +110 -0
  33. package/server/applications/files/modules/collabora-online/collabora-online.constants.js.map +1 -0
  34. package/server/applications/files/modules/collabora-online/collabora-online.controller.js +128 -0
  35. package/server/applications/files/modules/collabora-online/collabora-online.controller.js.map +1 -0
  36. package/server/applications/files/modules/collabora-online/collabora-online.controller.spec.js +47 -0
  37. package/server/applications/files/modules/collabora-online/collabora-online.controller.spec.js.map +1 -0
  38. package/server/applications/files/{interfaces/only-office-config.interface.js → modules/collabora-online/collabora-online.dtos.js} +1 -1
  39. package/server/applications/files/modules/collabora-online/collabora-online.dtos.js.map +1 -0
  40. package/server/applications/files/{guards/files-only-office.guard.js → modules/collabora-online/collabora-online.guard.js} +7 -21
  41. package/server/applications/files/modules/collabora-online/collabora-online.guard.js.map +1 -0
  42. package/server/applications/files/modules/collabora-online/collabora-online.guard.spec.js +86 -0
  43. package/server/applications/files/modules/collabora-online/collabora-online.guard.spec.js.map +1 -0
  44. package/server/applications/files/modules/collabora-online/collabora-online.interface.js +10 -0
  45. package/server/applications/files/modules/collabora-online/collabora-online.interface.js.map +1 -0
  46. package/server/applications/files/modules/collabora-online/collabora-online.module.js +41 -0
  47. package/server/applications/files/modules/collabora-online/collabora-online.module.js.map +1 -0
  48. package/server/applications/files/modules/collabora-online/collabora-online.routes.js +35 -0
  49. package/server/applications/files/modules/collabora-online/collabora-online.routes.js.map +1 -0
  50. package/server/applications/files/modules/collabora-online/collabora-online.strategy.js +59 -0
  51. package/server/applications/files/modules/collabora-online/collabora-online.strategy.js.map +1 -0
  52. package/server/applications/files/modules/collabora-online/collabora-online.utils.js +28 -0
  53. package/server/applications/files/modules/collabora-online/collabora-online.utils.js.map +1 -0
  54. package/server/applications/files/{decorators → modules/only-office}/only-office-environment.decorator.js +5 -5
  55. package/server/applications/files/modules/only-office/only-office-environment.decorator.js.map +1 -0
  56. package/server/applications/files/{services/files-only-office-manager.service.js → modules/only-office/only-office-manager.service.js} +101 -97
  57. package/server/applications/files/modules/only-office/only-office-manager.service.js.map +1 -0
  58. package/server/applications/files/modules/only-office/only-office-manager.service.spec.js +477 -0
  59. package/server/applications/files/modules/only-office/only-office-manager.service.spec.js.map +1 -0
  60. package/server/applications/files/modules/only-office/only-office.config.js +51 -0
  61. package/server/applications/files/modules/only-office/only-office.config.js.map +1 -0
  62. package/server/applications/files/modules/only-office/only-office.constants.js +417 -0
  63. package/server/applications/files/modules/only-office/only-office.constants.js.map +1 -0
  64. package/server/applications/files/{files-only-office.controller.js → modules/only-office/only-office.controller.js} +35 -52
  65. package/server/applications/files/modules/only-office/only-office.controller.js.map +1 -0
  66. package/server/applications/files/{files-only-office.controller.spec.js → modules/only-office/only-office.controller.spec.js} +24 -21
  67. package/server/applications/files/modules/only-office/only-office.controller.spec.js.map +1 -0
  68. package/server/applications/files/modules/only-office/only-office.dtos.js +10 -0
  69. package/server/applications/files/modules/only-office/only-office.dtos.js.map +1 -0
  70. package/server/applications/files/modules/only-office/only-office.guard.js +40 -0
  71. package/server/applications/files/modules/only-office/only-office.guard.js.map +1 -0
  72. package/server/applications/files/{guards/files-only-office.guard.spec.js → modules/only-office/only-office.guard.spec.js} +15 -21
  73. package/server/applications/files/modules/only-office/only-office.guard.spec.js.map +1 -0
  74. package/server/applications/files/modules/only-office/only-office.interface.js +10 -0
  75. package/server/applications/files/modules/only-office/only-office.interface.js.map +1 -0
  76. package/server/applications/files/modules/only-office/only-office.module.js +41 -0
  77. package/server/applications/files/modules/only-office/only-office.module.js.map +1 -0
  78. package/server/applications/files/modules/only-office/only-office.routes.js +45 -0
  79. package/server/applications/files/modules/only-office/only-office.routes.js.map +1 -0
  80. package/server/applications/files/{guards/files-only-office.strategy.js → modules/only-office/only-office.strategy.js} +11 -11
  81. package/server/applications/files/modules/only-office/only-office.strategy.js.map +1 -0
  82. package/server/applications/files/services/files-lock-manager.service.js +25 -33
  83. package/server/applications/files/services/files-lock-manager.service.js.map +1 -1
  84. package/server/applications/files/services/files-manager.service.js +17 -16
  85. package/server/applications/files/services/files-manager.service.js.map +1 -1
  86. package/server/applications/files/services/files-methods.service.js +2 -2
  87. package/server/applications/files/services/files-methods.service.js.map +1 -1
  88. package/server/applications/files/services/files-methods.service.spec.js +5 -5
  89. package/server/applications/files/services/files-methods.service.spec.js.map +1 -1
  90. package/server/applications/files/services/files-recents.service.js +4 -0
  91. package/server/applications/files/services/files-recents.service.js.map +1 -1
  92. package/server/applications/files/services/files-scheduler.service.js +24 -5
  93. package/server/applications/files/services/files-scheduler.service.js.map +1 -1
  94. package/server/applications/files/utils/files.js +10 -2
  95. package/server/applications/files/utils/files.js.map +1 -1
  96. package/server/applications/links/constants/routes.js +5 -0
  97. package/server/applications/links/constants/routes.js.map +1 -1
  98. package/server/applications/links/interfaces/link-space.interface.js.map +1 -1
  99. package/server/applications/links/links.controller.js +25 -5
  100. package/server/applications/links/links.controller.js.map +1 -1
  101. package/server/applications/links/services/links-manager.service.js +43 -21
  102. package/server/applications/links/services/links-manager.service.js.map +1 -1
  103. package/server/applications/links/services/links-manager.service.spec.js +4 -3
  104. package/server/applications/links/services/links-manager.service.spec.js.map +1 -1
  105. package/server/applications/links/services/links-queries.service.js +9 -2
  106. package/server/applications/links/services/links-queries.service.js.map +1 -1
  107. package/server/applications/shares/interfaces/share-link.interface.js.map +1 -1
  108. package/server/applications/shares/services/shares-manager.service.js +3 -0
  109. package/server/applications/shares/services/shares-manager.service.js.map +1 -1
  110. package/server/applications/shares/services/shares-manager.service.spec.js +2 -1
  111. package/server/applications/shares/services/shares-manager.service.spec.js.map +1 -1
  112. package/server/applications/shares/services/shares-queries.service.js +1 -0
  113. package/server/applications/shares/services/shares-queries.service.js.map +1 -1
  114. package/server/applications/spaces/constants/spaces.js +2 -2
  115. package/server/applications/spaces/constants/spaces.js.map +1 -1
  116. package/server/applications/spaces/decorators/space-override-permission.decorator.js +18 -0
  117. package/server/applications/spaces/decorators/space-override-permission.decorator.js.map +1 -0
  118. package/server/applications/spaces/guards/space.guard.js +40 -33
  119. package/server/applications/spaces/guards/space.guard.js.map +1 -1
  120. package/server/applications/spaces/guards/space.guard.spec.js +10 -15
  121. package/server/applications/spaces/guards/space.guard.spec.js.map +1 -1
  122. package/server/applications/spaces/services/spaces-scheduler.service.js +9 -1
  123. package/server/applications/spaces/services/spaces-scheduler.service.js.map +1 -1
  124. package/server/applications/webdav/constants/webdav.js +4 -0
  125. package/server/applications/webdav/constants/webdav.js.map +1 -1
  126. package/server/applications/webdav/guards/webdav-protocol.guard.js +9 -8
  127. package/server/applications/webdav/guards/webdav-protocol.guard.js.map +1 -1
  128. package/server/applications/webdav/guards/webdav-protocol.guard.spec.js +1 -1
  129. package/server/applications/webdav/guards/webdav-protocol.guard.spec.js.map +1 -1
  130. package/server/applications/webdav/interfaces/webdav.interface.js.map +1 -1
  131. package/server/applications/webdav/services/webdav-methods.service.js +40 -17
  132. package/server/applications/webdav/services/webdav-methods.service.js.map +1 -1
  133. package/server/applications/webdav/services/webdav-methods.service.spec.js +2157 -1289
  134. package/server/applications/webdav/services/webdav-methods.service.spec.js.map +1 -1
  135. package/server/applications/webdav/utils/webdav.js +8 -4
  136. package/server/applications/webdav/utils/webdav.js.map +1 -1
  137. package/server/applications/webdav/webdav.controller.js +4 -4
  138. package/server/applications/webdav/webdav.controller.js.map +1 -1
  139. package/server/authentication/guards/auth-token-access.guard.js +8 -3
  140. package/server/authentication/guards/auth-token-access.guard.js.map +1 -1
  141. package/server/authentication/services/auth-methods/auth-method-two-fa.service.js +1 -1
  142. package/server/authentication/services/auth-methods/auth-method-two-fa.service.js.map +1 -1
  143. package/server/authentication/services/auth-methods/auth-method-two-fa.service.spec.js +350 -4
  144. package/server/authentication/services/auth-methods/auth-method-two-fa.service.spec.js.map +1 -1
  145. package/server/configuration/config.environment.js +5 -1
  146. package/server/configuration/config.environment.js.map +1 -1
  147. package/server/configuration/config.interfaces.js.map +1 -1
  148. package/static/3rdpartylicenses.txt +507 -507
  149. package/static/assets/pdfjs/build/pdf.mjs +93 -33
  150. package/static/assets/pdfjs/build/pdf.mjs.map +1 -1
  151. package/static/assets/pdfjs/build/pdf.sandbox.mjs +3 -3
  152. package/static/assets/pdfjs/build/pdf.sandbox.mjs.map +1 -1
  153. package/static/assets/pdfjs/build/pdf.worker.mjs +166 -54
  154. package/static/assets/pdfjs/build/pdf.worker.mjs.map +1 -1
  155. package/static/assets/pdfjs/version +1 -1
  156. package/static/assets/pdfjs/web/images/checkmark.svg +5 -0
  157. package/static/assets/pdfjs/web/images/pages_closeButton.svg +3 -0
  158. package/static/assets/pdfjs/web/images/pages_selected.svg +7 -0
  159. package/static/assets/pdfjs/web/images/pages_viewArrow.svg +3 -0
  160. package/static/assets/pdfjs/web/images/pages_viewButton.svg +3 -0
  161. package/static/assets/pdfjs/web/locale/be/viewer.ftl +0 -2
  162. package/static/assets/pdfjs/web/locale/bs/viewer.ftl +0 -5
  163. package/static/assets/pdfjs/web/locale/cs/viewer.ftl +4 -6
  164. package/static/assets/pdfjs/web/locale/cy/viewer.ftl +0 -2
  165. package/static/assets/pdfjs/web/locale/da/viewer.ftl +0 -2
  166. package/static/assets/pdfjs/web/locale/de/viewer.ftl +0 -2
  167. package/static/assets/pdfjs/web/locale/dsb/viewer.ftl +0 -2
  168. package/static/assets/pdfjs/web/locale/el/viewer.ftl +0 -2
  169. package/static/assets/pdfjs/web/locale/en-CA/viewer.ftl +6 -2
  170. package/static/assets/pdfjs/web/locale/en-GB/viewer.ftl +0 -2
  171. package/static/assets/pdfjs/web/locale/en-US/viewer.ftl +82 -17
  172. package/static/assets/pdfjs/web/locale/eo/viewer.ftl +0 -2
  173. package/static/assets/pdfjs/web/locale/es-AR/viewer.ftl +0 -2
  174. package/static/assets/pdfjs/web/locale/es-CL/viewer.ftl +0 -2
  175. package/static/assets/pdfjs/web/locale/es-ES/viewer.ftl +0 -2
  176. package/static/assets/pdfjs/web/locale/es-MX/viewer.ftl +0 -2
  177. package/static/assets/pdfjs/web/locale/eu/viewer.ftl +0 -2
  178. package/static/assets/pdfjs/web/locale/fi/viewer.ftl +0 -2
  179. package/static/assets/pdfjs/web/locale/fr/viewer.ftl +0 -2
  180. package/static/assets/pdfjs/web/locale/fur/viewer.ftl +0 -5
  181. package/static/assets/pdfjs/web/locale/fy-NL/viewer.ftl +3 -5
  182. package/static/assets/pdfjs/web/locale/gn/viewer.ftl +0 -2
  183. package/static/assets/pdfjs/web/locale/he/viewer.ftl +0 -2
  184. package/static/assets/pdfjs/web/locale/hr/viewer.ftl +66 -0
  185. package/static/assets/pdfjs/web/locale/hsb/viewer.ftl +0 -2
  186. package/static/assets/pdfjs/web/locale/hu/viewer.ftl +0 -2
  187. package/static/assets/pdfjs/web/locale/hy-AM/viewer.ftl +3 -8
  188. package/static/assets/pdfjs/web/locale/ia/viewer.ftl +0 -2
  189. package/static/assets/pdfjs/web/locale/id/viewer.ftl +0 -5
  190. package/static/assets/pdfjs/web/locale/is/viewer.ftl +0 -5
  191. package/static/assets/pdfjs/web/locale/it/viewer.ftl +0 -2
  192. package/static/assets/pdfjs/web/locale/ja/viewer.ftl +0 -14
  193. package/static/assets/pdfjs/web/locale/ka/viewer.ftl +4 -6
  194. package/static/assets/pdfjs/web/locale/kab/viewer.ftl +0 -5
  195. package/static/assets/pdfjs/web/locale/kk/viewer.ftl +0 -2
  196. package/static/assets/pdfjs/web/locale/ko/viewer.ftl +0 -2
  197. package/static/assets/pdfjs/web/locale/nb-NO/viewer.ftl +1 -3
  198. package/static/assets/pdfjs/web/locale/nl/viewer.ftl +0 -2
  199. package/static/assets/pdfjs/web/locale/nn-NO/viewer.ftl +4 -2
  200. package/static/assets/pdfjs/web/locale/pa-IN/viewer.ftl +0 -2
  201. package/static/assets/pdfjs/web/locale/pl/viewer.ftl +0 -2
  202. package/static/assets/pdfjs/web/locale/pt-BR/viewer.ftl +0 -2
  203. package/static/assets/pdfjs/web/locale/pt-PT/viewer.ftl +35 -0
  204. package/static/assets/pdfjs/web/locale/rm/viewer.ftl +0 -5
  205. package/static/assets/pdfjs/web/locale/ro/viewer.ftl +4 -6
  206. package/static/assets/pdfjs/web/locale/ru/viewer.ftl +3 -5
  207. package/static/assets/pdfjs/web/locale/sk/viewer.ftl +0 -2
  208. package/static/assets/pdfjs/web/locale/sl/viewer.ftl +0 -2
  209. package/static/assets/pdfjs/web/locale/sq/viewer.ftl +0 -2
  210. package/static/assets/pdfjs/web/locale/sv-SE/viewer.ftl +0 -2
  211. package/static/assets/pdfjs/web/locale/tg/viewer.ftl +0 -2
  212. package/static/assets/pdfjs/web/locale/th/viewer.ftl +2 -2
  213. package/static/assets/pdfjs/web/locale/tr/viewer.ftl +0 -2
  214. package/static/assets/pdfjs/web/locale/vi/viewer.ftl +0 -2
  215. package/static/assets/pdfjs/web/locale/zh-CN/viewer.ftl +0 -2
  216. package/static/assets/pdfjs/web/locale/zh-TW/viewer.ftl +0 -2
  217. package/static/assets/pdfjs/web/viewer.css +1778 -835
  218. package/static/assets/pdfjs/web/viewer.html +167 -86
  219. package/static/assets/pdfjs/web/viewer.mjs +1106 -801
  220. package/static/assets/pdfjs/web/viewer.mjs.map +1 -1
  221. package/static/chunk-27V66YJV.js +2 -0
  222. package/static/{chunk-WJYVS27M.js → chunk-27Z3SYRL.js} +1 -1
  223. package/static/{chunk-NFIES7BC.js → chunk-2RWLNKZH.js} +1 -1
  224. package/static/chunk-2YQ4SX3A.js +13 -0
  225. package/static/{chunk-GENTF6JM.js → chunk-3JYMJQYT.js} +1 -1
  226. package/static/chunk-3QTROEHV.js +1 -0
  227. package/static/{chunk-ZPI7RQ2S.js → chunk-3RPUQ22U.js} +1 -1
  228. package/static/{chunk-R6VB3INJ.js → chunk-3WZ6F3LC.js} +1 -1
  229. package/static/chunk-3ZLBVUCX.js +2 -0
  230. package/static/{chunk-5HCVWZMA.js → chunk-45AZ6ZML.js} +1 -1
  231. package/static/chunk-46TJLPJY.js +1 -0
  232. package/static/chunk-4NIYCYRS.js +2 -0
  233. package/static/{chunk-XXYMVRSH.js → chunk-4TPFERL6.js} +1 -1
  234. package/static/{chunk-CAZSNVMS.js → chunk-5O66CLTD.js} +1 -1
  235. package/static/chunk-6OEOADR6.js +1 -0
  236. package/static/chunk-6WMXMIE4.js +1 -0
  237. package/static/{chunk-NK2NMAJI.js → chunk-7VRYTDX4.js} +1 -1
  238. package/static/{chunk-ASBPYTLT.js → chunk-ARS47O5X.js} +1 -1
  239. package/static/chunk-B6HQYQYG.js +1 -0
  240. package/static/chunk-BCN4T5DO.js +2 -0
  241. package/static/{chunk-PKU4IIIR.js → chunk-CCZWPM7Q.js} +1 -1
  242. package/static/{chunk-QUSS6SUC.js → chunk-CMNMPG6Z.js} +1 -1
  243. package/static/{chunk-GDPJRUVU.js → chunk-CSVPAZHK.js} +1 -1
  244. package/static/{chunk-BJARRIS6.js → chunk-D55YR5X7.js} +4 -4
  245. package/static/{chunk-Z6RJZIDG.js → chunk-D5FQ72R4.js} +1 -1
  246. package/static/{chunk-4DF2SQD4.js → chunk-DGCVA6BM.js} +1 -1
  247. package/static/{chunk-TVJQXN73.js → chunk-DVCN3P7Q.js} +1 -1
  248. package/static/chunk-E32J777S.js +5 -0
  249. package/static/{chunk-5NHB7SV3.js → chunk-FIUF2JM4.js} +1 -1
  250. package/static/{chunk-RJOHDAPM.js → chunk-G3PL6YX3.js} +1 -1
  251. package/static/chunk-G7RZN7HN.js +1 -0
  252. package/static/{chunk-DDRGLHOP.js → chunk-GQHXYX6Z.js} +1 -1
  253. package/static/{chunk-5HYSNQR4.js → chunk-GWRAGN3M.js} +1 -1
  254. package/static/{chunk-ZC5ZDCDC.js → chunk-GXWGB7WO.js} +1 -1
  255. package/static/{chunk-25PWAXTJ.js → chunk-HGODIZTV.js} +1 -1
  256. package/static/{chunk-4KXJ6C4N.js → chunk-HZAB6F4Q.js} +1 -1
  257. package/static/chunk-I3FR3A45.js +1 -0
  258. package/static/{chunk-A6J6SOM6.js → chunk-I5SPA4G2.js} +1 -1
  259. package/static/{chunk-TGHBDJZA.js → chunk-IMFO2MI7.js} +1 -1
  260. package/static/{chunk-CURVLK7L.js → chunk-JNTNMIUH.js} +1 -1
  261. package/static/chunk-JRXG43AA.js +2 -0
  262. package/static/{chunk-XAIOGRBO.js → chunk-KAUCN24H.js} +1 -1
  263. package/static/chunk-KDUAB76O.js +1 -0
  264. package/static/chunk-KPOQLDWF.js +1 -0
  265. package/static/{chunk-HE6EDXWI.js → chunk-KWFELZTM.js} +1 -1
  266. package/static/{chunk-2CAAJBRO.js → chunk-L3BIP4AA.js} +1 -1
  267. package/static/{chunk-U75PLYIJ.js → chunk-LGIVVJDD.js} +1 -1
  268. package/static/{chunk-JEVBUJQ4.js → chunk-LNLBIJZD.js} +1 -1
  269. package/static/chunk-LTJNLOX2.js +1 -0
  270. package/static/{chunk-SDR3UG2F.js → chunk-LZUHREOF.js} +1 -1
  271. package/static/{chunk-VO4WVT6K.js → chunk-NIR4YE2E.js} +1 -1
  272. package/static/{chunk-S6YKBWJE.js → chunk-NJJURHX4.js} +1 -1
  273. package/static/chunk-NNZWSNAW.js +1 -0
  274. package/static/chunk-NWKBB7J4.js +1 -0
  275. package/static/chunk-O3YLAEVE.js +3 -0
  276. package/static/chunk-OUHCDDT6.js +1 -0
  277. package/static/{chunk-ZRBLCAOK.js → chunk-PDG7DOEF.js} +1 -1
  278. package/static/chunk-POUWUMC4.js +1 -0
  279. package/static/{chunk-YTBSB2GE.js → chunk-PPJCVBJH.js} +1 -1
  280. package/static/{chunk-K3MOXDU5.js → chunk-PQZLR4P3.js} +1 -1
  281. package/static/chunk-PVYVY3GD.js +1 -0
  282. package/static/chunk-Q5X5TPAG.js +1 -0
  283. package/static/{chunk-LFAQLJZK.js → chunk-QHJT5H4M.js} +1 -1
  284. package/static/{chunk-A7DSX7VP.js → chunk-R4VMWCM5.js} +1 -1
  285. package/static/{chunk-27XEAHMV.js → chunk-R7PLNX75.js} +1 -1
  286. package/static/chunk-RJULB733.js +1 -0
  287. package/static/{chunk-MBFMTBVJ.js → chunk-RNVPQQKT.js} +5 -5
  288. package/static/chunk-RTNEBRKJ.js +1 -0
  289. package/static/{chunk-FXM7XXWA.js → chunk-S3TTWPQA.js} +1 -1
  290. package/static/{chunk-6VJI4X2A.js → chunk-SDJNZULP.js} +1 -1
  291. package/static/chunk-SNOOCDJD.js +1 -0
  292. package/static/chunk-T42BV6TR.js +1 -0
  293. package/static/{chunk-4OV3SAUS.js → chunk-TNCKNU6I.js} +1 -1
  294. package/static/{chunk-2LHHXDD5.js → chunk-ULSPQ3HP.js} +1 -1
  295. package/static/{chunk-4EUHBTWV.js → chunk-UOK3LKSX.js} +1 -1
  296. package/static/{chunk-7NI353LS.js → chunk-VD5JHSDS.js} +1 -1
  297. package/static/{chunk-YXWF2DGF.js → chunk-XBKCQCBI.js} +1 -1
  298. package/static/{chunk-KBWK65KM.js → chunk-XEWLBWFF.js} +1 -1
  299. package/static/{chunk-FLPZB3OX.js → chunk-XTVNHFKX.js} +1 -1
  300. package/static/chunk-ZCSHU3D7.js +1 -0
  301. package/static/{chunk-FRBTL2ER.js → chunk-ZEJLIGAY.js} +1 -1
  302. package/static/{chunk-7H5O4BLV.js → chunk-ZHOE5VEY.js} +1 -1
  303. package/static/chunk-ZOMRIN3G.js +2 -0
  304. package/static/index.html +2 -2
  305. package/static/main-YKDNJ7LK.js +11 -0
  306. package/static/{styles-S5HVK4H5.css → styles-XLLEY5Y3.css} +1 -1
  307. package/server/applications/files/constants/only-office.js +0 -531
  308. package/server/applications/files/constants/only-office.js.map +0 -1
  309. package/server/applications/files/decorators/only-office-environment.decorator.js.map +0 -1
  310. package/server/applications/files/files-only-office.controller.js.map +0 -1
  311. package/server/applications/files/files-only-office.controller.spec.js.map +0 -1
  312. package/server/applications/files/guards/files-only-office.guard.js.map +0 -1
  313. package/server/applications/files/guards/files-only-office.guard.spec.js.map +0 -1
  314. package/server/applications/files/guards/files-only-office.strategy.js.map +0 -1
  315. package/server/applications/files/interfaces/only-office-config.interface.js.map +0 -1
  316. package/server/applications/files/services/files-only-office-manager.service.js.map +0 -1
  317. package/server/applications/files/services/files-only-office-manager.service.spec.js +0 -58
  318. package/server/applications/files/services/files-only-office-manager.service.spec.js.map +0 -1
  319. package/static/chunk-2XY4PMI5.js +0 -1
  320. package/static/chunk-33WFRCUP.js +0 -1
  321. package/static/chunk-3LVFDMTN.js +0 -1
  322. package/static/chunk-42L6C5MT.js +0 -1
  323. package/static/chunk-5WCQBTXW.js +0 -1
  324. package/static/chunk-A7R246NW.js +0 -1
  325. package/static/chunk-BSB4VROD.js +0 -2
  326. package/static/chunk-DHFQIFOF.js +0 -1
  327. package/static/chunk-DRHPEERW.js +0 -2
  328. package/static/chunk-FCGTI42I.js +0 -1
  329. package/static/chunk-H4RLHI3Y.js +0 -1
  330. package/static/chunk-ITVA26X2.js +0 -2
  331. package/static/chunk-IUJ4IK26.js +0 -1
  332. package/static/chunk-L3PDWJZ3.js +0 -3
  333. package/static/chunk-LBXOAKBD.js +0 -1
  334. package/static/chunk-LZKI5P5T.js +0 -1
  335. package/static/chunk-MYM43ENO.js +0 -1
  336. package/static/chunk-MZBO5PAR.js +0 -1
  337. package/static/chunk-NAH4V2R6.js +0 -2
  338. package/static/chunk-O7UXVNR2.js +0 -1
  339. package/static/chunk-PCFH5HCI.js +0 -2
  340. package/static/chunk-SRBOO7AO.js +0 -1
  341. package/static/chunk-UUX3M6DC.js +0 -1
  342. package/static/chunk-VJ2HWQRJ.js +0 -5
  343. package/static/chunk-VZPCXSRG.js +0 -2
  344. package/static/chunk-W72JYHOH.js +0 -1
  345. package/static/chunk-XHQEF2IX.js +0 -1
  346. package/static/chunk-XKEBQNQJ.js +0 -1
  347. package/static/chunk-ZERBTNFW.js +0 -13
  348. package/static/main-FE6GWZXU.js +0 -11
  349. /package/static/assets/pdfjs/web/images/{toolbarButton-sidebarToggle.svg → toolbarButton-viewsManagerToggle.svg} +0 -0
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../backend/src/applications/links/services/links-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 { HttpService } from '@nestjs/axios'\nimport { ConfigService } from '@nestjs/config'\nimport { JwtService } from '@nestjs/jwt'\nimport { Test, TestingModule } from '@nestjs/testing'\nimport { AuthManager } from '../../../authentication/services/auth-manager.service'\nimport { Cache } from '../../../infrastructure/cache/services/cache.service'\nimport { ContextManager } from '../../../infrastructure/context/services/context-manager.service'\nimport { DB_TOKEN_PROVIDER } from '../../../infrastructure/database/constants'\nimport { FilesLockManager } from '../../files/services/files-lock-manager.service'\nimport { FilesManager } from '../../files/services/files-manager.service'\nimport { FilesQueries } from '../../files/services/files-queries.service'\nimport { NotificationsManager } from '../../notifications/services/notifications-manager.service'\nimport { SharesManager } from '../../shares/services/shares-manager.service'\nimport { SharesQueries } from '../../shares/services/shares-queries.service'\nimport { SpacesManager } from '../../spaces/services/spaces-manager.service'\nimport { SpacesQueries } from '../../spaces/services/spaces-queries.service'\nimport { UserModel } from '../../users/models/user.model'\nimport { AdminUsersManager } from '../../users/services/admin-users-manager.service'\nimport { AdminUsersQueries } from '../../users/services/admin-users-queries.service'\nimport { UsersManager } from '../../users/services/users-manager.service'\nimport { UsersQueries } from '../../users/services/users-queries.service'\nimport { getAvatarBase64 } from '../../users/utils/avatar'\nimport { LinksManager } from './links-manager.service'\nimport { LinksQueries } from './links-queries.service'\n\njest.mock('../../users/utils/avatar', () => ({\n getAvatarBase64: jest.fn()\n}))\n\ndescribe(LinksManager.name, () => {\n let service: LinksManager\n let linksQueriesMock: jest.Mocked<LinksQueries>\n let usersManagerMock: jest.Mocked<UsersManager>\n let filesManagerMock: jest.Mocked<FilesManager>\n let spacesManagerMock: jest.Mocked<SpacesManager>\n let authManagerMock: jest.Mocked<AuthManager>\n\n const identity: any = { id: 42, login: 'visitor' }\n const baseLink: any = {\n uuid: 'uuid-123',\n user: { id: 7, login: 'john', isActive: true },\n requireAuth: false,\n limitAccess: 0,\n nbAccess: 0,\n expiresAt: null\n }\n\n beforeAll(async () => {\n linksQueriesMock = {\n linkFromUUID: jest.fn(),\n spaceLink: jest.fn(),\n incrementLinkNbAccess: jest.fn().mockResolvedValue(undefined)\n } as any\n\n usersManagerMock = {\n compareUserPassword: jest.fn(),\n updateAccesses: jest.fn()\n } as any\n\n filesManagerMock = {\n sendFileFromSpace: jest.fn()\n } as any\n\n spacesManagerMock = {\n spaceEnv: jest.fn()\n } as any\n\n authManagerMock = {\n setCookies: jest.fn()\n } as any\n\n const module: TestingModule = await Test.createTestingModule({\n providers: [\n {\n provide: DB_TOKEN_PROVIDER,\n useValue: {}\n },\n {\n provide: Cache,\n useValue: {}\n },\n { provide: ContextManager, useValue: {} },\n {\n provide: NotificationsManager,\n useValue: {}\n },\n { provide: HttpService, useValue: {} },\n { provide: FilesLockManager, useValue: {} },\n { provide: ConfigService, useValue: {} },\n { provide: JwtService, useValue: {} },\n { provide: AuthManager, useValue: authManagerMock },\n { provide: UsersManager, useValue: usersManagerMock },\n { provide: UsersQueries, useValue: {} },\n { provide: AdminUsersManager, useValue: {} },\n { provide: AdminUsersQueries, useValue: {} },\n { provide: FilesQueries, useValue: {} },\n { provide: FilesManager, useValue: filesManagerMock },\n { provide: SpacesQueries, useValue: {} },\n { provide: SpacesManager, useValue: spacesManagerMock },\n { provide: SharesQueries, useValue: {} },\n { provide: SharesManager, useValue: {} },\n { provide: LinksQueries, useValue: linksQueriesMock },\n LinksManager\n ]\n }).compile()\n\n module.useLogger(['fatal'])\n service = module.get<LinksManager>(LinksManager)\n })\n\n beforeEach(() => {\n jest.clearAllMocks()\n })\n\n it('should be defined', () => {\n expect(service).toBeDefined()\n })\n\n describe('linkValidation', () => {\n it('returns ok with sanitized owner and avatar when link is valid', async () => {\n const link = { ...baseLink }\n linksQueriesMock.linkFromUUID.mockResolvedValueOnce(link)\n const spaceLink = {\n owner: { login: 'jane' },\n share: { isDir: true, alias: 's-alias', name: 'Docs' },\n space: null\n } as any\n linksQueriesMock.spaceLink.mockResolvedValueOnce(spaceLink)\n ;(getAvatarBase64 as jest.Mock).mockResolvedValueOnce('base64-xxx')\n\n const res = await service.linkValidation(identity, link.uuid)\n\n expect(res.ok).toBe(true)\n expect(res.error).toBeNull()\n expect(res.link).toBe(spaceLink)\n expect((spaceLink.owner as any).login).toBeUndefined()\n expect(linksQueriesMock.spaceLink).toHaveBeenCalledWith(link.uuid)\n expect(getAvatarBase64).toHaveBeenCalledWith('jane')\n\n // extra coverage: directly assert private checkLink with default ignoreAuth=false\n const directCheck = (service as any).checkLink(identity, link)\n expect(directCheck).toBe(true)\n })\n\n it('returns error and null link when uuid is not found', async () => {\n linksQueriesMock.linkFromUUID.mockResolvedValueOnce(null)\n\n const res = await service.linkValidation(identity, 'missing-uuid')\n\n expect(res.ok).toBe(false)\n expect(res.error).toBeDefined()\n expect(res.link).toBeNull()\n })\n\n it('returns unauthorized when auth is required and identity differs', async () => {\n const link = { ...baseLink, requireAuth: true }\n linksQueriesMock.linkFromUUID.mockResolvedValueOnce(link)\n\n const res = await service.linkValidation(identity, link.uuid)\n\n expect(res.ok).toBe(false)\n expect(String(res.error).toLowerCase()).toContain('unauthorized')\n expect(res.link).toBeNull()\n\n // extra coverage: directly assert private checkLink with default ignoreAuth=false\n const directCheck = (service as any).checkLink(identity, link)\n expect(String(directCheck).toLowerCase()).toContain('unauthorized')\n })\n\n it('returns exceeded when nbAccess >= limitAccess', async () => {\n const link = { ...baseLink, limitAccess: 5, nbAccess: 5 }\n linksQueriesMock.linkFromUUID.mockResolvedValueOnce(link)\n\n const res = await service.linkValidation(identity, link.uuid)\n\n expect(res.ok).toBe(false)\n expect(String(res.error).toLowerCase()).toContain('exceeded')\n })\n })\n\n describe('linkAccess', () => {\n const req: any = { ip: '127.0.0.1' }\n const res: any = {}\n\n it('streams a file when link targets a single file', async () => {\n const link = { ...baseLink, limitAccess: 10 }\n linksQueriesMock.linkFromUUID.mockResolvedValueOnce(link)\n const spaceLink = {\n space: null,\n share: { isDir: false, name: 'file.txt', alias: 'share-alias' }\n } as any\n linksQueriesMock.spaceLink.mockResolvedValueOnce(spaceLink)\n\n spacesManagerMock.spaceEnv.mockResolvedValueOnce({} as any)\n const streamable: any = { some: 'stream' }\n filesManagerMock.sendFileFromSpace.mockReturnValueOnce({\n checks: jest.fn().mockResolvedValueOnce(undefined),\n stream: jest.fn().mockResolvedValueOnce(streamable)\n } as any)\n\n // cover: incrementLinkNbAccess.catch(...) should log an error when the query rejects\n const logErrorSpy = jest.spyOn((service as any).logger, 'error').mockImplementation(() => undefined as any)\n linksQueriesMock.incrementLinkNbAccess.mockRejectedValueOnce(new Error('increment boom'))\n\n const result = await service.linkAccess(identity, link.uuid, req, res)\n\n expect(result).toBe(streamable)\n expect(filesManagerMock.sendFileFromSpace).toHaveBeenCalled()\n expect(linksQueriesMock.incrementLinkNbAccess).toHaveBeenCalledWith(link.uuid)\n // Assert repository selection for a share file (space falsy)\n // should call spacesManager.spaceEnv with SHARES and share alias when link.space is falsy\n expect(spacesManagerMock.spaceEnv).toHaveBeenCalledWith(expect.anything(), ['shares', 'share-alias'])\n // should log error when increment fails\n expect(logErrorSpy).toHaveBeenCalled()\n })\n\n it('authenticates and returns cookies when link targets a directory and user is different', async () => {\n const link = { ...baseLink, requireAuth: false, user: { id: 7, login: 'john', isActive: true } }\n linksQueriesMock.linkFromUUID.mockResolvedValueOnce(link)\n const spaceLink = {\n space: { alias: 'files', name: 'My Space' },\n share: { isDir: true, name: 'ignored', alias: 'ignored' }\n } as any\n linksQueriesMock.spaceLink.mockResolvedValueOnce(spaceLink)\n\n const loginDto: any = { token: 'jwt' }\n authManagerMock.setCookies.mockResolvedValueOnce(loginDto)\n\n // cover: usersManager.updateAccesses.catch(...) should log an error when updateAccesses rejects\n const logErrorSpy = jest.spyOn((service as any).logger, 'error').mockImplementation(() => undefined as any)\n usersManagerMock.updateAccesses.mockRejectedValueOnce(new Error('updateAccesses boom'))\n\n const result = await service.linkAccess(identity, link.uuid, req, res)\n\n expect(result).toBe(loginDto)\n expect(usersManagerMock.updateAccesses).toHaveBeenCalledWith(expect.anything(), req.ip, true)\n expect(authManagerMock.setCookies).toHaveBeenCalled()\n // additionally cover the \"space truthy\" branch by calling the private helper directly\n // should call spacesManager.spaceEnv with FILES and space alias when link.space is truthy\n await (service as any).spaceEnvFromLink(new UserModel(link.user as any), spaceLink as any)\n expect(spacesManagerMock.spaceEnv).toHaveBeenCalledWith(expect.anything(), ['files', 'files'])\n // should log error when updateAccesses fails\n expect(logErrorSpy).toHaveBeenCalled()\n })\n\n it('throws BAD_REQUEST when link is invalid', async () => {\n const disabledLink = { ...baseLink, user: { id: 7, login: 'john', isActive: false } }\n linksQueriesMock.linkFromUUID.mockResolvedValueOnce(disabledLink)\n\n await expect(service.linkAccess(identity, disabledLink.uuid, req, res)).rejects.toMatchObject({\n status: 400\n })\n })\n\n it('returns undefined for already authenticated directory access (same user) and does not set cookies or increment', async () => {\n const sameUserIdentity = { id: baseLink.user.id, login: 'john' }\n const link = { ...baseLink, requireAuth: true }\n linksQueriesMock.linkFromUUID.mockResolvedValueOnce(link)\n const spaceLink = {\n space: { alias: 'files', name: 'Space' },\n share: { isDir: true, name: 'dir', alias: 'share' }\n } as any\n linksQueriesMock.spaceLink.mockResolvedValueOnce(spaceLink)\n\n const result = await service.linkAccess(sameUserIdentity as any, link.uuid, req, res)\n\n expect(result).toBeUndefined()\n expect(authManagerMock.setCookies).not.toHaveBeenCalled()\n expect(linksQueriesMock.incrementLinkNbAccess).not.toHaveBeenCalled()\n })\n\n it('throws INTERNAL_SERVER_ERROR when file checks fail during streaming', async () => {\n const link = { ...baseLink, limitAccess: 10 }\n linksQueriesMock.linkFromUUID.mockResolvedValueOnce(link)\n const spaceLink = {\n space: null,\n share: { isDir: false, name: 'bad.txt', alias: 'share' }\n } as any\n linksQueriesMock.spaceLink.mockResolvedValueOnce(spaceLink)\n\n spacesManagerMock.spaceEnv.mockResolvedValueOnce({} as any)\n filesManagerMock.sendFileFromSpace.mockReturnValueOnce({\n checks: jest.fn().mockRejectedValueOnce(new Error('disk error')),\n stream: jest.fn()\n } as any)\n\n await expect(service.linkAccess(identity, link.uuid, req, res)).rejects.toMatchObject({\n status: 500\n })\n expect(linksQueriesMock.incrementLinkNbAccess).toHaveBeenCalledWith(link.uuid)\n })\n })\n\n describe('linkAuthentication', () => {\n const req: any = { ip: '10.0.0.1' }\n const res: any = {}\n\n it('returns cookies when password is correct', async () => {\n const link = { ...baseLink, requireAuth: true }\n linksQueriesMock.linkFromUUID.mockResolvedValueOnce(link)\n usersManagerMock.compareUserPassword.mockResolvedValueOnce(true)\n // usersManagerMock.updateAccesses.mockResolvedValueOnce(undefined) // removed to ensure rejection is hit\n const loginDto: any = { token: 'abc' }\n authManagerMock.setCookies.mockResolvedValueOnce(loginDto)\n\n // cover: usersManager.updateAccesses.catch(...) should log an error when updateAccesses rejects (success flow)\n const logErrorSpy = jest.spyOn((service as any).logger, 'error').mockImplementation(() => undefined as any)\n usersManagerMock.updateAccesses.mockRejectedValueOnce(new Error('updateAccesses auth success boom'))\n\n const result = await service.linkAuthentication(identity, link.uuid, { password: 'secret' } as any, req, res)\n\n expect(result).toBe(loginDto)\n expect(usersManagerMock.compareUserPassword).toHaveBeenCalledWith(link.user.id, 'secret')\n expect(usersManagerMock.updateAccesses).toHaveBeenCalledWith(expect.anything(), req.ip, true)\n expect(authManagerMock.setCookies).toHaveBeenCalled()\n // should log error when updateAccesses fails in successful authentication\n expect(logErrorSpy).toHaveBeenCalled()\n })\n\n it('throws FORBIDDEN when password is incorrect', async () => {\n const link = { ...baseLink, requireAuth: true }\n linksQueriesMock.linkFromUUID.mockResolvedValueOnce(link)\n usersManagerMock.compareUserPassword.mockResolvedValueOnce(false)\n usersManagerMock.updateAccesses.mockResolvedValueOnce(undefined)\n\n await expect(service.linkAuthentication(identity, link.uuid, { password: 'bad' } as any, req, res)).rejects.toMatchObject({ status: 403 })\n })\n\n it('throws BAD_REQUEST when link is invalid (e.g., expired)', async () => {\n const expired = { ...baseLink, expiresAt: new Date(Date.now() - 60_000) }\n linksQueriesMock.linkFromUUID.mockResolvedValueOnce(expired)\n\n await expect(service.linkAuthentication(identity, expired.uuid, { password: 'whatever' } as any, req, res)).rejects.toMatchObject({\n status: 400\n })\n })\n })\n})\n"],"names":["jest","mock","getAvatarBase64","fn","describe","LinksManager","name","service","linksQueriesMock","usersManagerMock","filesManagerMock","spacesManagerMock","authManagerMock","identity","id","login","baseLink","uuid","user","isActive","requireAuth","limitAccess","nbAccess","expiresAt","beforeAll","linkFromUUID","spaceLink","incrementLinkNbAccess","mockResolvedValue","undefined","compareUserPassword","updateAccesses","sendFileFromSpace","spaceEnv","setCookies","module","Test","createTestingModule","providers","provide","DB_TOKEN_PROVIDER","useValue","Cache","ContextManager","NotificationsManager","HttpService","FilesLockManager","ConfigService","JwtService","AuthManager","UsersManager","UsersQueries","AdminUsersManager","AdminUsersQueries","FilesQueries","FilesManager","SpacesQueries","SpacesManager","SharesQueries","SharesManager","LinksQueries","compile","useLogger","get","beforeEach","clearAllMocks","it","expect","toBeDefined","link","mockResolvedValueOnce","owner","share","isDir","alias","space","res","linkValidation","ok","toBe","error","toBeNull","toBeUndefined","toHaveBeenCalledWith","directCheck","checkLink","String","toLowerCase","toContain","req","ip","streamable","some","mockReturnValueOnce","checks","stream","logErrorSpy","spyOn","logger","mockImplementation","mockRejectedValueOnce","Error","result","linkAccess","toHaveBeenCalled","anything","loginDto","token","spaceEnvFromLink","UserModel","disabledLink","rejects","toMatchObject","status","sameUserIdentity","not","linkAuthentication","password","expired","Date","now"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../../backend/src/applications/links/services/links-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 { HttpService } from '@nestjs/axios'\nimport { ConfigService } from '@nestjs/config'\nimport { JwtService } from '@nestjs/jwt'\nimport { Test, TestingModule } from '@nestjs/testing'\nimport { AuthManager } from '../../../authentication/services/auth-manager.service'\nimport { Cache } from '../../../infrastructure/cache/services/cache.service'\nimport { ContextManager } from '../../../infrastructure/context/services/context-manager.service'\nimport { DB_TOKEN_PROVIDER } from '../../../infrastructure/database/constants'\nimport { FilesLockManager } from '../../files/services/files-lock-manager.service'\nimport { FilesManager } from '../../files/services/files-manager.service'\nimport { FilesQueries } from '../../files/services/files-queries.service'\nimport { NotificationsManager } from '../../notifications/services/notifications-manager.service'\nimport { SharesManager } from '../../shares/services/shares-manager.service'\nimport { SharesQueries } from '../../shares/services/shares-queries.service'\nimport { SpacesManager } from '../../spaces/services/spaces-manager.service'\nimport { SpacesQueries } from '../../spaces/services/spaces-queries.service'\nimport { UserModel } from '../../users/models/user.model'\nimport { AdminUsersManager } from '../../users/services/admin-users-manager.service'\nimport { AdminUsersQueries } from '../../users/services/admin-users-queries.service'\nimport { UsersManager } from '../../users/services/users-manager.service'\nimport { UsersQueries } from '../../users/services/users-queries.service'\nimport { getAvatarBase64 } from '../../users/utils/avatar'\nimport { LinksManager } from './links-manager.service'\nimport { LinksQueries } from './links-queries.service'\n\njest.mock('../../users/utils/avatar', () => ({\n getAvatarBase64: jest.fn()\n}))\n\ndescribe(LinksManager.name, () => {\n let service: LinksManager\n let linksQueriesMock: jest.Mocked<LinksQueries>\n let usersManagerMock: jest.Mocked<UsersManager>\n let filesManagerMock: jest.Mocked<FilesManager>\n let spacesManagerMock: jest.Mocked<SpacesManager>\n let authManagerMock: jest.Mocked<AuthManager>\n\n const identity: any = { id: 42, login: 'visitor' }\n const baseLink: any = {\n uuid: 'uuid-123',\n user: { id: 7, login: 'john', isActive: true },\n requireAuth: false,\n limitAccess: 0,\n nbAccess: 0,\n expiresAt: null\n }\n\n beforeAll(async () => {\n linksQueriesMock = {\n linkFromUUID: jest.fn(),\n spaceLink: jest.fn(),\n incrementLinkNbAccess: jest.fn().mockResolvedValue(undefined)\n } as any\n\n usersManagerMock = {\n compareUserPassword: jest.fn(),\n updateAccesses: jest.fn()\n } as any\n\n filesManagerMock = {\n sendFileFromSpace: jest.fn()\n } as any\n\n spacesManagerMock = {\n spaceEnv: jest.fn()\n } as any\n\n authManagerMock = {\n setCookies: jest.fn()\n } as any\n\n const module: TestingModule = await Test.createTestingModule({\n providers: [\n {\n provide: DB_TOKEN_PROVIDER,\n useValue: {}\n },\n {\n provide: Cache,\n useValue: {}\n },\n { provide: ContextManager, useValue: {} },\n {\n provide: NotificationsManager,\n useValue: {}\n },\n { provide: HttpService, useValue: {} },\n { provide: FilesLockManager, useValue: {} },\n { provide: ConfigService, useValue: {} },\n { provide: JwtService, useValue: {} },\n { provide: AuthManager, useValue: authManagerMock },\n { provide: UsersManager, useValue: usersManagerMock },\n { provide: UsersQueries, useValue: {} },\n { provide: AdminUsersManager, useValue: {} },\n { provide: AdminUsersQueries, useValue: {} },\n { provide: FilesQueries, useValue: {} },\n { provide: FilesManager, useValue: filesManagerMock },\n { provide: SpacesQueries, useValue: {} },\n { provide: SpacesManager, useValue: spacesManagerMock },\n { provide: SharesQueries, useValue: {} },\n { provide: SharesManager, useValue: {} },\n { provide: LinksQueries, useValue: linksQueriesMock },\n LinksManager\n ]\n }).compile()\n\n module.useLogger(['fatal'])\n service = module.get<LinksManager>(LinksManager)\n })\n\n beforeEach(() => {\n jest.clearAllMocks()\n })\n\n it('should be defined', () => {\n expect(service).toBeDefined()\n })\n\n describe('linkValidation', () => {\n it('returns ok with sanitized owner and avatar when link is valid', async () => {\n const link = { ...baseLink }\n linksQueriesMock.linkFromUUID.mockResolvedValueOnce(link)\n const spaceLink = {\n owner: { login: 'jane' },\n share: { isDir: true, alias: 's-alias', name: 'Docs' },\n space: null\n } as any\n linksQueriesMock.spaceLink.mockResolvedValueOnce(spaceLink)\n ;(getAvatarBase64 as jest.Mock).mockResolvedValueOnce('base64-xxx')\n\n const res = await service.linkValidation(identity, link.uuid)\n\n expect(res.ok).toBe(true)\n expect(res.error).toBeNull()\n expect(res.link).toBe(spaceLink)\n expect((spaceLink.owner as any).login).toBeUndefined()\n expect(linksQueriesMock.spaceLink).toHaveBeenCalledWith(link.uuid)\n expect(getAvatarBase64).toHaveBeenCalledWith('jane')\n\n // extra coverage: directly assert private checkLink with default ignoreAuth=false\n const directCheck = (service as any).checkLink(identity, link)\n expect(directCheck).toBe(true)\n })\n\n it('returns error and null link when uuid is not found', async () => {\n linksQueriesMock.linkFromUUID.mockResolvedValueOnce(null)\n\n const res = await service.linkValidation(identity, 'missing-uuid')\n\n expect(res.ok).toBe(false)\n expect(res.error).toBeDefined()\n expect(res.link).toBeNull()\n })\n\n it('returns unauthorized when auth is required and identity differs', async () => {\n const link = { ...baseLink, requireAuth: true }\n linksQueriesMock.linkFromUUID.mockResolvedValueOnce(link)\n\n const res = await service.linkValidation(identity, link.uuid)\n\n expect(res.ok).toBe(false)\n expect(String(res.error).toLowerCase()).toContain('unauthorized')\n expect(res.link).toBeNull()\n\n // extra coverage: directly assert private checkLink with default ignoreAuth=false\n const directCheck = (service as any).checkLink(identity, link)\n expect(String(directCheck).toLowerCase()).toContain('unauthorized')\n })\n\n it('returns exceeded when nbAccess >= limitAccess', async () => {\n const link = { ...baseLink, limitAccess: 5, nbAccess: 5 }\n linksQueriesMock.linkFromUUID.mockResolvedValueOnce(link)\n\n const res = await service.linkValidation(identity, link.uuid)\n\n expect(res.ok).toBe(false)\n expect(String(res.error).toLowerCase()).toContain('exceeded')\n })\n })\n\n describe('linkAccess', () => {\n const req: any = { ip: '127.0.0.1' }\n const res: any = {}\n\n it('streams a file when link targets a single file', async () => {\n const link = { ...baseLink, limitAccess: 10 }\n linksQueriesMock.linkFromUUID.mockResolvedValueOnce(link)\n const spaceLink = {\n space: null,\n share: { isDir: false, name: 'file.txt', alias: 'share-alias' }\n } as any\n linksQueriesMock.spaceLink.mockResolvedValueOnce(spaceLink)\n spacesManagerMock.spaceEnv.mockResolvedValueOnce({} as any)\n const streamable: any = { some: 'stream' }\n filesManagerMock.sendFileFromSpace.mockReturnValueOnce({\n checks: jest.fn().mockResolvedValueOnce(undefined),\n stream: jest.fn().mockResolvedValueOnce(streamable)\n } as any)\n\n // cover: incrementLinkNbAccess.catch(...) should log an error when the query rejects\n const logErrorSpy = jest.spyOn((service as any).logger, 'error').mockImplementation(() => undefined as any)\n linksQueriesMock.incrementLinkNbAccess.mockRejectedValueOnce(new Error('increment boom'))\n\n const result = await service.linkDownload(identity, link.uuid, req, res)\n\n expect(result).toBe(streamable)\n expect(filesManagerMock.sendFileFromSpace).toHaveBeenCalled()\n expect(linksQueriesMock.incrementLinkNbAccess).toHaveBeenCalledWith(link.uuid)\n // Assert repository selection for a share file (space falsy)\n // should call spacesManager.spaceEnv with SHARES and share alias when link.space is falsy\n expect(spacesManagerMock.spaceEnv).toHaveBeenCalledWith(expect.anything(), ['shares', 'share-alias'])\n // should log error when increment fails\n expect(logErrorSpy).toHaveBeenCalled()\n })\n\n it('authenticates and returns cookies when link targets a directory and user is different', async () => {\n const link = { ...baseLink, requireAuth: false, user: { id: 7, login: 'john', isActive: true } }\n linksQueriesMock.linkFromUUID.mockResolvedValueOnce(link)\n const spaceLink = {\n space: { alias: 'files', name: 'My Space' },\n share: { isDir: true, name: 'ignored', alias: 'ignored' }\n } as any\n linksQueriesMock.spaceLink.mockResolvedValueOnce(spaceLink)\n\n const loginDto: any = { token: 'jwt' }\n authManagerMock.setCookies.mockResolvedValueOnce(loginDto)\n\n // cover: usersManager.updateAccesses.catch(...) should log an error when updateAccesses rejects\n const logErrorSpy = jest.spyOn((service as any).logger, 'error').mockImplementation(() => undefined as any)\n usersManagerMock.updateAccesses.mockRejectedValueOnce(new Error('updateAccesses boom'))\n\n const result = await service.linkAccess(identity, link.uuid, req, res)\n\n expect(result).toBe(loginDto)\n expect(usersManagerMock.updateAccesses).toHaveBeenCalledWith(expect.anything(), req.ip, true)\n expect(authManagerMock.setCookies).toHaveBeenCalled()\n // additionally cover the \"space truthy\" branch by calling the private helper directly\n // should call spacesManager.spaceEnv with FILES and space alias when link.space is truthy\n await (service as any).spaceEnvFromLink(new UserModel(link.user as any), spaceLink as any)\n expect(spacesManagerMock.spaceEnv).toHaveBeenCalledWith(expect.anything(), ['files', 'files'])\n // should log error when updateAccesses fails\n expect(logErrorSpy).toHaveBeenCalled()\n })\n\n it('throws BAD_REQUEST when link is invalid', async () => {\n const disabledLink = { ...baseLink, user: { id: 7, login: 'john', isActive: false } }\n linksQueriesMock.linkFromUUID.mockResolvedValueOnce(disabledLink)\n\n await expect(service.linkAccess(identity, disabledLink.uuid, req, res)).rejects.toMatchObject({\n status: 400\n })\n })\n\n it('returns undefined for already authenticated directory access (same user) and does not set cookies or increment', async () => {\n const sameUserIdentity = { id: baseLink.user.id, login: 'john' }\n const link = { ...baseLink, requireAuth: true }\n linksQueriesMock.linkFromUUID.mockResolvedValueOnce(link)\n const spaceLink = {\n space: { alias: 'files', name: 'Space' },\n share: { isDir: true, name: 'dir', alias: 'share' }\n } as any\n linksQueriesMock.spaceLink.mockResolvedValueOnce(spaceLink)\n\n const result = await service.linkAccess(sameUserIdentity as any, link.uuid, req, res)\n\n expect(result.user.id).toEqual(baseLink.user.id)\n expect(authManagerMock.setCookies).not.toHaveBeenCalled()\n expect(linksQueriesMock.incrementLinkNbAccess).not.toHaveBeenCalled()\n })\n\n it('throws INTERNAL_SERVER_ERROR when file checks fail during streaming', async () => {\n const link = { ...baseLink, limitAccess: 10 }\n linksQueriesMock.linkFromUUID.mockResolvedValueOnce(link)\n const spaceLink = {\n space: null,\n share: { isDir: false, name: 'bad.txt', alias: 'share' }\n } as any\n linksQueriesMock.spaceLink.mockReset()\n linksQueriesMock.spaceLink.mockResolvedValueOnce(spaceLink)\n\n spacesManagerMock.spaceEnv.mockResolvedValueOnce({} as any)\n filesManagerMock.sendFileFromSpace.mockReturnValueOnce({\n checks: jest.fn().mockRejectedValueOnce(new Error('disk error')),\n stream: jest.fn()\n } as any)\n\n await expect(service.linkDownload(identity, link.uuid, req, res)).rejects.toMatchObject({\n status: 500\n })\n expect(linksQueriesMock.incrementLinkNbAccess).toHaveBeenCalledWith(link.uuid)\n })\n })\n\n describe('linkAuthentication', () => {\n const req: any = { ip: '10.0.0.1' }\n const res: any = {}\n\n it('returns cookies when password is correct', async () => {\n const link = { ...baseLink, requireAuth: true }\n linksQueriesMock.linkFromUUID.mockResolvedValueOnce(link)\n usersManagerMock.compareUserPassword.mockResolvedValueOnce(true)\n // usersManagerMock.updateAccesses.mockResolvedValueOnce(undefined) // removed to ensure rejection is hit\n const loginDto: any = { token: 'abc' }\n authManagerMock.setCookies.mockResolvedValueOnce(loginDto)\n\n // cover: usersManager.updateAccesses.catch(...) should log an error when updateAccesses rejects (success flow)\n const logErrorSpy = jest.spyOn((service as any).logger, 'error').mockImplementation(() => undefined as any)\n usersManagerMock.updateAccesses.mockRejectedValueOnce(new Error('updateAccesses auth success boom'))\n\n const result = await service.linkAuthentication(identity, link.uuid, { password: 'secret' } as any, req, res)\n\n expect(result).toBe(loginDto)\n expect(usersManagerMock.compareUserPassword).toHaveBeenCalledWith(link.user.id, 'secret')\n expect(usersManagerMock.updateAccesses).toHaveBeenCalledWith(expect.anything(), req.ip, true)\n expect(authManagerMock.setCookies).toHaveBeenCalled()\n // should log error when updateAccesses fails in successful authentication\n expect(logErrorSpy).toHaveBeenCalled()\n })\n\n it('throws FORBIDDEN when password is incorrect', async () => {\n const link = { ...baseLink, requireAuth: true }\n linksQueriesMock.linkFromUUID.mockResolvedValueOnce(link)\n usersManagerMock.compareUserPassword.mockResolvedValueOnce(false)\n usersManagerMock.updateAccesses.mockResolvedValueOnce(undefined)\n\n await expect(service.linkAuthentication(identity, link.uuid, { password: 'bad' } as any, req, res)).rejects.toMatchObject({ status: 403 })\n })\n\n it('throws BAD_REQUEST when link is invalid (e.g., expired)', async () => {\n const expired = { ...baseLink, expiresAt: new Date(Date.now() - 60_000) }\n linksQueriesMock.linkFromUUID.mockResolvedValueOnce(expired)\n\n await expect(service.linkAuthentication(identity, expired.uuid, { password: 'whatever' } as any, req, res)).rejects.toMatchObject({\n status: 400\n })\n })\n })\n})\n"],"names":["jest","mock","getAvatarBase64","fn","describe","LinksManager","name","service","linksQueriesMock","usersManagerMock","filesManagerMock","spacesManagerMock","authManagerMock","identity","id","login","baseLink","uuid","user","isActive","requireAuth","limitAccess","nbAccess","expiresAt","beforeAll","linkFromUUID","spaceLink","incrementLinkNbAccess","mockResolvedValue","undefined","compareUserPassword","updateAccesses","sendFileFromSpace","spaceEnv","setCookies","module","Test","createTestingModule","providers","provide","DB_TOKEN_PROVIDER","useValue","Cache","ContextManager","NotificationsManager","HttpService","FilesLockManager","ConfigService","JwtService","AuthManager","UsersManager","UsersQueries","AdminUsersManager","AdminUsersQueries","FilesQueries","FilesManager","SpacesQueries","SpacesManager","SharesQueries","SharesManager","LinksQueries","compile","useLogger","get","beforeEach","clearAllMocks","it","expect","toBeDefined","link","mockResolvedValueOnce","owner","share","isDir","alias","space","res","linkValidation","ok","toBe","error","toBeNull","toBeUndefined","toHaveBeenCalledWith","directCheck","checkLink","String","toLowerCase","toContain","req","ip","streamable","some","mockReturnValueOnce","checks","stream","logErrorSpy","spyOn","logger","mockImplementation","mockRejectedValueOnce","Error","result","linkDownload","toHaveBeenCalled","anything","loginDto","token","linkAccess","spaceEnvFromLink","UserModel","disabledLink","rejects","toMatchObject","status","sameUserIdentity","toEqual","not","mockReset","linkAuthentication","password","expired","Date","now"],"mappings":"AAAA;;;;CAIC;;;;uBAE2B;wBACE;qBACH;yBACS;oCACR;8BACN;uCACS;2BACG;yCACD;qCACJ;qCACA;6CACQ;sCACP;sCACA;sCACA;sCACA;2BACJ;0CACQ;0CACA;qCACL;qCACA;wBACG;qCACH;qCACA;AAE7BA,KAAKC,IAAI,CAAC,4BAA4B,IAAO,CAAA;QAC3CC,iBAAiBF,KAAKG,EAAE;IAC1B,CAAA;AAEAC,SAASC,iCAAY,CAACC,IAAI,EAAE;IAC1B,IAAIC;IACJ,IAAIC;IACJ,IAAIC;IACJ,IAAIC;IACJ,IAAIC;IACJ,IAAIC;IAEJ,MAAMC,WAAgB;QAAEC,IAAI;QAAIC,OAAO;IAAU;IACjD,MAAMC,WAAgB;QACpBC,MAAM;QACNC,MAAM;YAAEJ,IAAI;YAAGC,OAAO;YAAQI,UAAU;QAAK;QAC7CC,aAAa;QACbC,aAAa;QACbC,UAAU;QACVC,WAAW;IACb;IAEAC,UAAU;QACRhB,mBAAmB;YACjBiB,cAAczB,KAAKG,EAAE;YACrBuB,WAAW1B,KAAKG,EAAE;YAClBwB,uBAAuB3B,KAAKG,EAAE,GAAGyB,iBAAiB,CAACC;QACrD;QAEApB,mBAAmB;YACjBqB,qBAAqB9B,KAAKG,EAAE;YAC5B4B,gBAAgB/B,KAAKG,EAAE;QACzB;QAEAO,mBAAmB;YACjBsB,mBAAmBhC,KAAKG,EAAE;QAC5B;QAEAQ,oBAAoB;YAClBsB,UAAUjC,KAAKG,EAAE;QACnB;QAEAS,kBAAkB;YAChBsB,YAAYlC,KAAKG,EAAE;QACrB;QAEA,MAAMgC,SAAwB,MAAMC,aAAI,CAACC,mBAAmB,CAAC;YAC3DC,WAAW;gBACT;oBACEC,SAASC,4BAAiB;oBAC1BC,UAAU,CAAC;gBACb;gBACA;oBACEF,SAASG,mBAAK;oBACdD,UAAU,CAAC;gBACb;gBACA;oBAAEF,SAASI,qCAAc;oBAAEF,UAAU,CAAC;gBAAE;gBACxC;oBACEF,SAASK,iDAAoB;oBAC7BH,UAAU,CAAC;gBACb;gBACA;oBAAEF,SAASM,kBAAW;oBAAEJ,UAAU,CAAC;gBAAE;gBACrC;oBAAEF,SAASO,yCAAgB;oBAAEL,UAAU,CAAC;gBAAE;gBAC1C;oBAAEF,SAASQ,qBAAa;oBAAEN,UAAU,CAAC;gBAAE;gBACvC;oBAAEF,SAASS,eAAU;oBAAEP,UAAU,CAAC;gBAAE;gBACpC;oBAAEF,SAASU,+BAAW;oBAAER,UAAU7B;gBAAgB;gBAClD;oBAAE2B,SAASW,iCAAY;oBAAET,UAAUhC;gBAAiB;gBACpD;oBAAE8B,SAASY,iCAAY;oBAAEV,UAAU,CAAC;gBAAE;gBACtC;oBAAEF,SAASa,2CAAiB;oBAAEX,UAAU,CAAC;gBAAE;gBAC3C;oBAAEF,SAASc,2CAAiB;oBAAEZ,UAAU,CAAC;gBAAE;gBAC3C;oBAAEF,SAASe,iCAAY;oBAAEb,UAAU,CAAC;gBAAE;gBACtC;oBAAEF,SAASgB,iCAAY;oBAAEd,UAAU/B;gBAAiB;gBACpD;oBAAE6B,SAASiB,mCAAa;oBAAEf,UAAU,CAAC;gBAAE;gBACvC;oBAAEF,SAASkB,mCAAa;oBAAEhB,UAAU9B;gBAAkB;gBACtD;oBAAE4B,SAASmB,mCAAa;oBAAEjB,UAAU,CAAC;gBAAE;gBACvC;oBAAEF,SAASoB,mCAAa;oBAAElB,UAAU,CAAC;gBAAE;gBACvC;oBAAEF,SAASqB,iCAAY;oBAAEnB,UAAUjC;gBAAiB;gBACpDH,iCAAY;aACb;QACH,GAAGwD,OAAO;QAEV1B,OAAO2B,SAAS,CAAC;YAAC;SAAQ;QAC1BvD,UAAU4B,OAAO4B,GAAG,CAAe1D,iCAAY;IACjD;IAEA2D,WAAW;QACThE,KAAKiE,aAAa;IACpB;IAEAC,GAAG,qBAAqB;QACtBC,OAAO5D,SAAS6D,WAAW;IAC7B;IAEAhE,SAAS,kBAAkB;QACzB8D,GAAG,iEAAiE;YAClE,MAAMG,OAAO;gBAAE,GAAGrD,QAAQ;YAAC;YAC3BR,iBAAiBiB,YAAY,CAAC6C,qBAAqB,CAACD;YACpD,MAAM3C,YAAY;gBAChB6C,OAAO;oBAAExD,OAAO;gBAAO;gBACvByD,OAAO;oBAAEC,OAAO;oBAAMC,OAAO;oBAAWpE,MAAM;gBAAO;gBACrDqE,OAAO;YACT;YACAnE,iBAAiBkB,SAAS,CAAC4C,qBAAqB,CAAC5C;YAC/CxB,uBAAe,CAAeoE,qBAAqB,CAAC;YAEtD,MAAMM,MAAM,MAAMrE,QAAQsE,cAAc,CAAChE,UAAUwD,KAAKpD,IAAI;YAE5DkD,OAAOS,IAAIE,EAAE,EAAEC,IAAI,CAAC;YACpBZ,OAAOS,IAAII,KAAK,EAAEC,QAAQ;YAC1Bd,OAAOS,IAAIP,IAAI,EAAEU,IAAI,CAACrD;YACtByC,OAAO,AAACzC,UAAU6C,KAAK,CAASxD,KAAK,EAAEmE,aAAa;YACpDf,OAAO3D,iBAAiBkB,SAAS,EAAEyD,oBAAoB,CAACd,KAAKpD,IAAI;YACjEkD,OAAOjE,uBAAe,EAAEiF,oBAAoB,CAAC;YAE7C,kFAAkF;YAClF,MAAMC,cAAc,AAAC7E,QAAgB8E,SAAS,CAACxE,UAAUwD;YACzDF,OAAOiB,aAAaL,IAAI,CAAC;QAC3B;QAEAb,GAAG,sDAAsD;YACvD1D,iBAAiBiB,YAAY,CAAC6C,qBAAqB,CAAC;YAEpD,MAAMM,MAAM,MAAMrE,QAAQsE,cAAc,CAAChE,UAAU;YAEnDsD,OAAOS,IAAIE,EAAE,EAAEC,IAAI,CAAC;YACpBZ,OAAOS,IAAII,KAAK,EAAEZ,WAAW;YAC7BD,OAAOS,IAAIP,IAAI,EAAEY,QAAQ;QAC3B;QAEAf,GAAG,mEAAmE;YACpE,MAAMG,OAAO;gBAAE,GAAGrD,QAAQ;gBAAEI,aAAa;YAAK;YAC9CZ,iBAAiBiB,YAAY,CAAC6C,qBAAqB,CAACD;YAEpD,MAAMO,MAAM,MAAMrE,QAAQsE,cAAc,CAAChE,UAAUwD,KAAKpD,IAAI;YAE5DkD,OAAOS,IAAIE,EAAE,EAAEC,IAAI,CAAC;YACpBZ,OAAOmB,OAAOV,IAAII,KAAK,EAAEO,WAAW,IAAIC,SAAS,CAAC;YAClDrB,OAAOS,IAAIP,IAAI,EAAEY,QAAQ;YAEzB,kFAAkF;YAClF,MAAMG,cAAc,AAAC7E,QAAgB8E,SAAS,CAACxE,UAAUwD;YACzDF,OAAOmB,OAAOF,aAAaG,WAAW,IAAIC,SAAS,CAAC;QACtD;QAEAtB,GAAG,iDAAiD;YAClD,MAAMG,OAAO;gBAAE,GAAGrD,QAAQ;gBAAEK,aAAa;gBAAGC,UAAU;YAAE;YACxDd,iBAAiBiB,YAAY,CAAC6C,qBAAqB,CAACD;YAEpD,MAAMO,MAAM,MAAMrE,QAAQsE,cAAc,CAAChE,UAAUwD,KAAKpD,IAAI;YAE5DkD,OAAOS,IAAIE,EAAE,EAAEC,IAAI,CAAC;YACpBZ,OAAOmB,OAAOV,IAAII,KAAK,EAAEO,WAAW,IAAIC,SAAS,CAAC;QACpD;IACF;IAEApF,SAAS,cAAc;QACrB,MAAMqF,MAAW;YAAEC,IAAI;QAAY;QACnC,MAAMd,MAAW,CAAC;QAElBV,GAAG,kDAAkD;YACnD,MAAMG,OAAO;gBAAE,GAAGrD,QAAQ;gBAAEK,aAAa;YAAG;YAC5Cb,iBAAiBiB,YAAY,CAAC6C,qBAAqB,CAACD;YACpD,MAAM3C,YAAY;gBAChBiD,OAAO;gBACPH,OAAO;oBAAEC,OAAO;oBAAOnE,MAAM;oBAAYoE,OAAO;gBAAc;YAChE;YACAlE,iBAAiBkB,SAAS,CAAC4C,qBAAqB,CAAC5C;YACjDf,kBAAkBsB,QAAQ,CAACqC,qBAAqB,CAAC,CAAC;YAClD,MAAMqB,aAAkB;gBAAEC,MAAM;YAAS;YACzClF,iBAAiBsB,iBAAiB,CAAC6D,mBAAmB,CAAC;gBACrDC,QAAQ9F,KAAKG,EAAE,GAAGmE,qBAAqB,CAACzC;gBACxCkE,QAAQ/F,KAAKG,EAAE,GAAGmE,qBAAqB,CAACqB;YAC1C;YAEA,qFAAqF;YACrF,MAAMK,cAAchG,KAAKiG,KAAK,CAAC,AAAC1F,QAAgB2F,MAAM,EAAE,SAASC,kBAAkB,CAAC,IAAMtE;YAC1FrB,iBAAiBmB,qBAAqB,CAACyE,qBAAqB,CAAC,IAAIC,MAAM;YAEvE,MAAMC,SAAS,MAAM/F,QAAQgG,YAAY,CAAC1F,UAAUwD,KAAKpD,IAAI,EAAEwE,KAAKb;YAEpET,OAAOmC,QAAQvB,IAAI,CAACY;YACpBxB,OAAOzD,iBAAiBsB,iBAAiB,EAAEwE,gBAAgB;YAC3DrC,OAAO3D,iBAAiBmB,qBAAqB,EAAEwD,oBAAoB,CAACd,KAAKpD,IAAI;YAC7E,6DAA6D;YAC7D,0FAA0F;YAC1FkD,OAAOxD,kBAAkBsB,QAAQ,EAAEkD,oBAAoB,CAAChB,OAAOsC,QAAQ,IAAI;gBAAC;gBAAU;aAAc;YACpG,wCAAwC;YACxCtC,OAAO6B,aAAaQ,gBAAgB;QACtC;QAEAtC,GAAG,yFAAyF;YAC1F,MAAMG,OAAO;gBAAE,GAAGrD,QAAQ;gBAAEI,aAAa;gBAAOF,MAAM;oBAAEJ,IAAI;oBAAGC,OAAO;oBAAQI,UAAU;gBAAK;YAAE;YAC/FX,iBAAiBiB,YAAY,CAAC6C,qBAAqB,CAACD;YACpD,MAAM3C,YAAY;gBAChBiD,OAAO;oBAAED,OAAO;oBAASpE,MAAM;gBAAW;gBAC1CkE,OAAO;oBAAEC,OAAO;oBAAMnE,MAAM;oBAAWoE,OAAO;gBAAU;YAC1D;YACAlE,iBAAiBkB,SAAS,CAAC4C,qBAAqB,CAAC5C;YAEjD,MAAMgF,WAAgB;gBAAEC,OAAO;YAAM;YACrC/F,gBAAgBsB,UAAU,CAACoC,qBAAqB,CAACoC;YAEjD,gGAAgG;YAChG,MAAMV,cAAchG,KAAKiG,KAAK,CAAC,AAAC1F,QAAgB2F,MAAM,EAAE,SAASC,kBAAkB,CAAC,IAAMtE;YAC1FpB,iBAAiBsB,cAAc,CAACqE,qBAAqB,CAAC,IAAIC,MAAM;YAEhE,MAAMC,SAAS,MAAM/F,QAAQqG,UAAU,CAAC/F,UAAUwD,KAAKpD,IAAI,EAAEwE,KAAKb;YAElET,OAAOmC,QAAQvB,IAAI,CAAC2B;YACpBvC,OAAO1D,iBAAiBsB,cAAc,EAAEoD,oBAAoB,CAAChB,OAAOsC,QAAQ,IAAIhB,IAAIC,EAAE,EAAE;YACxFvB,OAAOvD,gBAAgBsB,UAAU,EAAEsE,gBAAgB;YACnD,sFAAsF;YACtF,0FAA0F;YAC1F,MAAM,AAACjG,QAAgBsG,gBAAgB,CAAC,IAAIC,oBAAS,CAACzC,KAAKnD,IAAI,GAAUQ;YACzEyC,OAAOxD,kBAAkBsB,QAAQ,EAAEkD,oBAAoB,CAAChB,OAAOsC,QAAQ,IAAI;gBAAC;gBAAS;aAAQ;YAC7F,6CAA6C;YAC7CtC,OAAO6B,aAAaQ,gBAAgB;QACtC;QAEAtC,GAAG,2CAA2C;YAC5C,MAAM6C,eAAe;gBAAE,GAAG/F,QAAQ;gBAAEE,MAAM;oBAAEJ,IAAI;oBAAGC,OAAO;oBAAQI,UAAU;gBAAM;YAAE;YACpFX,iBAAiBiB,YAAY,CAAC6C,qBAAqB,CAACyC;YAEpD,MAAM5C,OAAO5D,QAAQqG,UAAU,CAAC/F,UAAUkG,aAAa9F,IAAI,EAAEwE,KAAKb,MAAMoC,OAAO,CAACC,aAAa,CAAC;gBAC5FC,QAAQ;YACV;QACF;QAEAhD,GAAG,kHAAkH;YACnH,MAAMiD,mBAAmB;gBAAErG,IAAIE,SAASE,IAAI,CAACJ,EAAE;gBAAEC,OAAO;YAAO;YAC/D,MAAMsD,OAAO;gBAAE,GAAGrD,QAAQ;gBAAEI,aAAa;YAAK;YAC9CZ,iBAAiBiB,YAAY,CAAC6C,qBAAqB,CAACD;YACpD,MAAM3C,YAAY;gBAChBiD,OAAO;oBAAED,OAAO;oBAASpE,MAAM;gBAAQ;gBACvCkE,OAAO;oBAAEC,OAAO;oBAAMnE,MAAM;oBAAOoE,OAAO;gBAAQ;YACpD;YACAlE,iBAAiBkB,SAAS,CAAC4C,qBAAqB,CAAC5C;YAEjD,MAAM4E,SAAS,MAAM/F,QAAQqG,UAAU,CAACO,kBAAyB9C,KAAKpD,IAAI,EAAEwE,KAAKb;YAEjFT,OAAOmC,OAAOpF,IAAI,CAACJ,EAAE,EAAEsG,OAAO,CAACpG,SAASE,IAAI,CAACJ,EAAE;YAC/CqD,OAAOvD,gBAAgBsB,UAAU,EAAEmF,GAAG,CAACb,gBAAgB;YACvDrC,OAAO3D,iBAAiBmB,qBAAqB,EAAE0F,GAAG,CAACb,gBAAgB;QACrE;QAEAtC,GAAG,uEAAuE;YACxE,MAAMG,OAAO;gBAAE,GAAGrD,QAAQ;gBAAEK,aAAa;YAAG;YAC5Cb,iBAAiBiB,YAAY,CAAC6C,qBAAqB,CAACD;YACpD,MAAM3C,YAAY;gBAChBiD,OAAO;gBACPH,OAAO;oBAAEC,OAAO;oBAAOnE,MAAM;oBAAWoE,OAAO;gBAAQ;YACzD;YACAlE,iBAAiBkB,SAAS,CAAC4F,SAAS;YACpC9G,iBAAiBkB,SAAS,CAAC4C,qBAAqB,CAAC5C;YAEjDf,kBAAkBsB,QAAQ,CAACqC,qBAAqB,CAAC,CAAC;YAClD5D,iBAAiBsB,iBAAiB,CAAC6D,mBAAmB,CAAC;gBACrDC,QAAQ9F,KAAKG,EAAE,GAAGiG,qBAAqB,CAAC,IAAIC,MAAM;gBAClDN,QAAQ/F,KAAKG,EAAE;YACjB;YAEA,MAAMgE,OAAO5D,QAAQgG,YAAY,CAAC1F,UAAUwD,KAAKpD,IAAI,EAAEwE,KAAKb,MAAMoC,OAAO,CAACC,aAAa,CAAC;gBACtFC,QAAQ;YACV;YACA/C,OAAO3D,iBAAiBmB,qBAAqB,EAAEwD,oBAAoB,CAACd,KAAKpD,IAAI;QAC/E;IACF;IAEAb,SAAS,sBAAsB;QAC7B,MAAMqF,MAAW;YAAEC,IAAI;QAAW;QAClC,MAAMd,MAAW,CAAC;QAElBV,GAAG,4CAA4C;YAC7C,MAAMG,OAAO;gBAAE,GAAGrD,QAAQ;gBAAEI,aAAa;YAAK;YAC9CZ,iBAAiBiB,YAAY,CAAC6C,qBAAqB,CAACD;YACpD5D,iBAAiBqB,mBAAmB,CAACwC,qBAAqB,CAAC;YAC3D,yGAAyG;YACzG,MAAMoC,WAAgB;gBAAEC,OAAO;YAAM;YACrC/F,gBAAgBsB,UAAU,CAACoC,qBAAqB,CAACoC;YAEjD,+GAA+G;YAC/G,MAAMV,cAAchG,KAAKiG,KAAK,CAAC,AAAC1F,QAAgB2F,MAAM,EAAE,SAASC,kBAAkB,CAAC,IAAMtE;YAC1FpB,iBAAiBsB,cAAc,CAACqE,qBAAqB,CAAC,IAAIC,MAAM;YAEhE,MAAMC,SAAS,MAAM/F,QAAQgH,kBAAkB,CAAC1G,UAAUwD,KAAKpD,IAAI,EAAE;gBAAEuG,UAAU;YAAS,GAAU/B,KAAKb;YAEzGT,OAAOmC,QAAQvB,IAAI,CAAC2B;YACpBvC,OAAO1D,iBAAiBqB,mBAAmB,EAAEqD,oBAAoB,CAACd,KAAKnD,IAAI,CAACJ,EAAE,EAAE;YAChFqD,OAAO1D,iBAAiBsB,cAAc,EAAEoD,oBAAoB,CAAChB,OAAOsC,QAAQ,IAAIhB,IAAIC,EAAE,EAAE;YACxFvB,OAAOvD,gBAAgBsB,UAAU,EAAEsE,gBAAgB;YACnD,0EAA0E;YAC1ErC,OAAO6B,aAAaQ,gBAAgB;QACtC;QAEAtC,GAAG,+CAA+C;YAChD,MAAMG,OAAO;gBAAE,GAAGrD,QAAQ;gBAAEI,aAAa;YAAK;YAC9CZ,iBAAiBiB,YAAY,CAAC6C,qBAAqB,CAACD;YACpD5D,iBAAiBqB,mBAAmB,CAACwC,qBAAqB,CAAC;YAC3D7D,iBAAiBsB,cAAc,CAACuC,qBAAqB,CAACzC;YAEtD,MAAMsC,OAAO5D,QAAQgH,kBAAkB,CAAC1G,UAAUwD,KAAKpD,IAAI,EAAE;gBAAEuG,UAAU;YAAM,GAAU/B,KAAKb,MAAMoC,OAAO,CAACC,aAAa,CAAC;gBAAEC,QAAQ;YAAI;QAC1I;QAEAhD,GAAG,2DAA2D;YAC5D,MAAMuD,UAAU;gBAAE,GAAGzG,QAAQ;gBAAEO,WAAW,IAAImG,KAAKA,KAAKC,GAAG,KAAK;YAAQ;YACxEnH,iBAAiBiB,YAAY,CAAC6C,qBAAqB,CAACmD;YAEpD,MAAMtD,OAAO5D,QAAQgH,kBAAkB,CAAC1G,UAAU4G,QAAQxG,IAAI,EAAE;gBAAEuG,UAAU;YAAW,GAAU/B,KAAKb,MAAMoC,OAAO,CAACC,aAAa,CAAC;gBAChIC,QAAQ;YACV;QACF;IACF;AACF"}
@@ -124,7 +124,10 @@ let LinksQueries = class LinksQueries {
124
124
  alias: _sharesschema.shares.alias,
125
125
  hasParent: (0, _drizzleorm.isNotNull)(_sharesschema.shares.parentId).mapWith(Boolean),
126
126
  isDir: (0, _drizzleorm.sql)`IF (${(0, _drizzleorm.isNotNull)(_sharesschema.shares.externalPath)} OR ${(0, _drizzleorm.isNotNull)(shareSpaceRoot.externalPath)}, 1 ,${_filesschema.files.isDir})`.mapWith(Boolean),
127
- mime: _filesschema.files.mime
127
+ mime: _filesschema.files.mime,
128
+ mtime: _filesschema.files.mtime,
129
+ size: _filesschema.files.size,
130
+ permissions: _sharesmembersschema.sharesMembers.permissions
128
131
  },
129
132
  space: {
130
133
  name: _spacesschema.spaces.name,
@@ -135,7 +138,11 @@ let LinksQueries = class LinksQueries {
135
138
  fullName: (0, _usersschema.userFullNameSQL)(shareOwner)
136
139
  }
137
140
  }).from(_linksschema.links).leftJoin(_sharesmembersschema.sharesMembers, (0, _drizzleorm.eq)(_sharesmembersschema.sharesMembers.linkId, _linksschema.links.id)).leftJoin(_sharesschema.shares, (0, _drizzleorm.eq)(_sharesschema.shares.id, _sharesmembersschema.sharesMembers.shareId)).leftJoin(shareOwner, (0, _drizzleorm.eq)(shareOwner.id, _sharesschema.shares.ownerId)).leftJoin(_spacesmembersschema.spacesMembers, (0, _drizzleorm.eq)(_spacesmembersschema.spacesMembers.linkId, _linksschema.links.id)).leftJoin(_spacesschema.spaces, (0, _drizzleorm.eq)(_spacesschema.spaces.id, _spacesmembersschema.spacesMembers.spaceId)).leftJoin(shareSpaceRoot, (0, _drizzleorm.and)((0, _drizzleorm.isNull)(_sharesschema.shares.externalPath), (0, _drizzleorm.isNull)(_sharesschema.shares.fileId), (0, _drizzleorm.eq)(shareSpaceRoot.id, _sharesschema.shares.spaceRootId))).leftJoin(_filesschema.files, (0, _drizzleorm.or)((0, _drizzleorm.and)((0, _drizzleorm.isNotNull)(_sharesschema.shares.fileId), (0, _drizzleorm.eq)(_filesschema.files.id, _sharesschema.shares.fileId)), (0, _drizzleorm.and)((0, _drizzleorm.isNull)(_sharesschema.shares.externalPath), (0, _drizzleorm.isNotNull)(shareSpaceRoot.fileId), (0, _drizzleorm.eq)(_filesschema.files.id, shareSpaceRoot.fileId)))).where((0, _drizzleorm.eq)(_linksschema.links.uuid, uuid)).limit(1);
138
- return r;
141
+ return {
142
+ ...r,
143
+ space: r.space?.name ? r.space : null,
144
+ share: r.share?.name ? r.share : null
145
+ };
139
146
  }
140
147
  async incrementLinkNbAccess(uuid) {
141
148
  await this.db.update(_linksschema.links).set({
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../backend/src/applications/links/services/links-queries.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 { Inject, Injectable } from '@nestjs/common'\nimport { and, eq, getTableColumns, isNotNull, isNull, or, sql } from 'drizzle-orm'\nimport { alias } from 'drizzle-orm/mysql-core'\nimport { Cache } from '../../../infrastructure/cache/services/cache.service'\nimport { DB_TOKEN_PROVIDER } from '../../../infrastructure/database/constants'\nimport type { DBSchema } from '../../../infrastructure/database/interfaces/database.interface'\nimport { dbGetInsertedId } from '../../../infrastructure/database/utils'\nimport { files } from '../../files/schemas/files.schema'\nimport type { ShareMembers } from '../../shares/schemas/share-members.interface'\nimport type { Share } from '../../shares/schemas/share.interface'\nimport { sharesMembers } from '../../shares/schemas/shares-members.schema'\nimport { shares } from '../../shares/schemas/shares.schema'\nimport { SPACE_ROLE } from '../../spaces/constants/spaces'\nimport type { SpaceMembers } from '../../spaces/schemas/space-members.interface'\nimport { spacesMembers } from '../../spaces/schemas/spaces-members.schema'\nimport { spacesRoots } from '../../spaces/schemas/spaces-roots.schema'\nimport { spaces } from '../../spaces/schemas/spaces.schema'\nimport { USER_ROLE } from '../../users/constants/user'\nimport type { User } from '../../users/schemas/user.interface'\nimport { userFullNameSQL, users } from '../../users/schemas/users.schema'\nimport { CACHE_LINK_UUID_PREFIX, CACHE_LINK_UUID_TTL } from '../constants/cache'\nimport { LINK_TYPE } from '../constants/links'\nimport type { LinkAsUser, LinkGuest } from '../interfaces/link-guest.interface'\nimport type { SpaceLink } from '../interfaces/link-space.interface'\nimport type { Link } from '../schemas/link.interface'\nimport { links } from '../schemas/links.schema'\n\n@Injectable()\nexport class LinksQueries {\n constructor(\n @Inject(DB_TOKEN_PROVIDER) private readonly db: DBSchema,\n private readonly cache: Cache\n ) {}\n\n async linkFromShare(ownerId: number, linkId: number, shareId: number, isAdmin: number = 0): Promise<LinkGuest> {\n const [r] = await this.db\n .select({\n ...getTableColumns(links),\n permissions: sharesMembers.permissions,\n language: users.language,\n isActive: users.isActive\n })\n .from(links)\n .innerJoin(shares, and(eq(shares.id, shareId), or(eq(shares.ownerId, ownerId), and(eq(sql`${isAdmin}`, 1), isNull(shares.ownerId)))))\n .innerJoin(sharesMembers, and(eq(sharesMembers.shareId, shares.id), eq(sharesMembers.userId, links.userId), eq(sharesMembers.linkId, linkId)))\n .innerJoin(users, eq(users.id, links.userId))\n .where(eq(links.id, linkId))\n .limit(1)\n return r as LinkGuest\n }\n\n async linkFromSpace(managerId: number, linkId: number, spaceId: number): Promise<LinkGuest> {\n const linkMember: any = alias(spacesMembers, 'linkMember')\n const [r] = await this.db\n .select({\n ...getTableColumns(links),\n permissions: linkMember.permissions,\n language: users.language,\n isActive: users.isActive\n })\n .from(links)\n .innerJoin(\n spacesMembers,\n and(eq(spacesMembers.spaceId, spaceId), eq(spacesMembers.userId, managerId), eq(spacesMembers.role, SPACE_ROLE.IS_MANAGER))\n )\n .innerJoin(linkMember, and(eq(linkMember.spaceId, spacesMembers.spaceId), eq(linkMember.userId, links.userId), eq(linkMember.linkId, linkId)))\n .innerJoin(users, eq(users.id, links.userId))\n .where(eq(links.id, linkId))\n .limit(1)\n return r as LinkGuest\n }\n\n async updateLinkFromSpaceOrShare(\n link: LinkGuest,\n shareId: number,\n diffUser: Partial<User>,\n diffLink: Partial<Link>,\n diffShare: Partial<Share>,\n diffMember: Partial<ShareMembers>\n ) {\n if (Object.keys(diffUser).length) {\n await this.db.update(users).set(diffUser).where(eq(users.id, link.userId))\n }\n if (Object.keys(diffLink).length) {\n await this.db.update(links).set(diffLink).where(eq(links.id, link.id))\n }\n if (Object.keys(diffShare).length) {\n await this.db.update(shares).set(diffShare).where(eq(shares.id, shareId))\n }\n if (Object.keys(diffMember).length) {\n await this.db\n .update(sharesMembers)\n .set(diffMember)\n .where(and(eq(sharesMembers.shareId, shareId), eq(sharesMembers.userId, link.userId), eq(sharesMembers.linkId, link.id)))\n }\n }\n\n async createLinkToSpaceOrShare(guestId: number, spaceOrShareId: number, type: LINK_TYPE, link: Partial<LinkGuest>): Promise<number> {\n const linkId = dbGetInsertedId(await this.db.insert(links).values(link as Link))\n if (type === LINK_TYPE.SPACE) {\n await this.db.insert(spacesMembers).values({\n userId: guestId,\n spaceId: spaceOrShareId,\n permissions: link.permissions,\n role: SPACE_ROLE.IS_MEMBER,\n linkId: linkId\n } as SpaceMembers)\n } else {\n await this.db.insert(sharesMembers).values({\n userId: guestId,\n shareId: spaceOrShareId,\n linkId: linkId,\n permissions: link.permissions\n } as ShareMembers)\n }\n return linkId\n }\n\n allLinksFromSpaceOrShare(spaceOrShareId: number, type: LINK_TYPE): Promise<{ id: number; linkId: number }[]> {\n const members: any = alias(type == 'share' ? sharesMembers : spacesMembers, 'members')\n return this.db\n .select({ id: users.id, linkId: members.linkId })\n .from(members)\n .innerJoin(users, and(eq(users.id, members.userId), eq(users.role, USER_ROLE.LINK)))\n .where(and(eq(type == 'share' ? members.shareId : members.spaceId, spaceOrShareId), isNotNull(members.linkId)))\n }\n\n async linkFromUUID(uuid: string): Promise<LinkAsUser> {\n const { password, ...userColumns } = getTableColumns(users)\n const [r] = await this.db\n .select({\n ...getTableColumns(links),\n user: { ...userColumns }\n })\n .from(links)\n .leftJoin(users, eq(users.id, links.userId))\n .where(eq(links.uuid, uuid))\n .limit(1)\n return r\n }\n\n async spaceLink(uuid: string): Promise<SpaceLink> {\n const shareOwner: any = alias(users, 'shareOwner')\n const shareSpaceRoot: any = alias(spacesRoots, 'shareSpaceRoot')\n const [r]: SpaceLink[] = await this.db\n .select({\n share: {\n name: shares.name,\n alias: shares.alias,\n hasParent: isNotNull(shares.parentId).mapWith(Boolean),\n isDir: sql`IF (${isNotNull(shares.externalPath)} OR ${isNotNull(shareSpaceRoot.externalPath)}, 1 ,${files.isDir})`.mapWith(Boolean),\n mime: files.mime\n },\n space: { name: spaces.name, alias: spaces.alias },\n owner: { login: shareOwner.login, fullName: userFullNameSQL(shareOwner) }\n })\n .from(links)\n .leftJoin(sharesMembers, eq(sharesMembers.linkId, links.id))\n .leftJoin(shares, eq(shares.id, sharesMembers.shareId))\n .leftJoin(shareOwner, eq(shareOwner.id, shares.ownerId))\n .leftJoin(spacesMembers, eq(spacesMembers.linkId, links.id))\n .leftJoin(spaces, eq(spaces.id, spacesMembers.spaceId))\n .leftJoin(shareSpaceRoot, and(isNull(shares.externalPath), isNull(shares.fileId), eq(shareSpaceRoot.id, shares.spaceRootId)))\n .leftJoin(\n files,\n or(\n and(isNotNull(shares.fileId), eq(files.id, shares.fileId)),\n and(isNull(shares.externalPath), isNotNull(shareSpaceRoot.fileId), eq(files.id, shareSpaceRoot.fileId))\n )\n )\n .where(eq(links.uuid, uuid))\n .limit(1)\n return r\n }\n\n async incrementLinkNbAccess(uuid: string) {\n await this.db\n .update(links)\n .set({ nbAccess: sql`${links.nbAccess} + 1` } as Record<keyof Link, any>)\n .where(eq(links.uuid, uuid))\n .limit(1)\n }\n\n async isUniqueUUID(userId: number, uuid: string) {\n const [r] = await this.db.select({ check: links.uuid }).from(links).where(eq(links.uuid, uuid)).limit(1)\n if (!r) {\n // uuid does not exist in db\n const cacheKey = this.cache.genSlugKey(CACHE_LINK_UUID_PREFIX, userId, uuid)\n // check if uuid was already requested\n if (!(await this.cache.has(cacheKey))) {\n // store uuid to prevent reuse\n await this.cache.set(cacheKey, uuid, CACHE_LINK_UUID_TTL)\n return true\n }\n return false\n }\n return false\n }\n\n isReservedUUID(userId: number, uuid: string): Promise<boolean> {\n // check if uuid is reserved\n return this.cache.has(this.cache.genSlugKey(CACHE_LINK_UUID_PREFIX, userId, uuid))\n }\n}\n"],"names":["LinksQueries","linkFromShare","ownerId","linkId","shareId","isAdmin","r","db","select","getTableColumns","links","permissions","sharesMembers","language","users","isActive","from","innerJoin","shares","and","eq","id","or","sql","isNull","userId","where","limit","linkFromSpace","managerId","spaceId","linkMember","alias","spacesMembers","role","SPACE_ROLE","IS_MANAGER","updateLinkFromSpaceOrShare","link","diffUser","diffLink","diffShare","diffMember","Object","keys","length","update","set","createLinkToSpaceOrShare","guestId","spaceOrShareId","type","dbGetInsertedId","insert","values","LINK_TYPE","SPACE","IS_MEMBER","allLinksFromSpaceOrShare","members","USER_ROLE","LINK","isNotNull","linkFromUUID","uuid","password","userColumns","user","leftJoin","spaceLink","shareOwner","shareSpaceRoot","spacesRoots","share","name","hasParent","parentId","mapWith","Boolean","isDir","externalPath","files","mime","space","spaces","owner","login","fullName","userFullNameSQL","fileId","spaceRootId","incrementLinkNbAccess","nbAccess","isUniqueUUID","check","cacheKey","cache","genSlugKey","CACHE_LINK_UUID_PREFIX","has","CACHE_LINK_UUID_TTL","isReservedUUID"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../../backend/src/applications/links/services/links-queries.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 { Inject, Injectable } from '@nestjs/common'\nimport { and, eq, getTableColumns, isNotNull, isNull, or, sql } from 'drizzle-orm'\nimport { alias } from 'drizzle-orm/mysql-core'\nimport { Cache } from '../../../infrastructure/cache/services/cache.service'\nimport { DB_TOKEN_PROVIDER } from '../../../infrastructure/database/constants'\nimport type { DBSchema } from '../../../infrastructure/database/interfaces/database.interface'\nimport { dbGetInsertedId } from '../../../infrastructure/database/utils'\nimport { files } from '../../files/schemas/files.schema'\nimport type { ShareMembers } from '../../shares/schemas/share-members.interface'\nimport type { Share } from '../../shares/schemas/share.interface'\nimport { sharesMembers } from '../../shares/schemas/shares-members.schema'\nimport { shares } from '../../shares/schemas/shares.schema'\nimport { SPACE_ROLE } from '../../spaces/constants/spaces'\nimport type { SpaceMembers } from '../../spaces/schemas/space-members.interface'\nimport { spacesMembers } from '../../spaces/schemas/spaces-members.schema'\nimport { spacesRoots } from '../../spaces/schemas/spaces-roots.schema'\nimport { spaces } from '../../spaces/schemas/spaces.schema'\nimport { USER_ROLE } from '../../users/constants/user'\nimport type { User } from '../../users/schemas/user.interface'\nimport { userFullNameSQL, users } from '../../users/schemas/users.schema'\nimport { CACHE_LINK_UUID_PREFIX, CACHE_LINK_UUID_TTL } from '../constants/cache'\nimport { LINK_TYPE } from '../constants/links'\nimport type { LinkAsUser, LinkGuest } from '../interfaces/link-guest.interface'\nimport type { SpaceLink } from '../interfaces/link-space.interface'\nimport type { Link } from '../schemas/link.interface'\nimport { links } from '../schemas/links.schema'\n\n@Injectable()\nexport class LinksQueries {\n constructor(\n @Inject(DB_TOKEN_PROVIDER) private readonly db: DBSchema,\n private readonly cache: Cache\n ) {}\n\n async linkFromShare(ownerId: number, linkId: number, shareId: number, isAdmin: number = 0): Promise<LinkGuest> {\n const [r] = await this.db\n .select({\n ...getTableColumns(links),\n permissions: sharesMembers.permissions,\n language: users.language,\n isActive: users.isActive\n })\n .from(links)\n .innerJoin(shares, and(eq(shares.id, shareId), or(eq(shares.ownerId, ownerId), and(eq(sql`${isAdmin}`, 1), isNull(shares.ownerId)))))\n .innerJoin(sharesMembers, and(eq(sharesMembers.shareId, shares.id), eq(sharesMembers.userId, links.userId), eq(sharesMembers.linkId, linkId)))\n .innerJoin(users, eq(users.id, links.userId))\n .where(eq(links.id, linkId))\n .limit(1)\n return r as LinkGuest\n }\n\n async linkFromSpace(managerId: number, linkId: number, spaceId: number): Promise<LinkGuest> {\n const linkMember: any = alias(spacesMembers, 'linkMember')\n const [r] = await this.db\n .select({\n ...getTableColumns(links),\n permissions: linkMember.permissions,\n language: users.language,\n isActive: users.isActive\n })\n .from(links)\n .innerJoin(\n spacesMembers,\n and(eq(spacesMembers.spaceId, spaceId), eq(spacesMembers.userId, managerId), eq(spacesMembers.role, SPACE_ROLE.IS_MANAGER))\n )\n .innerJoin(linkMember, and(eq(linkMember.spaceId, spacesMembers.spaceId), eq(linkMember.userId, links.userId), eq(linkMember.linkId, linkId)))\n .innerJoin(users, eq(users.id, links.userId))\n .where(eq(links.id, linkId))\n .limit(1)\n return r as LinkGuest\n }\n\n async updateLinkFromSpaceOrShare(\n link: LinkGuest,\n shareId: number,\n diffUser: Partial<User>,\n diffLink: Partial<Link>,\n diffShare: Partial<Share>,\n diffMember: Partial<ShareMembers>\n ) {\n if (Object.keys(diffUser).length) {\n await this.db.update(users).set(diffUser).where(eq(users.id, link.userId))\n }\n if (Object.keys(diffLink).length) {\n await this.db.update(links).set(diffLink).where(eq(links.id, link.id))\n }\n if (Object.keys(diffShare).length) {\n await this.db.update(shares).set(diffShare).where(eq(shares.id, shareId))\n }\n if (Object.keys(diffMember).length) {\n await this.db\n .update(sharesMembers)\n .set(diffMember)\n .where(and(eq(sharesMembers.shareId, shareId), eq(sharesMembers.userId, link.userId), eq(sharesMembers.linkId, link.id)))\n }\n }\n\n async createLinkToSpaceOrShare(guestId: number, spaceOrShareId: number, type: LINK_TYPE, link: Partial<LinkGuest>): Promise<number> {\n const linkId = dbGetInsertedId(await this.db.insert(links).values(link as Link))\n if (type === LINK_TYPE.SPACE) {\n await this.db.insert(spacesMembers).values({\n userId: guestId,\n spaceId: spaceOrShareId,\n permissions: link.permissions,\n role: SPACE_ROLE.IS_MEMBER,\n linkId: linkId\n } as SpaceMembers)\n } else {\n await this.db.insert(sharesMembers).values({\n userId: guestId,\n shareId: spaceOrShareId,\n linkId: linkId,\n permissions: link.permissions\n } as ShareMembers)\n }\n return linkId\n }\n\n allLinksFromSpaceOrShare(spaceOrShareId: number, type: LINK_TYPE): Promise<{ id: number; linkId: number }[]> {\n const members: any = alias(type == 'share' ? sharesMembers : spacesMembers, 'members')\n return this.db\n .select({ id: users.id, linkId: members.linkId })\n .from(members)\n .innerJoin(users, and(eq(users.id, members.userId), eq(users.role, USER_ROLE.LINK)))\n .where(and(eq(type == 'share' ? members.shareId : members.spaceId, spaceOrShareId), isNotNull(members.linkId)))\n }\n\n async linkFromUUID(uuid: string): Promise<LinkAsUser> {\n const { password, ...userColumns } = getTableColumns(users)\n const [r] = await this.db\n .select({\n ...getTableColumns(links),\n user: { ...userColumns }\n })\n .from(links)\n .leftJoin(users, eq(users.id, links.userId))\n .where(eq(links.uuid, uuid))\n .limit(1)\n return r\n }\n\n async spaceLink(uuid: string): Promise<SpaceLink> {\n const shareOwner: any = alias(users, 'shareOwner')\n const shareSpaceRoot: any = alias(spacesRoots, 'shareSpaceRoot')\n const [r]: SpaceLink[] = await this.db\n .select({\n share: {\n name: shares.name,\n alias: shares.alias,\n hasParent: isNotNull(shares.parentId).mapWith(Boolean),\n isDir: sql`IF (${isNotNull(shares.externalPath)} OR ${isNotNull(shareSpaceRoot.externalPath)}, 1 ,${files.isDir})`.mapWith(Boolean),\n mime: files.mime,\n mtime: files.mtime,\n size: files.size,\n permissions: sharesMembers.permissions\n },\n space: { name: spaces.name, alias: spaces.alias },\n owner: { login: shareOwner.login, fullName: userFullNameSQL(shareOwner) }\n })\n .from(links)\n .leftJoin(sharesMembers, eq(sharesMembers.linkId, links.id))\n .leftJoin(shares, eq(shares.id, sharesMembers.shareId))\n .leftJoin(shareOwner, eq(shareOwner.id, shares.ownerId))\n .leftJoin(spacesMembers, eq(spacesMembers.linkId, links.id))\n .leftJoin(spaces, eq(spaces.id, spacesMembers.spaceId))\n .leftJoin(shareSpaceRoot, and(isNull(shares.externalPath), isNull(shares.fileId), eq(shareSpaceRoot.id, shares.spaceRootId)))\n .leftJoin(\n files,\n or(\n and(isNotNull(shares.fileId), eq(files.id, shares.fileId)),\n and(isNull(shares.externalPath), isNotNull(shareSpaceRoot.fileId), eq(files.id, shareSpaceRoot.fileId))\n )\n )\n .where(eq(links.uuid, uuid))\n .limit(1)\n return {\n ...r,\n space: r.space?.name ? r.space : null,\n share: r.share?.name ? r.share : null\n }\n }\n\n async incrementLinkNbAccess(uuid: string) {\n await this.db\n .update(links)\n .set({ nbAccess: sql`${links.nbAccess} + 1` } as Record<keyof Link, any>)\n .where(eq(links.uuid, uuid))\n .limit(1)\n }\n\n async isUniqueUUID(userId: number, uuid: string) {\n const [r] = await this.db.select({ check: links.uuid }).from(links).where(eq(links.uuid, uuid)).limit(1)\n if (!r) {\n // uuid does not exist in db\n const cacheKey = this.cache.genSlugKey(CACHE_LINK_UUID_PREFIX, userId, uuid)\n // check if uuid was already requested\n if (!(await this.cache.has(cacheKey))) {\n // store uuid to prevent reuse\n await this.cache.set(cacheKey, uuid, CACHE_LINK_UUID_TTL)\n return true\n }\n return false\n }\n return false\n }\n\n isReservedUUID(userId: number, uuid: string): Promise<boolean> {\n // check if uuid is reserved\n return this.cache.has(this.cache.genSlugKey(CACHE_LINK_UUID_PREFIX, userId, uuid))\n }\n}\n"],"names":["LinksQueries","linkFromShare","ownerId","linkId","shareId","isAdmin","r","db","select","getTableColumns","links","permissions","sharesMembers","language","users","isActive","from","innerJoin","shares","and","eq","id","or","sql","isNull","userId","where","limit","linkFromSpace","managerId","spaceId","linkMember","alias","spacesMembers","role","SPACE_ROLE","IS_MANAGER","updateLinkFromSpaceOrShare","link","diffUser","diffLink","diffShare","diffMember","Object","keys","length","update","set","createLinkToSpaceOrShare","guestId","spaceOrShareId","type","dbGetInsertedId","insert","values","LINK_TYPE","SPACE","IS_MEMBER","allLinksFromSpaceOrShare","members","USER_ROLE","LINK","isNotNull","linkFromUUID","uuid","password","userColumns","user","leftJoin","spaceLink","shareOwner","shareSpaceRoot","spacesRoots","share","name","hasParent","parentId","mapWith","Boolean","isDir","externalPath","files","mime","mtime","size","space","spaces","owner","login","fullName","userFullNameSQL","fileId","spaceRootId","incrementLinkNbAccess","nbAccess","isUniqueUUID","check","cacheKey","cache","genSlugKey","CACHE_LINK_UUID_PREFIX","has","CACHE_LINK_UUID_TTL","isReservedUUID"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../backend/src/applications/shares/interfaces/share-link.interface.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 type { FileSpace } from '../../files/interfaces/file-space.interface'\nimport type { LinkGuest } from '../../links/interfaces/link-guest.interface'\nimport type { Share } from '../schemas/share.interface'\n\nexport interface ShareLink extends Pick<Share, 'id' | 'name' | 'ownerId' | 'description'> {\n id: number\n ownerId: number\n name: string\n externalPath: string\n description: string\n parent: Pick<Share, 'id' | 'ownerId' | 'alias' | 'name'>\n file: FileSpace\n link: Omit<LinkGuest, 'userId'>\n}\n"],"names":[],"mappings":"AAAA;;;;CAIC"}
1
+ {"version":3,"sources":["../../../../../backend/src/applications/shares/interfaces/share-link.interface.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 type { FileSpace } from '../../files/interfaces/file-space.interface'\nimport type { LinkGuest } from '../../links/interfaces/link-guest.interface'\nimport type { Share } from '../schemas/share.interface'\n\nexport interface ShareLink extends Pick<Share, 'id' | 'name' | 'alias' | 'ownerId' | 'description'> {\n ownerId: number\n externalPath: string\n parent: Pick<Share, 'id' | 'ownerId' | 'alias' | 'name'>\n file: FileSpace\n link: Omit<LinkGuest, 'userId'>\n}\n"],"names":[],"mappings":"AAAA;;;;CAIC"}
@@ -555,6 +555,9 @@ let SharesManager = class SharesManager {
555
555
  // intersect permissions to ensure that the user does not attempt to exceed his rights
556
556
  const shareLink = await this.getShareLink(user, spaceOrShareId);
557
557
  updateMember.permissions = (0, _shared.intersectPermissions)(shareLink.file.permissions, v);
558
+ this.sharesQueries.clearCachePermissions(shareLink.alias, [
559
+ link.userId
560
+ ]).catch((e)=>this.logger.error(`${this.updateLinkFromSpaceOrShare.name} - ${e}`));
558
561
  }
559
562
  break;
560
563
  case 'language':