My app is crashing during JWT Authentication - javascript

I am new to MERN stack development and trying the JWT authentication. During this I am facing that my server is not working they crashed every time.
Yesterday It was working but today It's not working. Now they are showing this error.
This is error showing on console
MissingSchemaError: Schema hasn't been registered for model "users".
Here is my Schema:
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const UserSchema = new Schema({
name: {
type: String,
required: true
},
email: {
type: String,
required: true
},
password: {
type: String,
required: true
},
avatar: {
type: String
},
date: {
type: Date,
default: Date.now
}
});
const User = mongoose.model('users', UserSchema);
module.exports = User;
This code is in the routes folder - user.js file
// user.js
const express = require('express');
const router = express.Router();
const gravatar = require('gravatar');
const bcrypt = require('bcryptjs');
const jwt = require('jsonwebtoken');
const passport = require ('passport');
const validateRegisterInput = require('../validation/register');
const validateLoginInput = require('../validation/login');
const User = require('../models/User');
//Register Post Router
router.post('/register', function(req, res){
const {errors, isValid} = validateRegisterInput(req.body);
if(!isValid){
return res.status(400).json(errors);
}
User.findOne({
email: req.body.email
}).then(user => {
if(user){
return res.status(400).json({
email: 'Email already exists'
});
}
else {
const avatar = gravatar.url(req.body.email, {
s: '200',
r: 'pg',
d: 'mm'
});
const newUser = new User({
name: req.body.name,
email: req.body.email,
password: req.body.password,
avatar
});
bcrypt.genSalt(10, (err, salt) => {
if(err)
console.error('There was an error', err);
else{
bcrypt.hash(newUser.password, salt, (err, hash) => {
if(err)
console.error('There was an error', err);
else{
newUser.password = hash;
newUser
.save()
.then(user => {
res.json(user)
});
}
});
}
});
}
});
});
//Login Post Router
router.post('/login', (req, ress) => {
const {errors, isValid} = validateLoginInput(req.body);
if(isValid){
return res.status(400).json(errors);
}
const email = req.body.email;
const password = req.body.password;
User.findOne({email})
.then(user => {
if(!user) {
errors.email = 'User not found'
return res.status(404).json(errors);
}
bcrypt.compare(password, user.password)
.then(isMatch => {
if(isMatch){
const payload = {
id: user.id,
name: user.name,
avatar: user.avatar
}
jwt.sign(payload, 'secret', {
expiresIn: 3600
}, (err, token) => {
if(err)
console.error('There is some error in token', err);
else{
res.json({
success: true,
token: `Bearer ${token}`
});
}
});
}
else{
errors.password = 'Incorrect Password';
return
res.status(400).json(errors);
}
});
});
});
router.get('/me', passport.authenticate('jwt', {session: false}), (req, res) => {
return res.json({
id: req.user.id,
name: req.user.name,
email: req.user.email
});
});
module.exports = router;

Related

Error "Illegal arguments: undefined, string\n at bcrypt.hashSync"

while I am using bcrypt.js hashSync is not accepting numbers or symbols in password, if I pass string as value of password from postman only then it works otherwise it throws error 500 along with message "Illegal arguments: undefined, string\n at bcrypt.hashSync".
I also tried const hash = await bcrypt.hashSync(req.body.password, salt, { encoding: "utf8" }); it didn't work either.
my auth.js code is
import User from "../models/User.js";
import bcrypt from "bcryptjs";
import { createError } from "../utils/error.js";
import jwt from "jsonwebtoken";
export const register = async (req, res, next) => {
try {
const salt =await bcrypt.genSaltSync(10);
const hash =await bcrypt.hashSync(req.body.password, salt);
const newUser = new User({
...req.body,
password: hash,
});
await newUser.save();
res.status(200).send("User has been created.");
} catch (err) {
next(err);
}
};
export const login = async (req, res, next) => {
try {
const user = await User.findOne({ username: req.body.username });
if (!user) return next(createError(404, "User not found!"));
const isPasswordCorrect = await bcrypt.compare(
req.body.password,
user.password
);
if (!isPasswordCorrect)
return next(createError(400, "Wrong password or username!"));
const token = jwt.sign(
{ id: user._id, isAdmin: user.isAdmin },
process.env.JWT
);
const { password, isAdmin, ...otherDetails } = user._doc;
res
.cookie("access_token", token, {
httpOnly: true,
})
.status(200)
.json({ details: { ...otherDetails }, isAdmin });
} catch (err) {
next(err);
}
};
I am trying to use numbers and symbols along with text for password

how can i get the specific info about a user

i'm working on a web app in which a user can create an address when logged in, how can i get the current logged in user address which was created by the user
these my address route
const router = require("express").Router();
const Address = require("../models/address");
const User = require("../models/user");
const jwt = require("jsonwebtoken");
router.get('/addresses', (req, res, next) => {
let token = req.headers.token; //token
jwt.verify(token, 'secretkey', (err, decoded) => {
if (err) return res.status(401).json({
title: 'unauthorized'
})
//token is valid
Address.findOne({ _id: decoded.addressId }, (err, user) => {
if (err) return console.log(err)
return res.status(200).json({
title: 'adress grabbed',
address: {
streetAddress: user.streetAddress,
fullName: user.fullName
}
})
})
})
})
i get unauthorised any time i want to get the address of the current user
my db schema
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const AddressSchema = new Schema({
user: { type: Schema.Types.ObjectId, ref: "User" },
country: String,
fullName: String,
streetAddress: String,
city: String,
state: String,
zipCode: Number,
phoneNumber: String,
deliverInstructions: String,
securityCode: String
});
module.exports = mongoose.model("Address", AddressSchema);
my auth route to get details of current user
//grabbing user info
router.get('/auth/user', (req, res, next) => {
let token = req.headers.token; //token
jwt.verify(token, 'secretkey', (err, decoded) => {
if (err) return res.status(401).json({
title: 'unauthorized'
})
//token is valid
User.findOne({ _id: decoded.userId }, (err, user) => {
if (err) return console.log(err)
return res.status(200).json({
title: 'user grabbed',
user: {
email: user.email,
name: user.name
}
})
})
})
})```
please how can i go about it

How to save a given model in a specific collection in the database mongodb?

I have three models: user, teacher, student. The users, teachers, students collections appear in the database. But everything is saved in the users collection. How to set up in the code below that student is saved in the students collection, not in users.
model
const mongoose = require('mongoose');
extend = require('mongoose-extend-schema');
const Schema = mongoose.Schema;
const userSchema = new Schema({
name: {
type: String,
trim: true,
required: true,
maxLength: 32
},
surname: {
type: String,
trim: true,
required: true,
maxLength: 32
},
email: {
type: String,
unique: true,
trim: true,
required: true,
lowercase: true
},
initials: String
});
const studentSchema = extend(userSchema, {
teachers: []
});
const teacherSchema = extend(userSchema, {
isActiveTutor: {
type: Boolean,
default: false
}
})
const User = mongoose.model('User', userSchema);
const Student = mongoose.model('Student', studentSchema);
const Teacher = mongoose.model('Teacher', teacherSchema);
module.exports = {
User,
Student,
Teacher
}
controllers
const User = require('../models/user');
const Student = require('../models/user');
const Teacher = require('../models/user');
const jwt = require('jsonwebtoken');
const nodemailer = require('nodemailer');
const expressJwt = require('express-jwt');
module.exports.signup = (req, res) => {
const {name, surname, email, password, initials, role} = req.body;
Student.User.findOne({email}).exec((err, student) => {
if (student) {
return res.status(400).json({
error: "Email is taken"
})
}
}
}
module.exports.accountActivationStudent = (req, res) => {
const {token} = req.body;
if(token) {
jwt.verify(token, process.env.JWT_ACCOUNT_ACTIVATION, function(err, decoded) {
if(err) {
console.log('JWT VERIFY IN ACCOUNT ACTIVATION ERROR', err);
return res.status(401).json({
error: 'Expired link. Signup again'
})
}
const {name, surname, email, password} = jwt.decode(token);
const student = new Student.User ({name, surname, email, password});
student.save((err, student) => {
if(err) {
console.log('SAVE Student IN ACCOUNT ACTIVATION ERROR', err);
return res.status(401).json({
error: 'Error saving student in database. Try signup again'
});
}
return res.json({
message: 'Signup success. Please signin'
});
});
});
} else {
return res.json({
message: 'Something went wrong. Try again'
})
}
};
new Student is your schema
try to like this
router.post('/', async (req, res) => {
const _studentSave = await new Student({ name, surname, email, password, initials, role });
const saveProcess = await _studentSave.save();
try{
res.json(saveProcess)
}catch(error){
throw error
}
})

Mongoose, Bcrypt "Error: data and hash arguments required"

According to the error-trace the error occurs in the "validate" method, but as far as i see it my compare call is correct. I hope someone can explain to me why it happens anyways.
POST /user/register 500 23.312 ms - 2235
Error: data and hash arguments required
at Object.compare
at model.user_schema.methods.validate
The mongoose model:
const mongoose = require('mongoose');
const bcrypt = require('bcrypt');
const salty = 10;
const user_schema = new mongoose.Schema({
name: {
type: String,
required: true,
unique: false,
minlength: 3,
maxlength: 32
},
email: {
type: String,
required: true,
unique: true
},
password: {
type: String,
required: true
}
});
user_schema.pre('save', (next) => {
// if the password is not changed, there is no need to hash it again
if (!this.isModified('password')) return next();
// hash the user password
bcrypt.hash(this.password, salty, (err, hash) => {
if (err) return next(err);
this.password = hash;
return next();
});
});
user_schema.methods.validate = (claim, callback) => {
// compare the password to the existing hash from the database
bcrypt.compare(claim, this.password, (err, is_match) => {
if (err) return callback(err);
return callback(null, is_match);
});
}
module.exports = mongoose.model('user', user_schema);
The router with the create call:
router.post('/register', (req, res, next) => {
let new_user = {
name: req.body.name,
email: req.body.email,
password: req.body.password
};
user_model.create(new_user, (err, user) => {
if (err) return next(err);
res.send(user);
});
});

expressJs router.post() not working for multiple middleware giving [object Undefined] error

i am creating a REST API for my users, and i used express-validator for the validation before creating the user in the database.. but when i chain my middleware together in the router.py file it gives the error Error: Route.post() requires a callback function but got a [object Undefined]
i imported my middleware and controller from thier respective files.
here is the code in my router.py
const express = require('express');
const authMiddleware = require('../middlewares/authMiddleware');
const authController = require('../controllers/authController');
const router = express.Router();
router.post(
'/signup',
authMiddleware.verifySignUpInit(),
authMiddleware.verifySignUp,
authController.signup
);
module.exports = router;
in my middleware file i added this..
const jwt = require('jsonwebtoken');
const { authentication } = require('../config');
const { User } = require('../models');
const { body } = require('express-validator');
const verifySignUpInit = () => {
return [
body('email', 'email is required').exists().normalizeEmail().isEmail(),
body('phone', 'phone is required').exists().isInt(),
body('first_name', 'first_name is required').exists().isString(),
body('last_name', 'last_name is required').exists().isString(),
body('password', 'password is required').exists(),
];
};
const verifySignUp = (req, res, next) => {
const { email, phone, password } = req.body;
User.findOne({
email,
}).exec((err, user) => {
if (err) {
res.status(500).json({
status: 'error',
message: err,
});
}
if (user) {
return res.status(400).json({
status: 'failed',
message: 'Email Provided Already Exists',
});
}
});
User.findOne({
phone,
}).exec((err, user) => {
if (err) {
res.status(500).json({
status: 'error',
message: err,
});
}
if (user) {
return res.status(400).json({
status: 'failed',
message: 'Phone Provided Already Exists',
});
}
});
const password_is_valid = authentication.passwordSchema.validate(password);
if (!password_is_valid) {
return res.status(400).json({
status: 'failed',
message: 'password requirements not met',
});
}
next();
};
module.exports = {
verifySignUpInit,
verifySignUp,
};
and finally in my controller i have this..
const config = require('../config');
const db = require('../models');
var jwt = require('jsonwebtoken');
var bcrypt = require('bcryptjs');
const { validationResult } = require('express-validator');
const { User, Role } = db;
const { token_expiry_time, refresh_token_expiry_time } = config.authentication;
const signUp = (req, res) => {
const { email, phone, first_name, last_name, password } = req.body;
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({
status: 'failed',
message: errors.array(),
});
}
bcrypt.hash(password, 8, (err, hash) => {
if (err) {
return res.status(500).json({
status: 'error',
message: err,
});
}
const user = new User({
first_name: first_name,
last_name: last_name,
email: email,
phone: phone,
password: hash,
});
Role.findOne({ name: 'is_user' }, (err, role) => {
if (err) {
res.status(500).json({
status: 'error',
message: err,
});
return;
}
user.roles = [role._id];
user.save((err) => {
if (err) {
return res.status(500).json({
status: 'error',
message: err,
});
}
return res.status(201).json({
status: 'success',
data: {
user,
},
});
});
});
});
};
module.exports = {
signUp,
};
i cant tell what i am doing wrong :(
authController.signup
should be:
authController.signUp
You have to use the same capitalization for the property name you exported.

Categories

Resources