@sync-in/server 1.5.2 → 1.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +28 -0
- package/README.md +2 -1
- package/environment/environment.dist.min.yaml +1 -0
- package/environment/environment.dist.yaml +88 -30
- package/migrations/0002_sleepy_korath.sql +1 -0
- package/migrations/meta/0002_snapshot.json +2424 -0
- package/migrations/meta/_journal.json +7 -0
- package/package.json +14 -12
- package/server/app.bootstrap.js +1 -1
- package/server/app.bootstrap.js.map +1 -1
- package/server/applications/files/services/files-manager.service.js +1 -2
- package/server/applications/files/services/files-manager.service.js.map +1 -1
- package/server/applications/files/services/files-only-office-manager.service.js +5 -6
- package/server/applications/files/services/files-only-office-manager.service.js.map +1 -1
- package/server/applications/files/utils/files.js +6 -4
- package/server/applications/files/utils/files.js.map +1 -1
- package/server/applications/links/links.controller.js +2 -2
- package/server/applications/links/links.controller.js.map +1 -1
- package/server/applications/links/services/links-manager.service.js +2 -1
- package/server/applications/links/services/links-manager.service.js.map +1 -1
- package/server/applications/links/services/links-manager.service.spec.js +6 -3
- package/server/applications/links/services/links-manager.service.spec.js.map +1 -1
- package/server/applications/notifications/constants/notifications.js +9 -0
- package/server/applications/notifications/constants/notifications.js.map +1 -1
- package/server/applications/notifications/i18n/fr.js +10 -1
- package/server/applications/notifications/i18n/fr.js.map +1 -1
- package/server/applications/notifications/interfaces/notification-properties.interface.js.map +1 -1
- package/server/applications/notifications/mails/models.js +41 -3
- package/server/applications/notifications/mails/models.js.map +1 -1
- package/server/applications/notifications/mails/templates.js +1 -1
- package/server/applications/notifications/mails/templates.js.map +1 -1
- package/server/applications/notifications/schemas/notifications.schema.js +2 -1
- package/server/applications/notifications/schemas/notifications.schema.js.map +1 -1
- package/server/applications/notifications/services/notifications-manager.service.js +16 -13
- package/server/applications/notifications/services/notifications-manager.service.js.map +1 -1
- package/server/applications/notifications/services/notifications-manager.service.spec.js +9 -8
- package/server/applications/notifications/services/notifications-manager.service.spec.js.map +1 -1
- package/server/applications/notifications/services/notifications-queries.service.js +1 -1
- package/server/applications/notifications/services/notifications-queries.service.js.map +1 -1
- package/server/applications/shares/services/shares-manager.service.js +3 -2
- package/server/applications/shares/services/shares-manager.service.js.map +1 -1
- package/server/applications/sync/constants/auth.js +2 -2
- package/server/applications/sync/constants/auth.js.map +1 -1
- package/server/applications/sync/dtos/sync-client-registration.dto.js +5 -0
- package/server/applications/sync/dtos/sync-client-registration.dto.js.map +1 -1
- package/server/applications/sync/dtos/sync-operations.dto.js +1 -2
- package/server/applications/sync/dtos/sync-operations.dto.js.map +1 -1
- package/server/applications/sync/schemas/sync-clients.schema.js +2 -1
- package/server/applications/sync/schemas/sync-clients.schema.js.map +1 -1
- package/server/applications/sync/schemas/sync-paths.schema.js +2 -1
- package/server/applications/sync/schemas/sync-paths.schema.js.map +1 -1
- package/server/applications/sync/services/sync-clients-manager.service.js +28 -20
- package/server/applications/sync/services/sync-clients-manager.service.js.map +1 -1
- package/server/applications/sync/services/sync-clients-manager.service.spec.js +24 -18
- package/server/applications/sync/services/sync-clients-manager.service.spec.js.map +1 -1
- package/server/applications/sync/services/sync-queries.service.js +5 -5
- package/server/applications/sync/services/sync-queries.service.js.map +1 -1
- package/server/applications/users/admin-users.controller.js +48 -37
- package/server/applications/users/admin-users.controller.js.map +1 -1
- package/server/applications/users/admin-users.controller.spec.js +15 -0
- package/server/applications/users/admin-users.controller.spec.js.map +1 -1
- package/server/applications/users/constants/routes.js +5 -0
- package/server/applications/users/constants/routes.js.map +1 -1
- package/server/applications/users/constants/user.js +8 -0
- package/server/applications/users/constants/user.js.map +1 -1
- package/server/applications/users/dto/delete-user.dto.js +5 -23
- package/server/applications/users/dto/delete-user.dto.js.map +1 -1
- package/server/applications/users/dto/user-properties.dto.js +38 -3
- package/server/applications/users/dto/user-properties.dto.js.map +1 -1
- package/server/applications/users/interfaces/admin-user.interface.js.map +1 -1
- package/server/applications/users/interfaces/user-secrets.interface.js +10 -0
- package/server/applications/users/interfaces/user-secrets.interface.js.map +1 -0
- package/server/applications/users/models/user.model.js +84 -50
- package/server/applications/users/models/user.model.js.map +1 -1
- package/server/applications/users/schemas/user.interface.js.map +1 -1
- package/server/applications/users/schemas/users.schema.js +2 -0
- package/server/applications/users/schemas/users.schema.js.map +1 -1
- package/server/applications/users/services/admin-users-manager.service.js +7 -19
- package/server/applications/users/services/admin-users-manager.service.js.map +1 -1
- package/server/applications/users/services/admin-users-manager.service.spec.js +7 -26
- package/server/applications/users/services/admin-users-manager.service.spec.js.map +1 -1
- package/server/applications/users/services/admin-users-queries.service.js +1 -0
- package/server/applications/users/services/admin-users-queries.service.js.map +1 -1
- package/server/applications/users/services/users-manager.service.js +138 -28
- package/server/applications/users/services/users-manager.service.js.map +1 -1
- package/server/applications/users/services/users-manager.service.spec.js +11 -9
- package/server/applications/users/services/users-manager.service.spec.js.map +1 -1
- package/server/applications/users/services/users-queries.service.js +63 -57
- package/server/applications/users/services/users-queries.service.js.map +1 -1
- package/server/applications/users/users.controller.js +48 -1
- package/server/applications/users/users.controller.js.map +1 -1
- package/server/applications/users/users.controller.spec.js +8 -1
- package/server/applications/users/users.controller.spec.js.map +1 -1
- package/server/applications/users/users.e2e-spec.js +2 -1
- package/server/applications/users/users.e2e-spec.js.map +1 -1
- package/server/applications/users/utils/avatar.js +48 -0
- package/server/applications/users/utils/avatar.js.map +1 -0
- package/server/authentication/auth.config.js +89 -26
- package/server/authentication/auth.config.js.map +1 -1
- package/server/authentication/auth.controller.js +117 -9
- package/server/authentication/auth.controller.js.map +1 -1
- package/server/authentication/auth.controller.spec.js +16 -1
- package/server/authentication/auth.controller.spec.js.map +1 -1
- package/server/authentication/auth.e2e-spec.js +4 -3
- package/server/authentication/auth.e2e-spec.js.map +1 -1
- package/server/authentication/auth.module.js +4 -1
- package/server/authentication/auth.module.js.map +1 -1
- package/server/authentication/constants/auth-ldap.js +44 -0
- package/server/authentication/constants/auth-ldap.js.map +1 -0
- package/server/authentication/constants/auth.js +37 -4
- package/server/authentication/constants/auth.js.map +1 -1
- package/server/authentication/constants/routes.js +21 -0
- package/server/authentication/constants/routes.js.map +1 -1
- package/server/authentication/constants/scope.js +20 -0
- package/server/authentication/constants/scope.js.map +1 -0
- package/server/authentication/dto/login-response.dto.js +27 -4
- package/server/authentication/dto/login-response.dto.js.map +1 -1
- package/server/authentication/dto/token-response.dto.js +5 -0
- package/server/authentication/dto/token-response.dto.js.map +1 -1
- package/server/{applications/users/dto/user-password.dto.js → authentication/dto/two-fa-verify.dto.js} +27 -9
- package/server/authentication/dto/two-fa-verify.dto.js.map +1 -0
- package/server/authentication/guards/auth-basic.strategy.js +6 -5
- package/server/authentication/guards/auth-basic.strategy.js.map +1 -1
- package/server/authentication/guards/auth-token-access.strategy.js +3 -2
- package/server/authentication/guards/auth-token-access.strategy.js.map +1 -1
- package/server/authentication/guards/auth-token-refresh.strategy.js +3 -2
- package/server/authentication/guards/auth-token-refresh.strategy.js.map +1 -1
- package/server/authentication/guards/auth-two-fa-guard.js +81 -0
- package/server/authentication/guards/auth-two-fa-guard.js.map +1 -0
- package/server/authentication/interfaces/jwt-payload.interface.js +5 -0
- package/server/authentication/interfaces/jwt-payload.interface.js.map +1 -1
- package/server/authentication/interfaces/token.interface.js +2 -0
- package/server/authentication/interfaces/token.interface.js.map +1 -1
- package/server/authentication/interfaces/two-fa-setup.interface.js +10 -0
- package/server/authentication/interfaces/two-fa-setup.interface.js.map +1 -0
- package/server/authentication/models/auth-method.js.map +1 -1
- package/server/authentication/services/auth-manager.service.js +72 -49
- package/server/authentication/services/auth-manager.service.js.map +1 -1
- package/server/authentication/services/auth-methods/auth-method-database.service.js +3 -3
- package/server/authentication/services/auth-methods/auth-method-database.service.js.map +1 -1
- package/server/authentication/services/auth-methods/auth-method-database.service.spec.js +5 -0
- package/server/authentication/services/auth-methods/auth-method-database.service.spec.js.map +1 -1
- package/server/authentication/services/auth-methods/auth-method-ldap.service.js +151 -66
- package/server/authentication/services/auth-methods/auth-method-ldap.service.js.map +1 -1
- package/server/authentication/services/auth-methods/auth-method-ldap.service.spec.js +52 -50
- package/server/authentication/services/auth-methods/auth-method-ldap.service.spec.js.map +1 -1
- package/server/authentication/services/auth-methods/auth-method-two-fa.service.js +251 -0
- package/server/authentication/services/auth-methods/auth-method-two-fa.service.js.map +1 -0
- package/server/authentication/services/auth-methods/auth-method-two-fa.service.spec.js +41 -0
- package/server/authentication/services/auth-methods/auth-method-two-fa.service.spec.js.map +1 -0
- package/server/authentication/utils/crypt-secret.js +68 -0
- package/server/authentication/utils/crypt-secret.js.map +1 -0
- package/server/common/functions.js +18 -2
- package/server/common/functions.js.map +1 -1
- package/server/common/qrcode.js +34 -0
- package/server/common/qrcode.js.map +1 -0
- package/server/common/shared.js +18 -0
- package/server/common/shared.js.map +1 -1
- package/server/configuration/config.environment.js +23 -6
- package/server/configuration/config.environment.js.map +1 -1
- package/server/configuration/config.interfaces.js +10 -0
- package/server/configuration/config.interfaces.js.map +1 -0
- package/server/configuration/config.loader.js.map +1 -1
- package/server/configuration/config.validation.js +13 -13
- package/server/configuration/config.validation.js.map +1 -1
- package/server/infrastructure/cache/adapters/mysql-cache.adapter.js +6 -6
- package/server/infrastructure/cache/adapters/mysql-cache.adapter.js.map +1 -1
- package/server/infrastructure/cache/schemas/mysql-cache.schema.js +2 -1
- package/server/infrastructure/cache/schemas/mysql-cache.schema.js.map +1 -1
- package/server/infrastructure/cache/services/cache.service.js.map +1 -1
- package/server/infrastructure/database/columns.js +39 -0
- package/server/infrastructure/database/columns.js.map +1 -0
- package/server/infrastructure/database/database.config.js +0 -1
- package/server/infrastructure/database/database.config.js.map +1 -1
- package/server/infrastructure/mailer/interfaces/mail.interface.js.map +1 -1
- package/server/infrastructure/mailer/mailer.config.js +12 -0
- package/server/infrastructure/mailer/mailer.config.js.map +1 -1
- package/server/infrastructure/mailer/mailer.service.js +2 -1
- package/server/infrastructure/mailer/mailer.service.js.map +1 -1
- package/static/assets/mimes/text-x-c.svg +1 -0
- package/static/assets/pdfjs/build/pdf.mjs +2522 -914
- package/static/assets/pdfjs/build/pdf.mjs.map +1 -1
- package/static/assets/pdfjs/build/pdf.sandbox.mjs +2 -2
- package/static/assets/pdfjs/build/pdf.worker.mjs +1024 -566
- package/static/assets/pdfjs/build/pdf.worker.mjs.map +1 -1
- package/static/assets/pdfjs/version +1 -1
- package/static/assets/pdfjs/web/debugger.mjs +116 -37
- package/static/assets/pdfjs/web/images/comment-popup-editButton.svg +5 -0
- package/static/assets/pdfjs/web/locale/ach/viewer.ftl +0 -12
- package/static/assets/pdfjs/web/locale/af/viewer.ftl +0 -12
- package/static/assets/pdfjs/web/locale/an/viewer.ftl +0 -16
- package/static/assets/pdfjs/web/locale/ar/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/ast/viewer.ftl +0 -19
- package/static/assets/pdfjs/web/locale/az/viewer.ftl +0 -16
- package/static/assets/pdfjs/web/locale/be/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/bg/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/bn/viewer.ftl +0 -16
- package/static/assets/pdfjs/web/locale/bo/viewer.ftl +0 -12
- package/static/assets/pdfjs/web/locale/br/viewer.ftl +0 -22
- package/static/assets/pdfjs/web/locale/brx/viewer.ftl +0 -16
- package/static/assets/pdfjs/web/locale/bs/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/ca/viewer.ftl +12 -23
- package/static/assets/pdfjs/web/locale/cak/viewer.ftl +0 -23
- package/static/assets/pdfjs/web/locale/ckb/viewer.ftl +0 -16
- package/static/assets/pdfjs/web/locale/cs/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/cy/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/da/viewer.ftl +3 -35
- package/static/assets/pdfjs/web/locale/de/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/dsb/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/el/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/en-CA/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/en-GB/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/en-US/viewer.ftl +25 -13
- package/static/assets/pdfjs/web/locale/eo/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/es-AR/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/es-CL/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/es-ES/viewer.ftl +5 -32
- package/static/assets/pdfjs/web/locale/es-MX/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/et/viewer.ftl +0 -16
- package/static/assets/pdfjs/web/locale/eu/viewer.ftl +38 -32
- package/static/assets/pdfjs/web/locale/fa/viewer.ftl +0 -19
- package/static/assets/pdfjs/web/locale/ff/viewer.ftl +0 -12
- package/static/assets/pdfjs/web/locale/fi/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/fr/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/fur/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/fy-NL/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/ga-IE/viewer.ftl +0 -12
- package/static/assets/pdfjs/web/locale/gd/viewer.ftl +0 -23
- package/static/assets/pdfjs/web/locale/gl/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/gn/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/gu-IN/viewer.ftl +0 -12
- package/static/assets/pdfjs/web/locale/he/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/hi-IN/viewer.ftl +0 -16
- package/static/assets/pdfjs/web/locale/hr/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/hsb/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/hu/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/hy-AM/viewer.ftl +372 -16
- package/static/assets/pdfjs/web/locale/hye/viewer.ftl +0 -16
- package/static/assets/pdfjs/web/locale/ia/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/id/viewer.ftl +38 -32
- package/static/assets/pdfjs/web/locale/is/viewer.ftl +27 -32
- package/static/assets/pdfjs/web/locale/it/viewer.ftl +0 -33
- package/static/assets/pdfjs/web/locale/ja/viewer.ftl +31 -33
- package/static/assets/pdfjs/web/locale/ka/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/kab/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/kk/viewer.ftl +31 -32
- package/static/assets/pdfjs/web/locale/km/viewer.ftl +0 -12
- package/static/assets/pdfjs/web/locale/kn/viewer.ftl +0 -12
- package/static/assets/pdfjs/web/locale/ko/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/lij/viewer.ftl +0 -12
- package/static/assets/pdfjs/web/locale/lo/viewer.ftl +0 -23
- package/static/assets/pdfjs/web/locale/lt/viewer.ftl +0 -16
- package/static/assets/pdfjs/web/locale/ltg/viewer.ftl +0 -12
- package/static/assets/pdfjs/web/locale/lv/viewer.ftl +0 -12
- package/static/assets/pdfjs/web/locale/meh/viewer.ftl +0 -14
- package/static/assets/pdfjs/web/locale/mk/viewer.ftl +0 -19
- package/static/assets/pdfjs/web/locale/ml/viewer.ftl +0 -31
- package/static/assets/pdfjs/web/locale/mr/viewer.ftl +0 -16
- package/static/assets/pdfjs/web/locale/ms/viewer.ftl +0 -12
- package/static/assets/pdfjs/web/locale/my/viewer.ftl +0 -12
- package/static/assets/pdfjs/web/locale/nb-NO/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/ne-NP/viewer.ftl +0 -12
- package/static/assets/pdfjs/web/locale/nl/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/nn-NO/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/oc/viewer.ftl +0 -24
- package/static/assets/pdfjs/web/locale/pa-IN/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/pl/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/pt-BR/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/pt-PT/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/rm/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/ro/viewer.ftl +5 -37
- package/static/assets/pdfjs/web/locale/ru/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/sat/viewer.ftl +0 -23
- package/static/assets/pdfjs/web/locale/sc/viewer.ftl +8 -27
- package/static/assets/pdfjs/web/locale/sco/viewer.ftl +0 -16
- package/static/assets/pdfjs/web/locale/si/viewer.ftl +0 -22
- package/static/assets/pdfjs/web/locale/sk/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/skr/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/sl/viewer.ftl +30 -32
- package/static/assets/pdfjs/web/locale/son/viewer.ftl +0 -12
- package/static/assets/pdfjs/web/locale/sq/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/sr/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/sv-SE/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/szl/viewer.ftl +0 -16
- package/static/assets/pdfjs/web/locale/ta/viewer.ftl +0 -12
- package/static/assets/pdfjs/web/locale/te/viewer.ftl +0 -16
- package/static/assets/pdfjs/web/locale/tg/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/th/viewer.ftl +38 -32
- package/static/assets/pdfjs/web/locale/tl/viewer.ftl +0 -16
- package/static/assets/pdfjs/web/locale/tr/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/trs/viewer.ftl +0 -12
- package/static/assets/pdfjs/web/locale/uk/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/ur/viewer.ftl +0 -16
- package/static/assets/pdfjs/web/locale/uz/viewer.ftl +0 -12
- package/static/assets/pdfjs/web/locale/vi/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/xh/viewer.ftl +0 -12
- package/static/assets/pdfjs/web/locale/zh-CN/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/zh-TW/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/viewer.css +586 -437
- package/static/assets/pdfjs/web/viewer.html +12 -23
- package/static/assets/pdfjs/web/viewer.mjs +955 -514
- package/static/assets/pdfjs/web/viewer.mjs.map +1 -1
- package/static/assets/pdfjs/web/wasm/openjpeg.wasm +0 -0
- package/static/assets/pdfjs/web/wasm/openjpeg_nowasm_fallback.js +10 -22
- package/static/{chunk-SPTF6FSM.js → chunk-27YQB3TE.js} +1 -1
- package/static/chunk-2I4CUFUA.js +1 -0
- package/static/chunk-2MTM6SWN.js +4 -0
- package/static/{chunk-7VRUZRJG.js → chunk-34MKICK5.js} +2 -2
- package/static/chunk-5O3DIUU3.js +1 -0
- package/static/{chunk-VJRTMDEJ.js → chunk-6NMVZIIT.js} +1 -1
- package/static/{chunk-L6MU6S2V.js → chunk-7DN7ZAPU.js} +1 -1
- package/static/{chunk-MVO4WZLK.js → chunk-7FUM3JGM.js} +1 -1
- package/static/{chunk-RSS6GYNE.js → chunk-7ITZXYYJ.js} +1 -1
- package/static/chunk-7P27WBGC.js +4 -0
- package/static/chunk-ATP3BFHV.js +562 -0
- package/static/chunk-AWQ2YTVC.js +1 -0
- package/static/chunk-DSOE3FEP.js +1 -0
- package/static/{chunk-2R6HHGUR.js → chunk-EFKMBLRE.js} +1 -1
- package/static/chunk-FUFKVHPU.js +1 -0
- package/static/{chunk-MRSWNAVB.js → chunk-HCDLWTMW.js} +1 -1
- package/static/chunk-IPAC4VAF.js +1 -0
- package/static/{chunk-ZC5NIT55.js → chunk-IQOALFYU.js} +1 -1
- package/static/chunk-JASU3CIH.js +1 -0
- package/static/{chunk-6OJZWYRZ.js → chunk-JQ5FTO2M.js} +1 -1
- package/static/chunk-JUNZFADM.js +1 -0
- package/static/{chunk-LLWSLOSX.js → chunk-LJUKI4SQ.js} +1 -1
- package/static/{chunk-WI7FOANP.js → chunk-LUWQFIWR.js} +1 -1
- package/static/{chunk-BIUNUYZ5.js → chunk-ORMRCEGT.js} +1 -1
- package/static/{chunk-IZL7JPTS.js → chunk-Q7D6RN4N.js} +1 -1
- package/static/{chunk-JYXLQRHG.js → chunk-QJX6ITLW.js} +1 -1
- package/static/{chunk-YJMN3B4N.js → chunk-QQ6UQQBR.js} +1 -1
- package/static/chunk-S2HDY3OL.js +1 -0
- package/static/{chunk-NE4NDO45.js → chunk-S75P2FFI.js} +1 -1
- package/static/{chunk-CRQNEHTX.js → chunk-T3EYFSVZ.js} +1 -1
- package/static/{chunk-MCLQFZ3S.js → chunk-U34OZUZ7.js} +1 -1
- package/static/chunk-Y7EH7G5K.js +1 -0
- package/static/{chunk-MGGT6MIJ.js → chunk-ZQQPUYLU.js} +1 -1
- package/static/index.html +2 -2
- package/static/main-7SQDDVMD.js +9 -0
- package/static/{styles-FYUSO6OJ.css → styles-A5VYX3CE.css} +1 -1
- package/server/applications/users/dto/user-password.dto.js.map +0 -1
- package/static/chunk-4U5A2DEP.js +0 -4
- package/static/chunk-54EAZ2UD.js +0 -1
- package/static/chunk-7ZRXJONB.js +0 -1
- package/static/chunk-F2J2IIJE.js +0 -1
- package/static/chunk-FNFGUIQH.js +0 -4
- package/static/chunk-GGLK52CG.js +0 -1
- package/static/chunk-HW2H3ISM.js +0 -559
- package/static/chunk-HX6BBYVD.js +0 -1
- package/static/chunk-JF7S3UYQ.js +0 -1
- package/static/chunk-KSHPKI4G.js +0 -1
- package/static/chunk-VPJ2V27B.js +0 -1
- package/static/chunk-VUI3KV7V.js +0 -1
- package/static/chunk-ZXS4V7J2.js +0 -1
- package/static/main-FFIWFD2F.js +0 -7
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sync-in/server",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.6.1",
|
|
4
4
|
"description": "The secure, open-source platform for file storage, sharing, collaboration, and sync",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Johan Legrand",
|
|
@@ -73,7 +73,7 @@
|
|
|
73
73
|
},
|
|
74
74
|
"dependencies": {
|
|
75
75
|
"@fastify/cookie": "11.0.2",
|
|
76
|
-
"@fastify/helmet": "13.0.
|
|
76
|
+
"@fastify/helmet": "13.0.2",
|
|
77
77
|
"@fastify/multipart": "9.2.1",
|
|
78
78
|
"@fastify/send": "4.1.0",
|
|
79
79
|
"@fastify/static": "8.2.0",
|
|
@@ -87,7 +87,7 @@
|
|
|
87
87
|
"@nestjs/passport": "11.0.5",
|
|
88
88
|
"@nestjs/platform-fastify": "11.1.6",
|
|
89
89
|
"@nestjs/platform-socket.io": "11.1.6",
|
|
90
|
-
"@nestjs/schedule": "6.0.
|
|
90
|
+
"@nestjs/schedule": "6.0.1",
|
|
91
91
|
"@nestjs/websockets": "11.1.6",
|
|
92
92
|
"@socket.io/cluster-adapter": "0.2.2",
|
|
93
93
|
"@socket.io/redis-adapter": "8.3.0",
|
|
@@ -97,27 +97,29 @@
|
|
|
97
97
|
"class-transformer": "0.5.1",
|
|
98
98
|
"class-validator": "0.14.2",
|
|
99
99
|
"deepmerge": "4.3.1",
|
|
100
|
-
"drizzle-kit": "0.31.
|
|
101
|
-
"drizzle-orm": "0.44.
|
|
102
|
-
"fast-xml-parser": "5.
|
|
103
|
-
"fs-extra": "11.3.
|
|
100
|
+
"drizzle-kit": "0.31.5",
|
|
101
|
+
"drizzle-orm": "0.44.6",
|
|
102
|
+
"fast-xml-parser": "5.3.0",
|
|
103
|
+
"fs-extra": "11.3.2",
|
|
104
104
|
"html-to-text": "9.0.5",
|
|
105
105
|
"js-yaml": "4.1.0",
|
|
106
106
|
"ldapts": "8.0.9",
|
|
107
107
|
"mime-types": "3.0.1",
|
|
108
|
-
"mysql2": "3.
|
|
109
|
-
"nestjs-pino": "4.4.
|
|
110
|
-
"nodemailer": "7.0.
|
|
108
|
+
"mysql2": "3.15.2",
|
|
109
|
+
"nestjs-pino": "4.4.1",
|
|
110
|
+
"nodemailer": "7.0.9",
|
|
111
111
|
"passport-http": "0.3.0",
|
|
112
112
|
"passport-jwt": "4.0.1",
|
|
113
113
|
"passport-local": "1.0.0",
|
|
114
114
|
"passport": "0.7.0",
|
|
115
|
-
"pdfjs-dist": "5.4.
|
|
115
|
+
"pdfjs-dist": "5.4.296",
|
|
116
116
|
"pino-pretty": "13.1.1",
|
|
117
|
+
"qrcode-generator": "2.0.4",
|
|
117
118
|
"redis": "4.7.1",
|
|
118
119
|
"sax": "1.4.1",
|
|
119
120
|
"socket.io": "4.8.1",
|
|
120
|
-
"tar": "7.
|
|
121
|
+
"tar": "7.5.1",
|
|
122
|
+
"time2fa": "1.4.2",
|
|
121
123
|
"yauzl": "3.2.0"
|
|
122
124
|
}
|
|
123
125
|
}
|
package/server/app.bootstrap.js
CHANGED
|
@@ -90,7 +90,7 @@ async function appBootstrap() {
|
|
|
90
90
|
secret: _configenvironment.configuration.auth.token.csrf.secret,
|
|
91
91
|
parseOptions: {
|
|
92
92
|
secure: 'auto',
|
|
93
|
-
sameSite: _configenvironment.configuration.auth.
|
|
93
|
+
sameSite: _configenvironment.configuration.auth.cookieSameSite,
|
|
94
94
|
httpOnly: true
|
|
95
95
|
}
|
|
96
96
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../backend/src/app.bootstrap.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 fastifyCookie from '@fastify/cookie'\nimport fastifyHelmet from '@fastify/helmet'\nimport multipart from '@fastify/multipart'\nimport { ClassSerializerInterceptor, ValidationPipe } from '@nestjs/common'\nimport { NestFactory, Reflector } from '@nestjs/core'\nimport { FastifyAdapter, NestFastifyApplication } from '@nestjs/platform-fastify'\nimport { FastifyRequest } from 'fastify'\nimport { Logger, LoggerErrorInterceptor } from 'nestjs-pino'\nimport { CONTENT_SECURITY_POLICY } from './app.constants'\nimport { AppModule } from './app.module'\nimport { HTTP_WEBDAV_METHOD } from './applications/applications.constants'\nimport { WEBDAV_NS, WEBDAV_SPACES } from './applications/webdav/constants/routes'\nimport { IS_TEST_ENV, STATIC_PATH } from './configuration/config.constants'\nimport { configuration } from './configuration/config.environment'\nimport { WebSocketAdapter } from './infrastructure/websocket/adapters/web-socket.adapter'\n\nexport async function appBootstrap(): Promise<NestFastifyApplication> {\n /* APP */\n const fastifyAdapter = new FastifyAdapter({\n logger: false,\n trustProxy: configuration.server.trustProxy,\n ignoreTrailingSlash: true,\n maxParamLength: 256,\n bodyLimit: 26214400 /* 25 MB */\n })\n const app: NestFastifyApplication = await NestFactory.create<NestFastifyApplication>(AppModule, fastifyAdapter, {\n bufferLogs: true\n })\n\n /* Fastify instance */\n const fastifyInstance = fastifyAdapter.getInstance()\n\n /* LOGGER */\n app.useLogger(IS_TEST_ENV ? ['fatal'] : app.get(Logger))\n\n /* PARSER */\n // xml body parser is used for webdav methods\n app.useBodyParser(['application/xml', 'text/xml'])\n // add webdav methods\n for (const method of Object.values(HTTP_WEBDAV_METHOD)) {\n fastifyInstance.addHttpMethod(method, { hasBody: true })\n }\n // '*' body parser allow binary data as stream (unlimited body size)\n fastifyInstance.addContentTypeParser('*', { bodyLimit: 0 }, (_req: FastifyRequest, _payload: FastifyRequest['raw'], done) => done(null))\n\n // Joplin clients send incorrect `Content-Type` headers when syncing over WebDAV (issue: https://github.com/laurent22/joplin/issues/122499)\n // This hook intercepts matching requests and sets `application/octet-stream` to ensure compatibility and successful sync.\n // todo: remove it when fixed on Joplin side\n fastifyInstance.addHook('onRequest', async (req, _reply) => {\n if ((req.headers['user-agent'] || '').indexOf('Joplin') !== -1 && req.originalUrl.startsWith(WEBDAV_SPACES[WEBDAV_NS.WEBDAV].route)) {\n req.headers['content-type'] = 'application/octet-stream'\n }\n })\n\n /* INTERCEPTORS */\n app.useGlobalInterceptors(\n new LoggerErrorInterceptor(),\n new ClassSerializerInterceptor(app.get(Reflector), {\n excludePrefixes: ['_']\n })\n )\n /* VALIDATION */\n app.useGlobalPipes(new ValidationPipe({ transform: true, whitelist: true }))\n\n /* STATIC */\n app.useStaticAssets({ root: STATIC_PATH, prefixAvoidTrailingSlash: true })\n\n /* SECURITY */\n await app.register(fastifyHelmet, { contentSecurityPolicy: CONTENT_SECURITY_POLICY(configuration.applications.files.onlyoffice.externalServer) })\n\n /* COOKIES */\n // we use csrf secret to unsign csrf cookie\n await app.register(fastifyCookie, {\n secret: configuration.auth.token.csrf.secret,\n parseOptions: {\n secure: 'auto',\n sameSite: configuration.auth.
|
|
1
|
+
{"version":3,"sources":["../../backend/src/app.bootstrap.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 fastifyCookie from '@fastify/cookie'\nimport fastifyHelmet from '@fastify/helmet'\nimport multipart from '@fastify/multipart'\nimport { ClassSerializerInterceptor, ValidationPipe } from '@nestjs/common'\nimport { NestFactory, Reflector } from '@nestjs/core'\nimport { FastifyAdapter, NestFastifyApplication } from '@nestjs/platform-fastify'\nimport { FastifyRequest } from 'fastify'\nimport { Logger, LoggerErrorInterceptor } from 'nestjs-pino'\nimport { CONTENT_SECURITY_POLICY } from './app.constants'\nimport { AppModule } from './app.module'\nimport { HTTP_WEBDAV_METHOD } from './applications/applications.constants'\nimport { WEBDAV_NS, WEBDAV_SPACES } from './applications/webdav/constants/routes'\nimport { IS_TEST_ENV, STATIC_PATH } from './configuration/config.constants'\nimport { configuration } from './configuration/config.environment'\nimport { WebSocketAdapter } from './infrastructure/websocket/adapters/web-socket.adapter'\n\nexport async function appBootstrap(): Promise<NestFastifyApplication> {\n /* APP */\n const fastifyAdapter = new FastifyAdapter({\n logger: false,\n trustProxy: configuration.server.trustProxy,\n ignoreTrailingSlash: true,\n maxParamLength: 256,\n bodyLimit: 26214400 /* 25 MB */\n })\n const app: NestFastifyApplication = await NestFactory.create<NestFastifyApplication>(AppModule, fastifyAdapter, {\n bufferLogs: true\n })\n\n /* Fastify instance */\n const fastifyInstance = fastifyAdapter.getInstance()\n\n /* LOGGER */\n app.useLogger(IS_TEST_ENV ? ['fatal'] : app.get(Logger))\n\n /* PARSER */\n // xml body parser is used for webdav methods\n app.useBodyParser(['application/xml', 'text/xml'])\n // add webdav methods\n for (const method of Object.values(HTTP_WEBDAV_METHOD)) {\n fastifyInstance.addHttpMethod(method, { hasBody: true })\n }\n // '*' body parser allow binary data as stream (unlimited body size)\n fastifyInstance.addContentTypeParser('*', { bodyLimit: 0 }, (_req: FastifyRequest, _payload: FastifyRequest['raw'], done) => done(null))\n\n // Joplin clients send incorrect `Content-Type` headers when syncing over WebDAV (issue: https://github.com/laurent22/joplin/issues/122499)\n // This hook intercepts matching requests and sets `application/octet-stream` to ensure compatibility and successful sync.\n // todo: remove it when fixed on Joplin side\n fastifyInstance.addHook('onRequest', async (req, _reply) => {\n if ((req.headers['user-agent'] || '').indexOf('Joplin') !== -1 && req.originalUrl.startsWith(WEBDAV_SPACES[WEBDAV_NS.WEBDAV].route)) {\n req.headers['content-type'] = 'application/octet-stream'\n }\n })\n\n /* INTERCEPTORS */\n app.useGlobalInterceptors(\n new LoggerErrorInterceptor(),\n new ClassSerializerInterceptor(app.get(Reflector), {\n excludePrefixes: ['_']\n })\n )\n /* VALIDATION */\n app.useGlobalPipes(new ValidationPipe({ transform: true, whitelist: true }))\n\n /* STATIC */\n app.useStaticAssets({ root: STATIC_PATH, prefixAvoidTrailingSlash: true })\n\n /* SECURITY */\n await app.register(fastifyHelmet, { contentSecurityPolicy: CONTENT_SECURITY_POLICY(configuration.applications.files.onlyoffice.externalServer) })\n\n /* COOKIES */\n // we use csrf secret to unsign csrf cookie\n await app.register(fastifyCookie, {\n secret: configuration.auth.token.csrf.secret,\n parseOptions: {\n secure: 'auto',\n sameSite: configuration.auth.cookieSameSite,\n httpOnly: true\n }\n })\n\n /* UPLOAD */\n await app.register(multipart, {\n preservePath: true,\n limits: { parts: Infinity, fileSize: configuration.applications.files.maxUploadSize }\n })\n\n /* WEBSOCKET */\n if (!IS_TEST_ENV) {\n const webSocketAdapter = new WebSocketAdapter(app)\n await webSocketAdapter.initAdapter()\n app.useWebSocketAdapter(webSocketAdapter)\n }\n\n return app\n}\n"],"names":["appBootstrap","fastifyAdapter","FastifyAdapter","logger","trustProxy","configuration","server","ignoreTrailingSlash","maxParamLength","bodyLimit","app","NestFactory","create","AppModule","bufferLogs","fastifyInstance","getInstance","useLogger","IS_TEST_ENV","get","Logger","useBodyParser","method","Object","values","HTTP_WEBDAV_METHOD","addHttpMethod","hasBody","addContentTypeParser","_req","_payload","done","addHook","req","_reply","headers","indexOf","originalUrl","startsWith","WEBDAV_SPACES","WEBDAV_NS","WEBDAV","route","useGlobalInterceptors","LoggerErrorInterceptor","ClassSerializerInterceptor","Reflector","excludePrefixes","useGlobalPipes","ValidationPipe","transform","whitelist","useStaticAssets","root","STATIC_PATH","prefixAvoidTrailingSlash","register","fastifyHelmet","contentSecurityPolicy","CONTENT_SECURITY_POLICY","applications","files","onlyoffice","externalServer","fastifyCookie","secret","auth","token","csrf","parseOptions","secure","sameSite","cookieSameSite","httpOnly","multipart","preservePath","limits","parts","Infinity","fileSize","maxUploadSize","webSocketAdapter","WebSocketAdapter","initAdapter","useWebSocketAdapter"],"mappings":"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"}
|
|
@@ -212,8 +212,7 @@ let FilesManager = class FilesManager {
|
|
|
212
212
|
const fileExtension = _nodepath.default.extname(space.realPath);
|
|
213
213
|
if (checkDocument && fileExtension !== '.txt' && Object.values(_samples.DOCUMENT_TYPE).indexOf(fileExtension) > -1) {
|
|
214
214
|
const srcSample = _nodepath.default.join(__dirname, `${_samples.SAMPLE_PATH_WITHOUT_EXT}${fileExtension}`);
|
|
215
|
-
|
|
216
|
-
return (0, _files1.touchFile)(space.realPath);
|
|
215
|
+
return (0, _files1.copyFiles)(srcSample, space.realPath, false, false, false);
|
|
217
216
|
} else {
|
|
218
217
|
return (0, _files1.createEmptyFile)(space.realPath);
|
|
219
218
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../backend/src/applications/files/services/files-manager.service.ts"],"sourcesContent":["/*\n * Copyright (C) 2012-2025 Johan Legrand <johan.legrand@sync-in.com>\n * This file is part of Sync-in | The open source file sync and share solution\n * See the LICENSE file for licensing details\n */\n\nimport { HttpService } from '@nestjs/axios'\nimport { HttpStatus, Injectable, Logger } from '@nestjs/common'\nimport archiver, { Archiver, ArchiverError } from 'archiver'\nimport { AxiosResponse } from 'axios'\nimport { PNGStream } from 'canvas'\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport { pipeline } from 'node:stream/promises'\nimport { extract as extractTar } from 'tar'\nimport { FastifyAuthenticatedRequest } from '../../../authentication/interfaces/auth-request.interface'\nimport { generateThumbnail } from '../../../common/image'\nimport { HTTP_METHOD } from '../../applications.constants'\nimport { SPACE_OPERATION } from '../../spaces/constants/spaces'\nimport { FastifySpaceRequest } from '../../spaces/interfaces/space-request.interface'\nimport { SpaceEnv } from '../../spaces/models/space-env.model'\nimport { realTrashPathFromSpace } from '../../spaces/utils/paths'\nimport { canAccessToSpace, haveSpaceEnvPermissions } from '../../spaces/utils/permissions'\nimport { UserModel } from '../../users/models/user.model'\nimport { DEPTH, LOCK_DEPTH } from '../../webdav/constants/webdav'\nimport { tarGzExtension } from '../constants/compress'\nimport { COMPRESSION_EXTENSION, DEFAULT_HIGH_WATER_MARK } from '../constants/files'\nimport { FILE_OPERATION } from '../constants/operations'\nimport { DOCUMENT_TYPE, SAMPLE_PATH_WITHOUT_EXT } from '../constants/samples'\nimport { CompressFileDto } from '../dto/file-operations.dto'\nimport { FileTaskEvent } from '../events/file-task-event'\nimport { FileDBProps } from '../interfaces/file-db-props.interface'\nimport { FileLock } from '../interfaces/file-lock.interface'\nimport { FileError } from '../models/file-error'\nimport { LockConflict } from '../models/file-lock-error'\nimport {\n checkFileName,\n copyFiles,\n createEmptyFile,\n dirName,\n dirSize,\n fileName,\n fileSize,\n getMimeType,\n isPathExists,\n isPathIsDir,\n makeDir,\n moveFiles,\n removeFiles,\n touchFile,\n uniqueDatedFilePath,\n uniqueFilePathFromDir,\n writeFromStream,\n writeFromStreamAndChecksum\n} from '../utils/files'\nimport { SendFile } from '../utils/send-file'\nimport { extractZip } from '../utils/unzip-file'\nimport { regExpPrivateIP } from '../utils/url-file'\nimport { FilesLockManager } from './files-lock-manager.service'\nimport { FilesQueries } from './files-queries.service'\n\n@Injectable()\nexport class FilesManager {\n /* Spaces permissions are checked in the space guard, except for the copy/move destination */\n private logger = new Logger(FilesManager.name)\n\n constructor(\n private readonly http: HttpService,\n private readonly filesQueries: FilesQueries,\n private readonly filesLockManager: FilesLockManager\n ) {}\n\n sendFileFromSpace(space: SpaceEnv, asAttachment = false, downloadName = ''): SendFile {\n return new SendFile(space.realPath, asAttachment, downloadName)\n }\n\n async saveStream(\n user: UserModel,\n space: SpaceEnv,\n req: FastifyAuthenticatedRequest,\n options: {\n checksumAlg: string\n tmpPath?: string\n }\n ): Promise<string>\n async saveStream(user: UserModel, space: SpaceEnv, req: FastifyAuthenticatedRequest, options?: any): Promise<boolean>\n async saveStream(\n user: UserModel,\n space: SpaceEnv,\n req: FastifyAuthenticatedRequest,\n options?: { dav?: { depth: LOCK_DEPTH; lockTokens: string[] }; checksumAlg?: string; tmpPath?: string }\n ): Promise<boolean | string> {\n // if tmpPath is used, we lock the final destination during the transfer\n // space.realPath is replaced by tmpPath (if allowed), if the move operation failed we remove the tmp file\n const fExists = await isPathExists(space.realPath)\n const fTmpExists = options?.tmpPath ? await isPathExists(options.tmpPath) : false\n if (fExists && req.method === HTTP_METHOD.POST) {\n throw new FileError(HttpStatus.METHOD_NOT_ALLOWED, 'Resource already exists')\n }\n if (fExists && (await isPathIsDir(space.realPath))) {\n throw new FileError(HttpStatus.METHOD_NOT_ALLOWED, 'The location is a directory')\n }\n if (options?.tmpPath) {\n // ensure tmpPath parent dir exists\n await makeDir(dirName(options.tmpPath), true)\n } else if (!(await isPathExists(dirName(space.realPath)))) {\n throw new FileError(HttpStatus.CONFLICT, 'Parent must exists')\n }\n /* File Lock */\n let fileLock: FileLock | undefined\n if (options?.dav) {\n // check locks\n await this.filesLockManager.checkConflicts(space.dbFile, options?.dav?.depth || DEPTH.RESOURCE, {\n userId: user.id,\n lockTokens: options.dav?.lockTokens\n })\n } else {\n // create lock if there is no webdav context\n const [ok, lock] = await this.filesLockManager.create(user, space.dbFile, DEPTH.RESOURCE)\n if (!ok) {\n throw new LockConflict(lock, 'Conflicting lock')\n }\n fileLock = lock\n }\n try {\n // check range\n let startRange = 0\n if ((fExists || fTmpExists) && req.headers['content-range']) {\n // with PUT method, some webdav clients use the `content-range` header,\n // which is normally reserved for a response to a request containing the `range` header.\n // However, for more compatibility let's accept it\n const match = /\\d+/.exec(req.headers['content-range'])\n if (!match.length) {\n throw new FileError(HttpStatus.BAD_REQUEST, 'Content-range : header is malformed')\n }\n startRange = parseInt(match[0], 10)\n const size = await fileSize(options?.tmpPath || space.realPath)\n if (startRange !== size) {\n throw new FileError(HttpStatus.BAD_REQUEST, 'Content-range : start offset does not match the current file size')\n }\n }\n // todo: check file in db to update\n // todo : versioning here\n let checksum: string\n if (options?.checksumAlg) {\n checksum = await writeFromStreamAndChecksum(options?.tmpPath || space.realPath, req.raw, startRange, options.checksumAlg)\n } else {\n await writeFromStream(options?.tmpPath || space.realPath, req.raw, startRange)\n }\n if (options?.tmpPath) {\n try {\n // ensure parent path exists\n await makeDir(path.dirname(space.realPath), true)\n // move the uploaded file to destination\n await moveFiles(options.tmpPath, space.realPath, true)\n } catch (e) {\n // cleanup tmp file\n await removeFiles(options.tmpPath)\n this.logger.error(`${this.saveStream.name} - unable to move ${options.tmpPath} -> ${space.realPath} : ${e}`)\n throw new FileError(HttpStatus.INTERNAL_SERVER_ERROR, 'Unable to move tmp file to dst file')\n }\n }\n if (options?.checksumAlg) {\n return checksum\n }\n return fExists\n } finally {\n if (fileLock) {\n try {\n await this.filesLockManager.removeLock(fileLock.key)\n } catch (e) {\n this.logger.warn(`Failed to remove lock ${fileLock.key}: ${e}`)\n }\n }\n }\n }\n\n async saveMultipart(user: UserModel, space: SpaceEnv, req: FastifySpaceRequest) {\n /* Accepted methods:\n POST: create new resource\n PUT: create or update new resource (even if parent path does not exist)\n */\n const realParentPath = dirName(space.realPath)\n\n if (req.method === HTTP_METHOD.POST) {\n if (await isPathExists(space.realPath)) {\n throw new FileError(HttpStatus.BAD_REQUEST, 'Resource already exists')\n }\n if (!(await isPathExists(realParentPath))) {\n throw new FileError(HttpStatus.BAD_REQUEST, 'Parent must exists')\n }\n if (!(await isPathIsDir(realParentPath))) {\n throw new FileError(HttpStatus.BAD_REQUEST, 'Parent must be a directory')\n }\n }\n\n const basePath = realParentPath + path.sep\n\n for await (const part of req.files()) {\n // part.filename may contain a path like foo/bar.txt.\n const dstFile = path.resolve(basePath, part.filename)\n // prevent path traversal\n if (!dstFile.startsWith(basePath)) {\n throw new FileError(HttpStatus.FORBIDDEN, 'Location is not allowed')\n }\n // make dir in space\n const dstDir = dirName(dstFile)\n if (!(await isPathExists(dstDir))) {\n await makeDir(dstDir, true)\n }\n // create lock\n const dbFile = { ...space.dbFile, path: path.join(dirName(space.dbFile.path), part.filename) }\n const [ok, fileLock] = await this.filesLockManager.create(user, dbFile, DEPTH.RESOURCE)\n if (!ok) throw new LockConflict(fileLock, 'Conflicting lock')\n // do\n try {\n await pipeline(part.file, fs.createWriteStream(dstFile, { highWaterMark: DEFAULT_HIGH_WATER_MARK }))\n } finally {\n await this.filesLockManager.removeLock(fileLock.key)\n }\n }\n }\n\n async touch(user: UserModel, space: SpaceEnv, mtime: number, checkLocks = true): Promise<void> {\n if (!(await isPathExists(space.realPath))) {\n throw new FileError(HttpStatus.NOT_FOUND, 'Location not found')\n }\n if (checkLocks) {\n await this.filesLockManager.checkConflicts(space.dbFile, DEPTH.RESOURCE, { userId: user.id })\n }\n // todo: update mtime in last files ( & in db file ?)\n await touchFile(space.realPath, mtime)\n }\n\n async mkFile(user: UserModel, space: SpaceEnv, overwrite = false, checkLocks = true, checkDocument = false): Promise<void> {\n checkFileName(space.realPath)\n if (!overwrite && (await isPathExists(space.realPath))) {\n throw new FileError(HttpStatus.BAD_REQUEST, 'Resource already exists')\n }\n if (checkLocks) {\n await this.filesLockManager.checkConflicts(space.dbFile, DEPTH.RESOURCE, { userId: user.id })\n }\n // use sample documents when possible\n const fileExtension = path.extname(space.realPath)\n if (checkDocument && fileExtension !== '.txt' && Object.values(DOCUMENT_TYPE).indexOf(fileExtension) > -1) {\n const srcSample = path.join(__dirname, `${SAMPLE_PATH_WITHOUT_EXT}${fileExtension}`)\n await copyFiles(srcSample, space.realPath)\n return touchFile(space.realPath)\n } else {\n return createEmptyFile(space.realPath)\n }\n }\n\n async mkDir(user: UserModel, space: SpaceEnv, recursive = false, dav?: { depth: LOCK_DEPTH; lockTokens: string[] }): Promise<void> {\n checkFileName(space.realPath)\n if (!recursive) {\n if (await isPathExists(space.realPath)) {\n throw new FileError(HttpStatus.METHOD_NOT_ALLOWED, 'Resource already exists')\n } else if (!(await isPathExists(dirName(space.realPath)))) {\n throw new FileError(HttpStatus.CONFLICT, 'Parent must exists')\n }\n }\n await this.filesLockManager.checkConflicts(space.dbFile, dav?.depth || DEPTH.RESOURCE, { userId: user.id, lockTokens: dav?.lockTokens })\n await makeDir(space.realPath, recursive)\n }\n\n async copyMove(\n user: UserModel,\n srcSpace: SpaceEnv,\n dstSpace: SpaceEnv,\n isMove: boolean,\n overwrite = false,\n mkdirDstParentPath = false,\n dav?: { depth: LOCK_DEPTH; lockTokens: string[] }\n ): Promise<void> {\n // checks\n if (!canAccessToSpace(user, dstSpace)) {\n this.logger.warn(`${this.copyMove.name} - is not allowed to access to this space repository : ${dstSpace.repository}`)\n throw new FileError(HttpStatus.FORBIDDEN, 'You are not allowed to access to this repository')\n }\n if (!haveSpaceEnvPermissions(dstSpace, SPACE_OPERATION.ADD)) {\n this.logger.warn(`${this.copyMove.name} - is not allowed to copy/move on this space : *${dstSpace.alias}* (${dstSpace.id}) : ${dstSpace.url}`)\n throw new FileError(HttpStatus.FORBIDDEN, 'You are not allowed to copy/move on the destination')\n }\n if (dstSpace.quotaIsExceeded) {\n this.logger.warn(`${this.copyMove.name} - quota is exceeded for *${dstSpace.alias}* (${dstSpace.id})`)\n throw new FileError(HttpStatus.INSUFFICIENT_STORAGE, 'Quota is exceeded')\n }\n if (!(await isPathExists(srcSpace.realPath))) {\n throw new FileError(HttpStatus.NOT_FOUND, 'Location not found')\n }\n if (!(await isPathExists(dirName(dstSpace.realPath)))) {\n if (mkdirDstParentPath) {\n try {\n await makeDir(dirName(dstSpace.realPath), true)\n } catch (e) {\n this.logger.error(`${this.copyMove.name} - Cannot create parent directory for destination ${dstSpace.realPath} : ${e}`)\n throw new FileError(HttpStatus.INTERNAL_SERVER_ERROR, 'Cannot create parent directory for destination')\n }\n } else {\n throw new FileError(HttpStatus.CONFLICT, 'Parent must exists')\n }\n }\n if (srcSpace.realPath === dstSpace.realPath) {\n throw new FileError(HttpStatus.FORBIDDEN, 'Cannot copy/move source onto itself')\n }\n if (`${dstSpace.realPath}/`.startsWith(`${srcSpace.realPath}/`)) {\n throw new FileError(HttpStatus.FORBIDDEN, 'Cannot copy/move source below itself')\n }\n if (dirName(srcSpace.url) === dirName(dstSpace.url) && dirName(srcSpace.realPath) !== dirName(dstSpace.realPath)) {\n /* Handle renaming a space file with the same name as a space root :\n srcSpace.url = '/space/sync-in/code2.ts' (a space file)\n srcSpace.realPath = '/home/sync-in/spaces/sync-in/code2.ts\n dstSpace.url = '/space/sync-in/code.ts' (a space root)\n dstSpace.realPath = '/home/sync-in/users/jo/files/code2.ts !!\n */\n throw new FileError(HttpStatus.BAD_REQUEST, 'An anchored file already has this name')\n }\n if (!overwrite && (await isPathExists(dstSpace.realPath))) {\n /* Handle case-sensitive (in renaming context):\n srcSpace.url = '/space/sync-in/code.ts'\n dstSpace.url = '/space/sync-in/code.TS'\n The destination exists because it's the same file, bypass this\n */\n if (!(isMove && srcSpace.realPath.toLowerCase() === dstSpace.realPath.toLowerCase())) {\n throw new FileError(dav ? HttpStatus.PRECONDITION_FAILED : HttpStatus.BAD_REQUEST, 'The destination already exists')\n }\n }\n\n const isDir = await isPathIsDir(srcSpace.realPath)\n\n if (dstSpace.storageQuota) {\n /* Skip validation when moving to the same space; for copy operations, run all checks. */\n if (!isMove || (isMove && srcSpace.id !== dstSpace.id)) {\n const size = isDir ? (await dirSize(srcSpace.realPath))[0] : await fileSize(srcSpace.realPath)\n if (dstSpace.willExceedQuota(size)) {\n this.logger.warn(`${this.copyMove.name} - quota will be exceeded for *${dstSpace.alias}* (${dstSpace.id})`)\n throw new FileError(HttpStatus.INSUFFICIENT_STORAGE, 'Quota will be exceeded')\n }\n }\n }\n\n // check lock conflicts on source & destination\n let recursive: boolean\n let depth: LOCK_DEPTH\n if (dav?.depth) {\n recursive = dav.depth === DEPTH.INFINITY\n depth = dav.depth\n } else {\n recursive = isDir\n depth = recursive ? DEPTH.INFINITY : DEPTH.RESOURCE\n }\n if (isMove) {\n // check source\n await this.filesLockManager.checkConflicts(srcSpace.dbFile, depth, { userId: user.id, lockTokens: dav?.lockTokens })\n }\n // check destination\n await this.filesLockManager.checkConflicts(dstSpace.dbFile, depth, { userId: user.id, lockTokens: dav?.lockTokens })\n\n // overwrite\n if (overwrite && (await isPathExists(dstSpace.realPath))) {\n // todo : versioning here\n await this.delete(user, dstSpace)\n }\n\n // send to task watcher\n if (srcSpace.task?.cacheKey) {\n if (!isDir) srcSpace.task.props.totalSize = await fileSize(srcSpace.realPath)\n FileTaskEvent.emit('startWatch', srcSpace, isMove ? FILE_OPERATION.MOVE : FILE_OPERATION.COPY, dstSpace.realPath)\n }\n\n // do\n if (isMove) {\n await moveFiles(srcSpace.realPath, dstSpace.realPath, overwrite)\n return this.filesQueries.moveFiles(srcSpace.dbFile, dstSpace.dbFile, isDir)\n }\n return copyFiles(srcSpace.realPath, dstSpace.realPath, overwrite, recursive)\n }\n\n async delete(user: UserModel, space: SpaceEnv, dav?: { lockTokens: string[] }): Promise<void> {\n if (!(await isPathExists(space.realPath))) {\n throw new FileError(HttpStatus.NOT_FOUND, 'Location not found')\n }\n // check lock conflicts\n const isDir = await isPathIsDir(space.realPath)\n await this.filesLockManager.checkConflicts(space.dbFile, isDir ? DEPTH.INFINITY : DEPTH.RESOURCE, {\n userId: user.id,\n lockTokens: dav?.lockTokens\n })\n // file system deletion\n let forceDeleteInDB = false\n if (space.inTrashRepository) {\n await removeFiles(space.realPath)\n } else {\n const baseTrashPath = realTrashPathFromSpace(user, space)\n if (baseTrashPath) {\n const name = fileName(space.realPath)\n const trashDir = path.join(baseTrashPath, dirName(space.dbFile.path))\n const trashFile = path.join(trashDir, name)\n if (!(await isPathExists(trashDir))) {\n await makeDir(trashDir, true)\n }\n if (await isPathExists(trashFile)) {\n // if a resource already exists in the trash, rename it with the date\n const dstTrash = await uniqueDatedFilePath(trashFile)\n // move the resource on fs\n await moveFiles(trashFile, dstTrash.path)\n // move the resource in db\n const trashFileDB: FileDBProps = { ...space.dbFile, inTrash: true }\n const dstTrashFileDB: FileDBProps = { ...trashFileDB, path: path.join(dirName(trashFileDB.path), fileName(dstTrash.path)) }\n this.filesQueries\n .moveFiles(trashFileDB, dstTrashFileDB, dstTrash.isDir)\n .catch((e: Error) => this.logger.error(`${this.delete.name} - ${e}`))\n }\n await moveFiles(space.realPath, trashFile, true)\n } else {\n this.logger.log(`Unable to find trash path for space - *${space.alias}* (${space.id}) : delete permanently : ${space.realPath}`)\n // todo: define a default trash for external paths\n forceDeleteInDB = true\n await removeFiles(space.realPath)\n }\n }\n // remove locks, these locks have already been checked in the `checkConflicts` function\n if (isDir) {\n this.filesLockManager.removeChildLocks(user, space.dbFile).catch((e: Error) => this.logger.error(`${this.delete.name} - ${e}`))\n }\n for (const lock of await this.filesLockManager.getLocksByPath(space.dbFile)) {\n this.filesLockManager.removeLock(lock.key).catch((e: Error) => this.logger.error(`${this.delete.name} - ${e}`))\n }\n // delete or move to trash the files in db\n return this.filesQueries.deleteFiles(space.dbFile, isDir, forceDeleteInDB)\n }\n\n async downloadFromUrl(user: UserModel, space: SpaceEnv, url: string): Promise<void> {\n this.logger.log(`${this.downloadFromUrl.name} : ${url}`)\n // create lock\n const rPath = await uniqueFilePathFromDir(space.realPath)\n const dbFile = space.dbFile\n dbFile.path = path.join(dirName(dbFile.path), fileName(space.realPath))\n const [ok, fileLock] = await this.filesLockManager.create(user, dbFile, DEPTH.RESOURCE)\n if (!ok) {\n throw new LockConflict(fileLock, 'Conflicting lock')\n }\n // tasking\n if (space.task.cacheKey) {\n let headRes: AxiosResponse\n\n try {\n headRes = await this.http.axiosRef({ method: HTTP_METHOD.HEAD, url: url, maxRedirects: 1 })\n } catch (e) {\n // release lock\n await this.filesLockManager.removeLock(fileLock.key)\n this.logger.error(`${this.downloadFromUrl.name} - ${url} : ${e}`)\n throw new FileError(HttpStatus.BAD_REQUEST, 'Unable to download file')\n }\n\n if (regExpPrivateIP.test(headRes.request.socket.remoteAddress)) {\n // release lock\n await this.filesLockManager.removeLock(fileLock.key)\n // prevent SSRF attack\n throw new FileError(HttpStatus.FORBIDDEN, 'Access to internal IP addresses is forbidden')\n }\n\n // attempt to retrieve the Content-Length header\n try {\n if ('content-length' in headRes.headers) {\n space.task.props.totalSize = parseInt(headRes.headers['content-length'], 10) || null\n }\n } catch (e) {\n this.logger.debug(`${this.downloadFromUrl.name} - content-length : ${e}`)\n }\n FileTaskEvent.emit('startWatch', space, FILE_OPERATION.DOWNLOAD, rPath)\n }\n // do\n try {\n const getRes = await this.http.axiosRef({ method: HTTP_METHOD.GET, url: url, responseType: 'stream', maxRedirects: 1 })\n if (regExpPrivateIP.test(getRes.request.socket.remoteAddress)) {\n // Prevent SSRF attacks and perform a DNS-rebinding check if a HEAD request has already been made\n throw new FileError(HttpStatus.FORBIDDEN, 'Access to internal IP addresses is forbidden')\n }\n await writeFromStream(rPath, getRes.data)\n } finally {\n // release lock\n await this.filesLockManager.removeLock(fileLock.key)\n }\n }\n\n async compress(user: UserModel, space: SpaceEnv, dto: CompressFileDto): Promise<void> {\n // This method is currently used only by files-methods.service, which handles input sanitization.\n // If it is used in other services in the future, make sure to refactor accordingly to sanitize inputs properly.\n const srcPath = dirName(space.realPath)\n // todo: a guest link tasksPath should be in specific directory (guest link has no home)\n const archiveExt = dto.name.endsWith(dto.extension) ? '' : `.${dto.extension}`\n const dstPath = await uniqueFilePathFromDir(path.join(dto.compressInDirectory ? srcPath : user.tasksPath, `${dto.name}${archiveExt}`))\n const archive: Archiver = archiver('tar', {\n gzip: dto.extension === tarGzExtension,\n gzipOptions: {\n level: 9\n }\n })\n // create lock\n let fileLock: FileLock\n if (dto.compressInDirectory) {\n const dbFile = space.dbFile\n dbFile.path = path.join(dirName(dbFile.path), fileName(dstPath))\n const [ok, lock] = await this.filesLockManager.create(user, dbFile, DEPTH.RESOURCE)\n if (!ok) {\n throw new LockConflict(lock, 'Conflicting lock')\n }\n fileLock = lock\n }\n if (space.task?.cacheKey) {\n space.task.props.compressInDirectory = dto.compressInDirectory\n FileTaskEvent.emit('startWatch', space, FILE_OPERATION.COMPRESS, dstPath)\n }\n // do\n try {\n archive.on('error', (error: ArchiverError) => {\n throw error\n })\n const dstStream = fs.createWriteStream(dstPath, { highWaterMark: DEFAULT_HIGH_WATER_MARK })\n archive.pipe(dstStream)\n for (const f of dto.files) {\n if (await isPathIsDir(f.path)) {\n archive.directory(f.path, dto.files.length > 1 ? fileName(f.path) : false)\n } else {\n archive.file(f.path, {\n name: f.rootAlias ? f.name : fileName(f.path)\n })\n }\n }\n await archive.finalize()\n } finally {\n if (fileLock) {\n await this.filesLockManager.removeLock(fileLock.key)\n }\n }\n }\n\n async decompress(user: UserModel, space: SpaceEnv): Promise<void> {\n // checks\n if (!(await isPathExists(space.realPath))) {\n throw new FileError(HttpStatus.NOT_FOUND, 'Location not found')\n }\n const extension = path.extname(space.realPath)\n if (!COMPRESSION_EXTENSION.has(extension)) {\n throw new FileError(HttpStatus.BAD_REQUEST, `${extension} is not supported`)\n }\n // make destination folder\n const dstPath = await uniqueFilePathFromDir(path.join(dirName(space.realPath), path.basename(space.realPath, extension)))\n await makeDir(dstPath)\n // create lock\n const dbFile = space.dbFile\n dbFile.path = path.join(dirName(dbFile.path), fileName(dstPath))\n const [ok, fileLock] = await this.filesLockManager.create(user, dbFile, DEPTH.INFINITY)\n if (!ok) {\n throw new LockConflict(fileLock, 'Conflicting lock')\n }\n // tasking\n if (space.task?.cacheKey) FileTaskEvent.emit('startWatch', space, FILE_OPERATION.DECOMPRESS, dstPath)\n // do\n try {\n if (extension === '.zip') {\n await extractZip(space.realPath, dstPath)\n } else {\n await extractTar({\n file: space.realPath,\n cwd: dstPath,\n gzip: COMPRESSION_EXTENSION.get(extension) === tarGzExtension,\n preserveOwner: false\n })\n }\n } finally {\n await this.filesLockManager.removeLock(fileLock.key)\n }\n }\n\n async generateThumbnail(space: SpaceEnv, size: number): Promise<PNGStream> {\n if (!(await isPathExists(space.realPath))) {\n throw new FileError(HttpStatus.NOT_FOUND, 'Location not found')\n }\n if (getMimeType(space.realPath, false).indexOf('image') === -1) {\n throw new FileError(HttpStatus.BAD_REQUEST, 'File is not an image')\n }\n try {\n return generateThumbnail(space.realPath, size)\n } catch (e) {\n this.logger.warn(e)\n throw new FileError(HttpStatus.BAD_REQUEST, 'File is not an image')\n }\n }\n}\n"],"names":["FilesManager","sendFileFromSpace","space","asAttachment","downloadName","SendFile","realPath","saveStream","user","req","options","fExists","isPathExists","fTmpExists","tmpPath","method","HTTP_METHOD","POST","FileError","HttpStatus","METHOD_NOT_ALLOWED","isPathIsDir","makeDir","dirName","CONFLICT","fileLock","dav","filesLockManager","checkConflicts","dbFile","depth","DEPTH","RESOURCE","userId","id","lockTokens","ok","lock","create","LockConflict","startRange","headers","match","exec","length","BAD_REQUEST","parseInt","size","fileSize","checksum","checksumAlg","writeFromStreamAndChecksum","raw","writeFromStream","path","dirname","moveFiles","e","removeFiles","logger","error","name","INTERNAL_SERVER_ERROR","removeLock","key","warn","saveMultipart","realParentPath","basePath","sep","part","files","dstFile","resolve","filename","startsWith","FORBIDDEN","dstDir","join","pipeline","file","fs","createWriteStream","highWaterMark","DEFAULT_HIGH_WATER_MARK","touch","mtime","checkLocks","NOT_FOUND","touchFile","mkFile","overwrite","checkDocument","checkFileName","fileExtension","extname","Object","values","DOCUMENT_TYPE","indexOf","srcSample","__dirname","SAMPLE_PATH_WITHOUT_EXT","copyFiles","createEmptyFile","mkDir","recursive","copyMove","srcSpace","dstSpace","isMove","mkdirDstParentPath","canAccessToSpace","repository","haveSpaceEnvPermissions","SPACE_OPERATION","ADD","alias","url","quotaIsExceeded","INSUFFICIENT_STORAGE","toLowerCase","PRECONDITION_FAILED","isDir","storageQuota","dirSize","willExceedQuota","INFINITY","delete","task","cacheKey","props","totalSize","FileTaskEvent","emit","FILE_OPERATION","MOVE","COPY","filesQueries","forceDeleteInDB","inTrashRepository","baseTrashPath","realTrashPathFromSpace","fileName","trashDir","trashFile","dstTrash","uniqueDatedFilePath","trashFileDB","inTrash","dstTrashFileDB","catch","log","removeChildLocks","getLocksByPath","deleteFiles","downloadFromUrl","rPath","uniqueFilePathFromDir","headRes","http","axiosRef","HEAD","maxRedirects","regExpPrivateIP","test","request","socket","remoteAddress","debug","DOWNLOAD","getRes","GET","responseType","data","compress","dto","srcPath","archiveExt","endsWith","extension","dstPath","compressInDirectory","tasksPath","archive","archiver","gzip","tarGzExtension","gzipOptions","level","COMPRESS","on","dstStream","pipe","f","directory","rootAlias","finalize","decompress","COMPRESSION_EXTENSION","has","basename","DECOMPRESS","extractZip","extractTar","cwd","get","preserveOwner","generateThumbnail","getMimeType","Logger"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../../backend/src/applications/files/services/files-manager.service.ts"],"sourcesContent":["/*\n * Copyright (C) 2012-2025 Johan Legrand <johan.legrand@sync-in.com>\n * This file is part of Sync-in | The open source file sync and share solution\n * See the LICENSE file for licensing details\n */\n\nimport { HttpService } from '@nestjs/axios'\nimport { HttpStatus, Injectable, Logger } from '@nestjs/common'\nimport archiver, { Archiver, ArchiverError } from 'archiver'\nimport { AxiosResponse } from 'axios'\nimport { PNGStream } from 'canvas'\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport { pipeline } from 'node:stream/promises'\nimport { extract as extractTar } from 'tar'\nimport { FastifyAuthenticatedRequest } from '../../../authentication/interfaces/auth-request.interface'\nimport { generateThumbnail } from '../../../common/image'\nimport { HTTP_METHOD } from '../../applications.constants'\nimport { SPACE_OPERATION } from '../../spaces/constants/spaces'\nimport { FastifySpaceRequest } from '../../spaces/interfaces/space-request.interface'\nimport { SpaceEnv } from '../../spaces/models/space-env.model'\nimport { realTrashPathFromSpace } from '../../spaces/utils/paths'\nimport { canAccessToSpace, haveSpaceEnvPermissions } from '../../spaces/utils/permissions'\nimport { UserModel } from '../../users/models/user.model'\nimport { DEPTH, LOCK_DEPTH } from '../../webdav/constants/webdav'\nimport { tarGzExtension } from '../constants/compress'\nimport { COMPRESSION_EXTENSION, DEFAULT_HIGH_WATER_MARK } from '../constants/files'\nimport { FILE_OPERATION } from '../constants/operations'\nimport { DOCUMENT_TYPE, SAMPLE_PATH_WITHOUT_EXT } from '../constants/samples'\nimport { CompressFileDto } from '../dto/file-operations.dto'\nimport { FileTaskEvent } from '../events/file-task-event'\nimport { FileDBProps } from '../interfaces/file-db-props.interface'\nimport { FileLock } from '../interfaces/file-lock.interface'\nimport { FileError } from '../models/file-error'\nimport { LockConflict } from '../models/file-lock-error'\nimport {\n checkFileName,\n copyFiles,\n createEmptyFile,\n dirName,\n dirSize,\n fileName,\n fileSize,\n getMimeType,\n isPathExists,\n isPathIsDir,\n makeDir,\n moveFiles,\n removeFiles,\n touchFile,\n uniqueDatedFilePath,\n uniqueFilePathFromDir,\n writeFromStream,\n writeFromStreamAndChecksum\n} from '../utils/files'\nimport { SendFile } from '../utils/send-file'\nimport { extractZip } from '../utils/unzip-file'\nimport { regExpPrivateIP } from '../utils/url-file'\nimport { FilesLockManager } from './files-lock-manager.service'\nimport { FilesQueries } from './files-queries.service'\n\n@Injectable()\nexport class FilesManager {\n /* Spaces permissions are checked in the space guard, except for the copy/move destination */\n private logger = new Logger(FilesManager.name)\n\n constructor(\n private readonly http: HttpService,\n private readonly filesQueries: FilesQueries,\n private readonly filesLockManager: FilesLockManager\n ) {}\n\n sendFileFromSpace(space: SpaceEnv, asAttachment = false, downloadName = ''): SendFile {\n return new SendFile(space.realPath, asAttachment, downloadName)\n }\n\n async saveStream(\n user: UserModel,\n space: SpaceEnv,\n req: FastifyAuthenticatedRequest,\n options: {\n checksumAlg: string\n tmpPath?: string\n }\n ): Promise<string>\n async saveStream(user: UserModel, space: SpaceEnv, req: FastifyAuthenticatedRequest, options?: any): Promise<boolean>\n async saveStream(\n user: UserModel,\n space: SpaceEnv,\n req: FastifyAuthenticatedRequest,\n options?: { dav?: { depth: LOCK_DEPTH; lockTokens: string[] }; checksumAlg?: string; tmpPath?: string }\n ): Promise<boolean | string> {\n // if tmpPath is used, we lock the final destination during the transfer\n // space.realPath is replaced by tmpPath (if allowed), if the move operation failed we remove the tmp file\n const fExists = await isPathExists(space.realPath)\n const fTmpExists = options?.tmpPath ? await isPathExists(options.tmpPath) : false\n if (fExists && req.method === HTTP_METHOD.POST) {\n throw new FileError(HttpStatus.METHOD_NOT_ALLOWED, 'Resource already exists')\n }\n if (fExists && (await isPathIsDir(space.realPath))) {\n throw new FileError(HttpStatus.METHOD_NOT_ALLOWED, 'The location is a directory')\n }\n if (options?.tmpPath) {\n // ensure tmpPath parent dir exists\n await makeDir(dirName(options.tmpPath), true)\n } else if (!(await isPathExists(dirName(space.realPath)))) {\n throw new FileError(HttpStatus.CONFLICT, 'Parent must exists')\n }\n /* File Lock */\n let fileLock: FileLock | undefined\n if (options?.dav) {\n // check locks\n await this.filesLockManager.checkConflicts(space.dbFile, options?.dav?.depth || DEPTH.RESOURCE, {\n userId: user.id,\n lockTokens: options.dav?.lockTokens\n })\n } else {\n // create lock if there is no webdav context\n const [ok, lock] = await this.filesLockManager.create(user, space.dbFile, DEPTH.RESOURCE)\n if (!ok) {\n throw new LockConflict(lock, 'Conflicting lock')\n }\n fileLock = lock\n }\n try {\n // check range\n let startRange = 0\n if ((fExists || fTmpExists) && req.headers['content-range']) {\n // with PUT method, some webdav clients use the `content-range` header,\n // which is normally reserved for a response to a request containing the `range` header.\n // However, for more compatibility let's accept it\n const match = /\\d+/.exec(req.headers['content-range'])\n if (!match.length) {\n throw new FileError(HttpStatus.BAD_REQUEST, 'Content-range : header is malformed')\n }\n startRange = parseInt(match[0], 10)\n const size = await fileSize(options?.tmpPath || space.realPath)\n if (startRange !== size) {\n throw new FileError(HttpStatus.BAD_REQUEST, 'Content-range : start offset does not match the current file size')\n }\n }\n // todo: check file in db to update\n // todo : versioning here\n let checksum: string\n if (options?.checksumAlg) {\n checksum = await writeFromStreamAndChecksum(options?.tmpPath || space.realPath, req.raw, startRange, options.checksumAlg)\n } else {\n await writeFromStream(options?.tmpPath || space.realPath, req.raw, startRange)\n }\n if (options?.tmpPath) {\n try {\n // ensure parent path exists\n await makeDir(path.dirname(space.realPath), true)\n // move the uploaded file to destination\n await moveFiles(options.tmpPath, space.realPath, true)\n } catch (e) {\n // cleanup tmp file\n await removeFiles(options.tmpPath)\n this.logger.error(`${this.saveStream.name} - unable to move ${options.tmpPath} -> ${space.realPath} : ${e}`)\n throw new FileError(HttpStatus.INTERNAL_SERVER_ERROR, 'Unable to move tmp file to dst file')\n }\n }\n if (options?.checksumAlg) {\n return checksum\n }\n return fExists\n } finally {\n if (fileLock) {\n try {\n await this.filesLockManager.removeLock(fileLock.key)\n } catch (e) {\n this.logger.warn(`Failed to remove lock ${fileLock.key}: ${e}`)\n }\n }\n }\n }\n\n async saveMultipart(user: UserModel, space: SpaceEnv, req: FastifySpaceRequest) {\n /* Accepted methods:\n POST: create new resource\n PUT: create or update new resource (even if parent path does not exist)\n */\n const realParentPath = dirName(space.realPath)\n\n if (req.method === HTTP_METHOD.POST) {\n if (await isPathExists(space.realPath)) {\n throw new FileError(HttpStatus.BAD_REQUEST, 'Resource already exists')\n }\n if (!(await isPathExists(realParentPath))) {\n throw new FileError(HttpStatus.BAD_REQUEST, 'Parent must exists')\n }\n if (!(await isPathIsDir(realParentPath))) {\n throw new FileError(HttpStatus.BAD_REQUEST, 'Parent must be a directory')\n }\n }\n\n const basePath = realParentPath + path.sep\n\n for await (const part of req.files()) {\n // part.filename may contain a path like foo/bar.txt.\n const dstFile = path.resolve(basePath, part.filename)\n // prevent path traversal\n if (!dstFile.startsWith(basePath)) {\n throw new FileError(HttpStatus.FORBIDDEN, 'Location is not allowed')\n }\n // make dir in space\n const dstDir = dirName(dstFile)\n if (!(await isPathExists(dstDir))) {\n await makeDir(dstDir, true)\n }\n // create lock\n const dbFile = { ...space.dbFile, path: path.join(dirName(space.dbFile.path), part.filename) }\n const [ok, fileLock] = await this.filesLockManager.create(user, dbFile, DEPTH.RESOURCE)\n if (!ok) throw new LockConflict(fileLock, 'Conflicting lock')\n // do\n try {\n await pipeline(part.file, fs.createWriteStream(dstFile, { highWaterMark: DEFAULT_HIGH_WATER_MARK }))\n } finally {\n await this.filesLockManager.removeLock(fileLock.key)\n }\n }\n }\n\n async touch(user: UserModel, space: SpaceEnv, mtime: number, checkLocks = true): Promise<void> {\n if (!(await isPathExists(space.realPath))) {\n throw new FileError(HttpStatus.NOT_FOUND, 'Location not found')\n }\n if (checkLocks) {\n await this.filesLockManager.checkConflicts(space.dbFile, DEPTH.RESOURCE, { userId: user.id })\n }\n // todo: update mtime in last files ( & in db file ?)\n await touchFile(space.realPath, mtime)\n }\n\n async mkFile(user: UserModel, space: SpaceEnv, overwrite = false, checkLocks = true, checkDocument = false): Promise<void> {\n checkFileName(space.realPath)\n if (!overwrite && (await isPathExists(space.realPath))) {\n throw new FileError(HttpStatus.BAD_REQUEST, 'Resource already exists')\n }\n if (checkLocks) {\n await this.filesLockManager.checkConflicts(space.dbFile, DEPTH.RESOURCE, { userId: user.id })\n }\n // use sample documents when possible\n const fileExtension = path.extname(space.realPath)\n if (checkDocument && fileExtension !== '.txt' && Object.values(DOCUMENT_TYPE).indexOf(fileExtension) > -1) {\n const srcSample = path.join(__dirname, `${SAMPLE_PATH_WITHOUT_EXT}${fileExtension}`)\n return copyFiles(srcSample, space.realPath, false, false, false)\n } else {\n return createEmptyFile(space.realPath)\n }\n }\n\n async mkDir(user: UserModel, space: SpaceEnv, recursive = false, dav?: { depth: LOCK_DEPTH; lockTokens: string[] }): Promise<void> {\n checkFileName(space.realPath)\n if (!recursive) {\n if (await isPathExists(space.realPath)) {\n throw new FileError(HttpStatus.METHOD_NOT_ALLOWED, 'Resource already exists')\n } else if (!(await isPathExists(dirName(space.realPath)))) {\n throw new FileError(HttpStatus.CONFLICT, 'Parent must exists')\n }\n }\n await this.filesLockManager.checkConflicts(space.dbFile, dav?.depth || DEPTH.RESOURCE, { userId: user.id, lockTokens: dav?.lockTokens })\n await makeDir(space.realPath, recursive)\n }\n\n async copyMove(\n user: UserModel,\n srcSpace: SpaceEnv,\n dstSpace: SpaceEnv,\n isMove: boolean,\n overwrite = false,\n mkdirDstParentPath = false,\n dav?: { depth: LOCK_DEPTH; lockTokens: string[] }\n ): Promise<void> {\n // checks\n if (!canAccessToSpace(user, dstSpace)) {\n this.logger.warn(`${this.copyMove.name} - is not allowed to access to this space repository : ${dstSpace.repository}`)\n throw new FileError(HttpStatus.FORBIDDEN, 'You are not allowed to access to this repository')\n }\n if (!haveSpaceEnvPermissions(dstSpace, SPACE_OPERATION.ADD)) {\n this.logger.warn(`${this.copyMove.name} - is not allowed to copy/move on this space : *${dstSpace.alias}* (${dstSpace.id}) : ${dstSpace.url}`)\n throw new FileError(HttpStatus.FORBIDDEN, 'You are not allowed to copy/move on the destination')\n }\n if (dstSpace.quotaIsExceeded) {\n this.logger.warn(`${this.copyMove.name} - quota is exceeded for *${dstSpace.alias}* (${dstSpace.id})`)\n throw new FileError(HttpStatus.INSUFFICIENT_STORAGE, 'Quota is exceeded')\n }\n if (!(await isPathExists(srcSpace.realPath))) {\n throw new FileError(HttpStatus.NOT_FOUND, 'Location not found')\n }\n if (!(await isPathExists(dirName(dstSpace.realPath)))) {\n if (mkdirDstParentPath) {\n try {\n await makeDir(dirName(dstSpace.realPath), true)\n } catch (e) {\n this.logger.error(`${this.copyMove.name} - Cannot create parent directory for destination ${dstSpace.realPath} : ${e}`)\n throw new FileError(HttpStatus.INTERNAL_SERVER_ERROR, 'Cannot create parent directory for destination')\n }\n } else {\n throw new FileError(HttpStatus.CONFLICT, 'Parent must exists')\n }\n }\n if (srcSpace.realPath === dstSpace.realPath) {\n throw new FileError(HttpStatus.FORBIDDEN, 'Cannot copy/move source onto itself')\n }\n if (`${dstSpace.realPath}/`.startsWith(`${srcSpace.realPath}/`)) {\n throw new FileError(HttpStatus.FORBIDDEN, 'Cannot copy/move source below itself')\n }\n if (dirName(srcSpace.url) === dirName(dstSpace.url) && dirName(srcSpace.realPath) !== dirName(dstSpace.realPath)) {\n /* Handle renaming a space file with the same name as a space root :\n srcSpace.url = '/space/sync-in/code2.ts' (a space file)\n srcSpace.realPath = '/home/sync-in/spaces/sync-in/code2.ts\n dstSpace.url = '/space/sync-in/code.ts' (a space root)\n dstSpace.realPath = '/home/sync-in/users/jo/files/code2.ts !!\n */\n throw new FileError(HttpStatus.BAD_REQUEST, 'An anchored file already has this name')\n }\n if (!overwrite && (await isPathExists(dstSpace.realPath))) {\n /* Handle case-sensitive (in renaming context):\n srcSpace.url = '/space/sync-in/code.ts'\n dstSpace.url = '/space/sync-in/code.TS'\n The destination exists because it's the same file, bypass this\n */\n if (!(isMove && srcSpace.realPath.toLowerCase() === dstSpace.realPath.toLowerCase())) {\n throw new FileError(dav ? HttpStatus.PRECONDITION_FAILED : HttpStatus.BAD_REQUEST, 'The destination already exists')\n }\n }\n\n const isDir = await isPathIsDir(srcSpace.realPath)\n\n if (dstSpace.storageQuota) {\n /* Skip validation when moving to the same space; for copy operations, run all checks. */\n if (!isMove || (isMove && srcSpace.id !== dstSpace.id)) {\n const size = isDir ? (await dirSize(srcSpace.realPath))[0] : await fileSize(srcSpace.realPath)\n if (dstSpace.willExceedQuota(size)) {\n this.logger.warn(`${this.copyMove.name} - quota will be exceeded for *${dstSpace.alias}* (${dstSpace.id})`)\n throw new FileError(HttpStatus.INSUFFICIENT_STORAGE, 'Quota will be exceeded')\n }\n }\n }\n\n // check lock conflicts on source & destination\n let recursive: boolean\n let depth: LOCK_DEPTH\n if (dav?.depth) {\n recursive = dav.depth === DEPTH.INFINITY\n depth = dav.depth\n } else {\n recursive = isDir\n depth = recursive ? DEPTH.INFINITY : DEPTH.RESOURCE\n }\n if (isMove) {\n // check source\n await this.filesLockManager.checkConflicts(srcSpace.dbFile, depth, { userId: user.id, lockTokens: dav?.lockTokens })\n }\n // check destination\n await this.filesLockManager.checkConflicts(dstSpace.dbFile, depth, { userId: user.id, lockTokens: dav?.lockTokens })\n\n // overwrite\n if (overwrite && (await isPathExists(dstSpace.realPath))) {\n // todo : versioning here\n await this.delete(user, dstSpace)\n }\n\n // send to task watcher\n if (srcSpace.task?.cacheKey) {\n if (!isDir) srcSpace.task.props.totalSize = await fileSize(srcSpace.realPath)\n FileTaskEvent.emit('startWatch', srcSpace, isMove ? FILE_OPERATION.MOVE : FILE_OPERATION.COPY, dstSpace.realPath)\n }\n\n // do\n if (isMove) {\n await moveFiles(srcSpace.realPath, dstSpace.realPath, overwrite)\n return this.filesQueries.moveFiles(srcSpace.dbFile, dstSpace.dbFile, isDir)\n }\n return copyFiles(srcSpace.realPath, dstSpace.realPath, overwrite, recursive)\n }\n\n async delete(user: UserModel, space: SpaceEnv, dav?: { lockTokens: string[] }): Promise<void> {\n if (!(await isPathExists(space.realPath))) {\n throw new FileError(HttpStatus.NOT_FOUND, 'Location not found')\n }\n // check lock conflicts\n const isDir = await isPathIsDir(space.realPath)\n await this.filesLockManager.checkConflicts(space.dbFile, isDir ? DEPTH.INFINITY : DEPTH.RESOURCE, {\n userId: user.id,\n lockTokens: dav?.lockTokens\n })\n // file system deletion\n let forceDeleteInDB = false\n if (space.inTrashRepository) {\n await removeFiles(space.realPath)\n } else {\n const baseTrashPath = realTrashPathFromSpace(user, space)\n if (baseTrashPath) {\n const name = fileName(space.realPath)\n const trashDir = path.join(baseTrashPath, dirName(space.dbFile.path))\n const trashFile = path.join(trashDir, name)\n if (!(await isPathExists(trashDir))) {\n await makeDir(trashDir, true)\n }\n if (await isPathExists(trashFile)) {\n // if a resource already exists in the trash, rename it with the date\n const dstTrash = await uniqueDatedFilePath(trashFile)\n // move the resource on fs\n await moveFiles(trashFile, dstTrash.path)\n // move the resource in db\n const trashFileDB: FileDBProps = { ...space.dbFile, inTrash: true }\n const dstTrashFileDB: FileDBProps = { ...trashFileDB, path: path.join(dirName(trashFileDB.path), fileName(dstTrash.path)) }\n this.filesQueries\n .moveFiles(trashFileDB, dstTrashFileDB, dstTrash.isDir)\n .catch((e: Error) => this.logger.error(`${this.delete.name} - ${e}`))\n }\n await moveFiles(space.realPath, trashFile, true)\n } else {\n this.logger.log(`Unable to find trash path for space - *${space.alias}* (${space.id}) : delete permanently : ${space.realPath}`)\n // todo: define a default trash for external paths\n forceDeleteInDB = true\n await removeFiles(space.realPath)\n }\n }\n // remove locks, these locks have already been checked in the `checkConflicts` function\n if (isDir) {\n this.filesLockManager.removeChildLocks(user, space.dbFile).catch((e: Error) => this.logger.error(`${this.delete.name} - ${e}`))\n }\n for (const lock of await this.filesLockManager.getLocksByPath(space.dbFile)) {\n this.filesLockManager.removeLock(lock.key).catch((e: Error) => this.logger.error(`${this.delete.name} - ${e}`))\n }\n // delete or move to trash the files in db\n return this.filesQueries.deleteFiles(space.dbFile, isDir, forceDeleteInDB)\n }\n\n async downloadFromUrl(user: UserModel, space: SpaceEnv, url: string): Promise<void> {\n this.logger.log(`${this.downloadFromUrl.name} : ${url}`)\n // create lock\n const rPath = await uniqueFilePathFromDir(space.realPath)\n const dbFile = space.dbFile\n dbFile.path = path.join(dirName(dbFile.path), fileName(space.realPath))\n const [ok, fileLock] = await this.filesLockManager.create(user, dbFile, DEPTH.RESOURCE)\n if (!ok) {\n throw new LockConflict(fileLock, 'Conflicting lock')\n }\n // tasking\n if (space.task.cacheKey) {\n let headRes: AxiosResponse\n\n try {\n headRes = await this.http.axiosRef({ method: HTTP_METHOD.HEAD, url: url, maxRedirects: 1 })\n } catch (e) {\n // release lock\n await this.filesLockManager.removeLock(fileLock.key)\n this.logger.error(`${this.downloadFromUrl.name} - ${url} : ${e}`)\n throw new FileError(HttpStatus.BAD_REQUEST, 'Unable to download file')\n }\n\n if (regExpPrivateIP.test(headRes.request.socket.remoteAddress)) {\n // release lock\n await this.filesLockManager.removeLock(fileLock.key)\n // prevent SSRF attack\n throw new FileError(HttpStatus.FORBIDDEN, 'Access to internal IP addresses is forbidden')\n }\n\n // attempt to retrieve the Content-Length header\n try {\n if ('content-length' in headRes.headers) {\n space.task.props.totalSize = parseInt(headRes.headers['content-length'], 10) || null\n }\n } catch (e) {\n this.logger.debug(`${this.downloadFromUrl.name} - content-length : ${e}`)\n }\n FileTaskEvent.emit('startWatch', space, FILE_OPERATION.DOWNLOAD, rPath)\n }\n // do\n try {\n const getRes = await this.http.axiosRef({ method: HTTP_METHOD.GET, url: url, responseType: 'stream', maxRedirects: 1 })\n if (regExpPrivateIP.test(getRes.request.socket.remoteAddress)) {\n // Prevent SSRF attacks and perform a DNS-rebinding check if a HEAD request has already been made\n throw new FileError(HttpStatus.FORBIDDEN, 'Access to internal IP addresses is forbidden')\n }\n await writeFromStream(rPath, getRes.data)\n } finally {\n // release lock\n await this.filesLockManager.removeLock(fileLock.key)\n }\n }\n\n async compress(user: UserModel, space: SpaceEnv, dto: CompressFileDto): Promise<void> {\n // This method is currently used only by files-methods.service, which handles input sanitization.\n // If it is used in other services in the future, make sure to refactor accordingly to sanitize inputs properly.\n const srcPath = dirName(space.realPath)\n // todo: a guest link tasksPath should be in specific directory (guest link has no home)\n const archiveExt = dto.name.endsWith(dto.extension) ? '' : `.${dto.extension}`\n const dstPath = await uniqueFilePathFromDir(path.join(dto.compressInDirectory ? srcPath : user.tasksPath, `${dto.name}${archiveExt}`))\n const archive: Archiver = archiver('tar', {\n gzip: dto.extension === tarGzExtension,\n gzipOptions: {\n level: 9\n }\n })\n // create lock\n let fileLock: FileLock\n if (dto.compressInDirectory) {\n const dbFile = space.dbFile\n dbFile.path = path.join(dirName(dbFile.path), fileName(dstPath))\n const [ok, lock] = await this.filesLockManager.create(user, dbFile, DEPTH.RESOURCE)\n if (!ok) {\n throw new LockConflict(lock, 'Conflicting lock')\n }\n fileLock = lock\n }\n if (space.task?.cacheKey) {\n space.task.props.compressInDirectory = dto.compressInDirectory\n FileTaskEvent.emit('startWatch', space, FILE_OPERATION.COMPRESS, dstPath)\n }\n // do\n try {\n archive.on('error', (error: ArchiverError) => {\n throw error\n })\n const dstStream = fs.createWriteStream(dstPath, { highWaterMark: DEFAULT_HIGH_WATER_MARK })\n archive.pipe(dstStream)\n for (const f of dto.files) {\n if (await isPathIsDir(f.path)) {\n archive.directory(f.path, dto.files.length > 1 ? fileName(f.path) : false)\n } else {\n archive.file(f.path, {\n name: f.rootAlias ? f.name : fileName(f.path)\n })\n }\n }\n await archive.finalize()\n } finally {\n if (fileLock) {\n await this.filesLockManager.removeLock(fileLock.key)\n }\n }\n }\n\n async decompress(user: UserModel, space: SpaceEnv): Promise<void> {\n // checks\n if (!(await isPathExists(space.realPath))) {\n throw new FileError(HttpStatus.NOT_FOUND, 'Location not found')\n }\n const extension = path.extname(space.realPath)\n if (!COMPRESSION_EXTENSION.has(extension)) {\n throw new FileError(HttpStatus.BAD_REQUEST, `${extension} is not supported`)\n }\n // make destination folder\n const dstPath = await uniqueFilePathFromDir(path.join(dirName(space.realPath), path.basename(space.realPath, extension)))\n await makeDir(dstPath)\n // create lock\n const dbFile = space.dbFile\n dbFile.path = path.join(dirName(dbFile.path), fileName(dstPath))\n const [ok, fileLock] = await this.filesLockManager.create(user, dbFile, DEPTH.INFINITY)\n if (!ok) {\n throw new LockConflict(fileLock, 'Conflicting lock')\n }\n // tasking\n if (space.task?.cacheKey) FileTaskEvent.emit('startWatch', space, FILE_OPERATION.DECOMPRESS, dstPath)\n // do\n try {\n if (extension === '.zip') {\n await extractZip(space.realPath, dstPath)\n } else {\n await extractTar({\n file: space.realPath,\n cwd: dstPath,\n gzip: COMPRESSION_EXTENSION.get(extension) === tarGzExtension,\n preserveOwner: false\n })\n }\n } finally {\n await this.filesLockManager.removeLock(fileLock.key)\n }\n }\n\n async generateThumbnail(space: SpaceEnv, size: number): Promise<PNGStream> {\n if (!(await isPathExists(space.realPath))) {\n throw new FileError(HttpStatus.NOT_FOUND, 'Location not found')\n }\n if (getMimeType(space.realPath, false).indexOf('image') === -1) {\n throw new FileError(HttpStatus.BAD_REQUEST, 'File is not an image')\n }\n try {\n return generateThumbnail(space.realPath, size)\n } catch (e) {\n this.logger.warn(e)\n throw new FileError(HttpStatus.BAD_REQUEST, 'File is not an image')\n }\n }\n}\n"],"names":["FilesManager","sendFileFromSpace","space","asAttachment","downloadName","SendFile","realPath","saveStream","user","req","options","fExists","isPathExists","fTmpExists","tmpPath","method","HTTP_METHOD","POST","FileError","HttpStatus","METHOD_NOT_ALLOWED","isPathIsDir","makeDir","dirName","CONFLICT","fileLock","dav","filesLockManager","checkConflicts","dbFile","depth","DEPTH","RESOURCE","userId","id","lockTokens","ok","lock","create","LockConflict","startRange","headers","match","exec","length","BAD_REQUEST","parseInt","size","fileSize","checksum","checksumAlg","writeFromStreamAndChecksum","raw","writeFromStream","path","dirname","moveFiles","e","removeFiles","logger","error","name","INTERNAL_SERVER_ERROR","removeLock","key","warn","saveMultipart","realParentPath","basePath","sep","part","files","dstFile","resolve","filename","startsWith","FORBIDDEN","dstDir","join","pipeline","file","fs","createWriteStream","highWaterMark","DEFAULT_HIGH_WATER_MARK","touch","mtime","checkLocks","NOT_FOUND","touchFile","mkFile","overwrite","checkDocument","checkFileName","fileExtension","extname","Object","values","DOCUMENT_TYPE","indexOf","srcSample","__dirname","SAMPLE_PATH_WITHOUT_EXT","copyFiles","createEmptyFile","mkDir","recursive","copyMove","srcSpace","dstSpace","isMove","mkdirDstParentPath","canAccessToSpace","repository","haveSpaceEnvPermissions","SPACE_OPERATION","ADD","alias","url","quotaIsExceeded","INSUFFICIENT_STORAGE","toLowerCase","PRECONDITION_FAILED","isDir","storageQuota","dirSize","willExceedQuota","INFINITY","delete","task","cacheKey","props","totalSize","FileTaskEvent","emit","FILE_OPERATION","MOVE","COPY","filesQueries","forceDeleteInDB","inTrashRepository","baseTrashPath","realTrashPathFromSpace","fileName","trashDir","trashFile","dstTrash","uniqueDatedFilePath","trashFileDB","inTrash","dstTrashFileDB","catch","log","removeChildLocks","getLocksByPath","deleteFiles","downloadFromUrl","rPath","uniqueFilePathFromDir","headRes","http","axiosRef","HEAD","maxRedirects","regExpPrivateIP","test","request","socket","remoteAddress","debug","DOWNLOAD","getRes","GET","responseType","data","compress","dto","srcPath","archiveExt","endsWith","extension","dstPath","compressInDirectory","tasksPath","archive","archiver","gzip","tarGzExtension","gzipOptions","level","COMPRESS","on","dstStream","pipe","f","directory","rootAlias","finalize","decompress","COMPRESSION_EXTENSION","has","basename","DECOMPRESS","extractZip","extractTar","cwd","get","preserveOwner","generateThumbnail","getMimeType","Logger"],"mappings":"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"}
|
|
@@ -27,7 +27,7 @@ const _contextmanagerservice = require("../../../infrastructure/context/services
|
|
|
27
27
|
const _applicationsconstants = require("../../applications.constants");
|
|
28
28
|
const _spaces = require("../../spaces/constants/spaces");
|
|
29
29
|
const _permissions = require("../../spaces/utils/permissions");
|
|
30
|
-
const
|
|
30
|
+
const _avatar = require("../../users/utils/avatar");
|
|
31
31
|
const _webdav = require("../../webdav/constants/webdav");
|
|
32
32
|
const _cache = require("../constants/cache");
|
|
33
33
|
const _onlyoffice = require("../constants/only-office");
|
|
@@ -172,7 +172,7 @@ let FilesOnlyOfficeManager = class FilesOnlyOfficeManager {
|
|
|
172
172
|
user: {
|
|
173
173
|
id: user.id.toString(),
|
|
174
174
|
name: `${user.fullName} (${user.email})`,
|
|
175
|
-
image: await
|
|
175
|
+
image: await (0, _avatar.getAvatarBase64)(user.login)
|
|
176
176
|
},
|
|
177
177
|
coEditing: {
|
|
178
178
|
mode: 'fast',
|
|
@@ -221,6 +221,7 @@ let FilesOnlyOfficeManager = class FilesOnlyOfficeManager {
|
|
|
221
221
|
login: user.login,
|
|
222
222
|
email: user.email,
|
|
223
223
|
fullName: user.fullName,
|
|
224
|
+
language: user.language,
|
|
224
225
|
role: user.role,
|
|
225
226
|
applications: user.applications
|
|
226
227
|
}
|
|
@@ -271,7 +272,7 @@ let FilesOnlyOfficeManager = class FilesOnlyOfficeManager {
|
|
|
271
272
|
if (existingDocKey) {
|
|
272
273
|
return existingDocKey;
|
|
273
274
|
}
|
|
274
|
-
const docKey = (0, _functions.generateShortUUID)(
|
|
275
|
+
const docKey = (0, _functions.generateShortUUID)(64);
|
|
275
276
|
await this.cache.set(cacheKey, docKey, this.expiration);
|
|
276
277
|
this.logger.debug(`${this.getDocumentKey.name} - ${cacheKey} (${docKey}) created`);
|
|
277
278
|
return docKey;
|
|
@@ -367,12 +368,11 @@ let FilesOnlyOfficeManager = class FilesOnlyOfficeManager {
|
|
|
367
368
|
getCacheKey(fileId) {
|
|
368
369
|
return `${_cache.CACHE_ONLY_OFFICE}|${fileId}`;
|
|
369
370
|
}
|
|
370
|
-
constructor(http, contextManager, cache, jwt,
|
|
371
|
+
constructor(http, contextManager, cache, jwt, filesLockManager, filesQueries){
|
|
371
372
|
this.http = http;
|
|
372
373
|
this.contextManager = contextManager;
|
|
373
374
|
this.cache = cache;
|
|
374
375
|
this.jwt = jwt;
|
|
375
|
-
this.usersManager = usersManager;
|
|
376
376
|
this.filesLockManager = filesLockManager;
|
|
377
377
|
this.filesQueries = filesQueries;
|
|
378
378
|
this.logger = new _common.Logger(FilesOnlyOfficeManager.name);
|
|
@@ -391,7 +391,6 @@ FilesOnlyOfficeManager = _ts_decorate([
|
|
|
391
391
|
typeof _contextmanagerservice.ContextManager === "undefined" ? Object : _contextmanagerservice.ContextManager,
|
|
392
392
|
typeof _cacheservice.Cache === "undefined" ? Object : _cacheservice.Cache,
|
|
393
393
|
typeof _jwt.JwtService === "undefined" ? Object : _jwt.JwtService,
|
|
394
|
-
typeof _usersmanagerservice.UsersManager === "undefined" ? Object : _usersmanagerservice.UsersManager,
|
|
395
394
|
typeof _fileslockmanagerservice.FilesLockManager === "undefined" ? Object : _fileslockmanagerservice.FilesLockManager,
|
|
396
395
|
typeof _filesqueriesservice.FilesQueries === "undefined" ? Object : _filesqueriesservice.FilesQueries
|
|
397
396
|
])
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../backend/src/applications/files/services/files-only-office-manager.service.ts"],"sourcesContent":["/*\n * Copyright (C) 2012-2025 Johan Legrand <johan.legrand@sync-in.com>\n * This file is part of Sync-in | The open source file sync and share solution\n * See the LICENSE file for licensing details\n */\n\nimport { HttpService } from '@nestjs/axios'\nimport { HttpException, HttpStatus, Injectable, Logger } from '@nestjs/common'\nimport { JwtService } from '@nestjs/jwt'\nimport { AxiosResponse } from 'axios'\nimport https from 'https'\nimport crypto from 'node:crypto'\nimport os from 'node:os'\nimport path from 'node:path'\nimport { SERVER_NAME } from '../../../app.constants'\nimport { JwtIdentityPayload } from '../../../authentication/interfaces/jwt-payload.interface'\nimport { convertHumanTimeToSeconds, generateShortUUID } from '../../../common/functions'\nimport { configuration } from '../../../configuration/config.environment'\nimport { Cache } from '../../../infrastructure/cache/services/cache.service'\nimport { ContextManager } from '../../../infrastructure/context/services/context-manager.service'\nimport { HTTP_METHOD } from '../../applications.constants'\nimport { SPACE_OPERATION } from '../../spaces/constants/spaces'\nimport { FastifySpaceRequest } from '../../spaces/interfaces/space-request.interface'\nimport type { SpaceEnv } from '../../spaces/models/space-env.model'\nimport { haveSpaceEnvPermissions } from '../../spaces/utils/permissions'\nimport type { UserModel } from '../../users/models/user.model'\nimport { UsersManager } from '../../users/services/users-manager.service'\nimport { DEPTH, LOCK_SCOPE } from '../../webdav/constants/webdav'\nimport { CACHE_ONLY_OFFICE } from '../constants/cache'\nimport {\n ONLY_OFFICE_CONVERT_ERROR,\n ONLY_OFFICE_CONVERT_EXTENSIONS,\n ONLY_OFFICE_EXTENSIONS,\n ONLY_OFFICE_INTERNAL_URI,\n ONLY_OFFICE_TOKEN_QUERY_PARAM_NAME\n} from '../constants/only-office'\nimport { API_FILES_ONLY_OFFICE_CALLBACK, API_FILES_ONLY_OFFICE_DOCUMENT } from '../constants/routes'\nimport type { FileProps } from '../interfaces/file-props.interface'\nimport { OnlyOfficeCallBack, OnlyOfficeConfig, OnlyOfficeConvertForm, OnlyOfficeReqConfig } from '../interfaces/only-office-config.interface'\nimport { copyFileContent, fileSize, getProps, isPathExists, isPathIsDir, removeFiles, uniqueFilePathFromDir, writeFromStream } from '../utils/files'\nimport { FilesLockManager } from './files-lock-manager.service'\nimport { FilesQueries } from './files-queries.service'\n\n@Injectable()\nexport class FilesOnlyOfficeManager {\n private logger = new Logger(FilesOnlyOfficeManager.name)\n private readonly externalOnlyOfficeServer = configuration.applications.files.onlyoffice.externalServer || null\n private readonly rejectUnauthorized: boolean = !configuration.applications.files.onlyoffice?.verifySSL\n private readonly convertUrl = this.externalOnlyOfficeServer ? `${this.externalOnlyOfficeServer}/ConvertService.ashx` : null\n private readonly expiration = convertHumanTimeToSeconds(configuration.auth.token.refresh.expiration)\n private readonly mobileRegex: RegExp = /android|webos|iphone|ipad|ipod|blackberry|windows phone|opera mini|iemobile|mobile/i\n\n constructor(\n private readonly http: HttpService,\n private readonly contextManager: ContextManager,\n private readonly cache: Cache,\n private readonly jwt: JwtService,\n private readonly usersManager: UsersManager,\n private readonly filesLockManager: FilesLockManager,\n private readonly filesQueries: FilesQueries\n ) {}\n\n getStatus(): { enabled: boolean } {\n return { enabled: configuration.applications.files.onlyoffice.enabled }\n }\n\n async getSettings(user: UserModel, space: SpaceEnv, mode: 'edit' | 'view', req: FastifySpaceRequest): Promise<OnlyOfficeReqConfig> {\n if (!(await isPathExists(space.realPath))) {\n throw new HttpException('Document not found', HttpStatus.NOT_FOUND)\n }\n if (await isPathIsDir(space.realPath)) {\n throw new HttpException('Document must be a file', HttpStatus.BAD_REQUEST)\n }\n const fileExtension = path.extname(space.realPath).slice(1)\n if (!ONLY_OFFICE_EXTENSIONS.VIEWABLE.has(fileExtension) && !ONLY_OFFICE_EXTENSIONS.EDITABLE.has(fileExtension)) {\n throw new HttpException('Document not supported', HttpStatus.BAD_REQUEST)\n }\n if (mode === 'edit' && (!ONLY_OFFICE_EXTENSIONS.EDITABLE.has(fileExtension) || !haveSpaceEnvPermissions(space, SPACE_OPERATION.MODIFY))) {\n mode = 'view'\n }\n if (mode === 'edit') {\n // check lock conflicts\n try {\n await this.filesLockManager.checkConflicts(space.dbFile, DEPTH.RESOURCE, { userId: user.id, lockScope: LOCK_SCOPE.SHARED })\n } catch {\n throw new HttpException('The file is locked', HttpStatus.LOCKED)\n }\n }\n const isMobile: boolean = this.mobileRegex.test(req.headers['user-agent'])\n const fileProps: FileProps = await getProps(space.realPath, space.dbFile.path)\n const fileId: string = ((await this.filesQueries.getSpaceFileId(fileProps, space.dbFile)) || fileProps.id).toString()\n const userToken: string = await this.genUserToken(user)\n const fileUrl = this.getDocumentUrl(space, userToken)\n const callBackUrl = this.getCallBackUrl(space, userToken, fileId)\n const config: OnlyOfficeReqConfig = await this.genConfiguration(user, space, mode, fileId, fileUrl, fileExtension, callBackUrl, isMobile)\n config.config.token = await this.genPayloadToken(config.config)\n return config\n }\n\n async callBack(user: UserModel, space: SpaceEnv, token: string, fileId: string) {\n const callBackData: OnlyOfficeCallBack = await this.jwt.verifyAsync(token, { secret: configuration.applications.files.onlyoffice.secret })\n try {\n switch (callBackData.status) {\n case 1:\n await this.checkFileLock(user, space, callBackData)\n this.logger.debug(`document is being edited : ${space.url}`)\n break\n case 2:\n await this.checkFileLock(user, space, callBackData)\n if (callBackData.notmodified) {\n this.logger.debug(`document was edited but closed with no changes : ${space.url}`)\n } else {\n this.logger.debug(`document was edited but not saved (let's do it) : ${space.url}`)\n await this.saveDocument(space, callBackData.url)\n }\n await this.removeDocumentKey(fileId, space)\n break\n case 3:\n this.logger.error(`document cannot be saved, an error has occurred (try to save it) : ${space.url}`)\n await this.saveDocument(space, callBackData.url)\n break\n case 4:\n await this.removeFileLock(user.id, space)\n await this.removeDocumentKey(fileId, space)\n this.logger.debug(`document was closed with no changes : ${space.url}`)\n break\n case 6:\n this.logger.debug(`document is edited but save was requested : ${space.url}`)\n await this.saveDocument(space, callBackData.url)\n break\n case 7:\n this.logger.error(`document cannot be force saved, an error has occurred (try to save it) : ${space.url}`)\n await this.saveDocument(space, callBackData.url)\n break\n default:\n this.logger.error('unhandled case')\n }\n } catch (e) {\n this.logger.error(`${this.callBack.name} - ${e.message} : ${space.url}`)\n return { error: e.message }\n }\n return { error: 0 }\n }\n\n private async genConfiguration(\n user: UserModel,\n space: SpaceEnv,\n mode: 'edit' | 'view',\n fileId: string,\n fileUrl: string,\n fileExtension: string,\n callBackUrl: string,\n isMobile: boolean\n ): Promise<OnlyOfficeReqConfig> {\n const documentType = ONLY_OFFICE_EXTENSIONS.EDITABLE.get(fileExtension) || ONLY_OFFICE_EXTENSIONS.VIEWABLE.get(fileExtension)\n return {\n documentServerUrl: this.externalOnlyOfficeServer || `${this.contextManager.get('headerOriginUrl')}${ONLY_OFFICE_INTERNAL_URI}`,\n config: {\n type: isMobile ? 'mobile' : 'desktop',\n height: '100%',\n width: '100%',\n documentType: documentType,\n document: {\n title: path.basename(space.relativeUrl),\n fileType: fileExtension,\n key: await this.getDocumentKey(fileId),\n permissions: {\n download: true,\n edit: mode === 'edit',\n changeHistory: false,\n comment: true,\n fillForms: true,\n print: true,\n review: mode === 'edit'\n },\n url: fileUrl\n },\n editorConfig: {\n mode: mode,\n lang: 'en',\n region: 'en',\n callbackUrl: callBackUrl,\n user: { id: user.id.toString(), name: `${user.fullName} (${user.email})`, image: await this.usersManager.getAvatarBase64(user.login) },\n coEditing: {\n mode: 'fast',\n change: true\n },\n embedded: {\n embedUrl: fileUrl,\n saveUrl: fileUrl,\n shareUrl: fileUrl,\n toolbarDocked: 'top'\n },\n customization: {\n about: false,\n autosave: false,\n forcesave: true,\n zoom: documentType === 'slide' ? 60 : 90,\n help: false,\n features: { featuresTips: false },\n plugins: false\n }\n }\n }\n }\n }\n\n private getDocumentUrl(space: SpaceEnv, token: string): string {\n // user refresh token is used here for long session\n return `${this.contextManager.get('headerOriginUrl')}${API_FILES_ONLY_OFFICE_DOCUMENT}/${space.url}?${ONLY_OFFICE_TOKEN_QUERY_PARAM_NAME}=${token}`\n }\n\n private getCallBackUrl(space: SpaceEnv, token: string, fileId: string): string {\n // user refresh token is used here for long session\n return `${this.contextManager.get('headerOriginUrl')}${API_FILES_ONLY_OFFICE_CALLBACK}/${space.url}?fid=${fileId}&${ONLY_OFFICE_TOKEN_QUERY_PARAM_NAME}=${token}`\n }\n\n private genPayloadToken(payload: OnlyOfficeConfig | OnlyOfficeConvertForm): Promise<string> {\n return this.jwt.signAsync(payload, { secret: configuration.applications.files.onlyoffice.secret, expiresIn: 60 })\n }\n\n private genUserToken(user: UserModel): Promise<string> {\n // use refresh expiration to allow long session\n return this.jwt.signAsync(\n {\n identity: {\n id: user.id,\n login: user.login,\n email: user.email,\n fullName: user.fullName,\n role: user.role,\n applications: user.applications\n } satisfies JwtIdentityPayload\n },\n {\n secret: configuration.auth.token.access.secret,\n expiresIn: this.expiration\n }\n )\n }\n\n private async checkFileLock(user: UserModel, space: SpaceEnv, callBackData: OnlyOfficeCallBack) {\n for (const action of callBackData.actions) {\n if (action.type === 0) {\n // disconnect\n await this.removeFileLock(parseInt(action.userid), space)\n } else if (action.type === 1) {\n // connect\n await this.genFileLock(user, space)\n }\n }\n }\n\n private async genFileLock(user: UserModel, space: SpaceEnv): Promise<void> {\n const [ok, _fileLock] = await this.filesLockManager.create(user, space.dbFile, DEPTH.RESOURCE, this.expiration, {\n lockroot: null,\n locktoken: null,\n lockscope: LOCK_SCOPE.SHARED,\n owner: `${SERVER_NAME} - ${user.fullName} (${user.email})`\n })\n if (!ok) {\n throw new Error('document is locked')\n }\n }\n\n private async removeFileLock(userId: number, space: SpaceEnv): Promise<void> {\n for (const lock of await this.filesLockManager.getLocksByPath(space.dbFile)) {\n if (lock.owner.id === userId) {\n await this.filesLockManager.removeLock(lock.key)\n }\n }\n }\n\n private async removeDocumentKey(fileId: string, space: SpaceEnv): Promise<void> {\n if (!(await this.filesLockManager.isPathLocked(space.dbFile))) {\n const cacheKey = this.getCacheKey(fileId)\n const r = await this.cache.del(cacheKey)\n this.logger.debug(`${this.removeDocumentKey.name} - ${cacheKey} ${r ? '' : 'not'} removed`)\n }\n }\n\n private async getDocumentKey(fileId: string): Promise<string> {\n const cacheKey = this.getCacheKey(fileId)\n const existingDocKey: string = await this.cache.get(cacheKey)\n if (existingDocKey) {\n return existingDocKey\n }\n const docKey = generateShortUUID(16)\n await this.cache.set(cacheKey, docKey, this.expiration)\n this.logger.debug(`${this.getDocumentKey.name} - ${cacheKey} (${docKey}) created`)\n return docKey\n }\n\n private async saveDocument(space: SpaceEnv, url: string): Promise<void> {\n /* url format:\n https://onlyoffice-server.com/cache/files/data/-33120641_7158/output.pptx/output.pptx\n ?md5=duFHKC-5d47s-RRcYn3hAw&expires=1739400549&shardkey=-33120641&filename=output.pptx\n */\n const urlParams = new URLSearchParams(url.split('?').at(-1))\n // it is not the md5 of the file but a md5 generated by the combination of the elements of the url\n const md5: string = urlParams.get('md5')\n const tmpFilePath = await uniqueFilePathFromDir(path.join(os.tmpdir(), `${md5}-${urlParams.get('filename')}`))\n\n // convert remote file to the local file with the current extension if these extensions aren't equal\n const localExtension = path.extname(space.realPath).slice(1)\n const remoteExtension = path.extname(urlParams.get('filename')).slice(1)\n\n let downloadUrl: string\n if (localExtension !== remoteExtension && !ONLY_OFFICE_CONVERT_EXTENSIONS.ALLOW_AUTO.has(localExtension)) {\n if (ONLY_OFFICE_CONVERT_EXTENSIONS.FROM.has(remoteExtension) && ONLY_OFFICE_CONVERT_EXTENSIONS.TO.has(localExtension)) {\n downloadUrl = await this.convertDocument(urlParams.get('shardkey'), url, remoteExtension, localExtension, space.url)\n } else {\n throw new Error(`document cannot be converted from ${remoteExtension} -> ${localExtension} : ${space.url}`)\n }\n } else {\n downloadUrl = url\n }\n\n // download file\n let res: AxiosResponse\n try {\n res = await this.http.axiosRef({\n method: HTTP_METHOD.GET,\n url: downloadUrl,\n responseType: 'stream',\n httpsAgent: new https.Agent({ rejectUnauthorized: this.rejectUnauthorized })\n })\n await writeFromStream(tmpFilePath, res.data)\n } catch (e) {\n throw new Error(`unable to get document : ${e.message}`)\n }\n\n // try to verify the downloaded size\n const contentLength = parseInt(res.headers['content-length'], 10)\n if (!isNaN(contentLength)) {\n if (contentLength === 0) {\n this.logger.debug(`${this.saveDocument.name} - content length is 0 : ${space.url}`)\n return\n }\n const tmpFileSize = await fileSize(tmpFilePath)\n if (tmpFileSize !== contentLength) {\n throw new Error(`document size differs (${tmpFileSize} != ${contentLength})`)\n }\n }\n // copy contents to avoid inode changes (fileId in some cases)\n try {\n await copyFileContent(tmpFilePath, space.realPath)\n await removeFiles(tmpFilePath)\n } catch (e) {\n throw new Error(`unable to save document : ${e.message}`)\n }\n }\n\n private async convertDocument(id: string, url: string, fileType: string, outputType: string, spaceUrl: string): Promise<string> {\n const key: string = `${id}-${crypto.randomBytes(20).toString('hex')}`.slice(0, 20).replace('-', '_')\n const payload: OnlyOfficeConvertForm = {\n key: key,\n url: url,\n filetype: fileType,\n outputtype: outputType,\n async: false\n }\n payload.token = await this.genPayloadToken(payload)\n let result: { fileUrl?: string; fileType?: string; endConvert?: boolean; error?: number }\n try {\n const res: AxiosResponse = await this.http.axiosRef({\n method: HTTP_METHOD.POST,\n url: this.convertUrl,\n data: payload,\n httpsAgent: new https.Agent({ rejectUnauthorized: this.rejectUnauthorized })\n })\n result = res.data\n } catch (e) {\n throw new Error(`convert failed with status : ${e.response.status}`)\n }\n if (result.error) {\n throw new Error(`convert failed with reason : ${ONLY_OFFICE_CONVERT_ERROR.get(result.error)}`)\n }\n if (result.endConvert) {\n this.logger.log(`${this.convertDocument.name} - ${fileType} -> ${outputType} : ${spaceUrl}`)\n return result.fileUrl\n }\n }\n\n private getCacheKey(fileId: string): string {\n return `${CACHE_ONLY_OFFICE}|${fileId}`\n }\n}\n"],"names":["FilesOnlyOfficeManager","getStatus","enabled","configuration","applications","files","onlyoffice","getSettings","user","space","mode","req","isPathExists","realPath","HttpException","HttpStatus","NOT_FOUND","isPathIsDir","BAD_REQUEST","fileExtension","path","extname","slice","ONLY_OFFICE_EXTENSIONS","VIEWABLE","has","EDITABLE","haveSpaceEnvPermissions","SPACE_OPERATION","MODIFY","filesLockManager","checkConflicts","dbFile","DEPTH","RESOURCE","userId","id","lockScope","LOCK_SCOPE","SHARED","LOCKED","isMobile","mobileRegex","test","headers","fileProps","getProps","fileId","filesQueries","getSpaceFileId","toString","userToken","genUserToken","fileUrl","getDocumentUrl","callBackUrl","getCallBackUrl","config","genConfiguration","token","genPayloadToken","callBack","callBackData","jwt","verifyAsync","secret","status","checkFileLock","logger","debug","url","notmodified","saveDocument","removeDocumentKey","error","removeFileLock","e","name","message","documentType","get","documentServerUrl","externalOnlyOfficeServer","contextManager","ONLY_OFFICE_INTERNAL_URI","type","height","width","document","title","basename","relativeUrl","fileType","key","getDocumentKey","permissions","download","edit","changeHistory","comment","fillForms","print","review","editorConfig","lang","region","callbackUrl","fullName","email","image","usersManager","getAvatarBase64","login","coEditing","change","embedded","embedUrl","saveUrl","shareUrl","toolbarDocked","customization","about","autosave","forcesave","zoom","help","features","featuresTips","plugins","API_FILES_ONLY_OFFICE_DOCUMENT","ONLY_OFFICE_TOKEN_QUERY_PARAM_NAME","API_FILES_ONLY_OFFICE_CALLBACK","payload","signAsync","expiresIn","identity","role","auth","access","expiration","action","actions","parseInt","userid","genFileLock","ok","_fileLock","create","lockroot","locktoken","lockscope","owner","SERVER_NAME","Error","lock","getLocksByPath","removeLock","isPathLocked","cacheKey","getCacheKey","r","cache","del","existingDocKey","docKey","generateShortUUID","set","urlParams","URLSearchParams","split","at","md5","tmpFilePath","uniqueFilePathFromDir","join","os","tmpdir","localExtension","remoteExtension","downloadUrl","ONLY_OFFICE_CONVERT_EXTENSIONS","ALLOW_AUTO","FROM","TO","convertDocument","res","http","axiosRef","method","HTTP_METHOD","GET","responseType","httpsAgent","https","Agent","rejectUnauthorized","writeFromStream","data","contentLength","isNaN","tmpFileSize","fileSize","copyFileContent","removeFiles","outputType","spaceUrl","crypto","randomBytes","replace","filetype","outputtype","async","result","POST","convertUrl","response","ONLY_OFFICE_CONVERT_ERROR","endConvert","log","CACHE_ONLY_OFFICE","Logger","externalServer","verifySSL","convertHumanTimeToSeconds","refresh"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../../backend/src/applications/files/services/files-only-office-manager.service.ts"],"sourcesContent":["/*\n * Copyright (C) 2012-2025 Johan Legrand <johan.legrand@sync-in.com>\n * This file is part of Sync-in | The open source file sync and share solution\n * See the LICENSE file for licensing details\n */\n\nimport { HttpService } from '@nestjs/axios'\nimport { HttpException, HttpStatus, Injectable, Logger } from '@nestjs/common'\nimport { JwtService } from '@nestjs/jwt'\nimport { AxiosResponse } from 'axios'\nimport https from 'https'\nimport crypto from 'node:crypto'\nimport os from 'node:os'\nimport path from 'node:path'\nimport { SERVER_NAME } from '../../../app.constants'\nimport { JwtIdentityPayload } from '../../../authentication/interfaces/jwt-payload.interface'\nimport { convertHumanTimeToSeconds, generateShortUUID } from '../../../common/functions'\nimport { configuration } from '../../../configuration/config.environment'\nimport { Cache } from '../../../infrastructure/cache/services/cache.service'\nimport { ContextManager } from '../../../infrastructure/context/services/context-manager.service'\nimport { HTTP_METHOD } from '../../applications.constants'\nimport { SPACE_OPERATION } from '../../spaces/constants/spaces'\nimport { FastifySpaceRequest } from '../../spaces/interfaces/space-request.interface'\nimport type { SpaceEnv } from '../../spaces/models/space-env.model'\nimport { haveSpaceEnvPermissions } from '../../spaces/utils/permissions'\nimport type { UserModel } from '../../users/models/user.model'\nimport { getAvatarBase64 } from '../../users/utils/avatar'\nimport { DEPTH, LOCK_SCOPE } from '../../webdav/constants/webdav'\nimport { CACHE_ONLY_OFFICE } from '../constants/cache'\nimport {\n ONLY_OFFICE_CONVERT_ERROR,\n ONLY_OFFICE_CONVERT_EXTENSIONS,\n ONLY_OFFICE_EXTENSIONS,\n ONLY_OFFICE_INTERNAL_URI,\n ONLY_OFFICE_TOKEN_QUERY_PARAM_NAME\n} from '../constants/only-office'\nimport { API_FILES_ONLY_OFFICE_CALLBACK, API_FILES_ONLY_OFFICE_DOCUMENT } from '../constants/routes'\nimport type { FileProps } from '../interfaces/file-props.interface'\nimport { OnlyOfficeCallBack, OnlyOfficeConfig, OnlyOfficeConvertForm, OnlyOfficeReqConfig } from '../interfaces/only-office-config.interface'\nimport { copyFileContent, fileSize, getProps, isPathExists, isPathIsDir, removeFiles, uniqueFilePathFromDir, writeFromStream } from '../utils/files'\nimport { FilesLockManager } from './files-lock-manager.service'\nimport { FilesQueries } from './files-queries.service'\n\n@Injectable()\nexport class FilesOnlyOfficeManager {\n private logger = new Logger(FilesOnlyOfficeManager.name)\n private readonly externalOnlyOfficeServer = configuration.applications.files.onlyoffice.externalServer || null\n private readonly rejectUnauthorized: boolean = !configuration.applications.files.onlyoffice?.verifySSL\n private readonly convertUrl = this.externalOnlyOfficeServer ? `${this.externalOnlyOfficeServer}/ConvertService.ashx` : null\n private readonly expiration = convertHumanTimeToSeconds(configuration.auth.token.refresh.expiration)\n private readonly mobileRegex: RegExp = /android|webos|iphone|ipad|ipod|blackberry|windows phone|opera mini|iemobile|mobile/i\n\n constructor(\n private readonly http: HttpService,\n private readonly contextManager: ContextManager,\n private readonly cache: Cache,\n private readonly jwt: JwtService,\n private readonly filesLockManager: FilesLockManager,\n private readonly filesQueries: FilesQueries\n ) {}\n\n getStatus(): { enabled: boolean } {\n return { enabled: configuration.applications.files.onlyoffice.enabled }\n }\n\n async getSettings(user: UserModel, space: SpaceEnv, mode: 'edit' | 'view', req: FastifySpaceRequest): Promise<OnlyOfficeReqConfig> {\n if (!(await isPathExists(space.realPath))) {\n throw new HttpException('Document not found', HttpStatus.NOT_FOUND)\n }\n if (await isPathIsDir(space.realPath)) {\n throw new HttpException('Document must be a file', HttpStatus.BAD_REQUEST)\n }\n const fileExtension = path.extname(space.realPath).slice(1)\n if (!ONLY_OFFICE_EXTENSIONS.VIEWABLE.has(fileExtension) && !ONLY_OFFICE_EXTENSIONS.EDITABLE.has(fileExtension)) {\n throw new HttpException('Document not supported', HttpStatus.BAD_REQUEST)\n }\n if (mode === 'edit' && (!ONLY_OFFICE_EXTENSIONS.EDITABLE.has(fileExtension) || !haveSpaceEnvPermissions(space, SPACE_OPERATION.MODIFY))) {\n mode = 'view'\n }\n if (mode === 'edit') {\n // check lock conflicts\n try {\n await this.filesLockManager.checkConflicts(space.dbFile, DEPTH.RESOURCE, { userId: user.id, lockScope: LOCK_SCOPE.SHARED })\n } catch {\n throw new HttpException('The file is locked', HttpStatus.LOCKED)\n }\n }\n const isMobile: boolean = this.mobileRegex.test(req.headers['user-agent'])\n const fileProps: FileProps = await getProps(space.realPath, space.dbFile.path)\n const fileId: string = ((await this.filesQueries.getSpaceFileId(fileProps, space.dbFile)) || fileProps.id).toString()\n const userToken: string = await this.genUserToken(user)\n const fileUrl = this.getDocumentUrl(space, userToken)\n const callBackUrl = this.getCallBackUrl(space, userToken, fileId)\n const config: OnlyOfficeReqConfig = await this.genConfiguration(user, space, mode, fileId, fileUrl, fileExtension, callBackUrl, isMobile)\n config.config.token = await this.genPayloadToken(config.config)\n return config\n }\n\n async callBack(user: UserModel, space: SpaceEnv, token: string, fileId: string) {\n const callBackData: OnlyOfficeCallBack = await this.jwt.verifyAsync(token, { secret: configuration.applications.files.onlyoffice.secret })\n try {\n switch (callBackData.status) {\n case 1:\n await this.checkFileLock(user, space, callBackData)\n this.logger.debug(`document is being edited : ${space.url}`)\n break\n case 2:\n await this.checkFileLock(user, space, callBackData)\n if (callBackData.notmodified) {\n this.logger.debug(`document was edited but closed with no changes : ${space.url}`)\n } else {\n this.logger.debug(`document was edited but not saved (let's do it) : ${space.url}`)\n await this.saveDocument(space, callBackData.url)\n }\n await this.removeDocumentKey(fileId, space)\n break\n case 3:\n this.logger.error(`document cannot be saved, an error has occurred (try to save it) : ${space.url}`)\n await this.saveDocument(space, callBackData.url)\n break\n case 4:\n await this.removeFileLock(user.id, space)\n await this.removeDocumentKey(fileId, space)\n this.logger.debug(`document was closed with no changes : ${space.url}`)\n break\n case 6:\n this.logger.debug(`document is edited but save was requested : ${space.url}`)\n await this.saveDocument(space, callBackData.url)\n break\n case 7:\n this.logger.error(`document cannot be force saved, an error has occurred (try to save it) : ${space.url}`)\n await this.saveDocument(space, callBackData.url)\n break\n default:\n this.logger.error('unhandled case')\n }\n } catch (e) {\n this.logger.error(`${this.callBack.name} - ${e.message} : ${space.url}`)\n return { error: e.message }\n }\n return { error: 0 }\n }\n\n private async genConfiguration(\n user: UserModel,\n space: SpaceEnv,\n mode: 'edit' | 'view',\n fileId: string,\n fileUrl: string,\n fileExtension: string,\n callBackUrl: string,\n isMobile: boolean\n ): Promise<OnlyOfficeReqConfig> {\n const documentType = ONLY_OFFICE_EXTENSIONS.EDITABLE.get(fileExtension) || ONLY_OFFICE_EXTENSIONS.VIEWABLE.get(fileExtension)\n return {\n documentServerUrl: this.externalOnlyOfficeServer || `${this.contextManager.get('headerOriginUrl')}${ONLY_OFFICE_INTERNAL_URI}`,\n config: {\n type: isMobile ? 'mobile' : 'desktop',\n height: '100%',\n width: '100%',\n documentType: documentType,\n document: {\n title: path.basename(space.relativeUrl),\n fileType: fileExtension,\n key: await this.getDocumentKey(fileId),\n permissions: {\n download: true,\n edit: mode === 'edit',\n changeHistory: false,\n comment: true,\n fillForms: true,\n print: true,\n review: mode === 'edit'\n },\n url: fileUrl\n },\n editorConfig: {\n mode: mode,\n lang: 'en',\n region: 'en',\n callbackUrl: callBackUrl,\n user: { id: user.id.toString(), name: `${user.fullName} (${user.email})`, image: await getAvatarBase64(user.login) },\n coEditing: {\n mode: 'fast',\n change: true\n },\n embedded: {\n embedUrl: fileUrl,\n saveUrl: fileUrl,\n shareUrl: fileUrl,\n toolbarDocked: 'top'\n },\n customization: {\n about: false,\n autosave: false,\n forcesave: true,\n zoom: documentType === 'slide' ? 60 : 90,\n help: false,\n features: { featuresTips: false },\n plugins: false\n }\n }\n }\n }\n }\n\n private getDocumentUrl(space: SpaceEnv, token: string): string {\n // user refresh token is used here for long session\n return `${this.contextManager.get('headerOriginUrl')}${API_FILES_ONLY_OFFICE_DOCUMENT}/${space.url}?${ONLY_OFFICE_TOKEN_QUERY_PARAM_NAME}=${token}`\n }\n\n private getCallBackUrl(space: SpaceEnv, token: string, fileId: string): string {\n // user refresh token is used here for long session\n return `${this.contextManager.get('headerOriginUrl')}${API_FILES_ONLY_OFFICE_CALLBACK}/${space.url}?fid=${fileId}&${ONLY_OFFICE_TOKEN_QUERY_PARAM_NAME}=${token}`\n }\n\n private genPayloadToken(payload: OnlyOfficeConfig | OnlyOfficeConvertForm): Promise<string> {\n return this.jwt.signAsync(payload, { secret: configuration.applications.files.onlyoffice.secret, expiresIn: 60 })\n }\n\n private genUserToken(user: UserModel): Promise<string> {\n // use refresh expiration to allow long session\n return this.jwt.signAsync(\n {\n identity: {\n id: user.id,\n login: user.login,\n email: user.email,\n fullName: user.fullName,\n language: user.language,\n role: user.role,\n applications: user.applications\n } satisfies JwtIdentityPayload\n },\n {\n secret: configuration.auth.token.access.secret,\n expiresIn: this.expiration\n }\n )\n }\n\n private async checkFileLock(user: UserModel, space: SpaceEnv, callBackData: OnlyOfficeCallBack) {\n for (const action of callBackData.actions) {\n if (action.type === 0) {\n // disconnect\n await this.removeFileLock(parseInt(action.userid), space)\n } else if (action.type === 1) {\n // connect\n await this.genFileLock(user, space)\n }\n }\n }\n\n private async genFileLock(user: UserModel, space: SpaceEnv): Promise<void> {\n const [ok, _fileLock] = await this.filesLockManager.create(user, space.dbFile, DEPTH.RESOURCE, this.expiration, {\n lockroot: null,\n locktoken: null,\n lockscope: LOCK_SCOPE.SHARED,\n owner: `${SERVER_NAME} - ${user.fullName} (${user.email})`\n })\n if (!ok) {\n throw new Error('document is locked')\n }\n }\n\n private async removeFileLock(userId: number, space: SpaceEnv): Promise<void> {\n for (const lock of await this.filesLockManager.getLocksByPath(space.dbFile)) {\n if (lock.owner.id === userId) {\n await this.filesLockManager.removeLock(lock.key)\n }\n }\n }\n\n private async removeDocumentKey(fileId: string, space: SpaceEnv): Promise<void> {\n if (!(await this.filesLockManager.isPathLocked(space.dbFile))) {\n const cacheKey = this.getCacheKey(fileId)\n const r = await this.cache.del(cacheKey)\n this.logger.debug(`${this.removeDocumentKey.name} - ${cacheKey} ${r ? '' : 'not'} removed`)\n }\n }\n\n private async getDocumentKey(fileId: string): Promise<string> {\n const cacheKey = this.getCacheKey(fileId)\n const existingDocKey: string = await this.cache.get(cacheKey)\n if (existingDocKey) {\n return existingDocKey\n }\n const docKey = generateShortUUID(64)\n await this.cache.set(cacheKey, docKey, this.expiration)\n this.logger.debug(`${this.getDocumentKey.name} - ${cacheKey} (${docKey}) created`)\n return docKey\n }\n\n private async saveDocument(space: SpaceEnv, url: string): Promise<void> {\n /* url format:\n https://onlyoffice-server.com/cache/files/data/-33120641_7158/output.pptx/output.pptx\n ?md5=duFHKC-5d47s-RRcYn3hAw&expires=1739400549&shardkey=-33120641&filename=output.pptx\n */\n const urlParams = new URLSearchParams(url.split('?').at(-1))\n // it is not the md5 of the file but a md5 generated by the combination of the elements of the url\n const md5: string = urlParams.get('md5')\n const tmpFilePath = await uniqueFilePathFromDir(path.join(os.tmpdir(), `${md5}-${urlParams.get('filename')}`))\n\n // convert remote file to the local file with the current extension if these extensions aren't equal\n const localExtension = path.extname(space.realPath).slice(1)\n const remoteExtension = path.extname(urlParams.get('filename')).slice(1)\n\n let downloadUrl: string\n if (localExtension !== remoteExtension && !ONLY_OFFICE_CONVERT_EXTENSIONS.ALLOW_AUTO.has(localExtension)) {\n if (ONLY_OFFICE_CONVERT_EXTENSIONS.FROM.has(remoteExtension) && ONLY_OFFICE_CONVERT_EXTENSIONS.TO.has(localExtension)) {\n downloadUrl = await this.convertDocument(urlParams.get('shardkey'), url, remoteExtension, localExtension, space.url)\n } else {\n throw new Error(`document cannot be converted from ${remoteExtension} -> ${localExtension} : ${space.url}`)\n }\n } else {\n downloadUrl = url\n }\n\n // download file\n let res: AxiosResponse\n try {\n res = await this.http.axiosRef({\n method: HTTP_METHOD.GET,\n url: downloadUrl,\n responseType: 'stream',\n httpsAgent: new https.Agent({ rejectUnauthorized: this.rejectUnauthorized })\n })\n await writeFromStream(tmpFilePath, res.data)\n } catch (e) {\n throw new Error(`unable to get document : ${e.message}`)\n }\n\n // try to verify the downloaded size\n const contentLength = parseInt(res.headers['content-length'], 10)\n if (!isNaN(contentLength)) {\n if (contentLength === 0) {\n this.logger.debug(`${this.saveDocument.name} - content length is 0 : ${space.url}`)\n return\n }\n const tmpFileSize = await fileSize(tmpFilePath)\n if (tmpFileSize !== contentLength) {\n throw new Error(`document size differs (${tmpFileSize} != ${contentLength})`)\n }\n }\n // copy contents to avoid inode changes (fileId in some cases)\n try {\n await copyFileContent(tmpFilePath, space.realPath)\n await removeFiles(tmpFilePath)\n } catch (e) {\n throw new Error(`unable to save document : ${e.message}`)\n }\n }\n\n private async convertDocument(id: string, url: string, fileType: string, outputType: string, spaceUrl: string): Promise<string> {\n const key: string = `${id}-${crypto.randomBytes(20).toString('hex')}`.slice(0, 20).replace('-', '_')\n const payload: OnlyOfficeConvertForm = {\n key: key,\n url: url,\n filetype: fileType,\n outputtype: outputType,\n async: false\n }\n payload.token = await this.genPayloadToken(payload)\n let result: { fileUrl?: string; fileType?: string; endConvert?: boolean; error?: number }\n try {\n const res: AxiosResponse = await this.http.axiosRef({\n method: HTTP_METHOD.POST,\n url: this.convertUrl,\n data: payload,\n httpsAgent: new https.Agent({ rejectUnauthorized: this.rejectUnauthorized })\n })\n result = res.data\n } catch (e) {\n throw new Error(`convert failed with status : ${e.response.status}`)\n }\n if (result.error) {\n throw new Error(`convert failed with reason : ${ONLY_OFFICE_CONVERT_ERROR.get(result.error)}`)\n }\n if (result.endConvert) {\n this.logger.log(`${this.convertDocument.name} - ${fileType} -> ${outputType} : ${spaceUrl}`)\n return result.fileUrl\n }\n }\n\n private getCacheKey(fileId: string): string {\n return `${CACHE_ONLY_OFFICE}|${fileId}`\n }\n}\n"],"names":["FilesOnlyOfficeManager","getStatus","enabled","configuration","applications","files","onlyoffice","getSettings","user","space","mode","req","isPathExists","realPath","HttpException","HttpStatus","NOT_FOUND","isPathIsDir","BAD_REQUEST","fileExtension","path","extname","slice","ONLY_OFFICE_EXTENSIONS","VIEWABLE","has","EDITABLE","haveSpaceEnvPermissions","SPACE_OPERATION","MODIFY","filesLockManager","checkConflicts","dbFile","DEPTH","RESOURCE","userId","id","lockScope","LOCK_SCOPE","SHARED","LOCKED","isMobile","mobileRegex","test","headers","fileProps","getProps","fileId","filesQueries","getSpaceFileId","toString","userToken","genUserToken","fileUrl","getDocumentUrl","callBackUrl","getCallBackUrl","config","genConfiguration","token","genPayloadToken","callBack","callBackData","jwt","verifyAsync","secret","status","checkFileLock","logger","debug","url","notmodified","saveDocument","removeDocumentKey","error","removeFileLock","e","name","message","documentType","get","documentServerUrl","externalOnlyOfficeServer","contextManager","ONLY_OFFICE_INTERNAL_URI","type","height","width","document","title","basename","relativeUrl","fileType","key","getDocumentKey","permissions","download","edit","changeHistory","comment","fillForms","print","review","editorConfig","lang","region","callbackUrl","fullName","email","image","getAvatarBase64","login","coEditing","change","embedded","embedUrl","saveUrl","shareUrl","toolbarDocked","customization","about","autosave","forcesave","zoom","help","features","featuresTips","plugins","API_FILES_ONLY_OFFICE_DOCUMENT","ONLY_OFFICE_TOKEN_QUERY_PARAM_NAME","API_FILES_ONLY_OFFICE_CALLBACK","payload","signAsync","expiresIn","identity","language","role","auth","access","expiration","action","actions","parseInt","userid","genFileLock","ok","_fileLock","create","lockroot","locktoken","lockscope","owner","SERVER_NAME","Error","lock","getLocksByPath","removeLock","isPathLocked","cacheKey","getCacheKey","r","cache","del","existingDocKey","docKey","generateShortUUID","set","urlParams","URLSearchParams","split","at","md5","tmpFilePath","uniqueFilePathFromDir","join","os","tmpdir","localExtension","remoteExtension","downloadUrl","ONLY_OFFICE_CONVERT_EXTENSIONS","ALLOW_AUTO","FROM","TO","convertDocument","res","http","axiosRef","method","HTTP_METHOD","GET","responseType","httpsAgent","https","Agent","rejectUnauthorized","writeFromStream","data","contentLength","isNaN","tmpFileSize","fileSize","copyFileContent","removeFiles","outputType","spaceUrl","crypto","randomBytes","replace","filetype","outputtype","async","result","POST","convertUrl","response","ONLY_OFFICE_CONVERT_ERROR","endConvert","log","CACHE_ONLY_OFFICE","Logger","externalServer","verifySSL","convertHumanTimeToSeconds","refresh"],"mappings":"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"}
|