Inherited Users can't log in
See original GitHub issueIn keystone.js, there is a single model listed under ‘user model’ which can be used to sign in. In order to get multiple user types on a site, creating a model that inherits from the one listed under ‘user model’ seems to be the only way, however, there’s an issue when inherited users attempt to log in.
When any user attempts to log in the following happens:
- there’s a call to doSignin(…). A few checks pass and there’s an attempt to get a user of the type ‘user model’ specified in keystone.js.
- There’s a call to user._.password.compare(…) on the user object that returns from step 1, which is defined in PasswordType.js. The compare function runs ‘bcrypt.compare(candidate, item.get(this.path), callback);’, where candidate is the unencrypted password, and item.get(this.path) is the encrypted password.
This is where we see the difference, bcrypt.compare(…) on the model listed under ‘user model’ in keystone.js is successful, but bcrypt.compare(…) on the model inheriting from the model listed under ‘user model’ is not.
It’s the same behavior every time too. When the 60 character password hash created by bcrypt and stored in the user object is compared with the unencrypted password based on bcrypt’s logic, they don’t match. There’s some complicated behavior at play regarding a salt that is created from the first 30 characters of the encrypted hash in order to process the unencrypted password and make the match. If a non-inherited model is listed in keystone.js under ‘user model’, logging in works just fine.
Example model (this would be the one listed in keystone.js under ‘user model’:
var keystone = require('keystone'),
Types = keystone.Field.Types;
// Create model
var User = new keystone.List('User', {
track: true,
map: { name: 'name.last' },
defaultSort: 'name.last'
});
// Create fields
User.add('General Information', {
name: {
first: { type: Types.Text, label: 'first name', required: true, index: true, initial: true },
last: { type: Types.Text, label: 'last name', required: true, index: true, initial: true }
},
password: { type: Types.Password, label: 'password', required: true, initial: true },
avatar: { type: Types.CloudinaryImage, label: 'avatar', folder: 'users/admin', autoCleanup: true }
email: { type: Types.Email, label: 'email address', unique: true, required: true, index: true, initial: true },
});
// Provide access to Keystone (simplified for the test)
User.schema.virtual('canAccessKeystone').get(function() {
'use strict';
return true;
});
// Define default columns in the admin interface and register the model
User.defaultColumns = 'name.first, name.last, email';
User.register();
Example model which inherits from the one listed in keystone.js under ‘user model’:
var keystone = require('keystone'),
Types = keystone.Field.Types,
User = keystone.list('User');
// Create model
var TestUser = new keystone.List('TestUser', { inherits: User });
// Create fields
TestUser.add('More Permissions', {
morePermissions: {
canPassGo: { type: Boolean, label: 'can pass go', default: false, initial: true },
canCollect200: { type: Boolean, label: 'can collect $200.00', default: true, initial: true }
}
});
// Define default columns in the admin interface and register the model
TestUser.defaultColumns = 'name.last, email, canPassGo';
TestUser.register();
Issue Analytics
- State:
- Created 7 years ago
- Comments:10 (8 by maintainers)
Top GitHub Comments
@rafaneri, are you able to update to the master branch? It’s working for me there.
thanks @autoboxer, it works fine!