mirror of
https://github.com/finos/SymphonyElectron.git
synced 2025-02-25 18:55:29 -06:00
Electron-174 - implemented basic authentication for electron
This commit is contained in:
parent
bb28b1e7d8
commit
3c7aa59883
94
js/basicAuth/basic-auth.html
Normal file
94
js/basicAuth/basic-auth.html
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Authentication Request</title>
|
||||||
|
<style>
|
||||||
|
html, body {
|
||||||
|
margin: 0;
|
||||||
|
height: 100%;
|
||||||
|
font-family: sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
text-align: center;
|
||||||
|
padding: 20px
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
padding-top: 10px;
|
||||||
|
text-align: start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hostname {
|
||||||
|
font-size: .9em;
|
||||||
|
}
|
||||||
|
|
||||||
|
label {
|
||||||
|
display: inline-block;
|
||||||
|
width: 20%;
|
||||||
|
text-align: right;
|
||||||
|
padding-right: 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
form {
|
||||||
|
padding-top: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
|
border-spacing: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
input {
|
||||||
|
width: 200px;
|
||||||
|
height: 20px;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer {
|
||||||
|
display: flex;
|
||||||
|
text-align: center;
|
||||||
|
padding-top: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button-container {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<span>Please provide your login credentials for:</span>
|
||||||
|
<span id="hostname" class="hostname">hostname</span>
|
||||||
|
<form id="basicAuth" name="Basic Auth" action="Login">
|
||||||
|
<table class="form">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>User name:</td>
|
||||||
|
<td>
|
||||||
|
<input id="username" name="username" title="Username" required>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Password:</td>
|
||||||
|
<td>
|
||||||
|
<input id="password" type="password" title="Password" required>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<div class="footer">
|
||||||
|
<div class="button-container">
|
||||||
|
<button type="submit" id="login">Log In</button>
|
||||||
|
</div>
|
||||||
|
<div class="button-container">
|
||||||
|
<button id="cancel">Cancel</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
126
js/basicAuth/index.js
Normal file
126
js/basicAuth/index.js
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const electron = require('electron');
|
||||||
|
const BrowserWindow = electron.BrowserWindow;
|
||||||
|
const ipc = electron.ipcMain;
|
||||||
|
const path = require('path');
|
||||||
|
const fs = require('fs');
|
||||||
|
const log = require('../log.js');
|
||||||
|
const logLevels = require('../enums/logLevels.js');
|
||||||
|
|
||||||
|
let basicAuthWindow;
|
||||||
|
|
||||||
|
const local = {};
|
||||||
|
|
||||||
|
let windowConfig = {
|
||||||
|
width: 350,
|
||||||
|
height: 250,
|
||||||
|
show: false,
|
||||||
|
modal: true,
|
||||||
|
autoHideMenuBar: true,
|
||||||
|
titleBarStyle: true,
|
||||||
|
resizable: false,
|
||||||
|
webPreferences: {
|
||||||
|
preload: path.join(__dirname, 'renderer.js'),
|
||||||
|
sandbox: true,
|
||||||
|
nodeIntegration: false
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* method to get the HTML template path
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
function getTemplatePath() {
|
||||||
|
let templatePath = path.join(__dirname, 'basic-auth.html');
|
||||||
|
try {
|
||||||
|
fs.statSync(templatePath).isFile();
|
||||||
|
} catch (err) {
|
||||||
|
log.send(logLevels.ERROR, 'basic-auth: Could not find template ("' + templatePath + '").');
|
||||||
|
}
|
||||||
|
return 'file://' + templatePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Opens the basic auth window for authentication
|
||||||
|
* @param {String} windowName - name of the window upon which this window should show
|
||||||
|
* @param {String} hostname - name of the website that requires authentication
|
||||||
|
* @param {Function} callback
|
||||||
|
*/
|
||||||
|
function openBasicAuthWindow(windowName, hostname, callback) {
|
||||||
|
|
||||||
|
// Register callback function
|
||||||
|
if (typeof callback === 'function') {
|
||||||
|
local.authCallback = callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This prevents creating multiple instances of the
|
||||||
|
// basic auth window
|
||||||
|
if (basicAuthWindow) {
|
||||||
|
if (basicAuthWindow.isMinimized()) {
|
||||||
|
basicAuthWindow.restore();
|
||||||
|
}
|
||||||
|
basicAuthWindow.focus();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let allWindows = BrowserWindow.getAllWindows();
|
||||||
|
allWindows = allWindows.find((window) => { return window.winName === windowName });
|
||||||
|
|
||||||
|
// if we couldn't find any window matching the window name
|
||||||
|
// it will render as a new window
|
||||||
|
if (allWindows) {
|
||||||
|
windowConfig.parent = allWindows;
|
||||||
|
}
|
||||||
|
|
||||||
|
basicAuthWindow = new BrowserWindow(windowConfig);
|
||||||
|
basicAuthWindow.setVisibleOnAllWorkspaces(true);
|
||||||
|
basicAuthWindow.loadURL(getTemplatePath());
|
||||||
|
|
||||||
|
// sets the AlwaysOnTop property for the basic auth window
|
||||||
|
// if the main window's AlwaysOnTop is true
|
||||||
|
let focusedWindow = BrowserWindow.getFocusedWindow();
|
||||||
|
if (focusedWindow && focusedWindow.isAlwaysOnTop()) {
|
||||||
|
basicAuthWindow.setAlwaysOnTop(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
basicAuthWindow.once('ready-to-show', () => {
|
||||||
|
basicAuthWindow.show();
|
||||||
|
});
|
||||||
|
|
||||||
|
basicAuthWindow.webContents.on('did-finish-load', () => {
|
||||||
|
basicAuthWindow.webContents.send('hostname', hostname);
|
||||||
|
});
|
||||||
|
|
||||||
|
basicAuthWindow.on('close', () => {
|
||||||
|
destroyWindow();
|
||||||
|
});
|
||||||
|
|
||||||
|
basicAuthWindow.on('closed', () => {
|
||||||
|
destroyWindow();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
ipc.on('login', (event, args) => {
|
||||||
|
if (typeof args === 'object' && typeof local.authCallback === 'function') {
|
||||||
|
local.authCallback(args.username, args.password);
|
||||||
|
basicAuthWindow.close();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
ipc.on('close-basic-auth', () => {
|
||||||
|
if (basicAuthWindow) {
|
||||||
|
basicAuthWindow.close();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroys a window
|
||||||
|
*/
|
||||||
|
function destroyWindow() {
|
||||||
|
basicAuthWindow = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
openBasicAuthWindow: openBasicAuthWindow
|
||||||
|
};
|
55
js/basicAuth/renderer.js
Normal file
55
js/basicAuth/renderer.js
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
'use strict';
|
||||||
|
const electron = require('electron');
|
||||||
|
const ipc = electron.ipcRenderer;
|
||||||
|
|
||||||
|
renderDom();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method that renders application data
|
||||||
|
*/
|
||||||
|
function renderDom() {
|
||||||
|
document.addEventListener('DOMContentLoaded', function () {
|
||||||
|
loadContent();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadContent() {
|
||||||
|
let basicAuth = document.getElementById('basicAuth');
|
||||||
|
let cancel = document.getElementById('cancel');
|
||||||
|
|
||||||
|
if (basicAuth) {
|
||||||
|
basicAuth.onsubmit = (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
submitForm();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cancel) {
|
||||||
|
cancel.addEventListener('click', () => {
|
||||||
|
ipc.send('close-basic-auth');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method that gets invoked on submitting the form
|
||||||
|
*/
|
||||||
|
function submitForm() {
|
||||||
|
let username = document.getElementById('username').value;
|
||||||
|
let password = document.getElementById('password').value;
|
||||||
|
|
||||||
|
if (username && password) {
|
||||||
|
ipc.send('login', { username, password });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the hosts name
|
||||||
|
*/
|
||||||
|
ipc.on('hostname', (event, host) => {
|
||||||
|
let hostname = document.getElementById('hostname');
|
||||||
|
|
||||||
|
if (hostname){
|
||||||
|
hostname.innerHTML = host || 'unknown';
|
||||||
|
}
|
||||||
|
});
|
25
js/dialogs/showBasicAuth.js
Normal file
25
js/dialogs/showBasicAuth.js
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const electron = require('electron');
|
||||||
|
|
||||||
|
const basicAuth = require('../basicAuth');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Having a proxy or hosts that requires authentication will allow user to
|
||||||
|
* enter their credentials 'username' & 'password'
|
||||||
|
*/
|
||||||
|
electron.app.on('login', (event, webContents, request, authInfo, callback) => {
|
||||||
|
|
||||||
|
event.preventDefault();
|
||||||
|
|
||||||
|
// name of the host to display
|
||||||
|
let hostname = authInfo.host || authInfo.realm;
|
||||||
|
let browserWin = electron.BrowserWindow.fromWebContents(webContents);
|
||||||
|
let windowName = browserWin.winName || '';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Opens an electron modal window in which
|
||||||
|
* user can enter credentials fot the host
|
||||||
|
*/
|
||||||
|
basicAuth.openBasicAuthWindow(windowName, hostname, callback);
|
||||||
|
});
|
@ -23,6 +23,7 @@ const { isMac, isNodeEnv } = require('./utils/misc');
|
|||||||
|
|
||||||
// show dialog when certificate errors occur
|
// show dialog when certificate errors occur
|
||||||
require('./dialogs/showCertError.js');
|
require('./dialogs/showCertError.js');
|
||||||
|
require('./dialogs/showBasicAuth.js');
|
||||||
|
|
||||||
// Keep a global reference of the window object, if you don't, the window will
|
// Keep a global reference of the window object, if you don't, the window will
|
||||||
// be closed automatically when the JavaScript object is garbage collected.
|
// be closed automatically when the JavaScript object is garbage collected.
|
||||||
|
Loading…
Reference in New Issue
Block a user