I am making register/login page using nodejs but when it comes to the step it returns json when accessing the database as well as when creating a new database
here is my code
register.js
const bcrypt = require("bcryptjs");
const User = require("../model/user");
const register = async (req, res) => {
const {
username,
password: plainTextPassword,
password_confirmation: someOtherPlaintextPassword,
tel_or_email,
} = req.body;
if (!username || typeof username !== "string") {
return res.json({ status: "error", error: "Invalid username" });
}
if (!plainTextPassword || typeof someOtherPlaintextPassword !== "string") {
return res.json({ status: "error", error: "Invalid password" });
}
User.findOne({ Email: tel_or_email }, async (error, user) => {
if (error) throw error;
if (user) {
console.log(user);
return res.json({
status: "ok",
success: "email is already in use, please enter another email",
});
} else {
const password = await bcrypt.hash(plainTextPassword, 10);
const password_confirmation = await bcrypt.hash(
someOtherPlaintextPassword,
10
);
const user = new User({
Name: username,
Email: tel_or_email,
Password: password,
});
user.save((error, result) => {
if (error) throw error;
console.log(result);
});
return res.json({ status: "ok", success: "user successfully created" });
}
});
};
module.exports = register;
status work in the first return ( return res.json({ status: 'error', error: 'Invalid username'}) )and the second( return res.json({ status: 'error', error: 'Invalid password'}) ) , remaining is not
Related
i am getting this as error
TypeError : res.status is not a function
I do not know why, but i am getting this Error
My code is looking thus :
app.post('/api/v1/user/login', async function(req,res){
var email = req.body.email;
var password = req.body.password;
dbConn.query(`SELECT * FROM XXXXXXXXX_users WHERE email = ${dbConn.escape(req.body.email)};`,(err,result)=>{
if(err){
throw err;
return res.status(400).send({message: err,})
}
if(!result.length){
return res.status(400).send({message: 'Username and password incorrect!',})
}
bcrypt.compare(req.body.password,result[0]['password'],(err,res)=>{
if(err){
throw err;
return res.status(400).send({message: 'Username and password Incorrect!'});
}
if(result){
const token = jwt.sign({email: result[0].email,id:result[0].id},'the-super-strong-secrect',{ expiresIn: '1h' });
return res.status(200).send({message: 'OK', token}) // Error is here
}
return res.status(400).send({message: 'User and pass incorrect'})
})
})
})
I am trying to implement Login system backend API please I would like to know why this is not working as its supposed to. Kindly help. A bit new to this
Issue is in this line
bcrypt.compare(req.body.password,result[0]['password'],(err,res) //<-- Using res keyword here
See how you are using (err, res) for this callback. This interferes with
app.post('/api/v1/user/login', async function(req,res) //<-- Also using res keyword here
I would suggest you to use async/await for better cleanup.
app.post('/api/v1/user/login', async function(req, res) {
let email = req.body.email;
let password = req.body.password;
try {
const queryResult = await dbConn.query(`SELECT * FROM XXXXXXXXX_users WHERE email = ${dbConn.escape(req.body.email)};`)
if (!queryResult.length) {
return res.status(400).send({
message: 'Username and password incorrect!',
})
}
const compareResult = await bcrypt.compare(req.body.password, queryResult[0]['password'])
if (compareResult) {
const token = jwt.sign({
email: queryResult[0].email,
id: queryResult[0].id
}, 'the-super-strong-secrect', {
expiresIn: '1h'
});
return res.status(200).send({
message: 'OK',
token
})
}
return res.status(400).send({
message: 'User and pass incorrect'
})
}
catch (err) {
res.status(500).json({
err
});
}
I'm trying to do a sample register without JWT using MVC in nodejs, express and mysql so when I run my code and I have an error :
TypeError: Cannot read properties of undefined (reading 'firstName') at exports.register
here is my code :
AuthController
const AuthModel = require('../models/Auth')
// Create and Save a new User
exports.register = (req, res) => {
// Validate request
if (!req.body) {
res.status(400).send({
message: "Content can not be empty!"
});
}
// Create user
const user = new AuthModel({
firstName: req.body.firstName,
lastName: req.body.lastName,
email: req.body.email,
password: req.body.password
});
// Save user in the database
AuthModel.createUser(user, (err, data) => {
if (err)
res.status(500).send({
message:
err.message || "Some error occurred while registring."
});
else res.send(data);
});
};
AuthModel
const AuthModel = function(table){
this.firstName = table.firstName;
this.lastName = table.lastName;
this.email = table.email;
this.password = table.password;
}
AuthModel.createUser = ( newUser, result ) =>{
db.query("INSERT INTO users SET ?", newUser, (err, res) => {
if (err) {
console.log("error: ", err);
result(err, null);
return;
}
console.log("User are registed: ", { id: res.insertId, ...newUser });
result(null, { id: res.insertId, ...newUser });
});
};
It seems to me as if the req.body is undefined. I think you might need something like body-parser, which has been added into the core of Express starting with version 4.
Try adding this middleware to your entrypoint: app.use(express.json());
See more here: http://expressjs.com/en/api.html#express.json
In your exports.register, you .send() if the body is undefined. That doesn't mean the rest of the code won't be executed.
Replace:
res.status(400).send({
message: "Content can not be empty!"
});
by
return res.status(400).send({
message: "Content can not be empty!"
});
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;
I want to build an application with login and register. Register works fine, but login not (it gives me 501-not implemented error). Here is a snippet from my code:
const passport = require('passport')
router.post('/register', (req, res) => {
knex
.from('user')
.insert({
firstname: req.body.firstname,
lastname: req.body.lastname,
email: req.body.email,
password: req.body.password,
})
.then(() => {
res.json({ success: true, message: "Data successfully inserted." })
})
.catch(() => {
res.json({ success: false, message: "Error in adding user. Please try again." })
})
})
router.post('/login', function (req, res, next) {
passport.authenticate('local', function (err, user, info) {
console.log("1 err " + JSON.stringify(err))
console.log("2 user " + JSON.stringify(user))
console.log("3 info " + JSON.stringify(info))
if (err) { return res.status(501).json(err); }
if (!user) { return res.status(501).json(info); }
req.logIn(user, function (err) {
if (err) { return res.status(501).json(err); }
return res.status(200).json({ message: 'Login Success' });
});
})(req, res, next);
});
When I try to login, I get:
1 err [{"id":1,"firstname":"john","lastname":"doe","email":"jdoe#example.com","password":"joe"}]
2 user undefined
3 info undefined
Why is user undefined? I was expecting to get a true/false value. And also why does err has that value? Because of that, it will always enter on if(err).
I can provide more from my code, if u ask to. Thank you!
EDIT: localpassport
const passport = require('passport');
const LocalStrategy = require('passport-local').Strategy;
const knex = require('./db.js');
passport.use('local', new LocalStrategy({
usernameField: 'email',
passwordField: 'password'
},
function (username, password, done) {
knex('user')
.where('email', '=', username)
.then((err, user) => {
if (err) { return done(err); }
if (!user) {
return done(null, false, { message: 'Incorrect username.' });
}
if (!user.isValid(password)) {
return done(null, false, { message: 'Incorrect password.' });
}
return done(null, user);
})
}
));
passport.serializeUser((user, done) => {
done(null, user.id);
});
passport.deserializeUser((id, done) => {
knex.from('user').where('id', '=', id)
.then((user) => { done(null, user); })
.catch((err) => { done(err, null); });
});
module.exports = passport;
The problem was inside localpassport:
passport.use('local', new LocalStrategy({
usernameField: 'email',
passwordField: 'password'
},
function (username, password, done) {
knex('users')
.where('email', '=', username)
.then((user) => {
if (!user) {
return done(null, false, { message: 'Incorrect username.' });
}
if (password != user[0].password) {
return done(null, false, { message: 'Incorrect password.' });
}
return done(null, user[0]);
})
}
));
There was no attribute such err.
I'm trying to pass an object from a model to my route so I can finish my login system but I'm not recieving anything.
Model code:
const AWS = require('aws-sdk');
const bcrypt = require('bcryptjs');
const config = require('../config/config.json');
var dynamoose = require('dynamoose');
const express = require('express');
var Schema = dynamoose.Schema;
const USER_SCHEMA = new Schema({
username: {
type: String,
required: true
},
firstName: {
type: String
},
lastName: {
type: String
},
email: {
type: String,
required: true
},
credential: {
type: String
},
password: {
type: String,
required: true
}
})
const USER = module.exports = dynamoose.model('Usuarios', USER_SCHEMA);
module.exports.getUserByUsername = function (user, callback) {
var docClient = new AWS.DynamoDB.DocumentClient();
var params = {
TableName: "Users",
KeyConditionExpression: "#us = :uuuu",
ExpressionAttributeNames: {
"#us": "username"
},
ExpressionAttributeValues: {
":uuuu": user
}
};
docClient.query(params, function (err, data) {
if (err) {
console.error("Unable to query. Error:", JSON.stringify(err, null, 2));
} else {
data.Items.forEach(function (user, callback) {
console.log(user.username + ": " + user.password + user.email + user.firstName);
});
}
callback(null, user);
});
}
This is working fine, I can print user.username, user.password and so on, but for some reason my router is not importing the JSON
router.post('/authenticate', (req, res, next) => {
const username = req.body.username;
const password = req.body.password;
USER.getUserByUsername(username, (err, user) => {
if (err) throw err;
if (!user) {
return res.json({
success: false,
"msg": "User not found"
});
}
USER.comparePassword(password, user.password, (err, isMatch) => {
if (err) throw err;
if (isMatch) {
const token = jwt.sign({
username: user
}, secret.secret, {
expiresIn: 86400
});
res.json({
success: true,
token: 'JWT ' + token,
user: {
user: user.username,
password: USER.password,
email: user.email
}
});
} else {
return res.json({
success: false,
msg: 'Wrong password'
})
}
});
});
});
The res.json from comparePassword should be the object from the route (which is the user model) but is not recieving a thing. I have tried with USER.username/email/etc user.username/email/etc but nothing works.
I know I must be missing something somewhere, but where?
Edit: Also tried with module.export.user = user; inside the model