Not being able to connect to mongoDB - node.js

I am trying to connect my app to MongoDB but i get the following error as i run my app:
DepracationWarning: current URL string parser is deprecated, and will be removed in a future version. To use the new parser, pass option { useNewUrlParser: true } to MongoClient.connect.
[MONGODB DRIVER] Warning: Current Server Discover and Monitoring engine is deprecated, and will be removed in a future version. To use the new Server Discover and Monitoring engine, pass option { useUnifiedTopology: true } to MongoClient constructor
I know both above are just warnings but they are stopping my app and no letting me run it.
This is how i am setting the connection to mongodb in app.js:
const path = require('path');
const express = require('express');
const bodyParser = require('body-parser');
const mongoose = require('mongoose');
const session = require('express-session');
const MongoDBStore = require('connect-mongodb-session')(session);
const csrf = require('csurf');
const flash = require('connect-flash');
const multer = require('multer');
const errorController = require('./controllers/error');
const User = require('./models/user');
const MONGODB_URI =
'mongodb+srv://mateoghidini:<PASSWORD>#cluster0.9dernor.mongodb.net/test';
const app = express();
const store = new MongoDBStore({
uri: MONGODB_URI,
collection: 'sessions'
});
const csrfProtection = csrf();
const fileStorage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, 'images');
},
filename: (req, file, cb) => {
cb(null, new Date().toISOString() + '-' + file.originalname);
}
});
const fileFilter = (req, file, cb) => {
if (
file.mimetype === 'image/png' ||
file.mimetype === 'image/jpg' ||
file.mimetype === 'image/jpeg'
) {
cb(null, true);
} else {
cb(null, false);
}
};
app.set('view engine', 'ejs');
app.set('views', 'views');
const adminRoutes = require('./routes/admin');
const shopRoutes = require('./routes/shop');
const authRoutes = require('./routes/auth');
app.use(bodyParser.urlencoded({ extended: false }));
app.use(
multer({ storage: fileStorage, fileFilter: fileFilter }).single('image')
);
app.use(express.static(path.join(__dirname, 'public')));
app.use('/images', express.static(path.join(__dirname, 'images')));
app.use(
session({
secret: 'my secret',
resave: false,
saveUninitialized: false,
store: store
})
);
app.use(csrfProtection);
app.use(flash());
app.use((req, res, next) => {
res.locals.isAuthenticated = req.session.isLoggedIn;
res.locals.csrfToken = req.csrfToken();
next();
});
app.use((req, res, next) => {
// throw new Error('Sync Dummy');
if (!req.session.user) {
return next();
}
User.findById(req.session.user._id)
.then(user => {
if (!user) {
return next();
}
req.user = user;
next();
})
.catch(err => {
next(new Error(err));
});
});
app.use('/admin', adminRoutes);
app.use(shopRoutes);
app.use(authRoutes);
app.get('/500', errorController.get500);
app.use(errorController.get404);
app.use((error, req, res, next) => {
// res.status(error.httpStatusCode).render(...);
// res.redirect('/500');
res.status(500).render('500', {
pageTitle: 'Error!',
path: '/500',
isAuthenticated: req.session.isLoggedIn
});
});
mongoose
.connect(MONGODB_URI)
.then(result => {
app.listen(3000);
})
.catch(err => {
console.log(err);
});
Is any of the packages that i am requiring above deprecated? Or should i include new lines of code that i am missing?

I remember having similar issue, so first of all make sure your mongoose version is above 5.7.1, if it is you can pass the options objects suggested from your warning message to your connect function like so:
mongoose
.connect(MONGODB_URI, {useNewUrlParser: true, useUnifiedTopology: true})
.then(result => {
app.listen(3000);
})
.catch(err => {
console.log(err);
});

Related

TypeError: Cannot read properties of undefined (reading 'isLoggedIn')

In my app i was able to register a user and log in with that user but when i submit the form to add a product i have the following error and my app crashes
TypeError: Cannot read properties of undefined (reading 'isLoggedIn')
This is my app.js:
const path = require('path');
const express = require('express');
const bodyParser = require('body-parser');
const mongoose = require('mongoose');
const session = require('express-session');
const MongoDBStore = require('connect-mongodb-session')(session);
const csrf = require('csurf');
const flash = require('connect-flash');
const multer = require('multer');
const errorController = require('./controllers/error');
const User = require('./models/user');
const MONGODB_URI =
'mongodb+srv://mateoghidini:<PASSWORD>#cluster0.9dernor.mongodb.net/test';
const app = express();
const store = new MongoDBStore({
uri: MONGODB_URI,
collection: 'sessions'
});
const csrfProtection = csrf();
const fileStorage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, 'images');
},
filename: (req, file, cb) => {
cb(null, new Date().toISOString() + '-' + file.originalname);
}
});
const fileFilter = (req, file, cb) => {
if (
file.mimetype === 'image/png' ||
file.mimetype === 'image/jpg' ||
file.mimetype === 'image/jpeg'
) {
cb(null, true);
} else {
cb(null, false);
}
};
app.set('view engine', 'ejs');
app.set('views', 'views');
const adminRoutes = require('./routes/admin');
const shopRoutes = require('./routes/shop');
const authRoutes = require('./routes/auth');
app.use(bodyParser.urlencoded({ extended: false }));
app.use(
multer({ storage: fileStorage, fileFilter: fileFilter }).single('image')
);
app.use(express.static(path.join(__dirname, 'public')));
app.use('/images', express.static(path.join(__dirname, 'images')));
app.use(
session({
secret: 'my secret',
resave: false,
saveUninitialized: false,
store: store
})
);
app.use(csrfProtection);
app.use(flash());
app.use((req, res, next) => {
res.locals.isAuthenticated = req.session.isLoggedIn;
res.locals.csrfToken = req.csrfToken();
next();
});
app.use((req, res, next) => {
// throw new Error('Sync Dummy');
if (!req.session.user) {
return next();
}
User.findById(req.session.user._id)
.then(user => {
if (!user) {
return next();
}
req.user = user;
next();
})
.catch(err => {
next(new Error(err));
});
});
app.use('/admin', adminRoutes);
app.use(shopRoutes);
app.use(authRoutes);
app.get('/500', errorController.get500);
app.use(errorController.get404);
app.use((error, req, res, next) => {
// res.status(error.httpStatusCode).render(...);
// res.redirect('/500');
res.status(500).render('500', {
pageTitle: 'Error!',
path: '/500',
isAuthenticated: req.session.isLoggedIn
});
});
mongoose
.connect(MONGODB_URI, {useNewUrlParser: true, useUnifiedTopology: true})
.then(result => {
app.listen(3000);
})
.catch(err => {
console.log(err);
});
So i read in other questions that it might be an issue of file pathing but i don´t know exactly what is that is breaking my app. Does it has anything to do with file pathing or just an authentication error which seems odd due that i was able to log in with an existing user.

Cannot remote access to MongoDB Atlas from anywhere except my house

I am working on a full stack MERN app.
When I am working on the project from my home, everything works fine.
However, as soon as I change my location to somewhere else(different IP adress) like a cafe, the connection to mongoDB fails..
This is what I have tried:
1,Add the IP address of the new location to the network access of my DB => doesn’t work
2, Add “allow access from anywhere” to the network access => doesn’t work
3, disabled firewall on my MacBookAir => doesn’t work
4, create a new user in the DB and try to use the new user login => doesn’t work
5, I am not using any proxy.
I am using macOS BigSur(version 11.5.2)
this is my index.js file
const express = require("express");
const app = express();
const mongoose = require("mongoose");
const dotenv = require("dotenv");
const helmet = require("helmet");
const morgan = require("morgan");
const userRoute = require("./routes/users");
const auth = require("./routes/auth");
const postRoute = require("./routes/posts");
const motorRoute = require("./routes/motors");
const multer = require("multer");
const path = require("path");
var cors = require("cors");
dotenv.config();
//connect to the DB here
mongoose.connect(
process.env.MONGO_URL,
{ useNewUrlParser: true, useUnifiedTopology: true },
() => {
console.log("connected to MongoDB");
}
);
app.use("/images", express.static(path.join(__dirname, "public/images/")));
app.use(express.json());
// app.use(helmet());
app.use(morgan("common"));
// app.use(cors({ origin: true, credentials: true }));
const storage = multer.diskStorage({
destination: (req, file, cb) => {
if (req.path == "/api/upload") {
console.log("yes the path is /api/upload");
cb(null, "public/images/posts/");
}
if (req.path == "/api/upload/profile") {
console.log("yes the path is /api/upload/profile");
cb(null, "public/images/person/");
}
// cb(null, "public/images");
},
filename: (req, file, cb) => {
cb(null, file.originalname);
},
});
//upload post from share
const upload = multer({ storage });
app.post("/api/upload", upload.single("file"), (req, res) => {
try {
return res.status(200).json("File uploaded successfully");
} catch (error) {
console.log(error);
}
});
///upload profile picture
const upload2 = multer({ storage });
app.post("/api/upload/profile", upload2.single("file"), (req, res) => {
try {
return res.status(200).json("File uploaded successfully");
} catch (error) {
console.log(error);
}
});
//get all the users
app.get("/api/allusers", (req, res) => {
try {
console.log("debug: I will try to get all the users");
return res.status(200).json(" will return users here");
} catch (error) {
console.log(error);
}
});
//set some routes in here
app.use("/api/users", userRoute);
app.use("/api/auth", auth);
app.use("/api/posts", postRoute);
app.use("/api/motors", motorRoute);
app.listen(8800, () => {
console.log("Backend server is running");
});
Please let me know if you need more information about it.
Thank you
You are only allowed to connect from whitelisted IPs.
https://www.mongodb.com/docs/atlas/security/ip-access-list/

'Cannot GET /api/items'

Working on a MERN application as a way to learn how it all works, but I am stuck trying to get my routes to display. I don't get any other errors, and if I use a simple app.get('/'), I am able to see that just fine; it seems that the routes I have defined are not being recognized for some reason.
require('dotenv').config();
const express = require('express');
const cors = require('cors');
const app = express();
const port = process.env.PORT;
const options = {
origin: 'http://localhost:8081'
}
app.use(cors(options));
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
const db = require('./models');
db.mongoose
.connect(db.url, {
useNewUrlParser: true,
useUnifiedTopology: true,
})
.then(() => {
console.log('Successfully connected.');
})
.catch((error) =>{
console.log(`Connection failed. Error: ${error}`);
process.exit();
}
);
require('./routes/items.routes')(app)
app.listen(port, () => {
console.log(`Listening at localhost:${port}`);
});
const multer = require('multer');
const dir = './public/';
const storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, dir);
},
filename: (req, file, cb) => {
const fileName = file.originalname.toLowerCase().split(' ').join('-');
cb(null, fileName + '-' + Date.now());
}
});
var upload = multer({
storage: storage,
fileFilter: (req, file, cb) => {
if (file.mimetype == 'image/png' || file.mimetype == 'image/jpg' || file.mimetype == 'image/jpeg') {
cb(null, true);
} else {
cb(null, false);
return cb(new Error('Invalid file type.'));
}
}
});
module.exports = app => {
const items = require('../controllers/items.controller');
let router = require('express').Router();
router.post('/', upload.single('icon'), items.create);
router.delete('/:id', items.delete);
app.use('/api/items', router);
};
I followed this and this as a start point. Unsure what I am missing or why it is unable to retrieve my POST route.
The error in your title:
Cannot GET /api/items
means it is a GET request to /api/items. But, you don't have a GET handler for that route. You only have a POST handler for that route defined with these two lines of code:
router.post('/', upload.single('icon'), items.create);
app.use('/api/items', router);
So, you apparently need to change your test on that route to a POST, not a GET and the POST will be expecting a body part with the data for an icon in it.
If you want to see exactly what is getting to your router (for debugging/troubleshooting purposes), you can add this right after you declare the router as the first item you register on the router.
router.use((req, res, next) => {
console.log(`In router: ${req.method}:${req.originalUrl}`);
next();
});

I cant access the req.user from passport outside of my routes folder. MERN stack redux node.js

I am trying to access the req.user that passport creates when doing a google o auth strategy. I can access the req.user in the routes file below, but when I try to access it in my userController file it is showing up as undefined.
Why is user accessible in routes file but not userController?
googleAuthRoutes.js:
const passport = require('passport');
const requireLogin = require('../middlewares/requireLogin')
const cors = require('cors');
const axios = require('axios');
const Template = require('../models/Template');
const corsOptions ={
origin: true,
credentials:true, //access-control-allow-credentials:true
optionSuccessStatus:200
}
module.exports = app => {
app.get('/auth/google',
passport.authenticate('google', {
scope: ['profile', 'email']
}));
app.get(
'/auth/google/callback',
passport.authenticate('google'),
(req, res) => {
res.redirect('/dashboard');
}
);
app.post('/templates/create', async (req, res) => {
const { template, body } = req.body
console.log(req.user)
const newTemplate = new Template({
template: template,
body: body,
_user: req.user.id
})
try {
await newTemplate.save()
return res.status(200).json({
message: "Successfully saved template"
})
} catch (err) {
return console.log(err)
}
});
app.get('/api/logout', cors(), (req, res) => {
req.logout();
res.redirect('http://localhost:3000');
});
app.get('/api/current_user', (req, res) => {
res.send(req.user);
})
}
when I call the res.send(req.user) here above it sends the user no problem
But it is undefined with the /templates/create route middleware.
the console.log(req.user) is coming back as undefined??
index.js:
const express = require('express');
const cors = require('cors')
const mongoose = require('mongoose');
const cookieSession = require('cookie-session');
const passport = require('passport');
const keys = require('./config/keys');
const bodyParser = require('body-parser')
require("dotenv").config();
require('./models/GoogleUserModel'); // the user model must be placed before this services passport// this must be ran after requiring model bcuz this needs the model. ORDER
require('./models/UserModel');
require('./services/passport');
const corsOptions ={
origin:'http://localhost:3000',
credentials: true, //access-control-allow-credentials:true
optionSuccessStatus:200
}
const app = express();
app.use(cors(corsOptions))
mongoose.connect(keys.mongoURI, {
useNewUrlParser: true,
useCreateIndex: true,
useUnifiedTopology: true
})
mongoose.connection.on('error', () => {
throw new Error (`unable to connect to database: ${keys.mongoURI}`)
});
app.use(bodyParser.json())
app.use(express.urlencoded( { extended: true }))
app.use(
cookieSession({
maxAge: 30 * 24 * 60 * 60 * 1000,
keys: [keys.cookieKey]
})
)
app.use(passport.initialize());
app.use(passport.session());
require('./routes/userRoutes')(app);
require('./routes/googleAuthRoutes')(app);
require('./routes/messageRoutes')(app);
app.use((err, req, res, next) => {
if (err.name === 'UnauthorizedError') {
res.status(401).json({"error" : err.name + ": " + err.message})
} else if (err) {
res.status(400).json({"error" : err.name + ": " + err.message})
console.log(err)
}
})
const PORT = process.env.PORT || 5000;
app.listen(PORT);
Again, Why is the req.user available in the app.get to /api/current_user but available in a post request to /templates/create?
Im trying to add the user.id to the schema when it saves so i can retrieve each template by the user.id and not show everyone everybody elses templates lol

String Functions are not working in Multer

While I tried to rename uploaded image with date, an error is being thrown and it shows "Cannot read property 'isLoggedIn' of undefined".
I would be happy if anyone could solve the problem. Thanks in advance
I think from Multer an error is thrown and it goes to error handling middleware.
here is my app.js
const path = require('path');
const express = require('express');
const bodyParser = require('body-parser');
const mongoose = require('mongoose');
const session = require('express-session');
const MongoDBStore = require('connect-mongodb-session')(session);
const csrf = require('csurf');
const flash = require('connect-flash');
const multer = require('multer');
const errorController = require('./controllers/error');
const User = require('./models/user');
const MONGODB_URI = 'mongodb+srv://axxxxn:xxxxxx#cluster0-sm6lw.mongodb.net/sxhxoxxxp';
const app = express();
const store = new MongoDBStore({
uri: MONGODB_URI,
collection: 'sessions'
});
const csrfProtection = csrf();
const fileStorage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, 'images');
},
filename: (req, file, cb) => {
cb(null, new Date().toISOString() + '-' + file.originalname );
}
});
app.set('view engine', 'ejs');
app.set('views', 'views');
const adminRoutes = require('./routes/admin');
const shopRoutes = require('./routes/shop');
const authRoutes = require('./routes/auth');
app.use(bodyParser.urlencoded({ extended: false }));
app.use(multer({ storage: fileStorage }).single('image'));
app.use(express.static(path.join(__dirname, 'public')));
app.use(
session({
secret: 'my secret',
resave: false,
saveUninitialized: false,
store: store
})
);
app.use(csrfProtection);
app.use(flash());
app.use((req, res, next) => {
res.locals.isAuthenticated = req.session.isLoggedIn;
res.locals.csrfToken = req.csrfToken();
next();
});
app.use((req, res, next) => {
//throw new Error('Sync Dummy');
if (!req.session.user) {
return next();
}
User.findById(req.session.user._id)
.then(user => {
//throw new Error('Dummy');
if(!user){
return next()
}
req.user = user;
next();
})
.catch(err => {
next(new Error(err));
});
});
app.use('/admin', adminRoutes);
app.use(shopRoutes);
app.use(authRoutes);
app.get('/500', errorController.get500);
app.use(errorController.get404);
app.use((error, req, res, next) => {
res.status(404).render('500', {
pageTitle: 'Error 500',
path: '/500',
isAuthenticated: req.session.isLoggedIn
});
});
mongoose
.connect(MONGODB_URI)
.then(result => {
app.listen(3000);
console.log('connected');
})
.catch(err => {
console.log(err);
});
I had this problem on windows: new Date().toISOString() gives a 'zulu' date, something like
2020-08-13T10:01:36.688Z. But : is not a valid character in windows filenames. This worked for me:
const dateStr = new Date().toISOString().replace(/:/g, '-');
cb(null, dateStr + '-' + file.originalname);  
I think this problem is related to Windows, maybe Windows will be angry if you try to put ":" inside fileName so instead of "toIsoString" you can use "toDateString" like this:
cb(null, new Date().toDateString().replace(/\s/g, '_') + '_' + new Date().toTimeString().replace(/[\s:]/g, '_') + file.originalname);
By the way, this is more readable for the user and contains all the information (date and time)
Finally, make sure to replace '\\' to '/' inside file.path when you add imageUrl to db like:
{
...,
imageUrl: req.file.path.replace('\\', '/'),
...
}

Resources