WIP on OTP 2FA, stats, etc.

This commit is contained in:
Bryan Ashby 2019-05-07 21:36:33 -06:00
parent e960e2800d
commit e5398db07b
No known key found for this signature in database
GPG Key ID: B49EB437951D2542
2 changed files with 59 additions and 45 deletions

View File

@ -51,4 +51,5 @@ exports.ErrorReasons = {
Inactive : 'INACTIVE',
Locked : 'LOCKED',
NotAllowed : 'NOTALLOWED',
Invalid2FA : 'INVALID2FA',
};

View File

@ -22,6 +22,8 @@ const async = require('async');
const _ = require('lodash');
exports.userLogin = userLogin;
exports.recordLogin = recordLogin;
exports.transformLoginError = transformLoginError;
function userLogin(client, username, password, options, cb) {
if(!cb && _.isFunction(options)) {
@ -50,20 +52,13 @@ function userLogin(client, username, password, options, cb) {
client.user.authenticateFactor1(authInfo, err => {
if(err) {
client.user.sessionFailedLoginAttempts = _.get(client.user, 'sessionFailedLoginAttempts', 0) + 1;
const disconnect = config.users.failedLogin.disconnect;
if(disconnect > 0 && client.user.sessionFailedLoginAttempts >= disconnect) {
err = Errors.BadLogin('To many failed login attempts', ErrorReasons.TooMany);
}
client.log.info( { username, ip : client.remoteAddress, reason : err.message }, 'Failed login attempt');
return cb(err);
return cb(transformLoginError(err, client, username));
}
const user = client.user;
// Good login; reset any failed attempts
delete user.sessionFailedLoginAttempts;
delete client.sessionFailedLoginAttempts;
//
// Ensure this user is not already logged in.
@ -104,23 +99,31 @@ function userLogin(client, username, password, options, cb) {
Events.emit(Events.getSystemEvents().UserLogin, { user } );
setClientTheme(client, user.properties[UserProps.ThemeId]);
if(user.authenticated) {
return recordLogin(client, cb);
}
// recordLogin() must happen after 2FA!
return cb(null);
});
}
function recordLogin(client, cb) {
const user = client.user;
async.parallel(
[
function setTheme(callback) {
setClientTheme(client, user.properties[UserProps.ThemeId]);
return callback(null);
},
function updateSystemLoginCount(callback) {
(callback) => {
StatLog.incrementNonPersistentSystemStat(SysProps.LoginsToday, 1);
return StatLog.incrementSystemStat(SysProps.LoginCount, 1, callback);
},
function recordLastLogin(callback) {
(callback) => {
return StatLog.setUserStat(user, UserProps.LastLoginTs, StatLog.now, callback);
},
function updateUserLoginCount(callback) {
(callback) => {
return StatLog.incrementUserStat(user, UserProps.LoginCount, 1, callback);
},
function recordLoginHistory(callback) {
(callback) => {
const loginHistoryMax = Config().statLog.systemEvents.loginHistoryMax;
const historyItem = JSON.stringify({
userId : user.userId,
@ -140,5 +143,15 @@ function userLogin(client, username, password, options, cb) {
return cb(err);
}
);
});
}
function transformLoginError(err, client, username) {
client.sessionFailedLoginAttempts = _.get(client, 'sessionFailedLoginAttempts', 0) + 1;
const disconnect = Config().users.failedLogin.disconnect;
if(disconnect > 0 && client.sessionFailedLoginAttempts >= disconnect) {
err = Errors.BadLogin('To many failed login attempts', ErrorReasons.TooMany);
}
client.log.info( { username, ip : client.remoteAddress, reason : err.message }, 'Failed login attempt');
return err;
}