From 32d4efc1cda4fa6072230168060683f4ea0356ba Mon Sep 17 00:00:00 2001 From: martgil Date: Wed, 27 Nov 2024 18:07:54 +0800 Subject: [PATCH 1/7] initial commit --- .../generic/webmail-element-replacer.ts | 2 +- .../webmail/gmail/gmail-element-replacer.ts | 19 ++++++++++++------- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/extension/js/content_scripts/webmail/generic/webmail-element-replacer.ts b/extension/js/content_scripts/webmail/generic/webmail-element-replacer.ts index ed5fbf06606..e08b5c202c3 100644 --- a/extension/js/content_scripts/webmail/generic/webmail-element-replacer.ts +++ b/extension/js/content_scripts/webmail/generic/webmail-element-replacer.ts @@ -9,7 +9,7 @@ export abstract class WebmailElementReplacer { private replacePgpElsInterval: number; public abstract getIntervalFunctions: () => IntervalFunction[]; - public abstract setReplyBoxEditable: () => Promise; + public abstract setReplyBoxEditable: (messageContainer?: JQuery) => Promise; public abstract reinsertReplyBox: (replyMsgId: string) => void; public abstract scrollToReplyBox: (replyMsgId: string) => void; public abstract scrollToCursorInReplyBox: (replyMsgId: string, cursorOffsetTop: number) => void; diff --git a/extension/js/content_scripts/webmail/gmail/gmail-element-replacer.ts b/extension/js/content_scripts/webmail/gmail/gmail-element-replacer.ts index a691c7be657..5a6c0c72c99 100644 --- a/extension/js/content_scripts/webmail/gmail/gmail-element-replacer.ts +++ b/extension/js/content_scripts/webmail/gmail/gmail-element-replacer.ts @@ -85,16 +85,17 @@ export class GmailElementReplacer extends WebmailElementReplacer { ]; }; - public setReplyBoxEditable = async () => { + public setReplyBoxEditable = async (messageContainer?: JQuery) => { const replyContainerIframe = $('.reply_message_iframe_container > iframe').last(); - if (replyContainerIframe.length) { - $(replyContainerIframe).replaceWith(this.factory.embeddedReply(this.getLastMsgReplyParams(this.getConvoRootEl(replyContainerIframe[0])), true)); // xss-safe-value + if (replyContainerIframe.length && messageContainer) { + $(replyContainerIframe).replaceWith(this.factory.embeddedReply(this.getLastMsgReplyParams(messageContainer), true)); // xss-safe-value } else { await this.replaceStandardReplyBox(undefined, true); } }; public reinsertReplyBox = (replyMsgId: string) => { + console.log('wew', replyMsgId); const params: FactoryReplyParams = { replyMsgId }; $('.reply_message_iframe_container:visible') .last() @@ -351,10 +352,10 @@ export class GmailElementReplacer extends WebmailElementReplacer { return; } // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - const messageContainer = $(btn.closest('.h7')!); + const messageContainer: JQuery = $(btn.closest('.h7')!); if (messageContainer.is(':last-child')) { if (this.isEncrypted()) { - await this.setReplyBoxEditable(); + await this.setReplyBoxEditable(messageContainer); } else { await this.replaceStandardReplyBox(undefined, true); } @@ -589,8 +590,10 @@ export class GmailElementReplacer extends WebmailElementReplacer { return from ? Str.parseEmail(from) : undefined; }; - private getLastMsgReplyParams = (convoRootEl: JQuery): FactoryReplyParams => { - return { replyMsgId: this.determineMsgId($(convoRootEl).find(this.sel.msgInner).last()) }; + private getLastMsgReplyParams = (convoRootEl: JQuery): FactoryReplyParams => { + const msgIdElement = $(convoRootEl).find('[data-legacy-message-id], [data-message-id]'); + const msgId = msgIdElement.attr('data-legacy-message-id') || msgIdElement.attr('data-message-id'); + return { replyMsgId: msgId }; }; private getConvoRootEl = (anyInnerElement: HTMLElement) => { @@ -618,6 +621,7 @@ export class GmailElementReplacer extends WebmailElementReplacer { const convoRootEl = this.getConvoRootEl(newReplyBoxes[0]); const replyParams = this.getLastMsgReplyParams(convoRootEl); if (msgId) { + console.log(msgId); replyParams.replyMsgId = msgId; } const hasDraft = newReplyBoxes.filter(replyBox => { @@ -665,6 +669,7 @@ export class GmailElementReplacer extends WebmailElementReplacer { const isReplyButtonView = replyBoxEl.className.includes('nr'); const replyBoxes = document.querySelectorAll('iframe.reply_message'); const alreadyHasSecureReplyBox = replyBoxes.length > 0; + console.log('wew', replyParams); const secureReplyBoxXssSafe = /* xss-safe-factory */ `
${this.factory.embeddedReply(replyParams, !isReplyButtonView || alreadyHasSecureReplyBox || this.lastSwitchToEncryptedReply)} From e740933cd6ae392f40cae0ba3cd40564f11149e5 Mon Sep 17 00:00:00 2001 From: martgil Date: Thu, 28 Nov 2024 10:41:20 +0800 Subject: [PATCH 2/7] remove console.log() --- .../js/content_scripts/webmail/gmail/gmail-element-replacer.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/extension/js/content_scripts/webmail/gmail/gmail-element-replacer.ts b/extension/js/content_scripts/webmail/gmail/gmail-element-replacer.ts index 5a6c0c72c99..18e89cf1094 100644 --- a/extension/js/content_scripts/webmail/gmail/gmail-element-replacer.ts +++ b/extension/js/content_scripts/webmail/gmail/gmail-element-replacer.ts @@ -95,7 +95,6 @@ export class GmailElementReplacer extends WebmailElementReplacer { }; public reinsertReplyBox = (replyMsgId: string) => { - console.log('wew', replyMsgId); const params: FactoryReplyParams = { replyMsgId }; $('.reply_message_iframe_container:visible') .last() @@ -621,7 +620,6 @@ export class GmailElementReplacer extends WebmailElementReplacer { const convoRootEl = this.getConvoRootEl(newReplyBoxes[0]); const replyParams = this.getLastMsgReplyParams(convoRootEl); if (msgId) { - console.log(msgId); replyParams.replyMsgId = msgId; } const hasDraft = newReplyBoxes.filter(replyBox => { @@ -669,7 +667,6 @@ export class GmailElementReplacer extends WebmailElementReplacer { const isReplyButtonView = replyBoxEl.className.includes('nr'); const replyBoxes = document.querySelectorAll('iframe.reply_message'); const alreadyHasSecureReplyBox = replyBoxes.length > 0; - console.log('wew', replyParams); const secureReplyBoxXssSafe = /* xss-safe-factory */ `
${this.factory.embeddedReply(replyParams, !isReplyButtonView || alreadyHasSecureReplyBox || this.lastSwitchToEncryptedReply)} From 5c843f7caf4c8bd7aa1a5c3902b9b153a58c4f65 Mon Sep 17 00:00:00 2001 From: martgil Date: Thu, 28 Nov 2024 14:46:39 +0800 Subject: [PATCH 3/7] fix broken threading issue --- .../elements/compose-modules/compose-render-module.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/extension/chrome/elements/compose-modules/compose-render-module.ts b/extension/chrome/elements/compose-modules/compose-render-module.ts index 990e37e8779..753f3096805 100644 --- a/extension/chrome/elements/compose-modules/compose-render-module.ts +++ b/extension/chrome/elements/compose-modules/compose-render-module.ts @@ -98,9 +98,11 @@ export class ComposeRenderModule extends ViewModule { const thread = await this.view.emailProvider.threadGet(this.view.threadId, 'metadata'); const inReplyToMessage = thread.messages?.find(message => message.id === this.view.replyMsgId); if (inReplyToMessage) { - this.view.replyParams.inReplyTo = inReplyToMessage.payload?.headers?.find( - header => header.name === 'Message-Id' || header.name === 'Message-ID' - )?.value; + const msgId = inReplyToMessage.payload?.headers?.find(header => header.name === 'Message-Id' || header.name === 'Message-ID')?.value; + if (msgId) { + this.view.sendBtnModule.additionalMsgHeaders['In-Reply-To'] = msgId; + this.view.sendBtnModule.additionalMsgHeaders.References = msgId; + } } this.view.replyParams.subject = `${this.responseMethod === 'reply' ? 'Re' : 'Fwd'}: ${this.view.replyParams.subject}`; if (this.view.useFullScreenSecureCompose) { From 5d7f0528cdf255e653110ae727a0ce4a7a7c67f5 Mon Sep 17 00:00:00 2001 From: martgil Date: Fri, 29 Nov 2024 11:43:50 +0800 Subject: [PATCH 4/7] revert previous changes --- .../webmail/generic/webmail-element-replacer.ts | 2 +- .../webmail/gmail/gmail-element-replacer.ts | 16 +++++++--------- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/extension/js/content_scripts/webmail/generic/webmail-element-replacer.ts b/extension/js/content_scripts/webmail/generic/webmail-element-replacer.ts index e08b5c202c3..ed5fbf06606 100644 --- a/extension/js/content_scripts/webmail/generic/webmail-element-replacer.ts +++ b/extension/js/content_scripts/webmail/generic/webmail-element-replacer.ts @@ -9,7 +9,7 @@ export abstract class WebmailElementReplacer { private replacePgpElsInterval: number; public abstract getIntervalFunctions: () => IntervalFunction[]; - public abstract setReplyBoxEditable: (messageContainer?: JQuery) => Promise; + public abstract setReplyBoxEditable: () => Promise; public abstract reinsertReplyBox: (replyMsgId: string) => void; public abstract scrollToReplyBox: (replyMsgId: string) => void; public abstract scrollToCursorInReplyBox: (replyMsgId: string, cursorOffsetTop: number) => void; diff --git a/extension/js/content_scripts/webmail/gmail/gmail-element-replacer.ts b/extension/js/content_scripts/webmail/gmail/gmail-element-replacer.ts index 18e89cf1094..a691c7be657 100644 --- a/extension/js/content_scripts/webmail/gmail/gmail-element-replacer.ts +++ b/extension/js/content_scripts/webmail/gmail/gmail-element-replacer.ts @@ -85,10 +85,10 @@ export class GmailElementReplacer extends WebmailElementReplacer { ]; }; - public setReplyBoxEditable = async (messageContainer?: JQuery) => { + public setReplyBoxEditable = async () => { const replyContainerIframe = $('.reply_message_iframe_container > iframe').last(); - if (replyContainerIframe.length && messageContainer) { - $(replyContainerIframe).replaceWith(this.factory.embeddedReply(this.getLastMsgReplyParams(messageContainer), true)); // xss-safe-value + if (replyContainerIframe.length) { + $(replyContainerIframe).replaceWith(this.factory.embeddedReply(this.getLastMsgReplyParams(this.getConvoRootEl(replyContainerIframe[0])), true)); // xss-safe-value } else { await this.replaceStandardReplyBox(undefined, true); } @@ -351,10 +351,10 @@ export class GmailElementReplacer extends WebmailElementReplacer { return; } // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - const messageContainer: JQuery = $(btn.closest('.h7')!); + const messageContainer = $(btn.closest('.h7')!); if (messageContainer.is(':last-child')) { if (this.isEncrypted()) { - await this.setReplyBoxEditable(messageContainer); + await this.setReplyBoxEditable(); } else { await this.replaceStandardReplyBox(undefined, true); } @@ -589,10 +589,8 @@ export class GmailElementReplacer extends WebmailElementReplacer { return from ? Str.parseEmail(from) : undefined; }; - private getLastMsgReplyParams = (convoRootEl: JQuery): FactoryReplyParams => { - const msgIdElement = $(convoRootEl).find('[data-legacy-message-id], [data-message-id]'); - const msgId = msgIdElement.attr('data-legacy-message-id') || msgIdElement.attr('data-message-id'); - return { replyMsgId: msgId }; + private getLastMsgReplyParams = (convoRootEl: JQuery): FactoryReplyParams => { + return { replyMsgId: this.determineMsgId($(convoRootEl).find(this.sel.msgInner).last()) }; }; private getConvoRootEl = (anyInnerElement: HTMLElement) => { From 66384e28a32651635437535a258752931acbcf73 Mon Sep 17 00:00:00 2001 From: martgil Date: Fri, 29 Nov 2024 18:36:26 +0800 Subject: [PATCH 5/7] fix missing references value --- .../chrome/elements/compose-modules/compose-render-module.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/extension/chrome/elements/compose-modules/compose-render-module.ts b/extension/chrome/elements/compose-modules/compose-render-module.ts index 753f3096805..e11e8c3d672 100644 --- a/extension/chrome/elements/compose-modules/compose-render-module.ts +++ b/extension/chrome/elements/compose-modules/compose-render-module.ts @@ -99,9 +99,10 @@ export class ComposeRenderModule extends ViewModule { const inReplyToMessage = thread.messages?.find(message => message.id === this.view.replyMsgId); if (inReplyToMessage) { const msgId = inReplyToMessage.payload?.headers?.find(header => header.name === 'Message-Id' || header.name === 'Message-ID')?.value; - if (msgId) { + const references = inReplyToMessage.payload?.headers?.find(header => header.name === 'References')?.value; + if (msgId && references) { this.view.sendBtnModule.additionalMsgHeaders['In-Reply-To'] = msgId; - this.view.sendBtnModule.additionalMsgHeaders.References = msgId; + this.view.sendBtnModule.additionalMsgHeaders.References = references + ' ' + msgId; } } this.view.replyParams.subject = `${this.responseMethod === 'reply' ? 'Re' : 'Fwd'}: ${this.view.replyParams.subject}`; From 0c1633b2e5231402a410229f1f5a4baf9ebe95f1 Mon Sep 17 00:00:00 2001 From: martgil Date: Sat, 30 Nov 2024 11:12:49 +0800 Subject: [PATCH 6/7] pr reviews: correctly set references header --- .../compose-modules/compose-render-module.ts | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/extension/chrome/elements/compose-modules/compose-render-module.ts b/extension/chrome/elements/compose-modules/compose-render-module.ts index e11e8c3d672..79c0a5f46af 100644 --- a/extension/chrome/elements/compose-modules/compose-render-module.ts +++ b/extension/chrome/elements/compose-modules/compose-render-module.ts @@ -101,8 +101,7 @@ export class ComposeRenderModule extends ViewModule { const msgId = inReplyToMessage.payload?.headers?.find(header => header.name === 'Message-Id' || header.name === 'Message-ID')?.value; const references = inReplyToMessage.payload?.headers?.find(header => header.name === 'References')?.value; if (msgId && references) { - this.view.sendBtnModule.additionalMsgHeaders['In-Reply-To'] = msgId; - this.view.sendBtnModule.additionalMsgHeaders.References = references + ' ' + msgId; + this.setReplyHeaders(msgId, references); } } this.view.replyParams.subject = `${this.responseMethod === 'reply' ? 'Re' : 'Fwd'}: ${this.view.replyParams.subject}`; @@ -120,8 +119,7 @@ export class ComposeRenderModule extends ViewModule { ); if (this.view.quoteModule.messageToReplyOrForward) { const msgId = this.view.quoteModule.messageToReplyOrForward.headers['message-id']; - this.view.sendBtnModule.additionalMsgHeaders['In-Reply-To'] = msgId; - this.view.sendBtnModule.additionalMsgHeaders.References = this.view.quoteModule.messageToReplyOrForward.headers.references + ' ' + msgId; + this.setReplyHeaders(msgId, this.view.quoteModule.messageToReplyOrForward.headers.references); if (this.view.replyPubkeyMismatch) { await this.renderReplyMsgAsReplyPubkeyMismatch(); } else if (this.view.quoteModule.messageToReplyOrForward.isOnlySigned) { @@ -276,6 +274,13 @@ export class ComposeRenderModule extends ViewModule { } }; + private setReplyHeaders = (msgId?: string, references?: string) => { + if (msgId) { + this.view.sendBtnModule.additionalMsgHeaders['In-Reply-To'] = msgId; + this.view.sendBtnModule.additionalMsgHeaders.References = [references, msgId].filter(Boolean).join(' '); + } + }; + private initComposeBoxStyles = () => { if (this.view.isReplyBox) { this.view.S.cached('body').addClass('reply_box'); From f3f017ba554750293672b283563cfe32dc5a35c2 Mon Sep 17 00:00:00 2001 From: martgil Date: Wed, 4 Dec 2024 13:58:23 +0800 Subject: [PATCH 7/7] fix check redundancy --- .../chrome/elements/compose-modules/compose-render-module.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/extension/chrome/elements/compose-modules/compose-render-module.ts b/extension/chrome/elements/compose-modules/compose-render-module.ts index 79c0a5f46af..56403526799 100644 --- a/extension/chrome/elements/compose-modules/compose-render-module.ts +++ b/extension/chrome/elements/compose-modules/compose-render-module.ts @@ -100,9 +100,7 @@ export class ComposeRenderModule extends ViewModule { if (inReplyToMessage) { const msgId = inReplyToMessage.payload?.headers?.find(header => header.name === 'Message-Id' || header.name === 'Message-ID')?.value; const references = inReplyToMessage.payload?.headers?.find(header => header.name === 'References')?.value; - if (msgId && references) { - this.setReplyHeaders(msgId, references); - } + this.setReplyHeaders(msgId, references); } this.view.replyParams.subject = `${this.responseMethod === 'reply' ? 'Re' : 'Fwd'}: ${this.view.replyParams.subject}`; if (this.view.useFullScreenSecureCompose) {