import { Inject, Injectable } from '@nestjs/common'; import { EventEmitter2 } from '@nestjs/event-emitter'; import { ModelObject } from 'objection'; import { ServiceError } from '@/modules/Items/ServiceError'; import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel'; import { TenantUser } from '@/modules/Tenancy/TenancyModels/models/TenantUser.model'; import { ERRORS } from '../Users.constants'; import { ITenantUserInactivatedPayload } from '../Users.types'; import { TenancyContext } from '@/modules/Tenancy/TenancyContext.service'; import { events } from '@/common/events/events'; @Injectable() export class InactivateUserService { constructor( @Inject(TenantUser.name) private readonly tenantUserModel: TenantModelProxy, private readonly eventEmitter: EventEmitter2, private readonly tenancyContext: TenancyContext, ) {} /** * Inactivate the given user id. * @param {number} userId * @return {Promise} */ public async inactivateUser(userId: number): Promise { const authorizedUser = await this.tenancyContext.getSystemUser(); const authorizedTenantUser = await this.tenantUserModel() .query() .findOne({ systemUserId: authorizedUser.id }) .throwIfNotFound(); // Throw service error if the given user is equals the authorized user. this.throwErrorIfUserSameAuthorizedUser(userId, authorizedTenantUser); // Retrieve the user or throw not found service error. const tenantUser = await this.tenantUserModel() .query() .findById(userId) .throwIfNotFound(); // Throw serivce error if the user is already inactivated. this.throwErrorIfUserInactive(tenantUser); // Marks the tenant user as inactive. await this.tenantUserModel() .query() .findById(userId) .update({ active: false }); // Triggers `onTenantUserActivated` event. await this.eventEmitter.emitAsync(events.tenantUser.onInactivated, { userId, tenantUser, } as ITenantUserInactivatedPayload); } /** * Throw service error in case the given user same the authorized user. * @param {number} userId * @param {ModelObject} authorizedUser */ private throwErrorIfUserSameAuthorizedUser( userId: number, authorizedUser: ModelObject, ) { if (userId === authorizedUser.id) { throw new ServiceError(ERRORS.USER_SAME_THE_AUTHORIZED_USER); } } /** * Throws service error in case the user was already inactive. * @param {ModelObject} user * @throws {ServiceError} */ private throwErrorIfUserInactive(user: ModelObject) { if (!user.active) { throw new ServiceError(ERRORS.USER_ALREADY_INACTIVE); } } }