Added 2FA to user login reports
Ylian Saint-Hilaire committed
Mar 4, 2022 at 15:56 UTC
ecc27f5f20da03c1afc90f6872ea85970bdf6955
3 files changed
+84
-35
meshuser.js
+5
-5
@@ -5931,7 +5931,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
5931
break;
5932
}
5933
case 3: {
5934
- userLoginReport(command, msgIdFilter);
5934
+ userLoginReport(command);
5935
break;
5936
}
5937
}
@@ -6988,9 +6988,9 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
6988
var data = { groups: {} };
6989
if (command.groupBy == 1) {
6990
data.groupFormat = 'user';
6991
- data.columns = [{ id: 'time', title: "time", format: 'datetime' }, { id: 'ip', title: "ip" }, { id: 'browser', title: "browser" }, { id: 'os', title: "os" }];
6991
+ data.columns = [{ id: 'time', title: "time", format: 'datetime' }, { id: 'ip', title: "ip" }, { id: 'browser', title: "browser" }, { id: 'os', title: "os" }, { id: 'twofactor', title: "twofactor", format: '2fa' }];
6992
} else if (command.groupBy == 3) {
6993
- data.columns = [{ id: 'time', title: "time", format: 'time' }, { id: 'userid', title: "user", format: 'user' }, { id: 'ip', title: "ip" }, { id: 'browser', title: "browser" }, { id: 'os', title: "os" }];
6993
+ data.columns = [{ id: 'time', title: "time", format: 'time' }, { id: 'userid', title: "user", format: 'user' }, { id: 'ip', title: "ip" }, { id: 'browser', title: "browser" }, { id: 'os', title: "os" }, { id: 'twofactor', title: "twofactor", format: '2fa' }];
6994
}
6995
if (showInvalidLoginAttempts) { data.columns.push({ id: 'msg', title: "msg", format: 'msg' }); }
6996
@@ -7002,7 +7002,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
7002
7003
if (command.groupBy == 1) { // Add entry per user
7004
if (data.groups[docs[i].userid] == null) { data.groups[docs[i].userid] = { entries: [] }; }
7005
- const entry = { time: docs[i].time.valueOf(), ip: docs[i].msgArgs[0], browser: docs[i].msgArgs[1], os: docs[i].msgArgs[2] };
7005
+ const entry = { time: docs[i].time.valueOf(), ip: docs[i].msgArgs[0], browser: docs[i].msgArgs[1], os: docs[i].msgArgs[2], twofactor: docs[i].twoFactorType ? docs[i].twoFactorType : '' };
7006
if (showInvalidLoginAttempts) { entry.msg = docs[i].msgid }
7007
data.groups[docs[i].userid].entries.push(entry);
7008
} else if (command.groupBy == 3) { // Add entry per day
@@ -7013,7 +7013,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
7013
day = docs[i].time; // TODO
7014
}
7015
if (data.groups[day] == null) { data.groups[day] = { entries: [] }; }
7016
- const entry = { time: docs[i].time.valueOf(), userid: docs[i].userid, ip: docs[i].msgArgs[0], browser: docs[i].msgArgs[1], os: docs[i].msgArgs[2] };
7016
+ const entry = { time: docs[i].time.valueOf(), userid: docs[i].userid, ip: docs[i].msgArgs[0], browser: docs[i].msgArgs[1], os: docs[i].msgArgs[2], twofactor: docs[i].twoFactorType ? docs[i].twoFactorType : '' };
7017
if (showInvalidLoginAttempts) { entry.msg = docs[i].msgid }
7018
data.groups[day].entries.push(entry);
7019
}
views/default.handlebars
+13
-1
@@ -15701,7 +15701,7 @@
15701
}
15702
15703
function renderReport(r) {
15704
- var colTranslation = { time: "Time", device: "Device", session: "Session", user: "User", devgroup: "Device Group", guest: "Guest", length: "Length", bytesin: "Bytes In", bytesout: "Bytes Out", os: "Operating System", ip: "IP Address", browser: "Browser", msg: "Message" }
15704
+ var colTranslation = { time: "Time", device: "Device", session: "Session", user: "User", devgroup: "Device Group", guest: "Guest", length: "Length", bytesin: "Bytes In", bytesout: "Bytes Out", os: "Operating System", ip: "IP Address", browser: "Browser", msg: "Message", twofactor: "2nd Factor" }
15705
var x = '<table style=width:100%>', firstItem;
15706
var sumByCol = null; // Indicate by what colum we sum by
15707
var sumByValues = []; // Indicate by what values we sum by
@@ -15861,6 +15861,18 @@
15861
if (v == 109) return '<div style=float:left;margin-right:4px;cursor:pointer class="NotifyIconTiny4"></div>' + "Locked account";
15862
if (v == 110) return '<div style=float:left;margin-right:4px;cursor:pointer class="NotifyIconTiny3"></div>' + "Invalid login attempt";
15863
}
15864
+ if (f == '2fa') {
15865
+ if (v == '') { return "None"; }
15866
+ if (v == 'backup') { return "Backup Codes"; }
15867
+ if (v == 'fido') { return "FIDO key"; }
15868
+ if (v == 'sms') { return "SMS message"; }
15869
+ if (v == 'hwotp') { return "Hardware OTP"; }
15870
+ if (v == 'push') { return "Push Notification"; }
15871
+ if (v == 'otp') { return "One-Time Password"; }
15872
+ if (v == 'cookie') { return "Remember Device"; }
15873
+ if (v == 'tokenlogin') { return "Login Token"; }
15874
+ if (v == 'ipaddr') { return "IP Address"; }
15875
+ }
15876
return EscapeHtml(v);
15877
}
15878
webserver.js
+66
-29
@@ -792,6 +792,32 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF
792
if (req.query.key != null) { res.redirect(domain.url + '?key=' + req.query.key); } else { res.redirect(domain.url); }
793
}
794
795
+ // Return an object with 2FA type if 2-step auth can be skipped
796
+ function checkUserOneTimePasswordSkip(domain, user, req, loginOptions) {
797
+ if (parent.config.settings.no2factorauth == true) return null;
798
+
799
+ // If this login occured using a login token, no 2FA needed.
800
+ if ((loginOptions != null) && (typeof loginOptions.tokenName === 'string')) { return { twoFactorType: 'tokenlogin' }; }
801
+
802
+ // Check if we can skip 2nd factor auth because of the source IP address
803
+ if ((req != null) && (req.clientIp != null) && (domain.passwordrequirements != null) && (domain.passwordrequirements.skip2factor != null)) {
804
+ for (var i in domain.passwordrequirements.skip2factor) { if (require('ipcheck').match(req.clientIp, domain.passwordrequirements.skip2factor[i]) === true) { return { twoFactorType: 'ipaddr' }; } }
805
+ }
806
+
807
+ // Check if a 2nd factor cookie is present
808
+ if (typeof req.headers.cookie == 'string') {
809
+ const cookies = req.headers.cookie.split('; ');
810
+ for (var i in cookies) {
811
+ if (cookies[i].startsWith('twofactor=')) {
812
+ var twoFactorCookie = obj.parent.decodeCookie(decodeURIComponent(cookies[i].substring(10)), obj.parent.loginCookieEncryptionKey, (30 * 24 * 60)); // If the cookies does not have an expire feild, assume 30 day timeout.
813
+ if ((twoFactorCookie != null) && ((obj.args.cookieipcheck === false) || (twoFactorCookie.ip == null) || (twoFactorCookie.ip === req.clientIp)) && (twoFactorCookie.userid == user._id)) { return { twoFactorType: 'cookie' }; }
814
+ }
815
+ }
816
+ }
817
+
818
+ return null;
819
+ }
820
+
821
// Return true if this user has 2-step auth active
822
function checkUserOneTimePasswordRequired(domain, user, req, loginOptions) {
823
// If this login occured using a login token, no 2FA needed.
@@ -835,7 +861,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF
861
// Check 2FA login cookie
862
if ((token != null) && (token.startsWith('cookie='))) {
863
var twoFactorCookie = obj.parent.decodeCookie(decodeURIComponent(token.substring(7)), obj.parent.loginCookieEncryptionKey, (30 * 24 * 60)); // If the cookies does not have an expire feild, assume 30 day timeout.
838
- if ((twoFactorCookie != null) && ((obj.args.cookieipcheck === false) || (twoFactorCookie.ip == null) || (twoFactorCookie.ip === req.clientIp)) && (twoFactorCookie.userid == user._id)) { func(true); return; }
864
+ if ((twoFactorCookie != null) && ((obj.args.cookieipcheck === false) || (twoFactorCookie.ip == null) || (twoFactorCookie.ip === req.clientIp)) && (twoFactorCookie.userid == user._id)) { func(true, { twoFactorType: 'cookie' }); return; }
865
}
866
867
// Check email key
@@ -845,7 +871,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF
871
user.otpekey = {};
872
obj.db.SetUser(user);
873
parent.debug('web', 'checkUserOneTimePassword: success (email).');
848
- func(true);
874
+ func(true, { twoFactorType: 'email' });
875
return;
876
}
877
}
@@ -857,7 +883,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF
883
delete user.otpsms;
884
obj.db.SetUser(user);
885
parent.debug('web', 'checkUserOneTimePassword: success (SMS).');
860
- func(true);
886
+ func(true, { twoFactorType: 'sms' });
887
return;
888
}
889
}
@@ -908,7 +934,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF
934
webAuthnKey.counter = webauthnResponse.counter;
935
obj.db.SetUser(user);
936
parent.debug('web', 'checkUserOneTimePassword: success (hardware).');
911
- func(true);
937
+ func(true, { twoFactorType: 'fido' });
938
} else {
939
parent.debug('web', 'checkUserOneTimePassword: fail (hardware).');
940
func(false);
@@ -924,7 +950,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF
950
otplib.authenticator.options = { window: 2 }; // Set +/- 1 minute window
951
if (user.otpsecret && (typeof (token) == 'string') && (token.length == 6) && (otplib.authenticator.check(token, user.otpsecret) == true)) {
952
parent.debug('web', 'checkUserOneTimePassword: success (authenticator).');
927
- func(true);
953
+ func(true, { twoFactorType: 'otp' });
954
return;
955
};
956
@@ -934,12 +960,12 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF
960
for (var i = 0; i < user.otpkeys.keys.length; i++) {
961
if ((tokenNumber === user.otpkeys.keys[i].p) && (user.otpkeys.keys[i].u === true)) {
962
parent.debug('web', 'checkUserOneTimePassword: success (one-time).');
937
- user.otpkeys.keys[i].u = false; func(true); return;
963
+ user.otpkeys.keys[i].u = false; func(true, { twoFactorType: 'backup' }); return;
964
}
965
}
966
}
967
942
- // Check OTP hardware key
968
+ // Check OTP hardware key (Yubikey OTP)
969
if ((domain.yubikey != null) && (domain.yubikey.id != null) && (domain.yubikey.secret != null) && (user.otphkeys != null) && (user.otphkeys.length > 0) && (typeof (token) == 'string') && (token.length == 44)) {
970
var keyId = token.substring(0, 12);
971
@@ -955,7 +981,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF
981
yubikeyotp.verifyOTP(request, function (err, results) {
982
if ((results != null) && (results.status == 'OK')) {
983
parent.debug('web', 'checkUserOneTimePassword: success (Yubikey).');
958
- func(true);
984
+ func(true, { twoFactorType: 'hwotp' });
985
} else {
986
parent.debug('web', 'checkUserOneTimePassword: fail (Yubikey).');
987
func(false);
@@ -1033,8 +1059,11 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF
1059
var sms2fa = (((typeof domain.passwordrequirements != 'object') || (domain.passwordrequirements.sms2factor != false)) && (parent.smsserver != null) && (user.phone != null));
1060
var push2fa = ((parent.firebase != null) && (user.otpdev != null));
1061
1062
+ // Check if two factor can be skipped
1063
+ const twoFactorSkip = checkUserOneTimePasswordSkip(domain, user, req, loginOptions);
1064
+
1065
// Check if this user has 2-step login active
1037
- if ((req.session.loginmode != 6) && checkUserOneTimePasswordRequired(domain, user, req, loginOptions)) {
1066
+ if ((twoFactorSkip == null) && (req.session.loginmode != 6) && checkUserOneTimePasswordRequired(domain, user, req, loginOptions)) {
1067
if ((req.body.hwtoken == '**timeout**')) {
1068
delete req.session; // Clear the session
1069
res.redirect(domain.url + getQueryPortion(req));
@@ -1096,7 +1125,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF
1125
return;
1126
}
1127
1099
- checkUserOneTimePassword(req, domain, user, req.body.token, req.body.hwtoken, function (result) {
1128
+ checkUserOneTimePassword(req, domain, user, req.body.token, req.body.hwtoken, function (result, authData) {
1129
if (result == false) {
1130
var randomWaitTime = 0;
1131
@@ -1158,6 +1187,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF
1187
// Login successful
1188
if (obj.parent.authlog) { obj.parent.authLog('https', 'Accepted password for ' + xusername + ' from ' + req.clientIp + ' port ' + req.connection.remotePort); }
1189
parent.debug('web', 'handleLoginRequest: successful 2FA login');
1190
+ if (authData != null) { if (loginOptions == null) { loginOptions = {}; } loginOptions.twoFactorType = authData.twoFactorType; }
1191
completeLoginRequest(req, res, domain, user, userid, xusername, xpassword, direct, loginOptions);
1192
}
1193
});
@@ -1179,6 +1209,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF
1209
// Login successful
1210
if (obj.parent.authlog) { obj.parent.authLog('https', 'Accepted password for ' + xusername + ' from ' + req.clientIp + ' port ' + req.connection.remotePort); }
1211
parent.debug('web', 'handleLoginRequest: successful login');
1212
+ if (twoFactorSkip != null) { if (loginOptions == null) { loginOptions = {}; } loginOptions.twoFactorType = twoFactorSkip.twoFactorType; }
1213
completeLoginRequest(req, res, domain, user, userid, xusername, xpassword, direct, loginOptions);
1214
} else {
1215
// Login failed, log the error
@@ -1242,7 +1273,10 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF
1273
if (user.groups) { for (var i in user.groups) { targets.push('server-users:' + i); } }
1274
const ua = getUserAgentInfo(req);
1275
const loginEvent = { etype: 'user', userid: user._id, username: user.name, account: obj.CloneSafeUser(user), action: 'login', msgid: 107, msgArgs: [req.clientIp, ua.browserStr, ua.osStr], msg: 'Account login', domain: domain.id, ip: req.clientIp, userAgent: req.headers['user-agent'] };
1245
- if ((loginOptions != null) && (loginOptions.tokenName != null) && (loginOptions.tokenUser != null)) { loginEvent.tokenName = loginOptions.tokenName; loginEvent.tokenUser = loginOptions.tokenUser; } // If a login token was used, add it to the event.
1276
+ if (loginOptions != null) {
1277
+ if ((loginOptions.tokenName != null) && (loginOptions.tokenUser != null)) { loginEvent.tokenName = loginOptions.tokenName; loginEvent.tokenUser = loginOptions.tokenUser; } // If a login token was used, add it to the event.
1278
+ if (loginOptions.twoFactorType != null) { loginEvent.twoFactorType = loginOptions.twoFactorType; }
1279
+ }
1280
obj.parent.DispatchEvent(targets, obj, loginEvent);
1281
1282
// Regenerate session when signing in to prevent fixation
@@ -1614,7 +1648,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF
1648
var user = docs[i];
1649
if (checkUserOneTimePasswordRequired(domain, user, req) == true) {
1650
// Second factor setup, request it now.
1617
- checkUserOneTimePassword(req, domain, user, req.body.token, req.body.hwtoken, function (result) {
1651
+ checkUserOneTimePassword(req, domain, user, req.body.token, req.body.hwtoken, function (result, authData) {
1652
if (result == false) {
1653
if (i == 0) {
1654
@@ -5879,20 +5913,20 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF
5913
obj.app.get(url + 'webrelay.ashx', function (req, res) { res.send('Websocket connection expected'); });
5914
obj.app.get(url + 'health.ashx', function (req, res) { res.send('ok'); }); // TODO: Perform more server checking.
5915
obj.app.ws(url + 'webrelay.ashx', function (ws, req) { PerformWSSessionAuth(ws, req, false, handleRelayWebSocket); });
5882
- obj.app.ws(url + 'webider.ashx', function (ws, req) { PerformWSSessionAuth(ws, req, false, function (ws1, req1, domain, user, cookie) { obj.meshIderHandler.CreateAmtIderSession(obj, obj.db, ws1, req1, obj.args, domain, user); }); });
5916
+ obj.app.ws(url + 'webider.ashx', function (ws, req) { PerformWSSessionAuth(ws, req, false, function (ws1, req1, domain, user, cookie, authData) { obj.meshIderHandler.CreateAmtIderSession(obj, obj.db, ws1, req1, obj.args, domain, user); }); });
5917
obj.app.ws(url + 'control.ashx', function (ws, req) {
5918
getWebsocketArgs(ws, req, function (ws, req) {
5919
const domain = getDomain(req);
5920
if ((domain.loginkey != null) && (domain.loginkey.indexOf(req.query.key) == -1)) { ws.close(); return; } // Check 3FA URL key
5887
- PerformWSSessionAuth(ws, req, true, function (ws1, req1, domain, user, cookie) {
5921
+ PerformWSSessionAuth(ws, req, true, function (ws1, req1, domain, user, cookie, authData) {
5922
if (user == null) { // User is not authenticated, perform inner server authentication
5923
if (req.headers['x-meshauth'] === '*') {
5890
- PerformWSSessionInnerAuth(ws, req, domain, function (ws1, req1, domain, user) { obj.meshUserHandler.CreateMeshUser(obj, obj.db, ws1, req1, obj.args, domain, user); }); // User is authenticated
5924
+ PerformWSSessionInnerAuth(ws, req, domain, function (ws1, req1, domain, user) { obj.meshUserHandler.CreateMeshUser(obj, obj.db, ws1, req1, obj.args, domain, user, authData); }); // User is authenticated
5925
} else {
5926
try { ws.close(); } catch (ex) { } // user is not authenticated and inner authentication was not requested, disconnect now.
5927
}
5928
} else {
5895
- obj.meshUserHandler.CreateMeshUser(obj, obj.db, ws1, req1, obj.args, domain, user); // User is authenticated
5929
+ obj.meshUserHandler.CreateMeshUser(obj, obj.db, ws1, req1, obj.args, domain, user, authData); // User is authenticated
5930
}
5931
});
5932
});
@@ -5912,7 +5946,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF
5946
obj.app.get(url + 'sharing', handleSharingRequest);
5947
obj.app.ws(url + 'agenttransfer.ashx', handleAgentFileTransfer); // Setup agent to/from server file transfer handler
5948
obj.app.ws(url + 'meshrelay.ashx', function (ws, req) {
5915
- PerformWSSessionAuth(ws, req, true, function (ws1, req1, domain, user, cookie) {
5949
+ PerformWSSessionAuth(ws, req, true, function (ws1, req1, domain, user, cookie, authData) {
5950
if (((parent.config.settings.desktopmultiplex === true) || (domain.desktopmultiplex === true)) && (req.query.p == 2)) {
5951
obj.meshDesktopMultiplexHandler.CreateMeshRelay(obj, ws1, req1, domain, user, cookie); // Desktop multiplexor 1-to-n
5952
} else {
@@ -5922,7 +5956,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF
5956
});
5957
if (obj.args.wanonly != true) { // If the server is not in WAN mode, allow server relayed connections.
5958
obj.app.ws(url + 'localrelay.ashx', function (ws, req) {
5925
- PerformWSSessionAuth(ws, req, true, function (ws1, req1, domain, user, cookie) {
5959
+ PerformWSSessionAuth(ws, req, true, function (ws1, req1, domain, user, cookie, authData) {
5960
if ((user == null) || (cookie == null)) {
5961
try { ws1.close(); } catch (ex) { }
5962
} else {
@@ -5976,12 +6010,12 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF
6010
} catch (ex) { console.log(ex); }
6011
});
6012
obj.app.ws(url + 'sshterminalrelay.ashx', function (ws, req) {
5979
- PerformWSSessionAuth(ws, req, true, function (ws1, req1, domain, user, cookie) {
6013
+ PerformWSSessionAuth(ws, req, true, function (ws1, req1, domain, user, cookie, authData) {
6014
require('./apprelays.js').CreateSshTerminalRelay(obj, obj.db, ws1, req1, domain, user, cookie, obj.args);
6015
});
6016
});
6017
obj.app.ws(url + 'sshfilesrelay.ashx', function (ws, req) {
5984
- PerformWSSessionAuth(ws, req, true, function (ws1, req1, domain, user, cookie) {
6018
+ PerformWSSessionAuth(ws, req, true, function (ws1, req1, domain, user, cookie, authData) {
6019
require('./apprelays.js').CreateSshFilesRelay(obj, obj.db, ws1, req1, domain, user, cookie, obj.args);
6020
});
6021
});
@@ -6364,7 +6398,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF
6398
6399
// Setup mesh relay on alternative agent-only port
6400
obj.agentapp.ws(url + 'meshrelay.ashx', function (ws, req) {
6367
- PerformWSSessionAuth(ws, req, true, function (ws1, req1, domain, user, cookie) {
6401
+ PerformWSSessionAuth(ws, req, true, function (ws1, req1, domain, user, cookie, authData) {
6402
if (((parent.config.settings.desktopmultiplex === true) || (domain.desktopmultiplex === true)) && (req.query.p == 2)) {
6403
obj.meshDesktopMultiplexHandler.CreateMeshRelay(obj, ws1, req1, domain, user, cookie); // Desktop multiplexor 1-to-n
6404
} else {
@@ -6478,7 +6512,10 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF
6512
var twoFactorCookieDays = 30;
6513
if (typeof domain.twofactorcookiedurationdays == 'number') { twoFactorCookieDays = domain.twofactorcookiedurationdays; }
6514
6481
- if (checkUserOneTimePasswordRequired(domain, user, req, loginOptions) == true) {
6515
+ // Check if two factor can be skipped
6516
+ const twoFactorSkip = checkUserOneTimePasswordSkip(domain, user, req, loginOptions);
6517
+
6518
+ if ((twoFactorSkip == null) && (checkUserOneTimePasswordRequired(domain, user, req, loginOptions) == true)) {
6519
// Figure out if email 2FA is allowed
6520
var email2fa = (((typeof domain.passwordrequirements != 'object') || (domain.passwordrequirements.email2factor != false)) && (domain.mailserver != null) && (user.otpekey != null));
6521
var sms2fa = (((typeof domain.passwordrequirements != 'object') || (domain.passwordrequirements.sms2factor != false)) && (parent.smsserver != null) && (user.phone != null));
@@ -6517,7 +6554,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF
6554
try { ws.send(JSON.stringify({ action: 'close', cause: 'noauth', msg: 'tokenrequired', email2fa: email2fa, sms2fa: sms2fa, twoFactorCookieDays: twoFactorCookieDays })); ws.close(); } catch (ex) { console.log(ex); }
6555
}
6556
} else {
6520
- checkUserOneTimePassword(req, domain, user, command.token, null, function (result) {
6557
+ checkUserOneTimePassword(req, domain, user, command.token, null, function (result, authData) {
6558
if (result == false) {
6559
// Failed, ask for a login token again
6560
parent.debug('web', 'Invalid login token, asking again');
@@ -6532,7 +6569,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF
6569
// We are authenticated
6570
ws._socket.pause();
6571
ws.removeAllListeners(['message', 'close', 'error']);
6535
- func(ws, req, domain, user);
6572
+ func(ws, req, domain, user, authData);
6573
}
6574
}
6575
});
@@ -6548,7 +6585,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF
6585
// We are authenticated
6586
ws._socket.pause();
6587
ws.removeAllListeners(['message', 'close', 'error']);
6551
- func(ws, req, domain, user);
6588
+ func(ws, req, domain, user, twoFactorSkip);
6589
}
6590
}
6591
}
@@ -6664,7 +6701,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF
6701
try { ws.send(JSON.stringify({ action: 'close', cause: 'noauth', msg: 'tokenrequired', email2fa: email2fa, sms2fa: sms2fa, twoFactorCookieDays: twoFactorCookieDays })); ws.close(); } catch (e) { }
6702
}
6703
} else {
6667
- checkUserOneTimePassword(req, domain, user, req.query.token, null, function (result) {
6704
+ checkUserOneTimePassword(req, domain, user, req.query.token, null, function (result, authData) {
6705
if (result == false) {
6706
// Failed, ask for a login token again
6707
parent.debug('web', 'Invalid login token, asking again');
@@ -6676,7 +6713,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF
6713
parent.debug('web', 'Invalid login, asking for email validation');
6714
try { ws.send(JSON.stringify({ action: 'close', cause: 'emailvalidation', msg: 'emailvalidationrequired', email2fa: email2fa, sms2fa: sms2fa, email2fasent: true })); ws.close(); } catch (e) { }
6715
} else {
6679
- func(ws, req, domain, user);
6716
+ func(ws, req, domain, user, null, authData);
6717
}
6718
}
6719
});
@@ -6761,7 +6798,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF
6798
if (s.length != 3) {
6799
try { ws.send(JSON.stringify({ action: 'close', cause: 'noauth', msg: 'tokenrequired', email2fa: email2fa, sms2fa: sms2fa, twoFactorCookieDays: twoFactorCookieDays })); ws.close(); } catch (e) { }
6800
} else {
6764
- checkUserOneTimePassword(req, domain, user, s[2], null, function (result) {
6801
+ checkUserOneTimePassword(req, domain, user, s[2], null, function (result, authData) {
6802
if (result == false) {
6803
if ((s[2] == '**email**') && (email2fa == true)) {
6804
// Cause a token to be sent to the user's registered email
@@ -6790,7 +6827,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF
6827
parent.debug('web', 'Invalid login, asking for email validation');
6828
try { ws.send(JSON.stringify({ action: 'close', cause: 'emailvalidation', msg: 'emailvalidationrequired', email2fa: email2fa, email2fasent: true, twoFactorCookieDays: twoFactorCookieDays })); ws.close(); } catch (e) { }
6829
} else {
6793
- func(ws, req, domain, user);
6830
+ func(ws, req, domain, user, null, authData);
6831
}
6832
}
6833
});