mirror of
https://github.com/finos/SymphonyElectron.git
synced 2024-11-21 16:38:41 -06:00
SDA-3140 Insecure sites - Ability to allow insecure sites only once (#1352)
This commit is contained in:
parent
2fe326e378
commit
43df94f828
@ -55,16 +55,19 @@ describe('dialog handler', () => {
|
||||
});
|
||||
|
||||
describe('certificate-error', () => {
|
||||
const urlMocked = 'https://symphony.corporate.com/';
|
||||
let urlMocked;
|
||||
const errorMocked = 'check for server certificate revocation';
|
||||
const certificate = null;
|
||||
|
||||
it('should return false when buttonId is 1', async (done) => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks().resetModules();
|
||||
});
|
||||
it('should return true when buttonId is 0', async (done) => {
|
||||
urlMocked = 'https://symphony.corporate.com/';
|
||||
BrowserWindow.fromWebContents = jest.fn(() => {
|
||||
return { isDestroyed: jest.fn(() => false) };
|
||||
});
|
||||
dialog.showMessageBox = jest.fn(() => {
|
||||
return { response: 1 };
|
||||
return { response: 0 };
|
||||
});
|
||||
await ipcRenderer.send(
|
||||
'certificate-error',
|
||||
@ -74,22 +77,6 @@ describe('dialog handler', () => {
|
||||
certificate,
|
||||
callbackMocked,
|
||||
);
|
||||
done(expect(callbackMocked).toBeCalledWith(false));
|
||||
});
|
||||
|
||||
it('should return true when buttonId is not 1', async (done) => {
|
||||
BrowserWindow.fromWebContents = jest.fn(() => {
|
||||
return { isDestroyed: jest.fn(() => false) };
|
||||
});
|
||||
dialog.showMessageBox = jest.fn(() => 2);
|
||||
await ipcRenderer.send(
|
||||
'certificate-error',
|
||||
webContentsMocked,
|
||||
urlMocked,
|
||||
errorMocked,
|
||||
certificate,
|
||||
callbackMocked,
|
||||
);
|
||||
expect(callbackMocked).toBeCalledWith(true);
|
||||
await ipcRenderer.send(
|
||||
'certificate-error',
|
||||
@ -101,6 +88,34 @@ describe('dialog handler', () => {
|
||||
);
|
||||
done(expect(callbackMocked).toBeCalledWith(true));
|
||||
});
|
||||
|
||||
it('should return false when buttonId is 1', async (done) => {
|
||||
urlMocked = 'https://symphony2.corporate.com/';
|
||||
BrowserWindow.fromWebContents = jest.fn(() => {
|
||||
return { isDestroyed: jest.fn(() => false) };
|
||||
});
|
||||
dialog.showMessageBox = jest.fn(() => {
|
||||
return { response: 1 };
|
||||
});
|
||||
await ipcRenderer.send(
|
||||
'certificate-error',
|
||||
webContentsMocked,
|
||||
urlMocked,
|
||||
errorMocked,
|
||||
certificate,
|
||||
callbackMocked,
|
||||
);
|
||||
expect(callbackMocked).toBeCalledWith(false);
|
||||
await ipcRenderer.send(
|
||||
'certificate-error',
|
||||
webContentsMocked,
|
||||
urlMocked,
|
||||
errorMocked,
|
||||
certificate,
|
||||
callbackMocked,
|
||||
);
|
||||
done(expect(callbackMocked).toBeCalledWith(false));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -2,6 +2,7 @@ import { app, BrowserWindow, dialog } from 'electron';
|
||||
|
||||
import { i18n } from '../common/i18n';
|
||||
import { logger } from '../common/logger';
|
||||
import { whitelistHandler } from '../common/whitelist-handler';
|
||||
import { CloudConfigDataTypes, config } from './config-handler';
|
||||
import { ICustomBrowserWindow, windowHandler } from './window-handler';
|
||||
import { windowExists } from './window-utils';
|
||||
@ -50,47 +51,47 @@ app.on('login', (event, webContents, request, authInfo, callback) => {
|
||||
);
|
||||
});
|
||||
|
||||
let ignoreAllCertErrors = false;
|
||||
|
||||
/**
|
||||
* If certificate error occurs allow user to deny or allow particular certificate
|
||||
* error. If user selects 'Ignore All', then all subsequent certificate errors
|
||||
* will ignored during this session.
|
||||
* error.
|
||||
*
|
||||
* Note: the dialog is synchronous so further processing is blocked until
|
||||
* user provides a response.
|
||||
*/
|
||||
const siteNameAcceptedStatus = new Map<string, boolean>();
|
||||
app.on(
|
||||
'certificate-error',
|
||||
async (event, webContents, url, error, _certificate, callback) => {
|
||||
// TODO: Add logic verify custom certificate
|
||||
event.preventDefault();
|
||||
const { tld, domain, subdomain } = whitelistHandler.parseDomain(url);
|
||||
let siteName = `${domain}${tld}`;
|
||||
if (subdomain.length) {
|
||||
siteName = `${subdomain}.${siteName}`;
|
||||
}
|
||||
logger.warn(`Certificate error: ${error} for url: ${siteName}`);
|
||||
|
||||
if (ignoreAllCertErrors) {
|
||||
event.preventDefault();
|
||||
callback(true);
|
||||
const isSiteNameAccepted = siteNameAcceptedStatus.get(siteName);
|
||||
if (isSiteNameAccepted !== undefined) {
|
||||
callback(isSiteNameAccepted);
|
||||
return;
|
||||
}
|
||||
|
||||
logger.warn(`Certificate error: ${error} for url: ${url}`);
|
||||
|
||||
event.preventDefault();
|
||||
|
||||
const browserWin = BrowserWindow.fromWebContents(webContents);
|
||||
if (browserWin && windowExists(browserWin)) {
|
||||
const { response } = await dialog.showMessageBox(browserWin, {
|
||||
type: 'warning',
|
||||
buttons: [i18n.t('Allow')(), i18n.t('Deny')(), i18n.t('Ignore All')()],
|
||||
buttons: [i18n.t('Allow once (risky)')(), i18n.t('Deny')()],
|
||||
defaultId: 1,
|
||||
cancelId: 1,
|
||||
noLink: true,
|
||||
title: i18n.t('Certificate Error')(),
|
||||
message: `${i18n.t('Certificate Error')()}: ${error}\nURL: ${url}`,
|
||||
message: `${siteName} ${i18n.t(
|
||||
'Invalid security certificate',
|
||||
)()}\n ${error}`,
|
||||
});
|
||||
if (response === 2) {
|
||||
ignoreAllCertErrors = true;
|
||||
}
|
||||
|
||||
callback(response !== 1);
|
||||
siteNameAcceptedStatus.set(siteName, !response);
|
||||
callback(!response);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
@ -216,5 +216,8 @@
|
||||
"Your administrator has disabled": "Your administrator has disabled",
|
||||
"Zoom": "Zoom",
|
||||
"Zoom In": "Zoom In",
|
||||
"Zoom Out": "Zoom Out"
|
||||
"Zoom Out": "Zoom Out",
|
||||
"Allow once (risky)": "Allow once (risky)",
|
||||
"Deny": "Deny",
|
||||
"Invalid security certificate": "has an invalid security certificate."
|
||||
}
|
||||
|
@ -216,5 +216,8 @@
|
||||
"Your administrator has disabled": "Your administrator has disabled",
|
||||
"Zoom": "Zoom",
|
||||
"Zoom In": "Zoom In",
|
||||
"Zoom Out": "Zoom Out"
|
||||
"Zoom Out": "Zoom Out",
|
||||
"Allow once (risky)": "Allow once (risky)",
|
||||
"Deny": "Deny",
|
||||
"Invalid security certificate": "has an invalid security certificate."
|
||||
}
|
||||
|
@ -216,5 +216,8 @@
|
||||
"Your administrator has disabled": "Votre administrateur a désactivé",
|
||||
"Zoom": "Zoom",
|
||||
"Zoom In": "Zoom Avant",
|
||||
"Zoom Out": "Zoom Arrière"
|
||||
"Zoom Out": "Zoom Arrière",
|
||||
"Allow once (risky)": "Autoriser une fois (risqué)",
|
||||
"Deny": "Refuser",
|
||||
"Invalid security certificate": "possède un certificat de sécurité non valide."
|
||||
}
|
||||
|
@ -216,5 +216,8 @@
|
||||
"Your administrator has disabled": "Votre administrateur a désactivé",
|
||||
"Zoom": "Zoom",
|
||||
"Zoom In": "Zoom Avant",
|
||||
"Zoom Out": "Zoom Arrière"
|
||||
"Zoom Out": "Zoom Arrière",
|
||||
"Allow once (risky)": "Autoriser une fois (risqué)",
|
||||
"Deny": "Refuser",
|
||||
"Invalid security certificate": "possède un certificat de sécurité non valide."
|
||||
}
|
||||
|
@ -216,5 +216,8 @@
|
||||
"Your administrator has disabled": "管理者によて無効にされています",
|
||||
"Zoom": "ズーム",
|
||||
"Zoom In": "ズームイン",
|
||||
"Zoom Out": "ズームアウト"
|
||||
"Zoom Out": "ズームアウト",
|
||||
"Allow once (risky)": "今回は許可(推奨されません)",
|
||||
"Deny": "拒否",
|
||||
"Invalid security certificate": "のセキュリティ証明書は無効です。"
|
||||
}
|
||||
|
@ -216,5 +216,6 @@
|
||||
"Your administrator has disabled": "管理者によて無効にされています",
|
||||
"Zoom": "ズーム",
|
||||
"Zoom In": "ズームイン",
|
||||
"Zoom Out": "ズームアウト"
|
||||
"Zoom Out": "ズームアウト",
|
||||
"Invalid security certificate": "のセキュリティ証明書は無効です。"
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user