@sync-in/server
Version:
The secure, open-source platform for file storage, sharing, collaboration, and sync
539 lines (538 loc) • 27.4 kB
JavaScript
/*
* Copyright (C) 2012-2025 Johan Legrand <johan.legrand@sync-in.com>
* This file is part of Sync-in | The open source file sync and share solution
* See the LICENSE file for licensing details
*/ "use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "UsersManager", {
enumerable: true,
get: function() {
return UsersManager;
}
});
const _common = require("@nestjs/common");
const _bcryptjs = /*#__PURE__*/ _interop_require_default(require("bcryptjs"));
const _nodefs = require("node:fs");
const _nodepath = /*#__PURE__*/ _interop_require_default(require("node:path"));
const _promises = require("node:stream/promises");
const _constants = require("../../../common/constants");
const _functions = require("../../../common/functions");
const _image = require("../../../common/image");
const _shared = require("../../../common/shared");
const _configenvironment = require("../../../configuration/config.environment");
const _files = require("../../files/utils/files");
const _notifications = require("../../notifications/constants/notifications");
const _notificationsmanagerservice = require("../../notifications/services/notifications-manager.service");
const _member = require("../constants/member");
const _user = require("../constants/user");
const _usermodel = require("../models/user.model");
const _avatar = require("../utils/avatar");
const _adminusersmanagerservice = require("./admin-users-manager.service");
const _usersqueriesservice = require("./users-queries.service");
function _interop_require_default(obj) {
return obj && obj.__esModule ? obj : {
default: obj
};
}
function _ts_decorate(decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for(var i = decorators.length - 1; i >= 0; i--)if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
}
function _ts_metadata(k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
}
let UsersManager = class UsersManager {
async fromUserId(id) {
const user = await this.usersQueries.from(id);
return user ? new _usermodel.UserModel(user, true) : null;
}
async findUser(loginOrEmail, removePassword = true) {
const user = await this.usersQueries.from(null, loginOrEmail);
return user ? new _usermodel.UserModel(user, removePassword) : null;
}
async logUser(user, password, ip, scope) {
this.validateUserAccess(user, ip);
let authSuccess = await (0, _functions.comparePassword)(password, user.password);
if (!authSuccess && scope) {
authSuccess = await this.validateAppPassword(user, password, ip, scope);
}
this.updateAccesses(user, ip, authSuccess).catch((e)=>this.logger.error(`${this.logUser.name} - ${e}`));
if (authSuccess) {
await user.makePaths();
return user;
}
this.logger.warn(`${this.logUser.name} - bad password for *${user.login}*`);
return null;
}
validateUserAccess(user, ip) {
if (user.role === _user.USER_ROLE.LINK) {
this.logger.error(`${this.validateUserAccess.name} - guest link account ${user} is not authorized to login`);
throw new _common.HttpException('Account is not allowed', _common.HttpStatus.FORBIDDEN);
}
if (!user.isActive || user.passwordAttempts >= _user.USER_MAX_PASSWORD_ATTEMPTS) {
this.updateAccesses(user, ip, false).catch((e)=>this.logger.error(`${this.validateUserAccess.name} - ${e}`));
this.logger.error(`${this.validateUserAccess.name} - user account *${user.login}* is locked`);
this.notifyAccountLocked(user, ip);
throw new _common.HttpException('Account locked', _common.HttpStatus.FORBIDDEN);
}
}
async me(authUser) {
const user = await this.fromUserId(authUser.id);
if (!user) {
this.logger.warn(`User *${authUser.login} (${authUser.id}) not found`);
throw new _common.HttpException(`User not found`, _common.HttpStatus.NOT_FOUND);
}
user.impersonated = !!authUser.impersonatedFromId;
user.clientId = authUser.clientId;
return {
user: user,
server: _configenvironment.serverConfig
};
}
async compareUserPassword(userId, password) {
return this.usersQueries.compareUserPassword(userId, password);
}
async updateLanguage(user, userLanguageDto) {
if (!userLanguageDto.language) userLanguageDto.language = null;
if (!await this.usersQueries.updateUserOrGuest(user.id, userLanguageDto)) {
throw new _common.HttpException('Unable to update language', _common.HttpStatus.INTERNAL_SERVER_ERROR);
}
}
async updatePassword(user, userPasswordDto) {
const r = await this.usersQueries.selectUserProperties(user.id, [
'password'
]);
if (!r) {
throw new _common.HttpException('Unable to check password', _common.HttpStatus.NOT_FOUND);
}
if (!await (0, _functions.comparePassword)(userPasswordDto.oldPassword, r.password)) {
throw new _common.HttpException('Password mismatch', _common.HttpStatus.BAD_REQUEST);
}
const hash = await _bcryptjs.default.hash(userPasswordDto.newPassword, 10);
if (!await this.usersQueries.updateUserOrGuest(user.id, {
password: hash
})) {
throw new _common.HttpException('Unable to update password', _common.HttpStatus.INTERNAL_SERVER_ERROR);
}
}
async updateNotification(user, userNotificationDto) {
if (!await this.usersQueries.updateUserOrGuest(user.id, userNotificationDto)) {
throw new _common.HttpException('Unable to update notification preference', _common.HttpStatus.INTERNAL_SERVER_ERROR);
}
}
async updateStorageIndexing(user, userStorageIndexingDto) {
if (!await this.usersQueries.updateUserOrGuest(user.id, userStorageIndexingDto)) {
throw new _common.HttpException('Unable to update full-text search preference', _common.HttpStatus.INTERNAL_SERVER_ERROR);
}
}
async updateAvatar(req) {
const part = await req.file({
limits: {
fileSize: _avatar.USER_AVATAR_MAX_UPLOAD_SIZE
}
});
if (!part.mimetype.startsWith('image/')) {
throw new _common.HttpException('Unsupported file type', _common.HttpStatus.BAD_REQUEST);
}
const dstPath = _nodepath.default.join(req.user.tmpPath, _avatar.USER_AVATAR_FILE_NAME);
try {
await (0, _promises.pipeline)(part.file, (0, _nodefs.createWriteStream)(dstPath));
} catch (e) {
this.logger.error(`${this.updateAvatar.name} - ${e}`);
throw new _common.HttpException('Unable to upload avatar', _common.HttpStatus.INTERNAL_SERVER_ERROR);
}
if (part.file.truncated) {
this.logger.warn(`${this.updateAvatar.name} - image is too large`);
throw new _common.HttpException('Image is too large (5MB max)', _common.HttpStatus.PAYLOAD_TOO_LARGE);
}
try {
await (0, _files.moveFiles)(dstPath, _nodepath.default.join(req.user.homePath, _avatar.USER_AVATAR_FILE_NAME), true);
} catch (e) {
this.logger.error(`${this.updateAvatar.name} - ${e}`);
throw new _common.HttpException('Unable to create avatar', _common.HttpStatus.INTERNAL_SERVER_ERROR);
}
}
async updateSecrets(userId, secrets) {
const userSecrets = await this.usersQueries.getUserSecrets(userId);
const updatedSecrets = {
...userSecrets,
...secrets
};
if (!await this.usersQueries.updateUserOrGuest(userId, {
secrets: updatedSecrets
})) {
throw new _common.HttpException('Unable to update secrets', _common.HttpStatus.INTERNAL_SERVER_ERROR);
}
}
async updateAccesses(user, ip, success, isAuthTwoFa = false) {
let passwordAttempts;
if (!isAuthTwoFa && _configenvironment.configuration.auth.mfa.totp.enabled && user.twoFaEnabled) {
// Do not reset password attempts if the login still requires 2FA validation
passwordAttempts = user.passwordAttempts;
} else {
passwordAttempts = success ? 0 : Math.min(user.passwordAttempts + 1, _user.USER_MAX_PASSWORD_ATTEMPTS);
}
await this.usersQueries.updateUserOrGuest(user.id, {
lastAccess: user.currentAccess,
currentAccess: new Date(),
lastIp: user.currentIp,
currentIp: ip,
passwordAttempts: passwordAttempts,
isActive: user.isActive && passwordAttempts < _user.USER_MAX_PASSWORD_ATTEMPTS
});
}
async getAvatar(userLogin, generate = false, generateIsNotExists) {
const avatarPath = _nodepath.default.join(_usermodel.UserModel.getHomePath(userLogin), _avatar.USER_AVATAR_FILE_NAME);
const avatarExists = await (0, _files.isPathExists)(avatarPath);
if (!avatarExists && generateIsNotExists) {
generate = true;
}
if (!generate) {
return [
avatarExists ? avatarPath : _avatar.USER_DEFAULT_AVATAR_FILE_PATH,
avatarExists ? _image.pngMimeType : _image.svgMimeType
];
}
if (!await (0, _files.isPathExists)(_usermodel.UserModel.getHomePath(userLogin))) {
throw new _common.HttpException(`Home path for user *${userLogin}* does not exist`, _common.HttpStatus.FORBIDDEN);
}
const user = await this.findUser(userLogin);
if (!user) {
throw new _common.HttpException(`avatar not found`, _common.HttpStatus.NOT_FOUND);
}
const avatarFile = (0, _nodefs.createWriteStream)(avatarPath);
const avatarStream = await (0, _image.generateAvatar)(user.getInitials());
try {
await (0, _promises.pipeline)(avatarStream, avatarFile);
} catch (e) {
this.logger.error(`${this.updateAvatar.name} - ${e}`);
throw new _common.HttpException('Unable to create avatar', _common.HttpStatus.INTERNAL_SERVER_ERROR);
}
if (generateIsNotExists) {
return [
avatarPath,
_image.pngMimeType
];
}
}
async listAppPasswords(user) {
const secrets = await this.usersQueries.getUserSecrets(user.id);
if (Array.isArray(secrets.appPasswords)) {
// remove passwords from response
return secrets.appPasswords.map(({ password, ...rest })=>rest);
}
return [];
}
async generateAppPassword(user, userAppPasswordDto) {
const secrets = await this.usersQueries.getUserSecrets(user.id);
const slugName = (0, _shared.createLightSlug)(userAppPasswordDto.name);
if (Array.isArray(secrets.appPasswords) && secrets.appPasswords.find((p)=>p.name === slugName)) {
throw new _common.HttpException('Name already used', _common.HttpStatus.BAD_REQUEST);
}
secrets.appPasswords = Array.isArray(secrets.appPasswords) ? secrets.appPasswords : [];
const clearPassword = (0, _shared.genPassword)(24);
const appPassword = {
name: (0, _shared.createLightSlug)(userAppPasswordDto.name),
app: userAppPasswordDto.app,
expiration: userAppPasswordDto.expiration,
password: await (0, _functions.hashPassword)(clearPassword),
createdAt: new Date(),
currentIp: null,
currentAccess: null,
lastIp: null,
lastAccess: null
};
secrets.appPasswords.unshift(appPassword);
if (!await this.usersQueries.updateUserOrGuest(user.id, {
secrets: secrets
})) {
throw new _common.HttpException('Unable to update app passwords', _common.HttpStatus.INTERNAL_SERVER_ERROR);
}
// return clear password only once
return {
...appPassword,
password: clearPassword
};
}
async deleteAppPassword(user, passwordName) {
const secrets = await this.usersQueries.getUserSecrets(user.id);
if (!Array.isArray(secrets.appPasswords) || !secrets.appPasswords.find((p)=>p.name === passwordName)) {
throw new _common.HttpException('App password not found', _common.HttpStatus.NOT_FOUND);
}
secrets.appPasswords = secrets.appPasswords.filter((p)=>p.name !== passwordName);
if (!await this.usersQueries.updateUserOrGuest(user.id, {
secrets: secrets
})) {
throw new _common.HttpException('Unable to delete app password', _common.HttpStatus.INTERNAL_SERVER_ERROR);
}
}
async validateAppPassword(user, password, ip, scope) {
if (!scope || !user.haveRole(_user.USER_ROLE.USER)) return false;
const secrets = await this.usersQueries.getUserSecrets(user.id);
if (!Array.isArray(secrets.appPasswords)) return false;
for (const p of secrets.appPasswords){
if (p.app !== scope) continue;
const expMs = p.expiration ? new Date(p.expiration) : null;
if (p.expiration && new Date() > expMs) continue; // expired
if (await (0, _functions.comparePassword)(password, p.password)) {
p.lastAccess = p.currentAccess;
p.currentAccess = new Date();
p.lastIp = p.currentIp;
p.currentIp = ip;
// update accesses
this.usersQueries.updateUserOrGuest(user.id, {
secrets: secrets
}).catch((e)=>this.logger.error(`${this.validateAppPassword.name} - ${e}`));
return true;
}
}
return false;
}
setOnlineStatus(user, onlineStatus) {
this.usersQueries.setOnlineStatus(user.id, onlineStatus).catch((e)=>this.logger.error(`${this.setOnlineStatus.name} - ${e}`));
}
getOnlineUsers(userIds) {
return this.usersQueries.getOnlineUsers(userIds);
}
async usersWhitelist(userId) {
return this.usersQueries.usersWhitelist(userId);
}
async browseGroups(user, name) {
if (name) {
const group = await this.usersQueries.groupFromName(user.id, name);
if (!group) {
throw new _common.HttpException('Group not found', _common.HttpStatus.NOT_FOUND);
}
return {
parentGroup: group,
members: await this.usersQueries.browseGroupMembers(group.id)
};
}
return {
parentGroup: undefined,
members: await this.usersQueries.browseRootGroups(user.id)
};
}
async getGroup(user, groupId, withMembers = true, asAdmin = false) {
const group = withMembers ? await this.usersQueries.getGroupWithMembers(user.id, groupId, asAdmin) : await this.usersQueries.getGroup(user.id, groupId, asAdmin);
if (!group) {
throw new _common.HttpException('You are not allowed to do this action', _common.HttpStatus.FORBIDDEN);
}
return group;
}
async createPersonalGroup(user, userCreateOrUpdateGroupDto) {
if (!userCreateOrUpdateGroupDto.name) {
this.logger.error(`${this.createPersonalGroup.name} - missing group name : ${JSON.stringify(userCreateOrUpdateGroupDto)}`);
throw new _common.HttpException('Group name is missing', _common.HttpStatus.BAD_REQUEST);
}
if (await this.usersQueries.checkGroupNameExists(userCreateOrUpdateGroupDto.name)) {
throw new _common.HttpException('Name already used', _common.HttpStatus.BAD_REQUEST);
}
try {
const groupId = await this.usersQueries.createPersonalGroup(user.id, userCreateOrUpdateGroupDto);
this.logger.log(`${this.createPersonalGroup.name} - group (${groupId}) was created : ${JSON.stringify(userCreateOrUpdateGroupDto)}`);
// clear user whitelists
this.usersQueries.clearWhiteListCaches([
user.id
]);
return this.getGroup(user, groupId, false);
} catch (e) {
this.logger.error(`${this.createPersonalGroup.name} - group was not created : ${JSON.stringify(userCreateOrUpdateGroupDto)} : ${e}`);
throw new _common.HttpException('Unable to create group', _common.HttpStatus.INTERNAL_SERVER_ERROR);
}
}
async updatePersonalGroup(user, groupId, userCreateOrUpdateGroupDto) {
if (!Object.keys(userCreateOrUpdateGroupDto).length) {
throw new _common.HttpException('No changes to update', _common.HttpStatus.BAD_REQUEST);
}
const currentGroup = await this.getGroup(user, groupId, false, user.isAdmin);
if (currentGroup.type !== _member.MEMBER_TYPE.PGROUP) {
throw new _common.HttpException('You are not allowed to do this action', _common.HttpStatus.FORBIDDEN);
}
if (userCreateOrUpdateGroupDto.name && await this.usersQueries.checkGroupNameExists(userCreateOrUpdateGroupDto.name)) {
throw new _common.HttpException('Name already used', _common.HttpStatus.BAD_REQUEST);
}
try {
await this.usersQueries.updateGroup(groupId, userCreateOrUpdateGroupDto);
} catch (e) {
throw new _common.HttpException(e.message, _common.HttpStatus.INTERNAL_SERVER_ERROR);
}
return this.getGroup(user, groupId, false, user.isAdmin);
}
async addUsersToGroup(user, groupId, userIds) {
const currentGroup = await this.getGroup(user, groupId);
// only users can be added to users groups
// guests and users can be added to personal groups
const userWhiteList = await this.usersQueries.usersWhitelist(user.id, currentGroup.type === _member.MEMBER_TYPE.GROUP ? _user.USER_ROLE.USER : undefined);
// ignore user ids that are already group members & filter on user ids allowed to current user
userIds = userIds.filter((id)=>!currentGroup.members.find((m)=>m.id === id)).filter((id)=>userWhiteList.indexOf(id) > -1);
if (!userIds.length) {
throw new _common.HttpException('No users to add to group', _common.HttpStatus.BAD_REQUEST);
}
return this.usersQueries.updateGroupMembers(groupId, {
add: userIds.map((id)=>({
id: id,
groupRole: _user.USER_GROUP_ROLE.MEMBER
}))
});
}
async updateUserFromPersonalGroup(user, groupId, userId, updateUserFromGroupDto) {
const currentGroup = await this.getGroup(user, groupId);
if (currentGroup.type !== _member.MEMBER_TYPE.PGROUP) {
throw new _common.HttpException('You are not allowed to do this action', _common.HttpStatus.FORBIDDEN);
}
const userToUpdate = currentGroup.members.find((m)=>m.id === userId);
if (!userToUpdate) {
throw new _common.HttpException('User was not found', _common.HttpStatus.BAD_REQUEST);
}
if (userToUpdate.groupRole !== updateUserFromGroupDto.role) {
if (userToUpdate.groupRole === _user.USER_GROUP_ROLE.MANAGER) {
if (currentGroup.members.filter((m)=>m.groupRole === _user.USER_GROUP_ROLE.MANAGER).length === 1) {
throw new _common.HttpException('Group must have at least one manager', _common.HttpStatus.BAD_REQUEST);
}
}
return this.adminUsersManager.updateUserFromGroup(groupId, userId, updateUserFromGroupDto);
}
}
async removeUserFromGroup(user, groupId, userId) {
const currentGroup = await this.getGroup(user, groupId);
const userToRemove = currentGroup.members.find((m)=>m.id === userId);
if (!userToRemove) {
throw new _common.HttpException('User was not found', _common.HttpStatus.BAD_REQUEST);
}
if (userToRemove.groupRole === _user.USER_GROUP_ROLE.MANAGER) {
if (currentGroup.type === _member.MEMBER_TYPE.GROUP) {
throw new _common.HttpException('You are not allowed to do this action', _common.HttpStatus.FORBIDDEN);
}
if (currentGroup.members.filter((m)=>m.groupRole === _user.USER_GROUP_ROLE.MANAGER).length === 1) {
throw new _common.HttpException('Group must have at least one manager', _common.HttpStatus.BAD_REQUEST);
}
}
return this.usersQueries.updateGroupMembers(groupId, {
remove: [
userId
]
});
}
async leavePersonalGroup(user, groupId) {
const currentGroup = await this.usersQueries.getGroupWithMembers(user.id, groupId, true);
if (!currentGroup || currentGroup.type === _member.MEMBER_TYPE.GROUP) {
throw new _common.HttpException('You are not allowed to do this action', _common.HttpStatus.FORBIDDEN);
}
const userWhoLeaves = currentGroup.members.find((m)=>m.id === user.id);
if (!userWhoLeaves) {
throw new _common.HttpException('User was not found', _common.HttpStatus.BAD_REQUEST);
}
if (userWhoLeaves.groupRole === _user.USER_GROUP_ROLE.MANAGER) {
if (currentGroup.members.filter((m)=>m.groupRole === _user.USER_GROUP_ROLE.MANAGER).length === 1) {
throw new _common.HttpException('Group must have at least one manager', _common.HttpStatus.BAD_REQUEST);
}
}
try {
await this.usersQueries.updateGroupMembers(groupId, {
remove: [
user.id
]
});
this.logger.log(`${this.leavePersonalGroup.name} - user (${user.id}) has left group (${groupId})`);
} catch (e) {
this.logger.error(`${this.leavePersonalGroup.name} - user (${user.id}) has not left group (${groupId}) : ${e}`);
throw new _common.HttpException(e.message, _common.HttpStatus.INTERNAL_SERVER_ERROR);
}
}
async deletePersonalGroup(user, groupId) {
if (!await this.usersQueries.canDeletePersonalGroup(user.id, groupId)) {
throw new _common.HttpException('You are not allowed to do this action', _common.HttpStatus.FORBIDDEN);
}
if (await this.usersQueries.deletePersonalGroup(groupId)) {
this.logger.log(`${this.deletePersonalGroup.name} - group (${groupId}) was deleted`);
} else {
this.logger.warn(`${this.deletePersonalGroup.name} - group (${groupId}) does not exist`);
throw new _common.HttpException('Unable to delete group', _common.HttpStatus.BAD_REQUEST);
}
}
listGuests(user) {
return this.usersQueries.listGuests(null, user.id);
}
async getGuest(user, guestId) {
const guest = await this.usersQueries.listGuests(guestId, user.id);
this.adminUsersManager.checkUser(guest, true);
return guest;
}
async createGuest(user, createGuestDto) {
// filter managers that are allowed for current user
const userWhiteList = await this.usersQueries.usersWhitelist(user.id, _user.USER_ROLE.USER);
createGuestDto.managers = createGuestDto.managers.filter((id)=>userWhiteList.indexOf(id) > -1);
if (createGuestDto.managers.indexOf(user.id) === -1) {
// force user as manager during creation
createGuestDto.managers.push(user.id);
}
// clear user whitelists
this.usersQueries.clearWhiteListCaches([
user.id
]);
return this.adminUsersManager.createUserOrGuest(createGuestDto, _user.USER_ROLE.GUEST, true);
}
async updateGuest(user, guestId, updateGuestDto) {
if (!Object.keys(updateGuestDto).length) {
throw new _common.HttpException('No changes to update', _common.HttpStatus.BAD_REQUEST);
}
if (updateGuestDto.managers) {
// filter managers that are allowed for current user
const userWhiteList = await this.usersQueries.usersWhitelist(user.id, _user.USER_ROLE.USER);
updateGuestDto.managers = updateGuestDto.managers.filter((id)=>userWhiteList.indexOf(id) > -1);
if (!updateGuestDto.managers.length) {
throw new _common.HttpException('Guest must have at least one manager', _common.HttpStatus.BAD_REQUEST);
}
}
if (!await this.usersQueries.isGuestManager(user.id, guestId)) {
throw new _common.HttpException('You are not allowed to do this action', _common.HttpStatus.FORBIDDEN);
}
const guest = await this.adminUsersManager.updateUserOrGuest(guestId, updateGuestDto, _user.USER_ROLE.GUEST);
return guest.managers.find((m)=>m.id === user.id) ? guest : null;
}
async deleteGuest(user, guestId) {
const guest = await this.usersQueries.isGuestManager(user.id, guestId);
if (!guest) {
throw new _common.HttpException('You are not allowed to do this action', _common.HttpStatus.FORBIDDEN);
}
// guest has no space but a temporary directory
return this.adminUsersManager.deleteUserOrGuest(guest.id, guest.login, {
deleteSpace: true,
isGuest: true
});
}
searchMembers(user, searchMembersDto) {
return this.usersQueries.searchUsersOrGroups(searchMembersDto, user.id);
}
notifyAccountLocked(user, ip) {
this.notificationsManager.sendEmailNotification([
user
], {
app: _notifications.NOTIFICATION_APP.AUTH_LOCKED,
event: _notifications.NOTIFICATION_APP_EVENT.AUTH_LOCKED[_constants.ACTION.DELETE],
element: null,
url: ip
}).catch((e)=>this.logger.error(`${this.validateUserAccess.name} - ${e}`));
}
constructor(usersQueries, adminUsersManager, notificationsManager){
this.usersQueries = usersQueries;
this.adminUsersManager = adminUsersManager;
this.notificationsManager = notificationsManager;
this.logger = new _common.Logger(UsersManager.name);
}
};
UsersManager = _ts_decorate([
(0, _common.Injectable)(),
_ts_metadata("design:type", Function),
_ts_metadata("design:paramtypes", [
typeof _usersqueriesservice.UsersQueries === "undefined" ? Object : _usersqueriesservice.UsersQueries,
typeof _adminusersmanagerservice.AdminUsersManager === "undefined" ? Object : _adminusersmanagerservice.AdminUsersManager,
typeof _notificationsmanagerservice.NotificationsManager === "undefined" ? Object : _notificationsmanagerservice.NotificationsManager
])
], UsersManager);
//# sourceMappingURL=users-manager.service.js.map