fix: tighten edge cases across services (#3158)

This commit is contained in:
Hampus authored and GitHub committed 2026-10-03 13:04:29 +02:00
1 parent a9f7a23c0d
commit 4e6b837ccc
170 files changed
+2028 -421

No files matched your search

@@ -10,8 +10,11 @@ import {dispatchMessageCreateBroadcast} from '@app/api/channel/services/message/
import type {MessagePersistenceService} from '@app/api/channel/services/message/MessagePersistenceService';
import type {IGuildRepositoryAggregate} from '@app/api/guild/repositories/IGuildRepositoryAggregate';
import type {IGatewayService} from '@app/api/infrastructure/IGatewayService';
import type {ILiveKitService} from '@app/api/infrastructure/ILiveKitService';
import type {ISnowflakeService} from '@app/api/infrastructure/ISnowflakeService';
import type {IVoiceRoomStore} from '@app/api/infrastructure/IVoiceRoomStore';
import type {UserCacheService} from '@app/api/infrastructure/UserCacheService';
import {Logger} from '@app/api/Logger';
import type {LimitConfigService} from '@app/api/limits/LimitConfigService';
import {resolveLimitSafe} from '@app/api/limits/LimitConfigUtils';
import {createLimitMatchContext} from '@app/api/limits/LimitMatchContextBuilder';
@@ -47,6 +50,8 @@ export class GroupDmOperationsService {
private snowflakeService: ISnowflakeService,
private messagePersistenceService: MessagePersistenceService,
private readonly limitConfigService: LimitConfigService,
private readonly voiceRoomStore: IVoiceRoomStore,
private readonly liveKitService: ILiveKitService,
) {
this.userPermissionUtils = new UserPermissionUtils(userRepository, guildRepository);
}
@@ -258,6 +263,7 @@ export class GroupDmOperationsService {
await deleteChannelMessageSearchDocuments(channelId, {context: {source: 'group_dm_delete'}});
await this.channelRepository.channelData.delete(channelId);
await this.userRepository.closeDmForUser(recipientId, channelId);
await this.disconnectRemovedRecipientFromCall(channelId, recipientId);
await dispatchChannelDelete({
channel,
requestCache,
@@ -275,6 +281,7 @@ export class GroupDmOperationsService {
nicks: updatedNicknames.size > 0 ? updatedNicknames : null,
});
await this.userRepository.closeDmForUser(recipientId, channelId);
await this.disconnectRemovedRecipientFromCall(channelId, recipientId);
const recipientUserResponse = await this.userCacheService.getUserPartialResponse(recipientId, requestCache);
for (const recId of updatedRecipientIds) {
await this.gatewayService.dispatchPresence({
@@ -319,6 +326,31 @@ export class GroupDmOperationsService {
);
}
private async disconnectRemovedRecipientFromCall(channelId: ChannelID, recipientId: UserID): Promise<void> {
try {
const {voiceStates} = await this.gatewayService.getVoiceStatesForChannel({channelId});
await this.gatewayService.disconnectVoiceUserIfInChannel({channelId, userId: recipientId});
const recipientVoiceStates = voiceStates.filter((voiceState) => voiceState.userId === recipientId.toString());
if (recipientVoiceStates.length === 0) return;
const pinnedServer = await this.voiceRoomStore.getPinnedRoomServer(undefined, channelId);
if (!pinnedServer) return;
for (const voiceState of recipientVoiceStates) {
await this.liveKitService.disconnectParticipant({
userId: recipientId,
channelId,
connectionId: voiceState.connectionId,
regionId: pinnedServer.regionId,
serverId: pinnedServer.serverId,
});
}
} catch (error) {
Logger.error(
{error, channelId: channelId.toString(), userId: recipientId.toString()},
'Failed to disconnect removed group DM recipient from call',
);
}
}
private async syncGroupDmRecipientsForUser(userId: UserID): Promise<void> {
const channels = await this.userRepository.listPrivateChannels(userId);
const groupDmChannels = channels.filter((ch) => ch.type === ChannelTypes.GROUP_DM);