From ca27c0c46dae550cd54a098e85f75f07d50ee21e Mon Sep 17 00:00:00 2001 From: michael-volynets Date: Mon, 9 Dec 2019 22:12:55 +0200 Subject: [PATCH] Issue #2239, Refactored subscribe file --- extension/chrome/elements/subscribe.ts | 212 +++++++++++++------------ 1 file changed, 111 insertions(+), 101 deletions(-) diff --git a/extension/chrome/elements/subscribe.ts b/extension/chrome/elements/subscribe.ts index 8e5cd63abdd..92261823a1c 100644 --- a/extension/chrome/elements/subscribe.ts +++ b/extension/chrome/elements/subscribe.ts @@ -9,40 +9,121 @@ import { Ui } from '../../js/common/browser/ui.js'; import { Lang } from '../../js/common/lang.js'; import { Api } from '../../js/common/api/api.js'; import { BrowserMsg, Bm } from '../../js/common/browser/browser-msg.js'; -import { Backend, ProductName, Product } from '../../js/common/api/backend.js'; +import { Backend, ProductName, Product, FcUuidAuth } from '../../js/common/api/backend.js'; import { Assert } from '../../js/common/assert.js'; import { XssSafeFactory } from '../../js/common/xss_safe_factory.js'; import { Xss } from '../../js/common/platform/xss.js'; import { Settings } from '../../js/common/settings.js'; +import { View } from '../../js/common/view.js'; -Catch.try(async () => { +View.run(class SubscribeView extends View { + private readonly acctEmail: string; + private readonly parentTabId: string; + private readonly placement: string | undefined; + private authInfo: FcUuidAuth | undefined; + private tabId: string | undefined; - Ui.event.protect(); - - const uncheckedUrlParams = Url.parse(['acctEmail', 'placement', 'parentTabId']); - const acctEmail = Assert.urlParamRequire.string(uncheckedUrlParams, 'acctEmail'); - const parentTabId = Assert.urlParamRequire.string(uncheckedUrlParams, 'parentTabId'); - const placement = Assert.urlParamRequire.oneof(uncheckedUrlParams, 'placement', ['settings', 'settings_compose', 'default', 'dialog', 'gmail', 'embedded', 'compose', undefined]); - - const authInfo = await Store.authInfo(acctEmail); - - const PRODUCTS: { [productName in ProductName]: Product } = { + private readonly PRODUCTS: { [productName in ProductName]: Product } = { null: { id: null, method: null, name: null, level: null }, // tslint:disable-line:no-null-keyword trial: { id: 'free_month', method: 'trial', name: 'trial', level: 'pro' }, advancedMonthly: { id: 'cu-adv-month', method: 'stripe', name: 'advanced_monthly', level: 'pro' }, }; - const stripeCcEnteredHandler: Bm.AsyncResponselessHandler = async ({ token }: Bm.StripeResult) => { - $('.stripe_checkout').text('').css('display', 'none'); - await subscribeAndHandleResult(PRODUCTS.advancedMonthly, token); - }; + constructor() { + super(); + const uncheckedUrlParams = Url.parse(['acctEmail', 'placement', 'parentTabId']); + this.acctEmail = Assert.urlParamRequire.string(uncheckedUrlParams, 'acctEmail'); + this.parentTabId = Assert.urlParamRequire.string(uncheckedUrlParams, 'parentTabId'); + this.placement = Assert.urlParamRequire.oneof(uncheckedUrlParams, 'placement', ['settings', 'settings_compose', 'default', 'dialog', 'gmail', 'embedded', 'compose', undefined]); + } + + async render() { + Ui.event.protect(); + if (this.placement === 'settings') { + $('#content').removeClass('dialog').css({ 'margin-top': 0, 'margin-bottom': 30 }); + $('.line.button_padding').css('padding', 0); + } else { + $('body').css('overflow', 'hidden'); + } + $('.list_table').css('display', 'block'); + $('#content').css('display', 'block'); + await this.renderSubscriptionDetails(); + this.tabId = await BrowserMsg.requiredTabId(); + $('.stripe_checkout') + .html(`${Lang.account.creditOrDebit}

${new XssSafeFactory(this.acctEmail, this.tabId).embeddedStripeCheckout()}
${Ui.retryLink('back')}`); // xss-safe-factory + } + + setHandlers() { + $('.action_close').click(this.setHandler(() => this.closeDialog())); + $('.action_show_stripe').click(this.setHandler(() => this.showStripeHandler())); + $('.action_contact_page').click(this.setHandler(() => BrowserMsg.send.bg.settings({ page: '/chrome/settings/modules/contact_page.htm', acctEmail: this.acctEmail }))); + $('.action_get_trial').click(this.setHandlerPrevent('parallel', async (target, done) => { + await this.subscribeAndHandleResult(this.PRODUCTS.trial, undefined); + done(); + })); + BrowserMsg.addListener('stripe_result', (res) => this.stripeCcEnteredHandler(res as Bm.StripeResult)); + BrowserMsg.listen(this.tabId!); + } + + private async renderSubscriptionDetails() { + this.authInfo = await Store.authInfo(this.acctEmail); + try { + await Backend.accountGet(this.authInfo); + await Backend.getSubscriptionWithoutLogin(this.acctEmail); + } catch (e) { + if (Api.err.isAuthErr(e)) { + Xss.sanitizeRender('#content', `Not logged in. ${Ui.retryLink()}`); + Settings.offerToLoginWithPopupShowModalOnErr(this.acctEmail, () => window.location.reload()); + } else if (Api.err.isNetErr(e)) { + Xss.sanitizeRender('#content', `Failed to load due to internet connection. ${Ui.retryLink()}`); + } else { + Catch.reportErr(e); + Xss.sanitizeRender('#content', `Unknown error happened when fetching account info. ${Ui.retryLink()}`); + } + } + const subscription = await Store.subscription(this.acctEmail); // updated in getSubscriptionWithoutLogin + if (!subscription.active) { + if (subscription.level && subscription.expire) { + if (subscription.method === 'trial') { + $('.status').text('Your trial has expired on ' + Str.datetimeToDate(subscription.expire) + '. Upgrade now to continue using FlowCrypt Advanced.'); + } else if (subscription.method === 'group') { + $('.status').text('Your group licensing is due for renewal. Please check with company leadership.'); + } else { + $('.status').text('Your subscription has ended on ' + subscription.expire + '. Renew now to continue using FlowCrypt Advanced.'); + } + $('.action_get_trial').css('display', 'none'); + $('.action_show_stripe').removeClass('gray').addClass('green'); + } else { + $('.status').text('After the trial, your account will automatically switch to Free Forever.'); + } + } else if (subscription.active && subscription.method === 'trial') { + Xss.sanitizeRender('.status', + 'After the trial, your account will automatically switch to Free Forever.

You can subscribe now to stay on FlowCrypt Advanced. It\'s $5 a month.'); + } + if (subscription.active) { + if (subscription.method === 'trial') { + $('.list_table').css('display', 'none'); + $('.action_get_trial').css('display', 'none'); + $('.action_show_stripe').removeClass('gray').addClass('green'); + } else { + Xss.sanitizeRender('#content', `
${Lang.account.alreadyUpgraded}
close
`); + $('.action_close').click(this.setHandler(() => this.closeDialog())); + } + } + } + + private showStripeHandler() { + $('.status').text('You are subscribing to a $5 monthly payment for FlowCrypt Advanced.'); + $('.hide_on_checkout').css('display', 'none'); + $('.stripe_checkout').css('display', 'block'); + } - const subscribeAndHandleResult = async (chosenProduct: Product, source: string | undefined) => { + private async subscribeAndHandleResult(chosenProduct: Product, source: string | undefined) { try { - const response = await Backend.accountSubscribe(authInfo, chosenProduct.id!, chosenProduct.method!, source); + const response = await Backend.accountSubscribe(this.authInfo!, chosenProduct.id!, chosenProduct.method!, source); if (response.subscription.level === chosenProduct.level && response.subscription.method === chosenProduct.method) { await Ui.modal.info('Successfully upgraded to FlowCrypt Advanced.'); - closeDialog(); + this.closeDialog(); } throw new Error('Something went wrong when upgrading (values don\'t match), please email human@flowcrypt.com to get this resolved.'); } catch (e) { @@ -60,92 +141,21 @@ Catch.try(async () => { Catch.reportErr(e); } } - }; - - const closeDialog = () => { - $('body').attr('data-test-state', 'closed'); // used by automated tests - if (placement === 'settings_compose') { - window.close(); - } else if (placement === 'settings') { - BrowserMsg.send.reload(parentTabId, {}); - } else { - BrowserMsg.send.closeDialog(parentTabId); - } - }; - - try { - await Backend.accountGet(authInfo); - await Backend.getSubscriptionWithoutLogin(acctEmail); - } catch (e) { - if (Api.err.isAuthErr(e)) { - Xss.sanitizeRender('#content', `Not logged in. ${Ui.retryLink()}`); - Settings.offerToLoginWithPopupShowModalOnErr(acctEmail, () => window.location.reload()); - } else if (Api.err.isNetErr(e)) { - Xss.sanitizeRender('#content', `Failed to load due to internet connection. ${Ui.retryLink()}`); - } else { - Catch.reportErr(e); - Xss.sanitizeRender('#content', `Unknown error happened when fetching account info. ${Ui.retryLink()}`); - } } - const subscription = await Store.subscription(acctEmail); // updated in getSubscriptionWithoutLogin - - if (placement === 'settings') { - $('#content').removeClass('dialog').css({ 'margin-top': 0, 'margin-bottom': 30 }); - $('.line.button_padding').css('padding', 0); - } else { - $('body').css('overflow', 'hidden'); + private async stripeCcEnteredHandler({ token }: Bm.StripeResult) { + $('.stripe_checkout').text('').css('display', 'none'); + await this.subscribeAndHandleResult(this.PRODUCTS.advancedMonthly, token); } - $('.list_table').css('display', 'block'); - $('#content').css('display', 'block'); - $('.action_show_stripe').click(Ui.event.handle(() => { - $('.status').text('You are subscribing to a $5 monthly payment for FlowCrypt Advanced.'); - $('.hide_on_checkout').css('display', 'none'); - $('.stripe_checkout').css('display', 'block'); - })); - - $('.action_contact_page').click(Ui.event.handle(() => BrowserMsg.send.bg.settings({ page: '/chrome/settings/modules/contact_page.htm', acctEmail }))); - - $('.action_close').click(Ui.event.handle(closeDialog)); - - $('.action_get_trial').click(Ui.event.prevent('parallel', async (target, done) => { - await subscribeAndHandleResult(PRODUCTS.trial, undefined); - done(); - })); - - if (!subscription.active) { - if (subscription.level && subscription.expire) { - if (subscription.method === 'trial') { - $('.status').text('Your trial has expired on ' + Str.datetimeToDate(subscription.expire) + '. Upgrade now to continue using FlowCrypt Advanced.'); - } else if (subscription.method === 'group') { - $('.status').text('Your group licensing is due for renewal. Please check with company leadership.'); - } else { - $('.status').text('Your subscription has ended on ' + subscription.expire + '. Renew now to continue using FlowCrypt Advanced.'); - } - $('.action_get_trial').css('display', 'none'); - $('.action_show_stripe').removeClass('gray').addClass('green'); - } else { - $('.status').text('After the trial, your account will automatically switch to Free Forever.'); - } - } else if (subscription.active && subscription.method === 'trial') { - Xss.sanitizeRender('.status', 'After the trial, your account will automatically switch to Free Forever.

You can subscribe now to stay on FlowCrypt Advanced. It\'s $5 a month.'); - } - if (subscription.active) { - if (subscription.method === 'trial') { - $('.list_table').css('display', 'none'); - $('.action_get_trial').css('display', 'none'); - $('.action_show_stripe').removeClass('gray').addClass('green'); + private closeDialog() { + $('body').attr('data-test-state', 'closed'); // used by automated tests + if (this.placement === 'settings_compose') { + window.close(); + } else if (this.placement === 'settings') { + BrowserMsg.send.reload(this.parentTabId, {}); } else { - Xss.sanitizeRender('#content', `
${Lang.account.alreadyUpgraded}
close
`); - $('.action_close').click(Ui.event.handle(() => closeDialog())); + BrowserMsg.send.closeDialog(this.parentTabId); } } - - const tabId = await BrowserMsg.requiredTabId(); - BrowserMsg.addListener('stripe_result', stripeCcEnteredHandler); - BrowserMsg.listen(tabId); - - $('.stripe_checkout').html(`${Lang.account.creditOrDebit}

${new XssSafeFactory(acctEmail, tabId).embeddedStripeCheckout()}
${Ui.retryLink('back')}`); // xss-safe-factory - -})(); +});