Sequelize instance methods not working - node.js

I am trying to use Sequelize's instance method to validate a password on login attempt.
I have defined the User model as :
var User = sequelize.define('User',{
id:{
type:DataTypes.BIGINT,
autoIncrement: true,
allowNull: false,
primaryKey:true
},
username:{
type:DataTypes.STRING,
unique:true
},
password:{
type: DataTypes.STRING
},
...
},
{
classMethods:{
associate:function(models){
...
}
}
},
{
instanceMethods:{
validatePassword:function(password){
return bcrypt.compareSync(password, this.password);
}
}
}
);
return User;
}
In my login route I do the following :
1) Retrieve username & password from request body
2) Check if username exists in database
3) If user exists, get user object and compare sent password with hashed password in database using validatePassword method.
Here is the relevant code
var username = req.body.username || "";
var password = req.body.password || "";
models.User.findOne({ where: {username: username} }).
then(
function(user) {
if(user){
console.log(user.validatePassword(password));
}
....
Each time I try to login I get the following error
[TypeError: user.validatePassword is not a function]
What am I doing wrong?

I think you are using the sequelize model definition api incorrectly.
http://docs.sequelizejs.com/en/latest/docs/models-definition/#expansion-of-models
This is the correct way:
var User = sequelize.define('User',{}, {
classMethods: {
method1: ...
},
instanceMethods: {
method2: ...
}
});
not like this:
var User = sequelize.define('User',{}, {
classMethods: {
method1: ...
}
},{
instanceMethods: {
method2: ...
}
});

For anyone who's having a similar problem, I ran into the same issue but using Sequelize 5.21.5. According to this article, Sequelize Instance Methods, starting with Sequelize 4.0 and above, you have to use the prototype methodology in order to define instance methods like so:
// Adding an instance level methods.
User.prototype.validPassword = function(password) {
return bcrypt.compareSync(password, this.password);
};

We can add instanceLevelMethods to prototype,
User.prototype.your-instance-level-method-name = function() {
return 'foo';
};
I did it like this:
// Adding an instance level methods.
User.prototype.validPassword = function(password) {
return bcrypt.compareSync(password, this.password);
};

I use this approach:
const bcrypt = require('bcrypt-nodejs');
const constants = require('../constants/users');
module.exports = (Sequelize, type) => {
const User = Sequelize.define(constants.TABLE_NAME, {
username: {
type: type.STRING,
unique: true,
allowNull: false,
},
password: {
type: type.STRING,
allowNull: false,
},
// bla bla
});
const setSaltAndPassword = async function(user) {
if (user.changed('password')) {
const salt = bcrypt.genSaltSync(constants.PASSWORD_SALT_SIZE);
user.password = bcrypt.hashSync(user.password, salt);
}
};
User.prototype.validPassword = async function(password) {
return await bcrypt.compare(password, this.password);
};
User.beforeCreate(setSaltAndPassword);
User.beforeUpdate(setSaltAndPassword);
return User;
};

as at sequelize "sequelize": "^5.21.7" accessing the instanceMethods as shown by #user1695032 returns undefined.
here's what i found after several hours of getting undefined in the console.log() passing in the user object return from the query below:
User {
dataValues: {
id: 1,
firtName: null,
lasteName: null,
email: 'ugbanawaji.ekenekiso#ust.edu.ng',
phone: null,
password: '$2b$10$yEWnBFMAe15RLLgyU3XlrOUyw19c4PCmh8GJe9QVz3YkbdzK5fHWu',
createdAt: 2020-05-27T21:45:02.000Z,
updatedAt: 2020-05-27T21:45:02.000Z
},
_previousDataValues: {
id: 1,
firtName: null,
lasteName: null,
email: 'ugbanawaji.ekenekiso#ust.edu.ng',
phone: null,
password: '$2b$10$yEWnBFMAe15RLLgyU3XlrOUyw19c4PCmh8GJe9QVz3YkbdzK5fHWu',
createdAt: 2020-05-27T21:45:02.000Z,
updatedAt: 2020-05-27T21:45:02.000Z
},
_changed: {},
**_modelOptions: {**
timestamps: true,
validate: {},
freezeTableName: false,
underscored: false,
paranoid: false,
rejectOnEmpty: false,
whereCollection: { email: 'ugbanawaji.ekenekiso#ust.edu.ng' },
schema: null,
schemaDelimiter: '',
defaultScope: {},
scopes: {},
indexes: [],
name: { plural: 'Users', singular: 'User' },
omitNull: false,
**instanceMethods: { comparePasswords: [Function: comparePasswords] },**
hooks: { beforeValidate: [Array] },
sequelize: Sequelize {
options: [Object],
config: [Object],
dialect: [MysqlDialect],
queryInterface: [QueryInterface],
models: [Object],
modelManager: [ModelManager],
connectionManager: [ConnectionManager],
importCache: [Object]
}
},
_options: {
isNewRecord: false,
_schema: null,
_schemaDelimiter: '',
raw: true,
attributes: [
'id', 'firtName',
'lasteName', 'email',
'phone', 'password',
'createdAt', 'updatedAt'
]
},
isNewRecord: false
}
the code before the error:
models.User.findOne({where: {email: req.body.email}}).then((user)=>{
console.log(user)
if(!user) {
res.status(401).json({ message: 'Authentication failed!' });
} else {
user.comparePasswords(req.body.password, (error, isMatch) =>{
console.log(error + ' -- ' + isMatch)
if(isMatch && !error) {
const token = jwt.sign(
{ username: user.username },
keys.secret,
{ expiresIn: '30h' }
);
res.status(200).json({ success: true,message: 'signed in successfully', token: 'JWT ' + token });
} else {
res.status(401).json({ success: false, message: 'Login failed!' });
}
});
}
}).catch((error)=>{
console.log(error)
res.status(500).json({ success: false, message: 'There was an error!'});
})
this cause TypeError: user.comparePasswords is not a function
after changing this line:
** user.comparePasswords(req.body.password, (error, isMatch) =>{} **
to this:
** user._modelOptions.instanceMethods.comparePasswords(req.body.password, (error, isMatch) =>{}**
booooom! everything worked

Related

beforeBulkDestroy not finding model property to change

I am trying to use the beforeBulkDestory Sequelize hook on a user delete that will switch the deleted column boolean to true prior to updating the record to add a timestamp for deleted_at. However, when I console.log the function parameter it provides a list of options and not the model object that I can update for the record of focus. Am I approaching this the wrong way? Is this something that should be set using model instances?
API Call:
import db from '../../../models/index';
const User = db.users;
export default (req, res) => {
const {
query: { id },
} = req
console.log(User)
if (req.method === 'DELETE') {
User.destroy({
where: {
id: id
}
}).then(data => {
res.json({
message: 'Account successfully deleted!'
})
})
} else {
const GET = User.findOne({
where: {
id: id
}
});
GET.then(data => {
res.json(data)
})
}
}
Parameter Values (beforeBulkDestroy, afterBulkDestroy):
beforeBulkDestroy
{
where: { id: '5bff3820-3910-44f0-9ec1-e68263c0f61f' },
hooks: true,
individualHooks: false,
force: false,
cascade: false,
restartIdentity: false,
type: 'BULKDELETE',
model: users
}
afterDestroy
{
where: { id: '5bff3820-3910-44f0-9ec1-e68263c0f61f' },
hooks: true,
individualHooks: true,
force: false,
cascade: false,
restartIdentity: false,
type: 'BULKUPDATE',
model: users
}
Model (users.js):
'use strict';
const Sequelize = require('sequelize');
const { Model } = require('sequelize');
const bcrypt = require("bcrypt");
module.exports = (sequelize, DataTypes) => {
class users extends Model {
/**
* Helper method for defining associations.
* This method is not a part of Sequelize lifecycle.
* The `models/index` file will call this method automatically.
*/
static associate(models) {
// define association here
}
};
users.init({
id: {
type: DataTypes.UUID,
defaultValue: Sequelize.UUIDV4,
primaryKey: true
},
first_name: DataTypes.STRING,
last_name: DataTypes.STRING,
password: {
type: DataTypes.STRING
},
email: DataTypes.STRING,
active: {
type: DataTypes.BOOLEAN,
defaultValue: true
},
deleted: {
type: DataTypes.BOOLEAN,
defaultValue: false
}
}, {
hooks: {
beforeDestroy: (user, options) => {
console.log("beforeDestroy")
console.log(user)
console.log(options)
user.deleted = true
}
},
sequelize,
freezeTableName: true,
modelName: 'users',
omitNull: true,
paranoid: true,
underscored: true,
createdAt: 'created_at',
updatedAt: 'updated_at',
deletedAt: 'deleted_at',
hooks: {
beforeCreate: async function(user){
console.log("beforeCreate")
console.log(user)
const salt = await bcrypt.genSalt(12);
user.password = await bcrypt.hash(user.password, salt);
console.log(user.password)
},
beforeBulkDestroy: async function(user){
console.log("beforeBulkDestroy")
console.log(user)
},
afterBulkDestroy: async function(user){
console.log("afterDestroy")
console.log(user)
}
}
});
users.prototype.validPassword = async function(password) {
console.log("validatePassword")
console.log(password)
return await bcrypt.compare(password, this.password);
}
return users;
};
the before/after bulkDestroy hooks only receive the options, not the instances. One way you could do this is defining a before/after Destroy hook:
hooks: {
beforeDestroy: (user, { transaction }) => {
user.update({ deleted: true }, { transaction });
}
}
and calling User.destroy with the individualHooks option:
User.destroy({ where: { id: id }, individualHooks: true });
Be aware that this will load all selected models into memory.
Docs
Note: In your case, since you're only deleting one record by id, it would be better to just user = User.findByPk(id) then user.destroy(). This would always invoke the hooks and it also makes sure the record you want to delete actually exists.
Note 2: Not sure why you need a deleted column, you could just use deletedAt and coerce it into a boolean (with a virtual field if you want to get fancy).

Get error when trying to register new user or log in

For some reason whenever I make a request to the routes to create a new user I get "This email account is already in use" although the user is created, and when I try to log in I get "The login information was incorrect". I console logged the req.body when logging in and I get the object logged and it seems okay.
My AuthenticationController.js
const {User} = require('../models')
const jwt = require('jsonwebtoken')
const config = require('../config/config')
function jwtSignUser (user) {
const ONE_WEEK = 60 * 60 * 24 * 7
return jwt.sign(user, config.authentication.jwtSecret, {
expiresIn: ONE_WEEK
})
}
module.exports = {
async register (req, res) {
try {
const user = await User.create(req.body)
const userJson = user.toJSON()
res.send({
user: userJson,
token: jwtSignUser(userJson)
})
} catch (err) {
res.status(400).send('This email account is already in use.')
}
},
async login (req, res) {
console.log(req.body)
try {
const {email, password} = req.body
const user = await User.findOne({
where: {
email: email
}
})
if (!user) {
return res.status(403).send({
error: 'The login information was incorrect'
})
}
const isPasswordValid = await user.comparePassword(password)
if (!isPasswordValid) {
return res.status(403).send({
error: 'The login information was incorrect'
})
}
const userJson = user.toJSON()
res.send({
user: userJson,
token: jwtSignUser(userJson)
})
} catch (err) {
res.status(500).send({
error: 'An error has occured trying to log in'
})
}
}
}
console.log(user) gives me the following:
User {
dataValues:
{ id: 41,
username: 'testing',
email: 'testing#gmail.com',
password:
'$2a$08$J6/psKuCltiCpCll2rjz4OaCylud0zq/wKnjKK8Udmm.bFU3c2Tt6',
firstName: 'test',
lastName: 'ing',
createdAt: 2019-02-26T15:47:09.133Z,
updatedAt: 2019-02-26T15:47:09.133Z },
_previousDataValues:
{ id: 41,
username: 'testing',
email: 'testing#gmail.com',
password:
'$2a$08$J6/psKuCltiCpCll2rjz4OaCylud0zq/wKnjKK8Udmm.bFU3c2Tt6',
firstName: 'test',
lastName: 'ing',
createdAt: 2019-02-26T15:47:09.133Z,
updatedAt: 2019-02-26T15:47:09.133Z },
_changed: {},
_modelOptions:
{ timestamps: true,
validate: {},
freezeTableName: false,
underscored: false,
underscoredAll: false,
paranoid: false,
rejectOnEmpty: false,
whereCollection: { email: 'testing#gmail.com' },
schema: null,
schemaDelimiter: '',
defaultScope: {},
scopes: [],
indexes: [],
name: { plural: 'Users', singular: 'User' },
omitNull: false,
hooks:
{ beforeCreate: [Array],
beforeUpdate: [Array],
beforeSave: [Array] },
sequelize:
Sequelize {
options: [Object],
config: [Object],
dialect: [SqliteDialect],
queryInterface: [QueryInterface],
models: [Object],
modelManager: [ModelManager],
connectionManager: [ConnectionManager],
importCache: [Object],
test: [Object] },
uniqueKeys: { Users_email_unique: [Object] } },
_options:
{ isNewRecord: false,
_schema: null,
_schemaDelimiter: '',
raw: true,
attributes:
[ 'id',
'username',
'email',
'password',
'firstName',
'lastName',
'createdAt',
'updatedAt' ] },
__eagerlyLoadedAssociations: [],
isNewRecord: false }
console.log(req.body) gives me this:
{ email: 'testing#gmail.com',
password: 'testing99',
username: 'testing',
firstName: 'test',
lastName: 'ing' }
They have the same information but it gives me an error anyway.
I assume you are using mongoose, according to the documentation https://mongoosejs.com/docs/api.html#model_Model.findOne findOne is returning Query object, so validation may fail.
Check with debugger or even simple console.log to see what's inside of the user variable in login function.
So if user does not exist, you are getting Query object which is not empty, because mongoose filled this object with some functions.
You can try to use lean(), checkout this article http://www.tothenew.com/blog/high-performance-find-query-using-lean-in-mongoose-2/
We have 2 solution here:
Using raw: true
const user = await User.findOne({
where: {
email: email
},
raw: true
})
Using plain: true
user = user.get({
plain: true
});

Instance Methods is not working in Sequelize

I can't seem to set the User model properly. I've implemented some instance methods that don't seem to be working
var UserDetails = mysequelize.sequelize.define('user_tb', {
id: {
autoIncrement: true,
type: mysequelize.sequelize.Sequelize.INTEGER,
allowNull: false,
},
username: {
type: mysequelize.sequelize.Sequelize.STRING,
primaryKey: true,
unique: true,
},
hierarchyid: {
type: mysequelize.sequelize.Sequelize.STRING
},
password: {
type: mysequelize.sequelize.Sequelize.STRING,
validate: {
len: {
args: [6, 15],
msg: "Please enter a password with at least 6 chars but no more than 15"
}
},
allowNull: false
},
customerid: {
type: mysequelize.sequelize.Sequelize.INTEGER
},
statususer: {
type: mysequelize.sequelize.Sequelize.STRING,
allowNull: false
},
userid: {
unique: true,
type: mysequelize.sequelize.Sequelize.STRING,
allowNull: false
},
authtoken: {
unique: true,
type: mysequelize.sequelize.Sequelize.STRING,
allowNull: false
}
},
{
tableName: 'user_tb',
timestamps: false,
freezeTableName: true
});
UserDetails.prototype.toJSON = function(){
var user = this;
var userObject = user.toObject();
return _.pick(userObject,['userid','password']);
};
UserDetails.prototype.findByCredentials = function(userid, password)
{
console.log('Sunddep');
var User = this;
// return User.fin
User.findOne({userid}).then((user)=> {
if(!user)
{
return Promise.reject();
}
return new Promise((resolve,reject) => {
bcrypt.compare(password,user.password,(err,res) => {
if(res)
{
resolve(user);
}
else{
reject();
}
})
})
});
}
UserDetails.prototype.generateAuthToken = function()
{
var user = this;
var access = 'authtoken';
var token = jwt.sign({userid:
user.userid.toHexString(),access},process.env.JWT_SECRET).toString();
user.build({
access: token
});
user.save().then(() =>{
return token;
});
}
module.exports = {UserDetails}
server.js
app.post('/user/login', (req, res) => {
console.log(req.body);
var body = _.pick(req.body, ['userId', 'password']);
user.findByCredentials(body.userId, body.password).then(() => {
res.send('Sundeep');
},
(e) => {
sendData: ({
wsState: '0',
messageCode: 'WS000001',
message: 'No user find with this Id',
userData: []
});
res.status(400).send(sendData)
});
});
Hi, I am getting error while calling instance method from other class. Can any one tell me how can i achieve it
UserDetails.prototype.findByCredentials = function(userid, password) {.....}
But while run the server.js file i getting error like UserDetails.findByCredentials is not a function while calling from other class
Thanks for help in advance.

How to implement a follow system, return a list of followers and following users

In my application there are 4 features I need to implement:
A user can follow another user.
A user can unfollow another user.
A user can see a list of all of their followers.
A user can see a list of all whom they are following.
I believe I have implemented 1. and 2. correctly. I created a follow schema as you can see below in my follow.model and I have created follow.controller with two methods, to store (follow) and destroy (unfollow).
Now I want to to implement 3. and 4. I created two arrays in the user.model schema, one for following and one for followers. When I return the user in my user.controller, how do I populate the following and followers array? At the moment they are empty.
follow.model.js
var mongoose = require('mongoose'),
Schema = mongoose.Schema;
var FollowSchema = new Schema({
follower: {
type: Schema.Types.ObjectId,
ref: 'User'
},
followee: {
type: Schema.Types.ObjectId,
ref: 'User'
}
},
{
timestamps: {createdAt: 'created_at', updatedAt: 'updated_at'}
});
module.exports = mongoose.model('Follow', FollowSchema);
follow.controller.js
'use strict';
const User = require('../models/user.model');
const Follow = require('../models/follow.model');
class FollowController {
constructor() {
}
store(req, res) {
let follower = req.body.follower;
let followee = req.params.id;
let follow = new Follow({
follower: follower,
followee: followee,
});
follow.save(function (err) {
if (err) {
return res.status(404).json({
succes: false,
status: 404,
data: {},
message: "There was an error trying follow the user."
});
}
return res.status(200).json({
success: true,
status: 200,
data: follow,
message: 'Successfully followed user'
});
});
}
destroy(req, res) {
let follower = req.params.followerid;
let followee = req.params.id;
Follow.remove({ 'follower': follower, 'followee': followee }, (err, result) => {
if (err) {
return res.status(404).json({
success: false,
status: 404,
data: {},
message: "Error removing record"
});
}
return res.status(201).json({
success: true,
status: 201,
data: {},
message: "Successfully unfollowed user"
})
});
}
}
module.exports = FollowController;
user.model.js
let UserSchema = new Schema({
email: {
address: {
type: String,
lowercase: true,
//unique: true,
},
token: String,
verified: {
type: Boolean,
default: false,
},
},
password: {
type: String,
},
following: [{
type: Schema.Types.ObjectId, ref: 'Follow'
}],
followers: [{
type: Schema.Types.ObjectId, ref: 'Follow'
}],
{
timestamps: {createdAt: 'created_at', updatedAt: 'updated_at'}
});
user.controller.js
show(req, res) {
let id = req.params.id;
User.findOne({ '_id': id },
function (err, user) {
if (err) {
return res.json(err);
}
return res.json(user);
});
}
You just need to populate these fields:
User.findOne({ '_id': id }, (err, user) => {
if (err) return res.json(err);
return res.json(user);
}).populate([
{ path: 'following' },
{ path: 'followers' }
]);

Using BCrypt with Sequelize Model

I'm trying to use the bcrypt-nodejs package with my sequelize model and was tring to follow a tutorial to incorporate the hashing into my model, but I'm getting an error at generateHash. I can't seem to figure out the issue. Is there a better way to incorporate bcrypt?
Error:
/Users/user/Desktop/Projects/node/app/app/models/user.js:26
User.methods.generateHash = function(password) {
^
TypeError: Cannot set property 'generateHash' of undefined
at module.exports (/Users/user/Desktop/Projects/node/app/app/models/user.js:26:27)
at Sequelize.import (/Users/user/Desktop/Projects/node/app/node_modules/sequelize/lib/sequelize.js:641:30)
model:
var bcrypt = require("bcrypt-nodejs");
module.exports = function(sequelize, DataTypes) {
var User = sequelize.define('users', {
annotation_id: {
type: DataTypes.INTEGER,
autoIncrement: true,
primaryKey: true
},
firstName: {
type: DataTypes.DATE,
field: 'first_name'
},
lastName: {
type: DataTypes.DATE,
field: 'last_name'
},
email: DataTypes.STRING,
password: DataTypes.STRING,
}, {
freezeTableName: true
});
User.methods.generateHash = function(password) {
return bcrypt.hashSync(password, bcrypt.genSaltSync(8), null);
};
User.methods.validPassword = function(password) {
return bcrypt.compareSync(password, this.local.password);
};
return User;
}
Methods should be provided in the "options" argument of sequelize.define
const bcrypt = require("bcrypt");
module.exports = function(sequelize, DataTypes) {
const User = sequelize.define('users', {
annotation_id: {
type: DataTypes.INTEGER,
autoIncrement: true,
primaryKey: true
},
firstName: {
type: DataTypes.DATE,
field: 'first_name'
},
lastName: {
type: DataTypes.DATE,
field: 'last_name'
},
email: DataTypes.STRING,
password: DataTypes.STRING
}, {
freezeTableName: true,
instanceMethods: {
generateHash(password) {
return bcrypt.hash(password, bcrypt.genSaltSync(8));
},
validPassword(password) {
return bcrypt.compare(password, this.password);
}
}
});
return User;
}
Other alternative: Use hook and bcrypt async mode
User.beforeCreate((user, options) => {
return bcrypt.hash(user.password, 10)
.then(hash => {
user.password = hash;
})
.catch(err => {
throw new Error();
});
});
There's a tutorial out there on how to get a sequelize/postgreSQL auth system working with hooks and bcrypt.
The guy who wrote the tutorial did not use async hash/salt methods; in the user creation/instance method section he used the following code:
hooks: {
beforeCreate: (user) => {
const salt = bcrypt.genSaltSync();
user.password = bcrypt.hashSync(user.password, salt);
}
},
instanceMethods: {
validPassword: function(password) {
return bcrypt.compareSync(password, this.password);
}
}
Newer versions of Sequelize don't like instance methods being declared this way - and multiple people have explained how to remedy this (including someone who posted on the original tutorial):
The original comment still used the synchronous methods:
User.prototype.validPassword = function (password) {
return bcrypt.compareSync(password, this.password);
};
All you need to do to make these functions asyncronous is this:
Async beforeCreate bcrypt genSalt and genHash functions:
beforeCreate: async function(user) {
const salt = await bcrypt.genSalt(10); //whatever number you want
user.password = await bcrypt.hash(user.password, salt);
}
User.prototype.validPassword = async function(password) {
return await bcrypt.compare(password, this.password);
}
On the node.js app in the login route where you check the password, there's a findOne section:
User.findOne({ where: { username: username } }).then(function (user) {
if (!user) {
res.redirect('/login');
} else if (!user.validPassword(password)) {
res.redirect('/login');
} else {
req.session.user = user.dataValues;
res.redirect('/dashboard');
}
});
All you have to do here is add the words async and await as well:
User.findOne({ where: { username: username } }).then(async function (user) {
if (!user) {
res.redirect('/login');
} else if (!await user.validPassword(password)) {
res.redirect('/login');
} else {
req.session.user = user.dataValues;
res.redirect('/dashboard');
}
});
Bcrypt Is no longer part of node, so I included example with new module of crypto
I am sharing this code from one of working project.
My config file
require('dotenv').config();
const { Sequelize,DataTypes ,Model} = require("sequelize");
module.exports.Model = Model;
module.exports.DataTypes = DataTypes;
module.exports.sequelize = new Sequelize(process.env.DB_NAME,process.env.DB_USER_NAME, process.env.DB_PASSWORD, {
host: process.env.DB_HOST,
dialect: process.env.DB_DISELECT,
pool: {
max: 1,
min: 0,
idle: 10000
},
//logging: true
});
My user model
const { sequelize, DataTypes, Model } = require('../config/db.config');
var crypto = require('crypto');
class USERS extends Model {
validPassword(password) {
var hash = crypto.pbkdf2Sync(password,
this.SALT, 1000, 64, `sha512`).toString(`hex`);
console.log(hash == this.PASSWORD)
return this.PASSWORD === hash;
}
}
USERS.init(
{
ID: {
autoIncrement: true,
type: DataTypes.BIGINT,
allowNull: false,
primaryKey: true
},
MOBILE_NO: {
type: DataTypes.BIGINT,
allowNull: false,
unique: true
},
PASSWORD: {
type: DataTypes.STRING(200),
allowNull: false
},
SALT: {
type: DataTypes.STRING(200),
allowNull: false
}
},
{
sequelize,
tableName: 'USERS',
timestamps: true,
hooks: {
beforeCreate: (user) => {
console.log(user);
user.SALT = crypto.randomBytes(16).toString('hex');
user.PASSWORD = crypto.pbkdf2Sync(user.PASSWORD, user.SALT,
1000, 64, `sha512`).toString(`hex`);
},
}
});
module.exports.USERS = USERS;
And Auth Controller
const { USERS } = require('../../../models/USERS');
module.exports = class authController {
static register(req, res) {
USERS.create({
MOBILE_NO: req.body.mobile,
PASSWORD: req.body.password,
SALT:""
}).then(function (data) {
res.json(data.toJSON());
}).catch((err) => {
res.json({
error: err.errors[0].message
})
})
}
static login(req, res) {
var message = [];
var success = false;
var status = 404;
USERS.findOne({
where:{
MOBILE_NO: req.body.mobile
}
}).then(function (user) {
if (user) {
message.push("user found");
if(user.validPassword(req.body.password)) {
status=200;
success = true
message.push("You are authorised");
}else{
message.push("Check Credentials");
}
}else{
message.push("Check Credentials");
}
res.json({status,success,message});
});
}
}
Old question, but maybe can help someone, you can use sequelize-bcrypt
Example:
const { Sequelize, DataTypes } = require('sequelize');
const useBcrypt = require('sequelize-bcrypt');
const database = new Sequelize({
...sequelizeConnectionOptions,
});
const User = database.define('User', {
email: { type: DataTypes.STRING },
password: { type: DataTypes.STRING },
});
useBcrypt(User);
Usage
User.create({ email: 'john.doe#example.com', password: 'SuperSecret!' });
// { id: 1, email: 'john.doe#example.com', password: '$2a$12$VtyL7j5xx6t/GmmAqy53ZuKJ1nwPox5kHLXDaottN9tIQBsEB3EsW' }
const user = await User.findOne({ where: { email: 'john.doe#example.com' } });
user.authenticate('WrongPassword!'); // false
user.authenticate('SuperSecret!'); // true

Resources