113 lines
3.3 KiB
TypeScript
113 lines
3.3 KiB
TypeScript
import { Injectable } from '@nestjs/common';
|
|
import { InjectRepository } from '@nestjs/typeorm';
|
|
import { EntityManager, Repository } from 'typeorm';
|
|
import type {
|
|
AdminUserActiveFilter,
|
|
AdminUserSortField,
|
|
} from '../dto/user.dto';
|
|
import { UserEntity } from '../entities/user.entity';
|
|
|
|
@Injectable()
|
|
export class UsersRepository {
|
|
constructor(
|
|
@InjectRepository(UserEntity) private readonly repo: Repository<UserEntity>,
|
|
) {}
|
|
|
|
findById(id: string, manager?: EntityManager): Promise<UserEntity | null> {
|
|
return (manager?.getRepository(UserEntity) ?? this.repo).findOne({
|
|
where: { id },
|
|
});
|
|
}
|
|
|
|
findByIdentity(issuer: string, subject: string): Promise<UserEntity | null> {
|
|
return this.repo.findOne({ where: { issuer, subject } });
|
|
}
|
|
|
|
async search(
|
|
query: string | undefined,
|
|
page: number,
|
|
pageSize: number,
|
|
): Promise<[UserEntity[], number]> {
|
|
const qb = this.repo
|
|
.createQueryBuilder('user')
|
|
.leftJoinAndSelect('user.roles', 'role');
|
|
if (query) {
|
|
qb.where('user.name LIKE :query OR user.email LIKE :query', {
|
|
query: `%${query}%`,
|
|
});
|
|
}
|
|
return qb
|
|
.orderBy('user.createdAt', 'DESC')
|
|
.skip((page - 1) * pageSize)
|
|
.take(pageSize)
|
|
.getManyAndCount();
|
|
}
|
|
|
|
async adminSearch(
|
|
query: {
|
|
search?: string;
|
|
active: AdminUserActiveFilter;
|
|
roleId?: string;
|
|
sort: AdminUserSortField;
|
|
direction: 'ASC' | 'DESC';
|
|
page: number;
|
|
pageSize: number;
|
|
},
|
|
manager?: EntityManager,
|
|
): Promise<[UserEntity[], number]> {
|
|
const repo = manager?.getRepository(UserEntity) ?? this.repo;
|
|
const qb = repo
|
|
.createQueryBuilder('user')
|
|
.leftJoinAndSelect('user.roles', 'role')
|
|
.leftJoinAndSelect('role.permissions', 'permission');
|
|
if (query.search) {
|
|
qb.andWhere('user.name LIKE :search OR user.email LIKE :search', {
|
|
search: `%${query.search}%`,
|
|
});
|
|
}
|
|
if (query.active !== 'all') {
|
|
qb.andWhere('user.active = :active', {
|
|
active: query.active === 'active',
|
|
});
|
|
}
|
|
if (query.roleId) {
|
|
qb.andWhere(
|
|
'EXISTS (SELECT 1 FROM user_roles ur WHERE ur.user_id = user.id AND ur.role_id = :roleId)',
|
|
{ roleId: query.roleId },
|
|
);
|
|
}
|
|
return qb
|
|
.orderBy(`user.${query.sort}`, query.direction)
|
|
.skip((query.page - 1) * query.pageSize)
|
|
.take(query.pageSize)
|
|
.getManyAndCount();
|
|
}
|
|
|
|
findByIdWithRoles(
|
|
id: string,
|
|
manager?: EntityManager,
|
|
): Promise<UserEntity | null> {
|
|
return (manager?.getRepository(UserEntity) ?? this.repo).findOne({
|
|
where: { id },
|
|
relations: { roles: { permissions: true }, settings: true },
|
|
});
|
|
}
|
|
|
|
async save(user: UserEntity, manager?: EntityManager): Promise<UserEntity> {
|
|
return (manager?.getRepository(UserEntity) ?? this.repo).save(user);
|
|
}
|
|
|
|
findFirstActiveAdmin(excludedUserId?: string): Promise<UserEntity | null> {
|
|
const qb = this.repo
|
|
.createQueryBuilder('user')
|
|
.innerJoin('user.roles', 'role')
|
|
.where('user.active = :active', { active: true })
|
|
.andWhere('role.name = :role', { role: 'admin' })
|
|
.orderBy('user.createdAt', 'ASC');
|
|
if (excludedUserId) {
|
|
qb.andWhere('user.id <> :excludedUserId', { excludedUserId });
|
|
}
|
|
return qb.getOne();
|
|
}
|
|
}
|