I'm trying to create access levels in Node.js using Session. So for example, if the username is "test" it can view a certain page. If the username is "admin" it cannot view that same page. The username is stored in MySQL table "accounts". The table has the column attribute "username". Been trying to try different things but I can't seem to get it to work.
Here's my JS code:
app.get('/ViewPage', function(request, response) {
var connection = request.app.get('pool');
if (request.session.loggedin) {
var username;
connection.query('SELECT username FROM accounts WHERE username = test', function (error, results, fields) {
if (username == "test") {
// do the command here
} else if (username == "admin"){
response.redirect('/');
}
});
} else {
response.redirect('/');
}
});
Edit:
I updated my code as follows but it keeps looping to the "Admin cannot view this page" else if block.
app.get('/Create_Award', function (request, response) {
var connection = request.app.get('pool');
if (request.session.loggedin) {
connection.query('SELECT username FROM accounts', function (error, results, fields) {
{ account: results[0] };
if (error) {
console.log(error);
}
else {
if (results[0].username === "test") {
connection.query('SELECT accounts.id, accounts.username, awardType.id as awardTypeId, awardType.title FROM accounts JOIN awardType WHERE username = ?', [request.session.username], function(error, results, fields) {
response.render('Create_Award.html', { account: results[0], data: results });
console.log('Test account.');
}); //2nd connection
}
else if (results[0].username === "admin") {
response.redirect('/');
console.log('Admin cannot view this page.');
}
else {
response.redirect('/');
}
}
}); //1st connection
} else {
response.redirect('/');
}
});
app.get("/viewpage", async function(req, res) {
var connection = req.app.get("pool");
if (res.session.loggedin) {
try {
const result = await connection.query(
"SELECT * FROM accounts WHERE username = test"
);
if (result[0].username === "test") {
//something
} else if (result[0].username === "admin") {
//something
}
} catch (error) {
//You can log the error
return res.redirect("/");
}
}
return res.redirect("/");
});
There are some things to note here
1) Usage of async/await. It makes the code more readable, since queries can take some time to retrieve the data. Also encapsulating all of it inside a try/catch block so you can handle the error if there's any.
2) Your query callback wasn't used. You should use the results argument to retrieve the data in a callback-way.
3) While this is my opinion, always try to return a response, otherwise you may get "Routing error: Can't set headers after they are sent"
You are never populating your var username as it will always will be undefined and your code will go to else block
app.get('/ViewPage', function (request, response) {
var connection = request.app.get('pool');
if (request.session.loggedin) {
connection.query('SELECT username FROM accounts WHERE username = test', function (error, results, fields) {
if (error) {
console.log(error);
}
else {
if (results[0].username === "test") {
response.redirect('/myCustom');
}
else if (results[0].username === "admin") {
response.redirect('/');
}
else {
response.redirect('/');
}
}
});
} else {
response.redirect('/');
}
});
Update your code and it will work
Edit- From what I can see understand from your updated code, the only thing incorrect is how you are using res.render. have a look here, it takes a callback function
Try this in your code and let me know if it works
response.render('Create_Award.html', { account: results[0], data: results },(err,html)=>{
res.send(html)
});
Related
I am facing trouble when I try to throw an Error (to mark if there are no username) inside pool query. What I am expect is the error was catch by checkUsername and make it standard json response. But, I always get an error like this:
Here is my code in controller:
const checkUsername = (req, res) => {
const service = new AuthService()
try {
service.chekcUsernameIsExist(req.body.username, res)
return res.status(200).send('Username is exist')
} catch (error) {
const response = {
status: false,
message: error.message,
error_code: 400
}
return res.status(400).send(response)
}
}
And here is my code in service:
class AuthService {
chekcUsernameIsExist (username) {
const query = `select * from admins where username = '${username}';`
pool.query(query, (err, results, release) => {
if (err) {
throw err
} else if (results.rowCount !== 0) {
console.log('Username is exist')
} else {
console.log('Username is not exist')
throw new Error('Username is not exist')
}
})
}
}
I try to add try catch block inside checkUsernameIsExist but still got the same problem. At the stupid, I add a variable to which have value 1, 2, or 3 to mark is username exist, not exist, or other error.
I am building a user sign up and crud app. I have a db model.
var valid;
module.exports = {
connectDB: function(){
}
,
findUser: function(req,res) {
}
,
createUser: function(email,name,password){
var role = 'view';
var sql = "INSERT INTO `users`(email, name, password, role) VALUES (" + "'"+email+"'"+","+"'"+name+"'"+","+"'"+password+"'"+","+"'"+role+"'"+")";
db.query(sql, function(err, result){
if(err){
console.log(`FAILED: ${err}`)
return false; // tried setting valid to false
}
else
{
console.log(`User Created`);
valid = true;
}
});
return valid; // this also returns undefined
}
}
I want to be able to return a bool depending up on the succession of the query. I tried returning true/false. I did some searching on why this happens. Firstly there was an explanation about js being asynchronous.
My question is what is the correct way of returning values in function when exporting so that I can use it?
By using promises
createUser: function(email,name,password){
return new Promise(function(resolve,reject){
var role = 'view';
var sql = "INSERT INTO `users`(name, password, role) VALUES (" + "'"+email+"'"+","+"'"+name+"'"+","+"'"+password+"'"+","+"'"+role+"'"+")";
db.query(sql, function(err, result){
if(err){
console.log(`FAILED: ${err}`)
reject(err);
}
else
{
console.log(`User Created`);
resolve();
}
});
})
}
we can now use createUser like so;
db.createUser(email,name,password).then(function(){
console.log('redirect');
res.redirect('/');
}).catch(function(){
console.log('something went wrong');
res.render('signup', { message: 'something went wrong' })
});
I'm trying to compare an entered email on my website, to ones in the database to see whether it already exists. If it does, then the function returns false and an error is displayed.
var db = new sqlite3.Database('users_db.db');
db.get(
"SELECT * FROM users WHERE useremail = ?",
[email],
function (err, rows) {
if (rows == undefined ){
global.returnvalue2 = false;
}
}
);
What I want is for the function to be run immediately after the selection, so that the returned value is false, and the user record is not created.
At the moment I realise that the callback is being called after everything, so its just making the selection and carrying on throughout the rest of the program until the end.
How can I check if there are any existing records with the same email?
Make use of the async features in javascript, so your code would look something like this;
var db = new sqlite3.Database('users_db.db');
function checkemail(email, cb) {
db.get(
"SELECT * FROM users WHERE useremail = ?",
[email],
function (err, rows) {
if (err || rows == undefined ){
cb("bad email", null)
} else {
cb(null,rows)
}
});
}
function checkpassword(pw,cb) {....}
function checkclass(cls,cb) {....}
and then write you code like this;
checkemail(myemail, function(err,rows) {
if (err) return alert(err);
checkpassword(pw, function(err, msg) {
if (err) return alert(err);
checkclass(cls, function(err, msg) {
if (err) return alert(err);
alert("Congratulation you passed all the checks");
});
});
});
Here's a little one I made.
const sqlite3 = require('sqlite3').verbose();
let db = new sqlite3.Database('iHacks.db');
function get_user_credentials (email, password)
{ return new Promise((rs, rj) => {
function callback (err, User)
{
if (err) rj(err);
rs(User);
}
db.get('select * from users where email=? and password=?', [email, password], callback);
}); }
function login (email, password)
{ return new Promise ((rs, rj) => {
// Hashing the password.
password = sha256(password + 'EzSalt');
// Creating an Error
const err = new Error('Email or password did not match!');
// Callback functions
function check (User)
{
rs(User);
}
function fail (err)
{
rj(err);
}
// Getting the user credentials
get_user_details(email, password).then(check).catch(fail);
}); }
login()
.then(/* Continue code */)
.catch(err => {throw new Error(err); })
;
I am writing a simple script to retrieve a password from the table and validate in node.js Here is the script
module.exports = {
login: function (email, pass) {
var sqlite3 = require('sqlite3').verbose();
var db = new sqlite3.Database('test.db');
db.get("SELECT password FROM users WHERE user_email = ?", email, function(err, row) {
if (err !== null) {
console.log("An error has occured");
return "error";
} else if(row.password === pass) {
console.log("success");
return "success";
} else {
console.log("Incorrect password");
return "failure";
}
});
}
};
The console log statements are correct when the if else cases are evaluated. However the return value is undefined.
I do not understand why the return value is undefined if the logging is done correctly.
You can't return values from a callback because doing so is meaningless. You have to pass in a callback to your login() function and call that with (err, result) inside your db.get() callback:
module.exports = {
login: function (email, pass, cb) {
var sqlite3 = require('sqlite3').verbose();
var db = new sqlite3.Database('test.db');
db.get("SELECT password FROM users WHERE user_email = ?",
email,
function(err, row) {
if (err)
return cb(err);
cb(null, row.password === pass);
});
}
};
RouteHandler
function getProfile(req, res) {
var graphs = dataSaver.getGraphs(req.user.email)
console.log(graphs)
res.render('profile', {
title: 'EZgraph | User Home',
userGraphs: graphs
})
}
Db code
function getGraphs(username) {
model.findOne({
email: username
},
function(err, user) {
if (err) {
console.log('err')
}
if (!user) {
console.log('no user found!')
} else {
var graphs = user.savedGraphs
console.log(graphs)
return graphs
}
}
)
}
using the above two methods I'm trying to pass data read from the DB to a jade view. The problem is that within the scope of the 2nd method that reads from the db, the object is read fine, the console.log call shows me that. Once I return this object though and return to the scope of the route handler, the variable that should be equal to the object no prints as undefined. How do I fix this?
EDIT
In repsonse to the comments I tried the following, it isn't pretty at all but I run into the same problem.
Handler + helper
function getProfile(req, res) {
var graphs = dataSaver.getGraphs(req.user.email, readSuccess)
console.log(graphs);
res.render('profile', {
title: 'EZgraph | User Home',
userGraphs: graphs
})
}
function readSuccess(data) {
return data
}
db code
function getGraphs(username, callback) {
model.findOne({
email: username
},
function(err, user) {
if (err) {
console.log('err')
}
if (!user) {
console.log('no user found!')
} else {
callback(user.savedGraphs)
}
}
)
}