File

packages/server/src/modules/user/user.service.ts

Index

Methods

Constructor

constructor(configService: ConfigService, roleService: RoleService, companyService: CompanyService, repo: Repository)
Parameters :
Name Type Optional
configService ConfigService No
roleService RoleService No
companyService CompanyService No
repo Repository<UserEntity> No

Methods

Async all
all(query: UserQuery)
Parameters :
Name Type Optional
query UserQuery No
Returns : Promise<literal type>
Async changePassword
changePassword(body: UserPasswordRequest, user: ActiveUserData)
Parameters :
Name Type Optional
body UserPasswordRequest No
user ActiveUserData No
Returns : unknown
Async create
create(body: UserRequest)
Parameters :
Name Type Optional
body UserRequest No
Returns : Promise<UserEntity>
Async findOne
findOne(fullname: string, pass: string)
Parameters :
Name Type Optional
fullname string No
pass string No
Returns : Promise<UserEntity | null>
Async getById
getById(id?: number, relations?: FindOptionsRelations)
Parameters :
Name Type Optional
id number Yes
relations FindOptionsRelations<UserEntity> Yes
Returns : Promise<UserEntity | null>
Async getByIdWithError
getByIdWithError(id?: number, relations?: FindOptionsRelations)
Parameters :
Name Type Optional
id number Yes
relations FindOptionsRelations<UserEntity> Yes
Returns : Promise<UserEntity>
Async remove
remove(id: number)
Parameters :
Name Type Optional
id number No
Returns : unknown
Async update
update(id: number, body: UserRequest)
Parameters :
Name Type Optional
id number No
body UserRequest No
Returns : Promise<UserEntity>
import type {
  FindOptionsRelationByString,
  FindOptionsRelations,
  Repository,
} from "typeorm";
import { ApiStatusCode } from "@bill/database";
import { UserEntity } from "@bill/database/dist/entities";
import { Global, HttpStatus, Injectable } from "@nestjs/common";
import { ConfigService } from "@nestjs/config";
import { InjectRepository } from "@nestjs/typeorm";

import { ApiException } from "@/common/exception/api.exception";
import { ActiveUserData } from "@/common/interfaces/active-user-data.interface";
import hashPwd from "@/common/utils/hash";
import { RoleService } from "@/modules/role/role.service";

import { CompanyService } from "../company/company.service";
import type {
  UserPasswordRequest,
  UserQuery,
  UserRequest,
} from "./user.interface";

@Injectable()
@Global()
export class UserService {
  constructor(
    private configService: ConfigService,
    private roleService: RoleService,
    private companyService: CompanyService,
    @InjectRepository(UserEntity) private repo: Repository<UserEntity>
  ) {}

  async all(query: UserQuery): Promise<{ rows: UserEntity[]; count: number }> {
    const { role, ...rest } = query?.where || {};
    const [rows, count] = await this.repo.findAndCount({
      skip: query.skip,
      take: query.take,
      where: {
        ...rest,
        role: role?.id ? { id: ~~role.id } : undefined,
      },
      relations: {
        role: true,
        company: true,
      },
      select: ["role", "company"],
      withDeleted: false,
    });

    return {
      rows: rows.map((u) => {
        u.password = "";
        return u;
      }),
      count,
    };
  }

  async getById(
    id?: number,
    relations?: FindOptionsRelations<UserEntity>
  ): Promise<UserEntity | null> {
    if (!id) {
      return null;
    }

    const data = await this.repo.findOne({
      where: { id },
      relations,
    });

    return data || null;
  }

  async getByIdWithError(
    id?: number,
    relations?: FindOptionsRelations<UserEntity>
  ): Promise<UserEntity> {
    const user = await this.getById(id, relations);

    if (!user) {
      throw new ApiException(
        "can not find recoed",
        ApiStatusCode.KEY_NOT_EXIST,
        HttpStatus.OK,
        {
          id: id,
          type: "UserEntity",
        }
      );
    }

    return user;
  }

  async findOne(fullname: string, pass: string): Promise<UserEntity | null> {
    return this.repo.findOne({
      where: {
        fullname: fullname,
        password: hashPwd(pass, this.configService.get("app").secret),
      },
      relations: {
        role: true,
        company: true,
      },
    });
  }

  async create(body: UserRequest): Promise<UserEntity> {
    const { password, company, role, ...rest } = body;
    const user = new UserEntity().extend({
      ...rest,
      password: hashPwd(
        password ?? "123456789",
        this.configService.get("app").secret
      ),
      role: (await this.roleService.getById(role)) ?? undefined,
      company: (await this.companyService.getById(company)) ?? undefined,
    });

    return await this.repo.save(user);
  }

  async update(id: number, body: UserRequest): Promise<UserEntity> {
    const user = await this.getByIdWithError(id);
    const { password, company, role, ...rest } = body;

    user.extend({
      ...rest,
      role: await this.roleService.getById(role),
      company: await this.companyService.getById(company),
    });

    return this.repo.save(user);
  }

  async remove(id: number) {
    const child = await this.getByIdWithError(id);

    return this.repo.softRemove(child);
  }

  async changePassword(body: UserPasswordRequest, user: ActiveUserData) {
    const userEntity = await this.getByIdWithError(user.id);

    if (
      userEntity.password !==
      hashPwd(body.password, this.configService.get("app").secret)
    ) {
      throw new ApiException(
        "password not correct",
        ApiStatusCode.PASSWORD_NOT_CORRECT,
        HttpStatus.OK
      );
    }

    if (body.passwordNew !== body.passwordNewAgain) {
      throw new ApiException(
        "2 passwords are not match.",
        ApiStatusCode.TWO_PASSWORDS_NOT_MATCH,
        HttpStatus.OK
      );
    }

    userEntity.password = hashPwd(
      body.passwordNew,
      this.configService.get("app").secret
    );

    return this.repo.save(userEntity);
  }
}

results matching ""

    No results matching ""