UNPKG

openhim-core

Version:

The OpenHIM core application that provides logging and routing of http requests

376 lines (330 loc) 13.2 kB
var Q, User, atna, auditing, authorisation, config, contact, himSourceID, htmlMessageTemplate, logger, moment, os, passwordResetHtmlMessageTemplate, passwordResetPlainMessageTemplate, plainMessageTemplate, randtoken, utils; User = require('../model/users').User; Q = require('q'); logger = require('winston'); authorisation = require('./authorisation'); moment = require('moment'); randtoken = require('rand-token'); contact = require('../contact'); config = require("../config/config"); config.newUserExpiry = config.get('newUserExpiry'); config.userPasswordResetExpiry = config.get('userPasswordResetExpiry'); config.alerts = config.get('alerts'); utils = require("../utils"); atna = require('atna-audit'); os = require('os'); auditing = require('../auditing'); himSourceID = config.get('auditing').auditEvents.auditSourceID; /* * Get authentication details */ exports.authenticate = function*(email) { var audit, e, error, user; email = unescape(email); try { user = (yield User.findOne({ email: email }).exec()); if (!user) { utils.logAndSetResponse(this, 404, "Could not find user by email " + email, 'info'); audit = atna.userLoginAudit(atna.OUTCOME_SERIOUS_FAILURE, himSourceID, os.hostname(), email); audit = atna.wrapInSyslog(audit); return auditing.sendAuditEvent(audit, function() { return logger.debug('Processed internal audit'); }); } else { return this.body = { salt: user.passwordSalt, ts: new Date() }; } } catch (error) { e = error; return utils.logAndSetResponse(this, 500, "Error during authentication " + e, 'error'); } }; /* Reset password Functions */ passwordResetPlainMessageTemplate = function(firstname, setPasswordLink) { return "<---------- Existing User - Reset Password ---------->\nHi " + firstname + ",\n\nA request has been made to reset your password on the OpenHIM instance running on " + config.alerts.himInstance + "\nFollow the below link to reset your password and log into OpenHIM Console\n" + setPasswordLink + "\n<---------- Existing User - Reset Password ---------->"; }; passwordResetHtmlMessageTemplate = function(firstname, setPasswordLink) { return "<h1>Reset OpenHIM Password</h1>\n<p>Hi " + firstname + ",<br/><br/>A request has been made to reset your password on the OpenHIM instance running on " + config.alerts.himInstance + "</p>\n<p>Follow the below link to set your password and log into OpenHIM Console</p>\n<p>" + setPasswordLink + "</p>"; }; exports.generateRandomToken = function() { return randtoken.generate(32); }; /* * update user token/expiry and send new password email */ exports.userPasswordResetRequest = function*(email) { var consoleURL, duration, durationType, e, error, expiry, htmlMessage, plainMessage, sendEmail, sendEmailError, setPasswordLink, token, updateUserTokenExpiry, user; email = unescape(email); if (email === 'root@openhim.org') { this.body = "Cannot request password reset for 'root@openhim.org'"; this.status = 403; return; } token = exports.generateRandomToken(); duration = config.userPasswordResetExpiry.duration; durationType = config.userPasswordResetExpiry.durationType; expiry = moment().add(duration, durationType).utc().format(); updateUserTokenExpiry = { token: token, tokenType: 'existingUser', expiry: expiry }; try { user = (yield User.findOneAndUpdate({ email: email }, updateUserTokenExpiry).exec()); if (!user) { this.body = "Tried to request password reset for invalid email address: " + email; this.status = 404; logger.info("Tried to request password reset for invalid email address: " + email); return; } consoleURL = config.alerts.consoleURL; setPasswordLink = consoleURL + "/#/set-password/" + token; plainMessage = passwordResetPlainMessageTemplate(user.firstname, setPasswordLink); htmlMessage = passwordResetHtmlMessageTemplate(user.firstname, setPasswordLink); sendEmail = Q.denodeify(contact.contactUser); sendEmailError = (yield sendEmail('email', email, 'OpenHIM Console Password Reset', plainMessage, htmlMessage)); if (sendEmailError) { utils.logAndSetResponse(this, 500, "Could not send email to user via the API " + e, 'error'); } logger.info('The email has been sent to the user'); this.body = "Successfully set user token/expiry for password reset."; this.status = 201; return logger.info("User updated token/expiry for password reset " + email); } catch (error) { e = error; return utils.logAndSetResponse(this, 500, "Could not update user with email " + email + " via the API " + e, 'error'); } }; /* New User Set Password Functions */ exports.getUserByToken = function*(token) { var e, error, projectionRestriction, result; token = unescape(token); try { projectionRestriction = { "email": 1, "firstname": 1, "surname": 1, "msisdn": 1, "token": 1, "tokenType": 1, "locked": 1, "expiry": 1, "_id": 0 }; result = (yield User.findOne({ token: token }, projectionRestriction).exec()); if (!result) { this.body = "User with token " + token + " could not be found."; return this.status = 404; } else { if (moment(result.expiry).isBefore(moment())) { this.body = "Token " + token + " has expired"; return this.status = 410; } else { return this.body = result; } } } catch (error) { e = error; return utils.logAndSetResponse(this, 500, "Could not find user with token " + token + " via the API " + e, 'error'); } }; exports.updateUserByToken = function*(token) { var e, error, error1, msisdn, userData, userDataExpiry, userUpdateObj; token = unescape(token); userData = this.request.body; try { userDataExpiry = (yield User.findOne({ token: token }).exec()); if (!userDataExpiry) { this.body = "User with token " + token + " could not be found."; this.status = 404; return; } else { if (moment(userDataExpiry.expiry).isBefore(moment())) { this.body = "User with token " + token + " has expired to set their password."; this.status = 410; return; } } } catch (error) { e = error; utils.logAndSetResponse(this, 500, "Could not find user with token " + token + " via the API " + e, 'error'); return; } if (userData.msisdn) { msisdn = userData.msisdn; } else { msisdn = null; } userUpdateObj = { token: null, tokenType: null, expiry: null, passwordAlgorithm: userData.passwordAlgorithm, passwordSalt: userData.passwordSalt, passwordHash: userData.passwordHash }; if (userDataExpiry.tokenType === 'newUser') { userUpdateObj.firstname = userData.firstname; userUpdateObj.surname = userData.surname; userUpdateObj.locked = false; userUpdateObj.msisdn = msisdn; } try { (yield User.findOneAndUpdate({ token: token }, userUpdateObj).exec()); this.body = "Successfully set new user password."; return logger.info("User updated by token " + token); } catch (error1) { e = error1; return utils.logAndSetResponse(this, 500, "Could not update user with token " + token + " via the API " + e, 'error'); } }; /* New User Set Password Functions */ plainMessageTemplate = function(firstname, setPasswordLink) { return "<---------- New User - Set Password ---------->\nHi " + firstname + ",\n\nA profile has been created for you on the OpenHIM instance running on " + config.alerts.himInstance + "\nFollow the below link to set your password and log into OpenHIM Console\n" + setPasswordLink + "\n<---------- New User - Set Password ---------->"; }; htmlMessageTemplate = function(firstname, setPasswordLink) { return "<h1>New OpenHIM Profile</h1>\n<p>Hi " + firstname + ",<br/><br/>A profile has been created for you on the OpenHIM instance running on " + config.alerts.himInstance + "</p>\n<p>Follow the below link to set your password and log into OpenHIM Console</p>\n<p>" + setPasswordLink + "</p>"; }; /* * Adds a user */ exports.addUser = function*() { var consoleURL, duration, durationType, e, error, htmlMessage, plainMessage, result, setPasswordLink, token, user, userData; if (!authorisation.inGroup('admin', this.authenticated)) { utils.logAndSetResponse(this, 403, "User " + this.authenticated.email + " is not an admin, API access to addUser denied.", 'info'); return; } userData = this.request.body; token = randtoken.generate(32); userData.token = token; userData.tokenType = 'newUser'; userData.locked = true; duration = config.newUserExpiry.duration; durationType = config.newUserExpiry.durationType; userData.expiry = moment().add(duration, durationType).utc().format(); consoleURL = config.alerts.consoleURL; setPasswordLink = consoleURL + "/#/set-password/" + token; try { user = new User(userData); result = (yield Q.ninvoke(user, 'save')); plainMessage = plainMessageTemplate(userData.firstname, setPasswordLink); htmlMessage = htmlMessageTemplate(userData.firstname, setPasswordLink); contact.contactUser('email', userData.email, 'OpenHIM Console Profile', plainMessage, htmlMessage, function(err) { if (err) { return logger.error("The email could not be sent to the user via the API " + err); } else { return logger.info('The email has been sent to the new user'); } }); this.body = 'User successfully created'; this.status = 201; return logger.info("User " + this.authenticated.email + " created user " + userData.email); } catch (error) { e = error; return utils.logAndSetResponse(this, 500, "Could not add user via the API " + e, 'error'); } }; /* * Retrieves the details of a specific user */ exports.getUser = function*(email) { var e, error, result; email = unescape(email); if (!authorisation.inGroup('admin', this.authenticated) && this.authenticated.email !== email) { utils.logAndSetResponse(this, 403, "User " + this.authenticated.email + " is not an admin, API access to getUser denied.", 'info'); return; } try { result = (yield User.findOne({ email: email }).exec()); if (!result) { this.body = "User with email " + email + " could not be found."; return this.status = 404; } else { return this.body = result; } } catch (error) { e = error; return utils.logAndSetResponse(this, 500, "Could not get user via the API " + e, 'error'); } }; exports.updateUser = function*(email) { var e, error, userData; email = unescape(email); if (!authorisation.inGroup('admin', this.authenticated) && this.authenticated.email !== email) { utils.logAndSetResponse(this, 403, "User " + this.authenticated.email + " is not an admin, API access to updateUser denied.", 'info'); return; } userData = this.request.body; if (userData.passwordAlgorithm && userData.passwordHash && userData.passwordSalt) { userData.token = null; userData.tokenType = null; userData.locked = false; userData.expiry = null; } if (this.authenticated.email === email && !authorisation.inGroup('admin', this.authenticated)) { delete userData.groups; } if (userData._id) { delete userData._id; } try { (yield User.findOneAndUpdate({ email: email }, userData).exec()); this.body = "Successfully updated user."; return logger.info("User " + this.authenticated.email + " updated user " + userData.email); } catch (error) { e = error; return utils.logAndSetResponse(this, 500, "Could not update user " + email + " via the API " + e, 'error'); } }; exports.removeUser = function*(email) { var e, error; if (!authorisation.inGroup('admin', this.authenticated)) { utils.logAndSetResponse(this, 403, "User " + this.authenticated.email + " is not an admin, API access to removeUser denied.", 'info'); return; } email = unescape(email); if (email === 'root@openhim.org') { utils.logAndSetResponse(this, 403, "User root@openhim.org is OpenHIM root, User cannot be deleted through the API", 'info'); return; } try { (yield User.findOneAndRemove({ email: email }).exec()); this.body = "Successfully removed user with email " + email; return logger.info("User " + this.authenticated.email + " removed user " + email); } catch (error) { e = error; return utils.logAndSetResponse(this, 500, "Could not remove user " + email + " via the API " + e, 'error'); } }; exports.getUsers = function*() { var e, error; if (!authorisation.inGroup('admin', this.authenticated)) { utils.logAndSetResponse(this, 403, "User " + this.authenticated.email + " is not an admin, API access to getUsers denied.", 'info'); return; } try { return this.body = (yield User.find().exec()); } catch (error) { e = error; return utils.logAndSetResponse(this, 500, "Could not fetch all users via the API " + e, 'error'); } }; //# sourceMappingURL=users.js.map