From 0f512e39250494c7399dadd3bf300256f9aed823 Mon Sep 17 00:00:00 2001 From: Daniel Gasienica Date: Mon, 5 Mar 2018 16:03:13 -0500 Subject: [PATCH 01/27] Whitelist `js/logging.js` for ESLint --- .eslintignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.eslintignore b/.eslintignore index 8773f6f9f9..206f78eca0 100644 --- a/.eslintignore +++ b/.eslintignore @@ -16,6 +16,7 @@ test/views/*.js # ES2015+ files !js/background.js +!js/logging.js !js/models/conversations.js !js/views/attachment_view.js !js/views/conversation_search_view.js From 9d638797de0dc5f83cd9343391cb0940f502dabe Mon Sep 17 00:00:00 2001 From: Daniel Gasienica Date: Mon, 5 Mar 2018 17:36:41 -0500 Subject: [PATCH 02/27] Whitelist `js/views/debug_log_view.js` for ESLint --- .eslintignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.eslintignore b/.eslintignore index 206f78eca0..69eb4216d0 100644 --- a/.eslintignore +++ b/.eslintignore @@ -20,6 +20,7 @@ test/views/*.js !js/models/conversations.js !js/views/attachment_view.js !js/views/conversation_search_view.js +!js/views/debug_log_view.js !js/views/file_input_view.js !js/views/inbox_view.js !main.js From 5d6cd0ea39720d82308d3b8658955165f1ab0ee9 Mon Sep 17 00:00:00 2001 From: Daniel Gasienica Date: Mon, 5 Mar 2018 16:05:10 -0500 Subject: [PATCH 03/27] Apply ESLint auto-fixes: `js/logging.js` --- js/logging.js | 63 ++++++++++++++++++++++++--------------------------- 1 file changed, 30 insertions(+), 33 deletions(-) diff --git a/js/logging.js b/js/logging.js index cd66f9e976..678d55b98d 100644 --- a/js/logging.js +++ b/js/logging.js @@ -23,13 +23,11 @@ const LEVELS = { // Backwards-compatible logging, simple strings and no level (defaulted to INFO) function redactPhone(text) { - return text.replace(PHONE_REGEX, "+[REDACTED]$1"); + return text.replace(PHONE_REGEX, '+[REDACTED]$1'); } function redactGroup(text) { - return text.replace(GROUP_REGEX, function(match, before, id, after) { - return before + '[REDACTED]' + id.slice(-3) + after; - }); + return text.replace(GROUP_REGEX, (match, before, id, after) => `${before}[REDACTED]${id.slice(-3)}${after}`); } function now() { @@ -41,15 +39,14 @@ function log() { const args = Array.prototype.slice.call(arguments, 0); const consoleArgs = ['INFO ', now()].concat(args); - console._log.apply(console, consoleArgs); + console._log(...consoleArgs); // To avoid [Object object] in our log since console.log handles non-strings smoothly - const str = args.map(function(item) { + const str = args.map((item) => { if (typeof item !== 'string') { try { return JSON.stringify(item); - } - catch (e) { + } catch (e) { return item; } } @@ -71,14 +68,14 @@ if (window.console) { function getHeader() { let header = window.navigator.userAgent; - header += ' node/' + window.config.node_version; - header += ' env/' + window.config.environment; + header += ` node/${window.config.node_version}`; + header += ` env/${window.config.environment}`; return header; } function getLevel(level) { - var text = LEVELS[level]; + const text = LEVELS[level]; if (!text) { return BLANK_LEVEL; } @@ -87,7 +84,7 @@ function getLevel(level) { } function formatLine(entry) { - return getLevel(entry.level) + ' ' + entry.time + ' ' + entry.msg; + return `${getLevel(entry.level)} ${entry.time} ${entry.msg}`; } function format(entries) { @@ -95,35 +92,35 @@ function format(entries) { } function fetch() { - return new Promise(function(resolve) { + return new Promise(((resolve) => { ipc.send('fetch-log'); - ipc.on('fetched-log', function(event, text) { - var result = getHeader() + '\n' + format(text); + ipc.on('fetched-log', (event, text) => { + const result = `${getHeader()}\n${format(text)}`; resolve(result); }); - }); + })); } function publish(log) { log = log || fetch(); - return new Promise(function(resolve) { + return new Promise(((resolve) => { const payload = textsecure.utils.jsonThing({ files: { 'debugLog.txt': { - content: log - } - } + content: log, + }, + }, }); $.post('https://api.github.com/gists', payload) - .then(function(response) { + .then((response) => { console._log('Posted debug log to ', response.html_url); resolve(response.html_url); }) .fail(resolve); - }); + })); } @@ -136,11 +133,11 @@ const logger = bunyan.createLogger({ streams: [{ level: 'debug', stream: { - write: function(entry) { + write(entry) { console._log(formatLine(JSON.parse(entry))); - } - } - }] + }, + }, + }], }); // The Bunyan API: https://github.com/trentm/node-bunyan#log-method-api @@ -148,10 +145,10 @@ function logAtLevel() { const level = arguments[0]; const args = Array.prototype.slice.call(arguments, 1); - const ipcArgs = ['log-' + level].concat(args); - ipc.send.apply(ipc, ipcArgs); + const ipcArgs = [`log-${level}`].concat(args); + ipc.send(...ipcArgs); - logger[level].apply(logger, args); + logger[level](...args); } window.log = { @@ -165,11 +162,11 @@ window.log = { publish, }; -window.onerror = function(message, script, line, col, error) { +window.onerror = function (message, script, line, col, error) { const errorInfo = error && error.stack ? error.stack : JSON.stringify(error); - window.log.error('Top-level unhandled error: ' + errorInfo); + window.log.error(`Top-level unhandled error: ${errorInfo}`); }; -window.addEventListener('unhandledrejection', function(rejectionEvent) { - window.log.error('Top-level unhandled promise rejection: ' + rejectionEvent.reason); +window.addEventListener('unhandledrejection', (rejectionEvent) => { + window.log.error(`Top-level unhandled promise rejection: ${rejectionEvent.reason}`); }); From d4c9422a99c2436204edbb4b86f5802d75f9362d Mon Sep 17 00:00:00 2001 From: Daniel Gasienica Date: Mon, 5 Mar 2018 17:54:33 -0500 Subject: [PATCH 04/27] Apply ESLint auto-fixes: `debug_log_view.js` --- js/views/debug_log_view.js | 118 ++++++++++++++++++------------------- 1 file changed, 59 insertions(+), 59 deletions(-) diff --git a/js/views/debug_log_view.js b/js/views/debug_log_view.js index 357e2bf5ea..ed6b7c0b93 100644 --- a/js/views/debug_log_view.js +++ b/js/views/debug_log_view.js @@ -2,65 +2,65 @@ * vim: ts=4:sw=4:expandtab */ (function () { - 'use strict'; - window.Whisper = window.Whisper || {}; + 'use strict'; - Whisper.DebugLogLinkView = Whisper.View.extend({ - templateName: 'debug-log-link', - initialize: function(options) { - this.url = options.url; - }, - render_attributes: function() { - return { - url: this.url, - reportIssue: i18n('reportIssue') - }; - } - }); - Whisper.DebugLogView = Whisper.View.extend({ - templateName: 'debug-log', - className: 'debug-log modal', - initialize: function() { - this.render(); - this.$('textarea').val(i18n('loading')); + window.Whisper = window.Whisper || {}; - window.log.fetch().then(function(text) { - this.$('textarea').val(text); - }.bind(this)); - }, - events: { - 'click .submit': 'submit', - 'click .close': 'close' - }, - render_attributes: { - title: i18n('submitDebugLog'), - cancel: i18n('cancel'), - submit: i18n('submit'), - close: i18n('gotIt'), - debugLogExplanation: i18n('debugLogExplanation') - }, - close: function(e) { - e.preventDefault(); - this.remove(); - }, - submit: function(e) { - e.preventDefault(); - var text = this.$('textarea').val(); - if (text.length === 0) { - return; - } - log.publish(text).then(function(url) { - var view = new Whisper.DebugLogLinkView({ - url: url, - el: this.$('.result') - }); - this.$('.loading').removeClass('loading'); - view.render(); - this.$('.link').focus().select(); - }.bind(this)); - this.$('.buttons, textarea').remove(); - this.$('.result').addClass('loading'); - } - }); + Whisper.DebugLogLinkView = Whisper.View.extend({ + templateName: 'debug-log-link', + initialize(options) { + this.url = options.url; + }, + render_attributes() { + return { + url: this.url, + reportIssue: i18n('reportIssue'), + }; + }, + }); + Whisper.DebugLogView = Whisper.View.extend({ + templateName: 'debug-log', + className: 'debug-log modal', + initialize() { + this.render(); + this.$('textarea').val(i18n('loading')); -})(); + window.log.fetch().then((text) => { + this.$('textarea').val(text); + }); + }, + events: { + 'click .submit': 'submit', + 'click .close': 'close', + }, + render_attributes: { + title: i18n('submitDebugLog'), + cancel: i18n('cancel'), + submit: i18n('submit'), + close: i18n('gotIt'), + debugLogExplanation: i18n('debugLogExplanation'), + }, + close(e) { + e.preventDefault(); + this.remove(); + }, + submit(e) { + e.preventDefault(); + const text = this.$('textarea').val(); + if (text.length === 0) { + return; + } + log.publish(text).then((url) => { + const view = new Whisper.DebugLogLinkView({ + url, + el: this.$('.result'), + }); + this.$('.loading').removeClass('loading'); + view.render(); + this.$('.link').focus().select(); + }); + this.$('.buttons, textarea').remove(); + this.$('.result').addClass('loading'); + }, + }); +}()); From 7db44e35bd648aa4c553f1b1ac51def43f8a5639 Mon Sep 17 00:00:00 2001 From: Daniel Gasienica Date: Mon, 5 Mar 2018 16:05:43 -0500 Subject: [PATCH 05/27] Allow `node` environment for `js/logging.js` --- js/logging.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/js/logging.js b/js/logging.js index 678d55b98d..e4576b241f 100644 --- a/js/logging.js +++ b/js/logging.js @@ -1,3 +1,5 @@ +/* eslint-env node */ + const electron = require('electron'); const bunyan = require('bunyan'); const _ = require('lodash'); From 090345523f48b135804c2d703c31ddcf5ef49f61 Mon Sep 17 00:00:00 2001 From: Daniel Gasienica Date: Mon, 5 Mar 2018 16:07:06 -0500 Subject: [PATCH 06/27] Disable ESLint `strict` rule for module `js/logging.js` acts as a module even though it lives in `js/*`. --- js/logging.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/js/logging.js b/js/logging.js index e4576b241f..a00f7e02ef 100644 --- a/js/logging.js +++ b/js/logging.js @@ -1,5 +1,7 @@ /* eslint-env node */ +/* eslint strict: ['error', 'never'] */ + const electron = require('electron'); const bunyan = require('bunyan'); const _ = require('lodash'); From 6f7f55f78315e113e57b1926f28f4a63039fe2cf Mon Sep 17 00:00:00 2001 From: Daniel Gasienica Date: Mon, 5 Mar 2018 16:13:54 -0500 Subject: [PATCH 07/27] Whitelist globals --- js/logging.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/js/logging.js b/js/logging.js index a00f7e02ef..f6aa4ebd33 100644 --- a/js/logging.js +++ b/js/logging.js @@ -2,6 +2,9 @@ /* eslint strict: ['error', 'never'] */ +/* global $: false */ +/* global textsecure: false */ + const electron = require('electron'); const bunyan = require('bunyan'); const _ = require('lodash'); From b3a3729261224165597f13c817080a947b77b7ed Mon Sep 17 00:00:00 2001 From: Daniel Gasienica Date: Mon, 5 Mar 2018 16:14:22 -0500 Subject: [PATCH 08/27] Fix lint errors --- js/logging.js | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/js/logging.js b/js/logging.js index f6aa4ebd33..43ecaad0fa 100644 --- a/js/logging.js +++ b/js/logging.js @@ -34,7 +34,10 @@ function redactPhone(text) { } function redactGroup(text) { - return text.replace(GROUP_REGEX, (match, before, id, after) => `${before}[REDACTED]${id.slice(-3)}${after}`); + return text.replace( + GROUP_REGEX, + (match, before, id, after) => `${before}[REDACTED]${id.slice(-3)}${after}` + ); } function now() { @@ -42,9 +45,7 @@ function now() { return date.toJSON(); } -function log() { - const args = Array.prototype.slice.call(arguments, 0); - +function log(...args) { const consoleArgs = ['INFO ', now()].concat(args); console._log(...consoleArgs); @@ -53,7 +54,7 @@ function log() { if (typeof item !== 'string') { try { return JSON.stringify(item); - } catch (e) { + } catch (error) { return item; } } @@ -109,18 +110,19 @@ function fetch() { })); } -function publish(log) { - log = log || fetch(); +function publish(rawContent) { + const content = rawContent || fetch(); return new Promise(((resolve) => { const payload = textsecure.utils.jsonThing({ files: { 'debugLog.txt': { - content: log, + content, }, }, }); + // eslint-disable-next-line more/no-then $.post('https://api.github.com/gists', payload) .then((response) => { console._log('Posted debug log to ', response.html_url); @@ -148,10 +150,7 @@ const logger = bunyan.createLogger({ }); // The Bunyan API: https://github.com/trentm/node-bunyan#log-method-api -function logAtLevel() { - const level = arguments[0]; - const args = Array.prototype.slice.call(arguments, 1); - +function logAtLevel(level, ...args) { const ipcArgs = [`log-${level}`].concat(args); ipc.send(...ipcArgs); @@ -169,7 +168,7 @@ window.log = { publish, }; -window.onerror = function (message, script, line, col, error) { +window.onerror = (message, script, line, col, error) => { const errorInfo = error && error.stack ? error.stack : JSON.stringify(error); window.log.error(`Top-level unhandled error: ${errorInfo}`); }; From 325c0628cd6ae1e3e1cc1c940757e2e800e7c703 Mon Sep 17 00:00:00 2001 From: Daniel Gasienica Date: Mon, 5 Mar 2018 17:55:07 -0500 Subject: [PATCH 09/27] Remove Vim modeline --- js/views/debug_log_view.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/js/views/debug_log_view.js b/js/views/debug_log_view.js index ed6b7c0b93..e61f46f1d8 100644 --- a/js/views/debug_log_view.js +++ b/js/views/debug_log_view.js @@ -1,6 +1,3 @@ -/* - * vim: ts=4:sw=4:expandtab - */ (function () { 'use strict'; From 168788600a32081782c0085b1dabd157e7443ec4 Mon Sep 17 00:00:00 2001 From: Daniel Gasienica Date: Mon, 5 Mar 2018 17:57:23 -0500 Subject: [PATCH 10/27] Fix lint errors --- js/views/debug_log_view.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/js/views/debug_log_view.js b/js/views/debug_log_view.js index e61f46f1d8..032935a291 100644 --- a/js/views/debug_log_view.js +++ b/js/views/debug_log_view.js @@ -1,3 +1,9 @@ +/* eslint-env browser */ + +/* global i18n: false */ +/* global Whisper: false */ + +// eslint-disable-next-line func-names (function () { 'use strict'; @@ -22,6 +28,7 @@ this.render(); this.$('textarea').val(i18n('loading')); + // eslint-disable-next-line more/no-then window.log.fetch().then((text) => { this.$('textarea').val(text); }); @@ -47,7 +54,8 @@ if (text.length === 0) { return; } - log.publish(text).then((url) => { + // eslint-disable-next-line more/no-then + window.log.publish(text).then((url) => { const view = new Whisper.DebugLogLinkView({ url, el: this.$('.result'), From f6fd979ccb48d60e315ab913ebf92cf262bd1e75 Mon Sep 17 00:00:00 2001 From: Daniel Gasienica Date: Mon, 5 Mar 2018 17:58:05 -0500 Subject: [PATCH 11/27] Remove explicit ESLint `browser` directives --- js/background.js | 2 -- js/views/attachment_view.js | 2 -- js/views/debug_log_view.js | 2 -- 3 files changed, 6 deletions(-) diff --git a/js/background.js b/js/background.js index 0c6e733f5e..506874823f 100644 --- a/js/background.js +++ b/js/background.js @@ -1,7 +1,5 @@ /* eslint-disable */ -/* eslint-env browser */ - /* global Backbone: false */ /* global $: false */ diff --git a/js/views/attachment_view.js b/js/views/attachment_view.js index b429872845..861ab218f3 100644 --- a/js/views/attachment_view.js +++ b/js/views/attachment_view.js @@ -1,5 +1,3 @@ -/* eslint-env browser */ - /* global $: false */ /* global _: false */ /* global Backbone: false */ diff --git a/js/views/debug_log_view.js b/js/views/debug_log_view.js index 032935a291..0abdea58f6 100644 --- a/js/views/debug_log_view.js +++ b/js/views/debug_log_view.js @@ -1,5 +1,3 @@ -/* eslint-env browser */ - /* global i18n: false */ /* global Whisper: false */ From 969127a72a8e1bc4effccaece7c14968a78e938f Mon Sep 17 00:00:00 2001 From: Daniel Gasienica Date: Thu, 8 Mar 2018 13:45:22 -0500 Subject: [PATCH 12/27] Remove triple parens --- js/logging.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/js/logging.js b/js/logging.js index 43ecaad0fa..d1961226f8 100644 --- a/js/logging.js +++ b/js/logging.js @@ -100,20 +100,20 @@ function format(entries) { } function fetch() { - return new Promise(((resolve) => { + return new Promise((resolve) => { ipc.send('fetch-log'); ipc.on('fetched-log', (event, text) => { const result = `${getHeader()}\n${format(text)}`; resolve(result); }); - })); + }); } function publish(rawContent) { const content = rawContent || fetch(); - return new Promise(((resolve) => { + return new Promise((resolve) => { const payload = textsecure.utils.jsonThing({ files: { 'debugLog.txt': { @@ -129,7 +129,7 @@ function publish(rawContent) { resolve(response.html_url); }) .fail(resolve); - })); + }); } From e289479c6b079eedd68397e58ce28e84416c3a9a Mon Sep 17 00:00:00 2001 From: Daniel Gasienica Date: Mon, 5 Mar 2018 16:19:06 -0500 Subject: [PATCH 13/27] Add `superagent` dependency HTTP client with higher-level API than `fetch` and support for timeouts, etc. --- package.json | 1 + yarn.lock | 59 +++++++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 55 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 05a3b87a50..18d9de6b6a 100644 --- a/package.json +++ b/package.json @@ -69,6 +69,7 @@ "rimraf": "^2.6.2", "semver": "^5.4.1", "spellchecker": "^3.4.4", + "superagent": "^3.8.2", "testcheck": "^1.0.0-rc.2", "websocket": "^1.0.25" }, diff --git a/yarn.lock b/yarn.lock index 1892de8cb9..0932c58ac1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -858,6 +858,12 @@ colors@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/colors/-/colors-1.1.2.tgz#168a4701756b6a7f51a12ce0c97bfa28c084ed63" +combined-stream@1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.6.tgz#723e7df6e801ac5613113a7e445a9b69cb632818" + dependencies: + delayed-stream "~1.0.0" + combined-stream@^1.0.5, combined-stream@~1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.5.tgz#938370a57b4a51dea2c77c15d5c5fdf895164009" @@ -888,6 +894,10 @@ compare-version@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/compare-version/-/compare-version-0.1.2.tgz#0162ec2d9351f5ddd59a9202cba935366a725080" +component-emitter@^1.2.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.2.1.tgz#137918d6d78283f7df7a6b7c5a63e140e69425e6" + compress-commons@^1.2.0: version "1.2.2" resolved "https://registry.yarnpkg.com/compress-commons/-/compress-commons-1.2.2.tgz#524a9f10903f3a813389b0225d27c48bb751890f" @@ -966,6 +976,10 @@ convert-source-map@^1.3.0: version "1.5.1" resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.5.1.tgz#b8278097b9bc229365de5c62cf5fcaed8b5599e5" +cookiejar@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/cookiejar/-/cookiejar-2.1.1.tgz#41ad57b1b555951ec171412a81942b1e8200d34a" + core-js@^2.4.0: version "2.4.1" resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.4.1.tgz#4de911e667b0eae9124e34254b53aea6fc618d3e" @@ -1781,7 +1795,7 @@ expand-range@^1.8.1: dependencies: fill-range "^2.1.0" -extend@3, extend@~3.0.1: +extend@3, extend@^3.0.0, extend@~3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444" @@ -1963,6 +1977,14 @@ forever-agent@~0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" +form-data@^2.3.1: + version "2.3.2" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.2.tgz#4970498be604c20c005d4f5c23aecd21d6b49099" + dependencies: + asynckit "^0.4.0" + combined-stream "1.0.6" + mime-types "^2.1.12" + form-data@~2.1.1: version "2.1.4" resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.1.4.tgz#33c183acf193276ecaa98143a69e94bfee1750d1" @@ -1979,6 +2001,10 @@ form-data@~2.3.1: combined-stream "^1.0.5" mime-types "^2.1.12" +formidable@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/formidable/-/formidable-1.1.1.tgz#96b8886f7c3c3508b932d6bd70c4d3a88f35f1a9" + fs-extra-p@^4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/fs-extra-p/-/fs-extra-p-4.5.0.tgz#b79f3f3fcc0b5e57b7e7caeb06159f958ef15fe8" @@ -3364,6 +3390,10 @@ merge-source-map@^1.0.2: dependencies: source-map "^0.6.1" +methods@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" + micromatch@^2.3.11: version "2.3.11" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-2.3.11.tgz#86677c97d1720b363431d04d0d15293bd38c1565" @@ -3406,6 +3436,10 @@ mime@^1.3.4: version "1.4.0" resolved "https://registry.yarnpkg.com/mime/-/mime-1.4.0.tgz#69e9e0db51d44f2a3b56e48b7817d7d137f1a343" +mime@^1.4.1: + version "1.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" + mime@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/mime/-/mime-2.2.0.tgz#161e541965551d3b549fa1114391e3a3d55b923b" @@ -4139,6 +4173,10 @@ qs@5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/qs/-/qs-5.2.0.tgz#a9f31142af468cb72b25b30136ba2456834916be" +qs@^6.5.1, qs@~6.5.1: + version "6.5.1" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.1.tgz#349cdf6eef89ec45c12d7d5eb3fc0c870343a6d8" + qs@~5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/qs/-/qs-5.1.0.tgz#4d932e5c7ea411cca76a312d39a606200fd50cd9" @@ -4147,10 +4185,6 @@ qs@~6.4.0: version "6.4.0" resolved "https://registry.yarnpkg.com/qs/-/qs-6.4.0.tgz#13e26d28ad6b0ffaa91312cd3bf708ed351e7233" -qs@~6.5.1: - version "6.5.1" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.1.tgz#349cdf6eef89ec45c12d7d5eb3fc0c870343a6d8" - querystring@0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" @@ -4913,6 +4947,21 @@ sumchecker@^2.0.1, sumchecker@^2.0.2: dependencies: debug "^2.2.0" +superagent@^3.8.2: + version "3.8.2" + resolved "https://registry.yarnpkg.com/superagent/-/superagent-3.8.2.tgz#e4a11b9d047f7d3efeb3bbe536d9ec0021d16403" + dependencies: + component-emitter "^1.2.0" + cookiejar "^2.1.0" + debug "^3.1.0" + extend "^3.0.0" + form-data "^2.3.1" + formidable "^1.1.1" + methods "^1.1.1" + mime "^1.4.1" + qs "^6.5.1" + readable-stream "^2.0.5" + supports-color@4.4.0, supports-color@^4.0.0: version "4.4.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-4.4.0.tgz#883f7ddabc165142b2a61427f3352ded195d1a3e" From cb464c630111c0bf40927af02a96f96f82d474d5 Mon Sep 17 00:00:00 2001 From: Daniel Gasienica Date: Mon, 5 Mar 2018 17:59:29 -0500 Subject: [PATCH 14/27] Ensure `isFocused` always returns boolean --- js/focus_listener.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/js/focus_listener.js b/js/focus_listener.js index 08434f1cc9..04d4d33e39 100644 --- a/js/focus_listener.js +++ b/js/focus_listener.js @@ -1,7 +1,7 @@ (function () { 'use strict'; - var windowFocused; + var windowFocused = false; window.addEventListener('blur', function() { windowFocused = false; }); @@ -12,5 +12,4 @@ window.isFocused = function() { return windowFocused; }; - })(); From bd5f3bd73a1bda1fc8874c9f65741541f3c7d28a Mon Sep 17 00:00:00 2001 From: Daniel Gasienica Date: Mon, 5 Mar 2018 17:59:52 -0500 Subject: [PATCH 15/27] Make dialog title consistent with menu bar item --- _locales/en/messages.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/_locales/en/messages.json b/_locales/en/messages.json index 8b27ca1972..e5fe9f1e16 100644 --- a/_locales/en/messages.json +++ b/_locales/en/messages.json @@ -367,8 +367,8 @@ } }, "submitDebugLog": { - "message": "Submit debug log", - "description": "Menu item and header text for debug log modal, title case." + "message": "Debug log", + "description": "Menu item and header text for debug log modal (sentence case)" }, "debugLog": { "message": "Debug Log", From 3ab3e93a2865514420e7851a045256085620a0ca Mon Sep 17 00:00:00 2001 From: Daniel Gasienica Date: Mon, 5 Mar 2018 18:01:12 -0500 Subject: [PATCH 16/27] Upload debug logs to debuglogs.org --- js/logging.js | 40 ++++++++++++++++++---------------------- 1 file changed, 18 insertions(+), 22 deletions(-) diff --git a/js/logging.js b/js/logging.js index d1961226f8..6fedabc0c7 100644 --- a/js/logging.js +++ b/js/logging.js @@ -2,12 +2,10 @@ /* eslint strict: ['error', 'never'] */ -/* global $: false */ -/* global textsecure: false */ - const electron = require('electron'); const bunyan = require('bunyan'); const _ = require('lodash'); +const superagent = require('superagent'); const ipc = electron.ipcRenderer; @@ -110,27 +108,25 @@ function fetch() { }); } -function publish(rawContent) { - const content = rawContent || fetch(); - - return new Promise((resolve) => { - const payload = textsecure.utils.jsonThing({ - files: { - 'debugLog.txt': { - content, - }, - }, - }); +const DEBUGLOGS_API_URL = 'https://debuglogs.org'; +const publish = async (content) => { + const credentialsResponse = await superagent.get(DEBUGLOGS_API_URL); + const { fields, url } = credentialsResponse.body; + const uploadRequest = superagent.post(url); + Object.entries(fields).forEach(([key, value]) => { + uploadRequest.field(key, value); + }); - // eslint-disable-next-line more/no-then - $.post('https://api.github.com/gists', payload) - .then((response) => { - console._log('Posted debug log to ', response.html_url); - resolve(response.html_url); - }) - .fail(resolve); + const contentBuffer = Buffer.from(content, 'utf8'); + uploadRequest.attach('file', contentBuffer, { + contentType: 'text/plain', + filename: 'signal-desktop-debug-log.txt', }); -} + + await uploadRequest; + + return `${DEBUGLOGS_API_URL}/${fields.key}`; +}; // A modern logging interface for the browser From acf48595f39f711ef57c32fc5a0354a6892816b0 Mon Sep 17 00:00:00 2001 From: Daniel Gasienica Date: Mon, 5 Mar 2018 18:01:33 -0500 Subject: [PATCH 17/27] Show log in a monospaced font Makes it easier for users to edit it as timestamps, etc., better align. --- stylesheets/_debugLog.scss | 3 +++ 1 file changed, 3 insertions(+) diff --git a/stylesheets/_debugLog.scss b/stylesheets/_debugLog.scss index 91501ba030..8374e90850 100644 --- a/stylesheets/_debugLog.scss +++ b/stylesheets/_debugLog.scss @@ -15,6 +15,9 @@ width: 100%; resize: none; min-height: 100px; + + font-family: Monaco, Consolas, 'Courier New', Courier, monospace; + font-size: 12px; } } } From e4b34a6287b9c04255f4e3386f45dc3c05827e51 Mon Sep 17 00:00:00 2001 From: Daniel Gasienica Date: Mon, 5 Mar 2018 18:23:59 -0500 Subject: [PATCH 18/27] Make `DebugLogView::submit` async --- js/views/debug_log_view.js | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/js/views/debug_log_view.js b/js/views/debug_log_view.js index 0abdea58f6..6e8027cf6d 100644 --- a/js/views/debug_log_view.js +++ b/js/views/debug_log_view.js @@ -46,24 +46,24 @@ e.preventDefault(); this.remove(); }, - submit(e) { + async submit(e) { e.preventDefault(); const text = this.$('textarea').val(); if (text.length === 0) { return; } - // eslint-disable-next-line more/no-then - window.log.publish(text).then((url) => { - const view = new Whisper.DebugLogLinkView({ - url, - el: this.$('.result'), - }); - this.$('.loading').removeClass('loading'); - view.render(); - this.$('.link').focus().select(); - }); + this.$('.buttons, textarea').remove(); this.$('.result').addClass('loading'); + + const publishedLogURL = await window.log.publish(text); + const view = new Whisper.DebugLogLinkView({ + url: publishedLogURL, + el: this.$('.result'), + }); + this.$('.loading').removeClass('loading'); + view.render(); + this.$('.link').focus().select(); }, }); }()); From 1755e24854f622eefbe38aad66bd66f69026586c Mon Sep 17 00:00:00 2001 From: Daniel Gasienica Date: Mon, 5 Mar 2018 18:25:07 -0500 Subject: [PATCH 19/27] Add ES2015 modules to JSHint ignore list --- Gruntfile.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Gruntfile.js b/Gruntfile.js index e151775411..d644091483 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -103,7 +103,9 @@ module.exports = function(grunt) { '!js/Mp3LameEncoder.min.js', '!js/libsignal-protocol-worker.js', '!js/components.js', + '!js/logging.js', '!js/modules/**/*.js', + '!js/views/debug_log_view.js', '!js/signal_protocol_store.js', '_locales/**/*' ], From 1e2cd3ae1fd2ec330392b945e67d48ccd475a849 Mon Sep 17 00:00:00 2001 From: Daniel Gasienica Date: Mon, 5 Mar 2018 18:36:25 -0500 Subject: [PATCH 20/27] =?UTF-8?q?Rename=20=E2=80=98File=20a=20Bug=E2=80=99?= =?UTF-8?q?=20to=20=E2=80=98Report=20an=20Issue=E2=80=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This makes it more consistent with ‘Report an issue’ under View > Debug Log. Not using ellipsis as menu item doesn’t require user confirmation: https://stackoverflow.com/a/637708 --- _locales/en/messages.json | 6 +++--- app/menu.js | 2 +- test/app/fixtures/menu-mac-os-setup.json | 2 +- test/app/fixtures/menu-mac-os.json | 2 +- test/app/fixtures/menu-windows-linux-setup.json | 2 +- test/app/fixtures/menu-windows-linux.json | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/_locales/en/messages.json b/_locales/en/messages.json index e5fe9f1e16..101522c33d 100644 --- a/_locales/en/messages.json +++ b/_locales/en/messages.json @@ -386,9 +386,9 @@ "message": "Go to Support Page", "description": "Item under the Help menu, takes you to the support page" }, - "fileABug": { - "message": "File a Bug", - "description": "Item under the Help menu, takes you to GitHub new issue form" + "menuReportIssue": { + "message": "Report an Issue", + "description": "Item under the Help menu, takes you to GitHub new issue form (title case)" }, "aboutSignalDesktop": { "message": "About Signal Desktop", diff --git a/app/menu.js b/app/menu.js index 878a6ec1a8..16c0fe23f5 100644 --- a/app/menu.js +++ b/app/menu.js @@ -130,7 +130,7 @@ exports.createTemplate = (options, messages) => { click: openSupportPage, }, { - label: messages.fileABug.message, + label: messages.menuReportIssue.message, click: openNewBugForm, }, { diff --git a/test/app/fixtures/menu-mac-os-setup.json b/test/app/fixtures/menu-mac-os-setup.json index b68a81bbb6..c044898a0f 100644 --- a/test/app/fixtures/menu-mac-os-setup.json +++ b/test/app/fixtures/menu-mac-os-setup.json @@ -172,7 +172,7 @@ "click": null }, { - "label": "File a Bug", + "label": "Report an Issue", "click": null } ] diff --git a/test/app/fixtures/menu-mac-os.json b/test/app/fixtures/menu-mac-os.json index a0d79f593f..2a4d73d5c4 100644 --- a/test/app/fixtures/menu-mac-os.json +++ b/test/app/fixtures/menu-mac-os.json @@ -159,7 +159,7 @@ "click": null }, { - "label": "File a Bug", + "label": "Report an Issue", "click": null } ] diff --git a/test/app/fixtures/menu-windows-linux-setup.json b/test/app/fixtures/menu-windows-linux-setup.json index 57deb232d6..570bebbd93 100644 --- a/test/app/fixtures/menu-windows-linux-setup.json +++ b/test/app/fixtures/menu-windows-linux-setup.json @@ -119,7 +119,7 @@ "click": null }, { - "label": "File a Bug", + "label": "Report an Issue", "click": null }, { diff --git a/test/app/fixtures/menu-windows-linux.json b/test/app/fixtures/menu-windows-linux.json index 07927245e3..4185cf5869 100644 --- a/test/app/fixtures/menu-windows-linux.json +++ b/test/app/fixtures/menu-windows-linux.json @@ -108,7 +108,7 @@ "click": null }, { - "label": "File a Bug", + "label": "Report an Issue", "click": null }, { From b4c6f6733bb1320c1e0b0ce87cd88ea4d5b5901e Mon Sep 17 00:00:00 2001 From: Daniel Gasienica Date: Tue, 6 Mar 2018 17:00:48 -0500 Subject: [PATCH 21/27] Add `got` dependency The plan is to use this for our future HTTP needs as it is: - modern - promise based - popular - likely to support custom certificate authorities (CAs) Chosen over the following alternatives: - superagent (older, promises added later, potential lack of custom CA support) - axios (no team experience with it; less popular than `got`) - request (older, heavy-weight, promises not native) - jQuery (old, trying to move away from jQuery altogether and move towards declarative UIs) - `fetch` (too low-level, no native timeout support) --- package.json | 1 + yarn.lock | 178 +++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 175 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 18d9de6b6a..9d6be76cf0 100644 --- a/package.json +++ b/package.json @@ -59,6 +59,7 @@ "emoji-panel": "https://github.com/scottnonnenberg/emoji-panel.git#v0.5.5", "firstline": "^1.2.1", "google-libphonenumber": "^3.0.7", + "got": "^8.2.0", "lodash": "^4.17.4", "mkdirp": "^0.5.1", "node-fetch": "https://github.com/scottnonnenberg/node-fetch.git#3e5f51e08c647ee5f20c43b15cf2d352d61c36b4", diff --git a/yarn.lock b/yarn.lock index 0932c58ac1..0dc48e5cd3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -22,6 +22,10 @@ "7zip-bin-mac" "~1.0.1" "7zip-bin-win" "~2.2.0" +"@sindresorhus/is@^0.7.0": + version "0.7.0" + resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.7.0.tgz#9a06f4f137ee84d7df0460c1fdb1135ffa6c50fd" + "@sinonjs/formatio@^2.0.0": version "2.0.0" resolved "https://registry.yarnpkg.com/@sinonjs/formatio/-/formatio-2.0.0.tgz#84db7e9eb5531df18a8c5e0bfb6e449e55e654b2" @@ -650,6 +654,18 @@ bytes@3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" +cacheable-request@^2.1.1: + version "2.1.4" + resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-2.1.4.tgz#0d808801b6342ad33c91df9d0b44dc09b91e5c3d" + dependencies: + clone-response "1.0.2" + get-stream "3.0.0" + http-cache-semantics "3.8.1" + keyv "3.0.0" + lowercase-keys "1.0.0" + normalize-url "2.0.1" + responselike "1.0.2" + caching-transform@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/caching-transform/-/caching-transform-1.0.1.tgz#6dbdb2f20f8d8fbce79f3e94e9d1742dcdf5c0a1" @@ -820,6 +836,12 @@ cliui@^4.0.0: strip-ansi "^4.0.0" wrap-ansi "^2.0.0" +clone-response@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.2.tgz#d1dc973920314df67fbeb94223b4ee350239e96b" + dependencies: + mimic-response "^1.0.0" + co@^4.6.0: version "4.6.0" resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" @@ -1147,6 +1169,16 @@ decamelize@^1.0.0, decamelize@^1.1.1, decamelize@^1.1.2: version "1.2.0" resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" +decode-uri-component@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" + +decompress-response@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-3.3.0.tgz#80a4dd323748384bfa248083622aedec982adff3" + dependencies: + mimic-response "^1.0.0" + decompress-zip@0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/decompress-zip/-/decompress-zip-0.3.0.tgz#ae3bcb7e34c65879adfe77e19c30f86602b4bdb0" @@ -2001,6 +2033,12 @@ form-data@~2.3.1: combined-stream "^1.0.5" mime-types "^2.1.12" +from2@^2.1.1: + version "2.3.0" + resolved "https://registry.yarnpkg.com/from2/-/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af" + dependencies: + inherits "^2.0.1" + readable-stream "^2.0.0" formidable@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/formidable/-/formidable-1.1.1.tgz#96b8886f7c3c3508b932d6bd70c4d3a88f35f1a9" @@ -2138,7 +2176,7 @@ get-stdin@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe" -get-stream@^3.0.0: +get-stream@3.0.0, get-stream@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" @@ -2299,6 +2337,28 @@ got@^6.7.1: unzip-response "^2.0.1" url-parse-lax "^1.0.0" +got@^8.2.0: + version "8.2.0" + resolved "https://registry.yarnpkg.com/got/-/got-8.2.0.tgz#0d11a071d05046348a2f5c0a5fa047fb687fdfc6" + dependencies: + "@sindresorhus/is" "^0.7.0" + cacheable-request "^2.1.1" + decompress-response "^3.3.0" + duplexer3 "^0.1.4" + get-stream "^3.0.0" + into-stream "^3.1.0" + is-retry-allowed "^1.1.0" + isurl "^1.0.0-alpha5" + lowercase-keys "^1.0.0" + mimic-response "^1.0.0" + p-cancelable "^0.3.0" + p-timeout "^2.0.1" + pify "^3.0.0" + safe-buffer "^5.1.1" + timed-out "^4.0.1" + url-parse-lax "^3.0.0" + url-to-options "^1.0.1" + graceful-fs@^4.1.0, graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.3, graceful-fs@^4.1.6, graceful-fs@^4.1.9: version "4.1.11" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" @@ -2492,6 +2552,16 @@ has-flag@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" +has-symbol-support-x@^1.4.1: + version "1.4.2" + resolved "https://registry.yarnpkg.com/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz#1409f98bc00247da45da67cee0a36f282ff26455" + +has-to-string-tag-x@^1.2.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz#a045ab383d7b4b2012a00148ab0aa5f290044d4d" + dependencies: + has-symbol-support-x "^1.4.1" + has-unicode@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" @@ -2561,6 +2631,10 @@ htmlparser2@3.8.3, htmlparser2@3.8.x: entities "1.0" readable-stream "1.1" +http-cache-semantics@3.8.1: + version "3.8.1" + resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz#39b0e16add9b605bf0a9ef3d9daaf4843b4cacd2" + http-errors@1.6.2: version "1.6.2" resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.2.tgz#0a002cc85707192a7e7946ceedc11155f60ec736" @@ -2699,6 +2773,13 @@ inquirer@^3.0.6, inquirer@~3.3.0: strip-ansi "^4.0.0" through "^2.3.6" +into-stream@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/into-stream/-/into-stream-3.1.0.tgz#96fb0a936c12babd6ff1752a17d05616abd094c6" + dependencies: + from2 "^2.1.1" + p-is-promise "^1.1.0" + invariant@^2.2.2: version "2.2.2" resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.2.tgz#9e1f56ac0acdb6bf303306f338be3b204ae60360" @@ -2808,6 +2889,10 @@ is-obj@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" +is-object@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-object/-/is-object-1.0.1.tgz#8952688c5ec2ffd6b03ecc85e769e02903083470" + is-path-cwd@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-1.0.0.tgz#d225ec23132e89edd38fda767472e62e65f1106d" @@ -2824,6 +2909,10 @@ is-path-inside@^1.0.0: dependencies: path-is-inside "^1.0.1" +is-plain-obj@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" + is-posix-bracket@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz#3334dc79774368e92f016e6fbc0a88f5cd6e6bc4" @@ -2844,7 +2933,7 @@ is-resolvable@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.0.1.tgz#acca1cd36dbe44b974b924321555a70ba03b1cf4" -is-retry-allowed@^1.0.0: +is-retry-allowed@^1.0.0, is-retry-allowed@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz#11a060568b67339444033d0125a61a20d564fb34" @@ -2933,6 +3022,13 @@ istanbul-reports@^1.1.3: dependencies: handlebars "^4.0.3" +isurl@^1.0.0-alpha5: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isurl/-/isurl-1.0.0.tgz#b27f4f49f3cdaa3ea44a0a5b7f3462e6edc39d67" + dependencies: + has-to-string-tag-x "^1.2.0" + is-object "^1.0.1" + jimp@^0.2.27: version "0.2.27" resolved "https://registry.yarnpkg.com/jimp/-/jimp-0.2.27.tgz#41ef5082d8b63201d54747e04fe8bcacbaf25474" @@ -3066,6 +3162,10 @@ jshint@~2.9.4: shelljs "0.3.x" strip-json-comments "1.0.x" +json-buffer@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.0.tgz#5b1f397afc75d677bde8bcfc0e47e1f9a3d9a898" + json-schema-traverse@^0.3.0: version "0.3.1" resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz#349a6d44c53a51de89b40805c5d5e59b417d3340" @@ -3136,6 +3236,12 @@ kew@^0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/kew/-/kew-0.7.0.tgz#79d93d2d33363d6fdd2970b335d9141ad591d79b" +keyv@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/keyv/-/keyv-3.0.0.tgz#44923ba39e68b12a7cec7df6c3268c031f2ef373" + dependencies: + json-buffer "3.0.0" + kind-of@^3.0.2: version "3.2.2" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" @@ -3324,7 +3430,7 @@ loud-rejection@^1.0.0: currently-unhandled "^0.4.1" signal-exit "^3.0.0" -lowercase-keys@^1.0.0: +lowercase-keys@1.0.0, lowercase-keys@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.0.tgz#4e3366b39e7f5457e35f1324bdf6f88d0bfc7306" @@ -3448,6 +3554,10 @@ mimic-fn@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.1.0.tgz#e667783d92e89dbd342818b5230b9d62a672ad18" +mimic-response@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.0.tgz#df3d3652a73fded6b9b0b24146e6fd052353458e" + min-document@^2.19.0: version "2.19.0" resolved "https://registry.yarnpkg.com/min-document/-/min-document-2.19.0.tgz#7bd282e3f5842ed295bb748cdd9f1ffa2c824685" @@ -3688,6 +3798,14 @@ normalize-path@^2.0.0, normalize-path@^2.0.1: dependencies: remove-trailing-separator "^1.0.1" +normalize-url@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-2.0.1.tgz#835a9da1551fa26f70e92329069a23aa6574d7e6" + dependencies: + prepend-http "^2.0.0" + query-string "^5.0.1" + sort-keys "^2.0.0" + npm-install-package@~2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/npm-install-package/-/npm-install-package-2.1.0.tgz#d7efe3cfcd7ab00614b896ea53119dc9ab259125" @@ -3843,10 +3961,18 @@ osenv@0: os-homedir "^1.0.0" os-tmpdir "^1.0.0" +p-cancelable@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-0.3.0.tgz#b9e123800bcebb7ac13a479be195b507b98d30fa" + p-finally@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" +p-is-promise@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-1.1.0.tgz#9c9456989e9f6588017b0434d56097675c3da05e" + p-limit@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.1.0.tgz#b07ff2d9a5d88bec806035895a2bab66a27988bc" @@ -3861,6 +3987,12 @@ p-map@^1.1.1: version "1.2.0" resolved "https://registry.yarnpkg.com/p-map/-/p-map-1.2.0.tgz#e4e94f311eabbc8633a1e79908165fca26241b6b" +p-timeout@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-2.0.1.tgz#d8dd1979595d2dc0139e1fe46b8b646cb3cdf038" + dependencies: + p-finally "^1.0.0" + pac-proxy-agent@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/pac-proxy-agent/-/pac-proxy-agent-2.0.0.tgz#beb17cd2b06a20b379d57e1b2e2c29be0dfe5f9a" @@ -4096,6 +4228,10 @@ prepend-http@^1.0.1: version "1.0.4" resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" +prepend-http@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897" + preserve@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" @@ -4185,6 +4321,14 @@ qs@~6.4.0: version "6.4.0" resolved "https://registry.yarnpkg.com/qs/-/qs-6.4.0.tgz#13e26d28ad6b0ffaa91312cd3bf708ed351e7233" +query-string@^5.0.1: + version "5.1.0" + resolved "https://registry.yarnpkg.com/query-string/-/query-string-5.1.0.tgz#9583b15fd1307f899e973ed418886426a9976469" + dependencies: + decode-uri-component "^0.2.0" + object-assign "^4.1.0" + strict-uri-encode "^1.0.0" + querystring@0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" @@ -4475,6 +4619,12 @@ resolve@^1.2.0: dependencies: path-parse "^1.0.5" +responselike@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/responselike/-/responselike-1.0.2.tgz#918720ef3b631c5642be068f15ade5a46f4ba1e7" + dependencies: + lowercase-keys "^1.0.0" + restore-cursor@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf" @@ -4696,6 +4846,12 @@ socks@^1.1.10, socks@~1.1.5: ip "^1.1.4" smart-buffer "^1.0.13" +sort-keys@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-2.0.0.tgz#658535584861ec97d730d6cf41822e1f56684128" + dependencies: + is-plain-obj "^1.0.0" + source-map-resolve@^0.3.0: version "0.3.1" resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.3.1.tgz#610f6122a445b8dd51535a2a71b783dfc1248761" @@ -4848,6 +5004,10 @@ stream-to@~0.2.0: version "0.2.2" resolved "https://registry.yarnpkg.com/stream-to/-/stream-to-0.2.2.tgz#84306098d85fdb990b9fa300b1b3ccf55e8ef01d" +strict-uri-encode@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713" + string-similarity@1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/string-similarity/-/string-similarity-1.1.0.tgz#3c66498858a465ec7c40c7d81739bbd995904914" @@ -5099,7 +5259,7 @@ thunkify@^2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/thunkify/-/thunkify-2.1.2.tgz#faa0e9d230c51acc95ca13a361ac05ca7e04553d" -timed-out@^4.0.0: +timed-out@^4.0.0, timed-out@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f" @@ -5286,12 +5446,22 @@ url-parse-lax@^1.0.0: dependencies: prepend-http "^1.0.1" +url-parse-lax@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-3.0.0.tgz#16b5cafc07dbe3676c1b1999177823d6503acb0c" + dependencies: + prepend-http "^2.0.0" + url-regex@^3.0.0: version "3.2.0" resolved "https://registry.yarnpkg.com/url-regex/-/url-regex-3.2.0.tgz#dbad1e0c9e29e105dd0b1f09f6862f7fdb482724" dependencies: ip-regex "^1.0.1" +url-to-options@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/url-to-options/-/url-to-options-1.0.1.tgz#1505a03a289a48cbd7a434efbaeec5055f5633a9" + url@0.10.3: version "0.10.3" resolved "https://registry.yarnpkg.com/url/-/url-0.10.3.tgz#021e4d9c7705f21bbf37d03ceb58767402774c64" From 04afb6a3180127de748051e245764547e0316678 Mon Sep 17 00:00:00 2001 From: Daniel Gasienica Date: Tue, 6 Mar 2018 18:51:43 -0500 Subject: [PATCH 22/27] Add `form-data` dependency Used for upload debug logs to S3. --- package.json | 1 + yarn.lock | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 9d6be76cf0..b6c37f445f 100644 --- a/package.json +++ b/package.json @@ -58,6 +58,7 @@ "emoji-js": "^3.4.0", "emoji-panel": "https://github.com/scottnonnenberg/emoji-panel.git#v0.5.5", "firstline": "^1.2.1", + "form-data": "^2.3.2", "google-libphonenumber": "^3.0.7", "got": "^8.2.0", "lodash": "^4.17.4", diff --git a/yarn.lock b/yarn.lock index 0dc48e5cd3..f80ecea90f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2009,7 +2009,7 @@ forever-agent@~0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" -form-data@^2.3.1: +form-data@^2.3.2: version "2.3.2" resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.2.tgz#4970498be604c20c005d4f5c23aecd21d6b49099" dependencies: From 52f7de6a1018b0502de760b1463e8d5f51b8ff57 Mon Sep 17 00:00:00 2001 From: Daniel Gasienica Date: Tue, 6 Mar 2018 18:56:01 -0500 Subject: [PATCH 23/27] Add `debuglogs` module --- js/modules/debuglogs.js | 48 ++++++++++++++++++++++++++++++++++ test/modules/debuglogs_test.js | 17 ++++++++++++ 2 files changed, 65 insertions(+) create mode 100644 js/modules/debuglogs.js create mode 100644 test/modules/debuglogs_test.js diff --git a/js/modules/debuglogs.js b/js/modules/debuglogs.js new file mode 100644 index 0000000000..a753f104de --- /dev/null +++ b/js/modules/debuglogs.js @@ -0,0 +1,48 @@ +/* eslint-env node */ + +const FormData = require('form-data'); +const got = require('got'); + + +const BASE_URL = 'https://debuglogs.org'; + +// Workaround: Submitting `FormData` using native `FormData::submit` procedure +// as integration with `got` results in S3 error saying we haven’t set the +// `Content-Length` header: +const submitFormData = (form, url) => + new Promise((resolve, reject) => { + form.submit(url, (error) => { + if (error) { + return reject(error); + } + + return resolve(); + }); + }); + +// upload :: String -> Promise URL +exports.upload = async (content) => { + const signedForm = await got.get(BASE_URL, { json: true }); + const { fields, url } = signedForm.body; + + const form = new FormData(); + form.append('key', fields.key); + + Object.entries(fields) + .filter(([key]) => key !== 'key') + .forEach(([key, value]) => { + form.append(key, value); + }); + + const contentBuffer = Buffer.from(content, 'utf8'); + const contentType = 'text/plain'; + form.append('Content-Type', contentType); + form.append('file', contentBuffer, { + contentType, + filename: 'signal-desktop-debug-log.txt', + }); + + await submitFormData(form, url); + + return `${BASE_URL}/${fields.key}`; +}; diff --git a/test/modules/debuglogs_test.js b/test/modules/debuglogs_test.js new file mode 100644 index 0000000000..3a6e45e907 --- /dev/null +++ b/test/modules/debuglogs_test.js @@ -0,0 +1,17 @@ +const { assert } = require('chai'); +const got = require('got'); + +const debuglogs = require('../../js/modules/debuglogs'); + + +describe('debuglogs', () => { + describe('upload', () => { + it('should upload log content', async () => { + const nonce = Math.random().toString().slice(2); + const url = await debuglogs.upload(nonce); + + const { body } = await got.get(url); + assert.equal(nonce, body); + }); + }); +}); From 8b71155e7cb013effcb691cbb473a97393980ac1 Mon Sep 17 00:00:00 2001 From: Daniel Gasienica Date: Tue, 6 Mar 2018 18:58:01 -0500 Subject: [PATCH 24/27] Replace `superagent` with `got` for debug logs --- js/logging.js | 24 +++--------------------- 1 file changed, 3 insertions(+), 21 deletions(-) diff --git a/js/logging.js b/js/logging.js index 6fedabc0c7..45cd0a7e55 100644 --- a/js/logging.js +++ b/js/logging.js @@ -5,7 +5,8 @@ const electron = require('electron'); const bunyan = require('bunyan'); const _ = require('lodash'); -const superagent = require('superagent'); + +const debuglogs = require('./modules/debuglogs'); const ipc = electron.ipcRenderer; @@ -108,26 +109,7 @@ function fetch() { }); } -const DEBUGLOGS_API_URL = 'https://debuglogs.org'; -const publish = async (content) => { - const credentialsResponse = await superagent.get(DEBUGLOGS_API_URL); - const { fields, url } = credentialsResponse.body; - const uploadRequest = superagent.post(url); - Object.entries(fields).forEach(([key, value]) => { - uploadRequest.field(key, value); - }); - - const contentBuffer = Buffer.from(content, 'utf8'); - uploadRequest.attach('file', contentBuffer, { - contentType: 'text/plain', - filename: 'signal-desktop-debug-log.txt', - }); - - await uploadRequest; - - return `${DEBUGLOGS_API_URL}/${fields.key}`; -}; - +const publish = debuglogs.upload; // A modern logging interface for the browser From 0810ea6909a7e87992f0c1326f0f21dd926d83e1 Mon Sep 17 00:00:00 2001 From: Daniel Gasienica Date: Tue, 6 Mar 2018 19:03:07 -0500 Subject: [PATCH 25/27] Remove `superagent` dependency MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We’ve replaced it with more modern and Node.js based `got`: https://www.npmjs.com/package/got --- package.json | 1 - yarn.lock | 44 +++++--------------------------------------- 2 files changed, 5 insertions(+), 40 deletions(-) diff --git a/package.json b/package.json index b6c37f445f..d2101e3c4e 100644 --- a/package.json +++ b/package.json @@ -71,7 +71,6 @@ "rimraf": "^2.6.2", "semver": "^5.4.1", "spellchecker": "^3.4.4", - "superagent": "^3.8.2", "testcheck": "^1.0.0-rc.2", "websocket": "^1.0.25" }, diff --git a/yarn.lock b/yarn.lock index f80ecea90f..39d5b3ead7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -916,10 +916,6 @@ compare-version@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/compare-version/-/compare-version-0.1.2.tgz#0162ec2d9351f5ddd59a9202cba935366a725080" -component-emitter@^1.2.0: - version "1.2.1" - resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.2.1.tgz#137918d6d78283f7df7a6b7c5a63e140e69425e6" - compress-commons@^1.2.0: version "1.2.2" resolved "https://registry.yarnpkg.com/compress-commons/-/compress-commons-1.2.2.tgz#524a9f10903f3a813389b0225d27c48bb751890f" @@ -998,10 +994,6 @@ convert-source-map@^1.3.0: version "1.5.1" resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.5.1.tgz#b8278097b9bc229365de5c62cf5fcaed8b5599e5" -cookiejar@^2.1.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/cookiejar/-/cookiejar-2.1.1.tgz#41ad57b1b555951ec171412a81942b1e8200d34a" - core-js@^2.4.0: version "2.4.1" resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.4.1.tgz#4de911e667b0eae9124e34254b53aea6fc618d3e" @@ -1827,7 +1819,7 @@ expand-range@^1.8.1: dependencies: fill-range "^2.1.0" -extend@3, extend@^3.0.0, extend@~3.0.1: +extend@3, extend@~3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444" @@ -2039,9 +2031,6 @@ from2@^2.1.1: dependencies: inherits "^2.0.1" readable-stream "^2.0.0" -formidable@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/formidable/-/formidable-1.1.1.tgz#96b8886f7c3c3508b932d6bd70c4d3a88f35f1a9" fs-extra-p@^4.5.0: version "4.5.0" @@ -3496,10 +3485,6 @@ merge-source-map@^1.0.2: dependencies: source-map "^0.6.1" -methods@^1.1.1: - version "1.1.2" - resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" - micromatch@^2.3.11: version "2.3.11" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-2.3.11.tgz#86677c97d1720b363431d04d0d15293bd38c1565" @@ -3542,10 +3527,6 @@ mime@^1.3.4: version "1.4.0" resolved "https://registry.yarnpkg.com/mime/-/mime-1.4.0.tgz#69e9e0db51d44f2a3b56e48b7817d7d137f1a343" -mime@^1.4.1: - version "1.6.0" - resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" - mime@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/mime/-/mime-2.2.0.tgz#161e541965551d3b549fa1114391e3a3d55b923b" @@ -4309,10 +4290,6 @@ qs@5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/qs/-/qs-5.2.0.tgz#a9f31142af468cb72b25b30136ba2456834916be" -qs@^6.5.1, qs@~6.5.1: - version "6.5.1" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.1.tgz#349cdf6eef89ec45c12d7d5eb3fc0c870343a6d8" - qs@~5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/qs/-/qs-5.1.0.tgz#4d932e5c7ea411cca76a312d39a606200fd50cd9" @@ -4321,6 +4298,10 @@ qs@~6.4.0: version "6.4.0" resolved "https://registry.yarnpkg.com/qs/-/qs-6.4.0.tgz#13e26d28ad6b0ffaa91312cd3bf708ed351e7233" +qs@~6.5.1: + version "6.5.1" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.1.tgz#349cdf6eef89ec45c12d7d5eb3fc0c870343a6d8" + query-string@^5.0.1: version "5.1.0" resolved "https://registry.yarnpkg.com/query-string/-/query-string-5.1.0.tgz#9583b15fd1307f899e973ed418886426a9976469" @@ -5107,21 +5088,6 @@ sumchecker@^2.0.1, sumchecker@^2.0.2: dependencies: debug "^2.2.0" -superagent@^3.8.2: - version "3.8.2" - resolved "https://registry.yarnpkg.com/superagent/-/superagent-3.8.2.tgz#e4a11b9d047f7d3efeb3bbe536d9ec0021d16403" - dependencies: - component-emitter "^1.2.0" - cookiejar "^2.1.0" - debug "^3.1.0" - extend "^3.0.0" - form-data "^2.3.1" - formidable "^1.1.1" - methods "^1.1.1" - mime "^1.4.1" - qs "^6.5.1" - readable-stream "^2.0.5" - supports-color@4.4.0, supports-color@^4.0.0: version "4.4.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-4.4.0.tgz#883f7ddabc165142b2a61427f3352ded195d1a3e" From 710701d0fce7a2b968ce933c9b21a71708b7ed5c Mon Sep 17 00:00:00 2001 From: Daniel Gasienica Date: Wed, 7 Mar 2018 14:50:32 -0500 Subject: [PATCH 26/27] Document why `key` comes first --- js/modules/debuglogs.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/modules/debuglogs.js b/js/modules/debuglogs.js index a753f104de..f7173af436 100644 --- a/js/modules/debuglogs.js +++ b/js/modules/debuglogs.js @@ -26,8 +26,8 @@ exports.upload = async (content) => { const { fields, url } = signedForm.body; const form = new FormData(); + // The API expects `key` to be the first field: form.append('key', fields.key); - Object.entries(fields) .filter(([key]) => key !== 'key') .forEach(([key, value]) => { From b049412bfd8d13c5055324ceac5f305b7b680e0e Mon Sep 17 00:00:00 2001 From: Daniel Gasienica Date: Wed, 7 Mar 2018 15:19:02 -0500 Subject: [PATCH 27/27] Document workaround for `got` `FormData` bug See: https://github.com/sindresorhus/got/pull/466 --- js/modules/debuglogs.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/js/modules/debuglogs.js b/js/modules/debuglogs.js index f7173af436..44bb443f96 100644 --- a/js/modules/debuglogs.js +++ b/js/modules/debuglogs.js @@ -9,6 +9,7 @@ const BASE_URL = 'https://debuglogs.org'; // Workaround: Submitting `FormData` using native `FormData::submit` procedure // as integration with `got` results in S3 error saying we haven’t set the // `Content-Length` header: +// https://github.com/sindresorhus/got/pull/466 const submitFormData = (form, url) => new Promise((resolve, reject) => { form.submit(url, (error) => { @@ -42,6 +43,8 @@ exports.upload = async (content) => { filename: 'signal-desktop-debug-log.txt', }); + // WORKAROUND: See comment on `submitFormData`: + // await got.post(url, { body: form }); await submitFormData(form, url); return `${BASE_URL}/${fields.key}`;