@sync-in/server 1.4.0 → 1.5.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 +19 -0
- package/README.md +2 -1
- package/package.json +5 -5
- package/server/applications/comments/comments.controller.spec.js +103 -4
- package/server/applications/comments/comments.controller.spec.js.map +1 -1
- package/server/applications/comments/services/comments-manager.service.spec.js +409 -9
- package/server/applications/comments/services/comments-manager.service.spec.js.map +1 -1
- package/server/applications/files/adapters/files-indexer-mysql.service.spec.js +333 -0
- package/server/applications/files/adapters/files-indexer-mysql.service.spec.js.map +1 -0
- package/server/applications/files/constants/routes.js +6 -1
- package/server/applications/files/constants/routes.js.map +1 -1
- package/server/applications/files/files-only-office.controller.js +11 -0
- package/server/applications/files/files-only-office.controller.js.map +1 -1
- package/server/applications/files/files-only-office.controller.spec.js +97 -3
- package/server/applications/files/files-only-office.controller.spec.js.map +1 -1
- package/server/applications/files/files-tasks.controller.spec.js +91 -1
- package/server/applications/files/files-tasks.controller.spec.js.map +1 -1
- package/server/applications/files/files.controller.spec.js +268 -46
- package/server/applications/files/files.controller.spec.js.map +1 -1
- package/server/applications/files/guards/files-only-office.guard.spec.js +77 -1
- package/server/applications/files/guards/files-only-office.guard.spec.js.map +1 -1
- package/server/applications/files/services/files-only-office-manager.service.js +5 -0
- package/server/applications/files/services/files-only-office-manager.service.js.map +1 -1
- package/server/applications/links/links.controller.spec.js +91 -58
- package/server/applications/links/links.controller.spec.js.map +1 -1
- package/server/applications/links/services/links-manager.service.js +4 -6
- package/server/applications/links/services/links-manager.service.js.map +1 -1
- package/server/applications/links/services/links-manager.service.spec.js +378 -14
- package/server/applications/links/services/links-manager.service.spec.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/notifications.controller.spec.js +56 -1
- package/server/applications/notifications/notifications.controller.spec.js.map +1 -1
- package/server/applications/notifications/services/notifications-manager.service.spec.js +461 -5
- package/server/applications/notifications/services/notifications-manager.service.spec.js.map +1 -1
- package/server/applications/shares/services/shares-manager.service.spec.js +590 -14
- package/server/applications/shares/services/shares-manager.service.spec.js.map +1 -1
- package/server/applications/sync/interceptors/sync-diff-gzip-body.interceptor.spec.js +120 -0
- package/server/applications/sync/interceptors/sync-diff-gzip-body.interceptor.spec.js.map +1 -0
- package/server/applications/sync/services/sync-clients-manager.service.spec.js +548 -8
- package/server/applications/sync/services/sync-clients-manager.service.spec.js.map +1 -1
- package/server/applications/sync/services/sync-manager.service.spec.js +837 -5
- package/server/applications/sync/services/sync-manager.service.spec.js.map +1 -1
- package/server/applications/sync/services/sync-paths-manager.service.spec.js +900 -7
- package/server/applications/sync/services/sync-paths-manager.service.spec.js.map +1 -1
- package/server/applications/users/services/admin-users-manager.service.js +22 -24
- package/server/applications/users/services/admin-users-manager.service.js.map +1 -1
- package/server/applications/users/services/admin-users-manager.service.spec.js +763 -17
- package/server/applications/users/services/admin-users-manager.service.spec.js.map +1 -1
- package/server/applications/users/services/users-manager.service.js +1 -1
- package/server/applications/users/services/users-manager.service.js.map +1 -1
- package/server/applications/users/services/users-manager.service.spec.js +938 -49
- package/server/applications/users/services/users-manager.service.spec.js.map +1 -1
- package/server/applications/webdav/decorators/if-header.decorator.js +4 -1
- package/server/applications/webdav/decorators/if-header.decorator.js.map +1 -1
- package/server/applications/webdav/filters/webdav.filter.spec.js +77 -0
- package/server/applications/webdav/filters/webdav.filter.spec.js.map +1 -0
- package/server/applications/webdav/guards/webdav-protocol.guard.js +3 -7
- package/server/applications/webdav/guards/webdav-protocol.guard.js.map +1 -1
- package/server/applications/webdav/guards/webdav-protocol.guard.spec.js +580 -0
- package/server/applications/webdav/guards/webdav-protocol.guard.spec.js.map +1 -0
- package/server/applications/webdav/services/webdav-methods.service.spec.js +1582 -3
- package/server/applications/webdav/services/webdav-methods.service.spec.js.map +1 -1
- package/server/applications/webdav/services/webdav-spaces.service.spec.js +390 -2
- package/server/applications/webdav/services/webdav-spaces.service.spec.js.map +1 -1
- package/server/applications/webdav/webdav.controller.js +2 -2
- package/server/applications/webdav/webdav.controller.js.map +1 -1
- package/server/authentication/guards/auth-basic.guard.js.map +1 -1
- package/server/authentication/guards/auth-digest.guard.js +1 -2
- package/server/authentication/guards/auth-digest.guard.js.map +1 -1
- package/server/authentication/guards/auth-local.guard.js.map +1 -1
- package/server/infrastructure/context/interceptors/context.interceptor.spec.js +135 -0
- package/server/infrastructure/context/interceptors/context.interceptor.spec.js.map +1 -0
- package/static/3rdpartylicenses.txt +26 -26
- package/static/assets/pdfjs/build/pdf.mjs +1177 -255
- package/static/assets/pdfjs/build/pdf.mjs.map +1 -1
- package/static/assets/pdfjs/build/pdf.sandbox.mjs +25 -2
- package/static/assets/pdfjs/build/pdf.sandbox.mjs.map +1 -1
- package/static/assets/pdfjs/build/pdf.worker.mjs +140 -16
- package/static/assets/pdfjs/build/pdf.worker.mjs.map +1 -1
- package/static/assets/pdfjs/version +1 -1
- package/static/assets/pdfjs/web/debugger.css +31 -0
- package/static/assets/pdfjs/web/debugger.mjs +144 -2
- package/static/assets/pdfjs/web/images/comment-editButton.svg +6 -1
- package/static/assets/pdfjs/web/locale/ach/viewer.ftl +0 -63
- package/static/assets/pdfjs/web/locale/af/viewer.ftl +0 -71
- package/static/assets/pdfjs/web/locale/an/viewer.ftl +0 -63
- package/static/assets/pdfjs/web/locale/ast/viewer.ftl +0 -60
- package/static/assets/pdfjs/web/locale/az/viewer.ftl +0 -63
- package/static/assets/pdfjs/web/locale/be/viewer.ftl +38 -0
- package/static/assets/pdfjs/web/locale/bg/viewer.ftl +0 -37
- package/static/assets/pdfjs/web/locale/bn/viewer.ftl +0 -63
- package/static/assets/pdfjs/web/locale/bo/viewer.ftl +0 -63
- package/static/assets/pdfjs/web/locale/br/viewer.ftl +0 -37
- package/static/assets/pdfjs/web/locale/brx/viewer.ftl +0 -63
- package/static/assets/pdfjs/web/locale/bs/viewer.ftl +22 -0
- package/static/assets/pdfjs/web/locale/ca/viewer.ftl +0 -54
- package/static/assets/pdfjs/web/locale/cak/viewer.ftl +0 -54
- package/static/assets/pdfjs/web/locale/ckb/viewer.ftl +0 -63
- package/static/assets/pdfjs/web/locale/cs/viewer.ftl +38 -0
- package/static/assets/pdfjs/web/locale/cy/viewer.ftl +38 -0
- package/static/assets/pdfjs/web/locale/da/viewer.ftl +38 -0
- package/static/assets/pdfjs/web/locale/de/viewer.ftl +38 -0
- package/static/assets/pdfjs/web/locale/dsb/viewer.ftl +38 -0
- package/static/assets/pdfjs/web/locale/el/viewer.ftl +38 -0
- package/static/assets/pdfjs/web/locale/en-CA/viewer.ftl +38 -0
- package/static/assets/pdfjs/web/locale/en-GB/viewer.ftl +38 -0
- package/static/assets/pdfjs/web/locale/en-US/viewer.ftl +25 -0
- package/static/assets/pdfjs/web/locale/eo/viewer.ftl +38 -0
- package/static/assets/pdfjs/web/locale/es-AR/viewer.ftl +38 -0
- package/static/assets/pdfjs/web/locale/es-CL/viewer.ftl +38 -0
- package/static/assets/pdfjs/web/locale/es-MX/viewer.ftl +0 -6
- package/static/assets/pdfjs/web/locale/et/viewer.ftl +0 -57
- package/static/assets/pdfjs/web/locale/fa/viewer.ftl +0 -37
- package/static/assets/pdfjs/web/locale/ff/viewer.ftl +0 -63
- package/static/assets/pdfjs/web/locale/fi/viewer.ftl +38 -0
- package/static/assets/pdfjs/web/locale/fr/viewer.ftl +38 -0
- package/static/assets/pdfjs/web/locale/fy-NL/viewer.ftl +38 -0
- package/static/assets/pdfjs/web/locale/ga-IE/viewer.ftl +0 -71
- package/static/assets/pdfjs/web/locale/gd/viewer.ftl +0 -54
- package/static/assets/pdfjs/web/locale/gl/viewer.ftl +8 -0
- package/static/assets/pdfjs/web/locale/gn/viewer.ftl +38 -0
- package/static/assets/pdfjs/web/locale/gu-IN/viewer.ftl +0 -63
- package/static/assets/pdfjs/web/locale/he/viewer.ftl +38 -0
- package/static/assets/pdfjs/web/locale/hi-IN/viewer.ftl +0 -60
- package/static/assets/pdfjs/web/locale/hsb/viewer.ftl +38 -0
- package/static/assets/pdfjs/web/locale/hu/viewer.ftl +38 -0
- package/static/assets/pdfjs/web/locale/hy-AM/viewer.ftl +0 -49
- package/static/assets/pdfjs/web/locale/hye/viewer.ftl +0 -60
- package/static/assets/pdfjs/web/locale/ia/viewer.ftl +38 -0
- package/static/assets/pdfjs/web/locale/is/viewer.ftl +0 -3
- package/static/assets/pdfjs/web/locale/it/viewer.ftl +31 -0
- package/static/assets/pdfjs/web/locale/ja/viewer.ftl +8 -0
- package/static/assets/pdfjs/web/locale/ka/viewer.ftl +48 -10
- package/static/assets/pdfjs/web/locale/kab/viewer.ftl +5 -0
- package/static/assets/pdfjs/web/locale/kk/viewer.ftl +8 -0
- package/static/assets/pdfjs/web/locale/km/viewer.ftl +0 -63
- package/static/assets/pdfjs/web/locale/kn/viewer.ftl +0 -71
- package/static/assets/pdfjs/web/locale/ko/viewer.ftl +38 -0
- package/static/assets/pdfjs/web/locale/lij/viewer.ftl +0 -63
- package/static/assets/pdfjs/web/locale/lo/viewer.ftl +0 -54
- package/static/assets/pdfjs/web/locale/lt/viewer.ftl +0 -60
- package/static/assets/pdfjs/web/locale/ltg/viewer.ftl +0 -63
- package/static/assets/pdfjs/web/locale/lv/viewer.ftl +0 -63
- package/static/assets/pdfjs/web/locale/meh/viewer.ftl +0 -75
- package/static/assets/pdfjs/web/locale/mk/viewer.ftl +0 -63
- package/static/assets/pdfjs/web/locale/ml/viewer.ftl +0 -3
- package/static/assets/pdfjs/web/locale/mr/viewer.ftl +0 -63
- package/static/assets/pdfjs/web/locale/ms/viewer.ftl +0 -63
- package/static/assets/pdfjs/web/locale/my/viewer.ftl +0 -71
- package/static/assets/pdfjs/web/locale/nb-NO/viewer.ftl +44 -6
- package/static/assets/pdfjs/web/locale/ne-NP/viewer.ftl +0 -71
- package/static/assets/pdfjs/web/locale/nl/viewer.ftl +38 -0
- package/static/assets/pdfjs/web/locale/nn-NO/viewer.ftl +45 -1
- package/static/assets/pdfjs/web/locale/oc/viewer.ftl +0 -31
- package/static/assets/pdfjs/web/locale/pa-IN/viewer.ftl +38 -0
- package/static/assets/pdfjs/web/locale/pl/viewer.ftl +39 -1
- package/static/assets/pdfjs/web/locale/pt-BR/viewer.ftl +38 -0
- package/static/assets/pdfjs/web/locale/ro/viewer.ftl +355 -1
- package/static/assets/pdfjs/web/locale/ru/viewer.ftl +38 -0
- package/static/assets/pdfjs/web/locale/sat/viewer.ftl +0 -54
- package/static/assets/pdfjs/web/locale/sc/viewer.ftl +0 -38
- package/static/assets/pdfjs/web/locale/scn/viewer.ftl +0 -92
- package/static/assets/pdfjs/web/locale/sco/viewer.ftl +0 -60
- package/static/assets/pdfjs/web/locale/si/viewer.ftl +0 -51
- package/static/assets/pdfjs/web/locale/sk/viewer.ftl +38 -0
- package/static/assets/pdfjs/web/locale/skr/viewer.ftl +0 -27
- package/static/assets/pdfjs/web/locale/sl/viewer.ftl +8 -0
- package/static/assets/pdfjs/web/locale/son/viewer.ftl +0 -71
- package/static/assets/pdfjs/web/locale/sr/viewer.ftl +0 -33
- package/static/assets/pdfjs/web/locale/sv-SE/viewer.ftl +38 -0
- package/static/assets/pdfjs/web/locale/szl/viewer.ftl +0 -63
- package/static/assets/pdfjs/web/locale/ta/viewer.ftl +0 -63
- package/static/assets/pdfjs/web/locale/te/viewer.ftl +0 -60
- package/static/assets/pdfjs/web/locale/tg/viewer.ftl +38 -0
- package/static/assets/pdfjs/web/locale/tl/viewer.ftl +0 -63
- package/static/assets/pdfjs/web/locale/tr/viewer.ftl +40 -2
- package/static/assets/pdfjs/web/locale/trs/viewer.ftl +0 -72
- package/static/assets/pdfjs/web/locale/ur/viewer.ftl +0 -60
- package/static/assets/pdfjs/web/locale/uz/viewer.ftl +0 -71
- package/static/assets/pdfjs/web/locale/vi/viewer.ftl +38 -0
- package/static/assets/pdfjs/web/locale/wo/viewer.ftl +0 -77
- package/static/assets/pdfjs/web/locale/xh/viewer.ftl +0 -71
- package/static/assets/pdfjs/web/locale/zh-CN/viewer.ftl +38 -0
- package/static/assets/pdfjs/web/locale/zh-TW/viewer.ftl +38 -0
- package/static/assets/pdfjs/web/viewer.css +649 -120
- package/static/assets/pdfjs/web/viewer.html +19 -0
- package/static/assets/pdfjs/web/viewer.mjs +489 -38
- package/static/assets/pdfjs/web/viewer.mjs.map +1 -1
- package/static/chunk-22EANI6R.js +1 -0
- package/static/{chunk-3GC2BQZD.js → chunk-2UWN7IQF.js} +1 -1
- package/static/{chunk-TCFKH6K6.js → chunk-2VSPDSJS.js} +1 -1
- package/static/{chunk-KZQCFEPT.js → chunk-34UZ7SYI.js} +1 -1
- package/static/{chunk-5YKWZT33.js → chunk-45UQJGGY.js} +1 -1
- package/static/{chunk-N2LYWNTC.js → chunk-5TEXH3LJ.js} +1 -1
- package/static/{chunk-MOVWEZ7J.js → chunk-66FMKVJX.js} +1 -1
- package/static/{chunk-XE5YHU5J.js → chunk-BIUNUYZ5.js} +1 -1
- package/static/chunk-CK4BY2NX.js +27 -0
- package/static/{chunk-T55FAU2O.js → chunk-CSBDAY77.js} +1 -1
- package/static/{chunk-6F55D74O.js → chunk-CXXPLBDZ.js} +1 -1
- package/static/{chunk-YCINY2YI.js → chunk-EILQG525.js} +1 -1
- package/static/{chunk-DGVNNICG.js → chunk-ENWABUR4.js} +1 -1
- package/static/{chunk-Y2CDUS4J.js → chunk-FR4AOLYL.js} +4 -4
- package/static/chunk-HW2H3ISM.js +559 -0
- package/static/{chunk-VHYIXL7R.js → chunk-HYMDGBZL.js} +1 -1
- package/static/{chunk-W3QXNDI5.js → chunk-IML5UYQG.js} +1 -1
- package/static/{chunk-GBCYYDCI.js → chunk-IPSMJHMQ.js} +1 -1
- package/static/{chunk-TXPODW5Q.js → chunk-JVCWYSNP.js} +1 -1
- package/static/{chunk-VMQMD36Z.js → chunk-KGPCIUD2.js} +1 -1
- package/static/{chunk-TNW2CGK6.js → chunk-KQZJSEM3.js} +1 -1
- package/static/{chunk-HZA7R43P.js → chunk-NPEMJJIU.js} +1 -1
- package/static/{chunk-WWIC7UW3.js → chunk-OEFBC4GG.js} +1 -1
- package/static/{chunk-VMUOUCEI.js → chunk-P734A3XZ.js} +1 -1
- package/static/{chunk-FQ4AFNGE.js → chunk-RASR4CK6.js} +1 -1
- package/static/{chunk-LJIGRUEF.js → chunk-RFMOUC22.js} +1 -1
- package/static/{chunk-TTQ37MUV.js → chunk-RSS6GYNE.js} +1 -1
- package/static/{chunk-TDQAEVZN.js → chunk-SBOQGGZX.js} +1 -1
- package/static/{chunk-PF4K7MVG.js → chunk-SJAFPXQV.js} +1 -1
- package/static/{chunk-C23BPTJZ.js → chunk-XTYGMF2V.js} +1 -1
- package/static/{chunk-B2Y2RNFP.js → chunk-YCWMV2YR.js} +1 -1
- package/static/{chunk-X43VWRFP.js → chunk-YGD22MWQ.js} +1 -1
- package/static/{chunk-MTRNPGS4.js → chunk-ZC5NIT55.js} +1 -1
- package/static/{chunk-PY3BGNJN.js → chunk-ZVY37DKS.js} +1 -1
- package/static/index.html +1 -1
- package/static/main-N5CZRHAO.js +7 -0
- package/static/chunk-RSNLYAN6.js +0 -560
- package/static/chunk-WHMS3PJ3.js +0 -24
- package/static/chunk-ZZ3LHYOY.js +0 -1
- package/static/main-7LDKYVXO.js +0 -10
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../backend/src/applications/users/services/admin-users-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 { Test, TestingModule } from '@nestjs/testing'\nimport { AuthManager } from '../../../authentication/services/auth-manager.service'\nimport { Cache } from '../../../infrastructure/cache/services/cache.service'\nimport { DB_TOKEN_PROVIDER } from '../../../infrastructure/database/constants'\nimport { AdminUsersManager } from './admin-users-manager.service'\nimport { AdminUsersQueries } from './admin-users-queries.service'\nimport { UsersManager } from './users-manager.service'\nimport { UsersQueries } from './users-queries.service'\n\ndescribe(AdminUsersManager.name, () => {\n let service: AdminUsersManager\n\n beforeAll(async () => {\n const module: TestingModule = await Test.createTestingModule({\n providers: [\n AdminUsersManager,\n AdminUsersQueries,\n UsersQueries,\n { provide: AuthManager, useValue: {} },\n { provide: UsersManager, useValue: {} },\n { provide: DB_TOKEN_PROVIDER, useValue: {} },\n {\n provide: Cache,\n useValue: {}\n }\n ]\n }).compile()\n\n service = module.get<AdminUsersManager>(AdminUsersManager)\n })\n\n it('should be defined', () => {\n expect(service).toBeDefined()\n })\n})\n"],"names":["describe","AdminUsersManager","name","service","beforeAll","module","Test","createTestingModule","providers","AdminUsersQueries","UsersQueries","provide","AuthManager","useValue","UsersManager","DB_TOKEN_PROVIDER","Cache","compile","get","it","expect","toBeDefined"],"mappings":"AAAA;;;;CAIC;;;;yBAEmC;oCACR;8BACN;2BACY;0CACA;0CACA;qCACL;qCACA;AAE7BA,SAASC,2CAAiB,CAACC,IAAI,EAAE;IAC/B,IAAIC;IAEJC,UAAU;QACR,MAAMC,SAAwB,MAAMC,aAAI,CAACC,mBAAmB,CAAC;YAC3DC,WAAW;gBACTP,2CAAiB;gBACjBQ,2CAAiB;gBACjBC,iCAAY;gBACZ;oBAAEC,SAASC,+BAAW;oBAAEC,UAAU,CAAC;gBAAE;gBACrC;oBAAEF,SAASG,iCAAY;oBAAED,UAAU,CAAC;gBAAE;gBACtC;oBAAEF,SAASI,4BAAiB;oBAAEF,UAAU,CAAC;gBAAE;gBAC3C;oBACEF,SAASK,mBAAK;oBACdH,UAAU,CAAC;gBACb;aACD;QACH,GAAGI,OAAO;QAEVd,UAAUE,OAAOa,GAAG,CAAoBjB,2CAAiB;IAC3D;IAEAkB,GAAG,qBAAqB;QACtBC,OAAOjB,SAASkB,WAAW;IAC7B;AACF"}
|
|
1
|
+
{"version":3,"sources":["../../../../../backend/src/applications/users/services/admin-users-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 { HttpException } from '@nestjs/common'\nimport { Test, TestingModule } from '@nestjs/testing'\nimport { AuthManager } from '../../../authentication/services/auth-manager.service'\nimport { GROUP_TYPE } from '../constants/group'\nimport { USER_GROUP_ROLE, USER_ROLE } from '../constants/user'\nimport type { CreateOrUpdateGroupDto } from '../dto/create-or-update-group.dto'\nimport { CreateUserDto, UpdateUserDto, UpdateUserFromGroupDto } from '../dto/create-or-update-user.dto'\nimport type { AdminDeleteUserDto } from '../dto/delete-user.dto'\nimport type { SearchMembersDto } from '../dto/search-members.dto'\nimport type { UserPasswordDto } from '../dto/user-password.dto'\nimport { UserModel } from '../models/user.model'\nimport { AdminUsersManager } from './admin-users-manager.service'\nimport { AdminUsersQueries } from './admin-users-queries.service'\n\n// mock file utils used by the service (delete/rename user space)\njest.mock('../../files/utils/files', () => ({\n isPathExists: jest.fn(),\n moveFiles: jest.fn(),\n removeFiles: jest.fn()\n}))\n\n// mock hash/anonymize utilities (preserve other module exports)\njest.mock('../../../common/functions', () => {\n const actual = jest.requireActual('../../../common/functions')\n return {\n ...actual,\n hashPassword: jest.fn(async (pwd: string) => `hashed:${pwd}`),\n anonymizePassword: jest.fn((dto: any) => ({ ...dto, password: '***' }))\n }\n})\n\n// Alias FS mocks (avoid repetitions)\nconst fs = jest.requireMock('../../files/utils/files') as { isPathExists: jest.Mock; moveFiles: jest.Mock; removeFiles: jest.Mock }\n\n// Helper utilities\nconst expectHttp = async (p: Promise<any>) => expect(p).rejects.toBeInstanceOf(HttpException)\nconst spyMakePaths = () => jest.spyOn(UserModel.prototype, 'makePaths').mockResolvedValueOnce(undefined)\n\ndescribe(AdminUsersManager.name, () => {\n let service: AdminUsersManager\n\n // deep mocks\n let authManagerMock: { setCookies: jest.Mock }\n let adminQueriesMock: {\n listUsers: jest.Mock\n usersQueries: {\n listGuests: jest.Mock\n from: jest.Mock\n createUserOrGuest: jest.Mock\n updateUserOrGuest: jest.Mock\n deleteUser: jest.Mock\n compareUserPassword: jest.Mock\n checkGroupNameExists: jest.Mock\n checkUserExists: jest.Mock\n searchUsersOrGroups: jest.Mock\n }\n updateUserGroups: jest.Mock\n updateGuestManagers: jest.Mock\n deleteUser: jest.Mock\n groupFromName: jest.Mock\n browseGroupMembers: jest.Mock\n browseRootGroupMembers: jest.Mock\n groupFromId: jest.Mock\n createGroup: jest.Mock\n updateGroup: jest.Mock\n deleteGroup: jest.Mock\n addUsersToGroup: jest.Mock\n updateUserFromGroup: jest.Mock\n removeUserFromGroup: jest.Mock\n }\n\n const setUser = (u: any) => adminQueriesMock.listUsers.mockResolvedValueOnce(u)\n const setGuest = (g: any) => adminQueriesMock.usersQueries.listGuests.mockResolvedValueOnce(g)\n\n const baseUser = {\n id: 10,\n login: 'john',\n email: 'john@example.com',\n isActive: true,\n role: USER_ROLE.USER,\n groups: [{ id: 1 }, { id: 3 }]\n } as any\n\n beforeAll(async () => {\n authManagerMock = { setCookies: jest.fn() }\n\n adminQueriesMock = {\n listUsers: jest.fn(),\n usersQueries: {\n listGuests: jest.fn(),\n from: jest.fn(),\n createUserOrGuest: jest.fn(),\n updateUserOrGuest: jest.fn(),\n deleteUser: jest.fn(),\n compareUserPassword: jest.fn(),\n checkGroupNameExists: jest.fn(),\n checkUserExists: jest.fn(),\n searchUsersOrGroups: jest.fn()\n },\n updateUserGroups: jest.fn(),\n updateGuestManagers: jest.fn(),\n deleteUser: jest.fn(),\n groupFromName: jest.fn(),\n browseGroupMembers: jest.fn(),\n browseRootGroupMembers: jest.fn(),\n groupFromId: jest.fn(),\n createGroup: jest.fn(),\n updateGroup: jest.fn(),\n deleteGroup: jest.fn(),\n addUsersToGroup: jest.fn(),\n updateUserFromGroup: jest.fn(),\n removeUserFromGroup: jest.fn()\n }\n\n const module: TestingModule = await Test.createTestingModule({\n providers: [AdminUsersManager, { provide: AuthManager, useValue: authManagerMock }, { provide: AdminUsersQueries, useValue: adminQueriesMock }]\n }).compile()\n\n module.useLogger(['fatal'])\n service = module.get<AdminUsersManager>(AdminUsersManager)\n })\n\n beforeEach(() => {\n jest.clearAllMocks()\n })\n\n it('should be defined', () => {\n expect(service).toBeDefined()\n })\n\n describe('getUser / getGuest', () => {\n it('user ok + not found + guest ok', async () => {\n setUser(baseUser)\n expect(await service.getUser(10)).toEqual(baseUser)\n expect(adminQueriesMock.listUsers).toHaveBeenCalledWith(10)\n\n setUser(null)\n await expectHttp(service.getUser(999))\n\n const guest = { id: 22, login: 'guest', email: 'g@x', managers: [], role: USER_ROLE.GUEST }\n setGuest(guest as any)\n expect(await service.getGuest(22)).toEqual(guest)\n expect(adminQueriesMock.usersQueries.listGuests).toHaveBeenCalledWith(22, 0, true)\n })\n })\n\n describe('createUserOrGuest', () => {\n it.each([\n { role: USER_ROLE.USER, asAdmin: false, id: 101, exp: 'UserModel' },\n { role: USER_ROLE.GUEST, asAdmin: true, id: 202, exp: 'AdminGuest' },\n { role: USER_ROLE.USER, asAdmin: true, id: 707, exp: 'AdminUser' },\n { role: USER_ROLE.GUEST, asAdmin: false, id: 808, exp: 'UserModel' }\n ])('creation matrix ($role / asAdmin=$asAdmin)', async ({ role, asAdmin, id, exp }) => {\n const dto: CreateUserDto = { login: 'alice', email: 'a@x', password: 'pwd', managers: role === USER_ROLE.GUEST ? [1] : [] } as any\n adminQueriesMock.usersQueries.checkUserExists.mockResolvedValueOnce(false)\n adminQueriesMock.usersQueries.createUserOrGuest.mockResolvedValueOnce(id)\n spyMakePaths()\n\n if (exp === 'AdminUser') setUser({ id, login: 'alice', role })\n if (exp === 'AdminGuest') setGuest({ id, login: 'alice', role } as any)\n\n const res = await (service as any).createUserOrGuest(dto, role, asAdmin)\n\n if (exp === 'UserModel') {\n expect(res).toBeInstanceOf(UserModel)\n expect((res as any).id).toBe(id)\n } else if (exp === 'AdminUser') {\n expect(adminQueriesMock.listUsers).toHaveBeenCalledWith(id)\n } else {\n expect(adminQueriesMock.usersQueries.listGuests).toHaveBeenCalledWith(id, 0, true)\n }\n expect(adminQueriesMock.usersQueries.createUserOrGuest).toHaveBeenCalledWith(\n expect.objectContaining({ login: 'alice', email: 'a@x', password: 'hashed:pwd' }),\n role\n )\n })\n\n it('creation errors: duplication and DB error', async () => {\n adminQueriesMock.usersQueries.checkUserExists.mockResolvedValueOnce({ login: 'dup', email: 'dup@x' })\n await expectHttp(service.createUserOrGuest({ login: 'dup', email: 'dup@x', password: 'p', managers: [] } as any, USER_ROLE.USER, false))\n\n adminQueriesMock.usersQueries.checkUserExists.mockResolvedValueOnce(false)\n adminQueriesMock.usersQueries.createUserOrGuest.mockRejectedValueOnce(new Error('db fail'))\n await expectHttp(service.createUserOrGuest({ login: 'bob', email: 'b@x', password: 'p', managers: [] } as any, USER_ROLE.USER, false))\n })\n })\n\n describe('updateUserOrGuest - USER branch', () => {\n it('full update + FS rename + groups diff', async () => {\n const current = { ...baseUser, groups: [{ id: 1 }, { id: 3 }] }\n setUser(current)\n const updated = { ...current, login: 'johnny', email: 'j@new' }\n setUser(updated)\n\n adminQueriesMock.usersQueries.checkUserExists.mockResolvedValueOnce(false)\n adminQueriesMock.usersQueries.checkUserExists.mockResolvedValueOnce(false)\n fs.isPathExists.mockResolvedValueOnce(true)\n fs.isPathExists.mockResolvedValueOnce(false)\n fs.moveFiles.mockResolvedValueOnce(undefined)\n adminQueriesMock.usersQueries.updateUserOrGuest.mockResolvedValueOnce(true)\n adminQueriesMock.updateUserGroups.mockResolvedValueOnce(undefined)\n\n const dto: UpdateUserDto = { login: 'johnny', email: 'j@new', isActive: true, password: 'newpwd', groups: [3, 5] }\n const res = await service.updateUserOrGuest(current.id, dto)\n\n expect(adminQueriesMock.usersQueries.updateUserOrGuest).toHaveBeenCalledWith(\n current.id,\n expect.objectContaining({ login: 'johnny', email: 'j@new', isActive: true, passwordAttempts: 0, password: 'hashed:newpwd' }),\n undefined\n )\n expect(adminQueriesMock.updateUserGroups).toHaveBeenCalledWith(current.id, { add: [5], delete: [1] })\n expect(res).toEqual(updated)\n })\n\n it('login/email conflict', async () => {\n const current = { ...baseUser }\n setUser(current)\n adminQueriesMock.usersQueries.checkUserExists.mockResolvedValueOnce(true)\n await expectHttp(service.updateUserOrGuest(current.id, { login: 'taken' } as any))\n\n setUser(current)\n adminQueriesMock.usersQueries.checkUserExists.mockResolvedValueOnce(true)\n await expectHttp(service.updateUserOrGuest(current.id, { email: 'dup@x' } as any))\n expect(adminQueriesMock.usersQueries.updateUserOrGuest).not.toHaveBeenCalled()\n })\n\n it('renameUserSpace impossible (new space exists)', async () => {\n const current = { ...baseUser }\n setUser(current)\n adminQueriesMock.usersQueries.checkUserExists.mockResolvedValueOnce(false)\n fs.isPathExists.mockResolvedValueOnce(true) // current\n fs.isPathExists.mockResolvedValueOnce(true) // new already exists\n fs.moveFiles.mockResolvedValue(undefined)\n await expectHttp(service.updateUserOrGuest(current.id, { login: 'new' } as any))\n })\n\n it('DB update false => INTERNAL_SERVER_ERROR', async () => {\n const current = { ...baseUser }\n setUser(current)\n adminQueriesMock.usersQueries.updateUserOrGuest.mockResolvedValueOnce(false)\n await expectHttp(service.updateUserOrGuest(current.id, { email: 'e@x' } as any))\n })\n\n it('updateUserGroups fails', async () => {\n const current = { ...baseUser, groups: [{ id: 1 }] }\n setUser(current)\n adminQueriesMock.usersQueries.updateUserOrGuest.mockResolvedValueOnce(true)\n adminQueriesMock.updateUserGroups.mockRejectedValueOnce(new Error('group error'))\n await expectHttp(service.updateUserOrGuest(current.id, { groups: [2] } as any))\n })\n\n it('no change when login or email unchanged', async () => {\n const current = { ...baseUser }\n setUser(current)\n setUser(current)\n expect(await service.updateUserOrGuest(current.id, { login: current.login } as any)).toEqual(current)\n expect(adminQueriesMock.usersQueries.checkUserExists).not.toHaveBeenCalled()\n\n setUser(current)\n setUser(current)\n expect(await service.updateUserOrGuest(current.id, { email: current.email } as any)).toEqual(current)\n expect(adminQueriesMock.usersQueries.updateUserOrGuest).not.toHaveBeenCalled()\n })\n\n it('default branch (unknown field)', async () => {\n const current = { ...baseUser }\n setUser(current)\n adminQueriesMock.usersQueries.updateUserOrGuest.mockResolvedValueOnce(true)\n const updated = { ...current, language: 'fr' } as any\n setUser(updated)\n\n const res = await service.updateUserOrGuest(current.id, { language: 'fr' } as any)\n expect(adminQueriesMock.usersQueries.updateUserOrGuest).toHaveBeenCalledWith(current.id, expect.objectContaining({ language: 'fr' }), undefined)\n expect(res).toEqual(updated)\n })\n })\n\n describe('updateUserOrGuest - GUEST branch', () => {\n it('update guest + managers diff', async () => {\n const guest = { id: 33, login: 'g', email: 'g@x', managers: [{ id: 2 }, { id: 7 }], role: USER_ROLE.GUEST }\n setGuest(guest as any)\n const updatedGuest = { ...guest, email: 'new@x' }\n setGuest(updatedGuest as any)\n\n adminQueriesMock.usersQueries.updateUserOrGuest.mockResolvedValueOnce(true)\n adminQueriesMock.updateGuestManagers.mockResolvedValueOnce(undefined)\n\n const res = await service.updateUserOrGuest(guest.id, { email: 'new@x', managers: [7, 9] } as UpdateUserDto, USER_ROLE.GUEST)\n expect(adminQueriesMock.usersQueries.updateUserOrGuest).toHaveBeenCalledWith(guest.id, { email: 'new@x' }, USER_ROLE.GUEST)\n expect(adminQueriesMock.updateGuestManagers).toHaveBeenCalledWith(guest.id, { add: [9], delete: [2] })\n expect(res).toEqual(updatedGuest)\n })\n\n it('validations updateGuest', async () => {\n expect(() => service.updateGuest(1, {} as any)).toThrow(/no changes to update/i)\n expect(() => service.updateGuest(1, { managers: [] } as any)).toThrow(/guest must have at least one manager/i)\n })\n\n it('updateGuestManagers échoue', async () => {\n const guest = { id: 33, login: 'g', email: 'g@x', managers: [{ id: 2 }], role: USER_ROLE.GUEST }\n setGuest(guest as any)\n adminQueriesMock.usersQueries.updateUserOrGuest.mockResolvedValueOnce(true)\n adminQueriesMock.updateGuestManagers.mockRejectedValueOnce(new Error('mgr error'))\n await expectHttp(service.updateUserOrGuest(guest.id, { managers: [3] } as any, USER_ROLE.GUEST))\n })\n })\n\n describe('deleteUserOrGuest / deleteGuest', () => {\n it('delete user + optional space and errors', async () => {\n adminQueriesMock.deleteUser.mockResolvedValueOnce(true)\n fs.isPathExists.mockResolvedValueOnce(true)\n fs.removeFiles.mockResolvedValueOnce(undefined)\n await expect(service.deleteUserOrGuest(10, 'john', { deleteSpace: true, isGuest: false })).resolves.toBeUndefined()\n expect(adminQueriesMock.deleteUser).toHaveBeenCalledWith(10, 'john')\n expect(fs.isPathExists).toHaveBeenCalled()\n expect(fs.removeFiles).toHaveBeenCalled()\n\n adminQueriesMock.deleteUser.mockRejectedValueOnce(new Error('db crash'))\n await expectHttp(service.deleteUserOrGuest(10, 'john', { deleteSpace: false } as any))\n })\n\n it('deleteGuest -> getGuest then delete', async () => {\n setGuest({ id: 77, login: 'g77' } as any)\n adminQueriesMock.deleteUser.mockResolvedValueOnce(true)\n fs.isPathExists.mockResolvedValueOnce(false)\n await expect(service.deleteGuest(77)).resolves.toBeUndefined()\n expect(adminQueriesMock.deleteUser).toHaveBeenCalledWith(77, 'g77')\n })\n })\n\n describe('deleteUserFromAdmin', () => {\n it('admin password incorrect / deletion ok', async () => {\n const admin = new UserModel({ id: 1 } as any, true)\n adminQueriesMock.usersQueries.compareUserPassword.mockResolvedValueOnce(false)\n await expectHttp(service.deleteUserFromAdmin(admin, 10, { adminPassword: 'bad' } as AdminDeleteUserDto))\n\n adminQueriesMock.usersQueries.compareUserPassword.mockResolvedValueOnce(true)\n adminQueriesMock.usersQueries.from.mockResolvedValueOnce({ id: 10, login: 'to-del' } as any)\n adminQueriesMock.deleteUser.mockResolvedValueOnce(true)\n await service.deleteUserFromAdmin(admin, 10, { adminPassword: 'ok', deleteSpace: true } as any)\n expect(adminQueriesMock.deleteUser).toHaveBeenCalledWith(10, 'to-del')\n })\n })\n\n describe('groups', () => {\n it('browseGroups with/without name + NOT_FOUND', async () => {\n adminQueriesMock.groupFromName.mockResolvedValueOnce({ id: 5, name: 'dev', type: GROUP_TYPE.USER })\n adminQueriesMock.browseGroupMembers.mockResolvedValueOnce([{ id: 1 }, { id: 2 }])\n const withName = await service.browseGroups('dev', GROUP_TYPE.USER)\n expect(withName.parentGroup).toEqual({ id: 5, name: 'dev', type: GROUP_TYPE.USER })\n expect(withName.members).toHaveLength(2)\n\n adminQueriesMock.browseRootGroupMembers.mockResolvedValueOnce([{ id: 3 }])\n const root = await service.browseGroups(undefined, GROUP_TYPE.USER)\n expect(root.parentGroup).toBeUndefined()\n expect(root.members).toEqual([{ id: 3 }])\n\n adminQueriesMock.groupFromName.mockResolvedValueOnce(null)\n await expectHttp(service.browseGroups('unknown'))\n })\n\n it('getGroup OK / NOT_FOUND', async () => {\n adminQueriesMock.groupFromId.mockResolvedValueOnce({ id: 9 })\n expect(await service.getGroup(9)).toEqual({ id: 9 })\n adminQueriesMock.groupFromId.mockResolvedValueOnce(null)\n await expectHttp(service.getGroup(999))\n })\n\n it('createGroup OK + validations + creation error', async () => {\n const dto: CreateOrUpdateGroupDto = { name: 'team', type: GROUP_TYPE.USER } as any\n adminQueriesMock.usersQueries.checkGroupNameExists.mockResolvedValueOnce(false)\n adminQueriesMock.createGroup.mockResolvedValueOnce(123)\n adminQueriesMock.groupFromId.mockResolvedValueOnce({ id: 123, name: 'team' })\n expect(await service.createGroup(dto)).toEqual({ id: 123, name: 'team' })\n\n await expectHttp(service.createGroup({} as any))\n\n adminQueriesMock.usersQueries.checkGroupNameExists.mockResolvedValueOnce(true)\n await expectHttp(service.createGroup(dto))\n expect(adminQueriesMock.createGroup).toHaveBeenCalledTimes(1) // only the first one OK\n\n adminQueriesMock.usersQueries.checkGroupNameExists.mockResolvedValueOnce(false)\n adminQueriesMock.createGroup.mockRejectedValueOnce(new Error('db err'))\n await expectHttp(service.createGroup(dto))\n })\n\n it('updateGroup success / failure', async () => {\n adminQueriesMock.usersQueries.checkGroupNameExists.mockResolvedValueOnce(false)\n adminQueriesMock.updateGroup.mockResolvedValueOnce(true)\n adminQueriesMock.groupFromId.mockResolvedValueOnce({ id: 5, name: 'new' })\n expect(await service.updateGroup(5, { name: 'new' } as any)).toEqual({ id: 5, name: 'new' })\n\n adminQueriesMock.updateGroup.mockResolvedValueOnce(false)\n await expectHttp(service.updateGroup(5, {} as any))\n })\n\n it('deleteGroup success / fail', async () => {\n adminQueriesMock.deleteGroup.mockResolvedValueOnce(true)\n await expect(service.deleteGroup(5)).resolves.toBeUndefined()\n adminQueriesMock.deleteGroup.mockResolvedValueOnce(false)\n await expectHttp(service.deleteGroup(6))\n })\n\n it('addUsersToGroup: NOT_FOUND + error', async () => {\n adminQueriesMock.groupFromId.mockResolvedValueOnce(null)\n await expectHttp(service.addUsersToGroup(1, [2, 3]))\n\n adminQueriesMock.groupFromId.mockResolvedValueOnce({ id: 1, type: GROUP_TYPE.USER })\n adminQueriesMock.addUsersToGroup.mockRejectedValueOnce(new Error('bad users'))\n await expectHttp(service.addUsersToGroup(1, [2]))\n })\n\n it('updateUserFromGroup / removeUserFromGroup BAD_REQUEST errors', async () => {\n adminQueriesMock.updateUserFromGroup.mockRejectedValueOnce(new Error('bad role'))\n await expectHttp(service.updateUserFromGroup(1, 2, { role: USER_GROUP_ROLE.MEMBER } as UpdateUserFromGroupDto))\n\n adminQueriesMock.removeUserFromGroup.mockRejectedValueOnce(new Error('not member'))\n await expectHttp(service.removeUserFromGroup(1, 2))\n })\n })\n\n describe('searchMembers', () => {\n it('forwards to usersQueries.searchUsersOrGroups', async () => {\n const dto = { search: 'jo' } as SearchMembersDto\n adminQueriesMock.usersQueries.searchUsersOrGroups.mockResolvedValueOnce([{ id: 1 }])\n expect(await service.searchMembers(dto)).toEqual([{ id: 1 }])\n expect(adminQueriesMock.usersQueries.searchUsersOrGroups).toHaveBeenCalledWith(dto)\n })\n })\n\n describe('impersonation', () => {\n const res: any = {}\n it('self / bad password / ok + logout (guard + non-admin + admin)', async () => {\n const admin = new UserModel({ id: 5 } as any, true)\n await expectHttp(service.impersonateUser(admin, 5, { password: 'x' } as UserPasswordDto, res))\n\n adminQueriesMock.usersQueries.compareUserPassword.mockResolvedValueOnce(false)\n await expectHttp(service.impersonateUser(admin, 6, { password: 'bad' } as any, res))\n\n const admin2 = new UserModel({ id: 5, clientId: 'c1' } as any, true)\n adminQueriesMock.usersQueries.compareUserPassword.mockResolvedValueOnce(true)\n adminQueriesMock.usersQueries.from.mockResolvedValueOnce({ id: 6, login: 'user' } as any)\n authManagerMock.setCookies.mockResolvedValueOnce({ accessToken: 't' })\n expect(await service.impersonateUser(admin2, 6, { password: 'ok' } as any, res)).toEqual({ accessToken: 't' })\n\n const notImpersonated = new UserModel({ id: 1 } as any, true)\n await expectHttp(service.logoutImpersonateUser(notImpersonated, res))\n\n const impersonated = new UserModel({ id: 2, impersonatedFromId: 9, impersonatedClientId: 'X' } as any, true)\n adminQueriesMock.usersQueries.from.mockResolvedValueOnce({ id: 9, role: USER_ROLE.USER } as any)\n await expectHttp(service.logoutImpersonateUser(impersonated, res))\n\n adminQueriesMock.usersQueries.from.mockResolvedValueOnce({ id: 9, role: USER_ROLE.ADMINISTRATOR } as any)\n authManagerMock.setCookies.mockResolvedValueOnce({ accessToken: 'admin' })\n expect(await service.logoutImpersonateUser(impersonated, res)).toEqual({ accessToken: 'admin' })\n })\n })\n\n describe('listing', () => {\n it('forwards listUsers and listGuests', async () => {\n const users = [{ id: 1 }]\n adminQueriesMock.listUsers.mockResolvedValueOnce(users as any)\n expect(await service.listUsers()).toEqual(users)\n expect(adminQueriesMock.listUsers).toHaveBeenCalledWith()\n\n const guests = [{ id: 2 }]\n adminQueriesMock.usersQueries.listGuests.mockResolvedValueOnce(guests as any)\n expect(await service.listGuests()).toEqual(guests)\n expect(adminQueriesMock.usersQueries.listGuests).toHaveBeenCalledWith(null, null, true)\n })\n })\n\n describe('createGuest', () => {\n it('adds the creator as default manager and returns admin guest', async () => {\n const creator = new UserModel({ id: 88 } as any, true)\n const dto: CreateUserDto = { login: 'gg', email: 'g@x', password: 'pwd', managers: [] } as any\n adminQueriesMock.usersQueries.checkUserExists.mockResolvedValueOnce(false)\n adminQueriesMock.usersQueries.createUserOrGuest.mockResolvedValueOnce(505)\n spyMakePaths()\n const expectedGuest = { id: 505, login: 'gg', role: USER_ROLE.GUEST }\n setGuest(expectedGuest as any)\n\n expect(await service.createGuest(creator, dto)).toEqual(expectedGuest)\n expect(adminQueriesMock.usersQueries.createUserOrGuest).toHaveBeenCalledWith(\n expect.objectContaining({ login: 'gg', email: 'g@x', managers: [88] }),\n USER_ROLE.GUEST\n )\n })\n })\n\n describe('updateGuest wrapper', () => {\n it('updateGuest() -> success', async () => {\n const guest = { id: 33, login: 'g', email: 'g@x', managers: [{ id: 2 }], role: USER_ROLE.GUEST }\n const updatedGuest = { ...guest, email: 'new@x' }\n setGuest(guest as any)\n adminQueriesMock.usersQueries.updateUserOrGuest.mockResolvedValueOnce(true)\n setGuest(updatedGuest as any)\n expect(await service.updateGuest(guest.id, { email: 'new@x' } as any)).toEqual(updatedGuest)\n })\n })\n\n describe('deleteUserSpace', () => {\n it('space not existing / removeFiles failure', async () => {\n fs.isPathExists.mockResolvedValueOnce(false)\n await expect(service.deleteUserSpace('nobody')).resolves.toBeUndefined()\n\n fs.isPathExists.mockResolvedValueOnce(true)\n fs.removeFiles.mockRejectedValueOnce(new Error('fs error'))\n await expectHttp(service.deleteUserSpace('bob'))\n })\n })\n\n describe('renameUserSpace error handling', () => {\n it('moveFiles throws then restore', async () => {\n const current = { ...baseUser }\n setUser(current)\n adminQueriesMock.usersQueries.checkUserExists.mockResolvedValueOnce(false)\n fs.isPathExists.mockResolvedValueOnce(true)\n fs.isPathExists.mockResolvedValueOnce(false)\n fs.moveFiles.mockRejectedValueOnce(new Error('io error'))\n fs.moveFiles.mockResolvedValueOnce(undefined)\n await expectHttp(service.updateUserOrGuest(current.id, { login: 'new-login' } as any))\n expect(fs.moveFiles).toHaveBeenCalledTimes(2)\n })\n\n it('current space missing -> early return', async () => {\n const current = { ...baseUser }\n setUser(current)\n adminQueriesMock.usersQueries.checkUserExists.mockResolvedValueOnce(false)\n fs.isPathExists.mockResolvedValueOnce(false)\n await expectHttp(service.updateUserOrGuest(current.id, { login: 'new-login' } as any))\n expect(fs.moveFiles).not.toHaveBeenCalled()\n })\n })\n})\n"],"names":["jest","mock","isPathExists","fn","moveFiles","removeFiles","actual","requireActual","hashPassword","pwd","anonymizePassword","dto","password","fs","requireMock","expectHttp","p","expect","rejects","toBeInstanceOf","HttpException","spyMakePaths","spyOn","UserModel","prototype","mockResolvedValueOnce","undefined","describe","AdminUsersManager","name","service","authManagerMock","adminQueriesMock","setUser","u","listUsers","setGuest","g","usersQueries","listGuests","baseUser","id","login","email","isActive","role","USER_ROLE","USER","groups","beforeAll","setCookies","from","createUserOrGuest","updateUserOrGuest","deleteUser","compareUserPassword","checkGroupNameExists","checkUserExists","searchUsersOrGroups","updateUserGroups","updateGuestManagers","groupFromName","browseGroupMembers","browseRootGroupMembers","groupFromId","createGroup","updateGroup","deleteGroup","addUsersToGroup","updateUserFromGroup","removeUserFromGroup","module","Test","createTestingModule","providers","provide","AuthManager","useValue","AdminUsersQueries","compile","useLogger","get","beforeEach","clearAllMocks","it","toBeDefined","getUser","toEqual","toHaveBeenCalledWith","guest","managers","GUEST","getGuest","each","asAdmin","exp","res","toBe","objectContaining","mockRejectedValueOnce","Error","current","updated","passwordAttempts","add","delete","not","toHaveBeenCalled","mockResolvedValue","language","updatedGuest","updateGuest","toThrow","deleteUserOrGuest","deleteSpace","isGuest","resolves","toBeUndefined","deleteGuest","admin","deleteUserFromAdmin","adminPassword","type","GROUP_TYPE","withName","browseGroups","parentGroup","members","toHaveLength","root","getGroup","toHaveBeenCalledTimes","USER_GROUP_ROLE","MEMBER","search","searchMembers","impersonateUser","admin2","clientId","accessToken","notImpersonated","logoutImpersonateUser","impersonated","impersonatedFromId","impersonatedClientId","ADMINISTRATOR","users","guests","creator","expectedGuest","createGuest","deleteUserSpace"],"mappings":"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"}
|
|
@@ -314,7 +314,7 @@ let UsersManager = class UsersManager {
|
|
|
314
314
|
}
|
|
315
315
|
async leavePersonalGroup(user, groupId) {
|
|
316
316
|
const currentGroup = await this.usersQueries.getGroupWithMembers(user.id, groupId, true);
|
|
317
|
-
if (!currentGroup || currentGroup.type === _member.MEMBER_TYPE.GROUP
|
|
317
|
+
if (!currentGroup || currentGroup.type === _member.MEMBER_TYPE.GROUP) {
|
|
318
318
|
throw new _common.HttpException('You are not allowed to do this action', _common.HttpStatus.FORBIDDEN);
|
|
319
319
|
}
|
|
320
320
|
const userWhoLeaves = currentGroup.members.find((m)=>m.id === user.id);
|
|
@@ -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 || !currentGroup.members.find((m) => m.id === user.id)) {\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 { 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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"}
|