@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
@@ -15,18 +15,20 @@ Object.defineProperty(exports, "SpaceGuard", {
15
15
  const _common = require("@nestjs/common");
16
16
  const _core = require("@nestjs/core");
17
17
  const _applicationsconstants = require("../../applications.constants");
18
- const _onlyoffice = require("../../files/constants/only-office");
19
- const _routes = require("../../files/constants/routes");
18
+ const _collaboraonlineconstants = require("../../files/modules/collabora-online/collabora-online.constants");
19
+ const _collaboraonlineutils = require("../../files/modules/collabora-online/collabora-online.utils");
20
+ const _files = require("../../files/utils/files");
20
21
  const _synccontextdecorator = require("../../sync/decorators/sync-context.decorator");
21
- const _routes1 = require("../../sync/utils/routes");
22
+ const _routes = require("../../sync/utils/routes");
22
23
  const _webdavcontextdecorator = require("../../webdav/decorators/webdav-context.decorator");
23
- const _routes2 = require("../../webdav/utils/routes");
24
+ const _routes1 = require("../../webdav/utils/routes");
24
25
  const _spaces = require("../constants/spaces");
26
+ const _spaceoverridepermissiondecorator = require("../decorators/space-override-permission.decorator");
25
27
  const _spaceskipguarddecorator = require("../decorators/space-skip-guard.decorator");
26
28
  const _spaceskippermissionsdecorator = require("../decorators/space-skip-permissions.decorator");
27
29
  const _spacesmanagerservice = require("../services/spaces-manager.service");
28
30
  const _permissions = require("../utils/permissions");
29
- const _routes3 = require("../utils/routes");
31
+ const _routes2 = require("../utils/routes");
30
32
  function _ts_decorate(decorators, target, key, desc) {
31
33
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
32
34
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
@@ -37,13 +39,15 @@ function _ts_metadata(k, v) {
37
39
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
38
40
  }
39
41
  let SpaceGuard = class SpaceGuard {
40
- static checkPermissions(req, logger, onlyOfficeContext = false) {
42
+ static async checkPermissions(req, logger, overrideSpacePermission) {
41
43
  let permission;
42
- if (onlyOfficeContext && req.method === _applicationsconstants.HTTP_METHOD.POST && req.originalUrl.startsWith(_routes.API_FILES_ONLY_OFFICE_CALLBACK)) {
43
- // special case : onlyoffice callback use post method to update documents
44
+ if (req.method === _applicationsconstants.HTTP_METHOD.PUT && await (0, _files.isPathExists)(req.space.realPath) && !await (0, _files.isPathIsDir)(req.space.realPath)) {
45
+ // PUT method may either create a new resource or replace an existing one.
46
+ // Therefore, we must check whether the target resource already exists to apply the appropriate permission rules.
44
47
  permission = _spaces.SPACE_OPERATION.MODIFY;
45
48
  } else {
46
- permission = _spaces.SPACE_HTTP_PERMISSION[req.method];
49
+ // The override is applied for specific POST methods that update an existing file rather than creating it.
50
+ permission = overrideSpacePermission || _spaces.SPACE_HTTP_PERMISSION[req.method];
47
51
  }
48
52
  if (!(0, _permissions.haveSpaceEnvPermissions)(req.space, permission)) {
49
53
  logger.warn(`is not allowed to ${req.method} on this space path : *${req.space.alias}* (${req.space.id}) : ${req.space.url}`);
@@ -65,31 +69,26 @@ let SpaceGuard = class SpaceGuard {
65
69
  }
66
70
  }
67
71
  async canActivate(ctx) {
68
- const skipSpaceGuard = this.reflector.getAllAndOverride(_spaceskipguarddecorator.SKIP_SPACE_GUARD, [
72
+ if (this.reflector.getAllAndOverride(_spaceskipguarddecorator.SKIP_SPACE_GUARD, [
69
73
  ctx.getHandler(),
70
74
  ctx.getClass()
71
- ]);
72
- if (skipSpaceGuard) {
75
+ ])) {
73
76
  return true;
74
77
  }
75
- const skipSpacePermissionsCheck = this.reflector.getAllAndOverride(_spaceskippermissionsdecorator.SKIP_SPACE_PERMISSIONS_CHECK, [
76
- ctx.getHandler(),
77
- ctx.getClass()
78
- ]);
79
78
  const req = ctx.switchToHttp().getRequest();
80
- const onlyOfficeContext = this.reflector.getAllAndOverride(_onlyoffice.ONLY_OFFICE_CONTEXT, [
79
+ const webDAVContext = this.reflector.getAllAndOverride(_webdavcontextdecorator.WEB_DAV_CONTEXT, [
81
80
  ctx.getHandler(),
82
81
  ctx.getClass()
83
82
  ]);
84
- const webDAVContext = this.reflector.getAllAndOverride(_webdavcontextdecorator.WEB_DAV_CONTEXT, [
83
+ const syncContext = this.reflector.getAllAndOverride(_synccontextdecorator.SYNC_CONTEXT, [
85
84
  ctx.getHandler(),
86
85
  ctx.getClass()
87
86
  ]);
88
- const syncContext = this.reflector.getAllAndOverride(_synccontextdecorator.SYNC_CONTEXT, [
87
+ const collaboraOnlineContext = this.reflector.getAllAndOverride(_collaboraonlineconstants.COLLABORA_CONTEXT, [
89
88
  ctx.getHandler(),
90
89
  ctx.getClass()
91
90
  ]);
92
- const urlSegments = this.urlSegmentsFromContext(req, webDAVContext, syncContext);
91
+ const urlSegments = this.urlSegmentsFromContext(req, webDAVContext, syncContext, collaboraOnlineContext);
93
92
  this.checkAccessToSpace(req, urlSegments);
94
93
  let space;
95
94
  try {
@@ -107,25 +106,33 @@ let SpaceGuard = class SpaceGuard {
107
106
  }
108
107
  // assign space to request
109
108
  req.space = space;
109
+ const skipSpacePermissionsCheck = this.reflector.getAllAndOverride(_spaceskippermissionsdecorator.SKIP_SPACE_PERMISSIONS_CHECK, [
110
+ ctx.getHandler(),
111
+ ctx.getClass()
112
+ ]);
110
113
  if (skipSpacePermissionsCheck === undefined) {
111
- SpaceGuard.checkPermissions(req, this.logger, onlyOfficeContext);
114
+ const overrideSpacePermission = this.reflector.getAllAndOverride(_spaceoverridepermissiondecorator.OverrideSpacePermission, [
115
+ ctx.getHandler(),
116
+ ctx.getClass()
117
+ ]);
118
+ await SpaceGuard.checkPermissions(req, this.logger, overrideSpacePermission);
112
119
  }
113
120
  return true;
114
121
  }
115
- urlSegmentsFromContext(req, webDAVContext, syncContext) {
116
- if (webDAVContext || syncContext) {
117
- try {
118
- if (webDAVContext) {
119
- return (0, _routes2.WEBDAV_PATH_TO_SPACE_SEGMENTS)(req.params['*']);
120
- } else {
121
- return (0, _routes1.SYNC_PATH_TO_SPACE_SEGMENTS)(req.params['*']);
122
- }
123
- } catch (e) {
124
- this.logger.warn(`${this.canActivate.name} - ${e}`);
125
- throw new _common.HttpException(e.message, _common.HttpStatus.NOT_FOUND);
122
+ urlSegmentsFromContext(req, webDAVContext, syncContext, collaboraOnlineContext) {
123
+ try {
124
+ if (webDAVContext) {
125
+ return (0, _routes1.WEBDAV_PATH_TO_SPACE_SEGMENTS)(req.params['*']);
126
+ } else if (syncContext) {
127
+ return (0, _routes.SYNC_PATH_TO_SPACE_SEGMENTS)(req.params['*']);
128
+ } else if (collaboraOnlineContext) {
129
+ return (0, _collaboraonlineutils.COLLABORA_ONLINE_TO_SPACE_SEGMENTS)(req);
126
130
  }
131
+ return (0, _routes2.PATH_TO_SPACE_SEGMENTS)(req.params['*']);
132
+ } catch (e) {
133
+ this.logger.warn(`${this.canActivate.name} - ${e}`);
134
+ throw new _common.HttpException(e.message, _common.HttpStatus.NOT_FOUND);
127
135
  }
128
- return (0, _routes3.PATH_TO_SPACE_SEGMENTS)(req.params['*']);
129
136
  }
130
137
  checkAccessToSpace(req, urlSegments) {
131
138
  if (!(0, _permissions.canAccessToSpaceUrl)(req.user, urlSegments)) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../backend/src/applications/spaces/guards/space.guard.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 { CanActivate, ExecutionContext, HttpException, HttpStatus, Injectable, Logger } from '@nestjs/common'\nimport { Reflector } from '@nestjs/core'\nimport { HTTP_METHOD } from '../../applications.constants'\nimport { ONLY_OFFICE_CONTEXT } from '../../files/constants/only-office'\nimport { API_FILES_ONLY_OFFICE_CALLBACK } from '../../files/constants/routes'\nimport { SYNC_CONTEXT } from '../../sync/decorators/sync-context.decorator'\nimport { SYNC_PATH_TO_SPACE_SEGMENTS } from '../../sync/utils/routes'\nimport { WEB_DAV_CONTEXT } from '../../webdav/decorators/webdav-context.decorator'\nimport { WEBDAV_PATH_TO_SPACE_SEGMENTS } from '../../webdav/utils/routes'\nimport { SPACE_HTTP_PERMISSION, SPACE_OPERATION } from '../constants/spaces'\nimport { SKIP_SPACE_GUARD } from '../decorators/space-skip-guard.decorator'\nimport { SKIP_SPACE_PERMISSIONS_CHECK } from '../decorators/space-skip-permissions.decorator'\nimport { FastifySpaceRequest } from '../interfaces/space-request.interface'\nimport { SpaceEnv } from '../models/space-env.model'\nimport { SpacesManager } from '../services/spaces-manager.service'\nimport { canAccessToSpaceUrl, haveSpaceEnvPermissions } from '../utils/permissions'\nimport { PATH_TO_SPACE_SEGMENTS } from '../utils/routes'\n\n@Injectable()\nexport class SpaceGuard implements CanActivate {\n private readonly logger = new Logger(SpaceGuard.name)\n\n constructor(\n private readonly reflector: Reflector,\n private readonly spacesManager: SpacesManager\n ) {}\n\n static checkPermissions(req: FastifySpaceRequest, logger: Logger, onlyOfficeContext = false) {\n let permission: SPACE_OPERATION\n if (onlyOfficeContext && req.method === HTTP_METHOD.POST && req.originalUrl.startsWith(API_FILES_ONLY_OFFICE_CALLBACK)) {\n // special case : onlyoffice callback use post method to update documents\n permission = SPACE_OPERATION.MODIFY\n } else {\n permission = SPACE_HTTP_PERMISSION[req.method]\n }\n if (!haveSpaceEnvPermissions(req.space, permission)) {\n logger.warn(`is not allowed to ${req.method} on this space path : *${req.space.alias}* (${req.space.id}) : ${req.space.url}`)\n throw new HttpException('You are not allowed to do this action', HttpStatus.FORBIDDEN)\n }\n if ([SPACE_OPERATION.ADD, SPACE_OPERATION.MODIFY].indexOf(permission) > -1) {\n if (req.space.quotaIsExceeded) {\n logger.warn(`Storage quota exceeded for *${req.space.alias}* (${req.space.id})`)\n throw new HttpException('Storage quota exceeded', HttpStatus.INSUFFICIENT_STORAGE)\n } else if (req.space.storageQuota) {\n const contentLength = parseInt(req.headers['content-length'] || '0', 10) || 0\n if (req.space.willExceedQuota(contentLength)) {\n throw new HttpException('Storage quota will be exceeded', HttpStatus.INSUFFICIENT_STORAGE)\n }\n }\n }\n }\n\n async canActivate(ctx: ExecutionContext): Promise<boolean> {\n const skipSpaceGuard = this.reflector.getAllAndOverride(SKIP_SPACE_GUARD, [ctx.getHandler(), ctx.getClass()])\n if (skipSpaceGuard) {\n return true\n }\n const skipSpacePermissionsCheck = this.reflector.getAllAndOverride(SKIP_SPACE_PERMISSIONS_CHECK, [ctx.getHandler(), ctx.getClass()])\n const req: FastifySpaceRequest = ctx.switchToHttp().getRequest()\n const onlyOfficeContext = this.reflector.getAllAndOverride(ONLY_OFFICE_CONTEXT, [ctx.getHandler(), ctx.getClass()])\n const webDAVContext = this.reflector.getAllAndOverride(WEB_DAV_CONTEXT, [ctx.getHandler(), ctx.getClass()])\n const syncContext = this.reflector.getAllAndOverride(SYNC_CONTEXT, [ctx.getHandler(), ctx.getClass()])\n const urlSegments = this.urlSegmentsFromContext(req, webDAVContext, syncContext)\n this.checkAccessToSpace(req, urlSegments)\n let space: SpaceEnv\n try {\n space = await this.spacesManager.spaceEnv(req.user, urlSegments)\n } catch (e) {\n this.logger.warn(`${this.canActivate.name} - ${e}`)\n throw new HttpException('Space path is not valid', HttpStatus.BAD_REQUEST)\n }\n if (!space) {\n this.logger.warn(`${this.canActivate.name} - space not authorized or not found : ${req.params['*']}`)\n throw new HttpException('Space not found', HttpStatus.NOT_FOUND)\n }\n if (!space.enabled) {\n throw new HttpException('Space is disabled', HttpStatus.FORBIDDEN)\n }\n // assign space to request\n req.space = space\n if (skipSpacePermissionsCheck === undefined) {\n SpaceGuard.checkPermissions(req, this.logger, onlyOfficeContext)\n }\n return true\n }\n\n private urlSegmentsFromContext(req: FastifySpaceRequest, webDAVContext: boolean, syncContext: boolean): string[] {\n if (webDAVContext || syncContext) {\n try {\n if (webDAVContext) {\n return WEBDAV_PATH_TO_SPACE_SEGMENTS(req.params['*'])\n } else {\n return SYNC_PATH_TO_SPACE_SEGMENTS(req.params['*'])\n }\n } catch (e) {\n this.logger.warn(`${this.canActivate.name} - ${e}`)\n throw new HttpException(e.message, HttpStatus.NOT_FOUND)\n }\n }\n return PATH_TO_SPACE_SEGMENTS(req.params['*'])\n }\n\n private checkAccessToSpace(req: FastifySpaceRequest, urlSegments: string[]) {\n if (!canAccessToSpaceUrl(req.user, urlSegments)) {\n this.logger.warn(`is not allowed to access to this space repository : ${req.params['*']}`)\n throw new HttpException('You are not allowed to access to this repository', HttpStatus.FORBIDDEN)\n }\n }\n}\n"],"names":["SpaceGuard","checkPermissions","req","logger","onlyOfficeContext","permission","method","HTTP_METHOD","POST","originalUrl","startsWith","API_FILES_ONLY_OFFICE_CALLBACK","SPACE_OPERATION","MODIFY","SPACE_HTTP_PERMISSION","haveSpaceEnvPermissions","space","warn","alias","id","url","HttpException","HttpStatus","FORBIDDEN","ADD","indexOf","quotaIsExceeded","INSUFFICIENT_STORAGE","storageQuota","contentLength","parseInt","headers","willExceedQuota","canActivate","ctx","skipSpaceGuard","reflector","getAllAndOverride","SKIP_SPACE_GUARD","getHandler","getClass","skipSpacePermissionsCheck","SKIP_SPACE_PERMISSIONS_CHECK","switchToHttp","getRequest","ONLY_OFFICE_CONTEXT","webDAVContext","WEB_DAV_CONTEXT","syncContext","SYNC_CONTEXT","urlSegments","urlSegmentsFromContext","checkAccessToSpace","spacesManager","spaceEnv","user","e","name","BAD_REQUEST","params","NOT_FOUND","enabled","undefined","WEBDAV_PATH_TO_SPACE_SEGMENTS","SYNC_PATH_TO_SPACE_SEGMENTS","message","PATH_TO_SPACE_SEGMENTS","canAccessToSpaceUrl","Logger"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../../backend/src/applications/spaces/guards/space.guard.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 { CanActivate, ExecutionContext, HttpException, HttpStatus, Injectable, Logger } from '@nestjs/common'\nimport { Reflector } from '@nestjs/core'\nimport { HTTP_METHOD } from '../../applications.constants'\nimport { COLLABORA_CONTEXT } from '../../files/modules/collabora-online/collabora-online.constants'\nimport { COLLABORA_ONLINE_TO_SPACE_SEGMENTS } from '../../files/modules/collabora-online/collabora-online.utils'\nimport { isPathExists, isPathIsDir } from '../../files/utils/files'\nimport { SYNC_CONTEXT } from '../../sync/decorators/sync-context.decorator'\nimport { SYNC_PATH_TO_SPACE_SEGMENTS } from '../../sync/utils/routes'\nimport { WEB_DAV_CONTEXT } from '../../webdav/decorators/webdav-context.decorator'\nimport { WEBDAV_PATH_TO_SPACE_SEGMENTS } from '../../webdav/utils/routes'\nimport { SPACE_HTTP_PERMISSION, SPACE_OPERATION } from '../constants/spaces'\nimport { OverrideSpacePermission } from '../decorators/space-override-permission.decorator'\nimport { SKIP_SPACE_GUARD } from '../decorators/space-skip-guard.decorator'\nimport { SKIP_SPACE_PERMISSIONS_CHECK } from '../decorators/space-skip-permissions.decorator'\nimport { FastifySpaceRequest } from '../interfaces/space-request.interface'\nimport { SpaceEnv } from '../models/space-env.model'\nimport { SpacesManager } from '../services/spaces-manager.service'\nimport { canAccessToSpaceUrl, haveSpaceEnvPermissions } from '../utils/permissions'\nimport { PATH_TO_SPACE_SEGMENTS } from '../utils/routes'\n\n@Injectable()\nexport class SpaceGuard implements CanActivate {\n private readonly logger = new Logger(SpaceGuard.name)\n\n constructor(\n private readonly reflector: Reflector,\n private readonly spacesManager: SpacesManager\n ) {}\n\n static async checkPermissions(req: FastifySpaceRequest, logger: Logger, overrideSpacePermission?: SPACE_OPERATION) {\n let permission: SPACE_OPERATION\n if (req.method === HTTP_METHOD.PUT && (await isPathExists(req.space.realPath)) && !(await isPathIsDir(req.space.realPath))) {\n // PUT method may either create a new resource or replace an existing one.\n // Therefore, we must check whether the target resource already exists to apply the appropriate permission rules.\n permission = SPACE_OPERATION.MODIFY\n } else {\n // The override is applied for specific POST methods that update an existing file rather than creating it.\n permission = overrideSpacePermission || SPACE_HTTP_PERMISSION[req.method]\n }\n if (!haveSpaceEnvPermissions(req.space, permission)) {\n logger.warn(`is not allowed to ${req.method} on this space path : *${req.space.alias}* (${req.space.id}) : ${req.space.url}`)\n throw new HttpException('You are not allowed to do this action', HttpStatus.FORBIDDEN)\n }\n if ([SPACE_OPERATION.ADD, SPACE_OPERATION.MODIFY].indexOf(permission) > -1) {\n if (req.space.quotaIsExceeded) {\n logger.warn(`Storage quota exceeded for *${req.space.alias}* (${req.space.id})`)\n throw new HttpException('Storage quota exceeded', HttpStatus.INSUFFICIENT_STORAGE)\n } else if (req.space.storageQuota) {\n const contentLength = parseInt(req.headers['content-length'] || '0', 10) || 0\n if (req.space.willExceedQuota(contentLength)) {\n throw new HttpException('Storage quota will be exceeded', HttpStatus.INSUFFICIENT_STORAGE)\n }\n }\n }\n }\n\n async canActivate(ctx: ExecutionContext): Promise<boolean> {\n if (this.reflector.getAllAndOverride(SKIP_SPACE_GUARD, [ctx.getHandler(), ctx.getClass()])) {\n return true\n }\n\n const req: FastifySpaceRequest = ctx.switchToHttp().getRequest()\n const webDAVContext = this.reflector.getAllAndOverride(WEB_DAV_CONTEXT, [ctx.getHandler(), ctx.getClass()])\n const syncContext = this.reflector.getAllAndOverride(SYNC_CONTEXT, [ctx.getHandler(), ctx.getClass()])\n const collaboraOnlineContext = this.reflector.getAllAndOverride(COLLABORA_CONTEXT, [ctx.getHandler(), ctx.getClass()])\n\n const urlSegments = this.urlSegmentsFromContext(req, webDAVContext, syncContext, collaboraOnlineContext)\n this.checkAccessToSpace(req, urlSegments)\n let space: SpaceEnv\n try {\n space = await this.spacesManager.spaceEnv(req.user, urlSegments)\n } catch (e) {\n this.logger.warn(`${this.canActivate.name} - ${e}`)\n throw new HttpException('Space path is not valid', HttpStatus.BAD_REQUEST)\n }\n if (!space) {\n this.logger.warn(`${this.canActivate.name} - space not authorized or not found : ${req.params['*']}`)\n throw new HttpException('Space not found', HttpStatus.NOT_FOUND)\n }\n if (!space.enabled) {\n throw new HttpException('Space is disabled', HttpStatus.FORBIDDEN)\n }\n // assign space to request\n req.space = space\n const skipSpacePermissionsCheck = this.reflector.getAllAndOverride(SKIP_SPACE_PERMISSIONS_CHECK, [ctx.getHandler(), ctx.getClass()])\n if (skipSpacePermissionsCheck === undefined) {\n const overrideSpacePermission: SPACE_OPERATION = this.reflector.getAllAndOverride(OverrideSpacePermission, [ctx.getHandler(), ctx.getClass()])\n await SpaceGuard.checkPermissions(req, this.logger, overrideSpacePermission)\n }\n return true\n }\n\n private urlSegmentsFromContext(req: FastifySpaceRequest, webDAVContext: boolean, syncContext: boolean, collaboraOnlineContext: boolean): string[] {\n try {\n if (webDAVContext) {\n return WEBDAV_PATH_TO_SPACE_SEGMENTS(req.params['*'])\n } else if (syncContext) {\n return SYNC_PATH_TO_SPACE_SEGMENTS(req.params['*'])\n } else if (collaboraOnlineContext) {\n return COLLABORA_ONLINE_TO_SPACE_SEGMENTS(req)\n }\n return PATH_TO_SPACE_SEGMENTS(req.params['*'])\n } catch (e) {\n this.logger.warn(`${this.canActivate.name} - ${e}`)\n throw new HttpException(e.message, HttpStatus.NOT_FOUND)\n }\n }\n\n private checkAccessToSpace(req: FastifySpaceRequest, urlSegments: string[]) {\n if (!canAccessToSpaceUrl(req.user, urlSegments)) {\n this.logger.warn(`is not allowed to access to this space repository : ${req.params['*']}`)\n throw new HttpException('You are not allowed to access to this repository', HttpStatus.FORBIDDEN)\n }\n }\n}\n"],"names":["SpaceGuard","checkPermissions","req","logger","overrideSpacePermission","permission","method","HTTP_METHOD","PUT","isPathExists","space","realPath","isPathIsDir","SPACE_OPERATION","MODIFY","SPACE_HTTP_PERMISSION","haveSpaceEnvPermissions","warn","alias","id","url","HttpException","HttpStatus","FORBIDDEN","ADD","indexOf","quotaIsExceeded","INSUFFICIENT_STORAGE","storageQuota","contentLength","parseInt","headers","willExceedQuota","canActivate","ctx","reflector","getAllAndOverride","SKIP_SPACE_GUARD","getHandler","getClass","switchToHttp","getRequest","webDAVContext","WEB_DAV_CONTEXT","syncContext","SYNC_CONTEXT","collaboraOnlineContext","COLLABORA_CONTEXT","urlSegments","urlSegmentsFromContext","checkAccessToSpace","spacesManager","spaceEnv","user","e","name","BAD_REQUEST","params","NOT_FOUND","enabled","skipSpacePermissionsCheck","SKIP_SPACE_PERMISSIONS_CHECK","undefined","OverrideSpacePermission","WEBDAV_PATH_TO_SPACE_SEGMENTS","SYNC_PATH_TO_SPACE_SEGMENTS","COLLABORA_ONLINE_TO_SPACE_SEGMENTS","PATH_TO_SPACE_SEGMENTS","message","canAccessToSpaceUrl","Logger"],"mappings":"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"}
@@ -13,8 +13,6 @@ const _shared = require("../../../common/shared");
13
13
  const _cacheservice = require("../../../infrastructure/cache/services/cache.service");
14
14
  const _contextmanagerservice = require("../../../infrastructure/context/services/context-manager.service");
15
15
  const _constants = require("../../../infrastructure/database/constants");
16
- const _routes = require("../../files/constants/routes");
17
- const _onlyofficeenvironmentdecorator = require("../../files/decorators/only-office-environment.decorator");
18
16
  const _filesqueriesservice = require("../../files/services/files-queries.service");
19
17
  const _linksqueriesservice = require("../../links/services/links-queries.service");
20
18
  const _notificationsmanagerservice = require("../../notifications/services/notifications-manager.service");
@@ -28,6 +26,7 @@ const _usersqueriesservice = require("../../users/services/users-queries.service
28
26
  const _test = require("../../users/utils/test");
29
27
  const _webdavcontextdecorator = require("../../webdav/decorators/webdav-context.decorator");
30
28
  const _spaces = require("../constants/spaces");
29
+ const _spaceoverridepermissiondecorator = require("../decorators/space-override-permission.decorator");
31
30
  const _spaceskipguarddecorator = require("../decorators/space-skip-guard.decorator");
32
31
  const _spaceskippermissionsdecorator = require("../decorators/space-skip-permissions.decorator");
33
32
  const _spacesmanagerservice = require("../services/spaces-manager.service");
@@ -74,6 +73,8 @@ describe(_spaceguard.SpaceGuard.name, ()=>{
74
73
  // mocks
75
74
  spacesManager['setQuotaExceeded'] = jest.fn();
76
75
  userTest = new _usermodel.UserModel((0, _test.generateUserTest)());
76
+ });
77
+ beforeEach(()=>{
77
78
  context = (0, _tsjest.createMock)();
78
79
  });
79
80
  it('should be defined', ()=>{
@@ -386,8 +387,6 @@ describe(_spaceguard.SpaceGuard.name, ()=>{
386
387
  }
387
388
  });
388
389
  expect(await spacesGuard.canActivate(context)).toBe(true);
389
- // reset context
390
- context = (0, _tsjest.createMock)();
391
390
  });
392
391
  it('should fail with quota exceeded', async ()=>{
393
392
  userTest.role = _user.USER_ROLE.USER;
@@ -482,9 +481,8 @@ describe(_spaceguard.SpaceGuard.name, ()=>{
482
481
  }
483
482
  });
484
483
  await expect(spacesGuard.canActivate(context)).rejects.toThrow(_common.HttpException);
485
- // reset context
484
+ // reset mock
486
485
  spyUrlSegment.mockRestore();
487
- context = (0, _tsjest.createMock)();
488
486
  });
489
487
  it('should validate (or not) the sync routes', async ()=>{
490
488
  userTest.role = _user.USER_ROLE.USER;
@@ -514,24 +512,25 @@ describe(_spaceguard.SpaceGuard.name, ()=>{
514
512
  await expect(spacesGuard.canActivate(context)).rejects.toThrow(_common.HttpException);
515
513
  // reset context
516
514
  spyUrlSegment.mockRestore();
517
- context = (0, _tsjest.createMock)();
518
515
  });
519
- it('should require the modify permission when using the POST method on the OnlyOffice callback URL', async ()=>{
516
+ it('should allow the modify permission when using the POST method with override space permission decorator', async ()=>{
520
517
  userTest.role = _user.USER_ROLE.USER;
521
518
  spacesManager.spaceEnv = jest.fn().mockReturnValue({
522
519
  enabled: true,
523
520
  envPermissions: `${_spaces.SPACE_OPERATION.MODIFY}`
524
521
  });
525
- (0, _onlyofficeenvironmentdecorator.OnlyOfficeContext)()(context.getHandler());
522
+ (0, _spaceoverridepermissiondecorator.OverrideSpacePermission)(_spaces.SPACE_OPERATION.MODIFY)(context.getHandler());
526
523
  context.switchToHttp().getRequest.mockReturnValue({
527
524
  method: 'POST',
528
525
  user: userTest,
529
- originalUrl: _routes.API_FILES_ONLY_OFFICE_CALLBACK,
526
+ originalUrl: '1',
530
527
  params: {
531
528
  '*': 'files/personal/root'
532
529
  }
533
530
  });
534
531
  expect(await spacesGuard.canActivate(context)).toBe(true);
532
+ // reset context
533
+ context = (0, _tsjest.createMock)();
535
534
  spacesManager.spaceEnv = jest.fn().mockReturnValue({
536
535
  enabled: true,
537
536
  envPermissions: `${_spaces.SPACE_OPERATION.ADD}`
@@ -540,14 +539,12 @@ describe(_spaceguard.SpaceGuard.name, ()=>{
540
539
  context.switchToHttp().getRequest.mockReturnValue({
541
540
  method: 'POST',
542
541
  user: userTest,
543
- originalUrl: '',
542
+ originalUrl: '2',
544
543
  params: {
545
544
  '*': 'files/personal/root'
546
545
  }
547
546
  });
548
547
  expect(await spacesGuard.canActivate(context)).toBe(true);
549
- // reset context
550
- context = (0, _tsjest.createMock)();
551
548
  });
552
549
  it('should pass if skipSpaceGuard context is enabled', async ()=>{
553
550
  userTest.role = _user.USER_ROLE.USER;
@@ -568,8 +565,6 @@ describe(_spaceguard.SpaceGuard.name, ()=>{
568
565
  });
569
566
  (0, _spaceskipguarddecorator.SkipSpaceGuard)()(context.getHandler());
570
567
  expect(await spacesGuard.canActivate(context)).toBe(true);
571
- // reset context
572
- context = (0, _tsjest.createMock)();
573
568
  });
574
569
  it('coverage only', async ()=>{
575
570
  userTest.role = _user.USER_ROLE.USER;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../backend/src/applications/spaces/guards/space.guard.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 { createMock, DeepMocked } from '@golevelup/ts-jest'\nimport { ExecutionContext, HttpException, HttpStatus } from '@nestjs/common'\nimport { Test, TestingModule } from '@nestjs/testing'\nimport { intersectPermissions } from '../../../common/shared'\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 { API_FILES_ONLY_OFFICE_CALLBACK } from '../../files/constants/routes'\nimport { OnlyOfficeContext } from '../../files/decorators/only-office-environment.decorator'\nimport { FilesQueries } from '../../files/services/files-queries.service'\nimport { LinksQueries } from '../../links/services/links-queries.service'\nimport { NotificationsManager } from '../../notifications/services/notifications-manager.service'\nimport { SHARE_ALL_OPERATIONS } from '../../shares/constants/shares'\nimport { SharesManager } from '../../shares/services/shares-manager.service'\nimport { SharesQueries } from '../../shares/services/shares-queries.service'\nimport { SyncContext } from '../../sync/decorators/sync-context.decorator'\nimport { USER_PERMISSION, USER_ROLE } from '../../users/constants/user'\nimport { UserModel } from '../../users/models/user.model'\nimport { UsersQueries } from '../../users/services/users-queries.service'\nimport { generateUserTest } from '../../users/utils/test'\nimport { WebDAVContext } from '../../webdav/decorators/webdav-context.decorator'\nimport { SPACE_ALIAS, SPACE_ALL_OPERATIONS, SPACE_OPERATION, SPACE_PERMS_SEP, SPACE_REPOSITORY } from '../constants/spaces'\nimport { SkipSpaceGuard } from '../decorators/space-skip-guard.decorator'\nimport { SkipSpacePermissionsCheck } from '../decorators/space-skip-permissions.decorator'\nimport { SpaceEnv } from '../models/space-env.model'\nimport { SpacesManager } from '../services/spaces-manager.service'\nimport { SpacesQueries } from '../services/spaces-queries.service'\nimport { SpaceGuard } from './space.guard'\n\ndescribe(SpaceGuard.name, () => {\n let spacesGuard: SpaceGuard\n let spacesManager: SpacesManager\n let spacesQueries: SpacesQueries\n let userTest: UserModel\n let context: DeepMocked<ExecutionContext>\n\n beforeAll(async () => {\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 SpaceGuard,\n SpacesManager,\n SpacesQueries,\n SharesManager,\n SharesQueries,\n FilesQueries,\n UsersQueries,\n LinksQueries\n ]\n }).compile()\n\n spacesManager = module.get<SpacesManager>(SpacesManager)\n spacesQueries = module.get<SpacesQueries>(SpacesQueries)\n spacesGuard = module.get<SpaceGuard>(SpaceGuard)\n // mocks\n spacesManager['setQuotaExceeded'] = jest.fn()\n userTest = new UserModel(generateUserTest())\n context = createMock<ExecutionContext>()\n })\n\n it('should be defined', () => {\n expect(spacesGuard).toBeDefined()\n expect(spacesManager).toBeDefined()\n expect(userTest).toBeDefined()\n })\n\n it('should pass for a personal space', async () => {\n context.switchToHttp().getRequest.mockReturnValue({\n user: userTest,\n params: { '*': 'files/personal/root/foo/bar' }\n })\n expect(await spacesGuard.canActivate(context)).toBe(true)\n const req: any = context.switchToHttp().getRequest()\n expect(req.space.id).toBe(0)\n expect(req.space.repository).toBe(SPACE_REPOSITORY.FILES)\n expect(req.space.alias).toBe(SPACE_ALIAS.PERSONAL)\n expect(req.space.name).toBe(SPACE_ALIAS.PERSONAL)\n expect(req.space.enabled).toBe(true)\n expect(req.space.root).toBeUndefined()\n expect(req.space.dbFile).toMatchObject({ inTrash: false, ownerId: userTest.id, path: 'root/foo/bar' })\n expect(req.space.permissions).toBe(SPACE_ALL_OPERATIONS)\n expect(req.space.envPermissions).toBe(SPACE_ALL_OPERATIONS)\n expect(req.space.inFilesRepository).toBe(true)\n expect(req.space.inPersonalSpace).toBe(true)\n expect(req.space.inTrashRepository).toBe(false)\n expect(req.space.inSharesRepository).toBe(false)\n expect(req.space.inSharesList).toBe(false)\n expect(req.space.paths).toEqual(expect.arrayContaining(['root', 'foo', 'bar']))\n })\n\n it('should pass for a common space', async () => {\n const fakeSpace = {\n id: -1,\n alias: 'test',\n name: 'Test',\n enabled: true,\n permissions: ':a:d:m:so',\n role: 0\n }\n spacesQueries.permissions = jest.fn().mockReturnValueOnce(fakeSpace)\n context.switchToHttp().getRequest.mockReturnValue({\n user: userTest,\n params: { '*': 'files/test' }\n })\n expect(await spacesGuard.canActivate(context)).toBe(true)\n const req: any = context.switchToHttp().getRequest()\n expect(req.space.id).toBe(fakeSpace.id)\n expect(req.space.repository).toBe(SPACE_REPOSITORY.FILES)\n expect(req.space.alias).toBe(fakeSpace.alias)\n expect(req.space.name).toBe(fakeSpace.name)\n expect(req.space.enabled).toBe(true)\n expect(req.space.root).toMatchObject({ id: 0, alias: '', name: '', permissions: 'a:d:m:so' })\n expect(req.space.dbFile).toMatchObject({ inTrash: false, spaceId: fakeSpace.id, spaceExternalRootId: null, path: '.' })\n expect(req.space.permissions).toBe(SHARE_ALL_OPERATIONS)\n expect(req.space.envPermissions).not.toContain('d')\n expect(req.space.inFilesRepository).toBe(true)\n expect(req.space.inPersonalSpace).toBe(false)\n expect(req.space.inTrashRepository).toBe(false)\n expect(req.space.inSharesRepository).toBe(false)\n expect(req.space.inSharesList).toBe(false)\n expect(req.space.paths).toHaveLength(0)\n })\n\n it('should pass for a common space root', async () => {\n const fakeSpace = {\n id: -1,\n alias: 'test',\n name: 'Test',\n enabled: true,\n permissions: 'a:d:m:so',\n role: 1,\n root: {\n id: -2,\n alias: 'root',\n name: 'Root',\n permissions: 'a:d:so',\n owner: { id: -3, login: 'johaven' },\n file: { id: -4, path: 'code', inTrash: false },\n externalPath: null\n }\n }\n spacesQueries.permissions = jest.fn().mockReturnValueOnce(fakeSpace)\n context.switchToHttp().getRequest.mockReturnValue({\n user: userTest,\n params: { '*': 'files/test/root' }\n })\n expect(await spacesGuard.canActivate(context)).toBe(true)\n const req: any = context.switchToHttp().getRequest()\n expect(req.space.id).toBe(fakeSpace.id)\n expect(req.space.repository).toBe(SPACE_REPOSITORY.FILES)\n expect(req.space.alias).toBe(fakeSpace.alias)\n expect(req.space.name).toBe(fakeSpace.name)\n expect(req.space.enabled).toBe(true)\n expect(req.space.root).toMatchObject(fakeSpace.root)\n expect(req.space.dbFile).toMatchObject({ inTrash: false, ownerId: fakeSpace.root.owner.id, path: fakeSpace.root.file.path })\n expect(req.space.permissions).toBe(SPACE_ALL_OPERATIONS)\n expect(req.space.envPermissions).toBe(\n intersectPermissions(fakeSpace.permissions, fakeSpace.root.permissions)\n .split(SPACE_PERMS_SEP)\n .filter((p) => p !== SPACE_OPERATION.DELETE)\n .join(SPACE_PERMS_SEP)\n )\n expect(req.space.inFilesRepository).toBe(true)\n expect(req.space.inPersonalSpace).toBe(false)\n expect(req.space.inTrashRepository).toBe(false)\n expect(req.space.inSharesRepository).toBe(false)\n expect(req.space.inSharesList).toBe(false)\n expect(req.space.paths).toHaveLength(0)\n })\n\n it('should pass for a common space root with a path', async () => {\n const fakeSpace = {\n id: -1,\n alias: 'test',\n name: 'Test',\n enabled: true,\n permissions: 'a:d:m:so',\n role: 1,\n root: {\n id: -2,\n alias: 'root',\n name: 'Root',\n permissions: 'a:d:so',\n owner: { id: -3, login: 'johaven' },\n file: { id: -4, path: 'code', inTrash: false },\n externalPath: null\n }\n }\n spacesQueries.permissions = jest.fn().mockReturnValueOnce(fakeSpace)\n context.switchToHttp().getRequest.mockReturnValue({\n user: userTest,\n params: { '*': 'files/test/root/path' }\n })\n expect(await spacesGuard.canActivate(context)).toBe(true)\n const req: any = context.switchToHttp().getRequest()\n expect(req.space.id).toBe(fakeSpace.id)\n expect(req.space.repository).toBe(SPACE_REPOSITORY.FILES)\n expect(req.space.alias).toBe(fakeSpace.alias)\n expect(req.space.name).toBe(fakeSpace.name)\n expect(req.space.enabled).toBe(true)\n expect(req.space.root).toMatchObject(fakeSpace.root)\n expect(req.space.dbFile).toMatchObject({\n inTrash: false,\n ownerId: fakeSpace.root.owner.id,\n path: `${fakeSpace.root.file.path}/${req.space.paths[0]}`\n })\n expect(req.space.permissions).toBe(SPACE_ALL_OPERATIONS)\n expect(req.space.envPermissions).toBe(fakeSpace.root.permissions)\n expect(req.space.inFilesRepository).toBe(true)\n expect(req.space.inPersonalSpace).toBe(false)\n expect(req.space.inTrashRepository).toBe(false)\n expect(req.space.inSharesRepository).toBe(false)\n expect(req.space.inSharesList).toBe(false)\n expect(req.space.paths).toHaveLength(1)\n })\n\n it('should pass for a space in shares repository', async () => {\n context.switchToHttp().getRequest.mockReturnValue({\n user: userTest,\n params: { '*': 'shares' }\n })\n expect(await spacesGuard.canActivate(context)).toBe(true)\n const req: any = context.switchToHttp().getRequest()\n expect(req.space.id).toBe(0)\n expect(req.space.repository).toBe(SPACE_REPOSITORY.SHARES)\n expect(req.space.alias).toBe(SPACE_REPOSITORY.SHARES)\n expect(req.space.name).toBe(SPACE_REPOSITORY.SHARES)\n expect(req.space.enabled).toBe(true)\n expect(req.space.root).toBeUndefined()\n expect(req.space.dbFile).toBeUndefined()\n expect(req.space.permissions).toBe('')\n expect(req.space.envPermissions).toBe('')\n expect(req.space.inFilesRepository).toBe(false)\n expect(req.space.inPersonalSpace).toBe(false)\n expect(req.space.inTrashRepository).toBe(false)\n expect(req.space.inSharesRepository).toBe(true)\n expect(req.space.inSharesList).toBe(true)\n expect(req.space.paths).toHaveLength(0)\n })\n\n it('should not pass if the space is not found or not valid', async () => {\n const fakeSpace = null\n spacesQueries.permissions = jest.fn().mockReturnValueOnce(fakeSpace)\n context.switchToHttp().getRequest.mockReturnValue({\n user: userTest,\n params: { '*': 'files/foo' }\n })\n await expect(spacesGuard.canActivate(context)).rejects.toThrow(HttpException)\n })\n\n it('should validate (or not) the access to the space depending on the user permissions', async () => {\n // we only check the `spacesManager.checkAccessToSpace` function, ignores the `spacesManager.spaceEnv`\n userTest.applications = [USER_PERMISSION.PERSONAL_SPACE]\n for (const url of ['', 'shares/personal', 'shares/toto']) {\n context.switchToHttp().getRequest.mockReturnValue({\n user: userTest,\n params: { '*': url }\n })\n await expect(spacesGuard.canActivate(context)).rejects.toThrow(HttpException)\n }\n // should pass because it is a standard user\n // should not pass because user is a guest (and dot not have the permission to access to a personal space)\n spacesManager.spaceEnv = jest.fn().mockReturnValueOnce({ enabled: true }) // only for user role\n context.switchToHttp().getRequest.mockReturnValue({\n user: userTest,\n params: { '*': 'files/personal/root/foo/bar' }\n })\n for (const userRole of [USER_ROLE.USER, USER_ROLE.GUEST]) {\n userTest.role = userRole\n if (userRole === USER_ROLE.USER) {\n expect(await spacesGuard.canActivate(context)).toBe(true)\n } else {\n await expect(spacesGuard.canActivate(context)).rejects.toThrow(HttpException)\n }\n }\n })\n\n it('should check user permissions on route', async () => {\n userTest.role = USER_ROLE.USER\n spacesManager.spaceEnv = jest.fn().mockReturnValue({\n enabled: true,\n envPermissions: `${SPACE_OPERATION.MODIFY}`\n } as Partial<SpaceEnv>)\n // does not allow creation (only modify)\n context.switchToHttp().getRequest.mockReturnValueOnce({\n method: 'POST',\n user: userTest,\n params: { '*': 'files/personal' }\n })\n await expect(spacesGuard.canActivate(context)).rejects.toThrow(HttpException)\n\n // allows modification\n context.switchToHttp().getRequest.mockReturnValue({\n method: 'PATCH',\n user: userTest,\n params: { '*': 'files/personal' }\n })\n expect(await spacesGuard.canActivate(context)).toBe(true)\n\n // does not allow guest (on personal space)\n userTest.role = USER_ROLE.GUEST\n await expect(spacesGuard.canActivate(context)).rejects.toThrow(HttpException)\n\n // allow if SkipSpacePermissionsCheck is enabled\n userTest.role = USER_ROLE.USER\n SkipSpacePermissionsCheck()(context.getHandler())\n spacesManager.spaceEnv = jest.fn().mockReturnValue({\n enabled: true,\n envPermissions: `${SPACE_OPERATION.MODIFY}`\n } as Partial<SpaceEnv>)\n // does not allow creation but pass\n context.switchToHttp().getRequest.mockReturnValueOnce({\n method: 'POST',\n user: userTest,\n params: { '*': 'files/personal' }\n })\n expect(await spacesGuard.canActivate(context)).toBe(true)\n // reset context\n context = createMock<ExecutionContext>()\n })\n\n it('should fail with quota exceeded', async () => {\n userTest.role = USER_ROLE.USER\n spacesManager.spaceEnv = jest.fn().mockReturnValueOnce({\n enabled: true,\n envPermissions: `${SPACE_OPERATION.ADD}`,\n quotaIsExceeded: true\n } as Partial<SpaceEnv>)\n context.switchToHttp().getRequest.mockReturnValueOnce({\n method: 'POST',\n user: userTest,\n params: { '*': 'files/personal' }\n })\n await expect(spacesGuard.canActivate(context)).rejects.toEqual(expect.objectContaining({ status: HttpStatus.INSUFFICIENT_STORAGE }))\n })\n\n it('should fail if request content-length header exceed the quota', async () => {\n userTest.role = USER_ROLE.USER\n const storageQuota = 12\n const storageUsage = 11\n spacesManager.spaceEnv = jest.fn().mockReturnValue({\n enabled: true,\n envPermissions: `${SPACE_OPERATION.ADD}`,\n storageQuota: storageQuota,\n storageUsage: storageUsage,\n willExceedQuota: (contentLength: number) => contentLength > storageQuota - storageUsage\n } as Partial<SpaceEnv>)\n context.switchToHttp().getRequest.mockReturnValueOnce({\n method: 'POST',\n headers: { 'content-length': 13 },\n user: userTest,\n params: { '*': 'files/personal' }\n })\n await expect(spacesGuard.canActivate(context)).rejects.toEqual(expect.objectContaining({ status: HttpStatus.INSUFFICIENT_STORAGE }))\n context.switchToHttp().getRequest.mockReturnValueOnce({\n method: 'POST',\n user: userTest,\n headers: {},\n params: { '*': 'files/personal' }\n })\n expect(await spacesGuard.canActivate(context)).toBe(true)\n })\n\n it('should fail with space disabled', async () => {\n userTest.role = USER_ROLE.USER\n spacesManager.spaceEnv = jest.fn().mockReturnValueOnce({\n enabled: false\n } as Partial<SpaceEnv>)\n context.switchToHttp().getRequest.mockReturnValueOnce({\n method: 'POST',\n user: userTest,\n params: { '*': 'files/personal' }\n })\n await expect(spacesGuard.canActivate(context)).rejects.toMatchObject({ status: HttpStatus.FORBIDDEN })\n })\n\n it('should validate (or not) the webdav routes', async () => {\n userTest.role = USER_ROLE.USER\n spacesManager.spaceEnv = jest.fn().mockReturnValue({ enabled: true })\n const spyUrlSegment = jest.spyOn(spacesGuard as any, 'urlSegmentsFromContext')\n WebDAVContext()(context.getHandler())\n context.switchToHttp().getRequest.mockReturnValueOnce({\n user: userTest,\n params: { '*': 'webdav/personal' }\n })\n expect(await spacesGuard.canActivate(context)).toBe(true)\n expect(spyUrlSegment.mock.results[0].value).toEqual(['files', 'personal'])\n context.switchToHttp().getRequest.mockReturnValueOnce({\n user: userTest,\n params: { '*': 'webdav/files' }\n })\n await expect(spacesGuard.canActivate(context)).rejects.toThrow(HttpException)\n // reset context\n spyUrlSegment.mockRestore()\n context = createMock<ExecutionContext>()\n })\n\n it('should validate (or not) the sync routes', async () => {\n userTest.role = USER_ROLE.USER\n spacesManager.spaceEnv = jest.fn().mockReturnValue({ enabled: true })\n const spyUrlSegment = jest.spyOn(spacesGuard as any, 'urlSegmentsFromContext')\n SyncContext()(context.getHandler())\n context.switchToHttp().getRequest.mockReturnValueOnce({\n user: userTest,\n params: { '*': 'personal/foo' }\n })\n expect(await spacesGuard.canActivate(context)).toBe(true)\n expect(spyUrlSegment.mock.results[0].value).toEqual(['files', 'personal', 'foo'])\n context.switchToHttp().getRequest.mockReturnValueOnce({\n user: userTest,\n params: { '*': 'sync/files' }\n })\n await expect(spacesGuard.canActivate(context)).rejects.toThrow(HttpException)\n // reset context\n spyUrlSegment.mockRestore()\n context = createMock<ExecutionContext>()\n })\n\n it('should require the modify permission when using the POST method on the OnlyOffice callback URL', async () => {\n userTest.role = USER_ROLE.USER\n spacesManager.spaceEnv = jest.fn().mockReturnValue({ enabled: true, envPermissions: `${SPACE_OPERATION.MODIFY}` })\n OnlyOfficeContext()(context.getHandler())\n context.switchToHttp().getRequest.mockReturnValue({\n method: 'POST',\n user: userTest,\n originalUrl: API_FILES_ONLY_OFFICE_CALLBACK,\n params: { '*': 'files/personal/root' }\n })\n expect(await spacesGuard.canActivate(context)).toBe(true)\n spacesManager.spaceEnv = jest.fn().mockReturnValue({ enabled: true, envPermissions: `${SPACE_OPERATION.ADD}` })\n await expect(spacesGuard.canActivate(context)).rejects.toThrow(HttpException)\n context.switchToHttp().getRequest.mockReturnValue({\n method: 'POST',\n user: userTest,\n originalUrl: '',\n params: { '*': 'files/personal/root' }\n })\n expect(await spacesGuard.canActivate(context)).toBe(true)\n // reset context\n context = createMock<ExecutionContext>()\n })\n\n it('should pass if skipSpaceGuard context is enabled', async () => {\n userTest.role = USER_ROLE.USER\n userTest.applications = [USER_PERMISSION.PERSONAL_SPACE]\n spacesManager.spaceEnv = jest.fn().mockReturnValue({ enabled: true })\n context.switchToHttp().getRequest.mockReturnValue({\n user: userTest,\n params: { '*': 'shares/personal' }\n })\n await expect(spacesGuard.canActivate(context)).rejects.toMatchObject({ status: HttpStatus.FORBIDDEN })\n SkipSpaceGuard()(context.getHandler())\n expect(await spacesGuard.canActivate(context)).toBe(true)\n // reset context\n context = createMock<ExecutionContext>()\n })\n\n it('coverage only', async () => {\n userTest.role = USER_ROLE.USER\n userTest.applications = [USER_PERMISSION.PERSONAL_SPACE]\n spacesManager.spaceEnv = jest.fn().mockRejectedValueOnce(new Error('error'))\n context.switchToHttp().getRequest.mockReturnValue({\n user: userTest,\n params: { '*': 'files/personal' }\n })\n await expect(spacesGuard.canActivate(context)).rejects.toMatchObject({ status: HttpStatus.BAD_REQUEST })\n })\n})\n"],"names":["describe","SpaceGuard","name","spacesGuard","spacesManager","spacesQueries","userTest","context","beforeAll","module","Test","createTestingModule","providers","provide","DB_TOKEN_PROVIDER","useValue","Cache","ContextManager","NotificationsManager","SpacesManager","SpacesQueries","SharesManager","SharesQueries","FilesQueries","UsersQueries","LinksQueries","compile","get","jest","fn","UserModel","generateUserTest","createMock","it","expect","toBeDefined","switchToHttp","getRequest","mockReturnValue","user","params","canActivate","toBe","req","space","id","repository","SPACE_REPOSITORY","FILES","alias","SPACE_ALIAS","PERSONAL","enabled","root","toBeUndefined","dbFile","toMatchObject","inTrash","ownerId","path","permissions","SPACE_ALL_OPERATIONS","envPermissions","inFilesRepository","inPersonalSpace","inTrashRepository","inSharesRepository","inSharesList","paths","toEqual","arrayContaining","fakeSpace","role","mockReturnValueOnce","spaceId","spaceExternalRootId","SHARE_ALL_OPERATIONS","not","toContain","toHaveLength","owner","login","file","externalPath","intersectPermissions","split","SPACE_PERMS_SEP","filter","p","SPACE_OPERATION","DELETE","join","SHARES","rejects","toThrow","HttpException","applications","USER_PERMISSION","PERSONAL_SPACE","url","spaceEnv","userRole","USER_ROLE","USER","GUEST","MODIFY","method","SkipSpacePermissionsCheck","getHandler","ADD","quotaIsExceeded","objectContaining","status","HttpStatus","INSUFFICIENT_STORAGE","storageQuota","storageUsage","willExceedQuota","contentLength","headers","FORBIDDEN","spyUrlSegment","spyOn","WebDAVContext","mock","results","value","mockRestore","SyncContext","OnlyOfficeContext","originalUrl","API_FILES_ONLY_OFFICE_CALLBACK","SkipSpaceGuard","mockRejectedValueOnce","Error","BAD_REQUEST"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../../backend/src/applications/spaces/guards/space.guard.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 { createMock, DeepMocked } from '@golevelup/ts-jest'\nimport { ExecutionContext, HttpException, HttpStatus } from '@nestjs/common'\nimport { Test, TestingModule } from '@nestjs/testing'\nimport { intersectPermissions } from '../../../common/shared'\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 { FilesQueries } from '../../files/services/files-queries.service'\nimport { LinksQueries } from '../../links/services/links-queries.service'\nimport { NotificationsManager } from '../../notifications/services/notifications-manager.service'\nimport { SHARE_ALL_OPERATIONS } from '../../shares/constants/shares'\nimport { SharesManager } from '../../shares/services/shares-manager.service'\nimport { SharesQueries } from '../../shares/services/shares-queries.service'\nimport { SyncContext } from '../../sync/decorators/sync-context.decorator'\nimport { USER_PERMISSION, USER_ROLE } from '../../users/constants/user'\nimport { UserModel } from '../../users/models/user.model'\nimport { UsersQueries } from '../../users/services/users-queries.service'\nimport { generateUserTest } from '../../users/utils/test'\nimport { WebDAVContext } from '../../webdav/decorators/webdav-context.decorator'\nimport { SPACE_ALIAS, SPACE_ALL_OPERATIONS, SPACE_OPERATION, SPACE_PERMS_SEP, SPACE_REPOSITORY } from '../constants/spaces'\nimport { OverrideSpacePermission } from '../decorators/space-override-permission.decorator'\nimport { SkipSpaceGuard } from '../decorators/space-skip-guard.decorator'\nimport { SkipSpacePermissionsCheck } from '../decorators/space-skip-permissions.decorator'\nimport { SpaceEnv } from '../models/space-env.model'\nimport { SpacesManager } from '../services/spaces-manager.service'\nimport { SpacesQueries } from '../services/spaces-queries.service'\nimport { SpaceGuard } from './space.guard'\n\ndescribe(SpaceGuard.name, () => {\n let spacesGuard: SpaceGuard\n let spacesManager: SpacesManager\n let spacesQueries: SpacesQueries\n let userTest: UserModel\n let context: DeepMocked<ExecutionContext>\n\n beforeAll(async () => {\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 SpaceGuard,\n SpacesManager,\n SpacesQueries,\n SharesManager,\n SharesQueries,\n FilesQueries,\n UsersQueries,\n LinksQueries\n ]\n }).compile()\n\n spacesManager = module.get<SpacesManager>(SpacesManager)\n spacesQueries = module.get<SpacesQueries>(SpacesQueries)\n spacesGuard = module.get<SpaceGuard>(SpaceGuard)\n // mocks\n spacesManager['setQuotaExceeded'] = jest.fn()\n userTest = new UserModel(generateUserTest())\n })\n\n beforeEach(() => {\n context = createMock<ExecutionContext>()\n })\n\n it('should be defined', () => {\n expect(spacesGuard).toBeDefined()\n expect(spacesManager).toBeDefined()\n expect(userTest).toBeDefined()\n })\n\n it('should pass for a personal space', async () => {\n context.switchToHttp().getRequest.mockReturnValue({\n user: userTest,\n params: { '*': 'files/personal/root/foo/bar' }\n })\n expect(await spacesGuard.canActivate(context)).toBe(true)\n const req: any = context.switchToHttp().getRequest()\n expect(req.space.id).toBe(0)\n expect(req.space.repository).toBe(SPACE_REPOSITORY.FILES)\n expect(req.space.alias).toBe(SPACE_ALIAS.PERSONAL)\n expect(req.space.name).toBe(SPACE_ALIAS.PERSONAL)\n expect(req.space.enabled).toBe(true)\n expect(req.space.root).toBeUndefined()\n expect(req.space.dbFile).toMatchObject({ inTrash: false, ownerId: userTest.id, path: 'root/foo/bar' })\n expect(req.space.permissions).toBe(SPACE_ALL_OPERATIONS)\n expect(req.space.envPermissions).toBe(SPACE_ALL_OPERATIONS)\n expect(req.space.inFilesRepository).toBe(true)\n expect(req.space.inPersonalSpace).toBe(true)\n expect(req.space.inTrashRepository).toBe(false)\n expect(req.space.inSharesRepository).toBe(false)\n expect(req.space.inSharesList).toBe(false)\n expect(req.space.paths).toEqual(expect.arrayContaining(['root', 'foo', 'bar']))\n })\n\n it('should pass for a common space', async () => {\n const fakeSpace = {\n id: -1,\n alias: 'test',\n name: 'Test',\n enabled: true,\n permissions: ':a:d:m:so',\n role: 0\n }\n spacesQueries.permissions = jest.fn().mockReturnValueOnce(fakeSpace)\n context.switchToHttp().getRequest.mockReturnValue({\n user: userTest,\n params: { '*': 'files/test' }\n })\n expect(await spacesGuard.canActivate(context)).toBe(true)\n const req: any = context.switchToHttp().getRequest()\n expect(req.space.id).toBe(fakeSpace.id)\n expect(req.space.repository).toBe(SPACE_REPOSITORY.FILES)\n expect(req.space.alias).toBe(fakeSpace.alias)\n expect(req.space.name).toBe(fakeSpace.name)\n expect(req.space.enabled).toBe(true)\n expect(req.space.root).toMatchObject({ id: 0, alias: '', name: '', permissions: 'a:d:m:so' })\n expect(req.space.dbFile).toMatchObject({ inTrash: false, spaceId: fakeSpace.id, spaceExternalRootId: null, path: '.' })\n expect(req.space.permissions).toBe(SHARE_ALL_OPERATIONS)\n expect(req.space.envPermissions).not.toContain('d')\n expect(req.space.inFilesRepository).toBe(true)\n expect(req.space.inPersonalSpace).toBe(false)\n expect(req.space.inTrashRepository).toBe(false)\n expect(req.space.inSharesRepository).toBe(false)\n expect(req.space.inSharesList).toBe(false)\n expect(req.space.paths).toHaveLength(0)\n })\n\n it('should pass for a common space root', async () => {\n const fakeSpace = {\n id: -1,\n alias: 'test',\n name: 'Test',\n enabled: true,\n permissions: 'a:d:m:so',\n role: 1,\n root: {\n id: -2,\n alias: 'root',\n name: 'Root',\n permissions: 'a:d:so',\n owner: { id: -3, login: 'johaven' },\n file: { id: -4, path: 'code', inTrash: false },\n externalPath: null\n }\n }\n spacesQueries.permissions = jest.fn().mockReturnValueOnce(fakeSpace)\n context.switchToHttp().getRequest.mockReturnValue({\n user: userTest,\n params: { '*': 'files/test/root' }\n })\n expect(await spacesGuard.canActivate(context)).toBe(true)\n const req: any = context.switchToHttp().getRequest()\n expect(req.space.id).toBe(fakeSpace.id)\n expect(req.space.repository).toBe(SPACE_REPOSITORY.FILES)\n expect(req.space.alias).toBe(fakeSpace.alias)\n expect(req.space.name).toBe(fakeSpace.name)\n expect(req.space.enabled).toBe(true)\n expect(req.space.root).toMatchObject(fakeSpace.root)\n expect(req.space.dbFile).toMatchObject({ inTrash: false, ownerId: fakeSpace.root.owner.id, path: fakeSpace.root.file.path })\n expect(req.space.permissions).toBe(SPACE_ALL_OPERATIONS)\n expect(req.space.envPermissions).toBe(\n intersectPermissions(fakeSpace.permissions, fakeSpace.root.permissions)\n .split(SPACE_PERMS_SEP)\n .filter((p) => p !== SPACE_OPERATION.DELETE)\n .join(SPACE_PERMS_SEP)\n )\n expect(req.space.inFilesRepository).toBe(true)\n expect(req.space.inPersonalSpace).toBe(false)\n expect(req.space.inTrashRepository).toBe(false)\n expect(req.space.inSharesRepository).toBe(false)\n expect(req.space.inSharesList).toBe(false)\n expect(req.space.paths).toHaveLength(0)\n })\n\n it('should pass for a common space root with a path', async () => {\n const fakeSpace = {\n id: -1,\n alias: 'test',\n name: 'Test',\n enabled: true,\n permissions: 'a:d:m:so',\n role: 1,\n root: {\n id: -2,\n alias: 'root',\n name: 'Root',\n permissions: 'a:d:so',\n owner: { id: -3, login: 'johaven' },\n file: { id: -4, path: 'code', inTrash: false },\n externalPath: null\n }\n }\n spacesQueries.permissions = jest.fn().mockReturnValueOnce(fakeSpace)\n context.switchToHttp().getRequest.mockReturnValue({\n user: userTest,\n params: { '*': 'files/test/root/path' }\n })\n expect(await spacesGuard.canActivate(context)).toBe(true)\n const req: any = context.switchToHttp().getRequest()\n expect(req.space.id).toBe(fakeSpace.id)\n expect(req.space.repository).toBe(SPACE_REPOSITORY.FILES)\n expect(req.space.alias).toBe(fakeSpace.alias)\n expect(req.space.name).toBe(fakeSpace.name)\n expect(req.space.enabled).toBe(true)\n expect(req.space.root).toMatchObject(fakeSpace.root)\n expect(req.space.dbFile).toMatchObject({\n inTrash: false,\n ownerId: fakeSpace.root.owner.id,\n path: `${fakeSpace.root.file.path}/${req.space.paths[0]}`\n })\n expect(req.space.permissions).toBe(SPACE_ALL_OPERATIONS)\n expect(req.space.envPermissions).toBe(fakeSpace.root.permissions)\n expect(req.space.inFilesRepository).toBe(true)\n expect(req.space.inPersonalSpace).toBe(false)\n expect(req.space.inTrashRepository).toBe(false)\n expect(req.space.inSharesRepository).toBe(false)\n expect(req.space.inSharesList).toBe(false)\n expect(req.space.paths).toHaveLength(1)\n })\n\n it('should pass for a space in shares repository', async () => {\n context.switchToHttp().getRequest.mockReturnValue({\n user: userTest,\n params: { '*': 'shares' }\n })\n expect(await spacesGuard.canActivate(context)).toBe(true)\n const req: any = context.switchToHttp().getRequest()\n expect(req.space.id).toBe(0)\n expect(req.space.repository).toBe(SPACE_REPOSITORY.SHARES)\n expect(req.space.alias).toBe(SPACE_REPOSITORY.SHARES)\n expect(req.space.name).toBe(SPACE_REPOSITORY.SHARES)\n expect(req.space.enabled).toBe(true)\n expect(req.space.root).toBeUndefined()\n expect(req.space.dbFile).toBeUndefined()\n expect(req.space.permissions).toBe('')\n expect(req.space.envPermissions).toBe('')\n expect(req.space.inFilesRepository).toBe(false)\n expect(req.space.inPersonalSpace).toBe(false)\n expect(req.space.inTrashRepository).toBe(false)\n expect(req.space.inSharesRepository).toBe(true)\n expect(req.space.inSharesList).toBe(true)\n expect(req.space.paths).toHaveLength(0)\n })\n\n it('should not pass if the space is not found or not valid', async () => {\n const fakeSpace = null\n spacesQueries.permissions = jest.fn().mockReturnValueOnce(fakeSpace)\n context.switchToHttp().getRequest.mockReturnValue({\n user: userTest,\n params: { '*': 'files/foo' }\n })\n await expect(spacesGuard.canActivate(context)).rejects.toThrow(HttpException)\n })\n\n it('should validate (or not) the access to the space depending on the user permissions', async () => {\n // we only check the `spacesManager.checkAccessToSpace` function, ignores the `spacesManager.spaceEnv`\n userTest.applications = [USER_PERMISSION.PERSONAL_SPACE]\n for (const url of ['', 'shares/personal', 'shares/toto']) {\n context.switchToHttp().getRequest.mockReturnValue({\n user: userTest,\n params: { '*': url }\n })\n await expect(spacesGuard.canActivate(context)).rejects.toThrow(HttpException)\n }\n // should pass because it is a standard user\n // should not pass because user is a guest (and dot not have the permission to access to a personal space)\n spacesManager.spaceEnv = jest.fn().mockReturnValueOnce({ enabled: true }) // only for user role\n context.switchToHttp().getRequest.mockReturnValue({\n user: userTest,\n params: { '*': 'files/personal/root/foo/bar' }\n })\n for (const userRole of [USER_ROLE.USER, USER_ROLE.GUEST]) {\n userTest.role = userRole\n if (userRole === USER_ROLE.USER) {\n expect(await spacesGuard.canActivate(context)).toBe(true)\n } else {\n await expect(spacesGuard.canActivate(context)).rejects.toThrow(HttpException)\n }\n }\n })\n\n it('should check user permissions on route', async () => {\n userTest.role = USER_ROLE.USER\n spacesManager.spaceEnv = jest.fn().mockReturnValue({\n enabled: true,\n envPermissions: `${SPACE_OPERATION.MODIFY}`\n } as Partial<SpaceEnv>)\n // does not allow creation (only modify)\n context.switchToHttp().getRequest.mockReturnValueOnce({\n method: 'POST',\n user: userTest,\n params: { '*': 'files/personal' }\n })\n await expect(spacesGuard.canActivate(context)).rejects.toThrow(HttpException)\n\n // allows modification\n context.switchToHttp().getRequest.mockReturnValue({\n method: 'PATCH',\n user: userTest,\n params: { '*': 'files/personal' }\n })\n expect(await spacesGuard.canActivate(context)).toBe(true)\n\n // does not allow guest (on personal space)\n userTest.role = USER_ROLE.GUEST\n await expect(spacesGuard.canActivate(context)).rejects.toThrow(HttpException)\n\n // allow if SkipSpacePermissionsCheck is enabled\n userTest.role = USER_ROLE.USER\n SkipSpacePermissionsCheck()(context.getHandler())\n spacesManager.spaceEnv = jest.fn().mockReturnValue({\n enabled: true,\n envPermissions: `${SPACE_OPERATION.MODIFY}`\n } as Partial<SpaceEnv>)\n // does not allow creation but pass\n context.switchToHttp().getRequest.mockReturnValueOnce({\n method: 'POST',\n user: userTest,\n params: { '*': 'files/personal' }\n })\n expect(await spacesGuard.canActivate(context)).toBe(true)\n })\n\n it('should fail with quota exceeded', async () => {\n userTest.role = USER_ROLE.USER\n spacesManager.spaceEnv = jest.fn().mockReturnValueOnce({\n enabled: true,\n envPermissions: `${SPACE_OPERATION.ADD}`,\n quotaIsExceeded: true\n } as Partial<SpaceEnv>)\n context.switchToHttp().getRequest.mockReturnValueOnce({\n method: 'POST',\n user: userTest,\n params: { '*': 'files/personal' }\n })\n await expect(spacesGuard.canActivate(context)).rejects.toEqual(expect.objectContaining({ status: HttpStatus.INSUFFICIENT_STORAGE }))\n })\n\n it('should fail if request content-length header exceed the quota', async () => {\n userTest.role = USER_ROLE.USER\n const storageQuota = 12\n const storageUsage = 11\n spacesManager.spaceEnv = jest.fn().mockReturnValue({\n enabled: true,\n envPermissions: `${SPACE_OPERATION.ADD}`,\n storageQuota: storageQuota,\n storageUsage: storageUsage,\n willExceedQuota: (contentLength: number) => contentLength > storageQuota - storageUsage\n } as Partial<SpaceEnv>)\n context.switchToHttp().getRequest.mockReturnValueOnce({\n method: 'POST',\n headers: { 'content-length': 13 },\n user: userTest,\n params: { '*': 'files/personal' }\n })\n await expect(spacesGuard.canActivate(context)).rejects.toEqual(expect.objectContaining({ status: HttpStatus.INSUFFICIENT_STORAGE }))\n context.switchToHttp().getRequest.mockReturnValueOnce({\n method: 'POST',\n user: userTest,\n headers: {},\n params: { '*': 'files/personal' }\n })\n expect(await spacesGuard.canActivate(context)).toBe(true)\n })\n\n it('should fail with space disabled', async () => {\n userTest.role = USER_ROLE.USER\n spacesManager.spaceEnv = jest.fn().mockReturnValueOnce({\n enabled: false\n } as Partial<SpaceEnv>)\n context.switchToHttp().getRequest.mockReturnValueOnce({\n method: 'POST',\n user: userTest,\n params: { '*': 'files/personal' }\n })\n await expect(spacesGuard.canActivate(context)).rejects.toMatchObject({ status: HttpStatus.FORBIDDEN })\n })\n\n it('should validate (or not) the webdav routes', async () => {\n userTest.role = USER_ROLE.USER\n spacesManager.spaceEnv = jest.fn().mockReturnValue({ enabled: true })\n const spyUrlSegment = jest.spyOn(spacesGuard as any, 'urlSegmentsFromContext')\n WebDAVContext()(context.getHandler())\n context.switchToHttp().getRequest.mockReturnValueOnce({\n user: userTest,\n params: { '*': 'webdav/personal' }\n })\n expect(await spacesGuard.canActivate(context)).toBe(true)\n expect(spyUrlSegment.mock.results[0].value).toEqual(['files', 'personal'])\n context.switchToHttp().getRequest.mockReturnValueOnce({\n user: userTest,\n params: { '*': 'webdav/files' }\n })\n await expect(spacesGuard.canActivate(context)).rejects.toThrow(HttpException)\n // reset mock\n spyUrlSegment.mockRestore()\n })\n\n it('should validate (or not) the sync routes', async () => {\n userTest.role = USER_ROLE.USER\n spacesManager.spaceEnv = jest.fn().mockReturnValue({ enabled: true })\n const spyUrlSegment = jest.spyOn(spacesGuard as any, 'urlSegmentsFromContext')\n SyncContext()(context.getHandler())\n context.switchToHttp().getRequest.mockReturnValueOnce({\n user: userTest,\n params: { '*': 'personal/foo' }\n })\n expect(await spacesGuard.canActivate(context)).toBe(true)\n expect(spyUrlSegment.mock.results[0].value).toEqual(['files', 'personal', 'foo'])\n context.switchToHttp().getRequest.mockReturnValueOnce({\n user: userTest,\n params: { '*': 'sync/files' }\n })\n await expect(spacesGuard.canActivate(context)).rejects.toThrow(HttpException)\n // reset context\n spyUrlSegment.mockRestore()\n })\n\n it('should allow the modify permission when using the POST method with override space permission decorator', async () => {\n userTest.role = USER_ROLE.USER\n spacesManager.spaceEnv = jest.fn().mockReturnValue({ enabled: true, envPermissions: `${SPACE_OPERATION.MODIFY}` })\n OverrideSpacePermission(SPACE_OPERATION.MODIFY)(context.getHandler())\n context.switchToHttp().getRequest.mockReturnValue({\n method: 'POST',\n user: userTest,\n originalUrl: '1',\n params: { '*': 'files/personal/root' }\n })\n expect(await spacesGuard.canActivate(context)).toBe(true)\n // reset context\n context = createMock<ExecutionContext>()\n spacesManager.spaceEnv = jest.fn().mockReturnValue({ enabled: true, envPermissions: `${SPACE_OPERATION.ADD}` })\n await expect(spacesGuard.canActivate(context)).rejects.toThrow(HttpException)\n context.switchToHttp().getRequest.mockReturnValue({\n method: 'POST',\n user: userTest,\n originalUrl: '2',\n params: { '*': 'files/personal/root' }\n })\n expect(await spacesGuard.canActivate(context)).toBe(true)\n })\n\n it('should pass if skipSpaceGuard context is enabled', async () => {\n userTest.role = USER_ROLE.USER\n userTest.applications = [USER_PERMISSION.PERSONAL_SPACE]\n spacesManager.spaceEnv = jest.fn().mockReturnValue({ enabled: true })\n context.switchToHttp().getRequest.mockReturnValue({\n user: userTest,\n params: { '*': 'shares/personal' }\n })\n await expect(spacesGuard.canActivate(context)).rejects.toMatchObject({ status: HttpStatus.FORBIDDEN })\n SkipSpaceGuard()(context.getHandler())\n expect(await spacesGuard.canActivate(context)).toBe(true)\n })\n\n it('coverage only', async () => {\n userTest.role = USER_ROLE.USER\n userTest.applications = [USER_PERMISSION.PERSONAL_SPACE]\n spacesManager.spaceEnv = jest.fn().mockRejectedValueOnce(new Error('error'))\n context.switchToHttp().getRequest.mockReturnValue({\n user: userTest,\n params: { '*': 'files/personal' }\n })\n await expect(spacesGuard.canActivate(context)).rejects.toMatchObject({ status: HttpStatus.BAD_REQUEST })\n })\n})\n"],"names":["describe","SpaceGuard","name","spacesGuard","spacesManager","spacesQueries","userTest","context","beforeAll","module","Test","createTestingModule","providers","provide","DB_TOKEN_PROVIDER","useValue","Cache","ContextManager","NotificationsManager","SpacesManager","SpacesQueries","SharesManager","SharesQueries","FilesQueries","UsersQueries","LinksQueries","compile","get","jest","fn","UserModel","generateUserTest","beforeEach","createMock","it","expect","toBeDefined","switchToHttp","getRequest","mockReturnValue","user","params","canActivate","toBe","req","space","id","repository","SPACE_REPOSITORY","FILES","alias","SPACE_ALIAS","PERSONAL","enabled","root","toBeUndefined","dbFile","toMatchObject","inTrash","ownerId","path","permissions","SPACE_ALL_OPERATIONS","envPermissions","inFilesRepository","inPersonalSpace","inTrashRepository","inSharesRepository","inSharesList","paths","toEqual","arrayContaining","fakeSpace","role","mockReturnValueOnce","spaceId","spaceExternalRootId","SHARE_ALL_OPERATIONS","not","toContain","toHaveLength","owner","login","file","externalPath","intersectPermissions","split","SPACE_PERMS_SEP","filter","p","SPACE_OPERATION","DELETE","join","SHARES","rejects","toThrow","HttpException","applications","USER_PERMISSION","PERSONAL_SPACE","url","spaceEnv","userRole","USER_ROLE","USER","GUEST","MODIFY","method","SkipSpacePermissionsCheck","getHandler","ADD","quotaIsExceeded","objectContaining","status","HttpStatus","INSUFFICIENT_STORAGE","storageQuota","storageUsage","willExceedQuota","contentLength","headers","FORBIDDEN","spyUrlSegment","spyOn","WebDAVContext","mock","results","value","mockRestore","SyncContext","OverrideSpacePermission","originalUrl","SkipSpaceGuard","mockRejectedValueOnce","Error","BAD_REQUEST"],"mappings":"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"}
@@ -26,6 +26,9 @@ function _ts_metadata(k, v) {
26
26
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
27
27
  }
28
28
  let SpacesScheduler = class SpacesScheduler {
29
+ async onStartup() {
30
+ await this.updateQuotas();
31
+ }
29
32
  async updateQuotas() {
30
33
  this.logger.log('Update Personal Quotas - START');
31
34
  try {
@@ -65,7 +68,12 @@ let SpacesScheduler = class SpacesScheduler {
65
68
  }
66
69
  };
67
70
  _ts_decorate([
68
- (0, _schedule.Timeout)(60000),
71
+ (0, _schedule.Timeout)(60_000),
72
+ _ts_metadata("design:type", Function),
73
+ _ts_metadata("design:paramtypes", []),
74
+ _ts_metadata("design:returntype", Promise)
75
+ ], SpacesScheduler.prototype, "onStartup", null);
76
+ _ts_decorate([
69
77
  (0, _schedule.Cron)(_schedule.CronExpression.EVERY_HOUR),
70
78
  _ts_metadata("design:type", Function),
71
79
  _ts_metadata("design:paramtypes", []),
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../backend/src/applications/spaces/services/spaces-scheduler.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 { Injectable, Logger } from '@nestjs/common'\nimport { Cron, CronExpression, Timeout } from '@nestjs/schedule'\nimport { SharesManager } from '../../shares/services/shares-manager.service'\nimport { SpacesManager } from './spaces-manager.service'\n\n@Injectable()\nexport class SpacesScheduler {\n private readonly logger = new Logger(SpacesScheduler.name)\n\n constructor(\n private readonly spacesManager: SpacesManager,\n private readonly sharesManager: SharesManager\n ) {}\n\n @Timeout(60000)\n @Cron(CronExpression.EVERY_HOUR)\n async updateQuotas() {\n this.logger.log('Update Personal Quotas - START')\n try {\n await this.spacesManager.updatePersonalSpacesQuota()\n } catch (e) {\n this.logger.error(`Update Personal Quotas} - ${e}`)\n }\n this.logger.log('Update Personal Quotas - END')\n this.logger.log('Update Space Quotas - START')\n try {\n await this.spacesManager.updateSpacesQuota()\n } catch (e) {\n this.logger.error(`Update Space Quotas - ${e}`)\n }\n this.logger.log('Update Space Quotas - END')\n this.logger.log('Update Share External Path Quotas - START')\n try {\n await this.sharesManager.updateSharesExternalPathQuota()\n } catch (e) {\n this.logger.error(`Update Share External Path Quotas - ${e}`)\n }\n this.logger.log('Update Share External Path Quotas - END')\n }\n\n @Cron(CronExpression.EVERY_DAY_AT_2AM)\n async deleteExpiredSpaces() {\n /* Removes spaces that have been disabled for more than 30 days */\n this.logger.log(`${this.deleteExpiredSpaces.name} - START`)\n try {\n await this.spacesManager.deleteExpiredSpaces()\n } catch (e) {\n this.logger.error(`${this.deleteExpiredSpaces.name} - ${e}`)\n }\n this.logger.log(`${this.deleteExpiredSpaces.name} - DONE`)\n }\n}\n"],"names":["SpacesScheduler","updateQuotas","logger","log","spacesManager","updatePersonalSpacesQuota","e","error","updateSpacesQuota","sharesManager","updateSharesExternalPathQuota","deleteExpiredSpaces","name","Logger","EVERY_HOUR","EVERY_DAY_AT_2AM"],"mappings":"AAAA;;;;CAIC;;;;+BAQYA;;;eAAAA;;;wBANsB;0BACW;sCAChB;sCACA;;;;;;;;;;AAGvB,IAAA,AAAMA,kBAAN,MAAMA;IAQX,MAEMC,eAAe;QACnB,IAAI,CAACC,MAAM,CAACC,GAAG,CAAC;QAChB,IAAI;YACF,MAAM,IAAI,CAACC,aAAa,CAACC,yBAAyB;QACpD,EAAE,OAAOC,GAAG;YACV,IAAI,CAACJ,MAAM,CAACK,KAAK,CAAC,CAAC,0BAA0B,EAAED,GAAG;QACpD;QACA,IAAI,CAACJ,MAAM,CAACC,GAAG,CAAC;QAChB,IAAI,CAACD,MAAM,CAACC,GAAG,CAAC;QAChB,IAAI;YACF,MAAM,IAAI,CAACC,aAAa,CAACI,iBAAiB;QAC5C,EAAE,OAAOF,GAAG;YACV,IAAI,CAACJ,MAAM,CAACK,KAAK,CAAC,CAAC,sBAAsB,EAAED,GAAG;QAChD;QACA,IAAI,CAACJ,MAAM,CAACC,GAAG,CAAC;QAChB,IAAI,CAACD,MAAM,CAACC,GAAG,CAAC;QAChB,IAAI;YACF,MAAM,IAAI,CAACM,aAAa,CAACC,6BAA6B;QACxD,EAAE,OAAOJ,GAAG;YACV,IAAI,CAACJ,MAAM,CAACK,KAAK,CAAC,CAAC,oCAAoC,EAAED,GAAG;QAC9D;QACA,IAAI,CAACJ,MAAM,CAACC,GAAG,CAAC;IAClB;IAEA,MACMQ,sBAAsB;QAC1B,gEAAgE,GAChE,IAAI,CAACT,MAAM,CAACC,GAAG,CAAC,GAAG,IAAI,CAACQ,mBAAmB,CAACC,IAAI,CAAC,QAAQ,CAAC;QAC1D,IAAI;YACF,MAAM,IAAI,CAACR,aAAa,CAACO,mBAAmB;QAC9C,EAAE,OAAOL,GAAG;YACV,IAAI,CAACJ,MAAM,CAACK,KAAK,CAAC,GAAG,IAAI,CAACI,mBAAmB,CAACC,IAAI,CAAC,GAAG,EAAEN,GAAG;QAC7D;QACA,IAAI,CAACJ,MAAM,CAACC,GAAG,CAAC,GAAG,IAAI,CAACQ,mBAAmB,CAACC,IAAI,CAAC,OAAO,CAAC;IAC3D;IAzCA,YACE,AAAiBR,aAA4B,EAC7C,AAAiBK,aAA4B,CAC7C;aAFiBL,gBAAAA;aACAK,gBAAAA;aAJFP,SAAS,IAAIW,cAAM,CAACb,gBAAgBY,IAAI;IAKtD;AAuCL;;;iDApCuBE;;;;;;iDAyBAC"}
1
+ {"version":3,"sources":["../../../../../backend/src/applications/spaces/services/spaces-scheduler.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 { Injectable, Logger } from '@nestjs/common'\nimport { Cron, CronExpression, Timeout } from '@nestjs/schedule'\nimport { SharesManager } from '../../shares/services/shares-manager.service'\nimport { SpacesManager } from './spaces-manager.service'\n\n@Injectable()\nexport class SpacesScheduler {\n private readonly logger = new Logger(SpacesScheduler.name)\n\n constructor(\n private readonly spacesManager: SpacesManager,\n private readonly sharesManager: SharesManager\n ) {}\n\n @Timeout(60_000)\n async onStartup() {\n await this.updateQuotas()\n }\n\n @Cron(CronExpression.EVERY_HOUR)\n async updateQuotas() {\n this.logger.log('Update Personal Quotas - START')\n try {\n await this.spacesManager.updatePersonalSpacesQuota()\n } catch (e) {\n this.logger.error(`Update Personal Quotas} - ${e}`)\n }\n this.logger.log('Update Personal Quotas - END')\n this.logger.log('Update Space Quotas - START')\n try {\n await this.spacesManager.updateSpacesQuota()\n } catch (e) {\n this.logger.error(`Update Space Quotas - ${e}`)\n }\n this.logger.log('Update Space Quotas - END')\n this.logger.log('Update Share External Path Quotas - START')\n try {\n await this.sharesManager.updateSharesExternalPathQuota()\n } catch (e) {\n this.logger.error(`Update Share External Path Quotas - ${e}`)\n }\n this.logger.log('Update Share External Path Quotas - END')\n }\n\n @Cron(CronExpression.EVERY_DAY_AT_2AM)\n async deleteExpiredSpaces() {\n /* Removes spaces that have been disabled for more than 30 days */\n this.logger.log(`${this.deleteExpiredSpaces.name} - START`)\n try {\n await this.spacesManager.deleteExpiredSpaces()\n } catch (e) {\n this.logger.error(`${this.deleteExpiredSpaces.name} - ${e}`)\n }\n this.logger.log(`${this.deleteExpiredSpaces.name} - DONE`)\n }\n}\n"],"names":["SpacesScheduler","onStartup","updateQuotas","logger","log","spacesManager","updatePersonalSpacesQuota","e","error","updateSpacesQuota","sharesManager","updateSharesExternalPathQuota","deleteExpiredSpaces","name","Logger","EVERY_HOUR","EVERY_DAY_AT_2AM"],"mappings":"AAAA;;;;CAIC;;;;+BAQYA;;;eAAAA;;;wBANsB;0BACW;sCAChB;sCACA;;;;;;;;;;AAGvB,IAAA,AAAMA,kBAAN,MAAMA;IAQX,MACMC,YAAY;QAChB,MAAM,IAAI,CAACC,YAAY;IACzB;IAEA,MACMA,eAAe;QACnB,IAAI,CAACC,MAAM,CAACC,GAAG,CAAC;QAChB,IAAI;YACF,MAAM,IAAI,CAACC,aAAa,CAACC,yBAAyB;QACpD,EAAE,OAAOC,GAAG;YACV,IAAI,CAACJ,MAAM,CAACK,KAAK,CAAC,CAAC,0BAA0B,EAAED,GAAG;QACpD;QACA,IAAI,CAACJ,MAAM,CAACC,GAAG,CAAC;QAChB,IAAI,CAACD,MAAM,CAACC,GAAG,CAAC;QAChB,IAAI;YACF,MAAM,IAAI,CAACC,aAAa,CAACI,iBAAiB;QAC5C,EAAE,OAAOF,GAAG;YACV,IAAI,CAACJ,MAAM,CAACK,KAAK,CAAC,CAAC,sBAAsB,EAAED,GAAG;QAChD;QACA,IAAI,CAACJ,MAAM,CAACC,GAAG,CAAC;QAChB,IAAI,CAACD,MAAM,CAACC,GAAG,CAAC;QAChB,IAAI;YACF,MAAM,IAAI,CAACM,aAAa,CAACC,6BAA6B;QACxD,EAAE,OAAOJ,GAAG;YACV,IAAI,CAACJ,MAAM,CAACK,KAAK,CAAC,CAAC,oCAAoC,EAAED,GAAG;QAC9D;QACA,IAAI,CAACJ,MAAM,CAACC,GAAG,CAAC;IAClB;IAEA,MACMQ,sBAAsB;QAC1B,gEAAgE,GAChE,IAAI,CAACT,MAAM,CAACC,GAAG,CAAC,GAAG,IAAI,CAACQ,mBAAmB,CAACC,IAAI,CAAC,QAAQ,CAAC;QAC1D,IAAI;YACF,MAAM,IAAI,CAACR,aAAa,CAACO,mBAAmB;QAC9C,EAAE,OAAOL,GAAG;YACV,IAAI,CAACJ,MAAM,CAACK,KAAK,CAAC,GAAG,IAAI,CAACI,mBAAmB,CAACC,IAAI,CAAC,GAAG,EAAEN,GAAG;QAC7D;QACA,IAAI,CAACJ,MAAM,CAACC,GAAG,CAAC,GAAG,IAAI,CAACQ,mBAAmB,CAACC,IAAI,CAAC,OAAO,CAAC;IAC3D;IA7CA,YACE,AAAiBR,aAA4B,EAC7C,AAAiBK,aAA4B,CAC7C;aAFiBL,gBAAAA;aACAK,gBAAAA;aAJFP,SAAS,IAAIW,cAAM,CAACd,gBAAgBa,IAAI;IAKtD;AA2CL;;;;;;;;iDApCuBE;;;;;;iDAyBAC"}
@@ -70,6 +70,9 @@ _export(exports, {
70
70
  get STANDARD_PROPS () {
71
71
  return STANDARD_PROPS;
72
72
  },
73
+ get WEBDAV_APP_LOCK () {
74
+ return WEBDAV_APP_LOCK;
75
+ },
73
76
  get XML_CONTENT_TYPE () {
74
77
  return XML_CONTENT_TYPE;
75
78
  }
@@ -83,6 +86,7 @@ const NS_PREFIX = 'D';
83
86
  const LOCK_PREFIX = 'urn:uuid:';
84
87
  const XML_CONTENT_TYPE = 'application/xml; charset=utf-8';
85
88
  const HTML_CONTENT_TYPE = 'text/html; charset=utf-8';
89
+ const WEBDAV_APP_LOCK = 'WebDAV';
86
90
  const ALLOWED_WEBDAV_METHODS = [
87
91
  _applicationsconstants.HTTP_STANDARD_METHOD.OPTIONS,
88
92
  _applicationsconstants.HTTP_STANDARD_METHOD.HEAD,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../backend/src/applications/webdav/constants/webdav.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 { SERVER_NAME } from '../../../common/shared'\nimport { HTTP_STANDARD_METHOD, HTTP_WEBDAV_METHOD } from '../../applications.constants'\nimport { WEBDAV_BASE_PATH } from './routes'\n\nexport const REGEX_BASE_PATH = new RegExp(`^/?${WEBDAV_BASE_PATH}/`)\nexport const NS_DAV = 'DAV:'\nexport const NS_PREFIX = 'D'\nexport const LOCK_PREFIX = 'urn:uuid:'\nexport const XML_CONTENT_TYPE = 'application/xml; charset=utf-8'\nexport const HTML_CONTENT_TYPE = 'text/html; charset=utf-8'\n\nexport const ALLOWED_WEBDAV_METHODS: string = [\n HTTP_STANDARD_METHOD.OPTIONS,\n HTTP_STANDARD_METHOD.HEAD,\n HTTP_STANDARD_METHOD.GET,\n HTTP_STANDARD_METHOD.PUT,\n HTTP_STANDARD_METHOD.DELETE,\n ...Object.values(HTTP_WEBDAV_METHOD)\n].join(', ')\n\nexport const ALLOW_EMPTY_BODY_METHODS: string[] = [HTTP_WEBDAV_METHOD.PROPFIND, HTTP_WEBDAV_METHOD.LOCK]\n\nexport const OPTIONS_HEADERS = {\n Server: SERVER_NAME,\n 'MS-Author-Via': 'DAV',\n DAV: '1,2',\n Allow: ALLOWED_WEBDAV_METHODS,\n 'Content-Type': HTML_CONTENT_TYPE,\n 'Content-Length': '0',\n 'Accept-Ranges': 'bytes'\n} as const\n\nexport const HEADER = {\n DEPTH: 'depth',\n IF: 'if',\n LOCK_TOKEN: 'lock-token',\n DESTINATION: 'destination',\n OVERWRITE: 'overwrite',\n TIMEOUT: 'timeout'\n} as const\n\nexport const LOCK_DISCOVERY_PROP = 'lockdiscovery'\nexport const STANDARD_PROPS = [\n 'creationdate',\n 'getcontenttype',\n 'resourcetype',\n 'getlastmodified',\n 'getcontentlength',\n 'displayname',\n 'getetag',\n 'supportedlock',\n LOCK_DISCOVERY_PROP\n]\n\nexport enum LOCK_SCOPE {\n EXCLUSIVE = 'exclusive',\n SHARED = 'shared'\n}\n\nexport enum DEPTH {\n INFINITY = 'infinity',\n RESOURCE = '0',\n MEMBERS = '1'\n}\n\nexport type LOCK_DEPTH = Omit<DEPTH, DEPTH.MEMBERS>\n\nexport enum PROPSTAT {\n ALLPROP = 'allprop',\n PROP = 'prop',\n PROPNAME = 'propname'\n}\n\nexport const PROPPATCH_PROP_UPDATE = 'propertyupdate'\nexport const PROPPATCH_METHOD = { SET: 'set', REMOVE: 'remove' }\nexport const PROPPATCH_MODIFIED_PROPS = ['getlastmodified', 'lastmodified', 'Win32LastModifiedTime']\nexport const PROPPATCH_SUPPORTED_PROPS = [...PROPPATCH_MODIFIED_PROPS, 'Win32CreationTime', 'Win32LastAccessTime', 'Win32FileAttributes']\n\nexport const PRECONDITION = {\n PROTECTED_PROPERTY: 'cannot-modify-protected-property',\n MISSING_LOCK_TOKEN: 'lock-token-submitted',\n LOCK_TOKEN_MISMATCH: 'lock-token-matches-request-uri',\n LOCK_CONFLICT: 'no-conflicting-lock',\n PROPFIND_FINITE_DEPTH: 'propfind-finite-depth'\n} as const\n"],"names":["ALLOWED_WEBDAV_METHODS","ALLOW_EMPTY_BODY_METHODS","DEPTH","HEADER","HTML_CONTENT_TYPE","LOCK_DISCOVERY_PROP","LOCK_PREFIX","LOCK_SCOPE","NS_DAV","NS_PREFIX","OPTIONS_HEADERS","PRECONDITION","PROPPATCH_METHOD","PROPPATCH_MODIFIED_PROPS","PROPPATCH_PROP_UPDATE","PROPPATCH_SUPPORTED_PROPS","PROPSTAT","REGEX_BASE_PATH","STANDARD_PROPS","XML_CONTENT_TYPE","RegExp","WEBDAV_BASE_PATH","HTTP_STANDARD_METHOD","OPTIONS","HEAD","GET","PUT","DELETE","Object","values","HTTP_WEBDAV_METHOD","join","PROPFIND","LOCK","Server","SERVER_NAME","DAV","Allow","IF","LOCK_TOKEN","DESTINATION","OVERWRITE","TIMEOUT","SET","REMOVE","PROTECTED_PROPERTY","MISSING_LOCK_TOKEN","LOCK_TOKEN_MISMATCH","LOCK_CONFLICT","PROPFIND_FINITE_DEPTH"],"mappings":"AAAA;;;;CAIC;;;;;;;;;;;QAaYA;eAAAA;;QASAC;eAAAA;;QAuCDC;eAAAA;;QA3BCC;eAAAA;;QAvBAC;eAAAA;;QAgCAC;eAAAA;;QAlCAC;eAAAA;;QA+CDC;eAAAA;;QAjDCC;eAAAA;;QACAC;eAAAA;;QAgBAC;eAAAA;;QAwDAC;eAAAA;;QAJAC;eAAAA;;QACAC;eAAAA;;QAFAC;eAAAA;;QAGAC;eAAAA;;QATDC;eAAAA;;QA/DCC;eAAAA;;QAsCAC;eAAAA;;QAlCAC;eAAAA;;;wBARe;uCAC6B;wBACxB;AAE1B,MAAMF,kBAAkB,IAAIG,OAAO,CAAC,GAAG,EAAEC,wBAAgB,CAAC,CAAC,CAAC;AAC5D,MAAMb,SAAS;AACf,MAAMC,YAAY;AAClB,MAAMH,cAAc;AACpB,MAAMa,mBAAmB;AACzB,MAAMf,oBAAoB;AAE1B,MAAMJ,yBAAiC;IAC5CsB,2CAAoB,CAACC,OAAO;IAC5BD,2CAAoB,CAACE,IAAI;IACzBF,2CAAoB,CAACG,GAAG;IACxBH,2CAAoB,CAACI,GAAG;IACxBJ,2CAAoB,CAACK,MAAM;OACxBC,OAAOC,MAAM,CAACC,yCAAkB;CACpC,CAACC,IAAI,CAAC;AAEA,MAAM9B,2BAAqC;IAAC6B,yCAAkB,CAACE,QAAQ;IAAEF,yCAAkB,CAACG,IAAI;CAAC;AAEjG,MAAMvB,kBAAkB;IAC7BwB,QAAQC,mBAAW;IACnB,iBAAiB;IACjBC,KAAK;IACLC,OAAOrC;IACP,gBAAgBI;IAChB,kBAAkB;IAClB,iBAAiB;AACnB;AAEO,MAAMD,SAAS;IACpBD,OAAO;IACPoC,IAAI;IACJC,YAAY;IACZC,aAAa;IACbC,WAAW;IACXC,SAAS;AACX;AAEO,MAAMrC,sBAAsB;AAC5B,MAAMa,iBAAiB;IAC5B;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACAb;CACD;AAEM,IAAA,AAAKE,oCAAAA;;;WAAAA;;AAKL,IAAA,AAAKL,+BAAAA;;;;WAAAA;;AAQL,IAAA,AAAKc,kCAAAA;;;;WAAAA;;AAML,MAAMF,wBAAwB;AAC9B,MAAMF,mBAAmB;IAAE+B,KAAK;IAAOC,QAAQ;AAAS;AACxD,MAAM/B,2BAA2B;IAAC;IAAmB;IAAgB;CAAwB;AAC7F,MAAME,4BAA4B;OAAIF;IAA0B;IAAqB;IAAuB;CAAsB;AAElI,MAAMF,eAAe;IAC1BkC,oBAAoB;IACpBC,oBAAoB;IACpBC,qBAAqB;IACrBC,eAAe;IACfC,uBAAuB;AACzB"}
1
+ {"version":3,"sources":["../../../../../backend/src/applications/webdav/constants/webdav.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 { SERVER_NAME } from '../../../common/shared'\nimport { HTTP_STANDARD_METHOD, HTTP_WEBDAV_METHOD } from '../../applications.constants'\nimport { WEBDAV_BASE_PATH } from './routes'\n\nexport const REGEX_BASE_PATH = new RegExp(`^/?${WEBDAV_BASE_PATH}/`)\nexport const NS_DAV = 'DAV:'\nexport const NS_PREFIX = 'D'\nexport const LOCK_PREFIX = 'urn:uuid:'\nexport const XML_CONTENT_TYPE = 'application/xml; charset=utf-8'\nexport const HTML_CONTENT_TYPE = 'text/html; charset=utf-8'\nexport const WEBDAV_APP_LOCK = 'WebDAV' as const\n\nexport const ALLOWED_WEBDAV_METHODS: string = [\n HTTP_STANDARD_METHOD.OPTIONS,\n HTTP_STANDARD_METHOD.HEAD,\n HTTP_STANDARD_METHOD.GET,\n HTTP_STANDARD_METHOD.PUT,\n HTTP_STANDARD_METHOD.DELETE,\n ...Object.values(HTTP_WEBDAV_METHOD)\n].join(', ')\n\nexport const ALLOW_EMPTY_BODY_METHODS: string[] = [HTTP_WEBDAV_METHOD.PROPFIND, HTTP_WEBDAV_METHOD.LOCK]\n\nexport const OPTIONS_HEADERS = {\n Server: SERVER_NAME,\n 'MS-Author-Via': 'DAV',\n DAV: '1,2',\n Allow: ALLOWED_WEBDAV_METHODS,\n 'Content-Type': HTML_CONTENT_TYPE,\n 'Content-Length': '0',\n 'Accept-Ranges': 'bytes'\n} as const\n\nexport const HEADER = {\n DEPTH: 'depth',\n IF: 'if',\n LOCK_TOKEN: 'lock-token',\n DESTINATION: 'destination',\n OVERWRITE: 'overwrite',\n TIMEOUT: 'timeout'\n} as const\n\nexport const LOCK_DISCOVERY_PROP = 'lockdiscovery'\nexport const STANDARD_PROPS = [\n 'creationdate',\n 'getcontenttype',\n 'resourcetype',\n 'getlastmodified',\n 'getcontentlength',\n 'displayname',\n 'getetag',\n 'supportedlock',\n LOCK_DISCOVERY_PROP\n]\n\nexport enum LOCK_SCOPE {\n EXCLUSIVE = 'exclusive',\n SHARED = 'shared'\n}\n\nexport enum DEPTH {\n INFINITY = 'infinity',\n RESOURCE = '0',\n MEMBERS = '1'\n}\n\nexport type LOCK_DEPTH = Omit<DEPTH, DEPTH.MEMBERS>\n\nexport enum PROPSTAT {\n ALLPROP = 'allprop',\n PROP = 'prop',\n PROPNAME = 'propname'\n}\n\nexport const PROPPATCH_PROP_UPDATE = 'propertyupdate'\nexport const PROPPATCH_METHOD = { SET: 'set', REMOVE: 'remove' }\nexport const PROPPATCH_MODIFIED_PROPS = ['getlastmodified', 'lastmodified', 'Win32LastModifiedTime']\nexport const PROPPATCH_SUPPORTED_PROPS = [...PROPPATCH_MODIFIED_PROPS, 'Win32CreationTime', 'Win32LastAccessTime', 'Win32FileAttributes']\n\nexport const PRECONDITION = {\n PROTECTED_PROPERTY: 'cannot-modify-protected-property',\n MISSING_LOCK_TOKEN: 'lock-token-submitted',\n LOCK_TOKEN_MISMATCH: 'lock-token-matches-request-uri',\n LOCK_CONFLICT: 'no-conflicting-lock',\n PROPFIND_FINITE_DEPTH: 'propfind-finite-depth'\n} as const\n"],"names":["ALLOWED_WEBDAV_METHODS","ALLOW_EMPTY_BODY_METHODS","DEPTH","HEADER","HTML_CONTENT_TYPE","LOCK_DISCOVERY_PROP","LOCK_PREFIX","LOCK_SCOPE","NS_DAV","NS_PREFIX","OPTIONS_HEADERS","PRECONDITION","PROPPATCH_METHOD","PROPPATCH_MODIFIED_PROPS","PROPPATCH_PROP_UPDATE","PROPPATCH_SUPPORTED_PROPS","PROPSTAT","REGEX_BASE_PATH","STANDARD_PROPS","WEBDAV_APP_LOCK","XML_CONTENT_TYPE","RegExp","WEBDAV_BASE_PATH","HTTP_STANDARD_METHOD","OPTIONS","HEAD","GET","PUT","DELETE","Object","values","HTTP_WEBDAV_METHOD","join","PROPFIND","LOCK","Server","SERVER_NAME","DAV","Allow","IF","LOCK_TOKEN","DESTINATION","OVERWRITE","TIMEOUT","SET","REMOVE","PROTECTED_PROPERTY","MISSING_LOCK_TOKEN","LOCK_TOKEN_MISMATCH","LOCK_CONFLICT","PROPFIND_FINITE_DEPTH"],"mappings":"AAAA;;;;CAIC;;;;;;;;;;;QAcYA;eAAAA;;QASAC;eAAAA;;QAuCDC;eAAAA;;QA3BCC;eAAAA;;QAxBAC;eAAAA;;QAiCAC;eAAAA;;QAnCAC;eAAAA;;QAgDDC;eAAAA;;QAlDCC;eAAAA;;QACAC;eAAAA;;QAiBAC;eAAAA;;QAwDAC;eAAAA;;QAJAC;eAAAA;;QACAC;eAAAA;;QAFAC;eAAAA;;QAGAC;eAAAA;;QATDC;eAAAA;;QAhECC;eAAAA;;QAuCAC;eAAAA;;QAjCAC;eAAAA;;QAFAC;eAAAA;;;wBARe;uCAC6B;wBACxB;AAE1B,MAAMH,kBAAkB,IAAII,OAAO,CAAC,GAAG,EAAEC,wBAAgB,CAAC,CAAC,CAAC;AAC5D,MAAMd,SAAS;AACf,MAAMC,YAAY;AAClB,MAAMH,cAAc;AACpB,MAAMc,mBAAmB;AACzB,MAAMhB,oBAAoB;AAC1B,MAAMe,kBAAkB;AAExB,MAAMnB,yBAAiC;IAC5CuB,2CAAoB,CAACC,OAAO;IAC5BD,2CAAoB,CAACE,IAAI;IACzBF,2CAAoB,CAACG,GAAG;IACxBH,2CAAoB,CAACI,GAAG;IACxBJ,2CAAoB,CAACK,MAAM;OACxBC,OAAOC,MAAM,CAACC,yCAAkB;CACpC,CAACC,IAAI,CAAC;AAEA,MAAM/B,2BAAqC;IAAC8B,yCAAkB,CAACE,QAAQ;IAAEF,yCAAkB,CAACG,IAAI;CAAC;AAEjG,MAAMxB,kBAAkB;IAC7ByB,QAAQC,mBAAW;IACnB,iBAAiB;IACjBC,KAAK;IACLC,OAAOtC;IACP,gBAAgBI;IAChB,kBAAkB;IAClB,iBAAiB;AACnB;AAEO,MAAMD,SAAS;IACpBD,OAAO;IACPqC,IAAI;IACJC,YAAY;IACZC,aAAa;IACbC,WAAW;IACXC,SAAS;AACX;AAEO,MAAMtC,sBAAsB;AAC5B,MAAMa,iBAAiB;IAC5B;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACAb;CACD;AAEM,IAAA,AAAKE,oCAAAA;;;WAAAA;;AAKL,IAAA,AAAKL,+BAAAA;;;;WAAAA;;AAQL,IAAA,AAAKc,kCAAAA;;;;WAAAA;;AAML,MAAMF,wBAAwB;AAC9B,MAAMF,mBAAmB;IAAEgC,KAAK;IAAOC,QAAQ;AAAS;AACxD,MAAMhC,2BAA2B;IAAC;IAAmB;IAAgB;CAAwB;AAC7F,MAAME,4BAA4B;OAAIF;IAA0B;IAAqB;IAAuB;CAAsB;AAElI,MAAMF,eAAe;IAC1BmC,oBAAoB;IACpBC,oBAAoB;IACpBC,qBAAqB;IACrBC,eAAe;IACfC,uBAAuB;AACzB"}