Skip to content

Commit a5a8aae

Browse files
committed
chore(server): Update to sequelize 4
Update sequelize to v4 and fix the user model to work with this. Part of angular-fullstack#2691
1 parent 73d1e29 commit a5a8aae

File tree

5 files changed

+134
-137
lines changed

5 files changed

+134
-137
lines changed

Diff for: templates/app/_package.json

+3-3
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,9 @@
3333
"mongoose": "^5.1.5",
3434
"bluebird": "^3.3.3",
3535
"connect-mongo": "^2.0.1",<% } %><% if(filters.sequelize) { %>
36-
"sequelize": "^3.23.6",
37-
"sqlite3": "~4.0.1",
38-
"connect-session-sequelize": "^4.1.0",<% } %><% if(filters.auth) { %>
36+
"sequelize": "^4.38.0",
37+
"sqlite3": "~4.0.2",
38+
"connect-session-sequelize": "^5.2.2",<% } %><% if(filters.auth) { %>
3939
"jsonwebtoken": "^8.3.0",
4040
"express-jwt": "^5.0.0",
4141
"passport": "~0.4.0",

Diff for: templates/app/server/api/user(auth)/user.model(sequelizeModels).js

+128-134
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ var validatePresenceOf = function(value) {
66
};
77

88
export default function(sequelize, DataTypes) {
9-
return sequelize.define('User', {
9+
const User = sequelize.define('User', {
1010
_id: {
1111
type: DataTypes.INTEGER,
1212
allowNull: false,
@@ -65,158 +65,152 @@ export default function(sequelize, DataTypes) {
6565
* Pre-save hooks
6666
*/
6767
hooks: {
68-
beforeBulkCreate(users, fields, fn) {
69-
var totalUpdated = 0;
70-
users.forEach(user => {
71-
user.updatePassword(err => {
72-
if(err) {
73-
return fn(err);
74-
}
75-
totalUpdated += 1;
76-
if(totalUpdated === users.length) {
77-
return fn();
78-
}
79-
});
80-
});
68+
beforeBulkCreate(users, fields) {
69+
return sequelize.Promise.map(users, user => user.updatePassword());
8170
},
82-
beforeCreate(user, fields, fn) {
83-
user.updatePassword(fn);
71+
beforeCreate(user, fields) {
72+
return user.updatePassword();
8473
},
85-
beforeUpdate(user, fields, fn) {
74+
beforeUpdate(user, fields) {
8675
if(user.changed('password')) {
87-
return user.updatePassword(fn);
76+
return user.updatePassword();
8877
}
89-
fn();
78+
return sequelize.promise.resolve(user);
9079
}
9180
},
9281

93-
/**
94-
* Instance Methods
95-
*/
96-
instanceMethods: {
97-
/**
98-
* Authenticate - check if the passwords are the same
99-
*
100-
* @param {String} password
101-
* @param {Function} callback
102-
* @return {Boolean}
103-
* @api public
104-
*/
105-
authenticate(password, callback) {
106-
if(!callback) {
107-
return this.password === this.encryptPassword(password);
108-
}
82+
});
10983

110-
var _this = this;
111-
this.encryptPassword(password, function(err, pwdGen) {
112-
if(err) {
113-
callback(err);
114-
}
84+
/**
85+
* Instance Methods
86+
*/
87+
88+
/**
89+
* Authenticate - check if the passwords are the same
90+
*
91+
* @param {String} password
92+
* @param {Function} callback
93+
* @return {Boolean}
94+
* @api public
95+
*/
96+
User.prototype.authenticate = function(password, callback) {
97+
if(!callback) {
98+
return this.password === this.encryptPassword(password);
99+
}
115100

116-
if(_this.password === pwdGen) {
117-
callback(null, true);
118-
}
119-
else {
120-
callback(null, false);
121-
}
122-
});
123-
},
101+
var _this = this;
102+
this.encryptPassword(password, function(err, pwdGen) {
103+
if(err) {
104+
callback(err);
105+
}
124106

125-
/**
126-
* Make salt
127-
*
128-
* @param {Number} [byteSize] - Optional salt byte size, default to 16
129-
* @param {Function} callback
130-
* @return {String}
131-
* @api public
132-
*/
133-
makeSalt(...args) {
134-
let byteSize;
135-
let callback;
136-
let defaultByteSize = 16;
137-
138-
if(typeof args[0] === 'function') {
139-
callback = args[0];
140-
byteSize = defaultByteSize;
141-
} else if(typeof args[1] === 'function') {
142-
callback = args[1];
143-
} else {
144-
throw new Error('Missing Callback');
145-
}
107+
if(_this.password === pwdGen) {
108+
callback(null, true);
109+
} else {
110+
callback(null, false);
111+
}
112+
});
113+
};
114+
115+
/**
116+
* Make salt
117+
*
118+
* @param {Number} [byteSize] - Optional salt byte size, default to 16
119+
* @param {Function} callback
120+
* @return {String}
121+
* @api public
122+
*/
123+
User.prototype.makeSalt = function(...args) {
124+
let byteSize;
125+
let callback;
126+
let defaultByteSize = 16;
127+
128+
if(typeof args[0] === 'function') {
129+
callback = args[0];
130+
byteSize = defaultByteSize;
131+
} else if(typeof args[1] === 'function') {
132+
callback = args[1];
133+
} else {
134+
throw new Error('Missing Callback');
135+
}
146136

147-
if(!byteSize) {
148-
byteSize = defaultByteSize;
149-
}
137+
if(!byteSize) {
138+
byteSize = defaultByteSize;
139+
}
150140

151-
return crypto.randomBytes(byteSize, function(err, salt) {
152-
if(err) {
153-
callback(err);
154-
}
155-
return callback(null, salt.toString('base64'));
156-
});
157-
},
141+
return crypto.randomBytes(byteSize, function(err, salt) {
142+
if(err) {
143+
callback(err);
144+
}
145+
return callback(null, salt.toString('base64'));
146+
});
147+
};
148+
149+
/**
150+
* Encrypt password
151+
*
152+
* @param {String} password
153+
* @param {Function} callback
154+
* @return {String}
155+
* @api public
156+
*/
157+
User.prototype.encryptPassword = function(password, callback) {
158+
if(!password || !this.salt) {
159+
return callback ? callback(null) : null;
160+
}
158161

159-
/**
160-
* Encrypt password
161-
*
162-
* @param {String} password
163-
* @param {Function} callback
164-
* @return {String}
165-
* @api public
166-
*/
167-
encryptPassword(password, callback) {
168-
if(!password || !this.salt) {
169-
return callback ? callback(null) : null;
170-
}
162+
var defaultIterations = 10000;
163+
var defaultKeyLength = 64;
164+
var salt = new Buffer(this.salt, 'base64');
171165

172-
var defaultIterations = 10000;
173-
var defaultKeyLength = 64;
174-
var salt = new Buffer(this.salt, 'base64');
166+
if(!callback) {
167+
return crypto.pbkdf2Sync(password, salt, defaultIterations, defaultKeyLength, 'sha256')
168+
.toString('base64');
169+
}
175170

176-
if(!callback) {
177-
return crypto.pbkdf2Sync(password, salt, defaultIterations, defaultKeyLength, 'sha256')
178-
.toString('base64');
171+
return crypto.pbkdf2(password, salt, defaultIterations, defaultKeyLength, 'sha256',
172+
function(err, key) {
173+
if(err) {
174+
callback(err);
179175
}
176+
return callback(null, key.toString('base64'));
177+
});
178+
};
179+
180+
/**
181+
* Update password field
182+
*
183+
* @param {Function} fn
184+
* @return {String}
185+
* @api public
186+
*/
187+
User.prototype.updatePassword = function() {
188+
var user = this;
189+
return new sequelize.Promise((resolve, reject) => {
190+
if (!user.password) {
191+
return resolve(user);
192+
}
180193

181-
return crypto.pbkdf2(password, salt, defaultIterations, defaultKeyLength, 'sha256',
182-
function(err, key) {
183-
if(err) {
184-
callback(err);
185-
}
186-
return callback(null, key.toString('base64'));
187-
});
188-
},
194+
if (!validatePresenceOf(user.password)<% if(filters.oauth) { %> && authTypes.indexOf(user.provider) === -1<% } %>) {
195+
return reject(new Error('Invalid password'));
196+
}
189197

190-
/**
191-
* Update password field
192-
*
193-
* @param {Function} fn
194-
* @return {String}
195-
* @api public
196-
*/
197-
updatePassword(fn) {
198-
// Handle new/update passwords
199-
if(!this.password) return fn(null);
200-
201-
if(!validatePresenceOf(this.password)<% if(filters.oauth) { %> && authTypes.indexOf(this.provider) === -1<% } %>) {
202-
fn(new Error('Invalid password'));
198+
// Make salt with a callback
199+
return user.makeSalt((saltErr, salt) => {
200+
if (saltErr) {
201+
return reject(saltErr);
203202
}
204-
205-
// Make salt with a callback
206-
this.makeSalt((saltErr, salt) => {
207-
if(saltErr) {
208-
return fn(saltErr);
203+
user.salt = salt;
204+
return user.encryptPassword(user.password, (encryptErr, hashedPassword) => {
205+
if (encryptErr) {
206+
return reject(encryptErr);
209207
}
210-
this.salt = salt;
211-
this.encryptPassword(this.password, (encryptErr, hashedPassword) => {
212-
if(encryptErr) {
213-
fn(encryptErr);
214-
}
215-
this.password = hashedPassword;
216-
fn(null);
217-
});
208+
user.password = hashedPassword;
209+
return resolve(user);
218210
});
219-
}
220-
}
221-
});
211+
});
212+
});
213+
};
214+
215+
return User;
222216
};

Diff for: templates/app/server/config/environment/development.js

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ module.exports = {<% if (filters.mongoose) { %>
1414
uri: 'sqlite://',
1515
options: {
1616
logging: false,
17+
operatorsAliases: false,
1718
storage: 'dev.sqlite',
1819
define: {
1920
timestamps: false

Diff for: templates/app/server/config/environment/production.js

+1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ module.exports = {
2727
|| 'sqlite://',
2828
options: {
2929
logging: false,
30+
operatorsAliases: false,
3031
storage: 'dist.sqlite',
3132
define: {
3233
timestamps: false

Diff for: templates/app/server/config/environment/test.js

+1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ module.exports = {
1212
uri: 'sqlite://',
1313
options: {
1414
logging: false,
15+
operatorsAliases: false,
1516
storage: 'test.sqlite',
1617
define: {
1718
timestamps: false

0 commit comments

Comments
 (0)