How to set an admin password with passport node - node.js

This website is only going to have admin users, I have created the schema, the registration view and the route, however something is bad with the logic in the route.
/register page only have three inputs, username, password and email address. At the moment, if the user uses any random password to enter, is showing a flash error saying the password is not valid and redirecting me to the landing page, however, it is still creating the new user in the database.
Also, if the user uses the right password same thing as above is happening.
What am I doing wrong?
here is my code:
Schema
var UserSchema = new mongoose.Schema({
username: {
type: String,
unique: true,
required: true
},
password: {
type: String
},
email: {
type: String,
unique: true,
required: true,
lowercase: true,
},
resetPasswordToken: String,
resetPasswordExpires: Date,
// isAdmin: {type: Boolean, default: false, required:true}
});
Register view
<form class="form-group" action="/register" method="POST">
<div class="form-group">
<input class="form-control mb-1" type="text" name="username">
</div>
<div class="form-group">
<input class="form-control mb-3" type="password" name="password">
</div>
<div class="form-group">
<input class="form-control" type="email" name="email">
</div>
<button class="btn btn-outline-info w-100">Register!</button>
</form>
Route
// register route
router.get("/register", function(req, res) {
res.render("register", {page: "register"});
});
// handle sign up logic
router.post("/register", function(req, res){
var newUser = new User({
username: req.body.username,
email: req.body.email
});
User.register(newUser, req.body.password, function(err, user){
if(err){
console.log(err);
return res.render("register", {error: err.message});
} else {
if(req.body.password !== process.env.ADMIN_CODE) {
req.flash('error', 'the password is not valid');
res.redirect("/");
} else {
passport.authenticate("local")(req, res, function(){
req.flash("success", "Great! Welcome! " + req.body.username);
res.redirect("/");
});
}
}
});
});

Related

how to fix this error ""name":"ValidatorError","message":"Path `Name` is required.""

I am trying to fetch data from client side when i make a post request I get this error , I am new to the mongoDB and Node.js please help
I don't understand this error that why this is coming please help to resolve it
this is my schema code
`
import mongoose from "mongoose";
const signupTemplate = mongoose.Schema({
Name: {
type: String,
required: true,
},
Phone: {
type: Number,
required: true,
},
Email: {
type: String,
required: true,
},
Password: {
type: String,
required: true,
},
date: {
type: Date,
Default: Date.now,
},
});
export default mongoose.model("users", signupTemplate);
`
this is my router code
`
router.post("/signup", (req, res) => {
const signedUpUser = new signUpTemplate({
Name: req.body.Name,
Phone: req.body.Phone,
Email: req.body.Email,
Password: req.body.Password,
});
console.log(req.body.Name);
signedUpUser
.save()
.then((data) => {
res.json(data);
})
.catch((err) => {
res.json(err);
// console.log('you made an error');
});
// res.send("User Registered successfully");
});
`
this is my form code
`
<form action="/signup" method="post">
<label for="Name">Full Name</label>
<input type="text" class="form-control" id="Name" name="Name" />
<label for="Phoneno">Phone No.</label>
<input type="text" class="form-control"id="Phoneno" name="Phone" />
<label for="Email">Email</label>
<input type="email" class="form-control"id="Email" name="Email" />
<label for="create-password">Create Password</label>
<input type="password" class="form-control"id="create-password" name="Password" />
<label for="confirm-password">Confirm Password</label>
<input type="password" class="form-control"id="confirm-password" name=" Confirm-password" />
<button type="submit" class="btn">Sign Up</button>
<hr>
<p style="display:inline;">Or continue with</p>
<i class="fa-brands fa-google"></i>
<i class="fa-brands fa-facebook"></i>
<i class="fa-brands fa-instagram"></i>
</form>
`
Hey do you have the express urlencoded middleware in your index.js or server.js and if not add this line of code
app.use(express.urlencoded({ extended: true }));

Update user profile page using mongoose express js

I am working on personal project. one of common functionality i am implementing is allowing users to update their profile but having hard time doing it.
here is what i did so far
form
<form
action="/users/doctor-profile?_method=PUT"
method="POST"
enctype="multipart/form-data"
>
<input type="hidden" name="_method" value="PUT" />
<div class="form-group">
<input
type="text"
class="form-control"
id="name"
name="name"
/>
</div>
<div class="form-group">
<label for="phone">Phone</label>
<input
type="tel"
class="form-control"
id="formGroupExampleInput"
name="phone"
/>
</div>
<div class="form-group">
<label for="exampleInputEmail1">Email</label>
<input
type="email"
class="form-control"
id="formGroupExampleInput"
name="email"
/>
</div>
<button type="submit" class="btn btn-primary">Save changes</button>
</form>
here is my user model
const mongoose = require("mongoose");
const UserSchema = new mongoose.Schema({
name: {
type: String,
required: true,
},
email: {
type: String,
required: true,
},
password: {
type: String,
required: true,
},
phone: {
type: String,
required: true,
},
});
const User = mongoose.model("User", UserSchema);
module.exports = User;
here is my post route
router.post("/users/doctor-profile", (req, res) => {
const { name, email,phone } = req.body;
const _id = ObjectId(req.session.passport.user._id);
console.log(_id)
USer.findOne({ _id: _id })
.then((user) => {
if (!user) {
req.flash("error_msg", "user not found");
res.redirect("/users/doctor-profile");
}
if (typeof name !== "undefined") {
user.name = name;
console.log(user.name);
}
if (typeof email !== "undefined") {
user.email = email;
}
if (typeof phone !== "undefined") {
user.phone = phone;
}
user.save().then((User) => {
req.flash("success_msg", "details updated successfully");
res.redirect("/users/profile");
});
})
.catch((err) => console.log(err));
});
console output
application running on port 5000
mongodb connection successfull
5ef5bc20261beb1e6c1c25a3
but it does not update fields in database.
try this:
user.save(function (err, resolve) {
if(err)
console.log('db error', err)
// saved!
});
You had a typo in your post route js file
here is the code you got the typo on:
USer.findOne({ _id: _id })
USer should be User

Form validation with flash messages in express js

I am trying to validate a form in express js before i post it onto the mongodb which i am using as a backend. My user.js for registration page looks something like this -
router.post('/register', (req, res) => {
userreg.register(
// eslint-disable-next-line new-cap
new userreg({
firstname: req.body.firstname,
lastname: req.body.lastname,
username: req.body.email,
usn: req.body.usn, // validate so that no space is taken or else request modal wont work
course: req.body.course,
}),
req.body.password,
(err) => {
if (err) {
console.log(err);
res.render('register', { user: 'error' });
} else {
console.log('no error');
res.render('submit-success', { username: req.body.firstname });
}
}
);
});
and my register.ejs looks something like this -
<form class="user" action = '/users/register' method="POST">
<div class="form-group row">
<div class="col-sm-6 mb-3 mb-sm-0">
<input type="text" class="form-control form-control-user" id="exampleFirstName" name="firstname" placeholder="First Name">
</div>
<div class="col-sm-6">
<input type="text" class="form-control form-control-user" id="exampleLastName" name="lastname" placeholder="Last Name">
</div>
</div>
<div class="form-group">
<input type="email" class="form-control form-control-user" id="exampleInputEmail" name="email" placeholder="Email Address">
</div>
<div class="form-group">
<input type="text" class="form-control form-control-user" id="exampleInputUSN" name="usn" placeholder="USN">
</div>
<div class="form-group">
<select class=" form-control selectpicker" name="course">
<optgroup label="Course"></optgroup>
<option selected hidden disabled>Course</option>
<option value="mca">Computer Applications</option>
<option value="mba">Business Administration</option>
</optgroup>
</select>
</div>
<div class="form-group">
<input type="password" class="form-control form-control-user" id="exampleInputPassword" name="password" placeholder="Password">
</div>
<div class="text-center">
<input type="submit" class = "btn btn-primary btn-user" value="Register">
</div>
</form>
By going through many sources on the internet(since i'm very very new to express js and im doing it as a part of my college project and since i can't consult any teachers for assistance during lockdown times) , I got to know that the validation part has to be implemented in user.js. Please help me with the code for validation and also displaying flash messages if field empty for atleast one field so that i can have a start atleast.
Thank you in advance
EDIT :
I Used the express-validator and ended up with the following changes -
var flash = require('connect-flash');
var app = express();
app.configure(function () {
app.use(express.cookieParser('keyboard cat'));
app.use(express.session({ cookie: { maxAge: 60000 } }));
app.use(flash());
});
app.get('/flash', function (req, res) {
// Set a flash message by passing the key, followed by the value, to
req.flash().
req.flash('info', 'There is an Error!')
res.redirect('/');
});
app.get('/', function (req, res) {
// Get an array of flash messages by passing the key to req.flash()
res.render('index', { messages: req.flash('info') });
});
const { check, validationResult } = require('express-validator');
router.post('/register', [
check('firstname', 'Please enter your first
name').exists().trim().escape().not().isEmpty(),
check('lastname', 'Please enter your last
name').exists().trim().not().isEmpty(),
check('username', 'Please enter an
email').exists().trim().not().isEmpty(),
check('usn', 'Please enter USN').exists().trim().not().isEmpty(),
check('course', 'Please enter Course').exists().trim().not().isEmpty(),
check('password', 'Please enter
password').exists().trim().not().isEmpty(),
], (req, res) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
req.flash('message', `${errors}`);
res.redirect('/users/register');
} else {
userreg.register(
// eslint-disable-next-line new-cap
new userreg({
firstname: req.body.firstname,
lastname: req.body.lastname,
username: req.body.email,
usn: req.body.usn, // validate so that no space is taken or else
request modal wont work
course: req.body.course,
})),
res.render('submit-success', { username: req.body.firstname });
}
}
);
And as a result , the if (!errors.isEmpty()) is being invoked but there is no flash message being displayed. Am i missing something else ?
I am assuming you are using connect-flash.
const { check, validationResult } = require('express-validator');
router.post('/register', [
check('firstname', 'Please enter your first name').exists().trim().escape().not().isEmpty(),
check('lastname', 'Please enter your last name').exists().trim().not().isEmpty(),
check('email', 'Please enter an email').exists().trim().not().isEmpty(),
// ...
], (req, res) => {
const errors = validationResult(req);
if (!errors.isEmpty()) {
req.flash('message', `${errors}`);
res.redirect('register');
}
else {
// your code here!
}
});
You might want to consider creating middleware to handle validation errors, to make your code cleaner.

System validation failed - Node / Express / Mongoose

When I submit my form I get the following error: Error [ValidationError]: System validation failed: lastName: Path lastName is required., firstName: Path firstName is required.
I'm not sure what's causing this, when I console.log(formData) I get the data I submitted into the form.
App.js
const express = require('express')
const app = express();
const mongoose = require('mongoose');
const dotenv = require ('dotenv/config');
const System = require('./models/System');
app.use(express.urlencoded({ extended: true }));
app.use(express.json());
app.get('/', (req,res) => {
res.render('index.ejs');
});
app.post('/post-feedback', (req, res) => {
const formData = {
firstame: req.body.firstName,
lastname: req.body.lastName,
assetTag: req.body.assetTag
}
const system = new System(formData);
system.save()
.then(result => {
console.log(result);
})
.catch(err => {
console.log(err);
});
});
Model:
const mongoose = require('mongoose');
var SystemSchema = new mongoose.Schema({
firstName: {
type: String,
required: true
},
lastName: {
type: String,
required: true
},
assetTag: {
type: Number,
required: true
}
});
module.exports = mongoose.model('System', SystemSchema);
Form:
<form action="/post-feedback" method="POST">
<div class="form-group">
<label for="firstName">First Name: </label>
<input type="text" class="form-control" id="firstName" name="firstName">
</div>
<div class="form-group">
<label for="lastName">Last Name: </label>
<input type="text" class="form-control" id="lastName" name="lastName">
</div>
<div class="form-group">
<label for="assetNum">Asset Tag: </label>
<input type="text" class="form-control" id="assetTag" name="assetTag">
</div>
<button type="submit" name="submit" class="btn btn-primary">Submit</button>
</form>
The only one reason why you got some error it's because you're typo on your formData. It must be firstName and lastName, make sure it same with your Schema field and then Make Sure your assetTag is a number, because your Schema type is number.
You can try with this code below:
app.post('/post-feedback', (req, res) => {
const formData = {
// you're typo here: firstame
firstName: req.body.firstName,
// you're typo here: lastname
lastName: req.body.lastName,
// must be number
assetTag: parseInt(req.body.assetTag);
}
const system = new System(formData);
system.save()
.then(result => {
console.log(result);
})
.catch(err => {
console.log(err);
});
});
I hope it can help you.
app.post('/post-feedback', (req, res) => {
const system = new System(req.body);
system.save()
.then(result => {
console.log(result);
})
.catch(err => {
console.log(err);
});
});
i think above code should be work.

Passport local auth plus passport mongoose local are not accepting email as username

I am using passport local strategy and passport mongoose local to create a user and check user authentication. However, I wanted to explore the option using email instead of username. I followed what the document says and I am getting unauthorized. Can someone tell me why I am getting an error, and it works if I just use the username as login.
From passport-local-mongoose
Note: usernameField: specifies the field name that holds the username. Defaults to 'username'. This option can be used if you want to use a different field to hold the username for example "email".
And from passport local strategy
By default, LocalStrategy expects to find credentials in parameters named username and password. If your site prefers to name these fields differently, options are available to change the defaults.
I have tried to set both true at the same time and I also have tried to set one true and another one off. I will get the same error
express 4.16.0
express-session 1.15.6
mongoose 5.1.2
passport 0.40
passport local 1.0.0
passport local mongoose 5.0.0
passport.js
module.exports = function (passport, LocalStrategy, User) {
passport.use(new LocalStrategy({
usernameField: 'email',
passwordField: 'password',
passReqToCallback: true,
session: true
},
function(req, username, password, done) {
return done(null, req.user);
}
));
passport.serializeUser(User.serializeUser());
passport.deserializeUser(User.deserializeUser());
};
model/User.js
var UserSchema = new mongoose.Schema({
name: { type: String, required: true, default: ''},
username: { type: String, unique: true, uniqueCaseInsensitive: true, required: true, default: ''},
email: { type: String, required: true, unique: true, uniqueCaseInsensitive: true, default: ''},
profileImage:{ type: String, default: ''},
timestamp: {type: String, default: () => moment().format("dddd, MMMM Do YYYY, h:mm:ss a") }
});
UserSchema.plugin(passportLocalMongoose, {usernameField: 'email'});
UserSchema.plugin(uniqueValidator);
module.exports = mongoose.model('UserSchema', UserSchema);
signinForm.js
<form class="form-signin" action="/users/signup" method="POST" enctype='multipart/form-data'>
<h1 class="h3 mb-3 font-weight-normal">Please sign up</h1>
<label for="inputName" class="sr-only">Name</label>
<input type="bane" id="inputName" class="form-control" placeholder="Name" name='name' required autofocus />
<label for="inputUsername" class="sr-only">Username</label>
<input type="bane" id="inputUsername" class="form-control" placeholder="Username" name='username' required autofocus />
<label for="inputEmail" class="sr-only">Email</label>
<input type="email" id="inputEmail" class="form-control" placeholder="Email" name='email' required autofocus />
<label for="inputPassword" class="sr-only">Password</label>
<input type="password" id="inputPassword" class="form-control" placeholder="Password" name='password' required autofocus/>
<label for="inputConfirmPassword" class="sr-only">Confirm Password</label>
<input type="password" id="inputConfirmPassword" class="form-control" placeholder="Confirm Password" name='confirmPassword' required autofocus/>
<input type='file' class='form-control' id='inputFile' name='profileImage' />
<div style="height: 10px"></div>
<button class="btn btn-lg btn-primary btn-block" type="submit">Sign in</button>
<p class="mt-5 mb-3 text-muted">© 2017-2018</p>
</form>
routes/users.js
router.post('/signup', upload.single('profileImage'), function(req, res, next) {
const name = req.body.name;
const email = req.body.email;
const password = req.body.password;
const confirmPassword = req.body.confirmPassword;
if (req.file) {
console.log('Uploading File...');
var profileImage = req.file.filename;
} else {
console.log('No File Uploaded... Setting to no image');
var profileImage = 'noimage.jpg';
}
UserController.createUser(req.body, function(err, user) {
if (err) {
res.json({
err: err
});
return;
}
passport.authenticate('local')(req, res, function() {
//res.render('index', {currentUser: user, title: 'Product Page' });
res.redirect('/');
return;
});
return;
})
});
I ended up getting authorized and 401
Thanks in advance.
Try to remove the 'return' at the end of UserController.createUser(), you need to wait for the result of passport.authenticate()

Resources