diff --git a/src/main/certificateStore.ts b/src/main/certificateStore.ts index 64c326b7..271ea700 100644 --- a/src/main/certificateStore.ts +++ b/src/main/certificateStore.ts @@ -13,10 +13,11 @@ import urlUtils from 'common/utils/url'; import * as Validator from './Validator'; -function comparableCertificate(certificate: Certificate): ComparableCertificate { +function comparableCertificate(certificate: Certificate, dontTrust = false): ComparableCertificate { return { data: certificate.data.toString(), issuerName: certificate.issuerName, + dontTrust, }; } @@ -53,8 +54,8 @@ export default class CertificateStore { fs.writeFileSync(this.storeFile, JSON.stringify(this.data, null, ' ')); }; - add = (targetURL: string, certificate: Certificate) => { - this.data[urlUtils.getHost(targetURL)] = comparableCertificate(certificate); + add = (targetURL: string, certificate: Certificate, dontTrust = false) => { + this.data[urlUtils.getHost(targetURL)] = comparableCertificate(certificate, dontTrust); }; isExisting = (targetURL: string) => { @@ -68,4 +69,12 @@ export default class CertificateStore { } return areEqual(this.data[host], comparableCertificate(certificate)); }; + + isExplicitlyUntrusted = (targetURL: string) => { + // Whether or not the certificate was explicitly marked as untrusted by + // clicking "Don't ask again" checkbox before cancelling the connection. + const host = urlUtils.getHost(targetURL); + const dontTrust = this.data[host]?.dontTrust; + return dontTrust === undefined ? false : dontTrust; + } } diff --git a/src/main/main.ts b/src/main/main.ts index 9ac155eb..a8531b08 100644 --- a/src/main/main.ts +++ b/src/main/main.ts @@ -396,7 +396,11 @@ function handleAppCertificateError(event: electron.Event, webContents: electron. return; } const origin = parsedURL.origin; - if (certificateStore.isTrusted(origin, certificate)) { + if (certificateStore.isExplicitlyUntrusted(origin)) { + event.preventDefault(); + log.warn(`Ignoring previously untrusted certificate for ${origin}`); + callback(false); + } else if (certificateStore.isTrusted(origin, certificate)) { event.preventDefault(); callback(true); } else { @@ -436,11 +440,13 @@ function handleAppCertificateError(event: electron.Event, webContents: electron. type: 'error', buttons: ['Trust Insecure Certificate', 'Cancel Connection'], cancelId: 1, + checkboxChecked: false, + checkboxLabel: "Don't ask again", }); } - return {response}; + return {response, checkboxChecked: false}; }).then( - ({response: responseTwo}) => { + ({response: responseTwo, checkboxChecked}) => { if (responseTwo === 0) { certificateStore.add(origin, certificate); certificateStore.save(); @@ -448,6 +454,10 @@ function handleAppCertificateError(event: electron.Event, webContents: electron. certificateErrorCallbacks.delete(errorID); webContents.loadURL(url); } else { + if (checkboxChecked) { + certificateStore.add(origin, certificate, true); + certificateStore.save(); + } certificateErrorCallbacks.get(errorID)(false); certificateErrorCallbacks.delete(errorID); } diff --git a/src/types/certificate.ts b/src/types/certificate.ts index 65462da4..5edb3240 100644 --- a/src/types/certificate.ts +++ b/src/types/certificate.ts @@ -6,6 +6,7 @@ import {Certificate} from 'electron/common'; export type ComparableCertificate = { data: string; issuerName: string; + dontTrust: boolean; } export type CertificateModalData = {