UNPKG

@fdm-monster/server

Version:

FDM Monster is a bulk OctoPrint manager to set up, configure and monitor 3D printers. Our aim is to provide extremely optimized websocket performance and reliability.

179 lines (178 loc) 7.1 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "UserService", { enumerable: true, get: function() { return UserService; } }); const _baseservice = require("./base.service"); const _userdto = require("../interfaces/user.dto"); const _entities = require("../../entities"); const _typeorm = require("typeorm"); const _runtimeexceptions = require("../../exceptions/runtime.exceptions"); const _validators = require("../../handlers/validators"); const _userservicevalidation = require("../validators/user-service.validation"); const _cryptoutils = require("../../utils/crypto.utils"); const _authorizationconstants = require("../../constants/authorization.constants"); class UserService extends (0, _baseservice.BaseService)(_entities.User, _userdto.UserDto) { userRoleService; roleService; constructor(typeormService, userRoleService, roleService){ super(typeormService), this.userRoleService = userRoleService, this.roleService = roleService; } toDto(user) { return { id: user.id, createdAt: user.createdAt, isVerified: user.isVerified, isDemoUser: user.isDemoUser, isRootUser: user.isRootUser, username: user.username, needsPasswordChange: user.needsPasswordChange, roles: (user.roles ?? []).map((r)=>r.roleId) }; } listUsers(limit) { return this.list({ take: limit }); } async getUser(userId) { return this.get(userId); } async getUserRoleIds(userId) { const userRoles = await this.userRoleService.listUserRoles(userId); return userRoles.map((ur)=>ur.roleId); } findRootUsers() { return this.repository.findBy({ isRootUser: true }); } async findUsersByRoleId(roleId) { const userRoles = await this.userRoleService.listByRoleId(roleId); const ids = userRoles.map((u)=>u.id); return this.repository.findBy({ id: (0, _typeorm.In)(ids) }); } findVerifiedUsers() { return this.repository.findBy({ isVerified: true }); } async isUserRootUser(userId) { const entity = await this.get(userId); return entity.isRootUser; } async deleteUser(userId) { const user = await this.getUser(userId); if (user.isRootUser) { throw new _runtimeexceptions.InternalServerException("Cannot delete a root user"); } if (!user.roles?.length) { throw new _runtimeexceptions.InternalServerException("User:roles relation not loaded, cannot perform deletion role check"); } const role = this.roleService.getRoleByName(_authorizationconstants.ROLES.ADMIN); if (user.roles.find((r)=>r.roleId == role.id)) { const administrators = await this.findUsersByRoleId(role.id); if (administrators?.length === 1 && administrators[0].id === userId) { throw new _runtimeexceptions.InternalServerException("Cannot delete the last user with ADMIN role"); } } await this.delete(userId); } findRawByUsername(username) { return this.repository.findOneBy({ username }); } async getDemoUserId() { return (await this.repository.findOneBy({ isDemoUser: true }))?.id; } async setIsRootUserById(userId, isRootUser) { const user = await this.getUser(userId); if (!user) throw new _runtimeexceptions.NotFoundException("User not found"); if (!isRootUser) { const rootUsers = await this.findRootUsers(); if (rootUsers.length === 1 && rootUsers[0].id === userId) { throw new _runtimeexceptions.InternalServerException("Cannot set the last root user to non-root user"); } } await this.update(userId, { isRootUser }); } async setUserRoleIds(userId, roleIds) { await this.userRoleService.setUserRoles(userId, roleIds); return await this.get(userId); } async setVerifiedById(userId, isVerified) { const user = await this.getUser(userId); if (!user) throw new _runtimeexceptions.NotFoundException("User not found"); if (!isVerified) { if (user.isRootUser) { throw new _runtimeexceptions.InternalServerException("Cannot set a owner (root user) to unverified"); } const verifiedUsers = await this.findVerifiedUsers(); if (verifiedUsers.length === 1) { throw new _runtimeexceptions.InternalServerException("Cannot set the last user to unverified"); } } await this.update(userId, { isVerified }); } async updatePasswordById(userId, oldPassword, newPassword) { const user = await this.getUser(userId); if (!user) throw new _runtimeexceptions.NotFoundException("User not found"); if (!(0, _cryptoutils.comparePasswordHash)(oldPassword, user.passwordHash)) { throw new _runtimeexceptions.NotFoundException("User old password incorrect"); } const { password } = await (0, _validators.validateInput)({ password: newPassword }, _userservicevalidation.newPasswordSchema); const passwordHash = (0, _cryptoutils.hashPassword)(password); return await this.update(userId, { passwordHash, needsPasswordChange: false }); } async updatePasswordUnsafeByUsername(username, newPassword) { const { password } = await (0, _validators.validateInput)({ password: newPassword }, _userservicevalidation.newPasswordSchema); const passwordHash = (0, _cryptoutils.hashPassword)(password); const user = await this.findRawByUsername(username); if (!user) throw new _runtimeexceptions.NotFoundException("User not found"); return await this.update(user.id, { passwordHash, needsPasswordChange: false }); } updateUsernameById(userId, newUsername) { return this.update(userId, { username: newUsername }); } async register(input) { const { username, password, roles, isDemoUser, isRootUser, needsPasswordChange, isVerified } = await (0, _validators.validateInput)(input, (0, _userservicevalidation.registerUserSchema)(true)); const passwordHash = (0, _cryptoutils.hashPassword)(password); const result = await this.create({ username, passwordHash, isVerified: isVerified ?? false, isDemoUser: isDemoUser ?? false, isRootUser: isRootUser ?? false, needsPasswordChange: needsPasswordChange ?? true }); await this.userRoleService.setUserRoles(result.id, roles); return this.get(result.id); } } //# sourceMappingURL=user.service.js.map