im trying to log a user in but keep getting the error user is not defined ive tried using both upper and lowercase "user/User" but its still saying undefined.
var mongoose = require("mongoose")
var Schema = mongoose.Schema
//var bcrypt = require("bcrypt-nodejs")
var bcrypt = require("bcryptjs")
mongoose.set('useCreateIndex', true,
);
var userSchema = new Schema({
fname: { type: String, required: true },
lname: { type: String, required: true },
email: { type: String, set: toLower, required: true },
address: { type: String, required: true },
phonenumber: { type: String, required: true },
city: { type: String, required: true },
state: { type: String, required: true },
country: { type: String, required: true },
zipcode: { type: Number, required: true },
cpassword: { type: String, required: true }
})
var db = mongoose.createConnection('mongodb://localhost/main', {
useNewUrlParser: true,
useUnifiedTopology: true
});
userSchema.statics.authenticate =
function (email, password, callback) {
console.log('im here')
user.findOne({ email: email })
.exec(function (err, user) {
if (err) {
return callback(err)
} else if (!user) {
var err = new Error('User not found!');
err.status = 401;
return callback(err);
} else {
bcrypt.compare(password, user.cpassword, function (err, result) {
if (result === true) {
return callback(null, user);
} else {
return callback('Wrong password!');
}
})
}
});
}
//userSchema.methods.authenticate = function (password) {
userSchema.methods.validPassword = function (password) {
return bcrypt.compareSync(password, this.cpassword)
}
/*
//}
userSchema.methods.encryptPassword = function (cpassword) {
return bcrypt.hashSync(cpassword, bcrypt.genSaltSync(5), null)
}
/*
userSchema.methods.validPassword = function (cpassword) {
return bcrypt.compareSync(cpassword, this.cpassword)
}
*/
function toLower(str) {
return str.toLowerCase();
}
//userSchema.plugin(passportLocalMongoose);
module.exports = mongoose.model("User", userSchema, "users")
Above is the model-users.js file
Below is my server.js file
var express = require('express');
const app = express();
var bodyParser = require("body-parser");
var router = express.Router();
var path = require('path');
var passport = require('passport');
const flash = require('connect-flash');
var LocalStrategy = require("passport-local").Strategy;
var user = require('./models/user-model.js');
var config = require('./passport-config')
const methodOverride = require('method-override')
var morgan = require('morgan')
const get = require('./insert.js');
//const register = require('./register.js');
const mongoose = require('mongoose')
const session = require('express-session');
const { check, validationResult }
= require('express-validator');
const MongoStore = require('connect-mongo')(session);
var bcrypt = require("bcryptjs");
const { triggerAsyncId } = require('async_hooks');
mongoose.connect('mongodb://localhost/main', {
useNewUrlParser: true,
useUnifiedTopology: true,
useFindAndModify: false,
useCreateIndex: true
});
app.use(session({
store: new MongoStore({ mongooseConnection: mongoose.connection, collection: 'sessions', }
),
secret: 'keyboard cat',
resave: true,
saveUninitialized: true,
unset: 'destroy',
cookie: {
secure: false,
}
}));
var db = mongoose.createConnection('mongodb://localhost/main', {
useNewUrlParser: true,
useUnifiedTopology: true
});
app.set('views', __dirname + '/views');
app.set('view engine', 'pug');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
extended: true,
}));
app.use(morgan('dev'))
app.use(flash())
// ROUTES
app.get('/about', function (req, res) {
res.render('about,{ title: "About Us" }')
})
app.get('/contact', function (req, res) {
res.render('contact', { title: "Contact Us" });
});
app.get('/index', function (req, res) {
res.render('index', { title: "Home" });
});
app.get('/bookingform', function (req, res) {
res.render('bookingform', { title: "Book Your Tour" });
});
app.get('/login', function (req, res) {
res.render('login', { title: "Login" });
});
app.get('/tours', function (req, res) {
res.render('tours', { title: "Tours" });
});
app.get('/', (req, res) => {
app.use(express.static(path.join(__dirname + '/public')));
res.render('index');
})
app.get('/signup', (req, res) => {
//app.use(express.static(path.join(__dirname + '/public')));
res.render('signup');
})
app.get('/checkout', (req, res) => {
get(req, res);
res.render('checkout')
})
//
app.post('/insert', (req, res) => {
get(req, res);
console.log(req.body)
});
app.post("/login",
function (req, res, next) {
if (req.body.email && req.body.password) {
console.log(req.body)
db.collection("users")
user.authenticate(req.body.email, req.body.password,
function (error, user) {
if (error || !user) {
error.status = 401;
return next(error);
}
else {
//res.send(user);
console.log("Sign in Successfull ")
res.redirect('about');
}
}
);
}
else {
var err = new Error('Something went wrong!');
err.status = 400;
res.render('login', { notif: err })
return next(err);
}
console.log('failed')
},
)
function checkPassword(password) {
return bcrypt.compareSync(password, user.cpassword)
}
function findUserByEmail(email) {
if (email) {
return new Promise((resolve, reject) => {
user.findOne({ email: email })
.exec((err, doc) => {
if (err) return reject(err)
if (doc) return reject(new Error('This email already exists. Please enter another email.'))
else return resolve(email)
})
})
}
}
//Handling user logout
app.get("/logout", function (req, res) {
req.logout();
res.redirect("/");
});
function isLoggedIn(req, res, next) {
if (req.isAuthenticated()) return next();
res.redirect("/login");
}
function checkAuthenticated(req, res, next) {
if (req.isAuthenticated()) {
return next()
}
res.redirect('/login')
}
function unWindMessages(em) {
var m = [];
for (var i in em) {
m.push(em[i].msg);
}
return m;
}
function checkNotAuthenticated(req, res, next) {
if (req.isAuthenticated()) {
return res.redirect('/')
}
next()
}
app.listen(27017, function () {
console.log('listening on 27017')
})
module.exports = app;
So far i have tried specifying the database collection to use in both files , it didnt work still getting user not defined.
I fixed it by making a User variable that stored the model.
var User = mongoose.model("User", userSchema, "users")
module.exports = User
Related
I have installed express-session before initializing passport yet the passport authenticate doesn't works and it simply redirects to the failureRedirect url without any errors or messages.
i have checked that passport initializing works perfectly just authentication is not working
my index.js file
const ejs = require("ejs");
const url = require("url");
const session = require("express-session");
const cookieParser = require('cookie-parser')
const flash = require('connect-flash');
const toastr = require('express-toastr');
const Profile = require('./models/Profile.js');
const passport = require("passport");
const { customAlphabet } = require('nanoid');
const express = require("express"),
path = require('path')
const app = express();
const port = 3000;
const { Notyf } = require('notyf')
const { connect } = require('mongoose');
const LocalStrategy = require('passport-local');
const MemoryStore = require("memorystore")(session);
const methodOverride = require('method-override')
connect(process.env.mongodb);
const initializePassport = require('./utils/passport-config.js')
initializePassport(
passport,
email => Profile.find({ email_id: email }),
id => Profile.find({ user_id: email })
)
var bodyParser = require('body-parser');
app.use(cookieParser());
app.use(
session({
store: new MemoryStore({ checkPeriod: 86400000 }),
secret: "##%#&^$^$%#$^$&%#$%##$%$^%&$%^#$%##$%#E%#%#$FEErfgr3g#%GT%536c53cc6%5%tv%4y4hrgrggrgrgf4n",
resave: false,
saveUninitialized: false,
}),
);
app.use(passport.initialize());
app.use(passport.session());
app.use(flash());
app.use(toastr());
app.use('/assets', express.static(path.join(__dirname, 'assets')))
app.use('/scripts', express.static(path.join(__dirname, 'node_modules')))
app.set('views', './views');
app.set('view engine', 'ejs');
app.use(bodyParser.json());
app.use(
bodyParser.urlencoded({
extended: true,
}),
);
const checkAuth = (req, res, next) => {
try {
if (req.isAuthenticated()) return next();
req.session.backURL = req.url;
res.redirect("/login");
} catch (e) {
console.log(e)
}
};
app.get('/', async function(req, res){
res.render('index.ejs', { url: req.url })
});
app.get('/login', async function(req, res){
if (req.session.backURL) {
req.session.backURL = req.session.backURL;
} else if (req.headers.referer) {
const parsed = url.parse(req.headers.referer);
if (parsed.hostname === app.locals.domain) {
req.session.backURL = parsed.path;
}
} else {
req.session.backURL = "/";
}
res.render('login.ejs', { url: req.url })
});
app.get('/signup', async function(req, res){
res.render('signup.ejs', { url: req.url })
});
app.get('/newshop', async function(req, res){
res.render('shopcreate.ejs', { url: req.url })
});
app.get('/profile', async function(req, res){
res.render('profile.ejs', { url: req.url })
});
app.get('/settings', async function(req, res){
res.render('settings.ejs', { url: req.url })
});
app.post('/login', passport.authenticate('local', {
failureRedirect: '/login',
}), async (
err,
req,
res,
next,
) => {
try {
await console.log(req)
if (req.session.backURL) {
const backURL = req.session.backURL;
req.session.backURL = null;
res.redirect(backURL);
} else {
res.redirect('/');
}
} catch(e) {
console.log(e)
}
})
app.listen(port, () => console.log(`Example app listening at http://localhost:${port}`));
my passport-config.js file -
const LocalStrategy = require('passport-local').Strategy
const bcrypt = require('bcrypt')
function initialize(passport, getUserByEmail, getUserById) {
const authenticateUser = async (email, password, done) => {
console.log(email)
const user = getUserByEmail(email)
if (user == null) {
return done(null, false, { message: 'User not found' })
}
try {
if (await bcrypt.compare(password, user.password)) {
return done(null, user)
} else {
return done(null, false, { message: 'Password incorrect' })
}
} catch (e) {
return done(e)
}
}
passport.use(new LocalStrategy({ usernameField: 'email' }, authenticateUser))
passport.serializeUser((user, done) => done(null, user.id))
passport.deserializeUser((id, done) => {
return done(null, getUserById(id))
})
}
module.exports = initialize
When I do the login "post" I want to be authenticated but req.isAuthenticated is always false, so I can't access home. This problem will not be solved. I don't know what's wrong, any help would be appreciated.
I'm starting to learn backend.
These would basically be the files with which I am working on this part of the project
app.js
const app = express();
app.use(express.json());
app.use(express.urlencoded({
extended: true
}));
app.set("views", "./views");
app.set("view engine", "ejs");
passport.use(
"login",
new LocalStrategy((username, password, done) => {
User.findOne({ username }, (err, user) => {
if (err) return done(err);
if (!user) {
return done(null, false);
}
if (!isValidPassword(user, password)) {
return done(null, false);
}
return done(null, user);
});
})
);
passport.use(
"register",
new LocalStrategy({
passReqToCallback: true
}, (req, username, password, done) => {
User.findOne({
username: username
}, (err, user) => {
if (err) {
return done(err);
}
if (user) {
return done(null, false, {
message: "Usuario ya registrado",
});
}
const newUser = new User({
username: username,
password: createHash(password),
});
User.create(newUser, (err, userWithId) => {
if (err) {
return done(err);
}
return done(null, userWithId);
});
});
})
);
passport.serializeUser((user, done) => {
done(null, user._id);
});
passport.deserializeUser((id, done) => {
User.findById(id, done);
});
app.use(passport.initialize());
app.use(passport.session());
//Redis
const client = redis.createClient({
legacyMode: true,
});
client.connect();
const RedisStore = connectRedis(session);
app.use(
session({
store: new RedisStore({ host: "localhost", port: 6379, client, ttl: 300 }),
secret: "keyboard cat",
resave: false,
saveUninitialized: false,
rolling: true,
cookie: {
maxAge: 86400000,
httpOnly: false,
secure: false,
},
})
);
app.use(homeRouter);
app.use(authWebRoutes);
auth.routes.js
export const authWebRouter = new Router();
authWebRouter.get('/', (req, res) => {
res.redirect('/home')
})
authWebRouter.get("/login", (req, res) => {
if (req.isAuthenticated()) {
res.redirect("/home");
} else {
res.render("login");
}
})
authWebRouter.get("/register", (req, res) => {
if (req.isAuthenticated()) {
res.redirect('/home')
} else {
res.render(path.join(process.cwd(), '/views/register.ejs'))
}
})
authWebRouter.get('/logout', (req, res) => {
req.logout();
res.redirect('/login')
})
authWebRouter.get('/failLogin', (req, res) => {
res.render(path.join(process.cwd(), '/views/failLogin.ejs'))
})
authWebRouter.get('/failRegister', (req, res) => {
res.render(path.join(process.cwd(), '/views/failRegister.ejs'))
})
authWebRouter.post(
"/login",
passport.authenticate("login", {
successRedirect: "/home",
failureRedirect: "/failLogin",
})
);
authWebRouter.post(
"/register",
passport.authenticate("register", {
successRedirect: "/login",
failureRedirect: "/failRegister",
})
);
home.routes.js
export const homeRouter = new Router();
homeRouter.get("/home", checkAuth, (req, res) => {
res.render(path.join(process.cwd(), '/views/home.ejs'), {
username: req.user.username,
})
});
auth.js
export function checkAuth(req, res, next) {
console.log(req.isAuthenticated());
if (req.isAuthenticated()) {
next();
} else {
res.redirect("/login");
}
}
This is an example site that I have created with a basic Node.js server. I am able to successfully post, create a user given the schema, and "save" to the database; however, saving does not return the user object and cannot be found in my actual database. The connection is also returned as successful.
main.js
const session = require('express-session');
const pug = require('pug');
const mongoose = require('mongoose');
const bodyParser = require('body-parser');
const User = require('./schema.js');
const app = express();
var path = require('path');
const MongoClient = require('mongodb').MongoClient;
const client = new MongoClient('mongodb://localhost:27017');
var db;
client.connect((err, client) => {
if (err) {
console.log(err);
}
else if (!err) {
db = client.db('node');
console.log('Connected to Mongodb');
client.close()
}
});
app.engine('pug', require('pug').__express)
app.set('view engine', 'pug');
app.use(bodyParser.urlencoded({ extended : true }));
app.use(bodyParser.json());
app.use(express.static(path.join(__dirname, 'styles')));
app.use(session({secret: 'testing',saveUninitialized: true,resave: true}));
//root directory get response
app.get('/', (req, res) => {
res.render('homepage', {
title : 'Homepage',
req : req
});
});
//register directory get response
app.get('/register', (req, res) => {
res.render('register', {
title : 'Register',
req: req
});
});
//profile directory get response
app.get('/profile', (req, res) => {
res.render('profile', {
title: 'Profile',
email: req.session.email,
username: req.session.username,
req: req
});
});
//login directory get response
app.get('/login', (req, res) => {
res.render('login', {
title: 'Login',
req: req
})
})
//register directory post request
app.post('/register', (req, res) => {
console.log(req.body);
if(req.body.username && req.body.email && req.body.password){
var user = User({
email : req.body.email,
username : req.body.username,
password : req.body.password
});
console.log(user);
user.save((err) => {
user.markModified('password')
console.log("Trying to save")
console.log(user)
if(err){
console.log(err);
} else {
var sess = req.session;
sess.email = req.body.email;
console.log("Saved")
res.redirect('/profile')
}
});
}
});
//login directory post request
app.post('/login', (req, res) => {
console.log(req.body);
if(req.body.username && req.body.password){
var sess = req.session;
sess.username = req.body.username;
res.redirect('/profile')
}
})
const server = app.listen(8000, () => {
console.log(`Express running → PORT ${server.address().port}`);
});
schema.js
const bcrypt = require('bcrypt');
var UserSchema = new mongoose.Schema({
email: {
type: String,
unique: true,
required: true,
trim: true
},
username: {
type: String,
unique: true,
required: true,
trim: true
},
password: {
type: String,
unique: false,
required: true,
trim: true
}
});
UserSchema.pre('save', function(req, err, next) {
var user = this;
bcrypt.genSalt(10, (err, salt) => {
if(err){
return next(err);
}
bcrypt.hash(user.password, salt, (err, hash) => {
if(err){
return next(err);
}
user.password = hash;
console.log(hash);
next()
});
});
});
var User = mongoose.model('User', UserSchema);
module.exports = User;
You are using mongoose to create models and make db querys but not connecting to mongoose. Instead you are connecting to MongoDb native driver.
Replace this
const MongoClient = require('mongodb').MongoClient;
const client = new MongoClient('mongodb://localhost:27017');
var db;
client.connect((err, client) => {
if (err) {
console.log(err);
}
else if (!err) {
db = client.db('node');
console.log('Connected to Mongodb');
client.close()
}
});
with
mongoose.connect(connectionString, {useNewUrlParser: true});
mongoose.connection.on("open", function(ref) {
console.log("Connected to mongo server.");
});
mongoose.connection.on("error", function(err) {
console.log("Could not connect to mongo server!");
console.log(err);
});
Try this var user = new User({ ... }); instead of this var user = User({ ... });. Notice the new keyword.
I am trying out node_acl with passport-local. When I run my code I cannot secure the route for the admin-user '/admin' and I am redirected to the /login page.
Find below my minimum runnable example:
require('dotenv').config()
const express = require('express')
// const fs = require('fs')
const path = require('path')
const logger = require('morgan')
const bodyParser = require('body-parser')
const cookieParser = require('cookie-parser')
const session = require('express-session')
const passport = require('passport')
const LocalStrategy = require('passport-local').Strategy
const ACL = require('acl')
// load user.json file
// const d = fs.readFileSync(path.join(__dirname, '/../data/user.json'))
// const userObj = JSON.parse(d)
const userObj = [{
id: 1,
username: 'admin',
password: 'admin',
email: 'admin#admin.com',
role: 'admin',
},
{
id: 2,
username: 'user',
password: 'user',
email: 'user#user.com',
role: 'user',
},
]
const app = express()
// view engine setup
app.set('views', path.join(__dirname, 'views'))
app.set('view engine', 'pug')
app.use(logger(process.env.LOG_ENV))
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({
extended: false,
}))
app.use(express.static(path.join(__dirname, '/../public')))
app.use(cookieParser())
app.use(session({
secret: 'super-mega-hyper-secret',
resave: false,
saveUninitialized: false,
}))
/**
* Passport Local
*/
app.use(passport.initialize())
app.use(passport.session())
function authenticate() {
passport.serializeUser((user, done) => {
done(null, user.id)
})
passport.deserializeUser(async(id, done) => {
// const user = await serviceAuth.findById(id)
const user = userObj.find(item => item.id === id)
done(null, user)
})
// Sign in with username and Password
passport.use('local', new LocalStrategy({
usernameField: 'username',
}, async(username, password, done) => {
const user = userObj.find(item => item.username === username)
done(null, user)
}))
}
const isAuthenticated = (req, res, next) => {
if (req.isAuthenticated()) {
res.locals.user = req.session.user
return next()
}
res.redirect('login')
}
authenticate()
/**
* Node ACL
*/
function accessControl() {
const nodeAcl = new ACL(new ACL.memoryBackend())
nodeAcl.allow([{
roles: 'admin',
allows: [{
resources: '/admin',
permissions: '*',
}],
}, {
roles: 'user',
allows: [{
resources: '/dashboard',
permissions: 'get',
}],
}, {
roles: 'guest',
allows: [],
}])
// Inherit roles
// Every user is allowed to do what guests do
// Every admin is allowed to do what users do
nodeAcl.addRoleParents('user', 'guest')
nodeAcl.addRoleParents('admin', 'user')
nodeAcl.addUserRoles(1, 'admin')
nodeAcl.addUserRoles(2, 'user')
nodeAcl.addUserRoles(0, 'guest')
return nodeAcl
}
/*
function checkPermission(resource, action) {
const access = accessControl()
return (req, res, next) => {
const uid = req.session.user.id
access.isAllowed(uid, resource, action, (err, result) => {
if (result) {
next()
} else {
const checkError = new Error('User does not have permission to perform this action on this resource')
next(checkError)
}
})
}
} */
const getCurrentUserId = (req) => {
console.log(req)
req.user && req.user.id.toString() || false
}
const access = accessControl()
// Routes
app.get('/login', (req, res) => {
res.render('login')
})
app.post('/login', (req, res, next) => {
passport.authenticate('local', (err, user) => {
if (err) return next(err)
if (!user) {
return res.status(401).json({
error: 'Email or password is incorrect.',
})
}
return res.render('dashboard')
})(req, res, next)
})
app.get('/dashboard', [isAuthenticated, access.middleware()], (req, res) => {
res.render('dashboard')
})
app.get('/admin', [isAuthenticated, access.middleware()], (req, res) => {
res.render('admin')
})
app.get('/status', (request, response) => {
access.userRoles(getCurrentUserId(request), (error, roles) => {
response.send(`User: ${JSON.stringify(request.user)} Roles: ${JSON.stringify(roles)}`)
})
})
// Start Server
const port = process.env.APP_PORT || 8080
const host = process.env.APP_URL || 'localhost'
app.listen(port, host, () => {
console.log(`Listening on ${host}:${port}`)
})
module.exports = app
Any suggestions why the route, /admin cannot be called only be the admin user?
Thank you in advance for your replies!
I couldn't run your "runnable" code so i changed it a bit to check it out.
So after some tests it seems that it works just fine. Can you check it too?
Using POSTMAN I did a POST on /login?username=user&password=user
After that I did a GET on `/status' and I got
User: {"id":2,"username":"user","password":"user","email":"user#user.com","role":"user"} Roles: []
Then I did a GET on /admin and i got
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Error</title>
</head>
<body>
<pre>HttpError: Insufficient permissions to access resource
<br> at C:\Users\stamoulis.zamanis\Desktop\aclTest\node_modules\acl\lib\acl.js:705:14
<br> at tryCatcher (C:\Users\stamoulis.zamanis\Desktop\aclTest\node_modules\bluebird\js\release\util.js:16:23)
<br> at Promise.successAdapter [as _fulfillmentHandler0] (C:\Users\stamoulis.zamanis\Desktop\aclTest\node_modules\bluebird\js\release\nodeify.js:23:30)
<br> at Promise._settlePromise (C:\Users\stamoulis.zamanis\Desktop\aclTest\node_modules\bluebird\js\release\promise.js:566:21)
<br> at Promise._settlePromise0 (C:\Users\stamoulis.zamanis\Desktop\aclTest\node_modules\bluebird\js\release\promise.js:614:10)
<br> at Promise._settlePromises (C:\Users\stamoulis.zamanis\Desktop\aclTest\node_modules\bluebird\js\release\promise.js:693:18)
<br> at Async._drainQueue (C:\Users\stamoulis.zamanis\Desktop\aclTest\node_modules\bluebird\js\release\async.js:133:16)
<br> at Async._drainQueues (C:\Users\stamoulis.zamanis\Desktop\aclTest\node_modules\bluebird\js\release\async.js:143:10)
<br> at Immediate.Async.drainQueues (C:\Users\stamoulis.zamanis\Desktop\aclTest\node_modules\bluebird\js\release\async.js:17:14)
<br> at runCallback (timers.js:789:20)
<br> at tryOnImmediate (timers.js:751:5)
<br> at processImmediate [as _immediateCallback] (timers.js:722:5)
</pre>
</body>
</html>
Then I logged in as admin and when I called /admin again i got admin
I had to change app.post('/login'). If i didnt do req.login then passport.serializeUser was never called, the cookie wasn't correct resulting in bad session.
app.post('/login', (req, res, next) => {
passport.authenticate('local', (err, user) => {
if (err) return next(err)
if (!user) {
return res.status(401).json({
error: 'Email or password is incorrect.',
})
}
req.logIn(user, function (err) { // <-- Log user in
next();
});
})(req, res, next)
},function(req,res){
res.send('dashboard')
})
All code:
require('dotenv').config()
const express = require('express')
// const fs = require('fs')
const path = require('path')
const logger = require('morgan')
const bodyParser = require('body-parser')
const cookieParser = require('cookie-parser')
const session = require('express-session')
const passport = require('passport')
const LocalStrategy = require('passport-local').Strategy
const ACL = require('acl')
// load user.json file
// const d = fs.readFileSync(path.join(__dirname, '/../data/user.json'))
// const userObj = JSON.parse(d)
const userObj = [{
id: 1,
username: 'admin',
password: 'admin',
email: 'admin#admin.com',
role: 'admin',
},
{
id: 2,
username: 'user',
password: 'user',
email: 'user#user.com',
role: 'user',
},
]
const app = express()
// view engine setup
app.set('views', path.join(__dirname, 'views'))
app.set('view engine', 'pug')
app.use(logger(process.env.LOG_ENV))
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({
extended: false,
}))
app.use(express.static(path.join(__dirname, '/../public')))
app.use(cookieParser())
app.use(session({
secret: 'super-mega-hyper-secret',
resave: false,
saveUninitialized: false,
}))
function authenticate() {
passport.serializeUser((user, done) => {
done(null, user.id)
})
passport.deserializeUser((id, done) => {
// const user = await serviceAuth.findById(id)
const user = userObj.find(item => item.id === id)
done(null, user)
})
// Sign in with username and Password
passport.use('local', new LocalStrategy({
usernameField : 'username',
passwordField : 'password'
}, async(username, password, done) => {
const user = userObj.find(item => item.username === username)
done(null, user)
}))
}
const isAuthenticated = (req, res, next) => {
if (req.isAuthenticated()) {
res.locals.user = req.session.user
return next()
}
res.redirect('login')
}
authenticate()
/**
* Passport Local
*/
app.use(passport.initialize())
app.use(passport.session())
/**
* Node ACL
*/
function accessControl() {
const nodeAcl = new ACL(new ACL.memoryBackend())
nodeAcl.allow([{
roles: 'admin',
allows: [{
resources: '/admin',
permissions: '*',
}],
}, {
roles: 'user',
allows: [{
resources: '/dashboard',
permissions: 'get',
}],
}, {
roles: 'guest',
allows: [],
}])
// Inherit roles
// Every user is allowed to do what guests do
// Every admin is allowed to do what users do
nodeAcl.addRoleParents('user', 'guest')
nodeAcl.addRoleParents('admin', 'user')
nodeAcl.addUserRoles(1, 'admin')
nodeAcl.addUserRoles(2, 'user')
nodeAcl.addUserRoles(0, 'guest')
return nodeAcl
}
/*
function checkPermission(resource, action) {
const access = accessControl()
return (req, res, next) => {
const uid = req.session.user.id
access.isAllowed(uid, resource, action, (err, result) => {
if (result) {
next()
} else {
const checkError = new Error('User does not have permission to perform this action on this resource')
next(checkError)
}
})
}
} */
const getCurrentUserId = (req) => {
console.log(req)
req.user && req.user.id.toString() || false
}
const access = accessControl()
// Routes
app.get('/login', (req, res) => {
res.send('login')
})
app.post('/login', (req, res, next) => {
passport.authenticate('local', (err, user) => {
if (err) return next(err)
if (!user) {
return res.status(401).json({
error: 'Email or password is incorrect.',
})
}
req.logIn(user, function (err) { // <-- Log user in
next();
});
})(req, res, next)
},function(req,res){
res.send('dashboard')
})
app.get('/dashboard', [isAuthenticated, access.middleware()], (req, res) => {
res.send('dashboard')
})
app.get('/admin', [isAuthenticated, access.middleware()], (req, res) => {
res.send('admin')
})
app.get('/status', (request, response) => {
access.userRoles(getCurrentUserId(request), (error, roles) => {
response.send(`User: ${JSON.stringify(request.user)} Roles: ${JSON.stringify(roles)}`)
})
})
// Start Server
const port = process.env.APP_PORT || 3335
const host = process.env.APP_URL || 'localhost'
app.listen(port, host, () => {
console.log(`Listening on ${host}:${port}`)
})
module.exports = app
I have the following mongoose Schema setup in models/user.js:
const mongoose = require('mongoose');
const userSchema = mongoose.Schema({
loginId: String,
firstname: String,
lastname: String,
eMail: String,
password: String,
active: Boolean
});
module.exports = userSchema;
In my main app.js I have the following code:
const mongoose = require('mongoose');
var MongoClient = require('mongodb').MongoClient;
var url = "mongodb://localhost:27017/";
MongoClient.connect(url, {
useUnifiedTopology: true,
useNewUrlParser: true,
},function(err, db) {
if (err) throw err;
var dbo = db.db("db");
dbo.collection("db").find({}).toArray(function(err, result) {
if (err) throw err;
console.log(result);
db.close();
});
});
let userSchema = require('./models/user.js');
// Get single user
app.get('/user/:id', function (req, res) {
userSchema.findById(req.params.id, (error, data) => {
if (error) {
return next(error)
} else {
res.json(data)
}
})
})
I get the error which is in the title (just replace mongooseSchemahere with userSchema). What did I do wrong? I tried putting the userSchema declaration in different places, it did not help..
You need to use mongoose.connect to work with mongoose models.
Make these changes:
1-) Create the user model like this and export:
const mongoose = require("mongoose");
const userSchema = new mongoose.Schema({
loginId: String,
firstname: String,
lastname: String,
eMail: String,
password: String,
active: Boolean
});
module.exports = mongoose.model("User", userSchema);
2-) Change your App.js to connect your db with mongoose.connect:
const express = require("express");
const app = express();
const mongoose = require("mongoose");
const User = require("./models/user");
const url = "mongodb://localhost:27017/mydb";
const port = process.env.PORT || 3000;
app.use(express.json());
mongoose
.connect(url, {
useNewUrlParser: true,
useUnifiedTopology: true
})
.then(() => {
app.listen(port, () => {
console.log(`App running on port ${port}...`);
});
})
.catch(error => console.log(error));
Now you can create a user like this:
app.post("/user", function(req, res, next) {
console.log("Req body:", req.body);
User.create(req.body)
.then(result => {
console.log({ result });
res.send(result);
})
.catch(err => {
console.log(err);
res.status(500).send("something went wrong");
});
});
To retrieve the user by _id:
app.get("/user/:id", function(req, res, next) {
User.findById(req.params.id, (error, data) => {
if (error) {
return next(error);
} else {
res.json(data);
}
});
});
To retrieve a user by firstname: (if you want to find all users by firstname change findOne to find.):
app.get("/user/firstname/:firstname", function(req, res, next) {
console.log(req.params.firstname);
User.findOne({ firstname: req.params.firstname }, (error, data) => {
if (error) {
return next(error);
} else {
res.json(data);
}
});
});
You need to export the model and not the schema.
const mongoose = require('mongoose');
const userSchema = mongoose.Schema({
loginId: String,
firstname: String,
lastname: String,
eMail: String,
password: String,
active: Boolean
});
module.exports = mongoose.model('user', userSchema);
Now you can do things like:
let User = require('./models/user.js');
// Get single user
app.get('/user/:id', function (req, res) {
User.findById(req.params.id, (error, data) => {
if (error) {
return next(error)
} else {
res.json(data)
}
})
})