how to reference itself in mongoose schema? - express

I am trying to create profile of a user and in friends key I want to store array of objectId of other users. So how to reference itself
const mongoose = require("mongoose")
const userSchema = mongoose.Schema({
firstname:String,
lastname:String,
password:String,
email:{
type:String,
unique:true
},
birthday:Date,
creation_date:{
type:Date,
default:Date.now
},
gender:String,
profile_picture:{
type:String,
default:""
},
friends:[{
type:mongoose.Schema.Types.ObjectId,
ref:"userModel"
}]
})
const userModel = new mongoose.model("userModel", userSchema)
module.exports = userModel
By doing this, and sending request from postman i am getting empty array of friends
Fields
firstname
dhiran
lastname
sapkota
email
dhiransapkota9#gmail.com
password
thisisemail
birthday
2059-08-09
gender
male
friends
["6319b1bd2d4f0f0145662f3b", "6319ad712d4f0f0145662f35"]
Output I am getting is:
{
"success": true,
"msg": "user has been signed up",
"signupUser": {
"firstname": "dhiran",
"lastname": "sapkota",
"password": "$2a$10$rOaA3QlameBO4my8C9fmye73Zi9QxtPbi3X.XFpDNd7J8tBD3SbMq",
"email": "dhiransapkota999#gmail.com",
"birthday": "2059-08-09T00:00:00.000Z",
"gender": "male",
"profile_picture": "1662798667954-cv_image.png",
"friends": [],
"_id": "631c4b4c2d832a439c88720f",
"creation_date": "2022-09-10T08:31:08.072Z",
"__v": 0
}
}
I am using multipart/formdata so data is in this format.
route
router.post("/signup", upload.single("profile"), (req, res) => {
userControllerInstance.signup(req, res, profile_picture)
});
controller:
class UserController {
async signup(req, res, profile_picture) {
try {
const { firstname, lastname, email, password, birthday, gender, friends } =
req.body;
const response = await userModel.find({ email: email });
console.log(response);
if (response.length > 0) {
return res
.status(409)
.json({ success: false, msg: "email already exists" });
}
const hashedPassword = generateHash(password);
const signupUser = await userModel.create({
firstname,
lastname,
email,
password: hashedPassword,
birthday,
gender,
profile_picture,
friends
});
return res.json({
success: true,
msg: "user has been signed up",
signupUser,
});
} catch (error) {
return res.json(error);
}
}
}

Related

Freecodecamp execrise tracker unable to fetch date from data base

Unaable to fetch data from get request : /api/users/:_id/logs
url passed to this request : https://boilerplate-project-exercisetracker.sushilgupta4.repl.co/api/users/63a42aa0beed29d45418f2d5/logs?from=2022-10-10&to=2022-12-30&limit=2
link to my project : https://replit.com/#SushilGupta4/boilerplate-project-exercisetracker
As when I save the data for exercise for particular user the date is saved in the format of 2022-11-05T00:00:00.000+00:00.
But When I recevice date from the user request then convert date to new Date(date) and date is converted in the format of 2022-10-10T00:00:00.000Z
I think if able to change format of either one my code will work. Please look into to code and please tell me how can solve this problem.
This is the project from freecodecamp which i need complete in order to get back-end certificate.
https://www.freecodecamp.org/learn/back-end-development-and-apis/back-end-development-and-apis-projects/exercise-tracker
const express = require('express')
const app = express()
const cors = require('cors')
const mongoose = require('mongoose')
require('dotenv').config()
try {
mongoose.connect(process.env.MANGO_URI, { useNewUrlParser: true, useUnifiedTopology: true });
console.log('db connected')
} catch (err) {
console.log(err)
}
const personSchema = new mongoose.Schema({
username: {
type: String,
require: [true, 'username must be provided'],
unique: true
},
})
const exerciseSchema = new mongoose.Schema({
userId: {
type: String,
require: [true, 'userId must be provided']
},
username: {
type: String,
require: [true, 'username must be provided']
},
description: {
type: String,
require: [true, 'desc must be provided']
},
duration: {
type: Number,
require: [true, 'Duration must be provided']
},
date: {
type: String,
require: [true, 'date must be provided']
},
})
const Person = mongoose.model("Person", personSchema)
const Exercise = mongoose.model("Exercise", exerciseSchema)
app.use(cors())
app.use(express.static('public'))
app.use(express.urlencoded({ extended: true }))
app.get('/', (req, res) => {
res.sendFile(__dirname + '/views/index.html')
});
app.post('/api/users', function(req, res) {
const username = req.body.username
const data = new Person({ username: username })
data.save((err, data) => {
if (err) {
res.json("username already Taken")
} else {
res.json({ username: data.username, _id: data._id })
}
})
})
app.get('/api/users', (req, res) => {
Person.find({}, (err, data) => {
if (!data) {
res.send("No user")
} else {
res.json(data)
}
})
})
app.post('/api/users/:_id/exercises', (req, res) => {
const _id = req.body[':_id']
const { description, duration, date } = req.body
console.log(new Date(date).toISOString())
let formatDate = new Date(date).toISOString()
console.log("format date" + formatDate)
Person.findById(_id, (err, data) => {
if (!data) {
res.send("User Not found")
} else {
const username = data.username
const addExercise = new Exercise({ userId: _id, username, description, duration, date: formatDate })
addExercise.save((err, user) => {
if (err) console.log(err)
res.json({ username: username, description: user.description, duration: user.duration, date: user.date.toDateString, _id })
})
}
})
})
app.get('/api/users/:_id/logs', (req, res) => {
const userId = req.params._id
const _id = userId
let { from, to, limit } = req.query
let filter = { userId }
let dateFilter = {}
if (from) {
from = new Date(from)
from = from.slice(23)
dateFilter['&gte'] = from
console.log(from)
}
if (to) {
dateFilter['&lte'] = new Date(to)
}
if (from || to) {
filter.date = dateFilter
}
console.log(filter)
Person.findById({ _id }, (err, data) => {
if (!data) {
res.send("userId not found")
} else {
console.log("found the id user")
const username = data.username
//{date: {$gte: new Date(from), $lte:new Date (to)}}
Exercise.find(filter).limit(limit).exec((err, data) => {
console.log("found user exericse")
if (err) console.log(err)
//console.log(data)
let customdata = data.map(items => {
let formattedDate = new Date(items.date).toDateString()
return { description: items.description, duration: items.duration, date: formattedDate }
})
if (!data) {
res.json({
"_id": userId,
"username": username,
"count": 0,
"log": []
})
} else {
console.log("inside")
res.json({
"_id": userId,
"username": username,
"count": data.length,
"log": customdata
})
}
})
}
})
})
const listener = app.listen(process.env.PORT || 3000, () => {
console.log('Your app is listening on port ' + listener.address().port)
})
I was expecting how can i fetch the data from that get request or how can i change the date format.

How to get data from related table in 1:N relationship when login in Sequelize?

I have two tables, users and recyclings, which are 1:N relationship (one user have many recyclings, one recycling belongs to one user. When login, I also want to fetch user's recyclings, but it doesn't work when I try to use include. I get response, but without recyclings array.
Response should be like this:
{
"id": 2,
"name": "Bernt",
"surname": "Bjornson",
"vat": "78965412354",
"email": "bernt#mail.sv",
"password": "$2a$08$N02C/YMq0MO.b.eiEZVAc.7cmdb49X1yEPKrFy.8bWU9TsrGgcdfG",
"createdAt": "2022-08-22T10:04:07.454Z",
"updatedAt": "2022-08-22T10:04:07.454Z",
"recyclings": [
{
"id": 4,
"solvents": 0,
"acids": 5,
"createdAt": "2022-08-22T10:04:36.413Z",
"updatedAt": "2022-08-22T10:04:36.413Z",
"userId": 2
},
{
"id": 5,
"solvents": 0.4,
"acids": 77,
"createdAt": "2022-08-22T10:05:05.733Z",
"updatedAt": "2022-08-22T10:05:05.733Z",
"userId": 2
}
]
}
Here is login function in AuthController:
const db = require("../models");
const config = require("../config/auth.config");
const User = db.user;
const Role = db.role;
const Recycling = db.recyclings;
const Op = db.Sequelize.Op;
var jwt = require("jsonwebtoken");
var bcrypt = require("bcryptjs");
exports.signin = (req, res) => {
User.findOne({
where: {
email: req.body.email
}
}, {include: ["recyclings"]}) //HERE IS INCLUDE-doesn't work!
.then(user => {
if (!user) {
return res.status(404).send({ message: "User not found!" });
}
var passwordIsValid = bcrypt.compareSync(
req.body.password,
user.password
);
if (!passwordIsValid) {
return res.status(401).send({
accessToken: null,
message: "Password not correct!"
});
}
var token = jwt.sign({ id: user.id }, config.secret, {
expiresIn: 86400 // 24 hours
});
var authorities = [];
user.getRoles().then(roles => {
for (let i = 0; i < roles.length; i++) {
authorities.push("ROLE_" + roles[i].name.toUpperCase());
}
res.status(200).send({
id: user.id,
name: user.name,
surname: user.surname,
vat: user.vat,
email: user.email,
roles: authorities,
accessToken: token
});
});
})
.catch(err => {
res.status(500).send({ message: err.message });
});
};
I don't know how to incorporate getRecyclings() function with existing getRoles(). Can someone help me, please?
spelling error,
you import Recycling to your code
and use recyclings in to your find query include.
change it.and try again

[uncaught application error]: TypeError - Cannot read properties of undefined (reading 'name')

I get this error message when I try to test the /api/register end point with Postman and following POST request:
{
"name" : "first",
"email" : "first#one.com",
"password" : "123"
}
[uncaught application error]: TypeError - Cannot read properties of undefined (reading 'name')
request: { url: "http://0.0.0.0:8000/api/register", method: "POST", hasBody: true }
response: { status: 404, type: undefined, hasBody: false, writable: true }
at register (file:///C:/Users/m/app_back/controllers/auth_controller.ts:9:22)
at async dispatch (https://deno.land/x/oak#v9.0.1/middleware.ts:41:7)
at async dispatch (https://deno.land/x/oak#v9.0.1/middleware.ts:41:7)
at async dispatch (https://deno.land/x/oak#v9.0.1/middleware.ts:41:7)
at async EventTarget.#handleRequest (https://deno.land/x/oak#v9.0.1/application.ts:379:9)
TypeError: Cannot read properties of undefined (reading 'name')
at register (file:///C:/Users/m/app_back/controllers/auth_controller.ts:9:22)
at async dispatch (https://deno.land/x/oak#v9.0.1/middleware.ts:41:7)
at async dispatch (https://deno.land/x/oak#v9.0.1/middleware.ts:41:7)
at async dispatch (https://deno.land/x/oak#v9.0.1/middleware.ts:41:7)
at async EventTarget.#handleRequest (https://deno.land/x/oak#v9.0.1/application.ts:379:9)
This is my auth_controller.ts file:
import {
create, verify, decode, getNumericDate, RouterContext, hashSync, compareSync
} from "../deps.ts";
import { userCollection } from "../mongo.ts";
import User from "../models/user.ts";
export class AuthController {
async register(ctx: RouterContext) {
const { value: { name, email, password } } = await ctx.request.body().value;
let user = await User.findOne({ email });
if (user) {
ctx.response.status = 422;
ctx.response.body = { message: "Email is already used" };
return;
}
const hashedPassword = hashSync(password);
user = new User({ name, email, password: hashedPassword });
await user.save();
ctx.response.status = 201;
ctx.response.body = {
id: user.id,
name: user.name,
email: user.email
};
}
async login(ctx: RouterContext) {
const { value: { email, password } } = await ctx.request.body().value;
if (!email || !password) {
ctx.response.status = 422;
ctx.response.body = { message: "Please provide email and password" };
return;
}
let user = await User.findOne({ email });
if (!user) {
ctx.response.status = 422;
ctx.response.body = { message: "Incorrect email" };
return;
}
if (!compareSync(password, user.password)) {
ctx.response.status = 422;
ctx.response.body = { message: "Incorrect password" };
return;
}
const key = await crypto.subtle.generateKey(
{ name: "HMAC", hash: "SHA-512" },
true,
["sign", "verify"],
);
const jwt = create( {
alg: "HS256",
typ: "JWT",
}, {
iss: user.email,
exp: getNumericDate(
Date.now() + parseInt(Deno.env.get("JWT_EXP_DURATION") || "0"))
},
key
);
ctx.response.body = {
id: user.id,
name: user.name,
email: user.email,
jwt,
};
}
}
export default new AuthController();
What is the problem and how can I resolve it?
EDIT: I added this line to the code:
console.log( await ctx.request.body().value );
And this is the result:
{ name: "first", email: "first#one.com", password: "123" }
You are facing this issue because you are trying to access ctx.request.body().value.value.name (notice multiple value porperties). You could change line 9 of your auth_controller.ts to this to fix it:
const { name, email, password } = await ctx.request.body().value;
On a side note, I also noticed few more issues with your current code.
Your JWT algorithm and generated secret key encryption algorithm should match
So either change your hash encryption on line 47 to SHA-256 or your JWT algorithm on line 53 to HS512.
You don't need to pass current date to getNumericDate function
This helper function already does this job for you, all you need to pass here is the time period (in seconds) when you want your token to expire. In your case it would be:
getNumericDate(Deno.env.get("JWT_EXP_DURATION") || 0)}

User authentication error using express not working

So I'm having trouble authenticating a user login using express for the backend. If I do a simple res.send I could get a response in postman. but if I do a check if the user and password check and generate a token if says error 401 invalid usernames and password. mind the tokens work for register and update profiles. I also attached the user schema.
Simple Approach
const authUser = asyncHandler(async (req, res) => {
const { email, password } = req.body
res.send({ email, password })
})
When I try to check and generate a token
const authUser = asyncHandler(async (req, res) => {
const { email, password } = req.body
const user = await User.findOne({ email })
if (user && (await user.matchPassword(password))) {
res.json({
_id: user._id,
name: user.name,
email: user.email,
isAdmin: user.isAdmin,
token: generateToken(user._id),
})
} else {
res.status(401)
throw new Error('Invalid Email or password')
}
})
Also here's my user schema using mongoose and added a function to check password since in the database it's encrypted using bcrypt.js
import mongoose from 'mongoose'
import bcrypt from 'bcryptjs'
const userSchema = mongoose.Schema(
{
name: {
type: String,
required: true,
},
email: {
type: String,
required: true,
unique: true,
},
password: {
type: String,
required: true,
},
isAdmin: {
type: Boolean,
required: true,
default: false,
},
},
{
timestamps: true,
}
)
userSchema.methods.matchPassword = async function (enteredPassword) {
return await bcrypt.compare(enteredPassword, this.password)
}
const User = mongoose.model('User', userSchema)
export default User
You see, your code is absolutely correct, but only if you have saved the user correctly in your model at the first. In addition, the password used during storage is hashed in the same way and from the same module.
Now you have to change your checking terms because there may not really be a user with this email in the database to match your password and return true value.
import mongoose from 'mongoose'
import bcrypt from 'bcryptjs'
const userSchema = mongoose.Schema(
{
name: {
type: String,
required: true,
},
email: {
type: String,
required: true,
unique: true,
},
password: {
type: String,
required: true,
},
isAdmin: {
type: Boolean,
required: true,
default: false,
},
},
{
timestamps: true,
}
)
userSchema.pre('save', function (next) {
if (this.password) {
bcrypt.hash(this.password, bcrypt.genSaltSync(15), (err, hash) => {
if (err) console.log(err);
this.password = hash;
next();
});
}
}
userSchema.methods.Save = async (data) => {
let model=new User(data)
await model.save();
}
userSchema.methods.matchPassword = async function (enteredPassword) {
return await bcrypt.compare(enteredPassword, this.password)
}
const User = mongoose.model('User', userSchema)
export default User
and update this code:
const authUser = asyncHandler(async (req, res) => {
const { email, password } = req.body
const user = await User.findOne({ email })
if (user) {
if(await user.matchPassword(password)) {
res.json({
_id: user._id,
name: user.name,
email: user.email,
isAdmin: user.isAdmin,
token: generateToken(user._id),
})
} else {
res.status(401)
throw new Error('Invalid password')
}
} else {
res.status(401)
throw new Error('Invalid Email')
}
})
Now you know which part of the job is the problem. No user or no wrist password

user.setPassword is not a function - passport local mongoose

I am implementing a reset password feature on for the users of my website. However, it seems to throw this error when the user confirms new password at the reset.ejs page.
The following steps are being performed correctly:
Token sent on mail
When clicked on token, new password page opens
When user enters new password and confirm new password and hits the button to save the new password, the function in users.js user.setPassword does not work as the error is mentioned below. It is a built in function of passport-local-mongoose.
ERROR: user.savePassword is not a function
Including all the code files below:
users.js:
var express = require('express');
var router = express.Router();
var multer = require('multer');
var upload = multer({dest: './uploads'});
var passport = require('passport');
var mongoose = require('mongoose');
var LocalStrategy = require('passport-local').Strategy;
var randomstring = require("randomstring");
var User = require('../models/user');
var data=require('../models/data');
var checklist=require("../models/checklist");
var async = require("async");
var crypto = require("crypto");
var passportLocalMongoose=require("passport-local-mongoose");
// "use strict";
const nodemailer = require("nodemailer");
var transporter = nodemailer.createTransport({
service: 'gmail',
auth: {
user: 'dataseedltd#gmail.com',
pass: 'mypassword'
}
});
/* GET users listing. */
router.get('/', function(req, res, next) {
res.send('respond with a resource');
});
router.get('/register/:type', function(req, res, next) {
res.render('user/register.ejs',{title:'Register',type:req.params.type});
});
router.get('/login', function(req, res, next) {
res.render('user/login.ejs', {title:'Login'});
});
router.post('/login',
passport.authenticate('local',{failureRedirect:'/users/login', failureFlash: 'Invalid username or password'}),
function(req, res) {
var previouspath=req.cookies.previouspath;
if(req.cookies.checklist==undefined){
req.flash('success', 'You are now logged in');
if(req.user.as=='seller'){
if(previouspath!=undefined){
if(previouspath.length!=0)
res.redirect(previouspath);
else
res.redirect('/buyer');
}
else
res.redirect('/buyer');
}
else {
if(previouspath!=undefined){
if(previouspath.length!=0)
res.redirect(previouspath);
else
res.redirect('/buyer');
}
else
res.redirect('/buyer');
}
}
else{
var ids=req.cookies.checklist['data']
var checks=[];
for(var i=0;i<ids.length;i++){
checks.push({user:req.user,data:ids[i]});
}
checklist.insertMany(checks,function(err, d) {
if(err)console.log(err);
res.clearCookie('checklist');
req.flash('success', 'You are now logged in');
if(req.user.as=='seller'){
if(previouspath.length!=0)
res.redirect(previouspath);
else
res.redirect('/seller')
}
else {
if(previouspath.length!=0)
res.redirect(previouspath);
else
res.redirect('/buyer')
}
});
}
});
passport.serializeUser(function(user, done) {
done(null, user.id);
});
passport.deserializeUser(function(id, done) {
User.getUserById(id, function(err, user) {
done(err, user);
});
});
passport.use(new LocalStrategy(function(username, password, done){
User.getUserByUsername(username, function(err, user){
if(err) throw err;
if(!user){
return done(null, false, {message: 'Unknown User'});
}
User.comparePassword(password, user.password, function(err, isMatch){
if(err) return done(err);
if(isMatch){
return done(null, user);
} else {
return done(null, false, {message:'Invalid Password'});
}
});
});
}));
router.post('/register/:type',function(req, res, next) {
var name = req.body.name;
var email = req.body.email;
var username = req.body.username;
var institution=req.body.institution;
var education=req.body.education;
var proffession=req.body.proffession;
var country=req.body.country;
//check if email does not already exists
//check if username does not already exists
User.find({ $or: [ { email: { $eq: req.body.email } }, { username: { $eq: req.body.username } } ] },function(err,data){
if(err)console.log(err);
if(data.length!=0){
console.log(data.length);
req.flash('success','email or username is repeated.');
res.redirect('/users/register/'+req.params.type);
}
else
{
var password = req.body.password;
var password2 = req.body.password2;
var as =req.params.type;
// Form Validator
req.checkBody('name','Name field is required').notEmpty();
req.checkBody('email','Email field is required').notEmpty();
req.checkBody('email','Email is not valid').isEmail();
req.checkBody('username','Username field is required').notEmpty();
req.checkBody('password','Password field is required').notEmpty();
// Check Errors
var errors = req.validationErrors();
if(errors){
res.render('user/register.ejs', {
errors: errors
});
} else{
var newUser = new User({
name: name,
email: email,
username: username,
password: password,
as :as,
institution:institution,
education:education,
proffession:proffession,
country:country
});
User.createUser(newUser, function(err, user){
if(err) throw err;
console.log(user);
});
// res.location('/');
var token=randomstring.generate(7);
var to=req.body.email;
var subject='Email Confirmation from dataSeed ';
var message='<h1>Use this code to register </h1><p>Your verification Code is: <h2>'+token+'</h2></p>';
var mailOptions=sendmail(to,subject,message);
transporter.sendMail(mailOptions, function(error, info){
if (error) {
console.log(error);
}
else
{
res.render('user/emailconfirmation.ejs',{username:req.body.username,token:token});
}
});
}
}
});
function sendmail(to,subject,message){
var mailOptions = {
from: 'dataseedltd#gmail.com',
to: to,
subject: subject,
html: message
};
return mailOptions;
}
router.post('/emailconfirmation/:token',function(req, res) {
if(req.params.token==req.body.token){
req.flash('success', 'You are now registered and can login');
res.redirect('/');
}
else{
User.remove({username:req.body.username},function(err,data){
if(err)console.log(err);
res.redirect('/');
});
}
});
});
router.get('/logout', function(req, res){
req.logout();
req.flash('success', 'You are now logged out');
res.redirect('/users/login');
});
//Forgot Password
router.get('/forgot',function(req,res){
res.render("forgotpassword.ejs");
});
router.post('/forgot', function(req, res, next) {
async.waterfall([
function(done) {
crypto.randomBytes(20, function(err, buf) {
var token = buf.toString('hex');
done(err, token);
});
},
function(token, done) {
User.findOne({ email: req.body.email }, function(err, user) {
if (!user) {
req.flash('success', 'No account with that email address exists.');
return res.redirect('/users/forgot');
}
user.resetPasswordToken = token;
user.resetPasswordExpires = Date.now() + 3600000; // 1 hour
user.save(function(err) {
done(err, token, user);
});
});
},
function(token, user, done) {
var smtpTransport = nodemailer.createTransport({
service: 'Gmail',
auth: {
user: 'dataseedltd#gmail.com',
pass: 'mypassword'
}
});
var mailOptions = {
to: user.email,
from: 'dataseedltd#gmail.com',
subject: 'Node.js Password Reset',
text: 'You are receiving this because you (or someone else) have requested the reset of the password for your account.\n\n' +
'Please click on the following link, or paste this into your browser to complete the process:\n\n' +
'http://' + req.headers.host + '/users/reset/' + token + '\n\n' +
'If you did not request this, please ignore this email and your password will remain unchanged.\n'
};
smtpTransport.sendMail(mailOptions, function(err) {
console.log('mail sent');
req.flash('success', 'An e-mail has been sent to ' + user.email + ' with further instructions.');
done(err, 'done');
});
}
], function(err) {
if (err) return next(err);
res.redirect('/users/forgot');
});
});
router.get('/reset/:token', function(req, res) {
User.findOne({ resetPasswordToken: req.params.token, resetPasswordExpires: { $gt: Date.now() } }, function(err, user) {
if (!user) {
req.flash('success', 'Password reset token is invalid or has expired.');
return res.redirect('/users/forgot');
}
res.render('reset', {token: req.params.token});
});
});
router.post('/reset/:token', function(req, res) {
async.waterfall([
function(done) {
User.findOne({ resetPasswordToken: req.params.token, resetPasswordExpires: { $gt: Date.now() } }, function(err, user) {
if (!user) {
req.flash('error', 'Password reset token is invalid or has expired.');
return res.redirect('back');
}
if(req.body.password === req.body.confirm) {
user.setPassword(req.body.password, function(err) {
user.resetPasswordToken = undefined;
user.resetPasswordExpires = undefined;
user.save(function(err) {
req.logIn(user, function(err) {
done(err, user);
});
});
})
} else {
req.flash("error", "Passwords do not match.");
return res.redirect('back');
}
});
},
function(user, done) {
var smtpTransport = nodemailer.createTransport({
service: 'Gmail',
auth: {
user: 'dataseedltd#gmail.com',
pass: 'mypassword'
}
});
var mailOptions = {
to: user.email,
from: 'dataseedltd#gmail.com',
subject: 'Your password has been changed',
text: 'Hello,\n\n' +
'This is a confirmation that the password for your account ' + user.email + ' has just been changed.\n'
};
smtpTransport.sendMail(mailOptions, function(err) {
req.flash('success', 'Success! Your password has been changed.');
done(err);
});
}
], function(err) {
res.redirect('/login');
});
});
module.exports = router;
users.js (model):
var mongoose = require('mongoose');
var bcrypt = require('bcryptjs');
var passportLocalMongoose=require("passport-local-mongoose");
mongoose.connect('mongodb://localhost/dataseed');
var db = mongoose.connection;
// User Schema
var UserSchema = mongoose.Schema({
username: {
type: String,
index: true
},
password: {
type: String
},
email: {
type: String
},
name: {
type: String
},
profileimage:{
type: String
},
as:{
type:String
},
institution:{
type:String
},
education:{
type:String
},
proffession:{
type:String
},
country:{
type:String
},
resetPasswordToken: String,
resetPasswordExpires: Date
});
var User = module.exports = mongoose.model('User', UserSchema);
module.exports.getUserById = function(id, callback){
User.findById(id, callback);
}
module.exports.getUserByUsername = function(username, callback){
var query = {username: username};
User.findOne(query, callback);
}
module.exports.comparePassword = function(candidatePassword, hash, callback){
bcrypt.compare(candidatePassword, hash, function(err, isMatch) {
callback(null, isMatch);
});
}
module.exports.createUser = function(newUser, callback){
bcrypt.genSalt(10, function(err, salt) {
bcrypt.hash(newUser.password, salt, function(err, hash) {
newUser.password = hash;
newUser.save(callback);
});
});
}
It seems like you don't have a method called setPassword defined under user model. This is mainly because you haven't plugin the passport-local-mongoose to UserSchema. Add UserSchema.plugin(passportLocalMongoose); before creating the model from UserSchema. like this
var mongoose = require('mongoose');
var bcrypt = require('bcryptjs');
var passportLocalMongoose=require("passport-local-mongoose");
mongoose.connect('mongodb://localhost/dataseed');
var db = mongoose.connection;
// User Schema
var UserSchema = mongoose.Schema({
username: {
type: String,
index: true
},
password: {
type: String
},
email: {
type: String
},
name: {
type: String
},
profileimage:{
type: String
},
as:{
type:String
},
institution:{
type:String
},
education:{
type:String
},
proffession:{
type:String
},
country:{
type:String
},
resetPasswordToken: String,
resetPasswordExpires: Date
});
UserSchema.plugin(passportLocalMongoose);
var User = module.exports = mongoose.model('User', UserSchema);