Friday 5 May 2017

Expressjs and PassportJS - Route Conditions and Isolating Navigation

I am trying to build upon my current passportjs authentication solution by adding in a condition to check on the billing status of the current user and either redirect him to the /app if the user credentials are correct AND the billing status is "trialing" or "active", or route him to a payment wall page that allows the user to update their billing information to pay their balance and then continue along using the application.

I currently have in place the login authentication, as well as the store account status to the session object, but I need to one figure out how to manipulate the passportjs success redirect to change based on req.isAuthenticated() and req.session.accountStatus, as well as when if the user is redirected to the billing page, how to prevent access to other pages within the application routing of /app/various-paths.

Here is my passport.jslogin config (simplified):

//Login logic

    passport.use('local', new LocalStrategy({
        passReqToCallback: true,
        usernameField: 'email'
    }, function(req, email, password, done) {
        //Database Query user by email
        ...
        }).then(function(_user) {
        //Database Query account by user's organization

        }).then(function(account){
           //Call the Stripe API to check the status of the account
           ....
        }).then(function(stripeAccount){
            if (!user) {
                done(null, false, {
                    message: 'The email you entered is incorrect'
                }, console.log("Unknown User"));
            } else if (!user.validPassword(password)) {
                done(null, false, console.log("Incorrect Password"));
            } else {
                //Set session key value pairs for organizationId and acountStatus
                req.session.organizationId = user.organizations[0].organizationId;
                req.session.accountStatus = stripeAccount.status;
                done(null, user);
            }
    }).catch(function(err) {
        console.log(err);
        console.log("Server Error");
        return done(null, false);
    });
}));

passport.authenticate setup:

.post(passport.authenticate('local', {
        successRedirect: '/app',
        failureRedirect: '/login',
        failureFlash: 'Invalid email or password.'
    })

Routing index:

router.use('/app', isLoggedIn, require('./app-routes'));

function isLoggedIn(req, res, next) {
    if (req.isAuthenticated()){
        return next();
    }
    res.redirect('/login');
}

My first thought is the routing conditionals should exist within my isLoggedIn middleware:

function isLoggedIn(req, res, next) {
    if (req.isAuthenticated()){
        return next();
    }
    res.redirect('/login');
}

I'm not aware of a good solution to prevent users from accessing other /app pages until the account status has been updated. Maybe additional middleware with the router.user('/app',...?

Any help would be great!



via cphill

No comments:

Post a Comment