New code for routes.js and login.ejs:
`module.exports = function(app, passport) {
// =====================================
// HOME PAGE (with login links) ========
// =====================================
app.get('/', function(req, res) {
res.render('./pages/index.ejs'); // load the index.ejs file
});
// =====================================
// LOGIN ===============================
// =====================================
app.get('/login', function(req, res) {
// render the page and pass in any flash data if it exists
res.render('./pages/login.ejs', { message: req.flash('error') });
});
// process the login form
app.post('/login', passport.authenticate('local-login', {
successRedirect : '/profile', // redirect to the secure profile section
failureRedirect : '/login', // redirect back to the signup page if there is an error
failureFlash : true
}));
// =====================================
// SIGNUP ==============================
// =====================================
app.get('/signup', function(req, res) {
// render the page and pass in any flash data if it exists
res.render('./pages/signup.ejs', { message: req.flash('signupMessage') });
});
// process the signup form
app.post('/signup', passport.authenticate('local-signup', {
successRedirect : '/profile', // redirect to the secure profile section
failureRedirect : '/signup', // redirect back to the signup page if there is an error
failureFlash : true // allow flash messages
}));
// =====================================
// PROFILE SECTION =========================
// =====================================
// we will want this protected so you have to be logged in to visit
// we will use route middleware to verify this (the isLoggedIn function)
app.get('/profile/:id', isLoggedIn, function (req, res) {
var id = req.params.id;
res.send('./pages/profile.ejs' + req.params.id);
});
// =====================================
// LOGOUT ==============================
// =====================================
app.get('/logout', function(req, res) {
req.logout();
res.redirect('/');
});
// =====================================
// UPLOAD ==============================
// =====================================
app.get('/upload', function (req, res){
res.render('./pages/upload.ejs');
});
// =====================================
// PASSWORD RESET ======================
// =====================================
app.get('/forgot', isLoggedIn, function (req, res){
res.render('./pages/forgot.ejs');
});
app.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('error', 'No account with that email address exists.');
return res.redirect('/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('SMTP', {
service: 'SendGrid',
auth: {
user: '!!! YOUR SENDGRID USERNAME !!!',
pass: '!!! YOUR SENDGRID PASSWORD !!!'
}
});
var mailOptions = {
to: user.email,
from: 'passwordreset#demo.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 + '/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) {
req.flash('info', 'An e-mail has been sent to ' + user.email + ' with further instructions.');
done(err, 'done');
});
}
], function(err) {
if (err) return next(err);
res.redirect('/forgot');
});
});
};
// route middleware to make sure
function isLoggedIn(req, res, next) {
// if user is authenticated in the session, carry on
if(req.isAuthenticated()){
return next();
}
// if they aren't redirect them to the home page
else{
res.redirect('/');
}
}`
And the view (login.ejs):
`<!DOCTYPE html>
<html>
<head>
<% include ../partials/head %>
</head>
<body>
<div class="container">
<div class="col-sm-6 col-sm-offset-3">
<h1><span class="fa fa-sign-in"></span>Login</h1>
<% if(message.length > 0){ %>
<div class="alert alert-danger"><%= message %></div>
<% } %>
<!-- LOGIN FORM -->
<form action="/login" method="post">
<div class="form-group">
<label>Email</label>
<input type="text" class="form-control" name="email">
</div>
<div class="form-group">
<label>Password</label>
<input type="password" class="form-control" name="password">
</div>
<button type="submit" class="btn btn-warning btn-lg">Login</button>
</form>
<hr>
<p>Need an account? Signup</p>
<p>Forgot your or password? Forgot</p>
</div>
</div>
</body>
</html>`
I could also have it like = http://localhost:8080/profile/emailAddress.
The emailAddress is given when signing up for my website.
The emailAddress is stored in my database that I set up.
app.get('/profile', isLoggedIn, function (req, res) {
// store userId on login into session or any global variable
var userId = req.session.userId
res.redirect('/profile/'+userId)
}); // =>directs to http://localhost:8080/profile for every signup.
Create new route with addition param
app.get('/profile/:id', function (req, res) {
var id = req.params.id
res.render('./pages/profile.ejs', {user: id});
})
You should use request parameters. With express you can do the following:
app.get('/profile/:id', isLoggedIn, function (req, res) {
var id = req.params.id;
//do with id whatever you want
res.render('./pages/profile.ejs', {user: req.user});
});
In your isLoggedIn middleware you will have something like this:
function(req, res, next) {
if (isLoggedIn) { //check if the user is logged in
req.user = user; //fetch the user from the DB or wherever you have it
}
}
In your view you will use the user's id to build the url:
<%=user.name%>
Related
[isLoggedin Middleware]
[Routes]
[login route and trying to authenticate using passport.js]
module.exports.isLoggedin = (req, res, next) => {
if (req.isAuthenticated()) {
return next();
} else {
// store the url the users are requesting
req.session.returnTo = req.originalUrl;
req.flash('error', 'You must be signed in first!')
req.session.save(function (err) {
return res.redirect("/login");
})
}
}
router.get('/login', (req, res) => {
res.render('users/login')
})
router.post('/login', passport.authenticate('local', {
failureFlash: true,
failureRedirect: '/login'
}), (req, res) => {
console.log(req.session.returnTo);
req.flash('success', 'Welcome back!');
res.redirect(req.session.returnTo || '/campgrounds');
})
router.get('/:id/edit', isLoggedin, catchAsync(async (req, res) => {
const campground = await Campground.findById(req.params.id);
if (!campground) {
req.flash('error', 'Cannot find that campground!')
return res.redirect('/campgrounds')
}
res.render('campgrounds/edit', { campground });
}))
I added in a middleware called isLoggedIn and I saved req.session.returnTo = req.originalUrl; and I passed in this middleware to 2 routes (get('/:id/edit'). This middleware should be triggered if I accessed the route.
I was meant to Redirect to the previous page after authentication using passport.js, but after I logged in, req.session.returnTo was shown as undefined...
req.session.returnTo should've been req.originalUrl but after I logged in and tried to redirect to the previous page, it turned out to be undefined and I've been struggling with this...
Now These routes below function properly when I hit them directly but when I am redirecting a user them from a page to these routes the authentication is never successful instead I am redirected back to the route '/auth/openidconnect/undefined'.
Moreover Something that I found really weird was that after trying at least 2 more times (redirecting the user to the auth route from the above mentioned page) I get successfully authenticated.
router.get('/auth/openidconnect',oidcSettings, oidcProviderReq);
router.get('/auth/openidconnect/callback',oidcSettings, oidcCallback);
let oidcSettings = function (req, res, next) {
//provider contains all the required data
var OidcStrategy = require('passport-openidconnect').Strategy;
passport.use('oidc', new OidcStrategy({
issuer: provider.settings.issuer,
authorizationURL: provider.settings.authorizationURL,
tokenURL: provider.settings.tokenURL,
userInfoURL: provider.settings.userInfoURL,
clientID: provider.settings.ClientID,
clientSecret: provider.settings.clientSecret,
callbackURL: provider.settings.callbackURL,
scope: 'openid profile'
}, (issuer, sub, profile, accessToken, refreshToken, done) => {
if (!(profile && profile._json && profile._json.email)) {
return done(null, false);
}
req.params.provider =profile.id
oidcLogin(req, profile, 'oidc_user', done); //basically either logs into the application or creates a new user
}));
next();
}
let oidcProviderReq = function(req, res, next){
passport.authenticate('oidc', {scope: 'openid profile'})(req, res, next);
}
let oidcCallback = function(req, res, next){
passport.authenticate('oidc', function (err, user, info) {
if(err) throw err;
console.log(user)
})(req, res, next);
}
```
I am trying to render a view after a login validation form has created a session after successful credentials have been entered.
This view must only be accessible after the login procedure, but when I type in the url (127.0.0.1:3000/newsfeed) the 'newsfeed' page is loaded and bypasses the login. I understand that this could be an issue related to routes but I can not get it to work.
//session
app.use(session({
secret: 'secret',
resave: true,
saveUninitialized: true
}))
app.use(bodyParser.urlencoded({extended : true}));
app.use(bodyParser.json());
app.get('/', function(request, response) {
response.sendFile(path.join(__dirname + '/'));
});
// Checking credentials
app.post('/auth', function(request, response) {
var username = request.body.username;
var password = request.body.password;
if (username && password) {
connection.query('SELECT * FROM accounts WHERE username = ? AND password
= ?', [username, password], function(error, results, fields) {
if (results.length > 0) {
request.session.loggedin = true;
request.session.username = username;
response.redirect('authres');
} else {
response.send('Incorrect Username and/or Password!');
}
response.end();
});
} else {
response.send('Please enter Username and Password!');
response.end();
}
});
//**Would like page to appear here instead of text**
app.get('/authres', function(request, response) {
if (request.session.loggedin) {
response.send('Welcome back, ' + request.session.username + '!');
} else {
response.send('Please login to view this page!');
}
response.end();
});
Methods in app.js
//uses routes
app.use('/', indexRouter);
app.use('/users', usersRouter);
app.use('/newsfeed', newsfeedRouter);
index.js route for the log in
router.get('/', function(req, res, next) {
res.render('index');
});
newsfeed.js route for newsfeed page
router.get('/', function(req, res, next) {
res.render('newsfeed');
});
router.get('/', function(req, res, next) {
res.render(req.session.loggedin?"newsfeed":"index");
});
If the user is logged in this will render the newsfeed view.
So i am trying to allow users to upload a profile image for there profile and i got the form kinda how i want it for now but i keep running into an error saying TypeError: Cannot read property 'profilePicUpload' of undefined
even though i am almost certain that all of my code is fine here is the routes.js
// app/routes.js
var mysql = require('mysql');
var dbconfig = require('../config/database');
var connection = mysql.createConnection(dbconfig.connection);
const fileUpload = require('express-fileupload');
module.exports = function(app, passport) {
app.get('/logout', function(req, res) {
req.logout();
res.redirect('/');
});
// =====================================
// HOME PAGE (with login links) ========
// =====================================
app.get('/', function(req, res) {
res.render('login.ejs', { message: req.flash('loginMessage') }); // load the index.ejs file
});
// =====================================
// LOGIN ===============================
// =====================================
// show the login form
app.get('/login', function(req, res) {
// render the page and pass in any flash data if it exists
res.render('login.ejs', { message: req.flash('loginMessage') });
});
app.use(fileUpload());
app.post('/upload', function(req, res) {
console.log(req.files.profilePicUpload);
});
passport.serializeUser(function(user, done) {
done(null, user.id);
});
passport.deserializeUser(function(id, done) {
User.findById(id, function(err, user) {
done(err, user);
});
});
// process the login form
app.post('/login', passport.authenticate('local-login', {
successRedirect: '/mainchat', // redirect to the secure profile section
failureRedirect: '/login', // redirect back to the signup page if there is an error
failureFlash: true // allow flash messages
}),
function(req, res) {
console.log("hello");
if (req.body.remember) {
req.session.cookie.maxAge = 1000 * 60 * 3;
} else {
req.session.cookie.expires = false;
}
res.redirect('/');
});
// =====================================
// SIGNUP ==============================
// =====================================
// show the signup form
app.get('/signup', function(req, res) {
// render the page and pass in any flash data if it exists
res.render('signup.ejs', { message: req.flash('signupMessage') });
});
// process the signup form
app.post('/signup', passport.authenticate('local-signup', {
successRedirect: '/mainchat', // redirect to the secure profile section
failureRedirect: '/signup', // redirect back to the signup page if there is an error
failureFlash: true // allow flash messages
}));
// =====================================
// PROFILE SECTION =========================
// =====================================
// we will want this protected so you have to be logged in to visit
// we will use route middleware to verify this (the isLoggedIn function)
app.get('/profile', isLoggedIn, function(req, res) {
var aboutUser = connection.query("SELECT about FROM users WHERE username = ?", req.user, function(err, rows) {
res.render('profile.ejs', {
user: req.user,
about: rows
});
});
});
app.get('/mainchat', isLoggedIn, function(req, res) {
var username = req.user.displayName;
res.render('mainchat.ejs', username);
console.log(req.user.displayName)
});
// =====================================
// LOGOUT ============================= rows.forEach(function(row) {=
// =====================================
app.get('/logout', function(req, res) {
req.logout();
res.redirect('/');
});
};
// route middleware to make sure
function isLoggedIn(req, res, next) {
// if user is authenticated in the session, carry on
if (req.isAuthenticated())
return next();
// if they aren't redirect them to the home page
res.redirect('/');
}
and here is my upload form
<form id="form" action="/upload" method="POST">
<div class="fileUpload" id="profile-picture-upload">
<input name="profilePictureToUpload" type="file" id="profile-picture-upload" class="upload" />
</div>
<input type="submit" name="profilePicUpload" id="upload-profilePic-button"></input>
</form>
when i press enter it just shows that error i said above ? can someone please help me
Print out the content of req.files. ie console.log(req.files);
should you be using req.files.profilePictureToUpload instead? As opposed to req.files.profilePicUpload;
If you don't see the property, then it's likely an issue with the file contents not getting appended onto the request object properly.
Also, you don't need to globally apply the file upload to every single route you're using. just use it for whichever endpoint actually uploads:
app.post('/upload', fileUpload(), function(req, res) {
console.log(req.files.profilePicUpload);
});
You should use express-fileupload in app.js as a middle ware
const fileUpload = require('express-fileupload');
const app = express()
app.use(fileUpload());
then you can see req.files anywhare in routes or in app
Server side code:
var User = require("./models/user");
var express = require('express'),
app = express(),
Account = require("./models/account"),
mongoose = require('mongoose'),
passport = require("passport"),
basicAuth = require('basic-auth'),
bodyParser = require("body-parser"),
LocalStrategy = require("passport-local"),
passportLocalMongoose = require("passport-local-mongoose"); //libraries
mongoose.connect("mongodb://localhost/test");
app.set('view engine', 'ejs'); //using engine of ejs file
app.use(bodyParser.urlencoded({extended: true}));
app.use(require("express-session")({
secret: "kiss my ass",
resave: false,
saveUninitialized: false
}));
app.use(passport.initialize());
app.use(passport.session());
passport.use(new LocalStrategy(Account.authenticate()));
passport.serializeUser(Account.serializeUser());
passport.deserializeUser(Account.deserializeUser());
// AUTH Routes
//create account success
app.get('/success', function (req, res) {
res.render('success');
});
// deleteUser form
app.get("/delete", function(req, res, next) {
res.render("deleteuser");
});
app.get("/viewall", function(req, res, next) {
res.render("viewall");
});
//view all User form
app.get('/view', function (req, res) {
console.log('getting all user');
Account.find({})
.exec(function(err, results) {
if(err) {
res.send('error has occured');
}else{
console.log(results);
res.json(results);
}
});
});
app.get('/viewall/:id', function (req, res) {
console.log('getting one user');
Account.findOne({
_id:req.params.id
})
.exec(function(err, account) {
if(err) {
res.send('error occured');
}else{
console.log(account);
res.json(account);
}
})
})
// LOGIN for user
// render login form
app.get("/", function(req, res) {
res.render("login");
});
//login for user
//middleware
app.post("/login", passport.authenticate("local", {
successRedirect: "http://localhost:8082/viewImage.html",
failureRedirect: "http://localhost:8081/error"
}), function(req, res) {
});
//logout from basicauth
app.get('/logout', function (req, res) {
res.set('WWW-Authenticate', 'Basic realm=Authenticate Required');
return res.sendStatus(401);
// res.send("<a href='/login'>Show Users</a>");
});
//basicauth for admin login
var auth = function (req, res, next) {
function unauthorized(res) {
res.set('WWW-Authenticate', 'Basic realm=Authenticate Required');
return res.send(401);
};
var user = basicAuth(req);
if (!user || !user.name || !user.pass) {
return unauthorized(res);
};
if (user.name === 'admin' && user.pass === 'admin123') {
return next();
} else {
return unauthorized(res);
};
};
//LOGIN for admin
//render login form
app.get("/register", auth, function(req, res) {
res.render("register");
});
// register post
app.post("/register", function(req,res){
Account.register(new Account({username: req.body.username}), req.body.password, function(err, user){
if(err){
console.log(err);
return res.render('/register');
}
passport.authenticate("local")(req, res, function(){
res.redirect("/success");
});
});
});
app.listen(8081, function () {
console.log('ImageViewer listening on port 8081!');
});
JS code:
$scope.delete = function (data) {
if (confirm('Do you really want to delete?')){
$window.location.reload();
$http['delete']('/viewall/' + data._id).success(function() {
$scope.users.splice($scope.users.indexOf(data), 1);
});
}
};
html code:
<tr ng-repeat="user in users | filter:searchBox | orderBy:'+username'">
<td>{{user._id}}</td>
<td>{{user.username}}</td>
<td><button class="btn btn-primary" ng-click="delete(user)">Delete</button></td>
This is the error i got:
DELETE
XHR
http://localhost:8081/viewall/5784919136ccb93d0ba78d4b [HTTP/1.1 404 Not Found 8ms]
But when i run the url of http://localhost:8081/viewall/5784919136ccb93d0ba78d4b and it does give me the data:
{"_id":"5784919136ccb93d0ba78d4b","username":"qs","__v":0}
Anybody can help me? don't know what's with the error404 when i'm able to get the data.
You have no route for '/viewall/:id' with DELETE verb. So you should add route with DELETE verb. like
app.delete('/viewall/:id',function(req,res){
// rest of code here
// assume your model name Account
Account.remove({ _id: req.params.id },function(err,doc) {
if(err) {
return res.status(400).send({msg: 'Error occurred during delete account'});
}
return res.status(200).send({msg: 'Successfully deleted'});
});
}
and you should reload after success in your angular controller. like
$http['delete']('/viewall/' + data._id).then(function(response) {
$scope.users.splice($scope.users.indexOf(data), 1);
$window.location.reload();
});