How do I pass data to different routes using Express? - node.js

I'm creating a web application that requires a user to register/login, and once they've done that, they're taken to their "account page" where their account information is available for them to see.
I'm using MongoDB, Mongoose, and Passport.
I have my post route:
app.post("/", function(req, res){
User.findOne({username: req.body.username}, function(err, foundUser){
if(foundUser){
//found user in database
const user = new User({
username: req.body.username,
password: req.body.password
});
req.login(user, function(err){
if(err){
console.log(err);
} else {
passport.authenticate("local", function(err, user){
if(err){
console.log(err);
} else {
if(user){
res.redirect("/user");
} else {
res.render("home", {failedAttempt: true});
}
}
})(req, res);
}
});
} else {
//user does not exist
console.log("the user does not exist here");
res.render("home", {failedAttempt: true})
}
});
});
I would like to be able to pass the database info for that particular user to the "/user" route, but I don't know how. How can I make it so that once the user is redirected to root/user, I can then pull up the info on their database?

You may want to look into Express Middleware. This allows you to do some processing first to pull out the user info and then pass the resulting data to your route.
Read all about it:
https://expressjs.com/en/guide/using-middleware.html

Related

passport.authenticate() is always executing failureRedirect after saving the user information in mongoDB

I'm a beginner to nodejs and tying to apply authentication using passport, passport-local-mongoose. I have a register page where user can enter mail id and password and click on register button.
when user makes a post request by clicking on that button, I want to store the mailid and hash(generated using User.register method from lpassport-local-mongoose) in mongoDB.
I'm doing that using passportlocal-mongoose and then wanted to authenticate the user if there are no errors in creating the user.
app.post("/register", function(req, res){
const username = req.body.mailbox;
User.register({username: username}, req.body.passwordbox, function(err, user){
if(err){
console.log(err);
}
else{
passport.authenticate("local", successRedirect: "/secrets", failureRedirect: "/register")(req, res);
}
})
});
Based on your provided context, you can try this code:
app.post("/register", function(req,res){
const username = req.body.mailid
User.register({username:username}, req.body.password, function(err, user){
if(!err){
passport.authenticate("local")(req, res, function(){
res.redirect("/secrets");
});
}
else {
res.redirect("/register");
}
});
});
following code using the passport.authenticate() method to authenticate the user, and providing a callback function to redirect to the secrets page if authentication is successful. If an error occurs during user creation, we redirect to the registration page.

User Registration using Mongo and NodeJs not working

i have made a usewr registration login in react and node . My signup route is working and user is saved in mongo , but signin route is not working ?
SignIn Component:-
signIn(){
axios.post('/tasks/signin', {
email: this.state.email,
password: this.state.password,
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
}
Routes are:-
Router.post('/signin', (req, res) => {
var User = new db1();
User.findOne({ email: req.body.email , password: req.body.password
}, function(err, user) {
console.log(user);
if(err) return next(err);
if(!user) return res.send('Not logged in!');
return res.send('Logged In!');
});
});
Error:
User.findOne is not a functionand i am getting 500 status.
Please help where am i wrong .
The findOne method is on the model, not the object. So it should be:
db1.findOne({ email: req.body.email , password: req.body.password
See previous question.
It seems to me that you require the model and assign it to a variable call db1 and create an instance called User. After that, you call the findOne method of the instance instead of the model itself.
If you are using Mongoose, this should be the problem. If not, please give some more details.
Also, it is usually a good practice to call your classes with PascalCase and your instances with camelCase. This way you won't get confused.

Node.js - Check if user exists

I'm using NodeJS and passport to let users create an account before they can see results of a quiz they've just taken. My challenge is I need to confirm the username is available before the page refreshes because the user will lose their results if this happens.
Again: I need to verify the username is not taken prior to refreshing.
I think I'm close but it is not working. How would I change my code to handle this challenge?
Currently if the user name is taken it returns an error on trying to create an account and the user ends up on the /failpage as shown below.
app.post('/quiz', usernameToLowerCase, emailToLowerCase, function(req, res) {
User.findOne({
username: req.body.username
}, function(err, user) {
if (err) {
alert(err)
if (user) {
alert('this username is already taken. Please choose another.')
console.log('there was a user');
return false;
}
}
});
var user = new User({
username: req.body.username,
email: req.body.email,
password: req.body.password,
})
user.save(function(err) {
console.log('this is the problem' + ' ' + err)
if (err) {
return res.redirect('/failpage')
}
req.logIn(user, function(err) {
if (err) {
console.log(err);
}
console.log('all looks good')
res.redirect('/results');
});
});
});
Solved it with this if anyone else is trying to do the same thing:
in app.js
app.get('/usercheck', function(req, res) {
User.findOne({username: req.query.username}, function(err, user){
if(err) {
console.log(err);
}
var message;
if(user) {
console.log(user)
message = "user exists";
console.log(message)
} else {
message= "user doesn't exist";
console.log(message)
}
res.json({message: message});
});
});
In js
$('#usercheck').on('change', function() {
$.get('/usercheck?username='+$('#usernameValue').val().toLowerCase(), function(response) {
$('#usernameResponseHidden').text(response.message)
if ($('#usernameResponseHidden').html() === "user exists"){
$('#usernameResponse').text('That username is taken. Please pick another')
}
To solve your problem I think you need to routes. At least a app.get('/quiz') which returns a boolean on if the user exists or not. The section User.findOne can be sent in that route instead. You just need to make a request using ajax when he looses focus of the username field of your form, and display a notification if the name is available or not.

Calling and Saving User Account Custom Data

I'm making a user account system for my new website using node.sdk,stormpath,express.js and passport.js . So I've set up an account with a custom data slot. I would like to know how can I post new data to this custom data slot when they log out and retrieve it when they log in.I'm new to using node and I don't know where to put my code or how to access the 'user' account info when they have logged in. From what I can tell passport.js is handling authentication so I probably can't see the users email to search for their user account url on the stormpath api... maybe I'm missing something here??
router.post('/register', function(req, res) {
var username = req.body.username; var password = req.body.password;
// Grab user fields. if (!username || !password) { return res.render('register', { title: 'Register', error: 'Email and password required.' }); }
// Initialize our Stormpath client. var apiKey = new stormpath.ApiKey( process.env['STORMPATH_API_KEY_ID'], process.env['STORMPATH_API_KEY_SECRET'] ); var spClient = new stormpath.Client({ apiKey: apiKey });
var app = spClient.getApplication(process.env['STORMPATH_APP_HREF'], function(err, app) { if (err) throw err;
account = {
givenName: 'John',
surname: 'Smith',
username: username,
email: username,
password: password,
customData:{
favList:'',
},
};
app.createAccount(account, function (err, createdAccount) {
if (err) {
return res.render('register', {'title': 'Register', error: err.userMessage });
} else {
passport.authenticate('stormpath')(req, res, function () {
return res.redirect('/home');
});
}
});
});
});
// Render the login page. router.get('/login', function(req, res) {
res.render('login', { title: 'Login', error: req.flash('error')[0] }); });
// Authenticate a user. router.post( '/login',
passport.authenticate( 'stormpath', { successRedirect: '/home', failureRedirect: '/login', failureFlash: 'Oops I guess you need an account to get in here..Soz', } ) );
// Render the dashboard page. router.get('/home', function (req, res) { if (!req.user || req.user.status !== 'ENABLED') { return res.redirect('/login'); }
res.render('home', { title: 'Home', user: req.user, } ); });
This is a great question. Thankfully the Passport API has you covered. You want to use a "Custom Callback" function, then you can get access to the user inside of that function. In the case of the Stormpath strategy the user object will be a Stormpath Account instance. However you will need to re-implement some of the redirection logic that you're currently passing in as options. Here is an example of how that would look with the Stormpath strategy:
app.post('/login', function(req, res, next) {
passport.authenticate('stormpath', function(err, user, info) {
if (err) {
return next(err);
}
else if (user) {
console.log('The account is: ', user);
req.logIn(user, function(err) {
if (err) {
next(err);
}else{
res.redirect('/dashboard');
}
});
}else{
req.flash('error',info.message);
res.redirect('/login');
}
})(req, res, next);
});
The docs for this custom strategy can be found here: http://passportjs.org/guide/authenticate/
Another note: I'd suggest creating your spClient outside of the route handler. The Stormpath Client can be used for multiple requests and only needs to be created once per process.

Getting out of sync server response

On a successful signup of a user I am currently seeing a mostly empty page with the text undefined. Redirecting to /app at the top.
UPDATE: I should also mention that after form submittal I am redirected to /users. So on /users I see the text mentioned above.
I think it is because of the req.redirect call being within the user.save callback but I am not sure what the fix is.
I am using mongoose for the ORM.
var User = require('../models/user');
module.exports = function(app) {
app.post('/users', function(req, res, next) {
var user = new User({
email: req.body.email,
password: req.body.password
});
user.save(function(err) {
if (err)
res.send(412, {message: err});
else
req.login(user, function(err) {
if (err !== undefined) return next(err);
res.redirect('/app', {
email: user.email,
id: user._id
});
});
});
});
};
It turns out that the req.login call has to be contained in a password.authenticate callback. The example on the site left that part out.
user.save(function(err) {
if (err)
res.send(412, {message: err});
else
passport.authenticate('local', function(err, user) {
if (err) { return next(err) }
if (!user) { return res.redirect('/login') }
req.login(user, function(err) {
if (err) { return next(err); }
return res.redirect('/app', { email:user.email, id:user._id });
});
})(req, res, next);
});

Resources