family update

This commit is contained in:
lendry
2026-06-24 23:17:24 +03:00
parent 9727cf3f35
commit f2366a69a0
18 changed files with 1374 additions and 103 deletions

View File

@@ -128,11 +128,11 @@ export class MediaService {
throw new ForbiddenException('Ссылка недействительна');
}
if (payload.objectKey.startsWith('chat/')) {
if (payload.objectKey.startsWith('chat/') || payload.objectKey.startsWith('chat-rooms/')) {
if (!requesterId) {
throw new ForbiddenException('Для доступа к файлу чата требуется авторизация');
}
const roomId = payload.roomId ?? this.extractChatRoomId(payload.objectKey);
const roomId = payload.roomId ?? this.extractChatRoomId(payload.objectKey) ?? this.extractChatRoomAvatarRoomId(payload.objectKey);
if (!roomId) {
throw new ForbiddenException('Некорректный ключ файла чата');
}
@@ -238,6 +238,39 @@ export class MediaService {
return this.createStreamAccessUrl(storageKey, requesterId, { roomId, fileName });
}
async createChatRoomAvatarUploadUrl(requesterId: string, roomId: string, contentType: string) {
await this.assertChatMember(roomId, requesterId);
try {
this.minio.assertImageContentType(contentType);
} catch (error) {
throw new BadRequestException(error instanceof Error ? error.message : 'Некорректный тип файла');
}
const extension = this.minio.extensionForContentType(contentType);
const storageKey = `chat-rooms/${roomId}/${crypto.randomUUID()}.${extension}`;
return this.createUploadTarget(requesterId, storageKey, contentType);
}
async confirmChatRoomAvatar(requesterId: string, roomId: string, storageKey: string) {
await this.assertChatMember(roomId, requesterId);
if (!storageKey.startsWith(`chat-rooms/${roomId}/`)) {
throw new BadRequestException('Некорректный ключ аватара чата');
}
await this.prisma.chatRoom.update({
where: { id: roomId },
data: { avatarStorageKey: storageKey, hasAvatar: true }
});
return { roomId, hasAvatar: true };
}
async getChatRoomAvatarAccessUrl(requesterId: string, roomId: string) {
await this.assertChatMember(roomId, requesterId);
const room = await this.prisma.chatRoom.findUnique({ where: { id: roomId } });
if (!room?.avatarStorageKey) {
throw new NotFoundException('Аватар чата не найден');
}
return this.createStreamAccessUrl(room.avatarStorageKey, requesterId, { roomId });
}
private extractChatRoomId(storageKey: string) {
const [prefix, roomId] = storageKey.split('/');
if (prefix !== 'chat' || !roomId) {
@@ -246,6 +279,14 @@ export class MediaService {
return roomId;
}
private extractChatRoomAvatarRoomId(storageKey: string) {
const [prefix, roomId] = storageKey.split('/');
if (prefix !== 'chat-rooms' || !roomId) {
return null;
}
return roomId;
}
private async createUploadTarget(userId: string, storageKey: string, contentType: string) {
const viaApi = this.config.get<string>('MINIO_UPLOAD_VIA_API', 'true') !== 'false';
const expiresAt = new Date(Date.now() + UPLOAD_TTL_SECONDS * 1000).toISOString();