diff options
author | brunobar79 <brunobar79@gmail.com> | 2018-07-04 02:21:17 +0800 |
---|---|---|
committer | brunobar79 <brunobar79@gmail.com> | 2018-07-04 02:21:17 +0800 |
commit | 595447ccac0c6d178d63850d45f0ad5456964e4f (patch) | |
tree | 61b83e1ba63615351da8e4c2dc7b446353411c9d /app/scripts/lib | |
parent | 11736e6318182ab5b43430410a46059e5f46ad52 (diff) | |
parent | 2e9bd7e9d101287b4466475561df9131f0ef56a6 (diff) | |
download | tangerine-wallet-browser-595447ccac0c6d178d63850d45f0ad5456964e4f.tar tangerine-wallet-browser-595447ccac0c6d178d63850d45f0ad5456964e4f.tar.gz tangerine-wallet-browser-595447ccac0c6d178d63850d45f0ad5456964e4f.tar.bz2 tangerine-wallet-browser-595447ccac0c6d178d63850d45f0ad5456964e4f.tar.lz tangerine-wallet-browser-595447ccac0c6d178d63850d45f0ad5456964e4f.tar.xz tangerine-wallet-browser-595447ccac0c6d178d63850d45f0ad5456964e4f.tar.zst tangerine-wallet-browser-595447ccac0c6d178d63850d45f0ad5456964e4f.zip |
Merge remote-tracking branch 'upstream/develop' into HEAD
Diffstat (limited to 'app/scripts/lib')
-rw-r--r-- | app/scripts/lib/cleanErrorStack.js | 2 | ||||
-rw-r--r-- | app/scripts/lib/createErrorMiddleware.js | 3 | ||||
-rw-r--r-- | app/scripts/lib/createStreamSink.js | 24 | ||||
-rw-r--r-- | app/scripts/lib/diagnostics-reporter.js | 71 | ||||
-rw-r--r-- | app/scripts/lib/extractEthjsErrorMessage.js | 4 | ||||
-rw-r--r-- | app/scripts/lib/get-first-preferred-lang-code.js | 20 | ||||
-rw-r--r-- | app/scripts/lib/getObjStructure.js | 6 | ||||
-rw-r--r-- | app/scripts/lib/local-store.js | 12 | ||||
-rw-r--r-- | app/scripts/lib/notification-manager.js | 10 | ||||
-rw-r--r-- | app/scripts/lib/port-stream.js | 2 | ||||
-rw-r--r-- | app/scripts/lib/reportFailedTxToSentry.js | 2 | ||||
-rw-r--r-- | app/scripts/lib/setupMetamaskMeshMetrics.js | 2 | ||||
-rw-r--r-- | app/scripts/lib/setupRaven.js | 16 |
13 files changed, 143 insertions, 31 deletions
diff --git a/app/scripts/lib/cleanErrorStack.js b/app/scripts/lib/cleanErrorStack.js index fe1bfb0ce..8adf55db7 100644 --- a/app/scripts/lib/cleanErrorStack.js +++ b/app/scripts/lib/cleanErrorStack.js @@ -3,7 +3,7 @@ * @param {Error} err - error * @returns {Error} Error with clean stack trace. */ -function cleanErrorStack(err){ +function cleanErrorStack (err) { var name = err.name name = (name === undefined) ? 'Error' : String(name) diff --git a/app/scripts/lib/createErrorMiddleware.js b/app/scripts/lib/createErrorMiddleware.js index baed99e45..7f6a4bd73 100644 --- a/app/scripts/lib/createErrorMiddleware.js +++ b/app/scripts/lib/createErrorMiddleware.js @@ -59,8 +59,9 @@ function createErrorMiddleware ({ override = true } = {}) { if (!error) { return done() } sanitizeRPCError(error) log.error(`MetaMask - RPC Error: ${error.message}`, error) + done() }) } } -module.exports = createErrorMiddleware
\ No newline at end of file +module.exports = createErrorMiddleware diff --git a/app/scripts/lib/createStreamSink.js b/app/scripts/lib/createStreamSink.js new file mode 100644 index 000000000..b93dbc089 --- /dev/null +++ b/app/scripts/lib/createStreamSink.js @@ -0,0 +1,24 @@ +const WritableStream = require('readable-stream').Writable +const promiseToCallback = require('promise-to-callback') + +module.exports = createStreamSink + + +function createStreamSink (asyncWriteFn, _opts) { + return new AsyncWritableStream(asyncWriteFn, _opts) +} + +class AsyncWritableStream extends WritableStream { + + constructor (asyncWriteFn, _opts) { + const opts = Object.assign({ objectMode: true }, _opts) + super(opts) + this._asyncWriteFn = asyncWriteFn + } + + // write from incomming stream to state + _write (chunk, encoding, callback) { + promiseToCallback(this._asyncWriteFn(chunk, encoding))(callback) + } + +} diff --git a/app/scripts/lib/diagnostics-reporter.js b/app/scripts/lib/diagnostics-reporter.js new file mode 100644 index 000000000..569eb3268 --- /dev/null +++ b/app/scripts/lib/diagnostics-reporter.js @@ -0,0 +1,71 @@ +class DiagnosticsReporter { + + constructor ({ firstTimeInfo, version }) { + this.firstTimeInfo = firstTimeInfo + this.version = version + } + + async reportOrphans (orphans) { + try { + return await this.submit({ + accounts: Object.keys(orphans), + metadata: { + type: 'orphans', + }, + }) + } catch (err) { + console.error('DiagnosticsReporter - "reportOrphans" encountered an error:') + console.error(err) + } + } + + async reportMultipleKeyrings (rawKeyrings) { + try { + const keyrings = await Promise.all(rawKeyrings.map(async (keyring, index) => { + return { + index, + type: keyring.type, + accounts: await keyring.getAccounts(), + } + })) + return await this.submit({ + accounts: [], + metadata: { + type: 'keyrings', + keyrings, + }, + }) + } catch (err) { + console.error('DiagnosticsReporter - "reportMultipleKeyrings" encountered an error:') + console.error(err) + } + } + + async submit (message) { + try { + // add metadata + message.metadata.version = this.version + message.metadata.firstTimeInfo = this.firstTimeInfo + return await postData(message) + } catch (err) { + console.error('DiagnosticsReporter - "submit" encountered an error:') + throw err + } + } + +} + +function postData (data) { + const uri = 'https://diagnostics.metamask.io/v1/orphanedAccounts' + return fetch(uri, { + body: JSON.stringify(data), // must match 'Content-Type' header + credentials: 'same-origin', // include, same-origin, *omit + headers: { + 'content-type': 'application/json', + }, + method: 'POST', // *GET, POST, PUT, DELETE, etc. + mode: 'cors', // no-cors, cors, *same-origin + }) +} + +module.exports = DiagnosticsReporter diff --git a/app/scripts/lib/extractEthjsErrorMessage.js b/app/scripts/lib/extractEthjsErrorMessage.js index 0f100756f..4891075c3 100644 --- a/app/scripts/lib/extractEthjsErrorMessage.js +++ b/app/scripts/lib/extractEthjsErrorMessage.js @@ -10,13 +10,13 @@ module.exports = extractEthjsErrorMessage * * @param {string} errorMessage The error message to parse * @returns {string} Returns an error message, either the same as was passed, or the ending message portion of an isEthjsRpcError - * + * * @example * // returns 'Transaction Failed: replacement transaction underpriced' * extractEthjsErrorMessage(`Error: [ethjs-rpc] rpc error with payload {"id":3947817945380,"jsonrpc":"2.0","params":["0xf8eb8208708477359400830398539406012c8cf97bead5deae237070f9587f8e7a266d80b8843d7d3f5a0000000000000000000000000000000000000000000000000000000000081d1a000000000000000000000000000000000000000000000000001ff973cafa800000000000000000000000000000000000000000000000000000038d7ea4c68000000000000000000000000000000000000000000000000000000000000003f48025a04c32a9b630e0d9e7ff361562d850c86b7a884908135956a7e4a336fa0300d19ca06830776423f25218e8d19b267161db526e66895567147015b1f3fc47aef9a3c7"],"method":"eth_sendRawTransaction"} Error: replacement transaction underpriced`) * */ -function extractEthjsErrorMessage(errorMessage) { +function extractEthjsErrorMessage (errorMessage) { const isEthjsRpcError = errorMessage.includes(ethJsRpcSlug) if (isEthjsRpcError) { const payloadAndError = errorMessage.slice(ethJsRpcSlug.length) diff --git a/app/scripts/lib/get-first-preferred-lang-code.js b/app/scripts/lib/get-first-preferred-lang-code.js index 1e6a83ba6..170d508c1 100644 --- a/app/scripts/lib/get-first-preferred-lang-code.js +++ b/app/scripts/lib/get-first-preferred-lang-code.js @@ -2,8 +2,7 @@ const extension = require('extensionizer') const promisify = require('pify') const allLocales = require('../../_locales/index.json') -const isSupported = extension.i18n && extension.i18n.getAcceptLanguages -const getPreferredLocales = isSupported ? promisify( +const getPreferredLocales = extension.i18n ? promisify( extension.i18n.getAcceptLanguages, { errorFirst: false } ) : async () => [] @@ -18,7 +17,21 @@ const existingLocaleCodes = allLocales.map(locale => locale.code.toLowerCase().r * */ async function getFirstPreferredLangCode () { - const userPreferredLocaleCodes = await getPreferredLocales() + let userPreferredLocaleCodes + + try { + userPreferredLocaleCodes = await getPreferredLocales() + } catch (e) { + // Brave currently throws when calling getAcceptLanguages, so this handles that. + userPreferredLocaleCodes = [] + } + + // safeguard for Brave Browser until they implement chrome.i18n.getAcceptLanguages + // https://github.com/MetaMask/metamask-extension/issues/4270 + if (!userPreferredLocaleCodes) { + userPreferredLocaleCodes = [] + } + const firstPreferredLangCode = userPreferredLocaleCodes .map(code => code.toLowerCase()) .find(code => existingLocaleCodes.includes(code)) @@ -26,3 +39,4 @@ async function getFirstPreferredLangCode () { } module.exports = getFirstPreferredLangCode + diff --git a/app/scripts/lib/getObjStructure.js b/app/scripts/lib/getObjStructure.js index 52250d3fb..9c92879fb 100644 --- a/app/scripts/lib/getObjStructure.js +++ b/app/scripts/lib/getObjStructure.js @@ -18,12 +18,12 @@ module.exports = getObjStructure * Creates an object that represents the structure of the given object. It replaces all values with the result of their * type. * - * @param {object} obj The object for which a 'structure' will be returned. Usually a plain object and not a class. + * @param {object} obj The object for which a 'structure' will be returned. Usually a plain object and not a class. * @returns {object} The "mapped" version of a deep clone of the passed object, with each non-object property value * replaced with the javascript type of that value. * */ -function getObjStructure(obj) { +function getObjStructure (obj) { const structure = clone(obj) return deepMap(structure, (value) => { return value === null ? 'null' : typeof value @@ -38,7 +38,7 @@ function getObjStructure(obj) { * @param {Function} visit The modifier to apply to each non-object property value * @returns {object} The modified object */ -function deepMap(target = {}, visit) { +function deepMap (target = {}, visit) { Object.entries(target).forEach(([key, value]) => { if (typeof value === 'object' && value !== null) { target[key] = deepMap(value, visit) diff --git a/app/scripts/lib/local-store.js b/app/scripts/lib/local-store.js index 139ff86bd..fbcba09cd 100644 --- a/app/scripts/lib/local-store.js +++ b/app/scripts/lib/local-store.js @@ -8,7 +8,7 @@ module.exports = class ExtensionStore { /** * @constructor */ - constructor() { + constructor () { this.isSupported = !!(extension.storage.local) if (!this.isSupported) { log.error('Storage local API not available.') @@ -19,7 +19,7 @@ module.exports = class ExtensionStore { * Returns all of the keys currently saved * @return {Promise<*>} */ - async get() { + async get () { if (!this.isSupported) return undefined const result = await this._get() // extension.storage.local always returns an obj @@ -36,7 +36,7 @@ module.exports = class ExtensionStore { * @param {object} state - The state to set * @return {Promise<void>} */ - async set(state) { + async set (state) { return this._set(state) } @@ -45,7 +45,7 @@ module.exports = class ExtensionStore { * @private * @return {object} the key-value map from local storage */ - _get() { + _get () { const local = extension.storage.local return new Promise((resolve, reject) => { local.get(null, (/** @type {any} */ result) => { @@ -65,7 +65,7 @@ module.exports = class ExtensionStore { * @return {Promise<void>} * @private */ - _set(obj) { + _set (obj) { const local = extension.storage.local return new Promise((resolve, reject) => { local.set(obj, () => { @@ -85,6 +85,6 @@ module.exports = class ExtensionStore { * @param {object} obj - The object to check * @returns {boolean} */ -function isEmpty(obj) { +function isEmpty (obj) { return Object.keys(obj).length === 0 } diff --git a/app/scripts/lib/notification-manager.js b/app/scripts/lib/notification-manager.js index 5dfb42078..969a9459a 100644 --- a/app/scripts/lib/notification-manager.js +++ b/app/scripts/lib/notification-manager.js @@ -26,13 +26,15 @@ class NotificationManager { // bring focus to existing chrome popup extension.windows.update(popup.id, { focused: true }) } else { + const cb = (currentPopup) => { this._popupId = currentPopup.id } // create new notification popup - extension.windows.create({ + const creation = extension.windows.create({ url: 'notification.html', type: 'popup', width, height, - }) + }, cb) + creation && creation.then && creation.then(cb) } }) } @@ -84,7 +86,7 @@ class NotificationManager { } /** - * Given an array of windows, returns the first that has a 'popup' type, or null if no such window exists. + * Given an array of windows, returns the 'popup' that has been opened by MetaMask, or null if no such window exists. * * @private * @param {array} windows An array of objects containing data about the open MetaMask extension windows. @@ -93,7 +95,7 @@ class NotificationManager { _getPopupIn (windows) { return windows ? windows.find((win) => { // Returns notification popup - return (win && win.type === 'popup') + return (win && win.type === 'popup' && win.id === this._popupId) }) : null } diff --git a/app/scripts/lib/port-stream.js b/app/scripts/lib/port-stream.js index 5c4224fd9..fd65d94f3 100644 --- a/app/scripts/lib/port-stream.js +++ b/app/scripts/lib/port-stream.js @@ -58,7 +58,7 @@ PortDuplexStream.prototype._read = noop /** * Called internally when data should be written to * this writable stream. - * + * * @private * @param {*} msg Arbitrary object to write * @param {string} encoding Encoding to use when writing payload diff --git a/app/scripts/lib/reportFailedTxToSentry.js b/app/scripts/lib/reportFailedTxToSentry.js index e09f4f1f8..df5661e59 100644 --- a/app/scripts/lib/reportFailedTxToSentry.js +++ b/app/scripts/lib/reportFailedTxToSentry.js @@ -7,7 +7,7 @@ module.exports = reportFailedTxToSentry // for sending to sentry // -function reportFailedTxToSentry({ raven, txMeta }) { +function reportFailedTxToSentry ({ raven, txMeta }) { const errorMessage = 'Transaction Failed: ' + extractEthjsErrorMessage(txMeta.err.message) raven.captureMessage(errorMessage, { // "extra" key is required by Sentry diff --git a/app/scripts/lib/setupMetamaskMeshMetrics.js b/app/scripts/lib/setupMetamaskMeshMetrics.js index 02690a948..fd3b93fc4 100644 --- a/app/scripts/lib/setupMetamaskMeshMetrics.js +++ b/app/scripts/lib/setupMetamaskMeshMetrics.js @@ -4,7 +4,7 @@ module.exports = setupMetamaskMeshMetrics /** * Injects an iframe into the current document for testing */ -function setupMetamaskMeshMetrics() { +function setupMetamaskMeshMetrics () { const testingContainer = document.createElement('iframe') testingContainer.src = 'https://metamask.github.io/mesh-testing/' console.log('Injecting MetaMask Mesh testing client') diff --git a/app/scripts/lib/setupRaven.js b/app/scripts/lib/setupRaven.js index d164827ab..3f69fb3bb 100644 --- a/app/scripts/lib/setupRaven.js +++ b/app/scripts/lib/setupRaven.js @@ -7,7 +7,7 @@ const DEV = 'https://f59f3dd640d2429d9d0e2445a87ea8e1@sentry.io/273496' module.exports = setupRaven // Setup raven / sentry remote error reporting -function setupRaven(opts) { +function setupRaven (opts) { const { release } = opts let ravenTarget @@ -21,7 +21,7 @@ function setupRaven(opts) { const client = Raven.config(ravenTarget, { release, - transport: function(opts) { + transport: function (opts) { const report = opts.data try { // handle error-like non-error exceptions @@ -42,7 +42,7 @@ function setupRaven(opts) { return Raven } -function rewriteErrorLikeExceptions(report) { +function rewriteErrorLikeExceptions (report) { // handle errors that lost their error-ness in serialization (e.g. dnode) rewriteErrorMessages(report, (errorMessage) => { if (!errorMessage.includes('Non-Error exception captured with keys:')) return errorMessage @@ -51,7 +51,7 @@ function rewriteErrorLikeExceptions(report) { }) } -function simplifyErrorMessages(report) { +function simplifyErrorMessages (report) { rewriteErrorMessages(report, (errorMessage) => { // simplify ethjs error messages errorMessage = extractEthjsErrorMessage(errorMessage) @@ -64,9 +64,9 @@ function simplifyErrorMessages(report) { }) } -function rewriteErrorMessages(report, rewriteFn) { +function rewriteErrorMessages (report, rewriteFn) { // rewrite top level message - report.message = rewriteFn(report.message) + if (report.message) report.message = rewriteFn(report.message) // rewrite each exception message if (report.exception && report.exception.values) { report.exception.values.forEach(item => { @@ -75,7 +75,7 @@ function rewriteErrorMessages(report, rewriteFn) { } } -function rewriteReportUrls(report) { +function rewriteReportUrls (report) { // update request url report.request.url = toMetamaskUrl(report.request.url) // update exception stack trace @@ -88,7 +88,7 @@ function rewriteReportUrls(report) { } } -function toMetamaskUrl(origUrl) { +function toMetamaskUrl (origUrl) { const filePath = origUrl.split(location.origin)[1] if (!filePath) return origUrl const metamaskUrl = `metamask${filePath}` |