From 02f038542a64ee9d53eaba4d193d738d710776d3 Mon Sep 17 00:00:00 2001 From: Andrew Thornton Date: Sun, 22 Jul 2018 13:30:32 +0100 Subject: [PATCH] chore(server): Update to sequelize 4 Update sequelize to v4 and fix the user model to work with this. Part of #2691 --- templates/app/_package.json | 6 +- .../user(auth)/user.model(sequelizeModels).js | 263 +++++++++--------- .../server/config/environment/development.js | 1 + .../server/config/environment/production.js | 1 + .../app/server/config/environment/test.js | 1 + 5 files changed, 135 insertions(+), 137 deletions(-) diff --git a/templates/app/_package.json b/templates/app/_package.json index 71768decc..69d434fbd 100644 --- a/templates/app/_package.json +++ b/templates/app/_package.json @@ -33,9 +33,9 @@ "mongoose": "^5.1.5", "bluebird": "^3.3.3", "connect-mongo": "^2.0.1",<% } %><% if(filters.sequelize) { %> - "sequelize": "^3.23.6", - "sqlite3": "~4.0.1", - "connect-session-sequelize": "^4.1.0",<% } %><% if(filters.auth) { %> + "sequelize": "^4.38.0", + "sqlite3": "~4.0.2", + "connect-session-sequelize": "^5.2.2",<% } %><% if(filters.auth) { %> "jsonwebtoken": "^8.3.0", "express-jwt": "^5.0.0", "passport": "~0.4.0", diff --git a/templates/app/server/api/user(auth)/user.model(sequelizeModels).js b/templates/app/server/api/user(auth)/user.model(sequelizeModels).js index 413769463..5ac47112a 100644 --- a/templates/app/server/api/user(auth)/user.model(sequelizeModels).js +++ b/templates/app/server/api/user(auth)/user.model(sequelizeModels).js @@ -6,7 +6,7 @@ var validatePresenceOf = function(value) { }; export default function(sequelize, DataTypes) { - return sequelize.define('User', { + const User = sequelize.define('User', { _id: { type: DataTypes.INTEGER, allowNull: false, @@ -65,158 +65,153 @@ export default function(sequelize, DataTypes) { * Pre-save hooks */ hooks: { - beforeBulkCreate(users, fields, fn) { - var totalUpdated = 0; - users.forEach(user => { - user.updatePassword(err => { - if(err) { - return fn(err); - } - totalUpdated += 1; - if(totalUpdated === users.length) { - return fn(); - } - }); - }); + beforeBulkCreate(users, fields) { + var promises = []; + users.forEach(user => promises.push(user.updatePassword())); + return Promise.all(promises); }, - beforeCreate(user, fields, fn) { - user.updatePassword(fn); + beforeCreate(user, fields) { + return user.updatePassword(); }, - beforeUpdate(user, fields, fn) { + beforeUpdate(user, fields) { if(user.changed('password')) { - return user.updatePassword(fn); + return user.updatePassword(); } - fn(); + return Promise.resolve(user); } }, - /** - * Instance Methods - */ - instanceMethods: { - /** - * Authenticate - check if the passwords are the same - * - * @param {String} password - * @param {Function} callback - * @return {Boolean} - * @api public - */ - authenticate(password, callback) { - if(!callback) { - return this.password === this.encryptPassword(password); - } + }); - var _this = this; - this.encryptPassword(password, function(err, pwdGen) { - if(err) { - callback(err); - } + /** + * Instance Methods + */ + + /** + * Authenticate - check if the passwords are the same + * + * @param {String} password + * @param {Function} callback + * @return {Boolean} + * @api public + */ + User.prototype.authenticate = function(password, callback) { + if(!callback) { + return this.password === this.encryptPassword(password); + } - if(_this.password === pwdGen) { - callback(null, true); - } - else { - callback(null, false); - } - }); - }, + var _this = this; + this.encryptPassword(password, function(err, pwdGen) { + if(err) { + callback(err); + } - /** - * Make salt - * - * @param {Number} [byteSize] - Optional salt byte size, default to 16 - * @param {Function} callback - * @return {String} - * @api public - */ - makeSalt(...args) { - let byteSize; - let callback; - let defaultByteSize = 16; - - if(typeof args[0] === 'function') { - callback = args[0]; - byteSize = defaultByteSize; - } else if(typeof args[1] === 'function') { - callback = args[1]; - } else { - throw new Error('Missing Callback'); - } + if(_this.password === pwdGen) { + callback(null, true); + } else { + callback(null, false); + } + }); + }; + + /** + * Make salt + * + * @param {Number} [byteSize] - Optional salt byte size, default to 16 + * @param {Function} callback + * @return {String} + * @api public + */ + User.prototype.makeSalt = function(...args) { + let byteSize; + let callback; + let defaultByteSize = 16; + + if(typeof args[0] === 'function') { + callback = args[0]; + byteSize = defaultByteSize; + } else if(typeof args[1] === 'function') { + callback = args[1]; + } else { + throw new Error('Missing Callback'); + } - if(!byteSize) { - byteSize = defaultByteSize; - } + if(!byteSize) { + byteSize = defaultByteSize; + } - return crypto.randomBytes(byteSize, function(err, salt) { - if(err) { - callback(err); - } - return callback(null, salt.toString('base64')); - }); - }, + return crypto.randomBytes(byteSize, function(err, salt) { + if(err) { + callback(err); + } + return callback(null, salt.toString('base64')); + }); + }; + + /** + * Encrypt password + * + * @param {String} password + * @param {Function} callback + * @return {String} + * @api public + */ + User.prototype.encryptPassword = function(password, callback) { + if(!password || !this.salt) { + return callback ? callback(null) : null; + } - /** - * Encrypt password - * - * @param {String} password - * @param {Function} callback - * @return {String} - * @api public - */ - encryptPassword(password, callback) { - if(!password || !this.salt) { - return callback ? callback(null) : null; - } + var defaultIterations = 10000; + var defaultKeyLength = 64; + var salt = new Buffer(this.salt, 'base64'); - var defaultIterations = 10000; - var defaultKeyLength = 64; - var salt = new Buffer(this.salt, 'base64'); + if(!callback) { + return crypto.pbkdf2Sync(password, salt, defaultIterations, defaultKeyLength, 'sha256') + .toString('base64'); + } - if(!callback) { - return crypto.pbkdf2Sync(password, salt, defaultIterations, defaultKeyLength, 'sha256') - .toString('base64'); + return crypto.pbkdf2(password, salt, defaultIterations, defaultKeyLength, 'sha256', + function(err, key) { + if(err) { + callback(err); } + return callback(null, key.toString('base64')); + }); + }; + + /** + * Update password field + * + * @param {Function} fn + * @return {String} + * @api public + */ + User.prototype.updatePassword = function() { + return new Promise((resolve, reject) => { + if (!this.password) { + return resolve(user); + } - return crypto.pbkdf2(password, salt, defaultIterations, defaultKeyLength, 'sha256', - function(err, key) { - if(err) { - callback(err); - } - return callback(null, key.toString('base64')); - }); - }, + if (!validatePresenceOf(this.password)<% if(filters.oauth) { %> && authTypes.indexOf(this.provider) === -1<% } %>) { + return reject(new Error('Invalid password')); + } - /** - * Update password field - * - * @param {Function} fn - * @return {String} - * @api public - */ - updatePassword(fn) { - // Handle new/update passwords - if(!this.password) return fn(null); - - if(!validatePresenceOf(this.password)<% if(filters.oauth) { %> && authTypes.indexOf(this.provider) === -1<% } %>) { - fn(new Error('Invalid password')); + // Make salt with a callback + return this.makeSalt((saltErr, salt) => { + if (saltErr) { + return reject(saltErr); } - - // Make salt with a callback - this.makeSalt((saltErr, salt) => { - if(saltErr) { - return fn(saltErr); + this.salt = salt; + return this.encryptPassword(this.password, (encryptErr, hashedPassword) => { + if (encryptErr) { + return reject(encryptErr); } - this.salt = salt; - this.encryptPassword(this.password, (encryptErr, hashedPassword) => { - if(encryptErr) { - fn(encryptErr); - } - this.password = hashedPassword; - fn(null); - }); + this.password = hashedPassword; + return resolve(this); }); - } - } - }); + }); + }); + }; + + return User; }; diff --git a/templates/app/server/config/environment/development.js b/templates/app/server/config/environment/development.js index 1a0705de6..2e4c9ac43 100644 --- a/templates/app/server/config/environment/development.js +++ b/templates/app/server/config/environment/development.js @@ -14,6 +14,7 @@ module.exports = {<% if (filters.mongoose) { %> uri: 'sqlite://', options: { logging: false, + operatorsAliases: false, storage: 'dev.sqlite', define: { timestamps: false diff --git a/templates/app/server/config/environment/production.js b/templates/app/server/config/environment/production.js index 87f58dacf..2c7d2aad6 100644 --- a/templates/app/server/config/environment/production.js +++ b/templates/app/server/config/environment/production.js @@ -27,6 +27,7 @@ module.exports = { || 'sqlite://', options: { logging: false, + operatorsAliases: false, storage: 'dist.sqlite', define: { timestamps: false diff --git a/templates/app/server/config/environment/test.js b/templates/app/server/config/environment/test.js index dc05b53b2..4b2dcf2bf 100644 --- a/templates/app/server/config/environment/test.js +++ b/templates/app/server/config/environment/test.js @@ -12,6 +12,7 @@ module.exports = { uri: 'sqlite://', options: { logging: false, + operatorsAliases: false, storage: 'test.sqlite', define: { timestamps: false