@sync-in/server 1.5.2 → 1.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +28 -0
- package/README.md +2 -1
- package/environment/environment.dist.min.yaml +1 -0
- package/environment/environment.dist.yaml +88 -30
- package/migrations/0002_sleepy_korath.sql +1 -0
- package/migrations/meta/0002_snapshot.json +2424 -0
- package/migrations/meta/_journal.json +7 -0
- package/package.json +14 -12
- package/server/app.bootstrap.js +1 -1
- package/server/app.bootstrap.js.map +1 -1
- package/server/applications/files/services/files-manager.service.js +1 -2
- package/server/applications/files/services/files-manager.service.js.map +1 -1
- package/server/applications/files/services/files-only-office-manager.service.js +5 -6
- package/server/applications/files/services/files-only-office-manager.service.js.map +1 -1
- package/server/applications/files/utils/files.js +6 -4
- package/server/applications/files/utils/files.js.map +1 -1
- package/server/applications/links/links.controller.js +2 -2
- package/server/applications/links/links.controller.js.map +1 -1
- package/server/applications/links/services/links-manager.service.js +2 -1
- package/server/applications/links/services/links-manager.service.js.map +1 -1
- package/server/applications/links/services/links-manager.service.spec.js +6 -3
- package/server/applications/links/services/links-manager.service.spec.js.map +1 -1
- package/server/applications/notifications/constants/notifications.js +9 -0
- package/server/applications/notifications/constants/notifications.js.map +1 -1
- package/server/applications/notifications/i18n/fr.js +10 -1
- package/server/applications/notifications/i18n/fr.js.map +1 -1
- package/server/applications/notifications/interfaces/notification-properties.interface.js.map +1 -1
- package/server/applications/notifications/mails/models.js +41 -3
- package/server/applications/notifications/mails/models.js.map +1 -1
- package/server/applications/notifications/mails/templates.js +1 -1
- package/server/applications/notifications/mails/templates.js.map +1 -1
- package/server/applications/notifications/schemas/notifications.schema.js +2 -1
- package/server/applications/notifications/schemas/notifications.schema.js.map +1 -1
- package/server/applications/notifications/services/notifications-manager.service.js +16 -13
- package/server/applications/notifications/services/notifications-manager.service.js.map +1 -1
- package/server/applications/notifications/services/notifications-manager.service.spec.js +9 -8
- package/server/applications/notifications/services/notifications-manager.service.spec.js.map +1 -1
- package/server/applications/notifications/services/notifications-queries.service.js +1 -1
- package/server/applications/notifications/services/notifications-queries.service.js.map +1 -1
- package/server/applications/shares/services/shares-manager.service.js +3 -2
- package/server/applications/shares/services/shares-manager.service.js.map +1 -1
- package/server/applications/sync/constants/auth.js +2 -2
- package/server/applications/sync/constants/auth.js.map +1 -1
- package/server/applications/sync/dtos/sync-client-registration.dto.js +5 -0
- package/server/applications/sync/dtos/sync-client-registration.dto.js.map +1 -1
- package/server/applications/sync/dtos/sync-operations.dto.js +1 -2
- package/server/applications/sync/dtos/sync-operations.dto.js.map +1 -1
- package/server/applications/sync/schemas/sync-clients.schema.js +2 -1
- package/server/applications/sync/schemas/sync-clients.schema.js.map +1 -1
- package/server/applications/sync/schemas/sync-paths.schema.js +2 -1
- package/server/applications/sync/schemas/sync-paths.schema.js.map +1 -1
- package/server/applications/sync/services/sync-clients-manager.service.js +28 -20
- package/server/applications/sync/services/sync-clients-manager.service.js.map +1 -1
- package/server/applications/sync/services/sync-clients-manager.service.spec.js +24 -18
- package/server/applications/sync/services/sync-clients-manager.service.spec.js.map +1 -1
- package/server/applications/sync/services/sync-queries.service.js +5 -5
- package/server/applications/sync/services/sync-queries.service.js.map +1 -1
- package/server/applications/users/admin-users.controller.js +48 -37
- package/server/applications/users/admin-users.controller.js.map +1 -1
- package/server/applications/users/admin-users.controller.spec.js +15 -0
- package/server/applications/users/admin-users.controller.spec.js.map +1 -1
- package/server/applications/users/constants/routes.js +5 -0
- package/server/applications/users/constants/routes.js.map +1 -1
- package/server/applications/users/constants/user.js +8 -0
- package/server/applications/users/constants/user.js.map +1 -1
- package/server/applications/users/dto/delete-user.dto.js +5 -23
- package/server/applications/users/dto/delete-user.dto.js.map +1 -1
- package/server/applications/users/dto/user-properties.dto.js +38 -3
- package/server/applications/users/dto/user-properties.dto.js.map +1 -1
- package/server/applications/users/interfaces/admin-user.interface.js.map +1 -1
- package/server/applications/users/interfaces/user-secrets.interface.js +10 -0
- package/server/applications/users/interfaces/user-secrets.interface.js.map +1 -0
- package/server/applications/users/models/user.model.js +84 -50
- package/server/applications/users/models/user.model.js.map +1 -1
- package/server/applications/users/schemas/user.interface.js.map +1 -1
- package/server/applications/users/schemas/users.schema.js +2 -0
- package/server/applications/users/schemas/users.schema.js.map +1 -1
- package/server/applications/users/services/admin-users-manager.service.js +7 -19
- package/server/applications/users/services/admin-users-manager.service.js.map +1 -1
- package/server/applications/users/services/admin-users-manager.service.spec.js +7 -26
- package/server/applications/users/services/admin-users-manager.service.spec.js.map +1 -1
- package/server/applications/users/services/admin-users-queries.service.js +1 -0
- package/server/applications/users/services/admin-users-queries.service.js.map +1 -1
- package/server/applications/users/services/users-manager.service.js +138 -28
- package/server/applications/users/services/users-manager.service.js.map +1 -1
- package/server/applications/users/services/users-manager.service.spec.js +11 -9
- package/server/applications/users/services/users-manager.service.spec.js.map +1 -1
- package/server/applications/users/services/users-queries.service.js +63 -57
- package/server/applications/users/services/users-queries.service.js.map +1 -1
- package/server/applications/users/users.controller.js +48 -1
- package/server/applications/users/users.controller.js.map +1 -1
- package/server/applications/users/users.controller.spec.js +8 -1
- package/server/applications/users/users.controller.spec.js.map +1 -1
- package/server/applications/users/users.e2e-spec.js +2 -1
- package/server/applications/users/users.e2e-spec.js.map +1 -1
- package/server/applications/users/utils/avatar.js +48 -0
- package/server/applications/users/utils/avatar.js.map +1 -0
- package/server/authentication/auth.config.js +89 -26
- package/server/authentication/auth.config.js.map +1 -1
- package/server/authentication/auth.controller.js +117 -9
- package/server/authentication/auth.controller.js.map +1 -1
- package/server/authentication/auth.controller.spec.js +16 -1
- package/server/authentication/auth.controller.spec.js.map +1 -1
- package/server/authentication/auth.e2e-spec.js +4 -3
- package/server/authentication/auth.e2e-spec.js.map +1 -1
- package/server/authentication/auth.module.js +4 -1
- package/server/authentication/auth.module.js.map +1 -1
- package/server/authentication/constants/auth-ldap.js +44 -0
- package/server/authentication/constants/auth-ldap.js.map +1 -0
- package/server/authentication/constants/auth.js +37 -4
- package/server/authentication/constants/auth.js.map +1 -1
- package/server/authentication/constants/routes.js +21 -0
- package/server/authentication/constants/routes.js.map +1 -1
- package/server/authentication/constants/scope.js +20 -0
- package/server/authentication/constants/scope.js.map +1 -0
- package/server/authentication/dto/login-response.dto.js +27 -4
- package/server/authentication/dto/login-response.dto.js.map +1 -1
- package/server/authentication/dto/token-response.dto.js +5 -0
- package/server/authentication/dto/token-response.dto.js.map +1 -1
- package/server/{applications/users/dto/user-password.dto.js → authentication/dto/two-fa-verify.dto.js} +27 -9
- package/server/authentication/dto/two-fa-verify.dto.js.map +1 -0
- package/server/authentication/guards/auth-basic.strategy.js +6 -5
- package/server/authentication/guards/auth-basic.strategy.js.map +1 -1
- package/server/authentication/guards/auth-token-access.strategy.js +3 -2
- package/server/authentication/guards/auth-token-access.strategy.js.map +1 -1
- package/server/authentication/guards/auth-token-refresh.strategy.js +3 -2
- package/server/authentication/guards/auth-token-refresh.strategy.js.map +1 -1
- package/server/authentication/guards/auth-two-fa-guard.js +81 -0
- package/server/authentication/guards/auth-two-fa-guard.js.map +1 -0
- package/server/authentication/interfaces/jwt-payload.interface.js +5 -0
- package/server/authentication/interfaces/jwt-payload.interface.js.map +1 -1
- package/server/authentication/interfaces/token.interface.js +2 -0
- package/server/authentication/interfaces/token.interface.js.map +1 -1
- package/server/authentication/interfaces/two-fa-setup.interface.js +10 -0
- package/server/authentication/interfaces/two-fa-setup.interface.js.map +1 -0
- package/server/authentication/models/auth-method.js.map +1 -1
- package/server/authentication/services/auth-manager.service.js +72 -49
- package/server/authentication/services/auth-manager.service.js.map +1 -1
- package/server/authentication/services/auth-methods/auth-method-database.service.js +3 -3
- package/server/authentication/services/auth-methods/auth-method-database.service.js.map +1 -1
- package/server/authentication/services/auth-methods/auth-method-database.service.spec.js +5 -0
- package/server/authentication/services/auth-methods/auth-method-database.service.spec.js.map +1 -1
- package/server/authentication/services/auth-methods/auth-method-ldap.service.js +151 -66
- package/server/authentication/services/auth-methods/auth-method-ldap.service.js.map +1 -1
- package/server/authentication/services/auth-methods/auth-method-ldap.service.spec.js +52 -50
- package/server/authentication/services/auth-methods/auth-method-ldap.service.spec.js.map +1 -1
- package/server/authentication/services/auth-methods/auth-method-two-fa.service.js +251 -0
- package/server/authentication/services/auth-methods/auth-method-two-fa.service.js.map +1 -0
- package/server/authentication/services/auth-methods/auth-method-two-fa.service.spec.js +41 -0
- package/server/authentication/services/auth-methods/auth-method-two-fa.service.spec.js.map +1 -0
- package/server/authentication/utils/crypt-secret.js +68 -0
- package/server/authentication/utils/crypt-secret.js.map +1 -0
- package/server/common/functions.js +18 -2
- package/server/common/functions.js.map +1 -1
- package/server/common/qrcode.js +34 -0
- package/server/common/qrcode.js.map +1 -0
- package/server/common/shared.js +18 -0
- package/server/common/shared.js.map +1 -1
- package/server/configuration/config.environment.js +23 -6
- package/server/configuration/config.environment.js.map +1 -1
- package/server/configuration/config.interfaces.js +10 -0
- package/server/configuration/config.interfaces.js.map +1 -0
- package/server/configuration/config.loader.js.map +1 -1
- package/server/configuration/config.validation.js +13 -13
- package/server/configuration/config.validation.js.map +1 -1
- package/server/infrastructure/cache/adapters/mysql-cache.adapter.js +6 -6
- package/server/infrastructure/cache/adapters/mysql-cache.adapter.js.map +1 -1
- package/server/infrastructure/cache/schemas/mysql-cache.schema.js +2 -1
- package/server/infrastructure/cache/schemas/mysql-cache.schema.js.map +1 -1
- package/server/infrastructure/cache/services/cache.service.js.map +1 -1
- package/server/infrastructure/database/columns.js +39 -0
- package/server/infrastructure/database/columns.js.map +1 -0
- package/server/infrastructure/database/database.config.js +0 -1
- package/server/infrastructure/database/database.config.js.map +1 -1
- package/server/infrastructure/mailer/interfaces/mail.interface.js.map +1 -1
- package/server/infrastructure/mailer/mailer.config.js +12 -0
- package/server/infrastructure/mailer/mailer.config.js.map +1 -1
- package/server/infrastructure/mailer/mailer.service.js +2 -1
- package/server/infrastructure/mailer/mailer.service.js.map +1 -1
- package/static/assets/mimes/text-x-c.svg +1 -0
- package/static/assets/pdfjs/build/pdf.mjs +2522 -914
- package/static/assets/pdfjs/build/pdf.mjs.map +1 -1
- package/static/assets/pdfjs/build/pdf.sandbox.mjs +2 -2
- package/static/assets/pdfjs/build/pdf.worker.mjs +1024 -566
- package/static/assets/pdfjs/build/pdf.worker.mjs.map +1 -1
- package/static/assets/pdfjs/version +1 -1
- package/static/assets/pdfjs/web/debugger.mjs +116 -37
- package/static/assets/pdfjs/web/images/comment-popup-editButton.svg +5 -0
- package/static/assets/pdfjs/web/locale/ach/viewer.ftl +0 -12
- package/static/assets/pdfjs/web/locale/af/viewer.ftl +0 -12
- package/static/assets/pdfjs/web/locale/an/viewer.ftl +0 -16
- package/static/assets/pdfjs/web/locale/ar/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/ast/viewer.ftl +0 -19
- package/static/assets/pdfjs/web/locale/az/viewer.ftl +0 -16
- package/static/assets/pdfjs/web/locale/be/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/bg/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/bn/viewer.ftl +0 -16
- package/static/assets/pdfjs/web/locale/bo/viewer.ftl +0 -12
- package/static/assets/pdfjs/web/locale/br/viewer.ftl +0 -22
- package/static/assets/pdfjs/web/locale/brx/viewer.ftl +0 -16
- package/static/assets/pdfjs/web/locale/bs/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/ca/viewer.ftl +12 -23
- package/static/assets/pdfjs/web/locale/cak/viewer.ftl +0 -23
- package/static/assets/pdfjs/web/locale/ckb/viewer.ftl +0 -16
- package/static/assets/pdfjs/web/locale/cs/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/cy/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/da/viewer.ftl +3 -35
- package/static/assets/pdfjs/web/locale/de/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/dsb/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/el/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/en-CA/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/en-GB/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/en-US/viewer.ftl +25 -13
- package/static/assets/pdfjs/web/locale/eo/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/es-AR/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/es-CL/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/es-ES/viewer.ftl +5 -32
- package/static/assets/pdfjs/web/locale/es-MX/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/et/viewer.ftl +0 -16
- package/static/assets/pdfjs/web/locale/eu/viewer.ftl +38 -32
- package/static/assets/pdfjs/web/locale/fa/viewer.ftl +0 -19
- package/static/assets/pdfjs/web/locale/ff/viewer.ftl +0 -12
- package/static/assets/pdfjs/web/locale/fi/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/fr/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/fur/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/fy-NL/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/ga-IE/viewer.ftl +0 -12
- package/static/assets/pdfjs/web/locale/gd/viewer.ftl +0 -23
- package/static/assets/pdfjs/web/locale/gl/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/gn/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/gu-IN/viewer.ftl +0 -12
- package/static/assets/pdfjs/web/locale/he/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/hi-IN/viewer.ftl +0 -16
- package/static/assets/pdfjs/web/locale/hr/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/hsb/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/hu/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/hy-AM/viewer.ftl +372 -16
- package/static/assets/pdfjs/web/locale/hye/viewer.ftl +0 -16
- package/static/assets/pdfjs/web/locale/ia/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/id/viewer.ftl +38 -32
- package/static/assets/pdfjs/web/locale/is/viewer.ftl +27 -32
- package/static/assets/pdfjs/web/locale/it/viewer.ftl +0 -33
- package/static/assets/pdfjs/web/locale/ja/viewer.ftl +31 -33
- package/static/assets/pdfjs/web/locale/ka/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/kab/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/kk/viewer.ftl +31 -32
- package/static/assets/pdfjs/web/locale/km/viewer.ftl +0 -12
- package/static/assets/pdfjs/web/locale/kn/viewer.ftl +0 -12
- package/static/assets/pdfjs/web/locale/ko/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/lij/viewer.ftl +0 -12
- package/static/assets/pdfjs/web/locale/lo/viewer.ftl +0 -23
- package/static/assets/pdfjs/web/locale/lt/viewer.ftl +0 -16
- package/static/assets/pdfjs/web/locale/ltg/viewer.ftl +0 -12
- package/static/assets/pdfjs/web/locale/lv/viewer.ftl +0 -12
- package/static/assets/pdfjs/web/locale/meh/viewer.ftl +0 -14
- package/static/assets/pdfjs/web/locale/mk/viewer.ftl +0 -19
- package/static/assets/pdfjs/web/locale/ml/viewer.ftl +0 -31
- package/static/assets/pdfjs/web/locale/mr/viewer.ftl +0 -16
- package/static/assets/pdfjs/web/locale/ms/viewer.ftl +0 -12
- package/static/assets/pdfjs/web/locale/my/viewer.ftl +0 -12
- package/static/assets/pdfjs/web/locale/nb-NO/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/ne-NP/viewer.ftl +0 -12
- package/static/assets/pdfjs/web/locale/nl/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/nn-NO/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/oc/viewer.ftl +0 -24
- package/static/assets/pdfjs/web/locale/pa-IN/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/pl/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/pt-BR/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/pt-PT/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/rm/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/ro/viewer.ftl +5 -37
- package/static/assets/pdfjs/web/locale/ru/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/sat/viewer.ftl +0 -23
- package/static/assets/pdfjs/web/locale/sc/viewer.ftl +8 -27
- package/static/assets/pdfjs/web/locale/sco/viewer.ftl +0 -16
- package/static/assets/pdfjs/web/locale/si/viewer.ftl +0 -22
- package/static/assets/pdfjs/web/locale/sk/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/skr/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/sl/viewer.ftl +30 -32
- package/static/assets/pdfjs/web/locale/son/viewer.ftl +0 -12
- package/static/assets/pdfjs/web/locale/sq/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/sr/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/sv-SE/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/szl/viewer.ftl +0 -16
- package/static/assets/pdfjs/web/locale/ta/viewer.ftl +0 -12
- package/static/assets/pdfjs/web/locale/te/viewer.ftl +0 -16
- package/static/assets/pdfjs/web/locale/tg/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/th/viewer.ftl +38 -32
- package/static/assets/pdfjs/web/locale/tl/viewer.ftl +0 -16
- package/static/assets/pdfjs/web/locale/tr/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/trs/viewer.ftl +0 -12
- package/static/assets/pdfjs/web/locale/uk/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/ur/viewer.ftl +0 -16
- package/static/assets/pdfjs/web/locale/uz/viewer.ftl +0 -12
- package/static/assets/pdfjs/web/locale/vi/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/xh/viewer.ftl +0 -12
- package/static/assets/pdfjs/web/locale/zh-CN/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/locale/zh-TW/viewer.ftl +0 -32
- package/static/assets/pdfjs/web/viewer.css +586 -437
- package/static/assets/pdfjs/web/viewer.html +12 -23
- package/static/assets/pdfjs/web/viewer.mjs +955 -514
- package/static/assets/pdfjs/web/viewer.mjs.map +1 -1
- package/static/assets/pdfjs/web/wasm/openjpeg.wasm +0 -0
- package/static/assets/pdfjs/web/wasm/openjpeg_nowasm_fallback.js +10 -22
- package/static/{chunk-SPTF6FSM.js → chunk-27YQB3TE.js} +1 -1
- package/static/chunk-2I4CUFUA.js +1 -0
- package/static/chunk-2MTM6SWN.js +4 -0
- package/static/{chunk-7VRUZRJG.js → chunk-34MKICK5.js} +2 -2
- package/static/chunk-5O3DIUU3.js +1 -0
- package/static/{chunk-VJRTMDEJ.js → chunk-6NMVZIIT.js} +1 -1
- package/static/{chunk-L6MU6S2V.js → chunk-7DN7ZAPU.js} +1 -1
- package/static/{chunk-MVO4WZLK.js → chunk-7FUM3JGM.js} +1 -1
- package/static/{chunk-RSS6GYNE.js → chunk-7ITZXYYJ.js} +1 -1
- package/static/chunk-7P27WBGC.js +4 -0
- package/static/chunk-ATP3BFHV.js +562 -0
- package/static/chunk-AWQ2YTVC.js +1 -0
- package/static/chunk-DSOE3FEP.js +1 -0
- package/static/{chunk-2R6HHGUR.js → chunk-EFKMBLRE.js} +1 -1
- package/static/chunk-FUFKVHPU.js +1 -0
- package/static/{chunk-MRSWNAVB.js → chunk-HCDLWTMW.js} +1 -1
- package/static/chunk-IPAC4VAF.js +1 -0
- package/static/{chunk-ZC5NIT55.js → chunk-IQOALFYU.js} +1 -1
- package/static/chunk-JASU3CIH.js +1 -0
- package/static/{chunk-6OJZWYRZ.js → chunk-JQ5FTO2M.js} +1 -1
- package/static/chunk-JUNZFADM.js +1 -0
- package/static/{chunk-LLWSLOSX.js → chunk-LJUKI4SQ.js} +1 -1
- package/static/{chunk-WI7FOANP.js → chunk-LUWQFIWR.js} +1 -1
- package/static/{chunk-BIUNUYZ5.js → chunk-ORMRCEGT.js} +1 -1
- package/static/{chunk-IZL7JPTS.js → chunk-Q7D6RN4N.js} +1 -1
- package/static/{chunk-JYXLQRHG.js → chunk-QJX6ITLW.js} +1 -1
- package/static/{chunk-YJMN3B4N.js → chunk-QQ6UQQBR.js} +1 -1
- package/static/chunk-S2HDY3OL.js +1 -0
- package/static/{chunk-NE4NDO45.js → chunk-S75P2FFI.js} +1 -1
- package/static/{chunk-CRQNEHTX.js → chunk-T3EYFSVZ.js} +1 -1
- package/static/{chunk-MCLQFZ3S.js → chunk-U34OZUZ7.js} +1 -1
- package/static/chunk-Y7EH7G5K.js +1 -0
- package/static/{chunk-MGGT6MIJ.js → chunk-ZQQPUYLU.js} +1 -1
- package/static/index.html +2 -2
- package/static/main-7SQDDVMD.js +9 -0
- package/static/{styles-FYUSO6OJ.css → styles-A5VYX3CE.css} +1 -1
- package/server/applications/users/dto/user-password.dto.js.map +0 -1
- package/static/chunk-4U5A2DEP.js +0 -4
- package/static/chunk-54EAZ2UD.js +0 -1
- package/static/chunk-7ZRXJONB.js +0 -1
- package/static/chunk-F2J2IIJE.js +0 -1
- package/static/chunk-FNFGUIQH.js +0 -4
- package/static/chunk-GGLK52CG.js +0 -1
- package/static/chunk-HW2H3ISM.js +0 -559
- package/static/chunk-HX6BBYVD.js +0 -1
- package/static/chunk-JF7S3UYQ.js +0 -1
- package/static/chunk-KSHPKI4G.js +0 -1
- package/static/chunk-VPJ2V27B.js +0 -1
- package/static/chunk-VUI3KV7V.js +0 -1
- package/static/chunk-ZXS4V7J2.js +0 -1
- package/static/main-FFIWFD2F.js +0 -7
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../backend/src/applications/users/services/users-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 { MultipartFile } from '@fastify/multipart'\nimport { HttpException, HttpStatus, Injectable, Logger } from '@nestjs/common'\nimport bcrypt from 'bcryptjs'\nimport { PNGStream } from 'canvas'\nimport { WriteStream } from 'fs'\nimport { createWriteStream } from 'node:fs'\nimport path from 'node:path'\nimport { pipeline } from 'node:stream/promises'\nimport { FastifyAuthenticatedRequest } from '../../../authentication/interfaces/auth-request.interface'\nimport { JwtIdentityPayload } from '../../../authentication/interfaces/jwt-payload.interface'\nimport { comparePassword } from '../../../common/functions'\nimport { convertImageToBase64, generateAvatar, pngMimeType, svgMimeType } from '../../../common/image'\nimport { STATIC_ASSETS_PATH } from '../../../configuration/config.constants'\nimport { isPathExists, moveFiles } from '../../files/utils/files'\nimport { MEMBER_TYPE } from '../constants/member'\nimport { USER_GROUP_ROLE, USER_MAX_PASSWORD_ATTEMPTS, USER_ONLINE_STATUS, USER_ROLE } from '../constants/user'\nimport { UserCreateOrUpdateGroupDto } from '../dto/create-or-update-group.dto'\nimport { CreateUserDto, UpdateUserDto, UpdateUserFromGroupDto } from '../dto/create-or-update-user.dto'\nimport { SearchMembersDto } from '../dto/search-members.dto'\nimport { UserLanguageDto, UserNotificationDto, UserPasswordDto } from '../dto/user-properties.dto'\nimport type { GroupBrowse } from '../interfaces/group-browse.interface'\nimport type { GroupMember, GroupWithMembers } from '../interfaces/group-member'\nimport type { GuestUser } from '../interfaces/guest-user.interface'\nimport type { Member } from '../interfaces/member.interface'\nimport type { UserOnline } from '../interfaces/websocket.interface'\nimport { UserModel } from '../models/user.model'\nimport type { Group } from '../schemas/group.interface'\nimport type { UserGroup } from '../schemas/user-group.interface'\nimport type { User } from '../schemas/user.interface'\nimport { AdminUsersManager } from './admin-users-manager.service'\nimport { UsersQueries } from './users-queries.service'\n\n@Injectable()\nexport class UsersManager {\n private readonly defaultAvatarFilePath = path.join(STATIC_ASSETS_PATH, 'avatar.svg')\n private readonly userAvatarFileName = 'avatar.png'\n private readonly maxAvatarUploadSize = 1024 * 1024 * 5\n private readonly logger = new Logger(UsersManager.name)\n\n constructor(\n private readonly usersQueries: UsersQueries,\n private readonly adminUsersManager: AdminUsersManager\n ) {}\n\n async fromUserId(id: number): Promise<UserModel> {\n const user: User = await this.usersQueries.from(id)\n return user ? new UserModel(user, true) : null\n }\n\n async findUser(loginOrEmail: string, removePassword: false): Promise<UserModel>\n async findUser(loginOrEmail: string, removePassword?: true): Promise<Omit<UserModel, 'password'>>\n async findUser(loginOrEmail: string, removePassword: boolean = true): Promise<Omit<UserModel, 'password'>> {\n const user: User = await this.usersQueries.from(null, loginOrEmail)\n return user ? new UserModel(user, removePassword) : null\n }\n\n async logUser(user: UserModel, password: string, ip: string): Promise<UserModel> {\n if (user.role === USER_ROLE.LINK) {\n this.logger.error(`${this.logUser.name} - guest link account ${user} is not authorized to login`)\n throw new HttpException('Account is not allowed', HttpStatus.FORBIDDEN)\n }\n if (!user.isActive || user.passwordAttempts >= USER_MAX_PASSWORD_ATTEMPTS) {\n this.updateAccesses(user, ip, false).catch((e: Error) => this.logger.error(`${this.logUser.name} - ${e}`))\n this.logger.error(`${this.logUser.name} - user account *${user.login}* is locked`)\n throw new HttpException('Account locked', HttpStatus.FORBIDDEN)\n }\n const authSuccess: boolean = await comparePassword(password, user.password)\n this.updateAccesses(user, ip, authSuccess).catch((e: Error) => this.logger.error(`${this.logUser.name} - ${e}`))\n if (authSuccess) {\n await user.makePaths()\n return user\n }\n this.logger.warn(`${this.logUser.name} - bad password for *${user.login}*`)\n return null\n }\n\n async me(authUser: UserModel): Promise<{ user: Omit<UserModel, 'password'> }> {\n const user = await this.fromUserId(authUser.id)\n if (!user) {\n throw new HttpException(`User *${authUser.login} (${authUser.id}) not found`, HttpStatus.NOT_FOUND)\n }\n user.impersonated = !!authUser.impersonatedFromId\n user.clientId = authUser.clientId\n return { user: user }\n }\n\n async compareUserPassword(userId: number, password: string): Promise<boolean> {\n return this.usersQueries.compareUserPassword(userId, password)\n }\n\n async updateLanguage(user: UserModel, userLanguageDto: UserLanguageDto) {\n if (!userLanguageDto.language) userLanguageDto.language = null\n if (!(await this.usersQueries.updateUserOrGuest(user.id, userLanguageDto))) {\n throw new HttpException('Unable to update language', HttpStatus.INTERNAL_SERVER_ERROR)\n }\n }\n\n async updatePassword(user: UserModel, userPasswordDto: UserPasswordDto) {\n const r = await this.usersQueries.selectUserProperties(user.id, ['password'])\n if (!r) {\n throw new HttpException('Unable to check password', HttpStatus.NOT_FOUND)\n }\n if (!(await comparePassword(userPasswordDto.oldPassword, r.password))) {\n throw new HttpException('Password mismatch', HttpStatus.BAD_REQUEST)\n }\n const hash = await bcrypt.hash(userPasswordDto.newPassword, 10)\n if (!(await this.usersQueries.updateUserOrGuest(user.id, { password: hash }))) {\n throw new HttpException('Unable to update password', HttpStatus.INTERNAL_SERVER_ERROR)\n }\n }\n\n async updateNotification(user: UserModel, userNotificationDto: UserNotificationDto) {\n if (!(await this.usersQueries.updateUserOrGuest(user.id, userNotificationDto))) {\n throw new HttpException('Unable to update notification', HttpStatus.INTERNAL_SERVER_ERROR)\n }\n }\n\n async updateAvatar(req: FastifyAuthenticatedRequest) {\n const part: MultipartFile = await req.file({ limits: { fileSize: this.maxAvatarUploadSize } })\n if (!part.mimetype.startsWith('image/')) {\n throw new HttpException('Unsupported file type', HttpStatus.BAD_REQUEST)\n }\n const dstPath = path.join(req.user.tmpPath, this.userAvatarFileName)\n try {\n await pipeline(part.file, createWriteStream(dstPath))\n } catch (e) {\n this.logger.error(`${this.updateAvatar.name} - ${e}`)\n throw new HttpException('Unable to upload avatar', HttpStatus.INTERNAL_SERVER_ERROR)\n }\n if (part.file.truncated) {\n this.logger.warn(`${this.updateAvatar.name} - image is too large`)\n throw new HttpException('Image is too large (5MB max)', HttpStatus.PAYLOAD_TOO_LARGE)\n }\n try {\n await moveFiles(dstPath, path.join(req.user.homePath, this.userAvatarFileName), true)\n } catch (e) {\n this.logger.error(`${this.updateAvatar.name} - ${e}`)\n throw new HttpException('Unable to create avatar', HttpStatus.INTERNAL_SERVER_ERROR)\n }\n }\n\n async updateAccesses(user: UserModel, ip: string, success: boolean) {\n const passwordAttempts = success ? 0 : Math.min(user.passwordAttempts + 1, USER_MAX_PASSWORD_ATTEMPTS)\n await this.usersQueries.updateUserOrGuest(user.id, {\n lastAccess: user.currentAccess,\n currentAccess: new Date(),\n lastIp: user.currentIp,\n currentIp: ip,\n passwordAttempts: passwordAttempts,\n isActive: user.isActive && passwordAttempts < USER_MAX_PASSWORD_ATTEMPTS\n })\n }\n\n async getAvatar(userLogin: string, generate: true, generateIsNotExists?: boolean): Promise<undefined>\n async getAvatar(userLogin: string, generate?: false, generateIsNotExists?: boolean): Promise<[path: string, mime: string]>\n async getAvatar(userLogin: string, generate: boolean = false, generateIsNotExists?: boolean): Promise<[path: string, mime: string]> {\n const avatarPath = path.join(UserModel.getHomePath(userLogin), this.userAvatarFileName)\n const avatarExists = await isPathExists(avatarPath)\n if (!avatarExists && generateIsNotExists) {\n generate = true\n }\n if (!generate) {\n return [avatarExists ? avatarPath : this.defaultAvatarFilePath, avatarExists ? pngMimeType : svgMimeType]\n }\n if (!(await isPathExists(UserModel.getHomePath(userLogin)))) {\n throw new HttpException(`Home path for user *${userLogin}* does not exist`, HttpStatus.FORBIDDEN)\n }\n const user: Partial<UserModel> = await this.findUser(userLogin)\n if (!user) {\n throw new HttpException(`avatar not found`, HttpStatus.NOT_FOUND)\n }\n const avatarFile: WriteStream = createWriteStream(avatarPath)\n const avatarStream: PNGStream = generateAvatar(user.getInitials())\n try {\n await pipeline(avatarStream, avatarFile)\n } catch (e) {\n this.logger.error(`${this.updateAvatar.name} - ${e}`)\n throw new HttpException('Unable to create avatar', HttpStatus.INTERNAL_SERVER_ERROR)\n }\n if (generateIsNotExists) {\n return [avatarPath, pngMimeType]\n }\n }\n\n async getAvatarBase64(userLogin: string): Promise<string> {\n const userAvatarPath = path.join(UserModel.getHomePath(userLogin), this.userAvatarFileName)\n return convertImageToBase64((await isPathExists(userAvatarPath)) ? userAvatarPath : this.defaultAvatarFilePath)\n }\n\n setOnlineStatus(user: JwtIdentityPayload, onlineStatus: USER_ONLINE_STATUS) {\n this.usersQueries.setOnlineStatus(user.id, onlineStatus).catch((e: Error) => this.logger.error(`${this.setOnlineStatus.name} - ${e}`))\n }\n\n getOnlineUsers(userIds: number[]): Promise<UserOnline[]> {\n return this.usersQueries.getOnlineUsers(userIds)\n }\n\n async usersWhitelist(userId: number): Promise<number[]> {\n return this.usersQueries.usersWhitelist(userId)\n }\n\n async browseGroups(user: UserModel, name: string): Promise<GroupBrowse> {\n if (name) {\n const group: Pick<Group, 'id' | 'name' | 'type'> & { role: UserGroup['role'] } = await this.usersQueries.groupFromName(user.id, name)\n if (!group) {\n throw new HttpException('Group not found', HttpStatus.NOT_FOUND)\n }\n return { parentGroup: group, members: await this.usersQueries.browseGroupMembers(group.id) }\n }\n return { parentGroup: undefined, members: await this.usersQueries.browseRootGroups(user.id) }\n }\n\n async getGroup(user: UserModel, groupId: number, withMembers?: true, asAdmin?: boolean): Promise<GroupWithMembers>\n async getGroup(user: UserModel, groupId: number, withMembers: false, asAdmin?: boolean): Promise<GroupMember>\n async getGroup(user: UserModel, groupId: number, withMembers = true, asAdmin = false): Promise<GroupMember | GroupWithMembers> {\n const group = withMembers\n ? await this.usersQueries.getGroupWithMembers(user.id, groupId, asAdmin)\n : await this.usersQueries.getGroup(user.id, groupId, asAdmin)\n if (!group) {\n throw new HttpException('You are not allowed to do this action', HttpStatus.FORBIDDEN)\n }\n return group\n }\n\n async createPersonalGroup(user: UserModel, userCreateOrUpdateGroupDto: UserCreateOrUpdateGroupDto): Promise<GroupMember> {\n if (!userCreateOrUpdateGroupDto.name) {\n this.logger.error(`${this.createPersonalGroup.name} - missing group name : ${JSON.stringify(userCreateOrUpdateGroupDto)}`)\n throw new HttpException('Group name is missing', HttpStatus.BAD_REQUEST)\n }\n if (await this.usersQueries.checkGroupNameExists(userCreateOrUpdateGroupDto.name)) {\n throw new HttpException('Name already used', HttpStatus.BAD_REQUEST)\n }\n try {\n const groupId: number = await this.usersQueries.createPersonalGroup(user.id, userCreateOrUpdateGroupDto)\n this.logger.log(`${this.createPersonalGroup.name} - group (${groupId}) was created : ${JSON.stringify(userCreateOrUpdateGroupDto)}`)\n // clear user whitelists\n this.usersQueries.clearWhiteListCaches([user.id])\n return this.getGroup(user, groupId, false)\n } catch (e) {\n this.logger.error(`${this.createPersonalGroup.name} - group was not created : ${JSON.stringify(userCreateOrUpdateGroupDto)} : ${e}`)\n throw new HttpException('Unable to create group', HttpStatus.INTERNAL_SERVER_ERROR)\n }\n }\n\n async updatePersonalGroup(user: UserModel, groupId: number, userCreateOrUpdateGroupDto: UserCreateOrUpdateGroupDto): Promise<GroupMember> {\n if (!Object.keys(userCreateOrUpdateGroupDto).length) {\n throw new HttpException('No changes to update', HttpStatus.BAD_REQUEST)\n }\n const currentGroup: GroupMember = await this.getGroup(user, groupId, false, user.isAdmin)\n if (currentGroup.type !== MEMBER_TYPE.PGROUP) {\n throw new HttpException('You are not allowed to do this action', HttpStatus.FORBIDDEN)\n }\n if (userCreateOrUpdateGroupDto.name && (await this.usersQueries.checkGroupNameExists(userCreateOrUpdateGroupDto.name))) {\n throw new HttpException('Name already used', HttpStatus.BAD_REQUEST)\n }\n try {\n await this.usersQueries.updateGroup(groupId, userCreateOrUpdateGroupDto)\n } catch (e) {\n throw new HttpException(e.message, HttpStatus.INTERNAL_SERVER_ERROR)\n }\n return this.getGroup(user, groupId, false, user.isAdmin)\n }\n\n async addUsersToGroup(user: UserModel, groupId: number, userIds: number[]): Promise<void> {\n const currentGroup: GroupWithMembers = await this.getGroup(user, groupId)\n // only users can be added to users groups\n // guests and users can be added to personal groups\n const userWhiteList: number[] = await this.usersQueries.usersWhitelist(\n user.id,\n currentGroup.type === MEMBER_TYPE.GROUP ? USER_ROLE.USER : undefined\n )\n // ignore user ids that are already group members & filter on user ids allowed to current user\n userIds = userIds.filter((id) => !currentGroup.members.find((m) => m.id === id)).filter((id) => userWhiteList.indexOf(id) > -1)\n if (!userIds.length) {\n throw new HttpException('No users to add to group', HttpStatus.BAD_REQUEST)\n }\n return this.usersQueries.updateGroupMembers(groupId, { add: userIds.map((id) => ({ id: id, groupRole: USER_GROUP_ROLE.MEMBER })) })\n }\n\n async updateUserFromPersonalGroup(user: UserModel, groupId: number, userId: number, updateUserFromGroupDto: UpdateUserFromGroupDto): Promise<void> {\n const currentGroup: GroupWithMembers = await this.getGroup(user, groupId)\n if (currentGroup.type !== MEMBER_TYPE.PGROUP) {\n throw new HttpException('You are not allowed to do this action', HttpStatus.FORBIDDEN)\n }\n const userToUpdate = currentGroup.members.find((m) => m.id === userId)\n if (!userToUpdate) {\n throw new HttpException('User was not found', HttpStatus.BAD_REQUEST)\n }\n if (userToUpdate.groupRole !== updateUserFromGroupDto.role) {\n if (userToUpdate.groupRole === USER_GROUP_ROLE.MANAGER) {\n if (currentGroup.members.filter((m) => m.groupRole === USER_GROUP_ROLE.MANAGER).length === 1) {\n throw new HttpException('Group must have at least one manager', HttpStatus.BAD_REQUEST)\n }\n }\n return this.adminUsersManager.updateUserFromGroup(groupId, userId, updateUserFromGroupDto)\n }\n }\n\n async removeUserFromGroup(user: UserModel, groupId: number, userId: number): Promise<void> {\n const currentGroup: GroupWithMembers = await this.getGroup(user, groupId)\n const userToRemove = currentGroup.members.find((m) => m.id === userId)\n if (!userToRemove) {\n throw new HttpException('User was not found', HttpStatus.BAD_REQUEST)\n }\n if (userToRemove.groupRole === USER_GROUP_ROLE.MANAGER) {\n if (currentGroup.type === MEMBER_TYPE.GROUP) {\n throw new HttpException('You are not allowed to do this action', HttpStatus.FORBIDDEN)\n }\n if (currentGroup.members.filter((m) => m.groupRole === USER_GROUP_ROLE.MANAGER).length === 1) {\n throw new HttpException('Group must have at least one manager', HttpStatus.BAD_REQUEST)\n }\n }\n return this.usersQueries.updateGroupMembers(groupId, { remove: [userId] })\n }\n\n async leavePersonalGroup(user: UserModel, groupId: number): Promise<void> {\n const currentGroup: GroupWithMembers = await this.usersQueries.getGroupWithMembers(user.id, groupId, true)\n if (!currentGroup || currentGroup.type === MEMBER_TYPE.GROUP) {\n throw new HttpException('You are not allowed to do this action', HttpStatus.FORBIDDEN)\n }\n const userWhoLeaves = currentGroup.members.find((m) => m.id === user.id)\n if (!userWhoLeaves) {\n throw new HttpException('User was not found', HttpStatus.BAD_REQUEST)\n }\n if (userWhoLeaves.groupRole === USER_GROUP_ROLE.MANAGER) {\n if (currentGroup.members.filter((m) => m.groupRole === USER_GROUP_ROLE.MANAGER).length === 1) {\n throw new HttpException('Group must have at least one manager', HttpStatus.BAD_REQUEST)\n }\n }\n try {\n await this.usersQueries.updateGroupMembers(groupId, { remove: [user.id] })\n this.logger.log(`${this.leavePersonalGroup.name} - user (${user.id}) has left group (${groupId})`)\n } catch (e) {\n this.logger.error(`${this.leavePersonalGroup.name} - user (${user.id}) has not left group (${groupId}) : ${e}`)\n throw new HttpException(e.message, HttpStatus.INTERNAL_SERVER_ERROR)\n }\n }\n\n async deletePersonalGroup(user: UserModel, groupId: number): Promise<void> {\n if (!(await this.usersQueries.canDeletePersonalGroup(user.id, groupId))) {\n throw new HttpException('You are not allowed to do this action', HttpStatus.FORBIDDEN)\n }\n if (await this.usersQueries.deletePersonalGroup(groupId)) {\n this.logger.log(`${this.deletePersonalGroup.name} - group (${groupId}) was deleted`)\n } else {\n this.logger.warn(`${this.deletePersonalGroup.name} - group (${groupId}) does not exist`)\n throw new HttpException('Unable to delete group', HttpStatus.BAD_REQUEST)\n }\n }\n\n listGuests(user: UserModel): Promise<GuestUser[]> {\n return this.usersQueries.listGuests(null, user.id)\n }\n\n async getGuest(user: UserModel, guestId: number): Promise<GuestUser> {\n const guest: GuestUser = await this.usersQueries.listGuests(guestId, user.id)\n this.adminUsersManager.checkUser(guest, true)\n return guest\n }\n\n async createGuest(user: UserModel, createGuestDto: CreateUserDto): Promise<GuestUser> {\n // filter managers that are allowed for current user\n const userWhiteList = await this.usersQueries.usersWhitelist(user.id, USER_ROLE.USER)\n createGuestDto.managers = createGuestDto.managers.filter((id) => userWhiteList.indexOf(id) > -1)\n if (createGuestDto.managers.indexOf(user.id) === -1) {\n // force user as manager during creation\n createGuestDto.managers.push(user.id)\n }\n // clear user whitelists\n this.usersQueries.clearWhiteListCaches([user.id])\n return this.adminUsersManager.createUserOrGuest(createGuestDto, USER_ROLE.GUEST, true)\n }\n\n async updateGuest(user: UserModel, guestId: number, updateGuestDto: UpdateUserDto): Promise<GuestUser> {\n if (!Object.keys(updateGuestDto).length) {\n throw new HttpException('No changes to update', HttpStatus.BAD_REQUEST)\n }\n if (updateGuestDto.managers) {\n // filter managers that are allowed for current user\n const userWhiteList = await this.usersQueries.usersWhitelist(user.id, USER_ROLE.USER)\n updateGuestDto.managers = updateGuestDto.managers.filter((id) => userWhiteList.indexOf(id) > -1)\n if (!updateGuestDto.managers.length) {\n throw new HttpException('Guest must have at least one manager', HttpStatus.BAD_REQUEST)\n }\n }\n if (!(await this.usersQueries.isGuestManager(user.id, guestId))) {\n throw new HttpException('You are not allowed to do this action', HttpStatus.FORBIDDEN)\n }\n const guest = await this.adminUsersManager.updateUserOrGuest(guestId, updateGuestDto, USER_ROLE.GUEST)\n return guest.managers.find((m) => m.id === user.id) ? guest : null\n }\n\n async deleteGuest(user: UserModel, guestId: number): Promise<void> {\n const guest = await this.usersQueries.isGuestManager(user.id, guestId)\n if (!guest) {\n throw new HttpException('You are not allowed to do this action', HttpStatus.FORBIDDEN)\n }\n // guest has no space but a temporary directory\n return this.adminUsersManager.deleteUserOrGuest(guest.id, guest.login, { deleteSpace: true, isGuest: true })\n }\n\n searchMembers(user: UserModel, searchMembersDto: SearchMembersDto): Promise<Member[]> {\n return this.usersQueries.searchUsersOrGroups(searchMembersDto, user.id)\n }\n}\n"],"names":["UsersManager","fromUserId","id","user","usersQueries","from","UserModel","findUser","loginOrEmail","removePassword","logUser","password","ip","role","USER_ROLE","LINK","logger","error","name","HttpException","HttpStatus","FORBIDDEN","isActive","passwordAttempts","USER_MAX_PASSWORD_ATTEMPTS","updateAccesses","catch","e","login","authSuccess","comparePassword","makePaths","warn","me","authUser","NOT_FOUND","impersonated","impersonatedFromId","clientId","compareUserPassword","userId","updateLanguage","userLanguageDto","language","updateUserOrGuest","INTERNAL_SERVER_ERROR","updatePassword","userPasswordDto","r","selectUserProperties","oldPassword","BAD_REQUEST","hash","bcrypt","newPassword","updateNotification","userNotificationDto","updateAvatar","req","part","file","limits","fileSize","maxAvatarUploadSize","mimetype","startsWith","dstPath","path","join","tmpPath","userAvatarFileName","pipeline","createWriteStream","truncated","PAYLOAD_TOO_LARGE","moveFiles","homePath","success","Math","min","lastAccess","currentAccess","Date","lastIp","currentIp","getAvatar","userLogin","generate","generateIsNotExists","avatarPath","getHomePath","avatarExists","isPathExists","defaultAvatarFilePath","pngMimeType","svgMimeType","avatarFile","avatarStream","generateAvatar","getInitials","getAvatarBase64","userAvatarPath","convertImageToBase64","setOnlineStatus","onlineStatus","getOnlineUsers","userIds","usersWhitelist","browseGroups","group","groupFromName","parentGroup","members","browseGroupMembers","undefined","browseRootGroups","getGroup","groupId","withMembers","asAdmin","getGroupWithMembers","createPersonalGroup","userCreateOrUpdateGroupDto","JSON","stringify","checkGroupNameExists","log","clearWhiteListCaches","updatePersonalGroup","Object","keys","length","currentGroup","isAdmin","type","MEMBER_TYPE","PGROUP","updateGroup","message","addUsersToGroup","userWhiteList","GROUP","USER","filter","find","m","indexOf","updateGroupMembers","add","map","groupRole","USER_GROUP_ROLE","MEMBER","updateUserFromPersonalGroup","updateUserFromGroupDto","userToUpdate","MANAGER","adminUsersManager","updateUserFromGroup","removeUserFromGroup","userToRemove","remove","leavePersonalGroup","userWhoLeaves","deletePersonalGroup","canDeletePersonalGroup","listGuests","getGuest","guestId","guest","checkUser","createGuest","createGuestDto","managers","push","createUserOrGuest","GUEST","updateGuest","updateGuestDto","isGuestManager","deleteGuest","deleteUserOrGuest","deleteSpace","isGuest","searchMembers","searchMembersDto","searchUsersOrGroups","STATIC_ASSETS_PATH","Logger"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../../backend/src/applications/users/services/users-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 { MultipartFile } from '@fastify/multipart'\nimport { HttpException, HttpStatus, Injectable, Logger } from '@nestjs/common'\nimport bcrypt from 'bcryptjs'\nimport { PNGStream } from 'canvas'\nimport { WriteStream } from 'fs'\nimport { createWriteStream } from 'node:fs'\nimport path from 'node:path'\nimport { pipeline } from 'node:stream/promises'\nimport { AUTH_SCOPE } from '../../../authentication/constants/scope'\nimport { LoginResponseDto } from '../../../authentication/dto/login-response.dto'\nimport { FastifyAuthenticatedRequest } from '../../../authentication/interfaces/auth-request.interface'\nimport { JwtIdentityPayload } from '../../../authentication/interfaces/jwt-payload.interface'\nimport { ACTION } from '../../../common/constants'\nimport { comparePassword, hashPassword } from '../../../common/functions'\nimport { generateAvatar, pngMimeType, svgMimeType } from '../../../common/image'\nimport { createLightSlug, genPassword } from '../../../common/shared'\nimport { configuration, serverConfig } from '../../../configuration/config.environment'\nimport { isPathExists, moveFiles } from '../../files/utils/files'\nimport { NOTIFICATION_APP, NOTIFICATION_APP_EVENT } from '../../notifications/constants/notifications'\nimport { NotificationsManager } from '../../notifications/services/notifications-manager.service'\nimport { MEMBER_TYPE } from '../constants/member'\nimport { USER_GROUP_ROLE, USER_MAX_PASSWORD_ATTEMPTS, USER_ONLINE_STATUS, USER_ROLE } from '../constants/user'\nimport type { UserCreateOrUpdateGroupDto } from '../dto/create-or-update-group.dto'\nimport type { CreateUserDto, UpdateUserDto, UpdateUserFromGroupDto } from '../dto/create-or-update-user.dto'\nimport type { SearchMembersDto } from '../dto/search-members.dto'\nimport type { UserAppPasswordDto, UserLanguageDto, UserNotificationDto, UserUpdatePasswordDto } from '../dto/user-properties.dto'\nimport type { GroupBrowse } from '../interfaces/group-browse.interface'\nimport type { GroupMember, GroupWithMembers } from '../interfaces/group-member'\nimport type { GuestUser } from '../interfaces/guest-user.interface'\nimport type { Member } from '../interfaces/member.interface'\nimport type { UserAppPassword, UserSecrets } from '../interfaces/user-secrets.interface'\nimport type { UserOnline } from '../interfaces/websocket.interface'\nimport { UserModel } from '../models/user.model'\nimport type { Group } from '../schemas/group.interface'\nimport type { UserGroup } from '../schemas/user-group.interface'\nimport type { User } from '../schemas/user.interface'\nimport { USER_AVATAR_FILE_NAME, USER_AVATAR_MAX_UPLOAD_SIZE, USER_DEFAULT_AVATAR_FILE_PATH } from '../utils/avatar'\nimport { AdminUsersManager } from './admin-users-manager.service'\nimport { UsersQueries } from './users-queries.service'\n\n@Injectable()\nexport class UsersManager {\n private readonly logger = new Logger(UsersManager.name)\n\n constructor(\n public readonly usersQueries: UsersQueries,\n private readonly adminUsersManager: AdminUsersManager,\n private readonly notificationsManager: NotificationsManager\n ) {}\n\n async fromUserId(id: number): Promise<UserModel> {\n const user: User = await this.usersQueries.from(id)\n return user ? new UserModel(user, true) : null\n }\n\n async findUser(loginOrEmail: string, removePassword: false): Promise<UserModel>\n async findUser(loginOrEmail: string, removePassword?: true): Promise<Omit<UserModel, 'password'>>\n async findUser(loginOrEmail: string, removePassword: boolean = true): Promise<Omit<UserModel, 'password'>> {\n const user: User = await this.usersQueries.from(null, loginOrEmail)\n return user ? new UserModel(user, removePassword) : null\n }\n\n async logUser(user: UserModel, password: string, ip: string, scope?: AUTH_SCOPE): Promise<UserModel> {\n this.validateUserAccess(user, ip)\n let authSuccess: boolean = await comparePassword(password, user.password)\n if (!authSuccess && scope) {\n authSuccess = await this.validateAppPassword(user, password, ip, scope)\n }\n this.updateAccesses(user, ip, authSuccess).catch((e: Error) => this.logger.error(`${this.logUser.name} - ${e}`))\n if (authSuccess) {\n await user.makePaths()\n return user\n }\n this.logger.warn(`${this.logUser.name} - bad password for *${user.login}*`)\n return null\n }\n\n validateUserAccess(user: UserModel, ip: string) {\n if (user.role === USER_ROLE.LINK) {\n this.logger.error(`${this.validateUserAccess.name} - guest link account ${user} is not authorized to login`)\n throw new HttpException('Account is not allowed', HttpStatus.FORBIDDEN)\n }\n if (!user.isActive || user.passwordAttempts >= USER_MAX_PASSWORD_ATTEMPTS) {\n this.updateAccesses(user, ip, false).catch((e: Error) => this.logger.error(`${this.validateUserAccess.name} - ${e}`))\n this.logger.error(`${this.validateUserAccess.name} - user account *${user.login}* is locked`)\n this.notifyAccountLocked(user, ip)\n throw new HttpException('Account locked', HttpStatus.FORBIDDEN)\n }\n }\n\n async me(authUser: UserModel): Promise<Omit<LoginResponseDto, 'token'>> {\n const user = await this.fromUserId(authUser.id)\n if (!user) {\n this.logger.warn(`User *${authUser.login} (${authUser.id}) not found`)\n throw new HttpException(`User not found`, HttpStatus.NOT_FOUND)\n }\n user.impersonated = !!authUser.impersonatedFromId\n user.clientId = authUser.clientId\n return { user: user, server: serverConfig }\n }\n\n async compareUserPassword(userId: number, password: string): Promise<boolean> {\n return this.usersQueries.compareUserPassword(userId, password)\n }\n\n async updateLanguage(user: UserModel, userLanguageDto: UserLanguageDto) {\n if (!userLanguageDto.language) userLanguageDto.language = null\n if (!(await this.usersQueries.updateUserOrGuest(user.id, userLanguageDto))) {\n throw new HttpException('Unable to update language', HttpStatus.INTERNAL_SERVER_ERROR)\n }\n }\n\n async updatePassword(user: UserModel, userPasswordDto: UserUpdatePasswordDto) {\n const r = await this.usersQueries.selectUserProperties(user.id, ['password'])\n if (!r) {\n throw new HttpException('Unable to check password', HttpStatus.NOT_FOUND)\n }\n if (!(await comparePassword(userPasswordDto.oldPassword, r.password))) {\n throw new HttpException('Password mismatch', HttpStatus.BAD_REQUEST)\n }\n const hash = await bcrypt.hash(userPasswordDto.newPassword, 10)\n if (!(await this.usersQueries.updateUserOrGuest(user.id, { password: hash }))) {\n throw new HttpException('Unable to update password', HttpStatus.INTERNAL_SERVER_ERROR)\n }\n }\n\n async updateNotification(user: UserModel, userNotificationDto: UserNotificationDto) {\n if (!(await this.usersQueries.updateUserOrGuest(user.id, userNotificationDto))) {\n throw new HttpException('Unable to update notification', HttpStatus.INTERNAL_SERVER_ERROR)\n }\n }\n\n async updateAvatar(req: FastifyAuthenticatedRequest) {\n const part: MultipartFile = await req.file({ limits: { fileSize: USER_AVATAR_MAX_UPLOAD_SIZE } })\n if (!part.mimetype.startsWith('image/')) {\n throw new HttpException('Unsupported file type', HttpStatus.BAD_REQUEST)\n }\n const dstPath = path.join(req.user.tmpPath, USER_AVATAR_FILE_NAME)\n try {\n await pipeline(part.file, createWriteStream(dstPath))\n } catch (e) {\n this.logger.error(`${this.updateAvatar.name} - ${e}`)\n throw new HttpException('Unable to upload avatar', HttpStatus.INTERNAL_SERVER_ERROR)\n }\n if (part.file.truncated) {\n this.logger.warn(`${this.updateAvatar.name} - image is too large`)\n throw new HttpException('Image is too large (5MB max)', HttpStatus.PAYLOAD_TOO_LARGE)\n }\n try {\n await moveFiles(dstPath, path.join(req.user.homePath, USER_AVATAR_FILE_NAME), true)\n } catch (e) {\n this.logger.error(`${this.updateAvatar.name} - ${e}`)\n throw new HttpException('Unable to create avatar', HttpStatus.INTERNAL_SERVER_ERROR)\n }\n }\n\n async updateSecrets(userId: number, secrets: UserSecrets) {\n const userSecrets = await this.usersQueries.getUserSecrets(userId)\n const updatedSecrets = { ...userSecrets, ...secrets }\n if (!(await this.usersQueries.updateUserOrGuest(userId, { secrets: updatedSecrets }))) {\n throw new HttpException('Unable to update secrets', HttpStatus.INTERNAL_SERVER_ERROR)\n }\n }\n\n async updateAccesses(user: UserModel, ip: string, success: boolean, isAuthTwoFa = false) {\n let passwordAttempts: number\n if (!isAuthTwoFa && configuration.auth.mfa.totp.enabled && user.twoFaEnabled) {\n // Do not reset password attempts if the login still requires 2FA validation\n passwordAttempts = user.passwordAttempts\n } else {\n passwordAttempts = success ? 0 : Math.min(user.passwordAttempts + 1, USER_MAX_PASSWORD_ATTEMPTS)\n }\n await this.usersQueries.updateUserOrGuest(user.id, {\n lastAccess: user.currentAccess,\n currentAccess: new Date(),\n lastIp: user.currentIp,\n currentIp: ip,\n passwordAttempts: passwordAttempts,\n isActive: user.isActive && passwordAttempts < USER_MAX_PASSWORD_ATTEMPTS\n })\n }\n\n async getAvatar(userLogin: string, generate: true, generateIsNotExists?: boolean): Promise<undefined>\n async getAvatar(userLogin: string, generate?: false, generateIsNotExists?: boolean): Promise<[path: string, mime: string]>\n async getAvatar(userLogin: string, generate: boolean = false, generateIsNotExists?: boolean): Promise<[path: string, mime: string]> {\n const avatarPath = path.join(UserModel.getHomePath(userLogin), USER_AVATAR_FILE_NAME)\n const avatarExists = await isPathExists(avatarPath)\n if (!avatarExists && generateIsNotExists) {\n generate = true\n }\n if (!generate) {\n return [avatarExists ? avatarPath : USER_DEFAULT_AVATAR_FILE_PATH, avatarExists ? pngMimeType : svgMimeType]\n }\n if (!(await isPathExists(UserModel.getHomePath(userLogin)))) {\n throw new HttpException(`Home path for user *${userLogin}* does not exist`, HttpStatus.FORBIDDEN)\n }\n const user: Partial<UserModel> = await this.findUser(userLogin)\n if (!user) {\n throw new HttpException(`avatar not found`, HttpStatus.NOT_FOUND)\n }\n const avatarFile: WriteStream = createWriteStream(avatarPath)\n const avatarStream: PNGStream = generateAvatar(user.getInitials())\n try {\n await pipeline(avatarStream, avatarFile)\n } catch (e) {\n this.logger.error(`${this.updateAvatar.name} - ${e}`)\n throw new HttpException('Unable to create avatar', HttpStatus.INTERNAL_SERVER_ERROR)\n }\n if (generateIsNotExists) {\n return [avatarPath, pngMimeType]\n }\n }\n\n async listAppPasswords(user: UserModel): Promise<Omit<UserAppPassword, 'password'>[]> {\n const secrets = await this.usersQueries.getUserSecrets(user.id)\n if (Array.isArray(secrets.appPasswords)) {\n // remove passwords from response\n return secrets.appPasswords.map(({ password, ...rest }: UserAppPassword) => rest)\n }\n return []\n }\n\n async generateAppPassword(user: UserModel, userAppPasswordDto: UserAppPasswordDto): Promise<UserAppPassword> {\n const secrets = await this.usersQueries.getUserSecrets(user.id)\n const slugName = createLightSlug(userAppPasswordDto.name)\n if (Array.isArray(secrets.appPasswords) && secrets.appPasswords.find((p: UserAppPassword) => p.name === slugName)) {\n throw new HttpException('Name already used', HttpStatus.BAD_REQUEST)\n }\n secrets.appPasswords = Array.isArray(secrets.appPasswords) ? secrets.appPasswords : []\n const clearPassword = genPassword(24)\n const appPassword: UserAppPassword = {\n name: createLightSlug(userAppPasswordDto.name),\n app: userAppPasswordDto.app,\n expiration: userAppPasswordDto.expiration,\n password: await hashPassword(clearPassword),\n createdAt: new Date(),\n currentIp: null,\n currentAccess: null,\n lastIp: null,\n lastAccess: null\n }\n secrets.appPasswords.unshift(appPassword)\n if (!(await this.usersQueries.updateUserOrGuest(user.id, { secrets: secrets }))) {\n throw new HttpException('Unable to update app passwords', HttpStatus.INTERNAL_SERVER_ERROR)\n }\n // return clear password only once\n return { ...appPassword, password: clearPassword }\n }\n\n async deleteAppPassword(user: UserModel, passwordName: string): Promise<void> {\n const secrets = await this.usersQueries.getUserSecrets(user.id)\n if (!Array.isArray(secrets.appPasswords) || !secrets.appPasswords.find((p: UserAppPassword) => p.name === passwordName)) {\n throw new HttpException('App password not found', HttpStatus.NOT_FOUND)\n }\n secrets.appPasswords = secrets.appPasswords.filter((p: UserAppPassword) => p.name !== passwordName)\n if (!(await this.usersQueries.updateUserOrGuest(user.id, { secrets: secrets }))) {\n throw new HttpException('Unable to delete app password', HttpStatus.INTERNAL_SERVER_ERROR)\n }\n }\n\n async validateAppPassword(user: UserModel, password: string, ip: string, scope: AUTH_SCOPE): Promise<boolean> {\n if (!scope || !user.haveRole(USER_ROLE.USER)) return false\n const secrets = await this.usersQueries.getUserSecrets(user.id)\n if (!Array.isArray(secrets.appPasswords)) return false\n for (const p of secrets.appPasswords) {\n if (p.app !== scope) continue\n const expMs = p.expiration ? new Date(p.expiration) : null\n if (p.expiration && new Date() > expMs) continue // expired\n if (await comparePassword(password, p.password)) {\n p.lastAccess = p.currentAccess\n p.currentAccess = new Date()\n p.lastIp = p.currentIp\n p.currentIp = ip\n // update accesses\n this.usersQueries\n .updateUserOrGuest(user.id, { secrets: secrets })\n .catch((e: Error) => this.logger.error(`${this.validateAppPassword.name} - ${e}`))\n return true\n }\n }\n return false\n }\n\n setOnlineStatus(user: JwtIdentityPayload, onlineStatus: USER_ONLINE_STATUS) {\n this.usersQueries.setOnlineStatus(user.id, onlineStatus).catch((e: Error) => this.logger.error(`${this.setOnlineStatus.name} - ${e}`))\n }\n\n getOnlineUsers(userIds: number[]): Promise<UserOnline[]> {\n return this.usersQueries.getOnlineUsers(userIds)\n }\n\n async usersWhitelist(userId: number): Promise<number[]> {\n return this.usersQueries.usersWhitelist(userId)\n }\n\n async browseGroups(user: UserModel, name: string): Promise<GroupBrowse> {\n if (name) {\n const group: Pick<Group, 'id' | 'name' | 'type'> & { role: UserGroup['role'] } = await this.usersQueries.groupFromName(user.id, name)\n if (!group) {\n throw new HttpException('Group not found', HttpStatus.NOT_FOUND)\n }\n return { parentGroup: group, members: await this.usersQueries.browseGroupMembers(group.id) }\n }\n return { parentGroup: undefined, members: await this.usersQueries.browseRootGroups(user.id) }\n }\n\n async getGroup(user: UserModel, groupId: number, withMembers?: true, asAdmin?: boolean): Promise<GroupWithMembers>\n async getGroup(user: UserModel, groupId: number, withMembers: false, asAdmin?: boolean): Promise<GroupMember>\n async getGroup(user: UserModel, groupId: number, withMembers = true, asAdmin = false): Promise<GroupMember | GroupWithMembers> {\n const group = withMembers\n ? await this.usersQueries.getGroupWithMembers(user.id, groupId, asAdmin)\n : await this.usersQueries.getGroup(user.id, groupId, asAdmin)\n if (!group) {\n throw new HttpException('You are not allowed to do this action', HttpStatus.FORBIDDEN)\n }\n return group\n }\n\n async createPersonalGroup(user: UserModel, userCreateOrUpdateGroupDto: UserCreateOrUpdateGroupDto): Promise<GroupMember> {\n if (!userCreateOrUpdateGroupDto.name) {\n this.logger.error(`${this.createPersonalGroup.name} - missing group name : ${JSON.stringify(userCreateOrUpdateGroupDto)}`)\n throw new HttpException('Group name is missing', HttpStatus.BAD_REQUEST)\n }\n if (await this.usersQueries.checkGroupNameExists(userCreateOrUpdateGroupDto.name)) {\n throw new HttpException('Name already used', HttpStatus.BAD_REQUEST)\n }\n try {\n const groupId: number = await this.usersQueries.createPersonalGroup(user.id, userCreateOrUpdateGroupDto)\n this.logger.log(`${this.createPersonalGroup.name} - group (${groupId}) was created : ${JSON.stringify(userCreateOrUpdateGroupDto)}`)\n // clear user whitelists\n this.usersQueries.clearWhiteListCaches([user.id])\n return this.getGroup(user, groupId, false)\n } catch (e) {\n this.logger.error(`${this.createPersonalGroup.name} - group was not created : ${JSON.stringify(userCreateOrUpdateGroupDto)} : ${e}`)\n throw new HttpException('Unable to create group', HttpStatus.INTERNAL_SERVER_ERROR)\n }\n }\n\n async updatePersonalGroup(user: UserModel, groupId: number, userCreateOrUpdateGroupDto: UserCreateOrUpdateGroupDto): Promise<GroupMember> {\n if (!Object.keys(userCreateOrUpdateGroupDto).length) {\n throw new HttpException('No changes to update', HttpStatus.BAD_REQUEST)\n }\n const currentGroup: GroupMember = await this.getGroup(user, groupId, false, user.isAdmin)\n if (currentGroup.type !== MEMBER_TYPE.PGROUP) {\n throw new HttpException('You are not allowed to do this action', HttpStatus.FORBIDDEN)\n }\n if (userCreateOrUpdateGroupDto.name && (await this.usersQueries.checkGroupNameExists(userCreateOrUpdateGroupDto.name))) {\n throw new HttpException('Name already used', HttpStatus.BAD_REQUEST)\n }\n try {\n await this.usersQueries.updateGroup(groupId, userCreateOrUpdateGroupDto)\n } catch (e) {\n throw new HttpException(e.message, HttpStatus.INTERNAL_SERVER_ERROR)\n }\n return this.getGroup(user, groupId, false, user.isAdmin)\n }\n\n async addUsersToGroup(user: UserModel, groupId: number, userIds: number[]): Promise<void> {\n const currentGroup: GroupWithMembers = await this.getGroup(user, groupId)\n // only users can be added to users groups\n // guests and users can be added to personal groups\n const userWhiteList: number[] = await this.usersQueries.usersWhitelist(\n user.id,\n currentGroup.type === MEMBER_TYPE.GROUP ? USER_ROLE.USER : undefined\n )\n // ignore user ids that are already group members & filter on user ids allowed to current user\n userIds = userIds.filter((id) => !currentGroup.members.find((m) => m.id === id)).filter((id) => userWhiteList.indexOf(id) > -1)\n if (!userIds.length) {\n throw new HttpException('No users to add to group', HttpStatus.BAD_REQUEST)\n }\n return this.usersQueries.updateGroupMembers(groupId, { add: userIds.map((id) => ({ id: id, groupRole: USER_GROUP_ROLE.MEMBER })) })\n }\n\n async updateUserFromPersonalGroup(user: UserModel, groupId: number, userId: number, updateUserFromGroupDto: UpdateUserFromGroupDto): Promise<void> {\n const currentGroup: GroupWithMembers = await this.getGroup(user, groupId)\n if (currentGroup.type !== MEMBER_TYPE.PGROUP) {\n throw new HttpException('You are not allowed to do this action', HttpStatus.FORBIDDEN)\n }\n const userToUpdate = currentGroup.members.find((m) => m.id === userId)\n if (!userToUpdate) {\n throw new HttpException('User was not found', HttpStatus.BAD_REQUEST)\n }\n if (userToUpdate.groupRole !== updateUserFromGroupDto.role) {\n if (userToUpdate.groupRole === USER_GROUP_ROLE.MANAGER) {\n if (currentGroup.members.filter((m) => m.groupRole === USER_GROUP_ROLE.MANAGER).length === 1) {\n throw new HttpException('Group must have at least one manager', HttpStatus.BAD_REQUEST)\n }\n }\n return this.adminUsersManager.updateUserFromGroup(groupId, userId, updateUserFromGroupDto)\n }\n }\n\n async removeUserFromGroup(user: UserModel, groupId: number, userId: number): Promise<void> {\n const currentGroup: GroupWithMembers = await this.getGroup(user, groupId)\n const userToRemove = currentGroup.members.find((m) => m.id === userId)\n if (!userToRemove) {\n throw new HttpException('User was not found', HttpStatus.BAD_REQUEST)\n }\n if (userToRemove.groupRole === USER_GROUP_ROLE.MANAGER) {\n if (currentGroup.type === MEMBER_TYPE.GROUP) {\n throw new HttpException('You are not allowed to do this action', HttpStatus.FORBIDDEN)\n }\n if (currentGroup.members.filter((m) => m.groupRole === USER_GROUP_ROLE.MANAGER).length === 1) {\n throw new HttpException('Group must have at least one manager', HttpStatus.BAD_REQUEST)\n }\n }\n return this.usersQueries.updateGroupMembers(groupId, { remove: [userId] })\n }\n\n async leavePersonalGroup(user: UserModel, groupId: number): Promise<void> {\n const currentGroup: GroupWithMembers = await this.usersQueries.getGroupWithMembers(user.id, groupId, true)\n if (!currentGroup || currentGroup.type === MEMBER_TYPE.GROUP) {\n throw new HttpException('You are not allowed to do this action', HttpStatus.FORBIDDEN)\n }\n const userWhoLeaves = currentGroup.members.find((m) => m.id === user.id)\n if (!userWhoLeaves) {\n throw new HttpException('User was not found', HttpStatus.BAD_REQUEST)\n }\n if (userWhoLeaves.groupRole === USER_GROUP_ROLE.MANAGER) {\n if (currentGroup.members.filter((m) => m.groupRole === USER_GROUP_ROLE.MANAGER).length === 1) {\n throw new HttpException('Group must have at least one manager', HttpStatus.BAD_REQUEST)\n }\n }\n try {\n await this.usersQueries.updateGroupMembers(groupId, { remove: [user.id] })\n this.logger.log(`${this.leavePersonalGroup.name} - user (${user.id}) has left group (${groupId})`)\n } catch (e) {\n this.logger.error(`${this.leavePersonalGroup.name} - user (${user.id}) has not left group (${groupId}) : ${e}`)\n throw new HttpException(e.message, HttpStatus.INTERNAL_SERVER_ERROR)\n }\n }\n\n async deletePersonalGroup(user: UserModel, groupId: number): Promise<void> {\n if (!(await this.usersQueries.canDeletePersonalGroup(user.id, groupId))) {\n throw new HttpException('You are not allowed to do this action', HttpStatus.FORBIDDEN)\n }\n if (await this.usersQueries.deletePersonalGroup(groupId)) {\n this.logger.log(`${this.deletePersonalGroup.name} - group (${groupId}) was deleted`)\n } else {\n this.logger.warn(`${this.deletePersonalGroup.name} - group (${groupId}) does not exist`)\n throw new HttpException('Unable to delete group', HttpStatus.BAD_REQUEST)\n }\n }\n\n listGuests(user: UserModel): Promise<GuestUser[]> {\n return this.usersQueries.listGuests(null, user.id)\n }\n\n async getGuest(user: UserModel, guestId: number): Promise<GuestUser> {\n const guest: GuestUser = await this.usersQueries.listGuests(guestId, user.id)\n this.adminUsersManager.checkUser(guest, true)\n return guest\n }\n\n async createGuest(user: UserModel, createGuestDto: CreateUserDto): Promise<GuestUser> {\n // filter managers that are allowed for current user\n const userWhiteList = await this.usersQueries.usersWhitelist(user.id, USER_ROLE.USER)\n createGuestDto.managers = createGuestDto.managers.filter((id) => userWhiteList.indexOf(id) > -1)\n if (createGuestDto.managers.indexOf(user.id) === -1) {\n // force user as manager during creation\n createGuestDto.managers.push(user.id)\n }\n // clear user whitelists\n this.usersQueries.clearWhiteListCaches([user.id])\n return this.adminUsersManager.createUserOrGuest(createGuestDto, USER_ROLE.GUEST, true)\n }\n\n async updateGuest(user: UserModel, guestId: number, updateGuestDto: UpdateUserDto): Promise<GuestUser> {\n if (!Object.keys(updateGuestDto).length) {\n throw new HttpException('No changes to update', HttpStatus.BAD_REQUEST)\n }\n if (updateGuestDto.managers) {\n // filter managers that are allowed for current user\n const userWhiteList = await this.usersQueries.usersWhitelist(user.id, USER_ROLE.USER)\n updateGuestDto.managers = updateGuestDto.managers.filter((id) => userWhiteList.indexOf(id) > -1)\n if (!updateGuestDto.managers.length) {\n throw new HttpException('Guest must have at least one manager', HttpStatus.BAD_REQUEST)\n }\n }\n if (!(await this.usersQueries.isGuestManager(user.id, guestId))) {\n throw new HttpException('You are not allowed to do this action', HttpStatus.FORBIDDEN)\n }\n const guest = await this.adminUsersManager.updateUserOrGuest(guestId, updateGuestDto, USER_ROLE.GUEST)\n return guest.managers.find((m) => m.id === user.id) ? guest : null\n }\n\n async deleteGuest(user: UserModel, guestId: number): Promise<void> {\n const guest = await this.usersQueries.isGuestManager(user.id, guestId)\n if (!guest) {\n throw new HttpException('You are not allowed to do this action', HttpStatus.FORBIDDEN)\n }\n // guest has no space but a temporary directory\n return this.adminUsersManager.deleteUserOrGuest(guest.id, guest.login, { deleteSpace: true, isGuest: true })\n }\n\n searchMembers(user: UserModel, searchMembersDto: SearchMembersDto): Promise<Member[]> {\n return this.usersQueries.searchUsersOrGroups(searchMembersDto, user.id)\n }\n\n private notifyAccountLocked(user: UserModel, ip: string) {\n this.notificationsManager\n .sendEmailNotification([user], {\n app: NOTIFICATION_APP.AUTH_LOCKED,\n event: NOTIFICATION_APP_EVENT.AUTH_LOCKED[ACTION.DELETE],\n element: null,\n url: ip\n })\n .catch((e: Error) => this.logger.error(`${this.validateUserAccess.name} - ${e}`))\n }\n}\n"],"names":["UsersManager","fromUserId","id","user","usersQueries","from","UserModel","findUser","loginOrEmail","removePassword","logUser","password","ip","scope","validateUserAccess","authSuccess","comparePassword","validateAppPassword","updateAccesses","catch","e","logger","error","name","makePaths","warn","login","role","USER_ROLE","LINK","HttpException","HttpStatus","FORBIDDEN","isActive","passwordAttempts","USER_MAX_PASSWORD_ATTEMPTS","notifyAccountLocked","me","authUser","NOT_FOUND","impersonated","impersonatedFromId","clientId","server","serverConfig","compareUserPassword","userId","updateLanguage","userLanguageDto","language","updateUserOrGuest","INTERNAL_SERVER_ERROR","updatePassword","userPasswordDto","r","selectUserProperties","oldPassword","BAD_REQUEST","hash","bcrypt","newPassword","updateNotification","userNotificationDto","updateAvatar","req","part","file","limits","fileSize","USER_AVATAR_MAX_UPLOAD_SIZE","mimetype","startsWith","dstPath","path","join","tmpPath","USER_AVATAR_FILE_NAME","pipeline","createWriteStream","truncated","PAYLOAD_TOO_LARGE","moveFiles","homePath","updateSecrets","secrets","userSecrets","getUserSecrets","updatedSecrets","success","isAuthTwoFa","configuration","auth","mfa","totp","enabled","twoFaEnabled","Math","min","lastAccess","currentAccess","Date","lastIp","currentIp","getAvatar","userLogin","generate","generateIsNotExists","avatarPath","getHomePath","avatarExists","isPathExists","USER_DEFAULT_AVATAR_FILE_PATH","pngMimeType","svgMimeType","avatarFile","avatarStream","generateAvatar","getInitials","listAppPasswords","Array","isArray","appPasswords","map","rest","generateAppPassword","userAppPasswordDto","slugName","createLightSlug","find","p","clearPassword","genPassword","appPassword","app","expiration","hashPassword","createdAt","unshift","deleteAppPassword","passwordName","filter","haveRole","USER","expMs","setOnlineStatus","onlineStatus","getOnlineUsers","userIds","usersWhitelist","browseGroups","group","groupFromName","parentGroup","members","browseGroupMembers","undefined","browseRootGroups","getGroup","groupId","withMembers","asAdmin","getGroupWithMembers","createPersonalGroup","userCreateOrUpdateGroupDto","JSON","stringify","checkGroupNameExists","log","clearWhiteListCaches","updatePersonalGroup","Object","keys","length","currentGroup","isAdmin","type","MEMBER_TYPE","PGROUP","updateGroup","message","addUsersToGroup","userWhiteList","GROUP","m","indexOf","updateGroupMembers","add","groupRole","USER_GROUP_ROLE","MEMBER","updateUserFromPersonalGroup","updateUserFromGroupDto","userToUpdate","MANAGER","adminUsersManager","updateUserFromGroup","removeUserFromGroup","userToRemove","remove","leavePersonalGroup","userWhoLeaves","deletePersonalGroup","canDeletePersonalGroup","listGuests","getGuest","guestId","guest","checkUser","createGuest","createGuestDto","managers","push","createUserOrGuest","GUEST","updateGuest","updateGuestDto","isGuestManager","deleteGuest","deleteUserOrGuest","deleteSpace","isGuest","searchMembers","searchMembersDto","searchUsersOrGroups","notificationsManager","sendEmailNotification","NOTIFICATION_APP","AUTH_LOCKED","event","NOTIFICATION_APP_EVENT","ACTION","DELETE","element","url","Logger"],"mappings":"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"}
|
|
@@ -16,6 +16,7 @@ const _image = /*#__PURE__*/ _interop_require_wildcard(require("../../../common/
|
|
|
16
16
|
const _cacheservice = require("../../../infrastructure/cache/services/cache.service");
|
|
17
17
|
const _constants = require("../../../infrastructure/database/constants");
|
|
18
18
|
const _files = /*#__PURE__*/ _interop_require_wildcard(require("../../files/utils/files"));
|
|
19
|
+
const _notificationsmanagerservice = require("../../notifications/services/notifications-manager.service");
|
|
19
20
|
const _member = require("../constants/member");
|
|
20
21
|
const _user = require("../constants/user");
|
|
21
22
|
const _usermodel = require("../models/user.model");
|
|
@@ -89,8 +90,7 @@ jest.mock('../../../common/image', ()=>{
|
|
|
89
90
|
...actual,
|
|
90
91
|
generateAvatar: jest.fn(()=>_nodestream.Readable.from([
|
|
91
92
|
Buffer.from('PNGDATA')
|
|
92
|
-
]))
|
|
93
|
-
convertImageToBase64: jest.fn(()=>Promise.resolve('BASE64_IMAGE'))
|
|
93
|
+
]))
|
|
94
94
|
};
|
|
95
95
|
});
|
|
96
96
|
describe(_usersmanagerservice.UsersManager.name, ()=>{
|
|
@@ -129,6 +129,9 @@ describe(_usersmanagerservice.UsersManager.name, ()=>{
|
|
|
129
129
|
await userTest.makePaths();
|
|
130
130
|
}
|
|
131
131
|
};
|
|
132
|
+
const notificationsManager = {
|
|
133
|
+
sendEmailNotification: jest.fn().mockResolvedValue(undefined)
|
|
134
|
+
};
|
|
132
135
|
beforeAll(async ()=>{
|
|
133
136
|
const module = await _testing.Test.createTestingModule({
|
|
134
137
|
providers: [
|
|
@@ -136,6 +139,10 @@ describe(_usersmanagerservice.UsersManager.name, ()=>{
|
|
|
136
139
|
_adminusersqueriesservice.AdminUsersQueries,
|
|
137
140
|
_usersmanagerservice.UsersManager,
|
|
138
141
|
_usersqueriesservice.UsersQueries,
|
|
142
|
+
{
|
|
143
|
+
provide: _notificationsmanagerservice.NotificationsManager,
|
|
144
|
+
useValue: notificationsManager
|
|
145
|
+
},
|
|
139
146
|
{
|
|
140
147
|
provide: _authmanagerservice.AuthManager,
|
|
141
148
|
useValue: {}
|
|
@@ -159,7 +166,8 @@ describe(_usersmanagerservice.UsersManager.name, ()=>{
|
|
|
159
166
|
usersQueriesService = module.get(_usersqueriesservice.UsersQueries);
|
|
160
167
|
userTest = new _usermodel.UserModel((0, _test.generateUserTest)(), false);
|
|
161
168
|
deleteUserDto = {
|
|
162
|
-
deleteSpace: true
|
|
169
|
+
deleteSpace: true,
|
|
170
|
+
isGuest: false
|
|
163
171
|
};
|
|
164
172
|
});
|
|
165
173
|
afterEach(()=>jest.restoreAllMocks());
|
|
@@ -391,12 +399,6 @@ describe(_usersmanagerservice.UsersManager.name, ()=>{
|
|
|
391
399
|
await expect(usersManager.getAvatar(userTest.login, true)).rejects.toThrow('Unable to create avatar');
|
|
392
400
|
usersManager.findUser = jest.fn().mockResolvedValue(null);
|
|
393
401
|
await expect(usersManager.getAvatar(userTest.login, true)).rejects.toThrow('avatar not found');
|
|
394
|
-
const s1 = await usersManager.getAvatarBase64(userTest.login);
|
|
395
|
-
expect(s1).toBe('BASE64_IMAGE');
|
|
396
|
-
_image.convertImageToBase64.mockClear();
|
|
397
|
-
const s2 = await usersManager.getAvatarBase64('non-existent-login');
|
|
398
|
-
expect(s2).toBe('BASE64_IMAGE');
|
|
399
|
-
expect(_image.convertImageToBase64).toHaveBeenCalledWith(expect.stringMatching(/avatar\.svg$/));
|
|
400
402
|
});
|
|
401
403
|
it('updateAvatar branches: mime error, stream error, truncated, move fail, success', async ()=>{
|
|
402
404
|
await ensurePaths();
|