Skip to content

Commit

Permalink
fix(accounts): security enhancement
Browse files Browse the repository at this point in the history
  • Loading branch information
polonel committed Jun 8, 2022
1 parent 012d0ea commit 83fd5a8
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 1 deletion.
1 change: 1 addition & 0 deletions src/controllers/api/v1/routes.js
Expand Up @@ -122,6 +122,7 @@ module.exports = function (middleware, router, controllers) {
router.delete('/api/v1/groups/:id', apiv1, canUser('groups:delete'), apiCtrl.groups.deleteGroup)

// Users
router.put('/api/v1/profile', apiv1, apiCtrl.users.profileUpdate)
router.get('/api/v1/users', apiv1, canUser('accounts:view'), apiCtrl.users.getWithLimit)
router.post('/api/v1/users/create', apiv1, canUser('accounts:create'), apiCtrl.users.create)
router.get('/api/v1/users/notifications', apiv1, apiCtrl.users.getNotifications)
Expand Down
98 changes: 98 additions & 0 deletions src/controllers/api/v1/users.js
Expand Up @@ -384,6 +384,104 @@ apiUsers.createPublicAccount = function (req, res) {
)
}

apiUsers.profileUpdate = function (req, res) {
if (!req.user) return res.status(400).json({ success: false, error: 'Invalid Post Data' })
const username = req.user.username
if (_.isNull(username) || _.isUndefined(username))
return res.status(400).json({ success: false, error: 'Invalid Post Data' })

const data = req.body
let passwordUpdated = false

const obj = {
fullname: data.aFullname,
title: data.aTitle,
password: data.aPassword,
passconfirm: data.aPassConfirm,
email: data.aEmail
}

let passwordComplexityEnabled = true

async.series(
{
settings: function (done) {
const SettingUtil = require('../../../settings/settingsUtil')
SettingUtil.getSettings(function (err, content) {
if (err) return done(err)

const settings = content.data.settings
passwordComplexityEnabled = settings.accountsPasswordComplexity.value

return done()
})
},
user: function (done) {
UserSchema.getUserByUsername(username, function (err, user) {
if (err) return done(err)
if (!user) return done('Invalid User Object')

obj._id = user._id

if (
!_.isUndefined(obj.password) &&
!_.isEmpty(obj.password) &&
!_.isUndefined(obj.passconfirm) &&
!_.isEmpty(obj.passconfirm)
) {
if (obj.password === obj.passconfirm) {
if (passwordComplexityEnabled) {
// check Password Complexity
const passwordComplexity = require('../../../settings/passwordComplexity')
if (!passwordComplexity.validate(obj.password)) return done('Password does not meet requirements')
}

user.password = obj.password
passwordUpdated = true
}
}

if (!_.isUndefined(obj.fullname) && obj.fullname.length > 0) user.fullname = obj.fullname
if (!_.isUndefined(obj.email) && obj.email.length > 0) user.email = obj.email
if (!_.isUndefined(obj.title) && obj.title.length > 0) user.title = obj.title

user.save(function (err, nUser) {
if (err) return done(err)

nUser.populate('role', function (err, populatedUser) {
if (err) return done(err)
const resUser = stripUserFields(populatedUser)

return done(null, resUser)
})
})
})
},
groups: function (done) {
groupSchema.getAllGroupsOfUser(obj._id, done)
}
},
async function (err, results) {
if (err) {
winston.debug(err)
return res.status(400).json({ success: false, error: err })
}

const user = results.user.toJSON()
user.groups = results.groups.map(function (g) {
return { _id: g._id, name: g.name }
})

if (passwordUpdated) {
const Session = require('../../../models/session')
await Session.destroy(user._id)
}

return res.json({ success: true, user: user })
}
)
}

/**
* @api {put} /api/v1/users/:username Update User
* @apiName updateUser
Expand Down
2 changes: 1 addition & 1 deletion src/public/js/angularjs/controllers/profile.js
Expand Up @@ -74,7 +74,7 @@ define([
}

$http
.put('/api/v1/users/' + data.username, {
.put('/api/v1/profile/', {
aId: id,
aFullname: data.fullname,
aPass: data.password,
Expand Down

0 comments on commit 83fd5a8

Please sign in to comment.