@sync-in/server 1.9.6 → 1.10.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (367) hide show
  1. package/CHANGELOG.md +38 -4
  2. package/README.md +2 -2
  3. package/environment/environment.dist.yaml +15 -5
  4. package/package.json +14 -16
  5. package/server/app.bootstrap.js +4 -23
  6. package/server/app.bootstrap.js.map +1 -1
  7. package/server/app.constants.js +3 -2
  8. package/server/app.constants.js.map +1 -1
  9. package/server/applications/comments/services/comments-queries.service.js +5 -9
  10. package/server/applications/comments/services/comments-queries.service.js.map +1 -1
  11. package/server/applications/files/constants/cache.js +2 -5
  12. package/server/applications/files/constants/cache.js.map +1 -1
  13. package/server/applications/files/constants/files.js +4 -0
  14. package/server/applications/files/constants/files.js.map +1 -1
  15. package/server/applications/files/constants/operations.js +4 -0
  16. package/server/applications/files/constants/operations.js.map +1 -1
  17. package/server/applications/files/constants/routes.js +1 -26
  18. package/server/applications/files/constants/routes.js.map +1 -1
  19. package/server/applications/files/files.config.js +15 -39
  20. package/server/applications/files/files.config.js.map +1 -1
  21. package/server/applications/files/files.controller.js +4 -4
  22. package/server/applications/files/files.controller.js.map +1 -1
  23. package/server/applications/files/files.module.js +12 -9
  24. package/server/applications/files/files.module.js.map +1 -1
  25. package/server/applications/files/interfaces/file-lock.interface.js.map +1 -1
  26. package/server/applications/files/interfaces/file-props.interface.js.map +1 -1
  27. package/server/applications/files/modules/collabora-online/collabora-online-environment.decorator.js +32 -0
  28. package/server/applications/files/modules/collabora-online/collabora-online-environment.decorator.js.map +1 -0
  29. package/server/applications/files/modules/collabora-online/collabora-online-manager.service.js +280 -0
  30. package/server/applications/files/modules/collabora-online/collabora-online-manager.service.js.map +1 -0
  31. package/server/applications/files/modules/collabora-online/collabora-online-manager.service.spec.js +552 -0
  32. package/server/applications/files/modules/collabora-online/collabora-online-manager.service.spec.js.map +1 -0
  33. package/server/applications/files/modules/collabora-online/collabora-online.config.js +40 -0
  34. package/server/applications/files/modules/collabora-online/collabora-online.config.js.map +1 -0
  35. package/server/applications/files/modules/collabora-online/collabora-online.constants.js +110 -0
  36. package/server/applications/files/modules/collabora-online/collabora-online.constants.js.map +1 -0
  37. package/server/applications/files/modules/collabora-online/collabora-online.controller.js +128 -0
  38. package/server/applications/files/modules/collabora-online/collabora-online.controller.js.map +1 -0
  39. package/server/applications/files/modules/collabora-online/collabora-online.controller.spec.js +47 -0
  40. package/server/applications/files/modules/collabora-online/collabora-online.controller.spec.js.map +1 -0
  41. package/server/applications/files/{interfaces/only-office-config.interface.js → modules/collabora-online/collabora-online.dtos.js} +1 -1
  42. package/server/applications/files/modules/collabora-online/collabora-online.dtos.js.map +1 -0
  43. package/server/applications/files/{guards/files-only-office.guard.js → modules/collabora-online/collabora-online.guard.js} +7 -21
  44. package/server/applications/files/modules/collabora-online/collabora-online.guard.js.map +1 -0
  45. package/server/applications/files/modules/collabora-online/collabora-online.guard.spec.js +86 -0
  46. package/server/applications/files/modules/collabora-online/collabora-online.guard.spec.js.map +1 -0
  47. package/server/applications/files/modules/collabora-online/collabora-online.interface.js +10 -0
  48. package/server/applications/files/modules/collabora-online/collabora-online.interface.js.map +1 -0
  49. package/server/applications/files/modules/collabora-online/collabora-online.module.js +41 -0
  50. package/server/applications/files/modules/collabora-online/collabora-online.module.js.map +1 -0
  51. package/server/applications/files/modules/collabora-online/collabora-online.routes.js +35 -0
  52. package/server/applications/files/modules/collabora-online/collabora-online.routes.js.map +1 -0
  53. package/server/applications/files/modules/collabora-online/collabora-online.strategy.js +59 -0
  54. package/server/applications/files/modules/collabora-online/collabora-online.strategy.js.map +1 -0
  55. package/server/applications/files/modules/collabora-online/collabora-online.utils.js +28 -0
  56. package/server/applications/files/modules/collabora-online/collabora-online.utils.js.map +1 -0
  57. package/server/applications/files/{decorators → modules/only-office}/only-office-environment.decorator.js +5 -5
  58. package/server/applications/files/modules/only-office/only-office-environment.decorator.js.map +1 -0
  59. package/server/applications/files/{services/files-only-office-manager.service.js → modules/only-office/only-office-manager.service.js} +101 -97
  60. package/server/applications/files/modules/only-office/only-office-manager.service.js.map +1 -0
  61. package/server/applications/files/modules/only-office/only-office-manager.service.spec.js +477 -0
  62. package/server/applications/files/modules/only-office/only-office-manager.service.spec.js.map +1 -0
  63. package/server/applications/files/modules/only-office/only-office.config.js +51 -0
  64. package/server/applications/files/modules/only-office/only-office.config.js.map +1 -0
  65. package/server/applications/files/modules/only-office/only-office.constants.js +417 -0
  66. package/server/applications/files/modules/only-office/only-office.constants.js.map +1 -0
  67. package/server/applications/files/{files-only-office.controller.js → modules/only-office/only-office.controller.js} +35 -52
  68. package/server/applications/files/modules/only-office/only-office.controller.js.map +1 -0
  69. package/server/applications/files/{files-only-office.controller.spec.js → modules/only-office/only-office.controller.spec.js} +24 -21
  70. package/server/applications/files/modules/only-office/only-office.controller.spec.js.map +1 -0
  71. package/server/applications/files/modules/only-office/only-office.dtos.js +10 -0
  72. package/server/applications/files/modules/only-office/only-office.dtos.js.map +1 -0
  73. package/server/applications/files/modules/only-office/only-office.guard.js +40 -0
  74. package/server/applications/files/modules/only-office/only-office.guard.js.map +1 -0
  75. package/server/applications/files/{guards/files-only-office.guard.spec.js → modules/only-office/only-office.guard.spec.js} +15 -21
  76. package/server/applications/files/modules/only-office/only-office.guard.spec.js.map +1 -0
  77. package/server/applications/files/modules/only-office/only-office.interface.js +10 -0
  78. package/server/applications/files/modules/only-office/only-office.interface.js.map +1 -0
  79. package/server/applications/files/modules/only-office/only-office.module.js +41 -0
  80. package/server/applications/files/modules/only-office/only-office.module.js.map +1 -0
  81. package/server/applications/files/modules/only-office/only-office.routes.js +45 -0
  82. package/server/applications/files/modules/only-office/only-office.routes.js.map +1 -0
  83. package/server/applications/files/{guards/files-only-office.strategy.js → modules/only-office/only-office.strategy.js} +11 -11
  84. package/server/applications/files/modules/only-office/only-office.strategy.js.map +1 -0
  85. package/server/applications/files/services/files-lock-manager.service.js +25 -33
  86. package/server/applications/files/services/files-lock-manager.service.js.map +1 -1
  87. package/server/applications/files/services/files-manager.service.js +17 -16
  88. package/server/applications/files/services/files-manager.service.js.map +1 -1
  89. package/server/applications/files/services/files-methods.service.js +2 -2
  90. package/server/applications/files/services/files-methods.service.js.map +1 -1
  91. package/server/applications/files/services/files-methods.service.spec.js +3 -1
  92. package/server/applications/files/services/files-methods.service.spec.js.map +1 -1
  93. package/server/applications/files/services/files-scheduler.service.js +2 -2
  94. package/server/applications/files/services/files-scheduler.service.js.map +1 -1
  95. package/server/applications/files/utils/files.js +10 -2
  96. package/server/applications/files/utils/files.js.map +1 -1
  97. package/server/applications/links/constants/routes.js +5 -0
  98. package/server/applications/links/constants/routes.js.map +1 -1
  99. package/server/applications/links/interfaces/link-space.interface.js.map +1 -1
  100. package/server/applications/links/links.controller.js +25 -5
  101. package/server/applications/links/links.controller.js.map +1 -1
  102. package/server/applications/links/services/links-manager.service.js +43 -21
  103. package/server/applications/links/services/links-manager.service.js.map +1 -1
  104. package/server/applications/links/services/links-manager.service.spec.js +4 -3
  105. package/server/applications/links/services/links-manager.service.spec.js.map +1 -1
  106. package/server/applications/links/services/links-queries.service.js +9 -2
  107. package/server/applications/links/services/links-queries.service.js.map +1 -1
  108. package/server/applications/shares/interfaces/share-link.interface.js.map +1 -1
  109. package/server/applications/shares/services/shares-manager.service.js +3 -0
  110. package/server/applications/shares/services/shares-manager.service.js.map +1 -1
  111. package/server/applications/shares/services/shares-manager.service.spec.js +2 -1
  112. package/server/applications/shares/services/shares-manager.service.spec.js.map +1 -1
  113. package/server/applications/shares/services/shares-queries.service.js +1 -0
  114. package/server/applications/shares/services/shares-queries.service.js.map +1 -1
  115. package/server/applications/spaces/constants/spaces.js +2 -2
  116. package/server/applications/spaces/constants/spaces.js.map +1 -1
  117. package/server/applications/spaces/decorators/space-override-permission.decorator.js +18 -0
  118. package/server/applications/spaces/decorators/space-override-permission.decorator.js.map +1 -0
  119. package/server/applications/spaces/guards/space.guard.js +40 -33
  120. package/server/applications/spaces/guards/space.guard.js.map +1 -1
  121. package/server/applications/spaces/guards/space.guard.spec.js +10 -15
  122. package/server/applications/spaces/guards/space.guard.spec.js.map +1 -1
  123. package/server/applications/users/users.e2e-spec.js +0 -1
  124. package/server/applications/users/users.e2e-spec.js.map +1 -1
  125. package/server/applications/webdav/constants/webdav.js +11 -0
  126. package/server/applications/webdav/constants/webdav.js.map +1 -1
  127. package/server/applications/webdav/guards/webdav-protocol.guard.js +9 -8
  128. package/server/applications/webdav/guards/webdav-protocol.guard.js.map +1 -1
  129. package/server/applications/webdav/guards/webdav-protocol.guard.spec.js +1 -1
  130. package/server/applications/webdav/guards/webdav-protocol.guard.spec.js.map +1 -1
  131. package/server/applications/webdav/interfaces/webdav.interface.js.map +1 -1
  132. package/server/applications/webdav/services/webdav-methods.service.js +40 -17
  133. package/server/applications/webdav/services/webdav-methods.service.js.map +1 -1
  134. package/server/applications/webdav/services/webdav-methods.service.spec.js +2157 -1289
  135. package/server/applications/webdav/services/webdav-methods.service.spec.js.map +1 -1
  136. package/server/applications/webdav/utils/bootstrap.js +45 -0
  137. package/server/applications/webdav/utils/bootstrap.js.map +1 -0
  138. package/server/applications/webdav/utils/webdav.js +8 -4
  139. package/server/applications/webdav/utils/webdav.js.map +1 -1
  140. package/server/applications/webdav/webdav.controller.js +5 -5
  141. package/server/applications/webdav/webdav.controller.js.map +1 -1
  142. package/server/applications/webdav/webdav.e2e-spec.js +131 -2
  143. package/server/applications/webdav/webdav.e2e-spec.js.map +1 -1
  144. package/server/authentication/auth.e2e-spec.js +12 -6
  145. package/server/authentication/auth.e2e-spec.js.map +1 -1
  146. package/server/authentication/guards/auth-basic.guard.spec.js +23 -0
  147. package/server/authentication/guards/auth-basic.guard.spec.js.map +1 -1
  148. package/server/authentication/guards/auth-basic.strategy.js +3 -3
  149. package/server/authentication/guards/auth-basic.strategy.js.map +1 -1
  150. package/server/authentication/guards/auth-digest.strategy.js +32 -11
  151. package/server/authentication/guards/auth-digest.strategy.js.map +1 -1
  152. package/server/authentication/guards/auth-token-access.guard.js +8 -3
  153. package/server/authentication/guards/auth-token-access.guard.js.map +1 -1
  154. package/server/authentication/guards/implementations/http-basic.strategy.js +76 -0
  155. package/server/authentication/guards/implementations/http-basic.strategy.js.map +1 -0
  156. package/server/authentication/guards/implementations/http-digest.strategy.js +155 -0
  157. package/server/authentication/guards/implementations/http-digest.strategy.js.map +1 -0
  158. package/server/authentication/services/auth-manager.service.js +1 -2
  159. package/server/authentication/services/auth-manager.service.js.map +1 -1
  160. package/server/authentication/services/auth-methods/auth-method-two-fa.service.js +1 -1
  161. package/server/authentication/services/auth-methods/auth-method-two-fa.service.js.map +1 -1
  162. package/server/authentication/services/auth-methods/auth-method-two-fa.service.spec.js +350 -4
  163. package/server/authentication/services/auth-methods/auth-method-two-fa.service.spec.js.map +1 -1
  164. package/server/configuration/config.environment.js +5 -1
  165. package/server/configuration/config.environment.js.map +1 -1
  166. package/server/configuration/config.interfaces.js.map +1 -1
  167. package/static/3rdpartylicenses.txt +507 -507
  168. package/static/assets/pdfjs/build/pdf.mjs +93 -33
  169. package/static/assets/pdfjs/build/pdf.mjs.map +1 -1
  170. package/static/assets/pdfjs/build/pdf.sandbox.mjs +3 -3
  171. package/static/assets/pdfjs/build/pdf.sandbox.mjs.map +1 -1
  172. package/static/assets/pdfjs/build/pdf.worker.mjs +166 -54
  173. package/static/assets/pdfjs/build/pdf.worker.mjs.map +1 -1
  174. package/static/assets/pdfjs/version +1 -1
  175. package/static/assets/pdfjs/web/images/checkmark.svg +5 -0
  176. package/static/assets/pdfjs/web/images/pages_closeButton.svg +3 -0
  177. package/static/assets/pdfjs/web/images/pages_selected.svg +7 -0
  178. package/static/assets/pdfjs/web/images/pages_viewArrow.svg +3 -0
  179. package/static/assets/pdfjs/web/images/pages_viewButton.svg +3 -0
  180. package/static/assets/pdfjs/web/locale/be/viewer.ftl +0 -2
  181. package/static/assets/pdfjs/web/locale/bs/viewer.ftl +0 -5
  182. package/static/assets/pdfjs/web/locale/cs/viewer.ftl +4 -6
  183. package/static/assets/pdfjs/web/locale/cy/viewer.ftl +0 -2
  184. package/static/assets/pdfjs/web/locale/da/viewer.ftl +0 -2
  185. package/static/assets/pdfjs/web/locale/de/viewer.ftl +0 -2
  186. package/static/assets/pdfjs/web/locale/dsb/viewer.ftl +0 -2
  187. package/static/assets/pdfjs/web/locale/el/viewer.ftl +0 -2
  188. package/static/assets/pdfjs/web/locale/en-CA/viewer.ftl +6 -2
  189. package/static/assets/pdfjs/web/locale/en-GB/viewer.ftl +0 -2
  190. package/static/assets/pdfjs/web/locale/en-US/viewer.ftl +82 -17
  191. package/static/assets/pdfjs/web/locale/eo/viewer.ftl +0 -2
  192. package/static/assets/pdfjs/web/locale/es-AR/viewer.ftl +0 -2
  193. package/static/assets/pdfjs/web/locale/es-CL/viewer.ftl +0 -2
  194. package/static/assets/pdfjs/web/locale/es-ES/viewer.ftl +0 -2
  195. package/static/assets/pdfjs/web/locale/es-MX/viewer.ftl +0 -2
  196. package/static/assets/pdfjs/web/locale/eu/viewer.ftl +0 -2
  197. package/static/assets/pdfjs/web/locale/fi/viewer.ftl +0 -2
  198. package/static/assets/pdfjs/web/locale/fr/viewer.ftl +0 -2
  199. package/static/assets/pdfjs/web/locale/fur/viewer.ftl +0 -5
  200. package/static/assets/pdfjs/web/locale/fy-NL/viewer.ftl +3 -5
  201. package/static/assets/pdfjs/web/locale/gn/viewer.ftl +0 -2
  202. package/static/assets/pdfjs/web/locale/he/viewer.ftl +0 -2
  203. package/static/assets/pdfjs/web/locale/hr/viewer.ftl +66 -0
  204. package/static/assets/pdfjs/web/locale/hsb/viewer.ftl +0 -2
  205. package/static/assets/pdfjs/web/locale/hu/viewer.ftl +0 -2
  206. package/static/assets/pdfjs/web/locale/hy-AM/viewer.ftl +3 -8
  207. package/static/assets/pdfjs/web/locale/ia/viewer.ftl +0 -2
  208. package/static/assets/pdfjs/web/locale/id/viewer.ftl +0 -5
  209. package/static/assets/pdfjs/web/locale/is/viewer.ftl +0 -5
  210. package/static/assets/pdfjs/web/locale/it/viewer.ftl +0 -2
  211. package/static/assets/pdfjs/web/locale/ja/viewer.ftl +0 -14
  212. package/static/assets/pdfjs/web/locale/ka/viewer.ftl +4 -6
  213. package/static/assets/pdfjs/web/locale/kab/viewer.ftl +0 -5
  214. package/static/assets/pdfjs/web/locale/kk/viewer.ftl +0 -2
  215. package/static/assets/pdfjs/web/locale/ko/viewer.ftl +0 -2
  216. package/static/assets/pdfjs/web/locale/nb-NO/viewer.ftl +1 -3
  217. package/static/assets/pdfjs/web/locale/nl/viewer.ftl +0 -2
  218. package/static/assets/pdfjs/web/locale/nn-NO/viewer.ftl +4 -2
  219. package/static/assets/pdfjs/web/locale/pa-IN/viewer.ftl +0 -2
  220. package/static/assets/pdfjs/web/locale/pl/viewer.ftl +0 -2
  221. package/static/assets/pdfjs/web/locale/pt-BR/viewer.ftl +0 -2
  222. package/static/assets/pdfjs/web/locale/pt-PT/viewer.ftl +35 -0
  223. package/static/assets/pdfjs/web/locale/rm/viewer.ftl +0 -5
  224. package/static/assets/pdfjs/web/locale/ro/viewer.ftl +4 -6
  225. package/static/assets/pdfjs/web/locale/ru/viewer.ftl +3 -5
  226. package/static/assets/pdfjs/web/locale/sk/viewer.ftl +0 -2
  227. package/static/assets/pdfjs/web/locale/sl/viewer.ftl +0 -2
  228. package/static/assets/pdfjs/web/locale/sq/viewer.ftl +0 -2
  229. package/static/assets/pdfjs/web/locale/sv-SE/viewer.ftl +0 -2
  230. package/static/assets/pdfjs/web/locale/tg/viewer.ftl +0 -2
  231. package/static/assets/pdfjs/web/locale/th/viewer.ftl +2 -2
  232. package/static/assets/pdfjs/web/locale/tr/viewer.ftl +0 -2
  233. package/static/assets/pdfjs/web/locale/vi/viewer.ftl +0 -2
  234. package/static/assets/pdfjs/web/locale/zh-CN/viewer.ftl +0 -2
  235. package/static/assets/pdfjs/web/locale/zh-TW/viewer.ftl +0 -2
  236. package/static/assets/pdfjs/web/viewer.css +1778 -835
  237. package/static/assets/pdfjs/web/viewer.html +167 -86
  238. package/static/assets/pdfjs/web/viewer.mjs +1106 -801
  239. package/static/assets/pdfjs/web/viewer.mjs.map +1 -1
  240. package/static/chunk-27V66YJV.js +2 -0
  241. package/static/{chunk-2F42MZQ5.js → chunk-2GXOVGTD.js} +1 -1
  242. package/static/{chunk-HLKZCMKV.js → chunk-2RWLNKZH.js} +1 -1
  243. package/static/chunk-2YQ4SX3A.js +13 -0
  244. package/static/{chunk-LFAQLJZK.js → chunk-3MVPXC3U.js} +1 -1
  245. package/static/chunk-3QTROEHV.js +1 -0
  246. package/static/{chunk-JYHTSSKW.js → chunk-3VRUIWQG.js} +1 -1
  247. package/static/{chunk-2CAAJBRO.js → chunk-3ZBAQTHJ.js} +1 -1
  248. package/static/chunk-3ZLBVUCX.js +2 -0
  249. package/static/chunk-46TJLPJY.js +1 -0
  250. package/static/chunk-4NIYCYRS.js +2 -0
  251. package/static/chunk-6OEOADR6.js +1 -0
  252. package/static/{chunk-BJARRIS6.js → chunk-76M3BMK6.js} +11 -11
  253. package/static/{chunk-ANH4VNOS.js → chunk-76REYAEA.js} +1 -1
  254. package/static/{chunk-7HL5Z6PF.js → chunk-7HJFIMNF.js} +1 -1
  255. package/static/{chunk-XIQXRSZ2.js → chunk-7KAYOR3A.js} +1 -1
  256. package/static/chunk-AALPWGPB.js +3 -0
  257. package/static/{chunk-Z2KBIZ5D.js → chunk-ARS47O5X.js} +1 -1
  258. package/static/chunk-BCN4T5DO.js +2 -0
  259. package/static/{chunk-DU4Q4RWJ.js → chunk-CMNMPG6Z.js} +1 -1
  260. package/static/{chunk-UO7ATVQG.js → chunk-CN5YVRFT.js} +1 -1
  261. package/static/{chunk-BX3QZ7IL.js → chunk-CSVPAZHK.js} +1 -1
  262. package/static/chunk-CVXLHSO5.js +1 -0
  263. package/static/{chunk-O233BXWK.js → chunk-D2MLAO5N.js} +1 -1
  264. package/static/{chunk-NHMYAVJK.js → chunk-D5FQ72R4.js} +1 -1
  265. package/static/{chunk-IBC7CFBQ.js → chunk-DVCN3P7Q.js} +1 -1
  266. package/static/{chunk-25PWAXTJ.js → chunk-EKWB5W72.js} +1 -1
  267. package/static/{chunk-ZCOEP4O2.js → chunk-FTFEQDWH.js} +1 -1
  268. package/static/{chunk-EPDWJEPD.js → chunk-FWQJ4ZCD.js} +1 -1
  269. package/static/chunk-G7RZN7HN.js +1 -0
  270. package/static/{chunk-X5UDV4ZB.js → chunk-HZAB6F4Q.js} +1 -1
  271. package/static/{chunk-FEQUP26G.js → chunk-IHS5LSJJ.js} +1 -1
  272. package/static/{chunk-DQAQUSVW.js → chunk-IMFO2MI7.js} +1 -1
  273. package/static/{chunk-ODAQRAPO.js → chunk-J7474P3L.js} +1 -1
  274. package/static/{chunk-DK2LAJEL.js → chunk-JAJ7VXMB.js} +1 -1
  275. package/static/{chunk-AYYJZMBE.js → chunk-JNTNMIUH.js} +1 -1
  276. package/static/chunk-JRXG43AA.js +2 -0
  277. package/static/{chunk-3AR5VNJE.js → chunk-KAUCN24H.js} +1 -1
  278. package/static/{chunk-3WS72A6C.js → chunk-KDUAB76O.js} +1 -1
  279. package/static/chunk-KEZNIIFH.js +1 -0
  280. package/static/chunk-LTJNLOX2.js +1 -0
  281. package/static/chunk-LWSCODLD.js +1 -0
  282. package/static/{chunk-GRV44RYI.js → chunk-LZUHREOF.js} +1 -1
  283. package/static/chunk-NIKNG2FX.js +1 -0
  284. package/static/chunk-NNZWSNAW.js +1 -0
  285. package/static/chunk-NWKBB7J4.js +1 -0
  286. package/static/{chunk-B4TDS6AQ.js → chunk-PDG7DOEF.js} +1 -1
  287. package/static/{chunk-NQCKX2AD.js → chunk-PPJCVBJH.js} +1 -1
  288. package/static/chunk-PVYVY3GD.js +1 -0
  289. package/static/chunk-Q5X5TPAG.js +1 -0
  290. package/static/chunk-QGHNJVJ6.js +1 -0
  291. package/static/{chunk-5HYSNQR4.js → chunk-QJ22N76V.js} +1 -1
  292. package/static/{chunk-TOCCCZP2.js → chunk-QTPIEEZW.js} +1 -1
  293. package/static/{chunk-D6QWQHWE.js → chunk-R4VMWCM5.js} +1 -1
  294. package/static/{chunk-7H5O4BLV.js → chunk-R4VYKZVJ.js} +1 -1
  295. package/static/{chunk-QKMN3S4M.js → chunk-RBTLSPYJ.js} +1 -1
  296. package/static/chunk-RJULB733.js +1 -0
  297. package/static/{chunk-E5C4QRNQ.js → chunk-RNVPQQKT.js} +5 -5
  298. package/static/chunk-RTNEBRKJ.js +1 -0
  299. package/static/{chunk-IIKL33TV.js → chunk-S44QIK3G.js} +1 -1
  300. package/static/{chunk-SF6Q6VRC.js → chunk-S6H2ELRY.js} +1 -1
  301. package/static/{chunk-4GBA6EJ4.js → chunk-SDJNZULP.js} +1 -1
  302. package/static/chunk-SNOOCDJD.js +1 -0
  303. package/static/chunk-SPQH3ATC.js +5 -0
  304. package/static/{chunk-5KVI243T.js → chunk-TNCKNU6I.js} +1 -1
  305. package/static/{chunk-7QYALK5T.js → chunk-TTWMFWEC.js} +1 -1
  306. package/static/{chunk-OVUMPMVM.js → chunk-U5E5H2DD.js} +1 -1
  307. package/static/{chunk-5NFH4E2B.js → chunk-UOK3LKSX.js} +1 -1
  308. package/static/{chunk-5ATJIR5S.js → chunk-VBTZDHZ3.js} +1 -1
  309. package/static/{chunk-CHMDM2ZW.js → chunk-VD5JHSDS.js} +1 -1
  310. package/static/chunk-VZFZUI6D.js +1 -0
  311. package/static/{chunk-GYYJ4FWN.js → chunk-WFMEUST4.js} +1 -1
  312. package/static/{chunk-BVKDW5XO.js → chunk-WRK2FTKU.js} +1 -1
  313. package/static/{chunk-GLPKRULI.js → chunk-WZPF4LS2.js} +1 -1
  314. package/static/chunk-X7NHX5C7.js +1 -0
  315. package/static/{chunk-FSGT46LM.js → chunk-XSURUW7C.js} +1 -1
  316. package/static/{chunk-KAAFVHYE.js → chunk-XX3JPJUM.js} +1 -1
  317. package/static/{chunk-C5T7RZSD.js → chunk-XZHWESIY.js} +1 -1
  318. package/static/chunk-ZCSHU3D7.js +1 -0
  319. package/static/{chunk-QUUQOBTF.js → chunk-ZEJLIGAY.js} +1 -1
  320. package/static/{chunk-GENTF6JM.js → chunk-ZHUBWKA2.js} +1 -1
  321. package/static/chunk-ZOMRIN3G.js +2 -0
  322. package/static/{chunk-2U5VKTML.js → chunk-ZU5MQTFN.js} +1 -1
  323. package/static/index.html +2 -2
  324. package/static/main-5O3KLGIR.js +11 -0
  325. package/static/{styles-S5HVK4H5.css → styles-XLLEY5Y3.css} +1 -1
  326. package/server/applications/files/constants/only-office.js +0 -531
  327. package/server/applications/files/constants/only-office.js.map +0 -1
  328. package/server/applications/files/decorators/only-office-environment.decorator.js.map +0 -1
  329. package/server/applications/files/files-only-office.controller.js.map +0 -1
  330. package/server/applications/files/files-only-office.controller.spec.js.map +0 -1
  331. package/server/applications/files/guards/files-only-office.guard.js.map +0 -1
  332. package/server/applications/files/guards/files-only-office.guard.spec.js.map +0 -1
  333. package/server/applications/files/guards/files-only-office.strategy.js.map +0 -1
  334. package/server/applications/files/interfaces/only-office-config.interface.js.map +0 -1
  335. package/server/applications/files/services/files-only-office-manager.service.js.map +0 -1
  336. package/server/applications/files/services/files-only-office-manager.service.spec.js +0 -58
  337. package/server/applications/files/services/files-only-office-manager.service.spec.js.map +0 -1
  338. package/static/chunk-42L6C5MT.js +0 -1
  339. package/static/chunk-4ZKAVMB4.js +0 -1
  340. package/static/chunk-5GIWZKNS.js +0 -1
  341. package/static/chunk-5WCQBTXW.js +0 -1
  342. package/static/chunk-B2A4HNDC.js +0 -1
  343. package/static/chunk-BSB4VROD.js +0 -2
  344. package/static/chunk-CUC7R6C2.js +0 -1
  345. package/static/chunk-DHFQIFOF.js +0 -1
  346. package/static/chunk-DRHPEERW.js +0 -2
  347. package/static/chunk-FCGTI42I.js +0 -1
  348. package/static/chunk-FCR5AEHR.js +0 -3
  349. package/static/chunk-HB5DC7RJ.js +0 -1
  350. package/static/chunk-ITVA26X2.js +0 -2
  351. package/static/chunk-KWKZN53T.js +0 -1
  352. package/static/chunk-LBXOAKBD.js +0 -1
  353. package/static/chunk-LZKI5P5T.js +0 -1
  354. package/static/chunk-MGMDT4VN.js +0 -1
  355. package/static/chunk-MWUUM2NK.js +0 -13
  356. package/static/chunk-MYM43ENO.js +0 -1
  357. package/static/chunk-NAH4V2R6.js +0 -2
  358. package/static/chunk-PCFH5HCI.js +0 -2
  359. package/static/chunk-Q6B4OVER.js +0 -5
  360. package/static/chunk-QV5LQKTS.js +0 -1
  361. package/static/chunk-S4UTSOPV.js +0 -1
  362. package/static/chunk-SRBOO7AO.js +0 -1
  363. package/static/chunk-VZPCXSRG.js +0 -2
  364. package/static/chunk-XKEBQNQJ.js +0 -1
  365. package/static/chunk-YYTDPI5S.js +0 -1
  366. package/static/main-ODUA232E.js +0 -11
  367. /package/static/assets/pdfjs/web/images/{toolbarButton-sidebarToggle.svg → toolbarButton-viewsManagerToggle.svg} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../backend/src/applications/files/modules/collabora-online/collabora-online-manager.service.spec.ts"],"sourcesContent":["/*\n * Copyright (C) 2012-2025 Johan Legrand <johan.legrand@sync-in.com>\n * This file is part of Sync-in | The open source file sync and share solution\n * See the LICENSE file for licensing details\n */\n\nimport { HttpException, HttpStatus } from '@nestjs/common'\nimport { JwtService } from '@nestjs/jwt'\nimport { Test, TestingModule } from '@nestjs/testing'\nimport { FastifyReply } from 'fastify'\nimport fs from 'node:fs/promises'\nimport { Readable } from 'node:stream'\nimport { ContextManager } from '../../../../infrastructure/context/services/context-manager.service'\nimport { SPACE_OPERATION } from '../../../spaces/constants/spaces'\nimport type { SpaceEnv } from '../../../spaces/models/space-env.model'\nimport type { UserModel } from '../../../users/models/user.model'\nimport { DEPTH, LOCK_SCOPE } from '../../../webdav/constants/webdav'\nimport { FILE_MODE } from '../../constants/operations'\nimport { FileLockProps } from '../../interfaces/file-props.interface'\nimport { LockConflict } from '../../models/file-lock-error'\nimport { FilesLockManager } from '../../services/files-lock-manager.service'\nimport * as filesUtils from '../../utils/files'\nimport { CollaboraOnlineManager } from './collabora-online-manager.service'\nimport { COLLABORA_APP_LOCK, COLLABORA_HEADERS, COLLABORA_LOCK_ACTION } from './collabora-online.constants'\nimport type { FastifyCollaboraOnlineSpaceRequest } from './collabora-online.interface'\n\njest.mock('../../utils/files')\njest.mock('node:fs/promises')\njest.mock('../../../users/utils/avatar')\n\ndescribe(CollaboraOnlineManager.name, () => {\n let service: CollaboraOnlineManager\n let filesLockManager: FilesLockManager\n\n const mockUser: UserModel = {\n id: 1,\n login: 'testuser',\n email: 'test@example.com',\n fullName: 'Test User',\n language: 'en',\n role: 1,\n applications: []\n } as UserModel\n\n const mockSpace = {\n realPath: '/path/to/document.docx',\n url: '/files/document.docx',\n envPermissions: '',\n dbFile: {\n id: 1,\n path: '/document.docx',\n ownerId: 1,\n name: 'document.docx'\n }\n } as unknown as SpaceEnv\n\n beforeEach(async () => {\n const module: TestingModule = await Test.createTestingModule({\n providers: [\n CollaboraOnlineManager,\n {\n provide: ContextManager,\n useValue: {\n headerOriginUrl: jest.fn().mockReturnValue('https://domain.com')\n }\n },\n {\n provide: JwtService,\n useValue: {\n signAsync: jest.fn().mockResolvedValue('mock-jwt-token')\n }\n },\n {\n provide: FilesLockManager,\n useValue: {\n checkConflicts: jest.fn(),\n convertLockToFileLockProps: jest.fn(),\n create: jest.fn(),\n removeLock: jest.fn(),\n getLocksByPath: jest.fn(),\n isLockedWithToken: jest.fn(),\n refreshLockTimeout: jest.fn()\n }\n }\n ]\n }).compile()\n\n module.useLogger(['fatal'])\n service = module.get<CollaboraOnlineManager>(CollaboraOnlineManager)\n filesLockManager = module.get<FilesLockManager>(FilesLockManager)\n })\n\n afterEach(() => {\n jest.clearAllMocks()\n })\n\n it('should be defined', () => {\n expect(service).toBeDefined()\n })\n\n describe('getSettings', () => {\n beforeEach(() => {\n jest.spyOn(filesUtils, 'isPathExists').mockResolvedValue(true)\n jest.spyOn(filesUtils, 'isPathIsDir').mockResolvedValue(false)\n jest.spyOn(filesUtils, 'genUniqHashFromFileDBProps').mockReturnValue('file-hash-123')\n })\n\n it('should return settings with edit mode when user has modify permissions and no lock conflicts', async () => {\n const spaceWithPermissions = {\n ...mockSpace,\n envPermissions: SPACE_OPERATION.MODIFY\n } as unknown as SpaceEnv\n\n jest.spyOn(filesLockManager, 'checkConflicts').mockResolvedValue(undefined)\n\n const result = await service.getSettings(mockUser, spaceWithPermissions)\n\n expect(result).toEqual({\n documentServerUrl: expect.stringContaining('file-hash-123'),\n mode: FILE_MODE.EDIT,\n hasLock: false\n })\n expect(filesLockManager.checkConflicts).toHaveBeenCalledWith(\n mockSpace.dbFile,\n DEPTH.RESOURCE,\n expect.objectContaining({\n userId: mockUser.id,\n app: COLLABORA_APP_LOCK,\n lockScope: LOCK_SCOPE.SHARED\n })\n )\n })\n\n it('should return settings with view mode when lock conflict exists', async () => {\n const spaceWithPermissions = {\n ...mockSpace,\n envPermissions: SPACE_OPERATION.MODIFY\n } as unknown as SpaceEnv\n\n const mockLock = { userId: 2, options: { lockToken: 'token-123' } }\n const mockFileLockProps: FileLockProps = {\n owner: {\n id: 2,\n login: 'otheruser',\n email: 'other@example.com',\n fullName: 'Other User'\n },\n app: COLLABORA_APP_LOCK,\n isExclusive: false\n }\n\n jest.spyOn(filesLockManager, 'checkConflicts').mockRejectedValue(new LockConflict(mockLock as any, 'conflict'))\n jest.spyOn(filesLockManager, 'convertLockToFileLockProps').mockReturnValue(mockFileLockProps)\n\n const result = await service.getSettings(mockUser, spaceWithPermissions)\n\n expect(result.mode).toBe(FILE_MODE.VIEW)\n expect(result.hasLock).toEqual(mockFileLockProps)\n })\n\n it('should return view mode when user does not have modify permissions', async () => {\n const spaceWithoutPermissions = {\n ...mockSpace,\n envPermissions: ''\n } as unknown as SpaceEnv\n\n const result = await service.getSettings(mockUser, spaceWithoutPermissions)\n\n expect(result.mode).toBe(FILE_MODE.VIEW)\n expect(filesLockManager.checkConflicts).not.toHaveBeenCalled()\n })\n\n it('should throw error when document extension is not supported', async () => {\n const spaceWithUnsupportedFile = {\n ...mockSpace,\n realPath: '/path/to/document.xyz'\n } as unknown as SpaceEnv\n\n jest.spyOn(filesUtils, 'isPathExists').mockResolvedValue(true)\n jest.spyOn(filesUtils, 'isPathIsDir').mockResolvedValue(false)\n\n await expect(service.getSettings(mockUser, spaceWithUnsupportedFile)).rejects.toThrow(\n new HttpException('Document not supported', HttpStatus.BAD_REQUEST)\n )\n })\n\n it('should throw error when document does not exist', async () => {\n jest.spyOn(filesUtils, 'isPathExists').mockResolvedValue(false)\n\n await expect(service.getSettings(mockUser, mockSpace)).rejects.toThrow(new HttpException('Document not found', HttpStatus.NOT_FOUND))\n })\n\n it('should throw error when path is a directory', async () => {\n jest.spyOn(filesUtils, 'isPathExists').mockResolvedValue(true)\n jest.spyOn(filesUtils, 'isPathIsDir').mockResolvedValue(true)\n\n await expect(service.getSettings(mockUser, mockSpace)).rejects.toThrow(new HttpException('Document must be a file', HttpStatus.BAD_REQUEST))\n })\n })\n\n describe('checkFileInfo', () => {\n it('should return file information', async () => {\n const mockStats = {\n size: 1024,\n mtime: new Date('2024-01-01T10:00:00Z')\n }\n\n const mockRequest = {\n user: mockUser,\n space: {\n ...mockSpace,\n envPermissions: SPACE_OPERATION.MODIFY\n }\n } as unknown as FastifyCollaboraOnlineSpaceRequest\n\n jest.spyOn(fs, 'stat').mockResolvedValue(mockStats as any)\n jest.spyOn(filesUtils, 'fileName').mockReturnValue('document.docx')\n jest.spyOn(filesUtils, 'genEtag').mockReturnValue('etag-123')\n const { getAvatarBase64 } = await import('../../../users/utils/avatar')\n ;(getAvatarBase64 as jest.Mock).mockResolvedValue('base64-avatar')\n\n const result = await service.checkFileInfo(mockRequest)\n\n expect(result).toEqual({\n BaseFileName: 'document.docx',\n Version: 'etag-123',\n OwnerId: '1',\n Size: 1024,\n LastModifiedTime: '2024-01-01T10:00:00.000Z',\n UserId: '1',\n UserFriendlyName: 'Test User (test@example.com)',\n ReadOnly: false,\n UserExtraInfo: { avatar: 'base64-avatar' },\n UserCanNotWriteRelative: true,\n UserCanWrite: true,\n UserCanRename: false,\n SupportsUpdate: true,\n SupportsRename: false,\n SupportsExport: true,\n SupportsCoauth: true,\n SupportsLocks: true,\n SupportsGetLock: true\n })\n })\n\n it('should set UserCanWrite to false when user does not have modify permissions', async () => {\n const mockStats = {\n size: 1024,\n mtime: new Date('2024-01-01T10:00:00Z')\n }\n\n const mockRequest = {\n user: mockUser,\n space: {\n ...mockSpace,\n envPermissions: ''\n }\n } as unknown as FastifyCollaboraOnlineSpaceRequest\n\n jest.spyOn(fs, 'stat').mockResolvedValue(mockStats as any)\n jest.spyOn(filesUtils, 'fileName').mockReturnValue('document.docx')\n jest.spyOn(filesUtils, 'genEtag').mockReturnValue('etag-123')\n const { getAvatarBase64 } = await import('../../../users/utils/avatar')\n ;(getAvatarBase64 as jest.Mock).mockResolvedValue('base64-avatar')\n\n const result = await service.checkFileInfo(mockRequest)\n\n expect(result.UserCanWrite).toBe(false)\n })\n })\n\n describe('saveDocument', () => {\n beforeEach(() => {\n jest.spyOn(filesUtils, 'isPathExists').mockResolvedValue(true)\n jest.spyOn(filesUtils, 'isPathIsDir').mockResolvedValue(false)\n jest.spyOn(filesUtils, 'fileName').mockReturnValue('document.docx')\n jest.spyOn(filesUtils, 'uniqueFilePathFromDir').mockResolvedValue('/tmp/document-unique.docx')\n jest.spyOn(filesUtils, 'writeFromStream').mockResolvedValue(undefined)\n jest.spyOn(filesUtils, 'copyFileContent').mockResolvedValue(undefined)\n jest.spyOn(filesUtils, 'removeFiles').mockResolvedValue(undefined)\n })\n\n it('should save document successfully', async () => {\n const mockStats = {\n mtime: new Date('2024-01-01T11:00:00Z')\n }\n\n const mockRequest = {\n user: mockUser,\n space: mockSpace,\n headers: {\n 'content-length': '1024'\n },\n raw: new Readable()\n } as unknown as FastifyCollaboraOnlineSpaceRequest\n\n jest.spyOn(fs, 'stat').mockResolvedValue(mockStats as any)\n jest.spyOn(filesUtils, 'fileSize').mockResolvedValue(1024)\n\n const result = await service.saveDocument(mockRequest)\n\n expect(result).toEqual({\n LastModifiedTime: '2024-01-01T11:00:00.000Z'\n })\n expect(filesUtils.writeFromStream).toHaveBeenCalledWith('/tmp/document-unique.docx', mockRequest.raw)\n expect(filesUtils.copyFileContent).toHaveBeenCalledWith('/tmp/document-unique.docx', mockSpace.realPath)\n expect(filesUtils.removeFiles).toHaveBeenCalledWith('/tmp/document-unique.docx')\n })\n\n it('should throw error when document size mismatch', async () => {\n const mockRequest = {\n user: mockUser,\n space: mockSpace,\n headers: {\n 'content-length': '1024',\n [COLLABORA_HEADERS.Timestamp]: '2024-01-01T10:00:00.000Z'\n },\n raw: new Readable()\n } as unknown as FastifyCollaboraOnlineSpaceRequest\n\n jest.spyOn(filesUtils, 'fileSize').mockResolvedValue(512)\n jest.spyOn(fs, 'stat').mockResolvedValue({ mtime: new Date('2024-01-01T10:00:00.000Z') } as any)\n\n await expect(service.saveDocument(mockRequest)).rejects.toThrow(new HttpException('Size Mismatch', HttpStatus.BAD_REQUEST))\n })\n\n it('should throw error when timestamp mismatch', async () => {\n const mockRequest = {\n user: mockUser,\n space: mockSpace,\n headers: {\n 'content-length': '1024',\n [COLLABORA_HEADERS.Timestamp]: '2024-01-01T10:00:00.000Z'\n },\n raw: new Readable()\n } as unknown as FastifyCollaboraOnlineSpaceRequest\n\n jest.spyOn(fs, 'stat').mockResolvedValue({ mtime: new Date('2024-01-01T11:00:00.000Z') } as any)\n\n await expect(service.saveDocument(mockRequest)).rejects.toThrow(new HttpException({ LOOLStatusCode: 1010 }, HttpStatus.CONFLICT))\n })\n\n it('should throw error when document does not exist', async () => {\n const mockRequest = {\n user: mockUser,\n space: mockSpace,\n headers: {\n 'content-length': '1024'\n },\n raw: new Readable()\n } as unknown as FastifyCollaboraOnlineSpaceRequest\n\n jest.spyOn(filesUtils, 'isPathExists').mockResolvedValue(false)\n\n await expect(service.saveDocument(mockRequest)).rejects.toThrow(new HttpException('Document not found', HttpStatus.NOT_FOUND))\n })\n })\n\n describe('manageLock', () => {\n const mockReply = {\n header: jest.fn().mockReturnThis()\n } as unknown as FastifyReply\n\n describe('LOCK action', () => {\n it('should create a new lock', async () => {\n const mockRequest = {\n user: mockUser,\n space: mockSpace,\n headers: {\n [COLLABORA_HEADERS.Action]: COLLABORA_LOCK_ACTION.LOCK,\n [COLLABORA_HEADERS.LockToken]: 'new-lock-token'\n }\n } as unknown as FastifyCollaboraOnlineSpaceRequest\n\n jest.spyOn(filesLockManager, 'isLockedWithToken').mockResolvedValue(null)\n jest.spyOn(filesLockManager, 'create').mockResolvedValue([true, {} as any])\n\n await service.manageLock(mockRequest, mockReply)\n\n expect(filesLockManager.create).toHaveBeenCalledWith(\n mockUser,\n mockSpace.dbFile,\n COLLABORA_APP_LOCK,\n DEPTH.RESOURCE,\n expect.objectContaining({\n lockToken: 'new-lock-token',\n lockScope: LOCK_SCOPE.SHARED\n }),\n expect.any(Number)\n )\n })\n\n it('should refresh existing lock', async () => {\n const mockRequest = {\n user: mockUser,\n space: mockSpace,\n headers: {\n [COLLABORA_HEADERS.Action]: COLLABORA_LOCK_ACTION.LOCK,\n [COLLABORA_HEADERS.LockToken]: 'existing-lock-token'\n }\n } as unknown as FastifyCollaboraOnlineSpaceRequest\n\n const existingLock = { key: 'lock-key', options: { lockToken: 'existing-lock-token' } }\n jest.spyOn(filesLockManager, 'isLockedWithToken').mockResolvedValue(existingLock as any)\n jest.spyOn(filesLockManager, 'refreshLockTimeout').mockResolvedValue(undefined)\n\n await service.manageLock(mockRequest, mockReply)\n\n expect(filesLockManager.refreshLockTimeout).toHaveBeenCalledWith(existingLock, expect.any(Number))\n expect(filesLockManager.create).not.toHaveBeenCalled()\n })\n\n it('should throw conflict when lock creation fails', async () => {\n const mockRequest = {\n user: mockUser,\n space: mockSpace,\n headers: {\n [COLLABORA_HEADERS.Action]: COLLABORA_LOCK_ACTION.LOCK,\n [COLLABORA_HEADERS.LockToken]: 'new-lock-token'\n }\n } as unknown as FastifyCollaboraOnlineSpaceRequest\n\n const conflictingLock = { options: { lockToken: 'conflicting-token' } }\n jest.spyOn(filesLockManager, 'isLockedWithToken').mockResolvedValue(null)\n jest.spyOn(filesLockManager, 'create').mockResolvedValue([false, conflictingLock as any])\n\n await expect(service.manageLock(mockRequest, mockReply)).rejects.toThrow(new HttpException('The file is locked', HttpStatus.CONFLICT))\n expect(mockReply.header).toHaveBeenCalledWith(COLLABORA_HEADERS.LockToken, 'conflicting-token')\n })\n\n it('should throw error when lock token is missing', async () => {\n const mockRequest = {\n user: mockUser,\n space: mockSpace,\n headers: {\n [COLLABORA_HEADERS.Action]: COLLABORA_LOCK_ACTION.LOCK\n }\n } as unknown as FastifyCollaboraOnlineSpaceRequest\n\n await expect(service.manageLock(mockRequest, mockReply)).rejects.toThrow(new HttpException('Lock token is required', HttpStatus.CONFLICT))\n })\n })\n\n describe('UNLOCK action', () => {\n it('should remove existing lock', async () => {\n const mockRequest = {\n user: mockUser,\n space: mockSpace,\n headers: {\n [COLLABORA_HEADERS.Action]: COLLABORA_LOCK_ACTION.UNLOCK,\n [COLLABORA_HEADERS.LockToken]: 'lock-token-to-remove'\n }\n } as unknown as FastifyCollaboraOnlineSpaceRequest\n\n const existingLock = { key: 'lock-key', options: { lockToken: 'lock-token-to-remove' } }\n jest.spyOn(filesLockManager, 'isLockedWithToken').mockResolvedValue(existingLock as any)\n jest.spyOn(filesLockManager, 'removeLock').mockResolvedValue(undefined)\n\n await service.manageLock(mockRequest, mockReply)\n\n expect(filesLockManager.removeLock).toHaveBeenCalledWith('lock-key')\n })\n\n it('should throw error when lock does not exist', async () => {\n const mockRequest = {\n user: mockUser,\n space: mockSpace,\n headers: {\n [COLLABORA_HEADERS.Action]: COLLABORA_LOCK_ACTION.UNLOCK,\n [COLLABORA_HEADERS.LockToken]: 'non-existent-token'\n }\n } as unknown as FastifyCollaboraOnlineSpaceRequest\n\n jest.spyOn(filesLockManager, 'isLockedWithToken').mockResolvedValue(null)\n\n await expect(service.manageLock(mockRequest, mockReply)).rejects.toThrow(new HttpException('Lock not found', HttpStatus.CONFLICT))\n })\n })\n\n describe('GET_LOCK action', () => {\n it('should return lock token when lock exists', async () => {\n const mockRequest = {\n user: mockUser,\n space: mockSpace,\n headers: {\n [COLLABORA_HEADERS.Action]: COLLABORA_LOCK_ACTION.GET_LOCK\n }\n } as unknown as FastifyCollaboraOnlineSpaceRequest\n\n const existingLock = { options: { lockToken: 'existing-lock-token' } }\n jest.spyOn(filesLockManager, 'getLocksByPath').mockResolvedValue([existingLock as any])\n\n await service.manageLock(mockRequest, mockReply)\n\n expect(mockReply.header).toHaveBeenCalledWith(COLLABORA_HEADERS.LockToken, 'existing-lock-token')\n })\n\n it('should not set header when no lock exists', async () => {\n const mockRequest = {\n user: mockUser,\n space: mockSpace,\n headers: {\n [COLLABORA_HEADERS.Action]: COLLABORA_LOCK_ACTION.GET_LOCK\n }\n } as unknown as FastifyCollaboraOnlineSpaceRequest\n\n jest.spyOn(filesLockManager, 'getLocksByPath').mockResolvedValue([])\n\n await service.manageLock(mockRequest, mockReply)\n\n expect(mockReply.header).not.toHaveBeenCalled()\n })\n })\n\n describe('REFRESH_LOCK action', () => {\n it('should refresh existing lock', async () => {\n const mockRequest = {\n user: mockUser,\n space: mockSpace,\n headers: {\n [COLLABORA_HEADERS.Action]: COLLABORA_LOCK_ACTION.REFRESH_LOCK,\n [COLLABORA_HEADERS.LockToken]: 'lock-token-to-refresh'\n }\n } as unknown as FastifyCollaboraOnlineSpaceRequest\n\n const existingLock = { key: 'lock-key', options: { lockToken: 'lock-token-to-refresh' } }\n jest.spyOn(filesLockManager, 'isLockedWithToken').mockResolvedValue(existingLock as any)\n jest.spyOn(filesLockManager, 'refreshLockTimeout').mockResolvedValue(undefined)\n\n await service.manageLock(mockRequest, mockReply)\n\n expect(filesLockManager.refreshLockTimeout).toHaveBeenCalledWith(existingLock, expect.any(Number))\n })\n\n it('should throw error when lock does not exist', async () => {\n const mockRequest = {\n user: mockUser,\n space: mockSpace,\n headers: {\n [COLLABORA_HEADERS.Action]: COLLABORA_LOCK_ACTION.REFRESH_LOCK,\n [COLLABORA_HEADERS.LockToken]: 'non-existent-token'\n }\n } as unknown as FastifyCollaboraOnlineSpaceRequest\n\n jest.spyOn(filesLockManager, 'isLockedWithToken').mockResolvedValue(null)\n\n await expect(service.manageLock(mockRequest, mockReply)).rejects.toThrow(new HttpException('Lock not found', HttpStatus.CONFLICT))\n })\n })\n\n describe('Unknown action', () => {\n it('should throw error for unknown lock action', async () => {\n const mockRequest = {\n user: mockUser,\n space: mockSpace,\n headers: {\n [COLLABORA_HEADERS.Action]: 'UNKNOWN_ACTION'\n }\n } as unknown as FastifyCollaboraOnlineSpaceRequest\n\n await expect(service.manageLock(mockRequest, mockReply)).rejects.toThrow(new HttpException('Unknown lock action', HttpStatus.BAD_REQUEST))\n })\n })\n })\n})\n"],"names":["jest","mock","describe","CollaboraOnlineManager","name","service","filesLockManager","mockUser","id","login","email","fullName","language","role","applications","mockSpace","realPath","url","envPermissions","dbFile","path","ownerId","beforeEach","module","Test","createTestingModule","providers","provide","ContextManager","useValue","headerOriginUrl","fn","mockReturnValue","JwtService","signAsync","mockResolvedValue","FilesLockManager","checkConflicts","convertLockToFileLockProps","create","removeLock","getLocksByPath","isLockedWithToken","refreshLockTimeout","compile","useLogger","get","afterEach","clearAllMocks","it","expect","toBeDefined","spyOn","filesUtils","spaceWithPermissions","SPACE_OPERATION","MODIFY","undefined","result","getSettings","toEqual","documentServerUrl","stringContaining","mode","FILE_MODE","EDIT","hasLock","toHaveBeenCalledWith","DEPTH","RESOURCE","objectContaining","userId","app","COLLABORA_APP_LOCK","lockScope","LOCK_SCOPE","SHARED","mockLock","options","lockToken","mockFileLockProps","owner","isExclusive","mockRejectedValue","LockConflict","toBe","VIEW","spaceWithoutPermissions","not","toHaveBeenCalled","spaceWithUnsupportedFile","rejects","toThrow","HttpException","HttpStatus","BAD_REQUEST","NOT_FOUND","mockStats","size","mtime","Date","mockRequest","user","space","fs","getAvatarBase64","checkFileInfo","BaseFileName","Version","OwnerId","Size","LastModifiedTime","UserId","UserFriendlyName","ReadOnly","UserExtraInfo","avatar","UserCanNotWriteRelative","UserCanWrite","UserCanRename","SupportsUpdate","SupportsRename","SupportsExport","SupportsCoauth","SupportsLocks","SupportsGetLock","headers","raw","Readable","saveDocument","writeFromStream","copyFileContent","removeFiles","COLLABORA_HEADERS","Timestamp","LOOLStatusCode","CONFLICT","mockReply","header","mockReturnThis","Action","COLLABORA_LOCK_ACTION","LOCK","LockToken","manageLock","any","Number","existingLock","key","conflictingLock","UNLOCK","GET_LOCK","REFRESH_LOCK"],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ /*
2
+ * Copyright (C) 2012-2025 Johan Legrand <johan.legrand@sync-in.com>
3
+ * This file is part of Sync-in | The open source file sync and share solution
4
+ * See the LICENSE file for licensing details
5
+ */ "use strict";
6
+ Object.defineProperty(exports, "__esModule", {
7
+ value: true
8
+ });
9
+ Object.defineProperty(exports, "CollaboraOnlineConfig", {
10
+ enumerable: true,
11
+ get: function() {
12
+ return CollaboraOnlineConfig;
13
+ }
14
+ });
15
+ const _classvalidator = require("class-validator");
16
+ function _ts_decorate(decorators, target, key, desc) {
17
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
18
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
19
+ else for(var i = decorators.length - 1; i >= 0; i--)if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
20
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
21
+ }
22
+ function _ts_metadata(k, v) {
23
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
24
+ }
25
+ let CollaboraOnlineConfig = class CollaboraOnlineConfig {
26
+ constructor(){
27
+ this.enabled = false;
28
+ this.externalServer = null;
29
+ }
30
+ };
31
+ _ts_decorate([
32
+ (0, _classvalidator.IsBoolean)()
33
+ ], CollaboraOnlineConfig.prototype, "enabled", void 0);
34
+ _ts_decorate([
35
+ (0, _classvalidator.IsOptional)(),
36
+ (0, _classvalidator.IsString)(),
37
+ _ts_metadata("design:type", String)
38
+ ], CollaboraOnlineConfig.prototype, "externalServer", void 0);
39
+
40
+ //# sourceMappingURL=collabora-online.config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../backend/src/applications/files/modules/collabora-online/collabora-online.config.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 { IsBoolean, IsOptional, IsString } from 'class-validator'\n\nexport class CollaboraOnlineConfig {\n @IsBoolean()\n enabled = false\n\n @IsOptional()\n @IsString()\n externalServer: string = null\n}\n"],"names":["CollaboraOnlineConfig","enabled","externalServer"],"mappings":"AAAA;;;;CAIC;;;;+BAIYA;;;eAAAA;;;gCAFmC;;;;;;;;;;AAEzC,IAAA,AAAMA,wBAAN,MAAMA;;aAEXC,UAAU;aAIVC,iBAAyB;;AAC3B"}
@@ -0,0 +1,110 @@
1
+ /*
2
+ * Copyright (C) 2012-2025 Johan Legrand <johan.legrand@sync-in.com>
3
+ * This file is part of Sync-in | The open source file sync and share solution
4
+ * See the LICENSE file for licensing details
5
+ */ "use strict";
6
+ Object.defineProperty(exports, "__esModule", {
7
+ value: true
8
+ });
9
+ function _export(target, all) {
10
+ for(var name in all)Object.defineProperty(target, name, {
11
+ enumerable: true,
12
+ get: Object.getOwnPropertyDescriptor(all, name).get
13
+ });
14
+ }
15
+ _export(exports, {
16
+ get COLLABORA_APP_LOCK () {
17
+ return COLLABORA_APP_LOCK;
18
+ },
19
+ get COLLABORA_CONTEXT () {
20
+ return COLLABORA_CONTEXT;
21
+ },
22
+ get COLLABORA_HEADERS () {
23
+ return COLLABORA_HEADERS;
24
+ },
25
+ get COLLABORA_LOCK_ACTION () {
26
+ return COLLABORA_LOCK_ACTION;
27
+ },
28
+ get COLLABORA_ONLINE_EXTENSIONS () {
29
+ return COLLABORA_ONLINE_EXTENSIONS;
30
+ },
31
+ get COLLABORA_TOKEN_QUERY_PARAM_NAME () {
32
+ return COLLABORA_TOKEN_QUERY_PARAM_NAME;
33
+ },
34
+ get COLLABORA_URI () {
35
+ return COLLABORA_URI;
36
+ },
37
+ get COLLABORA_WOPI_SRC_QUERY_PARAM_NAME () {
38
+ return COLLABORA_WOPI_SRC_QUERY_PARAM_NAME;
39
+ }
40
+ });
41
+ const COLLABORA_URI = 'browser/dist/cool.html';
42
+ const COLLABORA_CONTEXT = 'CollaboraOnlineEnvironment';
43
+ const COLLABORA_WOPI_SRC_QUERY_PARAM_NAME = 'WOPISrc';
44
+ const COLLABORA_TOKEN_QUERY_PARAM_NAME = 'access_token';
45
+ const COLLABORA_APP_LOCK = 'Collabora';
46
+ const COLLABORA_HEADERS = {
47
+ Action: 'x-wopi-override',
48
+ LockToken: 'x-wopi-lock',
49
+ Timestamp: 'x-cool-wopi-timestamp'
50
+ };
51
+ var COLLABORA_LOCK_ACTION = /*#__PURE__*/ function(COLLABORA_LOCK_ACTION) {
52
+ COLLABORA_LOCK_ACTION["LOCK"] = "LOCK";
53
+ COLLABORA_LOCK_ACTION["UNLOCK"] = "UNLOCK";
54
+ COLLABORA_LOCK_ACTION["GET_LOCK"] = "GET_LOCK";
55
+ COLLABORA_LOCK_ACTION["REFRESH_LOCK"] = "REFRESH_LOCK";
56
+ return COLLABORA_LOCK_ACTION;
57
+ }({});
58
+ const COLLABORA_ONLINE_EXTENSIONS = new Set([
59
+ // ─────────────
60
+ // WORD (Writer)
61
+ // ─────────────
62
+ 'doc',
63
+ 'docx',
64
+ 'docm',
65
+ 'dot',
66
+ 'dotx',
67
+ 'dotm',
68
+ 'odt',
69
+ 'ott',
70
+ 'rtf',
71
+ 'fodt',
72
+ // StarOffice / legacy
73
+ 'sxw',
74
+ 'stw',
75
+ // ─────────────
76
+ // CELL (Calc)
77
+ // ─────────────
78
+ 'xls',
79
+ 'xlsx',
80
+ 'xlsm',
81
+ 'xlt',
82
+ 'xltx',
83
+ 'ods',
84
+ 'ots',
85
+ 'csv',
86
+ 'fods',
87
+ // StarOffice
88
+ 'sxc',
89
+ 'sdc',
90
+ // ─────────────
91
+ // SLIDE (Impress)
92
+ // ─────────────
93
+ 'ppt',
94
+ 'pptx',
95
+ 'pptm',
96
+ 'pps',
97
+ 'ppsx',
98
+ 'odp',
99
+ 'otp',
100
+ 'fodp',
101
+ // StarOffice
102
+ 'sxi',
103
+ 'sdd',
104
+ // ─────────────
105
+ // DRAW / DIAGRAM
106
+ // ─────────────
107
+ 'odg'
108
+ ]);
109
+
110
+ //# sourceMappingURL=collabora-online.constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../backend/src/applications/files/modules/collabora-online/collabora-online.constants.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\nexport const COLLABORA_URI = 'browser/dist/cool.html'\nexport const COLLABORA_CONTEXT = 'CollaboraOnlineEnvironment' as const\nexport const COLLABORA_WOPI_SRC_QUERY_PARAM_NAME = 'WOPISrc' as const\nexport const COLLABORA_TOKEN_QUERY_PARAM_NAME = 'access_token' as const\nexport const COLLABORA_APP_LOCK = 'Collabora' as const\n\nexport const COLLABORA_HEADERS = {\n Action: 'x-wopi-override',\n LockToken: 'x-wopi-lock',\n Timestamp: 'x-cool-wopi-timestamp'\n} as const\n\nexport enum COLLABORA_LOCK_ACTION {\n LOCK = 'LOCK',\n UNLOCK = 'UNLOCK',\n GET_LOCK = 'GET_LOCK',\n REFRESH_LOCK = 'REFRESH_LOCK'\n}\n\nexport const COLLABORA_ONLINE_EXTENSIONS = new Set<string>([\n // ─────────────\n // WORD (Writer)\n // ─────────────\n 'doc',\n 'docx',\n 'docm',\n 'dot',\n 'dotx',\n 'dotm',\n 'odt',\n 'ott',\n 'rtf',\n 'fodt',\n\n // StarOffice / legacy\n 'sxw',\n 'stw',\n\n // ─────────────\n // CELL (Calc)\n // ─────────────\n 'xls',\n 'xlsx',\n 'xlsm',\n 'xlt',\n 'xltx',\n 'ods',\n 'ots',\n 'csv',\n 'fods',\n\n // StarOffice\n 'sxc',\n 'sdc',\n\n // ─────────────\n // SLIDE (Impress)\n // ─────────────\n 'ppt',\n 'pptx',\n 'pptm',\n 'pps',\n 'ppsx',\n 'odp',\n 'otp',\n 'fodp',\n\n // StarOffice\n 'sxi',\n 'sdd',\n\n // ─────────────\n // DRAW / DIAGRAM\n // ─────────────\n 'odg'\n])\n"],"names":["COLLABORA_APP_LOCK","COLLABORA_CONTEXT","COLLABORA_HEADERS","COLLABORA_LOCK_ACTION","COLLABORA_ONLINE_EXTENSIONS","COLLABORA_TOKEN_QUERY_PARAM_NAME","COLLABORA_URI","COLLABORA_WOPI_SRC_QUERY_PARAM_NAME","Action","LockToken","Timestamp","Set"],"mappings":"AAAA;;;;CAIC;;;;;;;;;;;QAMYA;eAAAA;;QAHAC;eAAAA;;QAKAC;eAAAA;;QAMDC;eAAAA;;QAOCC;eAAAA;;QAhBAC;eAAAA;;QAHAC;eAAAA;;QAEAC;eAAAA;;;AAFN,MAAMD,gBAAgB;AACtB,MAAML,oBAAoB;AAC1B,MAAMM,sCAAsC;AAC5C,MAAMF,mCAAmC;AACzC,MAAML,qBAAqB;AAE3B,MAAME,oBAAoB;IAC/BM,QAAQ;IACRC,WAAW;IACXC,WAAW;AACb;AAEO,IAAA,AAAKP,+CAAAA;;;;;WAAAA;;AAOL,MAAMC,8BAA8B,IAAIO,IAAY;IACzD,gBAAgB;IAChB,gBAAgB;IAChB,gBAAgB;IAChB;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IAEA,sBAAsB;IACtB;IACA;IAEA,gBAAgB;IAChB,cAAc;IACd,gBAAgB;IAChB;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IAEA,aAAa;IACb;IACA;IAEA,gBAAgB;IAChB,kBAAkB;IAClB,gBAAgB;IAChB;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IAEA,aAAa;IACb;IACA;IAEA,gBAAgB;IAChB,iBAAiB;IACjB,gBAAgB;IAChB;CACD"}
@@ -0,0 +1,128 @@
1
+ /*
2
+ * Copyright (C) 2012-2025 Johan Legrand <johan.legrand@sync-in.com>
3
+ * This file is part of Sync-in | The open source file sync and share solution
4
+ * See the LICENSE file for licensing details
5
+ */ "use strict";
6
+ Object.defineProperty(exports, "__esModule", {
7
+ value: true
8
+ });
9
+ Object.defineProperty(exports, "CollaboraOnlineController", {
10
+ enumerable: true,
11
+ get: function() {
12
+ return CollaboraOnlineController;
13
+ }
14
+ });
15
+ const _common = require("@nestjs/common");
16
+ const _fastify = require("fastify");
17
+ const _contextinterceptor = require("../../../../infrastructure/context/interceptors/context.interceptor");
18
+ const _spaces = require("../../../spaces/constants/spaces");
19
+ const _spaceoverridepermissiondecorator = require("../../../spaces/decorators/space-override-permission.decorator");
20
+ const _spacerequestinterface = require("../../../spaces/interfaces/space-request.interface");
21
+ const _filesmethodsservice = require("../../services/files-methods.service");
22
+ const _collaboraonlineenvironmentdecorator = require("./collabora-online-environment.decorator");
23
+ const _collaboraonlinemanagerservice = require("./collabora-online-manager.service");
24
+ const _collaboraonlineroutes = require("./collabora-online.routes");
25
+ function _ts_decorate(decorators, target, key, desc) {
26
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
27
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
28
+ else for(var i = decorators.length - 1; i >= 0; i--)if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
29
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
30
+ }
31
+ function _ts_metadata(k, v) {
32
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
33
+ }
34
+ function _ts_param(paramIndex, decorator) {
35
+ return function(target, key) {
36
+ decorator(target, key, paramIndex);
37
+ };
38
+ }
39
+ let CollaboraOnlineController = class CollaboraOnlineController {
40
+ collaboraOnlineSettings(req) {
41
+ return this.filesCollaboraOnlineService.getSettings(req.user, req.space);
42
+ }
43
+ collaboraOnlineGetDocumentContent(req, res) {
44
+ return this.filesMethods.headOrGet(req, res);
45
+ }
46
+ collaboraOnlineGetDocumentInfo(req) {
47
+ return this.filesCollaboraOnlineService.checkFileInfo(req);
48
+ }
49
+ collaboraOnlineSaveDocument(req) {
50
+ return this.filesCollaboraOnlineService.saveDocument(req);
51
+ }
52
+ collaboraOnlineManageLockOnDocument(req, res) {
53
+ return this.filesCollaboraOnlineService.manageLock(req, res);
54
+ }
55
+ constructor(filesMethods, filesCollaboraOnlineService){
56
+ this.filesMethods = filesMethods;
57
+ this.filesCollaboraOnlineService = filesCollaboraOnlineService;
58
+ }
59
+ };
60
+ _ts_decorate([
61
+ (0, _common.Get)(`${_collaboraonlineroutes.COLLABORA_ONLINE_ROUTE.SETTINGS}/*`),
62
+ (0, _common.UseInterceptors)(_contextinterceptor.ContextInterceptor),
63
+ _ts_param(0, (0, _common.Request)()),
64
+ _ts_metadata("design:type", Function),
65
+ _ts_metadata("design:paramtypes", [
66
+ typeof _spacerequestinterface.FastifySpaceRequest === "undefined" ? Object : _spacerequestinterface.FastifySpaceRequest
67
+ ]),
68
+ _ts_metadata("design:returntype", typeof Promise === "undefined" ? Object : Promise)
69
+ ], CollaboraOnlineController.prototype, "collaboraOnlineSettings", null);
70
+ _ts_decorate([
71
+ (0, _common.Get)(`${_collaboraonlineroutes.COLLABORA_ONLINE_ROUTE.FILES}/:dbFileHash/${_collaboraonlineroutes.COLLABORA_ONLINE_ROUTE.CONTENTS}`),
72
+ _ts_param(0, (0, _common.Request)()),
73
+ _ts_param(1, (0, _common.Res)({
74
+ passthrough: true
75
+ })),
76
+ _ts_metadata("design:type", Function),
77
+ _ts_metadata("design:paramtypes", [
78
+ typeof _spacerequestinterface.FastifySpaceRequest === "undefined" ? Object : _spacerequestinterface.FastifySpaceRequest,
79
+ typeof _fastify.FastifyReply === "undefined" ? Object : _fastify.FastifyReply
80
+ ]),
81
+ _ts_metadata("design:returntype", typeof Promise === "undefined" ? Object : Promise)
82
+ ], CollaboraOnlineController.prototype, "collaboraOnlineGetDocumentContent", null);
83
+ _ts_decorate([
84
+ (0, _common.Get)(`${_collaboraonlineroutes.COLLABORA_ONLINE_ROUTE.FILES}/:dbFileHash`),
85
+ _ts_param(0, (0, _common.Request)()),
86
+ _ts_metadata("design:type", Function),
87
+ _ts_metadata("design:paramtypes", [
88
+ typeof _spacerequestinterface.FastifySpaceRequest === "undefined" ? Object : _spacerequestinterface.FastifySpaceRequest
89
+ ]),
90
+ _ts_metadata("design:returntype", typeof Promise === "undefined" ? Object : Promise)
91
+ ], CollaboraOnlineController.prototype, "collaboraOnlineGetDocumentInfo", null);
92
+ _ts_decorate([
93
+ (0, _common.Post)(`${_collaboraonlineroutes.COLLABORA_ONLINE_ROUTE.FILES}/:dbFileHash/${_collaboraonlineroutes.COLLABORA_ONLINE_ROUTE.CONTENTS}`),
94
+ (0, _spaceoverridepermissiondecorator.OverrideSpacePermission)(_spaces.SPACE_OPERATION.MODIFY),
95
+ (0, _common.HttpCode)(_common.HttpStatus.OK),
96
+ _ts_param(0, (0, _common.Request)()),
97
+ _ts_metadata("design:type", Function),
98
+ _ts_metadata("design:paramtypes", [
99
+ typeof _spacerequestinterface.FastifySpaceRequest === "undefined" ? Object : _spacerequestinterface.FastifySpaceRequest
100
+ ]),
101
+ _ts_metadata("design:returntype", typeof Promise === "undefined" ? Object : Promise)
102
+ ], CollaboraOnlineController.prototype, "collaboraOnlineSaveDocument", null);
103
+ _ts_decorate([
104
+ (0, _common.Post)(`${_collaboraonlineroutes.COLLABORA_ONLINE_ROUTE.FILES}/:dbFileHash`),
105
+ (0, _spaceoverridepermissiondecorator.OverrideSpacePermission)(_spaces.SPACE_OPERATION.MODIFY),
106
+ (0, _common.HttpCode)(_common.HttpStatus.OK),
107
+ _ts_param(0, (0, _common.Request)()),
108
+ _ts_param(1, (0, _common.Res)({
109
+ passthrough: true
110
+ })),
111
+ _ts_metadata("design:type", Function),
112
+ _ts_metadata("design:paramtypes", [
113
+ typeof _spacerequestinterface.FastifySpaceRequest === "undefined" ? Object : _spacerequestinterface.FastifySpaceRequest,
114
+ typeof _fastify.FastifyReply === "undefined" ? Object : _fastify.FastifyReply
115
+ ]),
116
+ _ts_metadata("design:returntype", typeof Promise === "undefined" ? Object : Promise)
117
+ ], CollaboraOnlineController.prototype, "collaboraOnlineManageLockOnDocument", null);
118
+ CollaboraOnlineController = _ts_decorate([
119
+ (0, _common.Controller)(_collaboraonlineroutes.COLLABORA_ONLINE_ROUTE.BASE),
120
+ (0, _collaboraonlineenvironmentdecorator.CollaboraOnlineEnvironment)(),
121
+ _ts_metadata("design:type", Function),
122
+ _ts_metadata("design:paramtypes", [
123
+ typeof _filesmethodsservice.FilesMethods === "undefined" ? Object : _filesmethodsservice.FilesMethods,
124
+ typeof _collaboraonlinemanagerservice.CollaboraOnlineManager === "undefined" ? Object : _collaboraonlinemanagerservice.CollaboraOnlineManager
125
+ ])
126
+ ], CollaboraOnlineController);
127
+
128
+ //# sourceMappingURL=collabora-online.controller.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../backend/src/applications/files/modules/collabora-online/collabora-online.controller.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 { Controller, Get, HttpCode, HttpStatus, Post, Request, Res, StreamableFile, UseInterceptors } from '@nestjs/common'\nimport { FastifyReply } from 'fastify'\nimport { ContextInterceptor } from '../../../../infrastructure/context/interceptors/context.interceptor'\nimport { SPACE_OPERATION } from '../../../spaces/constants/spaces'\nimport { OverrideSpacePermission } from '../../../spaces/decorators/space-override-permission.decorator'\nimport { FastifySpaceRequest } from '../../../spaces/interfaces/space-request.interface'\nimport { FilesMethods } from '../../services/files-methods.service'\nimport { CollaboraOnlineEnvironment } from './collabora-online-environment.decorator'\nimport { CollaboraOnlineManager } from './collabora-online-manager.service'\nimport { CollaboraOnlineReqDto, CollaboraSaveDocumentDto } from './collabora-online.dtos'\nimport type { CollaboraOnlineCheckFileInfo } from './collabora-online.interface'\nimport { COLLABORA_ONLINE_ROUTE } from './collabora-online.routes'\n\n@Controller(COLLABORA_ONLINE_ROUTE.BASE)\n@CollaboraOnlineEnvironment()\nexport class CollaboraOnlineController {\n constructor(\n private readonly filesMethods: FilesMethods,\n private readonly filesCollaboraOnlineService: CollaboraOnlineManager\n ) {}\n\n @Get(`${COLLABORA_ONLINE_ROUTE.SETTINGS}/*`)\n @UseInterceptors(ContextInterceptor)\n collaboraOnlineSettings(@Request() req: FastifySpaceRequest): Promise<CollaboraOnlineReqDto> {\n return this.filesCollaboraOnlineService.getSettings(req.user, req.space)\n }\n\n @Get(`${COLLABORA_ONLINE_ROUTE.FILES}/:dbFileHash/${COLLABORA_ONLINE_ROUTE.CONTENTS}`)\n collaboraOnlineGetDocumentContent(\n @Request() req: FastifySpaceRequest,\n @Res({ passthrough: true }) res: FastifyReply\n ): Promise<StreamableFile | CollaboraOnlineCheckFileInfo> {\n return this.filesMethods.headOrGet(req, res)\n }\n\n @Get(`${COLLABORA_ONLINE_ROUTE.FILES}/:dbFileHash`)\n collaboraOnlineGetDocumentInfo(@Request() req: FastifySpaceRequest): Promise<StreamableFile | CollaboraOnlineCheckFileInfo> {\n return this.filesCollaboraOnlineService.checkFileInfo(req)\n }\n\n @Post(`${COLLABORA_ONLINE_ROUTE.FILES}/:dbFileHash/${COLLABORA_ONLINE_ROUTE.CONTENTS}`)\n @OverrideSpacePermission(SPACE_OPERATION.MODIFY)\n @HttpCode(HttpStatus.OK)\n collaboraOnlineSaveDocument(@Request() req: FastifySpaceRequest): Promise<CollaboraSaveDocumentDto> {\n return this.filesCollaboraOnlineService.saveDocument(req)\n }\n\n @Post(`${COLLABORA_ONLINE_ROUTE.FILES}/:dbFileHash`)\n @OverrideSpacePermission(SPACE_OPERATION.MODIFY)\n @HttpCode(HttpStatus.OK)\n collaboraOnlineManageLockOnDocument(@Request() req: FastifySpaceRequest, @Res({ passthrough: true }) res: FastifyReply): Promise<void> {\n return this.filesCollaboraOnlineService.manageLock(req, res)\n }\n}\n"],"names":["CollaboraOnlineController","collaboraOnlineSettings","req","filesCollaboraOnlineService","getSettings","user","space","collaboraOnlineGetDocumentContent","res","filesMethods","headOrGet","collaboraOnlineGetDocumentInfo","checkFileInfo","collaboraOnlineSaveDocument","saveDocument","collaboraOnlineManageLockOnDocument","manageLock","COLLABORA_ONLINE_ROUTE","SETTINGS","FILES","CONTENTS","passthrough","MODIFY","OK","BASE"],"mappings":"AAAA;;;;CAIC;;;;+BAiBYA;;;eAAAA;;;wBAf8F;yBAC9E;oCACM;wBACH;kDACQ;uCACJ;qCACP;qDACc;+CACJ;uCAGA;;;;;;;;;;;;;;;AAIhC,IAAA,AAAMA,4BAAN,MAAMA;IAQXC,wBAAwB,AAAWC,GAAwB,EAAkC;QAC3F,OAAO,IAAI,CAACC,2BAA2B,CAACC,WAAW,CAACF,IAAIG,IAAI,EAAEH,IAAII,KAAK;IACzE;IAGAC,kCACE,AAAWL,GAAwB,EACnC,AAA4BM,GAAiB,EACW;QACxD,OAAO,IAAI,CAACC,YAAY,CAACC,SAAS,CAACR,KAAKM;IAC1C;IAGAG,+BAA+B,AAAWT,GAAwB,EAA0D;QAC1H,OAAO,IAAI,CAACC,2BAA2B,CAACS,aAAa,CAACV;IACxD;IAKAW,4BAA4B,AAAWX,GAAwB,EAAqC;QAClG,OAAO,IAAI,CAACC,2BAA2B,CAACW,YAAY,CAACZ;IACvD;IAKAa,oCAAoC,AAAWb,GAAwB,EAAE,AAA4BM,GAAiB,EAAiB;QACrI,OAAO,IAAI,CAACL,2BAA2B,CAACa,UAAU,CAACd,KAAKM;IAC1D;IApCA,YACE,AAAiBC,YAA0B,EAC3C,AAAiBN,2BAAmD,CACpE;aAFiBM,eAAAA;aACAN,8BAAAA;IAChB;AAkCL;;wBAhCUc,6CAAsB,CAACC,QAAQ,CAAC,EAAE;;;;;;;;;;wBAMlCD,6CAAsB,CAACE,KAAK,CAAC,aAAa,EAAEF,6CAAsB,CAACG,QAAQ;;;QAG1EC,aAAa;;;;;;;;;;wBAKdJ,6CAAsB,CAACE,KAAK,CAAC,YAAY;;;;;;;;;yBAKxCF,6CAAsB,CAACE,KAAK,CAAC,aAAa,EAAEF,6CAAsB,CAACG,QAAQ;2FAC3CE;6CACpBC;;;;;;;;;yBAKZN,6CAAsB,CAACE,KAAK,CAAC,YAAY;2FACTG;6CACpBC;;;QAC2DF,aAAa;;;;;;;;;;0EArC5DG"}
@@ -0,0 +1,47 @@
1
+ /*
2
+ * Copyright (C) 2012-2025 Johan Legrand <johan.legrand@sync-in.com>
3
+ * This file is part of Sync-in | The open source file sync and share solution
4
+ * See the LICENSE file for licensing details
5
+ */ "use strict";
6
+ Object.defineProperty(exports, "__esModule", {
7
+ value: true
8
+ });
9
+ const _testing = require("@nestjs/testing");
10
+ const _contextinterceptor = require("../../../../infrastructure/context/interceptors/context.interceptor");
11
+ const _contextmanagerservice = require("../../../../infrastructure/context/services/context-manager.service");
12
+ const _spacesmanagerservice = require("../../../spaces/services/spaces-manager.service");
13
+ const _filesmethodsservice = require("../../services/files-methods.service");
14
+ const _collaboraonlinemanagerservice = require("./collabora-online-manager.service");
15
+ const _collaboraonlinecontroller = require("./collabora-online.controller");
16
+ describe(_collaboraonlinecontroller.CollaboraOnlineController.name, ()=>{
17
+ let controller;
18
+ beforeAll(async ()=>{
19
+ const module = await _testing.Test.createTestingModule({
20
+ controllers: [
21
+ _collaboraonlinecontroller.CollaboraOnlineController
22
+ ],
23
+ providers: [
24
+ _contextmanagerservice.ContextManager,
25
+ _contextinterceptor.ContextInterceptor,
26
+ {
27
+ provide: _collaboraonlinemanagerservice.CollaboraOnlineManager,
28
+ useValue: {}
29
+ },
30
+ {
31
+ provide: _filesmethodsservice.FilesMethods,
32
+ useValue: {}
33
+ },
34
+ {
35
+ provide: _spacesmanagerservice.SpacesManager,
36
+ useValue: {}
37
+ }
38
+ ]
39
+ }).compile();
40
+ controller = module.get(_collaboraonlinecontroller.CollaboraOnlineController);
41
+ });
42
+ it('should be defined', ()=>{
43
+ expect(controller).toBeDefined();
44
+ });
45
+ });
46
+
47
+ //# sourceMappingURL=collabora-online.controller.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../backend/src/applications/files/modules/collabora-online/collabora-online.controller.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 { Test, TestingModule } from '@nestjs/testing'\nimport { ContextInterceptor } from '../../../../infrastructure/context/interceptors/context.interceptor'\nimport { ContextManager } from '../../../../infrastructure/context/services/context-manager.service'\nimport { SpacesManager } from '../../../spaces/services/spaces-manager.service'\nimport { FilesMethods } from '../../services/files-methods.service'\nimport { CollaboraOnlineManager } from './collabora-online-manager.service'\nimport { CollaboraOnlineController } from './collabora-online.controller'\n\ndescribe(CollaboraOnlineController.name, () => {\n let controller: CollaboraOnlineController\n\n beforeAll(async () => {\n const module: TestingModule = await Test.createTestingModule({\n controllers: [CollaboraOnlineController],\n providers: [\n ContextManager,\n ContextInterceptor,\n { provide: CollaboraOnlineManager, useValue: {} },\n { provide: FilesMethods, useValue: {} },\n { provide: SpacesManager, useValue: {} }\n ]\n }).compile()\n\n controller = module.get<CollaboraOnlineController>(CollaboraOnlineController)\n })\n\n it('should be defined', () => {\n expect(controller).toBeDefined()\n })\n})\n"],"names":["describe","CollaboraOnlineController","name","controller","beforeAll","module","Test","createTestingModule","controllers","providers","ContextManager","ContextInterceptor","provide","CollaboraOnlineManager","useValue","FilesMethods","SpacesManager","compile","get","it","expect","toBeDefined"],"mappings":"AAAA;;;;CAIC;;;;yBAEmC;oCACD;uCACJ;sCACD;qCACD;+CACU;2CACG;AAE1CA,SAASC,oDAAyB,CAACC,IAAI,EAAE;IACvC,IAAIC;IAEJC,UAAU;QACR,MAAMC,SAAwB,MAAMC,aAAI,CAACC,mBAAmB,CAAC;YAC3DC,aAAa;gBAACP,oDAAyB;aAAC;YACxCQ,WAAW;gBACTC,qCAAc;gBACdC,sCAAkB;gBAClB;oBAAEC,SAASC,qDAAsB;oBAAEC,UAAU,CAAC;gBAAE;gBAChD;oBAAEF,SAASG,iCAAY;oBAAED,UAAU,CAAC;gBAAE;gBACtC;oBAAEF,SAASI,mCAAa;oBAAEF,UAAU,CAAC;gBAAE;aACxC;QACH,GAAGG,OAAO;QAEVd,aAAaE,OAAOa,GAAG,CAA4BjB,oDAAyB;IAC9E;IAEAkB,GAAG,qBAAqB;QACtBC,OAAOjB,YAAYkB,WAAW;IAChC;AACF"}
@@ -7,4 +7,4 @@ Object.defineProperty(exports, "__esModule", {
7
7
  value: true
8
8
  });
9
9
 
10
- //# sourceMappingURL=only-office-config.interface.js.map
10
+ //# sourceMappingURL=collabora-online.dtos.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../backend/src/applications/files/modules/collabora-online/collabora-online.dtos.ts"],"sourcesContent":["/*\n * Copyright (C) 2012-2025 Johan Legrand <johan.legrand@sync-in.com>\n * This file is part of Sync-in | The open source file sync and share solution\n * See the LICENSE file for licensing details\n */\n\nimport type { FILE_MODE } from '../../constants/operations'\nimport type { FileLockProps } from '../../interfaces/file-props.interface'\n\nexport interface CollaboraOnlineReqDto {\n documentServerUrl: string\n mode: FILE_MODE\n hasLock: false | FileLockProps\n}\n\nexport interface CollaboraSaveDocumentDto {\n LastModifiedTime: string\n}\n"],"names":[],"mappings":"AAAA;;;;CAIC"}
@@ -6,35 +6,21 @@
6
6
  Object.defineProperty(exports, "__esModule", {
7
7
  value: true
8
8
  });
9
- Object.defineProperty(exports, "FilesOnlyOfficeGuard", {
9
+ Object.defineProperty(exports, "CollaboraOnlineGuard", {
10
10
  enumerable: true,
11
11
  get: function() {
12
- return FilesOnlyOfficeGuard;
12
+ return CollaboraOnlineGuard;
13
13
  }
14
14
  });
15
15
  const _common = require("@nestjs/common");
16
16
  const _passport = require("@nestjs/passport");
17
- const _configenvironment = require("../../../configuration/config.environment");
18
- const _routes = require("../constants/routes");
19
17
  function _ts_decorate(decorators, target, key, desc) {
20
18
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
21
19
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
22
20
  else for(var i = decorators.length - 1; i >= 0; i--)if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
23
21
  return c > 3 && r && Object.defineProperty(target, key, r), r;
24
22
  }
25
- let FilesOnlyOfficeGuard = class FilesOnlyOfficeGuard extends (0, _passport.AuthGuard)('filesOnlyOfficeToken') {
26
- canActivate(ctx) {
27
- const req = ctx.switchToHttp().getRequest();
28
- if (req.originalUrl === _routes.API_FILES_ONLY_OFFICE_STATUS) {
29
- // Skip token validation for the status endpoint
30
- return true;
31
- }
32
- if (!_configenvironment.configuration.applications.files.onlyoffice.enabled) {
33
- this.logger.warn(`${this.canActivate.name} - feature not enabled`);
34
- throw new _common.HttpException('Feature not enabled', _common.HttpStatus.BAD_REQUEST);
35
- }
36
- return super.canActivate(ctx);
37
- }
23
+ let CollaboraOnlineGuard = class CollaboraOnlineGuard extends (0, _passport.AuthGuard)('filesCollaboraOnlineToken') {
38
24
  handleRequest(err, user, info, ctx, status) {
39
25
  const req = this.getRequest(ctx);
40
26
  req.raw.user = user?.login || 'unauthorized';
@@ -44,11 +30,11 @@ let FilesOnlyOfficeGuard = class FilesOnlyOfficeGuard extends (0, _passport.Auth
44
30
  return super.handleRequest(err, user, info, ctx, status);
45
31
  }
46
32
  constructor(...args){
47
- super(...args), this.logger = new _common.Logger(FilesOnlyOfficeGuard.name);
33
+ super(...args), this.logger = new _common.Logger(CollaboraOnlineGuard.name);
48
34
  }
49
35
  };
50
- FilesOnlyOfficeGuard = _ts_decorate([
36
+ CollaboraOnlineGuard = _ts_decorate([
51
37
  (0, _common.Injectable)()
52
- ], FilesOnlyOfficeGuard);
38
+ ], CollaboraOnlineGuard);
53
39
 
54
- //# sourceMappingURL=files-only-office.guard.js.map
40
+ //# sourceMappingURL=collabora-online.guard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../backend/src/applications/files/modules/collabora-online/collabora-online.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 { ExecutionContext, Injectable, Logger } from '@nestjs/common'\nimport { AuthGuard, IAuthGuard } from '@nestjs/passport'\n\n@Injectable()\nexport class CollaboraOnlineGuard extends AuthGuard('filesCollaboraOnlineToken') implements IAuthGuard {\n private readonly logger = new Logger(CollaboraOnlineGuard.name)\n\n handleRequest<TUser = any>(err: any, user: any, info: Error, ctx: ExecutionContext, status?: any): TUser {\n const req = this.getRequest(ctx)\n req.raw.user = user?.login || 'unauthorized'\n if (info) {\n this.logger.warn(`<${req.raw.user}> <${req.ip}> ${info}`)\n }\n return super.handleRequest(err, user, info, ctx, status)\n }\n}\n"],"names":["CollaboraOnlineGuard","AuthGuard","handleRequest","err","user","info","ctx","status","req","getRequest","raw","login","logger","warn","ip","Logger","name"],"mappings":"AAAA;;;;CAIC;;;;+BAMYA;;;eAAAA;;;wBAJwC;0BACf;;;;;;;AAG/B,IAAA,AAAMA,uBAAN,MAAMA,6BAA6BC,IAAAA,mBAAS,EAAC;IAGlDC,cAA2BC,GAAQ,EAAEC,IAAS,EAAEC,IAAW,EAAEC,GAAqB,EAAEC,MAAY,EAAS;QACvG,MAAMC,MAAM,IAAI,CAACC,UAAU,CAACH;QAC5BE,IAAIE,GAAG,CAACN,IAAI,GAAGA,MAAMO,SAAS;QAC9B,IAAIN,MAAM;YACR,IAAI,CAACO,MAAM,CAACC,IAAI,CAAC,CAAC,CAAC,EAAEL,IAAIE,GAAG,CAACN,IAAI,CAAC,GAAG,EAAEI,IAAIM,EAAE,CAAC,EAAE,EAAET,MAAM;QAC1D;QACA,OAAO,KAAK,CAACH,cAAcC,KAAKC,MAAMC,MAAMC,KAAKC;IACnD;;QAVK,qBACYK,SAAS,IAAIG,cAAM,CAACf,qBAAqBgB,IAAI;;AAUhE"}
@@ -0,0 +1,86 @@
1
+ /*
2
+ * Copyright (C) 2012-2025 Johan Legrand <johan.legrand@sync-in.com>
3
+ * This file is part of Sync-in | The open source file sync and share solution
4
+ * See the LICENSE file for licensing details
5
+ */ "use strict";
6
+ Object.defineProperty(exports, "__esModule", {
7
+ value: true
8
+ });
9
+ const _tsjest = require("@golevelup/ts-jest");
10
+ const _jwt = require("@nestjs/jwt");
11
+ const _testing = require("@nestjs/testing");
12
+ const _nestjspino = require("nestjs-pino");
13
+ const _configenvironment = require("../../../../configuration/config.environment");
14
+ const _collaboraonlineconstants = require("./collabora-online.constants");
15
+ const _collaboraonlineguard = require("./collabora-online.guard");
16
+ const _collaboraonlineroutes = require("./collabora-online.routes");
17
+ const _collaboraonlinestrategy = require("./collabora-online.strategy");
18
+ describe(_collaboraonlineguard.CollaboraOnlineGuard.name, ()=>{
19
+ let jwtService;
20
+ let filesCollaboraGuard;
21
+ let context;
22
+ let accessToken;
23
+ beforeAll(async ()=>{
24
+ const module = await _testing.Test.createTestingModule({
25
+ imports: [
26
+ _jwt.JwtModule.register({
27
+ global: true
28
+ })
29
+ ],
30
+ providers: [
31
+ _collaboraonlineguard.CollaboraOnlineGuard,
32
+ _collaboraonlinestrategy.CollaboraOnlineStrategy,
33
+ {
34
+ provide: _nestjspino.PinoLogger,
35
+ useValue: {
36
+ assign: ()=>undefined
37
+ }
38
+ }
39
+ ]
40
+ }).compile();
41
+ jwtService = module.get(_jwt.JwtService);
42
+ filesCollaboraGuard = module.get(_collaboraonlineguard.CollaboraOnlineGuard);
43
+ context = (0, _tsjest.createMock)();
44
+ accessToken = await jwtService.signAsync({
45
+ identity: {
46
+ id: 1,
47
+ login: 'foo'
48
+ }
49
+ }, {
50
+ secret: _configenvironment.configuration.auth.token.access.secret,
51
+ expiresIn: 30
52
+ });
53
+ });
54
+ it('should be defined', ()=>{
55
+ expect(jwtService).toBeDefined();
56
+ expect(filesCollaboraGuard).toBeDefined();
57
+ expect(accessToken).toBeDefined();
58
+ });
59
+ it('should not pass without a valid token', async ()=>{
60
+ context.switchToHttp().getRequest.mockReturnValue({
61
+ url: `${_collaboraonlineroutes.API_COLLABORA_ONLINE_FILES}`,
62
+ raw: {
63
+ user: ''
64
+ }
65
+ });
66
+ await expect(filesCollaboraGuard.canActivate(context)).rejects.toThrow('Unauthorized');
67
+ });
68
+ it('should pass with a (un)valid token', async ()=>{
69
+ context.switchToHttp().getRequest.mockReturnValue({
70
+ url: `${_collaboraonlineroutes.API_COLLABORA_ONLINE_FILES}?${_collaboraonlineconstants.COLLABORA_TOKEN_QUERY_PARAM_NAME}=${accessToken}`,
71
+ raw: {
72
+ user: ''
73
+ }
74
+ });
75
+ expect(await filesCollaboraGuard.canActivate(context)).toBe(true);
76
+ context.switchToHttp().getRequest.mockReturnValue({
77
+ url: `${_collaboraonlineroutes.API_COLLABORA_ONLINE_FILES}?${_collaboraonlineconstants.COLLABORA_TOKEN_QUERY_PARAM_NAME}=unvalidToken`,
78
+ raw: {
79
+ user: ''
80
+ }
81
+ });
82
+ await expect(filesCollaboraGuard.canActivate(context)).rejects.toThrow('Unauthorized');
83
+ });
84
+ });
85
+
86
+ //# sourceMappingURL=collabora-online.guard.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../backend/src/applications/files/modules/collabora-online/collabora-online.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 } from '@nestjs/common'\nimport { JwtModule, JwtService } from '@nestjs/jwt'\nimport { Test, TestingModule } from '@nestjs/testing'\nimport { PinoLogger } from 'nestjs-pino'\nimport { JwtPayload } from '../../../../authentication/interfaces/jwt-payload.interface'\nimport { configuration } from '../../../../configuration/config.environment'\nimport { COLLABORA_TOKEN_QUERY_PARAM_NAME } from './collabora-online.constants'\nimport { CollaboraOnlineGuard } from './collabora-online.guard'\nimport { API_COLLABORA_ONLINE_FILES } from './collabora-online.routes'\nimport { CollaboraOnlineStrategy } from './collabora-online.strategy'\n\ndescribe(CollaboraOnlineGuard.name, () => {\n let jwtService: JwtService\n let filesCollaboraGuard: CollaboraOnlineGuard\n let context: DeepMocked<ExecutionContext>\n let accessToken: string\n\n beforeAll(async () => {\n const module: TestingModule = await Test.createTestingModule({\n imports: [JwtModule.register({ global: true })],\n providers: [\n CollaboraOnlineGuard,\n CollaboraOnlineStrategy,\n {\n provide: PinoLogger,\n useValue: {\n assign: () => undefined\n }\n }\n ]\n }).compile()\n\n jwtService = module.get<JwtService>(JwtService)\n filesCollaboraGuard = module.get<CollaboraOnlineGuard>(CollaboraOnlineGuard)\n context = createMock<ExecutionContext>()\n accessToken = await jwtService.signAsync({ identity: { id: 1, login: 'foo' } } as JwtPayload, {\n secret: configuration.auth.token.access.secret,\n expiresIn: 30\n })\n })\n\n it('should be defined', () => {\n expect(jwtService).toBeDefined()\n expect(filesCollaboraGuard).toBeDefined()\n expect(accessToken).toBeDefined()\n })\n\n it('should not pass without a valid token', async () => {\n context.switchToHttp().getRequest.mockReturnValue({\n url: `${API_COLLABORA_ONLINE_FILES}`,\n raw: { user: '' }\n })\n await expect(filesCollaboraGuard.canActivate(context)).rejects.toThrow('Unauthorized')\n })\n\n it('should pass with a (un)valid token', async () => {\n context.switchToHttp().getRequest.mockReturnValue({\n url: `${API_COLLABORA_ONLINE_FILES}?${COLLABORA_TOKEN_QUERY_PARAM_NAME}=${accessToken}`,\n raw: { user: '' }\n })\n expect(await filesCollaboraGuard.canActivate(context)).toBe(true)\n context.switchToHttp().getRequest.mockReturnValue({\n url: `${API_COLLABORA_ONLINE_FILES}?${COLLABORA_TOKEN_QUERY_PARAM_NAME}=unvalidToken`,\n raw: { user: '' }\n })\n await expect(filesCollaboraGuard.canActivate(context)).rejects.toThrow('Unauthorized')\n })\n})\n"],"names":["describe","CollaboraOnlineGuard","name","jwtService","filesCollaboraGuard","context","accessToken","beforeAll","module","Test","createTestingModule","imports","JwtModule","register","global","providers","CollaboraOnlineStrategy","provide","PinoLogger","useValue","assign","undefined","compile","get","JwtService","createMock","signAsync","identity","id","login","secret","configuration","auth","token","access","expiresIn","it","expect","toBeDefined","switchToHttp","getRequest","mockReturnValue","url","API_COLLABORA_ONLINE_FILES","raw","user","canActivate","rejects","toThrow","COLLABORA_TOKEN_QUERY_PARAM_NAME","toBe"],"mappings":"AAAA;;;;CAIC;;;;wBAEsC;qBAED;yBACF;4BACT;mCAEG;0CACmB;sCACZ;uCACM;yCACH;AAExCA,SAASC,0CAAoB,CAACC,IAAI,EAAE;IAClC,IAAIC;IACJ,IAAIC;IACJ,IAAIC;IACJ,IAAIC;IAEJC,UAAU;QACR,MAAMC,SAAwB,MAAMC,aAAI,CAACC,mBAAmB,CAAC;YAC3DC,SAAS;gBAACC,cAAS,CAACC,QAAQ,CAAC;oBAAEC,QAAQ;gBAAK;aAAG;YAC/CC,WAAW;gBACTd,0CAAoB;gBACpBe,gDAAuB;gBACvB;oBACEC,SAASC,sBAAU;oBACnBC,UAAU;wBACRC,QAAQ,IAAMC;oBAChB;gBACF;aACD;QACH,GAAGC,OAAO;QAEVnB,aAAaK,OAAOe,GAAG,CAAaC,eAAU;QAC9CpB,sBAAsBI,OAAOe,GAAG,CAAuBtB,0CAAoB;QAC3EI,UAAUoB,IAAAA,kBAAU;QACpBnB,cAAc,MAAMH,WAAWuB,SAAS,CAAC;YAAEC,UAAU;gBAAEC,IAAI;gBAAGC,OAAO;YAAM;QAAE,GAAiB;YAC5FC,QAAQC,gCAAa,CAACC,IAAI,CAACC,KAAK,CAACC,MAAM,CAACJ,MAAM;YAC9CK,WAAW;QACb;IACF;IAEAC,GAAG,qBAAqB;QACtBC,OAAOlC,YAAYmC,WAAW;QAC9BD,OAAOjC,qBAAqBkC,WAAW;QACvCD,OAAO/B,aAAagC,WAAW;IACjC;IAEAF,GAAG,yCAAyC;QAC1C/B,QAAQkC,YAAY,GAAGC,UAAU,CAACC,eAAe,CAAC;YAChDC,KAAK,GAAGC,iDAA0B,EAAE;YACpCC,KAAK;gBAAEC,MAAM;YAAG;QAClB;QACA,MAAMR,OAAOjC,oBAAoB0C,WAAW,CAACzC,UAAU0C,OAAO,CAACC,OAAO,CAAC;IACzE;IAEAZ,GAAG,sCAAsC;QACvC/B,QAAQkC,YAAY,GAAGC,UAAU,CAACC,eAAe,CAAC;YAChDC,KAAK,GAAGC,iDAA0B,CAAC,CAAC,EAAEM,0DAAgC,CAAC,CAAC,EAAE3C,aAAa;YACvFsC,KAAK;gBAAEC,MAAM;YAAG;QAClB;QACAR,OAAO,MAAMjC,oBAAoB0C,WAAW,CAACzC,UAAU6C,IAAI,CAAC;QAC5D7C,QAAQkC,YAAY,GAAGC,UAAU,CAACC,eAAe,CAAC;YAChDC,KAAK,GAAGC,iDAA0B,CAAC,CAAC,EAAEM,0DAAgC,CAAC,aAAa,CAAC;YACrFL,KAAK;gBAAEC,MAAM;YAAG;QAClB;QACA,MAAMR,OAAOjC,oBAAoB0C,WAAW,CAACzC,UAAU0C,OAAO,CAACC,OAAO,CAAC;IACzE;AACF"}