From b3a6854eb6ea6aceb8676c9f4ce54299e899867d Mon Sep 17 00:00:00 2001 From: Baruch Rothkoff Date: Thu, 27 Feb 2020 17:20:36 +0200 Subject: [PATCH 01/12] Add Sentry report # Need to handle email validation only for RpoertProblem --- package.json | 1 + scripts/sentry-symbols.js | 113 +++++++++++++++ src/background.js | 3 + .../MainPage/ReportProblemDialog.vue | 38 ++++- src/main.js | 10 +- src/modules/reporting/index.js | 38 +++++ src/modules/reporting/sentry.config.js | 1 + yarn.lock | 130 +++++++++++++++++- 8 files changed, 326 insertions(+), 8 deletions(-) create mode 100644 scripts/sentry-symbols.js create mode 100644 src/modules/reporting/index.js create mode 100644 src/modules/reporting/sentry.config.js diff --git a/package.json b/package.json index 2e5679b1..9909a05f 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,7 @@ ], "dependencies": { "@getstation/electron-google-oauth2": "2.1.0", + "@sentry/electron": "^1.2.1", "core-js": "^3.4.4", "download-chromium": "^2.2.0", "electron-log": "^4.0.7", diff --git a/scripts/sentry-symbols.js b/scripts/sentry-symbols.js new file mode 100644 index 00000000..aa7ae79b --- /dev/null +++ b/scripts/sentry-symbols.js @@ -0,0 +1,113 @@ +#!/usr/bin/env node + +/* +To upload debug information for native crashes when updating Electron, run: + + npm install --save-dev @sentry/cli electron-download + node sentry-symbols.js + +For more information, see https://docs.sentry.io/clients/electron/ +*/ +let SentryCli; +let download; + +try { + SentryCli = require('@sentry/cli'); + download = require('electron-download'); +} catch (e) { + console.error('ERROR: Missing required packages, please run:'); + console.error('npm install --save-dev @sentry/cli electron-download'); + process.exit(1); +} + +const VERSION = /\bv?(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)(?:-[\da-z-]+(?:\.[\da-z-]+)*)?(?:\+[\da-z-]+(?:\.[\da-z-]+)*)?\b/i; +const SYMBOL_CACHE_FOLDER = '.electron-symbols'; +const package = require('./package.json'); +const sentryCli = new SentryCli('./sentry.properties'); + +async function main() { + let version = getElectronVersion(); + if (!version) { + console.error('Cannot detect electron version, check package.json'); + return; + } + + console.log('We are starting to download all possible electron symbols'); + console.log('We need it in order to symbolicate native crashes'); + console.log( + 'This step is only needed once whenever you update your electron version', + ); + console.log('Just call this script again it should do everything for you.'); + + let zipPath = await downloadSymbols({ + version, + platform: 'darwin', + arch: 'x64', + dsym: true, + }); + await sentryCli.execute(['upload-dif', '-t', 'dsym', zipPath], true); + + zipPath = await downloadSymbols({ + version, + platform: 'win32', + arch: 'ia32', + symbols: true, + }); + await sentryCli.execute(['upload-dif', '-t', 'breakpad', zipPath], true); + + zipPath = await downloadSymbols({ + version, + platform: 'win32', + arch: 'x64', + symbols: true, + }); + await sentryCli.execute(['upload-dif', '-t', 'breakpad', zipPath], true); + + zipPath = await downloadSymbols({ + version, + platform: 'linux', + arch: 'x64', + symbols: true, + }); + await sentryCli.execute(['upload-dif', '-t', 'breakpad', zipPath], true); + + console.log('Finished downloading and uploading to Sentry'); + console.log(`Feel free to delete the ${SYMBOL_CACHE_FOLDER}`); +} + +function getElectronVersion() { + if (!package) { + return false; + } + + let electronVersion = + (package.dependencies && package.dependencies.electron) || + (package.devDependencies && package.devDependencies.electron); + + if (!electronVersion) { + return false; + } + + const matches = VERSION.exec(electronVersion); + return matches ? matches[0] : false; +} + +async function downloadSymbols(options) { + return new Promise((resolve, reject) => { + download( + { + ...options, + cache: SYMBOL_CACHE_FOLDER, + }, + (err, zipPath) => { + if (err) { + reject(err); + } else { + resolve(zipPath); + } + }, + ); + }); +} + +main().catch(e => console.error(e)); diff --git a/src/background.js b/src/background.js index 15ebb25c..b5dc4c2f 100644 --- a/src/background.js +++ b/src/background.js @@ -2,8 +2,11 @@ import { app, BrowserWindow } from 'electron'; // eslint-disable-next-line import/no-extraneous-dependencies import { createProtocol, installVueDevtools } from 'vue-cli-plugin-electron-builder/lib'; import CreateLogger from './logger'; +import { initializeReporter } from './modules/reporting'; import './store'; +initializeReporter(); + const isDevelopment = process.env.NODE_ENV !== 'production'; // Keep a global reference of the window object, if you don't, the window will diff --git a/src/components/MainPage/ReportProblemDialog.vue b/src/components/MainPage/ReportProblemDialog.vue index dd735a5e..f8abaa5d 100644 --- a/src/components/MainPage/ReportProblemDialog.vue +++ b/src/components/MainPage/ReportProblemDialog.vue @@ -21,6 +21,15 @@ :rules="[titleRule]" /> + + + @@ -66,10 +75,18 @@ color="blue darken-1" text :disabled="!valid" - @click="open" + @click="openGithub" > Open Github Issue + + Send Report + @@ -77,6 +94,7 @@ From 661f35e73fa95a4f8c9e26b6b60c77819048d42a Mon Sep 17 00:00:00 2001 From: Baruch Rothkoff Date: Fri, 28 Feb 2020 15:33:28 +0200 Subject: [PATCH 04/12] Exceeded timeout --- test/e2e/specs/Launch.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/e2e/specs/Launch.spec.js b/test/e2e/specs/Launch.spec.js index 008b4fe4..50eff92f 100644 --- a/test/e2e/specs/Launch.spec.js +++ b/test/e2e/specs/Launch.spec.js @@ -6,7 +6,7 @@ import Interactions from '../utils/interactions'; const screenshotsDir = './screenshots'; -jest.setTimeout(200000); +jest.setTimeout(300000); // Remove when https://github.com/nklayman/vue-cli-plugin-electron-builder/issues/625 closed const skip = process.env.GITHUB_ACTIONS && process.platform === 'win32'; From 5d349432917d898572cc3afde3fe0f053f6cff45 Mon Sep 17 00:00:00 2001 From: Baruch Rothkoff Date: Sun, 1 Mar 2020 07:27:04 +0200 Subject: [PATCH 05/12] Exceeded timeout --- test/e2e/specs/Launch.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/e2e/specs/Launch.spec.js b/test/e2e/specs/Launch.spec.js index 50eff92f..6c3f7bcd 100644 --- a/test/e2e/specs/Launch.spec.js +++ b/test/e2e/specs/Launch.spec.js @@ -6,7 +6,7 @@ import Interactions from '../utils/interactions'; const screenshotsDir = './screenshots'; -jest.setTimeout(300000); +jest.setTimeout(400000); // Remove when https://github.com/nklayman/vue-cli-plugin-electron-builder/issues/625 closed const skip = process.env.GITHUB_ACTIONS && process.platform === 'win32'; From 525e7fbd101e1ea37143a97b1ffab3b7994f2c12 Mon Sep 17 00:00:00 2001 From: Baruch Rothkoff Date: Sun, 1 Mar 2020 07:27:52 +0200 Subject: [PATCH 06/12] Email hint: only if send a report --- src/components/MainPage/ReportProblemDialog.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/MainPage/ReportProblemDialog.vue b/src/components/MainPage/ReportProblemDialog.vue index f411481b..11e93834 100644 --- a/src/components/MainPage/ReportProblemDialog.vue +++ b/src/components/MainPage/ReportProblemDialog.vue @@ -25,7 +25,7 @@ From 96aad1be0fd2a3d35ff020069f2a225c950323d3 Mon Sep 17 00:00:00 2001 From: Baruch Rothkoff Date: Sun, 1 Mar 2020 14:53:50 +0200 Subject: [PATCH 07/12] Try specific import for Webpack --- src/background.js | 4 ++-- src/main.js | 4 ++-- src/modules/reporting/index.js | 14 +++++++++----- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/src/background.js b/src/background.js index b5dc4c2f..a91574c7 100644 --- a/src/background.js +++ b/src/background.js @@ -2,10 +2,10 @@ import { app, BrowserWindow } from 'electron'; // eslint-disable-next-line import/no-extraneous-dependencies import { createProtocol, installVueDevtools } from 'vue-cli-plugin-electron-builder/lib'; import CreateLogger from './logger'; -import { initializeReporter } from './modules/reporting'; +import { initializeReporterMain } from './modules/reporting'; import './store'; -initializeReporter(); +initializeReporterMain(); const isDevelopment = process.env.NODE_ENV !== 'production'; diff --git a/src/main.js b/src/main.js index a78289cd..c9551dfc 100644 --- a/src/main.js +++ b/src/main.js @@ -2,14 +2,14 @@ import electron from 'electron'; import Vue from 'vue'; import App from './App'; -import { initializeReporter } from './modules/reporting'; +import { initializeReporterRenderer } from './modules/reporting'; import './plugins/element'; import LoggerPlugin from './plugins/logger'; import vuetify from './plugins/vuetify'; import router from './router'; import store from './store'; -initializeReporter(); +initializeReporterRenderer(); const logger = electron.remote.getGlobal('logger'); diff --git a/src/modules/reporting/index.js b/src/modules/reporting/index.js index 47e6fffa..c428d2c5 100644 --- a/src/modules/reporting/index.js +++ b/src/modules/reporting/index.js @@ -1,18 +1,22 @@ import * as Sentry from '@sentry/electron'; +import { init as rendererInit } from '@sentry/electron/dist/renderer'; +import { init as mainInit } from '@sentry/electron/dist/main'; + import config from './sentry.config'; // https://github.com/getsentry/sentry-electron/issues/142 -const { init } = (process.type === 'browser' - ? require('@sentry/electron/dist/main') - : require('@sentry/electron/dist/renderer')); const reporterConfiguration = { ...config, defaultIntegrations: false, }; -export function initializeReporter() { - if (process.env.NODE_ENV === 'production') init(reporterConfiguration); +export function initializeReporterRenderer() { + if (process.env.NODE_ENV === 'production') rendererInit(reporterConfiguration); +} + +export function initializeReporterMain() { + if (process.env.NODE_ENV === 'production') mainInit(reporterConfiguration); } function isSentryInitialized() { From 0d9cebd49fb13144c7e35f762797b04fd6e54e75 Mon Sep 17 00:00:00 2001 From: Baruch Rothkoff Date: Sun, 1 Mar 2020 15:06:29 +0200 Subject: [PATCH 08/12] Revert "Try specific import for Webpack" This reverts commit 96aad1be0fd2a3d35ff020069f2a225c950323d3. --- src/background.js | 4 ++-- src/main.js | 4 ++-- src/modules/reporting/index.js | 14 +++++--------- 3 files changed, 9 insertions(+), 13 deletions(-) diff --git a/src/background.js b/src/background.js index a91574c7..b5dc4c2f 100644 --- a/src/background.js +++ b/src/background.js @@ -2,10 +2,10 @@ import { app, BrowserWindow } from 'electron'; // eslint-disable-next-line import/no-extraneous-dependencies import { createProtocol, installVueDevtools } from 'vue-cli-plugin-electron-builder/lib'; import CreateLogger from './logger'; -import { initializeReporterMain } from './modules/reporting'; +import { initializeReporter } from './modules/reporting'; import './store'; -initializeReporterMain(); +initializeReporter(); const isDevelopment = process.env.NODE_ENV !== 'production'; diff --git a/src/main.js b/src/main.js index c9551dfc..a78289cd 100644 --- a/src/main.js +++ b/src/main.js @@ -2,14 +2,14 @@ import electron from 'electron'; import Vue from 'vue'; import App from './App'; -import { initializeReporterRenderer } from './modules/reporting'; +import { initializeReporter } from './modules/reporting'; import './plugins/element'; import LoggerPlugin from './plugins/logger'; import vuetify from './plugins/vuetify'; import router from './router'; import store from './store'; -initializeReporterRenderer(); +initializeReporter(); const logger = electron.remote.getGlobal('logger'); diff --git a/src/modules/reporting/index.js b/src/modules/reporting/index.js index c428d2c5..47e6fffa 100644 --- a/src/modules/reporting/index.js +++ b/src/modules/reporting/index.js @@ -1,22 +1,18 @@ import * as Sentry from '@sentry/electron'; -import { init as rendererInit } from '@sentry/electron/dist/renderer'; -import { init as mainInit } from '@sentry/electron/dist/main'; - import config from './sentry.config'; // https://github.com/getsentry/sentry-electron/issues/142 +const { init } = (process.type === 'browser' + ? require('@sentry/electron/dist/main') + : require('@sentry/electron/dist/renderer')); const reporterConfiguration = { ...config, defaultIntegrations: false, }; -export function initializeReporterRenderer() { - if (process.env.NODE_ENV === 'production') rendererInit(reporterConfiguration); -} - -export function initializeReporterMain() { - if (process.env.NODE_ENV === 'production') mainInit(reporterConfiguration); +export function initializeReporter() { + if (process.env.NODE_ENV === 'production') init(reporterConfiguration); } function isSentryInitialized() { From ac6d88cc518a40506bc152ed3974a5a1d1cb7aa0 Mon Sep 17 00:00:00 2001 From: Baruch Rothkoff Date: Sun, 1 Mar 2020 15:08:09 +0200 Subject: [PATCH 09/12] Exceeded timeout --- test/e2e/specs/Launch.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/e2e/specs/Launch.spec.js b/test/e2e/specs/Launch.spec.js index 6c3f7bcd..96eb839a 100644 --- a/test/e2e/specs/Launch.spec.js +++ b/test/e2e/specs/Launch.spec.js @@ -6,7 +6,7 @@ import Interactions from '../utils/interactions'; const screenshotsDir = './screenshots'; -jest.setTimeout(400000); +jest.setTimeout(1000000); // Remove when https://github.com/nklayman/vue-cli-plugin-electron-builder/issues/625 closed const skip = process.env.GITHUB_ACTIONS && process.platform === 'win32'; From 51ddb891dcf7ff97c79295429deeb2ea3cbdae03 Mon Sep 17 00:00:00 2001 From: Baruch Rothkoff Date: Mon, 2 Mar 2020 16:55:33 +0200 Subject: [PATCH 10/12] Move to Webpack DefinePlugin --- .eslintrc.js | 6 ++++++ globals.js | 5 +++++ src/modules/reporting/index.js | 20 ++++++++----------- src/modules/reporting/sentry.config.js | 1 - src/modules/spreadsheet/googleOAuth2.js | 5 ++--- .../google_client_secret.config.js | 12 ----------- vue.config.js | 15 ++++++++++++++ 7 files changed, 36 insertions(+), 28 deletions(-) create mode 100644 globals.js delete mode 100644 src/modules/reporting/sentry.config.js delete mode 100644 src/modules/spreadsheet/google_client_secret.config.js diff --git a/.eslintrc.js b/.eslintrc.js index 6e8a9942..73006c38 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,3 +1,5 @@ +const globals = require('./globals') + module.exports = { root: true, @@ -15,6 +17,10 @@ module.exports = { globals: { __static: true, + ...globals.reduce((prev, curr) => { + prev[curr] = true; + return prev; + }, {}), }, plugins: [ diff --git a/globals.js b/globals.js new file mode 100644 index 00000000..c57c02d6 --- /dev/null +++ b/globals.js @@ -0,0 +1,5 @@ +module.exports = [ + 'SENTRY_DSN', + 'GOOGLE_CLIENT_ID', + 'GOOGLE_CLIENT_SECRET', +]; diff --git a/src/modules/reporting/index.js b/src/modules/reporting/index.js index 47e6fffa..035e264f 100644 --- a/src/modules/reporting/index.js +++ b/src/modules/reporting/index.js @@ -1,28 +1,26 @@ import * as Sentry from '@sentry/electron'; -import config from './sentry.config'; // https://github.com/getsentry/sentry-electron/issues/142 const { init } = (process.type === 'browser' ? require('@sentry/electron/dist/main') : require('@sentry/electron/dist/renderer')); + const reporterConfiguration = { - ...config, + dsn: SENTRY_DSN, defaultIntegrations: false, + environment: process.env.NODE_ENV, + enableJavaScript: false, + enableNative: false, + enableUnresponsive: false, }; export function initializeReporter() { - if (process.env.NODE_ENV === 'production') init(reporterConfiguration); -} - -function isSentryInitialized() { - return !!Sentry.getCurrentHub().getClient(); + init(reporterConfiguration); } export function ReportProblem(title, body, logs, email, extra) { - const suffix = isSentryInitialized() ? '' : `-${process.env.NODE_ENV}`; - - const eventId = Sentry.captureEvent({ + return Sentry.captureEvent({ message: title, logger: logs, user: { @@ -33,6 +31,4 @@ export function ReportProblem(title, body, logs, email, extra) { ...extra, }, }); - - return eventId + suffix; } diff --git a/src/modules/reporting/sentry.config.js b/src/modules/reporting/sentry.config.js deleted file mode 100644 index ce66f9fd..00000000 --- a/src/modules/reporting/sentry.config.js +++ /dev/null @@ -1 +0,0 @@ -export default { dsn: 'SENTRY_DSN' }; diff --git a/src/modules/spreadsheet/googleOAuth2.js b/src/modules/spreadsheet/googleOAuth2.js index b2f8073a..a81253ea 100644 --- a/src/modules/spreadsheet/googleOAuth2.js +++ b/src/modules/spreadsheet/googleOAuth2.js @@ -1,7 +1,6 @@ import { encryptObject, decryptObject } from '@/modules/encryption/credentials'; import { saveIntoAccount, getFromAccount } from '@/modules/encryption/keytar'; import ElectronGoogleOAuth2 from '@getstation/electron-google-oauth2'; -import clientDetails from './google_client_secret.config'; const keytarAccount = 'googleOauth2Token'; @@ -23,8 +22,8 @@ async function loadToken() { export async function CreateClient() { const myApiOauth = new ElectronGoogleOAuth2( - clientDetails.client_id, - clientDetails.client_secret, + GOOGLE_CLIENT_ID, + GOOGLE_CLIENT_SECRET, [ 'https://www.googleapis.com/auth/drive.metadata.readonly', 'https://www.googleapis.com/auth/spreadsheets', diff --git a/src/modules/spreadsheet/google_client_secret.config.js b/src/modules/spreadsheet/google_client_secret.config.js deleted file mode 100644 index 71e23dd8..00000000 --- a/src/modules/spreadsheet/google_client_secret.config.js +++ /dev/null @@ -1,12 +0,0 @@ -export default { - client_id: 'GOOGLE_CLIENT_ID', - project_id: 'israeli-bank-scrapers-desktop', - auth_uri: 'https://accounts.google.com/o/oauth2/auth', - token_uri: 'https://oauth2.googleapis.com/token', - auth_provider_x509_cert_url: 'https://www.googleapis.com/oauth2/v1/certs', - client_secret: 'GOOGLE_CLIENT_SECRET', - redirect_uris: [ - 'urn:ietf:wg:oauth:2.0:oob', - 'http://localhost', - ], -}; diff --git a/vue.config.js b/vue.config.js index 0686ed92..18b6e04c 100644 --- a/vue.config.js +++ b/vue.config.js @@ -1,6 +1,21 @@ +const globals = require('./globals'); + +const defineGlobals = (config) => { + config.plugin('define').tap((args) => { + const defined = globals.reduce((prev, curr) => { + prev[curr] = JSON.stringify(process.env[curr]); + return prev; + }, {}); + args[0] = defined; + return args; + }); +}; + module.exports = { pluginOptions: { electronBuilder: { + chainWebpackMainProcess: defineGlobals, + chainWebpackRendererProcess: defineGlobals, // List native deps here if they don't work externals: [ 'keytar', From 45e5278408ddf7b7f029f79cc563688ac29613b8 Mon Sep 17 00:00:00 2001 From: Baruch Rothkoff Date: Mon, 2 Mar 2020 16:59:37 +0200 Subject: [PATCH 11/12] Remove prebuild script --- package.json | 1 - scripts/prebuild.js | 31 ------------------------------- 2 files changed, 32 deletions(-) delete mode 100644 scripts/prebuild.js diff --git a/package.json b/package.json index 7445119b..a7ca1375 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,6 @@ "private": true, "scripts": { "serve": "vue-cli-service electron:serve", - "prebuild": "node scripts/prebuild.js", "build": "vue-cli-service electron:build", "postinstall": "electron-builder install-app-deps", "postuninstall": "electron-builder install-app-deps", diff --git a/scripts/prebuild.js b/scripts/prebuild.js deleted file mode 100644 index 8590eda0..00000000 --- a/scripts/prebuild.js +++ /dev/null @@ -1,31 +0,0 @@ -/* eslint-disable no-console */ -// eslint-disable-next-line import/no-extraneous-dependencies -const replace = require('replace-in-file'); - -function replaceValueByEnvVar(key) { - if (process.env[key]) { - console.log(`Replacing ${key}`); - const options = { - files: 'src/**/*.config.js', - from: new RegExp(key, 'g'), - to: process.env[key], - }; - - try { - const results = replace.sync(options); - console.log('Replacement results:', results); - } catch (error) { - console.error('Error occurred:', error); - } - } else { - console.log(`No key ${key} to inject`); - } -} - -const envsToReplace = [ - 'GOOGLE_CLIENT_ID', - 'GOOGLE_CLIENT_SECRET', - 'SENTRY_DSN', -]; - -envsToReplace.forEach((env) => replaceValueByEnvVar(env)); From 056343bfbba1b8bd2dab81e9e1b6be9748e8f94d Mon Sep 17 00:00:00 2001 From: "Baruch Odem (Rothkoff)" Date: Wed, 4 Mar 2020 07:02:22 +0200 Subject: [PATCH 12/12] eslint globals as writable and readonly --- .eslintrc.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 73006c38..2acad1fb 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -16,9 +16,9 @@ module.exports = { extends: ['airbnb-base', 'plugin:vue/recommended'], globals: { - __static: true, + __static: 'writable', ...globals.reduce((prev, curr) => { - prev[curr] = true; + prev[curr] = 'readonly'; return prev; }, {}), },