diff --git a/meshuser.js b/meshuser.js
index a322d89e..318e9b16 100644
--- a/meshuser.js
+++ b/meshuser.js
@@ -1503,9 +1503,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
// Send back the list of keys we have, just send the list of names and index
var hkeys = [];
- if (user.otphkeys != null) { for (var i = 0; i < user.otphkeys.length; i++) { hkeys.push({ i: user.otphkeys[i].keyIndex, name: user.otphkeys[i].name }); } }
-
- //hkeys = [{ i: 1234, name: 'My Normal Key' }, { i: 5678, name: 'Backup Key' }, { i: 90122, name: 'Blue Extra Key' }];
+ if (user.otphkeys != null) { for (var i = 0; i < user.otphkeys.length; i++) { hkeys.push({ i: user.otphkeys[i].keyIndex, name: user.otphkeys[i].name, type: user.otphkeys[i].type }); } }
ws.send(JSON.stringify({ action: 'otp-hkey-get', keys: hkeys }));
break;
@@ -1539,22 +1537,31 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
// Check if Yubikey support is present
if ((typeof domain.yubikey != 'object') || (typeof domain.yubikey.id != 'string') || (typeof domain.yubikey.secret != 'string')) break;
- /*
- var yub = require('yubikey-client');
- yub.init(domain.yubikey.id, domain.yubikey.secret);
- yub.verify(command.otp, function (err, data) {
- console.log(err, data);
- });
- */
-
+ // Query the YubiKey server to validate the OTP
var yubikeyotp = require('yubikeyotp');
- //var request = { otp: command.otp, id: domain.yubikey.id, key: domain.yubikey.secret, sl: '100', timestamp: true }
var request = { otp: command.otp, id: domain.yubikey.id, key: domain.yubikey.secret, timestamp: true }
if (domain.yubikey.proxy) { request.requestParams = { proxy: domain.yubikey.proxy }; }
-
- console.log('YubiKey Request: ' + JSON.stringify(request));
yubikeyotp.verifyOTP(request, function (err, results) {
- console.log(err, results);
+ if (results.status == 'OK') {
+ var keyIndex = obj.parent.crypto.randomBytes(4).readUInt32BE(0);
+ var keyId = command.otp.substring(0, 12);
+ if (user.otphkeys == null) { user.otphkeys = []; }
+
+ // Check if this key was already registered, if so, remove it.
+ var foundAtIndex = -1;
+ for (var i = 0; i < user.otphkeys.length; i++) { if (user.otphkeys[i].keyid == keyId) { foundAtIndex = i; } }
+ if (foundAtIndex != -1) { user.otphkeys.splice(foundAtIndex, 1); }
+
+ // Add the new key and notify
+ user.otphkeys.push({ name: command.name, type: 2, keyid: keyId, keyIndex: keyIndex });
+ obj.parent.db.SetUser(user);
+ ws.send(JSON.stringify({ action: 'otp-hkey-yubikey-add', result: true, name: command.name, index: keyIndex }));
+
+ // Notify change TODO: Should be done on all sessions/servers for this user.
+ try { ws.send(JSON.stringify({ action: 'userinfo', userinfo: obj.parent.CloneSafeUser(user) })); } catch (ex) { }
+ } else {
+ ws.send(JSON.stringify({ action: 'otp-hkey-yubikey-add', result: false, name: command.name }));
+ }
});
break;
@@ -1587,7 +1594,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
ws.send(JSON.stringify({ action: 'otp-hkey-setup-response', result: result.successful, name: command.name, index: keyIndex }));
if (result.successful) {
if (user.otphkeys == null) { user.otphkeys = []; }
- user.otphkeys.push({ name: command.name, publicKey: result.publicKey, keyHandle: result.keyHandle, keyIndex: keyIndex });
+ user.otphkeys.push({ name: command.name, type: 1, publicKey: result.publicKey, keyHandle: result.keyHandle, keyIndex: keyIndex });
obj.parent.db.SetUser(user);
//console.log('KEYS', JSON.stringify(user.otphkeys));
diff --git a/package.json b/package.json
index fe6a4ddd..2b957f8d 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "meshcentral",
- "version": "0.2.7-n",
+ "version": "0.2.7-o",
"keywords": [
"Remote Management",
"Intel AMT",
diff --git a/public/images/hardware-key-24.png b/public/images/hardware-key-24.png
deleted file mode 100644
index f2ecfb7f..00000000
Binary files a/public/images/hardware-key-24.png and /dev/null differ
diff --git a/public/images/hardware-key-32.png b/public/images/hardware-key-32.png
deleted file mode 100644
index 1ad6f6a3..00000000
Binary files a/public/images/hardware-key-32.png and /dev/null differ
diff --git a/public/images/hardware-key-OTP-24.png b/public/images/hardware-key-OTP-24.png
new file mode 100644
index 00000000..2cdedb90
Binary files /dev/null and b/public/images/hardware-key-OTP-24.png differ
diff --git a/public/images/hardware-key-U2F-24.png b/public/images/hardware-key-U2F-24.png
new file mode 100644
index 00000000..7d11dd81
Binary files /dev/null and b/public/images/hardware-key-U2F-24.png differ
diff --git a/public/images/hardware-keypress-120 - Copy.png b/public/images/hardware-keypress-120 - Copy.png
new file mode 100644
index 00000000..c1d804b1
Binary files /dev/null and b/public/images/hardware-keypress-120 - Copy.png differ
diff --git a/public/images/hardware-keypress-120.png b/public/images/hardware-keypress-120.png
index c1d804b1..bec0f394 100644
Binary files a/public/images/hardware-keypress-120.png and b/public/images/hardware-keypress-120.png differ
diff --git a/views/default-min.handlebars b/views/default-min.handlebars
index 31a6e765..d688c160 100644
--- a/views/default-min.handlebars
+++ b/views/default-min.handlebars
@@ -1 +1 @@
-
MeshCentral
↔
My Devices My Account My Events My Files My Users My Server
General Desktop Terminal Files Events Intel® AMT Console
Server disconnected , click to reconnect .
My Account Device Groups (
New )
My Files These files are shared publicly, click "link" to get public url.
✓
✗
My Server Server actions
Server Statistics
Intel® AMT Redirection port or KVM feature is disabled, click here to enable it.
Remote computer is not powered on, click here to issue a power command.
Intel® AMT Redirection port or KVM feature is disabled, click here to enable it.
Remote computer is not powered on, click here to issue a power command.
Show
Last 60 Last 120 Last 250 Last 500 Last 1000
General -
Events -
Show
Last 60 Last 120 Last 250 Last 500 Last 1000
Local file upload Server file selection File Selection
Agent Remote Desktop 100% 87.5% 75% 62.5% 50% 37.5% 25% 12.5% Scaling
Fast Medium Slow Very slow Frame rate
Intel® AMT Hardware KVM RLE8, Fastest RLE16, Recommended RAW8, Slow RAW16, Very Slow Image Encoding
\ No newline at end of file
+ MeshCentral
↔
My Devices My Account My Events My Files My Users My Server
General Desktop Terminal Files Events Intel® AMT Console
Server disconnected , click to reconnect .
My Account Device Groups (
New )
My Files These files are shared publicly, click "link" to get public url.
✓
✗
My Server Server actions
Server Statistics
Intel® AMT Redirection port or KVM feature is disabled, click here to enable it.
Remote computer is not powered on, click here to issue a power command.
Intel® AMT Redirection port or KVM feature is disabled, click here to enable it.
Remote computer is not powered on, click here to issue a power command.
Show
Last 60 Last 120 Last 250 Last 500 Last 1000
General -
Events -
Show
Last 60 Last 120 Last 250 Last 500 Last 1000
Local file upload Server file selection File Selection
Agent Remote Desktop 100% 87.5% 75% 62.5% 50% 37.5% 25% 12.5% Scaling
Fast Medium Slow Very slow Frame rate
Intel® AMT Hardware KVM RLE8, Fastest RLE16, Recommended RAW8, Slow RAW16, Very Slow Image Encoding
\ No newline at end of file
diff --git a/views/default.handlebars b/views/default.handlebars
index 05bc7abf..76a44d3a 100644
--- a/views/default.handlebars
+++ b/views/default.handlebars
@@ -1447,38 +1447,44 @@
var end = "";
var x = "Hardware keys are used as secondary login authentication.";
x += "";
+ var keyType1 = 0;
if (message.keys && message.keys.length > 0) {
for (var i in message.keys) {
var key = message.keys[i];
- x += start + '' + key.name + " " + end;
+ var type = 'OTP';
+ if (key.type == 1) { keyType1++; type = 'U2F'; }
+ x += start + '' + key.name + " " + end;
}
} else {
x += start + 'No Hardware Keys Configured' + end;
}
x += " ";
x += " ";
- //x += " ";
-
- if (u2fSupported()) {
- x += " ";
- } else {
- x += "No hardware key support on this browser.";
- }
+ x += " ";
+ if ((features & 0x4000) != 0) { x += " "; }
x += "
";
setDialogMode(2, "Manage Hardware Login Keys", 8, null, x, 'otpauth-hardware-manage');
- if (u2fSupported() && (message.keys.length > 0)) { QE('d2addkey', false); }
+ if ((u2fSupported() == false) || (keyType1 > 0)) { QE('d2addkey1', false); }
+ break;
+ }
+ case 'otp-hkey-yubikey-add': {
+ if (message.result) {
+ meshserver.send({ action: 'otp-hkey-get' }); // Success, ask for the full list of keys.
+ } else {
+ setDialogMode(2, "Add Hardware Login Key", 1, null, ' Error, Unable to add key. ');
+ }
break;
}
case 'otp-hkey-setup-request': {
if (xxdialogMode && (xxdialogTag != 'otpauth-hardware-manage')) return;
- var x = "Press the key button now. ";
+ var x = "Press the key button now. ";
setDialogMode(2, "Add Hardware Login Key", 2, null, x);
window.u2f.register(message.request.appId, [message.request], [], function (registrationResponse) {
if (registrationResponse.registrationData) {
meshserver.send({ action: 'otp-hkey-setup-response', request: message.request, response: registrationResponse, name: Q('dp1keyname').value });
setDialogMode(2, "Add Hardware Login Key", 0, null, ' Checking... ', 'otpauth-hardware-manage');
} else {
- setDialogMode(0);
+ setDialogMode(2, "Add Hardware Login Key", 1, null, ' Error code ' + registrationResponse.errorCode + ' ');
}
});
break;
@@ -5310,38 +5316,32 @@
meshserver.send({ action: 'otp-hkey-get' });
}
- function account_addhkey() {
- var x = "Type in the name of the key to add. ";
- x += addHtmlValue('Key Name', ' ');
- setDialogMode(2, "Add Hardware Login Key", 3, account_addhkeyEx, x);
+ function account_addhkey(type) {
+ if (type == 1) {
+ var x = "Type in the name of the key to add. ";
+ x += addHtmlValue('Key Name', ' ');
+ } else if (type == 2) {
+ var x = "Type in a key name, select the OTP box and press the USB key button ";
+ x += addHtmlValue('Key Name', ' ');
+ x += addHtmlValue('OTP from key', ' ');
+ }
+ setDialogMode(2, "Add Hardware Login Key", 3, account_addhkeyEx, x, type);
Q('dp1keyname').focus();
}
- function account_addhkeyValidate(e) {
- if ((e != null) && (e.keyCode == 13)) { dialogclose(1); }
+ function account_addhkeyValidate(e,action) {
+ if ((e != null) && (e.keyCode == 13)) { if (action == 2) { dialogclose(1); } else { Q('dp1key').focus(); } }
}
- function account_addhkeyEx() {
+ function account_addhkeyEx(button, type) {
var name = Q('dp1keyname').value;
if (name == '') { name = 'MyKey'; }
- meshserver.send({ action: 'otp-hkey-setup-request', name: name });
- }
-
- function account_addYubiKey() {
- if (xxdialogMode && (xxdialogTag != 'otpauth-hardware-manage')) return;
- var x = "Type in a name for the key and press button on the key to register the new hardware key. ";
- x += addHtmlValue('Key Name', ' ');
- x += addHtmlValue('Key Token', ' ');
- setDialogMode(2, "Add Yubikey", 3, account_addYubiKeyEx, x);
- account_addYubiKeyValidate();
- }
-
- function account_addYubiKeyValidate() {
- QE('idx_dlgOkButton', (Q('dp1keyname').value.length > 0) && (Q('dp1keytoken').value.length > 0));
- }
-
- function account_addYubiKeyEx() {
- meshserver.send({ action: 'otp-hkey-yubikey-add', name: Q('dp1keyname').value, otp: Q('dp1keytoken').value });
+ if (type == 1) {
+ meshserver.send({ action: 'otp-hkey-setup-request', name: name });
+ } else if (type == 2) {
+ meshserver.send({ action: 'otp-hkey-yubikey-add', name: name, otp: Q('dp1key').value });
+ setDialogMode(2, "Add Hardware Login Key", 0, null, " Checking... ", 'otpauth-hardware-manage');
+ }
}
function account_removehkey(index) {
diff --git a/views/login-min.handlebars b/views/login-min.handlebars
index 4a09c04c..2e45fd30 100644
--- a/views/login-min.handlebars
+++ b/views/login-min.handlebars
@@ -1 +1 @@
- MeshCentral - Login
Welcome Connect to your home or office devices from anywhere in the world using MeshCentral , the real time, open source remote monitoring and management web site. You will need to download and install a management agent on your computers. Once installed, computers will show up in the "My Devices" section of this web site and you will be able to monitor them and take control of them.
\ No newline at end of file
+ MeshCentral - Login
Welcome Connect to your home or office devices from anywhere in the world using MeshCentral , the real time, open source remote monitoring and management web site. You will need to download and install a management agent on your computers. Once installed, computers will show up in the "My Devices" section of this web site and you will be able to monitor them and take control of them.
\ No newline at end of file
diff --git a/views/login-mobile-min.handlebars b/views/login-mobile-min.handlebars
index 16a50e47..baeadf9c 100644
--- a/views/login-mobile-min.handlebars
+++ b/views/login-mobile-min.handlebars
@@ -1 +1 @@
- MeshCentral - Login
\ No newline at end of file
+ MeshCentral - Login
\ No newline at end of file
diff --git a/views/login-mobile.handlebars b/views/login-mobile.handlebars
index 9edf2d0d..c8aef775 100644
--- a/views/login-mobile.handlebars
+++ b/views/login-mobile.handlebars
@@ -150,7 +150,7 @@
Login token:
-
+
@@ -351,9 +351,9 @@
function checkToken() {
var t1 = Q('tokenInput').value;
- var t2 = t1.replace(/\D/g, '');
+ var t2 = t1.split(' ').join('');
if (t1 != t2) { Q('tokenInput').value = t2; }
- QE('tokenOkButton', (Q('tokenInput').value.length == 6) || (Q('tokenInput').value.length == 8));
+ QE('tokenOkButton', (Q('tokenInput').value.length == 6) || (Q('tokenInput').value.length == 8) || (Q('tokenInput').value.length == 44));
}
//
diff --git a/views/login.handlebars b/views/login.handlebars
index c833f28f..3457af8a 100644
--- a/views/login.handlebars
+++ b/views/login.handlebars
@@ -223,7 +223,7 @@
Login token:
-
+
@@ -446,9 +446,9 @@
function checkToken() {
var t1 = Q('tokenInput').value;
- var t2 = t1.replace(/\D/g, '');
+ var t2 = t1.split(' ').join('');
if (t1 != t2) { Q('tokenInput').value = t2; }
- QE('tokenOkButton', (Q('tokenInput').value.length == 6) || (Q('tokenInput').value.length == 8));
+ QE('tokenOkButton', (Q('tokenInput').value.length == 6) || (Q('tokenInput').value.length == 8) || (Q('tokenInput').value.length == 44));
}
//
diff --git a/webserver.js b/webserver.js
index 7687abe5..f8addf87 100644
--- a/webserver.js
+++ b/webserver.js
@@ -342,43 +342,76 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
}
// Check the 2-step auth token
- function checkUserOneTimePassword(domain, user, token, hwtoken1, hwtoken2) {
+ function checkUserOneTimePassword(domain, user, token, hwtoken1, hwtoken2, func) {
const twoStepLoginSupported = ((domain.auth != 'sspi') && (obj.parent.certificates.CommonName != 'un-configured') && (obj.args.lanonly !== true) && (obj.args.nousers !== true));
- if (twoStepLoginSupported == false) return true;
+ if (twoStepLoginSupported == false) { func(true); return; };
- // Check hardware key
+ // Check U2F hardware key
if (user.otphkeys && (user.otphkeys.length > 0) && (typeof (hwtoken1) == 'string') && (typeof (hwtoken2) == 'string')) {
- // Check hardware token
- var authRequest = null, authResponse = null;
- try { authRequest = JSON.parse(hwtoken1); } catch (ex) { }
- try { authResponse = JSON.parse(hwtoken2); } catch (ex) { }
- if ((authRequest != null) && (authResponse != null)) {
- const u2f = require('u2f');
- const result = u2f.checkSignature(authRequest[0], authResponse, user.otphkeys[0].publicKey);
- if (result.successful === true) return true;
+ var u2fpublicKey = null;
+
+ // Find a U2F key
+ for (var i = 0; i < user.otphkeys.length; i++) { if (user.otphkeys[i].type == 1) { u2fpublicKey = user.otphkeys[i].publicKey; } }
+
+ if (u2fpublicKey != null) {
+ // Check hardware token
+ var authRequest = null, authResponse = null;
+ try { authRequest = JSON.parse(hwtoken1); } catch (ex) { }
+ try { authResponse = JSON.parse(hwtoken2); } catch (ex) { }
+ if ((authRequest != null) && (authResponse != null)) {
+ const u2f = require('u2f');
+ const result = u2f.checkSignature(authRequest[0], authResponse, u2fpublicKey);
+ if (result.successful === true) { func(true); return; };
+ }
}
}
// Check Google Authenticator
const otplib = require('otplib')
- if (user.otpsecret && (typeof (token) == 'string') && (otplib.authenticator.check(token, user.otpsecret) == true)) return true;
+ if (user.otpsecret && (typeof (token) == 'string') && (token.length == 6) && (otplib.authenticator.check(token, user.otpsecret) == true)) { func(true); return; };
// Check written down keys
- if ((user.otpkeys != null) && (user.otpkeys.keys != null)) {
+ if ((user.otpkeys != null) && (user.otpkeys.keys != null) && (typeof (token) == 'string') && (token.length == 8)) {
var tokenNumber = parseInt(token);
- for (var i = 0; i < user.otpkeys.keys.length; i++) { if ((tokenNumber === user.otpkeys.keys[i].p) && (user.otpkeys.keys[i].u === true)) { user.otpkeys.keys[i].u = false; return true; } }
+ for (var i = 0; i < user.otpkeys.keys.length; i++) { if ((tokenNumber === user.otpkeys.keys[i].p) && (user.otpkeys.keys[i].u === true)) { user.otpkeys.keys[i].u = false; func(true); return; } }
}
- return false;
+ // Check OTP hardware key
+ if (domain.yubikey.id && domain.yubikey.secret && user.otphkeys && (user.otphkeys.length > 0) && (typeof (token) == 'string') && (token.length == 44)) {
+ var keyId = token.substring(0, 12);
+
+ // Find a matching OPT key
+ var match = false;
+ for (var i = 0; i < user.otphkeys.length; i++) { if ((user.otphkeys[i].type === 2) && (user.otphkeys[i].keyid === keyId)) { match = true; } }
+
+ // If we have a match, check the OTP
+ if (match === true) {
+ var yubikeyotp = require('yubikeyotp');
+ var request = { otp: token, id: domain.yubikey.id, key: domain.yubikey.secret, timestamp: true }
+ if (domain.yubikey.proxy) { request.requestParams = { proxy: domain.yubikey.proxy }; }
+ yubikeyotp.verifyOTP(request, function (err, results) { func(results.status == 'OK'); });
+ return;
+ }
+ }
+
+ func(false);
}
- // Return a hardware key challenge
+ // Return a U2F hardware key challenge
+ // TODO: Figure out how to support many U2F keys at the same time.
function getHardwareKeyChallenge(domain, user) {
if (user.otphkeys && (user.otphkeys.length > 0)) {
- var requests = [];
- const u2f = require('u2f');
- for (var i in user.otphkeys) { requests.push(u2f.request('https://' + obj.parent.certificates.CommonName, user.otphkeys[i].keyHandle)); }
- return JSON.stringify(requests);
+ // Find a U2F key
+ var u2fKeyHandle = null;
+ for (var i = 0; i < user.otphkeys.length; i++) { if (user.otphkeys[i].type == 1) { u2fKeyHandle = user.otphkeys[i].keyHandle; } }
+
+ // Generate a U2F challenge
+ if (u2fKeyHandle != null) {
+ var requests = [];
+ const u2f = require('u2f');
+ for (var i in user.otphkeys) { requests.push(u2f.request('https://' + obj.parent.certificates.CommonName, u2fKeyHandle)); }
+ return JSON.stringify(requests);
+ }
}
return '';
}
@@ -398,89 +431,24 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
// Check if this user has 2-step login active
if (checkUserOneTimePasswordRequired(domain, user)) {
- if (checkUserOneTimePassword(domain, user, req.body.token, req.body.hwtoken1, req.body.hwtoken2) == false) {
- // 2-step auth is required, but the token is not present or not valid.
- if (user.otpsecret != null) { req.session.error = 'Invalid token, try again. '; }
- req.session.loginmode = '4';
- req.session.tokenusername = xusername;
- req.session.tokenpassword = xpassword;
- res.redirect(domain.url);
- return;
- }
- }
-
- /*
- // Check if this user has 2-step login active
- var tokenValid = 0;
- const twoStepLoginSupported = ((domain.auth != 'sspi') && (obj.parent.certificates.CommonName != 'un-configured') && (obj.args.lanonly !== true) && (obj.args.nousers !== true));
- const otplib = require('otplib')
- otplib.authenticator.options = { window: 6 }; // Set +/- 3 minute window
- if (twoStepLoginSupported && user.otpsecret && ((typeof (req.body.token) != 'string') || ((tokenValid = otplib.authenticator.check(req.body.token, user.otpsecret)) !== true))) {
- // Failed OTP, check user's one time passwords
- console.log(user);
- if ((req.body.token != null) && ((user.otpkeys != null) && (user.otpkeys.keys != null)) || (user.otphkeys && user.otphkeys.length > 0)) {
- var found = null;
- var tokenNumber = parseInt(req.body.token);
- for (var i = 0; i < user.otpkeys.keys.length; i++) { if ((tokenNumber === user.otpkeys.keys[i].p) && (user.otpkeys.keys[i].u === true)) { user.otpkeys.keys[i].u = false; found = i; } }
- if (found == null) {
+ checkUserOneTimePassword(domain, user, req.body.token, req.body.hwtoken1, req.body.hwtoken2, function (result) {
+ if (result == false) {
// 2-step auth is required, but the token is not present or not valid.
if (user.otpsecret != null) { req.session.error = 'Invalid token, try again. '; }
req.session.loginmode = '4';
req.session.tokenusername = xusername;
req.session.tokenpassword = xpassword;
res.redirect(domain.url);
- return;
+ } else {
+ // Login succesful
+ completeLoginRequest(req, res, domain, user, userid);
}
- } else {
- // 2-step auth is required, but the token is not present or not valid.
- if (user.otpsecret != null) { req.session.error = 'Invalid token, try again. '; }
- req.session.loginmode = '4';
- req.session.tokenusername = xusername;
- req.session.tokenpassword = xpassword;
- res.redirect(domain.url);
- return;
- }
- }
- */
-
- // Save login time
- user.login = Math.floor(Date.now() / 1000);
- obj.db.SetUser(user);
-
- // Regenerate session when signing in to prevent fixation
- //req.session.regenerate(function () {
- // Store the user's primary key in the session store to be retrieved, or in this case the entire user object
- // req.session.success = 'Authenticated as ' + user.name + 'click to logout . You may now access /restricted .';
- delete req.session.loginmode;
- delete req.session.tokenusername;
- delete req.session.tokenpassword;
- req.session.userid = userid;
- req.session.domainid = domain.id;
- req.session.currentNode = '';
- if (req.session.passhint) { delete req.session.passhint; }
- if (req.body.viewmode) { req.session.viewmode = req.body.viewmode; }
- if (req.body.host) {
- // TODO: This is a terrible search!!! FIX THIS.
- /*
- obj.db.GetAllType('node', function (err, docs) {
- for (var i = 0; i < docs.length; i++) {
- if (docs[i].name == req.body.host) {
- req.session.currentNode = docs[i]._id;
- break;
- }
- }
- console.log("CurrentNode: " + req.session.currentNode);
- // This redirect happens after finding node is completed
- res.redirect(domain.url);
});
- */
- res.redirect(domain.url); // Temporary
- } else {
- res.redirect(domain.url);
+ return;
}
- //});
- obj.parent.DispatchEvent(['*'], obj, { etype: 'user', username: user.name, action: 'login', msg: 'Account login', domain: domain.id });
+ // Login succesful
+ completeLoginRequest(req, res, domain, user, userid);
} else {
delete req.session.loginmode;
if (err == 'locked') { req.session.error = 'Account locked. '; } else { req.session.error = 'Login failed, check username and password. '; }
@@ -494,6 +462,47 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
});
}
+ function completeLoginRequest(req, res, domain, user, userid) {
+ // Save login time
+ user.login = Math.floor(Date.now() / 1000);
+ obj.db.SetUser(user);
+
+ // Regenerate session when signing in to prevent fixation
+ //req.session.regenerate(function () {
+ // Store the user's primary key in the session store to be retrieved, or in this case the entire user object
+ // req.session.success = 'Authenticated as ' + user.name + 'click to logout . You may now access /restricted .';
+ delete req.session.loginmode;
+ delete req.session.tokenusername;
+ delete req.session.tokenpassword;
+ req.session.userid = userid;
+ req.session.domainid = domain.id;
+ req.session.currentNode = '';
+ if (req.session.passhint) { delete req.session.passhint; }
+ if (req.body.viewmode) { req.session.viewmode = req.body.viewmode; }
+ if (req.body.host) {
+ // TODO: This is a terrible search!!! FIX THIS.
+ /*
+ obj.db.GetAllType('node', function (err, docs) {
+ for (var i = 0; i < docs.length; i++) {
+ if (docs[i].name == req.body.host) {
+ req.session.currentNode = docs[i]._id;
+ break;
+ }
+ }
+ console.log("CurrentNode: " + req.session.currentNode);
+ // This redirect happens after finding node is completed
+ res.redirect(domain.url);
+ });
+ */
+ res.redirect(domain.url); // Temporary
+ } else {
+ res.redirect(domain.url);
+ }
+ //});
+
+ obj.parent.DispatchEvent(['*'], obj, { etype: 'user', username: user.name, action: 'login', msg: 'Account login', domain: domain.id });
+ }
+
function handleCreateAccountRequest(req, res) {
const domain = checkUserIpAddress(req, res);
if ((domain == null) || (domain.auth == 'sspi')) return;