@sync-in/server 1.8.0 → 1.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +64 -10
- package/environment/environment.dist.yaml +29 -26
- package/package.json +18 -17
- package/server/app.bootstrap.js +4 -2
- package/server/app.bootstrap.js.map +1 -1
- package/server/app.constants.js +9 -0
- package/server/app.constants.js.map +1 -1
- package/server/app.module.js +4 -0
- package/server/app.module.js.map +1 -1
- package/server/applications/admin/admin.module.js +6 -1
- package/server/applications/admin/admin.module.js.map +1 -1
- package/server/applications/{notifications/interfaces/user-mail-notification.js → admin/interfaces/check-update.interfaces.js} +1 -1
- package/server/applications/admin/interfaces/check-update.interfaces.js.map +1 -0
- package/server/applications/admin/services/admin-scheduler.service.js +53 -0
- package/server/applications/admin/services/admin-scheduler.service.js.map +1 -0
- package/server/applications/admin/services/admin.service.js +102 -0
- package/server/applications/admin/services/admin.service.js.map +1 -0
- package/server/applications/admin/services/admin.service.spec.js +46 -0
- package/server/applications/admin/services/admin.service.spec.js.map +1 -0
- package/server/applications/admin/utils/check-update.js +28 -0
- package/server/applications/admin/utils/check-update.js.map +1 -0
- package/server/applications/comments/services/comments-manager.service.js +1 -1
- package/server/applications/comments/services/comments-manager.service.js.map +1 -1
- package/server/applications/comments/services/comments-manager.service.spec.js +1 -1
- package/server/applications/comments/services/comments-manager.service.spec.js.map +1 -1
- package/server/applications/comments/services/comments-queries.service.js.map +1 -1
- package/server/applications/files/constants/cache.js +10 -1
- package/server/applications/files/constants/cache.js.map +1 -1
- package/server/applications/files/constants/only-office.js +0 -25
- package/server/applications/files/constants/only-office.js.map +1 -1
- package/server/applications/files/constants/operations.js +20 -3
- package/server/applications/files/constants/operations.js.map +1 -1
- package/server/applications/files/dto/file-operations.dto.js +7 -0
- package/server/applications/files/dto/file-operations.dto.js.map +1 -1
- package/server/applications/files/files-only-office.controller.js +3 -2
- package/server/applications/files/files-only-office.controller.js.map +1 -1
- package/server/applications/files/files-only-office.controller.spec.js +6 -5
- package/server/applications/files/files-only-office.controller.spec.js.map +1 -1
- package/server/applications/files/files.controller.js +100 -12
- package/server/applications/files/files.controller.js.map +1 -1
- package/server/applications/files/files.controller.spec.js +29 -8
- package/server/applications/files/files.controller.spec.js.map +1 -1
- package/server/applications/files/guards/files-only-office.guard.js +6 -0
- package/server/applications/files/guards/files-only-office.guard.js.map +1 -1
- package/server/applications/files/interfaces/file-db-props.interface.js.map +1 -1
- package/server/applications/files/interfaces/file-props.interface.js.map +1 -1
- package/server/applications/files/interfaces/only-office-config.interface.js.map +1 -1
- package/server/applications/files/services/files-content-manager.service.js +3 -3
- package/server/applications/files/services/files-content-manager.service.js.map +1 -1
- package/server/applications/files/services/files-lock-manager.service.js +61 -22
- package/server/applications/files/services/files-lock-manager.service.js.map +1 -1
- package/server/applications/files/services/files-manager.service.js +122 -24
- package/server/applications/files/services/files-manager.service.js.map +1 -1
- package/server/applications/files/services/files-manager.service.spec.js +15 -0
- package/server/applications/files/services/files-manager.service.spec.js.map +1 -1
- package/server/applications/files/services/files-methods.service.js +39 -14
- package/server/applications/files/services/files-methods.service.js.map +1 -1
- package/server/applications/files/services/files-only-office-manager.service.js +12 -12
- package/server/applications/files/services/files-only-office-manager.service.js.map +1 -1
- package/server/applications/files/services/files-parser.service.js +1 -1
- package/server/applications/files/services/files-parser.service.js.map +1 -1
- package/server/applications/files/services/files-queries.service.js +10 -0
- package/server/applications/files/services/files-queries.service.js.map +1 -1
- package/server/applications/files/utils/doc-textify/adapters/pdf.js +5 -16
- package/server/applications/files/utils/doc-textify/adapters/pdf.js.map +1 -1
- package/server/applications/files/utils/files.js +1 -1
- package/server/applications/files/utils/files.js.map +1 -1
- package/server/applications/files/utils/send-file.js +3 -2
- package/server/applications/files/utils/send-file.js.map +1 -1
- package/server/applications/links/services/links-queries.service.js +1 -1
- package/server/applications/links/services/links-queries.service.js.map +1 -1
- package/server/applications/notifications/constants/notifications.js +5 -1
- package/server/applications/notifications/constants/notifications.js.map +1 -1
- package/server/applications/notifications/i18n/de.js +8 -2
- package/server/applications/notifications/i18n/de.js.map +1 -1
- package/server/applications/notifications/i18n/es.js +8 -2
- package/server/applications/notifications/i18n/es.js.map +1 -1
- package/server/applications/notifications/i18n/fr.js +8 -2
- package/server/applications/notifications/i18n/fr.js.map +1 -1
- package/server/applications/notifications/i18n/hi.js +8 -2
- package/server/applications/notifications/i18n/hi.js.map +1 -1
- package/server/applications/notifications/i18n/it.js +8 -2
- package/server/applications/notifications/i18n/it.js.map +1 -1
- package/server/applications/notifications/i18n/ja.js +8 -2
- package/server/applications/notifications/i18n/ja.js.map +1 -1
- package/server/applications/notifications/i18n/ko.js +8 -2
- package/server/applications/notifications/i18n/ko.js.map +1 -1
- package/server/applications/notifications/i18n/pl.js +8 -2
- package/server/applications/notifications/i18n/pl.js.map +1 -1
- package/server/applications/notifications/i18n/pt.js +8 -2
- package/server/applications/notifications/i18n/pt.js.map +1 -1
- package/server/applications/notifications/i18n/pt_br.js +8 -2
- package/server/applications/notifications/i18n/pt_br.js.map +1 -1
- package/server/applications/notifications/i18n/ru.js +8 -2
- package/server/applications/notifications/i18n/ru.js.map +1 -1
- package/server/applications/notifications/i18n/tr.js +8 -2
- package/server/applications/notifications/i18n/tr.js.map +1 -1
- package/server/applications/notifications/i18n/zh.js +8 -2
- package/server/applications/notifications/i18n/zh.js.map +1 -1
- package/server/applications/notifications/interfaces/notification-properties.interface.js.map +1 -1
- package/server/applications/notifications/interfaces/user-mail-notification.interface.js +10 -0
- package/server/applications/notifications/interfaces/user-mail-notification.interface.js.map +1 -0
- package/server/applications/notifications/mails/models.js +38 -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/services/notifications-manager.service.js +8 -1
- package/server/applications/notifications/services/notifications-manager.service.js.map +1 -1
- package/server/applications/notifications/services/notifications-queries.service.js.map +1 -1
- package/server/applications/shares/services/shares-manager.service.js +17 -10
- package/server/applications/shares/services/shares-manager.service.js.map +1 -1
- package/server/applications/shares/services/shares-manager.service.spec.js +10 -3
- package/server/applications/shares/services/shares-manager.service.spec.js.map +1 -1
- package/server/applications/shares/services/shares-queries.service.js +11 -1
- package/server/applications/shares/services/shares-queries.service.js.map +1 -1
- package/server/applications/spaces/guards/space.guard.spec.js +2 -2
- package/server/applications/spaces/guards/space.guard.spec.js.map +1 -1
- package/server/applications/spaces/services/spaces-browser.service.js +31 -11
- package/server/applications/spaces/services/spaces-browser.service.js.map +1 -1
- package/server/applications/spaces/services/spaces-manager.service.js +2 -2
- package/server/applications/spaces/services/spaces-manager.service.js.map +1 -1
- package/server/applications/spaces/services/spaces-queries.service.js +6 -2
- package/server/applications/spaces/services/spaces-queries.service.js.map +1 -1
- package/server/applications/spaces/utils/permissions.js +2 -2
- package/server/applications/spaces/utils/permissions.js.map +1 -1
- package/server/applications/sync/services/sync-manager.service.js +1 -0
- package/server/applications/sync/services/sync-manager.service.js.map +1 -1
- package/server/applications/sync/services/sync-paths-manager.service.js +1 -1
- package/server/applications/sync/services/sync-paths-manager.service.js.map +1 -1
- package/server/applications/sync/services/sync-paths-manager.service.spec.js +1 -1
- package/server/applications/sync/services/sync-paths-manager.service.spec.js.map +1 -1
- package/server/applications/users/constants/user.js +1 -1
- package/server/applications/users/constants/user.js.map +1 -1
- package/server/applications/users/services/admin-users-queries.service.js +8 -0
- package/server/applications/users/services/admin-users-queries.service.js.map +1 -1
- package/server/applications/users/services/users-manager.service.js +1 -2
- package/server/applications/users/services/users-manager.service.js.map +1 -1
- package/server/applications/users/services/users-queries.service.js +67 -68
- package/server/applications/users/services/users-queries.service.js.map +1 -1
- package/server/applications/users/users.gateway.js +6 -0
- package/server/applications/users/users.gateway.js.map +1 -1
- package/server/applications/users/users.module.js +2 -1
- package/server/applications/users/users.module.js.map +1 -1
- package/server/applications/webdav/guards/webdav-protocol.guard.js +4 -4
- package/server/applications/webdav/guards/webdav-protocol.guard.js.map +1 -1
- package/server/applications/webdav/guards/webdav-protocol.guard.spec.js +6 -6
- package/server/applications/webdav/guards/webdav-protocol.guard.spec.js.map +1 -1
- package/server/applications/webdav/services/webdav-methods.service.js +3 -2
- package/server/applications/webdav/services/webdav-methods.service.js.map +1 -1
- package/server/applications/webdav/services/webdav-methods.service.spec.js +2 -2
- package/server/applications/webdav/services/webdav-methods.service.spec.js.map +1 -1
- package/server/authentication/constants/auth-ldap.js +2 -0
- package/server/authentication/constants/auth-ldap.js.map +1 -1
- package/server/authentication/services/auth-methods/auth-method-ldap.service.js +34 -21
- package/server/authentication/services/auth-methods/auth-method-ldap.service.js.map +1 -1
- package/server/common/functions.js +0 -8
- package/server/common/functions.js.map +1 -1
- package/server/common/image.js +63 -58
- package/server/common/image.js.map +1 -1
- package/server/common/shared.js +18 -1
- package/server/common/shared.js.map +1 -1
- package/server/infrastructure/context/services/context-manager.service.js +3 -0
- package/server/infrastructure/context/services/context-manager.service.js.map +1 -1
- package/server/infrastructure/websocket/adapters/cluster.adapter.js +4 -4
- package/server/infrastructure/websocket/adapters/cluster.adapter.js.map +1 -1
- package/static/3rdpartylicenses.txt +1380 -57
- package/static/assets/favicon.svg +2 -25
- package/static/assets/logo-dark.svg +2 -32
- package/static/assets/logo.svg +2 -32
- package/static/assets/mimes/application-sql.svg +29 -1
- package/static/assets/mimes/application-x-sql.svg +29 -0
- package/static/assets/mimes/image-bmp.svg +12 -0
- package/static/assets/pdfjs/build/pdf.mjs +4869 -4454
- package/static/assets/pdfjs/build/pdf.mjs.map +1 -1
- package/static/assets/pdfjs/build/pdf.sandbox.mjs +3 -3
- package/static/assets/pdfjs/build/pdf.sandbox.mjs.map +1 -1
- package/static/assets/pdfjs/build/pdf.worker.mjs +885 -596
- package/static/assets/pdfjs/build/pdf.worker.mjs.map +1 -1
- package/static/assets/pdfjs/version +1 -1
- package/static/assets/pdfjs/web/locale/be/viewer.ftl +40 -0
- package/static/assets/pdfjs/web/locale/bg/viewer.ftl +2 -0
- package/static/assets/pdfjs/web/locale/cs/viewer.ftl +41 -0
- package/static/assets/pdfjs/web/locale/cy/viewer.ftl +43 -0
- package/static/assets/pdfjs/web/locale/da/viewer.ftl +39 -0
- package/static/assets/pdfjs/web/locale/de/viewer.ftl +41 -0
- package/static/assets/pdfjs/web/locale/dsb/viewer.ftl +43 -0
- package/static/assets/pdfjs/web/locale/el/viewer.ftl +39 -0
- package/static/assets/pdfjs/web/locale/en-CA/viewer.ftl +35 -0
- package/static/assets/pdfjs/web/locale/en-GB/viewer.ftl +41 -0
- package/static/assets/pdfjs/web/locale/en-US/viewer.ftl +2 -2
- package/static/assets/pdfjs/web/locale/eo/viewer.ftl +39 -0
- package/static/assets/pdfjs/web/locale/es-AR/viewer.ftl +41 -0
- package/static/assets/pdfjs/web/locale/es-CL/viewer.ftl +39 -0
- package/static/assets/pdfjs/web/locale/es-ES/viewer.ftl +72 -0
- package/static/assets/pdfjs/web/locale/es-MX/viewer.ftl +120 -0
- package/static/assets/pdfjs/web/locale/eu/viewer.ftl +41 -0
- package/static/assets/pdfjs/web/locale/fi/viewer.ftl +41 -0
- package/static/assets/pdfjs/web/locale/fr/viewer.ftl +41 -0
- package/static/assets/pdfjs/web/locale/fur/viewer.ftl +77 -0
- package/static/assets/pdfjs/web/locale/fy-NL/viewer.ftl +41 -0
- package/static/assets/pdfjs/web/locale/gn/viewer.ftl +39 -0
- package/static/assets/pdfjs/web/locale/he/viewer.ftl +41 -0
- package/static/assets/pdfjs/web/locale/hsb/viewer.ftl +43 -0
- package/static/assets/pdfjs/web/locale/hu/viewer.ftl +41 -0
- package/static/assets/pdfjs/web/locale/hy-AM/viewer.ftl +1 -1
- package/static/assets/pdfjs/web/locale/ia/viewer.ftl +41 -0
- package/static/assets/pdfjs/web/locale/it/viewer.ftl +41 -0
- package/static/assets/pdfjs/web/locale/ja/viewer.ftl +32 -0
- package/static/assets/pdfjs/web/locale/ka/viewer.ftl +41 -0
- package/static/assets/pdfjs/web/locale/kab/viewer.ftl +73 -0
- package/static/assets/pdfjs/web/locale/kk/viewer.ftl +21 -0
- package/static/assets/pdfjs/web/locale/ko/viewer.ftl +38 -1
- package/static/assets/pdfjs/web/locale/nb-NO/viewer.ftl +39 -0
- package/static/assets/pdfjs/web/locale/nl/viewer.ftl +41 -0
- package/static/assets/pdfjs/web/locale/nn-NO/viewer.ftl +37 -0
- package/static/assets/pdfjs/web/locale/pa-IN/viewer.ftl +37 -0
- package/static/assets/pdfjs/web/locale/pl/viewer.ftl +39 -0
- package/static/assets/pdfjs/web/locale/pt-BR/viewer.ftl +39 -0
- package/static/assets/pdfjs/web/locale/rm/viewer.ftl +73 -0
- package/static/assets/pdfjs/web/locale/ro/viewer.ftl +41 -0
- package/static/assets/pdfjs/web/locale/ru/viewer.ftl +42 -0
- package/static/assets/pdfjs/web/locale/sc/viewer.ftl +6 -0
- package/static/assets/pdfjs/web/locale/sk/viewer.ftl +43 -0
- package/static/assets/pdfjs/web/locale/sl/viewer.ftl +42 -1
- package/static/assets/pdfjs/web/locale/sq/viewer.ftl +77 -0
- package/static/assets/pdfjs/web/locale/sv-SE/viewer.ftl +41 -0
- package/static/assets/pdfjs/web/locale/tg/viewer.ftl +39 -0
- package/static/assets/pdfjs/web/locale/th/viewer.ftl +35 -0
- package/static/assets/pdfjs/web/locale/tr/viewer.ftl +39 -0
- package/static/assets/pdfjs/web/locale/vi/viewer.ftl +42 -5
- package/static/assets/pdfjs/web/locale/zh-CN/viewer.ftl +35 -0
- package/static/assets/pdfjs/web/locale/zh-TW/viewer.ftl +37 -0
- package/static/assets/pdfjs/web/viewer.css +141 -110
- package/static/assets/pdfjs/web/viewer.html +7 -7
- package/static/assets/pdfjs/web/viewer.mjs +97 -14
- package/static/assets/pdfjs/web/viewer.mjs.map +1 -1
- package/static/chunk-22DWHRCL.js +1 -0
- package/static/chunk-23UUFZSR.js +1 -0
- package/static/{chunk-VM4YX6Q7.js → chunk-24Q7OUU2.js} +1 -1
- package/static/chunk-25QTY2GI.js +1 -0
- package/static/chunk-2E7IJZLL.js +1 -0
- package/static/chunk-2FC5EKS5.js +1 -0
- package/static/chunk-2FOWUJQF.js +1 -0
- package/static/chunk-2XPHUNYN.js +1 -0
- package/static/chunk-32L7RG2G.js +1 -0
- package/static/chunk-3IISSX63.js +1 -0
- package/static/chunk-3OHSTP3R.js +1 -0
- package/static/chunk-42L6C5MT.js +1 -0
- package/static/chunk-4AGQL5GV.js +1 -0
- package/static/chunk-4BPSQMI2.js +1 -0
- package/static/chunk-4FDRWZWT.js +1 -0
- package/static/chunk-4FJUCMEG.js +1 -0
- package/static/chunk-4GCCF6PF.js +1 -0
- package/static/chunk-4ORP3SBY.js +1 -0
- package/static/chunk-4QBOHIC3.js +1 -0
- package/static/chunk-4YT6K5KY.js +1 -0
- package/static/chunk-556I6YIW.js +1 -0
- package/static/chunk-5DPIGJU4.js +1 -0
- package/static/chunk-5HNQLBSW.js +3 -0
- package/static/chunk-5IL7C45D.js +1 -0
- package/static/chunk-5KJXGMKR.js +1 -0
- package/static/chunk-5SPGSHKL.js +1 -0
- package/static/chunk-5WCQBTXW.js +1 -0
- package/static/chunk-5XUIPWOH.js +1 -0
- package/static/chunk-62WT7PI3.js +1 -0
- package/static/chunk-6F6OMQ5H.js +1 -0
- package/static/chunk-6I5BGQHT.js +1 -0
- package/static/chunk-6NOS45DG.js +1 -0
- package/static/chunk-6OKLPRCD.js +1 -0
- package/static/chunk-6VEJCG43.js +1 -0
- package/static/chunk-77SS36Z2.js +1 -0
- package/static/chunk-7AXEPO3G.js +1 -0
- package/static/chunk-7CFSJ4BO.js +1 -0
- package/static/chunk-7CKHC72R.js +1 -0
- package/static/chunk-7DUTYOJG.js +1 -0
- package/static/chunk-7HKFYRPF.js +1 -0
- package/static/chunk-7NZJZATZ.js +1 -0
- package/static/chunk-AADK5D2H.js +1 -0
- package/static/chunk-ACUF7IKP.js +1 -0
- package/static/chunk-AGREZPV4.js +1 -0
- package/static/chunk-ATBJWFA3.js +1 -0
- package/static/chunk-ATXLZN2B.js +1 -0
- package/static/chunk-AZ5TF5Y3.js +1 -0
- package/static/chunk-BBHYIURC.js +1 -0
- package/static/chunk-BHZEPHRI.js +13 -0
- package/static/chunk-BQZWSZNN.js +1 -0
- package/static/chunk-BSB4VROD.js +2 -0
- package/static/chunk-BYWSTP3P.js +1 -0
- package/static/chunk-C3AAEQKW.js +1 -0
- package/static/chunk-CCGGCHGN.js +1 -0
- package/static/chunk-CFTKW432.js +1 -0
- package/static/chunk-CNOVT6KU.js +1 -0
- package/static/chunk-D56H3XE2.js +1 -0
- package/static/chunk-DFOOSIIA.js +1 -0
- package/static/chunk-DHFQIFOF.js +1 -0
- package/static/{chunk-3GMLWAFZ.js → chunk-DIC2MVRI.js} +1 -1
- package/static/chunk-DJDRX53V.js +2 -0
- package/static/chunk-DKGXUMLT.js +1 -0
- package/static/chunk-DRHPEERW.js +2 -0
- package/static/chunk-DWYP6ZGG.js +1 -0
- package/static/chunk-EDJAISWO.js +13 -0
- package/static/chunk-EIYRBM4J.js +1 -0
- package/static/chunk-EKEGRXCV.js +7 -0
- package/static/chunk-EL6QL4TP.js +1 -0
- package/static/chunk-ERDZ7IVF.js +1 -0
- package/static/chunk-EVQKKVUZ.js +1 -0
- package/static/chunk-F2XG7EWI.js +1 -0
- package/static/chunk-F672FY5I.js +1 -0
- package/static/chunk-F6V37MKG.js +1 -0
- package/static/chunk-F7TXTNZC.js +1 -0
- package/static/chunk-FCGTI42I.js +1 -0
- package/static/chunk-FQHOSSCO.js +1 -0
- package/static/chunk-FTSIPHMG.js +1 -0
- package/static/chunk-GAGHHYLF.js +1 -0
- package/static/{chunk-JPT5WEAT.js → chunk-GOJYWL2M.js} +1 -1
- package/static/chunk-H6WOTGQ5.js +1 -0
- package/static/{chunk-CHJ64RJM.js → chunk-H6ZXFINQ.js} +1 -1
- package/static/chunk-HC7F57NA.js +1 -0
- package/static/chunk-HHWXIK2M.js +7 -0
- package/static/chunk-HKRGIRKB.js +3 -0
- package/static/chunk-HNMGPG72.js +1 -0
- package/static/chunk-HS4S6BV3.js +1 -0
- package/static/chunk-IJ7K7ATQ.js +1 -0
- package/static/chunk-IOIBQGHN.js +562 -0
- package/static/chunk-ITVA26X2.js +2 -0
- package/static/chunk-J6YSFHLZ.js +1 -0
- package/static/chunk-JAEJ6IMV.js +1 -0
- package/static/chunk-JB5R6V33.js +1 -0
- package/static/chunk-JF6WIV6M.js +1 -0
- package/static/chunk-JGB4LLUT.js +1 -0
- package/static/chunk-JGXVTKLG.js +1 -0
- package/static/chunk-JMYAD7E2.js +1 -0
- package/static/chunk-JSE63Q5X.js +1 -0
- package/static/chunk-JVV3ZL6L.js +1 -0
- package/static/chunk-JXZCNFW7.js +1 -0
- package/static/chunk-KAVP6UXH.js +1 -0
- package/static/{chunk-WLMNXRBS.js → chunk-KDEEERWZ.js} +1 -1
- package/static/chunk-KHRF67SG.js +1 -0
- package/static/chunk-KLOUBIO4.js +1 -0
- package/static/chunk-KMF3ZRAO.js +1 -0
- package/static/chunk-KNZ3AQPR.js +1 -0
- package/static/chunk-KT3TWCST.js +1 -0
- package/static/chunk-L6SYG23T.js +1 -0
- package/static/chunk-LJSVNPPQ.js +1 -0
- package/static/{chunk-LNTUR3GU.js → chunk-LRDKG274.js} +1 -1
- package/static/chunk-LRQSPCYZ.js +1 -0
- package/static/chunk-LUSVISM6.js +1 -0
- package/static/chunk-LXQGVNU2.js +1 -0
- package/static/{chunk-BIKLW4YS.js → chunk-LYZGJZNP.js} +1 -1
- package/static/chunk-LZKI5P5T.js +1 -0
- package/static/chunk-M4XL3JN5.js +6 -0
- package/static/{chunk-UNCPXHHT.js → chunk-MGWG7OD7.js} +1 -1
- package/static/chunk-MKUUWY6Y.js +1 -0
- package/static/{chunk-HAS5ZOTR.js → chunk-MNNCSSHN.js} +1 -1
- package/static/chunk-MR3U7TKQ.js +1 -0
- package/static/chunk-MRF3CNLZ.js +1 -0
- package/static/chunk-MRMSMTWD.js +1 -0
- package/static/chunk-MVZJSG5R.js +1 -0
- package/static/chunk-MYM43ENO.js +1 -0
- package/static/chunk-N3P6P6GW.js +7 -0
- package/static/chunk-NAH4V2R6.js +2 -0
- package/static/chunk-NBBDVVUF.js +1 -0
- package/static/chunk-NMF2ZFBE.js +1 -0
- package/static/chunk-NN4ONTOT.js +1 -0
- package/static/chunk-NOPACN4F.js +1 -0
- package/static/chunk-NYJPOP4L.js +1 -0
- package/static/chunk-OJCAIKUK.js +1 -0
- package/static/chunk-OQRWXCLY.js +1 -0
- package/static/chunk-PCFH5HCI.js +2 -0
- package/static/chunk-PG54TWBO.js +4 -0
- package/static/chunk-PJF5XUTO.js +1 -0
- package/static/{chunk-FJE6BOFL.js → chunk-PSUAQBYM.js} +1 -1
- package/static/chunk-PTLYIUFW.js +1 -0
- package/static/chunk-PZGLDZZM.js +1 -0
- package/static/chunk-Q4VNZGFI.js +1 -0
- package/static/chunk-Q556XB3S.js +1 -0
- package/static/{chunk-PB4AIT7O.js → chunk-Q7IXRPOO.js} +1 -1
- package/static/chunk-Q7U2VPIS.js +1 -0
- package/static/chunk-QM6CQMEX.js +1 -0
- package/static/chunk-QMHUIHSR.js +1 -0
- package/static/chunk-QNFNXDSX.js +1 -0
- package/static/chunk-QVFPHTOH.js +1 -0
- package/static/chunk-R4MI25E2.js +1 -0
- package/static/chunk-R7JRAR3P.js +1 -0
- package/static/chunk-R7PNKQU2.js +1 -0
- package/static/chunk-RCAORRB7.js +1 -0
- package/static/chunk-RK7XRDNB.js +1 -0
- package/static/chunk-RO7SAOLK.js +1 -0
- package/static/chunk-RQUUINHV.js +1 -0
- package/static/chunk-RT3K6DZR.js +1 -0
- package/static/chunk-RUN556VW.js +1 -0
- package/static/chunk-RX3YQ67K.js +1 -0
- package/static/chunk-S6EVLDHA.js +5 -0
- package/static/chunk-S7S5M3AZ.js +1 -0
- package/static/chunk-SBLNYV74.js +1 -0
- package/static/chunk-SIZCHHUA.js +1 -0
- package/static/chunk-SRBOO7AO.js +1 -0
- package/static/{chunk-PVDHBQRM.js → chunk-STA7NTYL.js} +1 -1
- package/static/chunk-T3YI3BSS.js +1 -0
- package/static/chunk-T74SMT7I.js +1 -0
- package/static/chunk-TAL3RTTQ.js +1 -0
- package/static/chunk-TJZKTNNS.js +1 -0
- package/static/chunk-UJTFWZEC.js +1 -0
- package/static/chunk-UPGVU5LG.js +1 -0
- package/static/chunk-UQ6O3I6W.js +1 -0
- package/static/{chunk-5NMSIIQB.js → chunk-V43RGNXA.js} +1 -1
- package/static/chunk-VWIRXLNE.js +1 -0
- package/static/chunk-VZMVGIVW.js +1 -0
- package/static/chunk-VZPCXSRG.js +2 -0
- package/static/chunk-WR3MA3L3.js +1 -0
- package/static/chunk-XCLK7NJL.js +1 -0
- package/static/{chunk-DSWEWLXJ.js → chunk-XCPDPB5G.js} +1 -1
- package/static/chunk-XEGHEUP5.js +1 -0
- package/static/chunk-XKEBQNQJ.js +1 -0
- package/static/chunk-XOF4UW3S.js +1 -0
- package/static/chunk-XOTKK2NJ.js +1 -0
- package/static/chunk-XX7JXKA6.js +1 -0
- package/static/chunk-Y2I36A4K.js +1 -0
- package/static/chunk-Y44XDRM5.js +1 -0
- package/static/{chunk-QO6BTONN.js → chunk-Y4MAPE2C.js} +1 -1
- package/static/chunk-Y5RLD72B.js +1 -0
- package/static/{chunk-DPUVSXRB.js → chunk-Y5XTRCFK.js} +1 -1
- package/static/chunk-Y63UUJGJ.js +1 -0
- package/static/chunk-YBNAC7QM.js +1 -0
- package/static/chunk-YCTCESL4.js +1 -0
- package/static/chunk-YMAN4LIU.js +1 -0
- package/static/chunk-YTDE6SXT.js +1 -0
- package/static/chunk-YZPIUJB3.js +1 -0
- package/static/chunk-ZCOWBVOT.js +1 -0
- package/static/chunk-ZHRYYMYE.js +1 -0
- package/static/chunk-ZNXTOQFG.js +1 -0
- package/static/{chunk-URHTCJ7G.js → chunk-ZQLBPLXI.js} +1 -1
- package/static/favicon.ico +0 -0
- package/static/index.html +2 -2
- package/static/main-3PLRDZTO.js +11 -0
- package/static/styles-Q4OZOSSK.css +1 -0
- package/server/applications/notifications/interfaces/user-mail-notification.js.map +0 -1
- package/static/assets/codemirror/mode/apl/apl.js +0 -174
- package/static/assets/codemirror/mode/asciiarmor/asciiarmor.js +0 -74
- package/static/assets/codemirror/mode/asn.1/asn.1.js +0 -204
- package/static/assets/codemirror/mode/asterisk/asterisk.js +0 -220
- package/static/assets/codemirror/mode/brainfuck/brainfuck.js +0 -85
- package/static/assets/codemirror/mode/clike/clike.js +0 -942
- package/static/assets/codemirror/mode/clojure/clojure.js +0 -293
- package/static/assets/codemirror/mode/cmake/cmake.js +0 -97
- package/static/assets/codemirror/mode/cobol/cobol.js +0 -255
- package/static/assets/codemirror/mode/coffeescript/coffeescript.js +0 -359
- package/static/assets/codemirror/mode/commonlisp/commonlisp.js +0 -125
- package/static/assets/codemirror/mode/crystal/crystal.js +0 -433
- package/static/assets/codemirror/mode/css/css.js +0 -862
- package/static/assets/codemirror/mode/cypher/cypher.js +0 -152
- package/static/assets/codemirror/mode/d/d.js +0 -223
- package/static/assets/codemirror/mode/dart/dart.js +0 -168
- package/static/assets/codemirror/mode/diff/diff.js +0 -47
- package/static/assets/codemirror/mode/django/django.js +0 -356
- package/static/assets/codemirror/mode/dockerfile/dockerfile.js +0 -211
- package/static/assets/codemirror/mode/dtd/dtd.js +0 -142
- package/static/assets/codemirror/mode/dylan/dylan.js +0 -352
- package/static/assets/codemirror/mode/ebnf/ebnf.js +0 -195
- package/static/assets/codemirror/mode/ecl/ecl.js +0 -206
- package/static/assets/codemirror/mode/eiffel/eiffel.js +0 -160
- package/static/assets/codemirror/mode/elm/elm.js +0 -245
- package/static/assets/codemirror/mode/erlang/erlang.js +0 -619
- package/static/assets/codemirror/mode/factor/factor.js +0 -85
- package/static/assets/codemirror/mode/fcl/fcl.js +0 -173
- package/static/assets/codemirror/mode/forth/forth.js +0 -180
- package/static/assets/codemirror/mode/fortran/fortran.js +0 -188
- package/static/assets/codemirror/mode/gas/gas.js +0 -355
- package/static/assets/codemirror/mode/gfm/gfm.js +0 -129
- package/static/assets/codemirror/mode/gherkin/gherkin.js +0 -194
- package/static/assets/codemirror/mode/go/go.js +0 -187
- package/static/assets/codemirror/mode/groovy/groovy.js +0 -245
- package/static/assets/codemirror/mode/haml/haml.js +0 -161
- package/static/assets/codemirror/mode/handlebars/handlebars.js +0 -70
- package/static/assets/codemirror/mode/haskell/haskell.js +0 -268
- package/static/assets/codemirror/mode/haskell-literate/haskell-literate.js +0 -43
- package/static/assets/codemirror/mode/haxe/haxe.js +0 -515
- package/static/assets/codemirror/mode/htmlembedded/htmlembedded.js +0 -37
- package/static/assets/codemirror/mode/htmlmixed/htmlmixed.js +0 -153
- package/static/assets/codemirror/mode/http/http.js +0 -113
- package/static/assets/codemirror/mode/idl/idl.js +0 -290
- package/static/assets/codemirror/mode/javascript/javascript.js +0 -960
- package/static/assets/codemirror/mode/jinja2/jinja2.js +0 -193
- package/static/assets/codemirror/mode/jsx/jsx.js +0 -149
- package/static/assets/codemirror/mode/julia/julia.js +0 -390
- package/static/assets/codemirror/mode/livescript/livescript.js +0 -280
- package/static/assets/codemirror/mode/lua/lua.js +0 -160
- package/static/assets/codemirror/mode/markdown/markdown.js +0 -886
- package/static/assets/codemirror/mode/mathematica/mathematica.js +0 -176
- package/static/assets/codemirror/mode/mbox/mbox.js +0 -129
- package/static/assets/codemirror/mode/meta.js +0 -221
- package/static/assets/codemirror/mode/mirc/mirc.js +0 -193
- package/static/assets/codemirror/mode/mllike/mllike.js +0 -359
- package/static/assets/codemirror/mode/modelica/modelica.js +0 -245
- package/static/assets/codemirror/mode/mscgen/mscgen.js +0 -175
- package/static/assets/codemirror/mode/mumps/mumps.js +0 -148
- package/static/assets/codemirror/mode/nginx/nginx.js +0 -178
- package/static/assets/codemirror/mode/nsis/nsis.js +0 -95
- package/static/assets/codemirror/mode/ntriples/ntriples.js +0 -195
- package/static/assets/codemirror/mode/octave/octave.js +0 -139
- package/static/assets/codemirror/mode/oz/oz.js +0 -252
- package/static/assets/codemirror/mode/pascal/pascal.js +0 -136
- package/static/assets/codemirror/mode/pegjs/pegjs.js +0 -111
- package/static/assets/codemirror/mode/perl/perl.js +0 -836
- package/static/assets/codemirror/mode/php/php.js +0 -234
- package/static/assets/codemirror/mode/pig/pig.js +0 -178
- package/static/assets/codemirror/mode/powershell/powershell.js +0 -398
- package/static/assets/codemirror/mode/properties/properties.js +0 -78
- package/static/assets/codemirror/mode/protobuf/protobuf.js +0 -72
- package/static/assets/codemirror/mode/pug/pug.js +0 -591
- package/static/assets/codemirror/mode/puppet/puppet.js +0 -220
- package/static/assets/codemirror/mode/python/python.js +0 -402
- package/static/assets/codemirror/mode/q/q.js +0 -139
- package/static/assets/codemirror/mode/r/r.js +0 -190
- package/static/assets/codemirror/mode/rpm/changes/index.html +0 -66
- package/static/assets/codemirror/mode/rpm/rpm.js +0 -109
- package/static/assets/codemirror/mode/rst/rst.js +0 -557
- package/static/assets/codemirror/mode/ruby/ruby.js +0 -303
- package/static/assets/codemirror/mode/rust/rust.js +0 -72
- package/static/assets/codemirror/mode/sas/sas.js +0 -303
- package/static/assets/codemirror/mode/sass/sass.js +0 -459
- package/static/assets/codemirror/mode/scheme/scheme.js +0 -284
- package/static/assets/codemirror/mode/shell/shell.js +0 -168
- package/static/assets/codemirror/mode/sieve/sieve.js +0 -193
- package/static/assets/codemirror/mode/slim/slim.js +0 -575
- package/static/assets/codemirror/mode/smalltalk/smalltalk.js +0 -168
- package/static/assets/codemirror/mode/smarty/smarty.js +0 -225
- package/static/assets/codemirror/mode/solr/solr.js +0 -104
- package/static/assets/codemirror/mode/soy/soy.js +0 -665
- package/static/assets/codemirror/mode/sparql/sparql.js +0 -184
- package/static/assets/codemirror/mode/spreadsheet/spreadsheet.js +0 -112
- package/static/assets/codemirror/mode/sql/sql.js +0 -529
- package/static/assets/codemirror/mode/stex/stex.js +0 -264
- package/static/assets/codemirror/mode/stylus/stylus.js +0 -775
- package/static/assets/codemirror/mode/swift/swift.js +0 -221
- package/static/assets/codemirror/mode/tcl/tcl.js +0 -140
- package/static/assets/codemirror/mode/textile/textile.js +0 -469
- package/static/assets/codemirror/mode/tiddlywiki/tiddlywiki.css +0 -14
- package/static/assets/codemirror/mode/tiddlywiki/tiddlywiki.js +0 -308
- package/static/assets/codemirror/mode/tiki/tiki.css +0 -26
- package/static/assets/codemirror/mode/tiki/tiki.js +0 -312
- package/static/assets/codemirror/mode/toml/toml.js +0 -88
- package/static/assets/codemirror/mode/tornado/tornado.js +0 -68
- package/static/assets/codemirror/mode/troff/troff.js +0 -84
- package/static/assets/codemirror/mode/ttcn/ttcn.js +0 -283
- package/static/assets/codemirror/mode/ttcn-cfg/ttcn-cfg.js +0 -214
- package/static/assets/codemirror/mode/turtle/turtle.js +0 -162
- package/static/assets/codemirror/mode/twig/twig.js +0 -141
- package/static/assets/codemirror/mode/vb/vb.js +0 -275
- package/static/assets/codemirror/mode/vbscript/vbscript.js +0 -350
- package/static/assets/codemirror/mode/velocity/velocity.js +0 -202
- package/static/assets/codemirror/mode/verilog/verilog.js +0 -781
- package/static/assets/codemirror/mode/vhdl/vhdl.js +0 -189
- package/static/assets/codemirror/mode/vue/vue.js +0 -77
- package/static/assets/codemirror/mode/wast/wast.js +0 -132
- package/static/assets/codemirror/mode/webidl/webidl.js +0 -195
- package/static/assets/codemirror/mode/xml/xml.js +0 -417
- package/static/assets/codemirror/mode/xquery/xquery.js +0 -448
- package/static/assets/codemirror/mode/yacas/yacas.js +0 -204
- package/static/assets/codemirror/mode/yaml/yaml.js +0 -120
- package/static/assets/codemirror/mode/yaml-frontmatter/yaml-frontmatter.js +0 -72
- package/static/assets/codemirror/mode/z80/z80.js +0 -116
- package/static/chunk-2KLC4T2Z.js +0 -1
- package/static/chunk-373XVRXW.js +0 -1
- package/static/chunk-3XVM35O2.js +0 -1
- package/static/chunk-3YVRP3VM.js +0 -2
- package/static/chunk-AF24EYXU.js +0 -1
- package/static/chunk-AKQVEHO6.js +0 -2
- package/static/chunk-AY2SZ3G6.js +0 -1
- package/static/chunk-BCVX464U.js +0 -2
- package/static/chunk-C36MW4ME.js +0 -562
- package/static/chunk-DKSEQTMX.js +0 -1
- package/static/chunk-FZ3JPGYZ.js +0 -1
- package/static/chunk-GUGNR5TF.js +0 -3
- package/static/chunk-H6NE33VX.js +0 -1
- package/static/chunk-HNQRZALS.js +0 -1
- package/static/chunk-JSWCNGXJ.js +0 -1
- package/static/chunk-KFJIQIGR.js +0 -1
- package/static/chunk-LVM4QB22.js +0 -1
- package/static/chunk-M3XVNQZQ.js +0 -1
- package/static/chunk-MFLIJH6T.js +0 -1
- package/static/chunk-MSUHTBB2.js +0 -1
- package/static/chunk-N3U6637P.js +0 -1
- package/static/chunk-NNV4OXSB.js +0 -1
- package/static/chunk-NO2LTNW3.js +0 -1
- package/static/chunk-OOGP4WSH.js +0 -2
- package/static/chunk-PCWDQPOM.js +0 -2
- package/static/chunk-PGZZP5W3.js +0 -1
- package/static/chunk-Q5KM7LTX.js +0 -1
- package/static/chunk-QHC6ZPQ4.js +0 -1
- package/static/chunk-QZU2S5CV.js +0 -1
- package/static/chunk-SBZ572Q4.js +0 -2
- package/static/chunk-SHIVUDP3.js +0 -1
- package/static/chunk-SLHTEGRU.js +0 -1
- package/static/chunk-SSFF27P2.js +0 -24
- package/static/chunk-TPYBFZS5.js +0 -1
- package/static/chunk-UEQCWMXD.js +0 -1
- package/static/chunk-UG5DMXYO.js +0 -1
- package/static/chunk-UJPPR4MX.js +0 -1
- package/static/chunk-V3AT2BKP.js +0 -1
- package/static/chunk-VKK5BSLX.js +0 -1
- package/static/chunk-WJW7CT6G.js +0 -27
- package/static/chunk-X5XGK6T7.js +0 -4
- package/static/chunk-YEKR5OPO.js +0 -1
- package/static/chunk-YW57T2PF.js +0 -1
- package/static/chunk-Z5J5F5SX.js +0 -1
- package/static/chunk-ZPF2DSQV.js +0 -1
- package/static/chunk-ZTCRGJ6Y.js +0 -7
- package/static/main-VOL6OMJ5.js +0 -9
- package/static/scripts-WRDOQIU5.js +0 -24
- package/static/styles-2C2UNCNB.css +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../backend/src/applications/sync/services/sync-paths-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 { HttpException, HttpStatus, Injectable, Logger } from '@nestjs/common'\nimport { ACTION } from '../../../common/constants'\nimport { currentTimeStamp } from '../../../common/shared'\nimport { ContextManager } from '../../../infrastructure/context/services/context-manager.service'\nimport type { FileProps } from '../../files/interfaces/file-props.interface'\nimport { FilesQueries } from '../../files/services/files-queries.service'\nimport { getProps, isPathExists, isPathIsDir } from '../../files/utils/files'\nimport { NOTIFICATION_APP, NOTIFICATION_APP_EVENT } from '../../notifications/constants/notifications'\nimport { NotificationContent } from '../../notifications/interfaces/notification-properties.interface'\nimport { NotificationsManager } from '../../notifications/services/notifications-manager.service'\nimport { FastifySpaceRequest } from '../../spaces/interfaces/space-request.interface'\nimport { SpaceEnv } from '../../spaces/models/space-env.model'\nimport { SpacesManager } from '../../spaces/services/spaces-manager.service'\nimport { getEnvPermissions } from '../../spaces/utils/permissions'\nimport { UserModel } from '../../users/models/user.model'\nimport { SYNC_PATH_REPOSITORY } from '../constants/sync'\nimport { SyncPathDto, SyncPathUpdateDto } from '../dtos/sync-path.dto'\nimport { SyncDBProps, SyncPathSettings } from '../interfaces/sync-path.interface'\nimport { SyncClient } from '../schemas/sync-client.interface'\nimport { SYNC_PATH_TO_SPACE_SEGMENTS } from '../utils/routes'\nimport { SyncQueries } from './sync-queries.service'\n\n@Injectable()\nexport class SyncPathsManager {\n private readonly logger = new Logger(SyncPathsManager.name)\n\n constructor(\n private readonly contextManager: ContextManager,\n private readonly spacesManager: SpacesManager,\n private readonly filesQueries: FilesQueries,\n private readonly syncQueries: SyncQueries,\n private readonly notificationsManager: NotificationsManager\n ) {}\n\n async createPath(req: FastifySpaceRequest, syncPathDto: SyncPathDto): Promise<{ id: number; permissions: string }> {\n if (!req.user.clientId) {\n throw new HttpException('Client id is missing', HttpStatus.BAD_REQUEST)\n }\n if (req.space.quotaIsExceeded) {\n throw new HttpException('Storage quota exceeded', HttpStatus.INSUFFICIENT_STORAGE)\n }\n if (!(await isPathExists(req.space.realPath))) {\n throw new HttpException(`Remote path not found : ${syncPathDto.remotePath}`, HttpStatus.NOT_FOUND)\n }\n if (!(await isPathIsDir(req.space.realPath))) {\n throw new HttpException('Remote path must be a directory', HttpStatus.BAD_REQUEST)\n }\n const client: SyncClient = await this.syncQueries.getClient(req.user.clientId, req.user.id)\n if (!client) {\n throw new HttpException('Client not found', HttpStatus.NOT_FOUND)\n }\n const syncDBProps: SyncDBProps = await this.getDBProps(req.space)\n\n // important : ensures the right remote path is used and stored\n syncPathDto.remotePath = req.params['*']\n // add permissions (skip end point protection using getEnvPermission)\n syncPathDto.permissions = getEnvPermissions(req.space, req.space.root)\n const pathId = await this.syncQueries.createPath(client.id, syncDBProps, syncPathDto)\n return { id: pathId, permissions: syncPathDto.permissions }\n }\n\n async deletePath(user: UserModel, pathId: number, clientId?: string): Promise<void> {\n clientId = user.clientId || clientId\n if (!clientId) {\n throw new HttpException('Client id is missing', HttpStatus.BAD_REQUEST)\n }\n if (!(await this.syncQueries.clientExistsForOwner(user.id, clientId))) {\n throw new HttpException('You are not allowed to do this action', HttpStatus.FORBIDDEN)\n }\n try {\n await this.syncQueries.deletePath(clientId, pathId)\n } catch (e) {\n this.logger.error(`${this.deletePath.name} - ${e}`)\n throw new HttpException('Unable to remove path', HttpStatus.BAD_REQUEST)\n }\n }\n\n async updatePath(user: UserModel, clientId: string, pathId: number, syncPathUpdateDto: SyncPathUpdateDto): Promise<SyncPathSettings> {\n if (!(await this.syncQueries.clientExistsForOwner(user.id, clientId))) {\n throw new HttpException('You are not allowed to do this action', HttpStatus.FORBIDDEN)\n }\n const syncPathSettings: SyncPathSettings = await this.syncQueries.getPathSettings(clientId, pathId)\n if (!syncPathSettings) {\n throw new HttpException('Sync path not found', HttpStatus.NOT_FOUND)\n }\n // delete possible id\n delete syncPathUpdateDto.id\n // update current path settings\n Object.assign(syncPathSettings, syncPathUpdateDto)\n syncPathSettings.timestamp = currentTimeStamp()\n try {\n await this.syncQueries.updatePathSettings(clientId, pathId, syncPathSettings)\n } catch (e) {\n this.logger.error(`${this.updatePath.name} - ${e}`)\n throw new HttpException('Unable to update path', HttpStatus.INTERNAL_SERVER_ERROR)\n } finally {\n // clear cache\n this.syncQueries.clearCachePathSettings(clientId, pathId)\n }\n return syncPathSettings\n }\n\n async updatePaths(\n user: UserModel,\n syncPathsDto: SyncPathDto[]\n ): Promise<{\n add: SyncPathSettings[]\n update: Partial<Record<keyof SyncPathSettings, any>>[]\n delete: number[]\n }> {\n /* Update the client or server paths */\n if (!user.clientId) {\n throw new HttpException('Client id is missing', HttpStatus.BAD_REQUEST)\n }\n if (!(await this.syncQueries.clientExistsForOwner(user.id, user.clientId))) {\n throw new HttpException('You are not allowed to do this action', HttpStatus.FORBIDDEN)\n }\n const clientPathIds: number[] = syncPathsDto.map((p) => p.id)\n const serverPathIds: number[] = []\n\n const clientDiff: { add: SyncPathSettings[]; update: Partial<Record<keyof SyncPathSettings, any>>[]; delete: number[] } = {\n add: [],\n update: [],\n delete: []\n }\n const serverPaths: { id: number; settings: SyncPathSettings; remotePath: string }[] = await this.syncQueries.getPaths(user.clientId)\n for (const serverPath of serverPaths) {\n if (!serverPath.remotePath) {\n // unable to determine path, will be stored as deleted\n continue\n }\n let space: SpaceEnv\n try {\n space = await this.spacesManager.spaceEnv(user, SYNC_PATH_TO_SPACE_SEGMENTS(serverPath.remotePath), true)\n } catch (e) {\n throw new HttpException(e.message, HttpStatus.BAD_REQUEST)\n }\n if (!space) {\n // removed or inaccessible space, the path will be stored as deleted\n continue\n }\n serverPathIds.push(serverPath.id)\n if (clientPathIds.indexOf(serverPath.id) === -1) {\n // path exists on server but not on client, add it to client\n clientDiff.add.push({ ...serverPath.settings, id: serverPath.id, remotePath: serverPath.remotePath, permissions: space.envPermissions })\n continue\n }\n\n // path exists on both server and client side\n const clientPath: SyncPathDto = syncPathsDto.find((p) => p.id === serverPath.id)\n // remotePath and permissions settings are only managed by server\n const updateClientInfo: { remotePath?: string; permissions?: string } = {\n ...(serverPath.remotePath !== clientPath.remotePath && { remotePath: serverPath.remotePath }),\n ...(space.envPermissions !== clientPath.permissions && { permissions: space.envPermissions })\n }\n const clientNewer = clientPath.timestamp > serverPath.settings.timestamp\n const serverNewer = clientPath.timestamp < serverPath.settings.timestamp\n const hasUpdates = Object.keys(updateClientInfo).length > 0\n\n let updatedSettings: SyncPathSettings = { ...serverPath.settings, ...updateClientInfo }\n\n if (clientNewer) {\n updatedSettings = { ...clientPath, ...updateClientInfo }\n } else if (serverNewer) {\n clientDiff.update.push({ id: clientPath.id, ...serverPath.settings, ...updateClientInfo })\n }\n\n if (clientNewer || hasUpdates || serverPath.settings.lastSync !== clientPath.lastSync) {\n this.syncQueries\n .updatePathSettings(user.clientId, clientPath.id, { ...updatedSettings, lastSync: clientPath.lastSync })\n .catch((e: Error) => this.logger.error(`${this.updatePaths.name} - ${e}`))\n }\n\n if (!clientNewer && hasUpdates) {\n clientDiff.update.push({ id: clientPath.id, ...updateClientInfo })\n }\n }\n // path does not exist on server side\n clientDiff.delete = clientPathIds.filter((cid) => serverPathIds.indexOf(cid) === -1)\n for (const cPathId of clientDiff.delete) {\n const cPath: SyncPathDto = syncPathsDto.find((p) => p.id === cPathId)\n this.notify(user.id, ACTION.DELETE, cPath.remotePath).catch((e: Error) => this.logger.error(`${this.updatePaths.name} - ${e}`))\n }\n // clear cache\n clientDiff.update.forEach((path) => this.syncQueries.clearCachePathSettings(user.clientId, path.id))\n return clientDiff\n }\n\n private async getDBProps(space: SpaceEnv): Promise<SyncDBProps> {\n if (space.inSharesList) {\n throw new HttpException('Sync all shares is not supported, you must select a sub-directory', HttpStatus.BAD_REQUEST)\n } else if (space.inPersonalSpace) {\n if (space.paths.length) {\n return { ownerId: space.dbFile.ownerId, fileId: await this.getOrCreateFileId(space) }\n } else {\n return { ownerId: space.dbFile.ownerId }\n }\n } else if (space.inFilesRepository) {\n if (!space?.root?.alias) {\n // The synchronization direction should be adapted for each root depending on the permissions, this is not yet supported\n throw new HttpException('Sync all space is not yet supported, you must select a sub-directory', HttpStatus.BAD_REQUEST)\n }\n if (space.root.id && !space.paths.length) {\n return { spaceId: space.id, spaceRootId: space.root.id }\n } else {\n return { spaceId: space.id, spaceRootId: space?.root?.id || null, fileId: await this.getOrCreateFileId(space) }\n }\n } else if (space.inSharesRepository) {\n if (space.paths.length) {\n return { shareId: space.id, fileId: await this.getOrCreateFileId(space) }\n } else {\n return { shareId: space.id }\n }\n }\n }\n\n private async getOrCreateFileId(space: SpaceEnv): Promise<number> {\n const fileProps: FileProps = await getProps(space.realPath, space.dbFile.path)\n let fileId: number = await this.filesQueries.getSpaceFileId(fileProps, space.dbFile)\n if (!fileId) {\n fileId = await this.filesQueries.getOrCreateSpaceFile(fileId, { ...fileProps, id: undefined }, space.dbFile)\n }\n return fileId\n }\n\n private async notify(userId: number, action: ACTION, remotePath: string) {\n const notification: NotificationContent = {\n app: NOTIFICATION_APP.SYNC,\n event: NOTIFICATION_APP_EVENT.SYNC[action],\n element: remotePath,\n url: [...SYNC_PATH_REPOSITORY[remotePath.split('/').at(0)], ...remotePath.split('/').slice(1, -1)].join('/')\n }\n this.notificationsManager\n .create([userId], notification, {\n currentUrl: this.contextManager.get('headerOriginUrl'),\n action: action\n })\n .catch((e: Error) => this.logger.error(`${this.notify.name} - ${e}`))\n }\n}\n"],"names":["SyncPathsManager","createPath","req","syncPathDto","user","clientId","HttpException","HttpStatus","BAD_REQUEST","space","quotaIsExceeded","INSUFFICIENT_STORAGE","isPathExists","realPath","remotePath","NOT_FOUND","isPathIsDir","client","syncQueries","getClient","id","syncDBProps","getDBProps","params","permissions","getEnvPermissions","root","pathId","deletePath","clientExistsForOwner","FORBIDDEN","e","logger","error","name","updatePath","syncPathUpdateDto","syncPathSettings","getPathSettings","Object","assign","timestamp","currentTimeStamp","updatePathSettings","INTERNAL_SERVER_ERROR","clearCachePathSettings","updatePaths","syncPathsDto","clientPathIds","map","p","serverPathIds","clientDiff","add","update","delete","serverPaths","getPaths","serverPath","spacesManager","spaceEnv","SYNC_PATH_TO_SPACE_SEGMENTS","message","push","indexOf","settings","envPermissions","clientPath","find","updateClientInfo","clientNewer","serverNewer","hasUpdates","keys","length","updatedSettings","lastSync","catch","filter","cid","cPathId","cPath","notify","ACTION","DELETE","forEach","path","inSharesList","inPersonalSpace","paths","ownerId","dbFile","fileId","getOrCreateFileId","inFilesRepository","alias","spaceId","spaceRootId","inSharesRepository","shareId","fileProps","getProps","filesQueries","getSpaceFileId","getOrCreateSpaceFile","undefined","userId","action","notification","app","NOTIFICATION_APP","SYNC","event","NOTIFICATION_APP_EVENT","element","url","SYNC_PATH_REPOSITORY","split","at","slice","join","notificationsManager","create","currentUrl","contextManager","get","Logger"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../../backend/src/applications/sync/services/sync-paths-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 { HttpException, HttpStatus, Injectable, Logger } from '@nestjs/common'\nimport { ACTION } from '../../../common/constants'\nimport { currentTimeStamp } from '../../../common/shared'\nimport { ContextManager } from '../../../infrastructure/context/services/context-manager.service'\nimport type { FileProps } from '../../files/interfaces/file-props.interface'\nimport { FilesQueries } from '../../files/services/files-queries.service'\nimport { getProps, isPathExists, isPathIsDir } from '../../files/utils/files'\nimport { NOTIFICATION_APP, NOTIFICATION_APP_EVENT } from '../../notifications/constants/notifications'\nimport { NotificationContent } from '../../notifications/interfaces/notification-properties.interface'\nimport { NotificationsManager } from '../../notifications/services/notifications-manager.service'\nimport { FastifySpaceRequest } from '../../spaces/interfaces/space-request.interface'\nimport { SpaceEnv } from '../../spaces/models/space-env.model'\nimport { SpacesManager } from '../../spaces/services/spaces-manager.service'\nimport { getEnvPermissions } from '../../spaces/utils/permissions'\nimport { UserModel } from '../../users/models/user.model'\nimport { SYNC_PATH_REPOSITORY } from '../constants/sync'\nimport { SyncPathDto, SyncPathUpdateDto } from '../dtos/sync-path.dto'\nimport { SyncDBProps, SyncPathSettings } from '../interfaces/sync-path.interface'\nimport { SyncClient } from '../schemas/sync-client.interface'\nimport { SYNC_PATH_TO_SPACE_SEGMENTS } from '../utils/routes'\nimport { SyncQueries } from './sync-queries.service'\n\n@Injectable()\nexport class SyncPathsManager {\n private readonly logger = new Logger(SyncPathsManager.name)\n\n constructor(\n private readonly contextManager: ContextManager,\n private readonly spacesManager: SpacesManager,\n private readonly filesQueries: FilesQueries,\n private readonly syncQueries: SyncQueries,\n private readonly notificationsManager: NotificationsManager\n ) {}\n\n async createPath(req: FastifySpaceRequest, syncPathDto: SyncPathDto): Promise<{ id: number; permissions: string }> {\n if (!req.user.clientId) {\n throw new HttpException('Client id is missing', HttpStatus.BAD_REQUEST)\n }\n if (req.space.quotaIsExceeded) {\n throw new HttpException('Storage quota exceeded', HttpStatus.INSUFFICIENT_STORAGE)\n }\n if (!(await isPathExists(req.space.realPath))) {\n throw new HttpException(`Remote path not found : ${syncPathDto.remotePath}`, HttpStatus.NOT_FOUND)\n }\n if (!(await isPathIsDir(req.space.realPath))) {\n throw new HttpException('Remote path must be a directory', HttpStatus.BAD_REQUEST)\n }\n const client: SyncClient = await this.syncQueries.getClient(req.user.clientId, req.user.id)\n if (!client) {\n throw new HttpException('Client not found', HttpStatus.NOT_FOUND)\n }\n const syncDBProps: SyncDBProps = await this.getDBProps(req.space)\n\n // important : ensures the right remote path is used and stored\n syncPathDto.remotePath = req.params['*']\n // add permissions (skip end point protection using getEnvPermission)\n syncPathDto.permissions = getEnvPermissions(req.space, req.space.root)\n const pathId = await this.syncQueries.createPath(client.id, syncDBProps, syncPathDto)\n return { id: pathId, permissions: syncPathDto.permissions }\n }\n\n async deletePath(user: UserModel, pathId: number, clientId?: string): Promise<void> {\n clientId = user.clientId || clientId\n if (!clientId) {\n throw new HttpException('Client id is missing', HttpStatus.BAD_REQUEST)\n }\n if (!(await this.syncQueries.clientExistsForOwner(user.id, clientId))) {\n throw new HttpException('You are not allowed to do this action', HttpStatus.FORBIDDEN)\n }\n try {\n await this.syncQueries.deletePath(clientId, pathId)\n } catch (e) {\n this.logger.error(`${this.deletePath.name} - ${e}`)\n throw new HttpException('Unable to remove path', HttpStatus.BAD_REQUEST)\n }\n }\n\n async updatePath(user: UserModel, clientId: string, pathId: number, syncPathUpdateDto: SyncPathUpdateDto): Promise<SyncPathSettings> {\n if (!(await this.syncQueries.clientExistsForOwner(user.id, clientId))) {\n throw new HttpException('You are not allowed to do this action', HttpStatus.FORBIDDEN)\n }\n const syncPathSettings: SyncPathSettings = await this.syncQueries.getPathSettings(clientId, pathId)\n if (!syncPathSettings) {\n throw new HttpException('Sync path not found', HttpStatus.NOT_FOUND)\n }\n // delete possible id\n delete syncPathUpdateDto.id\n // update current path settings\n Object.assign(syncPathSettings, syncPathUpdateDto)\n syncPathSettings.timestamp = currentTimeStamp()\n try {\n await this.syncQueries.updatePathSettings(clientId, pathId, syncPathSettings)\n } catch (e) {\n this.logger.error(`${this.updatePath.name} - ${e}`)\n throw new HttpException('Unable to update path', HttpStatus.INTERNAL_SERVER_ERROR)\n } finally {\n // clear cache\n this.syncQueries.clearCachePathSettings(clientId, pathId)\n }\n return syncPathSettings\n }\n\n async updatePaths(\n user: UserModel,\n syncPathsDto: SyncPathDto[]\n ): Promise<{\n add: SyncPathSettings[]\n update: Partial<Record<keyof SyncPathSettings, any>>[]\n delete: number[]\n }> {\n /* Update the client or server paths */\n if (!user.clientId) {\n throw new HttpException('Client id is missing', HttpStatus.BAD_REQUEST)\n }\n if (!(await this.syncQueries.clientExistsForOwner(user.id, user.clientId))) {\n throw new HttpException('You are not allowed to do this action', HttpStatus.FORBIDDEN)\n }\n const clientPathIds: number[] = syncPathsDto.map((p) => p.id)\n const serverPathIds: number[] = []\n\n const clientDiff: { add: SyncPathSettings[]; update: Partial<Record<keyof SyncPathSettings, any>>[]; delete: number[] } = {\n add: [],\n update: [],\n delete: []\n }\n const serverPaths: { id: number; settings: SyncPathSettings; remotePath: string }[] = await this.syncQueries.getPaths(user.clientId)\n for (const serverPath of serverPaths) {\n if (!serverPath.remotePath) {\n // unable to determine path, will be stored as deleted\n continue\n }\n let space: SpaceEnv\n try {\n space = await this.spacesManager.spaceEnv(user, SYNC_PATH_TO_SPACE_SEGMENTS(serverPath.remotePath), true)\n } catch (e) {\n throw new HttpException(e.message, HttpStatus.BAD_REQUEST)\n }\n if (!space) {\n // removed or inaccessible space, the path will be stored as deleted\n continue\n }\n serverPathIds.push(serverPath.id)\n if (clientPathIds.indexOf(serverPath.id) === -1) {\n // path exists on server but not on client, add it to client\n clientDiff.add.push({ ...serverPath.settings, id: serverPath.id, remotePath: serverPath.remotePath, permissions: space.envPermissions })\n continue\n }\n\n // path exists on both server and client side\n const clientPath: SyncPathDto = syncPathsDto.find((p) => p.id === serverPath.id)\n // remotePath and permissions settings are only managed by server\n const updateClientInfo: { remotePath?: string; permissions?: string } = {\n ...(serverPath.remotePath !== clientPath.remotePath && { remotePath: serverPath.remotePath }),\n ...(space.envPermissions !== clientPath.permissions && { permissions: space.envPermissions })\n }\n const clientNewer = clientPath.timestamp > serverPath.settings.timestamp\n const serverNewer = clientPath.timestamp < serverPath.settings.timestamp\n const hasUpdates = Object.keys(updateClientInfo).length > 0\n\n let updatedSettings: SyncPathSettings = { ...serverPath.settings, ...updateClientInfo }\n\n if (clientNewer) {\n updatedSettings = { ...clientPath, ...updateClientInfo }\n } else if (serverNewer) {\n clientDiff.update.push({ id: clientPath.id, ...serverPath.settings, ...updateClientInfo })\n }\n\n if (clientNewer || hasUpdates || serverPath.settings.lastSync !== clientPath.lastSync) {\n this.syncQueries\n .updatePathSettings(user.clientId, clientPath.id, { ...updatedSettings, lastSync: clientPath.lastSync })\n .catch((e: Error) => this.logger.error(`${this.updatePaths.name} - ${e}`))\n }\n\n if (!clientNewer && hasUpdates) {\n clientDiff.update.push({ id: clientPath.id, ...updateClientInfo })\n }\n }\n // path does not exist on server side\n clientDiff.delete = clientPathIds.filter((cid) => serverPathIds.indexOf(cid) === -1)\n for (const cPathId of clientDiff.delete) {\n const cPath: SyncPathDto = syncPathsDto.find((p) => p.id === cPathId)\n this.notify(user.id, ACTION.DELETE, cPath.remotePath).catch((e: Error) => this.logger.error(`${this.updatePaths.name} - ${e}`))\n }\n // clear cache\n clientDiff.update.forEach((path) => this.syncQueries.clearCachePathSettings(user.clientId, path.id))\n return clientDiff\n }\n\n private async getDBProps(space: SpaceEnv): Promise<SyncDBProps> {\n if (space.inSharesList) {\n throw new HttpException('Sync all shares is not supported, you must select a sub-directory', HttpStatus.BAD_REQUEST)\n } else if (space.inPersonalSpace) {\n if (space.paths.length) {\n return { ownerId: space.dbFile.ownerId, fileId: await this.getOrCreateFileId(space) }\n } else {\n return { ownerId: space.dbFile.ownerId }\n }\n } else if (space.inFilesRepository) {\n if (!space?.root?.alias) {\n // The synchronization direction should be adapted for each root depending on the permissions, this is not yet supported\n throw new HttpException('Sync all space is not yet supported, you must select a sub-directory', HttpStatus.BAD_REQUEST)\n }\n if (space.root.id && !space.paths.length) {\n return { spaceId: space.id, spaceRootId: space.root.id }\n } else {\n return { spaceId: space.id, spaceRootId: space?.root?.id || null, fileId: await this.getOrCreateFileId(space) }\n }\n } else if (space.inSharesRepository) {\n if (space.paths.length) {\n return { shareId: space.id, fileId: await this.getOrCreateFileId(space) }\n } else {\n return { shareId: space.id }\n }\n }\n }\n\n private async getOrCreateFileId(space: SpaceEnv): Promise<number> {\n const fileProps: FileProps = await getProps(space.realPath, space.dbFile.path)\n let fileId: number = await this.filesQueries.getSpaceFileId(fileProps, space.dbFile)\n if (!fileId) {\n fileId = await this.filesQueries.getOrCreateSpaceFile(fileId, { ...fileProps, id: undefined }, space.dbFile)\n }\n return fileId\n }\n\n private async notify(userId: number, action: ACTION, remotePath: string) {\n const notification: NotificationContent = {\n app: NOTIFICATION_APP.SYNC,\n event: NOTIFICATION_APP_EVENT.SYNC[action],\n element: remotePath,\n url: [...SYNC_PATH_REPOSITORY[remotePath.split('/').at(0)], ...remotePath.split('/').slice(1, -1)].join('/')\n }\n this.notificationsManager\n .create([userId], notification, {\n currentUrl: this.contextManager.headerOriginUrl(),\n action: action\n })\n .catch((e: Error) => this.logger.error(`${this.notify.name} - ${e}`))\n }\n}\n"],"names":["SyncPathsManager","createPath","req","syncPathDto","user","clientId","HttpException","HttpStatus","BAD_REQUEST","space","quotaIsExceeded","INSUFFICIENT_STORAGE","isPathExists","realPath","remotePath","NOT_FOUND","isPathIsDir","client","syncQueries","getClient","id","syncDBProps","getDBProps","params","permissions","getEnvPermissions","root","pathId","deletePath","clientExistsForOwner","FORBIDDEN","e","logger","error","name","updatePath","syncPathUpdateDto","syncPathSettings","getPathSettings","Object","assign","timestamp","currentTimeStamp","updatePathSettings","INTERNAL_SERVER_ERROR","clearCachePathSettings","updatePaths","syncPathsDto","clientPathIds","map","p","serverPathIds","clientDiff","add","update","delete","serverPaths","getPaths","serverPath","spacesManager","spaceEnv","SYNC_PATH_TO_SPACE_SEGMENTS","message","push","indexOf","settings","envPermissions","clientPath","find","updateClientInfo","clientNewer","serverNewer","hasUpdates","keys","length","updatedSettings","lastSync","catch","filter","cid","cPathId","cPath","notify","ACTION","DELETE","forEach","path","inSharesList","inPersonalSpace","paths","ownerId","dbFile","fileId","getOrCreateFileId","inFilesRepository","alias","spaceId","spaceRootId","inSharesRepository","shareId","fileProps","getProps","filesQueries","getSpaceFileId","getOrCreateSpaceFile","undefined","userId","action","notification","app","NOTIFICATION_APP","SYNC","event","NOTIFICATION_APP_EVENT","element","url","SYNC_PATH_REPOSITORY","split","at","slice","join","notificationsManager","create","currentUrl","contextManager","headerOriginUrl","Logger"],"mappings":"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"}
|
|
@@ -71,7 +71,7 @@ describe(_syncpathsmanagerservice.SyncPathsManager.name, ()=>{
|
|
|
71
71
|
const flush = ()=>new Promise((r)=>setImmediate(r));
|
|
72
72
|
beforeEach(async ()=>{
|
|
73
73
|
contextManager = {
|
|
74
|
-
|
|
74
|
+
headerOriginUrl: jest.fn(()=>'http://origin.local')
|
|
75
75
|
};
|
|
76
76
|
spacesManager = {
|
|
77
77
|
spaceEnv: jest.fn()
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../backend/src/applications/sync/services/sync-paths-manager.service.spec.ts"],"sourcesContent":["/*\n * Copyright (C) 2012-2025 Johan Legrand <johan.legrand@sync-in.com>\n * This file is part of Sync-in | The open source file sync and share solution\n * See the LICENSE file for licensing details\n */\n\nimport { HttpStatus } from '@nestjs/common'\nimport { Test, TestingModule } from '@nestjs/testing'\nimport { currentTimeStamp } from '../../../common/shared'\nimport { ContextManager } from '../../../infrastructure/context/services/context-manager.service'\nimport { FilesQueries } from '../../files/services/files-queries.service'\nimport { getProps, isPathExists, isPathIsDir } from '../../files/utils/files'\nimport { NotificationsManager } from '../../notifications/services/notifications-manager.service'\nimport { SpacesManager } from '../../spaces/services/spaces-manager.service'\nimport { getEnvPermissions } from '../../spaces/utils/permissions'\nimport { UsersQueries } from '../../users/services/users-queries.service'\nimport { SyncPathsManager } from './sync-paths-manager.service'\nimport { SyncQueries } from './sync-queries.service'\n\n// Mock modules used directly inside SyncPathsManager\njest.mock('../../../common/shared', () => ({\n currentTimeStamp: jest.fn(() => 1000)\n}))\njest.mock('../../files/utils/files', () => ({\n isPathExists: jest.fn(),\n isPathIsDir: jest.fn(),\n getProps: jest.fn(),\n sanitizePath: jest.fn((p: string) => p)\n}))\njest.mock('../../spaces/utils/permissions', () => ({\n getEnvPermissions: jest.fn(() => 'server-perms')\n}))\njest.mock('../constants/sync', () => ({\n SYNC_PATH_REPOSITORY: {\n SPACES: ['spaces'],\n PERSONAL: ['personal'],\n SHARES: ['shares']\n }\n}))\njest.mock('../../notifications/constants/notifications', () => ({\n NOTIFICATION_APP: { SYNC: 'SYNC' },\n NOTIFICATION_APP_EVENT: { SYNC: { DELETE: 'DELETE', CREATE: 'CREATE', UPDATE: 'UPDATE' } }\n}))\n\ndescribe(SyncPathsManager.name, () => {\n let service: SyncPathsManager\n let contextManager: { get: jest.Mock }\n let spacesManager: { spaceEnv: jest.Mock }\n let usersQueries: Record<string, jest.Mock>\n let filesQueries: { getSpaceFileId: jest.Mock; getOrCreateSpaceFile: jest.Mock }\n let notificationsManager: { create: jest.Mock }\n let syncQueries: {\n getClient: jest.Mock\n clientExistsForOwner: jest.Mock\n createPath: jest.Mock\n deletePath: jest.Mock\n getPaths: jest.Mock\n getPathSettings: jest.Mock\n updatePathSettings: jest.Mock\n clearCachePathSettings: jest.Mock\n }\n\n const userWith = (clientId?: string) => ({ id: 1, clientId })\n const flush = () => new Promise((r) => setImmediate(r))\n\n beforeEach(async () => {\n contextManager = { get: jest.fn(() => 'http://origin.local') }\n spacesManager = { spaceEnv: jest.fn() }\n usersQueries = {}\n filesQueries = {\n getSpaceFileId: jest.fn(),\n getOrCreateSpaceFile: jest.fn()\n }\n notificationsManager = {\n create: jest.fn().mockResolvedValue(undefined)\n }\n syncQueries = {\n getClient: jest.fn(),\n clientExistsForOwner: jest.fn(),\n createPath: jest.fn(),\n deletePath: jest.fn(),\n getPaths: jest.fn(),\n getPathSettings: jest.fn(),\n updatePathSettings: jest.fn().mockResolvedValue(undefined),\n clearCachePathSettings: jest.fn()\n }\n ;(isPathExists as jest.Mock).mockReset()\n ;(isPathIsDir as jest.Mock).mockReset()\n ;(getProps as jest.Mock).mockReset()\n ;(getEnvPermissions as jest.Mock).mockReset().mockReturnValue('server-perms')\n ;(currentTimeStamp as jest.Mock).mockReset().mockReturnValue(1000)\n\n const module: TestingModule = await Test.createTestingModule({\n providers: [\n SyncPathsManager,\n { provide: ContextManager, useValue: contextManager },\n { provide: SpacesManager, useValue: spacesManager },\n { provide: UsersQueries, useValue: usersQueries },\n { provide: FilesQueries, useValue: filesQueries },\n { provide: NotificationsManager, useValue: notificationsManager },\n { provide: SyncQueries, useValue: syncQueries }\n ]\n }).compile()\n\n module.useLogger(['fatal'])\n service = module.get<SyncPathsManager>(SyncPathsManager)\n })\n\n it('should be defined', () => {\n expect(service).toBeDefined()\n })\n\n describe('createPath', () => {\n const baseReq = () =>\n ({\n user: { id: 1, clientId: 'client-1' },\n params: { '*': 'SPACES/alias/sub' },\n space: {\n realPath: '/real/path',\n quotaIsExceeded: false,\n root: { id: 1, alias: 'alias' },\n inFilesRepository: true,\n paths: ['sub'],\n dbFile: { ownerId: 1, path: '.' },\n id: 10\n }\n }) as any\n\n it('should throw BAD_REQUEST when client id is missing', async () => {\n const req = baseReq()\n req.user.clientId = undefined\n await expect(service.createPath(req, { remotePath: 'x' } as any)).rejects.toMatchObject({\n status: HttpStatus.BAD_REQUEST,\n message: 'Client id is missing'\n })\n })\n\n it('should throw INSUFFICIENT_STORAGE when storage quota is exceeded', async () => {\n const req = baseReq()\n req.space.quotaIsExceeded = true\n await expect(service.createPath(req, { remotePath: 'x' } as any)).rejects.toMatchObject({\n status: HttpStatus.INSUFFICIENT_STORAGE\n })\n })\n\n it.each([\n {\n title: 'NOT_FOUND when remote path does not exist',\n setup: () => (isPathExists as jest.Mock).mockResolvedValue(false),\n expected: { status: HttpStatus.NOT_FOUND, message: 'Remote path not found : client/remote' }\n },\n {\n title: 'BAD_REQUEST when remote path is not a directory',\n setup: () => ((isPathExists as jest.Mock).mockResolvedValue(true), (isPathIsDir as jest.Mock).mockResolvedValue(false)),\n expected: { status: HttpStatus.BAD_REQUEST, message: 'Remote path must be a directory' }\n },\n {\n title: 'NOT_FOUND when client is not found',\n setup: () => (\n (isPathExists as jest.Mock).mockResolvedValue(true),\n (isPathIsDir as jest.Mock).mockResolvedValue(true),\n syncQueries.getClient.mockResolvedValue(null)\n ),\n expected: { status: HttpStatus.NOT_FOUND, message: 'Client not found' }\n }\n ])('should throw $title', async ({ setup, expected }) => {\n const req = baseReq()\n setup()\n await expect(service.createPath(req, { remotePath: 'client/remote' } as any)).rejects.toMatchObject(expected)\n })\n\n it('should create path and return id and permissions, overriding remotePath and permissions', async () => {\n const req = baseReq()\n ;(isPathExists as jest.Mock).mockResolvedValue(true)\n ;(isPathIsDir as jest.Mock).mockResolvedValue(true)\n ;(getEnvPermissions as jest.Mock).mockReturnValue('env-perms')\n syncQueries.getClient.mockResolvedValue({ id: 'client-1' })\n // Spy on private getDBProps to simplify\n const getDBPropsSpy = jest.spyOn<any, any>(service as any, 'getDBProps').mockResolvedValue({ ownerId: 1 })\n syncQueries.createPath.mockResolvedValue(123)\n\n const res = await service.createPath(req, { remotePath: 'client/remote', permissions: 'client-perms' } as any)\n expect(res).toEqual({ id: 123, permissions: 'env-perms' })\n expect(syncQueries.createPath).toHaveBeenCalledWith(\n 'client-1',\n { ownerId: 1 },\n expect.objectContaining({ remotePath: 'SPACES/alias/sub', permissions: 'env-perms' })\n )\n\n getDBPropsSpy.mockRestore()\n })\n })\n\n describe('deletePath', () => {\n it.each([\n { user: { id: 1, clientId: undefined } as any, id: 10, status: HttpStatus.BAD_REQUEST, msg: 'Client id is missing' },\n { user: { id: 1, clientId: 'c1' } as any, id: 10, status: HttpStatus.FORBIDDEN }\n ])('should handle errors (status=$status)', async ({ user, id, status, msg }) => {\n if (status === HttpStatus.FORBIDDEN) syncQueries.clientExistsForOwner.mockResolvedValue(false)\n await expect(service.deletePath(user, id)).rejects.toMatchObject(msg ? { status, message: msg } : { status })\n })\n\n it('should catch errors from deletePath and throw BAD_REQUEST', async () => {\n const user: any = { id: 1, clientId: 'c1' }\n syncQueries.clientExistsForOwner.mockResolvedValue(true)\n syncQueries.deletePath.mockRejectedValue(new Error('db'))\n await expect(service.deletePath(user, 10)).rejects.toMatchObject({\n status: HttpStatus.BAD_REQUEST,\n message: 'Unable to remove path'\n })\n expect(syncQueries.deletePath).toHaveBeenCalledWith('c1', 10)\n })\n\n it('should delete path successfully when allowed', async () => {\n const user: any = { id: 1, clientId: undefined }\n syncQueries.clientExistsForOwner.mockResolvedValue(true)\n syncQueries.deletePath.mockResolvedValue(undefined)\n await expect(service.deletePath(user, 10, 'cX')).resolves.toBeUndefined()\n expect(syncQueries.deletePath).toHaveBeenCalledWith('cX', 10)\n })\n })\n\n describe('updatePath', () => {\n it('should throw FORBIDDEN when client does not belong to owner', async () => {\n syncQueries.clientExistsForOwner.mockResolvedValue(false)\n await expect(service.updatePath({ id: 1 } as any, 'c1', 5, {} as any)).rejects.toMatchObject({\n status: HttpStatus.FORBIDDEN\n })\n })\n\n it('should throw NOT_FOUND when path settings do not exist', async () => {\n syncQueries.clientExistsForOwner.mockResolvedValue(true)\n syncQueries.getPathSettings.mockResolvedValue(null)\n await expect(service.updatePath({ id: 1 } as any, 'c1', 5, {} as any)).rejects.toMatchObject({\n status: HttpStatus.NOT_FOUND,\n message: 'Sync path not found'\n })\n })\n\n it('should update path settings, set new timestamp, clear cache and return updated settings', async () => {\n syncQueries.clientExistsForOwner.mockResolvedValue(true)\n syncQueries.getPathSettings.mockResolvedValue({ id: 5, timestamp: 500, lastSync: 1, remotePath: '/a', permissions: 'p' })\n syncQueries.updatePathSettings.mockResolvedValue(undefined)\n ;(currentTimeStamp as jest.Mock).mockReturnValue(4242)\n\n const out = await service.updatePath({ id: 1 } as any, 'c1', 5, { id: 666, lastSync: 3, permissions: 'new' } as any)\n expect(syncQueries.updatePathSettings).toHaveBeenCalledWith(\n 'c1',\n 5,\n expect.objectContaining({ id: 5, lastSync: 3, timestamp: 4242, permissions: 'new' })\n )\n expect(syncQueries.clearCachePathSettings).toHaveBeenCalledWith('c1', 5)\n expect(out).toEqual(expect.objectContaining({ id: 5, lastSync: 3, timestamp: 4242, permissions: 'new' }))\n })\n\n it('should clear cache and throw INTERNAL_SERVER_ERROR when update fails', async () => {\n syncQueries.clientExistsForOwner.mockResolvedValue(true)\n syncQueries.getPathSettings.mockResolvedValue({ id: 5, timestamp: 500, lastSync: 1 })\n syncQueries.updatePathSettings.mockRejectedValue(new Error('db'))\n await expect(service.updatePath({ id: 1 } as any, 'c1', 5, {} as any)).rejects.toMatchObject({\n status: HttpStatus.INTERNAL_SERVER_ERROR,\n message: 'Unable to update path'\n })\n expect(syncQueries.clearCachePathSettings).toHaveBeenCalledWith('c1', 5)\n })\n })\n\n describe('updatePaths', () => {\n beforeEach(() => {\n syncQueries.clientExistsForOwner.mockResolvedValue(true)\n spacesManager.spaceEnv.mockResolvedValue({ envPermissions: 'p' })\n })\n\n it('should throw when client id is missing', async () => {\n await expect(service.updatePaths(userWith(undefined) as any, [])).rejects.toMatchObject({\n status: HttpStatus.BAD_REQUEST,\n message: 'Client id is missing'\n })\n })\n\n it('should throw FORBIDDEN when client does not belong to owner', async () => {\n syncQueries.clientExistsForOwner.mockResolvedValue(false)\n await expect(service.updatePaths(userWith('c1') as any, [])).rejects.toMatchObject({\n status: HttpStatus.FORBIDDEN\n })\n })\n\n it('should mark client paths as deleted and notify when no corresponding server paths (server remotePath undefined)', async () => {\n syncQueries.clientExistsForOwner.mockResolvedValue(true)\n syncQueries.getPaths.mockResolvedValue([{ id: 2, settings: { timestamp: 1, lastSync: 1 }, remotePath: undefined }])\n const clientPaths = [{ id: 1, remotePath: 'SPACES/a', timestamp: 1, lastSync: 1, permissions: 'p' } as any]\n\n const res = await service.updatePaths(userWith('c1') as any, clientPaths)\n expect(res.delete).toEqual([1])\n expect(notificationsManager.create).toHaveBeenCalledTimes(1)\n })\n\n it('should propagate spaceEnv errors as BAD_REQUEST', async () => {\n syncQueries.clientExistsForOwner.mockResolvedValue(true)\n syncQueries.getPaths.mockResolvedValue([{ id: 1, settings: { timestamp: 1, lastSync: 1 }, remotePath: 'SPACES/x' }])\n spacesManager.spaceEnv.mockRejectedValue(new Error('boom'))\n await expect(\n service.updatePaths(userWith('c1') as any, [{ id: 1, remotePath: 'SPACES/x', timestamp: 1, lastSync: 1, permissions: 'p' } as any])\n ).rejects.toMatchObject({\n status: HttpStatus.BAD_REQUEST,\n message: 'boom'\n })\n })\n\n it('should skip server path when space is null and mark client item as deleted', async () => {\n syncQueries.clientExistsForOwner.mockResolvedValue(true)\n syncQueries.getPaths.mockResolvedValue([{ id: 2, settings: { timestamp: 1, lastSync: 1 }, remotePath: 'SPACES/x' }])\n spacesManager.spaceEnv.mockResolvedValue(null)\n const res = await service.updatePaths(userWith('c1') as any, [\n { id: 2, remotePath: 'SPACES/x', timestamp: 1, lastSync: 1, permissions: 'p' } as any\n ])\n expect(res.delete).toEqual([2])\n expect(notificationsManager.create).toHaveBeenCalledTimes(1)\n })\n\n it('should add server-only path to client with server permissions', async () => {\n syncQueries.clientExistsForOwner.mockResolvedValue(true)\n syncQueries.getPaths.mockResolvedValue([{ id: 3, settings: { timestamp: 1, lastSync: 1 }, remotePath: 'SPACES/x' }])\n spacesManager.spaceEnv.mockResolvedValue({ envPermissions: 'perm-xyz' })\n const res = await service.updatePaths(userWith('c1') as any, [])\n expect(res.add).toHaveLength(1)\n expect(res.add[0]).toEqual(expect.objectContaining({ id: 3, remotePath: 'SPACES/x', permissions: 'perm-xyz' }))\n })\n\n it('should update server settings from client when client is newer (no hasUpdates)', async () => {\n syncQueries.clientExistsForOwner.mockResolvedValue(true)\n syncQueries.getPaths.mockResolvedValue([{ id: 5, settings: { timestamp: 1, lastSync: 1, foo: 'server' }, remotePath: 'SPACES/x' }])\n spacesManager.spaceEnv.mockResolvedValue({ envPermissions: 'p' })\n\n const client = [{ id: 5, timestamp: 10, lastSync: 2, remotePath: 'SPACES/x', permissions: 'p', foo: 'client' } as any]\n await service.updatePaths(userWith('c1') as any, client)\n\n expect(syncQueries.updatePathSettings).toHaveBeenCalledWith('c1', 5, expect.objectContaining({ foo: 'client', lastSync: 2 }))\n // No client update instructions because hasUpdates=false and serverNewer=false\n })\n\n it('should push server-newer updates to client and also remotePath/permissions corrections', async () => {\n syncQueries.clientExistsForOwner.mockResolvedValue(true)\n syncQueries.getPaths.mockResolvedValue([{ id: 7, settings: { timestamp: 20, lastSync: 5, srv: true }, remotePath: 'SPACES/correct' }])\n spacesManager.spaceEnv.mockResolvedValue({ envPermissions: 'permX' })\n\n const client = [{ id: 7, timestamp: 10, lastSync: 5, remotePath: 'SPACES/wrong', permissions: 'old' } as any]\n const res = await service.updatePaths(userWith('c1') as any, client)\n\n // Should have two client updates: one full server settings + corrections, and one corrections-only\n expect(res.update).toEqual(\n expect.arrayContaining([\n expect.objectContaining({ id: 7, srv: true, remotePath: 'SPACES/correct', permissions: 'permX' }),\n expect.objectContaining({ id: 7, remotePath: 'SPACES/correct', permissions: 'permX' })\n ])\n )\n expect(syncQueries.updatePathSettings).toHaveBeenCalledWith('c1', 7, expect.objectContaining({ lastSync: 5 }))\n // clear cache called for each update instruction\n expect(syncQueries.clearCachePathSettings).toHaveBeenCalledTimes(res.update.length)\n for (const u of res.update) {\n expect(syncQueries.clearCachePathSettings).toHaveBeenCalledWith('c1', u.id)\n }\n })\n\n it('should trigger update when lastSync differs even if timestamps and settings match', async () => {\n syncQueries.clientExistsForOwner.mockResolvedValue(true)\n syncQueries.getPaths.mockResolvedValue([{ id: 9, settings: { timestamp: 10, lastSync: 1, flag: 'S' }, remotePath: 'SPACES/x' }])\n spacesManager.spaceEnv.mockResolvedValue({ envPermissions: 'p' })\n\n const client = [{ id: 9, timestamp: 10, lastSync: 2, remotePath: 'SPACES/x', permissions: 'p', flag: 'S' } as any]\n await service.updatePaths(userWith('c1') as any, client)\n expect(syncQueries.updatePathSettings).toHaveBeenCalledWith('c1', 9, expect.objectContaining({ lastSync: 2 }))\n })\n\n it('should perform no changes when client and server are identical (no-op branch)', async () => {\n syncQueries.clientExistsForOwner.mockResolvedValue(true)\n syncQueries.getPaths.mockResolvedValue([{ id: 12, settings: { timestamp: 5, lastSync: 7, flag: 'A' }, remotePath: 'SPACES/x' }])\n spacesManager.spaceEnv.mockResolvedValue({ envPermissions: 'p' })\n\n const client = [{ id: 12, timestamp: 5, lastSync: 7, remotePath: 'SPACES/x', permissions: 'p', flag: 'A' } as any]\n const res = await service.updatePaths(userWith('c1') as any, client)\n\n expect(res).toEqual({ add: [], update: [], delete: [] })\n expect(syncQueries.updatePathSettings).not.toHaveBeenCalled()\n })\n\n it('should correct client info while keeping server settings when timestamps are equal (hasUpdates=true)', async () => {\n syncQueries.clientExistsForOwner.mockResolvedValue(true)\n // Server has srv='S', client has wrong remotePath/permissions and extra clientOnly flag\n syncQueries.getPaths.mockResolvedValue([{ id: 13, settings: { timestamp: 5, lastSync: 1, srv: 'S' }, remotePath: 'SPACES/correct' }])\n spacesManager.spaceEnv.mockResolvedValue({ envPermissions: 'permX' })\n\n const client = [{ id: 13, timestamp: 5, lastSync: 1, remotePath: 'SPACES/wrong', permissions: 'old', clientOnly: 'C' } as any]\n const res = await service.updatePaths(userWith('c1') as any, client)\n\n // Server uses its own settings base (srv: 'S') with corrections applied\n expect(syncQueries.updatePathSettings).toHaveBeenCalledWith(\n 'c1',\n 13,\n expect.objectContaining({ srv: 'S', lastSync: 1, remotePath: 'SPACES/correct', permissions: 'permX' })\n )\n // Client should receive corrections for remotePath and permissions\n expect(res.update).toEqual(expect.arrayContaining([expect.objectContaining({ id: 13, remotePath: 'SPACES/correct', permissions: 'permX' })]))\n })\n\n it('should log error when updatePathSettings rejects inside updatePaths', async () => {\n syncQueries.clientExistsForOwner.mockResolvedValue(true)\n syncQueries.getPaths.mockResolvedValue([{ id: 11, settings: { timestamp: 1, lastSync: 1 }, remotePath: 'SPACES/x' }])\n spacesManager.spaceEnv.mockResolvedValue({ envPermissions: 'p' })\n // Force client newer to trigger updatePathSettings\n const client = [{ id: 11, timestamp: 10, lastSync: 2, remotePath: 'SPACES/x', permissions: 'p' } as any]\n syncQueries.updatePathSettings.mockRejectedValueOnce(new Error('db-fail'))\n const loggerSpy = jest.spyOn((service as any).logger, 'error').mockImplementation(() => undefined)\n\n await service.updatePaths(userWith('c1') as any, client)\n // wait for microtasks to ensure .catch executed\n await flush()\n\n expect(loggerSpy).toHaveBeenCalled()\n expect(loggerSpy.mock.calls.some(([msg]) => String(msg).includes('updatePaths'))).toBe(true)\n })\n\n it('should catch notify failure at updatePaths level when building notification fails', async () => {\n syncQueries.clientExistsForOwner.mockResolvedValue(true)\n // No server paths: will mark client path as deleted and call notify\n syncQueries.getPaths.mockResolvedValue([])\n const loggerSpy = jest.spyOn((service as any).logger, 'error').mockImplementation(() => undefined)\n // BAD first segment to make notify fail while building URL (before notificationsManager.create)\n const client = [{ id: 1, remotePath: 'BAD/a/b', timestamp: 1, lastSync: 1, permissions: 'p' } as any]\n\n const res = await service.updatePaths(userWith('c1') as any, client)\n await flush()\n\n expect(res.delete).toEqual([1])\n expect(loggerSpy).toHaveBeenCalled()\n expect(loggerSpy.mock.calls.some(([msg]) => String(msg).includes('updatePaths'))).toBe(true)\n // create not called because we failed before reaching it\n expect(notificationsManager.create).not.toHaveBeenCalled()\n })\n\n it('should catch error inside notify when notifications creation fails', async () => {\n syncQueries.clientExistsForOwner.mockResolvedValue(true)\n syncQueries.getPaths.mockResolvedValue([])\n // Valid remotePath to build URL correctly\n const client = [{ id: 2, remotePath: 'SPACES/a', timestamp: 1, lastSync: 1, permissions: 'p' } as any]\n const loggerSpy = jest.spyOn((service as any).logger, 'error').mockImplementation(() => undefined)\n notificationsManager.create.mockRejectedValueOnce(new Error('notify-fail'))\n\n const res = await service.updatePaths(userWith('c1') as any, client)\n await flush()\n\n expect(res.delete).toEqual([2])\n expect(loggerSpy).toHaveBeenCalled()\n // error comes from notify() catch\n expect(loggerSpy.mock.calls.some(([msg]) => String(msg).includes('notify'))).toBe(true)\n })\n })\n\n describe('getDBProps (private) branches', () => {\n it('should throw BAD_REQUEST for shares list selection', async () => {\n await expect((service as any).getDBProps({ inSharesList: true } as any)).rejects.toMatchObject({\n status: HttpStatus.BAD_REQUEST,\n message: 'Sync all shares is not supported, you must select a sub-directory'\n })\n })\n\n it('should return ownerId only for personal space at root', async () => {\n const res = await (service as any).getDBProps({\n inSharesList: false,\n inPersonalSpace: true,\n paths: [],\n dbFile: { ownerId: 42 }\n } as any)\n expect(res).toEqual({ ownerId: 42 })\n })\n\n it('should return ownerId and fileId for personal space subdir', async () => {\n const getOrCreateFileIdSpy = jest.spyOn<any, any>(service as any, 'getOrCreateFileId').mockResolvedValue(77)\n const res = await (service as any).getDBProps({\n inPersonalSpace: true,\n paths: ['sub'],\n dbFile: { ownerId: 42 }\n } as any)\n expect(res).toEqual({ ownerId: 42, fileId: 77 })\n getOrCreateFileIdSpy.mockRestore()\n })\n\n it('should throw BAD_REQUEST for whole files repository without alias', async () => {\n await expect((service as any).getDBProps({ inFilesRepository: true, root: { alias: null }, paths: [] } as any)).rejects.toMatchObject({\n status: HttpStatus.BAD_REQUEST,\n message: 'Sync all space is not yet supported, you must select a sub-directory'\n })\n })\n\n it('should return spaceId and rootId for files repository root selection', async () => {\n const res = await (service as any).getDBProps({\n inFilesRepository: true,\n id: 5,\n root: { id: 3, alias: 'x' },\n paths: []\n } as any)\n expect(res).toEqual({ spaceId: 5, spaceRootId: 3 })\n })\n\n it('should return spaceId, rootId and fileId for files repository subdir or null root', async () => {\n const getOrCreateFileIdSpy = jest.spyOn<any, any>(service as any, 'getOrCreateFileId').mockResolvedValue(88)\n const res = await (service as any).getDBProps({\n inFilesRepository: true,\n id: 5,\n root: { id: 3, alias: 'x' },\n paths: ['sub']\n } as any)\n expect(res).toEqual({ spaceId: 5, spaceRootId: 3, fileId: 88 })\n getOrCreateFileIdSpy.mockRestore()\n })\n\n it('should return spaceId and null spaceRootId plus fileId when files repository root has no id', async () => {\n const getOrCreateFileIdSpy = jest.spyOn<any, any>(service as any, 'getOrCreateFileId').mockResolvedValue(90)\n const res = await (service as any).getDBProps({\n inFilesRepository: true,\n id: 6,\n root: { id: undefined, alias: 'x' },\n paths: []\n } as any)\n expect(res).toEqual({ spaceId: 6, spaceRootId: null, fileId: 90 })\n getOrCreateFileIdSpy.mockRestore()\n })\n\n it('should return shareId only for shares repository root', async () => {\n const res = await (service as any).getDBProps({\n inSharesList: false,\n inPersonalSpace: false,\n inFilesRepository: false,\n inSharesRepository: true,\n id: 9,\n paths: []\n } as any)\n expect(res).toEqual({ shareId: 9 })\n })\n\n it('should return shareId and fileId for shares repository subdir', async () => {\n const getOrCreateFileIdSpy = jest.spyOn<any, any>(service as any, 'getOrCreateFileId').mockResolvedValue(55)\n const res = await (service as any).getDBProps({\n inSharesList: false,\n inPersonalSpace: false,\n inFilesRepository: false,\n inSharesRepository: true,\n id: 9,\n paths: ['sub']\n } as any)\n expect(res).toEqual({ shareId: 9, fileId: 55 })\n getOrCreateFileIdSpy.mockRestore()\n })\n\n it('should return undefined when no space flags match (no branch taken)', async () => {\n const res = await (service as any).getDBProps({\n inSharesList: false,\n inPersonalSpace: false,\n inFilesRepository: false,\n inSharesRepository: false,\n paths: []\n } as any)\n expect(res).toBeUndefined()\n })\n })\n\n describe('getOrCreateFileId (private) branches', () => {\n it('should return existing file id without creation', async () => {\n ;(getProps as jest.Mock).mockResolvedValue({ name: 'file' })\n filesQueries.getSpaceFileId.mockResolvedValue(101)\n const id = await (service as any).getOrCreateFileId({\n realPath: '/rp',\n dbFile: { path: '.' }\n })\n expect(id).toBe(101)\n expect(filesQueries.getOrCreateSpaceFile).not.toHaveBeenCalled()\n })\n\n it('should create file when not exists and return its id', async () => {\n ;(getProps as jest.Mock).mockResolvedValue({ id: 999, name: 'file' })\n filesQueries.getSpaceFileId.mockResolvedValue(0)\n filesQueries.getOrCreateSpaceFile.mockResolvedValue(202)\n const id = await (service as any).getOrCreateFileId({\n realPath: '/rp',\n dbFile: { path: '.' }\n })\n expect(id).toBe(202)\n expect(filesQueries.getOrCreateSpaceFile).toHaveBeenCalledWith(0, expect.objectContaining({ id: undefined }), { path: '.' })\n })\n })\n})\n"],"names":["jest","mock","currentTimeStamp","fn","isPathExists","isPathIsDir","getProps","sanitizePath","p","getEnvPermissions","SYNC_PATH_REPOSITORY","SPACES","PERSONAL","SHARES","NOTIFICATION_APP","SYNC","NOTIFICATION_APP_EVENT","DELETE","CREATE","UPDATE","describe","SyncPathsManager","name","service","contextManager","spacesManager","usersQueries","filesQueries","notificationsManager","syncQueries","userWith","clientId","id","flush","Promise","r","setImmediate","beforeEach","get","spaceEnv","getSpaceFileId","getOrCreateSpaceFile","create","mockResolvedValue","undefined","getClient","clientExistsForOwner","createPath","deletePath","getPaths","getPathSettings","updatePathSettings","clearCachePathSettings","mockReset","mockReturnValue","module","Test","createTestingModule","providers","provide","ContextManager","useValue","SpacesManager","UsersQueries","FilesQueries","NotificationsManager","SyncQueries","compile","useLogger","it","expect","toBeDefined","baseReq","user","params","space","realPath","quotaIsExceeded","root","alias","inFilesRepository","paths","dbFile","ownerId","path","req","remotePath","rejects","toMatchObject","status","HttpStatus","BAD_REQUEST","message","INSUFFICIENT_STORAGE","each","title","setup","expected","NOT_FOUND","getDBPropsSpy","spyOn","res","permissions","toEqual","toHaveBeenCalledWith","objectContaining","mockRestore","msg","FORBIDDEN","mockRejectedValue","Error","resolves","toBeUndefined","updatePath","timestamp","lastSync","out","INTERNAL_SERVER_ERROR","envPermissions","updatePaths","settings","clientPaths","delete","toHaveBeenCalledTimes","add","toHaveLength","foo","client","srv","update","arrayContaining","length","u","flag","not","toHaveBeenCalled","clientOnly","mockRejectedValueOnce","loggerSpy","logger","mockImplementation","calls","some","String","includes","toBe","getDBProps","inSharesList","inPersonalSpace","getOrCreateFileIdSpy","fileId","spaceId","spaceRootId","inSharesRepository","shareId","getOrCreateFileId"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../../backend/src/applications/sync/services/sync-paths-manager.service.spec.ts"],"sourcesContent":["/*\n * Copyright (C) 2012-2025 Johan Legrand <johan.legrand@sync-in.com>\n * This file is part of Sync-in | The open source file sync and share solution\n * See the LICENSE file for licensing details\n */\n\nimport { HttpStatus } from '@nestjs/common'\nimport { Test, TestingModule } from '@nestjs/testing'\nimport { currentTimeStamp } from '../../../common/shared'\nimport { ContextManager } from '../../../infrastructure/context/services/context-manager.service'\nimport { FilesQueries } from '../../files/services/files-queries.service'\nimport { getProps, isPathExists, isPathIsDir } from '../../files/utils/files'\nimport { NotificationsManager } from '../../notifications/services/notifications-manager.service'\nimport { SpacesManager } from '../../spaces/services/spaces-manager.service'\nimport { getEnvPermissions } from '../../spaces/utils/permissions'\nimport { UsersQueries } from '../../users/services/users-queries.service'\nimport { SyncPathsManager } from './sync-paths-manager.service'\nimport { SyncQueries } from './sync-queries.service'\n\n// Mock modules used directly inside SyncPathsManager\njest.mock('../../../common/shared', () => ({\n currentTimeStamp: jest.fn(() => 1000)\n}))\njest.mock('../../files/utils/files', () => ({\n isPathExists: jest.fn(),\n isPathIsDir: jest.fn(),\n getProps: jest.fn(),\n sanitizePath: jest.fn((p: string) => p)\n}))\njest.mock('../../spaces/utils/permissions', () => ({\n getEnvPermissions: jest.fn(() => 'server-perms')\n}))\njest.mock('../constants/sync', () => ({\n SYNC_PATH_REPOSITORY: {\n SPACES: ['spaces'],\n PERSONAL: ['personal'],\n SHARES: ['shares']\n }\n}))\njest.mock('../../notifications/constants/notifications', () => ({\n NOTIFICATION_APP: { SYNC: 'SYNC' },\n NOTIFICATION_APP_EVENT: { SYNC: { DELETE: 'DELETE', CREATE: 'CREATE', UPDATE: 'UPDATE' } }\n}))\n\ndescribe(SyncPathsManager.name, () => {\n let service: SyncPathsManager\n let contextManager: { headerOriginUrl: jest.Mock }\n let spacesManager: { spaceEnv: jest.Mock }\n let usersQueries: Record<string, jest.Mock>\n let filesQueries: { getSpaceFileId: jest.Mock; getOrCreateSpaceFile: jest.Mock }\n let notificationsManager: { create: jest.Mock }\n let syncQueries: {\n getClient: jest.Mock\n clientExistsForOwner: jest.Mock\n createPath: jest.Mock\n deletePath: jest.Mock\n getPaths: jest.Mock\n getPathSettings: jest.Mock\n updatePathSettings: jest.Mock\n clearCachePathSettings: jest.Mock\n }\n\n const userWith = (clientId?: string) => ({ id: 1, clientId })\n const flush = () => new Promise((r) => setImmediate(r))\n\n beforeEach(async () => {\n contextManager = { headerOriginUrl: jest.fn(() => 'http://origin.local') }\n spacesManager = { spaceEnv: jest.fn() }\n usersQueries = {}\n filesQueries = {\n getSpaceFileId: jest.fn(),\n getOrCreateSpaceFile: jest.fn()\n }\n notificationsManager = {\n create: jest.fn().mockResolvedValue(undefined)\n }\n syncQueries = {\n getClient: jest.fn(),\n clientExistsForOwner: jest.fn(),\n createPath: jest.fn(),\n deletePath: jest.fn(),\n getPaths: jest.fn(),\n getPathSettings: jest.fn(),\n updatePathSettings: jest.fn().mockResolvedValue(undefined),\n clearCachePathSettings: jest.fn()\n }\n ;(isPathExists as jest.Mock).mockReset()\n ;(isPathIsDir as jest.Mock).mockReset()\n ;(getProps as jest.Mock).mockReset()\n ;(getEnvPermissions as jest.Mock).mockReset().mockReturnValue('server-perms')\n ;(currentTimeStamp as jest.Mock).mockReset().mockReturnValue(1000)\n\n const module: TestingModule = await Test.createTestingModule({\n providers: [\n SyncPathsManager,\n { provide: ContextManager, useValue: contextManager },\n { provide: SpacesManager, useValue: spacesManager },\n { provide: UsersQueries, useValue: usersQueries },\n { provide: FilesQueries, useValue: filesQueries },\n { provide: NotificationsManager, useValue: notificationsManager },\n { provide: SyncQueries, useValue: syncQueries }\n ]\n }).compile()\n\n module.useLogger(['fatal'])\n service = module.get<SyncPathsManager>(SyncPathsManager)\n })\n\n it('should be defined', () => {\n expect(service).toBeDefined()\n })\n\n describe('createPath', () => {\n const baseReq = () =>\n ({\n user: { id: 1, clientId: 'client-1' },\n params: { '*': 'SPACES/alias/sub' },\n space: {\n realPath: '/real/path',\n quotaIsExceeded: false,\n root: { id: 1, alias: 'alias' },\n inFilesRepository: true,\n paths: ['sub'],\n dbFile: { ownerId: 1, path: '.' },\n id: 10\n }\n }) as any\n\n it('should throw BAD_REQUEST when client id is missing', async () => {\n const req = baseReq()\n req.user.clientId = undefined\n await expect(service.createPath(req, { remotePath: 'x' } as any)).rejects.toMatchObject({\n status: HttpStatus.BAD_REQUEST,\n message: 'Client id is missing'\n })\n })\n\n it('should throw INSUFFICIENT_STORAGE when storage quota is exceeded', async () => {\n const req = baseReq()\n req.space.quotaIsExceeded = true\n await expect(service.createPath(req, { remotePath: 'x' } as any)).rejects.toMatchObject({\n status: HttpStatus.INSUFFICIENT_STORAGE\n })\n })\n\n it.each([\n {\n title: 'NOT_FOUND when remote path does not exist',\n setup: () => (isPathExists as jest.Mock).mockResolvedValue(false),\n expected: { status: HttpStatus.NOT_FOUND, message: 'Remote path not found : client/remote' }\n },\n {\n title: 'BAD_REQUEST when remote path is not a directory',\n setup: () => ((isPathExists as jest.Mock).mockResolvedValue(true), (isPathIsDir as jest.Mock).mockResolvedValue(false)),\n expected: { status: HttpStatus.BAD_REQUEST, message: 'Remote path must be a directory' }\n },\n {\n title: 'NOT_FOUND when client is not found',\n setup: () => (\n (isPathExists as jest.Mock).mockResolvedValue(true),\n (isPathIsDir as jest.Mock).mockResolvedValue(true),\n syncQueries.getClient.mockResolvedValue(null)\n ),\n expected: { status: HttpStatus.NOT_FOUND, message: 'Client not found' }\n }\n ])('should throw $title', async ({ setup, expected }) => {\n const req = baseReq()\n setup()\n await expect(service.createPath(req, { remotePath: 'client/remote' } as any)).rejects.toMatchObject(expected)\n })\n\n it('should create path and return id and permissions, overriding remotePath and permissions', async () => {\n const req = baseReq()\n ;(isPathExists as jest.Mock).mockResolvedValue(true)\n ;(isPathIsDir as jest.Mock).mockResolvedValue(true)\n ;(getEnvPermissions as jest.Mock).mockReturnValue('env-perms')\n syncQueries.getClient.mockResolvedValue({ id: 'client-1' })\n // Spy on private getDBProps to simplify\n const getDBPropsSpy = jest.spyOn<any, any>(service as any, 'getDBProps').mockResolvedValue({ ownerId: 1 })\n syncQueries.createPath.mockResolvedValue(123)\n\n const res = await service.createPath(req, { remotePath: 'client/remote', permissions: 'client-perms' } as any)\n expect(res).toEqual({ id: 123, permissions: 'env-perms' })\n expect(syncQueries.createPath).toHaveBeenCalledWith(\n 'client-1',\n { ownerId: 1 },\n expect.objectContaining({ remotePath: 'SPACES/alias/sub', permissions: 'env-perms' })\n )\n\n getDBPropsSpy.mockRestore()\n })\n })\n\n describe('deletePath', () => {\n it.each([\n { user: { id: 1, clientId: undefined } as any, id: 10, status: HttpStatus.BAD_REQUEST, msg: 'Client id is missing' },\n { user: { id: 1, clientId: 'c1' } as any, id: 10, status: HttpStatus.FORBIDDEN }\n ])('should handle errors (status=$status)', async ({ user, id, status, msg }) => {\n if (status === HttpStatus.FORBIDDEN) syncQueries.clientExistsForOwner.mockResolvedValue(false)\n await expect(service.deletePath(user, id)).rejects.toMatchObject(msg ? { status, message: msg } : { status })\n })\n\n it('should catch errors from deletePath and throw BAD_REQUEST', async () => {\n const user: any = { id: 1, clientId: 'c1' }\n syncQueries.clientExistsForOwner.mockResolvedValue(true)\n syncQueries.deletePath.mockRejectedValue(new Error('db'))\n await expect(service.deletePath(user, 10)).rejects.toMatchObject({\n status: HttpStatus.BAD_REQUEST,\n message: 'Unable to remove path'\n })\n expect(syncQueries.deletePath).toHaveBeenCalledWith('c1', 10)\n })\n\n it('should delete path successfully when allowed', async () => {\n const user: any = { id: 1, clientId: undefined }\n syncQueries.clientExistsForOwner.mockResolvedValue(true)\n syncQueries.deletePath.mockResolvedValue(undefined)\n await expect(service.deletePath(user, 10, 'cX')).resolves.toBeUndefined()\n expect(syncQueries.deletePath).toHaveBeenCalledWith('cX', 10)\n })\n })\n\n describe('updatePath', () => {\n it('should throw FORBIDDEN when client does not belong to owner', async () => {\n syncQueries.clientExistsForOwner.mockResolvedValue(false)\n await expect(service.updatePath({ id: 1 } as any, 'c1', 5, {} as any)).rejects.toMatchObject({\n status: HttpStatus.FORBIDDEN\n })\n })\n\n it('should throw NOT_FOUND when path settings do not exist', async () => {\n syncQueries.clientExistsForOwner.mockResolvedValue(true)\n syncQueries.getPathSettings.mockResolvedValue(null)\n await expect(service.updatePath({ id: 1 } as any, 'c1', 5, {} as any)).rejects.toMatchObject({\n status: HttpStatus.NOT_FOUND,\n message: 'Sync path not found'\n })\n })\n\n it('should update path settings, set new timestamp, clear cache and return updated settings', async () => {\n syncQueries.clientExistsForOwner.mockResolvedValue(true)\n syncQueries.getPathSettings.mockResolvedValue({ id: 5, timestamp: 500, lastSync: 1, remotePath: '/a', permissions: 'p' })\n syncQueries.updatePathSettings.mockResolvedValue(undefined)\n ;(currentTimeStamp as jest.Mock).mockReturnValue(4242)\n\n const out = await service.updatePath({ id: 1 } as any, 'c1', 5, { id: 666, lastSync: 3, permissions: 'new' } as any)\n expect(syncQueries.updatePathSettings).toHaveBeenCalledWith(\n 'c1',\n 5,\n expect.objectContaining({ id: 5, lastSync: 3, timestamp: 4242, permissions: 'new' })\n )\n expect(syncQueries.clearCachePathSettings).toHaveBeenCalledWith('c1', 5)\n expect(out).toEqual(expect.objectContaining({ id: 5, lastSync: 3, timestamp: 4242, permissions: 'new' }))\n })\n\n it('should clear cache and throw INTERNAL_SERVER_ERROR when update fails', async () => {\n syncQueries.clientExistsForOwner.mockResolvedValue(true)\n syncQueries.getPathSettings.mockResolvedValue({ id: 5, timestamp: 500, lastSync: 1 })\n syncQueries.updatePathSettings.mockRejectedValue(new Error('db'))\n await expect(service.updatePath({ id: 1 } as any, 'c1', 5, {} as any)).rejects.toMatchObject({\n status: HttpStatus.INTERNAL_SERVER_ERROR,\n message: 'Unable to update path'\n })\n expect(syncQueries.clearCachePathSettings).toHaveBeenCalledWith('c1', 5)\n })\n })\n\n describe('updatePaths', () => {\n beforeEach(() => {\n syncQueries.clientExistsForOwner.mockResolvedValue(true)\n spacesManager.spaceEnv.mockResolvedValue({ envPermissions: 'p' })\n })\n\n it('should throw when client id is missing', async () => {\n await expect(service.updatePaths(userWith(undefined) as any, [])).rejects.toMatchObject({\n status: HttpStatus.BAD_REQUEST,\n message: 'Client id is missing'\n })\n })\n\n it('should throw FORBIDDEN when client does not belong to owner', async () => {\n syncQueries.clientExistsForOwner.mockResolvedValue(false)\n await expect(service.updatePaths(userWith('c1') as any, [])).rejects.toMatchObject({\n status: HttpStatus.FORBIDDEN\n })\n })\n\n it('should mark client paths as deleted and notify when no corresponding server paths (server remotePath undefined)', async () => {\n syncQueries.clientExistsForOwner.mockResolvedValue(true)\n syncQueries.getPaths.mockResolvedValue([{ id: 2, settings: { timestamp: 1, lastSync: 1 }, remotePath: undefined }])\n const clientPaths = [{ id: 1, remotePath: 'SPACES/a', timestamp: 1, lastSync: 1, permissions: 'p' } as any]\n\n const res = await service.updatePaths(userWith('c1') as any, clientPaths)\n expect(res.delete).toEqual([1])\n expect(notificationsManager.create).toHaveBeenCalledTimes(1)\n })\n\n it('should propagate spaceEnv errors as BAD_REQUEST', async () => {\n syncQueries.clientExistsForOwner.mockResolvedValue(true)\n syncQueries.getPaths.mockResolvedValue([{ id: 1, settings: { timestamp: 1, lastSync: 1 }, remotePath: 'SPACES/x' }])\n spacesManager.spaceEnv.mockRejectedValue(new Error('boom'))\n await expect(\n service.updatePaths(userWith('c1') as any, [{ id: 1, remotePath: 'SPACES/x', timestamp: 1, lastSync: 1, permissions: 'p' } as any])\n ).rejects.toMatchObject({\n status: HttpStatus.BAD_REQUEST,\n message: 'boom'\n })\n })\n\n it('should skip server path when space is null and mark client item as deleted', async () => {\n syncQueries.clientExistsForOwner.mockResolvedValue(true)\n syncQueries.getPaths.mockResolvedValue([{ id: 2, settings: { timestamp: 1, lastSync: 1 }, remotePath: 'SPACES/x' }])\n spacesManager.spaceEnv.mockResolvedValue(null)\n const res = await service.updatePaths(userWith('c1') as any, [\n { id: 2, remotePath: 'SPACES/x', timestamp: 1, lastSync: 1, permissions: 'p' } as any\n ])\n expect(res.delete).toEqual([2])\n expect(notificationsManager.create).toHaveBeenCalledTimes(1)\n })\n\n it('should add server-only path to client with server permissions', async () => {\n syncQueries.clientExistsForOwner.mockResolvedValue(true)\n syncQueries.getPaths.mockResolvedValue([{ id: 3, settings: { timestamp: 1, lastSync: 1 }, remotePath: 'SPACES/x' }])\n spacesManager.spaceEnv.mockResolvedValue({ envPermissions: 'perm-xyz' })\n const res = await service.updatePaths(userWith('c1') as any, [])\n expect(res.add).toHaveLength(1)\n expect(res.add[0]).toEqual(expect.objectContaining({ id: 3, remotePath: 'SPACES/x', permissions: 'perm-xyz' }))\n })\n\n it('should update server settings from client when client is newer (no hasUpdates)', async () => {\n syncQueries.clientExistsForOwner.mockResolvedValue(true)\n syncQueries.getPaths.mockResolvedValue([{ id: 5, settings: { timestamp: 1, lastSync: 1, foo: 'server' }, remotePath: 'SPACES/x' }])\n spacesManager.spaceEnv.mockResolvedValue({ envPermissions: 'p' })\n\n const client = [{ id: 5, timestamp: 10, lastSync: 2, remotePath: 'SPACES/x', permissions: 'p', foo: 'client' } as any]\n await service.updatePaths(userWith('c1') as any, client)\n\n expect(syncQueries.updatePathSettings).toHaveBeenCalledWith('c1', 5, expect.objectContaining({ foo: 'client', lastSync: 2 }))\n // No client update instructions because hasUpdates=false and serverNewer=false\n })\n\n it('should push server-newer updates to client and also remotePath/permissions corrections', async () => {\n syncQueries.clientExistsForOwner.mockResolvedValue(true)\n syncQueries.getPaths.mockResolvedValue([{ id: 7, settings: { timestamp: 20, lastSync: 5, srv: true }, remotePath: 'SPACES/correct' }])\n spacesManager.spaceEnv.mockResolvedValue({ envPermissions: 'permX' })\n\n const client = [{ id: 7, timestamp: 10, lastSync: 5, remotePath: 'SPACES/wrong', permissions: 'old' } as any]\n const res = await service.updatePaths(userWith('c1') as any, client)\n\n // Should have two client updates: one full server settings + corrections, and one corrections-only\n expect(res.update).toEqual(\n expect.arrayContaining([\n expect.objectContaining({ id: 7, srv: true, remotePath: 'SPACES/correct', permissions: 'permX' }),\n expect.objectContaining({ id: 7, remotePath: 'SPACES/correct', permissions: 'permX' })\n ])\n )\n expect(syncQueries.updatePathSettings).toHaveBeenCalledWith('c1', 7, expect.objectContaining({ lastSync: 5 }))\n // clear cache called for each update instruction\n expect(syncQueries.clearCachePathSettings).toHaveBeenCalledTimes(res.update.length)\n for (const u of res.update) {\n expect(syncQueries.clearCachePathSettings).toHaveBeenCalledWith('c1', u.id)\n }\n })\n\n it('should trigger update when lastSync differs even if timestamps and settings match', async () => {\n syncQueries.clientExistsForOwner.mockResolvedValue(true)\n syncQueries.getPaths.mockResolvedValue([{ id: 9, settings: { timestamp: 10, lastSync: 1, flag: 'S' }, remotePath: 'SPACES/x' }])\n spacesManager.spaceEnv.mockResolvedValue({ envPermissions: 'p' })\n\n const client = [{ id: 9, timestamp: 10, lastSync: 2, remotePath: 'SPACES/x', permissions: 'p', flag: 'S' } as any]\n await service.updatePaths(userWith('c1') as any, client)\n expect(syncQueries.updatePathSettings).toHaveBeenCalledWith('c1', 9, expect.objectContaining({ lastSync: 2 }))\n })\n\n it('should perform no changes when client and server are identical (no-op branch)', async () => {\n syncQueries.clientExistsForOwner.mockResolvedValue(true)\n syncQueries.getPaths.mockResolvedValue([{ id: 12, settings: { timestamp: 5, lastSync: 7, flag: 'A' }, remotePath: 'SPACES/x' }])\n spacesManager.spaceEnv.mockResolvedValue({ envPermissions: 'p' })\n\n const client = [{ id: 12, timestamp: 5, lastSync: 7, remotePath: 'SPACES/x', permissions: 'p', flag: 'A' } as any]\n const res = await service.updatePaths(userWith('c1') as any, client)\n\n expect(res).toEqual({ add: [], update: [], delete: [] })\n expect(syncQueries.updatePathSettings).not.toHaveBeenCalled()\n })\n\n it('should correct client info while keeping server settings when timestamps are equal (hasUpdates=true)', async () => {\n syncQueries.clientExistsForOwner.mockResolvedValue(true)\n // Server has srv='S', client has wrong remotePath/permissions and extra clientOnly flag\n syncQueries.getPaths.mockResolvedValue([{ id: 13, settings: { timestamp: 5, lastSync: 1, srv: 'S' }, remotePath: 'SPACES/correct' }])\n spacesManager.spaceEnv.mockResolvedValue({ envPermissions: 'permX' })\n\n const client = [{ id: 13, timestamp: 5, lastSync: 1, remotePath: 'SPACES/wrong', permissions: 'old', clientOnly: 'C' } as any]\n const res = await service.updatePaths(userWith('c1') as any, client)\n\n // Server uses its own settings base (srv: 'S') with corrections applied\n expect(syncQueries.updatePathSettings).toHaveBeenCalledWith(\n 'c1',\n 13,\n expect.objectContaining({ srv: 'S', lastSync: 1, remotePath: 'SPACES/correct', permissions: 'permX' })\n )\n // Client should receive corrections for remotePath and permissions\n expect(res.update).toEqual(expect.arrayContaining([expect.objectContaining({ id: 13, remotePath: 'SPACES/correct', permissions: 'permX' })]))\n })\n\n it('should log error when updatePathSettings rejects inside updatePaths', async () => {\n syncQueries.clientExistsForOwner.mockResolvedValue(true)\n syncQueries.getPaths.mockResolvedValue([{ id: 11, settings: { timestamp: 1, lastSync: 1 }, remotePath: 'SPACES/x' }])\n spacesManager.spaceEnv.mockResolvedValue({ envPermissions: 'p' })\n // Force client newer to trigger updatePathSettings\n const client = [{ id: 11, timestamp: 10, lastSync: 2, remotePath: 'SPACES/x', permissions: 'p' } as any]\n syncQueries.updatePathSettings.mockRejectedValueOnce(new Error('db-fail'))\n const loggerSpy = jest.spyOn((service as any).logger, 'error').mockImplementation(() => undefined)\n\n await service.updatePaths(userWith('c1') as any, client)\n // wait for microtasks to ensure .catch executed\n await flush()\n\n expect(loggerSpy).toHaveBeenCalled()\n expect(loggerSpy.mock.calls.some(([msg]) => String(msg).includes('updatePaths'))).toBe(true)\n })\n\n it('should catch notify failure at updatePaths level when building notification fails', async () => {\n syncQueries.clientExistsForOwner.mockResolvedValue(true)\n // No server paths: will mark client path as deleted and call notify\n syncQueries.getPaths.mockResolvedValue([])\n const loggerSpy = jest.spyOn((service as any).logger, 'error').mockImplementation(() => undefined)\n // BAD first segment to make notify fail while building URL (before notificationsManager.create)\n const client = [{ id: 1, remotePath: 'BAD/a/b', timestamp: 1, lastSync: 1, permissions: 'p' } as any]\n\n const res = await service.updatePaths(userWith('c1') as any, client)\n await flush()\n\n expect(res.delete).toEqual([1])\n expect(loggerSpy).toHaveBeenCalled()\n expect(loggerSpy.mock.calls.some(([msg]) => String(msg).includes('updatePaths'))).toBe(true)\n // create not called because we failed before reaching it\n expect(notificationsManager.create).not.toHaveBeenCalled()\n })\n\n it('should catch error inside notify when notifications creation fails', async () => {\n syncQueries.clientExistsForOwner.mockResolvedValue(true)\n syncQueries.getPaths.mockResolvedValue([])\n // Valid remotePath to build URL correctly\n const client = [{ id: 2, remotePath: 'SPACES/a', timestamp: 1, lastSync: 1, permissions: 'p' } as any]\n const loggerSpy = jest.spyOn((service as any).logger, 'error').mockImplementation(() => undefined)\n notificationsManager.create.mockRejectedValueOnce(new Error('notify-fail'))\n\n const res = await service.updatePaths(userWith('c1') as any, client)\n await flush()\n\n expect(res.delete).toEqual([2])\n expect(loggerSpy).toHaveBeenCalled()\n // error comes from notify() catch\n expect(loggerSpy.mock.calls.some(([msg]) => String(msg).includes('notify'))).toBe(true)\n })\n })\n\n describe('getDBProps (private) branches', () => {\n it('should throw BAD_REQUEST for shares list selection', async () => {\n await expect((service as any).getDBProps({ inSharesList: true } as any)).rejects.toMatchObject({\n status: HttpStatus.BAD_REQUEST,\n message: 'Sync all shares is not supported, you must select a sub-directory'\n })\n })\n\n it('should return ownerId only for personal space at root', async () => {\n const res = await (service as any).getDBProps({\n inSharesList: false,\n inPersonalSpace: true,\n paths: [],\n dbFile: { ownerId: 42 }\n } as any)\n expect(res).toEqual({ ownerId: 42 })\n })\n\n it('should return ownerId and fileId for personal space subdir', async () => {\n const getOrCreateFileIdSpy = jest.spyOn<any, any>(service as any, 'getOrCreateFileId').mockResolvedValue(77)\n const res = await (service as any).getDBProps({\n inPersonalSpace: true,\n paths: ['sub'],\n dbFile: { ownerId: 42 }\n } as any)\n expect(res).toEqual({ ownerId: 42, fileId: 77 })\n getOrCreateFileIdSpy.mockRestore()\n })\n\n it('should throw BAD_REQUEST for whole files repository without alias', async () => {\n await expect((service as any).getDBProps({ inFilesRepository: true, root: { alias: null }, paths: [] } as any)).rejects.toMatchObject({\n status: HttpStatus.BAD_REQUEST,\n message: 'Sync all space is not yet supported, you must select a sub-directory'\n })\n })\n\n it('should return spaceId and rootId for files repository root selection', async () => {\n const res = await (service as any).getDBProps({\n inFilesRepository: true,\n id: 5,\n root: { id: 3, alias: 'x' },\n paths: []\n } as any)\n expect(res).toEqual({ spaceId: 5, spaceRootId: 3 })\n })\n\n it('should return spaceId, rootId and fileId for files repository subdir or null root', async () => {\n const getOrCreateFileIdSpy = jest.spyOn<any, any>(service as any, 'getOrCreateFileId').mockResolvedValue(88)\n const res = await (service as any).getDBProps({\n inFilesRepository: true,\n id: 5,\n root: { id: 3, alias: 'x' },\n paths: ['sub']\n } as any)\n expect(res).toEqual({ spaceId: 5, spaceRootId: 3, fileId: 88 })\n getOrCreateFileIdSpy.mockRestore()\n })\n\n it('should return spaceId and null spaceRootId plus fileId when files repository root has no id', async () => {\n const getOrCreateFileIdSpy = jest.spyOn<any, any>(service as any, 'getOrCreateFileId').mockResolvedValue(90)\n const res = await (service as any).getDBProps({\n inFilesRepository: true,\n id: 6,\n root: { id: undefined, alias: 'x' },\n paths: []\n } as any)\n expect(res).toEqual({ spaceId: 6, spaceRootId: null, fileId: 90 })\n getOrCreateFileIdSpy.mockRestore()\n })\n\n it('should return shareId only for shares repository root', async () => {\n const res = await (service as any).getDBProps({\n inSharesList: false,\n inPersonalSpace: false,\n inFilesRepository: false,\n inSharesRepository: true,\n id: 9,\n paths: []\n } as any)\n expect(res).toEqual({ shareId: 9 })\n })\n\n it('should return shareId and fileId for shares repository subdir', async () => {\n const getOrCreateFileIdSpy = jest.spyOn<any, any>(service as any, 'getOrCreateFileId').mockResolvedValue(55)\n const res = await (service as any).getDBProps({\n inSharesList: false,\n inPersonalSpace: false,\n inFilesRepository: false,\n inSharesRepository: true,\n id: 9,\n paths: ['sub']\n } as any)\n expect(res).toEqual({ shareId: 9, fileId: 55 })\n getOrCreateFileIdSpy.mockRestore()\n })\n\n it('should return undefined when no space flags match (no branch taken)', async () => {\n const res = await (service as any).getDBProps({\n inSharesList: false,\n inPersonalSpace: false,\n inFilesRepository: false,\n inSharesRepository: false,\n paths: []\n } as any)\n expect(res).toBeUndefined()\n })\n })\n\n describe('getOrCreateFileId (private) branches', () => {\n it('should return existing file id without creation', async () => {\n ;(getProps as jest.Mock).mockResolvedValue({ name: 'file' })\n filesQueries.getSpaceFileId.mockResolvedValue(101)\n const id = await (service as any).getOrCreateFileId({\n realPath: '/rp',\n dbFile: { path: '.' }\n })\n expect(id).toBe(101)\n expect(filesQueries.getOrCreateSpaceFile).not.toHaveBeenCalled()\n })\n\n it('should create file when not exists and return its id', async () => {\n ;(getProps as jest.Mock).mockResolvedValue({ id: 999, name: 'file' })\n filesQueries.getSpaceFileId.mockResolvedValue(0)\n filesQueries.getOrCreateSpaceFile.mockResolvedValue(202)\n const id = await (service as any).getOrCreateFileId({\n realPath: '/rp',\n dbFile: { path: '.' }\n })\n expect(id).toBe(202)\n expect(filesQueries.getOrCreateSpaceFile).toHaveBeenCalledWith(0, expect.objectContaining({ id: undefined }), { path: '.' })\n })\n })\n})\n"],"names":["jest","mock","currentTimeStamp","fn","isPathExists","isPathIsDir","getProps","sanitizePath","p","getEnvPermissions","SYNC_PATH_REPOSITORY","SPACES","PERSONAL","SHARES","NOTIFICATION_APP","SYNC","NOTIFICATION_APP_EVENT","DELETE","CREATE","UPDATE","describe","SyncPathsManager","name","service","contextManager","spacesManager","usersQueries","filesQueries","notificationsManager","syncQueries","userWith","clientId","id","flush","Promise","r","setImmediate","beforeEach","headerOriginUrl","spaceEnv","getSpaceFileId","getOrCreateSpaceFile","create","mockResolvedValue","undefined","getClient","clientExistsForOwner","createPath","deletePath","getPaths","getPathSettings","updatePathSettings","clearCachePathSettings","mockReset","mockReturnValue","module","Test","createTestingModule","providers","provide","ContextManager","useValue","SpacesManager","UsersQueries","FilesQueries","NotificationsManager","SyncQueries","compile","useLogger","get","it","expect","toBeDefined","baseReq","user","params","space","realPath","quotaIsExceeded","root","alias","inFilesRepository","paths","dbFile","ownerId","path","req","remotePath","rejects","toMatchObject","status","HttpStatus","BAD_REQUEST","message","INSUFFICIENT_STORAGE","each","title","setup","expected","NOT_FOUND","getDBPropsSpy","spyOn","res","permissions","toEqual","toHaveBeenCalledWith","objectContaining","mockRestore","msg","FORBIDDEN","mockRejectedValue","Error","resolves","toBeUndefined","updatePath","timestamp","lastSync","out","INTERNAL_SERVER_ERROR","envPermissions","updatePaths","settings","clientPaths","delete","toHaveBeenCalledTimes","add","toHaveLength","foo","client","srv","update","arrayContaining","length","u","flag","not","toHaveBeenCalled","clientOnly","mockRejectedValueOnce","loggerSpy","logger","mockImplementation","calls","some","String","includes","toBe","getDBProps","inSharesList","inPersonalSpace","getOrCreateFileIdSpy","fileId","spaceId","spaceRootId","inSharesRepository","shareId","getOrCreateFileId"],"mappings":"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"}
|
|
@@ -52,7 +52,7 @@ _export(exports, {
|
|
|
52
52
|
});
|
|
53
53
|
const USER_PASSWORD_MIN_LENGTH = 8;
|
|
54
54
|
const USER_MAX_PASSWORD_ATTEMPTS = 10;
|
|
55
|
-
const USER_LOGIN_VALIDATION = /^[a-zA-Z0-9
|
|
55
|
+
const USER_LOGIN_VALIDATION = /^(?! )(?!.* $)[a-zA-Z0-9@\-\\._ ]{2,255}$/;
|
|
56
56
|
const USER_PATH = {
|
|
57
57
|
TMP: 'tmp',
|
|
58
58
|
TASKS: 'tasks'
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../backend/src/applications/users/constants/user.ts"],"sourcesContent":["/*\n * Copyright (C) 2012-2025 Johan Legrand <johan.legrand@sync-in.com>\n * This file is part of Sync-in | The open source file sync and share solution\n * See the LICENSE file for licensing details\n */\n\nexport const USER_PASSWORD_MIN_LENGTH = 8\nexport const USER_MAX_PASSWORD_ATTEMPTS = 10\nexport const USER_LOGIN_VALIDATION = /^[a-zA-Z0-9
|
|
1
|
+
{"version":3,"sources":["../../../../../backend/src/applications/users/constants/user.ts"],"sourcesContent":["/*\n * Copyright (C) 2012-2025 Johan Legrand <johan.legrand@sync-in.com>\n * This file is part of Sync-in | The open source file sync and share solution\n * See the LICENSE file for licensing details\n */\n\nexport const USER_PASSWORD_MIN_LENGTH = 8\nexport const USER_MAX_PASSWORD_ATTEMPTS = 10\nexport const USER_LOGIN_VALIDATION = /^(?! )(?!.* $)[a-zA-Z0-9@\\-\\\\._ ]{2,255}$/\n\nexport const USER_PATH = {\n TMP: 'tmp',\n TASKS: 'tasks'\n} as const\n\nexport enum USER_ROLE {\n ADMINISTRATOR,\n USER,\n GUEST,\n LINK\n}\n\nexport enum USER_GROUP_ROLE {\n MEMBER,\n MANAGER\n}\n\nexport const USER_PERMS_SEP = ','\n\nexport enum USER_PERMISSION {\n PERSONAL_SPACE = 'personal_space',\n SPACES = 'spaces_access',\n SPACES_ADMIN = 'spaces_admin',\n SHARES = 'shares_access',\n SHARES_ADMIN = 'shares_admin',\n GUESTS_ADMIN = 'guests_admin',\n PERSONAL_GROUPS_ADMIN = 'personal_groups_admin',\n DESKTOP_APP = 'desktop_app_access',\n DESKTOP_APP_SYNC = 'desktop_app_sync',\n WEBDAV = 'webdav_access'\n}\n\nexport enum GUEST_PERMISSION {\n SPACES = USER_PERMISSION.SPACES,\n SHARES = USER_PERMISSION.SHARES,\n WEBDAV = USER_PERMISSION.WEBDAV\n}\n\nexport enum USER_ONLINE_STATUS {\n AVAILABLE,\n BUSY,\n ABSENT,\n OFFLINE\n}\n\nexport enum USER_NOTIFICATION {\n APPLICATION,\n APPLICATION_EMAIL\n}\n\nexport const USER_SECRET = {\n TWO_FA_SECRET: 'twoFaSecret',\n RECOVERY_CODES: 'recoveryCodes',\n APP_PASSWORDS: 'appPasswords'\n} as const\n"],"names":["GUEST_PERMISSION","USER_GROUP_ROLE","USER_LOGIN_VALIDATION","USER_MAX_PASSWORD_ATTEMPTS","USER_NOTIFICATION","USER_ONLINE_STATUS","USER_PASSWORD_MIN_LENGTH","USER_PATH","USER_PERMISSION","USER_PERMS_SEP","USER_ROLE","USER_SECRET","TMP","TASKS","TWO_FA_SECRET","RECOVERY_CODES","APP_PASSWORDS"],"mappings":"AAAA;;;;CAIC;;;;;;;;;;;QAsCWA;eAAAA;;QApBAC;eAAAA;;QAdCC;eAAAA;;QADAC;eAAAA;;QAgDDC;eAAAA;;QAPAC;eAAAA;;QA1CCC;eAAAA;;QAIAC;eAAAA;;QAmBDC;eAAAA;;QAFCC;eAAAA;;QAZDC;eAAAA;;QA6CCC;eAAAA;;;AAtDN,MAAML,2BAA2B;AACjC,MAAMH,6BAA6B;AACnC,MAAMD,wBAAwB;AAE9B,MAAMK,YAAY;IACvBK,KAAK;IACLC,OAAO;AACT;AAEO,IAAA,AAAKH,mCAAAA;;;;;WAAAA;;AAOL,IAAA,AAAKT,yCAAAA;;;WAAAA;;AAKL,MAAMQ,iBAAiB;AAEvB,IAAA,AAAKD,yCAAAA;;;;;;;;;;;WAAAA;;AAaL,IAAA,AAAKR,0CAAAA;;;;WAAAA;;AAML,IAAA,AAAKK,4CAAAA;;;;;WAAAA;;AAOL,IAAA,AAAKD,2CAAAA;;;WAAAA;;AAKL,MAAMO,cAAc;IACzBG,eAAe;IACfC,gBAAgB;IAChBC,eAAe;AACjB"}
|
|
@@ -92,6 +92,14 @@ let AdminUsersQueries = class AdminUsersQueries {
|
|
|
92
92
|
}
|
|
93
93
|
return rs;
|
|
94
94
|
}
|
|
95
|
+
async listAdminsToNotify() {
|
|
96
|
+
return this.db.select({
|
|
97
|
+
id: _usersschema.users.id,
|
|
98
|
+
email: _usersschema.users.email,
|
|
99
|
+
language: _usersschema.users.language,
|
|
100
|
+
notification: _usersschema.users.notification
|
|
101
|
+
}).from(_usersschema.users).where((0, _drizzleorm.eq)(_usersschema.users.role, _user.USER_ROLE.ADMINISTRATOR));
|
|
102
|
+
}
|
|
95
103
|
async groupFromId(groupId) {
|
|
96
104
|
const groupParent = (0, _mysqlcore.alias)(_groupsschema.groups, 'groupParent');
|
|
97
105
|
const [group] = await this.db.select({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../backend/src/applications/users/services/admin-users-queries.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 { Inject, Injectable, Logger } from '@nestjs/common'\nimport { and, count, countDistinct, eq, inArray, isNotNull, isNull, lte, SelectedFields, SQL, sql } from 'drizzle-orm'\nimport { alias, union } from 'drizzle-orm/mysql-core'\nimport { DB_TOKEN_PROVIDER } from '../../../infrastructure/database/constants'\nimport { DBSchema } from '../../../infrastructure/database/interfaces/database.interface'\nimport { concatDistinctObjectsInArray, dateTimeUTC, dbCheckAffectedRows, dbGetInsertedId } from '../../../infrastructure/database/utils'\nimport { GROUP_TYPE } from '../constants/group'\nimport { MEMBER_TYPE } from '../constants/member'\nimport { USER_GROUP_ROLE, USER_ROLE, USER_SECRET } from '../constants/user'\nimport { CreateOrUpdateGroupDto } from '../dto/create-or-update-group.dto'\nimport type { AdminGroup } from '../interfaces/admin-group.interface'\nimport type { AdminUser } from '../interfaces/admin-user.interface'\nimport { Member } from '../interfaces/member.interface'\nimport type { Group } from '../schemas/group.interface'\nimport { groups } from '../schemas/groups.schema'\nimport { UserGroup } from '../schemas/user-group.interface'\nimport { usersGroups } from '../schemas/users-groups.schema'\nimport { usersGuests } from '../schemas/users-guests.schema'\nimport { userFullNameSQL, users } from '../schemas/users.schema'\nimport { UsersQueries } from './users-queries.service'\n\n@Injectable()\nexport class AdminUsersQueries {\n private readonly logger = new Logger(AdminUsersQueries.name)\n\n constructor(\n @Inject(DB_TOKEN_PROVIDER) private readonly db: DBSchema,\n public readonly usersQueries: UsersQueries\n ) {}\n\n async listUsers(): Promise<AdminUser[]>\n async listUsers(userId: number): Promise<AdminUser>\n async listUsers(userId?: number): Promise<AdminUser | AdminUser[]> {\n const where: SQL[] = [lte(users.role, USER_ROLE.USER), ...(userId ? [eq(users.id, userId)] : [])]\n const q = this.db\n .select({\n id: users.id,\n login: users.login,\n email: users.email,\n role: users.role,\n fullName: userFullNameSQL(users),\n isActive: users.isActive,\n ...(userId && {\n firstName: users.firstName,\n lastName: users.lastName,\n notification: users.notification,\n permissions: users.permissions,\n twoFaEnabled:\n sql<boolean>`JSON_UNQUOTE(JSON_EXTRACT(${users.secrets}, ${sql.raw(`'$.${USER_SECRET.TWO_FA_SECRET}'`)})) IS NOT NULL`.mapWith(Boolean),\n groups: concatDistinctObjectsInArray(groups.id, {\n id: groups.id,\n name: groups.name,\n description: groups.description,\n type: sql.raw(`'${MEMBER_TYPE.GROUP}'`),\n permissions: groups.permissions,\n createdAt: dateTimeUTC(usersGroups.createdAt)\n } satisfies Record<keyof Pick<Member, 'id' | 'name' | 'description' | 'type' | 'permissions' | 'createdAt'>, any>)\n }),\n language: users.language,\n passwordAttempts: users.passwordAttempts,\n storageUsage: users.storageUsage,\n storageQuota: users.storageQuota,\n currentIp: users.currentIp,\n lastIp: users.lastIp,\n currentAccess: users.currentAccess,\n lastAccess: users.lastAccess,\n createdAt: users.createdAt\n } satisfies AdminUser | SelectedFields<any, any>)\n .from(users)\n if (userId) {\n q.leftJoin(usersGroups, eq(usersGroups.userId, users.id))\n q.leftJoin(groups, and(eq(groups.id, usersGroups.groupId), eq(groups.type, GROUP_TYPE.USER)))\n q.limit(1)\n }\n q.where(and(...where)).groupBy(users.id)\n const rs: AdminUser[] = await q\n if (userId) {\n return rs.length ? rs[0] : null\n }\n return rs\n }\n\n async groupFromId(groupId: number): Promise<AdminGroup> {\n const groupParent = alias(groups, 'groupParent')\n const [group] = await this.db\n .select({\n id: groups.id,\n name: groups.name,\n type: groups.type,\n description: groups.description,\n permissions: groups.permissions,\n visibility: groups.visibility,\n createdAt: groups.createdAt,\n modifiedAt: groups.modifiedAt,\n parent: { id: groupParent.id, name: groupParent.name }\n } satisfies AdminGroup | SelectedFields<any, any>)\n .from(groups)\n .leftJoin(groupParent, eq(groupParent.id, groups.parentId))\n .where(eq(groups.id, groupId))\n .limit(1)\n return group\n }\n\n async deleteUser(userId: number, userLogin: string): Promise<boolean> {\n return dbCheckAffectedRows(await this.db.delete(users).where(and(eq(users.id, userId), eq(users.login, userLogin))), 1, false)\n }\n\n async groupFromName(groupName: string): Promise<Pick<Group, 'id' | 'name' | 'type'>> {\n const [group] = await this.db\n .select({\n id: groups.id,\n name: groups.name,\n type: groups.type\n } satisfies Pick<Group, 'id' | 'name' | 'type'> | SelectedFields<any, any>)\n .from(groups)\n .where(eq(groups.name, groupName))\n .limit(1)\n return group\n }\n\n async browseRootGroupMembers(type: GROUP_TYPE = GROUP_TYPE.USER): Promise<Member[]> {\n const childGroups = alias(groups, 'childGroups')\n return this.db\n .select({\n id: groups.id,\n name: groups.name,\n description: groups.description,\n createdAt: groups.createdAt,\n modifiedAt: groups.modifiedAt,\n type: sql<MEMBER_TYPE>`IF(${groups.type} = ${GROUP_TYPE.USER}, ${MEMBER_TYPE.GROUP}, ${MEMBER_TYPE.PGROUP})`,\n counts: { users: count(usersGroups.userId), groups: countDistinct(childGroups.id) }\n } satisfies Member | SelectedFields<any, any>)\n .from(groups)\n .leftJoin(usersGroups, eq(usersGroups.groupId, groups.id))\n .leftJoin(childGroups, eq(childGroups.parentId, groups.id))\n .where(and(isNull(groups.parentId), eq(groups.type, type)))\n .groupBy(groups.id)\n }\n\n async browseGroupMembers(groupId: number, type: GROUP_TYPE = GROUP_TYPE.USER): Promise<Member[]> {\n const childGroups = alias(groups, 'childGroups')\n const childGroupMembers = alias(usersGroups, 'childGroupMembers')\n const subChildGroups = alias(groups, 'subChildGroups')\n const userMembers = this.db\n .select({\n id: users.id,\n login: users.login,\n name: userFullNameSQL(users).as('name'),\n description: users.email,\n createdAt: usersGroups.createdAt,\n modifiedAt: sql<Date>`NULL`,\n type: sql<MEMBER_TYPE>`${MEMBER_TYPE.USER}`,\n groupRole: sql<USER_GROUP_ROLE>`${usersGroups.role}`.mapWith(Number),\n counts: { users: sql<number>`0`, groups: sql<number>`0` }\n } satisfies Member | SelectedFields<any, any>)\n .from(groups)\n .innerJoin(usersGroups, eq(usersGroups.groupId, groups.id))\n .leftJoin(users, eq(users.id, usersGroups.userId))\n .where(and(eq(groups.id, groupId), eq(groups.type, type), isNotNull(users.id)))\n .groupBy(users.id)\n if (type === GROUP_TYPE.PERSONAL) {\n return userMembers\n }\n const groupMembers: any = this.db\n .select({\n id: childGroups.id,\n login: sql`NULL`,\n name: childGroups.name,\n description: childGroups.description,\n createdAt: childGroups.createdAt,\n modifiedAt: childGroups.modifiedAt,\n type: sql<MEMBER_TYPE>`${MEMBER_TYPE.GROUP}`,\n groupRole: sql<USER_GROUP_ROLE>`null`,\n counts: { users: count(usersGroups.userId), groups: count(subChildGroups.id) }\n } satisfies Member | SelectedFields<any, any>)\n .from(groups)\n .innerJoin(childGroups, eq(childGroups.parentId, groups.id))\n .leftJoin(usersGroups, eq(usersGroups.groupId, childGroups.id))\n .leftJoin(childGroupMembers, eq(childGroupMembers.groupId, childGroups.id))\n .leftJoin(subChildGroups, eq(subChildGroups.parentId, childGroups.id))\n .where(and(eq(groups.id, groupId), eq(groups.type, type), isNotNull(childGroups.id)))\n .groupBy(childGroups.id)\n return union(userMembers, groupMembers)\n }\n\n async updateUserGroups(userId: number, groups: { add: number[]; delete: number[] }): Promise<void> {\n if (groups.add.length) {\n try {\n dbCheckAffectedRows(\n await this.db.insert(usersGroups).values(\n groups.add.map((gid: number) => ({\n userId: userId,\n groupId: gid\n }))\n ),\n groups.add.length\n )\n this.logger.log(`${this.updateUserGroups.name} - user (${userId}) groups ${JSON.stringify(groups.add)} was added`)\n this.usersQueries.clearWhiteListCaches([userId])\n } catch (e) {\n this.logger.error(`${this.updateUserGroups.name} - user (${userId}) groups ${JSON.stringify(groups.add)} was not added: ${e}`)\n throw new Error('User groups was not added')\n }\n }\n if (groups.delete.length) {\n try {\n dbCheckAffectedRows(\n await this.db.delete(usersGroups).where(and(eq(usersGroups.userId, userId), inArray(usersGroups.groupId, groups.delete))),\n groups.delete.length\n )\n this.logger.log(`${this.updateUserGroups.name} - user (${userId}) groups ${JSON.stringify(groups.delete)} was deleted`)\n this.usersQueries.clearWhiteListCaches([userId])\n } catch (e) {\n this.logger.error(`${this.updateUserGroups.name} - user (${userId}) groups ${JSON.stringify(groups.delete)} was not deleted: ${e}`)\n throw new Error('User groups was not deleted')\n }\n }\n }\n\n async createGroup(createGroupDto: CreateOrUpdateGroupDto): Promise<Group['id']> {\n return dbGetInsertedId(await this.db.insert(groups).values({ ...createGroupDto, type: GROUP_TYPE.USER } as Group))\n }\n\n async updateGroup(groupId: number, set: Partial<Record<keyof Group, any>>): Promise<boolean> {\n try {\n dbCheckAffectedRows(await this.db.update(groups).set(set).where(eq(groups.id, groupId)), 1)\n this.logger.log(`${this.updateGroup.name} - group (${groupId}) was updated : ${JSON.stringify(set)}`)\n return true\n } catch (e) {\n this.logger.error(`${this.updateGroup.name} - group (${groupId}) was not updated : ${JSON.stringify(set)} : ${e}`)\n return false\n }\n }\n\n async deleteGroup(groupId: number): Promise<boolean> {\n const [parent] = await this.db.select({ id: groups.parentId }).from(groups).where(eq(groups.id, groupId)).limit(1)\n const parentId = parent?.id\n if (parentId) {\n // attach child groups to current parent\n await this.db\n .update(groups)\n .set({ parentId: parentId } as Partial<Group>)\n .where(eq(groups.parentId, groupId))\n }\n return dbCheckAffectedRows(await this.db.delete(groups).where(eq(groups.id, groupId)).limit(1), 1, false)\n }\n\n async addUsersToGroup(groupId: number, userIds: number[], lowerOrEqualUserRole: USER_ROLE = USER_ROLE.GUEST): Promise<void> {\n const userIdsWithRequiredRole = await this.db\n .select({ id: users.id })\n .from(users)\n .where(and(inArray(users.id, userIds), lte(users.role, lowerOrEqualUserRole)))\n userIds = userIdsWithRequiredRole.map((u) => u.id)\n if (userIds.length === 0) {\n throw new Error('No users to add to group')\n }\n try {\n dbCheckAffectedRows(\n await this.db.insert(usersGroups).values(\n userIdsWithRequiredRole.map((u) => ({\n groupId: groupId,\n userId: u.id\n }))\n ),\n userIdsWithRequiredRole.length\n )\n this.logger.log(`${this.addUsersToGroup.name} - users (${userIds}) was added to group (${groupId})`)\n this.usersQueries.clearWhiteListCaches(userIds)\n } catch (e) {\n this.logger.error(`${this.addUsersToGroup.name} - unable to add users (${userIds}) to group (${groupId}) : ${e}`)\n throw new Error('Unable to add users to group')\n }\n }\n\n async updateUserFromGroup(groupId: number, userId: number, role: USER_GROUP_ROLE): Promise<void> {\n try {\n dbCheckAffectedRows(\n await this.db\n .update(usersGroups)\n .set({ role: role } as UserGroup)\n .where(and(eq(usersGroups.groupId, groupId), eq(usersGroups.userId, userId)))\n .limit(1),\n 1\n )\n this.logger.log(`${this.updateUserFromGroup.name} - user (${userId}) was updated on group (${groupId}) as ${USER_GROUP_ROLE[role]}`)\n } catch (e) {\n this.logger.error(\n `${this.updateUserFromGroup.name} - user (${userId}) was not updated on group (${groupId}) as ${USER_GROUP_ROLE[role]} : ${e}`\n )\n throw new Error('Unable to update user from group')\n }\n }\n\n async removeUserFromGroup(groupId: number, userId: number): Promise<void> {\n try {\n dbCheckAffectedRows(\n await this.db\n .delete(usersGroups)\n .where(and(eq(usersGroups.groupId, groupId), eq(usersGroups.userId, userId)))\n .limit(1),\n 1\n )\n this.logger.log(`${this.removeUserFromGroup.name} - user (${userId}) was removed from group (${groupId})`)\n this.usersQueries.clearWhiteListCaches([userId])\n } catch (e) {\n this.logger.error(`${this.removeUserFromGroup.name} - user (${userId}) or group (${groupId}) does not exist : ${e}`)\n throw new Error('Unable to remove user from group')\n }\n }\n\n async updateGuestManagers(guestId: number, managers: { add: number[]; delete: number[] }): Promise<void> {\n if (managers.add.length) {\n try {\n dbCheckAffectedRows(\n await this.db.insert(usersGuests).values(\n managers.add.map((uid: number) => ({\n userId: uid,\n guestId: guestId\n }))\n ),\n managers.add.length\n )\n this.logger.log(`${this.updateGuestManagers.name} - guest (${guestId}) managers ${JSON.stringify(managers.add)} was added`)\n } catch (e) {\n this.logger.error(`${this.updateGuestManagers.name} - guest (${guestId}) managers ${JSON.stringify(managers.add)} was not added: ${e}`)\n throw new Error('Guest managers was not added')\n }\n }\n if (managers.delete.length) {\n try {\n dbCheckAffectedRows(\n await this.db.delete(usersGuests).where(and(eq(usersGuests.guestId, guestId), inArray(usersGuests.userId, managers.delete))),\n managers.delete.length\n )\n this.logger.log(`${this.updateGuestManagers.name} - guest (${guestId}) managers ${JSON.stringify(managers.delete)} was deleted`)\n } catch (e) {\n this.logger.error(`${this.updateGuestManagers.name} - guest (${guestId}) managers ${JSON.stringify(managers.delete)} was not deleted: ${e}`)\n throw new Error('Guest managers was not deleted')\n }\n }\n }\n}\n"],"names":["AdminUsersQueries","listUsers","userId","where","lte","users","role","USER_ROLE","USER","eq","id","q","db","select","login","email","fullName","userFullNameSQL","isActive","firstName","lastName","notification","permissions","twoFaEnabled","sql","secrets","raw","USER_SECRET","TWO_FA_SECRET","mapWith","Boolean","groups","concatDistinctObjectsInArray","name","description","type","MEMBER_TYPE","GROUP","createdAt","dateTimeUTC","usersGroups","language","passwordAttempts","storageUsage","storageQuota","currentIp","lastIp","currentAccess","lastAccess","from","leftJoin","and","groupId","GROUP_TYPE","limit","groupBy","rs","length","groupFromId","groupParent","alias","group","visibility","modifiedAt","parent","parentId","deleteUser","userLogin","dbCheckAffectedRows","delete","groupFromName","groupName","browseRootGroupMembers","childGroups","PGROUP","counts","count","countDistinct","isNull","browseGroupMembers","childGroupMembers","subChildGroups","userMembers","as","groupRole","Number","innerJoin","isNotNull","PERSONAL","groupMembers","union","updateUserGroups","add","insert","values","map","gid","logger","log","JSON","stringify","usersQueries","clearWhiteListCaches","e","error","Error","inArray","createGroup","createGroupDto","dbGetInsertedId","updateGroup","set","update","deleteGroup","addUsersToGroup","userIds","lowerOrEqualUserRole","GUEST","userIdsWithRequiredRole","u","updateUserFromGroup","USER_GROUP_ROLE","removeUserFromGroup","updateGuestManagers","guestId","managers","usersGuests","uid","Logger"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../../backend/src/applications/users/services/admin-users-queries.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 { Inject, Injectable, Logger } from '@nestjs/common'\nimport { and, count, countDistinct, eq, inArray, isNotNull, isNull, lte, SelectedFields, SQL, sql } from 'drizzle-orm'\nimport { alias, union } from 'drizzle-orm/mysql-core'\nimport { DB_TOKEN_PROVIDER } from '../../../infrastructure/database/constants'\nimport { DBSchema } from '../../../infrastructure/database/interfaces/database.interface'\nimport { concatDistinctObjectsInArray, dateTimeUTC, dbCheckAffectedRows, dbGetInsertedId } from '../../../infrastructure/database/utils'\nimport { UserMailNotification } from '../../notifications/interfaces/user-mail-notification.interface'\nimport { GROUP_TYPE } from '../constants/group'\nimport { MEMBER_TYPE } from '../constants/member'\nimport { USER_GROUP_ROLE, USER_ROLE, USER_SECRET } from '../constants/user'\nimport { CreateOrUpdateGroupDto } from '../dto/create-or-update-group.dto'\nimport type { AdminGroup } from '../interfaces/admin-group.interface'\nimport type { AdminUser } from '../interfaces/admin-user.interface'\nimport { Member } from '../interfaces/member.interface'\nimport type { Group } from '../schemas/group.interface'\nimport { groups } from '../schemas/groups.schema'\nimport { UserGroup } from '../schemas/user-group.interface'\nimport { usersGroups } from '../schemas/users-groups.schema'\nimport { usersGuests } from '../schemas/users-guests.schema'\nimport { userFullNameSQL, users } from '../schemas/users.schema'\nimport { UsersQueries } from './users-queries.service'\n\n@Injectable()\nexport class AdminUsersQueries {\n private readonly logger = new Logger(AdminUsersQueries.name)\n\n constructor(\n @Inject(DB_TOKEN_PROVIDER) private readonly db: DBSchema,\n public readonly usersQueries: UsersQueries\n ) {}\n\n async listUsers(): Promise<AdminUser[]>\n async listUsers(userId: number): Promise<AdminUser>\n async listUsers(userId?: number): Promise<AdminUser | AdminUser[]> {\n const where: SQL[] = [lte(users.role, USER_ROLE.USER), ...(userId ? [eq(users.id, userId)] : [])]\n const q = this.db\n .select({\n id: users.id,\n login: users.login,\n email: users.email,\n role: users.role,\n fullName: userFullNameSQL(users),\n isActive: users.isActive,\n ...(userId && {\n firstName: users.firstName,\n lastName: users.lastName,\n notification: users.notification,\n permissions: users.permissions,\n twoFaEnabled:\n sql<boolean>`JSON_UNQUOTE(JSON_EXTRACT(${users.secrets}, ${sql.raw(`'$.${USER_SECRET.TWO_FA_SECRET}'`)})) IS NOT NULL`.mapWith(Boolean),\n groups: concatDistinctObjectsInArray(groups.id, {\n id: groups.id,\n name: groups.name,\n description: groups.description,\n type: sql.raw(`'${MEMBER_TYPE.GROUP}'`),\n permissions: groups.permissions,\n createdAt: dateTimeUTC(usersGroups.createdAt)\n } satisfies Record<keyof Pick<Member, 'id' | 'name' | 'description' | 'type' | 'permissions' | 'createdAt'>, any>)\n }),\n language: users.language,\n passwordAttempts: users.passwordAttempts,\n storageUsage: users.storageUsage,\n storageQuota: users.storageQuota,\n currentIp: users.currentIp,\n lastIp: users.lastIp,\n currentAccess: users.currentAccess,\n lastAccess: users.lastAccess,\n createdAt: users.createdAt\n } satisfies AdminUser | SelectedFields<any, any>)\n .from(users)\n if (userId) {\n q.leftJoin(usersGroups, eq(usersGroups.userId, users.id))\n q.leftJoin(groups, and(eq(groups.id, usersGroups.groupId), eq(groups.type, GROUP_TYPE.USER)))\n q.limit(1)\n }\n q.where(and(...where)).groupBy(users.id)\n const rs: AdminUser[] = await q\n if (userId) {\n return rs.length ? rs[0] : null\n }\n return rs\n }\n\n async listAdminsToNotify(): Promise<UserMailNotification[]> {\n return this.db\n .select({ id: users.id, email: users.email, language: users.language, notification: users.notification })\n .from(users)\n .where(eq(users.role, USER_ROLE.ADMINISTRATOR))\n }\n\n async groupFromId(groupId: number): Promise<AdminGroup> {\n const groupParent = alias(groups, 'groupParent')\n const [group] = await this.db\n .select({\n id: groups.id,\n name: groups.name,\n type: groups.type,\n description: groups.description,\n permissions: groups.permissions,\n visibility: groups.visibility,\n createdAt: groups.createdAt,\n modifiedAt: groups.modifiedAt,\n parent: { id: groupParent.id, name: groupParent.name }\n } satisfies AdminGroup | SelectedFields<any, any>)\n .from(groups)\n .leftJoin(groupParent, eq(groupParent.id, groups.parentId))\n .where(eq(groups.id, groupId))\n .limit(1)\n return group\n }\n\n async deleteUser(userId: number, userLogin: string): Promise<boolean> {\n return dbCheckAffectedRows(await this.db.delete(users).where(and(eq(users.id, userId), eq(users.login, userLogin))), 1, false)\n }\n\n async groupFromName(groupName: string): Promise<Pick<Group, 'id' | 'name' | 'type'>> {\n const [group] = await this.db\n .select({\n id: groups.id,\n name: groups.name,\n type: groups.type\n } satisfies Pick<Group, 'id' | 'name' | 'type'> | SelectedFields<any, any>)\n .from(groups)\n .where(eq(groups.name, groupName))\n .limit(1)\n return group\n }\n\n async browseRootGroupMembers(type: GROUP_TYPE = GROUP_TYPE.USER): Promise<Member[]> {\n const childGroups = alias(groups, 'childGroups')\n return this.db\n .select({\n id: groups.id,\n name: groups.name,\n description: groups.description,\n createdAt: groups.createdAt,\n modifiedAt: groups.modifiedAt,\n type: sql<MEMBER_TYPE>`IF(${groups.type} = ${GROUP_TYPE.USER}, ${MEMBER_TYPE.GROUP}, ${MEMBER_TYPE.PGROUP})`,\n counts: { users: count(usersGroups.userId), groups: countDistinct(childGroups.id) }\n } satisfies Member | SelectedFields<any, any>)\n .from(groups)\n .leftJoin(usersGroups, eq(usersGroups.groupId, groups.id))\n .leftJoin(childGroups, eq(childGroups.parentId, groups.id))\n .where(and(isNull(groups.parentId), eq(groups.type, type)))\n .groupBy(groups.id)\n }\n\n async browseGroupMembers(groupId: number, type: GROUP_TYPE = GROUP_TYPE.USER): Promise<Member[]> {\n const childGroups = alias(groups, 'childGroups')\n const childGroupMembers = alias(usersGroups, 'childGroupMembers')\n const subChildGroups = alias(groups, 'subChildGroups')\n const userMembers = this.db\n .select({\n id: users.id,\n login: users.login,\n name: userFullNameSQL(users).as('name'),\n description: users.email,\n createdAt: usersGroups.createdAt,\n modifiedAt: sql<Date>`NULL`,\n type: sql<MEMBER_TYPE>`${MEMBER_TYPE.USER}`,\n groupRole: sql<USER_GROUP_ROLE>`${usersGroups.role}`.mapWith(Number),\n counts: { users: sql<number>`0`, groups: sql<number>`0` }\n } satisfies Member | SelectedFields<any, any>)\n .from(groups)\n .innerJoin(usersGroups, eq(usersGroups.groupId, groups.id))\n .leftJoin(users, eq(users.id, usersGroups.userId))\n .where(and(eq(groups.id, groupId), eq(groups.type, type), isNotNull(users.id)))\n .groupBy(users.id)\n if (type === GROUP_TYPE.PERSONAL) {\n return userMembers\n }\n const groupMembers: any = this.db\n .select({\n id: childGroups.id,\n login: sql`NULL`,\n name: childGroups.name,\n description: childGroups.description,\n createdAt: childGroups.createdAt,\n modifiedAt: childGroups.modifiedAt,\n type: sql<MEMBER_TYPE>`${MEMBER_TYPE.GROUP}`,\n groupRole: sql<USER_GROUP_ROLE>`null`,\n counts: { users: count(usersGroups.userId), groups: count(subChildGroups.id) }\n } satisfies Member | SelectedFields<any, any>)\n .from(groups)\n .innerJoin(childGroups, eq(childGroups.parentId, groups.id))\n .leftJoin(usersGroups, eq(usersGroups.groupId, childGroups.id))\n .leftJoin(childGroupMembers, eq(childGroupMembers.groupId, childGroups.id))\n .leftJoin(subChildGroups, eq(subChildGroups.parentId, childGroups.id))\n .where(and(eq(groups.id, groupId), eq(groups.type, type), isNotNull(childGroups.id)))\n .groupBy(childGroups.id)\n return union(userMembers, groupMembers)\n }\n\n async updateUserGroups(userId: number, groups: { add: number[]; delete: number[] }): Promise<void> {\n if (groups.add.length) {\n try {\n dbCheckAffectedRows(\n await this.db.insert(usersGroups).values(\n groups.add.map((gid: number) => ({\n userId: userId,\n groupId: gid\n }))\n ),\n groups.add.length\n )\n this.logger.log(`${this.updateUserGroups.name} - user (${userId}) groups ${JSON.stringify(groups.add)} was added`)\n this.usersQueries.clearWhiteListCaches([userId])\n } catch (e) {\n this.logger.error(`${this.updateUserGroups.name} - user (${userId}) groups ${JSON.stringify(groups.add)} was not added: ${e}`)\n throw new Error('User groups was not added')\n }\n }\n if (groups.delete.length) {\n try {\n dbCheckAffectedRows(\n await this.db.delete(usersGroups).where(and(eq(usersGroups.userId, userId), inArray(usersGroups.groupId, groups.delete))),\n groups.delete.length\n )\n this.logger.log(`${this.updateUserGroups.name} - user (${userId}) groups ${JSON.stringify(groups.delete)} was deleted`)\n this.usersQueries.clearWhiteListCaches([userId])\n } catch (e) {\n this.logger.error(`${this.updateUserGroups.name} - user (${userId}) groups ${JSON.stringify(groups.delete)} was not deleted: ${e}`)\n throw new Error('User groups was not deleted')\n }\n }\n }\n\n async createGroup(createGroupDto: CreateOrUpdateGroupDto): Promise<Group['id']> {\n return dbGetInsertedId(await this.db.insert(groups).values({ ...createGroupDto, type: GROUP_TYPE.USER } as Group))\n }\n\n async updateGroup(groupId: number, set: Partial<Record<keyof Group, any>>): Promise<boolean> {\n try {\n dbCheckAffectedRows(await this.db.update(groups).set(set).where(eq(groups.id, groupId)), 1)\n this.logger.log(`${this.updateGroup.name} - group (${groupId}) was updated : ${JSON.stringify(set)}`)\n return true\n } catch (e) {\n this.logger.error(`${this.updateGroup.name} - group (${groupId}) was not updated : ${JSON.stringify(set)} : ${e}`)\n return false\n }\n }\n\n async deleteGroup(groupId: number): Promise<boolean> {\n const [parent] = await this.db.select({ id: groups.parentId }).from(groups).where(eq(groups.id, groupId)).limit(1)\n const parentId = parent?.id\n if (parentId) {\n // attach child groups to current parent\n await this.db\n .update(groups)\n .set({ parentId: parentId } as Partial<Group>)\n .where(eq(groups.parentId, groupId))\n }\n return dbCheckAffectedRows(await this.db.delete(groups).where(eq(groups.id, groupId)).limit(1), 1, false)\n }\n\n async addUsersToGroup(groupId: number, userIds: number[], lowerOrEqualUserRole: USER_ROLE = USER_ROLE.GUEST): Promise<void> {\n const userIdsWithRequiredRole = await this.db\n .select({ id: users.id })\n .from(users)\n .where(and(inArray(users.id, userIds), lte(users.role, lowerOrEqualUserRole)))\n userIds = userIdsWithRequiredRole.map((u) => u.id)\n if (userIds.length === 0) {\n throw new Error('No users to add to group')\n }\n try {\n dbCheckAffectedRows(\n await this.db.insert(usersGroups).values(\n userIdsWithRequiredRole.map((u) => ({\n groupId: groupId,\n userId: u.id\n }))\n ),\n userIdsWithRequiredRole.length\n )\n this.logger.log(`${this.addUsersToGroup.name} - users (${userIds}) was added to group (${groupId})`)\n this.usersQueries.clearWhiteListCaches(userIds)\n } catch (e) {\n this.logger.error(`${this.addUsersToGroup.name} - unable to add users (${userIds}) to group (${groupId}) : ${e}`)\n throw new Error('Unable to add users to group')\n }\n }\n\n async updateUserFromGroup(groupId: number, userId: number, role: USER_GROUP_ROLE): Promise<void> {\n try {\n dbCheckAffectedRows(\n await this.db\n .update(usersGroups)\n .set({ role: role } as UserGroup)\n .where(and(eq(usersGroups.groupId, groupId), eq(usersGroups.userId, userId)))\n .limit(1),\n 1\n )\n this.logger.log(`${this.updateUserFromGroup.name} - user (${userId}) was updated on group (${groupId}) as ${USER_GROUP_ROLE[role]}`)\n } catch (e) {\n this.logger.error(\n `${this.updateUserFromGroup.name} - user (${userId}) was not updated on group (${groupId}) as ${USER_GROUP_ROLE[role]} : ${e}`\n )\n throw new Error('Unable to update user from group')\n }\n }\n\n async removeUserFromGroup(groupId: number, userId: number): Promise<void> {\n try {\n dbCheckAffectedRows(\n await this.db\n .delete(usersGroups)\n .where(and(eq(usersGroups.groupId, groupId), eq(usersGroups.userId, userId)))\n .limit(1),\n 1\n )\n this.logger.log(`${this.removeUserFromGroup.name} - user (${userId}) was removed from group (${groupId})`)\n this.usersQueries.clearWhiteListCaches([userId])\n } catch (e) {\n this.logger.error(`${this.removeUserFromGroup.name} - user (${userId}) or group (${groupId}) does not exist : ${e}`)\n throw new Error('Unable to remove user from group')\n }\n }\n\n async updateGuestManagers(guestId: number, managers: { add: number[]; delete: number[] }): Promise<void> {\n if (managers.add.length) {\n try {\n dbCheckAffectedRows(\n await this.db.insert(usersGuests).values(\n managers.add.map((uid: number) => ({\n userId: uid,\n guestId: guestId\n }))\n ),\n managers.add.length\n )\n this.logger.log(`${this.updateGuestManagers.name} - guest (${guestId}) managers ${JSON.stringify(managers.add)} was added`)\n } catch (e) {\n this.logger.error(`${this.updateGuestManagers.name} - guest (${guestId}) managers ${JSON.stringify(managers.add)} was not added: ${e}`)\n throw new Error('Guest managers was not added')\n }\n }\n if (managers.delete.length) {\n try {\n dbCheckAffectedRows(\n await this.db.delete(usersGuests).where(and(eq(usersGuests.guestId, guestId), inArray(usersGuests.userId, managers.delete))),\n managers.delete.length\n )\n this.logger.log(`${this.updateGuestManagers.name} - guest (${guestId}) managers ${JSON.stringify(managers.delete)} was deleted`)\n } catch (e) {\n this.logger.error(`${this.updateGuestManagers.name} - guest (${guestId}) managers ${JSON.stringify(managers.delete)} was not deleted: ${e}`)\n throw new Error('Guest managers was not deleted')\n }\n }\n }\n}\n"],"names":["AdminUsersQueries","listUsers","userId","where","lte","users","role","USER_ROLE","USER","eq","id","q","db","select","login","email","fullName","userFullNameSQL","isActive","firstName","lastName","notification","permissions","twoFaEnabled","sql","secrets","raw","USER_SECRET","TWO_FA_SECRET","mapWith","Boolean","groups","concatDistinctObjectsInArray","name","description","type","MEMBER_TYPE","GROUP","createdAt","dateTimeUTC","usersGroups","language","passwordAttempts","storageUsage","storageQuota","currentIp","lastIp","currentAccess","lastAccess","from","leftJoin","and","groupId","GROUP_TYPE","limit","groupBy","rs","length","listAdminsToNotify","ADMINISTRATOR","groupFromId","groupParent","alias","group","visibility","modifiedAt","parent","parentId","deleteUser","userLogin","dbCheckAffectedRows","delete","groupFromName","groupName","browseRootGroupMembers","childGroups","PGROUP","counts","count","countDistinct","isNull","browseGroupMembers","childGroupMembers","subChildGroups","userMembers","as","groupRole","Number","innerJoin","isNotNull","PERSONAL","groupMembers","union","updateUserGroups","add","insert","values","map","gid","logger","log","JSON","stringify","usersQueries","clearWhiteListCaches","e","error","Error","inArray","createGroup","createGroupDto","dbGetInsertedId","updateGroup","set","update","deleteGroup","addUsersToGroup","userIds","lowerOrEqualUserRole","GUEST","userIdsWithRequiredRole","u","updateUserFromGroup","USER_GROUP_ROLE","removeUserFromGroup","updateGuestManagers","guestId","managers","usersGuests","uid","Logger"],"mappings":"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"}
|
|
@@ -16,7 +16,6 @@ const _common = require("@nestjs/common");
|
|
|
16
16
|
const _bcryptjs = /*#__PURE__*/ _interop_require_default(require("bcryptjs"));
|
|
17
17
|
const _nodefs = require("node:fs");
|
|
18
18
|
const _nodepath = /*#__PURE__*/ _interop_require_default(require("node:path"));
|
|
19
|
-
const _nodestream = require("node:stream");
|
|
20
19
|
const _promises = require("node:stream/promises");
|
|
21
20
|
const _constants = require("../../../common/constants");
|
|
22
21
|
const _functions = require("../../../common/functions");
|
|
@@ -206,7 +205,7 @@ let UsersManager = class UsersManager {
|
|
|
206
205
|
throw new _common.HttpException(`avatar not found`, _common.HttpStatus.NOT_FOUND);
|
|
207
206
|
}
|
|
208
207
|
const avatarFile = (0, _nodefs.createWriteStream)(avatarPath);
|
|
209
|
-
const avatarStream =
|
|
208
|
+
const avatarStream = await (0, _image.generateAvatar)(user.getInitials());
|
|
210
209
|
try {
|
|
211
210
|
await (0, _promises.pipeline)(avatarStream, avatarFile);
|
|
212
211
|
} catch (e) {
|