cannot find module '../app/models/user' - node.js

im struggled with this problem like more then 40 hours and sill don't know how to solve this, the problem is a little big to explain but i will try my best, im a little newbie with Node.Js and mongo stuffs so forgive me any stupid mistake.
I followed the book Mean Stack and the problem appears when i started this tutorial to do the autentication with auth, i am at the beginning doing the local authentication without any social at the moment.
folder structure
so basicly i set the server like this:
process.env.NODE_ENV = process.env.NODE_ENV || 'development';
var mongoose = require('./config/mongoose');
var express = require('./config/express');
var db = mongoose();
var app = express();
app.listen(3000);
module.exports = app;
console.log("running at port 3000");
this is the ./config/mongoose
var config = require('./config');
var mongoose = require('mongoose');
var connectionString = "mongodb://localhost:27017/ShareIdea"
module.exports = function(){
mongoose.Promise = global.Promise;
var db = mongoose.connect(connectionString);
require('../app/models/user.server.model');
return db;
};
the required user.server model
var mongoose = require('mongoose');
var bcrypt = require('bcrypt-nodejs');
var Schema = mongoose.Schema;
var UserSchema = new Schema({
local : {
email : String,
password : String,
},
facebook : {
id : String,
token : String,
email : String,
name : String
},
twitter : {
id : String,
token : String,
displayName : String,
username : String
},
google : {
id : String,
token : String,
email : String,
name : String
}
/*firstname:String,
lastname:String,
email:String,
username:String,
password:String,
userChoice: {type: String, possibleValues: ['programmer','inovator']}*/
});
UserSchema.methods.generateHash = function(password) {
return bcrypt.hashSync(password, bcrypt.genSaltSync(8), null);
};
UserSchema.methods.validPassword = function(password) {
return bcrypt.compareSync(password, this.local.password);
};
mongoose.model('User',UserSchema);
here is the express configuration
var config = require('./config');
var express = require('express');
var passport = require('passport');
var flash = require('connect-flash');
var compress = require('compression');
var cookieParser = require('cookie-parser');
var session = require('express-session');
var bodyParser = require('body-parser');
var morgan = require('morgan');
var methodOverride = require('method-override');
var expressLayouts = require('express-ejs-layouts');
module.exports = function(){
var app = express();
**require('./passport')(passport);**
if(process.env.NODE_ENV === 'development')
{
app.use(morgan('dev'));
}
else if(process.env.NODE_ENV === 'production')
{
app.use(compress());
}
app.use(cookieParser());
app.use(bodyParser.urlencoded({
extended:true
}));
app.use(morgan('dev'));
app.use(bodyParser.json());
app.use(methodOverride());
app.use(session({
saveUninitialized: true,
resave: true,
secret: 'aaaaaaa'
}));
app.use(passport.initialize());
app.use(passport.session()); // persistent login sessions
app.use(flash());
app.set('views', './app/views');
app.set('view engine','ejs');
app.use(expressLayouts);
require('../app/routes/index.server.routes.js')(app,passport);
require('../app/routes/register.server.routes.js')(app,passport);
require('../app/routes/login.server.routes.js')(app,passport);
require('../app/routes/profile.server.routes.js')(app,passport);
app.use(express.static('./public'));
return app;
}
here in the express is where the problems appear, this line is the main problem at the moment: `require('./passport')(passport);
if i put this code it gives me the problem that i mentioned in the title, if not when i do a POST request with my form it never posts, i have this troubles because i set the structures of my code to a MVC structure like the book and want to adapt the authentication in the tutorial to my code to learn a little,
so basicly im passing the passport to my routes like this:`
register route
var register = require('../../app/controllers/register.server.controller');
module.exports = function(app,passport) {
app.route('/register')
.post(function(req,res){
console.log("HY");
passport.authenticate('local-signup', {
successRedirect : '/profile', // redirect to the secure profile section
failureRedirect : '/register', // redirect back to the signup page if there is an error
failureFlash : true // allow flash messages
})})
.get(register.getPage);
};
Register controller
var User = require('mongoose').model('User');
module.exports = {
getPage: function(req,res){
res.render('./pages/register',{ message: req.flash('signupMessage') });
}
};
and to end here is the passport code:
// config/passport.js
// load all the things we need
var LocalStrategy = require('passport-local').Strategy;
// load up the user model
var User = require('../app/models/user');
// expose this function to our app using module.exports
module.exports = function(passport) {
// =========================================================================
// passport session setup ==================================================
// =========================================================================
// required for persistent login sessions
// passport needs ability to serialize and unserialize users out of session
// used to serialize the user for the session
passport.serializeUser(function(user, done) {
done(null, user.id);
});
// used to deserialize the user
passport.deserializeUser(function(id, done) {
User.findById(id, function(err, user) {
done(err, user);
});
});
// =========================================================================
// LOCAL SIGNUP ============================================================
// =========================================================================
// we are using named strategies since we have one for login and one for signup
// by default, if there was no name, it would just be called 'local'
passport.use('local-signup', new LocalStrategy({
// by default, local strategy uses username and password, we will override with email
usernameField : 'email',
passwordField : 'password',
passReqToCallback : true // allows us to pass back the entire request to the callback
},
function(req, email, password, done) {
// asynchronous
// User.findOne wont fire unless data is sent back
process.nextTick(function() {
// find a user whose email is the same as the forms email
// we are checking to see if the user trying to login already exists
User.findOne({ 'local.email' : email }, function(err, user) {
// if there are any errors, return the error
if (err)
return done(err);
// check to see if theres already a user with that email
if (user) {
return done(null, false, req.flash('signupMessage', 'That email is already taken.'));
} else {
// if there is no user with that email
// create the user
var newUser = new User();
// set the user's local credentials
newUser.local.email = email;
newUser.local.password = newUser.generateHash(password);
// save the user
newUser.save(function(err) {
if (err)
throw err;
return done(null, newUser);
});
}
});
});
}));
};
Ps: Sorry for the long post, i hope i can get a explanation since i want to learn more, when i read the book i felt like the mvc structure adapted by the autor was dificult, but anyways thanks a lot.
if you guys want to not look at this i understand and here is the gitProject:git project

Try this in your user.server.model.js file. Instead of just
mongoose.model('User',UserSchema);
Try this below to have it accessible.
module.exports = {
User : mongoose.model('User', UserSchema)
}

Related

Passport req.user not persisting across requests -

Using passport.js local strategy I am trying to use the req.user to obtain current user id so that I can store recipes in the database with the users id. The problem seems to be around the deserialization part of the passport.js file I have in my config file in my app. Whenever I hit the /api/saveRecipe route for some reason it gets deserialized and the req user is then no longer available.
Notes: I am authenticating on my backend server using react on the front end.
Below is my server.js file
Problem: req.user is available after calling passport.authenticate('local') but once api/saveRecipe route is hit req.user is no longer available.
After researching this subject on S.O. it appears that it most often has to do with order in the server file setup but i have looked and reviewed and i believe my setup correct...
const express = require("express");
const bodyParser = require("body-parser");
const session = require("express-session");
const routes = require("./routes");
// Requiring passport as we've configured it
let passport = require("./config/passport");
const sequelize = require("sequelize");
// const routes = require("./routes");
const app = express();
var db = require("./models");
const PORT = process.env.PORT || 3001;
// Define middleware here
app.use(express.urlencoded({ extended: true }));
app.use(express.json());
// passport stuff
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.use(express.static("public"));
// We need to use sessions to keep track of our user's login status
// app.use(cookieParser('cookit'));
app.use(
session({
secret: "cookit",
name: "cookit_Cookie"
})
);
app.use(passport.initialize());
app.use(passport.session());
// Serve up static assets (usually on heroku)
if (process.env.NODE_ENV === "production") {
app.use(express.static("client/public"));
}
// the view files are JavaScript files, hence the extension
app.set('view engine', 'js');
// the directory containing the view files
app.set('pages', './');
// Add routes, both API and view
app.use(routes);
// Syncing our database and logging a message to the user upon success
db.connection.sync().then(function() {
console.log("\nDB connected\n")
// Start the API server
app.listen(PORT, function() {
console.log(`🌎 ==> API Server now listening on PORT ${PORT}!`);
});
});
module.exports = app;
my passport.js code
//we import passport packages required for authentication
var passport = require("passport");
var LocalStrategy = require("passport-local").Strategy;
//
//We will need the models folder to check passport against
var db = require("../models");
// Telling passport we want to use a Local Strategy. In other words, we want login with a username/email and password
passport.use(
new LocalStrategy(
// Our user will sign in using an email, rather than a "username"
{
usernameField: "email",
passwordField: "password",
passReqToCallback: true
},
function(req, username, password, done) {
// console.log(`loggin in with email: ${username} \n and password: ${password}`)
// When a user tries to sign in this code runs
db.User.findOne({
where: {
email: username
}
}).then(function(dbUser) {
// console.log(dbUser)
// If there's no user with the given email
if (!dbUser) {
return done(null, false, {
message: "Incorrect email."
});
}
// If there is a user with the given email, but the password the user gives us is incorrect
else if (!dbUser.validPassword(password)) {
return done(null, false, {
message: "Incorrect password."
});
}
// If none of the above, return the user
return done(null, dbUser);
});
}
)
);
// serialize determines what to store in the session data so we are storing email, ID and firstName
passport.serializeUser(function(user, done) {
console.log(`\n\n serializing ${user.id}\n`)
done(null, user.id);
});
passport.deserializeUser(function(id, done) {
console.log(`\n\n DEserializing ${id}\n`)
db.User.findOne({where: {id:id}}, function(err, user) {
done(err, user);
});
});
// Exporting our configured passport
module.exports = passport;
const router = require("express").Router();
const controller = require("../../controllers/controller.js");
const passport = require("../../config/passport");
router.post(
"/login",
passport.authenticate("local", { failureRedirect: "/login" }),
function(req, res) {
console.log(`req body -${req.body}`);
res.json({
message: "user authenticated",
});
}
);
router.post("/saveRecipe", (req, res) => {
console.log(req.user)
if (req.isAuthenticated()) {
controller.saveRecipe;
} else {
res.json({ message: "user not signed in" });
}
});
module.exports = router;
The problem is in your router.post('login'). Try changing it to something like this:
app.post('/login', passport.authenticate('local-login', {
successRedirect: '/profile',
failureRedirect: '/login/failed'})
)
This will correctly set the req.user in your next requests!

Passport.SocketIo - How to get a list of online users with NodeJS, Express and Passport

i am finish sessionStore with MongoStore every login is being performed correctly and sessions are being written to the database without errors. I am using this package github.com/jfromaniello/passport.socketio to align the passport with socket io but I have already looked for several places about how after login make the treatment of the sessionStorageso it lists which users with names are online and offline, Could show me a light on this?
app.js
var express = require('express');
var mongoose = require('mongoose');
var path = require('path');
var bodyParser = require('body-parser');
var cookieParser = require('cookie-parser');
var session = require('express-session');
const MongoStore = require('connect-mongo')(session);
var flash = require('connect-flash');
var logger = require('morgan');
var passport = require('passport');
var passportSetup = require('./passport-setup');
// import routes
var routes = require('./routes');
// setup express app
var app = express();
app.use(logger());
// setup connection with mongodb
mongoose.connect( process.env.MONGODB_URI || "mongodb://smachs:***#d***.mlab.com:****/****-messenger",
(err, db)=> {
if (err) return new Error(err);
console.log('🔐 Conexão estabelecida com banco de dados!');
});
// setup passport from different class
passportSetup();
// set view engine and connection of application
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
app.use(bodyParser.urlencoded({extended:false}));
app.use(cookieParser());
// session storage based in mongodb
var sessionStore = new MongoStore({
url: 'mongodb://smachs:***#d***.mlab.com:****/****-messenger',
ttl: 1 * 24 * 60 * 60, // = 1 days. Default
autoReconnect: true
})
// setup session based in express-session
app.use(session({
secret:"58585858585858",
key: "connect.sid",
resave: false,
saveUninitialized: false,
store: sessionStore
}));
app.use(flash());
// public directory
app.use(express.static(__dirname + '/public'));
// passport staff
app.use(passport.initialize());
app.use(passport.session());
// start routes
app.use(routes);
// start server
var port = process.env.PORT || 3000;
var server = app.listen(port, () => { console.log('🌐 Servidor iniciado em localhost:', port); });;
// setup socket.io and passport.socketio packages
var io = require('socket.io').listen(server);
var passportSocketIo = require("passport.socketio");
// setup session found in express-session
io.use(passportSocketIo.authorize({
cookieParser: cookieParser, // the same middleware you registrer in express
key: 'connect.sid', // the name of the cookie where express/connect stores its session_id
secret: '58585858585858', // the session_secret to parse the cookie
store: sessionStore, // we NEED to use a sessionstore. no memorystore please
success: onAuthorizeSuccess, // *optional* callback on success - read more below
fail: onAuthorizeFail, // *optional* callback on fail/error - read more below
}));
// setup route just for clients authenticate
function ensureAutheticated(req, res, next) {
if (req.isAuthenticated()) next();
else {
req.flash("info", "Você precisa estar logado para visualizar essa página!");
res.redirect('/login');
}
}
// setup current online clients
var User = require('./models/user');
app.use((req, res, next) => {
res.locals.currentUser = req.user;
res.locals.errors = req.flash('error');
res.locals.infos = req.flash('info');
next();
});
// callback from passport.socketio
function onAuthorizeSuccess(data, accept) {
console.log('🗲 Passport-Socket.IO conectado com sucesso');
io.on('connection', function (socket) {
console.log("🗲 Socket.IO-Native conectado com sucesso");
});
// get current user online after authentication
io.on('connection', function (socket) {
// get user details of documents in database
app.get('/user-online', ensureAutheticated, (req, res) => {
User.find()
.sort({ createdAd: 'descending' })
.exec((err, users) => {
if (err) return next(err);
// render response
res.send({
users: users
})
});
});
});
accept();
}
function onAuthorizeFail(data, message, error, accept) {
console.log('failed connection to socket.io:', data, message);
if (error)
accept(new Error(message));
}
user.js
var mongoose = require('mongoose');
var bcrypt = require('bcrypt-nodejs');
const SALT_FACTOR = 10;
var userSchema = mongoose.Schema({
username: { type: String, required: true, unique: true },
password: { type: String, required: true },
createdAt: { type: Date, default: Date.now },
displayName: String,
bio: String
});
userSchema.methods.name = function() { return this.displayName || this.username;}
function noop() { };
userSchema.pre('save', function(done) {
var user = this;
console.log('USER: ' + JSON.stringify( user));
if (!( user.isModified('password'))) return done();
bcrypt.genSalt(SALT_FACTOR, function(err, salt) {
if (err) return done(err);
bcrypt.hash(user.password, salt, noop,
function (err, hashedPassword) {
if (err) return done(err);
user.password = hashedPassword;
done();
});
});
});
userSchema.methods.checkPassword = function(guess, done){
bcrypt.compare(guess, this.password, function(err, isMatch){
done(err,isMatch);
});
};
var User = mongoose.model('User', userSchema);
module.exports = User;
I was trying after login to make an query in a collection to list the users I logged but it is limited to only 1 user and gives me no option to treat this result better, thank you very much for the help they give me!
You can track connection, disconnect, login and logout events to create a list of online users.
You can manage online users in RAM or you can use redis for that. Following code snippet may help you achieve your goal -
// Store userIds here
let onlineUsers = [];
io.on('connection', function (socket) {
socket.on('login', (userTokenOrId) => {
// store this to onlineUsers or redis
// Other stuff
});
socket.on('logout', (userTokenOrId) => {
// remove this from onlineUsers or redis
// Other stuff
});
socket.on('disconnect', (userTokenOrId) => {
// remove this from onlineUsers or redis
// Other stuff
});
});
For better use, You can manage one array of objects to store userId and list of socketIds for same and one object to map socketId to userId. This way you can track is one user is online on different browsers/system.

passportjs local connectflash not working with ejs

I have a project using passportjs fully working, but not showing flash messages.
The passportjs file looks like this:
passport.use('local-login', new LocalStrategy({
// by default, local strategy uses username and password, we will override with email
usernameField: 'email',
passwordField: 'password',
passReqToCallback: true // allows us to pass in the req from our route (lets us check if a user is logged in or not)
},
function (req, email, password, done) {
if (email) {
email = email.toLowerCase()
} // Use lower-case e-mails to avoid case-sensitive e-mail matching
// asynchronous
process.nextTick(function () {
User.findOne({ 'local.email': email }, function (err, user) {
// if there are any errors, return the error
if (err) {
console.log(err)
return done(err)
}
// if no user is found, return the message
if (!user) {
console.log('No user found')
return done(null, false, req.flash('message', 'No user found'))
}
My routes.js file looks like this:
// Login
app.get('/login', function (req, res) {
console.log('login get')
res.render('pages/login', {message: req.flash('messsage')})
})
my login.ejs file looks like this:
<%if (message) {%>
<%=message%>
<%}%>
I have no idea why it isn't working?
Here comes my server.js if it is any problem related to includes:
var express = require('express')
var mongoose = require('mongoose')
var passport = require('passport')
var path = require('path')
var ejs = require('ejs') // Not used?
var fs = require('fs') // Not used?
const session = require('express-session')
const MongoStore = require('connect-mongo')(session)
// Reads .env variables for encrypted data
require('dotenv').config()
var port = process.env.PORT || 8080
var db = process.env.MONGO_URI
mongoose.connect(db) // connect to our database
var app = express()
app.set('views', './views')
app.set('view engine', 'ejs')
// GET /public/style.css etc.
app.use(express.static(path.join(__dirname, '/public')))
var bodyParser = require('body-parser')
app.use(bodyParser.urlencoded())
app.use(session({
secret: 'hakunamatata',
store: new MongoStore({
mongooseConnection: mongoose.connection,
saveUninitialized: false,
resave: false
})
}))
var flash = require('connect-flash')
app.use(flash())
var initPassport = require('./app/authentication/passport')
initPassport(passport)
app.use(passport.initialize())
app.use(passport.session()) // persistent login sessions
require('./app/routes/routes')(app, passport)
app.listen(port)
console.log('Dev port is: ' + port)
I tested with:
req.flash('loginMessage', 'No user found')
instead of:
req.flash('message', 'No user found')
and on the routes.js file:
{message: req.flash('loginMessage')}
instead of:
{message: req.flash('message')}
And now it works... I dont know what made the difference, but I hope this can help someone else in the future..

How to make API call using API token in Node.js using express, passport-local

I'm a newbie in Node.js and trying to use API token to access Grafana.
And I created one API token by following instruction from Grafana page.
However, I don't know how to make API calls from my code of node.js to access my local server of grafana page. Also, I have a local login-page by using mongoDB to manage users.
How can I make Node.js API calls to access my local server of grafana page?
Please help me out here.. I'm having hard time on this..
If you want me to show code, I can edit here..
EDIT:
This is my whole code for app.js
var io = require('socket.io');
var express = require('express');
var app = express();
var redis = require('redis');
var sys = require('util');
var fs = require('fs');
//Added for connecting login session
var http = require('http');
var server = http.createServer(app);
var path = require('path');
var mongoose = require('mongoose');
var passport = require('passport');
var session = require('express-session');
var flash = require('connect-flash');
var async = require('async');
var bodyParser = require('body-parser');
var methodOverride = require('method-override');
//Adding grafana
var request = require('request');
//Connecting Database (MongoDB)
mongoose.connect("my mongoDB private address");
var db = mongoose.connection;
db.once("open",function () {
console.log("DB connected!");
});
db.on("error",function (err) {
console.log("DB ERROR :", err);
});
//Setting bcrypt for password.
var bcrypt = require("bcrypt-nodejs");
//Setting userSchema for MongoDB.
var userSchema = mongoose.Schema({
email: {type:String, required:true, unique:true},
password: {type:String, required:true},
createdAt: {type:Date, default:Date.now}
});
userSchema.pre("save", function (next){
var user = this;
if(!user.isModified("password")){
return next();
} else {
user.password = bcrypt.hashSync(user.password);
return next();
}
});
//setting bcrypt for password.
userSchema.methods.authenticate = function (password) {
var user = this;
return bcrypt.compareSync(password,user.password);
};
//Setting User as userSchema.
var User = mongoose.model('user',userSchema);
io = io.listen(server);
//Setting middleware for login format.
app.set("view engine", 'ejs');
app.use(express.static(path.join(__dirname, 'public')));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended:true}));
app.use(methodOverride("_method"));
app.use(flash());
app.use(session({secret:'MySecret', resave: true, saveUninitialized: true}));
app.use(passport.initialize());
app.use(passport.session());
//Initializing passport.
passport.serializeUser(function(user, done) {
//console.log('serializeUser()', user);
done(null, user.id);
});
passport.deserializeUser(function(id, done) {
//console.log('deserializeUser()', user);
User.findById(id, function(err, user) {
done(err, user);
});
});
var username_tmp = '';
var global_username = ''; //Global variable for username to put in the address
var pass = '';
//Initializing passport-local strategy.
var LocalStrategy = require('passport-local').Strategy;
passport.use('local-login',
new LocalStrategy({
usernameField : 'email',
passwordField : 'password',
passReqToCallback : true
},
function(req, email, password, done) {
User.findOne({ 'email' : email }, function(err, user) {
if (err) return done(err);
if (!user){
req.flash("email", req.body.email);
return done(null, false, req.flash('loginError', 'No user found.'));
}
if (!user.authenticate(password)){
req.flash("email", req.body.email);
return done(null, false, req.flash('loginError', 'Password does not Match.'));
}
var email_address = req.body.email;
username_tmp = email_address;
var username = email_address.substring(0, email_address.lastIndexOf("#"));
global_username = username;
pass = req.body.password;
return done(null, user);
});
}
)
);
//Check whether it is logged in or not.
//If it is not logged in(Session is out), it goes to login page
//If it is logged in(Session is still on), it goes directly to status.html
app.get('/', loggedInCheck);
app.get('/login', function (req, res) {
res.render('login/login',{email:req.flash("email")[0], loginError:req.flash('loginError')});
});
//Accessing to MongoDB to check to login or not
app.post('/login',
function (req,res,next){
next();
}, passport.authenticate('local-login', {
successRedirect : '/status',
failureRedirect : '/login',
failureFlash : true
})
);
//Creating new account
app.get('/users/new', function(req,res){
res.render('users/new', {
formData: req.flash('formData')[0],
emailError: req.flash('emailError')[0],
passwordError: req.flash('passwordError')[0]
}
);
});
//Calling status.html
app.get('/status', isLoggedIn, function(req, res){
var user_temp = {user: ''};
user_temp.user = global_username;
res.render('status/status', user_temp);
//res.redirect('/status.html?channel=' + global_username);
});
app.get('/grafana', isLoggedIn, function(req, res){
console.log('Accessing to grafana');
res.redirect('http://localhost:8080');
});
request.get('http://localhost:8080',{
auth: {
bearer: 'TOKEN HERE'
}
});
server.listen(4000);
Edited more
app.get('/grafana', isLoggedIn, function(req, res){
console.log('Accessing to grafana');
var url = 'http://localhost:8080/api/dashboards/db/test';
request.get(url,{
auth: {
bearer: 'API token from Grafana page'
}
});
res.redirect(url);
});
Thank you..
The API calls are made with HTTP requests. You can use the request package from npm.
From the docs:
You use the token in all requests in the Authorization header, like this:
GET http://your.grafana.com/api/dashboards/db/mydash HTTP/1.1
Accept: application/json
Authorization: Bearer eyJrIjoiT0tTcG1pUlY2RnVKZTFVaDFsNFZXdE9ZWmNrMkZYbk
Example (I'm using request-promise but you can use whatever you want):
let request = require('request-promise');
let url = `http://your.grafana.com/api/dashboards/db/mydash`;
//Obviously replace this with your token
let myToken = `eyJrIjoiT0tTcG1pUlY2RnVKZTFVaDFsNFZXdE9ZWmNrMkZYbk`;
request.get(url).auth(null, null, true, myToken).then(res=> { ... });
// or
request.get(url, {
auth: {
bearer: myToken
}
}).then(res=> { ... });

Passport and Mongoose Issue

Hi I have this models:
user.js
// app/models/user.js
// load the things we need
var Schema = require('mongoose').Schema;
var bcrypt = require('bcrypt-nodejs');
var db = require('mongoose');
// define the schema for our user model
// create the model for users and expose it to our app
module.exports = function(app){
var userSchema = Schema({
local : {
email : String,
password : String,
},
facebook : {
id : String,
token : String,
email : String,
name : String
},
twitter : {
id : String,
token : String,
displayName : String,
username : String
},
google : {
id : String,
token : String,
email : String,
name : String
}
});
// methods ======================
// generating a hash
userSchema.methods.generateHash = function(password) {
return bcrypt.hashSync(password, bcrypt.genSaltSync(8), null);
};
// checking if password is valid
userSchema.methods.validPassword = function(password) {
return bcrypt.compareSync(password, this.local.password);
};
return db.model('User', userSchema);
};
post.js
var db = require('mongoose');
module.exports = function(app){
var Schema = require('mongoose').Schema;
var post = Schema({
title: String,
private: Boolean,
text: String,
tags: [],
createdAt: { type: Date, default: Date.now }
});
return db.model('post', post);
};
And a passport config file:
// config/passport.js
// load all the things we need
var db = require('../config/db_connect')();
var LocalStrategy = require('passport-local').Strategy;
// load up the user model
var User = db.model('User');
// expose this function to our app using module.exports
module.exports = function(passport) {
// =========================================================================
// passport session setup ==================================================
// =========================================================================
// required for persistent login sessions
// passport needs ability to serialize and unserialize users out of session
// used to serialize the user for the session
passport.serializeUser(function(user, done) {
done(null, user.id);
});
// used to deserialize the user
passport.deserializeUser(function(id, done) {
User.findById(id, function(err, user) {
done(err, user);
});
});
// =========================================================================
// LOCAL SIGNUP ============================================================
// =========================================================================
// we are using named strategies since we have one for login and one for signup
// by default, if there was no name, it would just be called 'local'
passport.use('local-signup', new LocalStrategy({
// by default, local strategy uses username and password, we will override with email
usernameField : 'email',
passwordField : 'password',
passReqToCallback : true // allows us to pass back the entire request to the callback
},
function(req, email, password, done) {
// asynchronous
// User.findOne wont fire unless data is sent back
process.nextTick(function() {
// find a user whose email is the same as the forms email
// we are checking to see if the user trying to login already exists
User.findOne({ 'local.email' : email }, function(err, user) {
// if there are any errors, return the error
if (err)
return done(err);
// check to see if theres already a user with that email
if (user) {
return done(null, false, req.flash('signupMessage', 'That email is already taken.'));
} else {
// if there is no user with that email
// create the user
var newUser = new User();
// set the user's local credentials
newUser.local.email = email;
newUser.local.password = newUser.generateHash(password);
// save the user
newUser.save(function(err) {
if (err)
throw err;
return done(null, newUser);
});
}
});
});
}));
};
And at least my app.js
var express = require('express')
, load = require('express-load')
, bodyParser = require('body-parser')
, cookieParser = require('cookie-parser')
, passport = require('passport')
, flash = require('connect-flash')
, mongoose = require('mongoose')
, session = require('express-session')
, app = express();
require('./config/passport')(passport);
app.set('views', __dirname + '/views');
app.set('view engine', 'ejs');
app.use(cookieParser('blog'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));
// required for passport
app.use(session({
secret: 'appsecret',
resave: false,
saveUninitialized: true,
cookie: {
secure: true,
maxAge: new Date(Date.now() + 3600000)
}
}));
app.use(passport.initialize());
app.use(passport.session()); // persistent login sessions
app.use(flash()); // use connect-flash for flash messages stored in session
app.use(express.static(__dirname + '/public'));
load('models')
.then('controllers')
.then('routes')
.into(app);
require('./routes/login.js')(app, passport);
app.listen(3030, function(){
console.log("Blog no ar.");
});
But when i try to run my app, I got an exception:
/home/caio/workspace/personal-blog/node_modules/mongoose/lib/index.js:323
throw new mongoose.Error.MissingSchemaError(name);
^
MissingSchemaError: Schema hasn't been registered for model "User".
Use mongoose.model(name, schema)
at Mongoose.model (/home/caio/workspace/personal-blog/node_modules/mongoose/lib/index.js:323:13)
at Object.<anonymous> (/home/caio/workspace/personal-blog/config/passport.js:10:15)
at Module._compile (module.js:456:26)
at Object.Module._extensions..js (module.js:474:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Module.require (module.js:364:17)
at require (module.js:380:17)
at Object.<anonymous> (/home/caio/workspace/personal-blog/app.js:13:1)
I am registering my user model, but mongoose is not recognizing, anyone can help me?
In your app.js, load mongoose first before express.
var mongoose = require('./config/mongoose'),
express = require('./config/express');
var db = mongoose();
var app = express();
And don't forget to register the model. your code should be
return db.model('User', userSchema);
Okay, a mongoose Model requires a schema.
Instead of:
var User = db.model('User');
Do something like:
var Schema = require('mongoose').Schema
var userSchema = new Schema({
name: {
type: String,
default: 'hahaha'
}
});
var User = db.model('User', userSchema);

Resources