feat: add presigned URL generation for user avatar URLs in user management service

Convert formatUserResponse to async method to support presigned URL generation for avatar_url field. Add getAvatarPresignedUrl helper method to generate 1-hour expiry presigned URLs for user avatars. Update listUsers and getUserById to await formatUserResponse calls.
This commit is contained in:
JakkrapartXD 2026-02-04 16:54:44 +07:00
parent 2728af9efe
commit a0b93978a7

View file

@ -13,6 +13,7 @@ import {
} from '../types/usersmanagement.types';
import { UserResponse } from '../types/user.types';
import { UnauthorizedError, ValidationError, ForbiddenError } from '../middleware/errorHandler';
import { getPresignedUrl } from '../config/minio';
export class UserManagementService {
async listUsers(): Promise<ListUsersResponse> {
@ -32,7 +33,7 @@ export class UserManagementService {
code: 200,
message: 'Users fetched successfully',
total: users.length,
data: users.map(user => this.formatUserResponse(user))
data: await Promise.all(users.map(user => this.formatUserResponse(user)))
};
} catch (error) {
logger.error('Failed to fetch users', { error });
@ -54,7 +55,7 @@ export class UserManagementService {
return {
code: 200,
message: 'User fetched successfully',
data: this.formatUserResponse(user)
data: await this.formatUserResponse(user)
};
} catch (error) {
logger.error('Failed to fetch user by ID', { error });
@ -178,7 +179,7 @@ export class UserManagementService {
/**
* Format user response
*/
private formatUserResponse(user: any): UserResponse {
private async formatUserResponse(user: any): Promise<UserResponse> {
return {
id: user.id,
username: user.username,
@ -194,10 +195,22 @@ export class UserManagementService {
prefix: user.profile.prefix as { th?: string; en?: string } | undefined,
first_name: user.profile.first_name,
last_name: user.profile.last_name,
avatar_url: user.profile.avatar_url,
avatar_url: user.profile.avatar_url ? await this.getAvatarPresignedUrl(user.profile.avatar_url) : null,
birth_date: user.profile.birth_date,
phone: user.profile.phone
} : undefined
};
}
/**
* Get presigned URL for avatar
*/
private async getAvatarPresignedUrl(avatarPath: string): Promise<string> {
try {
return await getPresignedUrl(avatarPath, 3600); // 1 hour expiry
} catch (error) {
logger.warn(`Failed to generate presigned URL for avatar: ${error}`);
throw error;
}
}
}