@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.
173 lines (172 loc) • 6.89 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "UserService", {
enumerable: true,
get: function() {
return UserService;
}
});
const _models = require("../../models");
const _runtimeexceptions = require("../../exceptions/runtime.exceptions");
const _validators = require("../../handlers/validators");
const _userservicevalidation = require("../validators/user-service.validation");
const _authorizationconstants = require("../../constants/authorization.constants");
const _cryptoutils = require("../../utils/crypto.utils");
class UserService {
roleService;
constructor(roleService){
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.toString())
};
}
async listUsers(limit = 10) {
return _models.User.find().limit(limit);
}
async findUsersByRoleId(roleId) {
return _models.User.find({
roles: {
$in: [
roleId
]
}
});
}
async findVerifiedUsers() {
return _models.User.find({
isVerified: true
});
}
async isUserRootUser(userId) {
const entity = await this.getUser(userId);
return entity.isRootUser;
}
async findRootUsers() {
return _models.User.find({
isRootUser: true
});
}
async getDemoUserId() {
return (await _models.User.findOne({
isDemoUser: true
}))?.id;
}
async findRawByUsername(username) {
return _models.User.findOne({
username
});
}
async getUser(userId) {
const user = await _models.User.findById(userId);
if (!user) throw new _runtimeexceptions.NotFoundException("User not found");
return user;
}
async getUserRoleIds(userId) {
const user = await this.getUser(userId);
return user.roles?.map((r)=>r.toString());
}
async setUserRoleIds(userId, roleIds) {
const user = await _models.User.findById(userId);
if (!user) throw new _runtimeexceptions.NotFoundException("User not found");
const roles = this.roleService.getManyRoles(roleIds);
user.roles = roles.map((r)=>r.id);
user.roles = Array.from(new Set(user.roles));
return await user.save();
}
async deleteUser(userId) {
const user = await this.getUser(userId);
if (user.isRootUser) {
throw new _runtimeexceptions.InternalServerException("Cannot delete a root user");
}
const role = this.roleService.getRoleByName(_authorizationconstants.ROLES.ADMIN);
if (user.roles.includes(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 _models.User.findByIdAndDelete(user.id);
}
async updateUsernameById(userId, newUsername) {
const user = await _models.User.findById(userId);
if (!user) throw new _runtimeexceptions.NotFoundException("User not found");
user.username = newUsername;
return await user.save();
}
async updatePasswordById(userId, oldPassword, newPassword) {
const user = await _models.User.findById(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);
user.passwordHash = (0, _cryptoutils.hashPassword)(password);
user.needsPasswordChange = false;
return await user.save();
}
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");
user.passwordHash = passwordHash;
user.needsPasswordChange = false;
return await user.save();
}
async setIsRootUserById(userId, isRootUser) {
const user = await _models.User.findById(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");
}
}
user.isRootUser = isRootUser;
await user.save();
}
async setVerifiedById(userId, isVerified) {
const user = await _models.User.findById(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");
}
}
user.isVerified = isVerified;
await user.save();
}
async register(input) {
const { username, password, roles, isDemoUser, isRootUser, needsPasswordChange, isVerified } = await (0, _validators.validateInput)(input, (0, _userservicevalidation.registerUserSchema)(false));
const passwordHash = (0, _cryptoutils.hashPassword)(password);
return await _models.User.create({
username,
passwordHash,
roles,
isVerified: isVerified ?? false,
isDemoUser: isDemoUser ?? false,
isRootUser: isRootUser ?? false,
needsPasswordChange: needsPasswordChange ?? true
});
}
}
//# sourceMappingURL=user.service.js.map