From fba17d77de9e60de0e02e90dc6dbcbbf7454158a Mon Sep 17 00:00:00 2001 From: Alexander Tseung Date: Wed, 23 Jan 2019 07:25:34 -0800 Subject: Refactor first time flow, remove seed phrase from state (#5994) * Refactor and fix styling for first time flow. Remove seed phrase from persisted metamask state * Fix linting and tests * Fix translations, initialization notice routing * Fix drizzle tests * Fix e2e tests * Fix integration tests * Fix styling * Fix migration naming from 030 to 031 * Open extension in browser when user has not completed onboarding --- app/_locales/en/messages.json | 54 ++++++++++++++++++++++++++++++++++ app/scripts/controllers/preferences.js | 10 +++++++ app/scripts/metamask-controller.js | 1 + app/scripts/migrations/031.js | 31 +++++++++++++++++++ app/scripts/migrations/index.js | 1 + app/scripts/ui.js | 11 +++++-- 6 files changed, 106 insertions(+), 2 deletions(-) create mode 100644 app/scripts/migrations/031.js (limited to 'app') diff --git a/app/_locales/en/messages.json b/app/_locales/en/messages.json index e849517a8..7810c6eb4 100644 --- a/app/_locales/en/messages.json +++ b/app/_locales/en/messages.json @@ -206,6 +206,9 @@ "clickToAdd": { "message": "Click on $1 to add them to your account" }, + "clickToRevealSeed": { + "message": "Click here to reveal secret words" + }, "close": { "message": "Close" }, @@ -227,6 +230,9 @@ "confirmPassword": { "message": "Confirm Password" }, + "confirmSecretBackupPhrase": { + "message": "Confirm your Secret Backup Phrase" + }, "confirmTransaction": { "message": "Confirm Transaction" }, @@ -314,6 +320,9 @@ "createDen": { "message": "Create" }, + "createPassword": { + "message": "Create Password" + }, "crypto": { "message": "Crypto", "description": "Exchange type (cryptocurrencies)" @@ -403,6 +412,9 @@ "downloadGoogleChrome": { "message": "Download Google Chrome" }, + "downloadSecretBackup": { + "message": "Download this Secret Backup Phrase and keep it stored safely on an external encrypted hard drive or storage medium." + }, "downloadStateLogs": { "message": "Download State Logs" }, @@ -611,6 +623,9 @@ "importAccountMsg": { "message": " Imported accounts will not be associated with your originally created MetaMask account seedphrase. Learn more about imported accounts " }, + "importAccountSeedPhrase": { + "message": "Import an Account with Seed Phrase" + }, "importAnAccount": { "message": "Import an account" }, @@ -624,6 +639,9 @@ "importUsingSeed": { "message": "Import using account seed phrase" }, + "importWithSeedPhrase": { + "message": "Import with seed phrase" + }, "info": { "message": "Info" }, @@ -731,6 +749,9 @@ "mainnet": { "message": "Main Ethereum Network" }, + "memorizePhrase": { + "message": "Memorize this phrase." + }, "menu": { "message": "Menu" }, @@ -1096,12 +1117,24 @@ "searchResults": { "message": "Search Results" }, + "secretBackupPhrase": { + "message": "Secret Backup Phrase" + }, + "secretBackupPhraseDescription": { + "message": "Your secret backup phrase makes it easy to back up and restore your account." + }, + "secretBackupPhraseWarning": { + "message": "WARNING: Never disclose your backup phrase. Anyone with this phrase can take your Ether forever." + }, "secretPhrase": { "message": "Enter your secret twelve word phrase here to restore your vault." }, "secondsShorthand": { "message": "Sec" }, + "seedPhrasePlaceholder": { + "message": "Separate each word with a single space" + }, "seedPhraseReq": { "message": "Seed phrases are 12 words long" }, @@ -1111,6 +1144,9 @@ "selectCurrency": { "message": "Select Currency" }, + "selectEachPhrase": { + "message": "Please select each phrase in order to make sure it is correct." + }, "selectLocale": { "message": "Select Locale" }, @@ -1258,6 +1294,9 @@ "step3HardwareWalletMsg": { "message": "Use your hardware account like you would with any Ethereum account. Log in to dApps, send Eth, buy and store ERC20 tokens and Non-Fungible tokens like CryptoKitties." }, + "storePhrase": { + "message": "Store this phrase in a password manager like 1Password." + }, "submit": { "message": "Submit" }, @@ -1279,6 +1318,9 @@ "testFaucet": { "message": "Test Faucet" }, + "tips": { + "message": "Tips" + }, "to": { "message": "To" }, @@ -1477,6 +1519,9 @@ "whatsThis": { "message": "What's this?" }, + "writePhrase": { + "message": "Write this phrase on a piece of paper and store in a secure location. If you want even more security, write it down on multiple pieces of paper and store each in 2 - 3 different locations." + }, "yesLetsTry": { "message": "Yes, let's try" }, @@ -1492,6 +1537,15 @@ "yourPrivateSeedPhrase": { "message": "Your private seed phrase" }, + "yourUniqueAccountImage": { + "message": "Your unique account image" + }, + "yourUniqueAccountImageDescription1": { + "message": "This image was programmatically generated for you by your new account number." + }, + "yourUniqueAccountImageDescription2": { + "message": "You’ll see this image everytime you need to confirm a transaction." + }, "zeroGasPriceOnSpeedUpError": { "message":"Zero gas price on speed up" } diff --git a/app/scripts/controllers/preferences.js b/app/scripts/controllers/preferences.js index fa162c21f..e82a69da2 100644 --- a/app/scripts/controllers/preferences.js +++ b/app/scripts/controllers/preferences.js @@ -46,6 +46,7 @@ class PreferencesController { preferences: { useNativeCurrencyAsPrimaryCurrency: true, }, + completedOnboarding: false, }, opts.initState) this.diagnostics = opts.diagnostics @@ -516,6 +517,15 @@ class PreferencesController { return this.store.getState().preferences } + /** + * Sets the completedOnboarding state to true, indicating that the user has completed the + * onboarding process. + */ + completeOnboarding () { + this.store.updateState({ completedOnboarding: true }) + return Promise.resolve(true) + } + // // PRIVATE METHODS // diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index ea57582a0..4189bdd10 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -425,6 +425,7 @@ module.exports = class MetamaskController extends EventEmitter { setAccountLabel: nodeify(preferencesController.setAccountLabel, preferencesController), setFeatureFlag: nodeify(preferencesController.setFeatureFlag, preferencesController), setPreference: nodeify(preferencesController.setPreference, preferencesController), + completeOnboarding: nodeify(preferencesController.completeOnboarding, preferencesController), addKnownMethodData: nodeify(preferencesController.addKnownMethodData, preferencesController), // BlacklistController diff --git a/app/scripts/migrations/031.js b/app/scripts/migrations/031.js new file mode 100644 index 000000000..98d182828 --- /dev/null +++ b/app/scripts/migrations/031.js @@ -0,0 +1,31 @@ +// next version number +const version = 31 +const clone = require('clone') + + /* + * The purpose of this migration is to properly set the completedOnboarding flag baesd on the state + * of the KeyringController. + */ +module.exports = { + version, + + migrate: async function (originalVersionedData) { + const versionedData = clone(originalVersionedData) + versionedData.meta.version = version + const state = versionedData.data + const newState = transformState(state) + versionedData.data = newState + return versionedData + }, +} + + function transformState (state) { + const { KeyringController, PreferencesController } = state + + if (KeyringController && PreferencesController) { + const { vault } = KeyringController + PreferencesController.completedOnboarding = Boolean(vault) + } + + return state +} diff --git a/app/scripts/migrations/index.js b/app/scripts/migrations/index.js index 99cca94b8..eb1b51685 100644 --- a/app/scripts/migrations/index.js +++ b/app/scripts/migrations/index.js @@ -41,4 +41,5 @@ module.exports = [ require('./028'), require('./029'), require('./030'), + require('./031'), ] diff --git a/app/scripts/ui.js b/app/scripts/ui.js index 682a4aaac..e4b9b7b9c 100644 --- a/app/scripts/ui.js +++ b/app/scripts/ui.js @@ -5,7 +5,7 @@ const {getShouldUseNewUi} = require('../../ui/app/selectors') const startPopup = require('./popup-core') const PortStream = require('extension-port-stream') const { getEnvironmentType } = require('./lib/util') -const { ENVIRONMENT_TYPE_NOTIFICATION } = require('./lib/enums') +const { ENVIRONMENT_TYPE_NOTIFICATION, ENVIRONMENT_TYPE_FULLSCREEN } = require('./lib/enums') const extension = require('extensionizer') const ExtensionPlatform = require('./platforms/extension') const NotificationManager = require('./lib/notification-manager') @@ -49,7 +49,14 @@ async function start () { if (err) return displayCriticalError(err) const state = store.getState() - let betaUIState = Boolean(state.featureFlags && state.featureFlags.betaUI) + const { metamask: { completedOnboarding, featureFlags } = {} } = state + + if (!completedOnboarding && windowType !== ENVIRONMENT_TYPE_FULLSCREEN) { + global.platform.openExtensionInBrowser() + return + } + + let betaUIState = Boolean(featureFlags && featureFlags.betaUI) const useBetaCss = getShouldUseNewUi(state) let css = useBetaCss ? NewMetaMaskUiCss() : OldMetaMaskUiCss() -- cgit