/**
*
* Authentication related methods
*
*/
const md5 = require('md5');
const Usersgroups = require('./usersgroups');
class auth {
constructor() {
}
/**
* Returns access groups (users_groups) for given user
* @param {integer} uId userId of user
* @param {*} callback rows or null
*/
getUsersGroupsForUserWithId(uId, callback) {
let query = "SELECT " +
"xt_users_users_groups.*, " +
"users_groups.isSystemGroup, " +
"users_groups.grantnamespace, " +
"users_groups.title AS groupTitle " +
"FROM xt_users_users_groups " +
"INNER JOIN users_groups ON users_groups.id = xt_users_users_groups.groupId " +
"WHERE xt_users_users_groups.userId = ?";
global.coreDb.all(query, [
uId
], (err, rows) => {
if (err) {
this._logger.error('AUTH-MODEL | Error loading users group for user from core data: ' + err.message);
return callback(null);
} else {
return callback(rows);
}
});
}
/**
*
* @param {string} username username
* @param {string} passwordHashMD5 hash of password
* @param {function} callback success (true/false), if true row of user from core database
*/
authenticateUserMD5(username, passwordHashMD5, callback) {
let query = "SELECT `users`.*, " +
"`organizations`.`name` AS organizationname, " +
"`basedata`.`image` AS image, " +
"`basedata`.`firstname` AS firstname, " +
"`basedata`.`id` AS basedataId, " +
"`basedata`.`lastname` AS lastname " +
"FROM `users` " +
"LEFT JOIN `basedata` ON `users`.`basedataid` = `basedata`.`id` " +
"LEFT JOIN `organizations` ON `basedata`.`organizationid` = `organizations`.`id` " +
"WHERE `username` = ? COLLATE NOCASE";
global.coreDb.all(query, [
username
], (err, rows) => {
if (err) {
this._logger.error('AUTH-MODEL | Error loading user for authentication from core data: ' + err.message);
return callback(false, null);
} else {
if (rows.length > 0) {
// user found
var userRow = rows[0];
// Check if passwords match
if (passwordHashMD5 === userRow['password']) {
// Password typed in correct --> return user row
if (userRow['state'] === 1) {
// user is active
this.setLastLoginDate(userRow.id, (successLastLogin) => {
if (successLastLogin) {
return callback(true, userRow);
} else {
return callback(false, userRow);
}
})
} else {
return callback(false, userRow);
}
} else if (passwordHashMD5 === userRow['startPasswordHash']) {
// User sent in a startPassword --> inform App that user is enforced to change password now
if (userRow['state'] === 1) {
// user is active
this.setLastLoginDate(userRow.id, (successLastLogin) => {
if (successLastLogin) {
return callback(true, userRow);
} else {
return callback(false, userRow);
}
})
} else {
return callback(false, userRow);
}
} else {
return callback(false, null)
}
} else {
// No User for given username found
return callback(false, null);
}
}
});
}
/**
*
* @param {string} username username caseinsensitive as string
* @param {string} password password casesensitive as string
* @param {function} callback success(true or false), userrowsuccess (row or null), passwordchange enforced (true, false)
*/
authenticateUser(username, password, callback) {
let query = "SELECT `users`.*, " +
"`organizations`.`name` AS organizationname, " +
"`basedata`.`image` AS image, " +
"`basedata`.`firstname` AS firstname, " +
"`basedata`.`lastname` AS lastname " +
"FROM `users` " +
"LEFT JOIN `basedata` ON `users`.`basedataid` = `basedata`.`id` " +
"LEFT JOIN `organizations` ON `basedata`.`organizationid` = `organizations`.`id` " +
"WHERE `username` = ? COLLATE NOCASE";
global.coreDb.all(query, [
username
], (err, rows) => {
if (err) {
this._logger.error('AUTH-MODEL | Error loading user for authentication from core data: ' + err.message);
return callback(false, null, false);
} else {
if (rows.length > 0) {
// user found
var userRow = rows[0];
// Check if passwords match
var passwordHashMD5 = md5(password);
if (passwordHashMD5 === userRow['password']) {
this.setLastLoginDate(userRow.id, (successLastLogin) => {
if (successLastLogin) {
return callback(true, userRow, false);
} else {
return callback(false, userRow, false);
}
})
} else if (password === userRow['startPassword']) {
// User sent his startPassword
this.setLastLoginDate(userRow.id, (successLastLogin) => {
if (successLastLogin) {
return callback(true, userRow, true);
} else {
return callback(false, userRow, false);
}
})
} else {
// Wrong password typed in
return callback(false, null, false)
}
} else {
// No User for given username found
return callback(false, null, false);
}
}
});
}
/**
* Sets last login timestamp in user record in core database to "now" in local timezone
* @param {integer} uId
* @param {function} callback success, true or false
*/
setLastLoginDate(uId, callback) {
let query = "UPDATE users SET lastlogin = DATETIME('now', 'localtime') WHERE id = ?;"
global.coreDb.all(query, [
uId
], (err, rows) => {
if (err) {
this._logger.error('AUTH-MODEL | Error setting last login date in core database for user: ' + err.message);
return callback(false);
} else {
return callback(true);
}
});
}
/**
* Changes a users password
* @param {integer} basedataId basedata id of user the password should be changed for
* @param {string} oldPassword the old password
* @param {string} newPassword the new password
* @param {function} callback success (true or false)
*/
changePassword(username, oldPassword, newPassword, callback) {
let query = "SELECT * FROM users WHERE username = ?;"
global.coreDb.all(query, [
username
], (err, rows) => {
if (err) {
this._logger.error('AUTH-MODEL | Error getting user for password change request: ' + err.message);
return callback(false);
} else {
if (rows.length > 0) {
// User found. Check if passwords match
var passwordHashMD5 = md5(oldPassword);
if (passwordHashMD5 === rows[0]['password']) {
// given old password matches existing one in database. now set the new password in database;
var newPasswordMD5 = md5(newPassword);
let query = "UPDATE users SET password = ? WHERE username = ?";
global.coreDb.all(query, [
newPasswordMD5,
username
], (err, rows) => {
if (err) {
this._logger.error('AUTH-MODEL | Error setting new password in core database for user: ' + err.message);
return callback(false);
} else {
return callback(true);
}
});
} else {
// Wrong password typed in
return callback(false)
}
} else {
return callback(false);
}
}
});
}
/**
* Checks if session is valid for redirecting user from login page to home dashboard
* @param {object} session session object
* @param {*} callback valid (true) or not valid (false)
*/
checkForValidSession(session, callback) {
var valid = false;
if (typeof session != 'undefined') {
if (session != null) {
if (typeof session.loggedin != 'undefined') {
if (session.loggedin === true) {
valid = true;
} else {
return callback(false);
}
} else {
return callback(false);
}
if (typeof session.username != 'undefined') {
if (session.username.length > 0) {
valid = true;
} else {
return callback(false);
}
} else {
return callback(false);
}
if (typeof session.userid != 'undefined') {
if (session.userid > 0) {
valid = true;
} else {
return callback(false);
}
} else {
return callback(false);
}
if (typeof session.basedataId != 'undefined') {
if (session.basedataId > 0) {
valid = true;
} else {
return callback(false);
}
} else {
return callback(false);
}
if (typeof session.organization != 'undefined') {
if (session.organization.length > 0) {
valid = true;
} else {
return callback(false);
}
} else {
return callback(false);
}
if (typeof session.name != 'undefined') {
if (session.name.length > 0) {
valid = true;
} else {
return callback(false);
}
} else {
return callback(false);
}
return callback(valid);
} else {
return callback(false);
}
} else {
return callback(false);
}
}
}
module.exports = auth;