Skip to content

Commit

Permalink
feat: Uses redis based session instead of JWT so that we can expire s…
Browse files Browse the repository at this point in the history
…ession on logout
  • Loading branch information
Arul- committed Aug 28, 2021
1 parent e34fcb1 commit 0334a44
Show file tree
Hide file tree
Showing 4 changed files with 1,340 additions and 1,067 deletions.
52 changes: 38 additions & 14 deletions Parse-Dashboard/Authentication.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ var bcrypt = require('bcryptjs');
var csrf = require('csurf');
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
const session = require('express-session');
const redis = require('redis');
const connectRedis = require('connect-redis');

/**
* Constructor for Authentication class
Expand All @@ -18,10 +21,10 @@ function Authentication(validUsers, useEncryptedPasswords, mountPath) {
}

function initialize(app, options) {
options = options || {};
options = options || { };
var self = this;
passport.use('local', new LocalStrategy(
function(username, password, cb) {
function (username, password, cb) {
var match = self.authenticate({
name: username,
pass: password
Expand All @@ -33,11 +36,11 @@ function initialize(app, options) {
})
);

passport.serializeUser(function(username, cb) {
passport.serializeUser(function (username, cb) {
cb(null, username);
});

passport.deserializeUser(function(username, cb) {
passport.deserializeUser(function (username, cb) {
var user = self.authenticate({
name: username
}, true);
Expand All @@ -47,13 +50,30 @@ function initialize(app, options) {
var cookieSessionSecret = options.cookieSessionSecret || require('crypto').randomBytes(64).toString('hex');
app.use(require('connect-flash')());
app.use(require('body-parser').urlencoded({ extended: true }));
app.use(require('cookie-session')({
key : 'parse_dash',
secret : cookieSessionSecret,
cookie : {
maxAge: (2 * 7 * 24 * 60 * 60 * 1000) // 2 weeks
app.set('trust proxy', 1);
const RedisStore = connectRedis(session)
const redisClient = redis.createClient(options.config.redisOptions || {
host: 'localhost',
port: 6379
})
redisClient.on('error', function (err) {
console.log('Could not establish a connection with redis. ' + err);
});
redisClient.on('connect', function (err) {
console.log('Connected to redis successfully');
});
app.use(session({
store: new RedisStore({ client: redisClient }),
secret: cookieSessionSecret,
resave: false,
saveUninitialized: false,
cookie: {
secure: false, // if true only transmit cookie over https
httpOnly: false, // if true prevent client side JS from reading the cookie
maxAge: 1000 * 60 * 10 // session max age in miliseconds
}
}));
}))

app.use(passport.initialize());
app.use(passport.session());

Expand All @@ -62,13 +82,17 @@ function initialize(app, options) {
passport.authenticate('local', {
successRedirect: `${self.mountPath}apps`,
failureRedirect: `${self.mountPath}login`,
failureFlash : true
failureFlash: true
})
);

app.get('/logout', function(req, res){
req.logout();
res.redirect(`${self.mountPath}login`);
app.get('/logout', function (req, res) {
req.session.destroy(err => {
if (err) {
return console.log(err);
}
res.redirect(`${self.mountPath}login`);
});
});
}

Expand Down
40 changes: 20 additions & 20 deletions Parse-Dashboard/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,39 +31,39 @@ function checkIfIconsExistForApps(apps, iconsFolder) {
var iconName = currentApp.iconName;
var path = iconsFolder + '/' + iconName;

fs.stat(path, function(err) {
fs.stat(path, function (err) {
if (err) {
if ('ENOENT' == err.code) {// file does not exist
console.warn('Icon with file name: ' + iconName +' couldn\'t be found in icons folder!');
} else {
console.log(
'An error occurd while checking for icons, please check permission!');
}
if ('ENOENT' == err.code) {// file does not exist
console.warn('Icon with file name: ' + iconName + ' couldn\'t be found in icons folder!');
} else {
console.log(
'An error occurd while checking for icons, please check permission!');
}
} else {
//every thing was ok so for example you can read it and send it to client
//every thing was ok so for example you can read it and send it to client
}
} );
});
}
}

module.exports = function(config, options) {
options = options || {};
module.exports = function (config, options) {
options = options || { };
var app = express();
// Serve public files.
app.use(express.static(path.join(__dirname,'public')));
app.use(express.static(path.join(__dirname, 'public')));

// Allow setting via middleware
if (config.trustProxy && app.disabled('trust proxy')) {
app.enable('trust proxy');
}

// wait for app to mount in order to get mountpath
app.on('mount', function() {
app.on('mount', function () {
const mountPath = getMount(app.mountpath);
const users = config.users;
const useEncryptedPasswords = config.useEncryptedPasswords ? true : false;
const authInstance = config.authInstance || new Authentication(users, useEncryptedPasswords, mountPath);
authInstance.initialize(app, { cookieSessionSecret: options.cookieSessionSecret });
authInstance.initialize(app, { cookieSessionSecret: options.cookieSessionSecret, config });

// CSRF error handler
app.use(function (err, req, res, next) {
Expand All @@ -75,8 +75,8 @@ module.exports = function(config, options) {
});

// Serve the configuration.
app.get('/parse-dashboard-config.json', function(req, res) {
let apps = config.apps.map((app) => Object.assign({}, app)); // make a copy
app.get('/parse-dashboard-config.json', function (req, res) {
let apps = config.apps.map((app) => Object.assign({ }, app)); // make a copy
let response = {
apps: apps,
newFeaturesInLatestVersion: newFeaturesInLatestVersion,
Expand Down Expand Up @@ -152,9 +152,9 @@ module.exports = function(config, options) {
app.get('/allowed-features.json', function (req, res) {
if (users && req.user && req.user.matchingUsername) {
const found = users.find(i => i.user === req.user.matchingUsername);
return res.json(found.features || {});
return res.json(found.features || { });
}
return res.json({});
return res.json({ });
});

// Serve the app icons. Uses the optional `iconsFolder` parameter as
Expand Down Expand Up @@ -216,11 +216,11 @@ module.exports = function(config, options) {
});

// For every other request, go to index.html. Let client-side handle the rest.
app.get('/*', function(req, res) {
app.get('/*', function (req, res) {
if (users && (!req.user || !req.user.isAuthenticated)) {
return res.redirect(`${mountPath}login`);
}
if (users && req.user && req.user.matchingUsername ) {
if (users && req.user && req.user.matchingUsername) {
res.append('username', req.user.matchingUsername);
}
const customBrandIcon = config.customBrandIcon;
Expand Down
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,13 @@
"body-parser": "1.19.0",
"commander": "6.2.1",
"connect-flash": "0.1.1",
"connect-redis": "^6.0.0",
"cookie-session": "2.0.0-beta.3",
"copy-to-clipboard": "3.2.0",
"create-react-class": "15.7.0",
"csurf": "1.11.0",
"express": "4.17.1",
"express-session": "^1.17.2",
"graphql": "15.5.0",
"graphql-playground-react": "1.7.27",
"history": "4.10.1",
Expand All @@ -70,6 +72,7 @@
"react-redux": "5.1.2",
"react-router": "5.1.2",
"react-router-dom": "5.1.2",
"redis": "^3.1.2",
"regenerator-runtime": "0.13.5",
"semver": "7.3.4"
},
Expand Down
Loading

0 comments on commit 0334a44

Please sign in to comment.