email verification from database using express js node js and angular 6 with mysql database - mysql

i am creating a user, with 'email' field so i want to verify whether that email is already exist or not, if exists error must display. i have my code in express js, node js, angular 6 and mysql database and below is the code to create new user
exports.create = (req, res) => {
// Save to MySQL database
let customer = req.body;
Customer.create(customer).then(result => {
// Send created customer to client
res.json(result);
});
};
where should i use if statement in above code
Thanks in advance

I'm thinking the simplest way of solving your problem is making the email column in the database unique. If you try to insert a new user with an already existing email the query will fail.
Another solution would be that you first do a query that looks in the database if an already existing user has the email (from req.body.email). But that would require having two different SQL queries, which I personally would not prefer.

i think you are using Sequelize ORM.
You can do like this
Customer.findOrCreate({
where: {
email: req.body.email,
},
// other datas needs to inserted
defaults: {
name: req.body.name,
username: req.body.username,
},
}).spread((data, created) => {
if (created) {
// your logics
} else {
res.status(400).send(`${req.body.email} already exists.`);
}
});

Related

How to store n number of inputs into an array using mysql in express.js

Hi I a beginner to the web development
I wanted to accept n number of the instance(n is inputted by the user) from the user and then store those values in an array-like structure so that my frontend can have access to it. Can this be done using mysql ?. I was reading StackOverflow posts that mentioned that it is not a good idea to use MySQL for this. However I am already kind of deep into my project so I want to clarify this.
Is this feasible using MySQL?
I guess you want to store something like object or array of something
let's say that in your front end there is a form with input and button
where the input is Add More Columns and the input is value so in your backend you will get an array of objects like
[
{ question: '1', answer: 'Answer1' },
{ question: '2', answer: 'Answer2' },
{ question: '3', answer: 'Answer3' },
{ question: '4', answer: 'Answer4' }
]
you can make a table
id | userId | payload
where id is generated by SQL
userId that you injected in the token (or something else to relate the user with his payloads)
and payload that contains the information that you need to store
const saveUserPayLoads = async (req, res) => {
const { payloads } = req.body;
const { id } = req.user
const data = []
for(payload of payloads) data.push(DBModule.create({ payload: JSON.stringify(payload), userId: id }))
return res.status(201).json({
message: 'Done',
success: true,
data
})
}

Hooks not triggering when inserting raw queries via sequelize.query()

I have the following Employee model for a MySQL database:
var bcrypt = require('bcrypt');
module.exports = (sequelize, DataTypes) => {
const Employee = sequelize.define(
"Employee",
{
username: DataTypes.STRING,
password: DataTypes.STRING,
}, {}
);
return Employee;
};
Seeding the database is done by reading a .sql file containing 10,000+ employees via raw queries:
sequelize.query(mySeedingSqlFileHere);
The problem is that the passwords in the SQL file are plain text and I'd like to use bcrypt to hash them before inserting into the database. I've never done bulk inserts before so I was looking into Sequelize docs for adding a hook to the Employee model, like so:
hooks: {
beforeBulkCreate: (employees, options) => {
for (employee in employees) {
if (employee.password) {
employee.password = await bcrypt.hash(employee.password, 10);
}
}
}
}
This isn't working as I'm still getting the plain text values after reseeding - should I be looking into another way? I was looking into sequelize capitalize name before saving in database - instance hook
Your hooks won't be called until you use model's function for DB operation , so if you are running raw query , hooks will never be fired,
Reason : You can write anything inside your raw query , select/insert/update/delete anything , how does sequelize.js know that
it has to fire the hooks. This is only possible when you use methods
like
Model.create();
Model.bulkCreate();
Model.update();
Model.destroy;
And as per DOC raw query doesn't have hooks option to add.
And for MODEL queries you can check that it has option to
enable/disable hook.

How to use Auth0's custom database to add a user to a MySQL database?

I am using Auth0 for a login service but I have a need to add a user to a database in MySQL every time an account is registered through Auth0.
They give this following script template but I am a newbie and need help debugging and understanding it. My specific questions are detailed as comments:
function create(user, callback) {
var connection = mysql({
host: 'localhost', //what should this be?
user: 'KNOWN/Understood',
password: 'KNOWN/Understood',
database: 'KNOWN/Understood'
});
connection.connect();
var query = "INSERT INTO users SET ?"; //what does this do?
bcrypt.hash(user.password, 10, function (err, hash) { //what does this do?
if (err) { return callback(err); }
var insert = {
password: hash,
email: user.email
};
connection.query(query, insert, function (err, results) {
if (err) return callback(err);
if (results.length === 0) return callback();
callback(null);
});
});
}
Is there anything else I need to change for this script or understand or call in for it to work?
I often get the error missing username for Database connection with requires_username enabled and I'm unsure what this means.
I'm assuming you already went through this tutorial on custom databases so let's address your specific questions.
host: 'localhost' // What should this be?
This and the other properties of this object define the way to connect to your custom MySQL database. The database needs to be reached from within Auth0 servers so this needs to be a host name accessible from the Internet.
"INSERT INTO users SET ?"; // What does this do?
This defines an SQL insert command that uses ? as a placeholder for later substitution.
If you see where this query is later used, you will noticed it's invoked with an additional insert object parameter that will cause the above query to be expanded into something like:
INSERT INTO users SET email = 'user#example.com', password = 'asdf34ASws'
bcrypt.hash(user.password, 10, function (err, hash) // What does this do?
This hashes the user provided password so that it's not stored in plain text in the database.
If you chose to require a username in addition to email you need to address this in your custom scripts as I believe the default templates assume that only email will be used.
This means that when creating the user in your database you also need to store the username and in the script to verify a user you also need to return the username.

Sequelize.js Node.js: How to Pass Already Created Object to Create Many-to-Many relationship?

From this post: Node.js / Sequelize.js / Express.js - How to insert into many-to-many association? (sync/async?)
The answer show only when you create Individual and Email, however, I want to create an Individual with an already created email.
Original answer to correctly create Individual and Email after one another:
models.Individual.create({
name: "Test"
}).then(function(createdIndividual) { // note the argument
models.Email.create({
address: "test#gmail.com"
}).then(function(createdEmail) { // note the argument
createdIndividual.addEmail(createdEmail)
.then(function(addedEmail) { // note th-- well you get the idea :)
console.log("Success");
});
})
});
To create an individual with an already created email, I modified into this:
models.Individual.create({
name: "Test"
}).then(function(createdIndividual) { // note the argument
//This email id exists in the Email table.
var email = {
id: 1
}
createdIndividual.addEmail(email)
.then(function(addedEmail) {
console.log("Success");
});
});
Then I got this error:
Unhandled rejection TypeError: val.replace is not a function
at Object.SqlString.escape (/Users/Roller/Working/Web/ponds_web/node_modules/sequelize/lib/sql-string.js:63:15)
at Object.QueryGenerator.escape (/Users/Roller/Working/Web/ponds_web/node_modules/sequelize/lib/dialects/abstract/query-generator.js:977:22)
at /Users/Roller/Working/Web/ponds_web/node_modules/sequelize/lib/dialects/abstract/query-generator.js:2203:23
at Array.map (native)
at Object.QueryGenerator.whereItemQuery (/Users/Roller/Working/Web/ponds_web/node_modules/sequelize/lib/dialects/abstract/query-generator.js:2202:49)
at /Users/Roller/Working/Web/ponds_web/node_modules/sequelize/lib/dialects/abstract/query-generator.js:1903:25
at /Users/Roller/Working/Web/ponds_web/node_modules/sequelize/node_modules/lodash/lodash.js:4389:15
at baseForOwn (/Users/Roller/Working/Web/ponds_web/node_modules/sequelize/node_modules/lodash/lodash.js:2652:24)
at Function.forOwn (/Users/Roller/Working/Web/ponds_web/node_modules/sequelize/node_modules/lodash/lodash.js:12254:24)
at Object.QueryGenerator.whereItemsQuery (/Users/Roller/Working/Web/ponds_web/node_modules/sequelize/lib/dialects/abstract/query-generator.js:1902:9)
at Object.QueryGenerator.getWhereConditions (/Users/Roller/Working/Web/ponds_web/node_modules/sequelize/lib/dialects/abstract/query-generator.js:2337:19)
at Object.QueryGenerator.selectQuery (/Users/Roller/Working/Web/ponds_web/node_modules/sequelize/lib/dialects/abstract/query-generator.js:1451:28)
at QueryInterface.select (/Users/Roller/Working/Web/ponds_web/node_modules/sequelize/lib/query-interface.js:669:25)
at .<anonymous> (/Users/Roller/Working/Web/ponds_web/node_modules/sequelize/lib/model.js:1390:32)
at tryCatcher (/Users/Roller/Working/Web/ponds_web/node_modules/bluebird/js/release/util.js:16:23)
at Promise._settlePromiseFromHandler (/Users/Roller/Working/Web/ponds_web/node_modules/bluebird/js/release/promise.js:504:31)
I think this error because my email object is not a Sequelize object.
Questions in mind:
Should we convert the email object into a Sequalize object by query from Email models? Will it work?
What's the better way to convert that object into Sequalize, as clean code and performance are concerned?
What if I have multiple emails to be added into Individual_Email when creating a new Product? Like more than 1 email ids.
Please help to advice. Thanks.
You are correct, the problem is that email is not a sequelize object. It would work if you retrieve it from database before adding it. On the other hand sequelize allows you to set childs by id. So you can do something like this:
models.Individual.create({
name: "Test"
}).then(function(createdIndividual) {
createdIndividual.setEmails([emailIds]) //emails id array
.then(function() {
console.log("Success");
});
});

How to get relationship/ assosiation in sequelizejs ORM

By below reference I understood how map many to many with a relationship table
http://sequelizejs.com/docs/latest/associations#many-to-many
User = sequelize.define('User', { user_name : Sequelize.STRING})
Project = sequelize.define('Project', { project_name : Sequelize.STRING })
UserProjects = sequelize.define('UserProjects', {
status: DataTypes.STRING
})
User.hasMany(Project, { through: UserProjects })
Project.hasMany(User, { through: UserProjects })
But how to query Project 's of a User
I Tried like
User.find({where:{id:1},include,[UserProjects]})
User.find({where:{id:1},include,[Projects]})
User.find({where:{id:1},include,[UserProjects]})
User.find({where:{id:1},include,[Projects]})
But i dont get results
Sequelize created table like below
users(id,name)
projects(id,project_name)
userprojects(id,UserId,ProjectId)
I tried https://github.com/sequelize/sequelize/wiki/API-Reference-Associations#hasmanytarget-options
User.find({where:{id:1}}).success(function(user){
user.getProjects().success(function (projects) {
var p1 = projects[0] // this works fine but 2 queries required. I expect in single find. without getProjects
p1.userprojects.started // Is this project started yet?
})
})
How to get all the projects of a USER ??
You should be able to get all of the properties of the user in two different ways: using includes and getting the projects from a user instance.
Using includes the code you submitted above is almost right. This method will only make one query to the database using the JOIN operation. If you want all of the users with their corresponding projects, try:
User.findAll({include: [Project]})
You can also get the projects directly from a user instance. This will take two queries to the database. The code for this looks like
User.find(1).then(function(user) {
user.getProjects().then(function(projects) {
// do stuff with projects
});
});
Does this work for you?