Mongoose: Operation `schema.findOne()` buffering timed out after 10000ms - node.js

I have a REST API made with Node.js and I use Mongoose to connect with MongoDB. Whenever I try to interact with the DB using Mongoose, I get the timeout error.
I have made sure that the DB is running and accepts connections from my IP. Using the same connection method in other projects works for some reason.
I am using mobile hotspot connection. Could that be an issue?
server.js
const express = require('express');
const app = express();
const cors = require('cors');
const userRoutes = require('../Backend/routes/userRoutes')
const taskRoutes = require('../Backend/routes/taskRoutes')
const mongoose = require('mongoose');
require('dotenv').config()
mongoose.connect(process.env.DB_CONNECTION);
app.use(cors());
app.use(express.json());
app.use(userRoutes)
app.use(taskRoutes)
app.listen(process.env.PORT || 3000 , () => {
console.log("API is now running.")
});
userRoutes.js
const userController = require('../controllers/userController')
const express = require('express');
const router = express.Router();
router.get('/users/currentUser', userController.getCurrentUserData)
router.get('/users/:userId', userController.getUserData)
router.post('/register', userController.register);
router.post('/login', userController.login);
module.exports = router;
Method in userController that causes the error (the error is caused by no matter which method I call out)
exports.login = async (req, res) => {
if (!req.body.username || !req.body.password) {
return res.status(400).send("Missing one or all required request body fields: username, password");
}
let existingUser;
try {
existingUser = await userSchema.findOne({ username: req.body.username });
} catch(err) {
return res.status(500).send("Internal server error."); //Error comes from here
}
if (!existingUser) {
return res.status(404).send('User not found');
}
const isPasswordCorrect = await bcrypt.compare(req.body.password, existingUser.password);
if (!isPasswordCorrect) {
return res.status(401).send('Invalid credentials');
}
let token;
try {
token = jwt.sign(
{ userId: existingUser._id, username: existingUser.username, tasks: existingUser.tasks},
process.env.SECRET,
{ expiresIn: "1h" }
);
} catch (err) {
console.log(err);
return res.status(500).send("Couldn't create JWT.")
}
return res.status(200).json({ token: token });
}
User model
const mongoose = require('mongoose');
const bcrypt = require('bcrypt');
const userSchema = new mongoose.Schema({
username:{
type: String,
unique: true
},
password:{
type: String
},
tasks:{
type:[mongoose.Types.ObjectId]
}
})
userSchema.pre('save', async function(next) {
const salt = await bcrypt.genSalt();
this.password = await bcrypt.hash(this.password, salt);
next();
});
module.exports = mongoose.model('user',userSchema);
.env
DB_CONNECTION="mongodb://localhost:27017/test"
SECRET='test'

Related

Experiencing an issue with the .save() function in MongoDB

I am using Node.js, Express, and MongoDB for a project and in MongoDB, .save() is not working.
index.js file code:
const express = require("express");
const app = express();
const dotenv = require("dotenv");
const helmet = require("helmet");
const morgan = require("morgan");
const mongoose = require("mongoose");
//middleware;
app.use(express.json()); //for json files;
app.use(helmet());
app.use(morgan("common"));
//routing paths;
const authUser = require("./routes/auth");
// for secrets keys;
dotenv.config();
//Connecting to Mongoose;
mongoose.connect(process.env.MONGO_PATH, {
userNewUrlParser: true, useUnifiedTopology: true
}, () => {
console.log("Connected to MongoDb");
}
)
app.use("/api/auth", authUser);
app.listen(9000, () => {
console.log("Server is Running...");
}
)
Model file name User.js:
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const UserSchema = new Schema({
username: {
type: String,
require: true,
},
password: {
type: String,
require: true,
}
});
const User= mongoose.model("User", UserSchema);
module.exports = User;
auth.js file
const router = require("express").Router();
const User = require("../models/User");
const bcrypt = require("bcrypt");
//for register;
router.get("/register", async (req, res) => {
try {
const newuser = new User({
username: "herovinay",
password: "herovinay"
});
newuser.save((err)=> {
if (err) {
res.status(500).json({ msg: "internal error is here"});
}
else {
res.status(200).json({ msg: "Data saved successfully..." });
}
});
} catch (err) {
res.send("second error is here");
}
})
module.exports = router;
When accessing localhost:9000/api/auth/register, the output is msg: "internal error is here".
Screenshot of output:
Every time I tried to hit that request, the same error came over and over again.
I tried everything and was unable to save my data to the MongoDB cluster.
Change the get method to post. to create new data in the server the post method is used. and also add the await keyword before the newuser.save(),
here is a example.
const router = require("express").Router();
const User = require("../models/User");
const bcrypt = require("bcrypt");
//for register;
router.post("/register", async (req, res) => {
try {
const newuser = new User({
username: "herovinay",
password: "herovinay"
});
await newuser.save((err)=> {
if (err) {
res.status(500).json({ msg: "internal error is here"});
}
else {
res.status(200).json({ msg: "Data saved successfully..." });
}
});
} catch (err) {
res.send("second error is here");
}
})
module.exports = router;

POSTMAN API Request of (POST) is not working

I am new to node.js and facing some errors. I am trying to send a POST request on Postman but it's giving me blank with no data in it. And also I checked if my data is valid or not then I got, the data I am sending is valid. Can anyone suggest me?
This is my index File(index.js):
const express = require("express");
const app = express();
const dotenv = require("dotenv");
const mongoose = require("mongoose");
//Import Routes
const authRoute = require("./routes/auth");
const postRoute = require("./routes/posts");
dotenv.config();
//connect to DB
mongoose.connect(
process.env.DB_CONNECT,
{ useNewUrlParser: true, useUnifiedTopology: true, useCreateIndex: true },
() => console.log("connected to DB!!")
);
//Middleware
app.use(express.json());
//Route Middlewares
app.use("/api/user", authRoute);
app.use("/api/posts", postRoute);
//PORT NUMBER
const port = process.env.PORT || 8080; // default port to listen
// start the Express server
app.listen(port, () => {
console.log(`server started at http://localhost:${port}`);
});
This is my Auth file(auth.js):
const router = require("express").Router();
const User = require("../model/User");
const jwt = require("jsonwebtoken");
const bcrypt = require("bcryptjs");
const { registerValidation, loginValidation } = require("../validation");
//REGISTER
router.post("/register", async (req, res) => {
console.log("register");
//Lets validate a data before we make a user
const { error } = registerValidation(req.body);
if (error) return res.status(400).send(error.details[0].message);
//Checking if the user is already in the database
const emailExist = await User.findOne({ email: req.body.email });
if (emailExist) return res.status(400).send("Email Already Exists");
//HASH THE PASSWORD
const salt = await bcrypt.genSalt(10);
const hashedPassword = await bcrypt.hash(req.body.password, salt);
//Create a New User
const user = new User({
name: req.body.name,
email: req.body.email,
password: hashedPassword,
});
try {
const savedUser = await user.save();
res.send({ user: user._id });
} catch (err) {
res.status(400).send(err);
}
});
//LOGIN
router.post("/login", async (req, res) => {
//Lets validate a data before we make a user
const { error } = loginValidation(req.body);
if (error) return res.status(400).send(error.details[0].message);
//Checking if the email exists in the database
const user = await User.findOne({ email: req.body.email });
if (!user) return res.status(400).send("Email is Not Found");
//Check if password is correct
const validPass = await bcrypt.compare(req.body.password, user.password);
if (!validPass) return res.status(400).send("Invalid Password");
//Create and assign a Token
const token = jwt.sign({ _id: user._id }, process.env.TOKEN_SECRET);
res.header("auth-token", token).send(token);
});
module.exports = router;
As you can see:
I am not able to send data and fetch it with the POST request, DB is connected too.
Try console.log(req.body).
If your req.body is empty then you need to add a package body-parser in middleware(index.js file).
const bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({ extended: true }));

why is my cookie not saving in the browsers?

when i run router.post("/signin", async (req, res) from auth.js then cookie is not saving in my local host .
this is index.js
const express = require("express");
const dotenv = require("dotenv");
const mongoose = require("mongoose");
const cors = require("cors");
const { google } = require("googleapis");
const cookieParser= require('cookie-parser');
const app = express();
app.use(cors());
app.use(express.json());
const passport = require("passport");
dotenv.config({ path: "./config.env" });
const db = require("./db/connection");
app.use(require('./router/auth'));
const User= require("./UserSchema/Schma")
const messages=require("./sendMessage/message");
// messages()
// .then((e)=>{console.log(e)})
app.use(cookieParser());
app.listen(3001, (req, res) => {
console.log(`server running at port no 3001`);
});
this is auth.js
const express = require("express");
const router = express.Router();
const bcrypt = require('bcryptjs');
const jwt= require('jsonwebtoken');
const User = require("../UserSchema/Schma");
const cookieParser = require("cookie-parser");
const authenticate = require('../middleware/authenticate');
let token;
router.post("/signin", async (req, res) => {
console.log(req.body);
// res.cookie("raushan", "raushan");
try {
const { email, password } = req.body;
if (!email || !password) {
return res.json({ error: "invalid credentials you added " });
}
const details = await User.findOne({ email: email });
console.log(details);
if (!details) {
return res.json({ error: "users error" });
}
else
{
const isMatch = await bcrypt.compare(password,details.password);
console.log(isMatch);
token= await details.generateAuthToken();
console.log(token);
res.cookie("jwtoken",token,{
expiresIn:"1h",
httpOnly:true,
secure:true
}
);
if (!isMatch) {
return res.status(400).json({ error: "invalid credientials" });
} else {
return res.json({ message: "user signin successfully" });
}
}
}
catch {
console.log("something going bad");
res.status(400).json({ error: "sorry something missing" })
}
});
module.exports = router;
and this Schema.js and inside this generateAuthToken() function
const mongoose = require("mongoose");
const bcrypt = require("bcryptjs");
const jwt= require("jsonwebtoken");
const userSchema = new mongoose.Schema({
name: {
type: String,
require:true,
},
email: {
type: String,
require:true,
},
phone :{
type:Number,
require:true,
},
work:{
type:String,
require:true,
},
password:{
type:String,
require:true,
}
,
cpassword:{
type:String,
require:true,
},
tokens:[{
token:{
type:String,
require:true,
}
}]
});
userSchema.pre('save', async function(next) {
if(this.isModified('password'))
{
this.password=await bcrypt.hash(this.password,12);
this.cpassword=await bcrypt.hash(this.cpassword,12);
}
next();
})
userSchema.methods.generateAuthToken= async function(){
try {
let token= jwt.sign({_id:this._id},process.env.SECRET_KEY);
this.tokens=this.tokens.concat({token:token});
await this.save();
return token;
} catch (error) {
console.log(err);
}
}
const User = mongoose.model("USER", userSchema);
module.exports = User;
I am trying it from last two days but i can't get any solution till now please help .
It's not working because of the secure flag in auth.js:
res.cookie("jwtoken",token,{
expiresIn:"1h",
httpOnly:true,
secure:true
}
);
This is a great security practice, but it will not work on localhost because it's not over HTTPS. You need to either:
Disable the secure flag for development only, or
Enable https and use self-signed certificates for localhost development, or
Use a TLS-terminating proxy such as haproxy

OverwriteModelError: Cannot overwrite `user` model once compiled

I am facing this issue. I looked online for hours to find out what the problem is before posting here. I keep getting this error OverwriteModelError: Cannot overwrite ``user`` model once compiled. after sending a post request via postman and I can't find out what's going on. could you help me find out what's going on? thank you so much in advance!
server.js
const express = require("express");
const app = express();
const user = require("./routes/user");
const connectDB = require("./config/db");
connectDB();
app.use(express.json({extended: false}));
app.get("/", (req, res) => {
res.send("welcome to our api");
});
app.use("/user", user);
const PORT = 3000 || process.env.PORT;
app.listen(PORT, () => {
console.log(`PORT ${PORT} listening and refeshing...`);
});
db.js
const mongoose = require("mongoose");
const connectDB = () =>
mongoose
.connect(
"some database",
{
useNewUrlParser: true,
useUnifiedTopology: true,
}
)
.then(
() => {
console.log("mongoDB conneted");
},
(err) => {
console.log(err);
}
);
module.exports = connectDB;
user.js
const express = require("express");
const router = express.Router();
const mongoose = require("mongoose");
const bcrypt = require("bcrypt");
const jwt = require("jsonwebtoken");
const {body, validationResult} = require("express-validator");
router.get("/", (req, res) => {
res.send("hello");
});
router.post(
"/",
[
// password must be at least 5 chars long
body("email").isEmail(),
body("password").not().isEmpty(),
],
async (req, res) => {
const errors = validationResult(req);
if (!errors.isEmpty) {
return res.status(400).json({errors: errors.array()});
}
try {
const UsersSchema = mongoose.Schema({
email: {type: String, required: true},
password: {type: String, required: true},
});
var users = mongoose.model("user", UsersSchema);
var user = new users({
email: req.body.email,
password: req.body.password,
});
const salt = await bcrypt.genSalt(10);
user.password = await bcrypt.hash(req.body.password, salt);
user.save((err, user1) => {
if (err) {
console.log("error posing user");
throw err;
}
});
console.log(user.id);
const payload = {
user: {
id: user.id,
},
};
} catch (error) {
console.log(error);
res.status(400);
}
}
);
module.exports = router;
Every time the route runs it tries to create a schema which is already created.Mongoose create the collection with the first argument user by converting it to plural i.e. users.

User.find() returns empty response in mongodb express

I'm working with nextjs and express .I'm implementing simple signin form.I'm sending user credential and using find() ,checking whether user exist or not.but find() returns empty response.
In terminal find() returns array of that record.
model
const mongoose = require('mongoose')
const schema = mongoose.Schema
const user = new schema({
username: { type: String} ,
password: { type: String},
role: { type: String},
})
module.exports = mongoose.model('user', user);
router.js
const express = require('express')
const router = express.Router()
const user = require('../models/user');
router.post('/user/signin', (req, res) => {
user.find({
username: req.body.username, password: req.body.password
}, (err, user) => {
console.log(user);
if (err) {
result.status(404).send({ error: 'There is some error' });
} else if (user.length == 1) {
var token = 'kkl';//token
res.send({ token });
} else {
console.log(err);
res.send('Incorrect Email and Password');
}
});
})
module.exports = router;
this.is my index.js
const express = require('express')
const next = require('next')
const bodyParser = require('body-parser')
const PORT = process.env.PORT || 4000
const dev = process.env.NODE_DEV !== 'production' //true false
const nextApp = next({ dev })
const handle = nextApp.getRequestHandler() //part of next config
const mongoose = require('mongoose')
const router = express.Router();
nextApp.prepare().then(() => {
const app = express();
const db = mongoose.connect('mongodb://localhost:27017/knowledgeBase')
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use('/knowledgeBase', require('./routes/router'));
app.get('*', (req, res) => {
return handle(req, res) // for all the react stuff
})
app.listen(PORT, err => {
if (err) {
console.log(err);
throw err;
}
console.log(`ready at http://localhost:${PORT}`)
})
})
please help
What response you get when you try this?
According to the response I will edit response.
router.post("/user/signin", async (req, res) => {
if (!req.body.username) return res.status(400).send("username cannot be null");
if (!req.body.password) return res.status(400).send("Password cannot be null");
const user = await User.findOne({ username: req.body.username});
if (!user) return res.status(400).send("User not found");
if (req.body.password!== user.password)
return res.status(400).send("Invalid password.");
res.send("logined");
});

Resources