update and fix messanger
This commit is contained in:
@@ -5,6 +5,7 @@ import { GetObjectCommand } from '@aws-sdk/client-s3';
|
||||
import { PrismaService } from '../infra/prisma.service';
|
||||
import { AccessService } from './access.service';
|
||||
import { ChatService } from './chat.service';
|
||||
import { NotificationsService } from './notifications.service';
|
||||
import { MinioService } from '../infra/minio.service';
|
||||
|
||||
const AVATAR_ACCESS_TTL_SECONDS = 900;
|
||||
@@ -34,7 +35,8 @@ export class MediaService {
|
||||
private readonly jwt: JwtService,
|
||||
private readonly config: ConfigService,
|
||||
private readonly access: AccessService,
|
||||
private readonly chat: ChatService
|
||||
private readonly chat: ChatService,
|
||||
private readonly notifications: NotificationsService
|
||||
) {}
|
||||
|
||||
async createAvatarUploadUrl(userId: string, contentType: string) {
|
||||
@@ -61,6 +63,8 @@ export class MediaService {
|
||||
}
|
||||
});
|
||||
|
||||
await this.publishUserAvatarUpdated(userId);
|
||||
|
||||
return { userId, hasAvatar: true };
|
||||
}
|
||||
|
||||
@@ -70,12 +74,7 @@ export class MediaService {
|
||||
throw new NotFoundException('Аватар не найден');
|
||||
}
|
||||
|
||||
if (requesterId !== targetUserId) {
|
||||
const requester = await this.prisma.user.findUnique({ where: { id: requesterId } });
|
||||
if (!requester?.isSuperAdmin) {
|
||||
throw new ForbiddenException('Нет доступа к аватару пользователя');
|
||||
}
|
||||
}
|
||||
await this.assertCanViewUserAvatar(requesterId, targetUserId);
|
||||
|
||||
const token = await this.jwt.signAsync(
|
||||
{
|
||||
@@ -130,11 +129,11 @@ export class MediaService {
|
||||
throw new ForbiddenException('Ссылка недействительна');
|
||||
}
|
||||
|
||||
if (payload.objectKey.startsWith('chat/') || payload.objectKey.startsWith('chat-rooms/')) {
|
||||
if (payload.objectKey.startsWith('chat/')) {
|
||||
if (!requesterId) {
|
||||
throw new ForbiddenException('Для доступа к файлу чата требуется авторизация');
|
||||
}
|
||||
const roomId = payload.roomId ?? this.extractChatRoomId(payload.objectKey) ?? this.extractChatRoomAvatarRoomId(payload.objectKey);
|
||||
const roomId = payload.roomId ?? this.extractChatRoomId(payload.objectKey);
|
||||
if (!roomId) {
|
||||
throw new ForbiddenException('Некорректный ключ файла чата');
|
||||
}
|
||||
@@ -360,4 +359,60 @@ export class MediaService {
|
||||
throw new ForbiddenException('Нет доступа к чату');
|
||||
}
|
||||
}
|
||||
|
||||
private async publishUserAvatarUpdated(userId: string) {
|
||||
const memberships = await this.prisma.familyMember.findMany({
|
||||
where: { userId },
|
||||
select: { groupId: true }
|
||||
});
|
||||
const groupIds = memberships.map((member) => member.groupId);
|
||||
if (!groupIds.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
const coMembers = await this.prisma.familyMember.findMany({
|
||||
where: { groupId: { in: groupIds }, userId: { not: userId } },
|
||||
select: { userId: true }
|
||||
});
|
||||
const recipientIds = [...new Set(coMembers.map((member) => member.userId))];
|
||||
await Promise.all(
|
||||
recipientIds.map((memberId) =>
|
||||
this.notifications.publishRealtime(memberId, 'user_avatar_updated', '', '', { userId })
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
private async assertCanViewUserAvatar(requesterId: string, targetUserId: string) {
|
||||
if (requesterId === targetUserId) {
|
||||
return;
|
||||
}
|
||||
|
||||
const requester = await this.prisma.user.findUnique({ where: { id: requesterId } });
|
||||
if (requester?.isSuperAdmin) {
|
||||
return;
|
||||
}
|
||||
|
||||
const [requesterFamilies, targetFamilies] = await Promise.all([
|
||||
this.prisma.familyMember.findMany({ where: { userId: requesterId }, select: { groupId: true } }),
|
||||
this.prisma.familyMember.findMany({ where: { userId: targetUserId }, select: { groupId: true } })
|
||||
]);
|
||||
const targetGroupIds = new Set(targetFamilies.map((member) => member.groupId));
|
||||
if (requesterFamilies.some((member) => targetGroupIds.has(member.groupId))) {
|
||||
return;
|
||||
}
|
||||
|
||||
const sharedChat = await this.prisma.chatRoomMember.findFirst({
|
||||
where: {
|
||||
userId: requesterId,
|
||||
room: {
|
||||
members: {
|
||||
some: { userId: targetUserId }
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
if (!sharedChat) {
|
||||
throw new ForbiddenException('Нет доступа к аватару пользователя');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user