feat: implement avatar upload functionality with presigned URL support for user profiles and announcement attachments.

This commit is contained in:
JakkrapartXD 2026-01-28 11:49:11 +07:00
parent bacb8a3824
commit 53314dfd7e
5 changed files with 192 additions and 26 deletions

View file

@ -1,4 +1,4 @@
import { Get, Body, Post, Route, Tags, SuccessResponse, Response, Example, Controller, Security, Request, Put } from 'tsoa';
import { Get, Body, Post, Route, Tags, SuccessResponse, Response, Example, Controller, Security, Request, Put, UploadedFile } from 'tsoa';
import { ValidationError } from '../middleware/errorHandler';
import { UserService } from '../services/user.service';
import {
@ -7,7 +7,8 @@ import {
ProfileUpdate,
ProfileUpdateResponse,
ChangePasswordRequest,
ChangePasswordResponse
ChangePasswordResponse,
updateAvatarResponse
} from '../types/user.types';
import { ChangePassword } from '../types/auth.types';
import { profileUpdateSchema, changePasswordSchema } from "../validators/user.validator";
@ -78,4 +79,31 @@ export class UserController {
return await this.userService.changePassword(token, body.oldPassword, body.newPassword);
}
/**
* Upload user avatar picture
* @param request Express request object with JWT token in Authorization header
* @param file Avatar image file
*/
@Post('upload-avatar')
@Security('jwt')
@SuccessResponse('200', 'Avatar uploaded successfully')
@Response('401', 'Invalid or expired token')
@Response('400', 'Validation error')
public async uploadAvatar(
@Request() request: any,
@UploadedFile() file: Express.Multer.File
): Promise<updateAvatarResponse> {
const token = request.headers.authorization?.replace('Bearer ', '');
if (!token) throw new ValidationError('No token provided');
// Validate file type (images only)
if (!file.mimetype?.startsWith('image/')) throw new ValidationError('Only image files are allowed');
// Validate file size (max 5MB)
const maxSize = 5 * 1024 * 1024; // 5MB
if (file.size > maxSize) throw new ValidationError('File size must be less than 5MB');
return await this.userService.uploadAvatarPicture(token, file);
}
}