1
0
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:
Kiran Niranjan 2017-10-18 12:17:09 +05:30 committed by Kiran Niranjan
parent bb28b1e7d8
commit 3c7aa59883
5 changed files with 301 additions and 0 deletions

View 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
View 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
View 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';
}
});

View 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);
});

View File

@ -23,6 +23,7 @@ const { isMac, isNodeEnv } = require('./utils/misc');
// show dialog when certificate errors occur
require('./dialogs/showCertError.js');
require('./dialogs/showBasicAuth.js');
// 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.