@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
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../backend/src/applications/files/modules/collabora-online/collabora-online.routes.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_ONLINE_ROUTE = {\n BASE: '/wopi',\n FILES: 'files',\n CONTENTS: 'contents',\n SETTINGS: 'settings'\n} as const\n\nexport const API_COLLABORA_ONLINE_SETTINGS = `${COLLABORA_ONLINE_ROUTE.BASE}/${COLLABORA_ONLINE_ROUTE.SETTINGS}`\nexport const API_COLLABORA_ONLINE_FILES = `${COLLABORA_ONLINE_ROUTE.BASE}/${COLLABORA_ONLINE_ROUTE.FILES}`\n"],"names":["API_COLLABORA_ONLINE_FILES","API_COLLABORA_ONLINE_SETTINGS","COLLABORA_ONLINE_ROUTE","BASE","FILES","CONTENTS","SETTINGS"],"mappings":"AAAA;;;;CAIC;;;;;;;;;;;QAUYA;eAAAA;;QADAC;eAAAA;;QAPAC;eAAAA;;;AAAN,MAAMA,yBAAyB;IACpCC,MAAM;IACNC,OAAO;IACPC,UAAU;IACVC,UAAU;AACZ;AAEO,MAAML,gCAAgC,GAAGC,uBAAuBC,IAAI,CAAC,CAAC,EAAED,uBAAuBI,QAAQ,EAAE;AACzG,MAAMN,6BAA6B,GAAGE,uBAAuBC,IAAI,CAAC,CAAC,EAAED,uBAAuBE,KAAK,EAAE"}
@@ -0,0 +1,59 @@
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, "CollaboraOnlineStrategy", {
10
+ enumerable: true,
11
+ get: function() {
12
+ return CollaboraOnlineStrategy;
13
+ }
14
+ });
15
+ const _common = require("@nestjs/common");
16
+ const _passport = require("@nestjs/passport");
17
+ const _nestjspino = require("nestjs-pino");
18
+ const _passportjwt = require("passport-jwt");
19
+ const _authtokenaccessstrategy = require("../../../../authentication/guards/auth-token-access.strategy");
20
+ const _configenvironment = require("../../../../configuration/config.environment");
21
+ const _usermodel = require("../../../users/models/user.model");
22
+ const _collaboraonlineconstants = require("./collabora-online.constants");
23
+ function _ts_decorate(decorators, target, key, desc) {
24
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
25
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
26
+ 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;
27
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
28
+ }
29
+ function _ts_metadata(k, v) {
30
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
31
+ }
32
+ let CollaboraOnlineStrategy = class CollaboraOnlineStrategy extends (0, _passport.PassportStrategy)(_passportjwt.Strategy, 'filesCollaboraOnlineToken') {
33
+ validate(jwtPayload) {
34
+ this.logger.assign({
35
+ user: jwtPayload.identity.login
36
+ });
37
+ return new _usermodel.UserModel(jwtPayload.identity);
38
+ }
39
+ constructor(logger){
40
+ super({
41
+ jwtFromRequest: _passportjwt.ExtractJwt.fromExtractors([
42
+ _authtokenaccessstrategy.AuthTokenAccessStrategy.extractJWTFromCookie,
43
+ _passportjwt.ExtractJwt.fromUrlQueryParameter(_collaboraonlineconstants.COLLABORA_TOKEN_QUERY_PARAM_NAME)
44
+ ]),
45
+ secretOrKey: _configenvironment.configuration.auth.token.access.secret,
46
+ ignoreExpiration: false,
47
+ passReqToCallback: false
48
+ }), this.logger = logger;
49
+ }
50
+ };
51
+ CollaboraOnlineStrategy = _ts_decorate([
52
+ (0, _common.Injectable)(),
53
+ _ts_metadata("design:type", Function),
54
+ _ts_metadata("design:paramtypes", [
55
+ typeof _nestjspino.PinoLogger === "undefined" ? Object : _nestjspino.PinoLogger
56
+ ])
57
+ ], CollaboraOnlineStrategy);
58
+
59
+ //# sourceMappingURL=collabora-online.strategy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../backend/src/applications/files/modules/collabora-online/collabora-online.strategy.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 } from '@nestjs/common'\nimport { AbstractStrategy, PassportStrategy } from '@nestjs/passport'\nimport { PinoLogger } from 'nestjs-pino'\nimport { ExtractJwt, Strategy } from 'passport-jwt'\nimport { AuthTokenAccessStrategy } from '../../../../authentication/guards/auth-token-access.strategy'\nimport { JwtPayload } from '../../../../authentication/interfaces/jwt-payload.interface'\nimport { configuration } from '../../../../configuration/config.environment'\nimport { UserModel } from '../../../users/models/user.model'\nimport { COLLABORA_TOKEN_QUERY_PARAM_NAME } from './collabora-online.constants'\n\n@Injectable()\nexport class CollaboraOnlineStrategy extends PassportStrategy(Strategy, 'filesCollaboraOnlineToken') implements AbstractStrategy {\n constructor(private readonly logger: PinoLogger) {\n super({\n jwtFromRequest: ExtractJwt.fromExtractors([\n AuthTokenAccessStrategy.extractJWTFromCookie,\n ExtractJwt.fromUrlQueryParameter(COLLABORA_TOKEN_QUERY_PARAM_NAME)\n ]),\n secretOrKey: configuration.auth.token.access.secret,\n ignoreExpiration: false,\n passReqToCallback: false\n })\n }\n\n validate(jwtPayload: JwtPayload): UserModel {\n this.logger.assign({ user: jwtPayload.identity.login })\n return new UserModel(jwtPayload.identity)\n }\n}\n"],"names":["CollaboraOnlineStrategy","PassportStrategy","Strategy","validate","jwtPayload","logger","assign","user","identity","login","UserModel","jwtFromRequest","ExtractJwt","fromExtractors","AuthTokenAccessStrategy","extractJWTFromCookie","fromUrlQueryParameter","COLLABORA_TOKEN_QUERY_PARAM_NAME","secretOrKey","configuration","auth","token","access","secret","ignoreExpiration","passReqToCallback"],"mappings":"AAAA;;;;CAIC;;;;+BAaYA;;;eAAAA;;;wBAXc;0BACwB;4BACxB;6BACU;yCACG;mCAEV;2BACJ;0CACuB;;;;;;;;;;AAG1C,IAAA,AAAMA,0BAAN,MAAMA,gCAAgCC,IAAAA,0BAAgB,EAACC,qBAAQ,EAAE;IAatEC,SAASC,UAAsB,EAAa;QAC1C,IAAI,CAACC,MAAM,CAACC,MAAM,CAAC;YAAEC,MAAMH,WAAWI,QAAQ,CAACC,KAAK;QAAC;QACrD,OAAO,IAAIC,oBAAS,CAACN,WAAWI,QAAQ;IAC1C;IAfA,YAAY,AAAiBH,MAAkB,CAAE;QAC/C,KAAK,CAAC;YACJM,gBAAgBC,uBAAU,CAACC,cAAc,CAAC;gBACxCC,gDAAuB,CAACC,oBAAoB;gBAC5CH,uBAAU,CAACI,qBAAqB,CAACC,0DAAgC;aAClE;YACDC,aAAaC,gCAAa,CAACC,IAAI,CAACC,KAAK,CAACC,MAAM,CAACC,MAAM;YACnDC,kBAAkB;YAClBC,mBAAmB;QACrB,SAT2BpB,SAAAA;IAU7B;AAMF"}
@@ -0,0 +1,28 @@
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, "COLLABORA_ONLINE_TO_SPACE_SEGMENTS", {
10
+ enumerable: true,
11
+ get: function() {
12
+ return COLLABORA_ONLINE_TO_SPACE_SEGMENTS;
13
+ }
14
+ });
15
+ const _routes = require("../../../spaces/utils/routes");
16
+ function COLLABORA_ONLINE_TO_SPACE_SEGMENTS(req) {
17
+ if (req.user.spaceUrl) {
18
+ // `spaceUrl` and `dbFileHash` are set when the authentication token is provided via a query parameter by the Collabora Server
19
+ if (req.user.dbFileHash === req.params.dbFileHash) {
20
+ return req.user.spaceUrl.split('/');
21
+ }
22
+ throw new Error('Collabora Online - DB File Hash mismatch');
23
+ } else {
24
+ return (0, _routes.PATH_TO_SPACE_SEGMENTS)(req.params['*']);
25
+ }
26
+ }
27
+
28
+ //# sourceMappingURL=collabora-online.utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../backend/src/applications/files/modules/collabora-online/collabora-online.utils.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 { PATH_TO_SPACE_SEGMENTS } from '../../../spaces/utils/routes'\nimport type { FastifyCollaboraOnlineSpaceRequest } from './collabora-online.interface'\n\nexport function COLLABORA_ONLINE_TO_SPACE_SEGMENTS(req: FastifyCollaboraOnlineSpaceRequest): string[] {\n if (req.user.spaceUrl) {\n // `spaceUrl` and `dbFileHash` are set when the authentication token is provided via a query parameter by the Collabora Server\n if (req.user.dbFileHash === req.params.dbFileHash) {\n return req.user.spaceUrl.split('/')\n }\n throw new Error('Collabora Online - DB File Hash mismatch')\n } else {\n return PATH_TO_SPACE_SEGMENTS(req.params['*'])\n }\n}\n"],"names":["COLLABORA_ONLINE_TO_SPACE_SEGMENTS","req","user","spaceUrl","dbFileHash","params","split","Error","PATH_TO_SPACE_SEGMENTS"],"mappings":"AAAA;;;;CAIC;;;;+BAKeA;;;eAAAA;;;wBAHuB;AAGhC,SAASA,mCAAmCC,GAAuC;IACxF,IAAIA,IAAIC,IAAI,CAACC,QAAQ,EAAE;QACrB,8HAA8H;QAC9H,IAAIF,IAAIC,IAAI,CAACE,UAAU,KAAKH,IAAII,MAAM,CAACD,UAAU,EAAE;YACjD,OAAOH,IAAIC,IAAI,CAACC,QAAQ,CAACG,KAAK,CAAC;QACjC;QACA,MAAM,IAAIC,MAAM;IAClB,OAAO;QACL,OAAOC,IAAAA,8BAAsB,EAACP,IAAII,MAAM,CAAC,IAAI;IAC/C;AACF"}
@@ -21,12 +21,12 @@ _export(exports, {
21
21
  }
22
22
  });
23
23
  const _common = require("@nestjs/common");
24
- const _spaceguard = require("../../spaces/guards/space.guard");
25
- const _onlyoffice = require("../constants/only-office");
26
- const _filesonlyofficeguard = require("../guards/files-only-office.guard");
27
- const OnlyOfficeContext = ()=>(0, _common.SetMetadata)(_onlyoffice.ONLY_OFFICE_CONTEXT, true);
24
+ const _spaceguard = require("../../../spaces/guards/space.guard");
25
+ const _onlyofficeconstants = require("./only-office.constants");
26
+ const _onlyofficeguard = require("./only-office.guard");
27
+ const OnlyOfficeContext = ()=>(0, _common.SetMetadata)(_onlyofficeconstants.ONLY_OFFICE_CONTEXT, true);
28
28
  const OnlyOfficeEnvironment = ()=>{
29
- return (0, _common.applyDecorators)(OnlyOfficeContext(), (0, _common.UseGuards)(_filesonlyofficeguard.FilesOnlyOfficeGuard, _spaceguard.SpaceGuard));
29
+ return (0, _common.applyDecorators)(OnlyOfficeContext(), (0, _common.UseGuards)(_onlyofficeguard.OnlyOfficeGuard, _spaceguard.SpaceGuard));
30
30
  };
31
31
 
32
32
  //# sourceMappingURL=only-office-environment.decorator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../backend/src/applications/files/modules/only-office/only-office-environment.decorator.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 { applyDecorators, SetMetadata, UseGuards } from '@nestjs/common'\nimport { SpaceGuard } from '../../../spaces/guards/space.guard'\nimport { ONLY_OFFICE_CONTEXT } from './only-office.constants'\nimport { OnlyOfficeGuard } from './only-office.guard'\n\nexport const OnlyOfficeContext = () => SetMetadata(ONLY_OFFICE_CONTEXT, true)\nexport const OnlyOfficeEnvironment = () => {\n return applyDecorators(OnlyOfficeContext(), UseGuards(OnlyOfficeGuard, SpaceGuard))\n}\n"],"names":["OnlyOfficeContext","OnlyOfficeEnvironment","SetMetadata","ONLY_OFFICE_CONTEXT","applyDecorators","UseGuards","OnlyOfficeGuard","SpaceGuard"],"mappings":"AAAA;;;;CAIC;;;;;;;;;;;QAOYA;eAAAA;;QACAC;eAAAA;;;wBAN2C;4BAC7B;qCACS;iCACJ;AAEzB,MAAMD,oBAAoB,IAAME,IAAAA,mBAAW,EAACC,wCAAmB,EAAE;AACjE,MAAMF,wBAAwB;IACnC,OAAOG,IAAAA,uBAAe,EAACJ,qBAAqBK,IAAAA,iBAAS,EAACC,gCAAe,EAAEC,sBAAU;AACnF"}
@@ -6,10 +6,10 @@
6
6
  Object.defineProperty(exports, "__esModule", {
7
7
  value: true
8
8
  });
9
- Object.defineProperty(exports, "FilesOnlyOfficeManager", {
9
+ Object.defineProperty(exports, "OnlyOfficeManager", {
10
10
  enumerable: true,
11
11
  get: function() {
12
- return FilesOnlyOfficeManager;
12
+ return OnlyOfficeManager;
13
13
  }
14
14
  });
15
15
  const _axios = require("@nestjs/axios");
@@ -19,22 +19,21 @@ const _https = /*#__PURE__*/ _interop_require_default(require("https"));
19
19
  const _nodecrypto = /*#__PURE__*/ _interop_require_default(require("node:crypto"));
20
20
  const _nodeos = /*#__PURE__*/ _interop_require_default(require("node:os"));
21
21
  const _nodepath = /*#__PURE__*/ _interop_require_default(require("node:path"));
22
- const _functions = require("../../../common/functions");
23
- const _configenvironment = require("../../../configuration/config.environment");
24
- const _cacheservice = require("../../../infrastructure/cache/services/cache.service");
25
- const _contextmanagerservice = require("../../../infrastructure/context/services/context-manager.service");
26
- const _applicationsconstants = require("../../applications.constants");
27
- const _spaces = require("../../spaces/constants/spaces");
28
- const _permissions = require("../../spaces/utils/permissions");
29
- const _avatar = require("../../users/utils/avatar");
30
- const _webdav = require("../../webdav/constants/webdav");
31
- const _cache = require("../constants/cache");
32
- const _onlyoffice = require("../constants/only-office");
33
- const _operations = require("../constants/operations");
34
- const _routes = require("../constants/routes");
35
- const _files = require("../utils/files");
36
- const _fileslockmanagerservice = require("./files-lock-manager.service");
37
- const _filesqueriesservice = require("./files-queries.service");
22
+ const _functions = require("../../../../common/functions");
23
+ const _configenvironment = require("../../../../configuration/config.environment");
24
+ const _cacheservice = require("../../../../infrastructure/cache/services/cache.service");
25
+ const _contextmanagerservice = require("../../../../infrastructure/context/services/context-manager.service");
26
+ const _applicationsconstants = require("../../../applications.constants");
27
+ const _spaces = require("../../../spaces/constants/spaces");
28
+ const _permissions = require("../../../spaces/utils/permissions");
29
+ const _avatar = require("../../../users/utils/avatar");
30
+ const _webdav = require("../../../webdav/constants/webdav");
31
+ const _operations = require("../../constants/operations");
32
+ const _filelockerror = require("../../models/file-lock-error");
33
+ const _fileslockmanagerservice = require("../../services/files-lock-manager.service");
34
+ const _files = require("../../utils/files");
35
+ const _onlyofficeconstants = require("./only-office.constants");
36
+ const _onlyofficeroutes = require("./only-office.routes");
38
37
  function _interop_require_default(obj) {
39
38
  return obj && obj.__esModule ? obj : {
40
39
  default: obj
@@ -49,74 +48,77 @@ function _ts_decorate(decorators, target, key, desc) {
49
48
  function _ts_metadata(k, v) {
50
49
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
51
50
  }
52
- let FilesOnlyOfficeManager = class FilesOnlyOfficeManager {
53
- getStatus() {
54
- return {
55
- enabled: _configenvironment.configuration.applications.files.onlyoffice.enabled
56
- };
57
- }
58
- async getSettings(user, space, mode, req) {
51
+ let OnlyOfficeManager = class OnlyOfficeManager {
52
+ async getSettings(user, space, req) {
59
53
  if (!await (0, _files.isPathExists)(space.realPath)) {
60
- throw new _common.HttpException('Document not found', _common.HttpStatus.NOT_FOUND);
54
+ throw new _common.HttpException('Document not found', _common.HttpStatus.BAD_REQUEST);
61
55
  }
62
56
  if (await (0, _files.isPathIsDir)(space.realPath)) {
63
57
  throw new _common.HttpException('Document must be a file', _common.HttpStatus.BAD_REQUEST);
64
58
  }
65
59
  const fileExtension = _nodepath.default.extname(space.realPath).slice(1);
66
- if (!_onlyoffice.ONLY_OFFICE_EXTENSIONS.VIEWABLE.has(fileExtension) && !_onlyoffice.ONLY_OFFICE_EXTENSIONS.EDITABLE.has(fileExtension)) {
60
+ if (!_onlyofficeconstants.ONLY_OFFICE_EXTENSIONS.has(fileExtension)) {
67
61
  throw new _common.HttpException('Document not supported', _common.HttpStatus.BAD_REQUEST);
68
62
  }
69
- if (mode === _operations.FILE_MODE.EDIT && (!_onlyoffice.ONLY_OFFICE_EXTENSIONS.EDITABLE.has(fileExtension) || !(0, _permissions.haveSpaceEnvPermissions)(space, _spaces.SPACE_OPERATION.MODIFY))) {
70
- mode = _operations.FILE_MODE.VIEW;
71
- }
63
+ let hasLock = false;
64
+ let mode = (0, _permissions.haveSpaceEnvPermissions)(space, _spaces.SPACE_OPERATION.MODIFY) ? _operations.FILE_MODE.EDIT : _operations.FILE_MODE.VIEW;
72
65
  if (mode === _operations.FILE_MODE.EDIT) {
73
- // check lock conflicts
66
+ // Check lock conflicts
74
67
  try {
75
68
  await this.filesLockManager.checkConflicts(space.dbFile, _webdav.DEPTH.RESOURCE, {
76
69
  userId: user.id,
70
+ app: _onlyofficeconstants.ONLY_OFFICE_APP_LOCK,
77
71
  lockScope: _webdav.LOCK_SCOPE.SHARED
78
72
  });
79
- } catch {
80
- throw new _common.HttpException('The file is locked', _common.HttpStatus.LOCKED);
73
+ } catch (e) {
74
+ if (e instanceof _filelockerror.LockConflict) {
75
+ hasLock = this.filesLockManager.convertLockToFileLockProps(e.lock);
76
+ mode = _operations.FILE_MODE.VIEW;
77
+ } else {
78
+ this.logger.error(`${this.getSettings.name} - ${e}`);
79
+ throw new _common.HttpException('Unable to check file lock', _common.HttpStatus.INTERNAL_SERVER_ERROR);
80
+ }
81
81
  }
82
82
  }
83
83
  const isMobile = this.mobileRegex.test(req.headers['user-agent']);
84
- const fileProps = await (0, _files.getProps)(space.realPath, space.dbFile.path);
85
- const fileId = (await this.filesQueries.getSpaceFileId(fileProps, space.dbFile) || fileProps.id).toString();
86
- const userToken = await this.genUserToken(user);
87
- const fileUrl = this.getDocumentUrl(space, userToken);
88
- const callBackUrl = this.getCallBackUrl(space, userToken, fileId);
89
- const config = await this.genConfiguration(user, space, mode, fileId, fileUrl, fileExtension, callBackUrl, isMobile);
84
+ const authToken = await this.genAuthToken(user);
85
+ const fileUrl = this.buildUrl(_onlyofficeroutes.API_ONLY_OFFICE_DOCUMENT, space.url, authToken);
86
+ const callBackUrl = this.buildUrl(_onlyofficeroutes.API_ONLY_OFFICE_CALLBACK, space.url, authToken);
87
+ const config = await this.genConfiguration(user, space, mode, fileUrl, fileExtension, callBackUrl, isMobile, hasLock);
90
88
  config.config.token = await this.genPayloadToken(config.config);
91
89
  return config;
92
90
  }
93
- async callBack(user, space, token, fileId) {
91
+ async callBack(user, space, token) {
94
92
  const callBackData = await this.jwt.verifyAsync(token, {
95
93
  secret: _configenvironment.configuration.applications.files.onlyoffice.secret
96
94
  });
97
95
  try {
98
96
  switch(callBackData.status){
99
97
  case 1:
98
+ // users connect / disconnect
100
99
  await this.checkFileLock(user, space, callBackData);
101
100
  this.logger.debug(`document is being edited : ${space.url}`);
102
101
  break;
103
102
  case 2:
103
+ // No active users on the document
104
104
  await this.checkFileLock(user, space, callBackData);
105
105
  if (callBackData.notmodified) {
106
106
  this.logger.debug(`document was edited but closed with no changes : ${space.url}`);
107
107
  } else {
108
- this.logger.debug(`document was edited but not saved (let's do it) : ${space.url}`);
108
+ this.logger.debug(`document was edited and closed but not saved (let's do it) : ${space.url}`);
109
109
  await this.saveDocument(space, callBackData.url);
110
110
  }
111
- await this.removeDocumentKey(fileId, space);
111
+ await this.removeFileLock(user.id, space);
112
+ await this.removeDocumentKey(space);
112
113
  break;
113
114
  case 3:
114
115
  this.logger.error(`document cannot be saved, an error has occurred (try to save it) : ${space.url}`);
115
116
  await this.saveDocument(space, callBackData.url);
116
117
  break;
117
118
  case 4:
119
+ // No active users on the document
118
120
  await this.removeFileLock(user.id, space);
119
- await this.removeDocumentKey(fileId, space);
121
+ await this.removeDocumentKey(space);
120
122
  this.logger.debug(`document was closed with no changes : ${space.url}`);
121
123
  break;
122
124
  case 6:
@@ -140,10 +142,12 @@ let FilesOnlyOfficeManager = class FilesOnlyOfficeManager {
140
142
  error: 0
141
143
  };
142
144
  }
143
- async genConfiguration(user, space, mode, fileId, fileUrl, fileExtension, callBackUrl, isMobile) {
144
- const documentType = _onlyoffice.ONLY_OFFICE_EXTENSIONS.EDITABLE.get(fileExtension) || _onlyoffice.ONLY_OFFICE_EXTENSIONS.VIEWABLE.get(fileExtension);
145
+ async genConfiguration(user, space, mode, fileUrl, fileExtension, callBackUrl, isMobile, hasLock) {
146
+ const canEdit = mode === _operations.FILE_MODE.EDIT;
147
+ const documentType = _onlyofficeconstants.ONLY_OFFICE_EXTENSIONS.get(fileExtension);
145
148
  return {
146
- documentServerUrl: this.externalOnlyOfficeServer || `${this.contextManager.headerOriginUrl()}${_onlyoffice.ONLY_OFFICE_INTERNAL_URI}`,
149
+ hasLock: hasLock,
150
+ documentServerUrl: this.externalOnlyOfficeServer || `${this.contextManager.headerOriginUrl()}${_onlyofficeconstants.ONLY_OFFICE_INTERNAL_URI}`,
147
151
  config: {
148
152
  type: isMobile ? 'mobile' : 'desktop',
149
153
  height: '100%',
@@ -152,15 +156,15 @@ let FilesOnlyOfficeManager = class FilesOnlyOfficeManager {
152
156
  document: {
153
157
  title: _nodepath.default.basename(space.relativeUrl),
154
158
  fileType: fileExtension,
155
- key: await this.getDocumentKey(fileId),
159
+ key: await this.getDocumentKey(space),
156
160
  permissions: {
157
161
  download: true,
158
- edit: mode === _operations.FILE_MODE.EDIT,
162
+ edit: canEdit,
159
163
  changeHistory: false,
160
- comment: true,
161
- fillForms: true,
164
+ comment: canEdit,
165
+ fillForms: canEdit,
162
166
  print: true,
163
- review: mode === _operations.FILE_MODE.EDIT
167
+ review: canEdit
164
168
  },
165
169
  url: fileUrl
166
170
  },
@@ -199,13 +203,10 @@ let FilesOnlyOfficeManager = class FilesOnlyOfficeManager {
199
203
  }
200
204
  };
201
205
  }
202
- getDocumentUrl(space, token) {
203
- // user refresh token is used here for long session
204
- return `${this.contextManager.headerOriginUrl()}${_routes.API_FILES_ONLY_OFFICE_DOCUMENT}/${space.url}?${_onlyoffice.ONLY_OFFICE_TOKEN_QUERY_PARAM_NAME}=${token}`;
205
- }
206
- getCallBackUrl(space, token, fileId) {
207
- // user refresh token is used here for long session
208
- return `${this.contextManager.headerOriginUrl()}${_routes.API_FILES_ONLY_OFFICE_CALLBACK}/${space.url}?fid=${fileId}&${_onlyoffice.ONLY_OFFICE_TOKEN_QUERY_PARAM_NAME}=${token}`;
206
+ buildUrl(basePath, spaceUrl, token) {
207
+ const url = new URL(`${basePath}/${spaceUrl}`, this.contextManager.headerOriginUrl());
208
+ url.searchParams.set(_onlyofficeconstants.ONLY_OFFICE_TOKEN_QUERY_PARAM_NAME, token);
209
+ return url.toString();
209
210
  }
210
211
  genPayloadToken(payload) {
211
212
  return this.jwt.signAsync(payload, {
@@ -213,8 +214,8 @@ let FilesOnlyOfficeManager = class FilesOnlyOfficeManager {
213
214
  expiresIn: 60
214
215
  });
215
216
  }
216
- genUserToken(user) {
217
- // use refresh expiration to allow long session
217
+ genAuthToken(user) {
218
+ // use refresh expiration to allow long sessions
218
219
  return this.jwt.signAsync({
219
220
  identity: {
220
221
  id: user.id,
@@ -233,23 +234,28 @@ let FilesOnlyOfficeManager = class FilesOnlyOfficeManager {
233
234
  async checkFileLock(user, space, callBackData) {
234
235
  for (const action of callBackData.actions){
235
236
  if (action.type === 0) {
236
- // disconnect
237
- await this.removeFileLock(parseInt(action.userid), space);
237
+ // Disconnect
238
+ // Remove the lock if no other users are active on the document
239
+ if (!Array.isArray(callBackData.users)) {
240
+ await this.removeFileLock(parseInt(action.userid), space);
241
+ }
238
242
  } else if (action.type === 1) {
239
- // connect
240
- await this.genFileLock(user, space);
243
+ // Connect
244
+ // Create the lock if it's the first user to open the document
245
+ if (Array.isArray(callBackData.users) && callBackData.users.length === 1) {
246
+ await this.createFileLock(user, space);
247
+ }
241
248
  }
242
249
  }
243
250
  }
244
- async genFileLock(user, space) {
245
- const [ok, _fileLock] = await this.filesLockManager.create(user, space.dbFile, _webdav.DEPTH.RESOURCE, {
246
- lockroot: null,
247
- locktoken: null,
248
- lockscope: _webdav.LOCK_SCOPE.SHARED,
249
- owner: `OnlyOffice - ${user.fullName} (${user.email})`
251
+ async createFileLock(user, space) {
252
+ const [ok, _fileLock] = await this.filesLockManager.create(user, space.dbFile, _onlyofficeconstants.ONLY_OFFICE_APP_LOCK, _webdav.DEPTH.RESOURCE, {
253
+ lockRoot: null,
254
+ lockToken: null,
255
+ lockScope: _webdav.LOCK_SCOPE.SHARED
250
256
  }, this.expiration);
251
257
  if (!ok) {
252
- throw new Error('document is locked');
258
+ throw new _common.HttpException('The file is locked', _common.HttpStatus.LOCKED);
253
259
  }
254
260
  }
255
261
  async removeFileLock(userId, space) {
@@ -259,20 +265,21 @@ let FilesOnlyOfficeManager = class FilesOnlyOfficeManager {
259
265
  }
260
266
  }
261
267
  }
262
- async removeDocumentKey(fileId, space) {
268
+ async removeDocumentKey(space) {
263
269
  if (!await this.filesLockManager.isPathLocked(space.dbFile)) {
264
- const cacheKey = this.getCacheKey(fileId);
270
+ const cacheKey = this.getCacheKey(space.dbFile);
265
271
  const r = await this.cache.del(cacheKey);
266
272
  this.logger.debug(`${this.removeDocumentKey.name} - ${cacheKey} ${r ? '' : 'not'} removed`);
267
273
  }
268
274
  }
269
- async getDocumentKey(fileId) {
270
- const cacheKey = this.getCacheKey(fileId);
275
+ async getDocumentKey(space) {
276
+ // Uniq key to identify the document in OnlyOffice
277
+ const cacheKey = this.getCacheKey(space.dbFile);
271
278
  const existingDocKey = await this.cache.get(cacheKey);
272
279
  if (existingDocKey) {
273
280
  return existingDocKey;
274
281
  }
275
- const docKey = (0, _functions.generateShortUUID)(64);
282
+ const docKey = (0, _files.genEtag)(null, space.realPath, false);
276
283
  await this.cache.set(cacheKey, docKey, this.expiration);
277
284
  this.logger.debug(`${this.getDocumentKey.name} - ${cacheKey} (${docKey}) created`);
278
285
  return docKey;
@@ -282,15 +289,15 @@ let FilesOnlyOfficeManager = class FilesOnlyOfficeManager {
282
289
  https://onlyoffice-server.com/cache/files/data/-33120641_7158/output.pptx/output.pptx
283
290
  ?md5=duFHKC-5d47s-RRcYn3hAw&expires=1739400549&shardkey=-33120641&filename=output.pptx
284
291
  */ const urlParams = new URLSearchParams(url.split('?').at(-1));
285
- // it is not the md5 of the file but a md5 generated by the combination of the elements of the url
292
+ // it is not the md5 of the file but the md5 generated by the combination of the elements of the url
286
293
  const md5 = urlParams.get('md5');
287
294
  const tmpFilePath = await (0, _files.uniqueFilePathFromDir)(_nodepath.default.join(_nodeos.default.tmpdir(), `${md5}-${urlParams.get('filename')}`));
288
- // convert remote file to the local file with the current extension if these extensions aren't equal
295
+ // convert the remote file to the local file with the current extension if these extensions aren't equal
289
296
  const localExtension = _nodepath.default.extname(space.realPath).slice(1);
290
297
  const remoteExtension = _nodepath.default.extname(urlParams.get('filename')).slice(1);
291
298
  let downloadUrl;
292
- if (localExtension !== remoteExtension && !_onlyoffice.ONLY_OFFICE_CONVERT_EXTENSIONS.ALLOW_AUTO.has(localExtension)) {
293
- if (_onlyoffice.ONLY_OFFICE_CONVERT_EXTENSIONS.FROM.has(remoteExtension) && _onlyoffice.ONLY_OFFICE_CONVERT_EXTENSIONS.TO.has(localExtension)) {
299
+ if (localExtension !== remoteExtension && !_onlyofficeconstants.ONLY_OFFICE_CONVERT_EXTENSIONS.ALLOW_AUTO.has(localExtension)) {
300
+ if (_onlyofficeconstants.ONLY_OFFICE_CONVERT_EXTENSIONS.FROM.has(remoteExtension) && _onlyofficeconstants.ONLY_OFFICE_CONVERT_EXTENSIONS.TO.has(localExtension)) {
294
301
  downloadUrl = await this.convertDocument(urlParams.get('shardkey'), url, remoteExtension, localExtension, space.url);
295
302
  } else {
296
303
  throw new Error(`document cannot be converted from ${remoteExtension} -> ${localExtension} : ${space.url}`);
@@ -315,18 +322,17 @@ let FilesOnlyOfficeManager = class FilesOnlyOfficeManager {
315
322
  }
316
323
  // try to verify the downloaded size
317
324
  const contentLength = parseInt(res.headers['content-length'], 10);
318
- if (!isNaN(contentLength)) {
319
- if (contentLength === 0) {
320
- this.logger.debug(`${this.saveDocument.name} - content length is 0 : ${space.url}`);
321
- return;
322
- }
325
+ if (!isNaN(contentLength) && contentLength !== 0) {
323
326
  const tmpFileSize = await (0, _files.fileSize)(tmpFilePath);
324
327
  if (tmpFileSize !== contentLength) {
325
328
  throw new Error(`document size differs (${tmpFileSize} != ${contentLength})`);
326
329
  }
330
+ } else if (contentLength === 0) {
331
+ this.logger.warn(`${this.saveDocument.name} - content length is 0 : ${space.url}`);
327
332
  }
328
- // copy contents to avoid inode changes (fileId in some cases)
333
+ // copy contents to avoid inode changes (`file.id` in some cases)
329
334
  try {
335
+ // todo: versioning
330
336
  await (0, _files.copyFileContent)(tmpFilePath, space.realPath);
331
337
  await (0, _files.removeFiles)(tmpFilePath);
332
338
  } catch (e) {
@@ -358,24 +364,23 @@ let FilesOnlyOfficeManager = class FilesOnlyOfficeManager {
358
364
  throw new Error(`convert failed with status : ${e.response.status}`);
359
365
  }
360
366
  if (result.error) {
361
- throw new Error(`convert failed with reason : ${_onlyoffice.ONLY_OFFICE_CONVERT_ERROR.get(result.error)}`);
367
+ throw new Error(`convert failed with reason : ${_onlyofficeconstants.ONLY_OFFICE_CONVERT_ERROR.get(result.error)}`);
362
368
  }
363
369
  if (result.endConvert) {
364
370
  this.logger.log(`${this.convertDocument.name} - ${fileType} -> ${outputType} : ${spaceUrl}`);
365
371
  return result.fileUrl;
366
372
  }
367
373
  }
368
- getCacheKey(fileId) {
369
- return `${_cache.CACHE_ONLY_OFFICE}|${fileId}`;
374
+ getCacheKey(dbFile) {
375
+ return `${_onlyofficeconstants.ONLY_OFFICE_CACHE_KEY}|${(0, _files.genUniqHashFromFileDBProps)(dbFile)}`;
370
376
  }
371
- constructor(http, contextManager, cache, jwt, filesLockManager, filesQueries){
377
+ constructor(http, contextManager, cache, jwt, filesLockManager){
372
378
  this.http = http;
373
379
  this.contextManager = contextManager;
374
380
  this.cache = cache;
375
381
  this.jwt = jwt;
376
382
  this.filesLockManager = filesLockManager;
377
- this.filesQueries = filesQueries;
378
- this.logger = new _common.Logger(FilesOnlyOfficeManager.name);
383
+ this.logger = new _common.Logger(OnlyOfficeManager.name);
379
384
  this.externalOnlyOfficeServer = _configenvironment.configuration.applications.files.onlyoffice.externalServer || null;
380
385
  this.rejectUnauthorized = !_configenvironment.configuration.applications.files.onlyoffice?.verifySSL;
381
386
  this.convertUrl = this.externalOnlyOfficeServer ? `${this.externalOnlyOfficeServer}/ConvertService.ashx` : null;
@@ -383,7 +388,7 @@ let FilesOnlyOfficeManager = class FilesOnlyOfficeManager {
383
388
  this.mobileRegex = /android|webos|iphone|ipad|ipod|blackberry|windows phone|opera mini|iemobile|mobile/i;
384
389
  }
385
390
  };
386
- FilesOnlyOfficeManager = _ts_decorate([
391
+ OnlyOfficeManager = _ts_decorate([
387
392
  (0, _common.Injectable)(),
388
393
  _ts_metadata("design:type", Function),
389
394
  _ts_metadata("design:paramtypes", [
@@ -391,9 +396,8 @@ FilesOnlyOfficeManager = _ts_decorate([
391
396
  typeof _contextmanagerservice.ContextManager === "undefined" ? Object : _contextmanagerservice.ContextManager,
392
397
  typeof _cacheservice.Cache === "undefined" ? Object : _cacheservice.Cache,
393
398
  typeof _jwt.JwtService === "undefined" ? Object : _jwt.JwtService,
394
- typeof _fileslockmanagerservice.FilesLockManager === "undefined" ? Object : _fileslockmanagerservice.FilesLockManager,
395
- typeof _filesqueriesservice.FilesQueries === "undefined" ? Object : _filesqueriesservice.FilesQueries
399
+ typeof _fileslockmanagerservice.FilesLockManager === "undefined" ? Object : _fileslockmanagerservice.FilesLockManager
396
400
  ])
397
- ], FilesOnlyOfficeManager);
401
+ ], OnlyOfficeManager);
398
402
 
399
- //# sourceMappingURL=files-only-office-manager.service.js.map
403
+ //# sourceMappingURL=only-office-manager.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../backend/src/applications/files/modules/only-office/only-office-manager.service.ts"],"sourcesContent":["/*\n * Copyright (C) 2012-2025 Johan Legrand <johan.legrand@sync-in.com>\n * This file is part of Sync-in | The open source file sync and share solution\n * See the LICENSE file for licensing details\n */\n\nimport { HttpService } from '@nestjs/axios'\nimport { HttpException, HttpStatus, Injectable, Logger } from '@nestjs/common'\nimport { JwtService } from '@nestjs/jwt'\nimport { AxiosResponse } from 'axios'\nimport https from 'https'\nimport crypto from 'node:crypto'\nimport os from 'node:os'\nimport path from 'node:path'\nimport { JwtIdentityPayload } from '../../../../authentication/interfaces/jwt-payload.interface'\nimport { convertHumanTimeToSeconds } from '../../../../common/functions'\nimport { configuration } from '../../../../configuration/config.environment'\nimport { Cache } from '../../../../infrastructure/cache/services/cache.service'\nimport { ContextManager } from '../../../../infrastructure/context/services/context-manager.service'\nimport { HTTP_METHOD } from '../../../applications.constants'\nimport { SPACE_OPERATION } from '../../../spaces/constants/spaces'\nimport { FastifySpaceRequest } from '../../../spaces/interfaces/space-request.interface'\nimport type { SpaceEnv } from '../../../spaces/models/space-env.model'\nimport { haveSpaceEnvPermissions } from '../../../spaces/utils/permissions'\nimport type { UserModel } from '../../../users/models/user.model'\nimport { getAvatarBase64 } from '../../../users/utils/avatar'\nimport { DEPTH, LOCK_SCOPE } from '../../../webdav/constants/webdav'\nimport { FILE_MODE } from '../../constants/operations'\nimport type { FileDBProps } from '../../interfaces/file-db-props.interface'\nimport { FileLockOptions } from '../../interfaces/file-lock.interface'\nimport { FileLockProps } from '../../interfaces/file-props.interface'\nimport { LockConflict } from '../../models/file-lock-error'\nimport { FilesLockManager } from '../../services/files-lock-manager.service'\nimport {\n copyFileContent,\n fileSize,\n genEtag,\n genUniqHashFromFileDBProps,\n isPathExists,\n isPathIsDir,\n removeFiles,\n uniqueFilePathFromDir,\n writeFromStream\n} from '../../utils/files'\nimport {\n ONLY_OFFICE_APP_LOCK,\n ONLY_OFFICE_CACHE_KEY,\n ONLY_OFFICE_CONVERT_ERROR,\n ONLY_OFFICE_CONVERT_EXTENSIONS,\n ONLY_OFFICE_EXTENSIONS,\n ONLY_OFFICE_INTERNAL_URI,\n ONLY_OFFICE_TOKEN_QUERY_PARAM_NAME\n} from './only-office.constants'\nimport { OnlyOfficeReqDto } from './only-office.dtos'\nimport { OnlyOfficeCallBack, OnlyOfficeConfig, OnlyOfficeConvertForm } from './only-office.interface'\nimport { API_ONLY_OFFICE_CALLBACK, API_ONLY_OFFICE_DOCUMENT } from './only-office.routes'\n\n@Injectable()\nexport class OnlyOfficeManager {\n private logger = new Logger(OnlyOfficeManager.name)\n private readonly externalOnlyOfficeServer = configuration.applications.files.onlyoffice.externalServer || null\n private readonly rejectUnauthorized: boolean = !configuration.applications.files.onlyoffice?.verifySSL\n private readonly convertUrl = this.externalOnlyOfficeServer ? `${this.externalOnlyOfficeServer}/ConvertService.ashx` : null\n private readonly expiration = convertHumanTimeToSeconds(configuration.auth.token.refresh.expiration)\n private readonly mobileRegex: RegExp = /android|webos|iphone|ipad|ipod|blackberry|windows phone|opera mini|iemobile|mobile/i\n\n constructor(\n private readonly http: HttpService,\n private readonly contextManager: ContextManager,\n private readonly cache: Cache,\n private readonly jwt: JwtService,\n private readonly filesLockManager: FilesLockManager\n ) {}\n\n async getSettings(user: UserModel, space: SpaceEnv, req: FastifySpaceRequest): Promise<OnlyOfficeReqDto> {\n if (!(await isPathExists(space.realPath))) {\n throw new HttpException('Document not found', HttpStatus.BAD_REQUEST)\n }\n if (await isPathIsDir(space.realPath)) {\n throw new HttpException('Document must be a file', HttpStatus.BAD_REQUEST)\n }\n const fileExtension = path.extname(space.realPath).slice(1)\n if (!ONLY_OFFICE_EXTENSIONS.has(fileExtension)) {\n throw new HttpException('Document not supported', HttpStatus.BAD_REQUEST)\n }\n let hasLock: false | FileLockProps = false\n let mode: FILE_MODE = haveSpaceEnvPermissions(space, SPACE_OPERATION.MODIFY) ? FILE_MODE.EDIT : FILE_MODE.VIEW\n if (mode === FILE_MODE.EDIT) {\n // Check lock conflicts\n try {\n await this.filesLockManager.checkConflicts(space.dbFile, DEPTH.RESOURCE, {\n userId: user.id,\n app: ONLY_OFFICE_APP_LOCK,\n lockScope: LOCK_SCOPE.SHARED\n })\n } catch (e) {\n if (e instanceof LockConflict) {\n hasLock = this.filesLockManager.convertLockToFileLockProps(e.lock)\n mode = FILE_MODE.VIEW\n } else {\n this.logger.error(`${this.getSettings.name} - ${e}`)\n throw new HttpException('Unable to check file lock', HttpStatus.INTERNAL_SERVER_ERROR)\n }\n }\n }\n const isMobile: boolean = this.mobileRegex.test(req.headers['user-agent'])\n const authToken: string = await this.genAuthToken(user)\n const fileUrl = this.buildUrl(API_ONLY_OFFICE_DOCUMENT, space.url, authToken)\n const callBackUrl = this.buildUrl(API_ONLY_OFFICE_CALLBACK, space.url, authToken)\n const config: OnlyOfficeReqDto = await this.genConfiguration(user, space, mode, fileUrl, fileExtension, callBackUrl, isMobile, hasLock)\n config.config.token = await this.genPayloadToken(config.config)\n return config\n }\n\n async callBack(user: UserModel, space: SpaceEnv, token: string) {\n const callBackData: OnlyOfficeCallBack = await this.jwt.verifyAsync(token, { secret: configuration.applications.files.onlyoffice.secret })\n try {\n switch (callBackData.status) {\n case 1:\n // users connect / disconnect\n await this.checkFileLock(user, space, callBackData)\n this.logger.debug(`document is being edited : ${space.url}`)\n break\n case 2:\n // No active users on the document\n await this.checkFileLock(user, space, callBackData)\n if (callBackData.notmodified) {\n this.logger.debug(`document was edited but closed with no changes : ${space.url}`)\n } else {\n this.logger.debug(`document was edited and closed but not saved (let's do it) : ${space.url}`)\n await this.saveDocument(space, callBackData.url)\n }\n await this.removeFileLock(user.id, space)\n await this.removeDocumentKey(space)\n break\n case 3:\n this.logger.error(`document cannot be saved, an error has occurred (try to save it) : ${space.url}`)\n await this.saveDocument(space, callBackData.url)\n break\n case 4:\n // No active users on the document\n await this.removeFileLock(user.id, space)\n await this.removeDocumentKey(space)\n this.logger.debug(`document was closed with no changes : ${space.url}`)\n break\n case 6:\n this.logger.debug(`document is edited but save was requested : ${space.url}`)\n await this.saveDocument(space, callBackData.url)\n break\n case 7:\n this.logger.error(`document cannot be force saved, an error has occurred (try to save it) : ${space.url}`)\n await this.saveDocument(space, callBackData.url)\n break\n default:\n this.logger.error('unhandled case')\n }\n } catch (e) {\n this.logger.error(`${this.callBack.name} - ${e.message} : ${space.url}`)\n return { error: e.message }\n }\n return { error: 0 }\n }\n\n private async genConfiguration(\n user: UserModel,\n space: SpaceEnv,\n mode: FILE_MODE,\n fileUrl: string,\n fileExtension: string,\n callBackUrl: string,\n isMobile: boolean,\n hasLock: false | FileLockProps\n ): Promise<OnlyOfficeReqDto> {\n const canEdit = mode === FILE_MODE.EDIT\n const documentType = ONLY_OFFICE_EXTENSIONS.get(fileExtension)\n return {\n hasLock: hasLock,\n documentServerUrl: this.externalOnlyOfficeServer || `${this.contextManager.headerOriginUrl()}${ONLY_OFFICE_INTERNAL_URI}`,\n config: {\n type: isMobile ? 'mobile' : 'desktop',\n height: '100%',\n width: '100%',\n documentType: documentType,\n document: {\n title: path.basename(space.relativeUrl),\n fileType: fileExtension,\n key: await this.getDocumentKey(space),\n permissions: {\n download: true,\n edit: canEdit,\n changeHistory: false,\n comment: canEdit,\n fillForms: canEdit,\n print: true,\n review: canEdit\n },\n url: fileUrl\n },\n editorConfig: {\n mode: mode,\n lang: 'en',\n region: 'en',\n callbackUrl: callBackUrl,\n user: { id: user.id.toString(), name: `${user.fullName} (${user.email})`, image: await getAvatarBase64(user.login) },\n coEditing: {\n mode: 'fast',\n change: true\n },\n embedded: {\n embedUrl: fileUrl,\n saveUrl: fileUrl,\n shareUrl: fileUrl,\n toolbarDocked: 'top'\n },\n customization: {\n about: false,\n autosave: false,\n forcesave: true,\n zoom: documentType === 'slide' ? 60 : 90,\n help: false,\n features: { featuresTips: false },\n plugins: false\n }\n }\n }\n }\n }\n\n private buildUrl(basePath: string, spaceUrl: string, token: string): string {\n const url = new URL(`${basePath}/${spaceUrl}`, this.contextManager.headerOriginUrl())\n url.searchParams.set(ONLY_OFFICE_TOKEN_QUERY_PARAM_NAME, token)\n return url.toString()\n }\n\n private genPayloadToken(payload: OnlyOfficeConfig | OnlyOfficeConvertForm): Promise<string> {\n return this.jwt.signAsync(payload, { secret: configuration.applications.files.onlyoffice.secret, expiresIn: 60 })\n }\n\n private genAuthToken(user: UserModel): Promise<string> {\n // use refresh expiration to allow long sessions\n return this.jwt.signAsync(\n {\n identity: {\n id: user.id,\n login: user.login,\n email: user.email,\n fullName: user.fullName,\n language: user.language,\n role: user.role,\n applications: user.applications\n } satisfies JwtIdentityPayload\n },\n {\n secret: configuration.auth.token.access.secret,\n expiresIn: this.expiration\n }\n )\n }\n\n private async checkFileLock(user: UserModel, space: SpaceEnv, callBackData: OnlyOfficeCallBack) {\n for (const action of callBackData.actions) {\n if (action.type === 0) {\n // Disconnect\n // Remove the lock if no other users are active on the document\n if (!Array.isArray(callBackData.users)) {\n await this.removeFileLock(parseInt(action.userid), space)\n }\n } else if (action.type === 1) {\n // Connect\n // Create the lock if it's the first user to open the document\n if (Array.isArray(callBackData.users) && callBackData.users.length === 1) {\n await this.createFileLock(user, space)\n }\n }\n }\n }\n\n private async createFileLock(user: UserModel, space: SpaceEnv): Promise<void> {\n const [ok, _fileLock] = await this.filesLockManager.create(\n user,\n space.dbFile,\n ONLY_OFFICE_APP_LOCK,\n DEPTH.RESOURCE,\n {\n lockRoot: null,\n lockToken: null,\n lockScope: LOCK_SCOPE.SHARED\n } satisfies FileLockOptions,\n this.expiration\n )\n if (!ok) {\n throw new HttpException('The file is locked', HttpStatus.LOCKED)\n }\n }\n\n private async removeFileLock(userId: number, space: SpaceEnv): Promise<void> {\n for (const lock of await this.filesLockManager.getLocksByPath(space.dbFile)) {\n if (lock.owner.id === userId) {\n await this.filesLockManager.removeLock(lock.key)\n }\n }\n }\n\n private async removeDocumentKey(space: SpaceEnv): Promise<void> {\n if (!(await this.filesLockManager.isPathLocked(space.dbFile))) {\n const cacheKey = this.getCacheKey(space.dbFile)\n const r = await this.cache.del(cacheKey)\n this.logger.debug(`${this.removeDocumentKey.name} - ${cacheKey} ${r ? '' : 'not'} removed`)\n }\n }\n\n private async getDocumentKey(space: SpaceEnv): Promise<string> {\n // Uniq key to identify the document in OnlyOffice\n const cacheKey = this.getCacheKey(space.dbFile)\n const existingDocKey: string = await this.cache.get(cacheKey)\n if (existingDocKey) {\n return existingDocKey\n }\n const docKey = genEtag(null, space.realPath, false)\n await this.cache.set(cacheKey, docKey, this.expiration)\n this.logger.debug(`${this.getDocumentKey.name} - ${cacheKey} (${docKey}) created`)\n return docKey\n }\n\n private async saveDocument(space: SpaceEnv, url: string): Promise<void> {\n /* url format:\n https://onlyoffice-server.com/cache/files/data/-33120641_7158/output.pptx/output.pptx\n ?md5=duFHKC-5d47s-RRcYn3hAw&expires=1739400549&shardkey=-33120641&filename=output.pptx\n */\n const urlParams = new URLSearchParams(url.split('?').at(-1))\n // it is not the md5 of the file but the md5 generated by the combination of the elements of the url\n const md5: string = urlParams.get('md5')\n const tmpFilePath = await uniqueFilePathFromDir(path.join(os.tmpdir(), `${md5}-${urlParams.get('filename')}`))\n\n // convert the remote file to the local file with the current extension if these extensions aren't equal\n const localExtension = path.extname(space.realPath).slice(1)\n const remoteExtension = path.extname(urlParams.get('filename')).slice(1)\n\n let downloadUrl: string\n if (localExtension !== remoteExtension && !ONLY_OFFICE_CONVERT_EXTENSIONS.ALLOW_AUTO.has(localExtension)) {\n if (ONLY_OFFICE_CONVERT_EXTENSIONS.FROM.has(remoteExtension) && ONLY_OFFICE_CONVERT_EXTENSIONS.TO.has(localExtension)) {\n downloadUrl = await this.convertDocument(urlParams.get('shardkey'), url, remoteExtension, localExtension, space.url)\n } else {\n throw new Error(`document cannot be converted from ${remoteExtension} -> ${localExtension} : ${space.url}`)\n }\n } else {\n downloadUrl = url\n }\n\n // download file\n let res: AxiosResponse\n try {\n res = await this.http.axiosRef({\n method: HTTP_METHOD.GET,\n url: downloadUrl,\n responseType: 'stream',\n httpsAgent: new https.Agent({ rejectUnauthorized: this.rejectUnauthorized })\n })\n await writeFromStream(tmpFilePath, res.data)\n } catch (e) {\n throw new Error(`unable to get document : ${e.message}`)\n }\n\n // try to verify the downloaded size\n const contentLength = parseInt(res.headers['content-length'], 10)\n if (!isNaN(contentLength) && contentLength !== 0) {\n const tmpFileSize = await fileSize(tmpFilePath)\n if (tmpFileSize !== contentLength) {\n throw new Error(`document size differs (${tmpFileSize} != ${contentLength})`)\n }\n } else if (contentLength === 0) {\n this.logger.warn(`${this.saveDocument.name} - content length is 0 : ${space.url}`)\n }\n // copy contents to avoid inode changes (`file.id` in some cases)\n try {\n // todo: versioning\n await copyFileContent(tmpFilePath, space.realPath)\n await removeFiles(tmpFilePath)\n } catch (e) {\n throw new Error(`unable to save document : ${e.message}`)\n }\n }\n\n private async convertDocument(id: string, url: string, fileType: string, outputType: string, spaceUrl: string): Promise<string> {\n const key: string = `${id}-${crypto.randomBytes(20).toString('hex')}`.slice(0, 20).replace('-', '_')\n const payload: OnlyOfficeConvertForm = {\n key: key,\n url: url,\n filetype: fileType,\n outputtype: outputType,\n async: false\n }\n payload.token = await this.genPayloadToken(payload)\n let result: { fileUrl?: string; fileType?: string; endConvert?: boolean; error?: number }\n try {\n const res: AxiosResponse = await this.http.axiosRef({\n method: HTTP_METHOD.POST,\n url: this.convertUrl,\n data: payload,\n httpsAgent: new https.Agent({ rejectUnauthorized: this.rejectUnauthorized })\n })\n result = res.data\n } catch (e) {\n throw new Error(`convert failed with status : ${e.response.status}`)\n }\n if (result.error) {\n throw new Error(`convert failed with reason : ${ONLY_OFFICE_CONVERT_ERROR.get(result.error)}`)\n }\n if (result.endConvert) {\n this.logger.log(`${this.convertDocument.name} - ${fileType} -> ${outputType} : ${spaceUrl}`)\n return result.fileUrl\n }\n }\n\n private getCacheKey(dbFile: FileDBProps): string {\n return `${ONLY_OFFICE_CACHE_KEY}|${genUniqHashFromFileDBProps(dbFile)}`\n }\n}\n"],"names":["OnlyOfficeManager","getSettings","user","space","req","isPathExists","realPath","HttpException","HttpStatus","BAD_REQUEST","isPathIsDir","fileExtension","path","extname","slice","ONLY_OFFICE_EXTENSIONS","has","hasLock","mode","haveSpaceEnvPermissions","SPACE_OPERATION","MODIFY","FILE_MODE","EDIT","VIEW","filesLockManager","checkConflicts","dbFile","DEPTH","RESOURCE","userId","id","app","ONLY_OFFICE_APP_LOCK","lockScope","LOCK_SCOPE","SHARED","e","LockConflict","convertLockToFileLockProps","lock","logger","error","name","INTERNAL_SERVER_ERROR","isMobile","mobileRegex","test","headers","authToken","genAuthToken","fileUrl","buildUrl","API_ONLY_OFFICE_DOCUMENT","url","callBackUrl","API_ONLY_OFFICE_CALLBACK","config","genConfiguration","token","genPayloadToken","callBack","callBackData","jwt","verifyAsync","secret","configuration","applications","files","onlyoffice","status","checkFileLock","debug","notmodified","saveDocument","removeFileLock","removeDocumentKey","message","canEdit","documentType","get","documentServerUrl","externalOnlyOfficeServer","contextManager","headerOriginUrl","ONLY_OFFICE_INTERNAL_URI","type","height","width","document","title","basename","relativeUrl","fileType","key","getDocumentKey","permissions","download","edit","changeHistory","comment","fillForms","print","review","editorConfig","lang","region","callbackUrl","toString","fullName","email","image","getAvatarBase64","login","coEditing","change","embedded","embedUrl","saveUrl","shareUrl","toolbarDocked","customization","about","autosave","forcesave","zoom","help","features","featuresTips","plugins","basePath","spaceUrl","URL","searchParams","set","ONLY_OFFICE_TOKEN_QUERY_PARAM_NAME","payload","signAsync","expiresIn","identity","language","role","auth","access","expiration","action","actions","Array","isArray","users","parseInt","userid","length","createFileLock","ok","_fileLock","create","lockRoot","lockToken","LOCKED","getLocksByPath","owner","removeLock","isPathLocked","cacheKey","getCacheKey","r","cache","del","existingDocKey","docKey","genEtag","urlParams","URLSearchParams","split","at","md5","tmpFilePath","uniqueFilePathFromDir","join","os","tmpdir","localExtension","remoteExtension","downloadUrl","ONLY_OFFICE_CONVERT_EXTENSIONS","ALLOW_AUTO","FROM","TO","convertDocument","Error","res","http","axiosRef","method","HTTP_METHOD","GET","responseType","httpsAgent","https","Agent","rejectUnauthorized","writeFromStream","data","contentLength","isNaN","tmpFileSize","fileSize","warn","copyFileContent","removeFiles","outputType","crypto","randomBytes","replace","filetype","outputtype","async","result","POST","convertUrl","response","ONLY_OFFICE_CONVERT_ERROR","endConvert","log","ONLY_OFFICE_CACHE_KEY","genUniqHashFromFileDBProps","Logger","externalServer","verifySSL","convertHumanTimeToSeconds","refresh"],"mappings":"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"}