mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-01-06 22:40:14 -05:00
Disable user validation and errors on login
fixes #3658 - Catch any errors from user.save() events during login - Prevent validation from happening at all when only updating status/last_login - Fixes a problem I introduced with errors which are arrays in logError
This commit is contained in:
parent
4b83dfd6ab
commit
8d46705dbb
2 changed files with 46 additions and 9 deletions
|
@ -84,15 +84,20 @@ errors = {
|
|||
},
|
||||
|
||||
logError: function (err, context, help) {
|
||||
var self = this,
|
||||
origArgs = _.toArray(arguments).slice(1),
|
||||
stack,
|
||||
msgs;
|
||||
|
||||
if (_.isArray(err)) {
|
||||
_.each(err, function (e) {
|
||||
errors.logError(e);
|
||||
var newArgs = [e].concat(origArgs);
|
||||
errors.logError.apply(self, newArgs);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
var stack = err ? err.stack : null,
|
||||
msgs;
|
||||
stack = err ? err.stack : null;
|
||||
|
||||
err = _.isString(err) ? err : (_.isObject(err) ? err.message : 'An unknown error occurred.');
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ var _ = require('lodash'),
|
|||
http = require('http'),
|
||||
crypto = require('crypto'),
|
||||
validator = require('validator'),
|
||||
validation = require('../data/validation'),
|
||||
Role = require('./role').Role,
|
||||
|
||||
tokenSecurity = {},
|
||||
|
@ -55,6 +56,17 @@ User = ghostBookshelf.Model.extend({
|
|||
}
|
||||
},
|
||||
|
||||
// For the user model ONLY it is possible to disable validations.
|
||||
// This is used to bypass validation during the credential check, and must never be done with user-provided data
|
||||
// Should be removed when #3691 is done
|
||||
validate: function () {
|
||||
var opts = arguments[1];
|
||||
if (opts && _.has(opts, 'validate') && opts.validate === false) {
|
||||
return;
|
||||
}
|
||||
return validation.validateSchema(this.tableName, this.toJSON());
|
||||
},
|
||||
|
||||
// Get the user from the options object
|
||||
contextUser: function (options) {
|
||||
// Default to context user
|
||||
|
@ -561,7 +573,7 @@ User = ghostBookshelf.Model.extend({
|
|||
return when.reject();
|
||||
},
|
||||
|
||||
setWarning: function (user) {
|
||||
setWarning: function (user, options) {
|
||||
var status = user.get('status'),
|
||||
regexp = /warn-(\d+)/i,
|
||||
level;
|
||||
|
@ -577,7 +589,7 @@ User = ghostBookshelf.Model.extend({
|
|||
user.set('status', 'warn-' + level);
|
||||
}
|
||||
}
|
||||
return when(user.save()).then(function () {
|
||||
return when(user.save(options)).then(function () {
|
||||
return 5 - level;
|
||||
});
|
||||
},
|
||||
|
@ -598,16 +610,36 @@ User = ghostBookshelf.Model.extend({
|
|||
if (user.get('status') !== 'locked') {
|
||||
return nodefn.call(bcrypt.compare, object.password, user.get('password')).then(function (matched) {
|
||||
if (!matched) {
|
||||
return when(self.setWarning(user)).then(function (remaining) {
|
||||
return when(self.setWarning(user, {validate: false})).then(function (remaining) {
|
||||
s = (remaining > 1) ? 's' : '';
|
||||
return when.reject(new errors.UnauthorizedError('Your password is incorrect.<br>' +
|
||||
remaining + ' attempt' + s + ' remaining!'));
|
||||
|
||||
// Use comma structure, not .catch, because we don't want to catch incorrect passwords
|
||||
}, function (error) {
|
||||
|
||||
// If we get a validation or other error during this save, catch it and log it, but don't
|
||||
// cause a login error because of it. The user validation is not important here.
|
||||
errors.logError(
|
||||
error,
|
||||
'Error thrown from user update during login',
|
||||
'Visit and save your profile after logging in to check for problems.'
|
||||
);
|
||||
return when.reject(new errors.UnauthorizedError('Your password is incorrect.'));
|
||||
});
|
||||
}
|
||||
|
||||
return when(user.set({status : 'active', last_login : new Date()}).save()).then(function (user) {
|
||||
return user;
|
||||
});
|
||||
return when(user.set({status : 'active', last_login : new Date()}).save({validate: false}))
|
||||
.catch(function (error) {
|
||||
// If we get a validation or other error during this save, catch it and log it, but don't
|
||||
// cause a login error because of it. The user validation is not important here.
|
||||
errors.logError(
|
||||
error,
|
||||
'Error thrown from user update during login',
|
||||
'Visit and save your profile after logging in to check for problems.'
|
||||
);
|
||||
return user;
|
||||
});
|
||||
}, errors.logAndThrowError);
|
||||
}
|
||||
return when.reject(new errors.NoPermissionError('Your account is locked due to too many ' +
|
||||
|
|
Loading…
Reference in a new issue