From 066672205a8c3c9c8f79913a6cc435b06f10cea2 Mon Sep 17 00:00:00 2001 From: Yuya Ochiai Date: Sun, 6 Mar 2016 21:58:52 +0900 Subject: [PATCH 1/2] Confirm to trust certificate when there is error For #26 --- src/browser/index.jsx | 4 +++ src/main.js | 33 +++++++++++++++++++ src/main/certificateStore.js | 62 ++++++++++++++++++++++++++++++++++++ 3 files changed, 99 insertions(+) create mode 100644 src/main/certificateStore.js diff --git a/src/browser/index.jsx b/src/browser/index.jsx index 00c7bb83..c6ecf2b4 100644 --- a/src/browser/index.jsx +++ b/src/browser/index.jsx @@ -221,6 +221,10 @@ var MattermostView = React.createClass({ webview.addEventListener('did-fail-load', function(e) { console.log(thisObj.props.name, 'webview did-fail-load', e); + if (e.errorCode === -3) { // An operation was aborted (due to user action). + return; + } + // should use permanent way to indicate var did_fail_load_notification = new Notification(`Failed to load "${thisObj.props.name}"`, { body: `ErrorCode: ${e.errorCode}`, diff --git a/src/main.js b/src/main.js index f2a1b0f1..65763dc0 100644 --- a/src/main.js +++ b/src/main.js @@ -10,6 +10,7 @@ const fs = require('fs'); const path = require('path'); var settings = require('./common/settings'); +var certificateStore = require('./main/certificateStore').load(path.resolve(app.getPath('userData'), 'certificate.json')); var appMenu = require('./main/menus/app'); var argv = require('yargs').argv; @@ -80,6 +81,38 @@ app.on('before-quit', function() { willAppQuit = true; }); +app.on('certificate-error', function(event, webContents, url, error, certificate, callback) { + if (certificateStore.isTrusted(url, certificate)) { + event.preventDefault(); + callback(true); + } + else { + var detail = `URL: ${url}\nError: ${error}`; + if (certificateStore.isExisting(url)) { + detail = `Certificate is different from previous one.\n\n` + detail; + } + + electron.dialog.showMessageBox(mainWindow, { + title: 'Certificate error', + message: `Do you trust certificate from "${certificate.issuerName}"?`, + detail: detail, + type: 'warning', + buttons: [ + 'Yes', + 'No' + ], + cancelId: 1 + }, function(response) { + if (response === 0) { + certificateStore.add(url, certificate); + certificateStore.save(); + webContents.loadURL(url); + } + }); + callback(false); + } +}); + // This method will be called when Electron has finished // initialization and is ready to create browser windows. app.on('ready', function() { diff --git a/src/main/certificateStore.js b/src/main/certificateStore.js new file mode 100644 index 00000000..da091ac6 --- /dev/null +++ b/src/main/certificateStore.js @@ -0,0 +1,62 @@ +'use strict'; + +const fs = require('fs'); +const url = require('url'); + +function comparableCertificate(certificate) { + return { + data: certificate.data.toString(), + issuerName: certificate.issuerName + }; +} + +function areEqual(certificate0, certificate1) { + if (certificate0.data !== certificate1.data) { + return false; + } + if (certificate0.issuerName !== certificate1.issuerName) { + return false; + } + return true; +} + +function getHost(targetURL) { + return url.parse(targetURL).host; +} + +var CertificateStore = function(storeFile) { + this.storeFile = storeFile + try { + this.data = JSON.parse(fs.readFileSync(storeFile, 'utf-8')); + } + catch (e) { + console.log(e); + this.data = {}; + } +}; + +CertificateStore.prototype.save = function() { + fs.writeFileSync(this.storeFile, JSON.stringify(this.data, null, ' ')); +}; + +CertificateStore.prototype.add = function(targetURL, certificate) { + this.data[getHost(targetURL)] = comparableCertificate(certificate); +}; + +CertificateStore.prototype.isExisting = function(targetURL) { + return this.data.hasOwnProperty(getHost(targetURL)); +}; + +CertificateStore.prototype.isTrusted = function(targetURL, certificate) { + var host = getHost(targetURL); + if (!this.isExisting(targetURL)) { + return false; + } + return areEqual(this.data[host], comparableCertificate(certificate)); +}; + +module.exports = { + load: function(storeFile) { + return new CertificateStore(storeFile); + } +}; From 2dc6d1e26d23f578324b27012bff9eec4c513070 Mon Sep 17 00:00:00 2001 From: Yuya Ochiai Date: Sun, 6 Mar 2016 22:13:30 +0900 Subject: [PATCH 2/2] Update README.md For #26 --- README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/README.md b/README.md index 5aa8c8de..c1d4079a 100644 --- a/README.md +++ b/README.md @@ -40,6 +40,13 @@ Configuration will be saved into Electron's userData directory: * `~/Library/Application Support/electron-mattermost` on OS X * `~/.config/electron-mattermost` on Linux +### Proxy +You can resolve the proxy by following command line options. +*Note: Authorization is not supported.* + +* `--proxy-server=:` +* `--proxy-pac-url=` + ## Testing and Development Node.js is required to test this app.