@sync-in/server 1.7.0 → 1.8.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 +164 -58
- package/environment/environment.dist.yaml +6 -3
- package/migrations/0003_giant_luckman.sql +6 -0
- package/migrations/meta/0003_snapshot.json +2463 -0
- package/migrations/meta/_journal.json +7 -0
- package/package.json +16 -15
- package/server/app.bootstrap.js +1 -0
- package/server/app.bootstrap.js.map +1 -1
- package/server/app.constants.js +0 -4
- package/server/app.constants.js.map +1 -1
- package/server/app.service.js +7 -6
- package/server/app.service.js.map +1 -1
- package/server/applications/files/constants/only-office.js +12 -0
- package/server/applications/files/constants/only-office.js.map +1 -1
- package/server/applications/files/files.config.js +5 -0
- package/server/applications/files/files.config.js.map +1 -1
- package/server/applications/files/services/files-content-manager.service.js +6 -6
- package/server/applications/files/services/files-content-manager.service.js.map +1 -1
- package/server/applications/files/services/files-manager.service.js +4 -4
- package/server/applications/files/services/files-manager.service.js.map +1 -1
- package/server/applications/files/services/files-methods.service.js +5 -3
- package/server/applications/files/services/files-methods.service.js.map +1 -1
- package/server/applications/files/services/files-only-office-manager.service.js +2 -2
- package/server/applications/files/services/files-only-office-manager.service.js.map +1 -1
- package/server/applications/files/services/files-parser.service.js +6 -3
- package/server/applications/files/services/files-parser.service.js.map +1 -1
- package/server/applications/files/services/files-scheduler.service.js +51 -3
- package/server/applications/files/services/files-scheduler.service.js.map +1 -1
- package/server/applications/files/services/files-search-manager.service.js +4 -0
- package/server/applications/files/services/files-search-manager.service.js.map +1 -1
- package/server/applications/files/utils/doc-textify/adapters/pdf.js +10 -1
- package/server/applications/files/utils/doc-textify/adapters/pdf.js.map +1 -1
- package/server/applications/notifications/i18n/de.js +56 -0
- package/server/applications/notifications/i18n/de.js.map +1 -0
- package/server/applications/notifications/i18n/es.js +52 -0
- package/server/applications/notifications/i18n/es.js.map +1 -0
- package/server/applications/notifications/i18n/hi.js +52 -0
- package/server/applications/notifications/i18n/hi.js.map +1 -0
- package/server/applications/notifications/i18n/index.js +73 -8
- package/server/applications/notifications/i18n/index.js.map +1 -1
- package/server/applications/notifications/i18n/it.js +52 -0
- package/server/applications/notifications/i18n/it.js.map +1 -0
- package/server/applications/notifications/i18n/ja.js +52 -0
- package/server/applications/notifications/i18n/ja.js.map +1 -0
- package/server/applications/notifications/i18n/ko.js +52 -0
- package/server/applications/notifications/i18n/ko.js.map +1 -0
- package/server/applications/notifications/i18n/pl.js +52 -0
- package/server/applications/notifications/i18n/pl.js.map +1 -0
- package/server/applications/notifications/i18n/pt.js +52 -0
- package/server/applications/notifications/i18n/pt.js.map +1 -0
- package/server/applications/notifications/i18n/pt_br.js +52 -0
- package/server/applications/notifications/i18n/pt_br.js.map +1 -0
- package/server/applications/notifications/i18n/ru.js +52 -0
- package/server/applications/notifications/i18n/ru.js.map +1 -0
- package/server/applications/notifications/i18n/tr.js +52 -0
- package/server/applications/notifications/i18n/tr.js.map +1 -0
- package/server/applications/notifications/i18n/zh.js +52 -0
- package/server/applications/notifications/i18n/zh.js.map +1 -0
- package/server/applications/notifications/mails/models.js +6 -7
- package/server/applications/notifications/mails/models.js.map +1 -1
- package/server/applications/notifications/services/notifications-manager.service.js.map +1 -1
- package/server/applications/shares/dto/create-or-update-share.dto.js +11 -0
- package/server/applications/shares/dto/create-or-update-share.dto.js.map +1 -1
- package/server/applications/shares/interfaces/share-props.interface.js.map +1 -1
- package/server/applications/shares/schemas/share.interface.js.map +1 -1
- package/server/applications/shares/schemas/shares.schema.js +9 -0
- package/server/applications/shares/schemas/shares.schema.js.map +1 -1
- package/server/applications/shares/services/shares-manager.service.js +46 -17
- package/server/applications/shares/services/shares-manager.service.js.map +1 -1
- package/server/applications/shares/services/shares-queries.service.js +24 -5
- package/server/applications/shares/services/shares-queries.service.js.map +1 -1
- package/server/applications/spaces/constants/cache.js +4 -0
- package/server/applications/spaces/constants/cache.js.map +1 -1
- package/server/applications/spaces/dto/create-or-update-space.dto.js +5 -0
- package/server/applications/spaces/dto/create-or-update-space.dto.js.map +1 -1
- package/server/applications/spaces/guards/space.guard.js +3 -3
- package/server/applications/spaces/guards/space.guard.js.map +1 -1
- package/server/applications/spaces/models/space-props.model.js.map +1 -1
- package/server/applications/spaces/models/space.model.js.map +1 -1
- package/server/applications/spaces/schemas/space.interface.js.map +1 -1
- package/server/applications/spaces/schemas/spaces.schema.js +1 -0
- package/server/applications/spaces/schemas/spaces.schema.js.map +1 -1
- package/server/applications/spaces/services/spaces-browser.service.js.map +1 -1
- package/server/applications/spaces/services/spaces-manager.service.js +34 -31
- package/server/applications/spaces/services/spaces-manager.service.js.map +1 -1
- package/server/applications/spaces/services/spaces-queries.service.js +23 -7
- package/server/applications/spaces/services/spaces-queries.service.js.map +1 -1
- package/server/applications/spaces/services/spaces-scheduler.service.js +21 -20
- package/server/applications/spaces/services/spaces-scheduler.service.js.map +1 -1
- package/server/applications/spaces/spaces.controller.js +4 -2
- package/server/applications/spaces/spaces.controller.js.map +1 -1
- package/server/applications/spaces/utils/paths.js +14 -16
- package/server/applications/spaces/utils/paths.js.map +1 -1
- package/server/applications/sync/services/sync-manager.service.js +4 -3
- package/server/applications/sync/services/sync-manager.service.js.map +1 -1
- package/server/applications/sync/services/sync-paths-manager.service.js +1 -1
- package/server/applications/sync/services/sync-paths-manager.service.js.map +1 -1
- package/server/applications/sync/services/sync-paths-manager.service.spec.js +1 -1
- package/server/applications/sync/services/sync-paths-manager.service.spec.js.map +1 -1
- package/server/applications/sync/sync.controller.js +2 -1
- package/server/applications/sync/sync.controller.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 +0 -16
- package/server/applications/users/constants/user.js.map +1 -1
- package/server/applications/users/dto/user-properties.dto.js +10 -0
- package/server/applications/users/dto/user-properties.dto.js.map +1 -1
- 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 +3 -2
- package/server/applications/users/schemas/users.schema.js.map +1 -1
- package/server/applications/users/services/admin-users-manager.service.js +1 -0
- package/server/applications/users/services/admin-users-manager.service.js.map +1 -1
- package/server/applications/users/services/admin-users-manager.service.spec.js +2 -1
- package/server/applications/users/services/admin-users-manager.service.spec.js.map +1 -1
- package/server/applications/users/services/users-manager.service.js +8 -2
- package/server/applications/users/services/users-manager.service.js.map +1 -1
- package/server/applications/users/services/users-manager.service.spec.js +1 -0
- package/server/applications/users/services/users-manager.service.spec.js.map +1 -1
- package/server/applications/users/services/users-queries.service.js +18 -4
- package/server/applications/users/services/users-queries.service.js.map +1 -1
- package/server/applications/users/users.controller.js +15 -0
- package/server/applications/users/users.controller.js.map +1 -1
- package/server/applications/users/utils/test.js +2 -2
- package/server/applications/users/utils/test.js.map +1 -1
- package/server/applications/webdav/constants/routes.js +2 -2
- package/server/applications/webdav/constants/routes.js.map +1 -1
- package/server/applications/webdav/constants/webdav.js +2 -2
- package/server/applications/webdav/constants/webdav.js.map +1 -1
- package/server/applications/webdav/filters/webdav.filter.js +2 -2
- package/server/applications/webdav/filters/webdav.filter.js.map +1 -1
- package/server/applications/webdav/filters/webdav.filter.spec.js +2 -2
- package/server/applications/webdav/filters/webdav.filter.spec.js.map +1 -1
- package/server/applications/webdav/services/webdav-methods.service.js +3 -2
- package/server/applications/webdav/services/webdav-methods.service.js.map +1 -1
- package/server/applications/webdav/utils/webdav.js +1 -2
- package/server/applications/webdav/utils/webdav.js.map +1 -1
- package/server/authentication/auth.config.js +2 -2
- package/server/authentication/auth.config.js.map +1 -1
- package/server/authentication/guards/auth-basic.strategy.js +2 -2
- package/server/authentication/guards/auth-basic.strategy.js.map +1 -1
- package/server/common/i18n.js +52 -0
- package/server/common/i18n.js.map +1 -0
- package/server/common/image.js +49 -33
- package/server/common/image.js.map +1 -1
- package/server/common/interfaces.js.map +1 -1
- package/server/common/shared.js +5 -2
- package/server/common/shared.js.map +1 -1
- package/server/configuration/config.validation.js +3 -3
- package/server/configuration/config.validation.js.map +1 -1
- package/server/infrastructure/cache/adapters/mysql-cache.adapter.js +8 -6
- package/server/infrastructure/cache/adapters/mysql-cache.adapter.js.map +1 -1
- package/server/infrastructure/cache/adapters/redis-cache.adapter.js +22 -17
- package/server/infrastructure/cache/adapters/redis-cache.adapter.js.map +1 -1
- package/server/infrastructure/cache/cache.e2e-spec.js +1 -0
- package/server/infrastructure/cache/cache.e2e-spec.js.map +1 -1
- package/server/infrastructure/cache/cache.module.js +1 -14
- package/server/infrastructure/cache/cache.module.js.map +1 -1
- package/server/infrastructure/cache/services/cache.service.js.map +1 -1
- package/server/infrastructure/database/database.module.js +20 -1
- package/server/infrastructure/database/database.module.js.map +1 -1
- package/server/infrastructure/database/utils.js +48 -0
- package/server/infrastructure/database/utils.js.map +1 -1
- package/server/infrastructure/scheduler/scheduler.module.js +1 -1
- package/server/infrastructure/scheduler/scheduler.module.js.map +1 -1
- package/server/infrastructure/websocket/adapters/cluster.adapter.js +1 -3
- package/server/infrastructure/websocket/adapters/cluster.adapter.js.map +1 -1
- package/static/3rdpartylicenses.txt +137 -137
- package/static/chunk-2KLC4T2Z.js +1 -0
- package/static/chunk-373XVRXW.js +1 -0
- package/static/chunk-3GMLWAFZ.js +1 -0
- package/static/chunk-3XVM35O2.js +1 -0
- package/static/chunk-3YVRP3VM.js +2 -0
- package/static/chunk-5NMSIIQB.js +1 -0
- package/static/chunk-AF24EYXU.js +1 -0
- package/static/chunk-AKQVEHO6.js +2 -0
- package/static/{chunk-PTGDOWV3.js → chunk-AY2SZ3G6.js} +1 -1
- package/static/chunk-BCVX464U.js +2 -0
- package/static/{chunk-IPAC4VAF.js → chunk-BIKLW4YS.js} +1 -1
- package/static/chunk-C36MW4ME.js +562 -0
- package/static/chunk-CHJ64RJM.js +1 -0
- package/static/chunk-DKSEQTMX.js +1 -0
- package/static/chunk-DM4NXKEP.js +1 -0
- package/static/chunk-DPUVSXRB.js +1 -0
- package/static/chunk-DSWEWLXJ.js +1 -0
- package/static/chunk-FJE6BOFL.js +1 -0
- package/static/chunk-FZ3JPGYZ.js +1 -0
- package/static/chunk-GUGNR5TF.js +3 -0
- package/static/chunk-H6NE33VX.js +1 -0
- package/static/{chunk-DJYJ66UF.js → chunk-HAS5ZOTR.js} +1 -1
- package/static/chunk-HNQRZALS.js +1 -0
- package/static/chunk-JPT5WEAT.js +1 -0
- package/static/{chunk-QNJFQVYI.js → chunk-JSWCNGXJ.js} +1 -1
- package/static/chunk-KFJIQIGR.js +1 -0
- package/static/chunk-LNTUR3GU.js +1 -0
- package/static/chunk-LVM4QB22.js +1 -0
- package/static/chunk-M3XVNQZQ.js +1 -0
- package/static/{chunk-EVIE5F2U.js → chunk-MFLIJH6T.js} +1 -1
- package/static/{chunk-IQOALFYU.js → chunk-MSUHTBB2.js} +1 -1
- package/static/chunk-N3U6637P.js +1 -0
- package/static/chunk-NNV4OXSB.js +1 -0
- package/static/chunk-NO2LTNW3.js +1 -0
- package/static/chunk-OOGP4WSH.js +2 -0
- package/static/chunk-PB4AIT7O.js +1 -0
- package/static/chunk-PCWDQPOM.js +2 -0
- package/static/chunk-PGZZP5W3.js +1 -0
- package/static/chunk-PVDHBQRM.js +1 -0
- package/static/chunk-Q5KM7LTX.js +1 -0
- package/static/chunk-QHC6ZPQ4.js +1 -0
- package/static/chunk-QO6BTONN.js +1 -0
- package/static/chunk-QZU2S5CV.js +1 -0
- package/static/chunk-SBZ572Q4.js +2 -0
- package/static/chunk-SHIVUDP3.js +1 -0
- package/static/chunk-SLHTEGRU.js +1 -0
- package/static/{chunk-SH5EVL4E.js → chunk-SSFF27P2.js} +1 -1
- package/static/chunk-TPYBFZS5.js +1 -0
- package/static/chunk-UEQCWMXD.js +1 -0
- package/static/chunk-UG5DMXYO.js +1 -0
- package/static/chunk-UJPPR4MX.js +1 -0
- package/static/chunk-UNCPXHHT.js +1 -0
- package/static/chunk-URHTCJ7G.js +1 -0
- package/static/chunk-V3AT2BKP.js +1 -0
- package/static/chunk-VKK5BSLX.js +1 -0
- package/static/{chunk-SIPE37PA.js → chunk-VM4YX6Q7.js} +1 -1
- package/static/chunk-WJW7CT6G.js +27 -0
- package/static/{chunk-7ITZXYYJ.js → chunk-WLMNXRBS.js} +1 -1
- package/static/chunk-X5XGK6T7.js +4 -0
- package/static/chunk-YEKR5OPO.js +1 -0
- package/static/chunk-YW57T2PF.js +1 -0
- package/static/chunk-Z5J5F5SX.js +1 -0
- package/static/chunk-ZIJQRARU.js +1 -0
- package/static/chunk-ZPF2DSQV.js +1 -0
- package/static/chunk-ZTCRGJ6Y.js +7 -0
- package/static/index.html +2 -2
- package/static/main-VOL6OMJ5.js +9 -0
- package/static/scripts-WRDOQIU5.js +24 -0
- package/static/{styles-A5VYX3CE.css → styles-2C2UNCNB.css} +1 -1
- package/server/applications/spaces/interfaces/space-quota.interface.js +0 -10
- package/server/applications/spaces/interfaces/space-quota.interface.js.map +0 -1
- package/static/chunk-22EANI6R.js +0 -1
- package/static/chunk-3GFGJYMK.js +0 -1
- package/static/chunk-4YGJGZZZ.js +0 -1
- package/static/chunk-5K7HEX3C.js +0 -27
- package/static/chunk-5KLMS6A4.js +0 -1
- package/static/chunk-ATP3BFHV.js +0 -562
- package/static/chunk-BB4G55KE.js +0 -1
- package/static/chunk-EWKSX76T.js +0 -1
- package/static/chunk-FHLACA7V.js +0 -1
- package/static/chunk-GCATNU55.js +0 -1
- package/static/chunk-GYODPCIE.js +0 -1
- package/static/chunk-HZTFYLM5.js +0 -1
- package/static/chunk-JSUKJT6Z.js +0 -1
- package/static/chunk-JXZCNFW7.js +0 -1
- package/static/chunk-LTGFCQR7.js +0 -1
- package/static/chunk-LV3PYKWO.js +0 -1
- package/static/chunk-N2WFNW6M.js +0 -7
- package/static/chunk-ORMRCEGT.js +0 -1
- package/static/chunk-OUTBJSMW.js +0 -1
- package/static/chunk-RS2PX32L.js +0 -1
- package/static/chunk-RSSWH3S2.js +0 -1
- package/static/chunk-RTRJ3KFH.js +0 -1
- package/static/chunk-TKTCBDOG.js +0 -1
- package/static/chunk-V6K2N46L.js +0 -1
- package/static/chunk-XLCCZSQL.js +0 -4
- package/static/chunk-YPEH66GG.js +0 -1
- package/static/chunk-YPOIUQ57.js +0 -1
- package/static/chunk-ZKCFO2OA.js +0 -4
- package/static/main-MZ7HWZXO.js +0 -9
- package/static/scripts-VZVAP2P4.js +0 -30
|
@@ -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 { 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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"}
|
|
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 { WriteStream } from 'fs'\nimport { createWriteStream } from 'node:fs'\nimport path from 'node:path'\nimport { Readable } from 'node:stream'\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 {\n UserAppPasswordDto,\n UserLanguageDto,\n UserNotificationDto,\n UserStorageIndexingDto,\n UserUpdatePasswordDto\n} 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 preference', HttpStatus.INTERNAL_SERVER_ERROR)\n }\n }\n\n async updateStorageIndexing(user: UserModel, userStorageIndexingDto: UserStorageIndexingDto) {\n if (!(await this.usersQueries.updateUserOrGuest(user.id, userStorageIndexingDto))) {\n throw new HttpException('Unable to update full-text search preference', 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 = Readable.from(await 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","updateStorageIndexing","userStorageIndexingDto","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","Readable","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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"}
|
|
@@ -223,6 +223,7 @@ describe(_usersmanagerservice.UsersManager.name, ()=>{
|
|
|
223
223
|
expect(m1).toBe(_image.pngMimeType);
|
|
224
224
|
usersQueriesService.checkUserExists = jest.fn().mockReturnValue(undefined);
|
|
225
225
|
usersQueriesService.createUserOrGuest = jest.fn().mockReturnValue(888);
|
|
226
|
+
usersQueriesService.clearWhiteListCaches = jest.fn();
|
|
226
227
|
const created = await adminUsersManager.createUserOrGuest(userTest, _user.USER_ROLE.USER);
|
|
227
228
|
expect(created).toBeInstanceOf(_usermodel.UserModel);
|
|
228
229
|
expect(await (0, _files.isPathExists)(created.filesPath)).toBe(true);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../backend/src/applications/users/services/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 bcrypt from 'bcryptjs'\nimport path from 'node:path'\nimport { Readable } from 'node:stream'\nimport { AuthManager } from '../../../authentication/services/auth-manager.service'\nimport { comparePassword } from '../../../common/functions'\nimport * as imageModule from '../../../common/image'\nimport { pngMimeType, svgMimeType } from '../../../common/image'\nimport { Cache } from '../../../infrastructure/cache/services/cache.service'\nimport { DB_TOKEN_PROVIDER } from '../../../infrastructure/database/constants'\nimport * as filesUtilsModule from '../../files/utils/files'\nimport { fileName, isPathExists } from '../../files/utils/files'\nimport { NotificationsManager } from '../../notifications/services/notifications-manager.service'\nimport { MEMBER_TYPE } from '../constants/member'\nimport { USER_GROUP_ROLE, USER_MAX_PASSWORD_ATTEMPTS, USER_ROLE } from '../constants/user'\nimport { CreateUserDto } from '../dto/create-or-update-user.dto'\nimport { DeleteUserDto } from '../dto/delete-user.dto'\nimport { UserModel } from '../models/user.model'\nimport { generateUserTest } from '../utils/test'\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\njest.mock('../../../common/functions', () => {\n const actual = jest.requireActual('../../../common/functions')\n return { ...actual, comparePassword: jest.fn() }\n})\njest.mock('bcryptjs', () => ({ __esModule: true, default: { hash: jest.fn(() => Promise.resolve('hashed-password')) } }))\njest.mock('../../../common/image', () => {\n const actual = jest.requireActual('../../../common/image')\n return {\n ...actual,\n generateAvatar: jest.fn(() => Readable.from([Buffer.from('PNGDATA')]))\n }\n})\n\ndescribe(UsersManager.name, () => {\n let usersManager: UsersManager\n let adminUsersManager: AdminUsersManager\n let adminUsersQueries: AdminUsersQueries\n let usersQueriesService: UsersQueries\n let userTest: UserModel\n let deleteUserDto: DeleteUserDto\n const flush = () => new Promise<void>((r) => setImmediate(r))\n const okStream = (d = 'OK') => {\n const s: any = Readable.from([Buffer.from(d)])\n s.truncated = false\n return s\n }\n const errStream = (msg = 'err', truncated = false) => {\n const s: any = new Readable({\n read() {\n this.destroy(new Error(msg))\n }\n })\n s.truncated = truncated\n return s\n }\n const mkReq = (mimetype: string, stream: any, user = userTest) => ({ user, file: jest.fn().mockResolvedValue({ mimetype, file: stream }) })\n const ensurePaths = async () => {\n if (!(await isPathExists(userTest.homePath))) {\n await userTest.makePaths()\n }\n }\n\n const notificationsManager = {\n sendEmailNotification: jest.fn().mockResolvedValue(undefined)\n }\n\n beforeAll(async () => {\n const module: TestingModule = await Test.createTestingModule({\n providers: [\n AdminUsersManager,\n AdminUsersQueries,\n UsersManager,\n UsersQueries,\n { provide: NotificationsManager, useValue: notificationsManager },\n { provide: AuthManager, useValue: {} },\n { provide: DB_TOKEN_PROVIDER, useValue: {} },\n { provide: Cache, useValue: {} }\n ]\n }).compile()\n module.useLogger(['fatal'])\n usersManager = module.get(UsersManager)\n adminUsersManager = module.get(AdminUsersManager)\n adminUsersQueries = module.get(AdminUsersQueries)\n usersQueriesService = module.get(UsersQueries)\n userTest = new UserModel(generateUserTest(), false)\n deleteUserDto = { deleteSpace: true, isGuest: false } satisfies DeleteUserDto\n })\n\n afterEach(() => jest.restoreAllMocks())\n\n afterAll(async () => {\n await expect(adminUsersManager.deleteUserSpace(userTest.login)).resolves.not.toThrow()\n })\n\n it('instances + findUser/me/fromUserId + impersonation', async () => {\n expect(usersManager && adminUsersManager && usersQueriesService && userTest).toBeDefined()\n usersQueriesService.from = jest.fn().mockReturnValue(userTest)\n const u1: any = await usersManager.findUser(userTest.login, true)\n expect(u1).toBeInstanceOf(UserModel)\n expect(u1.password).toBeUndefined()\n const u2 = await usersManager.findUser(userTest.login, false)\n expect(u2).toBeInstanceOf(UserModel)\n expect(u2.password).toBeDefined()\n const me1: any = await usersManager.me(userTest)\n expect(me1.user.password).toBeUndefined()\n usersQueriesService.from = jest.fn().mockReturnValue(null)\n await expect(usersManager.findUser('unknown')).resolves.toBeNull()\n await expect(usersManager.me({ id: 0 } as UserModel)).rejects.toThrow()\n usersQueriesService.from = jest.fn().mockResolvedValue(null)\n await expect(usersManager.fromUserId(123)).resolves.toBeNull()\n const authUser = new UserModel({ ...generateUserTest(), id: 42, clientId: 'CID', impersonatedFromId: 1 } as any, true)\n const fromUser = new UserModel({ ...generateUserTest(), id: 42 }, true)\n usersQueriesService.from = jest.fn().mockResolvedValue(fromUser)\n const me2 = await usersManager.me(authUser)\n expect(me2.user.impersonated).toBe(true)\n expect(me2.user.clientId).toBe('CID')\n })\n\n it('paths + avatars (default/generate) + create/delete user', async () => {\n await expect(ensurePaths()).resolves.not.toThrow()\n expect(await isPathExists(userTest.filesPath)).toBe(true)\n usersQueriesService.from = jest.fn().mockReturnValueOnce(userTest)\n const [p0, m0] = await usersManager.getAvatar(userTest.login)\n expect(fileName(p0)).toBe('avatar.svg')\n expect(m0).toBe(svgMimeType)\n usersQueriesService.from = jest.fn().mockReturnValueOnce(null)\n await expect(usersManager.getAvatar('#', true)).rejects.toThrow('does not exist')\n usersQueriesService.from = jest.fn().mockReturnValue(userTest)\n expect(await usersManager.getAvatar(userTest.login, true)).toBeUndefined()\n const [p1, m1] = await usersManager.getAvatar(userTest.login)\n expect(fileName(p1)).toBe('avatar.png')\n expect(m1).toBe(pngMimeType)\n\n usersQueriesService.checkUserExists = jest.fn().mockReturnValue(undefined)\n usersQueriesService.createUserOrGuest = jest.fn().mockReturnValue(888)\n const created = await adminUsersManager.createUserOrGuest(userTest satisfies CreateUserDto, USER_ROLE.USER)\n expect(created).toBeInstanceOf(UserModel)\n expect(await isPathExists(created.filesPath)).toBe(true)\n\n usersQueriesService.checkUserExists = jest\n .fn()\n .mockReturnValueOnce({ login: userTest.login, email: '' })\n .mockReturnValueOnce({ login: '', email: userTest.email })\n .mockReturnValueOnce(undefined)\n await expect(adminUsersManager.createUserOrGuest(userTest satisfies CreateUserDto, USER_ROLE.USER)).rejects.toThrow()\n await expect(adminUsersManager.createUserOrGuest(userTest satisfies CreateUserDto, USER_ROLE.USER)).rejects.toThrow()\n usersQueriesService.createUserOrGuest = jest.fn().mockImplementation(() => {\n throw new Error('testing')\n })\n await expect(adminUsersManager.createUserOrGuest(userTest satisfies CreateUserDto, USER_ROLE.USER)).rejects.toThrow()\n\n adminUsersQueries.deleteUser = jest.fn().mockReturnValue(true)\n await expect(adminUsersManager.deleteUserOrGuest(userTest.id, userTest.login, deleteUserDto)).resolves.not.toThrow()\n expect(await isPathExists(userTest.filesPath)).toBe(false)\n adminUsersQueries.deleteUser = jest.fn().mockReturnValue(false)\n await expect(adminUsersManager.deleteUserOrGuest(userTest.id, userTest.login, deleteUserDto)).resolves.not.toThrow()\n adminUsersQueries.deleteUser = jest.fn().mockImplementation(() => {\n throw new Error('testing')\n })\n await expect(adminUsersManager.deleteUserOrGuest(userTest.id, userTest.login, deleteUserDto)).rejects.toThrow()\n })\n\n it('logUser branches: forbidden/locked/bad/good', async () => {\n const linkUser = new UserModel({ ...generateUserTest(), role: USER_ROLE.LINK }, false)\n await expect(usersManager.logUser(linkUser, 'x', '127.0.0.1')).rejects.toThrow('Account is not allowed')\n\n const uLocked = new UserModel({ ...generateUserTest(), isActive: false, passwordAttempts: 5 }, false)\n const errSpy = jest.spyOn((usersManager as any)['logger'], 'error').mockImplementation(() => undefined as any)\n const updSpy1 = jest.spyOn(usersManager, 'updateAccesses').mockRejectedValue(new Error('reject-locked'))\n await expect(usersManager.logUser(uLocked, 'pwd', 'ip')).rejects.toThrow('Account locked')\n await flush()\n expect(errSpy).toHaveBeenCalledWith(expect.stringContaining('reject-locked'))\n expect(updSpy1).toHaveBeenCalledWith(uLocked, 'ip', false)\n ;(comparePassword as jest.Mock).mockResolvedValue(false)\n const uBad = new UserModel({ ...generateUserTest(), isActive: true, passwordAttempts: 0 }, false)\n const errSpy2 = jest.spyOn((usersManager as any)['logger'], 'error').mockImplementation(() => undefined as any)\n const updSpy2 = jest.spyOn(usersManager, 'updateAccesses').mockRejectedValue(new Error('reject-auth'))\n const out = await usersManager.logUser(uBad, 'bad', '1.1.1.1')\n expect(out).toBeNull()\n await flush()\n expect(errSpy2).toHaveBeenCalledWith(expect.stringContaining('reject-auth'))\n expect(updSpy2).toHaveBeenCalledWith(uBad, '1.1.1.1', false)\n ;(comparePassword as jest.Mock).mockResolvedValue(true)\n const uGood = new UserModel({ ...generateUserTest(), isActive: true, passwordAttempts: 0 }, false)\n const updSpy3 = jest.spyOn(usersManager, 'updateAccesses').mockResolvedValue(undefined)\n const pathsSpy = jest.spyOn(uGood, 'makePaths').mockResolvedValue(undefined)\n const out2 = await usersManager.logUser(uGood, 'good', '8.8.8.8')\n expect(out2).toBe(uGood)\n expect(updSpy3).toHaveBeenCalledWith(uGood, '8.8.8.8', true)\n expect(pathsSpy).toHaveBeenCalled()\n })\n\n it('compareUserPassword + updateLanguage + updatePassword branches', async () => {\n usersQueriesService.compareUserPassword = jest.fn().mockResolvedValue(true)\n await expect(usersManager.compareUserPassword(1, 'p')).resolves.toBe(true)\n expect(usersQueriesService.compareUserPassword).toHaveBeenCalledWith(1, 'p')\n\n usersQueriesService.updateUserOrGuest = jest.fn().mockResolvedValue(false)\n await expect(usersManager.updateLanguage(userTest, { language: '' })).rejects.toThrow('Unable to update language')\n expect(usersQueriesService.updateUserOrGuest).toHaveBeenCalledWith(userTest.id, { language: null })\n usersQueriesService.updateUserOrGuest = jest.fn().mockResolvedValue(true)\n await expect(usersManager.updateLanguage(userTest, { language: 'fr' })).resolves.toBeUndefined()\n\n usersQueriesService.selectUserProperties = jest.fn().mockResolvedValue(null)\n await expect(usersManager.updatePassword(userTest, { oldPassword: 'a', newPassword: 'b' })).rejects.toThrow('Unable to check password')\n usersQueriesService.selectUserProperties = jest.fn().mockResolvedValue({ password: 'HASH' })\n ;(comparePassword as jest.Mock).mockResolvedValue(false)\n await expect(usersManager.updatePassword(userTest, { oldPassword: 'a', newPassword: 'b' })).rejects.toThrow('Password mismatch')\n ;(comparePassword as jest.Mock).mockResolvedValue(true)\n ;(bcrypt.hash as unknown as jest.Mock).mockResolvedValue('HASHED')\n usersQueriesService.updateUserOrGuest = jest.fn().mockResolvedValue(true)\n await expect(usersManager.updatePassword(userTest, { oldPassword: 'a', newPassword: 'b' })).resolves.toBeUndefined()\n expect(usersQueriesService.updateUserOrGuest).toHaveBeenCalledWith(userTest.id, { password: 'HASHED' })\n usersQueriesService.updateUserOrGuest = jest.fn().mockResolvedValue(false)\n usersQueriesService.selectUserProperties = jest.fn().mockResolvedValue({ password: 'HASH' })\n ;(comparePassword as jest.Mock).mockResolvedValue(true)\n ;(bcrypt.hash as unknown as jest.Mock).mockResolvedValue('HASHED2')\n await expect(usersManager.updatePassword(userTest, { oldPassword: 'a', newPassword: 'b' })).rejects.toThrow('Unable to update password')\n })\n\n it('updateNotification + updateAccesses branches', async () => {\n usersQueriesService.updateUserOrGuest = jest.fn().mockResolvedValue(false)\n await expect(usersManager.updateNotification(userTest, { notification: 1 })).rejects.toThrow('Unable to update notification')\n usersQueriesService.updateUserOrGuest = jest.fn().mockResolvedValue(true)\n await expect(usersManager.updateNotification(userTest, { notification: 2 })).resolves.toBeUndefined()\n\n const prevAccess1 = new Date('2021-01-01T00:00:00Z')\n const u1 = new UserModel(\n { ...generateUserTest(), isActive: true, passwordAttempts: 3, currentIp: '1.2.3.4', currentAccess: prevAccess1 } as any,\n false\n )\n usersQueriesService.updateUserOrGuest = jest.fn().mockResolvedValue(true)\n await expect(usersManager.updateAccesses(u1, '5.6.7.8', true)).resolves.toBeUndefined()\n const payload1 = (usersQueriesService.updateUserOrGuest as jest.Mock).mock.calls[0][1]\n expect(payload1).toMatchObject({ lastIp: '1.2.3.4', currentIp: '5.6.7.8', passwordAttempts: 0, isActive: true })\n expect(payload1.lastAccess).toBe(prevAccess1)\n expect(payload1.currentAccess).toBeInstanceOf(Date)\n\n const prevAccess2 = new Date('2022-02-02T00:00:00Z')\n const u2 = new UserModel(\n {\n ...generateUserTest(),\n isActive: true,\n passwordAttempts: USER_MAX_PASSWORD_ATTEMPTS - 1,\n currentIp: 'old.ip',\n currentAccess: prevAccess2\n } as any,\n false\n )\n usersQueriesService.updateUserOrGuest = jest.fn().mockResolvedValue(true)\n await expect(usersManager.updateAccesses(u2, 'new.ip', false)).resolves.toBeUndefined()\n const payload2 = (usersQueriesService.updateUserOrGuest as jest.Mock).mock.calls[0][1]\n expect(payload2.passwordAttempts).toBe(USER_MAX_PASSWORD_ATTEMPTS)\n expect(payload2.isActive).toBe(false)\n expect(payload2.lastAccess).toBe(prevAccess2)\n expect(payload2.lastIp).toBe('old.ip')\n expect(payload2.currentIp).toBe('new.ip')\n expect(payload2.currentAccess).toBeInstanceOf(Date)\n })\n\n it('avatars advanced: generateIsNotExists, failure branches, base64 fallback', async () => {\n await ensurePaths()\n usersManager.findUser = jest.fn().mockResolvedValue({ getInitials: () => 'UT' } as unknown as UserModel)\n const [p, m] = (await usersManager.getAvatar(userTest.login, false, true)) as [string, string]\n expect(fileName(p)).toBe('avatar.png')\n expect(m).toBe(pngMimeType)\n jest.spyOn(imageModule, 'generateAvatar').mockImplementation(() => errStream('gen error'))\n await expect(usersManager.getAvatar(userTest.login, true)).rejects.toThrow('Unable to create avatar')\n usersManager.findUser = jest.fn().mockResolvedValue(null)\n await expect(usersManager.getAvatar(userTest.login, true)).rejects.toThrow('avatar not found')\n })\n\n it('updateAvatar branches: mime error, stream error, truncated, move fail, success', async () => {\n await ensurePaths()\n await expect(usersManager.updateAvatar(mkReq('text/plain', okStream('X')) as any)).rejects.toThrow('Unsupported file type')\n await expect(usersManager.updateAvatar(mkReq('image/png', errStream('stream error')) as any)).rejects.toThrow('Unable to upload avatar')\n\n const t = okStream('OK')\n t.truncated = true\n const mvSpy = jest.spyOn(filesUtilsModule, 'moveFiles').mockResolvedValue(undefined)\n await expect(usersManager.updateAvatar(mkReq('image/png', t) as any)).rejects.toThrow('Image is too large (5MB max)')\n expect(mvSpy).not.toHaveBeenCalled()\n\n jest.spyOn(filesUtilsModule, 'moveFiles').mockRejectedValue(new Error('mv fail'))\n await expect(usersManager.updateAvatar(mkReq('image/png', okStream()) as any)).rejects.toThrow('Unable to create avatar')\n\n const mvSpy2 = jest.spyOn(filesUtilsModule, 'moveFiles').mockResolvedValue(undefined)\n await expect(usersManager.updateAvatar(mkReq('image/png', okStream()) as any)).resolves.toBeUndefined()\n const expectedSrc = path.join(userTest.tmpPath, 'avatar.png')\n const expectedDst = path.join(userTest.homePath, 'avatar.png')\n expect(mvSpy2).toHaveBeenCalledWith(expectedSrc, expectedDst, true)\n })\n\n it('setOnlineStatus + browseGroups + getGroup', async () => {\n usersQueriesService.setOnlineStatus = jest.fn().mockRejectedValue(new Error('boom'))\n expect(() => usersManager.setOnlineStatus({ id: 1 } as any, 1 as any)).not.toThrow()\n\n usersQueriesService.browseRootGroups = jest.fn().mockResolvedValue([{ id: 1 }])\n const root = await usersManager.browseGroups(userTest, '')\n expect(root.parentGroup).toBeUndefined()\n expect(root.members.length).toBe(1)\n usersQueriesService.groupFromName = jest.fn().mockResolvedValue(null)\n await expect(usersManager.browseGroups(userTest, 'unknown')).rejects.toThrow('Group not found')\n const group = { id: 42, name: 'Team' }\n usersQueriesService.groupFromName = jest.fn().mockResolvedValue(group)\n usersQueriesService.browseGroupMembers = jest.fn().mockResolvedValue([{ id: 7 }, { id: 8 }])\n const g2 = await usersManager.browseGroups(userTest, 'Team')\n expect(g2.parentGroup).toEqual(group)\n expect(g2.members).toEqual([{ id: 7 }, { id: 8 }])\n expect(usersQueriesService.browseGroupMembers).toHaveBeenCalledWith(42)\n\n usersQueriesService.getGroupWithMembers = jest.fn().mockResolvedValue({ id: 1, members: [] })\n await expect(usersManager.getGroup(userTest, 1)).resolves.toEqual({ id: 1, members: [] })\n usersQueriesService.getGroup = jest.fn().mockResolvedValue({ id: 2 })\n await expect(usersManager.getGroup(userTest, 2, false)).resolves.toEqual({ id: 2 })\n usersQueriesService.getGroup = jest.fn().mockResolvedValue(null)\n await expect(usersManager.getGroup(userTest, 3, false)).rejects.toThrow('You are not allowed to do this action')\n })\n\n it('create/update personal group', async () => {\n await expect(usersManager.createPersonalGroup(userTest, { name: '' } as any)).rejects.toThrow('Group name is missing')\n usersQueriesService.checkGroupNameExists = jest.fn().mockResolvedValue(true)\n await expect(usersManager.createPersonalGroup(userTest, { name: 'A' })).rejects.toThrow('Name already used')\n usersQueriesService.checkGroupNameExists = jest.fn().mockResolvedValue(false)\n usersQueriesService.createPersonalGroup = jest.fn().mockResolvedValue(10)\n usersQueriesService.clearWhiteListCaches = jest.fn()\n usersManager.getGroup = jest.fn().mockResolvedValue({ id: 10 })\n const logSpy = jest.spyOn((usersManager as any)['logger'], 'log').mockImplementation(() => undefined as any)\n await expect(usersManager.createPersonalGroup(userTest, { name: 'OK' })).resolves.toEqual({ id: 10 })\n expect(logSpy).toHaveBeenCalled()\n usersQueriesService.createPersonalGroup = jest.fn().mockRejectedValue(new Error('db down'))\n await expect(usersManager.createPersonalGroup(userTest, { name: 'OK' })).rejects.toThrow('Unable to create group')\n\n await expect(usersManager.updatePersonalGroup(userTest, 1, {} as any)).rejects.toThrow('No changes to update')\n usersManager.getGroup = jest.fn().mockResolvedValueOnce({ id: 1, type: MEMBER_TYPE.GROUP })\n await expect(usersManager.updatePersonalGroup(userTest, 1, { name: 'x' })).rejects.toThrow('You are not allowed to do this action')\n usersManager.getGroup = jest.fn().mockResolvedValue({ id: 1, type: MEMBER_TYPE.PGROUP })\n usersQueriesService.checkGroupNameExists = jest.fn().mockResolvedValue(true)\n await expect(usersManager.updatePersonalGroup(userTest, 1, { name: 'dup' })).rejects.toThrow('Name already used')\n usersQueriesService.checkGroupNameExists = jest.fn().mockResolvedValue(false)\n usersQueriesService.updateGroup = jest.fn().mockRejectedValue(new Error('oops'))\n await expect(usersManager.updatePersonalGroup(userTest, 1, { name: 'ok' })).rejects.toThrow('oops')\n usersQueriesService.updateGroup = jest.fn().mockResolvedValue(true)\n usersManager.getGroup = jest.fn().mockResolvedValue({ id: 1, type: MEMBER_TYPE.PGROUP })\n await expect(usersManager.updatePersonalGroup(userTest, 1, { name: 'ok' })).resolves.not.toThrow()\n expect(usersManager.getGroup).toHaveBeenCalledWith(userTest, 1, false, userTest.isAdmin)\n })\n\n it('addUsersToGroup (GROUP/PGROUP)', async () => {\n usersManager.getGroup = jest.fn().mockResolvedValue({ id: 1, type: MEMBER_TYPE.GROUP, members: [{ id: 2 }, { id: 3 }] })\n usersQueriesService.usersWhitelist = jest.fn().mockResolvedValue([3, 4, 5])\n await expect(usersManager.addUsersToGroup(userTest, 1, [2, 3])).rejects.toThrow('No users to add to group')\n usersQueriesService.updateGroupMembers = jest.fn().mockResolvedValue(undefined)\n await expect(usersManager.addUsersToGroup(userTest, 1, [3, 4, 5])).resolves.toBeUndefined()\n expect(usersQueriesService.updateGroupMembers).toHaveBeenCalledWith(1, {\n add: [\n { id: 4, groupRole: USER_GROUP_ROLE.MEMBER },\n { id: 5, groupRole: USER_GROUP_ROLE.MEMBER }\n ]\n })\n expect(usersQueriesService.usersWhitelist).toHaveBeenCalledWith(userTest.id, USER_ROLE.USER)\n\n usersManager.getGroup = jest.fn().mockResolvedValue({ id: 2, type: MEMBER_TYPE.PGROUP, members: [] })\n usersQueriesService.usersWhitelist = jest.fn().mockResolvedValue([10, 11])\n usersQueriesService.updateGroupMembers = jest.fn().mockResolvedValue(undefined)\n await expect(usersManager.addUsersToGroup(userTest, 2, [10, 11])).resolves.toBeUndefined()\n expect(usersQueriesService.usersWhitelist).toHaveBeenCalledWith(userTest.id, undefined)\n expect(usersQueriesService.updateGroupMembers).toHaveBeenCalledWith(2, {\n add: [\n { id: 10, groupRole: USER_GROUP_ROLE.MEMBER },\n { id: 11, groupRole: USER_GROUP_ROLE.MEMBER }\n ]\n })\n })\n\n it('updateUserFromPersonalGroup', async () => {\n usersManager.getGroup = jest.fn().mockResolvedValue({ id: 1, type: MEMBER_TYPE.GROUP, members: [] })\n await expect(usersManager.updateUserFromPersonalGroup(userTest, 1, 9, { role: 1 })).rejects.toThrow('You are not allowed to do this action')\n usersManager.getGroup = jest.fn().mockResolvedValue({ id: 1, type: MEMBER_TYPE.PGROUP, members: [] })\n await expect(usersManager.updateUserFromPersonalGroup(userTest, 1, 9, { role: 1 })).rejects.toThrow('User was not found')\n usersManager.getGroup = jest.fn().mockResolvedValue({\n id: 1,\n type: MEMBER_TYPE.PGROUP,\n members: [\n { id: 9, groupRole: USER_GROUP_ROLE.MANAGER },\n { id: 10, groupRole: USER_GROUP_ROLE.MEMBER }\n ]\n })\n await expect(usersManager.updateUserFromPersonalGroup(userTest, 1, 9, { role: USER_GROUP_ROLE.MEMBER })).rejects.toThrow(\n /group must have at least one manager/i\n )\n const spy = jest.spyOn(adminUsersManager, 'updateUserFromGroup').mockResolvedValue(undefined)\n usersManager.getGroup = jest.fn().mockResolvedValue({\n id: 1,\n type: MEMBER_TYPE.PGROUP,\n members: [\n { id: 9, groupRole: USER_GROUP_ROLE.MEMBER },\n { id: 10, groupRole: USER_GROUP_ROLE.MEMBER },\n { id: 11, groupRole: USER_GROUP_ROLE.MEMBER }\n ]\n })\n await expect(usersManager.updateUserFromPersonalGroup(userTest, 1, 9, { role: USER_GROUP_ROLE.MANAGER })).resolves.toBeUndefined()\n expect(spy).toHaveBeenCalledWith(1, 9, { role: 1 })\n usersManager.getGroup = jest.fn().mockResolvedValue({ id: 1, type: MEMBER_TYPE.PGROUP, members: [{ id: 9, groupRole: USER_GROUP_ROLE.MEMBER }] })\n await expect(usersManager.updateUserFromPersonalGroup(userTest, 1, 9, { role: USER_GROUP_ROLE.MEMBER })).resolves.toBeUndefined()\n ;(spy as jest.Mock).mockClear()\n usersManager.getGroup = jest.fn().mockResolvedValue({\n id: 1,\n type: MEMBER_TYPE.PGROUP,\n members: [\n { id: 9, groupRole: USER_GROUP_ROLE.MANAGER },\n { id: 10, groupRole: USER_GROUP_ROLE.MANAGER }\n ]\n })\n await expect(usersManager.updateUserFromPersonalGroup(userTest, 1, 9, { role: USER_GROUP_ROLE.MEMBER })).resolves.toBeUndefined()\n expect(spy).toHaveBeenCalledWith(1, 9, { role: USER_GROUP_ROLE.MEMBER })\n ;(spy as jest.Mock).mockClear()\n usersManager.getGroup = jest.fn().mockResolvedValue({\n id: 1,\n type: MEMBER_TYPE.PGROUP,\n members: [\n { id: 9, groupRole: USER_GROUP_ROLE.MANAGER },\n { id: 10, groupRole: USER_GROUP_ROLE.MANAGER }\n ]\n })\n await expect(usersManager.updateUserFromPersonalGroup(userTest, 1, 9, { role: USER_GROUP_ROLE.MANAGER })).resolves.toBeUndefined()\n expect(spy).not.toHaveBeenCalled()\n })\n\n it('removeUserFromGroup', async () => {\n usersManager.getGroup = jest.fn().mockResolvedValue({ id: 1, members: [] })\n await expect(usersManager.removeUserFromGroup(userTest, 1, 9)).rejects.toThrow('User was not found')\n usersManager.getGroup = jest.fn().mockResolvedValue({ id: 1, type: MEMBER_TYPE.GROUP, members: [{ id: 9, groupRole: USER_GROUP_ROLE.MANAGER }] })\n await expect(usersManager.removeUserFromGroup(userTest, 1, 9)).rejects.toThrow('You are not allowed to do this action')\n usersManager.getGroup = jest.fn().mockResolvedValue({ id: 1, type: MEMBER_TYPE.PGROUP, members: [{ id: 9, groupRole: USER_GROUP_ROLE.MANAGER }] })\n await expect(usersManager.removeUserFromGroup(userTest, 1, 9)).rejects.toThrow('Group must have at least one manager')\n usersQueriesService.updateGroupMembers = jest.fn().mockResolvedValue(undefined)\n usersManager.getGroup = jest.fn().mockResolvedValue({\n id: 1,\n type: MEMBER_TYPE.PGROUP,\n members: [\n { id: 9, groupRole: USER_GROUP_ROLE.MEMBER },\n { id: 10, groupRole: USER_GROUP_ROLE.MANAGER }\n ]\n })\n await expect(usersManager.removeUserFromGroup(userTest, 1, 9)).resolves.toBeUndefined()\n expect(usersQueriesService.updateGroupMembers).toHaveBeenCalledWith(1, { remove: [9] })\n usersQueriesService.updateGroupMembers = jest.fn().mockResolvedValue(undefined)\n usersManager.getGroup = jest.fn().mockResolvedValue({\n id: 1,\n type: MEMBER_TYPE.PGROUP,\n members: [\n { id: 9, groupRole: USER_GROUP_ROLE.MANAGER },\n { id: 10, groupRole: USER_GROUP_ROLE.MANAGER }\n ]\n })\n await expect(usersManager.removeUserFromGroup(userTest, 1, 9)).resolves.toBeUndefined()\n expect(usersQueriesService.updateGroupMembers).toHaveBeenCalledWith(1, { remove: [9] })\n })\n\n it('leave/delete personal group', async () => {\n usersQueriesService.getGroupWithMembers = jest.fn().mockResolvedValue(null)\n await expect(usersManager.leavePersonalGroup(userTest, 1)).rejects.toThrow('You are not allowed to do this action')\n usersQueriesService.getGroupWithMembers = jest.fn().mockResolvedValue({ id: 1, type: MEMBER_TYPE.GROUP, members: [{ id: userTest.id }] })\n await expect(usersManager.leavePersonalGroup(userTest, 1)).rejects.toThrow('You are not allowed to do this action')\n usersQueriesService.getGroupWithMembers = jest.fn().mockResolvedValue({ id: 1, type: MEMBER_TYPE.PGROUP, members: [] })\n await expect(usersManager.leavePersonalGroup(userTest, 1)).rejects.toThrow('User was not found')\n usersQueriesService.getGroupWithMembers = jest.fn().mockResolvedValue({\n id: 1,\n type: MEMBER_TYPE.PGROUP,\n members: [{ id: userTest.id, groupRole: USER_GROUP_ROLE.MANAGER }]\n })\n await expect(usersManager.leavePersonalGroup(userTest, 1)).rejects.toThrow('Group must have at least one manager')\n usersQueriesService.getGroupWithMembers = jest.fn().mockResolvedValue({\n id: 1,\n type: 2,\n members: [\n { id: userTest.id, groupRole: USER_GROUP_ROLE.MEMBER },\n { id: 9, groupRole: USER_GROUP_ROLE.MANAGER }\n ]\n })\n const lSpy = jest.spyOn((usersManager as any)['logger'], 'log').mockImplementation(() => undefined as any)\n usersQueriesService.updateGroupMembers = jest.fn().mockResolvedValue(undefined)\n await expect(usersManager.leavePersonalGroup(userTest, 1)).resolves.toBeUndefined()\n expect(lSpy).toHaveBeenCalledWith(expect.stringMatching(/has left group/))\n usersQueriesService.updateGroupMembers = jest.fn().mockRejectedValue(new Error('DB'))\n await expect(usersManager.leavePersonalGroup(userTest, 1)).rejects.toThrow('DB')\n usersQueriesService.getGroupWithMembers = jest.fn().mockResolvedValue({\n id: 1,\n type: MEMBER_TYPE.PGROUP,\n members: [\n { id: userTest.id, groupRole: USER_GROUP_ROLE.MANAGER },\n { id: 9, groupRole: USER_GROUP_ROLE.MANAGER }\n ]\n })\n usersQueriesService.updateGroupMembers = jest.fn().mockResolvedValue(undefined)\n await expect(usersManager.leavePersonalGroup(userTest, 1)).resolves.toBeUndefined()\n\n usersQueriesService.canDeletePersonalGroup = jest.fn().mockResolvedValue(false)\n await expect(usersManager.deletePersonalGroup(userTest, 7)).rejects.toThrow('You are not allowed to do this action')\n usersQueriesService.canDeletePersonalGroup = jest.fn().mockResolvedValue(true)\n const wSpy = jest.spyOn((usersManager as any)['logger'], 'warn').mockImplementation(() => undefined as any)\n usersQueriesService.deletePersonalGroup = jest.fn().mockResolvedValue(false)\n await expect(usersManager.deletePersonalGroup(userTest, 7)).rejects.toThrow('Unable to delete group')\n expect(wSpy).toHaveBeenCalledWith(expect.stringMatching(/does not exist/))\n const lgSpy = jest.spyOn((usersManager as any)['logger'], 'log').mockImplementation(() => undefined as any)\n usersQueriesService.deletePersonalGroup = jest.fn().mockResolvedValue(true)\n await expect(usersManager.deletePersonalGroup(userTest, 7)).resolves.toBeUndefined()\n expect(lgSpy).toHaveBeenCalledWith(expect.stringMatching(/was deleted/))\n })\n\n it('guests + proxies', async () => {\n usersQueriesService.listGuests = jest.fn().mockResolvedValue([{ id: 1 }])\n await expect(usersManager.listGuests(userTest)).resolves.toEqual([{ id: 1 }])\n const checkSpy = jest.spyOn(adminUsersManager, 'checkUser').mockImplementation(() => undefined)\n usersQueriesService.listGuests = jest.fn().mockResolvedValue({ id: 9 })\n await expect(usersManager.getGuest(userTest, 9)).resolves.toEqual({ id: 9 })\n expect(checkSpy).toHaveBeenCalled()\n\n usersQueriesService.usersWhitelist = jest.fn().mockResolvedValue([userTest.id, 100])\n usersQueriesService.clearWhiteListCaches = jest.fn()\n const createSpy = jest.spyOn(adminUsersManager, 'createUserOrGuest').mockResolvedValue({ id: 55 } as any)\n const dto1: CreateUserDto = { ...userTest, managers: [100], password: 'x' }\n const r = await usersManager.createGuest(userTest, dto1)\n expect(createSpy).toHaveBeenCalled()\n expect(usersQueriesService.clearWhiteListCaches).toHaveBeenCalledWith([userTest.id])\n expect(r).toEqual({ id: 55 })\n const args1 = (createSpy as jest.Mock).mock.calls[0][0]\n expect(args1.managers).toEqual(expect.arrayContaining([userTest.id]))\n ;(createSpy as jest.Mock).mockClear()\n const dto2: CreateUserDto = { ...userTest, managers: [userTest.id, 100], password: 'y' }\n await usersManager.createGuest(userTest, dto2)\n const args2 = (createSpy as jest.Mock).mock.calls[0][0]\n expect((args2.managers as number[]).filter((m: number) => m === userTest.id)).toHaveLength(1)\n\n await expect(usersManager.updateGuest(userTest, 9, {} as any)).rejects.toThrow('No changes to update')\n usersQueriesService.usersWhitelist = jest.fn().mockResolvedValue([1])\n await expect(usersManager.updateGuest(userTest, 9, { managers: [2] } as any)).rejects.toThrow('Guest must have at least one manager')\n usersQueriesService.isGuestManager = jest.fn().mockResolvedValue(false)\n await expect(usersManager.updateGuest(userTest, 9, { email: 'a' } as any)).rejects.toThrow('You are not allowed to do this action')\n usersQueriesService.isGuestManager = jest.fn().mockResolvedValue(true)\n jest.spyOn(adminUsersManager, 'updateUserOrGuest').mockResolvedValue({ managers: [{ id: 999 }] } as any)\n await expect(usersManager.updateGuest(userTest, 9, { email: 'a' } as any)).resolves.toBeNull()\n jest.spyOn(adminUsersManager, 'updateUserOrGuest').mockResolvedValue({ managers: [{ id: userTest.id }] } as any)\n await expect(usersManager.updateGuest(userTest, 9, { email: 'a' } as any)).resolves.toEqual({ managers: [{ id: userTest.id }] })\n usersQueriesService.usersWhitelist = jest.fn().mockResolvedValue([userTest.id, 77])\n usersQueriesService.isGuestManager = jest.fn().mockResolvedValue(true)\n jest.spyOn(adminUsersManager, 'updateUserOrGuest').mockResolvedValue({ managers: [{ id: userTest.id }, { id: 77 }] } as any)\n await expect(usersManager.updateGuest(userTest, 9, { managers: [userTest.id, 77] } as any)).resolves.toEqual({\n managers: [{ id: userTest.id }, { id: 77 }]\n })\n\n usersQueriesService.isGuestManager = jest.fn().mockResolvedValue(null)\n await expect(usersManager.deleteGuest(userTest, 9)).rejects.toThrow('You are not allowed to do this action')\n usersQueriesService.isGuestManager = jest.fn().mockResolvedValue({ id: 9, login: 'guest' })\n const delSpy = jest.spyOn(adminUsersManager, 'deleteUserOrGuest').mockResolvedValue(undefined)\n await expect(usersManager.deleteGuest(userTest, 9)).resolves.toBeUndefined()\n expect(delSpy).toHaveBeenCalledWith(9, 'guest', { deleteSpace: true, isGuest: true })\n\n usersQueriesService.searchUsersOrGroups = jest.fn().mockResolvedValue([{ id: 1 }])\n await expect(usersManager.searchMembers(userTest, { search: '' } as any)).resolves.toEqual([{ id: 1 }])\n\n usersQueriesService.getOnlineUsers = jest.fn().mockResolvedValue([{ id: 123 }])\n await expect(usersManager.getOnlineUsers([123])).resolves.toEqual([{ id: 123 }])\n expect(usersQueriesService.getOnlineUsers).toHaveBeenCalledWith([123])\n usersQueriesService.usersWhitelist = jest.fn().mockResolvedValue([10, 11])\n await expect(usersManager.usersWhitelist(userTest.id)).resolves.toEqual([10, 11])\n expect(usersQueriesService.usersWhitelist).toHaveBeenCalledWith(userTest.id)\n })\n})\n"],"names":["jest","mock","actual","requireActual","comparePassword","fn","__esModule","default","hash","Promise","resolve","generateAvatar","Readable","from","Buffer","describe","UsersManager","name","usersManager","adminUsersManager","adminUsersQueries","usersQueriesService","userTest","deleteUserDto","flush","r","setImmediate","okStream","d","s","truncated","errStream","msg","read","destroy","Error","mkReq","mimetype","stream","user","file","mockResolvedValue","ensurePaths","isPathExists","homePath","makePaths","notificationsManager","sendEmailNotification","undefined","beforeAll","module","Test","createTestingModule","providers","AdminUsersManager","AdminUsersQueries","UsersQueries","provide","NotificationsManager","useValue","AuthManager","DB_TOKEN_PROVIDER","Cache","compile","useLogger","get","UserModel","generateUserTest","deleteSpace","isGuest","afterEach","restoreAllMocks","afterAll","expect","deleteUserSpace","login","resolves","not","toThrow","it","toBeDefined","mockReturnValue","u1","findUser","toBeInstanceOf","password","toBeUndefined","u2","me1","me","toBeNull","id","rejects","fromUserId","authUser","clientId","impersonatedFromId","fromUser","me2","impersonated","toBe","filesPath","mockReturnValueOnce","p0","m0","getAvatar","fileName","svgMimeType","p1","m1","pngMimeType","checkUserExists","createUserOrGuest","created","USER_ROLE","USER","email","mockImplementation","deleteUser","deleteUserOrGuest","linkUser","role","LINK","logUser","uLocked","isActive","passwordAttempts","errSpy","spyOn","updSpy1","mockRejectedValue","toHaveBeenCalledWith","stringContaining","uBad","errSpy2","updSpy2","out","uGood","updSpy3","pathsSpy","out2","toHaveBeenCalled","compareUserPassword","updateUserOrGuest","updateLanguage","language","selectUserProperties","updatePassword","oldPassword","newPassword","bcrypt","updateNotification","notification","prevAccess1","Date","currentIp","currentAccess","updateAccesses","payload1","calls","toMatchObject","lastIp","lastAccess","prevAccess2","USER_MAX_PASSWORD_ATTEMPTS","payload2","getInitials","p","m","imageModule","updateAvatar","t","mvSpy","filesUtilsModule","mvSpy2","expectedSrc","path","join","tmpPath","expectedDst","setOnlineStatus","browseRootGroups","root","browseGroups","parentGroup","members","length","groupFromName","group","browseGroupMembers","g2","toEqual","getGroupWithMembers","getGroup","createPersonalGroup","checkGroupNameExists","clearWhiteListCaches","logSpy","updatePersonalGroup","mockResolvedValueOnce","type","MEMBER_TYPE","GROUP","PGROUP","updateGroup","isAdmin","usersWhitelist","addUsersToGroup","updateGroupMembers","add","groupRole","USER_GROUP_ROLE","MEMBER","updateUserFromPersonalGroup","MANAGER","spy","mockClear","removeUserFromGroup","remove","leavePersonalGroup","lSpy","stringMatching","canDeletePersonalGroup","deletePersonalGroup","wSpy","lgSpy","listGuests","checkSpy","getGuest","createSpy","dto1","managers","createGuest","args1","arrayContaining","dto2","args2","filter","toHaveLength","updateGuest","isGuestManager","deleteGuest","delSpy","searchUsersOrGroups","searchMembers","search","getOnlineUsers"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../../backend/src/applications/users/services/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 bcrypt from 'bcryptjs'\nimport path from 'node:path'\nimport { Readable } from 'node:stream'\nimport { AuthManager } from '../../../authentication/services/auth-manager.service'\nimport { comparePassword } from '../../../common/functions'\nimport * as imageModule from '../../../common/image'\nimport { pngMimeType, svgMimeType } from '../../../common/image'\nimport { Cache } from '../../../infrastructure/cache/services/cache.service'\nimport { DB_TOKEN_PROVIDER } from '../../../infrastructure/database/constants'\nimport * as filesUtilsModule from '../../files/utils/files'\nimport { fileName, isPathExists } from '../../files/utils/files'\nimport { NotificationsManager } from '../../notifications/services/notifications-manager.service'\nimport { MEMBER_TYPE } from '../constants/member'\nimport { USER_GROUP_ROLE, USER_MAX_PASSWORD_ATTEMPTS, USER_ROLE } from '../constants/user'\nimport { CreateUserDto } from '../dto/create-or-update-user.dto'\nimport { DeleteUserDto } from '../dto/delete-user.dto'\nimport { UserModel } from '../models/user.model'\nimport { generateUserTest } from '../utils/test'\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\njest.mock('../../../common/functions', () => {\n const actual = jest.requireActual('../../../common/functions')\n return { ...actual, comparePassword: jest.fn() }\n})\njest.mock('bcryptjs', () => ({ __esModule: true, default: { hash: jest.fn(() => Promise.resolve('hashed-password')) } }))\njest.mock('../../../common/image', () => {\n const actual = jest.requireActual('../../../common/image')\n return {\n ...actual,\n generateAvatar: jest.fn(() => Readable.from([Buffer.from('PNGDATA')]))\n }\n})\n\ndescribe(UsersManager.name, () => {\n let usersManager: UsersManager\n let adminUsersManager: AdminUsersManager\n let adminUsersQueries: AdminUsersQueries\n let usersQueriesService: UsersQueries\n let userTest: UserModel\n let deleteUserDto: DeleteUserDto\n const flush = () => new Promise<void>((r) => setImmediate(r))\n const okStream = (d = 'OK') => {\n const s: any = Readable.from([Buffer.from(d)])\n s.truncated = false\n return s\n }\n const errStream = (msg = 'err', truncated = false) => {\n const s: any = new Readable({\n read() {\n this.destroy(new Error(msg))\n }\n })\n s.truncated = truncated\n return s\n }\n const mkReq = (mimetype: string, stream: any, user = userTest) => ({ user, file: jest.fn().mockResolvedValue({ mimetype, file: stream }) })\n const ensurePaths = async () => {\n if (!(await isPathExists(userTest.homePath))) {\n await userTest.makePaths()\n }\n }\n\n const notificationsManager = {\n sendEmailNotification: jest.fn().mockResolvedValue(undefined)\n }\n\n beforeAll(async () => {\n const module: TestingModule = await Test.createTestingModule({\n providers: [\n AdminUsersManager,\n AdminUsersQueries,\n UsersManager,\n UsersQueries,\n { provide: NotificationsManager, useValue: notificationsManager },\n { provide: AuthManager, useValue: {} },\n { provide: DB_TOKEN_PROVIDER, useValue: {} },\n { provide: Cache, useValue: {} }\n ]\n }).compile()\n module.useLogger(['fatal'])\n usersManager = module.get(UsersManager)\n adminUsersManager = module.get(AdminUsersManager)\n adminUsersQueries = module.get(AdminUsersQueries)\n usersQueriesService = module.get(UsersQueries)\n userTest = new UserModel(generateUserTest(), false)\n deleteUserDto = { deleteSpace: true, isGuest: false } satisfies DeleteUserDto\n })\n\n afterEach(() => jest.restoreAllMocks())\n\n afterAll(async () => {\n await expect(adminUsersManager.deleteUserSpace(userTest.login)).resolves.not.toThrow()\n })\n\n it('instances + findUser/me/fromUserId + impersonation', async () => {\n expect(usersManager && adminUsersManager && usersQueriesService && userTest).toBeDefined()\n usersQueriesService.from = jest.fn().mockReturnValue(userTest)\n const u1: any = await usersManager.findUser(userTest.login, true)\n expect(u1).toBeInstanceOf(UserModel)\n expect(u1.password).toBeUndefined()\n const u2 = await usersManager.findUser(userTest.login, false)\n expect(u2).toBeInstanceOf(UserModel)\n expect(u2.password).toBeDefined()\n const me1: any = await usersManager.me(userTest)\n expect(me1.user.password).toBeUndefined()\n usersQueriesService.from = jest.fn().mockReturnValue(null)\n await expect(usersManager.findUser('unknown')).resolves.toBeNull()\n await expect(usersManager.me({ id: 0 } as UserModel)).rejects.toThrow()\n usersQueriesService.from = jest.fn().mockResolvedValue(null)\n await expect(usersManager.fromUserId(123)).resolves.toBeNull()\n const authUser = new UserModel({ ...generateUserTest(), id: 42, clientId: 'CID', impersonatedFromId: 1 } as any, true)\n const fromUser = new UserModel({ ...generateUserTest(), id: 42 }, true)\n usersQueriesService.from = jest.fn().mockResolvedValue(fromUser)\n const me2 = await usersManager.me(authUser)\n expect(me2.user.impersonated).toBe(true)\n expect(me2.user.clientId).toBe('CID')\n })\n\n it('paths + avatars (default/generate) + create/delete user', async () => {\n await expect(ensurePaths()).resolves.not.toThrow()\n expect(await isPathExists(userTest.filesPath)).toBe(true)\n usersQueriesService.from = jest.fn().mockReturnValueOnce(userTest)\n const [p0, m0] = await usersManager.getAvatar(userTest.login)\n expect(fileName(p0)).toBe('avatar.svg')\n expect(m0).toBe(svgMimeType)\n usersQueriesService.from = jest.fn().mockReturnValueOnce(null)\n await expect(usersManager.getAvatar('#', true)).rejects.toThrow('does not exist')\n usersQueriesService.from = jest.fn().mockReturnValue(userTest)\n expect(await usersManager.getAvatar(userTest.login, true)).toBeUndefined()\n const [p1, m1] = await usersManager.getAvatar(userTest.login)\n expect(fileName(p1)).toBe('avatar.png')\n expect(m1).toBe(pngMimeType)\n\n usersQueriesService.checkUserExists = jest.fn().mockReturnValue(undefined)\n usersQueriesService.createUserOrGuest = jest.fn().mockReturnValue(888)\n usersQueriesService.clearWhiteListCaches = jest.fn()\n const created = await adminUsersManager.createUserOrGuest(userTest satisfies CreateUserDto, USER_ROLE.USER)\n expect(created).toBeInstanceOf(UserModel)\n expect(await isPathExists(created.filesPath)).toBe(true)\n\n usersQueriesService.checkUserExists = jest\n .fn()\n .mockReturnValueOnce({ login: userTest.login, email: '' })\n .mockReturnValueOnce({ login: '', email: userTest.email })\n .mockReturnValueOnce(undefined)\n await expect(adminUsersManager.createUserOrGuest(userTest satisfies CreateUserDto, USER_ROLE.USER)).rejects.toThrow()\n await expect(adminUsersManager.createUserOrGuest(userTest satisfies CreateUserDto, USER_ROLE.USER)).rejects.toThrow()\n usersQueriesService.createUserOrGuest = jest.fn().mockImplementation(() => {\n throw new Error('testing')\n })\n await expect(adminUsersManager.createUserOrGuest(userTest satisfies CreateUserDto, USER_ROLE.USER)).rejects.toThrow()\n\n adminUsersQueries.deleteUser = jest.fn().mockReturnValue(true)\n await expect(adminUsersManager.deleteUserOrGuest(userTest.id, userTest.login, deleteUserDto)).resolves.not.toThrow()\n expect(await isPathExists(userTest.filesPath)).toBe(false)\n adminUsersQueries.deleteUser = jest.fn().mockReturnValue(false)\n await expect(adminUsersManager.deleteUserOrGuest(userTest.id, userTest.login, deleteUserDto)).resolves.not.toThrow()\n adminUsersQueries.deleteUser = jest.fn().mockImplementation(() => {\n throw new Error('testing')\n })\n await expect(adminUsersManager.deleteUserOrGuest(userTest.id, userTest.login, deleteUserDto)).rejects.toThrow()\n })\n\n it('logUser branches: forbidden/locked/bad/good', async () => {\n const linkUser = new UserModel({ ...generateUserTest(), role: USER_ROLE.LINK }, false)\n await expect(usersManager.logUser(linkUser, 'x', '127.0.0.1')).rejects.toThrow('Account is not allowed')\n\n const uLocked = new UserModel({ ...generateUserTest(), isActive: false, passwordAttempts: 5 }, false)\n const errSpy = jest.spyOn((usersManager as any)['logger'], 'error').mockImplementation(() => undefined as any)\n const updSpy1 = jest.spyOn(usersManager, 'updateAccesses').mockRejectedValue(new Error('reject-locked'))\n await expect(usersManager.logUser(uLocked, 'pwd', 'ip')).rejects.toThrow('Account locked')\n await flush()\n expect(errSpy).toHaveBeenCalledWith(expect.stringContaining('reject-locked'))\n expect(updSpy1).toHaveBeenCalledWith(uLocked, 'ip', false)\n ;(comparePassword as jest.Mock).mockResolvedValue(false)\n const uBad = new UserModel({ ...generateUserTest(), isActive: true, passwordAttempts: 0 }, false)\n const errSpy2 = jest.spyOn((usersManager as any)['logger'], 'error').mockImplementation(() => undefined as any)\n const updSpy2 = jest.spyOn(usersManager, 'updateAccesses').mockRejectedValue(new Error('reject-auth'))\n const out = await usersManager.logUser(uBad, 'bad', '1.1.1.1')\n expect(out).toBeNull()\n await flush()\n expect(errSpy2).toHaveBeenCalledWith(expect.stringContaining('reject-auth'))\n expect(updSpy2).toHaveBeenCalledWith(uBad, '1.1.1.1', false)\n ;(comparePassword as jest.Mock).mockResolvedValue(true)\n const uGood = new UserModel({ ...generateUserTest(), isActive: true, passwordAttempts: 0 }, false)\n const updSpy3 = jest.spyOn(usersManager, 'updateAccesses').mockResolvedValue(undefined)\n const pathsSpy = jest.spyOn(uGood, 'makePaths').mockResolvedValue(undefined)\n const out2 = await usersManager.logUser(uGood, 'good', '8.8.8.8')\n expect(out2).toBe(uGood)\n expect(updSpy3).toHaveBeenCalledWith(uGood, '8.8.8.8', true)\n expect(pathsSpy).toHaveBeenCalled()\n })\n\n it('compareUserPassword + updateLanguage + updatePassword branches', async () => {\n usersQueriesService.compareUserPassword = jest.fn().mockResolvedValue(true)\n await expect(usersManager.compareUserPassword(1, 'p')).resolves.toBe(true)\n expect(usersQueriesService.compareUserPassword).toHaveBeenCalledWith(1, 'p')\n\n usersQueriesService.updateUserOrGuest = jest.fn().mockResolvedValue(false)\n await expect(usersManager.updateLanguage(userTest, { language: '' })).rejects.toThrow('Unable to update language')\n expect(usersQueriesService.updateUserOrGuest).toHaveBeenCalledWith(userTest.id, { language: null })\n usersQueriesService.updateUserOrGuest = jest.fn().mockResolvedValue(true)\n await expect(usersManager.updateLanguage(userTest, { language: 'fr' })).resolves.toBeUndefined()\n\n usersQueriesService.selectUserProperties = jest.fn().mockResolvedValue(null)\n await expect(usersManager.updatePassword(userTest, { oldPassword: 'a', newPassword: 'b' })).rejects.toThrow('Unable to check password')\n usersQueriesService.selectUserProperties = jest.fn().mockResolvedValue({ password: 'HASH' })\n ;(comparePassword as jest.Mock).mockResolvedValue(false)\n await expect(usersManager.updatePassword(userTest, { oldPassword: 'a', newPassword: 'b' })).rejects.toThrow('Password mismatch')\n ;(comparePassword as jest.Mock).mockResolvedValue(true)\n ;(bcrypt.hash as unknown as jest.Mock).mockResolvedValue('HASHED')\n usersQueriesService.updateUserOrGuest = jest.fn().mockResolvedValue(true)\n await expect(usersManager.updatePassword(userTest, { oldPassword: 'a', newPassword: 'b' })).resolves.toBeUndefined()\n expect(usersQueriesService.updateUserOrGuest).toHaveBeenCalledWith(userTest.id, { password: 'HASHED' })\n usersQueriesService.updateUserOrGuest = jest.fn().mockResolvedValue(false)\n usersQueriesService.selectUserProperties = jest.fn().mockResolvedValue({ password: 'HASH' })\n ;(comparePassword as jest.Mock).mockResolvedValue(true)\n ;(bcrypt.hash as unknown as jest.Mock).mockResolvedValue('HASHED2')\n await expect(usersManager.updatePassword(userTest, { oldPassword: 'a', newPassword: 'b' })).rejects.toThrow('Unable to update password')\n })\n\n it('updateNotification + updateAccesses branches', async () => {\n usersQueriesService.updateUserOrGuest = jest.fn().mockResolvedValue(false)\n await expect(usersManager.updateNotification(userTest, { notification: 1 })).rejects.toThrow('Unable to update notification')\n usersQueriesService.updateUserOrGuest = jest.fn().mockResolvedValue(true)\n await expect(usersManager.updateNotification(userTest, { notification: 2 })).resolves.toBeUndefined()\n\n const prevAccess1 = new Date('2021-01-01T00:00:00Z')\n const u1 = new UserModel(\n { ...generateUserTest(), isActive: true, passwordAttempts: 3, currentIp: '1.2.3.4', currentAccess: prevAccess1 } as any,\n false\n )\n usersQueriesService.updateUserOrGuest = jest.fn().mockResolvedValue(true)\n await expect(usersManager.updateAccesses(u1, '5.6.7.8', true)).resolves.toBeUndefined()\n const payload1 = (usersQueriesService.updateUserOrGuest as jest.Mock).mock.calls[0][1]\n expect(payload1).toMatchObject({ lastIp: '1.2.3.4', currentIp: '5.6.7.8', passwordAttempts: 0, isActive: true })\n expect(payload1.lastAccess).toBe(prevAccess1)\n expect(payload1.currentAccess).toBeInstanceOf(Date)\n\n const prevAccess2 = new Date('2022-02-02T00:00:00Z')\n const u2 = new UserModel(\n {\n ...generateUserTest(),\n isActive: true,\n passwordAttempts: USER_MAX_PASSWORD_ATTEMPTS - 1,\n currentIp: 'old.ip',\n currentAccess: prevAccess2\n } as any,\n false\n )\n usersQueriesService.updateUserOrGuest = jest.fn().mockResolvedValue(true)\n await expect(usersManager.updateAccesses(u2, 'new.ip', false)).resolves.toBeUndefined()\n const payload2 = (usersQueriesService.updateUserOrGuest as jest.Mock).mock.calls[0][1]\n expect(payload2.passwordAttempts).toBe(USER_MAX_PASSWORD_ATTEMPTS)\n expect(payload2.isActive).toBe(false)\n expect(payload2.lastAccess).toBe(prevAccess2)\n expect(payload2.lastIp).toBe('old.ip')\n expect(payload2.currentIp).toBe('new.ip')\n expect(payload2.currentAccess).toBeInstanceOf(Date)\n })\n\n it('avatars advanced: generateIsNotExists, failure branches, base64 fallback', async () => {\n await ensurePaths()\n usersManager.findUser = jest.fn().mockResolvedValue({ getInitials: () => 'UT' } as unknown as UserModel)\n const [p, m] = (await usersManager.getAvatar(userTest.login, false, true)) as [string, string]\n expect(fileName(p)).toBe('avatar.png')\n expect(m).toBe(pngMimeType)\n jest.spyOn(imageModule, 'generateAvatar').mockImplementation(() => errStream('gen error'))\n await expect(usersManager.getAvatar(userTest.login, true)).rejects.toThrow('Unable to create avatar')\n usersManager.findUser = jest.fn().mockResolvedValue(null)\n await expect(usersManager.getAvatar(userTest.login, true)).rejects.toThrow('avatar not found')\n })\n\n it('updateAvatar branches: mime error, stream error, truncated, move fail, success', async () => {\n await ensurePaths()\n await expect(usersManager.updateAvatar(mkReq('text/plain', okStream('X')) as any)).rejects.toThrow('Unsupported file type')\n await expect(usersManager.updateAvatar(mkReq('image/png', errStream('stream error')) as any)).rejects.toThrow('Unable to upload avatar')\n\n const t = okStream('OK')\n t.truncated = true\n const mvSpy = jest.spyOn(filesUtilsModule, 'moveFiles').mockResolvedValue(undefined)\n await expect(usersManager.updateAvatar(mkReq('image/png', t) as any)).rejects.toThrow('Image is too large (5MB max)')\n expect(mvSpy).not.toHaveBeenCalled()\n\n jest.spyOn(filesUtilsModule, 'moveFiles').mockRejectedValue(new Error('mv fail'))\n await expect(usersManager.updateAvatar(mkReq('image/png', okStream()) as any)).rejects.toThrow('Unable to create avatar')\n\n const mvSpy2 = jest.spyOn(filesUtilsModule, 'moveFiles').mockResolvedValue(undefined)\n await expect(usersManager.updateAvatar(mkReq('image/png', okStream()) as any)).resolves.toBeUndefined()\n const expectedSrc = path.join(userTest.tmpPath, 'avatar.png')\n const expectedDst = path.join(userTest.homePath, 'avatar.png')\n expect(mvSpy2).toHaveBeenCalledWith(expectedSrc, expectedDst, true)\n })\n\n it('setOnlineStatus + browseGroups + getGroup', async () => {\n usersQueriesService.setOnlineStatus = jest.fn().mockRejectedValue(new Error('boom'))\n expect(() => usersManager.setOnlineStatus({ id: 1 } as any, 1 as any)).not.toThrow()\n\n usersQueriesService.browseRootGroups = jest.fn().mockResolvedValue([{ id: 1 }])\n const root = await usersManager.browseGroups(userTest, '')\n expect(root.parentGroup).toBeUndefined()\n expect(root.members.length).toBe(1)\n usersQueriesService.groupFromName = jest.fn().mockResolvedValue(null)\n await expect(usersManager.browseGroups(userTest, 'unknown')).rejects.toThrow('Group not found')\n const group = { id: 42, name: 'Team' }\n usersQueriesService.groupFromName = jest.fn().mockResolvedValue(group)\n usersQueriesService.browseGroupMembers = jest.fn().mockResolvedValue([{ id: 7 }, { id: 8 }])\n const g2 = await usersManager.browseGroups(userTest, 'Team')\n expect(g2.parentGroup).toEqual(group)\n expect(g2.members).toEqual([{ id: 7 }, { id: 8 }])\n expect(usersQueriesService.browseGroupMembers).toHaveBeenCalledWith(42)\n\n usersQueriesService.getGroupWithMembers = jest.fn().mockResolvedValue({ id: 1, members: [] })\n await expect(usersManager.getGroup(userTest, 1)).resolves.toEqual({ id: 1, members: [] })\n usersQueriesService.getGroup = jest.fn().mockResolvedValue({ id: 2 })\n await expect(usersManager.getGroup(userTest, 2, false)).resolves.toEqual({ id: 2 })\n usersQueriesService.getGroup = jest.fn().mockResolvedValue(null)\n await expect(usersManager.getGroup(userTest, 3, false)).rejects.toThrow('You are not allowed to do this action')\n })\n\n it('create/update personal group', async () => {\n await expect(usersManager.createPersonalGroup(userTest, { name: '' } as any)).rejects.toThrow('Group name is missing')\n usersQueriesService.checkGroupNameExists = jest.fn().mockResolvedValue(true)\n await expect(usersManager.createPersonalGroup(userTest, { name: 'A' })).rejects.toThrow('Name already used')\n usersQueriesService.checkGroupNameExists = jest.fn().mockResolvedValue(false)\n usersQueriesService.createPersonalGroup = jest.fn().mockResolvedValue(10)\n usersQueriesService.clearWhiteListCaches = jest.fn()\n usersManager.getGroup = jest.fn().mockResolvedValue({ id: 10 })\n const logSpy = jest.spyOn((usersManager as any)['logger'], 'log').mockImplementation(() => undefined as any)\n await expect(usersManager.createPersonalGroup(userTest, { name: 'OK' })).resolves.toEqual({ id: 10 })\n expect(logSpy).toHaveBeenCalled()\n usersQueriesService.createPersonalGroup = jest.fn().mockRejectedValue(new Error('db down'))\n await expect(usersManager.createPersonalGroup(userTest, { name: 'OK' })).rejects.toThrow('Unable to create group')\n\n await expect(usersManager.updatePersonalGroup(userTest, 1, {} as any)).rejects.toThrow('No changes to update')\n usersManager.getGroup = jest.fn().mockResolvedValueOnce({ id: 1, type: MEMBER_TYPE.GROUP })\n await expect(usersManager.updatePersonalGroup(userTest, 1, { name: 'x' })).rejects.toThrow('You are not allowed to do this action')\n usersManager.getGroup = jest.fn().mockResolvedValue({ id: 1, type: MEMBER_TYPE.PGROUP })\n usersQueriesService.checkGroupNameExists = jest.fn().mockResolvedValue(true)\n await expect(usersManager.updatePersonalGroup(userTest, 1, { name: 'dup' })).rejects.toThrow('Name already used')\n usersQueriesService.checkGroupNameExists = jest.fn().mockResolvedValue(false)\n usersQueriesService.updateGroup = jest.fn().mockRejectedValue(new Error('oops'))\n await expect(usersManager.updatePersonalGroup(userTest, 1, { name: 'ok' })).rejects.toThrow('oops')\n usersQueriesService.updateGroup = jest.fn().mockResolvedValue(true)\n usersManager.getGroup = jest.fn().mockResolvedValue({ id: 1, type: MEMBER_TYPE.PGROUP })\n await expect(usersManager.updatePersonalGroup(userTest, 1, { name: 'ok' })).resolves.not.toThrow()\n expect(usersManager.getGroup).toHaveBeenCalledWith(userTest, 1, false, userTest.isAdmin)\n })\n\n it('addUsersToGroup (GROUP/PGROUP)', async () => {\n usersManager.getGroup = jest.fn().mockResolvedValue({ id: 1, type: MEMBER_TYPE.GROUP, members: [{ id: 2 }, { id: 3 }] })\n usersQueriesService.usersWhitelist = jest.fn().mockResolvedValue([3, 4, 5])\n await expect(usersManager.addUsersToGroup(userTest, 1, [2, 3])).rejects.toThrow('No users to add to group')\n usersQueriesService.updateGroupMembers = jest.fn().mockResolvedValue(undefined)\n await expect(usersManager.addUsersToGroup(userTest, 1, [3, 4, 5])).resolves.toBeUndefined()\n expect(usersQueriesService.updateGroupMembers).toHaveBeenCalledWith(1, {\n add: [\n { id: 4, groupRole: USER_GROUP_ROLE.MEMBER },\n { id: 5, groupRole: USER_GROUP_ROLE.MEMBER }\n ]\n })\n expect(usersQueriesService.usersWhitelist).toHaveBeenCalledWith(userTest.id, USER_ROLE.USER)\n\n usersManager.getGroup = jest.fn().mockResolvedValue({ id: 2, type: MEMBER_TYPE.PGROUP, members: [] })\n usersQueriesService.usersWhitelist = jest.fn().mockResolvedValue([10, 11])\n usersQueriesService.updateGroupMembers = jest.fn().mockResolvedValue(undefined)\n await expect(usersManager.addUsersToGroup(userTest, 2, [10, 11])).resolves.toBeUndefined()\n expect(usersQueriesService.usersWhitelist).toHaveBeenCalledWith(userTest.id, undefined)\n expect(usersQueriesService.updateGroupMembers).toHaveBeenCalledWith(2, {\n add: [\n { id: 10, groupRole: USER_GROUP_ROLE.MEMBER },\n { id: 11, groupRole: USER_GROUP_ROLE.MEMBER }\n ]\n })\n })\n\n it('updateUserFromPersonalGroup', async () => {\n usersManager.getGroup = jest.fn().mockResolvedValue({ id: 1, type: MEMBER_TYPE.GROUP, members: [] })\n await expect(usersManager.updateUserFromPersonalGroup(userTest, 1, 9, { role: 1 })).rejects.toThrow('You are not allowed to do this action')\n usersManager.getGroup = jest.fn().mockResolvedValue({ id: 1, type: MEMBER_TYPE.PGROUP, members: [] })\n await expect(usersManager.updateUserFromPersonalGroup(userTest, 1, 9, { role: 1 })).rejects.toThrow('User was not found')\n usersManager.getGroup = jest.fn().mockResolvedValue({\n id: 1,\n type: MEMBER_TYPE.PGROUP,\n members: [\n { id: 9, groupRole: USER_GROUP_ROLE.MANAGER },\n { id: 10, groupRole: USER_GROUP_ROLE.MEMBER }\n ]\n })\n await expect(usersManager.updateUserFromPersonalGroup(userTest, 1, 9, { role: USER_GROUP_ROLE.MEMBER })).rejects.toThrow(\n /group must have at least one manager/i\n )\n const spy = jest.spyOn(adminUsersManager, 'updateUserFromGroup').mockResolvedValue(undefined)\n usersManager.getGroup = jest.fn().mockResolvedValue({\n id: 1,\n type: MEMBER_TYPE.PGROUP,\n members: [\n { id: 9, groupRole: USER_GROUP_ROLE.MEMBER },\n { id: 10, groupRole: USER_GROUP_ROLE.MEMBER },\n { id: 11, groupRole: USER_GROUP_ROLE.MEMBER }\n ]\n })\n await expect(usersManager.updateUserFromPersonalGroup(userTest, 1, 9, { role: USER_GROUP_ROLE.MANAGER })).resolves.toBeUndefined()\n expect(spy).toHaveBeenCalledWith(1, 9, { role: 1 })\n usersManager.getGroup = jest.fn().mockResolvedValue({ id: 1, type: MEMBER_TYPE.PGROUP, members: [{ id: 9, groupRole: USER_GROUP_ROLE.MEMBER }] })\n await expect(usersManager.updateUserFromPersonalGroup(userTest, 1, 9, { role: USER_GROUP_ROLE.MEMBER })).resolves.toBeUndefined()\n ;(spy as jest.Mock).mockClear()\n usersManager.getGroup = jest.fn().mockResolvedValue({\n id: 1,\n type: MEMBER_TYPE.PGROUP,\n members: [\n { id: 9, groupRole: USER_GROUP_ROLE.MANAGER },\n { id: 10, groupRole: USER_GROUP_ROLE.MANAGER }\n ]\n })\n await expect(usersManager.updateUserFromPersonalGroup(userTest, 1, 9, { role: USER_GROUP_ROLE.MEMBER })).resolves.toBeUndefined()\n expect(spy).toHaveBeenCalledWith(1, 9, { role: USER_GROUP_ROLE.MEMBER })\n ;(spy as jest.Mock).mockClear()\n usersManager.getGroup = jest.fn().mockResolvedValue({\n id: 1,\n type: MEMBER_TYPE.PGROUP,\n members: [\n { id: 9, groupRole: USER_GROUP_ROLE.MANAGER },\n { id: 10, groupRole: USER_GROUP_ROLE.MANAGER }\n ]\n })\n await expect(usersManager.updateUserFromPersonalGroup(userTest, 1, 9, { role: USER_GROUP_ROLE.MANAGER })).resolves.toBeUndefined()\n expect(spy).not.toHaveBeenCalled()\n })\n\n it('removeUserFromGroup', async () => {\n usersManager.getGroup = jest.fn().mockResolvedValue({ id: 1, members: [] })\n await expect(usersManager.removeUserFromGroup(userTest, 1, 9)).rejects.toThrow('User was not found')\n usersManager.getGroup = jest.fn().mockResolvedValue({ id: 1, type: MEMBER_TYPE.GROUP, members: [{ id: 9, groupRole: USER_GROUP_ROLE.MANAGER }] })\n await expect(usersManager.removeUserFromGroup(userTest, 1, 9)).rejects.toThrow('You are not allowed to do this action')\n usersManager.getGroup = jest.fn().mockResolvedValue({ id: 1, type: MEMBER_TYPE.PGROUP, members: [{ id: 9, groupRole: USER_GROUP_ROLE.MANAGER }] })\n await expect(usersManager.removeUserFromGroup(userTest, 1, 9)).rejects.toThrow('Group must have at least one manager')\n usersQueriesService.updateGroupMembers = jest.fn().mockResolvedValue(undefined)\n usersManager.getGroup = jest.fn().mockResolvedValue({\n id: 1,\n type: MEMBER_TYPE.PGROUP,\n members: [\n { id: 9, groupRole: USER_GROUP_ROLE.MEMBER },\n { id: 10, groupRole: USER_GROUP_ROLE.MANAGER }\n ]\n })\n await expect(usersManager.removeUserFromGroup(userTest, 1, 9)).resolves.toBeUndefined()\n expect(usersQueriesService.updateGroupMembers).toHaveBeenCalledWith(1, { remove: [9] })\n usersQueriesService.updateGroupMembers = jest.fn().mockResolvedValue(undefined)\n usersManager.getGroup = jest.fn().mockResolvedValue({\n id: 1,\n type: MEMBER_TYPE.PGROUP,\n members: [\n { id: 9, groupRole: USER_GROUP_ROLE.MANAGER },\n { id: 10, groupRole: USER_GROUP_ROLE.MANAGER }\n ]\n })\n await expect(usersManager.removeUserFromGroup(userTest, 1, 9)).resolves.toBeUndefined()\n expect(usersQueriesService.updateGroupMembers).toHaveBeenCalledWith(1, { remove: [9] })\n })\n\n it('leave/delete personal group', async () => {\n usersQueriesService.getGroupWithMembers = jest.fn().mockResolvedValue(null)\n await expect(usersManager.leavePersonalGroup(userTest, 1)).rejects.toThrow('You are not allowed to do this action')\n usersQueriesService.getGroupWithMembers = jest.fn().mockResolvedValue({ id: 1, type: MEMBER_TYPE.GROUP, members: [{ id: userTest.id }] })\n await expect(usersManager.leavePersonalGroup(userTest, 1)).rejects.toThrow('You are not allowed to do this action')\n usersQueriesService.getGroupWithMembers = jest.fn().mockResolvedValue({ id: 1, type: MEMBER_TYPE.PGROUP, members: [] })\n await expect(usersManager.leavePersonalGroup(userTest, 1)).rejects.toThrow('User was not found')\n usersQueriesService.getGroupWithMembers = jest.fn().mockResolvedValue({\n id: 1,\n type: MEMBER_TYPE.PGROUP,\n members: [{ id: userTest.id, groupRole: USER_GROUP_ROLE.MANAGER }]\n })\n await expect(usersManager.leavePersonalGroup(userTest, 1)).rejects.toThrow('Group must have at least one manager')\n usersQueriesService.getGroupWithMembers = jest.fn().mockResolvedValue({\n id: 1,\n type: 2,\n members: [\n { id: userTest.id, groupRole: USER_GROUP_ROLE.MEMBER },\n { id: 9, groupRole: USER_GROUP_ROLE.MANAGER }\n ]\n })\n const lSpy = jest.spyOn((usersManager as any)['logger'], 'log').mockImplementation(() => undefined as any)\n usersQueriesService.updateGroupMembers = jest.fn().mockResolvedValue(undefined)\n await expect(usersManager.leavePersonalGroup(userTest, 1)).resolves.toBeUndefined()\n expect(lSpy).toHaveBeenCalledWith(expect.stringMatching(/has left group/))\n usersQueriesService.updateGroupMembers = jest.fn().mockRejectedValue(new Error('DB'))\n await expect(usersManager.leavePersonalGroup(userTest, 1)).rejects.toThrow('DB')\n usersQueriesService.getGroupWithMembers = jest.fn().mockResolvedValue({\n id: 1,\n type: MEMBER_TYPE.PGROUP,\n members: [\n { id: userTest.id, groupRole: USER_GROUP_ROLE.MANAGER },\n { id: 9, groupRole: USER_GROUP_ROLE.MANAGER }\n ]\n })\n usersQueriesService.updateGroupMembers = jest.fn().mockResolvedValue(undefined)\n await expect(usersManager.leavePersonalGroup(userTest, 1)).resolves.toBeUndefined()\n\n usersQueriesService.canDeletePersonalGroup = jest.fn().mockResolvedValue(false)\n await expect(usersManager.deletePersonalGroup(userTest, 7)).rejects.toThrow('You are not allowed to do this action')\n usersQueriesService.canDeletePersonalGroup = jest.fn().mockResolvedValue(true)\n const wSpy = jest.spyOn((usersManager as any)['logger'], 'warn').mockImplementation(() => undefined as any)\n usersQueriesService.deletePersonalGroup = jest.fn().mockResolvedValue(false)\n await expect(usersManager.deletePersonalGroup(userTest, 7)).rejects.toThrow('Unable to delete group')\n expect(wSpy).toHaveBeenCalledWith(expect.stringMatching(/does not exist/))\n const lgSpy = jest.spyOn((usersManager as any)['logger'], 'log').mockImplementation(() => undefined as any)\n usersQueriesService.deletePersonalGroup = jest.fn().mockResolvedValue(true)\n await expect(usersManager.deletePersonalGroup(userTest, 7)).resolves.toBeUndefined()\n expect(lgSpy).toHaveBeenCalledWith(expect.stringMatching(/was deleted/))\n })\n\n it('guests + proxies', async () => {\n usersQueriesService.listGuests = jest.fn().mockResolvedValue([{ id: 1 }])\n await expect(usersManager.listGuests(userTest)).resolves.toEqual([{ id: 1 }])\n const checkSpy = jest.spyOn(adminUsersManager, 'checkUser').mockImplementation(() => undefined)\n usersQueriesService.listGuests = jest.fn().mockResolvedValue({ id: 9 })\n await expect(usersManager.getGuest(userTest, 9)).resolves.toEqual({ id: 9 })\n expect(checkSpy).toHaveBeenCalled()\n\n usersQueriesService.usersWhitelist = jest.fn().mockResolvedValue([userTest.id, 100])\n usersQueriesService.clearWhiteListCaches = jest.fn()\n const createSpy = jest.spyOn(adminUsersManager, 'createUserOrGuest').mockResolvedValue({ id: 55 } as any)\n const dto1: CreateUserDto = { ...userTest, managers: [100], password: 'x' }\n const r = await usersManager.createGuest(userTest, dto1)\n expect(createSpy).toHaveBeenCalled()\n expect(usersQueriesService.clearWhiteListCaches).toHaveBeenCalledWith([userTest.id])\n expect(r).toEqual({ id: 55 })\n const args1 = (createSpy as jest.Mock).mock.calls[0][0]\n expect(args1.managers).toEqual(expect.arrayContaining([userTest.id]))\n ;(createSpy as jest.Mock).mockClear()\n const dto2: CreateUserDto = { ...userTest, managers: [userTest.id, 100], password: 'y' }\n await usersManager.createGuest(userTest, dto2)\n const args2 = (createSpy as jest.Mock).mock.calls[0][0]\n expect((args2.managers as number[]).filter((m: number) => m === userTest.id)).toHaveLength(1)\n\n await expect(usersManager.updateGuest(userTest, 9, {} as any)).rejects.toThrow('No changes to update')\n usersQueriesService.usersWhitelist = jest.fn().mockResolvedValue([1])\n await expect(usersManager.updateGuest(userTest, 9, { managers: [2] } as any)).rejects.toThrow('Guest must have at least one manager')\n usersQueriesService.isGuestManager = jest.fn().mockResolvedValue(false)\n await expect(usersManager.updateGuest(userTest, 9, { email: 'a' } as any)).rejects.toThrow('You are not allowed to do this action')\n usersQueriesService.isGuestManager = jest.fn().mockResolvedValue(true)\n jest.spyOn(adminUsersManager, 'updateUserOrGuest').mockResolvedValue({ managers: [{ id: 999 }] } as any)\n await expect(usersManager.updateGuest(userTest, 9, { email: 'a' } as any)).resolves.toBeNull()\n jest.spyOn(adminUsersManager, 'updateUserOrGuest').mockResolvedValue({ managers: [{ id: userTest.id }] } as any)\n await expect(usersManager.updateGuest(userTest, 9, { email: 'a' } as any)).resolves.toEqual({ managers: [{ id: userTest.id }] })\n usersQueriesService.usersWhitelist = jest.fn().mockResolvedValue([userTest.id, 77])\n usersQueriesService.isGuestManager = jest.fn().mockResolvedValue(true)\n jest.spyOn(adminUsersManager, 'updateUserOrGuest').mockResolvedValue({ managers: [{ id: userTest.id }, { id: 77 }] } as any)\n await expect(usersManager.updateGuest(userTest, 9, { managers: [userTest.id, 77] } as any)).resolves.toEqual({\n managers: [{ id: userTest.id }, { id: 77 }]\n })\n\n usersQueriesService.isGuestManager = jest.fn().mockResolvedValue(null)\n await expect(usersManager.deleteGuest(userTest, 9)).rejects.toThrow('You are not allowed to do this action')\n usersQueriesService.isGuestManager = jest.fn().mockResolvedValue({ id: 9, login: 'guest' })\n const delSpy = jest.spyOn(adminUsersManager, 'deleteUserOrGuest').mockResolvedValue(undefined)\n await expect(usersManager.deleteGuest(userTest, 9)).resolves.toBeUndefined()\n expect(delSpy).toHaveBeenCalledWith(9, 'guest', { deleteSpace: true, isGuest: true })\n\n usersQueriesService.searchUsersOrGroups = jest.fn().mockResolvedValue([{ id: 1 }])\n await expect(usersManager.searchMembers(userTest, { search: '' } as any)).resolves.toEqual([{ id: 1 }])\n\n usersQueriesService.getOnlineUsers = jest.fn().mockResolvedValue([{ id: 123 }])\n await expect(usersManager.getOnlineUsers([123])).resolves.toEqual([{ id: 123 }])\n expect(usersQueriesService.getOnlineUsers).toHaveBeenCalledWith([123])\n usersQueriesService.usersWhitelist = jest.fn().mockResolvedValue([10, 11])\n await expect(usersManager.usersWhitelist(userTest.id)).resolves.toEqual([10, 11])\n expect(usersQueriesService.usersWhitelist).toHaveBeenCalledWith(userTest.id)\n })\n})\n"],"names":["jest","mock","actual","requireActual","comparePassword","fn","__esModule","default","hash","Promise","resolve","generateAvatar","Readable","from","Buffer","describe","UsersManager","name","usersManager","adminUsersManager","adminUsersQueries","usersQueriesService","userTest","deleteUserDto","flush","r","setImmediate","okStream","d","s","truncated","errStream","msg","read","destroy","Error","mkReq","mimetype","stream","user","file","mockResolvedValue","ensurePaths","isPathExists","homePath","makePaths","notificationsManager","sendEmailNotification","undefined","beforeAll","module","Test","createTestingModule","providers","AdminUsersManager","AdminUsersQueries","UsersQueries","provide","NotificationsManager","useValue","AuthManager","DB_TOKEN_PROVIDER","Cache","compile","useLogger","get","UserModel","generateUserTest","deleteSpace","isGuest","afterEach","restoreAllMocks","afterAll","expect","deleteUserSpace","login","resolves","not","toThrow","it","toBeDefined","mockReturnValue","u1","findUser","toBeInstanceOf","password","toBeUndefined","u2","me1","me","toBeNull","id","rejects","fromUserId","authUser","clientId","impersonatedFromId","fromUser","me2","impersonated","toBe","filesPath","mockReturnValueOnce","p0","m0","getAvatar","fileName","svgMimeType","p1","m1","pngMimeType","checkUserExists","createUserOrGuest","clearWhiteListCaches","created","USER_ROLE","USER","email","mockImplementation","deleteUser","deleteUserOrGuest","linkUser","role","LINK","logUser","uLocked","isActive","passwordAttempts","errSpy","spyOn","updSpy1","mockRejectedValue","toHaveBeenCalledWith","stringContaining","uBad","errSpy2","updSpy2","out","uGood","updSpy3","pathsSpy","out2","toHaveBeenCalled","compareUserPassword","updateUserOrGuest","updateLanguage","language","selectUserProperties","updatePassword","oldPassword","newPassword","bcrypt","updateNotification","notification","prevAccess1","Date","currentIp","currentAccess","updateAccesses","payload1","calls","toMatchObject","lastIp","lastAccess","prevAccess2","USER_MAX_PASSWORD_ATTEMPTS","payload2","getInitials","p","m","imageModule","updateAvatar","t","mvSpy","filesUtilsModule","mvSpy2","expectedSrc","path","join","tmpPath","expectedDst","setOnlineStatus","browseRootGroups","root","browseGroups","parentGroup","members","length","groupFromName","group","browseGroupMembers","g2","toEqual","getGroupWithMembers","getGroup","createPersonalGroup","checkGroupNameExists","logSpy","updatePersonalGroup","mockResolvedValueOnce","type","MEMBER_TYPE","GROUP","PGROUP","updateGroup","isAdmin","usersWhitelist","addUsersToGroup","updateGroupMembers","add","groupRole","USER_GROUP_ROLE","MEMBER","updateUserFromPersonalGroup","MANAGER","spy","mockClear","removeUserFromGroup","remove","leavePersonalGroup","lSpy","stringMatching","canDeletePersonalGroup","deletePersonalGroup","wSpy","lgSpy","listGuests","checkSpy","getGuest","createSpy","dto1","managers","createGuest","args1","arrayContaining","dto2","args2","filter","toHaveLength","updateGuest","isGuestManager","deleteGuest","delSpy","searchUsersOrGroups","searchMembers","search","getOnlineUsers"],"mappings":"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"}
|