Check user already available in db using sails.js - mysql

I am registering a new user by checking it is already available. But for every user it shows "user is already available"
signup: function (req, res) {
var username = req.param("username");
var password = req.param("password");
var status = false;
console.log("user : " + username + " : " + password);
Signup.find({username: username}).exec(function(err, usr){
if (err) {
var response = {status:status, error:"db error"};
res.send(500, response);
} else {
if (usr) {
status = true;
res.send(400, {error: "Username already Taken"});
}
else {
signup.create({username: username, password: password}).exec(function(error, user) {
if (error) {
res.send(500, {error: "DB Error"});
} else {
req.session.user = user;
res.send(user);
}
});
}}
});
},

I assume that in your model it clear that the username must be unique. So use findOne() function. It's return only one record( object ).
signup: function(req, res) {
var username = req.param("username");
var password = req.param("password");
var status = false;
Signup.findOne({ username: username })
.exec(function(err, usr) {
if (err) {
var response = { status: status, error: "db error" };
return res.send(500, response);
}
if (usr) {
//status = true; --> in this case you don't use 'status' so this assignment is unnecessary
return res.send(400, { error: "Username already Taken" });
} else {
Signup.create({ username: username, password: password })
.exec(function(err, user) {
if (err) {
res.send(500, { error: "DB Error" });
} else {
req.session.user = user;
res.send(user.username);
}
});
}
});
}

Signup.find({username: username}).exec(function(err, usr){
// usr is an array
});
the result of find is a list with objects matching your query. The list either has items or no items. In both cases
if (usr) {}
will be true, because you basically just check whether usr is defined which it always is. So change it to
if (usr.length === 0) {
// already exists
}
Or you change find to findOne.

Related

How do I make this owner authentication work?

I have a problem with this code. I would appreciate it very much if someone could help me with this. If you have any missing information feel free to ask. Note: Iam using mysql2.
router.get('/restaurants/:name/:location/dashboard', userContoller.isLoggedInAdmin, async (req, res) => {
const restaurantName = req.params.name;
const restaurantLocation = req.params.location;
console.log(`restaurantName: ${restaurantName}`);
console.log(`restaurantLocation: ${restaurantLocation}`);
try {
// Query the database to retrieve the owner's information and the information for the specific restaurant
const [ownerRows] = await db.promise().query(
'SELECT * FROM owner WHERE id = (SELECT owner_id FROM restaurant WHERE name = ? AND location = ?)',
[restaurantName, restaurantLocation]
);
const [restaurantRows] = await db.promise().query(
'SELECT * FROM restaurant WHERE name = ? AND location = ?',
[restaurantName, restaurantLocation]
);
console.log(`ownerRows: ${JSON.stringify(ownerRows)}`);
console.log(`restaurantRows: ${JSON.stringify(restaurantRows)}`);
const owner = ownerRows[0];
const restaurant = restaurantRows[0];
console.log(`owner: ${JSON.stringify(owner)}`);
console.log(`restaurant: ${JSON.stringify(restaurant)}`);
// Check if the owner is logged in and has permission to access the dashboard
if (req.owner && req.owner.id === restaurant.owner_id) {
// Render the dashboard template and pass the owner's information and information for the specific restaurant to it
res.render('role/admin/index', { owner: owner, restaurant: restaurant });
} else {
console.log('Owner not granted access to dashboard');
// Redirect the owner to the login page
res.render('errors/no permission');
}
} catch (error) {
console.error(error);
res.sendStatus(500);
}
});
So I have this route and I want it to work. I have a user, owner and a restaurant table. In the owner table is the owner id and the user id as a foreign key referencing to the primary key in the user table. In the restaurant table there is a column called owner_id which is a foreign key referencing to the primary key in the owner table. What this basically means is that the user is the owner/admin of one or more restaurants. The problem is that somehow the owner does not have access to the restaurant even though he is connected with it.
Here is the middleware:
exports.isLoggedInAdmin = async (req, res, next) => {
console.log('isLoggedInAdmin middleware called');
if (req.cookies.one) {
try {
const decode = await jwt.verify(req.cookies.one, process.env.JWT_SECRET);
const [user] = await db.promise().query("SELECT * FROM user WHERE id = ?", [decode.id]);
if (!user) {
return res.status(401).json({ message: "Unauthorized" });
}
const [owner] = await db.promise().query("SELECT * FROM owner WHERE user_id = ?", [decode.id]);
if (!owner) {
return res.status(401).json({ message: "Unauthorized" });
}
if (user.id !== owner.user_id) {
return res.status(401).json({ message: "Unauthorized" });
}
console.log('Owner found:', owner);
req.owner = {
id: owner.id,
user_id: owner.user_id,
};
next();
} catch (error) {
console.error(error);
return res.status(401).json({ message: "Unauthorized" });
}
} else {
console.log('No owner found');
next();
}
};
Here is the login system (focus on the cookie for the owner):
exports.login = async (req, res) => {
try {
const { email, password } = req.body;
if (!email || !password) {
return res.status(400).render("login", {
msg: "Please Enter Your Email and Password",
msg_type: "error",
});
}
db.query(
"select * from user where email=?",
[email],
async (error, result) => {
console.log(result);
if (result.length <= 0) {
return res.status(401).render("login", {
msg: "Please Enter Your Email and Password",
msg_type: "error",
});
} else {
if (!(await bcrypt.compare(password, result[0].password))) {
return res.status(401).render("login", {
msg: "Please Enter Your Email and Password",
msg_type: "error",
});
} else {
const id = result[0].id;
const token = jwt.sign({ id: id }, process.env.JWT_SECRET, {
expiresIn: process.env.JWT_EXPIRES_IN,
});
console.log("The Token is " + token);
const cookieOptions = {
expires: new Date(
Date.now() +
process.env.JWT_COOKIE_EXPIRES * 24 * 60 * 60 * 1000
),
httpOnly: true,
};
// Check if the user is in the owner table
db.query("SELECT * FROM owner WHERE user_id=?", [id], (error, result) => {
if (result.length > 0) {
// Set the cookie for owner
res.cookie("one", token, cookieOptions);
res.status(200).redirect("/restaurants/:name/:location/dashboard");
} else {
// Check if the user is in the manager table
db.query("SELECT * FROM manager WHERE user_id=?", [id], (error, result) => {
if (result.length > 0) {
// Set the cookie for manager
res.cookie("two", token, cookieOptions);
res.status(200).redirect("/manager/dashboard");
} else {
// Check if the user is in the cook table
db.query("SELECT * FROM cook WHERE user_id=?", [id], (error, result) => {
if (result.length > 0) {
// Set the cookie for cook
res.cookie("three", token, cookieOptions);
res.status(200).redirect("/cook/dashboard");
} else {
// Check if the user is in the waiter table
db.query("SELECT * FROM waiter WHERE user_id=?", [id], (error, result) => {
if (result.length > 0) {
// Set the cookie for waiter
res.cookie("four", token, cookieOptions);
res.status(200).redirect("/waiter/dashboard");
}
});
}
});
}
});
}
});
}
}
}
);
} catch (error) {
console.log(error);
}
};
Here is the log:
isLoggedInAdmin middleware called
Owner found: [ { id: 7, user_id: 42 } ]
restaurantName: BLOCKHOUSE
restaurantLocation: Pakistan
ownerRows: [{"id":7,"user_id":42}]
restaurantRows: [{"id":40,"name":"BLOCKHOUSE","location":"Pakistan","email":"2021erik.mettner#gmail.com","phonenumber":"012386763618","owner_id":7}]
owner: {"id":7,"user_id":42}
restaurant: {"id":40,"name":"BLOCKHOUSE","location":"Pakistan","email":"2021erik.mettner#gmail.com","phonenumber":"012386763618","owner_id":7}
Owner not granted access to dashboard
I know where the problem is. It is here:
// Check if the owner is logged in and has permission to access the dashboard
if (req.owner && req.owner.id === restaurant.owner_id)
My Problem is that I dont know how to fix it. I want that the owner can access his restaurants. Only he, not any other owner.

using bcrypt for login in nodejs

I'm having a hard time with integrating bcrypt to try to make my login system safe.
I basically get the username, password the user inputs and try to compare it from the hashed password in my db. here's what I have.
const inputUsername = req.body.inputUsername;
const inputPassword = req.body.inputPassword;
var userLogin = "select * from login where USERNAME = ?"
ibmdb.open(ibmdbconnMaster, function(err, conn) {
if (err) return console.log(err);
conn.query(userLogin, [inputUsername], function(err, rows) {
if (err) {
console.log(err)
}
if (rows.length > 0) {
var pass = ""
for (var i = 0; i < rows.length; i++) {
pass = rows[i]['PASSWORD'];
console.log(pass)
bcrypt.compare(inputPassword, hash, function(err, result) {
if (pass == result) {
console.log("this works")
userAuth = true;
res.redirect('/index')
}
})
}
console.log("does not work")
} else {
userAuth = "false";
res.render('login.ejs')
alert('Incorrect username or password. Please try again')
}
conn.close(function() {
console.log('closed the function /login');
});
})
})
what happens right now is I get the error ReferenceError: hash is not defined
not sure how to fix this. thanks in advance
Where have you defined hash? I don't see it in your code.
Here's an example of auth routes that I've used with bcrypt/node/express:
const Users = require("../users/users-model.js");
router.post("/register", (req, res) => {
// Pull the user's credentials from the body of the request.
const user = req.body;
// Hash the user's password, and set the hashed password as the
// user's password in the request.
const hash = bcrypt.hashSync(user.password, 10);
user.password = hash;
Users.add(user)
.then((newUser) => {
const token = generateToken(newUser);
res
.status(201)
.json({ created_user: newUser, token: token, user_id: newUser.id });
})
.catch((err) => {
res.status(500).json({
message: "There was an error adding a user to the database",
err,
});
});
});
router.post("/login", (req, res) => {
const { username, password } = req.body;
Users.findBy({ username })
.first()
.then((user) => {
if (user && bcrypt.compareSync(password, user.password)) {
const token = generateToken(user);
res
.status(200)
.json({
username: user.username,
first_name: user.first_name,
last_name: user.last_name,
email: user.email,
token: token,
user_id: user.id,
});
} else {
res.status(401).json({ message: "Invalid Credentials" });
}
})
.catch((err) => {
res.status(500).json(err);
});
});
function generateToken(user) {
const payload = {
userid: user.id,
username: user.username,
};
const options = {
expiresIn: "1h",
};
const token = jwt.sign(payload, secrets.jwtSecret, options);
return token;
}
module.exports = router;

if -else condition is not working in node js

What I am trying to implement is that after logged in ,system will check user's role and redirect the user accordingly.
1- Admin
2- User
role field is integer type. below is my code
router.post('/signin', function (req, res, next) {
session_store = req.session;
req.assert('Emailid', 'Please fill register Email Address').notEmpty();
req.assert('Emailid', 'Email not valid').isEmail();
req.assert('password', 'Please fill the Password').notEmpty();
var errors = req.validationErrors();
if (!errors) {
Emailid = req.sanitize('Emailid').escape().trim();
password = req.sanitize('password').escape().trim();
var query = 'select * from userdetails where Emailid=? and password=?';
var sql='select role from userdetails where Emailid=?'
db.query(query, [Emailid, password], function (err, rows) {
if (err) {
var errornya = ("Error Selecting : %s ", err.code);
console.log(err.code);
req.flash('msg_error', errornya);
res.redirect('/login-Form');
} else {
if (rows.length <= 0) {
req.flash('msg_error', "Wrong email address or password. Try again.");
res.redirect('/login-Form');
}
else {
session_store.is_login = true;
session_store.user = Emailid;
db.query(sql, Emailid, function (err, result) {
if (err) throw err
else {
if (result == 1) { // facing issue here. It is directly going to else block though the user role is 1 in the mysql table
console.log(result)
res.redirect('/Dashboard');
}
else {
res.redirect('/Audit-Record');
}
}
});
}
}
});
}
else {
res.redirect('/login-Form');
}
});
I guess I am making some mistake while comparing the result value. Can anyone of you please check and let me know where I am going wrong.
Thanks in advance!
The issue got resolved. Actually I was comparing in wrong way. we need to write it like this
else {
session_store.is_login = true;
session_store.user = Emailid;
db.query(sql, Emailid, function (err, result) {
if (err) throw err
else {
**if (result[0].role == 1)** {
console.log(result)
res.redirect('/Dashboard');
}
else {
res.redirect('/Audit-Record');
}
}
});

Authentification NodeJS Sequelize Express

I'm trying implement NodeJS authentification with express, sequelize, and mysql, but i'm blocked. I get login and password values by webservice. I want to match them with database value :
app.get('/login', function (req, res, err) {
var whereUser = {
login: req.query.login,
password: req.query.password
}
if (!req.query.login || !req.query.password) {
res.send('login failed');
//Here my code is wrong !
I try to compare login and password values with database login and passwword values
} else if (req.query.login && req.query.password == UsrPerson.findOne({ where: whereUser })) {
console.log("auth ok")
req.session.user = "amy";
req.session.admin = true;
res.send("login success!");
} else {
console.log("ERROR")
res.send(err)
}
});
How can I do that ? Thank you
app.get('/login', function (req, res, err) {
const { login, password } = req.query;
UsrPerson
.findOne({
where: {
login: login,
password: password
}
})
.then((foundUser) => {
if(!foundUser){
res.send('login failed');
} else {
console.log("auth ok");
req.session.user = "amy";
req.session.admin = true;
res.send("login success!");
}
})
.catch((err) => {
console.log('ERROR');
res.send(err);
});
});
You want to compare if the user with the given username and password combination exists.
And seems like you are storing the password without any encryption, in plain text. This is not secure at all. You have to use a library like bcrypt and only store the encrypted password in your database
The findOne method from sequelize return an instance object of the model.
that means than you can't compare a password to an instance.
The second problem is the findOne method is asynchronous, you need to await it and have an async method.
app.get('/login', async function (req, res, err) {
var whereUser = {
login: req.query.login,
password: req.query.password
}
if (!req.query.login || !req.query.password) {
res.send('login failed');
} else {
// The following code return an instance of the user if it was found.
const user = await UsrPerson.findOne({ where: whereUser }))
// If the user was not found that means the credentials was wrong.
if (user) {
console.log("auth ok")
req.session.user = "amy";
req.session.admin = true;
res.send("login success!");
} else {
console.log("ERROR")
res.send(err)
}
}
});

login validation with response from controller

I am using simple validation for login page. In the controller i have used the validation conditions.
LoginController.js
login : function(req,res) {
var username = req.param('username');
var password = req.param('password');
console.log("user : " + username + " : " + password);
Login.findOne({ username: username }, function (err, usr) {
if (err) {
res.send(500, { error: "DB Error" });
} else {
if (usr) {
console.log("found user : " + usr.username + " password : " + usr.password)
if (password == usr.password) {
req.session.user = usr;
res.send(200,usr);
} else {
res.send(400, { error: "Wrong Password" });
}
} else {
res.send(404, { error: "User not Found" });
}
}
});
These errors are displayed in the server side, like in run time to show these error in User Interface(UI) with the resin the react file
LoginForm.jsx
signin: function() {
console.log("in Signin");
var username = this.refs.username.value.trim();
var password = this.refs.password.value.trim();
this.onSubmit({username: username, password: password});
this.refs.password.value = '';
},
onSubmit: function(login) {
var username = this.refs.username.value.trim();
var password = this.refs.password.value.trim();
socket.post(this.props.url, login, function whenServerResponds(usr) {
console.log(usr);
/// how to correct it
if(res.usr){alert("login success");}else{
if(res.getResponseHeader("error")){alert("password incorrect");}
else{alert("user not found")}
///
}
});
},
This format is not gonna work res.send(200,usr);
Try to send in exact format like this
login: function(req, res) {
var username = req.param('username');
var password = req.param('password');
console.log("user : " + username + " : " + password);
Login.findOne({
username: username
}, function(err, usr) {
if (err) {
res.status(500).send({
error: "DB Error"
});
} else {
if (usr) {
console.log("found user : " + usr.username + " password : " + usr.password)
if (password == usr.password) {
req.session.user = usr;
res.status(200).send(usr);
} else {
res.status(400).send({
error: "Wrong Password"
});
}
} else {
res.status(404).send({
error: "User not Found"
});
}
}
});
}
And access your user object or error