refactor(server): user core (#4733)

This commit is contained in:
Jason Rasmussen
2023-10-31 11:01:32 -04:00
committed by GitHub
parent 2377df9dae
commit 088d5addf2
9 changed files with 160 additions and 304 deletions

View File

@@ -1,5 +1,5 @@
import { UserEntity } from '@app/infra/entities';
import { BadRequestException, Inject, Injectable, Logger, NotFoundException } from '@nestjs/common';
import { BadRequestException, ForbiddenException, Inject, Injectable, Logger, NotFoundException } from '@nestjs/common';
import { randomBytes } from 'crypto';
import { AuthUserDto } from '../auth';
import { IEntityJob, JobName } from '../job';
@@ -12,6 +12,7 @@ import {
IStorageRepository,
IUserRepository,
ImmichReadStream,
UserFindOptions,
} from '../repositories';
import { StorageCore, StorageFolder } from '../storage';
import { CreateUserDto, UpdateUserDto } from './dto';
@@ -41,7 +42,7 @@ export class UserService {
}
async get(userId: string): Promise<UserResponseDto> {
const user = await this.userRepository.get(userId, false);
const user = await this.userRepository.get(userId, { withDeleted: false });
if (!user) {
throw new NotFoundException('User not found');
}
@@ -49,47 +50,43 @@ export class UserService {
return mapUser(user);
}
async getMe(authUser: AuthUserDto): Promise<UserResponseDto> {
const user = await this.userRepository.get(authUser.id);
if (!user) {
throw new BadRequestException('User not found');
}
return mapUser(user);
getMe(authUser: AuthUserDto): Promise<UserResponseDto> {
return this.findOrFail(authUser.id, {}).then(mapUser);
}
async create(createUserDto: CreateUserDto): Promise<UserResponseDto> {
const createdUser = await this.userCore.createUser(createUserDto);
return mapUser(createdUser);
create(createUserDto: CreateUserDto): Promise<UserResponseDto> {
return this.userCore.createUser(createUserDto).then(mapUser);
}
async update(authUser: AuthUserDto, dto: UpdateUserDto): Promise<UserResponseDto> {
const user = await this.userRepository.get(dto.id);
if (!user) {
throw new NotFoundException('User not found');
}
const updatedUser = await this.userCore.updateUser(authUser, dto.id, dto);
return mapUser(updatedUser);
await this.findOrFail(dto.id, {});
return this.userCore.updateUser(authUser, dto.id, dto).then(mapUser);
}
async delete(authUser: AuthUserDto, userId: string): Promise<UserResponseDto> {
const user = await this.userRepository.get(userId);
if (!user) {
throw new BadRequestException('User not found');
async delete(authUser: AuthUserDto, id: string): Promise<UserResponseDto> {
if (!authUser.isAdmin) {
throw new ForbiddenException('Unauthorized');
}
await this.albumRepository.softDeleteAll(userId);
const deletedUser = await this.userCore.deleteUser(authUser, user);
return mapUser(deletedUser);
const user = await this.findOrFail(id, {});
if (user.isAdmin) {
throw new ForbiddenException('Cannot delete admin user');
}
await this.albumRepository.softDeleteAll(id);
return this.userRepository.delete(user).then(mapUser);
}
async restore(authUser: AuthUserDto, userId: string): Promise<UserResponseDto> {
const user = await this.userRepository.get(userId, true);
if (!user) {
throw new BadRequestException('User not found');
async restore(authUser: AuthUserDto, id: string): Promise<UserResponseDto> {
if (!authUser.isAdmin) {
throw new ForbiddenException('Unauthorized');
}
const updatedUser = await this.userCore.restoreUser(authUser, user);
await this.albumRepository.restoreAll(userId);
return mapUser(updatedUser);
let user = await this.findOrFail(id, { withDeleted: true });
user = await this.userRepository.restore(user);
await this.albumRepository.restoreAll(id);
return mapUser(user);
}
async createProfileImage(
@@ -101,7 +98,7 @@ export class UserService {
}
async getProfileImage(id: string): Promise<ImmichReadStream> {
const user = await this.findOrFail(id);
const user = await this.findOrFail(id, {});
if (!user.profileImagePath) {
throw new NotFoundException('User does not have a profile image');
}
@@ -134,7 +131,7 @@ export class UserService {
}
async handleUserDelete({ id }: IEntityJob) {
const user = await this.userRepository.get(id, true);
const user = await this.userRepository.get(id, { withDeleted: true });
if (!user) {
return false;
}
@@ -181,8 +178,8 @@ export class UserService {
return msSinceDelete >= msDeleteWait;
}
private async findOrFail(id: string) {
const user = await this.userRepository.get(id);
private async findOrFail(id: string, options: UserFindOptions) {
const user = await this.userRepository.get(id, options);
if (!user) {
throw new BadRequestException('User not found');
}