feat: allow user/edit/:id endpoint to upload avatar

This commit is contained in:
Mohamed Marrouchi 2025-01-06 18:54:02 +01:00
parent 57fcd9b3a3
commit 3721f4365e
2 changed files with 47 additions and 6 deletions

View File

@ -21,11 +21,14 @@ import {
Req,
Session,
UnauthorizedException,
UploadedFile,
UseInterceptors,
} from '@nestjs/common';
import { FileInterceptor } from '@nestjs/platform-express';
import { CsrfCheck } from '@tekuconcept/nestjs-csrf';
import { Request } from 'express';
import { Session as ExpressSession } from 'express-session';
import { diskStorage, memoryStorage } from 'multer';
import { AttachmentService } from '@/attachment/services/attachment.service';
import { config } from '@/config';
@ -261,17 +264,54 @@ export class ReadWriteUserController extends ReadOnlyUserController {
* @returns A promise that resolves to the updated user.
*/
@CsrfCheck(true)
@UseInterceptors(
FileInterceptor('avatar', {
limits: {
fileSize: config.parameters.maxUploadSize,
},
storage: (() => {
if (config.parameters.storageMode === 'memory') {
return memoryStorage();
} else {
return diskStorage({});
}
})(),
}),
)
@Patch('edit/:id')
async updateOne(
@Req() req: Request,
@Param('id') id: string,
@Body() userUpdate: UserEditProfileDto,
@UploadedFile() avatarFile?: Express.Multer.File,
) {
if (!('id' in req.user && req.user.id) || req.user.id !== id) {
throw new UnauthorizedException();
throw new ForbiddenException();
}
const result = await this.userService.updateOne(req.user.id, userUpdate);
// Upload Avatar if provided
const avatar = avatarFile
? await this.attachmentService.store(
avatarFile,
{
name: avatarFile.originalname,
size: avatarFile.size,
type: avatarFile.mimetype,
},
config.parameters.avatarDir,
)
: undefined;
const result = await this.userService.updateOne(
req.user.id,
avatar
? {
...userUpdate,
avatar: avatar.id,
}
: userUpdate,
);
if (!result) {
this.logger.warn(`Unable to update User by id ${id}`);
throw new NotFoundException(`User with ID ${id} not found`);

View File

@ -1,5 +1,5 @@
/*
* Copyright © 2024 Hexastack. All rights reserved.
* Copyright © 2025 Hexastack. All rights reserved.
*
* Licensed under the GNU Affero General Public License v3.0 (AGPLv3) with the following additional terms:
* 1. The name "Hexabot" is a trademark of Hexastack. You may not use this name in derivative works without express written permission.
@ -14,12 +14,12 @@ import {
PartialType,
} from '@nestjs/swagger';
import {
IsEmail,
IsNotEmpty,
IsString,
IsArray,
IsBoolean,
IsEmail,
IsNotEmpty,
IsOptional,
IsString,
} from 'class-validator';
import { IsObjectId } from '@/utils/validation-rules/is-object-id';
@ -66,6 +66,7 @@ export class UserCreateDto {
export class UserEditProfileDto extends OmitType(PartialType(UserCreateDto), [
'username',
'roles',
'avatar',
]) {
@ApiPropertyOptional({ description: 'User language', type: String })
@IsOptional()