From 03486f5c856ffe81e21f28102230f2bb421c11f3 Mon Sep 17 00:00:00 2001 From: Tom J Date: Sun, 23 Feb 2020 16:16:57 +0000 Subject: [PATCH 1/2] prompt user to reconnect google --- .../inbox/inbox-modules/inbox-menu-module.ts | 38 ---------------- extension/chrome/settings/inbox/inbox.ts | 44 +++++++++++++++++- extension/chrome/settings/index.ts | 45 +++++++++---------- 3 files changed, 64 insertions(+), 63 deletions(-) diff --git a/extension/chrome/settings/inbox/inbox-modules/inbox-menu-module.ts b/extension/chrome/settings/inbox/inbox-modules/inbox-menu-module.ts index 5db50ded713..319af495d3e 100644 --- a/extension/chrome/settings/inbox/inbox-modules/inbox-menu-module.ts +++ b/extension/chrome/settings/inbox/inbox-modules/inbox-menu-module.ts @@ -2,14 +2,11 @@ 'use strict'; -import { Bm, BrowserMsg } from '../../../../js/common/browser/browser-msg.js'; - import { Catch } from '../../../../js/common/platform/catch.js'; import { Dict } from '../../../../js/common/core/common.js'; import { GmailRes } from '../../../../js/common/api/email-provider/gmail/gmail-parser.js'; import { Google } from '../../../../js/common/api/google.js'; import { InboxView } from '../inbox.js'; -import { Settings } from '../../../../js/common/settings.js'; import { ViewModule } from '../../../../js/common/view-module.js'; import { Xss } from '../../../../js/common/platform/xss.js'; @@ -47,13 +44,6 @@ export class InboxMenuModule extends ViewModule { private setHandlers = () => { $('.action_open_secure_compose_window').click(this.view.setHandler(() => this.view.injector.openComposeWin())); $('.menu > .label').click(this.view.setHandler(this.renderFolder)); - this.addBrowserMsgListeners(); - $('.action_open_settings').click(this.view.setHandler(self => BrowserMsg.send.bg.settings({ acctEmail: this.view.acctEmail }))); - $(".action-toggle-accounts-menu").click(this.view.setHandler((target, event) => { - event.stopPropagation(); - $("#alt-accounts").toggleClass("active"); - })); - $('.action_add_account').click(this.view.setHandlerPrevent('double', async () => await Settings.newGoogleAcctAuthPromptThenAlertOrForward(this.view.tabId))); } private renderMenuAndLabelStyles = () => { @@ -132,32 +122,4 @@ export class InboxMenuModule extends ViewModule { this.view.redirectToUrl({ acctEmail: this.view.acctEmail }); } - private addBrowserMsgListeners = () => { - BrowserMsg.addListener('add_end_session_btn', () => this.view.injector.insertEndSessionBtn(this.view.acctEmail)); - BrowserMsg.addListener('close_new_message', async () => { - $('div.new_message').remove(); - }); - BrowserMsg.addListener('passphrase_dialog', async ({ longids, type }: Bm.PassphraseDialog) => { - if (!$('#cryptup_dialog').length) { - $('body').append(this.view.factory.dialogPassphrase(longids, type)) // xss-safe-factory; - .click(this.view.setHandler(e => { // click on the area outside the iframe - $('#cryptup_dialog').remove(); - })); - } - }); - BrowserMsg.addListener('subscribe_dialog', async ({ isAuthErr }: Bm.SubscribeDialog) => { - if (!$('#cryptup_dialog').length) { - $('body').append(this.view.factory.dialogSubscribe(isAuthErr)); // xss-safe-factory - } - }); - BrowserMsg.addListener('add_pubkey_dialog', async ({ emails }: Bm.AddPubkeyDialog) => { - if (!$('#cryptup_dialog').length) { - $('body').append(this.view.factory.dialogAddPubkey(emails)); // xss-safe-factory - } - }); - BrowserMsg.addListener('close_dialog', async () => { - $('#cryptup_dialog').remove(); - }); - } - } diff --git a/extension/chrome/settings/inbox/inbox.ts b/extension/chrome/settings/inbox/inbox.ts index 02ac5f9b683..9c6dcacb868 100644 --- a/extension/chrome/settings/inbox/inbox.ts +++ b/extension/chrome/settings/inbox/inbox.ts @@ -8,7 +8,7 @@ import { Url, UrlParams } from '../../../js/common/core/common.js'; import { ApiErr } from '../../../js/common/api/error/api-error.js'; import { Assert } from '../../../js/common/assert.js'; -import { BrowserMsg } from '../../../js/common/browser/browser-msg.js'; +import { BrowserMsg, Bm } from '../../../js/common/browser/browser-msg.js'; import { Catch } from '../../../js/common/platform/catch.js'; import { Gmail } from '../../../js/common/api/email-provider/gmail/gmail.js'; import { InboxActiveThreadModule } from './inbox-modules/inbox-active-thread-module.js'; @@ -79,7 +79,12 @@ export class InboxView extends View { await Settings.populateAccountsMenu('inbox.htm'); } catch (e) { ApiErr.reportIfSignificant(e); - await Ui.modal.error(`${ApiErr.eli5(e)}\n\n${String(e)}`); + if (ApiErr.isAuthErr(e) || ApiErr.isAuthPopupNeeded(e)) { + await Ui.modal.warning(`FlowCrypt must be re-connected to your Google account.`); + await Settings.newGoogleAcctAuthPromptThenAlertOrForward(this.tabId, this.acctEmail); + } else { + await Ui.modal.error(`${ApiErr.eli5(e)}\n\n${String(e)}`); + } } } @@ -87,6 +92,13 @@ export class InboxView extends View { // BrowserMsg.addPgpListeners(); // todo - re-allow when https://github.com/FlowCrypt/flowcrypt-browser/issues/2560 fixed BrowserMsg.listen(this.tabId); Catch.setHandledInterval(this.webmailCommon.addOrRemoveEndSessionBtnIfNeeded, 30000); + $('.action_open_settings').click(this.setHandler(self => BrowserMsg.send.bg.settings({ acctEmail: this.acctEmail }))); + $(".action-toggle-accounts-menu").click(this.setHandler((target, event) => { + event.stopPropagation(); + $("#alt-accounts").toggleClass("active"); + })); + $('.action_add_account').click(this.setHandlerPrevent('double', async () => await Settings.newGoogleAcctAuthPromptThenAlertOrForward(this.tabId))); + this.addBrowserMsgListeners(); } public redirectToUrl = (params: UrlParams) => { @@ -104,6 +116,34 @@ export class InboxView extends View { Xss.sanitizeRender('h1', `${title}`); } + private addBrowserMsgListeners = () => { + BrowserMsg.addListener('add_end_session_btn', () => this.injector.insertEndSessionBtn(this.acctEmail)); + BrowserMsg.addListener('close_new_message', async () => { + $('div.new_message').remove(); + }); + BrowserMsg.addListener('passphrase_dialog', async ({ longids, type }: Bm.PassphraseDialog) => { + if (!$('#cryptup_dialog').length) { + $('body').append(this.factory.dialogPassphrase(longids, type)) // xss-safe-factory; + .click(this.setHandler(e => { // click on the area outside the iframe + $('#cryptup_dialog').remove(); + })); + } + }); + BrowserMsg.addListener('subscribe_dialog', async ({ isAuthErr }: Bm.SubscribeDialog) => { + if (!$('#cryptup_dialog').length) { + $('body').append(this.factory.dialogSubscribe(isAuthErr)); // xss-safe-factory + } + }); + BrowserMsg.addListener('add_pubkey_dialog', async ({ emails }: Bm.AddPubkeyDialog) => { + if (!$('#cryptup_dialog').length) { + $('body').append(this.factory.dialogAddPubkey(emails)); // xss-safe-factory + } + }); + BrowserMsg.addListener('close_dialog', async () => { + $('#cryptup_dialog').remove(); + }); + } + } View.run(InboxView); diff --git a/extension/chrome/settings/index.ts b/extension/chrome/settings/index.ts index f1025380bf6..99937d6f246 100644 --- a/extension/chrome/settings/index.ts +++ b/extension/chrome/settings/index.ts @@ -66,9 +66,9 @@ View.run(class SettingsView extends View { } $.get('/changelog.txt', data => ($('#status-row #status_v') as any as JQS).featherlight(String(data).replace(/\n/g, '
')), 'html'); await this.initialize(); - await Assert.abortAndRenderErrOnUnprotectedKey(this.acctEmail, this.tabId!); + await Assert.abortAndRenderErrOnUnprotectedKey(this.acctEmail, this.tabId); if (this.page) { - Settings.renderSubPage(this.acctEmail, this.tabId!, this.page, this.pageUrlParams); + Settings.renderSubPage(this.acctEmail, this.tabId, this.page, this.pageUrlParams); } await Settings.populateAccountsMenu('index.htm'); Ui.setTestState('ready'); @@ -76,7 +76,7 @@ View.run(class SettingsView extends View { public setHandlers = () => { BrowserMsg.addListener('open_page', async ({ page, addUrlText }: Bm.OpenPage) => { - Settings.renderSubPage(this.acctEmail, this.tabId!, page, addUrlText); + Settings.renderSubPage(this.acctEmail, this.tabId, page, addUrlText); }); BrowserMsg.addListener('redirect', async ({ location }: Bm.Redirect) => { window.location.href = location; @@ -90,12 +90,12 @@ View.run(class SettingsView extends View { }); BrowserMsg.addListener('add_pubkey_dialog', async ({ emails }: Bm.AddPubkeyDialog) => { // todo: use #cryptup_dialog just like passphrase_dialog does - const factory = new XssSafeFactory(this.acctEmail!, this.tabId!); + const factory = new XssSafeFactory(this.acctEmail!, this.tabId); window.open(factory.srcAddPubkeyDialog(emails, 'settings'), '_blank', 'height=680,left=100,menubar=no,status=no,toolbar=no,top=30,width=660'); }); BrowserMsg.addListener('subscribe_dialog', async ({ }: Bm.SubscribeDialog) => { // todo: use #cryptup_dialog just like passphrase_dialog does - const factory = new XssSafeFactory(this.acctEmail!, this.tabId!); + const factory = new XssSafeFactory(this.acctEmail!, this.tabId); const subscribeDialogSrc = factory.srcSubscribeDialog('settings_compose', undefined); window.open(subscribeDialogSrc, '_blank', 'height=650,left=100,menubar=no,status=no,toolbar=no,top=30,width=640,scrollbars=no'); }); @@ -113,11 +113,11 @@ View.run(class SettingsView extends View { }); BrowserMsg.addListener('open_google_auth_dialog', async ({ acctEmail, scopes }: Bm.OpenGoogleAuthDialog) => { $('.featherlight-close').click(); - await Settings.newGoogleAcctAuthPromptThenAlertOrForward(this.tabId!, acctEmail, scopes); + await Settings.newGoogleAcctAuthPromptThenAlertOrForward(this.tabId, acctEmail, scopes); }); BrowserMsg.addListener('passphrase_dialog', async ({ longids, type }: Bm.PassphraseDialog) => { if (!$('#cryptup_dialog').length) { - const factory = new XssSafeFactory(this.acctEmail!, this.tabId!); + const factory = new XssSafeFactory(this.acctEmail!, this.tabId); $('body').append(factory.dialogPassphrase(longids, type)); // xss-safe-factory } }); @@ -127,11 +127,11 @@ View.run(class SettingsView extends View { BrowserMsg.addListener('close_dialog', async () => { $('#cryptup_dialog').remove(); }); - BrowserMsg.listen(this.tabId!); + BrowserMsg.listen(this.tabId); $('.show_settings_page').click(this.setHandler(async target => { const page = $(target).attr('page'); if (page) { - Settings.renderSubPage(this.acctEmail!, this.tabId!, page, $(target).attr('addurltext') || ''); + Settings.renderSubPage(this.acctEmail!, this.tabId, page, $(target).attr('addurltext') || ''); } else { Catch.report(`Unknown target page in element: ${target.outerHTML}`); } @@ -139,9 +139,9 @@ View.run(class SettingsView extends View { $('.action_show_encrypted_inbox').click(this.setHandler(target => { window.location.href = Url.create('/chrome/settings/inbox/inbox.htm', { acctEmail: this.acctEmail! }); })); - $('.action_go_auth_denied').click(this.setHandler(() => Settings.renderSubPage(this.acctEmail!, this.tabId!, '/chrome/settings/modules/auth_denied.htm'))); - $('.action_add_account').click(this.setHandlerPrevent('double', async () => await Settings.newGoogleAcctAuthPromptThenAlertOrForward(this.tabId!))); - $('.action_google_auth').click(this.setHandlerPrevent('double', async () => await Settings.newGoogleAcctAuthPromptThenAlertOrForward(this.tabId!, this.acctEmail))); + $('.action_go_auth_denied').click(this.setHandler(() => Settings.renderSubPage(this.acctEmail!, this.tabId, '/chrome/settings/modules/auth_denied.htm'))); + $('.action_add_account').click(this.setHandlerPrevent('double', async () => await Settings.newGoogleAcctAuthPromptThenAlertOrForward(this.tabId))); + $('.action_google_auth').click(this.setHandlerPrevent('double', async () => await Settings.newGoogleAcctAuthPromptThenAlertOrForward(this.tabId, this.acctEmail))); // $('.action_microsoft_auth').click(this.setHandlerPrevent('double', function() { // new_microsoft_account_authentication_prompt(account_email); // })); @@ -159,8 +159,8 @@ View.run(class SettingsView extends View { $(".ion-ios-arrow-down").toggleClass("up"); $(".add-account").toggleClass("hidden"); })); - $('#status-row #status_google').click(this.setHandler(() => Settings.renderSubPage(this.acctEmail!, this.tabId!, 'modules/debug_api.htm', { which: 'google_account' }))); - $('#status-row #status_local_store').click(this.setHandler(() => Settings.renderSubPage(this.acctEmail!, this.tabId!, 'modules/debug_api.htm', { which: 'local_store' }))); + $('#status-row #status_google').click(this.setHandler(() => Settings.renderSubPage(this.acctEmail!, this.tabId, 'modules/debug_api.htm', { which: 'google_account' }))); + $('#status-row #status_local_store').click(this.setHandler(() => Settings.renderSubPage(this.acctEmail!, this.tabId, 'modules/debug_api.htm', { which: 'local_store' }))); } private displayOrig = (selector: string) => { @@ -176,7 +176,7 @@ View.run(class SettingsView extends View { if (this.addNewAcct) { $('.show_if_setup_not_done').css('display', 'initial'); $('.hide_if_setup_not_done').css('display', 'none'); - await Settings.newGoogleAcctAuthPromptThenAlertOrForward(this.tabId!); + await Settings.newGoogleAcctAuthPromptThenAlertOrForward(this.tabId); } else if (this.acctEmail) { $('.email-address').text(this.acctEmail); const storage = await Store.getAcct(this.acctEmail, ['setup_done', 'email_provider', 'picture']); @@ -326,12 +326,11 @@ View.run(class SettingsView extends View { } } } catch (e) { - if (ApiErr.isAuthPopupNeeded(e)) { - $('#status-row #status_google').text(`g:?:disconnected`).addClass('bad').attr('title', 'Not connected to Google Account, click to resolve.') - .off().click(this.setHandler(() => Settings.newGoogleAcctAuthPromptThenAlertOrForward(this.tabId!, this.acctEmail))); - } else if (ApiErr.isAuthErr(e)) { - $('#status-row #status_google').text(`g:?:auth`).addClass('bad').attr('title', 'Auth error when checking Google Account, click to resolve.') - .off().click(this.setHandler(() => Settings.newGoogleAcctAuthPromptThenAlertOrForward(this.tabId!, this.acctEmail))); + if (ApiErr.isAuthPopupNeeded(e) || ApiErr.isAuthErr(e)) { + $('#status-row #status_google').text(`g:?:auth`).addClass('bad'); + if (await Ui.modal.confirm(`FlowCrypt must be re-connected to your Google account.`)) { + await Settings.newGoogleAcctAuthPromptThenAlertOrForward(this.tabId, this.acctEmail); + } } else if (ApiErr.isMailOrAcctDisabledOrPolicy(e)) { await Ui.modal.error(Lang.account.googleAcctDisabledOrPolicy); } else if (ApiErr.isNetErr(e)) { @@ -359,7 +358,7 @@ View.run(class SettingsView extends View { const subscription = await Store.subscription(acctEmail); $('#status-row #status_subscription').text(`s:${liveness}:${subscription.active ? 'active' : 'inactive'}-${subscription.method}:${subscription.expire}`); if (subscription.active) { - const showAcct = () => Settings.renderSubPage(acctEmail, this.tabId!, '/chrome/settings/modules/account.htm'); + const showAcct = () => Settings.renderSubPage(acctEmail, this.tabId, '/chrome/settings/modules/account.htm'); $('.logo-row .subscription .level').text('advanced').css('display', 'inline-block').click(this.setHandler(showAcct)).css('cursor', 'pointer'); if (subscription.method === 'trial') { $('.logo-row .subscription .expire').text(subscription.expire ? ('trial ' + subscription.expire.split(' ')[0]) : 'lifetime').css('display', 'inline-block'); @@ -400,7 +399,7 @@ View.run(class SettingsView extends View { Xss.sanitizeAppend('.key_list', html); $('.action_show_key').click(this.setHandler(target => { // the UI below only gets rendered when account_email is available - Settings.renderSubPage(this.acctEmail!, this.tabId!, $(target).attr('page')!, $(target).attr('addurltext') || ''); // all such elements do have page attr + Settings.renderSubPage(this.acctEmail!, this.tabId, $(target).attr('page')!, $(target).attr('addurltext') || ''); // all such elements do have page attr })); $('.action_remove_key').click(this.setHandler(async target => { // the UI below only gets rendered when account_email is available From c3fd9c83aa189fc44e33b2e2379a01da0cf24e51 Mon Sep 17 00:00:00 2001 From: Tom J Date: Sun, 23 Feb 2020 16:19:06 +0000 Subject: [PATCH 2/2] populate menu before network calls --- extension/chrome/settings/inbox/inbox.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extension/chrome/settings/inbox/inbox.ts b/extension/chrome/settings/inbox/inbox.ts index 9c6dcacb868..0f31530181b 100644 --- a/extension/chrome/settings/inbox/inbox.ts +++ b/extension/chrome/settings/inbox/inbox.ts @@ -66,6 +66,7 @@ export class InboxView extends View { this.inboxNotificationModule.render(); const emailProvider = this.storage.email_provider || 'gmail'; try { + await Settings.populateAccountsMenu('inbox.htm'); if (emailProvider !== 'gmail') { $('body').text('Not supported for ' + emailProvider); } else { @@ -76,7 +77,6 @@ export class InboxView extends View { await this.inboxListThreadsModule.render(this.labelId); } } - await Settings.populateAccountsMenu('inbox.htm'); } catch (e) { ApiErr.reportIfSignificant(e); if (ApiErr.isAuthErr(e) || ApiErr.isAuthPopupNeeded(e)) {