@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/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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"}
@@ -0,0 +1,477 @@
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 _axios = require("@nestjs/axios");
10
+ const _common = require("@nestjs/common");
11
+ const _jwt = require("@nestjs/jwt");
12
+ const _testing = require("@nestjs/testing");
13
+ const _stream = require("stream");
14
+ const _cacheservice = require("../../../../infrastructure/cache/services/cache.service");
15
+ const _contextmanagerservice = require("../../../../infrastructure/context/services/context-manager.service");
16
+ const _webdav = require("../../../webdav/constants/webdav");
17
+ const _operations = require("../../constants/operations");
18
+ const _filelockerror = require("../../models/file-lock-error");
19
+ const _fileslockmanagerservice = require("../../services/files-lock-manager.service");
20
+ const _files = /*#__PURE__*/ _interop_require_wildcard(require("../../utils/files"));
21
+ const _onlyofficemanagerservice = require("./only-office-manager.service");
22
+ const _onlyofficeconstants = require("./only-office.constants");
23
+ function _getRequireWildcardCache(nodeInterop) {
24
+ if (typeof WeakMap !== "function") return null;
25
+ var cacheBabelInterop = new WeakMap();
26
+ var cacheNodeInterop = new WeakMap();
27
+ return (_getRequireWildcardCache = function(nodeInterop) {
28
+ return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
29
+ })(nodeInterop);
30
+ }
31
+ function _interop_require_wildcard(obj, nodeInterop) {
32
+ if (!nodeInterop && obj && obj.__esModule) {
33
+ return obj;
34
+ }
35
+ if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
36
+ return {
37
+ default: obj
38
+ };
39
+ }
40
+ var cache = _getRequireWildcardCache(nodeInterop);
41
+ if (cache && cache.has(obj)) {
42
+ return cache.get(obj);
43
+ }
44
+ var newObj = {
45
+ __proto__: null
46
+ };
47
+ var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
48
+ for(var key in obj){
49
+ if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
50
+ var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
51
+ if (desc && (desc.get || desc.set)) {
52
+ Object.defineProperty(newObj, key, desc);
53
+ } else {
54
+ newObj[key] = obj[key];
55
+ }
56
+ }
57
+ }
58
+ newObj.default = obj;
59
+ if (cache) {
60
+ cache.set(obj, newObj);
61
+ }
62
+ return newObj;
63
+ }
64
+ jest.mock('../../utils/files');
65
+ jest.mock('../../../users/utils/avatar', ()=>({
66
+ getAvatarBase64: jest.fn().mockResolvedValue('data:image/png;base64,iVBORw0KGgo=')
67
+ }));
68
+ describe(_onlyofficemanagerservice.OnlyOfficeManager.name, ()=>{
69
+ let service;
70
+ let cache;
71
+ let httpService;
72
+ let jwtService;
73
+ let filesLockManager;
74
+ const mockUser = {
75
+ id: 1,
76
+ login: 'testuser',
77
+ email: 'test@example.com',
78
+ fullName: 'Test User',
79
+ language: 'en',
80
+ role: 'user',
81
+ applications: []
82
+ };
83
+ const mockSpaceEnv = {
84
+ realPath: '/real/path/document.docx',
85
+ relativeUrl: '/document.docx',
86
+ url: 'space/document.docx',
87
+ dbFile: {
88
+ directory: '/space',
89
+ name: 'document.docx',
90
+ storageId: 1,
91
+ storageTypeId: 1
92
+ },
93
+ permissions: 'r,m,d',
94
+ envPermissions: 'r,m,d'
95
+ };
96
+ const mockRequest = {
97
+ headers: {
98
+ 'user-agent': 'Mozilla/5.0'
99
+ }
100
+ };
101
+ beforeEach(async ()=>{
102
+ const module = await _testing.Test.createTestingModule({
103
+ providers: [
104
+ _onlyofficemanagerservice.OnlyOfficeManager,
105
+ {
106
+ provide: _cacheservice.Cache,
107
+ useValue: {
108
+ get: jest.fn(),
109
+ set: jest.fn(),
110
+ del: jest.fn()
111
+ }
112
+ },
113
+ {
114
+ provide: _axios.HttpService,
115
+ useValue: {
116
+ axiosRef: jest.fn()
117
+ }
118
+ },
119
+ {
120
+ provide: _jwt.JwtService,
121
+ useValue: {
122
+ signAsync: jest.fn(),
123
+ verifyAsync: jest.fn()
124
+ }
125
+ },
126
+ {
127
+ provide: _contextmanagerservice.ContextManager,
128
+ useValue: {
129
+ headerOriginUrl: jest.fn().mockReturnValue('http://localhost:3000')
130
+ }
131
+ },
132
+ {
133
+ provide: _fileslockmanagerservice.FilesLockManager,
134
+ useValue: {
135
+ checkConflicts: jest.fn(),
136
+ convertLockToFileLockProps: jest.fn(),
137
+ create: jest.fn(),
138
+ getLocksByPath: jest.fn(),
139
+ removeLock: jest.fn(),
140
+ isPathLocked: jest.fn()
141
+ }
142
+ }
143
+ ]
144
+ }).compile();
145
+ module.useLogger([
146
+ 'fatal'
147
+ ]);
148
+ service = module.get(_onlyofficemanagerservice.OnlyOfficeManager);
149
+ cache = module.get(_cacheservice.Cache);
150
+ httpService = module.get(_axios.HttpService);
151
+ jwtService = module.get(_jwt.JwtService);
152
+ filesLockManager = module.get(_fileslockmanagerservice.FilesLockManager);
153
+ });
154
+ afterEach(()=>{
155
+ jest.clearAllMocks();
156
+ });
157
+ describe('getSettings', ()=>{
158
+ beforeEach(()=>{
159
+ ;
160
+ _files.isPathExists.mockResolvedValue(true);
161
+ _files.isPathIsDir.mockResolvedValue(false);
162
+ filesLockManager.checkConflicts.mockResolvedValue(undefined);
163
+ jwtService.signAsync.mockResolvedValue('mock-token');
164
+ cache.get.mockResolvedValue(null);
165
+ cache.set.mockResolvedValue(undefined);
166
+ _files.genEtag.mockReturnValue('mock-etag');
167
+ });
168
+ it('should return OnlyOffice settings for editable document', async ()=>{
169
+ const result = await service.getSettings(mockUser, mockSpaceEnv, mockRequest);
170
+ expect(result).toBeDefined();
171
+ expect(result.config.documentType).toBe('word');
172
+ expect(result.config.editorConfig.mode).toBe(_operations.FILE_MODE.EDIT);
173
+ expect(result.config.document.permissions.edit).toBe(true);
174
+ expect(result.hasLock).toBe(false);
175
+ });
176
+ it('should throw error if document does not exist', async ()=>{
177
+ ;
178
+ _files.isPathExists.mockResolvedValue(false);
179
+ await expect(service.getSettings(mockUser, mockSpaceEnv, mockRequest)).rejects.toThrow(new _common.HttpException('Document not found', _common.HttpStatus.BAD_REQUEST));
180
+ });
181
+ it('should throw error if path is a directory', async ()=>{
182
+ ;
183
+ _files.isPathIsDir.mockResolvedValue(true);
184
+ await expect(service.getSettings(mockUser, mockSpaceEnv, mockRequest)).rejects.toThrow(new _common.HttpException('Document must be a file', _common.HttpStatus.BAD_REQUEST));
185
+ });
186
+ it('should throw error if document extension is not supported', async ()=>{
187
+ const unsupportedSpaceEnv = {
188
+ ...mockSpaceEnv,
189
+ realPath: '/real/path/document.xyz'
190
+ };
191
+ await expect(service.getSettings(mockUser, unsupportedSpaceEnv, mockRequest)).rejects.toThrow(new _common.HttpException('Document not supported', _common.HttpStatus.BAD_REQUEST));
192
+ });
193
+ it('should set mode to VIEW when file has lock conflict', async ()=>{
194
+ const mockLock = {
195
+ key: 'lock-key',
196
+ app: _onlyofficeconstants.ONLY_OFFICE_APP_LOCK,
197
+ owner: {
198
+ id: 2,
199
+ login: 'otheruser'
200
+ }
201
+ };
202
+ const lockError = new _filelockerror.LockConflict(mockLock, 'File is locked');
203
+ filesLockManager.checkConflicts.mockRejectedValue(lockError);
204
+ filesLockManager.convertLockToFileLockProps.mockReturnValue({
205
+ owner: {
206
+ id: 2,
207
+ login: 'otheruser'
208
+ }
209
+ });
210
+ const result = await service.getSettings(mockUser, mockSpaceEnv, mockRequest);
211
+ expect(result.config.editorConfig.mode).toBe(_operations.FILE_MODE.VIEW);
212
+ expect(result.config.document.permissions.edit).toBe(false);
213
+ expect(result.hasLock).toBeDefined();
214
+ });
215
+ it('should set mode to VIEW when user does not have modify permissions', async ()=>{
216
+ const viewOnlySpaceEnv = {
217
+ ...mockSpaceEnv,
218
+ permissions: 'r',
219
+ envPermissions: 'r'
220
+ };
221
+ const result = await service.getSettings(mockUser, viewOnlySpaceEnv, mockRequest);
222
+ expect(result.config.editorConfig.mode).toBe(_operations.FILE_MODE.VIEW);
223
+ expect(result.config.document.permissions.edit).toBe(false);
224
+ });
225
+ it('should detect mobile user agent', async ()=>{
226
+ const mobileRequest = {
227
+ headers: {
228
+ 'user-agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 14_0 like Mac OS X)'
229
+ }
230
+ };
231
+ const result = await service.getSettings(mockUser, mockSpaceEnv, mobileRequest);
232
+ expect(result.config.type).toBe('mobile');
233
+ });
234
+ it('should use cached document key', async ()=>{
235
+ cache.get.mockResolvedValue('cached-doc-key');
236
+ const result = await service.getSettings(mockUser, mockSpaceEnv, mockRequest);
237
+ expect(result.config.document.key).toBe('cached-doc-key');
238
+ expect(cache.set).not.toHaveBeenCalled();
239
+ });
240
+ });
241
+ describe('callBack', ()=>{
242
+ const mockToken = 'mock-callback-token';
243
+ beforeEach(()=>{
244
+ filesLockManager.removeLock.mockResolvedValue(undefined);
245
+ filesLockManager.getLocksByPath.mockResolvedValue([]);
246
+ filesLockManager.isPathLocked.mockResolvedValue(false);
247
+ cache.del.mockResolvedValue(true);
248
+ _files.uniqueFilePathFromDir.mockResolvedValue('/tmp/temp-file.docx');
249
+ _files.writeFromStream.mockResolvedValue(undefined);
250
+ _files.fileSize.mockResolvedValue(12);
251
+ _files.copyFileContent.mockResolvedValue(undefined);
252
+ _files.removeFiles.mockResolvedValue(undefined);
253
+ });
254
+ it('should handle status 1 (document being edited)', async ()=>{
255
+ jwtService.verifyAsync.mockResolvedValue({
256
+ status: 1,
257
+ actions: [],
258
+ users: [
259
+ '1'
260
+ ]
261
+ });
262
+ const result = await service.callBack(mockUser, mockSpaceEnv, mockToken);
263
+ expect(result).toEqual({
264
+ error: 0
265
+ });
266
+ });
267
+ it('should handle status 2 (document closed with changes)', async ()=>{
268
+ jwtService.verifyAsync.mockResolvedValue({
269
+ status: 2,
270
+ actions: [],
271
+ users: [],
272
+ notmodified: false,
273
+ url: 'http://onlyoffice/document.docx?md5=abc123&expires=1739400549&shardkey=-33120641&filename=document.docx'
274
+ });
275
+ const mockStream = _stream.Readable.from([
276
+ 'mock content'
277
+ ]);
278
+ httpService.axiosRef.mockResolvedValue({
279
+ data: mockStream,
280
+ headers: {
281
+ 'content-length': '12'
282
+ },
283
+ status: 200,
284
+ statusText: 'OK',
285
+ config: {}
286
+ });
287
+ const result = await service.callBack(mockUser, mockSpaceEnv, mockToken);
288
+ expect(result).toEqual({
289
+ error: 0
290
+ });
291
+ expect(httpService.axiosRef).toHaveBeenCalled();
292
+ });
293
+ it('should handle status 2 (document closed without changes)', async ()=>{
294
+ jwtService.verifyAsync.mockResolvedValue({
295
+ status: 2,
296
+ actions: [],
297
+ users: [],
298
+ notmodified: true
299
+ });
300
+ const result = await service.callBack(mockUser, mockSpaceEnv, mockToken);
301
+ expect(result).toEqual({
302
+ error: 0
303
+ });
304
+ expect(httpService.axiosRef).not.toHaveBeenCalled();
305
+ });
306
+ it('should handle status 3 (error saving document)', async ()=>{
307
+ jwtService.verifyAsync.mockResolvedValue({
308
+ status: 3,
309
+ actions: [],
310
+ url: 'http://onlyoffice/document.docx?md5=abc123&expires=1739400549&shardkey=-33120641&filename=document.docx'
311
+ });
312
+ const mockStream = _stream.Readable.from([
313
+ 'mock content'
314
+ ]);
315
+ httpService.axiosRef.mockResolvedValue({
316
+ data: mockStream,
317
+ headers: {
318
+ 'content-length': '12'
319
+ },
320
+ status: 200,
321
+ statusText: 'OK',
322
+ config: {}
323
+ });
324
+ const result = await service.callBack(mockUser, mockSpaceEnv, mockToken);
325
+ expect(result).toEqual({
326
+ error: 0
327
+ });
328
+ expect(httpService.axiosRef).toHaveBeenCalled();
329
+ });
330
+ it('should handle status 4 (document closed with no changes)', async ()=>{
331
+ jwtService.verifyAsync.mockResolvedValue({
332
+ status: 4,
333
+ actions: []
334
+ });
335
+ const result = await service.callBack(mockUser, mockSpaceEnv, mockToken);
336
+ expect(result).toEqual({
337
+ error: 0
338
+ });
339
+ });
340
+ it('should handle status 6 (force save)', async ()=>{
341
+ jwtService.verifyAsync.mockResolvedValue({
342
+ status: 6,
343
+ actions: [],
344
+ url: 'http://onlyoffice/document.docx?md5=abc123&expires=1739400549&shardkey=-33120641&filename=document.docx'
345
+ });
346
+ const mockStream = _stream.Readable.from([
347
+ 'mock content'
348
+ ]);
349
+ httpService.axiosRef.mockResolvedValue({
350
+ data: mockStream,
351
+ headers: {
352
+ 'content-length': '12'
353
+ },
354
+ status: 200,
355
+ statusText: 'OK',
356
+ config: {}
357
+ });
358
+ const result = await service.callBack(mockUser, mockSpaceEnv, mockToken);
359
+ expect(result).toEqual({
360
+ error: 0
361
+ });
362
+ });
363
+ it('should handle status 7 (error force saving)', async ()=>{
364
+ jwtService.verifyAsync.mockResolvedValue({
365
+ status: 7,
366
+ actions: [],
367
+ url: 'http://onlyoffice/document.docx?md5=abc123&expires=1739400549&shardkey=-33120641&filename=document.docx'
368
+ });
369
+ const mockStream = _stream.Readable.from([
370
+ 'mock content'
371
+ ]);
372
+ httpService.axiosRef.mockResolvedValue({
373
+ data: mockStream,
374
+ headers: {
375
+ 'content-length': '12'
376
+ },
377
+ status: 200,
378
+ statusText: 'OK',
379
+ config: {}
380
+ });
381
+ const result = await service.callBack(mockUser, mockSpaceEnv, mockToken);
382
+ expect(result).toEqual({
383
+ error: 0
384
+ });
385
+ });
386
+ it('should handle user connect action (type 1)', async ()=>{
387
+ jwtService.verifyAsync.mockResolvedValue({
388
+ status: 1,
389
+ actions: [
390
+ {
391
+ type: 1,
392
+ userid: '1'
393
+ }
394
+ ],
395
+ users: [
396
+ '1'
397
+ ]
398
+ });
399
+ filesLockManager.create.mockResolvedValue([
400
+ true,
401
+ {}
402
+ ]);
403
+ const result = await service.callBack(mockUser, mockSpaceEnv, mockToken);
404
+ expect(result).toEqual({
405
+ error: 0
406
+ });
407
+ expect(filesLockManager.create).toHaveBeenCalledWith(mockUser, mockSpaceEnv.dbFile, _onlyofficeconstants.ONLY_OFFICE_APP_LOCK, _webdav.DEPTH.RESOURCE, {
408
+ lockRoot: null,
409
+ lockToken: null,
410
+ lockScope: _webdav.LOCK_SCOPE.SHARED
411
+ }, expect.any(Number));
412
+ });
413
+ it('should handle user disconnect action (type 0)', async ()=>{
414
+ jwtService.verifyAsync.mockResolvedValue({
415
+ status: 1,
416
+ actions: [
417
+ {
418
+ type: 0,
419
+ userid: '1'
420
+ }
421
+ ],
422
+ users: undefined
423
+ });
424
+ filesLockManager.getLocksByPath.mockResolvedValue([
425
+ {
426
+ key: 'lock-key',
427
+ owner: {
428
+ id: 1
429
+ }
430
+ }
431
+ ]);
432
+ const result = await service.callBack(mockUser, mockSpaceEnv, mockToken);
433
+ expect(result).toEqual({
434
+ error: 0
435
+ });
436
+ expect(filesLockManager.removeLock).toHaveBeenCalledWith('lock-key');
437
+ });
438
+ it('should return error when callback fails', async ()=>{
439
+ jwtService.verifyAsync.mockResolvedValue({
440
+ status: 2,
441
+ actions: [],
442
+ notmodified: false,
443
+ url: 'http://onlyoffice/document.docx?md5=abc123&expires=1739400549&shardkey=-33120641&filename=document.docx'
444
+ });
445
+ httpService.axiosRef.mockRejectedValue(new Error('Network error'));
446
+ const result = await service.callBack(mockUser, mockSpaceEnv, mockToken);
447
+ expect(result).toHaveProperty('error');
448
+ expect(result.error).not.toBe(0);
449
+ });
450
+ it('should throw error when file lock creation fails', async ()=>{
451
+ jwtService.verifyAsync.mockResolvedValue({
452
+ status: 1,
453
+ actions: [
454
+ {
455
+ type: 1,
456
+ userid: '1'
457
+ }
458
+ ],
459
+ users: [
460
+ '1'
461
+ ]
462
+ });
463
+ filesLockManager.create.mockResolvedValue([
464
+ false,
465
+ null
466
+ ]);
467
+ const result = await service.callBack(mockUser, mockSpaceEnv, mockToken);
468
+ expect(result).toHaveProperty('error');
469
+ expect(result.error).not.toBe(0);
470
+ });
471
+ });
472
+ it('should be defined', ()=>{
473
+ expect(service).toBeDefined();
474
+ });
475
+ });
476
+
477
+ //# sourceMappingURL=only-office-manager.service.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../backend/src/applications/files/modules/only-office/only-office-manager.service.spec.ts"],"sourcesContent":["/*\n * Copyright (C) 2012-2025 Johan Legrand <johan.legrand@sync-in.com>\n * This file is part of Sync-in | The open source file sync and share solution\n * See the LICENSE file for licensing details\n */\n\nimport { HttpService } from '@nestjs/axios'\nimport { HttpException, HttpStatus } from '@nestjs/common'\nimport { JwtService } from '@nestjs/jwt'\nimport { Test, TestingModule } from '@nestjs/testing'\nimport { AxiosResponse } from 'axios'\nimport { Readable } from 'stream'\nimport { Cache } from '../../../../infrastructure/cache/services/cache.service'\nimport { ContextManager } from '../../../../infrastructure/context/services/context-manager.service'\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 { LockConflict } from '../../models/file-lock-error'\nimport { FilesLockManager } from '../../services/files-lock-manager.service'\nimport * as filesUtils from '../../utils/files'\nimport { OnlyOfficeManager } from './only-office-manager.service'\nimport { ONLY_OFFICE_APP_LOCK } from './only-office.constants'\n\njest.mock('../../utils/files')\njest.mock('../../../users/utils/avatar', () => ({\n getAvatarBase64: jest.fn().mockResolvedValue('data:image/png;base64,iVBORw0KGgo=')\n}))\n\ndescribe(OnlyOfficeManager.name, () => {\n let service: OnlyOfficeManager\n let cache: jest.Mocked<Cache>\n let httpService: jest.Mocked<HttpService>\n let jwtService: jest.Mocked<JwtService>\n let filesLockManager: jest.Mocked<FilesLockManager>\n\n const mockUser = {\n id: 1,\n login: 'testuser',\n email: 'test@example.com',\n fullName: 'Test User',\n language: 'en',\n role: 'user',\n applications: []\n } as unknown as UserModel\n\n const mockSpaceEnv = {\n realPath: '/real/path/document.docx',\n relativeUrl: '/document.docx',\n url: 'space/document.docx',\n dbFile: {\n directory: '/space',\n name: 'document.docx',\n storageId: 1,\n storageTypeId: 1\n },\n permissions: 'r,m,d',\n envPermissions: 'r,m,d'\n } as unknown as SpaceEnv\n\n const mockRequest = {\n headers: {\n 'user-agent': 'Mozilla/5.0'\n }\n } as any\n\n beforeEach(async () => {\n const module: TestingModule = await Test.createTestingModule({\n providers: [\n OnlyOfficeManager,\n {\n provide: Cache,\n useValue: {\n get: jest.fn(),\n set: jest.fn(),\n del: jest.fn()\n }\n },\n {\n provide: HttpService,\n useValue: {\n axiosRef: jest.fn()\n }\n },\n {\n provide: JwtService,\n useValue: {\n signAsync: jest.fn(),\n verifyAsync: jest.fn()\n }\n },\n {\n provide: ContextManager,\n useValue: {\n headerOriginUrl: jest.fn().mockReturnValue('http://localhost:3000')\n }\n },\n {\n provide: FilesLockManager,\n useValue: {\n checkConflicts: jest.fn(),\n convertLockToFileLockProps: jest.fn(),\n create: jest.fn(),\n getLocksByPath: jest.fn(),\n removeLock: jest.fn(),\n isPathLocked: jest.fn()\n }\n }\n ]\n }).compile()\n\n module.useLogger(['fatal'])\n service = module.get<OnlyOfficeManager>(OnlyOfficeManager)\n cache = module.get(Cache)\n httpService = module.get(HttpService)\n jwtService = module.get(JwtService)\n filesLockManager = module.get(FilesLockManager)\n })\n\n afterEach(() => {\n jest.clearAllMocks()\n })\n\n describe('getSettings', () => {\n beforeEach(() => {\n ;(filesUtils.isPathExists as jest.Mock).mockResolvedValue(true)\n ;(filesUtils.isPathIsDir as jest.Mock).mockResolvedValue(false)\n filesLockManager.checkConflicts.mockResolvedValue(undefined)\n jwtService.signAsync.mockResolvedValue('mock-token')\n cache.get.mockResolvedValue(null)\n cache.set.mockResolvedValue(undefined)\n ;(filesUtils.genEtag as jest.Mock).mockReturnValue('mock-etag')\n })\n\n it('should return OnlyOffice settings for editable document', async () => {\n const result = await service.getSettings(mockUser, mockSpaceEnv, mockRequest)\n\n expect(result).toBeDefined()\n expect(result.config.documentType).toBe('word')\n expect(result.config.editorConfig.mode).toBe(FILE_MODE.EDIT)\n expect(result.config.document.permissions.edit).toBe(true)\n expect(result.hasLock).toBe(false)\n })\n\n it('should throw error if document does not exist', async () => {\n ;(filesUtils.isPathExists as jest.Mock).mockResolvedValue(false)\n\n await expect(service.getSettings(mockUser, mockSpaceEnv, mockRequest)).rejects.toThrow(\n new HttpException('Document not found', HttpStatus.BAD_REQUEST)\n )\n })\n\n it('should throw error if path is a directory', async () => {\n ;(filesUtils.isPathIsDir as jest.Mock).mockResolvedValue(true)\n\n await expect(service.getSettings(mockUser, mockSpaceEnv, mockRequest)).rejects.toThrow(\n new HttpException('Document must be a file', HttpStatus.BAD_REQUEST)\n )\n })\n\n it('should throw error if document extension is not supported', async () => {\n const unsupportedSpaceEnv = {\n ...mockSpaceEnv,\n realPath: '/real/path/document.xyz'\n } as unknown as SpaceEnv\n\n await expect(service.getSettings(mockUser, unsupportedSpaceEnv, mockRequest)).rejects.toThrow(\n new HttpException('Document not supported', HttpStatus.BAD_REQUEST)\n )\n })\n\n it('should set mode to VIEW when file has lock conflict', async () => {\n const mockLock = {\n key: 'lock-key',\n app: ONLY_OFFICE_APP_LOCK,\n owner: { id: 2, login: 'otheruser' }\n } as any\n const lockError = new LockConflict(mockLock, 'File is locked')\n filesLockManager.checkConflicts.mockRejectedValue(lockError)\n filesLockManager.convertLockToFileLockProps.mockReturnValue({\n owner: { id: 2, login: 'otheruser' }\n } as any)\n\n const result = await service.getSettings(mockUser, mockSpaceEnv, mockRequest)\n\n expect(result.config.editorConfig.mode).toBe(FILE_MODE.VIEW)\n expect(result.config.document.permissions.edit).toBe(false)\n expect(result.hasLock).toBeDefined()\n })\n\n it('should set mode to VIEW when user does not have modify permissions', async () => {\n const viewOnlySpaceEnv = {\n ...mockSpaceEnv,\n permissions: 'r',\n envPermissions: 'r'\n } as unknown as SpaceEnv\n\n const result = await service.getSettings(mockUser, viewOnlySpaceEnv, mockRequest)\n\n expect(result.config.editorConfig.mode).toBe(FILE_MODE.VIEW)\n expect(result.config.document.permissions.edit).toBe(false)\n })\n\n it('should detect mobile user agent', async () => {\n const mobileRequest = {\n headers: {\n 'user-agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 14_0 like Mac OS X)'\n }\n } as any\n\n const result = await service.getSettings(mockUser, mockSpaceEnv, mobileRequest)\n\n expect(result.config.type).toBe('mobile')\n })\n\n it('should use cached document key', async () => {\n cache.get.mockResolvedValue('cached-doc-key')\n\n const result = await service.getSettings(mockUser, mockSpaceEnv, mockRequest)\n\n expect(result.config.document.key).toBe('cached-doc-key')\n expect(cache.set).not.toHaveBeenCalled()\n })\n })\n\n describe('callBack', () => {\n const mockToken = 'mock-callback-token'\n\n beforeEach(() => {\n filesLockManager.removeLock.mockResolvedValue(undefined)\n filesLockManager.getLocksByPath.mockResolvedValue([])\n filesLockManager.isPathLocked.mockResolvedValue(false)\n cache.del.mockResolvedValue(true)\n ;(filesUtils.uniqueFilePathFromDir as jest.Mock).mockResolvedValue('/tmp/temp-file.docx')\n ;(filesUtils.writeFromStream as jest.Mock).mockResolvedValue(undefined)\n ;(filesUtils.fileSize as jest.Mock).mockResolvedValue(12)\n ;(filesUtils.copyFileContent as jest.Mock).mockResolvedValue(undefined)\n ;(filesUtils.removeFiles as jest.Mock).mockResolvedValue(undefined)\n })\n\n it('should handle status 1 (document being edited)', async () => {\n jwtService.verifyAsync.mockResolvedValue({\n status: 1,\n actions: [],\n users: ['1']\n })\n\n const result = await service.callBack(mockUser, mockSpaceEnv, mockToken)\n\n expect(result).toEqual({ error: 0 })\n })\n\n it('should handle status 2 (document closed with changes)', async () => {\n jwtService.verifyAsync.mockResolvedValue({\n status: 2,\n actions: [],\n users: [],\n notmodified: false,\n url: 'http://onlyoffice/document.docx?md5=abc123&expires=1739400549&shardkey=-33120641&filename=document.docx'\n })\n\n const mockStream = Readable.from(['mock content'])\n httpService.axiosRef.mockResolvedValue({\n data: mockStream,\n headers: { 'content-length': '12' },\n status: 200,\n statusText: 'OK',\n config: {} as any\n } as AxiosResponse)\n\n const result = await service.callBack(mockUser, mockSpaceEnv, mockToken)\n\n expect(result).toEqual({ error: 0 })\n expect(httpService.axiosRef).toHaveBeenCalled()\n })\n\n it('should handle status 2 (document closed without changes)', async () => {\n jwtService.verifyAsync.mockResolvedValue({\n status: 2,\n actions: [],\n users: [],\n notmodified: true\n })\n\n const result = await service.callBack(mockUser, mockSpaceEnv, mockToken)\n\n expect(result).toEqual({ error: 0 })\n expect(httpService.axiosRef).not.toHaveBeenCalled()\n })\n\n it('should handle status 3 (error saving document)', async () => {\n jwtService.verifyAsync.mockResolvedValue({\n status: 3,\n actions: [],\n url: 'http://onlyoffice/document.docx?md5=abc123&expires=1739400549&shardkey=-33120641&filename=document.docx'\n })\n\n const mockStream = Readable.from(['mock content'])\n httpService.axiosRef.mockResolvedValue({\n data: mockStream,\n headers: { 'content-length': '12' },\n status: 200,\n statusText: 'OK',\n config: {} as any\n } as AxiosResponse)\n\n const result = await service.callBack(mockUser, mockSpaceEnv, mockToken)\n\n expect(result).toEqual({ error: 0 })\n expect(httpService.axiosRef).toHaveBeenCalled()\n })\n\n it('should handle status 4 (document closed with no changes)', async () => {\n jwtService.verifyAsync.mockResolvedValue({\n status: 4,\n actions: []\n })\n\n const result = await service.callBack(mockUser, mockSpaceEnv, mockToken)\n\n expect(result).toEqual({ error: 0 })\n })\n\n it('should handle status 6 (force save)', async () => {\n jwtService.verifyAsync.mockResolvedValue({\n status: 6,\n actions: [],\n url: 'http://onlyoffice/document.docx?md5=abc123&expires=1739400549&shardkey=-33120641&filename=document.docx'\n })\n\n const mockStream = Readable.from(['mock content'])\n httpService.axiosRef.mockResolvedValue({\n data: mockStream,\n headers: { 'content-length': '12' },\n status: 200,\n statusText: 'OK',\n config: {} as any\n } as AxiosResponse)\n\n const result = await service.callBack(mockUser, mockSpaceEnv, mockToken)\n\n expect(result).toEqual({ error: 0 })\n })\n\n it('should handle status 7 (error force saving)', async () => {\n jwtService.verifyAsync.mockResolvedValue({\n status: 7,\n actions: [],\n url: 'http://onlyoffice/document.docx?md5=abc123&expires=1739400549&shardkey=-33120641&filename=document.docx'\n })\n\n const mockStream = Readable.from(['mock content'])\n httpService.axiosRef.mockResolvedValue({\n data: mockStream,\n headers: { 'content-length': '12' },\n status: 200,\n statusText: 'OK',\n config: {} as any\n } as AxiosResponse)\n\n const result = await service.callBack(mockUser, mockSpaceEnv, mockToken)\n\n expect(result).toEqual({ error: 0 })\n })\n\n it('should handle user connect action (type 1)', async () => {\n jwtService.verifyAsync.mockResolvedValue({\n status: 1,\n actions: [{ type: 1, userid: '1' }],\n users: ['1']\n })\n filesLockManager.create.mockResolvedValue([true, {} as any])\n\n const result = await service.callBack(mockUser, mockSpaceEnv, mockToken)\n\n expect(result).toEqual({ error: 0 })\n expect(filesLockManager.create).toHaveBeenCalledWith(\n mockUser,\n mockSpaceEnv.dbFile,\n ONLY_OFFICE_APP_LOCK,\n DEPTH.RESOURCE,\n {\n lockRoot: null,\n lockToken: null,\n lockScope: LOCK_SCOPE.SHARED\n },\n expect.any(Number)\n )\n })\n\n it('should handle user disconnect action (type 0)', async () => {\n jwtService.verifyAsync.mockResolvedValue({\n status: 1,\n actions: [{ type: 0, userid: '1' }],\n users: undefined\n })\n filesLockManager.getLocksByPath.mockResolvedValue([{ key: 'lock-key', owner: { id: 1 } }] as any)\n\n const result = await service.callBack(mockUser, mockSpaceEnv, mockToken)\n\n expect(result).toEqual({ error: 0 })\n expect(filesLockManager.removeLock).toHaveBeenCalledWith('lock-key')\n })\n\n it('should return error when callback fails', async () => {\n jwtService.verifyAsync.mockResolvedValue({\n status: 2,\n actions: [],\n notmodified: false,\n url: 'http://onlyoffice/document.docx?md5=abc123&expires=1739400549&shardkey=-33120641&filename=document.docx'\n })\n httpService.axiosRef.mockRejectedValue(new Error('Network error'))\n\n const result = await service.callBack(mockUser, mockSpaceEnv, mockToken)\n\n expect(result).toHaveProperty('error')\n expect(result.error).not.toBe(0)\n })\n\n it('should throw error when file lock creation fails', async () => {\n jwtService.verifyAsync.mockResolvedValue({\n status: 1,\n actions: [{ type: 1, userid: '1' }],\n users: ['1']\n })\n filesLockManager.create.mockResolvedValue([false, null])\n\n const result = await service.callBack(mockUser, mockSpaceEnv, mockToken)\n\n expect(result).toHaveProperty('error')\n expect(result.error).not.toBe(0)\n })\n })\n\n it('should be defined', () => {\n expect(service).toBeDefined()\n })\n})\n"],"names":["jest","mock","getAvatarBase64","fn","mockResolvedValue","describe","OnlyOfficeManager","name","service","cache","httpService","jwtService","filesLockManager","mockUser","id","login","email","fullName","language","role","applications","mockSpaceEnv","realPath","relativeUrl","url","dbFile","directory","storageId","storageTypeId","permissions","envPermissions","mockRequest","headers","beforeEach","module","Test","createTestingModule","providers","provide","Cache","useValue","get","set","del","HttpService","axiosRef","JwtService","signAsync","verifyAsync","ContextManager","headerOriginUrl","mockReturnValue","FilesLockManager","checkConflicts","convertLockToFileLockProps","create","getLocksByPath","removeLock","isPathLocked","compile","useLogger","afterEach","clearAllMocks","filesUtils","isPathExists","isPathIsDir","undefined","genEtag","it","result","getSettings","expect","toBeDefined","config","documentType","toBe","editorConfig","mode","FILE_MODE","EDIT","document","edit","hasLock","rejects","toThrow","HttpException","HttpStatus","BAD_REQUEST","unsupportedSpaceEnv","mockLock","key","app","ONLY_OFFICE_APP_LOCK","owner","lockError","LockConflict","mockRejectedValue","VIEW","viewOnlySpaceEnv","mobileRequest","type","not","toHaveBeenCalled","mockToken","uniqueFilePathFromDir","writeFromStream","fileSize","copyFileContent","removeFiles","status","actions","users","callBack","toEqual","error","notmodified","mockStream","Readable","from","data","statusText","userid","toHaveBeenCalledWith","DEPTH","RESOURCE","lockRoot","lockToken","lockScope","LOCK_SCOPE","SHARED","any","Number","Error","toHaveProperty"],"mappings":"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"}