diff --git a/app/lib/constants/defaultSettings.ts b/app/lib/constants/defaultSettings.ts index ab1b4ea150..290d447ff7 100644 --- a/app/lib/constants/defaultSettings.ts +++ b/app/lib/constants/defaultSettings.ts @@ -258,5 +258,11 @@ export const defaultSettings = { Accounts_ConfirmPasswordPlaceholder: { type: 'valueAsString' }, + E2E_Enabled_Mentions: { + type: 'valueAsBoolean' + }, + UTF8_User_Names_Validation: { + type: 'valueAsString' + }, ...deprecatedSettings } as const; diff --git a/app/lib/encryption/room.ts b/app/lib/encryption/room.ts index 10cd50fda0..247d6f9f87 100644 --- a/app/lib/encryption/room.ts +++ b/app/lib/encryption/room.ts @@ -16,6 +16,7 @@ import { bufferToB64, bufferToB64URI, bufferToUtf8, + getE2EEMentions, encryptAESCTR, exportAESCTR, generateAESCTRKey, @@ -245,6 +246,7 @@ export default class EncryptionRoom { t: E2E_MESSAGE_TYPE, e2e: E2E_STATUS.PENDING, msg, + e2eMentions: getE2EEMentions(message.msg), content: { algorithm: 'rc.v1.aes-sha2' as const, ciphertext: await this.encryptText( diff --git a/app/lib/encryption/utils.ts b/app/lib/encryption/utils.ts index a79a55a6cd..71787799f1 100644 --- a/app/lib/encryption/utils.ts +++ b/app/lib/encryption/utils.ts @@ -59,6 +59,24 @@ export const toString = (thing: string | ByteBuffer | Buffer | ArrayBuffer | Uin // @ts-ignore return new ByteBuffer.wrap(thing).toString('binary'); }; + +// https://github.com/RocketChat/Rocket.Chat/blob/b94db45cab297a3bcbafca4d135d83c898222380/apps/meteor/app/mentions/lib/MentionsParser.ts#L50 +const userMentionRegex = (pattern: string) => new RegExp(`(^|\\s|>)@(${pattern}(@(${pattern}))?(:([0-9a-zA-Z-_.]+))?)`, 'gm'); +const channelMentionRegex = (pattern: string) => new RegExp(`(^|\\s|>)#(${pattern}(@(${pattern}))?)`, 'gm'); + +export const getE2EEMentions = (message?: string) => { + const e2eEnabledMentions = store.getState().settings.E2E_Enabled_Mentions; + if (!e2eEnabledMentions || !message) { + return undefined; + } + const utf8UserNamesValidation = store.getState().settings.UTF8_User_Names_Validation as string; + + return { + e2eUserMentions: (message.match(userMentionRegex(utf8UserNamesValidation)) || []).map(match => match.trim()), + e2eChannelMentions: (message.match(channelMentionRegex(utf8UserNamesValidation)) || []).map(match => match.trim()) + }; +}; + export const randomPassword = async (): Promise => { const random = await Promise.all(Array.from({ length: 4 }, () => SimpleCrypto.utils.getRandomValues(3))); return `${random[0]}-${random[1]}-${random[2]}-${random[3]}`;