2022-06-25 19:53:06 +02:00
|
|
|
import {
|
|
|
|
|
BadRequestException,
|
2022-07-15 21:30:56 +02:00
|
|
|
Inject,
|
2022-06-25 19:53:06 +02:00
|
|
|
Injectable,
|
|
|
|
|
InternalServerErrorException,
|
|
|
|
|
Logger,
|
|
|
|
|
NotFoundException,
|
|
|
|
|
StreamableFile,
|
|
|
|
|
} from '@nestjs/common';
|
2022-04-23 21:08:45 -05:00
|
|
|
import { AuthUserDto } from '../../decorators/auth-user.decorator';
|
2022-02-03 10:06:44 -06:00
|
|
|
import { CreateUserDto } from './dto/create-user.dto';
|
|
|
|
|
import { UpdateUserDto } from './dto/update-user.dto';
|
2022-06-06 18:16:03 +02:00
|
|
|
import { createReadStream } from 'fs';
|
2022-05-27 22:24:58 -05:00
|
|
|
import { Response as Res } from 'express';
|
2022-06-25 19:53:06 +02:00
|
|
|
import { mapUser, UserResponseDto } from './response-dto/user-response.dto';
|
2022-07-08 21:26:50 -05:00
|
|
|
import { mapUserCountResponse, UserCountResponseDto } from './response-dto/user-count-response.dto';
|
|
|
|
|
import {
|
|
|
|
|
CreateProfileImageResponseDto,
|
|
|
|
|
mapCreateProfileImageResponse,
|
|
|
|
|
} from './response-dto/create-profile-image-response.dto';
|
2022-07-15 21:30:56 +02:00
|
|
|
import { IUserRepository, USER_REPOSITORY } from './user-repository';
|
2022-02-03 10:06:44 -06:00
|
|
|
|
|
|
|
|
@Injectable()
|
|
|
|
|
export class UserService {
|
|
|
|
|
constructor(
|
2022-07-15 21:30:56 +02:00
|
|
|
@Inject(USER_REPOSITORY)
|
|
|
|
|
private userRepository: IUserRepository,
|
2022-06-06 18:16:03 +02:00
|
|
|
) {}
|
2022-05-21 02:23:55 -05:00
|
|
|
|
2022-07-08 21:26:50 -05:00
|
|
|
async getAllUsers(authUser: AuthUserDto, isAll: boolean): Promise<UserResponseDto[]> {
|
2022-05-21 02:23:55 -05:00
|
|
|
if (isAll) {
|
2022-07-15 21:30:56 +02:00
|
|
|
const allUsers = await this.userRepository.getList();
|
2022-07-08 21:26:50 -05:00
|
|
|
return allUsers.map(mapUser);
|
2022-05-21 02:23:55 -05:00
|
|
|
}
|
2022-04-23 21:08:45 -05:00
|
|
|
|
2022-07-15 21:30:56 +02:00
|
|
|
const allUserExceptRequestedUser = await this.userRepository.getList({ excludeId: authUser.id });
|
2022-07-08 21:26:50 -05:00
|
|
|
|
|
|
|
|
return allUserExceptRequestedUser.map(mapUser);
|
2022-04-23 21:08:45 -05:00
|
|
|
}
|
2022-05-21 02:23:55 -05:00
|
|
|
|
2022-07-16 23:52:00 -05:00
|
|
|
async getUserById(userId: string): Promise<UserResponseDto> {
|
|
|
|
|
const user = await this.userRepository.get(userId);
|
|
|
|
|
if (!user) {
|
|
|
|
|
throw new NotFoundException('User not found');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return mapUser(user);
|
|
|
|
|
}
|
2022-07-17 15:09:26 -05:00
|
|
|
|
2022-07-08 21:26:50 -05:00
|
|
|
async getUserInfo(authUser: AuthUserDto): Promise<UserResponseDto> {
|
2022-07-15 21:30:56 +02:00
|
|
|
const user = await this.userRepository.get(authUser.id);
|
2022-07-08 21:26:50 -05:00
|
|
|
if (!user) {
|
|
|
|
|
throw new BadRequestException('User not found');
|
|
|
|
|
}
|
|
|
|
|
return mapUser(user);
|
2022-06-27 15:13:07 -05:00
|
|
|
}
|
|
|
|
|
|
2022-07-10 21:41:45 -05:00
|
|
|
async getUserCount(): Promise<UserCountResponseDto> {
|
2022-07-15 21:30:56 +02:00
|
|
|
const users = await this.userRepository.getList();
|
2022-05-21 02:23:55 -05:00
|
|
|
|
2022-07-08 21:26:50 -05:00
|
|
|
return mapUserCountResponse(users.length);
|
2022-05-21 02:23:55 -05:00
|
|
|
}
|
|
|
|
|
|
2022-06-25 19:53:06 +02:00
|
|
|
async createUser(createUserDto: CreateUserDto): Promise<UserResponseDto> {
|
2022-07-15 21:30:56 +02:00
|
|
|
const user = await this.userRepository.getByEmail(createUserDto.email);
|
2022-05-21 02:23:55 -05:00
|
|
|
|
|
|
|
|
if (user) {
|
|
|
|
|
throw new BadRequestException('User exists');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
try {
|
2022-07-15 21:30:56 +02:00
|
|
|
const savedUser = await this.userRepository.create(createUserDto);
|
2022-05-21 02:23:55 -05:00
|
|
|
|
2022-06-06 18:16:03 +02:00
|
|
|
return mapUser(savedUser);
|
2022-05-21 02:23:55 -05:00
|
|
|
} catch (e) {
|
|
|
|
|
Logger.error(e, 'Create new user');
|
|
|
|
|
throw new InternalServerErrorException('Failed to register new user');
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-09-18 09:27:06 -05:00
|
|
|
async updateUser(authUser: AuthUserDto, updateUserDto: UpdateUserDto): Promise<UserResponseDto> {
|
|
|
|
|
const requestor = await this.userRepository.get(authUser.id);
|
|
|
|
|
|
|
|
|
|
if (!requestor) {
|
|
|
|
|
throw new NotFoundException('Requestor not found');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!requestor.isAdmin) {
|
|
|
|
|
if (requestor.id !== updateUserDto.id) {
|
|
|
|
|
throw new BadRequestException('Unauthorized');
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-07-15 21:30:56 +02:00
|
|
|
const user = await this.userRepository.get(updateUserDto.id);
|
2022-06-25 19:53:06 +02:00
|
|
|
if (!user) {
|
|
|
|
|
throw new NotFoundException('User not found');
|
|
|
|
|
}
|
2022-05-21 02:23:55 -05:00
|
|
|
try {
|
2022-07-15 21:30:56 +02:00
|
|
|
const updatedUser = await this.userRepository.update(user, updateUserDto);
|
2022-05-21 02:23:55 -05:00
|
|
|
|
2022-07-08 21:26:50 -05:00
|
|
|
return mapUser(updatedUser);
|
2022-05-21 02:23:55 -05:00
|
|
|
} catch (e) {
|
2022-09-18 09:27:06 -05:00
|
|
|
Logger.error(e, 'Failed to update user info');
|
|
|
|
|
throw new InternalServerErrorException('Failed to update user info');
|
2022-05-21 02:23:55 -05:00
|
|
|
}
|
|
|
|
|
}
|
2022-05-27 22:15:35 -05:00
|
|
|
|
2022-07-08 21:26:50 -05:00
|
|
|
async createProfileImage(
|
|
|
|
|
authUser: AuthUserDto,
|
|
|
|
|
fileInfo: Express.Multer.File,
|
|
|
|
|
): Promise<CreateProfileImageResponseDto> {
|
2022-07-15 21:30:56 +02:00
|
|
|
const user = await this.userRepository.get(authUser.id);
|
|
|
|
|
if (!user) {
|
|
|
|
|
throw new NotFoundException('User not found');
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-27 22:15:35 -05:00
|
|
|
try {
|
2022-07-16 23:52:00 -05:00
|
|
|
await this.userRepository.createProfileImage(user, fileInfo);
|
2022-05-27 22:15:35 -05:00
|
|
|
|
2022-07-08 21:26:50 -05:00
|
|
|
return mapCreateProfileImageResponse(authUser.id, fileInfo.path);
|
2022-05-27 22:15:35 -05:00
|
|
|
} catch (e) {
|
|
|
|
|
Logger.error(e, 'Create User Profile Image');
|
|
|
|
|
throw new InternalServerErrorException('Failed to create new user profile image');
|
|
|
|
|
}
|
2022-05-27 22:24:58 -05:00
|
|
|
}
|
2022-05-27 22:15:35 -05:00
|
|
|
|
2022-05-27 22:24:58 -05:00
|
|
|
async getUserProfileImage(userId: string, res: Res) {
|
2022-05-28 22:35:45 -05:00
|
|
|
try {
|
2022-07-15 21:30:56 +02:00
|
|
|
const user = await this.userRepository.get(userId);
|
2022-06-25 19:53:06 +02:00
|
|
|
if (!user) {
|
|
|
|
|
throw new NotFoundException('User not found');
|
|
|
|
|
}
|
2022-06-03 11:04:30 -05:00
|
|
|
|
2022-05-28 22:35:45 -05:00
|
|
|
if (!user.profileImagePath) {
|
2022-07-10 21:41:45 -05:00
|
|
|
throw new NotFoundException('User does not have a profile image');
|
2022-05-28 22:35:45 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
res.set({
|
|
|
|
|
'Content-Type': 'image/jpeg',
|
|
|
|
|
});
|
2022-06-06 18:16:03 +02:00
|
|
|
const fileStream = createReadStream(user.profileImagePath);
|
2022-05-28 22:35:45 -05:00
|
|
|
return new StreamableFile(fileStream);
|
|
|
|
|
} catch (e) {
|
2022-07-10 21:41:45 -05:00
|
|
|
throw new NotFoundException('User does not have a profile image');
|
2022-05-28 22:35:45 -05:00
|
|
|
}
|
2022-05-27 22:15:35 -05:00
|
|
|
}
|
2022-02-03 10:06:44 -06:00
|
|
|
}
|