import { EntityManager } from "typeorm"; import { dataSource } from "../../../data-source"; import { user } from "../../../entity/management/user"; import InternalException from "../../../exceptions/internalException"; import { CreateUserCommand, DeleteUserCommand, TransferUserOwnerCommand, UpdateUserCommand, UpdateUserRolesCommand, UpdateUserSecretCommand, } from "./userCommand"; import UserService from "../../../service/management/userService"; import DatabaseActionException from "../../../exceptions/databaseActionException"; export default abstract class UserCommandHandler { /** * @description create user * @param {CreateUserCommand} createUser * @returns {Promise} */ static async create(createUser: CreateUserCommand): Promise { return await dataSource .createQueryBuilder() .insert() .into(user) .values({ username: createUser.username, mail: createUser.mail, firstname: createUser.firstname, lastname: createUser.lastname, secret: createUser.secret, isOwner: createUser.isOwner, }) .execute() .then((result) => { return result.identifiers[0].id; }) .catch((err) => { throw new DatabaseActionException("CREATE", "user", err); }); } /** * @description update user * @param {UpdateUserCommand} updateUser * @returns {Promise} */ static async update(updateUser: UpdateUserCommand): Promise { return await dataSource .createQueryBuilder() .update(user) .set({ mail: updateUser.mail, firstname: updateUser.firstname, lastname: updateUser.lastname, username: updateUser.username, }) .where("id = :id", { id: updateUser.id }) .execute() .then(() => {}) .catch((err) => { throw new DatabaseActionException("UPDATE", "user", err); }); } /** * @description update user * @param {UpdateUserSecretCommand} updateUser * @returns {Promise} */ static async updateSecret(updateUser: UpdateUserSecretCommand): Promise { return await dataSource .createQueryBuilder() .update(user) .set({ secret: updateUser.secret, routine: updateUser.routine, }) .where("id = :id", { id: updateUser.id }) .execute() .then(() => {}) .catch((err) => { throw new DatabaseActionException("UPDATE", "user", err); }); } /** * @description update user roles * @param {UpdateUserRolesCommand} updateUserRoles * @returns {Promise} */ static async updateRoles(updateUserRoles: UpdateUserRolesCommand): Promise { let currentRoles = (await UserService.getAssignedRolesByUserId(updateUserRoles.id)).map((r) => r.id); return await dataSource.manager .transaction(async (manager) => { let newRoles = updateUserRoles.roleIds.filter((r) => !currentRoles.includes(r)); let removeRoles = currentRoles.filter((r) => !updateUserRoles.roleIds.includes(r)); for (let role of newRoles) { await this.updateRolesAdd(manager, updateUserRoles.id, role); } for (let role of removeRoles) { await this.updateRolesRemove(manager, updateUserRoles.id, role); } }) .then(() => {}) .catch((err) => { throw new DatabaseActionException("UPDATE", "userRoles", err); }); } private static async updateRolesAdd(manager: EntityManager, userId: string, roleId: number): Promise { return await manager.createQueryBuilder().relation(user, "roles").of(userId).add(roleId); } private static async updateRolesRemove(manager: EntityManager, userId: string, roleId: number): Promise { return await manager.createQueryBuilder().relation(user, "roles").of(userId).remove(roleId); } /** * @description transfer ownership * @param {TransferUserOwnerCommand} transferOwnership * @returns {Promise} */ static async transferOwnership(transferOwnership: TransferUserOwnerCommand): Promise { return await dataSource.manager .transaction(async (manager) => { await manager .createQueryBuilder() .update(user) .set({ isOwner: false, }) .where("id = :id", { id: transferOwnership.fromId }) .execute(); await manager .createQueryBuilder() .update(user) .set({ isOwner: true, }) .where("id = :id", { id: transferOwnership.toId }) .execute(); }) .then(() => {}) .catch((err) => { throw new DatabaseActionException("ABORT", "transfer owner", err); }); } /** * @description delete user * @param DeleteUserCommand * @returns {Promise} */ static async delete(deleteUser: DeleteUserCommand): Promise { return await dataSource .createQueryBuilder() .delete() .from(user) .where("id = :id", { id: deleteUser.id }) .execute() .then(() => {}) .catch((err) => { throw new DatabaseActionException("DELETE", "user", err); }); } }