beforeCreate hook changes are not saved to database - mysql

I am using the beforeCreate to encrypt password before saving to database.
When I do:
const user = await User.create({name, email, password});
res.json(user);
I see the encrypted password in response. But in the database the password is not encrypted. If I do user.reload() and then send, I see what's stored in the database(unencrypted password).
This is the model:
User.init({
name: {
type: DataTypes.STRING,
allowNull: false
},
...
},{
sequelize,
hooks: {
beforeCreate: (user, options) => {
return bcrypt.genSalt(10)
.then(salt => {
bcrypt.hash(user.password, salt)
.then(hashedPassword => {
user.password = hashedPassword;
console.log(user.password, "FS");
return user.password;
})
.catch(err => console.log(err));
})
.catch(err => console.log(err));
}
}
})
This is the controller:
try{
const {name, email, password} = req.body;
if(isEmpty(name) || isEmpty(email) || isEmpty(password)){
res.status(400).json({errMessage: 'Enter name, email and password'});
}
const user = await User.create({name, email, password});
res.json(user); //data with encrypted password is sent, but not saved in db
}

The beforeCreate hook does not need to return a value, the return value type of the function signature as follows:
export type HookReturn = Promise<void> | void;
Besides, you forgot to add return before bcrypt.hash(user.password, salt) statement causes the beforeCreate function not to wait for the encryption asynchronous operation to complete.
Here is a working example:
import { sequelize } from '../../db';
import { Model, DataTypes } from 'sequelize';
import bcrypt from 'bcrypt';
class User extends Model {
password!: string;
name!: string;
}
User.init(
{
name: {
type: DataTypes.STRING,
allowNull: false,
},
email: {
type: DataTypes.STRING,
allowNull: false,
},
password: {
type: DataTypes.STRING,
allowNull: false,
},
},
{
sequelize,
modelName: 'users',
hooks: {
beforeCreate: (user: User) => {
return bcrypt
.genSalt(10)
.then((salt) => {
return bcrypt
.hash(user.password, salt)
.then((hashedPassword) => {
user.password = hashedPassword;
})
.catch((err) => console.log(err));
})
.catch((err) => console.log(err));
},
},
},
);
(async function() {
try {
await sequelize.sync({ force: true });
await User.create({ name: 'ab', email: 'test#gmail.com', password: '123456' });
} catch (error) {
console.log(error);
} finally {
await sequelize.close();
}
})();
The execution log:
Executing (default): DROP TABLE IF EXISTS "users" CASCADE;
Executing (default): DROP TABLE IF EXISTS "users" CASCADE;
Executing (default): CREATE TABLE IF NOT EXISTS "users" ("id" SERIAL , "name" VARCHAR(255) NOT NULL, "email" VARCHAR(255) NOT NULL, "password" VARCHAR(255) NOT NULL, PRIMARY KEY ("id"));
Executing (default): SELECT i.relname AS name, ix.indisprimary AS primary, ix.indisunique AS unique, ix.indkey AS indkey, array_agg(a.attnum) as column_indexes, array_agg(a.attname) AS column_names, pg_get_indexdef(ix.indexrelid) AS definition FROM pg_class t, pg_class i, pg_index ix, pg_attribute a WHERE t.oid = ix.indrelid AND i.oid = ix.indexrelid AND a.attrelid = t.oid AND t.relkind = 'r' and t.relname = 'users' GROUP BY i.relname, ix.indexrelid, ix.indisprimary, ix.indisunique, ix.indkey ORDER BY i.relname;
Executing (default): INSERT INTO "users" ("id","name","email","password") VALUES (DEFAULT,$1,$2,$3) RETURNING *;
Check data record in the database:
node-sequelize-examples=# select * from users;
id | name | email | password
----+------+----------------+--------------------------------------------------------------
1 | ab | test#gmail.com | $2b$10$XQb89m.b6ie8ImokS6JPdurWfIH4Cq19y.XGhb7LpWYUklp5jaYh2
(1 row)

Related

when entering a new row in child table, how do i populate the foreign key ticketId using sequelize nodejs?

I am trying to figure out how I can populate the foreign key in my child table(subTaskTickets) from the parent table (Tickets).
When i create a Ticket, then I create a subTaskTicket, the ticketID and ETR_ID remain null and dont populate with the id from Ticket table.
Not sure how I can do this as i am new with sequelize, nodejs and mysql.
Here are my 2 modals:
SubTaskTicket model (child)
const Sequelize = require("sequelize-v5");
const sequelize = require("../connection");
//create a new Date object with the current date and time
const date = new Date();
//extract the year and month from the date
const year = date.getFullYear();
const month = date.getMonth() + 1;
//combine the year and month into a single string to be concat with id to form ETR_ID
const yearMonth = year.toString().concat("-", month.toString(), "-ST");
const SubTaskTicket = sequelize.define("subTaskTicket", {
id: {
type: Sequelize.INTEGER,
autoIncrement: true,
allowNull: false,
primaryKey: true
},
ETR_ID: {
type: Sequelize.STRING,
// primaryKey: true,
// defaultValue: ""
allowNull: true,
references: {
model: 'tickets',
key: 'ETR_ID'
}
},
subTaskId: {
type: Sequelize.STRING,
allowNull: false,
unique: true,
defaultValue: "",
primaryKey: true
},
Title: {
type: Sequelize.STRING,
allowNull: false
},
Description: {
type: Sequelize.STRING,
allowNull: false
},
Status: {
type: Sequelize.CHAR,
allowNull: false
},
ETR: {
type: Sequelize.STRING,
allowNull: false,
defaultValue: yearMonth
},
});
module.exports = SubTaskTicket;
Ticket model (Parent)
const Sequelize = require('sequelize-v5');
const sequelize = require('../connection');
//create a new Date object with the current date and time
const date = new Date();
//extract the year and month from the date
const year = date.getFullYear();
const month = date.getMonth()+1;
//combine the year and month into a single string to be concat with id to form ETR_ID
const yearMonth = year.toString().concat('-', month.toString(),'-');
const Tickets = sequelize.define('tickets', {
id: {
type: Sequelize.INTEGER,
autoIncrement: true,
allowNull: false,
primaryKey: true
},
ETR_CAT:{
type: Sequelize.STRING,
allowNull: false
},
ETR_ID: {
type: Sequelize.STRING,
primaryKey: true,
unique: true,
defaultValue: ""
},
Title: {
type: Sequelize.STRING,
allowNull: false
},
Description:{
type: Sequelize.STRING,
allowNull: false
},
ETR: {
type: Sequelize.STRING,
allowNull: false,
defaultValue: yearMonth
}
});
module.exports = Tickets;
Here is my app.js file containing express etc:
const express = require("express");
const cors = require("cors");
const app = express();
const sequelize = require("./connection");
const Tickets = require("./models/ticket.model");
const SubTaskTicket = require('./models/subTaskTicket.model');
var corsOptions = {
origin: "http://localhost:8081"
};
app.use(cors(corsOptions));
// parse requests of content-type - application/json
app.use(express.json());
// parse requests of content-type - application/x-www-form-urlencoded
app.use(express.urlencoded({ extended: true }));
// simple route
app.get("/", (req, res) => {
res.json({ message: "Welcome to Tylers application." });
});
require("./routes/ticket.routes")(app);
Tickets.hasMany(SubTaskTicket, {
as: 'subtaskticket'
});
SubTaskTicket.belongsTo(Tickets);
Tickets.hasMany(SubTaskTicket);
//will create tables from our modals, but also define relations in our DB
// sync() command for dev, add { force: true } so i can remake tables from scratch right away
sequelize.sync().then(result => {
console.log(result);
// set port, listen for requests
const PORT = process.env.PORT || 8080;
app.listen(PORT, () => {
console.log(`Server is running on port ${PORT}.`);
});
})
.catch(err => {
console.log(err);
});
Next are my 2 controllers for each model:
subTaskTicket controller
const Sequelize = require("sequelize-v5");
const sequelize = require("../connection");
const subTaskTicket = require("../models/subTaskTicket.model");
//Sequelized create format
exports.createTicket = (req, res, next) => {
const Title = req.body.Title;
const Description = req.body.Description;
const Status = req.body.Status;
// const ETR = req.body.ETR;
subTaskTicket.create({
Title: Title,
Status: Status,
Description: Description,
//ETR: ETR
})
.then(result => {
//console.log(result);
console.log("Created Ticket");
sequelize.query('update subtasktickets set subTaskId = concat(ETR,id)');
})
.catch(err => {
console.log(err);
})
}
//Sequelized findAll
exports.findAllTickets = (req, res, next) => {
subTaskTicket.findAll({include: ["subtaskticket"]})
.then(data => {
res.send(data);
}).catch(err => {
console.log(err);
});
}
// Sequelized Find a single Tutorial with a id
exports.findOneTicket = (req, res) => {
const id = req.params.id;
subTaskTicket.findByPk(id)
.then(data => {
if (data) {
res.send(data);
} else {
res.status(404).send({
message: 'Cannot find Child Ticket with id = ' + id
});
}
})
.catch(err => {
res.status(500).send({
message: 'Error retrieving child Ticket with id= ' + id
});
});
};
//Sequilized Update Ticket identified by the id in the req
exports.updateTicket = (req, res) => {
const id = req.params.id;
subTaskTicket.update(req.body, {
where: { id: id }
})
.then(num => {
if (num == 1) {
res.send({
message: "Child Ticket was updated successfully."
});
} else {
res.send({
message: `Cannot update Child Ticket with id=${id}. Maybe Child Ticket was not found or req.body is empty!`
});
}
})
.catch(err => {
res.status(500).send({
message: "Error updating Ticket with id=" + id
});
});
};
// Sequilized Delete a Ticket with the specified id in the request
exports.deleteTicket = (req, res) => {
const id = req.params.id;
subTaskTicket.destroy({
where: { id: id }
})
.then(num => {
if (num == 1) {
res.send({
message: "Child Ticket was deleted successfully!"
});
} else {
res.send({
message: `Cannot delete Child Ticket with id= ${id}. Maybe Child Ticket was not found!`
});
}
})
.catch(err => {
res.status(500).send({
message: "Could not delete Ticket with id=" + id
});
});
};
ticket.controller
const Sequelize = require("sequelize-v5");
const sequelize = require("../connection");
const Tickets = require("../models/ticket.model");
const { Op } = require("sequelize-v5");
//Sequelized create format
exports.createTicket = (req, res, next) => {
const ETR_CAT = req.body.ETR_CAT;
const Title = req.body.Title;
const Description = req.body.Description;
const ticketId = req.body.ticketId
Tickets.create({
ETR_CAT: ETR_CAT,
Title: Title,
Description: Description,
})
.then(result => {
//console.log(result);
console.log("Created Ticket");
sequelize.query('update tickets set ETR_ID = concat(ETR,id)');
})
.catch(err => {
console.log(err);
})
}
//Sequelized findAll
exports.findAllTickets = (req, res, next) => {
Tickets.findAll({include: ["subtaskticket"]})
.then(data => {
res.send(data);
}).catch(err => {
console.log(err);
});
}
// Sequelized Find a single Tutorial with a id
exports.findOneTicket = (req, res) => {
const id = req.params.id;
Tickets.findByPk(id, {include: ["subtaskticket"]})
.then(data => {
if (data) {
res.send(data);
} else {
res.status(404).send({
message: 'Cannot find Ticket with id = ' + id
});
}
})
.catch(err => {
res.status(500).send({
message: 'Error retrieving Ticket with id= ' + id
});
});
};
//Sequilized Update Ticket identified by the id in the req
exports.updateTicket = (req, res) => {
const id = req.params.id;
Tickets.update(req.body, {
where: { id: id }
})
.then(num => {
if (num == 1) {
res.send({
message: "Ticket was updated successfully."
});
} else {
res.send({
message: `Cannot update Ticket with id=${id}. Maybe Ticket was not found or req.body is empty!`
});
}
})
.catch(err => {
res.status(500).send({
message: "Error updating Ticket with id=" + id
});
});
};
// Sequilized Delete a Ticket with the specified id in the request
exports.deleteTicket = (req, res) => {
const id = req.params.id;
Tickets.destroy({
where: { id: id }
})
.then(num => {
if (num == 1) {
res.send({
message: "Ticket was deleted successfully!"
});
} else {
res.send({
message: `Cannot delete Ticket with id= ${id}. Maybe Ticket was not found!`
});
}
})
.catch(err => {
res.status(500).send({
message: "Could not delete Ticket with id=" + id
});
});
};
and this is my routes:
module.exports = app => {
const tickets = require("../controllers/ticket.controller");
const subTaskTicket = require("../controllers/subTaskTicket.controller")
var router = require("express").Router();
// Create a new Tutorial
router.post("/addTicket", tickets.createTicket);
router.post("/addSubTicket", subTaskTicket.createTicket);
// Retrieve all Tickets
router.get("/allTickets", tickets.findAllTickets);
// Retrieve a single Ticket with id
router.get("/ticket/:id", tickets.findOneTicket);
// Update a Ticket with id
router.put("/updateTicket/:id", tickets.updateTicket);
// Delete a Ticket with id
router.delete("/deleteTicket/:id", tickets.deleteTicket);
// // Delete all Tickets
// router.delete("/", tickets.deleteAll);
app.use("/api/tickets", router);
};
Any ideas on what i am missing or how I can create a row in the subTaskTicket table that would populate the foreign keys with the proper id?
when i integrate this with a frontend (angular) I want Ticket to be the main ticket (ex has id =1) and then i can create "sub tickets" that would be tasks under that main ticket. So they would populate the subtaskticket table and be tied into that parent Ticket with the id = 1.
Any help would be appreciated! as i am stuck and trying to figure this out while using sequelize
Below is the query that is generated when i run my nodemon command. This is using sequelize.sync() in app.js to make the tables when i first create it.
Executing (default): CREATE TABLE IF NOT EXISTS `tickets` (`id` INTEGER NOT NULL auto_increment , `ETR_CAT` VARCHAR(255) NOT NULL, `ETR_ID` VARCHAR(255) DEFAULT '' UNIQUE , `Title` VARCHAR(255) NOT NULL, `Description` VARCHAR(255) NOT NULL, `ETR` VARCHAR(255) NOT NULL DEFAULT '2022-12-', `createdAt` DATETIME NOT NULL, `updatedAt` DATETIME NOT NULL, PRIMARY KEY (`id`, `ETR_ID`)) ENGINE=InnoDB;
Executing (default): SHOW INDEX FROM `tickets`
Executing (default): CREATE TABLE IF NOT EXISTS `subTaskTickets` (`id` INTEGER NOT NULL auto_increment , `ETR_ID` VARCHAR(255), `subTaskId` VARCHAR(255) NOT NULL DEFAULT '' UNIQUE , `Title` VARCHAR(255) NOT NULL, `Description` VARCHAR(255) NOT NULL, `Status` CHAR(255) NOT NULL, `ETR` VARCHAR(255) NOT NULL DEFAULT '2022-12-ST', `createdAt` DATETIME NOT NULL, `updatedAt` DATETIME NOT NULL, `ticketId` INTEGER, PRIMARY KEY (`id`, `subTaskId`), FOREIGN KEY (`ETR_ID`) REFERENCES `tickets` (`ETR_ID`)) ENGINE=InnoDB;
Executing (default): SHOW INDEX FROM `subTaskTickets`
You need to choose only one auto-generated column as a primary key in both models
You need to indicate a foreign key column in associations explicitly (and the same for both paired associations) since you use the non-default name for it:
Tickets.hasMany(SubTaskTicket, {
foreignKey: 'ETR_ID'
});
SubTaskTicket.belongsTo(Tickets, {
foreignKey: 'ETR_ID'
});

Sequelize: beforeCreate hook not updating hashed password

I am trying to save the hashed password using beforeCreate hook. However, the hashed that I generate doesn't get saved but instead saves the plain text version.
This what my UserAuth model looks like
interface IUserAuthAttributes {
user_auth_id: number;
username: string;
password: string;
full_name: string;
disable_user: number;
user_level_id: number;
created_modified: string | Date;
}
interface IUserAuthCreationAttributes
extends Optional<IUserAuthAttributes, 'user_auth_id' | 'disable_user' | 'user_level_id' | 'created_modified'> {
username: string;
password: string;
full_name: string;
}
export class UserAuth
extends Model<IUserAuthAttributes, IUserAuthCreationAttributes>
implements IUserAuthAttributes {
public user_auth_id!: number;
public username!: string;
public password!: string;
public full_name!: string;
public disable_user: number;
public user_level_id!: number;
public created_modified: string | Date;
public toUserJSON: () => UserAuth;
public generateAccessToken: (payload: IUser) => string;
public generateRefreshToken: (payload: IUser) => string;
public passwordMatch: (pw: string, cb: (err: any, isMatch?: any) => void) => void;
public getRole: () => 'meter_reader' | 'evaluator' | null;
}
UserAuth.init({
user_auth_id: {
autoIncrement: true,
type: DataTypes.INTEGER.UNSIGNED,
allowNull: false,
primaryKey: true
},
username: {
type: DataTypes.STRING(20),
allowNull: false,
defaultValue: ""
},
password: {
type: DataTypes.STRING(100),
allowNull: false,
defaultValue: ""
},
full_name: {
type: DataTypes.STRING(100),
allowNull: false,
defaultValue: ""
}
// ... other
},
{
sequelize: DBInstance,
tableName: 'user_auth',
timestamps: false,
});
This is how I defined the hook:
UserAuth.beforeCreate((user, option) => {
const salt = bcrypt.genSaltSync();
// Using hashSync throws an error "Illegal arguments: undefined, string"
// const hash = bcrypt.hashSync(user.password, salt);
bcrypt.hash("password", salt, (err, hash) => {
if (err) throw new Error(err.message);
console.log('HASH -------', hash);
user.password = hash;
});
});
When I create a user:
const { username, password, full_name } = req.body;
const user = await UserAuth.create({
username, password, full_name
});
Upon logging the hashed value to the console, I indeed generate one successfully
HASH ------- $2a$10$KN.OSRXR7Od8WajjuD3hyutqk1tGS/Be.V9NDrm3F7fyZWxYAbJ/2
Finally found the solution.
In my previous code I was using a callback for the generating salt and hash. Also from the previous code
const hash = bcrypt.hashSync(user.getDataValue('password'), salt); it was throwing an error Illegal arguments: undefined, string because user.password returns undefined from the Instance, so instead, I get the value of the password using getDataValue method of the instance then using setDataValue to set the hashed password instead of using an assignment operation user.password = hash
UserAuth.beforeCreate((user, option) => {
if (user.isNewRecord) {
const salt = bcrypt.genSaltSync();
const hash = bcrypt.hashSync(user.getDataValue('password'), salt);
// user.password = hash; Not working
user.setDataValue('password', hash); // use this instead
}
})

Nodejs Sequelize and passport Js, stuck on executing query when registing user

this is the problem I am having:
I have 3 models(users,favorites,cryptocoins)
'use strict';
const { Model} = require('sequelize');
module.exports = (sequelize, DataTypes) => {
class Cryptocoin 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
}
}
Cryptocoin.init({
coinId:{
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: DataTypes.INTEGER
},
coinName: DataTypes.STRING,
coinPrice: DataTypes.INTEGER,
coinAmount: DataTypes.INTEGER,
totalValue: DataTypes.STRING,
boughtOn: DataTypes.DATE
}, {
sequelize,
modelName: 'Cryptocoin',
});
return Cryptocoin;
};
'use strict';
const { Model } = require('sequelize');
module.exports = (sequelize, DataTypes) => {
class Favorite 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
}
}
Favorite.init({
favoriteId: {
type:DataTypes.INTEGER,
primaryKey:true,
autoIncrement:true,
},
userId:{
type:DataTypes.INTEGER,
references:{
model:'Users',
key:'userId',
},
onDelete:'CASCADE',
},
coinId:{
type:DataTypes.INTEGER,
references:{
model:'Cryptocoins',
key:'coinId',
},
onDelete:'CASCADE',
},
}, {
sequelize,
modelName: 'Favorite',
});
return Favorite;
};
'use strict';
const { Model} = require('sequelize');
module.exports = (sequelize, DataTypes) => {
class User 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) {
}
}
User.init({
userId: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: DataTypes.INTEGER
},
userName: DataTypes.STRING,
passWord: DataTypes.STRING
}, {
sequelize,
modelName: 'User',
});
return User;
};
These all have migrations which work.
Now I have passport.js file which holds the passport stategies
const bcrypt = require('bcrypt');
module.exports = function (passport, Auth) {
const LocalStrategy = require('passport-local').Strategy;
passport.use('local-signup', new LocalStrategy(
{
usernameField: 'username',
passwordField: 'password',
passReqToCallback: true // allows us to pass back the entire request to the callback
}, function (req, username, password, done) {
console.log("Signup for - ", username)
const generateHash = function (password) {
return bcrypt.hashSync(password, bcrypt.genSaltSync(8), null);
}
Auth.findOne({
where: {
userName: username
}
}).then(function (user) {
//console.log(user);
if (user) {
return done(null, false, {
message: 'That username is already taken'
});
} else {
const userPassword = generateHash(password);
const data = {
username: username,
password: userPassword,
};
Auth.create(data).then(function (newUser, created) {
if (!newUser)return done(null, false);
if (newUser) return done(null, newUser)
});
}
});
}
));
This file is called via app.js like so
just a snippet of the code in app.js
const models = require('./models');
app.use(session({
genid: (req) => {
return uuid.v1();
},
name: 'Crypto-session',
store:new fileStore(),
secret: '------',
resave:false,
saveUninitialized:false,
}))
app.use(passport.initialize());
app.use(passport.session());
require('./config/passport')(passport,models.User);
Now when going to my /register route and inputing a username and password this is what happens
Signup for - randomUser
Executing (default): SELECT `userId`, `userName`, `passWord`, `createdAt`, `updatedAt` FROM `Users` AS `User` WHERE `User`.`userName` = 'randomUser' LIMIT 1;
Executing (default): INSERT INTO `Users` (`userId`,`createdAt`,`updatedAt`) VALUES (DEFAULT,?,?);
And it's stuck at the executing (default) part, It gets uploaded to the database but without any username or password, console logging both of them shows they are being populated with values from my form.
Any idea how I can fix this issue ?
note: I am fairly new to express and nodeJs in general.
Answer: After brainstorming and reading docs a bit these where the issues.
Ensure the deserializeUser function is either await or then based e.g
// deserialize user
passport.deserializeUser(function (id, done) {
Auth.findByPk(id).then(function (user) {
if (user) {
done(null, user.get());
} else {
done(user.errors, null);
}
});
});
Ensure you have a redirect in you route.post method e.g
// route for register action
app.post('/register',passport.authenticate('local-signup',{ successRedirect: '/',
failureRedirect: '/register' }),function (req, res) {
});
Ensure all of your passport js fields match the database fields e.g
I had username and password, but in my database it is userName and passWord.
changing these like so
const data = {
userName: username,
passWord: userPassword,
};
Uploads everything to the database.

How to use sequelize to fetch object data?

I am trying to implement Sequelize as an ORM in NodeJs and I am using it for Mysql,
I have 3 tables in the sample -
1. Role
2. User (Has a role)
3. Code (IsCreated by a user)
I'm unable to query the tables/models properly,
As I should be receiving an model representation of a table, which is referred as a foreign key.
Following is my DB structure -
1. Role table -
2. User table -
3. Code table -
Following are the table creation queries -
1. Role -
CREATE TABLE role (
id int(11) NOT NULL AUTO_INCREMENT,
name varchar(100) NOT NULL,
PRIMARY KEY (id)
);
2. User -
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(100) NOT NULL,
`email` varchar(100) NOT NULL,
`role` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `role` (`role`),
CONSTRAINT `user_ibfk_1` FOREIGN KEY (`role`) REFERENCES `role` (`id`)
);
3. Code -
CREATE TABLE `code` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(100) NOT NULL,
`createdBy` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `createdBy` (`createdBy`),
CONSTRAINT `code_ibfk_1` FOREIGN KEY (`createdBy`) REFERENCES `user` (`id`)
);
Following is my app.js file -
const db = require('./db');
const Code = require('./code');
const User = require('./user');
const Role = require('./role');
const async = require('async');
async.waterfall([
function(callback) {
db
.authenticate()
.then(() => {
console.log('Connection has been established successfully.');
callback(null,"ok");
})
.catch(err => {
return callback(err,null);
});
},
function(resp,callback) {
Code.findAll({include: [{ model: User}]})
.then(code => {
console.log("All users:", JSON.stringify(code, null, 4));
callback(null,"ok");
})
.catch(err => {
callback(err,null);
});
// Code.findOne({
// where: {
// id: 1
// }
// })
// .then(code => {
// console.log("All users:", JSON.stringify(code, null, 4));
// })
// .catch(err => console.log("Error => \n",err));
},
],
function(err, resp) {
if (err) {
console.log(err);
} else {
console.log(resp);
}
});
Following is my db.js file -
const Sequelize = require('sequelize');
module.exports = new Sequelize('junit', 'root', 'root', {
host: 'localhost',
/* one of 'mysql' | 'mariadb' | 'postgres' | 'mssql' */
dialect: 'mysql',
//operatorsAliases: false,
pool: {
max: 5,
min: 0,
acquire: 30000,
idle: 10000
}
});
Following is my role.js file -
const Sequelize = require('sequelize');
const db = require('./db');
const User = require('./user');
const Role = db.define('role', {
id: {
type: Sequelize.INTEGER,
primaryKey: true,
allowNull:false,
autoIncrement: true
},
name: {
type: Sequelize.STRING
}
}, {
tableName: 'role',
freezeTableName: true,
timestamps: false
});
associate : (models) => {
Role.hasMany(models.User,{
foreignKey: 'role'
});
};
module.exports = Role;
Following is my user.js file -
const Sequelize = require('sequelize');
const db = require('./db');
const Code = require('./code');
const Role = require('./role');
const User = db.define('user', {
id: {
type: Sequelize.INTEGER,
primaryKey: true,
allowNull:false,
autoIncrement: true
},
name: {
type: Sequelize.STRING
},
email: {
type: Sequelize.STRING
},
role: {
type: Sequelize.INTEGER,
references: {
// This is a reference to another model
model: Role,
// This is the column name of the referenced model
key: 'id'
}
}
}, {
tableName: 'user',
freezeTableName: true,
timestamps: false
});
associate : (models) => {
User.hasMany(models.Code,{
foreignKey: 'createdBy'
});
User.belongsTo(models.Role,{
foreignKey: 'role'
});
};
module.exports = User;
Following is my code.js file -
const Sequelize = require('sequelize');
const db = require('./db');
const User = require('./user');
//one-to-many
const Code = db.define('code', {
id: {
type: Sequelize.INTEGER,
primaryKey: true,
allowNull:false,
autoIncrement: true
},
name: {
type: Sequelize.STRING
},
// createdBy: {
// type: Sequelize.INTEGER
// },
createdBy: {
type: Sequelize.INTEGER,
references: {
// This is a reference to another model
model: User,
// This is the column name of the referenced model
key: 'id'
}
}
}, {
tableName: 'code',
freezeTableName: true,
timestamps: false
});
associate : (models) => {
Code.belongsTo(models.User,{
foreignKey: 'createdBy'
});
};
module.exports = Code;
When I run the app.js file I can't see the model reference of User,
But I get the usual Integer value, Can someone please help on how to properly use the Model here?
Error trace -
Looks like you're trying to fetch Code when connection wasn't established yet.
Try this:
const db = require('./db');
const Code = require('./code');
const User = require('./user');
const Role = require('./role');
function run() {
return db
.authenticate()
.then(() => Code.findOne({ // you can try execute whenever query you want here
where: {
id: 1
}})
.then(code => {
console.log("All users:", JSON.stringify(code, null, 4));
})
.catch(err => console.log("Error => \n",err)))
.catch(err => {
console.error('Unable to connect to the database:', err);
});
}
run();

PassportJS Executing the wrong Database Query

I am running into an issue where my PassportJS code is issuing the exact same query (using sequelize) every time I login regardless of the username and password being inputted and as a result I am successfully logged in each time. I feel like the issue is within my localStrategy code, but I can't seem to tell.
For Instance: I am logging in with user_id=3, email=test3#gmail.com, password=test
and this is the resulting sql output:
Executing (default): SELECT `user_id`, `first_name` AS `firstName`, `last_name` AS `lastName`, `email`, `password`, `createdAt`, `updatedAt` FROM `user` AS `user` WHERE `user`.`user_id` = 1;
It shouldn't be querying user_id=1 and was never checking the values in the input because the successful redirect for the login route is being triggered.
Here is my passport configuration and routing:
var express = require('express');
var siteRoutes = express.Router();
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
var models = require('../models/db-index');
/*==== Passport Configuration ====*/
// Serialize sessions
passport.serializeUser(function(user, done) {
console.log(user.user_id + "Serializing");
done(null, user.user_id);
});
passport.deserializeUser(function(user_id, done) {
models.User.find({where: {user_id: user_id}}).then(function(user){
done(null, user);
}).error(function(err){
done(err, null);
});
});
passport.use('local', new LocalStrategy({
passReqToCallback : true,
usernameField: 'email'
},
function(req, email, password, done) {
console.log(req.body.email);
console.log(req.body.password);
//Find user by email
models.User.findOne({
email: req.body.email,
password: req.body.password
}).then(function(user) {
return done(null, user);
})
.catch(function(err) {
return done(null, false, req.flash('message', 'Email not found.'));
});
}
));
/*==== Login ====*/
siteRoutes.route('/login')
.get(function(req, res){
res.render('pages/login.hbs');
})
.post(passport.authenticate('local', {
successRedirect: '/',
failureRedirect: '/sign-up',
failureFlash: true
}));
siteRoutes.route('/sign-up')
.get(function(req, res){
res.render('pages/sign-up.hbs');
})
.post(function(req, res){
models.User.create({
firstName: req.body.firstName,
lastName: req.body.lastName,
email: req.body.email,
password: req.body.password
}).then(function() {
res.redirect('/');
}).catch(function(error){
res.send(error);
})
});
module.exports = siteRoutes;
User Model:
var bcrypt = require('bcrypt-nodejs');
module.exports = function(sequelize, DataTypes) {
var User = sequelize.define('user', {
user_id: {
type: DataTypes.INTEGER,
autoIncrement: true,
primaryKey: true
},
firstName: {
type: DataTypes.STRING,
field: 'first_name'
},
lastName: {
type: DataTypes.STRING,
field: 'last_name'
},
email: {
type: DataTypes.STRING,
unique: true
},
password: DataTypes.STRING,
}, {
freezeTableName: true
});
return User;
}
the model variable is just a connector file for my various models. Please let me know if seeing that code would help