Merge branch 'security' into security-encrypted-images
This commit is contained in:
commit
17917f3257
|
@ -18,6 +18,10 @@ import { Utils } from 'common';
|
|||
import E2EEComponent from './E2EEComponent.vue';
|
||||
import E2EEMessageButton from './E2EEMessageButton.vue';
|
||||
|
||||
const userMentionPattern = new RegExp(`<@!?([0-9]{10,})>`, "g");
|
||||
const roleMentionPattern = new RegExp(`<@&([0-9]{10,})>`, "g");
|
||||
const everyoneMentionPattern = new RegExp(`(?:\\s+|^)@everyone(?:\\s+|$)`);
|
||||
|
||||
const TEMP_KEY = 'temporarymasterkey';
|
||||
let seed;
|
||||
|
||||
|
@ -75,11 +79,10 @@ export default new class E2EE extends BuiltinModule {
|
|||
}
|
||||
|
||||
async enabled(e) {
|
||||
window._sec = Security;
|
||||
seed = Security.randomBytes();
|
||||
// TODO Input modal for key
|
||||
this.master = Security.encrypt(seed, TEMP_KEY);
|
||||
|
||||
this.patchDispatcher();
|
||||
this.patchMessageContent();
|
||||
const selector = '.' + WebpackModules.getClassName('channelTextArea', 'emojiButton');
|
||||
const cta = await ReactComponents.getComponent('ChannelTextArea', { selector });
|
||||
|
@ -88,6 +91,38 @@ export default new class E2EE extends BuiltinModule {
|
|||
cta.forceUpdateAll();
|
||||
}
|
||||
|
||||
patchDispatcher() {
|
||||
const Dispatcher = WebpackModules.getModuleByName('Dispatcher');
|
||||
MonkeyPatch('BD:E2EE', Dispatcher).before('dispatch', (_, [event]) => {
|
||||
if (event.type !== "MESSAGE_CREATE") return;
|
||||
|
||||
const key = this.getKey(event.message.channel_id);
|
||||
if (!key) return; // We don't have a key for this channel
|
||||
|
||||
if (typeof event.message.content !== 'string') return; // Ignore any non string content
|
||||
if (!event.message.content.startsWith('$:')) return; // Not an encrypted string
|
||||
let decrypt;
|
||||
try {
|
||||
decrypt = this.decrypt(this.decrypt(this.decrypt(seed, this.master), key), event.message.content);
|
||||
} catch (err) { return } // Ignore errors such as non empty
|
||||
|
||||
const MessageParser = WebpackModules.getModuleByName('MessageParser');
|
||||
const Permissions = WebpackModules.getModuleByName('GuildPermissions');
|
||||
const DiscordConstants = WebpackModules.getModuleByName('DiscordConstants');
|
||||
const currentChannel = DiscordApi.Channel.fromId(event.message.channel_id).discordObject;
|
||||
|
||||
// Create a generic message object to parse mentions with
|
||||
const parsed = MessageParser.parse(currentChannel, decrypt).content;
|
||||
|
||||
if (userMentionPattern.test(parsed))
|
||||
event.message.mentions = parsed.match(userMentionPattern).map(m => {return {id: m.replace(/[^0-9]/g, '')}});
|
||||
if (roleMentionPattern.test(parsed))
|
||||
event.message.mention_roles = parsed.match(roleMentionPattern).map(m => m.replace(/[^0-9]/g, ''));
|
||||
if (everyoneMentionPattern.test(parsed))
|
||||
event.message.mention_everyone = Permissions.can(DiscordConstants.Permissions.MENTION_EVERYONE, currentChannel);
|
||||
});
|
||||
}
|
||||
|
||||
async patchMessageContent() {
|
||||
const selector = '.' + WebpackModules.getClassName('container', 'containerCozy', 'containerCompact', 'edited');
|
||||
const MessageContent = await ReactComponents.getComponent('MessageContent', { selector });
|
||||
|
@ -97,29 +132,45 @@ export default new class E2EE extends BuiltinModule {
|
|||
MonkeyPatch('BD:E2EE', ImageWrapper.component.prototype).before('render', this.beforeRenderImageWrapper.bind(this));
|
||||
}
|
||||
|
||||
beforeRenderMessageContent(component, args, retVal) {
|
||||
const key = this.getKey(DiscordApi.currentChannel.id);
|
||||
beforeRenderMessageContent(component) {
|
||||
if (!component.props || !component.props.message) return;
|
||||
|
||||
const key = this.getKey(component.props.message.channel_id);
|
||||
if (!key) return; // We don't have a key for this channel
|
||||
|
||||
const Message = WebpackModules.getModuleByPrototypes(['isMentioned']);
|
||||
const MessageParser = WebpackModules.getModuleByName('MessageParser');
|
||||
const currentChannel = DiscordApi.currentChannel.discordObject;
|
||||
|
||||
if (!component.props || !component.props.message) return;
|
||||
const { content } = component.props.message;
|
||||
if (typeof content !== 'string') return; // Ignore any non string content
|
||||
if (!content.startsWith('$:')) return; // Not an encrypted string
|
||||
const Permissions = WebpackModules.getModuleByName('GuildPermissions');
|
||||
const DiscordConstants = WebpackModules.getModuleByName('DiscordConstants');
|
||||
const currentChannel = DiscordApi.Channel.fromId(component.props.message.channel_id).discordObject;
|
||||
|
||||
if (typeof component.props.message.content !== 'string') return; // Ignore any non string content
|
||||
if (!component.props.message.content.startsWith('$:')) return; // Not an encrypted string
|
||||
let decrypt;
|
||||
try {
|
||||
decrypt = Security.decrypt(seed, [this.master, key, component.props.message.content]);
|
||||
} catch (err) { return } // Ignore errors such as non empty
|
||||
|
||||
component.props.message.bd_encrypted = true;
|
||||
component.props.message.bd_encrypted = true; // signal as encrypted
|
||||
|
||||
// Create a generic message object to parse mentions with
|
||||
const message = MessageParser.createMessage(currentChannel.id, MessageParser.parse(currentChannel, decrypt).content);
|
||||
|
||||
if (userMentionPattern.test(message.content))
|
||||
message.mentions = message.content.match(userMentionPattern).map(m => {return {id: m.replace(/[^0-9]/g, '')}});
|
||||
if (roleMentionPattern.test(message.content))
|
||||
message.mention_roles = message.content.match(roleMentionPattern).map(m => m.replace(/[^0-9]/g, ''));
|
||||
if (everyoneMentionPattern.test(message.content))
|
||||
message.mention_everyone = Permissions.can(DiscordConstants.Permissions.MENTION_EVERYONE, currentChannel);
|
||||
|
||||
// Create a new message to parse it properly
|
||||
const create = Message.create(MessageParser.createMessage(currentChannel, MessageParser.parse(currentChannel, decrypt).content));
|
||||
const create = Message.create(message);
|
||||
if (!create.content || !create.contentParsed) return;
|
||||
|
||||
component.props.message.mentions = create.mentions;
|
||||
component.props.message.mentionRoles = create.mentionRoles;
|
||||
component.props.message.mentionEveryone = create.mentionEveryone;
|
||||
component.props.message.mentioned = create.mentioned;
|
||||
component.props.message.content = create.content;
|
||||
component.props.message.contentParsed = create.contentParsed;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue