App crashed after the wrong login credential attempt in node .js - javascript

Here is my code of login its work when the user enter the right credential but the app crashed when its enter the wrong credential by showing showing the error message "Internal server error" which is right beacause I wriiten in it catch code but what I want the app should not be crashed when the user enter the wrong credentials.
router.post(
"/login",
[
body("email", "you enter wrong email").isEmail(),
body("password", "password cannot be blank").exists(),
],
async (req, res) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({ errors: errors.array() });
}
const { email, password } = req.body;
try {
let user = await User.findOne({ email });
if (!user) {
res.status(400).json({ error: "Please try to login with correct credentials" });
}
const passwordcompare = await bcrypt.compare(password, user.password);
if (!passwordcompare) {
res.status(400).json({ error: "Please Try to login with correct credential" });
}
const data = {
user: {
id: user.id,
},
};
const authtoken = jwt.sign(data, JWTSECRET);
res.json({ authtoken });
} catch (error) {
console.log(error.message);
res.status(500).send("Internal server error");
}
},
);
module.exports = router;

You're not returning after those res.status(400).json()s, so your program just continues on its merry way.
if (!user) {
res.status(400).json({error: "Please try to login with correct credentials"});
return; // add this
}

I think The problem in this line
const passwordcompare = await bcrypt.compare(password, user.password);
When password is undefined or wrong bcrypt.compare will throw an error and the catch block will catch it and return internal server error message
Try add return to res
if (!passwordcompare) {
return res.status(400).json({ error: "Please Try to login with correct credential" });
}
const data = {
user: {
id: user.id,
},
};
const authtoken = jwt.sign(data, JWTSECRET);
return res.json({ authtoken
});

You should add return statements on your error checks, otherwise, the function will keep executing and try to access user.password also if the user has not been found:
router.post(
"/login",
[
body("email", "you enter wrong email").isEmail(),
body("password", "password cannot be blank").exists(),
],
async (req, res) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({ errors: errors.array() });
}
const { email, password } = req.body;
try {
let user = await User.findOne({ email });
if (!user) {
return res.status(400).json({ error: "Please try to login with correct credentials" });
}
const passwordcompare = await bcrypt.compare(password, user.password);
if (!passwordcompare) {
return res.status(400).json({ error: "Please Try to login with correct credential" });
}
const data = {
user: {
id: user.id,
},
};
const authtoken = jwt.sign(data, JWTSECRET);
res.json({ authtoken });
} catch (error) {
console.log(error.message);
res.status(500).send("Internal server error");
}
},
);
module.exports = router;

You do not return res.status() that's why your code crashed.

Related

Cannot read properties of undefined (reading 'id')

I have a auth.js file And a middleware named as fetchuser code given beolow
Can anyone please tell me why am i getting this error.
I am using express js and mongoose but this error is occured during sending token to the user and verify the user whether is user logged in or not.
auth.js
const express = require('express');
const User = require('../models/User');
const router = express.Router();
const { body, validationResult } = require('express-validator');
const bcrypt = require('bcryptjs'); // it is used for password hashing
const jwt = require('jsonwebtoken');
const fetchuser=require('../middleware/fetchuser');
// Route:1 - Create a User using :POST. "/api/auth/createuser". NO Login Required.
router.post('/createuser', [
body('email', 'Enter valid email').isEmail(),
body('name', 'Enter valid email').isLength({ min: 3 }),
body('password').isLength({ min: 5 })
], async (req, res) => {
// Check fo vaidation whether is any rule(defined in User model) breaked or not
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({ errors: errors.array() });
}
// Check Whether user with same email id exist or not
try {
let user = await User.findOne({ email: req.body.email });
if (user) {
return res.status(400).json({ error: "Sorry user with same email id already exist" });
}
// hashing of password
const salt = await bcrypt.genSalt(10);
const securePassword = await bcrypt.hash(req.body.password, salt);
// create A new User
user = await User.create({
name: req.body.name,
email: req.body.email,
password: securePassword
})
// returning user id in Token
const JWT_secret = "Rishiisa#boy";
const data = { user:{id: user.id} };
const auth_token = jwt.sign(data, JWT_secret);
res.json({ auth_token });
}
catch (error) {
console.error(error.message);
res.status(500).send("Internal server error");
}
})
// Route:2 - Login a User using credential. "/api/auth/login". NO Login Required.
router.post('/login', [
body('email', 'Enter valid email').isEmail(),
body('password', 'password can not be blank').exists(),
], async (req, res) => {
// Check for vaidation according to the rule defined at line no. 53, 54;
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({ errors: errors.array() });
}
// destructure the email and password from body request
const { email, password } = req.body;
try {
// Checking whether email is exist or not
let user = await User.findOne({ email });
if (!user) {
return res.status(400).json({ error: "Please try to login using correct credentials" });
}
// Now Comparing password with help of bcryptjs
const comparepassword = await bcrypt.compare(password, user.password);
if (!comparepassword) {
return res.status(400).json({ error: "Please try to login using correct credentials" });
}
// Now if user enter coorect password and login then user got logged in;
// And We will send authtoken to user;
// returning user id in Token
const JWT_secret = "Rishiisa#boy";
const data = { user:{id: user.id} };
const auth_token = jwt.sign(data, JWT_secret);
res.json({ auth_token });
}
catch (error) {
console.error(error.message);
res.status(500).send("Internal server error");
}
})
// Route:3 - Get Loggedin User details using:POST "/api/auth/getuser" Login required
router.post('/getuser', fetchuser, async (req, res) => {
try {
const userid = req.user.id;
const user = await User.findById(userid).select("-password");
res.send(user);
} catch (error) {
console.error(error.message);
res.status(500).send("Internal server error");
}
})
module.exports = router
middleware:
fetchuser.js
const jwt = require('jsonwebtoken');
const JWT_secret = "Rishiisa#boy";
const fetchuser = (req, res, next) => {
// Get the user from jwt token and add user id to req object
const token = req.header('auth_token');
if (!token) {
res.status(401).send({ error: "Please authenticate using a valid token" });
}
try {
const data = jwt.verify(token, JWT_secret);
req.user = data.user;
next();
} catch (error) {
res.status(401).send({ error: "Please authenticate using a valid token" });
}
}
module.exports = fetchuser;
In auth.js, where you wrote: "const data = { user:{id: user.id} };" Try changing user.id to user._id, since in MongoDB the user id is referred to as '_id'.
Let me know if that works.
I've had problems sending jwt token back and even verifying it, but all is good on my side now.
Also, below is my (inspired) method of going about this:
router.post('/register', (req, res)=>{
const { username, password } = req.body;
const user = new User({
username,
password
});
bcrypt.genSalt(10, (err, salt)=>{
bcrypt.hash(user.password, salt, (err, hash)=>{
if(err) throw err;
user.password = hash;
user.save()
.then(user=>{
jwt.sign(
{ id: user._id },
process.env.jwtSecret,
{ expiresIn: 3600 },
(err, token) =>{
if(err) throw err;
res.status(200)
}
)
})
})
})
})

Mongodb Sign up retrun success but when I sign In user it return error. Am using Postman for testing the Api

I created Sign up and sign in function in node.js. I am able to sign up user using postman for testing but when I sign in, user, it return error message that I set up. I can't trace what is the problem currently. Can you please help?
export const signin = async (req, res) => {
const { email, password } = req.body;
try {
const oldUser = await UserModal.findOne({ email });
if (!oldUser) return res.status(404).json({ message: "User doesn't exist" });
const isPasswordCorrect = await bcrypt.compare(password, oldUser.password);
if (!isPasswordCorrect) return res.status(400).json({ message: "Invalid credentials" });
const token = jwt.sign({ email: oldUser.email, id: oldUser._id }, secret, { expiresIn: "1h" });
res.status(200).json({ result: oldUser, token });
} catch (err) {
res.status(500).json({ message: "Something went wrong" });
}
};
below is the sign up function...
export const signup = async (req, res) => {
const { email, password, firstName, lastName } = req.body;
try {
const oldUser = await UserModal.findOne({ email });
if (oldUser) return res.status(400).json({ message: "User already exists" });
const hashedPassword = await bcrypt.hash(password, 12);
const result = await UserModal.create({ email, password: hashedPassword, name: `${firstName} ${lastName}` });
const token = jwt.sign( { email: result.email, id: result._id }, secret, { expiresIn: "1h" } );
res.status(201).json({ result, token });
} catch (error) {
res.status(500).json({ message: "Something went wrong" });
console.log(error);
}
};

not delivering emails sent with nodemailer

i trying to send emails with in NextJs using nodemailer and it works and the response is success and i watch mailtrap it look like the emails was sent, but the problem is in there that i didn't receive any email and i don't know why its happening and how can i fix this..
its My configure code
import nodemailer from "nodemailer";
async function sendEmail(token, email) {
try {
var transporter = nodemailer.createTransport({
host: process.env.SMTP_HOST,
port: process.env.SMTP_PORT,
auth: {
user: process.env.SMTP_USER,
pass: process.env.SMTP_PASS,
},
});
transporter.verify(function (error, success) {
if (error) {
console.log(error);
} else {
// this console.log will print and every thing is OK!
console.log("Server is ready to take our messages");
}
});
const message = {
to: email,
from: `${process.env.STMP_FROM_NAME} <${process.env.STMP_FROM_EMAIL}>`,
subject: "Reset Password",
html: `
<p>
You Tried to reset your password, then just click this
link to do
this..
</p>
`,
};
await transporter.sendMail(message);
} catch (err) {
console.log(err);
}
}
export default sendEmail;
and its my controller codes
const sendResetMessage = asyncHandler(async (req, res, next) => {
try {
const user = await Users.findOne({ email: req.body.email });
if (!user) {
return next(new ErrorHandler("User not found with this email", 404));
}
// Get reset token
const resetToken = user.generateTokenToResetPassword();
await user.save({ validateBeforeSave: false });
await sendEmail(resetToken, user.email);
res.status(200).json({
success: true,
message: `Email sent to: ${user.email}`,
});
} catch (error) {
console.log(error);
user.resetPasswordToken = undefined;
user.resetPasswordExpire = undefined;
await user.save({ validateBeforeSave: false });
return next(new ErrorHandler(error.message, 500));
}
});

Does not work post-query when login

I'm trying to verify the user's password using bcrypt. But, unfortunately, my post-request does not work, it just loads for a long time and that's it.
I have a model user.js with this code:
UserSchema.methods.comparePasswords = function (password) {
return bcrypt.compare(password, this.password);
};
And i have a controller auth.js with this code:
export const signin = async (req, res, next) => {
const { login, password } = req.body;
const user = await User.findOne({ login });
if (!user) {
return next({
status: 400,
message: 'User not found'
});
}
try {
const result = await user.comparePasswords(password);
} catch (e) {
return next({
status: 400,
message: 'Bad Credentials'
});
}
req.session.userId = user._id;
req.json(user);
};
The handling of incorrect input works well and the server returns false messages for me, but does not process the correct input.

Why isn't .save for Mongoose working in ReactJS?

I have a ReactJS and Redux connected to MongoDB, Mongoose.
I have a Mongoose Schema (user.js) set up like so:
var UserSchema = new Schema({
email: {
type: String,
lowercase: true,
unique: true,
required: true
},
})
And a API controller that receives the email string request, and then if nothing is entered in the text field, it sends a 422 error, and inside User.findOne, if the email already exists in the database, then it throws a 422 error and if not, does user.save to save it in the database.
"use strict";
const User = require('../models/user')
exports.register = function(req, res, next) {
const email = req.body.email;
console.log('ERROR 1')
if(!email) {
return res.status(422).send({ error: 'You must enter an email address.'})
console.log('ERROR 1')
}
User.findOne({ email: email }, function(err, existingUser) {
if(err) { return next(err); }
console.log('ERROR 2')
if(existingUser) {
return res.status(422).send({ error: 'That email address is already in use.'})
}
console.log('ERROR 3')
let user = new User({
email: email,
})
console.log('ERROR 4')
user.save(function(err, user) {
if(err) { return next(err); }
console.log('ERROR 5')
res.status(201).json({
user: user,
})
})
})
console.log('ERROR 6')
}
And I am making a POST request as such:
export function registerUser({ email }) {
return function(dispatch) {
axios.post(`${API_URL}/auth/register`, { email })
.then(response => {
console.log('THIS IS TESTING PURPOSE')
console.log(response)
dispatch({ type: AUTH_USER });
})
.catch((error) => {
errorHandler(dispatch, error.response, AUTH_ERROR)
});
}
}
I made several POST requests and all get successful status back from API with sever config: {'database': 'mongodb://localhost/practicedb',
'port': process.env.PORT || 3000}, yet the data never gets saved and database (practicedb) doesn't show up on Terminal.
Everything seem to be set up correctly but why the problem? Could I be missing something? Any insight or guidance would be really appreciated.
Thank you in advance!
Here are some logs and what's OPTIONS request that I never made:
Tried registering with same email again:
Correct if i'm wrong but your bare save method is not async. Save method return a promise. See http://mongoosejs.com/docs/promises.html
EDIT
user.save().then(function(doc) {
if (!doc) { next(new Error('Error while persisting!')); }
console.log('ERROR 5');
res.status(201).json({
user: doc
});
});
You can also achieve this with any promised library (Q, bluebird) or use ES6 Promise. Alternatively use async.
Example with Q. NOT TESTED:
"use strict";
const User = require('../models/user');
const Q = require('Q'); //add https://github.com/kriskowal/q
exports.register = function(req, res, next) {
const email = req.body.email;
console.log('ERROR 1')
if(!email) {
return res.status(422).send({ error: 'You must enter an email address.'})
console.log('ERROR 1')
}
var deferred = Q.defer();
User.findOne({ email: email }, function(err, existingUser) {
if(err) { return next(err); }
console.log('ERROR 2')
if(existingUser) {
return res.status(422).send({ error: 'That email address is already in use.'})
}
console.log('ERROR 3')
let user = new User({
email: email,
})
console.log('ERROR 4')
user.save(function(err, user) {
if(err) {
deferred.reject(err);
return next(err);
}
console.log('ERROR 5')
deferred.resolve(user); //
});
res.status(201).json({
user: deferred.promise,
})
})
console.log('ERROR 6')
}

Categories

Resources