Gettting an undefined value from bcrypt hash function - javascript

Ok, I'm getting an undefined value from a function, I don't know why, I'm trying to get the value of a password hash for insert in the database, but the const that have the function has the value "undefined", so what I should change in my code?
async postCompletedetails(req, res) {
const company = req.params.company;
const name = req.params.name;
const password = req.params.password;
const hashPass = await bcrypt.hash(password, saltRounds, function(err, hash) {
if (err) {
throw err
} else {
console.log(hash)
}
})
if (
company !== undefined &&
name !== undefined &&
password !== undefined
) {
const {
token
} = req.headers;
const decoded = jwt.verify(token, process.env.JWT_ACCOUNT_ACTIVATION);
const id = decoded.id;
const update = await pool.query(
`UPDATE user SET Name_user= '${name}', password= '${hashPass}' WHERE ID_user = ${id}`
);
const incompany = await pool.query(
`INSERT INTO company (Name_company) VALUES ('${company}') `
);
const inrelcompany = await pool.query(
`INSERT INTO rel_company_user (ID_company, ID_user) VALUES (LAST_INSERT_ID(), ${id})`
);
return res.json({
code: 200,
message: "todo bien... todo correcto y yo que me alegro",
hashPass,
password
});
} else {
return res.json({
code: 400,
message: "Bro hiciste algo mal",
});
}
}

When you call bcrypt.hash() and pass in a callback function, no Promise is returned. You can leave off that callback and then your await will work as you expect.
Basically, as is common with a lot of APIs, you can choose between the "old school" callback function approach or the more modern Promise/async model. One or the other, but not both at the same time.

Related

Why doesn't it return the user from the database by id?

I use ORM Sequelize(Postgres). I wrote a code that should return user data by user id, but either it just doesn't return anything, or it says "Support for {where: 'raw query'} has been removed.".
async findOne(req,res) {
try {
const {id} = req.body;
console.log(id);
const user = await User.findOne({where: id})
return res.json({user});
} catch (e) {
console.log(e.message);
}
}
router.post('/getOne', userController.findOne);
You should use an object notation in order to indicate the condition id=:id:
const user = await User.findOne({where: { id: id } })
// OR
const user = await User.findOne({where: { id } })

Validating and comparing req.body values to founduser values

I have an api for reseting password. This api checks if there is a user with the entered phone number and if there is any it checks whether the inputs like dob, nationality and idnumber are also correct then if they are it then generates a new password for the user. However am using many if statements . So my question is whether this is practical or i should change my syntax for performance sake of the app and general good practices for writing standard code.
I have attached my code below with bunch of if statements lol
const asyncHandler = require("express-async-handler");
const User = require("../../models/user")
const bcrypt = require("bcrypt");
const jwt = require("jsonwebtoken");
const generateStrongPassword = require('../../utils/generateStrongPassword');
const resetPassword = asyncHandler(async (req, res) => {
const { phonenumber, fullname, nationality, nationalidnumber, dateofbirth } = req.body;
const user = await User.findOne({ phonenumber: phonenumber });
if (user) {
if (fullname != user.fullname) {
throw new Error('incorrect fullname');
}
if (nationality != user.nationality) {
throw new Error('incorrect nationality');
}
if (nationalidnumber != user.nationalidnumber) {
throw new Error('incorrect national id number ');
}
if (dateofbirth != user.dateofbirth) {
throw new Error('incorrect date of birth');
}
// if all validations are passed then
// generate new password
const newrawpassword = await generateStrongPassword();
console.log(newrawpassword);
// harsh the password
const salt = await bcrypt.genSalt(10);
const newHashedPassword = await bcrypt.hash(newrawpassword, salt);
const resetPassword = await User.updateOne({ $set: { password: newHashedPassword } })
res.json('password successfully reseted')
} else {
throw new Error('No account has that phone number');
}
});
module.exports = resetPassword;

bcrypt nodejs keeps returning false

I have been struggling with this for hours and have tried a lot of different variations I have found around the web and also on stack overflow but I keep getting stuck on the same thing.
This is my registration code:
// REGISTER USER
app.post("/register", async (request, response) => {
const saltRounds = 10;
const emailAddress = request.body.emailAddress;
const password = await bcrypt.hash(request.body.password, saltRounds);
console.log(password)
// CHECK IF A USER EXISTS
const sqlSearch = "SELECT * FROM users WHERE emailAddress = ?"
const search_query = mysql.format(sqlSearch, [emailAddress])
// INSERT NEW USER
const sqlInsert = "INSERT INTO users (emailAddress, password) VALUES (?,?)"
const insert_query = mysql.format(sqlInsert, [emailAddress, password])
await usersDB.query(search_query, async (err, result) => {
if (err) throw (err)
if (result.length != 0) {
console.log("------> User already exists")
response.send("exists")
} else {
await usersDB.query(insert_query, (err, result) => {
if (err) throw (err)
response.send("created")
})
}
})
})
This is my login code:
// LOGIN (AUTHENTICATE USER)
app.post("/login", async (request, response) => {
const emailAddress = request.body.emailAddress
const password = request.body.password
const sqlSearch = "SELECT * FROM users WHERE emailAddress = ?"
const search_query = mysql.format(sqlSearch, [emailAddress])
await usersDB.query(search_query, async (err, result) => {
if (err) throw (err)
if (result.length == 0) {
console.log("--------> User does not exist")
response.sendStatus(404)
} else {
// Get the hashed password from result
const hashedPassword = result[0].Password
await bcrypt.compare(password, hashedPassword, function(err, result) {
if (result) {
console.log("---------> Login Successful")
response.send(`${emailAddress} is logged in!`)
} else {
console.log("---------> Password Incorrect")
console.log(password)
console.log(hashedPassword)
response.send("Password incorrect!")
}
});
}
})
})
I don't really understand what is going wrong in the compare considering the hashes are the same, I also tried pulling the salt rounds out and declaring them as a variable as you can see, this was recommended on another answer. I have changed the compare await in several different ways but they all give the same result.
I did also check the typeof on each var and they are all strings as they need to be.
My output:
The first hash you see is what is going into the database, the password being "test" and the second hash is from the compare statement along with the plaintext being shown.
$2b$10$wXGSrneIiovWHG7wk6a0BOIXwhzelTlCcxeoLsVJ8Au4iiOcoBBhe
---------> Password Incorrect
test
$2b$10$wXGSrneIiovWHG7wk6a0BOIXwhzelTlCcxeoLsVJ8Au4iiOcoBBhe
Any help would be greatly appreciated.
Note: The password column in my DB is a VARCHAR(255)
You can make a 2 seperate function for achieve the bcrypt functions. Here is the helper file which holds the bcrypt functions
const logger = require('./logger');
const bcrypt = require('bcrypt');
const encryptUtil = {};
// It make a hash password
encryptUtil.oneWayEncrypt = async (text) => {
try {
const salt = await bcrypt.genSalt(parseInt(process.env.SALT_ROUND, 10));
const encoded = await bcrypt.hash(text, salt);
return { encoded, salt };
} catch (err) {
logger.error('[ERROR] From oneWayEncrypt in encryptUtils', err);
throw err;
}
};
// It will validate plain text with the hashed one
encryptUtil.validateBcryptHash = async (text, hash) => {
try {
const isExactMatch = await bcrypt.compare(text, hash);
return isExactMatch;
} catch (err) {
logger.error('[ERROR] From validateBcryptHash in encryptUtils', err);
throw err;
}
};
module.exports = encryptUtil;
Here is the usecase of that function in signup and login
const encryptUtil = require('../../../helper/encryptUtil');
const logger = require('../../../helper/logger');
const jwt = require('../../../helper/jwt');
const userUtils = {};
userUtils.signUp = async (obj) => {
try {
const { name, password } = obj;
const email = obj.email.toLowerCase();
const condition = { email };
const querying = {
attributes: ['id', 'name', 'email''],
where: { email },
};
const isEmailExist = await Model.user.findOne(querying);
if (isEmailExist) {
const errorObj = { code: 400, error: l10n.t('ERR_EMAIL_ALREADY_EXIST') };
throw errorObj;
}
const { encoded: encPassword } = await encryptUtil.oneWayEncrypt(password);
const insertObj = {
name,
email,
password: encPassword,
};
const result = await Model.user.create(insertObj);
const userId = result.id;
const token = jwt.getAuthToken({ userId });
return { token, msg: l10n.t('MSG_SIGNUP_SUCCESS'), user: { name, email, userId } };
} catch (error) {
logger.error('[ERROR] From signUp in userUtils', error);
throw error;
}
};
userUtils.login = async (obj) => {
try {
const { password } = obj;
const email = obj.email.toLowerCase();
const querying = {
attributes: ['id', 'name', 'email', 'password'],
where: { email },
};
const user = await Model.user.findOne(querying);
if (!user) {
const errorObj = { code: 400, error: l10n.t('ERR_CREDENTIAL_NOT_MATCHED') };
throw errorObj;
}
// Here it validates the simple text with hashed text which store in a dbatabase
const isExactMatch = await encryptUtil.validateBcryptHash(password, user.password);
if (!isExactMatch) {
const errorObj = { code: 400, error: l10n.t('ERR_CREDENTIAL_NOT_MATCHED') };
throw errorObj;
}
const token = jwt.getAuthToken({ userId: user.id });
const result = {
token,
user: {
userId: user.id,
name: user.name,
email: user.email,
};
return result;
} catch (error) {
logger.error('[ERROR] From login in userUtils', error);
throw error;
}
};
module.exports = userUtils;

Is this Transaction valid?

I am wondering if this transaction is even valid and actually ensuring quantity is being the most up to date.
async function deductQuantity(orders: [Order]) : Promise<boolean> {
try {
let document = await admin.firestore().collection("MenuItems")
orders.forEach(async (order)=> {
let itemDoc = (await document.where(`item.catalogType`, "==", order.catalogType).where(`item.id`, "==", order.item.id))
let get = await itemDoc.get()
get.forEach(async a=> {
const pp = document.doc(a.id)
await admin.firestore().runTransaction(async (t)=> {
const mostRecentDoc = await t.get(pp)
const data = await mostRecentDoc.data()
if (data == undefined){
return
}
const newQuantity = data.item.quantity - order.quantity
await t.update(pp, {[`item.quantity`] : newQuantity})
})
})
})
return true
} catch (error) {
console.log("dum: " + error)
return false
}
}
the part where I do let get = await itemDoc.get(), and get.ForEach, is kind of unnecessary because I know, that it will only return one document that matches the query field, but I need to forEach it in order to get the child component\s. Anyways, is it a valid transaction?

How to get values from mysql database using node js

I am working on a node js application and using DB as mysql what I am trying to do is when I run a query and all data is fetched I want to access the data or store that data to variables for further use
In my controller I am writing this code
exports.login = function(req, res) {
User.fetchUser()
.then(([rows]) => {
console.log(rows)
})
.catch(err => console.log(err));
}
this one is printing on console like [ BinaryRow { email: 'draj.8126#gmail.com', password: 'dheeraj' } ]
in my model class I am executing my fetchUser function
static fetchUser() {
const email = 'draj.8126#gmail.com'
const password = 'dheeraj'
let sql = 'SELECT email,password FROM tpconsumer where email = ? and password = ?'
return db.execute(sql, [email, password]);
}
Now what I am trying to do is get email and password values and store them in variable for further use, or simply how can I use email or my password I want to access them
Try to pass params to your fetchUser method
exports.login = function(req, res) {
User.fetchUser(email,password)
.then(([rows]) => {
if(rows.length >0)
{
for(var i=0; i<rows.length; i++){
console.log(rows[i].email);
console.log(rows[i].password);
}
}
else{
console.log('Nothing to fetch');
}
})
.catch(err => console.log(err));
And in your Class Model :
static fetchUser(email,password) {
/*const email = 'draj.8126#gmail.com'
const password = 'dheeraj'*/
//pass your data dynamically
let sql = 'SELECT email,password FROM tpconsumer where email = ? and password = ?'
return db.execute(sql, [email, password]);
}
The result we get after executing query will be an array. so please try this
user.fetchUser().then(rows => {
console.log(rows);
var email = rows[0].email;
var passw = rows[0].pass;
console.log("email--",email);
console.log("passw--",passw);
}).catch(err => {
console.log(err)
})

Categories

Resources