feat: implement privacy-aware profile visibility and activity status filtering using optional authentication guard

This commit is contained in:
pradeepkumar
2026-03-28 18:46:49 +05:30
parent ba931c350b
commit a71145f6a6
8 changed files with 235 additions and 38 deletions

View File

@@ -12,6 +12,8 @@ import { JwtService } from '@nestjs/jwt';
import { ConfigService } from '@nestjs/config';
import { MessagesService } from './messages.service';
import { SupportChatService } from '../support-chat/support-chat.service';
import { ConnectionRequestsService } from '../connection-requests/connection-requests.service';
import { PrismaService } from '../prisma/prisma.service';
import { CreateMessageDto } from './dto';
import { Logger } from '@nestjs/common';
@@ -37,6 +39,8 @@ export class MessagesGateway implements OnGatewayConnection, OnGatewayDisconnect
constructor(
private readonly messagesService: MessagesService,
private readonly supportChatService: SupportChatService,
private readonly connectionRequestsService: ConnectionRequestsService,
private readonly prisma: PrismaService,
private readonly jwtService: JwtService,
private readonly configService: ConfigService,
) {}
@@ -415,14 +419,46 @@ export class MessagesGateway implements OnGatewayConnection, OnGatewayDisconnect
}
/**
* Broadcast user online/offline status
* Broadcast user online/offline status respecting activity_status privacy setting
*/
private broadcastUserStatus(userId: string, isOnline: boolean) {
this.server.emit('user_status_change', {
private async broadcastUserStatus(userId: string, isOnline: boolean) {
const statusEvent = {
userId,
isOnline,
lastSeenAt: isOnline ? null : new Date(),
});
};
try {
// Get user's activity_status privacy setting
const user = await this.prisma.user.findUnique({
where: { id: userId },
select: { privacyPreferences: true },
});
const prefs = user?.privacyPreferences as any;
const activityStatus = prefs?.privacySettings?.activity_status || 'public';
if (activityStatus === 'private') {
// Don't broadcast status to anyone
return;
}
if (activityStatus === 'connections') {
// Only send status to connected users
const connectedIds = await this.connectionRequestsService.getConnectedUserIds(userId);
for (const connectedId of connectedIds) {
this.sendToUser(connectedId, 'user_status_change', statusEvent);
}
return;
}
// 'public' — broadcast to everyone
this.server.emit('user_status_change', statusEvent);
} catch (err) {
// Fallback to public broadcast if privacy check fails
this.logger.warn(`Privacy check failed for ${userId}, broadcasting publicly: ${err.message}`);
this.server.emit('user_status_change', statusEvent);
}
}
/**