From 5ca458dada2006381ab35258c2f03cb726dca9c2 Mon Sep 17 00:00:00 2001 From: Hampus Date: Sun, 4 Oct 2026 16:59:04 +0200 Subject: [PATCH] fix(mentions): ignore @everyone and @here in one-to-one DMs (#3199) --- .../services/message/MessageMentionService.ts | 4 ++ .../channel/tests/DMEveryoneMention.test.ts | 44 +++++++++++++++++++ .../lexical/composer/specialMentions.ts | 4 +- .../features/messaging/utils/MessageUtils.ts | 2 +- 4 files changed, 51 insertions(+), 3 deletions(-) create mode 100644 fluxer_api/src/api/channel/tests/DMEveryoneMention.test.ts diff --git a/fluxer_api/src/api/channel/services/message/MessageMentionService.ts b/fluxer_api/src/api/channel/services/message/MessageMentionService.ts index e952ba4ee..b0232fbcd 100644 --- a/fluxer_api/src/api/channel/services/message/MessageMentionService.ts +++ b/fluxer_api/src/api/channel/services/message/MessageMentionService.ts @@ -90,6 +90,10 @@ export class MessageMentionService { const roleMentions = allMentions.roles; const channelMentions = allMentions.channels; const isDMChannel = channelType === ChannelTypes.DM || channelType === ChannelTypes.DM_PERSONAL_NOTES; + if (isDMChannel) { + mentionsEveryone = false; + mentionsHere = false; + } const shouldAddReferencedUser = referencedMessage?.authorId && referencedMessage.authorId !== message.authorId && diff --git a/fluxer_api/src/api/channel/tests/DMEveryoneMention.test.ts b/fluxer_api/src/api/channel/tests/DMEveryoneMention.test.ts new file mode 100644 index 000000000..0e0ff0475 --- /dev/null +++ b/fluxer_api/src/api/channel/tests/DMEveryoneMention.test.ts @@ -0,0 +1,44 @@ +// SPDX-License-Identifier: AGPL-3.0-or-later + +import {createTestAccount} from '@app/api/auth/tests/AuthTestUtils'; +import { + createDmChannel, + createFriendship, + createGroupDmChannel, + sendChannelMessage, +} from '@app/api/channel/tests/ChannelTestUtils'; +import {type ApiTestHarness, createApiTestHarness} from '@app/api/test/ApiTestHarness'; +import {afterAll, beforeAll, beforeEach, describe, expect, it} from 'vitest'; + +describe('DM everyone mention', () => { + let harness: ApiTestHarness; + beforeAll(async () => { + harness = await createApiTestHarness(); + }); + beforeEach(async () => { + await harness.reset(); + }); + afterAll(async () => { + await harness?.shutdown(); + }); + it('does not mention everyone in a one-to-one DM', async () => { + const user1 = await createTestAccount(harness); + const user2 = await createTestAccount(harness); + await createFriendship(harness, user1, user2); + const dm = await createDmChannel(harness, user1.token, user2.userId); + const everyone = await sendChannelMessage(harness, user1.token, dm.id, '@everyone test'); + const here = await sendChannelMessage(harness, user1.token, dm.id, '@here test'); + expect(everyone.mention_everyone).toBe(false); + expect(here.mention_everyone).toBe(false); + }); + it('still mentions everyone in a group DM', async () => { + const user1 = await createTestAccount(harness); + const user2 = await createTestAccount(harness); + const user3 = await createTestAccount(harness); + await createFriendship(harness, user1, user2); + await createFriendship(harness, user1, user3); + const groupDm = await createGroupDmChannel(harness, user1.token, [user2.userId, user3.userId]); + const message = await sendChannelMessage(harness, user1.token, groupDm.id, '@everyone test'); + expect(message.mention_everyone).toBe(true); + }); +}); diff --git a/fluxer_app/src/features/lexical/composer/specialMentions.ts b/fluxer_app/src/features/lexical/composer/specialMentions.ts index a71769db0..16cf7cec1 100644 --- a/fluxer_app/src/features/lexical/composer/specialMentions.ts +++ b/fluxer_app/src/features/lexical/composer/specialMentions.ts @@ -26,7 +26,7 @@ export function createSpecialMentionPayload(kind: SpecialMentionKind): ComposerI } export function areSpecialMentionsAllowed( - channel: Pick | null, + channel: Pick | null, allowSpecialMentions: boolean | undefined, allowedTriggers: ReadonlyArray | undefined, canMentionEveryone: boolean, @@ -34,7 +34,7 @@ export function areSpecialMentionsAllowed( if (channel == null || allowSpecialMentions === false || !isAutocompleteTriggerAllowed('mention', allowedTriggers)) { return false; } - return channel.guildId == null ? !channel.isPersonalNotes() : canMentionEveryone; + return channel.guildId == null ? channel.isGroupDM() : canMentionEveryone; } export function hasOpenCodeFence(text: string): boolean { diff --git a/fluxer_app/src/features/messaging/utils/MessageUtils.ts b/fluxer_app/src/features/messaging/utils/MessageUtils.ts index e2cd69819..cba03cde9 100644 --- a/fluxer_app/src/features/messaging/utils/MessageUtils.ts +++ b/fluxer_app/src/features/messaging/utils/MessageUtils.ts @@ -17,7 +17,7 @@ export function isMentioned(user: User, message: Message): boolean { return false; } const suppressEveryone = UserGuildSettings.isEveryoneMentionSuppressed(channel.guildId ?? null); - const mentionEveryone = message.mentionEveryone && !suppressEveryone; + const mentionEveryone = message.mentionEveryone && !channel.isDM() && !suppressEveryone; if (mentionEveryone) { return true; }