@sync-in/server 1.9.6 → 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 +29 -4
- package/environment/environment.dist.yaml +15 -5
- package/package.json +13 -14
- 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 +3 -1
- package/server/applications/files/services/files-methods.service.spec.js.map +1 -1
- package/server/applications/files/services/files-scheduler.service.js +2 -2
- 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/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-BVKDW5XO.js → chunk-27Z3SYRL.js} +1 -1
- package/static/{chunk-HLKZCMKV.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-C5T7RZSD.js → chunk-3RPUQ22U.js} +1 -1
- package/static/{chunk-EPDWJEPD.js → chunk-3WZ6F3LC.js} +1 -1
- package/static/chunk-3ZLBVUCX.js +2 -0
- package/static/{chunk-SF6Q6VRC.js → chunk-45AZ6ZML.js} +1 -1
- package/static/chunk-46TJLPJY.js +1 -0
- package/static/chunk-4NIYCYRS.js +2 -0
- package/static/{chunk-GLPKRULI.js → chunk-4TPFERL6.js} +1 -1
- package/static/{chunk-KAAFVHYE.js → chunk-5O66CLTD.js} +1 -1
- package/static/chunk-6OEOADR6.js +1 -0
- package/static/chunk-6WMXMIE4.js +1 -0
- package/static/{chunk-QKMN3S4M.js → chunk-7VRYTDX4.js} +1 -1
- package/static/{chunk-Z2KBIZ5D.js → chunk-ARS47O5X.js} +1 -1
- package/static/chunk-B6HQYQYG.js +1 -0
- package/static/chunk-BCN4T5DO.js +2 -0
- package/static/{chunk-7HL5Z6PF.js → chunk-CCZWPM7Q.js} +1 -1
- package/static/{chunk-DU4Q4RWJ.js → chunk-CMNMPG6Z.js} +1 -1
- package/static/{chunk-BX3QZ7IL.js → chunk-CSVPAZHK.js} +1 -1
- package/static/{chunk-BJARRIS6.js → chunk-D55YR5X7.js} +4 -4
- package/static/{chunk-NHMYAVJK.js → chunk-D5FQ72R4.js} +1 -1
- package/static/{chunk-7QYALK5T.js → chunk-DGCVA6BM.js} +1 -1
- package/static/{chunk-IBC7CFBQ.js → chunk-DVCN3P7Q.js} +1 -1
- package/static/chunk-E32J777S.js +5 -0
- package/static/{chunk-FEQUP26G.js → chunk-FIUF2JM4.js} +1 -1
- package/static/{chunk-ODAQRAPO.js → chunk-G3PL6YX3.js} +1 -1
- package/static/chunk-G7RZN7HN.js +1 -0
- package/static/{chunk-IIKL33TV.js → chunk-GQHXYX6Z.js} +1 -1
- package/static/{chunk-5HYSNQR4.js → chunk-GWRAGN3M.js} +1 -1
- package/static/{chunk-ANH4VNOS.js → chunk-GXWGB7WO.js} +1 -1
- package/static/{chunk-25PWAXTJ.js → chunk-HGODIZTV.js} +1 -1
- package/static/{chunk-X5UDV4ZB.js → chunk-HZAB6F4Q.js} +1 -1
- package/static/chunk-I3FR3A45.js +1 -0
- package/static/{chunk-JYHTSSKW.js → chunk-I5SPA4G2.js} +1 -1
- package/static/{chunk-DQAQUSVW.js → chunk-IMFO2MI7.js} +1 -1
- package/static/{chunk-AYYJZMBE.js → chunk-JNTNMIUH.js} +1 -1
- package/static/chunk-JRXG43AA.js +2 -0
- package/static/{chunk-3AR5VNJE.js → chunk-KAUCN24H.js} +1 -1
- package/static/{chunk-3WS72A6C.js → chunk-KDUAB76O.js} +1 -1
- package/static/chunk-KPOQLDWF.js +1 -0
- package/static/{chunk-UO7ATVQG.js → chunk-KWFELZTM.js} +1 -1
- package/static/{chunk-2CAAJBRO.js → chunk-L3BIP4AA.js} +1 -1
- package/static/{chunk-DK2LAJEL.js → chunk-LGIVVJDD.js} +1 -1
- package/static/{chunk-5ATJIR5S.js → chunk-LNLBIJZD.js} +1 -1
- package/static/chunk-LTJNLOX2.js +1 -0
- package/static/{chunk-GRV44RYI.js → chunk-LZUHREOF.js} +1 -1
- package/static/{chunk-XIQXRSZ2.js → chunk-NIR4YE2E.js} +1 -1
- package/static/{chunk-TOCCCZP2.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-B4TDS6AQ.js → chunk-PDG7DOEF.js} +1 -1
- package/static/chunk-POUWUMC4.js +1 -0
- package/static/{chunk-NQCKX2AD.js → chunk-PPJCVBJH.js} +1 -1
- package/static/{chunk-ZCOEP4O2.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-D6QWQHWE.js → chunk-R4VMWCM5.js} +1 -1
- package/static/{chunk-O233BXWK.js → chunk-R7PLNX75.js} +1 -1
- package/static/chunk-RJULB733.js +1 -0
- package/static/{chunk-E5C4QRNQ.js → chunk-RNVPQQKT.js} +5 -5
- package/static/chunk-RTNEBRKJ.js +1 -0
- package/static/{chunk-GYYJ4FWN.js → chunk-S3TTWPQA.js} +1 -1
- package/static/{chunk-4GBA6EJ4.js → chunk-SDJNZULP.js} +1 -1
- package/static/chunk-SNOOCDJD.js +1 -0
- package/static/chunk-T42BV6TR.js +1 -0
- package/static/{chunk-5KVI243T.js → chunk-TNCKNU6I.js} +1 -1
- package/static/{chunk-OVUMPMVM.js → chunk-ULSPQ3HP.js} +1 -1
- package/static/{chunk-5NFH4E2B.js → chunk-UOK3LKSX.js} +1 -1
- package/static/{chunk-CHMDM2ZW.js → chunk-VD5JHSDS.js} +1 -1
- package/static/{chunk-2F42MZQ5.js → chunk-XBKCQCBI.js} +1 -1
- package/static/{chunk-2U5VKTML.js → chunk-XEWLBWFF.js} +1 -1
- package/static/{chunk-FSGT46LM.js → chunk-XTVNHFKX.js} +1 -1
- package/static/chunk-ZCSHU3D7.js +1 -0
- package/static/{chunk-QUUQOBTF.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-42L6C5MT.js +0 -1
- package/static/chunk-4ZKAVMB4.js +0 -1
- package/static/chunk-5GIWZKNS.js +0 -1
- package/static/chunk-5WCQBTXW.js +0 -1
- package/static/chunk-B2A4HNDC.js +0 -1
- package/static/chunk-BSB4VROD.js +0 -2
- package/static/chunk-CUC7R6C2.js +0 -1
- package/static/chunk-DHFQIFOF.js +0 -1
- package/static/chunk-DRHPEERW.js +0 -2
- package/static/chunk-FCGTI42I.js +0 -1
- package/static/chunk-FCR5AEHR.js +0 -3
- package/static/chunk-HB5DC7RJ.js +0 -1
- package/static/chunk-ITVA26X2.js +0 -2
- package/static/chunk-KWKZN53T.js +0 -1
- package/static/chunk-LBXOAKBD.js +0 -1
- package/static/chunk-LZKI5P5T.js +0 -1
- package/static/chunk-MGMDT4VN.js +0 -1
- package/static/chunk-MWUUM2NK.js +0 -13
- package/static/chunk-MYM43ENO.js +0 -1
- package/static/chunk-NAH4V2R6.js +0 -2
- package/static/chunk-PCFH5HCI.js +0 -2
- package/static/chunk-Q6B4OVER.js +0 -5
- package/static/chunk-QV5LQKTS.js +0 -1
- package/static/chunk-S4UTSOPV.js +0 -1
- package/static/chunk-SRBOO7AO.js +0 -1
- package/static/chunk-VZPCXSRG.js +0 -2
- package/static/chunk-XKEBQNQJ.js +0 -1
- package/static/chunk-YYTDPI5S.js +0 -1
- package/static/main-ODUA232E.js +0 -11
- /package/static/assets/pdfjs/web/images/{toolbarButton-sidebarToggle.svg → toolbarButton-viewsManagerToggle.svg} +0 -0
|
@@ -15,18 +15,20 @@ Object.defineProperty(exports, "SpaceGuard", {
|
|
|
15
15
|
const _common = require("@nestjs/common");
|
|
16
16
|
const _core = require("@nestjs/core");
|
|
17
17
|
const _applicationsconstants = require("../../applications.constants");
|
|
18
|
-
const
|
|
19
|
-
const
|
|
18
|
+
const _collaboraonlineconstants = require("../../files/modules/collabora-online/collabora-online.constants");
|
|
19
|
+
const _collaboraonlineutils = require("../../files/modules/collabora-online/collabora-online.utils");
|
|
20
|
+
const _files = require("../../files/utils/files");
|
|
20
21
|
const _synccontextdecorator = require("../../sync/decorators/sync-context.decorator");
|
|
21
|
-
const
|
|
22
|
+
const _routes = require("../../sync/utils/routes");
|
|
22
23
|
const _webdavcontextdecorator = require("../../webdav/decorators/webdav-context.decorator");
|
|
23
|
-
const
|
|
24
|
+
const _routes1 = require("../../webdav/utils/routes");
|
|
24
25
|
const _spaces = require("../constants/spaces");
|
|
26
|
+
const _spaceoverridepermissiondecorator = require("../decorators/space-override-permission.decorator");
|
|
25
27
|
const _spaceskipguarddecorator = require("../decorators/space-skip-guard.decorator");
|
|
26
28
|
const _spaceskippermissionsdecorator = require("../decorators/space-skip-permissions.decorator");
|
|
27
29
|
const _spacesmanagerservice = require("../services/spaces-manager.service");
|
|
28
30
|
const _permissions = require("../utils/permissions");
|
|
29
|
-
const
|
|
31
|
+
const _routes2 = require("../utils/routes");
|
|
30
32
|
function _ts_decorate(decorators, target, key, desc) {
|
|
31
33
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
32
34
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
@@ -37,13 +39,15 @@ function _ts_metadata(k, v) {
|
|
|
37
39
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
38
40
|
}
|
|
39
41
|
let SpaceGuard = class SpaceGuard {
|
|
40
|
-
static checkPermissions(req, logger,
|
|
42
|
+
static async checkPermissions(req, logger, overrideSpacePermission) {
|
|
41
43
|
let permission;
|
|
42
|
-
if (
|
|
43
|
-
//
|
|
44
|
+
if (req.method === _applicationsconstants.HTTP_METHOD.PUT && await (0, _files.isPathExists)(req.space.realPath) && !await (0, _files.isPathIsDir)(req.space.realPath)) {
|
|
45
|
+
// PUT method may either create a new resource or replace an existing one.
|
|
46
|
+
// Therefore, we must check whether the target resource already exists to apply the appropriate permission rules.
|
|
44
47
|
permission = _spaces.SPACE_OPERATION.MODIFY;
|
|
45
48
|
} else {
|
|
46
|
-
|
|
49
|
+
// The override is applied for specific POST methods that update an existing file rather than creating it.
|
|
50
|
+
permission = overrideSpacePermission || _spaces.SPACE_HTTP_PERMISSION[req.method];
|
|
47
51
|
}
|
|
48
52
|
if (!(0, _permissions.haveSpaceEnvPermissions)(req.space, permission)) {
|
|
49
53
|
logger.warn(`is not allowed to ${req.method} on this space path : *${req.space.alias}* (${req.space.id}) : ${req.space.url}`);
|
|
@@ -65,31 +69,26 @@ let SpaceGuard = class SpaceGuard {
|
|
|
65
69
|
}
|
|
66
70
|
}
|
|
67
71
|
async canActivate(ctx) {
|
|
68
|
-
|
|
72
|
+
if (this.reflector.getAllAndOverride(_spaceskipguarddecorator.SKIP_SPACE_GUARD, [
|
|
69
73
|
ctx.getHandler(),
|
|
70
74
|
ctx.getClass()
|
|
71
|
-
])
|
|
72
|
-
if (skipSpaceGuard) {
|
|
75
|
+
])) {
|
|
73
76
|
return true;
|
|
74
77
|
}
|
|
75
|
-
const skipSpacePermissionsCheck = this.reflector.getAllAndOverride(_spaceskippermissionsdecorator.SKIP_SPACE_PERMISSIONS_CHECK, [
|
|
76
|
-
ctx.getHandler(),
|
|
77
|
-
ctx.getClass()
|
|
78
|
-
]);
|
|
79
78
|
const req = ctx.switchToHttp().getRequest();
|
|
80
|
-
const
|
|
79
|
+
const webDAVContext = this.reflector.getAllAndOverride(_webdavcontextdecorator.WEB_DAV_CONTEXT, [
|
|
81
80
|
ctx.getHandler(),
|
|
82
81
|
ctx.getClass()
|
|
83
82
|
]);
|
|
84
|
-
const
|
|
83
|
+
const syncContext = this.reflector.getAllAndOverride(_synccontextdecorator.SYNC_CONTEXT, [
|
|
85
84
|
ctx.getHandler(),
|
|
86
85
|
ctx.getClass()
|
|
87
86
|
]);
|
|
88
|
-
const
|
|
87
|
+
const collaboraOnlineContext = this.reflector.getAllAndOverride(_collaboraonlineconstants.COLLABORA_CONTEXT, [
|
|
89
88
|
ctx.getHandler(),
|
|
90
89
|
ctx.getClass()
|
|
91
90
|
]);
|
|
92
|
-
const urlSegments = this.urlSegmentsFromContext(req, webDAVContext, syncContext);
|
|
91
|
+
const urlSegments = this.urlSegmentsFromContext(req, webDAVContext, syncContext, collaboraOnlineContext);
|
|
93
92
|
this.checkAccessToSpace(req, urlSegments);
|
|
94
93
|
let space;
|
|
95
94
|
try {
|
|
@@ -107,25 +106,33 @@ let SpaceGuard = class SpaceGuard {
|
|
|
107
106
|
}
|
|
108
107
|
// assign space to request
|
|
109
108
|
req.space = space;
|
|
109
|
+
const skipSpacePermissionsCheck = this.reflector.getAllAndOverride(_spaceskippermissionsdecorator.SKIP_SPACE_PERMISSIONS_CHECK, [
|
|
110
|
+
ctx.getHandler(),
|
|
111
|
+
ctx.getClass()
|
|
112
|
+
]);
|
|
110
113
|
if (skipSpacePermissionsCheck === undefined) {
|
|
111
|
-
|
|
114
|
+
const overrideSpacePermission = this.reflector.getAllAndOverride(_spaceoverridepermissiondecorator.OverrideSpacePermission, [
|
|
115
|
+
ctx.getHandler(),
|
|
116
|
+
ctx.getClass()
|
|
117
|
+
]);
|
|
118
|
+
await SpaceGuard.checkPermissions(req, this.logger, overrideSpacePermission);
|
|
112
119
|
}
|
|
113
120
|
return true;
|
|
114
121
|
}
|
|
115
|
-
urlSegmentsFromContext(req, webDAVContext, syncContext) {
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
} catch (e) {
|
|
124
|
-
this.logger.warn(`${this.canActivate.name} - ${e}`);
|
|
125
|
-
throw new _common.HttpException(e.message, _common.HttpStatus.NOT_FOUND);
|
|
122
|
+
urlSegmentsFromContext(req, webDAVContext, syncContext, collaboraOnlineContext) {
|
|
123
|
+
try {
|
|
124
|
+
if (webDAVContext) {
|
|
125
|
+
return (0, _routes1.WEBDAV_PATH_TO_SPACE_SEGMENTS)(req.params['*']);
|
|
126
|
+
} else if (syncContext) {
|
|
127
|
+
return (0, _routes.SYNC_PATH_TO_SPACE_SEGMENTS)(req.params['*']);
|
|
128
|
+
} else if (collaboraOnlineContext) {
|
|
129
|
+
return (0, _collaboraonlineutils.COLLABORA_ONLINE_TO_SPACE_SEGMENTS)(req);
|
|
126
130
|
}
|
|
131
|
+
return (0, _routes2.PATH_TO_SPACE_SEGMENTS)(req.params['*']);
|
|
132
|
+
} catch (e) {
|
|
133
|
+
this.logger.warn(`${this.canActivate.name} - ${e}`);
|
|
134
|
+
throw new _common.HttpException(e.message, _common.HttpStatus.NOT_FOUND);
|
|
127
135
|
}
|
|
128
|
-
return (0, _routes3.PATH_TO_SPACE_SEGMENTS)(req.params['*']);
|
|
129
136
|
}
|
|
130
137
|
checkAccessToSpace(req, urlSegments) {
|
|
131
138
|
if (!(0, _permissions.canAccessToSpaceUrl)(req.user, urlSegments)) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../backend/src/applications/spaces/guards/space.guard.ts"],"sourcesContent":["/*\n * Copyright (C) 2012-2025 Johan Legrand <johan.legrand@sync-in.com>\n * This file is part of Sync-in | The open source file sync and share solution\n * See the LICENSE file for licensing details\n */\n\nimport { CanActivate, ExecutionContext, HttpException, HttpStatus, Injectable, Logger } from '@nestjs/common'\nimport { Reflector } from '@nestjs/core'\nimport { HTTP_METHOD } from '../../applications.constants'\nimport { ONLY_OFFICE_CONTEXT } from '../../files/constants/only-office'\nimport { API_FILES_ONLY_OFFICE_CALLBACK } from '../../files/constants/routes'\nimport { SYNC_CONTEXT } from '../../sync/decorators/sync-context.decorator'\nimport { SYNC_PATH_TO_SPACE_SEGMENTS } from '../../sync/utils/routes'\nimport { WEB_DAV_CONTEXT } from '../../webdav/decorators/webdav-context.decorator'\nimport { WEBDAV_PATH_TO_SPACE_SEGMENTS } from '../../webdav/utils/routes'\nimport { SPACE_HTTP_PERMISSION, SPACE_OPERATION } from '../constants/spaces'\nimport { SKIP_SPACE_GUARD } from '../decorators/space-skip-guard.decorator'\nimport { SKIP_SPACE_PERMISSIONS_CHECK } from '../decorators/space-skip-permissions.decorator'\nimport { FastifySpaceRequest } from '../interfaces/space-request.interface'\nimport { SpaceEnv } from '../models/space-env.model'\nimport { SpacesManager } from '../services/spaces-manager.service'\nimport { canAccessToSpaceUrl, haveSpaceEnvPermissions } from '../utils/permissions'\nimport { PATH_TO_SPACE_SEGMENTS } from '../utils/routes'\n\n@Injectable()\nexport class SpaceGuard implements CanActivate {\n private readonly logger = new Logger(SpaceGuard.name)\n\n constructor(\n private readonly reflector: Reflector,\n private readonly spacesManager: SpacesManager\n ) {}\n\n static checkPermissions(req: FastifySpaceRequest, logger: Logger, onlyOfficeContext = false) {\n let permission: SPACE_OPERATION\n if (onlyOfficeContext && req.method === HTTP_METHOD.POST && req.originalUrl.startsWith(API_FILES_ONLY_OFFICE_CALLBACK)) {\n // special case : onlyoffice callback use post method to update documents\n permission = SPACE_OPERATION.MODIFY\n } else {\n permission = SPACE_HTTP_PERMISSION[req.method]\n }\n if (!haveSpaceEnvPermissions(req.space, permission)) {\n logger.warn(`is not allowed to ${req.method} on this space path : *${req.space.alias}* (${req.space.id}) : ${req.space.url}`)\n throw new HttpException('You are not allowed to do this action', HttpStatus.FORBIDDEN)\n }\n if ([SPACE_OPERATION.ADD, SPACE_OPERATION.MODIFY].indexOf(permission) > -1) {\n if (req.space.quotaIsExceeded) {\n logger.warn(`Storage quota exceeded for *${req.space.alias}* (${req.space.id})`)\n throw new HttpException('Storage quota exceeded', HttpStatus.INSUFFICIENT_STORAGE)\n } else if (req.space.storageQuota) {\n const contentLength = parseInt(req.headers['content-length'] || '0', 10) || 0\n if (req.space.willExceedQuota(contentLength)) {\n throw new HttpException('Storage quota will be exceeded', HttpStatus.INSUFFICIENT_STORAGE)\n }\n }\n }\n }\n\n async canActivate(ctx: ExecutionContext): Promise<boolean> {\n const skipSpaceGuard = this.reflector.getAllAndOverride(SKIP_SPACE_GUARD, [ctx.getHandler(), ctx.getClass()])\n if (skipSpaceGuard) {\n return true\n }\n const skipSpacePermissionsCheck = this.reflector.getAllAndOverride(SKIP_SPACE_PERMISSIONS_CHECK, [ctx.getHandler(), ctx.getClass()])\n const req: FastifySpaceRequest = ctx.switchToHttp().getRequest()\n const onlyOfficeContext = this.reflector.getAllAndOverride(ONLY_OFFICE_CONTEXT, [ctx.getHandler(), ctx.getClass()])\n const webDAVContext = this.reflector.getAllAndOverride(WEB_DAV_CONTEXT, [ctx.getHandler(), ctx.getClass()])\n const syncContext = this.reflector.getAllAndOverride(SYNC_CONTEXT, [ctx.getHandler(), ctx.getClass()])\n const urlSegments = this.urlSegmentsFromContext(req, webDAVContext, syncContext)\n this.checkAccessToSpace(req, urlSegments)\n let space: SpaceEnv\n try {\n space = await this.spacesManager.spaceEnv(req.user, urlSegments)\n } catch (e) {\n this.logger.warn(`${this.canActivate.name} - ${e}`)\n throw new HttpException('Space path is not valid', HttpStatus.BAD_REQUEST)\n }\n if (!space) {\n this.logger.warn(`${this.canActivate.name} - space not authorized or not found : ${req.params['*']}`)\n throw new HttpException('Space not found', HttpStatus.NOT_FOUND)\n }\n if (!space.enabled) {\n throw new HttpException('Space is disabled', HttpStatus.FORBIDDEN)\n }\n // assign space to request\n req.space = space\n if (skipSpacePermissionsCheck === undefined) {\n SpaceGuard.checkPermissions(req, this.logger, onlyOfficeContext)\n }\n return true\n }\n\n private urlSegmentsFromContext(req: FastifySpaceRequest, webDAVContext: boolean, syncContext: boolean): string[] {\n if (webDAVContext || syncContext) {\n try {\n if (webDAVContext) {\n return WEBDAV_PATH_TO_SPACE_SEGMENTS(req.params['*'])\n } else {\n return SYNC_PATH_TO_SPACE_SEGMENTS(req.params['*'])\n }\n } catch (e) {\n this.logger.warn(`${this.canActivate.name} - ${e}`)\n throw new HttpException(e.message, HttpStatus.NOT_FOUND)\n }\n }\n return PATH_TO_SPACE_SEGMENTS(req.params['*'])\n }\n\n private checkAccessToSpace(req: FastifySpaceRequest, urlSegments: string[]) {\n if (!canAccessToSpaceUrl(req.user, urlSegments)) {\n this.logger.warn(`is not allowed to access to this space repository : ${req.params['*']}`)\n throw new HttpException('You are not allowed to access to this repository', HttpStatus.FORBIDDEN)\n }\n }\n}\n"],"names":["SpaceGuard","checkPermissions","req","logger","onlyOfficeContext","permission","method","HTTP_METHOD","POST","originalUrl","startsWith","API_FILES_ONLY_OFFICE_CALLBACK","SPACE_OPERATION","MODIFY","SPACE_HTTP_PERMISSION","haveSpaceEnvPermissions","space","warn","alias","id","url","HttpException","HttpStatus","FORBIDDEN","ADD","indexOf","quotaIsExceeded","INSUFFICIENT_STORAGE","storageQuota","contentLength","parseInt","headers","willExceedQuota","canActivate","ctx","skipSpaceGuard","reflector","getAllAndOverride","SKIP_SPACE_GUARD","getHandler","getClass","skipSpacePermissionsCheck","SKIP_SPACE_PERMISSIONS_CHECK","switchToHttp","getRequest","ONLY_OFFICE_CONTEXT","webDAVContext","WEB_DAV_CONTEXT","syncContext","SYNC_CONTEXT","urlSegments","urlSegmentsFromContext","checkAccessToSpace","spacesManager","spaceEnv","user","e","name","BAD_REQUEST","params","NOT_FOUND","enabled","undefined","WEBDAV_PATH_TO_SPACE_SEGMENTS","SYNC_PATH_TO_SPACE_SEGMENTS","message","PATH_TO_SPACE_SEGMENTS","canAccessToSpaceUrl","Logger"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../../backend/src/applications/spaces/guards/space.guard.ts"],"sourcesContent":["/*\n * Copyright (C) 2012-2025 Johan Legrand <johan.legrand@sync-in.com>\n * This file is part of Sync-in | The open source file sync and share solution\n * See the LICENSE file for licensing details\n */\n\nimport { CanActivate, ExecutionContext, HttpException, HttpStatus, Injectable, Logger } from '@nestjs/common'\nimport { Reflector } from '@nestjs/core'\nimport { HTTP_METHOD } from '../../applications.constants'\nimport { COLLABORA_CONTEXT } from '../../files/modules/collabora-online/collabora-online.constants'\nimport { COLLABORA_ONLINE_TO_SPACE_SEGMENTS } from '../../files/modules/collabora-online/collabora-online.utils'\nimport { isPathExists, isPathIsDir } from '../../files/utils/files'\nimport { SYNC_CONTEXT } from '../../sync/decorators/sync-context.decorator'\nimport { SYNC_PATH_TO_SPACE_SEGMENTS } from '../../sync/utils/routes'\nimport { WEB_DAV_CONTEXT } from '../../webdav/decorators/webdav-context.decorator'\nimport { WEBDAV_PATH_TO_SPACE_SEGMENTS } from '../../webdav/utils/routes'\nimport { SPACE_HTTP_PERMISSION, SPACE_OPERATION } from '../constants/spaces'\nimport { OverrideSpacePermission } from '../decorators/space-override-permission.decorator'\nimport { SKIP_SPACE_GUARD } from '../decorators/space-skip-guard.decorator'\nimport { SKIP_SPACE_PERMISSIONS_CHECK } from '../decorators/space-skip-permissions.decorator'\nimport { FastifySpaceRequest } from '../interfaces/space-request.interface'\nimport { SpaceEnv } from '../models/space-env.model'\nimport { SpacesManager } from '../services/spaces-manager.service'\nimport { canAccessToSpaceUrl, haveSpaceEnvPermissions } from '../utils/permissions'\nimport { PATH_TO_SPACE_SEGMENTS } from '../utils/routes'\n\n@Injectable()\nexport class SpaceGuard implements CanActivate {\n private readonly logger = new Logger(SpaceGuard.name)\n\n constructor(\n private readonly reflector: Reflector,\n private readonly spacesManager: SpacesManager\n ) {}\n\n static async checkPermissions(req: FastifySpaceRequest, logger: Logger, overrideSpacePermission?: SPACE_OPERATION) {\n let permission: SPACE_OPERATION\n if (req.method === HTTP_METHOD.PUT && (await isPathExists(req.space.realPath)) && !(await isPathIsDir(req.space.realPath))) {\n // PUT method may either create a new resource or replace an existing one.\n // Therefore, we must check whether the target resource already exists to apply the appropriate permission rules.\n permission = SPACE_OPERATION.MODIFY\n } else {\n // The override is applied for specific POST methods that update an existing file rather than creating it.\n permission = overrideSpacePermission || SPACE_HTTP_PERMISSION[req.method]\n }\n if (!haveSpaceEnvPermissions(req.space, permission)) {\n logger.warn(`is not allowed to ${req.method} on this space path : *${req.space.alias}* (${req.space.id}) : ${req.space.url}`)\n throw new HttpException('You are not allowed to do this action', HttpStatus.FORBIDDEN)\n }\n if ([SPACE_OPERATION.ADD, SPACE_OPERATION.MODIFY].indexOf(permission) > -1) {\n if (req.space.quotaIsExceeded) {\n logger.warn(`Storage quota exceeded for *${req.space.alias}* (${req.space.id})`)\n throw new HttpException('Storage quota exceeded', HttpStatus.INSUFFICIENT_STORAGE)\n } else if (req.space.storageQuota) {\n const contentLength = parseInt(req.headers['content-length'] || '0', 10) || 0\n if (req.space.willExceedQuota(contentLength)) {\n throw new HttpException('Storage quota will be exceeded', HttpStatus.INSUFFICIENT_STORAGE)\n }\n }\n }\n }\n\n async canActivate(ctx: ExecutionContext): Promise<boolean> {\n if (this.reflector.getAllAndOverride(SKIP_SPACE_GUARD, [ctx.getHandler(), ctx.getClass()])) {\n return true\n }\n\n const req: FastifySpaceRequest = ctx.switchToHttp().getRequest()\n const webDAVContext = this.reflector.getAllAndOverride(WEB_DAV_CONTEXT, [ctx.getHandler(), ctx.getClass()])\n const syncContext = this.reflector.getAllAndOverride(SYNC_CONTEXT, [ctx.getHandler(), ctx.getClass()])\n const collaboraOnlineContext = this.reflector.getAllAndOverride(COLLABORA_CONTEXT, [ctx.getHandler(), ctx.getClass()])\n\n const urlSegments = this.urlSegmentsFromContext(req, webDAVContext, syncContext, collaboraOnlineContext)\n this.checkAccessToSpace(req, urlSegments)\n let space: SpaceEnv\n try {\n space = await this.spacesManager.spaceEnv(req.user, urlSegments)\n } catch (e) {\n this.logger.warn(`${this.canActivate.name} - ${e}`)\n throw new HttpException('Space path is not valid', HttpStatus.BAD_REQUEST)\n }\n if (!space) {\n this.logger.warn(`${this.canActivate.name} - space not authorized or not found : ${req.params['*']}`)\n throw new HttpException('Space not found', HttpStatus.NOT_FOUND)\n }\n if (!space.enabled) {\n throw new HttpException('Space is disabled', HttpStatus.FORBIDDEN)\n }\n // assign space to request\n req.space = space\n const skipSpacePermissionsCheck = this.reflector.getAllAndOverride(SKIP_SPACE_PERMISSIONS_CHECK, [ctx.getHandler(), ctx.getClass()])\n if (skipSpacePermissionsCheck === undefined) {\n const overrideSpacePermission: SPACE_OPERATION = this.reflector.getAllAndOverride(OverrideSpacePermission, [ctx.getHandler(), ctx.getClass()])\n await SpaceGuard.checkPermissions(req, this.logger, overrideSpacePermission)\n }\n return true\n }\n\n private urlSegmentsFromContext(req: FastifySpaceRequest, webDAVContext: boolean, syncContext: boolean, collaboraOnlineContext: boolean): string[] {\n try {\n if (webDAVContext) {\n return WEBDAV_PATH_TO_SPACE_SEGMENTS(req.params['*'])\n } else if (syncContext) {\n return SYNC_PATH_TO_SPACE_SEGMENTS(req.params['*'])\n } else if (collaboraOnlineContext) {\n return COLLABORA_ONLINE_TO_SPACE_SEGMENTS(req)\n }\n return PATH_TO_SPACE_SEGMENTS(req.params['*'])\n } catch (e) {\n this.logger.warn(`${this.canActivate.name} - ${e}`)\n throw new HttpException(e.message, HttpStatus.NOT_FOUND)\n }\n }\n\n private checkAccessToSpace(req: FastifySpaceRequest, urlSegments: string[]) {\n if (!canAccessToSpaceUrl(req.user, urlSegments)) {\n this.logger.warn(`is not allowed to access to this space repository : ${req.params['*']}`)\n throw new HttpException('You are not allowed to access to this repository', HttpStatus.FORBIDDEN)\n }\n }\n}\n"],"names":["SpaceGuard","checkPermissions","req","logger","overrideSpacePermission","permission","method","HTTP_METHOD","PUT","isPathExists","space","realPath","isPathIsDir","SPACE_OPERATION","MODIFY","SPACE_HTTP_PERMISSION","haveSpaceEnvPermissions","warn","alias","id","url","HttpException","HttpStatus","FORBIDDEN","ADD","indexOf","quotaIsExceeded","INSUFFICIENT_STORAGE","storageQuota","contentLength","parseInt","headers","willExceedQuota","canActivate","ctx","reflector","getAllAndOverride","SKIP_SPACE_GUARD","getHandler","getClass","switchToHttp","getRequest","webDAVContext","WEB_DAV_CONTEXT","syncContext","SYNC_CONTEXT","collaboraOnlineContext","COLLABORA_CONTEXT","urlSegments","urlSegmentsFromContext","checkAccessToSpace","spacesManager","spaceEnv","user","e","name","BAD_REQUEST","params","NOT_FOUND","enabled","skipSpacePermissionsCheck","SKIP_SPACE_PERMISSIONS_CHECK","undefined","OverrideSpacePermission","WEBDAV_PATH_TO_SPACE_SEGMENTS","SYNC_PATH_TO_SPACE_SEGMENTS","COLLABORA_ONLINE_TO_SPACE_SEGMENTS","PATH_TO_SPACE_SEGMENTS","message","canAccessToSpaceUrl","Logger"],"mappings":"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"}
|
|
@@ -13,8 +13,6 @@ const _shared = require("../../../common/shared");
|
|
|
13
13
|
const _cacheservice = require("../../../infrastructure/cache/services/cache.service");
|
|
14
14
|
const _contextmanagerservice = require("../../../infrastructure/context/services/context-manager.service");
|
|
15
15
|
const _constants = require("../../../infrastructure/database/constants");
|
|
16
|
-
const _routes = require("../../files/constants/routes");
|
|
17
|
-
const _onlyofficeenvironmentdecorator = require("../../files/decorators/only-office-environment.decorator");
|
|
18
16
|
const _filesqueriesservice = require("../../files/services/files-queries.service");
|
|
19
17
|
const _linksqueriesservice = require("../../links/services/links-queries.service");
|
|
20
18
|
const _notificationsmanagerservice = require("../../notifications/services/notifications-manager.service");
|
|
@@ -28,6 +26,7 @@ const _usersqueriesservice = require("../../users/services/users-queries.service
|
|
|
28
26
|
const _test = require("../../users/utils/test");
|
|
29
27
|
const _webdavcontextdecorator = require("../../webdav/decorators/webdav-context.decorator");
|
|
30
28
|
const _spaces = require("../constants/spaces");
|
|
29
|
+
const _spaceoverridepermissiondecorator = require("../decorators/space-override-permission.decorator");
|
|
31
30
|
const _spaceskipguarddecorator = require("../decorators/space-skip-guard.decorator");
|
|
32
31
|
const _spaceskippermissionsdecorator = require("../decorators/space-skip-permissions.decorator");
|
|
33
32
|
const _spacesmanagerservice = require("../services/spaces-manager.service");
|
|
@@ -74,6 +73,8 @@ describe(_spaceguard.SpaceGuard.name, ()=>{
|
|
|
74
73
|
// mocks
|
|
75
74
|
spacesManager['setQuotaExceeded'] = jest.fn();
|
|
76
75
|
userTest = new _usermodel.UserModel((0, _test.generateUserTest)());
|
|
76
|
+
});
|
|
77
|
+
beforeEach(()=>{
|
|
77
78
|
context = (0, _tsjest.createMock)();
|
|
78
79
|
});
|
|
79
80
|
it('should be defined', ()=>{
|
|
@@ -386,8 +387,6 @@ describe(_spaceguard.SpaceGuard.name, ()=>{
|
|
|
386
387
|
}
|
|
387
388
|
});
|
|
388
389
|
expect(await spacesGuard.canActivate(context)).toBe(true);
|
|
389
|
-
// reset context
|
|
390
|
-
context = (0, _tsjest.createMock)();
|
|
391
390
|
});
|
|
392
391
|
it('should fail with quota exceeded', async ()=>{
|
|
393
392
|
userTest.role = _user.USER_ROLE.USER;
|
|
@@ -482,9 +481,8 @@ describe(_spaceguard.SpaceGuard.name, ()=>{
|
|
|
482
481
|
}
|
|
483
482
|
});
|
|
484
483
|
await expect(spacesGuard.canActivate(context)).rejects.toThrow(_common.HttpException);
|
|
485
|
-
// reset
|
|
484
|
+
// reset mock
|
|
486
485
|
spyUrlSegment.mockRestore();
|
|
487
|
-
context = (0, _tsjest.createMock)();
|
|
488
486
|
});
|
|
489
487
|
it('should validate (or not) the sync routes', async ()=>{
|
|
490
488
|
userTest.role = _user.USER_ROLE.USER;
|
|
@@ -514,24 +512,25 @@ describe(_spaceguard.SpaceGuard.name, ()=>{
|
|
|
514
512
|
await expect(spacesGuard.canActivate(context)).rejects.toThrow(_common.HttpException);
|
|
515
513
|
// reset context
|
|
516
514
|
spyUrlSegment.mockRestore();
|
|
517
|
-
context = (0, _tsjest.createMock)();
|
|
518
515
|
});
|
|
519
|
-
it('should
|
|
516
|
+
it('should allow the modify permission when using the POST method with override space permission decorator', async ()=>{
|
|
520
517
|
userTest.role = _user.USER_ROLE.USER;
|
|
521
518
|
spacesManager.spaceEnv = jest.fn().mockReturnValue({
|
|
522
519
|
enabled: true,
|
|
523
520
|
envPermissions: `${_spaces.SPACE_OPERATION.MODIFY}`
|
|
524
521
|
});
|
|
525
|
-
(0,
|
|
522
|
+
(0, _spaceoverridepermissiondecorator.OverrideSpacePermission)(_spaces.SPACE_OPERATION.MODIFY)(context.getHandler());
|
|
526
523
|
context.switchToHttp().getRequest.mockReturnValue({
|
|
527
524
|
method: 'POST',
|
|
528
525
|
user: userTest,
|
|
529
|
-
originalUrl:
|
|
526
|
+
originalUrl: '1',
|
|
530
527
|
params: {
|
|
531
528
|
'*': 'files/personal/root'
|
|
532
529
|
}
|
|
533
530
|
});
|
|
534
531
|
expect(await spacesGuard.canActivate(context)).toBe(true);
|
|
532
|
+
// reset context
|
|
533
|
+
context = (0, _tsjest.createMock)();
|
|
535
534
|
spacesManager.spaceEnv = jest.fn().mockReturnValue({
|
|
536
535
|
enabled: true,
|
|
537
536
|
envPermissions: `${_spaces.SPACE_OPERATION.ADD}`
|
|
@@ -540,14 +539,12 @@ describe(_spaceguard.SpaceGuard.name, ()=>{
|
|
|
540
539
|
context.switchToHttp().getRequest.mockReturnValue({
|
|
541
540
|
method: 'POST',
|
|
542
541
|
user: userTest,
|
|
543
|
-
originalUrl: '',
|
|
542
|
+
originalUrl: '2',
|
|
544
543
|
params: {
|
|
545
544
|
'*': 'files/personal/root'
|
|
546
545
|
}
|
|
547
546
|
});
|
|
548
547
|
expect(await spacesGuard.canActivate(context)).toBe(true);
|
|
549
|
-
// reset context
|
|
550
|
-
context = (0, _tsjest.createMock)();
|
|
551
548
|
});
|
|
552
549
|
it('should pass if skipSpaceGuard context is enabled', async ()=>{
|
|
553
550
|
userTest.role = _user.USER_ROLE.USER;
|
|
@@ -568,8 +565,6 @@ describe(_spaceguard.SpaceGuard.name, ()=>{
|
|
|
568
565
|
});
|
|
569
566
|
(0, _spaceskipguarddecorator.SkipSpaceGuard)()(context.getHandler());
|
|
570
567
|
expect(await spacesGuard.canActivate(context)).toBe(true);
|
|
571
|
-
// reset context
|
|
572
|
-
context = (0, _tsjest.createMock)();
|
|
573
568
|
});
|
|
574
569
|
it('coverage only', async ()=>{
|
|
575
570
|
userTest.role = _user.USER_ROLE.USER;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../backend/src/applications/spaces/guards/space.guard.spec.ts"],"sourcesContent":["/*\n * Copyright (C) 2012-2025 Johan Legrand <johan.legrand@sync-in.com>\n * This file is part of Sync-in | The open source file sync and share solution\n * See the LICENSE file for licensing details\n */\n\nimport { createMock, DeepMocked } from '@golevelup/ts-jest'\nimport { ExecutionContext, HttpException, HttpStatus } from '@nestjs/common'\nimport { Test, TestingModule } from '@nestjs/testing'\nimport { intersectPermissions } from '../../../common/shared'\nimport { Cache } from '../../../infrastructure/cache/services/cache.service'\nimport { ContextManager } from '../../../infrastructure/context/services/context-manager.service'\nimport { DB_TOKEN_PROVIDER } from '../../../infrastructure/database/constants'\nimport { API_FILES_ONLY_OFFICE_CALLBACK } from '../../files/constants/routes'\nimport { OnlyOfficeContext } from '../../files/decorators/only-office-environment.decorator'\nimport { FilesQueries } from '../../files/services/files-queries.service'\nimport { LinksQueries } from '../../links/services/links-queries.service'\nimport { NotificationsManager } from '../../notifications/services/notifications-manager.service'\nimport { SHARE_ALL_OPERATIONS } from '../../shares/constants/shares'\nimport { SharesManager } from '../../shares/services/shares-manager.service'\nimport { SharesQueries } from '../../shares/services/shares-queries.service'\nimport { SyncContext } from '../../sync/decorators/sync-context.decorator'\nimport { USER_PERMISSION, USER_ROLE } from '../../users/constants/user'\nimport { UserModel } from '../../users/models/user.model'\nimport { UsersQueries } from '../../users/services/users-queries.service'\nimport { generateUserTest } from '../../users/utils/test'\nimport { WebDAVContext } from '../../webdav/decorators/webdav-context.decorator'\nimport { SPACE_ALIAS, SPACE_ALL_OPERATIONS, SPACE_OPERATION, SPACE_PERMS_SEP, SPACE_REPOSITORY } from '../constants/spaces'\nimport { SkipSpaceGuard } from '../decorators/space-skip-guard.decorator'\nimport { SkipSpacePermissionsCheck } from '../decorators/space-skip-permissions.decorator'\nimport { SpaceEnv } from '../models/space-env.model'\nimport { SpacesManager } from '../services/spaces-manager.service'\nimport { SpacesQueries } from '../services/spaces-queries.service'\nimport { SpaceGuard } from './space.guard'\n\ndescribe(SpaceGuard.name, () => {\n let spacesGuard: SpaceGuard\n let spacesManager: SpacesManager\n let spacesQueries: SpacesQueries\n let userTest: UserModel\n let context: DeepMocked<ExecutionContext>\n\n beforeAll(async () => {\n const module: TestingModule = await Test.createTestingModule({\n providers: [\n {\n provide: DB_TOKEN_PROVIDER,\n useValue: {}\n },\n {\n provide: Cache,\n useValue: {}\n },\n { provide: ContextManager, useValue: {} },\n {\n provide: NotificationsManager,\n useValue: {}\n },\n SpaceGuard,\n SpacesManager,\n SpacesQueries,\n SharesManager,\n SharesQueries,\n FilesQueries,\n UsersQueries,\n LinksQueries\n ]\n }).compile()\n\n spacesManager = module.get<SpacesManager>(SpacesManager)\n spacesQueries = module.get<SpacesQueries>(SpacesQueries)\n spacesGuard = module.get<SpaceGuard>(SpaceGuard)\n // mocks\n spacesManager['setQuotaExceeded'] = jest.fn()\n userTest = new UserModel(generateUserTest())\n context = createMock<ExecutionContext>()\n })\n\n it('should be defined', () => {\n expect(spacesGuard).toBeDefined()\n expect(spacesManager).toBeDefined()\n expect(userTest).toBeDefined()\n })\n\n it('should pass for a personal space', async () => {\n context.switchToHttp().getRequest.mockReturnValue({\n user: userTest,\n params: { '*': 'files/personal/root/foo/bar' }\n })\n expect(await spacesGuard.canActivate(context)).toBe(true)\n const req: any = context.switchToHttp().getRequest()\n expect(req.space.id).toBe(0)\n expect(req.space.repository).toBe(SPACE_REPOSITORY.FILES)\n expect(req.space.alias).toBe(SPACE_ALIAS.PERSONAL)\n expect(req.space.name).toBe(SPACE_ALIAS.PERSONAL)\n expect(req.space.enabled).toBe(true)\n expect(req.space.root).toBeUndefined()\n expect(req.space.dbFile).toMatchObject({ inTrash: false, ownerId: userTest.id, path: 'root/foo/bar' })\n expect(req.space.permissions).toBe(SPACE_ALL_OPERATIONS)\n expect(req.space.envPermissions).toBe(SPACE_ALL_OPERATIONS)\n expect(req.space.inFilesRepository).toBe(true)\n expect(req.space.inPersonalSpace).toBe(true)\n expect(req.space.inTrashRepository).toBe(false)\n expect(req.space.inSharesRepository).toBe(false)\n expect(req.space.inSharesList).toBe(false)\n expect(req.space.paths).toEqual(expect.arrayContaining(['root', 'foo', 'bar']))\n })\n\n it('should pass for a common space', async () => {\n const fakeSpace = {\n id: -1,\n alias: 'test',\n name: 'Test',\n enabled: true,\n permissions: ':a:d:m:so',\n role: 0\n }\n spacesQueries.permissions = jest.fn().mockReturnValueOnce(fakeSpace)\n context.switchToHttp().getRequest.mockReturnValue({\n user: userTest,\n params: { '*': 'files/test' }\n })\n expect(await spacesGuard.canActivate(context)).toBe(true)\n const req: any = context.switchToHttp().getRequest()\n expect(req.space.id).toBe(fakeSpace.id)\n expect(req.space.repository).toBe(SPACE_REPOSITORY.FILES)\n expect(req.space.alias).toBe(fakeSpace.alias)\n expect(req.space.name).toBe(fakeSpace.name)\n expect(req.space.enabled).toBe(true)\n expect(req.space.root).toMatchObject({ id: 0, alias: '', name: '', permissions: 'a:d:m:so' })\n expect(req.space.dbFile).toMatchObject({ inTrash: false, spaceId: fakeSpace.id, spaceExternalRootId: null, path: '.' })\n expect(req.space.permissions).toBe(SHARE_ALL_OPERATIONS)\n expect(req.space.envPermissions).not.toContain('d')\n expect(req.space.inFilesRepository).toBe(true)\n expect(req.space.inPersonalSpace).toBe(false)\n expect(req.space.inTrashRepository).toBe(false)\n expect(req.space.inSharesRepository).toBe(false)\n expect(req.space.inSharesList).toBe(false)\n expect(req.space.paths).toHaveLength(0)\n })\n\n it('should pass for a common space root', async () => {\n const fakeSpace = {\n id: -1,\n alias: 'test',\n name: 'Test',\n enabled: true,\n permissions: 'a:d:m:so',\n role: 1,\n root: {\n id: -2,\n alias: 'root',\n name: 'Root',\n permissions: 'a:d:so',\n owner: { id: -3, login: 'johaven' },\n file: { id: -4, path: 'code', inTrash: false },\n externalPath: null\n }\n }\n spacesQueries.permissions = jest.fn().mockReturnValueOnce(fakeSpace)\n context.switchToHttp().getRequest.mockReturnValue({\n user: userTest,\n params: { '*': 'files/test/root' }\n })\n expect(await spacesGuard.canActivate(context)).toBe(true)\n const req: any = context.switchToHttp().getRequest()\n expect(req.space.id).toBe(fakeSpace.id)\n expect(req.space.repository).toBe(SPACE_REPOSITORY.FILES)\n expect(req.space.alias).toBe(fakeSpace.alias)\n expect(req.space.name).toBe(fakeSpace.name)\n expect(req.space.enabled).toBe(true)\n expect(req.space.root).toMatchObject(fakeSpace.root)\n expect(req.space.dbFile).toMatchObject({ inTrash: false, ownerId: fakeSpace.root.owner.id, path: fakeSpace.root.file.path })\n expect(req.space.permissions).toBe(SPACE_ALL_OPERATIONS)\n expect(req.space.envPermissions).toBe(\n intersectPermissions(fakeSpace.permissions, fakeSpace.root.permissions)\n .split(SPACE_PERMS_SEP)\n .filter((p) => p !== SPACE_OPERATION.DELETE)\n .join(SPACE_PERMS_SEP)\n )\n expect(req.space.inFilesRepository).toBe(true)\n expect(req.space.inPersonalSpace).toBe(false)\n expect(req.space.inTrashRepository).toBe(false)\n expect(req.space.inSharesRepository).toBe(false)\n expect(req.space.inSharesList).toBe(false)\n expect(req.space.paths).toHaveLength(0)\n })\n\n it('should pass for a common space root with a path', async () => {\n const fakeSpace = {\n id: -1,\n alias: 'test',\n name: 'Test',\n enabled: true,\n permissions: 'a:d:m:so',\n role: 1,\n root: {\n id: -2,\n alias: 'root',\n name: 'Root',\n permissions: 'a:d:so',\n owner: { id: -3, login: 'johaven' },\n file: { id: -4, path: 'code', inTrash: false },\n externalPath: null\n }\n }\n spacesQueries.permissions = jest.fn().mockReturnValueOnce(fakeSpace)\n context.switchToHttp().getRequest.mockReturnValue({\n user: userTest,\n params: { '*': 'files/test/root/path' }\n })\n expect(await spacesGuard.canActivate(context)).toBe(true)\n const req: any = context.switchToHttp().getRequest()\n expect(req.space.id).toBe(fakeSpace.id)\n expect(req.space.repository).toBe(SPACE_REPOSITORY.FILES)\n expect(req.space.alias).toBe(fakeSpace.alias)\n expect(req.space.name).toBe(fakeSpace.name)\n expect(req.space.enabled).toBe(true)\n expect(req.space.root).toMatchObject(fakeSpace.root)\n expect(req.space.dbFile).toMatchObject({\n inTrash: false,\n ownerId: fakeSpace.root.owner.id,\n path: `${fakeSpace.root.file.path}/${req.space.paths[0]}`\n })\n expect(req.space.permissions).toBe(SPACE_ALL_OPERATIONS)\n expect(req.space.envPermissions).toBe(fakeSpace.root.permissions)\n expect(req.space.inFilesRepository).toBe(true)\n expect(req.space.inPersonalSpace).toBe(false)\n expect(req.space.inTrashRepository).toBe(false)\n expect(req.space.inSharesRepository).toBe(false)\n expect(req.space.inSharesList).toBe(false)\n expect(req.space.paths).toHaveLength(1)\n })\n\n it('should pass for a space in shares repository', async () => {\n context.switchToHttp().getRequest.mockReturnValue({\n user: userTest,\n params: { '*': 'shares' }\n })\n expect(await spacesGuard.canActivate(context)).toBe(true)\n const req: any = context.switchToHttp().getRequest()\n expect(req.space.id).toBe(0)\n expect(req.space.repository).toBe(SPACE_REPOSITORY.SHARES)\n expect(req.space.alias).toBe(SPACE_REPOSITORY.SHARES)\n expect(req.space.name).toBe(SPACE_REPOSITORY.SHARES)\n expect(req.space.enabled).toBe(true)\n expect(req.space.root).toBeUndefined()\n expect(req.space.dbFile).toBeUndefined()\n expect(req.space.permissions).toBe('')\n expect(req.space.envPermissions).toBe('')\n expect(req.space.inFilesRepository).toBe(false)\n expect(req.space.inPersonalSpace).toBe(false)\n expect(req.space.inTrashRepository).toBe(false)\n expect(req.space.inSharesRepository).toBe(true)\n expect(req.space.inSharesList).toBe(true)\n expect(req.space.paths).toHaveLength(0)\n })\n\n it('should not pass if the space is not found or not valid', async () => {\n const fakeSpace = null\n spacesQueries.permissions = jest.fn().mockReturnValueOnce(fakeSpace)\n context.switchToHttp().getRequest.mockReturnValue({\n user: userTest,\n params: { '*': 'files/foo' }\n })\n await expect(spacesGuard.canActivate(context)).rejects.toThrow(HttpException)\n })\n\n it('should validate (or not) the access to the space depending on the user permissions', async () => {\n // we only check the `spacesManager.checkAccessToSpace` function, ignores the `spacesManager.spaceEnv`\n userTest.applications = [USER_PERMISSION.PERSONAL_SPACE]\n for (const url of ['', 'shares/personal', 'shares/toto']) {\n context.switchToHttp().getRequest.mockReturnValue({\n user: userTest,\n params: { '*': url }\n })\n await expect(spacesGuard.canActivate(context)).rejects.toThrow(HttpException)\n }\n // should pass because it is a standard user\n // should not pass because user is a guest (and dot not have the permission to access to a personal space)\n spacesManager.spaceEnv = jest.fn().mockReturnValueOnce({ enabled: true }) // only for user role\n context.switchToHttp().getRequest.mockReturnValue({\n user: userTest,\n params: { '*': 'files/personal/root/foo/bar' }\n })\n for (const userRole of [USER_ROLE.USER, USER_ROLE.GUEST]) {\n userTest.role = userRole\n if (userRole === USER_ROLE.USER) {\n expect(await spacesGuard.canActivate(context)).toBe(true)\n } else {\n await expect(spacesGuard.canActivate(context)).rejects.toThrow(HttpException)\n }\n }\n })\n\n it('should check user permissions on route', async () => {\n userTest.role = USER_ROLE.USER\n spacesManager.spaceEnv = jest.fn().mockReturnValue({\n enabled: true,\n envPermissions: `${SPACE_OPERATION.MODIFY}`\n } as Partial<SpaceEnv>)\n // does not allow creation (only modify)\n context.switchToHttp().getRequest.mockReturnValueOnce({\n method: 'POST',\n user: userTest,\n params: { '*': 'files/personal' }\n })\n await expect(spacesGuard.canActivate(context)).rejects.toThrow(HttpException)\n\n // allows modification\n context.switchToHttp().getRequest.mockReturnValue({\n method: 'PATCH',\n user: userTest,\n params: { '*': 'files/personal' }\n })\n expect(await spacesGuard.canActivate(context)).toBe(true)\n\n // does not allow guest (on personal space)\n userTest.role = USER_ROLE.GUEST\n await expect(spacesGuard.canActivate(context)).rejects.toThrow(HttpException)\n\n // allow if SkipSpacePermissionsCheck is enabled\n userTest.role = USER_ROLE.USER\n SkipSpacePermissionsCheck()(context.getHandler())\n spacesManager.spaceEnv = jest.fn().mockReturnValue({\n enabled: true,\n envPermissions: `${SPACE_OPERATION.MODIFY}`\n } as Partial<SpaceEnv>)\n // does not allow creation but pass\n context.switchToHttp().getRequest.mockReturnValueOnce({\n method: 'POST',\n user: userTest,\n params: { '*': 'files/personal' }\n })\n expect(await spacesGuard.canActivate(context)).toBe(true)\n // reset context\n context = createMock<ExecutionContext>()\n })\n\n it('should fail with quota exceeded', async () => {\n userTest.role = USER_ROLE.USER\n spacesManager.spaceEnv = jest.fn().mockReturnValueOnce({\n enabled: true,\n envPermissions: `${SPACE_OPERATION.ADD}`,\n quotaIsExceeded: true\n } as Partial<SpaceEnv>)\n context.switchToHttp().getRequest.mockReturnValueOnce({\n method: 'POST',\n user: userTest,\n params: { '*': 'files/personal' }\n })\n await expect(spacesGuard.canActivate(context)).rejects.toEqual(expect.objectContaining({ status: HttpStatus.INSUFFICIENT_STORAGE }))\n })\n\n it('should fail if request content-length header exceed the quota', async () => {\n userTest.role = USER_ROLE.USER\n const storageQuota = 12\n const storageUsage = 11\n spacesManager.spaceEnv = jest.fn().mockReturnValue({\n enabled: true,\n envPermissions: `${SPACE_OPERATION.ADD}`,\n storageQuota: storageQuota,\n storageUsage: storageUsage,\n willExceedQuota: (contentLength: number) => contentLength > storageQuota - storageUsage\n } as Partial<SpaceEnv>)\n context.switchToHttp().getRequest.mockReturnValueOnce({\n method: 'POST',\n headers: { 'content-length': 13 },\n user: userTest,\n params: { '*': 'files/personal' }\n })\n await expect(spacesGuard.canActivate(context)).rejects.toEqual(expect.objectContaining({ status: HttpStatus.INSUFFICIENT_STORAGE }))\n context.switchToHttp().getRequest.mockReturnValueOnce({\n method: 'POST',\n user: userTest,\n headers: {},\n params: { '*': 'files/personal' }\n })\n expect(await spacesGuard.canActivate(context)).toBe(true)\n })\n\n it('should fail with space disabled', async () => {\n userTest.role = USER_ROLE.USER\n spacesManager.spaceEnv = jest.fn().mockReturnValueOnce({\n enabled: false\n } as Partial<SpaceEnv>)\n context.switchToHttp().getRequest.mockReturnValueOnce({\n method: 'POST',\n user: userTest,\n params: { '*': 'files/personal' }\n })\n await expect(spacesGuard.canActivate(context)).rejects.toMatchObject({ status: HttpStatus.FORBIDDEN })\n })\n\n it('should validate (or not) the webdav routes', async () => {\n userTest.role = USER_ROLE.USER\n spacesManager.spaceEnv = jest.fn().mockReturnValue({ enabled: true })\n const spyUrlSegment = jest.spyOn(spacesGuard as any, 'urlSegmentsFromContext')\n WebDAVContext()(context.getHandler())\n context.switchToHttp().getRequest.mockReturnValueOnce({\n user: userTest,\n params: { '*': 'webdav/personal' }\n })\n expect(await spacesGuard.canActivate(context)).toBe(true)\n expect(spyUrlSegment.mock.results[0].value).toEqual(['files', 'personal'])\n context.switchToHttp().getRequest.mockReturnValueOnce({\n user: userTest,\n params: { '*': 'webdav/files' }\n })\n await expect(spacesGuard.canActivate(context)).rejects.toThrow(HttpException)\n // reset context\n spyUrlSegment.mockRestore()\n context = createMock<ExecutionContext>()\n })\n\n it('should validate (or not) the sync routes', async () => {\n userTest.role = USER_ROLE.USER\n spacesManager.spaceEnv = jest.fn().mockReturnValue({ enabled: true })\n const spyUrlSegment = jest.spyOn(spacesGuard as any, 'urlSegmentsFromContext')\n SyncContext()(context.getHandler())\n context.switchToHttp().getRequest.mockReturnValueOnce({\n user: userTest,\n params: { '*': 'personal/foo' }\n })\n expect(await spacesGuard.canActivate(context)).toBe(true)\n expect(spyUrlSegment.mock.results[0].value).toEqual(['files', 'personal', 'foo'])\n context.switchToHttp().getRequest.mockReturnValueOnce({\n user: userTest,\n params: { '*': 'sync/files' }\n })\n await expect(spacesGuard.canActivate(context)).rejects.toThrow(HttpException)\n // reset context\n spyUrlSegment.mockRestore()\n context = createMock<ExecutionContext>()\n })\n\n it('should require the modify permission when using the POST method on the OnlyOffice callback URL', async () => {\n userTest.role = USER_ROLE.USER\n spacesManager.spaceEnv = jest.fn().mockReturnValue({ enabled: true, envPermissions: `${SPACE_OPERATION.MODIFY}` })\n OnlyOfficeContext()(context.getHandler())\n context.switchToHttp().getRequest.mockReturnValue({\n method: 'POST',\n user: userTest,\n originalUrl: API_FILES_ONLY_OFFICE_CALLBACK,\n params: { '*': 'files/personal/root' }\n })\n expect(await spacesGuard.canActivate(context)).toBe(true)\n spacesManager.spaceEnv = jest.fn().mockReturnValue({ enabled: true, envPermissions: `${SPACE_OPERATION.ADD}` })\n await expect(spacesGuard.canActivate(context)).rejects.toThrow(HttpException)\n context.switchToHttp().getRequest.mockReturnValue({\n method: 'POST',\n user: userTest,\n originalUrl: '',\n params: { '*': 'files/personal/root' }\n })\n expect(await spacesGuard.canActivate(context)).toBe(true)\n // reset context\n context = createMock<ExecutionContext>()\n })\n\n it('should pass if skipSpaceGuard context is enabled', async () => {\n userTest.role = USER_ROLE.USER\n userTest.applications = [USER_PERMISSION.PERSONAL_SPACE]\n spacesManager.spaceEnv = jest.fn().mockReturnValue({ enabled: true })\n context.switchToHttp().getRequest.mockReturnValue({\n user: userTest,\n params: { '*': 'shares/personal' }\n })\n await expect(spacesGuard.canActivate(context)).rejects.toMatchObject({ status: HttpStatus.FORBIDDEN })\n SkipSpaceGuard()(context.getHandler())\n expect(await spacesGuard.canActivate(context)).toBe(true)\n // reset context\n context = createMock<ExecutionContext>()\n })\n\n it('coverage only', async () => {\n userTest.role = USER_ROLE.USER\n userTest.applications = [USER_PERMISSION.PERSONAL_SPACE]\n spacesManager.spaceEnv = jest.fn().mockRejectedValueOnce(new Error('error'))\n context.switchToHttp().getRequest.mockReturnValue({\n user: userTest,\n params: { '*': 'files/personal' }\n })\n await expect(spacesGuard.canActivate(context)).rejects.toMatchObject({ status: HttpStatus.BAD_REQUEST })\n })\n})\n"],"names":["describe","SpaceGuard","name","spacesGuard","spacesManager","spacesQueries","userTest","context","beforeAll","module","Test","createTestingModule","providers","provide","DB_TOKEN_PROVIDER","useValue","Cache","ContextManager","NotificationsManager","SpacesManager","SpacesQueries","SharesManager","SharesQueries","FilesQueries","UsersQueries","LinksQueries","compile","get","jest","fn","UserModel","generateUserTest","createMock","it","expect","toBeDefined","switchToHttp","getRequest","mockReturnValue","user","params","canActivate","toBe","req","space","id","repository","SPACE_REPOSITORY","FILES","alias","SPACE_ALIAS","PERSONAL","enabled","root","toBeUndefined","dbFile","toMatchObject","inTrash","ownerId","path","permissions","SPACE_ALL_OPERATIONS","envPermissions","inFilesRepository","inPersonalSpace","inTrashRepository","inSharesRepository","inSharesList","paths","toEqual","arrayContaining","fakeSpace","role","mockReturnValueOnce","spaceId","spaceExternalRootId","SHARE_ALL_OPERATIONS","not","toContain","toHaveLength","owner","login","file","externalPath","intersectPermissions","split","SPACE_PERMS_SEP","filter","p","SPACE_OPERATION","DELETE","join","SHARES","rejects","toThrow","HttpException","applications","USER_PERMISSION","PERSONAL_SPACE","url","spaceEnv","userRole","USER_ROLE","USER","GUEST","MODIFY","method","SkipSpacePermissionsCheck","getHandler","ADD","quotaIsExceeded","objectContaining","status","HttpStatus","INSUFFICIENT_STORAGE","storageQuota","storageUsage","willExceedQuota","contentLength","headers","FORBIDDEN","spyUrlSegment","spyOn","WebDAVContext","mock","results","value","mockRestore","SyncContext","OnlyOfficeContext","originalUrl","API_FILES_ONLY_OFFICE_CALLBACK","SkipSpaceGuard","mockRejectedValueOnce","Error","BAD_REQUEST"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../../backend/src/applications/spaces/guards/space.guard.spec.ts"],"sourcesContent":["/*\n * Copyright (C) 2012-2025 Johan Legrand <johan.legrand@sync-in.com>\n * This file is part of Sync-in | The open source file sync and share solution\n * See the LICENSE file for licensing details\n */\n\nimport { createMock, DeepMocked } from '@golevelup/ts-jest'\nimport { ExecutionContext, HttpException, HttpStatus } from '@nestjs/common'\nimport { Test, TestingModule } from '@nestjs/testing'\nimport { intersectPermissions } from '../../../common/shared'\nimport { Cache } from '../../../infrastructure/cache/services/cache.service'\nimport { ContextManager } from '../../../infrastructure/context/services/context-manager.service'\nimport { DB_TOKEN_PROVIDER } from '../../../infrastructure/database/constants'\nimport { FilesQueries } from '../../files/services/files-queries.service'\nimport { LinksQueries } from '../../links/services/links-queries.service'\nimport { NotificationsManager } from '../../notifications/services/notifications-manager.service'\nimport { SHARE_ALL_OPERATIONS } from '../../shares/constants/shares'\nimport { SharesManager } from '../../shares/services/shares-manager.service'\nimport { SharesQueries } from '../../shares/services/shares-queries.service'\nimport { SyncContext } from '../../sync/decorators/sync-context.decorator'\nimport { USER_PERMISSION, USER_ROLE } from '../../users/constants/user'\nimport { UserModel } from '../../users/models/user.model'\nimport { UsersQueries } from '../../users/services/users-queries.service'\nimport { generateUserTest } from '../../users/utils/test'\nimport { WebDAVContext } from '../../webdav/decorators/webdav-context.decorator'\nimport { SPACE_ALIAS, SPACE_ALL_OPERATIONS, SPACE_OPERATION, SPACE_PERMS_SEP, SPACE_REPOSITORY } from '../constants/spaces'\nimport { OverrideSpacePermission } from '../decorators/space-override-permission.decorator'\nimport { SkipSpaceGuard } from '../decorators/space-skip-guard.decorator'\nimport { SkipSpacePermissionsCheck } from '../decorators/space-skip-permissions.decorator'\nimport { SpaceEnv } from '../models/space-env.model'\nimport { SpacesManager } from '../services/spaces-manager.service'\nimport { SpacesQueries } from '../services/spaces-queries.service'\nimport { SpaceGuard } from './space.guard'\n\ndescribe(SpaceGuard.name, () => {\n let spacesGuard: SpaceGuard\n let spacesManager: SpacesManager\n let spacesQueries: SpacesQueries\n let userTest: UserModel\n let context: DeepMocked<ExecutionContext>\n\n beforeAll(async () => {\n const module: TestingModule = await Test.createTestingModule({\n providers: [\n {\n provide: DB_TOKEN_PROVIDER,\n useValue: {}\n },\n {\n provide: Cache,\n useValue: {}\n },\n { provide: ContextManager, useValue: {} },\n {\n provide: NotificationsManager,\n useValue: {}\n },\n SpaceGuard,\n SpacesManager,\n SpacesQueries,\n SharesManager,\n SharesQueries,\n FilesQueries,\n UsersQueries,\n LinksQueries\n ]\n }).compile()\n\n spacesManager = module.get<SpacesManager>(SpacesManager)\n spacesQueries = module.get<SpacesQueries>(SpacesQueries)\n spacesGuard = module.get<SpaceGuard>(SpaceGuard)\n // mocks\n spacesManager['setQuotaExceeded'] = jest.fn()\n userTest = new UserModel(generateUserTest())\n })\n\n beforeEach(() => {\n context = createMock<ExecutionContext>()\n })\n\n it('should be defined', () => {\n expect(spacesGuard).toBeDefined()\n expect(spacesManager).toBeDefined()\n expect(userTest).toBeDefined()\n })\n\n it('should pass for a personal space', async () => {\n context.switchToHttp().getRequest.mockReturnValue({\n user: userTest,\n params: { '*': 'files/personal/root/foo/bar' }\n })\n expect(await spacesGuard.canActivate(context)).toBe(true)\n const req: any = context.switchToHttp().getRequest()\n expect(req.space.id).toBe(0)\n expect(req.space.repository).toBe(SPACE_REPOSITORY.FILES)\n expect(req.space.alias).toBe(SPACE_ALIAS.PERSONAL)\n expect(req.space.name).toBe(SPACE_ALIAS.PERSONAL)\n expect(req.space.enabled).toBe(true)\n expect(req.space.root).toBeUndefined()\n expect(req.space.dbFile).toMatchObject({ inTrash: false, ownerId: userTest.id, path: 'root/foo/bar' })\n expect(req.space.permissions).toBe(SPACE_ALL_OPERATIONS)\n expect(req.space.envPermissions).toBe(SPACE_ALL_OPERATIONS)\n expect(req.space.inFilesRepository).toBe(true)\n expect(req.space.inPersonalSpace).toBe(true)\n expect(req.space.inTrashRepository).toBe(false)\n expect(req.space.inSharesRepository).toBe(false)\n expect(req.space.inSharesList).toBe(false)\n expect(req.space.paths).toEqual(expect.arrayContaining(['root', 'foo', 'bar']))\n })\n\n it('should pass for a common space', async () => {\n const fakeSpace = {\n id: -1,\n alias: 'test',\n name: 'Test',\n enabled: true,\n permissions: ':a:d:m:so',\n role: 0\n }\n spacesQueries.permissions = jest.fn().mockReturnValueOnce(fakeSpace)\n context.switchToHttp().getRequest.mockReturnValue({\n user: userTest,\n params: { '*': 'files/test' }\n })\n expect(await spacesGuard.canActivate(context)).toBe(true)\n const req: any = context.switchToHttp().getRequest()\n expect(req.space.id).toBe(fakeSpace.id)\n expect(req.space.repository).toBe(SPACE_REPOSITORY.FILES)\n expect(req.space.alias).toBe(fakeSpace.alias)\n expect(req.space.name).toBe(fakeSpace.name)\n expect(req.space.enabled).toBe(true)\n expect(req.space.root).toMatchObject({ id: 0, alias: '', name: '', permissions: 'a:d:m:so' })\n expect(req.space.dbFile).toMatchObject({ inTrash: false, spaceId: fakeSpace.id, spaceExternalRootId: null, path: '.' })\n expect(req.space.permissions).toBe(SHARE_ALL_OPERATIONS)\n expect(req.space.envPermissions).not.toContain('d')\n expect(req.space.inFilesRepository).toBe(true)\n expect(req.space.inPersonalSpace).toBe(false)\n expect(req.space.inTrashRepository).toBe(false)\n expect(req.space.inSharesRepository).toBe(false)\n expect(req.space.inSharesList).toBe(false)\n expect(req.space.paths).toHaveLength(0)\n })\n\n it('should pass for a common space root', async () => {\n const fakeSpace = {\n id: -1,\n alias: 'test',\n name: 'Test',\n enabled: true,\n permissions: 'a:d:m:so',\n role: 1,\n root: {\n id: -2,\n alias: 'root',\n name: 'Root',\n permissions: 'a:d:so',\n owner: { id: -3, login: 'johaven' },\n file: { id: -4, path: 'code', inTrash: false },\n externalPath: null\n }\n }\n spacesQueries.permissions = jest.fn().mockReturnValueOnce(fakeSpace)\n context.switchToHttp().getRequest.mockReturnValue({\n user: userTest,\n params: { '*': 'files/test/root' }\n })\n expect(await spacesGuard.canActivate(context)).toBe(true)\n const req: any = context.switchToHttp().getRequest()\n expect(req.space.id).toBe(fakeSpace.id)\n expect(req.space.repository).toBe(SPACE_REPOSITORY.FILES)\n expect(req.space.alias).toBe(fakeSpace.alias)\n expect(req.space.name).toBe(fakeSpace.name)\n expect(req.space.enabled).toBe(true)\n expect(req.space.root).toMatchObject(fakeSpace.root)\n expect(req.space.dbFile).toMatchObject({ inTrash: false, ownerId: fakeSpace.root.owner.id, path: fakeSpace.root.file.path })\n expect(req.space.permissions).toBe(SPACE_ALL_OPERATIONS)\n expect(req.space.envPermissions).toBe(\n intersectPermissions(fakeSpace.permissions, fakeSpace.root.permissions)\n .split(SPACE_PERMS_SEP)\n .filter((p) => p !== SPACE_OPERATION.DELETE)\n .join(SPACE_PERMS_SEP)\n )\n expect(req.space.inFilesRepository).toBe(true)\n expect(req.space.inPersonalSpace).toBe(false)\n expect(req.space.inTrashRepository).toBe(false)\n expect(req.space.inSharesRepository).toBe(false)\n expect(req.space.inSharesList).toBe(false)\n expect(req.space.paths).toHaveLength(0)\n })\n\n it('should pass for a common space root with a path', async () => {\n const fakeSpace = {\n id: -1,\n alias: 'test',\n name: 'Test',\n enabled: true,\n permissions: 'a:d:m:so',\n role: 1,\n root: {\n id: -2,\n alias: 'root',\n name: 'Root',\n permissions: 'a:d:so',\n owner: { id: -3, login: 'johaven' },\n file: { id: -4, path: 'code', inTrash: false },\n externalPath: null\n }\n }\n spacesQueries.permissions = jest.fn().mockReturnValueOnce(fakeSpace)\n context.switchToHttp().getRequest.mockReturnValue({\n user: userTest,\n params: { '*': 'files/test/root/path' }\n })\n expect(await spacesGuard.canActivate(context)).toBe(true)\n const req: any = context.switchToHttp().getRequest()\n expect(req.space.id).toBe(fakeSpace.id)\n expect(req.space.repository).toBe(SPACE_REPOSITORY.FILES)\n expect(req.space.alias).toBe(fakeSpace.alias)\n expect(req.space.name).toBe(fakeSpace.name)\n expect(req.space.enabled).toBe(true)\n expect(req.space.root).toMatchObject(fakeSpace.root)\n expect(req.space.dbFile).toMatchObject({\n inTrash: false,\n ownerId: fakeSpace.root.owner.id,\n path: `${fakeSpace.root.file.path}/${req.space.paths[0]}`\n })\n expect(req.space.permissions).toBe(SPACE_ALL_OPERATIONS)\n expect(req.space.envPermissions).toBe(fakeSpace.root.permissions)\n expect(req.space.inFilesRepository).toBe(true)\n expect(req.space.inPersonalSpace).toBe(false)\n expect(req.space.inTrashRepository).toBe(false)\n expect(req.space.inSharesRepository).toBe(false)\n expect(req.space.inSharesList).toBe(false)\n expect(req.space.paths).toHaveLength(1)\n })\n\n it('should pass for a space in shares repository', async () => {\n context.switchToHttp().getRequest.mockReturnValue({\n user: userTest,\n params: { '*': 'shares' }\n })\n expect(await spacesGuard.canActivate(context)).toBe(true)\n const req: any = context.switchToHttp().getRequest()\n expect(req.space.id).toBe(0)\n expect(req.space.repository).toBe(SPACE_REPOSITORY.SHARES)\n expect(req.space.alias).toBe(SPACE_REPOSITORY.SHARES)\n expect(req.space.name).toBe(SPACE_REPOSITORY.SHARES)\n expect(req.space.enabled).toBe(true)\n expect(req.space.root).toBeUndefined()\n expect(req.space.dbFile).toBeUndefined()\n expect(req.space.permissions).toBe('')\n expect(req.space.envPermissions).toBe('')\n expect(req.space.inFilesRepository).toBe(false)\n expect(req.space.inPersonalSpace).toBe(false)\n expect(req.space.inTrashRepository).toBe(false)\n expect(req.space.inSharesRepository).toBe(true)\n expect(req.space.inSharesList).toBe(true)\n expect(req.space.paths).toHaveLength(0)\n })\n\n it('should not pass if the space is not found or not valid', async () => {\n const fakeSpace = null\n spacesQueries.permissions = jest.fn().mockReturnValueOnce(fakeSpace)\n context.switchToHttp().getRequest.mockReturnValue({\n user: userTest,\n params: { '*': 'files/foo' }\n })\n await expect(spacesGuard.canActivate(context)).rejects.toThrow(HttpException)\n })\n\n it('should validate (or not) the access to the space depending on the user permissions', async () => {\n // we only check the `spacesManager.checkAccessToSpace` function, ignores the `spacesManager.spaceEnv`\n userTest.applications = [USER_PERMISSION.PERSONAL_SPACE]\n for (const url of ['', 'shares/personal', 'shares/toto']) {\n context.switchToHttp().getRequest.mockReturnValue({\n user: userTest,\n params: { '*': url }\n })\n await expect(spacesGuard.canActivate(context)).rejects.toThrow(HttpException)\n }\n // should pass because it is a standard user\n // should not pass because user is a guest (and dot not have the permission to access to a personal space)\n spacesManager.spaceEnv = jest.fn().mockReturnValueOnce({ enabled: true }) // only for user role\n context.switchToHttp().getRequest.mockReturnValue({\n user: userTest,\n params: { '*': 'files/personal/root/foo/bar' }\n })\n for (const userRole of [USER_ROLE.USER, USER_ROLE.GUEST]) {\n userTest.role = userRole\n if (userRole === USER_ROLE.USER) {\n expect(await spacesGuard.canActivate(context)).toBe(true)\n } else {\n await expect(spacesGuard.canActivate(context)).rejects.toThrow(HttpException)\n }\n }\n })\n\n it('should check user permissions on route', async () => {\n userTest.role = USER_ROLE.USER\n spacesManager.spaceEnv = jest.fn().mockReturnValue({\n enabled: true,\n envPermissions: `${SPACE_OPERATION.MODIFY}`\n } as Partial<SpaceEnv>)\n // does not allow creation (only modify)\n context.switchToHttp().getRequest.mockReturnValueOnce({\n method: 'POST',\n user: userTest,\n params: { '*': 'files/personal' }\n })\n await expect(spacesGuard.canActivate(context)).rejects.toThrow(HttpException)\n\n // allows modification\n context.switchToHttp().getRequest.mockReturnValue({\n method: 'PATCH',\n user: userTest,\n params: { '*': 'files/personal' }\n })\n expect(await spacesGuard.canActivate(context)).toBe(true)\n\n // does not allow guest (on personal space)\n userTest.role = USER_ROLE.GUEST\n await expect(spacesGuard.canActivate(context)).rejects.toThrow(HttpException)\n\n // allow if SkipSpacePermissionsCheck is enabled\n userTest.role = USER_ROLE.USER\n SkipSpacePermissionsCheck()(context.getHandler())\n spacesManager.spaceEnv = jest.fn().mockReturnValue({\n enabled: true,\n envPermissions: `${SPACE_OPERATION.MODIFY}`\n } as Partial<SpaceEnv>)\n // does not allow creation but pass\n context.switchToHttp().getRequest.mockReturnValueOnce({\n method: 'POST',\n user: userTest,\n params: { '*': 'files/personal' }\n })\n expect(await spacesGuard.canActivate(context)).toBe(true)\n })\n\n it('should fail with quota exceeded', async () => {\n userTest.role = USER_ROLE.USER\n spacesManager.spaceEnv = jest.fn().mockReturnValueOnce({\n enabled: true,\n envPermissions: `${SPACE_OPERATION.ADD}`,\n quotaIsExceeded: true\n } as Partial<SpaceEnv>)\n context.switchToHttp().getRequest.mockReturnValueOnce({\n method: 'POST',\n user: userTest,\n params: { '*': 'files/personal' }\n })\n await expect(spacesGuard.canActivate(context)).rejects.toEqual(expect.objectContaining({ status: HttpStatus.INSUFFICIENT_STORAGE }))\n })\n\n it('should fail if request content-length header exceed the quota', async () => {\n userTest.role = USER_ROLE.USER\n const storageQuota = 12\n const storageUsage = 11\n spacesManager.spaceEnv = jest.fn().mockReturnValue({\n enabled: true,\n envPermissions: `${SPACE_OPERATION.ADD}`,\n storageQuota: storageQuota,\n storageUsage: storageUsage,\n willExceedQuota: (contentLength: number) => contentLength > storageQuota - storageUsage\n } as Partial<SpaceEnv>)\n context.switchToHttp().getRequest.mockReturnValueOnce({\n method: 'POST',\n headers: { 'content-length': 13 },\n user: userTest,\n params: { '*': 'files/personal' }\n })\n await expect(spacesGuard.canActivate(context)).rejects.toEqual(expect.objectContaining({ status: HttpStatus.INSUFFICIENT_STORAGE }))\n context.switchToHttp().getRequest.mockReturnValueOnce({\n method: 'POST',\n user: userTest,\n headers: {},\n params: { '*': 'files/personal' }\n })\n expect(await spacesGuard.canActivate(context)).toBe(true)\n })\n\n it('should fail with space disabled', async () => {\n userTest.role = USER_ROLE.USER\n spacesManager.spaceEnv = jest.fn().mockReturnValueOnce({\n enabled: false\n } as Partial<SpaceEnv>)\n context.switchToHttp().getRequest.mockReturnValueOnce({\n method: 'POST',\n user: userTest,\n params: { '*': 'files/personal' }\n })\n await expect(spacesGuard.canActivate(context)).rejects.toMatchObject({ status: HttpStatus.FORBIDDEN })\n })\n\n it('should validate (or not) the webdav routes', async () => {\n userTest.role = USER_ROLE.USER\n spacesManager.spaceEnv = jest.fn().mockReturnValue({ enabled: true })\n const spyUrlSegment = jest.spyOn(spacesGuard as any, 'urlSegmentsFromContext')\n WebDAVContext()(context.getHandler())\n context.switchToHttp().getRequest.mockReturnValueOnce({\n user: userTest,\n params: { '*': 'webdav/personal' }\n })\n expect(await spacesGuard.canActivate(context)).toBe(true)\n expect(spyUrlSegment.mock.results[0].value).toEqual(['files', 'personal'])\n context.switchToHttp().getRequest.mockReturnValueOnce({\n user: userTest,\n params: { '*': 'webdav/files' }\n })\n await expect(spacesGuard.canActivate(context)).rejects.toThrow(HttpException)\n // reset mock\n spyUrlSegment.mockRestore()\n })\n\n it('should validate (or not) the sync routes', async () => {\n userTest.role = USER_ROLE.USER\n spacesManager.spaceEnv = jest.fn().mockReturnValue({ enabled: true })\n const spyUrlSegment = jest.spyOn(spacesGuard as any, 'urlSegmentsFromContext')\n SyncContext()(context.getHandler())\n context.switchToHttp().getRequest.mockReturnValueOnce({\n user: userTest,\n params: { '*': 'personal/foo' }\n })\n expect(await spacesGuard.canActivate(context)).toBe(true)\n expect(spyUrlSegment.mock.results[0].value).toEqual(['files', 'personal', 'foo'])\n context.switchToHttp().getRequest.mockReturnValueOnce({\n user: userTest,\n params: { '*': 'sync/files' }\n })\n await expect(spacesGuard.canActivate(context)).rejects.toThrow(HttpException)\n // reset context\n spyUrlSegment.mockRestore()\n })\n\n it('should allow the modify permission when using the POST method with override space permission decorator', async () => {\n userTest.role = USER_ROLE.USER\n spacesManager.spaceEnv = jest.fn().mockReturnValue({ enabled: true, envPermissions: `${SPACE_OPERATION.MODIFY}` })\n OverrideSpacePermission(SPACE_OPERATION.MODIFY)(context.getHandler())\n context.switchToHttp().getRequest.mockReturnValue({\n method: 'POST',\n user: userTest,\n originalUrl: '1',\n params: { '*': 'files/personal/root' }\n })\n expect(await spacesGuard.canActivate(context)).toBe(true)\n // reset context\n context = createMock<ExecutionContext>()\n spacesManager.spaceEnv = jest.fn().mockReturnValue({ enabled: true, envPermissions: `${SPACE_OPERATION.ADD}` })\n await expect(spacesGuard.canActivate(context)).rejects.toThrow(HttpException)\n context.switchToHttp().getRequest.mockReturnValue({\n method: 'POST',\n user: userTest,\n originalUrl: '2',\n params: { '*': 'files/personal/root' }\n })\n expect(await spacesGuard.canActivate(context)).toBe(true)\n })\n\n it('should pass if skipSpaceGuard context is enabled', async () => {\n userTest.role = USER_ROLE.USER\n userTest.applications = [USER_PERMISSION.PERSONAL_SPACE]\n spacesManager.spaceEnv = jest.fn().mockReturnValue({ enabled: true })\n context.switchToHttp().getRequest.mockReturnValue({\n user: userTest,\n params: { '*': 'shares/personal' }\n })\n await expect(spacesGuard.canActivate(context)).rejects.toMatchObject({ status: HttpStatus.FORBIDDEN })\n SkipSpaceGuard()(context.getHandler())\n expect(await spacesGuard.canActivate(context)).toBe(true)\n })\n\n it('coverage only', async () => {\n userTest.role = USER_ROLE.USER\n userTest.applications = [USER_PERMISSION.PERSONAL_SPACE]\n spacesManager.spaceEnv = jest.fn().mockRejectedValueOnce(new Error('error'))\n context.switchToHttp().getRequest.mockReturnValue({\n user: userTest,\n params: { '*': 'files/personal' }\n })\n await expect(spacesGuard.canActivate(context)).rejects.toMatchObject({ status: HttpStatus.BAD_REQUEST })\n })\n})\n"],"names":["describe","SpaceGuard","name","spacesGuard","spacesManager","spacesQueries","userTest","context","beforeAll","module","Test","createTestingModule","providers","provide","DB_TOKEN_PROVIDER","useValue","Cache","ContextManager","NotificationsManager","SpacesManager","SpacesQueries","SharesManager","SharesQueries","FilesQueries","UsersQueries","LinksQueries","compile","get","jest","fn","UserModel","generateUserTest","beforeEach","createMock","it","expect","toBeDefined","switchToHttp","getRequest","mockReturnValue","user","params","canActivate","toBe","req","space","id","repository","SPACE_REPOSITORY","FILES","alias","SPACE_ALIAS","PERSONAL","enabled","root","toBeUndefined","dbFile","toMatchObject","inTrash","ownerId","path","permissions","SPACE_ALL_OPERATIONS","envPermissions","inFilesRepository","inPersonalSpace","inTrashRepository","inSharesRepository","inSharesList","paths","toEqual","arrayContaining","fakeSpace","role","mockReturnValueOnce","spaceId","spaceExternalRootId","SHARE_ALL_OPERATIONS","not","toContain","toHaveLength","owner","login","file","externalPath","intersectPermissions","split","SPACE_PERMS_SEP","filter","p","SPACE_OPERATION","DELETE","join","SHARES","rejects","toThrow","HttpException","applications","USER_PERMISSION","PERSONAL_SPACE","url","spaceEnv","userRole","USER_ROLE","USER","GUEST","MODIFY","method","SkipSpacePermissionsCheck","getHandler","ADD","quotaIsExceeded","objectContaining","status","HttpStatus","INSUFFICIENT_STORAGE","storageQuota","storageUsage","willExceedQuota","contentLength","headers","FORBIDDEN","spyUrlSegment","spyOn","WebDAVContext","mock","results","value","mockRestore","SyncContext","OverrideSpacePermission","originalUrl","SkipSpaceGuard","mockRejectedValueOnce","Error","BAD_REQUEST"],"mappings":"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"}
|
|
@@ -70,6 +70,9 @@ _export(exports, {
|
|
|
70
70
|
get STANDARD_PROPS () {
|
|
71
71
|
return STANDARD_PROPS;
|
|
72
72
|
},
|
|
73
|
+
get WEBDAV_APP_LOCK () {
|
|
74
|
+
return WEBDAV_APP_LOCK;
|
|
75
|
+
},
|
|
73
76
|
get XML_CONTENT_TYPE () {
|
|
74
77
|
return XML_CONTENT_TYPE;
|
|
75
78
|
}
|
|
@@ -83,6 +86,7 @@ const NS_PREFIX = 'D';
|
|
|
83
86
|
const LOCK_PREFIX = 'urn:uuid:';
|
|
84
87
|
const XML_CONTENT_TYPE = 'application/xml; charset=utf-8';
|
|
85
88
|
const HTML_CONTENT_TYPE = 'text/html; charset=utf-8';
|
|
89
|
+
const WEBDAV_APP_LOCK = 'WebDAV';
|
|
86
90
|
const ALLOWED_WEBDAV_METHODS = [
|
|
87
91
|
_applicationsconstants.HTTP_STANDARD_METHOD.OPTIONS,
|
|
88
92
|
_applicationsconstants.HTTP_STANDARD_METHOD.HEAD,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../backend/src/applications/webdav/constants/webdav.ts"],"sourcesContent":["/*\n * Copyright (C) 2012-2025 Johan Legrand <johan.legrand@sync-in.com>\n * This file is part of Sync-in | The open source file sync and share solution\n * See the LICENSE file for licensing details\n */\n\nimport { SERVER_NAME } from '../../../common/shared'\nimport { HTTP_STANDARD_METHOD, HTTP_WEBDAV_METHOD } from '../../applications.constants'\nimport { WEBDAV_BASE_PATH } from './routes'\n\nexport const REGEX_BASE_PATH = new RegExp(`^/?${WEBDAV_BASE_PATH}/`)\nexport const NS_DAV = 'DAV:'\nexport const NS_PREFIX = 'D'\nexport const LOCK_PREFIX = 'urn:uuid:'\nexport const XML_CONTENT_TYPE = 'application/xml; charset=utf-8'\nexport const HTML_CONTENT_TYPE = 'text/html; charset=utf-8'\n\nexport const ALLOWED_WEBDAV_METHODS: string = [\n HTTP_STANDARD_METHOD.OPTIONS,\n HTTP_STANDARD_METHOD.HEAD,\n HTTP_STANDARD_METHOD.GET,\n HTTP_STANDARD_METHOD.PUT,\n HTTP_STANDARD_METHOD.DELETE,\n ...Object.values(HTTP_WEBDAV_METHOD)\n].join(', ')\n\nexport const ALLOW_EMPTY_BODY_METHODS: string[] = [HTTP_WEBDAV_METHOD.PROPFIND, HTTP_WEBDAV_METHOD.LOCK]\n\nexport const OPTIONS_HEADERS = {\n Server: SERVER_NAME,\n 'MS-Author-Via': 'DAV',\n DAV: '1,2',\n Allow: ALLOWED_WEBDAV_METHODS,\n 'Content-Type': HTML_CONTENT_TYPE,\n 'Content-Length': '0',\n 'Accept-Ranges': 'bytes'\n} as const\n\nexport const HEADER = {\n DEPTH: 'depth',\n IF: 'if',\n LOCK_TOKEN: 'lock-token',\n DESTINATION: 'destination',\n OVERWRITE: 'overwrite',\n TIMEOUT: 'timeout'\n} as const\n\nexport const LOCK_DISCOVERY_PROP = 'lockdiscovery'\nexport const STANDARD_PROPS = [\n 'creationdate',\n 'getcontenttype',\n 'resourcetype',\n 'getlastmodified',\n 'getcontentlength',\n 'displayname',\n 'getetag',\n 'supportedlock',\n LOCK_DISCOVERY_PROP\n]\n\nexport enum LOCK_SCOPE {\n EXCLUSIVE = 'exclusive',\n SHARED = 'shared'\n}\n\nexport enum DEPTH {\n INFINITY = 'infinity',\n RESOURCE = '0',\n MEMBERS = '1'\n}\n\nexport type LOCK_DEPTH = Omit<DEPTH, DEPTH.MEMBERS>\n\nexport enum PROPSTAT {\n ALLPROP = 'allprop',\n PROP = 'prop',\n PROPNAME = 'propname'\n}\n\nexport const PROPPATCH_PROP_UPDATE = 'propertyupdate'\nexport const PROPPATCH_METHOD = { SET: 'set', REMOVE: 'remove' }\nexport const PROPPATCH_MODIFIED_PROPS = ['getlastmodified', 'lastmodified', 'Win32LastModifiedTime']\nexport const PROPPATCH_SUPPORTED_PROPS = [...PROPPATCH_MODIFIED_PROPS, 'Win32CreationTime', 'Win32LastAccessTime', 'Win32FileAttributes']\n\nexport const PRECONDITION = {\n PROTECTED_PROPERTY: 'cannot-modify-protected-property',\n MISSING_LOCK_TOKEN: 'lock-token-submitted',\n LOCK_TOKEN_MISMATCH: 'lock-token-matches-request-uri',\n LOCK_CONFLICT: 'no-conflicting-lock',\n PROPFIND_FINITE_DEPTH: 'propfind-finite-depth'\n} as const\n"],"names":["ALLOWED_WEBDAV_METHODS","ALLOW_EMPTY_BODY_METHODS","DEPTH","HEADER","HTML_CONTENT_TYPE","LOCK_DISCOVERY_PROP","LOCK_PREFIX","LOCK_SCOPE","NS_DAV","NS_PREFIX","OPTIONS_HEADERS","PRECONDITION","PROPPATCH_METHOD","PROPPATCH_MODIFIED_PROPS","PROPPATCH_PROP_UPDATE","PROPPATCH_SUPPORTED_PROPS","PROPSTAT","REGEX_BASE_PATH","STANDARD_PROPS","XML_CONTENT_TYPE","RegExp","WEBDAV_BASE_PATH","HTTP_STANDARD_METHOD","OPTIONS","HEAD","GET","PUT","DELETE","Object","values","HTTP_WEBDAV_METHOD","join","PROPFIND","LOCK","Server","SERVER_NAME","DAV","Allow","IF","LOCK_TOKEN","DESTINATION","OVERWRITE","TIMEOUT","SET","REMOVE","PROTECTED_PROPERTY","MISSING_LOCK_TOKEN","LOCK_TOKEN_MISMATCH","LOCK_CONFLICT","PROPFIND_FINITE_DEPTH"],"mappings":"AAAA;;;;CAIC;;;;;;;;;;;
|
|
1
|
+
{"version":3,"sources":["../../../../../backend/src/applications/webdav/constants/webdav.ts"],"sourcesContent":["/*\n * Copyright (C) 2012-2025 Johan Legrand <johan.legrand@sync-in.com>\n * This file is part of Sync-in | The open source file sync and share solution\n * See the LICENSE file for licensing details\n */\n\nimport { SERVER_NAME } from '../../../common/shared'\nimport { HTTP_STANDARD_METHOD, HTTP_WEBDAV_METHOD } from '../../applications.constants'\nimport { WEBDAV_BASE_PATH } from './routes'\n\nexport const REGEX_BASE_PATH = new RegExp(`^/?${WEBDAV_BASE_PATH}/`)\nexport const NS_DAV = 'DAV:'\nexport const NS_PREFIX = 'D'\nexport const LOCK_PREFIX = 'urn:uuid:'\nexport const XML_CONTENT_TYPE = 'application/xml; charset=utf-8'\nexport const HTML_CONTENT_TYPE = 'text/html; charset=utf-8'\nexport const WEBDAV_APP_LOCK = 'WebDAV' as const\n\nexport const ALLOWED_WEBDAV_METHODS: string = [\n HTTP_STANDARD_METHOD.OPTIONS,\n HTTP_STANDARD_METHOD.HEAD,\n HTTP_STANDARD_METHOD.GET,\n HTTP_STANDARD_METHOD.PUT,\n HTTP_STANDARD_METHOD.DELETE,\n ...Object.values(HTTP_WEBDAV_METHOD)\n].join(', ')\n\nexport const ALLOW_EMPTY_BODY_METHODS: string[] = [HTTP_WEBDAV_METHOD.PROPFIND, HTTP_WEBDAV_METHOD.LOCK]\n\nexport const OPTIONS_HEADERS = {\n Server: SERVER_NAME,\n 'MS-Author-Via': 'DAV',\n DAV: '1,2',\n Allow: ALLOWED_WEBDAV_METHODS,\n 'Content-Type': HTML_CONTENT_TYPE,\n 'Content-Length': '0',\n 'Accept-Ranges': 'bytes'\n} as const\n\nexport const HEADER = {\n DEPTH: 'depth',\n IF: 'if',\n LOCK_TOKEN: 'lock-token',\n DESTINATION: 'destination',\n OVERWRITE: 'overwrite',\n TIMEOUT: 'timeout'\n} as const\n\nexport const LOCK_DISCOVERY_PROP = 'lockdiscovery'\nexport const STANDARD_PROPS = [\n 'creationdate',\n 'getcontenttype',\n 'resourcetype',\n 'getlastmodified',\n 'getcontentlength',\n 'displayname',\n 'getetag',\n 'supportedlock',\n LOCK_DISCOVERY_PROP\n]\n\nexport enum LOCK_SCOPE {\n EXCLUSIVE = 'exclusive',\n SHARED = 'shared'\n}\n\nexport enum DEPTH {\n INFINITY = 'infinity',\n RESOURCE = '0',\n MEMBERS = '1'\n}\n\nexport type LOCK_DEPTH = Omit<DEPTH, DEPTH.MEMBERS>\n\nexport enum PROPSTAT {\n ALLPROP = 'allprop',\n PROP = 'prop',\n PROPNAME = 'propname'\n}\n\nexport const PROPPATCH_PROP_UPDATE = 'propertyupdate'\nexport const PROPPATCH_METHOD = { SET: 'set', REMOVE: 'remove' }\nexport const PROPPATCH_MODIFIED_PROPS = ['getlastmodified', 'lastmodified', 'Win32LastModifiedTime']\nexport const PROPPATCH_SUPPORTED_PROPS = [...PROPPATCH_MODIFIED_PROPS, 'Win32CreationTime', 'Win32LastAccessTime', 'Win32FileAttributes']\n\nexport const PRECONDITION = {\n PROTECTED_PROPERTY: 'cannot-modify-protected-property',\n MISSING_LOCK_TOKEN: 'lock-token-submitted',\n LOCK_TOKEN_MISMATCH: 'lock-token-matches-request-uri',\n LOCK_CONFLICT: 'no-conflicting-lock',\n PROPFIND_FINITE_DEPTH: 'propfind-finite-depth'\n} as const\n"],"names":["ALLOWED_WEBDAV_METHODS","ALLOW_EMPTY_BODY_METHODS","DEPTH","HEADER","HTML_CONTENT_TYPE","LOCK_DISCOVERY_PROP","LOCK_PREFIX","LOCK_SCOPE","NS_DAV","NS_PREFIX","OPTIONS_HEADERS","PRECONDITION","PROPPATCH_METHOD","PROPPATCH_MODIFIED_PROPS","PROPPATCH_PROP_UPDATE","PROPPATCH_SUPPORTED_PROPS","PROPSTAT","REGEX_BASE_PATH","STANDARD_PROPS","WEBDAV_APP_LOCK","XML_CONTENT_TYPE","RegExp","WEBDAV_BASE_PATH","HTTP_STANDARD_METHOD","OPTIONS","HEAD","GET","PUT","DELETE","Object","values","HTTP_WEBDAV_METHOD","join","PROPFIND","LOCK","Server","SERVER_NAME","DAV","Allow","IF","LOCK_TOKEN","DESTINATION","OVERWRITE","TIMEOUT","SET","REMOVE","PROTECTED_PROPERTY","MISSING_LOCK_TOKEN","LOCK_TOKEN_MISMATCH","LOCK_CONFLICT","PROPFIND_FINITE_DEPTH"],"mappings":"AAAA;;;;CAIC;;;;;;;;;;;QAcYA;eAAAA;;QASAC;eAAAA;;QAuCDC;eAAAA;;QA3BCC;eAAAA;;QAxBAC;eAAAA;;QAiCAC;eAAAA;;QAnCAC;eAAAA;;QAgDDC;eAAAA;;QAlDCC;eAAAA;;QACAC;eAAAA;;QAiBAC;eAAAA;;QAwDAC;eAAAA;;QAJAC;eAAAA;;QACAC;eAAAA;;QAFAC;eAAAA;;QAGAC;eAAAA;;QATDC;eAAAA;;QAhECC;eAAAA;;QAuCAC;eAAAA;;QAjCAC;eAAAA;;QAFAC;eAAAA;;;wBARe;uCAC6B;wBACxB;AAE1B,MAAMH,kBAAkB,IAAII,OAAO,CAAC,GAAG,EAAEC,wBAAgB,CAAC,CAAC,CAAC;AAC5D,MAAMd,SAAS;AACf,MAAMC,YAAY;AAClB,MAAMH,cAAc;AACpB,MAAMc,mBAAmB;AACzB,MAAMhB,oBAAoB;AAC1B,MAAMe,kBAAkB;AAExB,MAAMnB,yBAAiC;IAC5CuB,2CAAoB,CAACC,OAAO;IAC5BD,2CAAoB,CAACE,IAAI;IACzBF,2CAAoB,CAACG,GAAG;IACxBH,2CAAoB,CAACI,GAAG;IACxBJ,2CAAoB,CAACK,MAAM;OACxBC,OAAOC,MAAM,CAACC,yCAAkB;CACpC,CAACC,IAAI,CAAC;AAEA,MAAM/B,2BAAqC;IAAC8B,yCAAkB,CAACE,QAAQ;IAAEF,yCAAkB,CAACG,IAAI;CAAC;AAEjG,MAAMxB,kBAAkB;IAC7ByB,QAAQC,mBAAW;IACnB,iBAAiB;IACjBC,KAAK;IACLC,OAAOtC;IACP,gBAAgBI;IAChB,kBAAkB;IAClB,iBAAiB;AACnB;AAEO,MAAMD,SAAS;IACpBD,OAAO;IACPqC,IAAI;IACJC,YAAY;IACZC,aAAa;IACbC,WAAW;IACXC,SAAS;AACX;AAEO,MAAMtC,sBAAsB;AAC5B,MAAMa,iBAAiB;IAC5B;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACAb;CACD;AAEM,IAAA,AAAKE,oCAAAA;;;WAAAA;;AAKL,IAAA,AAAKL,+BAAAA;;;;WAAAA;;AAQL,IAAA,AAAKc,kCAAAA;;;;WAAAA;;AAML,MAAMF,wBAAwB;AAC9B,MAAMF,mBAAmB;IAAEgC,KAAK;IAAOC,QAAQ;AAAS;AACxD,MAAMhC,2BAA2B;IAAC;IAAmB;IAAgB;CAAwB;AAC7F,MAAME,4BAA4B;OAAIF;IAA0B;IAAqB;IAAuB;CAAsB;AAElI,MAAMF,eAAe;IAC1BmC,oBAAoB;IACpBC,oBAAoB;IACpBC,qBAAqB;IACrBC,eAAe;IACfC,uBAAuB;AACzB"}
|
|
@@ -171,24 +171,25 @@ let WebDAVProtocolGuard = class WebDAVProtocolGuard {
|
|
|
171
171
|
}
|
|
172
172
|
this.parseBody(req);
|
|
173
173
|
if (req.dav.body) {
|
|
174
|
-
if (!req.dav.body
|
|
174
|
+
if (!req.dav.body.lockinfo) {
|
|
175
175
|
this.logger.warn(`Missing lockinfo : ${JSON.stringify(req.dav.body)}`);
|
|
176
176
|
throw new _common.HttpException('Missing lockinfo', _common.HttpStatus.BAD_REQUEST);
|
|
177
177
|
}
|
|
178
178
|
try {
|
|
179
|
-
req.dav.lock.lockscope = Object.keys(req.dav.body
|
|
179
|
+
req.dav.lock.lockscope = Object.keys(req.dav.body.lockinfo.lockscope)[0];
|
|
180
180
|
} catch (e) {
|
|
181
|
-
this.logger.warn(`${this.parseBody.name} - invalid or undefined lockscope : ${JSON.stringify(req.dav.body
|
|
181
|
+
this.logger.warn(`${this.parseBody.name} - invalid or undefined lockscope : ${JSON.stringify(req.dav.body.lockinfo)} : ${e}`);
|
|
182
182
|
throw new _common.HttpException('Invalid or undefined lockscope', _common.HttpStatus.BAD_REQUEST);
|
|
183
183
|
}
|
|
184
184
|
if (Object.values(_webdav.LOCK_SCOPE).indexOf(req.dav.lock.lockscope) === -1) {
|
|
185
|
-
this.logger.warn(`${this.parseBody.name} - invalid or undefined lockscope : ${JSON.stringify(req.dav.body
|
|
185
|
+
this.logger.warn(`${this.parseBody.name} - invalid or undefined lockscope : ${JSON.stringify(req.dav.body.lockinfo)}`);
|
|
186
186
|
throw new _common.HttpException('Invalid or undefined lockscope', _common.HttpStatus.BAD_REQUEST);
|
|
187
187
|
}
|
|
188
|
-
if (req.dav.body
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
188
|
+
if (req.dav.body.lockinfo.owner) {
|
|
189
|
+
const owner = typeof req.dav.body?.lockinfo?.owner === 'string' ? req.dav.body.lockinfo.owner : req.dav.body?.lockinfo?.owner?.href;
|
|
190
|
+
if (typeof owner === 'string') {
|
|
191
|
+
req.dav.lock.owner = owner.trim();
|
|
192
|
+
}
|
|
192
193
|
}
|
|
193
194
|
const depth = (req.headers[_webdav.HEADER.DEPTH] || '').toLowerCase();
|
|
194
195
|
req.dav.depth = [
|