@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.
- package/CHANGELOG.md +41 -4
- package/environment/environment.dist.yaml +15 -5
- package/package.json +18 -19
- package/server/app.bootstrap.js +1 -1
- package/server/app.bootstrap.js.map +1 -1
- package/server/app.constants.js +3 -2
- package/server/app.constants.js.map +1 -1
- package/server/applications/files/constants/cache.js +2 -5
- package/server/applications/files/constants/cache.js.map +1 -1
- package/server/applications/files/constants/files.js +4 -0
- package/server/applications/files/constants/files.js.map +1 -1
- package/server/applications/files/constants/operations.js +4 -0
- package/server/applications/files/constants/operations.js.map +1 -1
- package/server/applications/files/constants/routes.js +1 -26
- package/server/applications/files/constants/routes.js.map +1 -1
- package/server/applications/files/files.config.js +15 -39
- package/server/applications/files/files.config.js.map +1 -1
- package/server/applications/files/files.controller.js +4 -4
- package/server/applications/files/files.controller.js.map +1 -1
- package/server/applications/files/files.module.js +12 -9
- package/server/applications/files/files.module.js.map +1 -1
- package/server/applications/files/interfaces/file-lock.interface.js.map +1 -1
- package/server/applications/files/interfaces/file-props.interface.js.map +1 -1
- package/server/applications/files/modules/collabora-online/collabora-online-environment.decorator.js +32 -0
- package/server/applications/files/modules/collabora-online/collabora-online-environment.decorator.js.map +1 -0
- package/server/applications/files/modules/collabora-online/collabora-online-manager.service.js +280 -0
- package/server/applications/files/modules/collabora-online/collabora-online-manager.service.js.map +1 -0
- package/server/applications/files/modules/collabora-online/collabora-online-manager.service.spec.js +552 -0
- package/server/applications/files/modules/collabora-online/collabora-online-manager.service.spec.js.map +1 -0
- package/server/applications/files/modules/collabora-online/collabora-online.config.js +40 -0
- package/server/applications/files/modules/collabora-online/collabora-online.config.js.map +1 -0
- package/server/applications/files/modules/collabora-online/collabora-online.constants.js +110 -0
- package/server/applications/files/modules/collabora-online/collabora-online.constants.js.map +1 -0
- package/server/applications/files/modules/collabora-online/collabora-online.controller.js +128 -0
- package/server/applications/files/modules/collabora-online/collabora-online.controller.js.map +1 -0
- package/server/applications/files/modules/collabora-online/collabora-online.controller.spec.js +47 -0
- package/server/applications/files/modules/collabora-online/collabora-online.controller.spec.js.map +1 -0
- package/server/applications/files/{interfaces/only-office-config.interface.js → modules/collabora-online/collabora-online.dtos.js} +1 -1
- package/server/applications/files/modules/collabora-online/collabora-online.dtos.js.map +1 -0
- package/server/applications/files/{guards/files-only-office.guard.js → modules/collabora-online/collabora-online.guard.js} +7 -21
- package/server/applications/files/modules/collabora-online/collabora-online.guard.js.map +1 -0
- package/server/applications/files/modules/collabora-online/collabora-online.guard.spec.js +86 -0
- package/server/applications/files/modules/collabora-online/collabora-online.guard.spec.js.map +1 -0
- package/server/applications/files/modules/collabora-online/collabora-online.interface.js +10 -0
- package/server/applications/files/modules/collabora-online/collabora-online.interface.js.map +1 -0
- package/server/applications/files/modules/collabora-online/collabora-online.module.js +41 -0
- package/server/applications/files/modules/collabora-online/collabora-online.module.js.map +1 -0
- package/server/applications/files/modules/collabora-online/collabora-online.routes.js +35 -0
- package/server/applications/files/modules/collabora-online/collabora-online.routes.js.map +1 -0
- package/server/applications/files/modules/collabora-online/collabora-online.strategy.js +59 -0
- package/server/applications/files/modules/collabora-online/collabora-online.strategy.js.map +1 -0
- package/server/applications/files/modules/collabora-online/collabora-online.utils.js +28 -0
- package/server/applications/files/modules/collabora-online/collabora-online.utils.js.map +1 -0
- package/server/applications/files/{decorators → modules/only-office}/only-office-environment.decorator.js +5 -5
- package/server/applications/files/modules/only-office/only-office-environment.decorator.js.map +1 -0
- package/server/applications/files/{services/files-only-office-manager.service.js → modules/only-office/only-office-manager.service.js} +101 -97
- package/server/applications/files/modules/only-office/only-office-manager.service.js.map +1 -0
- package/server/applications/files/modules/only-office/only-office-manager.service.spec.js +477 -0
- package/server/applications/files/modules/only-office/only-office-manager.service.spec.js.map +1 -0
- package/server/applications/files/modules/only-office/only-office.config.js +51 -0
- package/server/applications/files/modules/only-office/only-office.config.js.map +1 -0
- package/server/applications/files/modules/only-office/only-office.constants.js +417 -0
- package/server/applications/files/modules/only-office/only-office.constants.js.map +1 -0
- package/server/applications/files/{files-only-office.controller.js → modules/only-office/only-office.controller.js} +35 -52
- package/server/applications/files/modules/only-office/only-office.controller.js.map +1 -0
- package/server/applications/files/{files-only-office.controller.spec.js → modules/only-office/only-office.controller.spec.js} +24 -21
- package/server/applications/files/modules/only-office/only-office.controller.spec.js.map +1 -0
- package/server/applications/files/modules/only-office/only-office.dtos.js +10 -0
- package/server/applications/files/modules/only-office/only-office.dtos.js.map +1 -0
- package/server/applications/files/modules/only-office/only-office.guard.js +40 -0
- package/server/applications/files/modules/only-office/only-office.guard.js.map +1 -0
- package/server/applications/files/{guards/files-only-office.guard.spec.js → modules/only-office/only-office.guard.spec.js} +15 -21
- package/server/applications/files/modules/only-office/only-office.guard.spec.js.map +1 -0
- package/server/applications/files/modules/only-office/only-office.interface.js +10 -0
- package/server/applications/files/modules/only-office/only-office.interface.js.map +1 -0
- package/server/applications/files/modules/only-office/only-office.module.js +41 -0
- package/server/applications/files/modules/only-office/only-office.module.js.map +1 -0
- package/server/applications/files/modules/only-office/only-office.routes.js +45 -0
- package/server/applications/files/modules/only-office/only-office.routes.js.map +1 -0
- package/server/applications/files/{guards/files-only-office.strategy.js → modules/only-office/only-office.strategy.js} +11 -11
- package/server/applications/files/modules/only-office/only-office.strategy.js.map +1 -0
- package/server/applications/files/services/files-lock-manager.service.js +25 -33
- package/server/applications/files/services/files-lock-manager.service.js.map +1 -1
- package/server/applications/files/services/files-manager.service.js +17 -16
- package/server/applications/files/services/files-manager.service.js.map +1 -1
- package/server/applications/files/services/files-methods.service.js +2 -2
- package/server/applications/files/services/files-methods.service.js.map +1 -1
- package/server/applications/files/services/files-methods.service.spec.js +5 -5
- package/server/applications/files/services/files-methods.service.spec.js.map +1 -1
- package/server/applications/files/services/files-recents.service.js +4 -0
- package/server/applications/files/services/files-recents.service.js.map +1 -1
- package/server/applications/files/services/files-scheduler.service.js +24 -5
- package/server/applications/files/services/files-scheduler.service.js.map +1 -1
- package/server/applications/files/utils/files.js +10 -2
- package/server/applications/files/utils/files.js.map +1 -1
- package/server/applications/links/constants/routes.js +5 -0
- package/server/applications/links/constants/routes.js.map +1 -1
- package/server/applications/links/interfaces/link-space.interface.js.map +1 -1
- package/server/applications/links/links.controller.js +25 -5
- package/server/applications/links/links.controller.js.map +1 -1
- package/server/applications/links/services/links-manager.service.js +43 -21
- package/server/applications/links/services/links-manager.service.js.map +1 -1
- package/server/applications/links/services/links-manager.service.spec.js +4 -3
- package/server/applications/links/services/links-manager.service.spec.js.map +1 -1
- package/server/applications/links/services/links-queries.service.js +9 -2
- package/server/applications/links/services/links-queries.service.js.map +1 -1
- package/server/applications/shares/interfaces/share-link.interface.js.map +1 -1
- package/server/applications/shares/services/shares-manager.service.js +3 -0
- package/server/applications/shares/services/shares-manager.service.js.map +1 -1
- package/server/applications/shares/services/shares-manager.service.spec.js +2 -1
- package/server/applications/shares/services/shares-manager.service.spec.js.map +1 -1
- package/server/applications/shares/services/shares-queries.service.js +1 -0
- package/server/applications/shares/services/shares-queries.service.js.map +1 -1
- package/server/applications/spaces/constants/spaces.js +2 -2
- package/server/applications/spaces/constants/spaces.js.map +1 -1
- package/server/applications/spaces/decorators/space-override-permission.decorator.js +18 -0
- package/server/applications/spaces/decorators/space-override-permission.decorator.js.map +1 -0
- package/server/applications/spaces/guards/space.guard.js +40 -33
- package/server/applications/spaces/guards/space.guard.js.map +1 -1
- package/server/applications/spaces/guards/space.guard.spec.js +10 -15
- package/server/applications/spaces/guards/space.guard.spec.js.map +1 -1
- package/server/applications/spaces/services/spaces-scheduler.service.js +9 -1
- package/server/applications/spaces/services/spaces-scheduler.service.js.map +1 -1
- package/server/applications/webdav/constants/webdav.js +4 -0
- package/server/applications/webdav/constants/webdav.js.map +1 -1
- package/server/applications/webdav/guards/webdav-protocol.guard.js +9 -8
- package/server/applications/webdav/guards/webdav-protocol.guard.js.map +1 -1
- package/server/applications/webdav/guards/webdav-protocol.guard.spec.js +1 -1
- package/server/applications/webdav/guards/webdav-protocol.guard.spec.js.map +1 -1
- package/server/applications/webdav/interfaces/webdav.interface.js.map +1 -1
- package/server/applications/webdav/services/webdav-methods.service.js +40 -17
- package/server/applications/webdav/services/webdav-methods.service.js.map +1 -1
- package/server/applications/webdav/services/webdav-methods.service.spec.js +2157 -1289
- package/server/applications/webdav/services/webdav-methods.service.spec.js.map +1 -1
- package/server/applications/webdav/utils/webdav.js +8 -4
- package/server/applications/webdav/utils/webdav.js.map +1 -1
- package/server/applications/webdav/webdav.controller.js +4 -4
- package/server/applications/webdav/webdav.controller.js.map +1 -1
- package/server/authentication/guards/auth-token-access.guard.js +8 -3
- package/server/authentication/guards/auth-token-access.guard.js.map +1 -1
- package/server/authentication/services/auth-methods/auth-method-two-fa.service.js +1 -1
- package/server/authentication/services/auth-methods/auth-method-two-fa.service.js.map +1 -1
- package/server/authentication/services/auth-methods/auth-method-two-fa.service.spec.js +350 -4
- package/server/authentication/services/auth-methods/auth-method-two-fa.service.spec.js.map +1 -1
- package/server/configuration/config.environment.js +5 -1
- package/server/configuration/config.environment.js.map +1 -1
- package/server/configuration/config.interfaces.js.map +1 -1
- package/static/3rdpartylicenses.txt +507 -507
- package/static/assets/pdfjs/build/pdf.mjs +93 -33
- package/static/assets/pdfjs/build/pdf.mjs.map +1 -1
- package/static/assets/pdfjs/build/pdf.sandbox.mjs +3 -3
- package/static/assets/pdfjs/build/pdf.sandbox.mjs.map +1 -1
- package/static/assets/pdfjs/build/pdf.worker.mjs +166 -54
- package/static/assets/pdfjs/build/pdf.worker.mjs.map +1 -1
- package/static/assets/pdfjs/version +1 -1
- package/static/assets/pdfjs/web/images/checkmark.svg +5 -0
- package/static/assets/pdfjs/web/images/pages_closeButton.svg +3 -0
- package/static/assets/pdfjs/web/images/pages_selected.svg +7 -0
- package/static/assets/pdfjs/web/images/pages_viewArrow.svg +3 -0
- package/static/assets/pdfjs/web/images/pages_viewButton.svg +3 -0
- package/static/assets/pdfjs/web/locale/be/viewer.ftl +0 -2
- package/static/assets/pdfjs/web/locale/bs/viewer.ftl +0 -5
- package/static/assets/pdfjs/web/locale/cs/viewer.ftl +4 -6
- package/static/assets/pdfjs/web/locale/cy/viewer.ftl +0 -2
- package/static/assets/pdfjs/web/locale/da/viewer.ftl +0 -2
- package/static/assets/pdfjs/web/locale/de/viewer.ftl +0 -2
- package/static/assets/pdfjs/web/locale/dsb/viewer.ftl +0 -2
- package/static/assets/pdfjs/web/locale/el/viewer.ftl +0 -2
- package/static/assets/pdfjs/web/locale/en-CA/viewer.ftl +6 -2
- package/static/assets/pdfjs/web/locale/en-GB/viewer.ftl +0 -2
- package/static/assets/pdfjs/web/locale/en-US/viewer.ftl +82 -17
- package/static/assets/pdfjs/web/locale/eo/viewer.ftl +0 -2
- package/static/assets/pdfjs/web/locale/es-AR/viewer.ftl +0 -2
- package/static/assets/pdfjs/web/locale/es-CL/viewer.ftl +0 -2
- package/static/assets/pdfjs/web/locale/es-ES/viewer.ftl +0 -2
- package/static/assets/pdfjs/web/locale/es-MX/viewer.ftl +0 -2
- package/static/assets/pdfjs/web/locale/eu/viewer.ftl +0 -2
- package/static/assets/pdfjs/web/locale/fi/viewer.ftl +0 -2
- package/static/assets/pdfjs/web/locale/fr/viewer.ftl +0 -2
- package/static/assets/pdfjs/web/locale/fur/viewer.ftl +0 -5
- package/static/assets/pdfjs/web/locale/fy-NL/viewer.ftl +3 -5
- package/static/assets/pdfjs/web/locale/gn/viewer.ftl +0 -2
- package/static/assets/pdfjs/web/locale/he/viewer.ftl +0 -2
- package/static/assets/pdfjs/web/locale/hr/viewer.ftl +66 -0
- package/static/assets/pdfjs/web/locale/hsb/viewer.ftl +0 -2
- package/static/assets/pdfjs/web/locale/hu/viewer.ftl +0 -2
- package/static/assets/pdfjs/web/locale/hy-AM/viewer.ftl +3 -8
- package/static/assets/pdfjs/web/locale/ia/viewer.ftl +0 -2
- package/static/assets/pdfjs/web/locale/id/viewer.ftl +0 -5
- package/static/assets/pdfjs/web/locale/is/viewer.ftl +0 -5
- package/static/assets/pdfjs/web/locale/it/viewer.ftl +0 -2
- package/static/assets/pdfjs/web/locale/ja/viewer.ftl +0 -14
- package/static/assets/pdfjs/web/locale/ka/viewer.ftl +4 -6
- package/static/assets/pdfjs/web/locale/kab/viewer.ftl +0 -5
- package/static/assets/pdfjs/web/locale/kk/viewer.ftl +0 -2
- package/static/assets/pdfjs/web/locale/ko/viewer.ftl +0 -2
- package/static/assets/pdfjs/web/locale/nb-NO/viewer.ftl +1 -3
- package/static/assets/pdfjs/web/locale/nl/viewer.ftl +0 -2
- package/static/assets/pdfjs/web/locale/nn-NO/viewer.ftl +4 -2
- package/static/assets/pdfjs/web/locale/pa-IN/viewer.ftl +0 -2
- package/static/assets/pdfjs/web/locale/pl/viewer.ftl +0 -2
- package/static/assets/pdfjs/web/locale/pt-BR/viewer.ftl +0 -2
- package/static/assets/pdfjs/web/locale/pt-PT/viewer.ftl +35 -0
- package/static/assets/pdfjs/web/locale/rm/viewer.ftl +0 -5
- package/static/assets/pdfjs/web/locale/ro/viewer.ftl +4 -6
- package/static/assets/pdfjs/web/locale/ru/viewer.ftl +3 -5
- package/static/assets/pdfjs/web/locale/sk/viewer.ftl +0 -2
- package/static/assets/pdfjs/web/locale/sl/viewer.ftl +0 -2
- package/static/assets/pdfjs/web/locale/sq/viewer.ftl +0 -2
- package/static/assets/pdfjs/web/locale/sv-SE/viewer.ftl +0 -2
- package/static/assets/pdfjs/web/locale/tg/viewer.ftl +0 -2
- package/static/assets/pdfjs/web/locale/th/viewer.ftl +2 -2
- package/static/assets/pdfjs/web/locale/tr/viewer.ftl +0 -2
- package/static/assets/pdfjs/web/locale/vi/viewer.ftl +0 -2
- package/static/assets/pdfjs/web/locale/zh-CN/viewer.ftl +0 -2
- package/static/assets/pdfjs/web/locale/zh-TW/viewer.ftl +0 -2
- package/static/assets/pdfjs/web/viewer.css +1778 -835
- package/static/assets/pdfjs/web/viewer.html +167 -86
- package/static/assets/pdfjs/web/viewer.mjs +1106 -801
- package/static/assets/pdfjs/web/viewer.mjs.map +1 -1
- package/static/chunk-27V66YJV.js +2 -0
- package/static/{chunk-WJYVS27M.js → chunk-27Z3SYRL.js} +1 -1
- package/static/{chunk-NFIES7BC.js → chunk-2RWLNKZH.js} +1 -1
- package/static/chunk-2YQ4SX3A.js +13 -0
- package/static/{chunk-GENTF6JM.js → chunk-3JYMJQYT.js} +1 -1
- package/static/chunk-3QTROEHV.js +1 -0
- package/static/{chunk-ZPI7RQ2S.js → chunk-3RPUQ22U.js} +1 -1
- package/static/{chunk-R6VB3INJ.js → chunk-3WZ6F3LC.js} +1 -1
- package/static/chunk-3ZLBVUCX.js +2 -0
- package/static/{chunk-5HCVWZMA.js → chunk-45AZ6ZML.js} +1 -1
- package/static/chunk-46TJLPJY.js +1 -0
- package/static/chunk-4NIYCYRS.js +2 -0
- package/static/{chunk-XXYMVRSH.js → chunk-4TPFERL6.js} +1 -1
- package/static/{chunk-CAZSNVMS.js → chunk-5O66CLTD.js} +1 -1
- package/static/chunk-6OEOADR6.js +1 -0
- package/static/chunk-6WMXMIE4.js +1 -0
- package/static/{chunk-NK2NMAJI.js → chunk-7VRYTDX4.js} +1 -1
- package/static/{chunk-ASBPYTLT.js → chunk-ARS47O5X.js} +1 -1
- package/static/chunk-B6HQYQYG.js +1 -0
- package/static/chunk-BCN4T5DO.js +2 -0
- package/static/{chunk-PKU4IIIR.js → chunk-CCZWPM7Q.js} +1 -1
- package/static/{chunk-QUSS6SUC.js → chunk-CMNMPG6Z.js} +1 -1
- package/static/{chunk-GDPJRUVU.js → chunk-CSVPAZHK.js} +1 -1
- package/static/{chunk-BJARRIS6.js → chunk-D55YR5X7.js} +4 -4
- package/static/{chunk-Z6RJZIDG.js → chunk-D5FQ72R4.js} +1 -1
- package/static/{chunk-4DF2SQD4.js → chunk-DGCVA6BM.js} +1 -1
- package/static/{chunk-TVJQXN73.js → chunk-DVCN3P7Q.js} +1 -1
- package/static/chunk-E32J777S.js +5 -0
- package/static/{chunk-5NHB7SV3.js → chunk-FIUF2JM4.js} +1 -1
- package/static/{chunk-RJOHDAPM.js → chunk-G3PL6YX3.js} +1 -1
- package/static/chunk-G7RZN7HN.js +1 -0
- package/static/{chunk-DDRGLHOP.js → chunk-GQHXYX6Z.js} +1 -1
- package/static/{chunk-5HYSNQR4.js → chunk-GWRAGN3M.js} +1 -1
- package/static/{chunk-ZC5ZDCDC.js → chunk-GXWGB7WO.js} +1 -1
- package/static/{chunk-25PWAXTJ.js → chunk-HGODIZTV.js} +1 -1
- package/static/{chunk-4KXJ6C4N.js → chunk-HZAB6F4Q.js} +1 -1
- package/static/chunk-I3FR3A45.js +1 -0
- package/static/{chunk-A6J6SOM6.js → chunk-I5SPA4G2.js} +1 -1
- package/static/{chunk-TGHBDJZA.js → chunk-IMFO2MI7.js} +1 -1
- package/static/{chunk-CURVLK7L.js → chunk-JNTNMIUH.js} +1 -1
- package/static/chunk-JRXG43AA.js +2 -0
- package/static/{chunk-XAIOGRBO.js → chunk-KAUCN24H.js} +1 -1
- package/static/chunk-KDUAB76O.js +1 -0
- package/static/chunk-KPOQLDWF.js +1 -0
- package/static/{chunk-HE6EDXWI.js → chunk-KWFELZTM.js} +1 -1
- package/static/{chunk-2CAAJBRO.js → chunk-L3BIP4AA.js} +1 -1
- package/static/{chunk-U75PLYIJ.js → chunk-LGIVVJDD.js} +1 -1
- package/static/{chunk-JEVBUJQ4.js → chunk-LNLBIJZD.js} +1 -1
- package/static/chunk-LTJNLOX2.js +1 -0
- package/static/{chunk-SDR3UG2F.js → chunk-LZUHREOF.js} +1 -1
- package/static/{chunk-VO4WVT6K.js → chunk-NIR4YE2E.js} +1 -1
- package/static/{chunk-S6YKBWJE.js → chunk-NJJURHX4.js} +1 -1
- package/static/chunk-NNZWSNAW.js +1 -0
- package/static/chunk-NWKBB7J4.js +1 -0
- package/static/chunk-O3YLAEVE.js +3 -0
- package/static/chunk-OUHCDDT6.js +1 -0
- package/static/{chunk-ZRBLCAOK.js → chunk-PDG7DOEF.js} +1 -1
- package/static/chunk-POUWUMC4.js +1 -0
- package/static/{chunk-YTBSB2GE.js → chunk-PPJCVBJH.js} +1 -1
- package/static/{chunk-K3MOXDU5.js → chunk-PQZLR4P3.js} +1 -1
- package/static/chunk-PVYVY3GD.js +1 -0
- package/static/chunk-Q5X5TPAG.js +1 -0
- package/static/{chunk-LFAQLJZK.js → chunk-QHJT5H4M.js} +1 -1
- package/static/{chunk-A7DSX7VP.js → chunk-R4VMWCM5.js} +1 -1
- package/static/{chunk-27XEAHMV.js → chunk-R7PLNX75.js} +1 -1
- package/static/chunk-RJULB733.js +1 -0
- package/static/{chunk-MBFMTBVJ.js → chunk-RNVPQQKT.js} +5 -5
- package/static/chunk-RTNEBRKJ.js +1 -0
- package/static/{chunk-FXM7XXWA.js → chunk-S3TTWPQA.js} +1 -1
- package/static/{chunk-6VJI4X2A.js → chunk-SDJNZULP.js} +1 -1
- package/static/chunk-SNOOCDJD.js +1 -0
- package/static/chunk-T42BV6TR.js +1 -0
- package/static/{chunk-4OV3SAUS.js → chunk-TNCKNU6I.js} +1 -1
- package/static/{chunk-2LHHXDD5.js → chunk-ULSPQ3HP.js} +1 -1
- package/static/{chunk-4EUHBTWV.js → chunk-UOK3LKSX.js} +1 -1
- package/static/{chunk-7NI353LS.js → chunk-VD5JHSDS.js} +1 -1
- package/static/{chunk-YXWF2DGF.js → chunk-XBKCQCBI.js} +1 -1
- package/static/{chunk-KBWK65KM.js → chunk-XEWLBWFF.js} +1 -1
- package/static/{chunk-FLPZB3OX.js → chunk-XTVNHFKX.js} +1 -1
- package/static/chunk-ZCSHU3D7.js +1 -0
- package/static/{chunk-FRBTL2ER.js → chunk-ZEJLIGAY.js} +1 -1
- package/static/{chunk-7H5O4BLV.js → chunk-ZHOE5VEY.js} +1 -1
- package/static/chunk-ZOMRIN3G.js +2 -0
- package/static/index.html +2 -2
- package/static/main-YKDNJ7LK.js +11 -0
- package/static/{styles-S5HVK4H5.css → styles-XLLEY5Y3.css} +1 -1
- package/server/applications/files/constants/only-office.js +0 -531
- package/server/applications/files/constants/only-office.js.map +0 -1
- package/server/applications/files/decorators/only-office-environment.decorator.js.map +0 -1
- package/server/applications/files/files-only-office.controller.js.map +0 -1
- package/server/applications/files/files-only-office.controller.spec.js.map +0 -1
- package/server/applications/files/guards/files-only-office.guard.js.map +0 -1
- package/server/applications/files/guards/files-only-office.guard.spec.js.map +0 -1
- package/server/applications/files/guards/files-only-office.strategy.js.map +0 -1
- package/server/applications/files/interfaces/only-office-config.interface.js.map +0 -1
- package/server/applications/files/services/files-only-office-manager.service.js.map +0 -1
- package/server/applications/files/services/files-only-office-manager.service.spec.js +0 -58
- package/server/applications/files/services/files-only-office-manager.service.spec.js.map +0 -1
- package/static/chunk-2XY4PMI5.js +0 -1
- package/static/chunk-33WFRCUP.js +0 -1
- package/static/chunk-3LVFDMTN.js +0 -1
- package/static/chunk-42L6C5MT.js +0 -1
- package/static/chunk-5WCQBTXW.js +0 -1
- package/static/chunk-A7R246NW.js +0 -1
- package/static/chunk-BSB4VROD.js +0 -2
- package/static/chunk-DHFQIFOF.js +0 -1
- package/static/chunk-DRHPEERW.js +0 -2
- package/static/chunk-FCGTI42I.js +0 -1
- package/static/chunk-H4RLHI3Y.js +0 -1
- package/static/chunk-ITVA26X2.js +0 -2
- package/static/chunk-IUJ4IK26.js +0 -1
- package/static/chunk-L3PDWJZ3.js +0 -3
- package/static/chunk-LBXOAKBD.js +0 -1
- package/static/chunk-LZKI5P5T.js +0 -1
- package/static/chunk-MYM43ENO.js +0 -1
- package/static/chunk-MZBO5PAR.js +0 -1
- package/static/chunk-NAH4V2R6.js +0 -2
- package/static/chunk-O7UXVNR2.js +0 -1
- package/static/chunk-PCFH5HCI.js +0 -2
- package/static/chunk-SRBOO7AO.js +0 -1
- package/static/chunk-UUX3M6DC.js +0 -1
- package/static/chunk-VJ2HWQRJ.js +0 -5
- package/static/chunk-VZPCXSRG.js +0 -2
- package/static/chunk-W72JYHOH.js +0 -1
- package/static/chunk-XHQEF2IX.js +0 -1
- package/static/chunk-XKEBQNQJ.js +0 -1
- package/static/chunk-ZERBTNFW.js +0 -13
- package/static/main-FE6GWZXU.js +0 -11
- /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("
|
|
25
|
-
const
|
|
26
|
-
const
|
|
27
|
-
const OnlyOfficeContext = ()=>(0, _common.SetMetadata)(
|
|
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)(
|
|
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
|
package/server/applications/files/modules/only-office/only-office-environment.decorator.js.map
ADDED
|
@@ -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, "
|
|
9
|
+
Object.defineProperty(exports, "OnlyOfficeManager", {
|
|
10
10
|
enumerable: true,
|
|
11
11
|
get: function() {
|
|
12
|
-
return
|
|
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("
|
|
23
|
-
const _configenvironment = require("
|
|
24
|
-
const _cacheservice = require("
|
|
25
|
-
const _contextmanagerservice = require("
|
|
26
|
-
const _applicationsconstants = require("
|
|
27
|
-
const _spaces = require("
|
|
28
|
-
const _permissions = require("
|
|
29
|
-
const _avatar = require("
|
|
30
|
-
const _webdav = require("
|
|
31
|
-
const
|
|
32
|
-
const
|
|
33
|
-
const
|
|
34
|
-
const
|
|
35
|
-
const
|
|
36
|
-
const
|
|
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
|
|
53
|
-
|
|
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.
|
|
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 (!
|
|
60
|
+
if (!_onlyofficeconstants.ONLY_OFFICE_EXTENSIONS.has(fileExtension)) {
|
|
67
61
|
throw new _common.HttpException('Document not supported', _common.HttpStatus.BAD_REQUEST);
|
|
68
62
|
}
|
|
69
|
-
|
|
70
|
-
|
|
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
|
-
//
|
|
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
|
-
|
|
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
|
|
85
|
-
const
|
|
86
|
-
const
|
|
87
|
-
const
|
|
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
|
|
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.
|
|
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(
|
|
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,
|
|
144
|
-
const
|
|
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
|
-
|
|
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(
|
|
159
|
+
key: await this.getDocumentKey(space),
|
|
156
160
|
permissions: {
|
|
157
161
|
download: true,
|
|
158
|
-
edit:
|
|
162
|
+
edit: canEdit,
|
|
159
163
|
changeHistory: false,
|
|
160
|
-
comment:
|
|
161
|
-
fillForms:
|
|
164
|
+
comment: canEdit,
|
|
165
|
+
fillForms: canEdit,
|
|
162
166
|
print: true,
|
|
163
|
-
review:
|
|
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
|
-
|
|
203
|
-
|
|
204
|
-
|
|
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
|
-
|
|
217
|
-
// use refresh expiration to allow long
|
|
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
|
-
//
|
|
237
|
-
|
|
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
|
-
//
|
|
240
|
-
|
|
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
|
|
245
|
-
const [ok, _fileLock] = await this.filesLockManager.create(user, space.dbFile, _webdav.DEPTH.RESOURCE, {
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
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
|
|
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(
|
|
268
|
+
async removeDocumentKey(space) {
|
|
263
269
|
if (!await this.filesLockManager.isPathLocked(space.dbFile)) {
|
|
264
|
-
const cacheKey = this.getCacheKey(
|
|
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(
|
|
270
|
-
|
|
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,
|
|
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
|
|
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 && !
|
|
293
|
-
if (
|
|
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 (
|
|
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 : ${
|
|
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(
|
|
369
|
-
return `${
|
|
374
|
+
getCacheKey(dbFile) {
|
|
375
|
+
return `${_onlyofficeconstants.ONLY_OFFICE_CACHE_KEY}|${(0, _files.genUniqHashFromFileDBProps)(dbFile)}`;
|
|
370
376
|
}
|
|
371
|
-
constructor(http, contextManager, cache, jwt, filesLockManager
|
|
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.
|
|
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
|
-
|
|
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
|
-
],
|
|
401
|
+
], OnlyOfficeManager);
|
|
398
402
|
|
|
399
|
-
//# sourceMappingURL=
|
|
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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"}
|