How can i access values from database - node.js

How can i access for example username and put it in profile page ?
model/db.js
const mongoose = require('mongoose');
const stDB = mongoose.Schema({
username : {
type: String,
required: true
},
email : {
type: String,
required: true
},
password : {
type: String,
required: true
}
});
module.exports = mongoose.model('db', stDB);
views/profiles/instructor.hbs
<h5>I want access username from db and put it here!</h5>
index.js
const users = require('../model/db'); // db that username stored in it (model/db.js)
//instructor
router.get('/profiles/instructor', function (req, res, next) {
res.render('./profiles/instructor', {
title: 'Instructor'
});
});
router.post('/signup', function (req, res, next){
const newUser = new users({
username : req.body.username,
email : req.body.email,
password : req.body.password,
});
users.findOne({email : req.body.email}, (err, doc)=>{
if(err){
console.log('ERR while getting username =>' + err);
return ;
}
if(doc){
res.send('this email is already registered before!');
return ;
}
newUser.save((err, doc)=>{
if(err){
console.log('err' + err)
}else{
console.log(doc)
res.redirect('/login')
}
});
});
// etc.....

Related

How to Append key: value pairs to existing Mongodb objects using Mongoose

const express = require('express');
const bcrypt = require('bcryptjs');
const passport = require('passport');
const { ensureAuthenticated } = require('../config/auth');
const router = express.Router();
//User/Post model
const User = require('../models/DBmusevista');
//Welcome/register page
router.get('/', (req, res) => res.render('register'));
//Login page
router.get('/login', (req, res) => res.render('login'));
//Home page
router.get('/home', ensureAuthenticated, (req, res) => res.render('home', {user_mv: req.user}));
//Create topic page
router.get('/create-topic', ensureAuthenticated, (req, res) => res.render('create-topic', {user_mv: req.user}));
//Register handle
router.post('/', (req, res) => {
const {firstname, lastname, username, email, password} = req.body;
let errors =[];
if(!firstname || !lastname || !username || !email || !password) {
errors.push({msg: 'Please check all fields.'});
};
//Check password length
if(password.length < 6) {
errors.push({msg: 'Password should be at least 6 characters.'});
};
if(errors.length > 0){
res.render('register', {
errors,
firstname,
lastname,
username,
email,
password
});
}else {
//Validation passed
User.findOne({email: email})
.then(user => {
if(user){
//User exists
errors.push({msg: 'Email is already registered.'})
res.render('register', {
errors,
firstname,
lastname,
username,
email,
password
});
} else {
const newUser = new User({ //Check User
firstname,
lastname,
username,
email,
password
});
//Hash password
bcrypt.genSalt(10, (err, salt) =>
bcrypt.hash(newUser.password,salt, (err, hash) => {
if(err) throw err;
//Set password to hash
newUser.password = hash;
//Save user
newUser.save()
.then(user => {
req.flash('success_msg', 'You are now registered and can now log in');
res.redirect('/login');
})
.catch(err => console.log(err));
}))
}
});
}
});
//Post handle
router.post('/create-topic', (req, res) => {
let newObj = {
title: req.body.title,
category: req.body.category,
vista: req.body.vista,
description: req.body.description
}
User.updateOne({username: user_mv.username}, { $set: {post: newObj}});
res.send('Hello');
//This is the code that does not work. Anything else I've tried has not worked.
});
//Login handle
router.post('/login', (req, res, next) => {
passport.authenticate('local', {
successRedirect: '/home',
failureRedirect: '/login',
failureFlash: true
})(req, res, next);
});
module.exports = router;
const mongoose = require('mongoose');
const DBmusevistaSchema = mongoose.Schema({
firstname: {
type: String,
required: false
},
lastname: {
type: String,
required: false
},
username: {
type: String,
required: false
},
email: {
type: String,
required: false
},
password: {
type: String,
required: false
},
date: {
type: Date,
default: Date.now
}
});
const DBmusevista = mongoose.model('DBmusevista', DBmusevistaSchema);
module.exports = DBmusevista;
When an individual comes to my website the beginning page ('/') is a registration for for my site. I have a post request for my MongoDB collection that creates a 'user register' object (fname, lname, username, email, pass). Once logged in ('/home') a user can then create a new post(s) form that is located in my create-topic.ejs file('/create-topic'). I'm new to using MongoDB so my question is how can I append the post submitted (title, category, vista, description) to an array for the users' object.
I'm not sure if I should add an array (posts: []) to DBmusevistaSchema and create a Post.Schema({key: value}) in my DBmusevista file? I tried using User.findOne but I cannot get it to work. Please help.
try {
const pirs = await Pir.find();
pirs.forEach(async (pir) => {
let pir2 = new Pir();
pir.isSubmitted = false;
pir2 = pir;
const out = await pir2.save();
console.log(out);
});
} catch (err) {
next(err);
}

How to fix "User.findOne()" returning null for user

I'm currently working on a new project and I'm trying to get the login route working. But the login always fails because the User.findOne() method is always returning as null.
I've tried changing the export from the usermodel to
var User = mongoose.model('User', UserSchema, 'User');
But it hasn't change anything.
I know the connection to the database is fine because the register route works fine and saves correctly.
Login Route
router.post('/login', function (req, res) {
User.findOne({ username: req.body.username, password: req.body.password }, function (err, user) {
if (err || user == null) {
res.redirect('/login');
console.log(user);
} else {
req.session.userId = user._id;
res.redirect('/');
}
});
});
User Schema
var mongoose = require('mongoose');
var 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,
required: true
}
});
UserSchema.statics.authenticate = function (email, password, callback) {
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);
}
bcrypt.compare(password, hash, function (err, result) {
if (result === true) {
return callback(null, user);
} else {
return callback();
}
});
});
};
//hashing a password before saving it to the database
UserSchema.pre('save', function (next) {
var user = this;
bcrypt.hash(user.password, 10, function (err, hash) {
if (err) {
return next(err);
}
user.password = hash;
next();
});
});
var User = mongoose.model('users', UserSchema);
module.exports = User;
Database Connection
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost:27017/wowDb', { useNewUrlParser: true });
var db = mongoose.connection;
mongoose.set('useCreateIndex', true);
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', function () { });
I used
db.users.findOne({username: "Imortalshard"});
and got the output
{
"_id" : ObjectId("5cc10cd13361880abc767d78"),
"email" : "admin#wowdb.com",
"username" : "Imortalshard",
"password" : "$2b$10$7Ln5yHFqzPw/Xz6bAW84SOVhw7.c0A1mve7Y00tTdaKzxzTph5IWS",
"__v" : 0
}
Console output from console.log(req.body) and console.log(user)
I'm waiting the user that i registered to be able to successfully login, but currently it is just redirecting me back to the login page and giving me a null reading for user in the console.

MissingUsernameError: No username was given - Unsure where i'm going wrong

I'm using Node.js with Mongoose and Passport trying to get the user to save to the DB but keep encountering the error where No Username was given. I can get it to save if just using using username and password but as soon as I try to add more fields I get the issue. This is the code I have:
app.js
const userSchema = new mongoose.Schema ({
firstname: String,
lastname: String,
username: String,
password: String,
userLevel: {type: Number},
profileImage: String,
title: String
});
//ENABLE PASSPORT LOCAL
userSchema.plugin(passportLocalMongoose, {
selectFields: ' firstname lastname username password userLevel profileImage title'
});
//CREATE NEW model
const User = new mongoose.model("User", userSchema);
passport.use(User.createStrategy());
passport.serializeUser(User.serializeUser());
passport.deserializeUser(User.deserializeUser());
app.get('/control', (res, req) => {
if (req.isAuthenticated()) {
res.render('control');
} else {
res.redirect('/login')
}
});
app.post("/register", (req, res) => {
User.register(new User(
{firstname: req.body.firstname},
{lastname: req.body.lastname},
{username:req.body.username},
{userLevel: 1},
{profileImage:"not set"},
{title:"not set"}
),
req.body.password,
(err, user) => {
if (err) {
console.log(err);
console.log(req.body.username);
} else {
passport.authenticate('local')(req, res, () =>{
res.redirect('/control');
});
}
});
});
Figured it out! I was using individual objects rather that just the one object :
User.register((
{firstname: req.body.firstname,
lastname: req.body.lastname,
username: req.body.username,
userLevel: 1,
profileImage:"not set",
title:"not set"
}),
req.body.password,
(err, user) => {
if (err) {
console.log(err);
console.log(req.body.username);
} else {
passport.authenticate('local')(req, res, () =>{
res.redirect('/control');
});
}
});
});

bcrypt login is not working in production while works on localhost

I used the user model like below:
the usermodel uses bcrypt authentication and is working fine over the localhost.
In the production, the registration works fine and while registering the user gets logged in. However, in the login it gives the error "Either Username or Password is wrong".
var mongoose = require("mongoose");
var passportLocalMongoose = require("passport-local-mongoose");
var bcrypt = require('bcrypt-nodejs');
var userSchema = new mongoose.Schema({
username: {type: String, required: true, unique: true},
email : {type: String, required: true, unique: true},
password : {type: String},
twitterId : String,
twitterToken: String,
profileUserName: String,
displayName : String,
coachingUser: Boolean,
coaching_name: String,
resetPasswordToken: String,
resetPasswordExpires: Date
});
userSchema.plugin(passportLocalMongoose);
userSchema.pre('save', function(next) {
var user = this;
var SALT_FACTOR = 5;
console.log("in the presave method");
if (!user.isModified('password'))
{
//console.log("in the presave method");
return next();
}
bcrypt.genSalt(SALT_FACTOR, function(err, salt) {
if (err) return next(err);
bcrypt.hash(user.password, salt, null, function(err, hash) {
console.log("in the presave method");
if (err) return next(err);
user.password = hash;
next();
});});});
userSchema.methods.comparePassword = function(candidatePassword, cb) {
console.log("candidatePassword: " + candidatePassword);
console.log(this.password);
var passlen = this.password;
console.log("password length: " + passlen.length);
bcrypt.compare(candidatePassword, this.password, function(err, isMatch) {
console.log("isMatch: " + isMatch);
if (err) return cb(err);
cb(null, isMatch);
});
};`
module.exports = mongoose.model("User",userSchema);
in the localhost, the bcrypt login is working fine. However in the production over https://mlab.com/home and digitalocean, the login always gives Email or password not correct.
router.post('/login', function(req, res, next) {
console.log(req);
passport.authenticate('local', function(err, user, info) {
if (err) return next(err)
if (!user) {
//console.log(user);
req.flash("error", "Either Username or Password is wrong");
return res.redirect('/login');
}
req.logIn(user, function(err) {
if (err) return next(err);
{
//console.log(user);
req.flash("success","Successfully logged in as " + user.username);
res.redirect('/coaching');
}
});
})(req, res, next);
});
Kindly provide help as to why in production the particular logic not work

How to use methods on schema in mongoose + express

I'm getting the following error when I try to run user.comparePassword from exports.index.post (see below) -- I pasted all code to help narrow down the problem. The UserSchema.pre('save') method works fine, but not the one in ./routes/account.js (I'm using mongoose 3)
Here is the error I get.
Caught exception: [TypeError: Object { username: 'test4',
email: 'test4#test.com',
password: '$2a$10$Ix5vCuVYGIU7AmXglmfIxOyYnF6CiPJfw9HLSAGcRDxMJEttud/F6',
_id: 505fee7ce28f10711e000002,
__v: 0 } has no method 'comparePassword']
## ./app.js
app.post('/account', routes.account.index.post);
## ./models/user.js
var mongoose = require('mongoose')
, bcrypt = require('bcrypt')
, Schema = mongoose.Schema
, db = mongoose.createConnection('localhost', 'mydb');
var UserSchema = new Schema({
username : { type: String, required: true, index: { unique: true }, trim: true }
, email : { type: String, required: true, index: { unique: true }, trim: true, lowercase: true }
, password : { type: String, required: true, trim: true }
});
UserSchema.pre('save', function(next) {
var user = this;
// only hash the password if it has been modified (or is new)
if (!user.isModified('password')) return next();
// generate a salt
bcrypt.genSalt(function(err, salt) {
if (err) return next(err);
// hash the password along with our new salt
bcrypt.hash(user.password, salt, function(err, hash) {
if (err) return next(err);
// override the cleartext password with the hashed one
user.password = hash;
next();
});
});
});
//compare supplied password
UserSchema.methods.comparePassword = function(candidatePassword, cb) {
bcrypt.compare(candidatePassword, this.password, function(err, isMatch) {
if (err) return cb(err);
cb(null, isMatch);
});
};
module.exports = db.model('User', UserSchema);
##./routes/account.js
/*
* GET account home page.
*/
exports.index = {};
exports.index.get = function(req, res){
var d = { title: 'Edit account' };
res.render('account', { d: d } );
};
exports.index.post = function(req, res){
req.assert('email', 'Enter email').notEmpty().isEmail();
req.assert('password', 'Enter password').notEmpty().isAlphanumeric().len(5,20);
//user must confirm password
if ( req.body.password_new ) {
req.assert('password_new', 'Enter password').notEmpty().isAlphanumeric().len(5,20);
req.assert('password_new_confirm', 'Passwords must match').equals(req.body.password);
}
res.locals.err = req.validationErrors(true);
if ( res.locals.err ) {
var d = { title: 'Edit account' };
res.render('account', { d: d } );
return;
}
var User = require('../models/user')
, mongoose = require('mongoose')
, db = mongoose.createConnection('localhost', 'mydb');
var user = db.model('User', User.UserSchema);
user.find({username: req.session.user.username }, function(err, user){
if ( err ) return next(err);
/*********** THIS IS WHERE THE ERROR OCCURS **************/
user.comparePassword(req.body.password, function(err, isMatch) {
console.log("isMatch", isMatch);
if (err) next(err);
if (!isMatch) {
req.flash('error', 'Woops, looks like you mistyped your password.');
req.session.user = user;
res.locals.user = user;
res.redirect('/account');
return;
}
//user is authenticated
//session length
console.log(req.body);
});
});
};
user.find queries for 0 or more docs, so the second parameter to its callback is an array of docs, not a single doc. user.findOne queries for 0 or 1 docs, so the second parameter to its callback is either null or that single doc. So you're trying to call your schema's method on a JavaScript Array which of course won't work. Change that find call to a findOne and it should work.

Resources