Username entries all come out as 'null' in mongodb nodejs - javascript

I'm getting started in node.js and trying to create a user authentication system for my web application. I am watching a tutorial on YouTube and have followed every step through. When it comes to actually registering my user. the username entry in the collecting comes out as null. I'm not sure why this is happening, and I'm a rookie to javascript and node js. I am using passport, express and mongodb modules.
this is the video i am watching 'https://www.youtube.com/watch?v=m2ZzRZemc98'
If anyone knows how to fix my issue, please respond
Thanks
This is my main app.js
var express = require("express");
var path = require("path");
var cookieParser = require("cookie-parser");
var logger = require("morgan");
const MongoClient = require("mongodb").MongoClient;
const passport = require("passport");
const Strategy = require("passport-local").Strategy;
const session = require("express-session");
const flash = require("connect-flash");
const authUtils = require("./utils/auth");
const hbs = require("hbs");
var indexRouter = require("./routes/index");
var usersRouter = require("./routes/users");
const authRouter = require("./routes/auth");
var app = express();
//Connet to MongoDB database
MongoClient.connect("mongodb://localhost", (err, client) => {
if (err) {
throw err;
}
const db = client.db("user-profiles");
const users = db.collection("users");
app.locals.users = users;
});
//Passport streategy
passport.use(
new Strategy((username, passport, done) => {
app.locals.users.findOne({ username }, (err, user) => {
if (err) {
return done(err);
}
if (!user) {
return done(null, false);
}
if (user.password != authUtils.hashPassword(password)) {
return done(null, false);
}
return done(null, user);
});
})
);
passport.serializeUser((user, done) => {
done(null, user._id);
});
passport.deserializeUser((id, done) => {
done(null, { id });
});
// view engine setup
app.set("views", path.join(__dirname, "views"));
app.set("view engine", "hbs");
hbs.registerPartials(path.join(__dirname, "views/partials"));
app.use(logger("dev"));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, "public")));
app.use(
session({
secret: "session secret",
resave: false,
saveUninitialized: false
})
);
app.use(passport.initialize());
app.use(passport.session());
app.use(flash());
app.use((req, res, next) => {
res.locals.loggedIn = req.isAuthenticated();
next();
});
app.use("/", indexRouter);
app.use("/users", usersRouter);
app.use("/auth", authRouter);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
next(createError(404));
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get("env") === "development" ? err : {};
// render the error page
res.status(err.status || 500);
res.render("error");
});
module.exports = app;
This is my auth.js
const router = express.Router();
const authUtils = require("../utils/auth");
const passport = require("passport");
router.get("/login", (req, res, next) => {
const messages = req.flash();
res.render("login", { messages });
});
router.post(
"/login",
passport.authenticate("local", {
failureRedirect: "/auth/login",
failureFlash: "Wrong username or password"
}),
(req, res, next) => {
res.redirect("/users");
}
);
router.get("/register", (req, res, next) => {
const messages = req.flash();
res.render("register", { messages });
});
router.post("/register", (req, res, next) => {
const registrationParams = req.body;
const users = req.app.locals.users;
const payload = {
username: registrationParams.username,
password: authUtils.hashPassword(registrationParams.password)
};
users.insertOne(payload, err => {
if (err) {
req.flash("error", "User account already exists");
} else {
req.flash("success", "User account was registered succesfully");
}
res.redirect("/auth/register");
});
});
router.get("/logout", (req, res, next) => {
req.session.destroy();
res.redirect("/");
});
module.exports = router;

I fixed my error, it was a mistake i made in the handlebars file, i put the input name as none the class of form-control and then named it again. Obviously the js looked at the first name and not the second name

Related

passport.js .register() function goes in infinite loop

while submitting the post request it does not redirect me to the failureRedirect route, nor to the SuccessRedirect one, instead, the web page enters into an endless loop. Why is this happening.
It has two files
app.js:
const express = require('express');
const path = require('path');
const mongoose = require('mongoose');
const ejsmate = require('ejs-mate');
const session = require('express-session');
const flash= require('connect-flash');
const methodOverride = require('method-override');
const passport= require('passport');
const LocalStrategy= require('passport-local');
const User= require('./models/user');
const ExpressError = require('./Utilities/ExpressError');
const campgroundRoutes=require('./Routes/campgrounds');
const reviewRoutes=require('./Routes/review');
const userRoutes=require('./Routes/User');
mongoose.connect('mongodb://localhost:27017/yelp-camp');
const db = mongoose.connection;
db.on('error', console.error.bind(console, "connection error:"));
db.once('open', () => {
console.log("open connection");
});
const app = express();
app.engine('ejs', ejsmate)
app.set('view engine', 'ejs');
app.set('views', path.join(__dirname, 'views'));
app.use(express.urlencoded({ extended: true }));
app.use(methodOverride('_method'));
app.use(express.static(path.join(__dirname, 'public')))
const sessionConfig={
secret:'thisshouldbeabettersecret',
resave: false,
saveUninitialized: true,
cookie:
{
httpOnly:true,
expires:Date.now+1000*60*60*24*7,
maxAge:1000*60*60*24*7
}
}
app.use(session(sessionConfig))
app.use(flash())
app.use(passport.initialize())
app.use(passport.session())
passport.use(new LocalStrategy(User.authenticate()));
passport.serializeUser(User.serializeUser())
passport.deserializeUser(User.deserializeUser()) //deserializeUser
app.use((req, res, next) => {
res.locals.success = req.flash('success');
res.locals.error = req.flash('error');
next();
})
app.use('/',userRoutes)
app.use('/campgrounds',campgroundRoutes);
app.use('/campgrounds/:id/reviews',reviewRoutes)
app.get('/', (req, res) => {
console.log('hi on server ');
res.render('home')
});
app.all('*', (req, res, next) => {
next(new ExpressError('Page Not Found', 404));
})
app.use((err, req, res, next) => {
// { const {statusCode=500,message="SomThing went wrong "} = err;
// res.status(statusCode).send(message)
if (!err.message) err.message = "Problem Occurs Man"
res.render('Error', { err })
next();
})
app.listen(3000, () => {
console.log('listening on port 3000');
});
User.js:
const express=require('express');
const router=express.Router();
const catchAsync=require('../Utilities/catchAsync')
const User = require('../models/user');
const passport = require('passport');
// const LocalStrategy= require('passpi')
router.get('/register', (req, res) => {
res.render('users/register')
});
router.post('/register', catchAsync( async (req, res) => {
try {
const {usermail,username,userpassword}=req.body;
console.log(req.body);
const user= new User({usermail,username});
console.log(req.body);
const registerdUser= await User.register(user,userpassword);
console.log(req.body);
console.log(registerdUser);
req.flash('success','Welcome to YelpCamp');
req.redirect('/campgrounds')
} catch (err) {
req.flash('error', err.message);
res.redirect('/register')
}
}));
router.get('/login', (req, res) => {
res.render('users/login')
});
router.post('/login',passport.authenticate('local',{failureFlash: true,failureRedirect:'/login'}),(req,res) => {
req.flash('success', 'Successfully logged in!');
res.redirect('/campgrounds')
});
module.exports = router;
I have searched everywhere and tried all the available possible solutions but nothing is solving this.

how to make a page only accessible when logged in with express & ejs

Currently I'm working on a little project for a dummy login/register page and now I want to add a page that is only accessible when you're logged in. So the question is how do I make a session or cookie and retrieve them? And how do I block not logged in users.
I'm currently using this code for the app.js
var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var mongoose = require('mongoose');
var expressSession = require('express-session');
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
var AuthTokenStrategy = require('passport-auth-token').Strategy;
require('./models');
var User = mongoose.model('User')
mongoose.connect('mongodb://localhost:27017/my-data', { useNewUrlParser: true, useUnifiedTopology: true })
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
passport.use(new LocalStrategy({
usernameField: "key"
}, function(key, next) {
User.findOne({
key: key
}, function(err, user) {
if (err) return next(err);
if (!user) {
return next({message: 'Key incorrect'})
}
next(null, user);
})
}));
passport.serializeUser(function (user, next) {
next(null, user._id)
})
passport.deserializeUser(function (id, next){
User.findById(id, function (err, user) {
next(err, user);
});
});
app.use(passport.initialize());
app.use(passport.session());
app.use(expressSession({
secret: 'aksndklajsdjicpwoemcklnaiohdandascopkqpowdmklasmdiojqwndjkasndosiqjwdklnasaksndklajsdjicpwoemcklnaiohdandascopkqpowdmklasmdiojqwndjkasndosiqjwdklnas'
}))
app.get('/', function(req, res, next){
res.render('index', {title: 'MySite'})
});
app.get('/main', function(req, res, next){
res.render('main')
});
app.get('/login', function(req, res, next){
res.render('login')
});
app.post('/signup', function(req, res, next){
User.findOne({
key: req.body.key
}, function (err, user) {
if (err) return next(err)
if (user) return next({message: 'This client exists'})
let newUser = new User({
key: req.body.key
});
newUser.save(function(err) {
if (err) return next(err);
res.redirect('/main');
});
console.log(req.body)
});
});
app.post('/login', async (req, res, next) => {
const key = req.body.key;
//const ip = req.header('x-forwarded-for') || req.connection.remoteAddress;
//console.log(ip);
if (!key) return res.status(401).json({ err: 'Key not provided' });
const User = mongoose.model('User');
const user = await User.findOne({ key }).exec();
if (!user) return res.status(401).json({ err: 'Invalid Key' });
res.redirect('/main');
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
module.exports = app;
Try do add this middleware to protected route:
function isAuthenticated(req,res,next){
if(req.isAuthenticated()){ // will return true if user is logged in
next();
} else{
res.redirect("/login");
}
}
app.get('/protectedPath',isAuthenticated, function(req,res) {
//protected content
);

When I make a GET request to NodeJS it doesn't run the code in the route

I am trying to make a get request with ajax, it doesn't seem to run the code in my NodeJS /tools route, maybe someone can enlighten me. I am looking to run a script from nodeJS from an AJAX request. xhr GET request doesn't seem to work with to initiate the that console log in the nodejs route.
These are my routes.
const express = require('express');
const router = express.Router();
const User = require('../models/user.js');
const mid = require('../middleware');
const axios = require('axios');
// Home Routes
router.get('/', (req, res, next) => {
res.render('index');
});
// About Routes
router.get('/about', (req, res, next) => {
res.render('about', {title : '| About'});
});
// Tools Routes
router.get('/tools', (req, res, next) => {
console.log("ajax request went through!");
});
router.post('/tools', (req, res, next) => {
var domain = req.body.domain;
canYouDigIt(domain);
});
router.get('/map', (req, res, next) => {
res.render('map');
});
// Login Routes
router.get('/login', mid.loggedOut, (req, res, next) => {
res.render('login', {title : '| Log in'});
});
router.post('/login', (req, res, next) => {
if ( req.body.email && req.body.password) {
User.authenticate(req.body.email, req.body.password, function(error, user){
if (error || !user) {
var err =new Error('Wrong email or password.');
err.status = 401;
return next(err);
} else {
req.session.userId = user._id;
return res.redirect('/profile');
}
});
} else {
var err =new Error('Email and password are required!');
err.status = 401;
return next(err);
}
});
// Logout Routes
router.get('/logout', (req, res, next) => {
if (req.session){
// Delete Session
req.session.destroy(function(err) {
if(err) {
return next(err);
} else {
return res.redirect('/');
}
});
}
});
// Registration Routes
router.get('/registration', mid.loggedOut, (req, res, next) => {
res.render('registration', {title : '| Registration'});
});
router.post('/registration', (req, res, next) => {
// Check if all fields are filled
if (req.body.userName && req.body.password && req.body.confirmPassword && req.body.firstName && req.body.lastName && req.body.email) {
// Confirm Password is the same
if ( req.body.password != req.body.confirmPassword) {
const err = new Error ("Passwords don't match!");
err.status = 400;
return next(err);
};
const userData = {
userName: req.body.userName,
password: req.body.password,
firstName: req.body.firstName,
lastName: req.body.lastName,
email: req.body.email
};
// Use schema 'create' method to insert document into Mongo
User.create(userData, (error, user) => {
if (error) {
return next(error);
} else {
req.session.userId = user._id;
return res.redirect('/profile');
}
});
} else {
const err = new Error("All Fields Required.");
err.status = 400;
return next(err);
}
});
module.exports = router;
This is my html/pug calling the route
section(id="digToolWrapper")
form( id="digToolInput" )
ul
li #[input(id="digTool" name="domain" type="text" placeholder="Can you dig it?")]#[input(id="whois" value="whois" type="button" onclick="digIt()")]
This is my ajax request
function digIt() {
var xhr = new XMLHttpRequest();
var domain = document.getElementById("digTool").value;
xhr.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
console.log(domain);
}
};
xhr.open('GET', '/tools', true);
console.log(domain);
xhr.send();
};
App.js file
const express = require('express');
const session = require('express-session');
const bodyParser = require('body-parser');
const cookieParser = require('cookie-parser');
const path = require('path');
const mongoose = require('mongoose');
const MongoStore = require('connect-mongo')(session);
const axios = require('axios');
const app = express();
// Mongodb connection
mongoose.connect("mongodb://localhost:27017/nymadic", { useNewUrlParser: true });
const db = mongoose.connection
// Mongo error
db.on('error', console.error.bind(console, 'connection error:'));
// Use sessions for tracking logins
app.use(session({
secret: 'keyboard cat!',
resave: true,
saveUninitialized: false,
// This stores sessions in the Mongo DB so the server doesnt become overloaded
store: new MongoStore({
mongooseConnection: db
})
}));
// Make user ID available in template
app.use(function (req, res, next){
res.locals.currentUser = req.session.userId;
next();
});
// Body Parser and Cookie Parser
app.use(bodyParser.urlencoded({ extended:false }));
app.use(cookieParser());
// Static Files
app.use(express.static(__dirname + '/public'));
// Pug Render Engine
app.set('view engine', 'pug');
// Routes
const mainRoutes = require('./routes');
const profileRoutes = require('./routes/profile');
const wikiRoutes = require('./routes/wiki');
app.use(mainRoutes);
app.use('/profile', profileRoutes);
app.use('/wiki', wikiRoutes);
app.listen(8080, () => {
console.log('Nodejs is running on port 8080...');
});

Random redirection

i have a Problem with my project. I want to make a little download system for pictures, so i made a router for /download/:filename. I have the pictures in /userdata/${userId}/ and if i request /download/ with a param like test it logs in my console, but if i use a param wich exists in the userdata folder like Download.jpg it redirects me back to the homepath of the user: /file/${userId} here is my code:
app.js
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var index = require('./routes/index');
const admin = require("./routes/admin");
import file from "./routes/file";
import download from "./routes/download";
const session = require("express-session");
var app = express();
app.set("trust proxy", 1);
app.use(session({
secret: "bla",
resave: false,
cookie: {
maxAge: 120000000
},
saveUninitialized: false
}));
function checkIfLoggedin(req,res,next){
if(!(req.originalUrl === "/") && !req.session.loggedIn){
res.redirect('/');
return;
}
next();
};
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use(checkIfLoggedin);
app.use('/', index);
app.use("/admin", admin);
app.use("/file", file);
app.use("/download", download);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
module.exports = app;
index.js router
var express = require('express');
var router = express.Router();
const bcrypt = require('bcrypt-nodejs');
var dbPassword;
import mysql from "mysql";
//
/* GET home page. */
router.get('/', function(req, res, next) {
if (req.session.user != undefined) {
res.redirect("/file/"+req.session.user.userId);
}
else{
res.render('index', {});
}
});
router.post('/', function(req,res,next) {
console.log("1");
const enteredUsername = req.body.username;
const enteredPassword = req.body.password;
const con = mysql.createConnection({
host: "localhost",
user: "user",
password: "pass",
database: "db"
});
con.query('SELECT * FROM users WHERE username = ?;', [`${enteredUsername}`], (error, results, fields) => {
if (results.length > 0) {
console.log("2");
console.log(error);
let dbPassword = results[0].password;
bcrypt.compare(enteredPassword, dbPassword, (err,response) => {
console.log(err);
console.log(response);
console.log("3");
if (response == true) {
req.session.user = {
userId: results[0].userId,
username: results[0].username,
isAdmin: results[0].isAdmin,
};
req.session.loggedIn = true;
console.log("file");
if (req.session.user.isAdmin) {
res.redirect("/admin");
}
else{
res.redirect("/file/" + req.session.user.userId);
}
}
else{
req.session.loggedIn = false;
console.log("false");
res.send("Falsches Passwort");
}
});
}
else{
res.send("Falsche Daten");
}
});
});
router.get("/logout", (req,res,next) => {
if (req.session.user.userId) {
req.session.destroy();
res.redirect("/");
}
});
module.exports = router;
file.js
import express from "express";
import fs from "fs";
const router = express.Router();
const userDataPath = "/srv/www/www.precode.tech/www/userdata/";
router.get("/:userId", (req,res,next) => {
//console.log(req.params.userId == req.session.user.userId);
if (req.params.userId == req.session.user.userId) {
const userDataFiles = fs.readdirSync(userDataPath+req.session.user.userId);
res.render("file", {files : userDataFiles, user: req.session.user});
}
else{
res.status(403).render("unauthorized");
}
//res.send(`${req.params.userId} ${req.session.user.userId}`);
});
/*router.get("/:userId/download/:filename", (req,res,next) => {
console.log(req.params.filename);
if (req.params.userId == req.session.user.userId) {
let filePath = `${__dirname}/../userdata/${req.session.user.userId}/`;
res.download(filePath, req.params.filename);
next();
};
});*/
export default router;
download.js
import express from "express";
const router = express.Router();
/*router.get("/", (req,res,next) => {
res.send("download");
});*/
router.get("/:filename", (req,res,next) =>{
console.log(req.params.filename);
});
export default router;
It would be very nice, if you have ideas or see the problem.
Thank you :)
EDIT: It should not redirect to the base path of the user, the get request on download should allways console.log the item
I did not find the flaw, but let's cleanup the code and fix middleware attaching sequence (at least I saw cookie parser attached after session middleware, I suspect only that part) and check.
But let's check my code review / cleanup.
Really hope it helps.
app.js:
const express = require('express');
const path = require('path');
//const favicon = require('serve-favicon');
const logger = require('morgan');
const cookieParser = require('cookie-parser');
const bodyParser = require('body-parser');
const session = require("express-session");
const mysql = require('mysql');
const db = mysql.createConnection({
host: "localhost",
user: "user",
password: "pass",
database: "db"
});
const app = express();
app.set("trust proxy", 1);
// set view engine and renderer
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
// serve static files
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico'))); // no need for it since express static will serve all static files in public folder
app.use(express.static(path.join(__dirname, 'public')));
// connect morgan to profile requests
app.use(logger('dev'));
// parse cookies first
app.use(cookieParser());
// then handle session
app.use(session({
secret: "bla",
resave: false,
cookie: {
maxAge: 120000000
},
saveUninitialized: true
}));
// handle requests data
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use((req, res, next) => {
req.db = db; // attach db connection to request context
next();
});
// public routes that does not need auth check
app.use('/', require('./routes/index'));
const checkIfLoggedin = (req, res, next) => {
if (!req.session.loggedIn) {
return res.redirect('/');
}
res.locals.user = req.session.user;
next();
};
// internal routes that needs auth check
app.use(
'/admin',
checkIfLoggedin,
require('./routes/admin'));
app.use(
'/files',
checkIfLoggedin,
require('./routes/files'));
/* no need for this route, it's covered in files.js
app.use(
'/download',
checkIfLoggedin,
download);
*/
// catch 404 and forward to error handler
app.use((error, req, res, next) => {
if (error) return next(error);
const err = new Error('Not Found');
err.status = 404;
next(err);
});
// error handler
app.use((error, req, res, next) => {
// set locals, only providing error in development
res
.status(error.status || 500)
.render('error', {
message: error.message,
error: req.app.get('env') === 'development' ? error : {}
});
});
module.exports = app;
routes/index.js:
const express = require('express');
const router = express.Router();
const logger = require('winston');
const bcrypt = require('bcrypt-nodejs');
const _ = require('lodash'); // install it: npm i --save lodash
/* GET home page. */
router.get('/', (req, res) => {
if (_.get(req, 'session.user.userId')) {
return res.redirect("/files/" + req.session.user.userId);
}
res.render('index', {});
});
router.post('/auth', (req, res, next) => {
const {username, password} = req.body;
const db = req.db;
const query = 'SELECT * FROM users WHERE username = ? LIMIT 1';
const fields = [username];
db.query(
query,
fields,
(err, result) => {
if (err) {
logger.error(err);
const error = new Error('System fehler');
return next(error);
}
const user = _.get(result, '0');
if (!user) {
req.session.loggedIn = false;
const error = new Error('Benutzer nicht gefunden');
error.status = 403;
return next(error);
}
bcrypt.compare(password, user.password,
(err, isEqual) => {
if(err || !isEqual) {
if (err) logger.error('Error in password compare:', err);
const error = new Error('Passwort ungültig');
error.status = 403;
return next(error);
}
req.session.user = _.pick(user, ['id', 'userId', 'username', 'isAdmin']);
req.session.loggedIn = true;
if (user.isAdmin) {
return res.redirect("/admin");
}
res.redirect("/files/" + user.userId);
});
});
});
router.get("/logout", (req, res) => {
// simply destroy session and redirect,
// no need for session check
req.session.destroy();
res.redirect("/");
});
module.exports = router;
routes/files.js:
const express = require('express');
const router = express.Router();
const logger = require('winston');
const fs = require('fs');
const path = require('path');
const async = require('async');
const userDataPath = path.join(__dirname, '..', 'userdata');
// no need to check userId with session.user.userId
// since middleware attached in app.js will guard this route
// and redirect user to '/'
router.get('/:userId', (req, res, next) => {
if(req.params.userId != req.session.user.userId) {
const error = new Error("You cannot access other user's files");
error.status = 403;
return next(error);
}
const directory = path.join(userDataPath, req.params.userId);
logger.info('Reading directory:', directory);
fs.readdir(
directory,
(err, entries) => {
if (err) {
logger.error(err);
const error = new Error('System error');
return next(error);
}
const directories = [];
const files = [];
async.eachLimit(
entries, 10,
(entry, done) => {
fs.stat(path.join(dir, entry), (error, stat) => {
if (stat.isFile()) files.push(entry);
if (stat.isDirectory()) directories.push(entry);
done();
});
},
() => {
res.render("files", {
directories,
files
});
});
});
});
router.get('/:userId/download/:filename', (req, res, next) => {
if(req.params.userId != req.session.user.userId) {
const error = new Error("You cannot access other user's files");
error.status = 403;
return next(error);
}
res.download(path.join(userDataPath, req.params.userId, req.params.filename));
});
module.exports = router;
P.S. If it works behind nginx, apache and etc make sure userdata folder is not accessible publicly.

Route separation in express routing with passing passport instance

I'm trying to add user-login module to an existing app in node. It is using separate route files for each module and one main route file to use all the child routes which is ultimately used in server.js
When I try to pass passport instance to the user route, it gives me error as passport is not defined. Here is my app code and structure:
app
views
user
index.ejs
login.ejs
signup.ejs
profile.ejs
routes
docs
index.js
user
index.js
index.js
config
passport.js
server.js
server.js
const express = require('express')
const app = express()
const path = require('path')
const bodyParser = require('body-parser')
const cookieParser = require('cookie-parser')
const passport = require('passport')
const flash = require('connect-flash')
const session = require('express-session')
const routes = require('./routes/')
const port = process.env.PORT || 3000;
app.use(express.static(path.join(__dirname, 'public')));
require('./config/passport')(passport);
app.use(bodyParser.urlencoded({
extended: true
}));
app.use(cookieParser());
app.use(bodyParser.json());
app.set('view engine', 'ejs');
app.set('views', path.join(__dirname, 'views'));
app.use(session({ secret: '********' }));
app.use(passport.initialize());
app.use(passport.session());
app.use(flash());
app.use('/', routes)(app,passport);
const server = app.listen(port, function(){
console.log('Server listening on port '+port);
});
config/passport.js
var LocalStrategy = require('passport-local').Strategy;
const sql = require('mssql')
const bcrypt = require('bcrypt-nodejs')
module.exports = function(passport) {
passport.serializeUser(function(user, done) {
done(null, user);
});
passport.deserializeUser(function (username, done) {
done(null,username);
});
passport.use('local-signup', new LocalStrategy({
usernameField : 'email',
passwordField : 'password',
passReqToCallback : true
},
function(req, email, password, done) {
process.nextTick(function() {
var strSQL = "SELECT count(id) as uCount FROM <tbl> WHERE username = '"+email+"'";
var cb1 = function(err,recordset){
if(recordset[0].uCount>0){
return done(null, false, req.flash('signupMessage', 'That email is already taken.'));
} else{
var strSQL1 = "INSERT INTO <tbl>(username, password) VALUES('"+email+"','"+generateHash(password)+"')";
var cb2 = function(err,recordset){
return done(null, recordset,req.flash('signupMessage', 'Email registered successfully.'));
};
executeQuery(strSQL1,'INSERTION','<tbl>',cb2);
}
};
executeSelection(strSQL,'SELECTION','<tbl>',cb1);
});
}));
passport.use('local-login', new LocalStrategy({
usernameField : 'email',
passwordField : 'password',
passReqToCallback : true
},
function(req, email, password, done) {
var strSQL = "SELECT a.count, id, username, password FROM <tbl> c , (SELECT COUNT(dbid) count FROM <tbl> b WHERE b.username = '"+email+"' ) a WHERE c.username = '"+email+"'";
var cb1 = function(err,recordset){
if(recordset[0].uCount <= 0){
return done(null, false, req.flash('loginMessage', 'No user found.'));
}
if (!validPassword(password,recordset[0].password))
return done(null, false, req.flash('loginMessage', 'Oops! Wrong password.'));
return done(null, recordset[0]);
};
executeSelection(strSQL,'SELECTION','<tbl>',cb1);
}));
};
executeSelection = function(strSQL, operationType, tableName, cb){
var request = new sql.Request(connection);
request.query(strSQL,function(err,recordset) {
if(err){
logger.error('ERROR in '+operationType+' ON '+tableName+': '+err);
}
logger.info(operationType+' ON '+tableName+' successful!');
cb(err,recordset);
});
};
executeQuery = function(strSQL, operationType, tableName, cb,validateClient) {
var request = new sql.Request(connection);
request.query(strSQL,function(err, recordset) {
if(err){
logger.error('ERROR in '+operationType+' ON '+tableName+': '+err);
}
logger.info(operationType+' ON '+tableName+' successful!');
if(cb){
cb(validateClient);
}
});
};
generatePasswordHash = function(password) {
return bcrypt.hashSync(password, bcrypt.genSaltSync(8), null);
};
validatePassword = function(curPass, dbPass) {
return bcrypt.compareSync(curPass, dbPass);
};
routes/index.js
const mainroute = require('express').Router()
/* ---- other existing routes included ---- */
const r_docs = require('./docs')
const r_user = require('./user') /*my custom route*/
/* ---- all other routes ---- */
mainroute.use('/docs', r_docs);
mainroute.use('/user', r_user)(app, passport); /*my custom route*/
mainroute.get('/', function(req, res){
res.render('home');
});
module.exports = function(app, passport){
mainroute;
}
routes/user/index.js
const express = require('express')
const router = express.Router()
router.get('/', function(req, res) {
res.render('user/index.ejs');
});
router.get('/login', function(req, res) {
res.render('user/login.ejs', { message: req.flash('loginMessage') });
});
// process the login form
router.post('/login', passport.authenticate('local-login', {
successRedirect : '/profile',
failureRedirect : '/login',
failureFlash : true
}));
router.get('/signup', function(req, res) {
res.render('user/signup.ejs', { message: req.flash('signupMessage') });
});
router.post('/signup', passport.authenticate('local-signup', {
successRedirect : '/profile',
failureRedirect : '/signup',
failureFlash : true
}));
router.get('/profile', isLoggedIn, function(req, res) {
res.render('user/profile.ejs', {
user : req.user
});
});
router.get('/logout', function(req, res) {
req.logout();
res.redirect('/');
});
function isLoggedIn(req, res, next) {
if (req.isAuthenticated())
return next();
res.redirect('/');
}
module.exports = function(app, passport) {
router;
}
Please suggest what am I doing wrong here. Thanks
You should wrap your main and user routes to run their logic when you call them and at end return prepared route:
routes/index.js
module.exports = function(app, passport) {
const mainroute = require('express').Router()
/* ---- other existing routes included ---- */
const r_docs = require('./docs');
const r_user = require('./user'); /*my custom route*/
/* ---- all other routes ---- */
mainroute.use('/docs', r_docs);
mainroute.use('/user', r_user)(app, passport); /*my custom route*/
mainroute.get('/', function(req, res) {
res.render('home');
});
return mainroute;
};
routes/user/index.js
module.exports = function(app, passport) {
const express = require('express');
const router = express.Router();
router.get('/', function(req, res) {
res.render('user/index.ejs');
});
router.get('/login', function(req, res) {
res.render('user/login.ejs', {
message: req.flash('loginMessage')
});
});
// process the login form
router.post('/login', passport.authenticate('local-login', {
successRedirect: '/profile',
failureRedirect: '/login',
failureFlash: true
}));
router.get('/signup', function(req, res) {
res.render('user/signup.ejs', {
message: req.flash('signupMessage')
});
});
router.post('/signup', passport.authenticate('local-signup', {
successRedirect: '/profile',
failureRedirect: '/signup',
failureFlash: true
}));
router.get('/profile', isLoggedIn, function(req, res) {
res.render('user/profile.ejs', {
user: req.user
});
});
router.get('/logout', function(req, res) {
req.logout();
res.redirect('/');
});
function isLoggedIn(req, res, next) {
if (req.isAuthenticated())
return next();
res.redirect('/');
}
return router;
};
You need to require it at the top of your user/index.js. Simply:
var passport = require('passport');
Then to make sure the user is authenticated:
router.get('/some/path', isLoggedIn, function(req, res) {
var user = req.user;
});
function isLoggedIn(req, res, next) {
if (req.isAuthenticated())
return next();
res.redirect('/');
}

Categories

Resources