Skip to content

Commit

Permalink
Merge pull request #397 from pokemontrades/version-2.3
Browse files Browse the repository at this point in the history
Version 2.3
  • Loading branch information
AlMcKinlay committed Dec 13, 2015
2 parents 72857b5 + 6abf259 commit f2b720f
Show file tree
Hide file tree
Showing 112 changed files with 2,652 additions and 2,021 deletions.
8 changes: 4 additions & 4 deletions .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,14 @@
},
"rules": {
"no-console": 0,
"indent": [
2,
2
],
"linebreak-style": [
2,
"unix"
],
"indent": [
2,
2
],
"semi": [
2,
"always"
Expand Down
3 changes: 3 additions & 0 deletions .sailsrc
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
{
"generators": {
"modules": {}
},
"paths": {
"views": "./assets/views"
}
}
13 changes: 8 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@

## Setup

1. Make sure you have a recent version of Node and NPM installed (NPM is usually bundled with Node these days).
1. Clone the repository `git clone https://github.com/yamanickill/reddit-flair-apps.git`
1. Navigate into the directory `reddit-flair-apps`
1. Make sure you have Node (>=4.0.0), and MongoDB installed
1. Clone the repository `git clone https://github.com/YaManicKill/flairhq.git`
1. Navigate into the directory `flairhq`
1. Run `npm install` to install the dependencies
1. Set up your MongoDB settings `config/local.js`
1. Start your MongoDB from the command line with `sudo mongod`
1. Copy config/local.example.js to config/local.js
1. Create a reddit app on [https://www.reddit.com/prefs/apps](https://www.reddit.com/prefs/apps)
1. Copy the id and secret to config/local.js
1. Use something like https://github.com/xoru/easy-oauth to get a refresh token for a moderator on the subs
1. Start your MongoDB
1. Start sails with `npm start`
1. Open `http://localhost:1337` in your browser
6 changes: 5 additions & 1 deletion api/.eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,20 @@
"globals": {
"Reference": true,
"User": true,
"Users": true,
"Ban": true,
"Reddit": true,
"Event": true,
"sails": true,
"Flair": true,
"Flairs": true,
"Usernotes": true,
"References": true,
"Sessions": true,
"Game": true,
"Application": true,
"ModNote": true
"ModNote": true,
"Modmail": true,
"Modmails": true
}
}
134 changes: 58 additions & 76 deletions api/controllers/AuthController.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,90 +21,72 @@ module.exports = {
},

reddit: function (req, res) {
req.session.state = crypto.randomBytes(32).toString('hex');
if (req.query.url) {
req.session.redirectUrl = req.query.url;
/* Pass the redirect info as JSON with the OAuth state. This behavior is more intuitive than storing it in the session, because otherwise the user
* might fail to complete the login and then be confused when they get redirected somewhere unexpected the next time they visit the site. */
var login_info = {type: req.query.loginType, redirect: req.query.redirect || '/', validation: crypto.randomBytes(32).toString('hex')};
req.session.validation = login_info.validation;
var auth_data = {state: JSON.stringify(login_info)};
if (req.query.loginType === 'mod') {
auth_data.duration = 'permanent'; //Mods have a permanent access token. Scope is not specified here, so the scope from config/express.js is used.
} else {
auth_data.scope = 'identity'; //Regular users only need a temporary access token with reduced scope.
}
passport.authenticate('reddit', {
state: req.session.state,
duration: 'permanent',
failureRedirect: '/login',
scope: 'identity'
})(req, res);
},

modAuth: function (req, res) {
req.session.state = crypto.randomBytes(32).toString('hex') + '_modlogin'; //The bit at the end prevents an infinite loop, see below
if (req.query.url) {
req.session.redirectUrl = req.query.url;
}
passport.authenticate('reddit', {
state: req.session.state,
duration: 'permanent',
failureRedirect: '/login'
})(req, res);
passport.authenticate('reddit', auth_data)(req, res);
},

callback: function (req, res) {
passport.authenticate('reddit',
{
state: req.session.state,
duration: 'permanent',
failureRedirect: '/login'
},
function (err, user) {
if (req.query.state !== req.session.state) {
console.log("Warning: A user was redirected to the reddit callback, but does not have a valid session state.");
console.log("The code in the request belongs to /u/" + user.name + '.');
return res.forbidden();
}
var url = req.session.redirectUrl ? req.session.redirectUrl : '/';
req.session.redirectUrl = "";
req.logIn(user, function (err) {
if (err) {
console.log("Failed login: " + err);
return res.forbidden();
passport.authenticate('reddit', async function (err, user) {
try {
if (err) {
if (err === 'banned') {
return res.view(403, {error: 'You have been banned from FlairHQ'});
}

Reddit.checkModeratorStatus(sails.config.reddit.adminRefreshToken, user.name, 'pokemontrades').then(function (modStatus) {
if (modStatus) { //User is a mod, set isMod to true
user.isMod = true;
user.save(function (err) {
if (err) {
console.log('Failed to give /u/' + user.name + ' moderator status');
return res.view(500, {error: "You appear to be a mod, but you weren't given moderator status for some reason.\nTry logging in again."});
}
/* Redirect to the mod authentication page. If the state ends in '_modlogin', the user was just there, so get rid of the _modlogin flag
* instead of redirecting there again. If a mod ends up on a different page while they still have the _modlogin flag, they have not
* successfully authenticated, so they will get redirected to /auth/modauth. */
if (req.session.state.substr(-9) === '_modlogin') {
req.session.state = req.session.state.slice(0, -9);
return res.redirect(url);
}
return res.redirect('/auth/modauth');
});
return res.view(403, {error: 'Sorry, something went wrong. Try logging in again.'});
}
var login_info;
try {
login_info = JSON.parse(req.query.state);
} catch (err) {
console.log('Error with parsing /u/' + user.name + '\'s session state');
return res.serverError(err);
}
if (login_info.validation !== req.session.validation) {
console.log("Failed login for /u/" + user.name + ": invalid session state");
return res.view(403, {error: 'You have an invalid session state. (Try logging in again.)'});
}
let finishLogin = function () {
req.logIn(user, function (err) {
if (err) {
sails.log.error('Failed login: ' + err);
return res.forbidden(err);
}

else if (user.isMod) { // User is not a mod, but had isMod set for some reason (e.g. maybe the user used to be a mod). Set isMod to false.
user.isMod = false;
user.save(function (err) {
if (err) {
console.log('Failed to demote user /u/' + user.name + 'from moderator status');
return res.view(500, {error: err});
}
return res.redirect(url);
});
} else { // Regular user
return res.redirect(url);
var url = decodeURIComponent(login_info.redirect);
// Don't redirect to other callback urls (this may cause infinite loops) or to absolute url paths (which might lead to other sites).
if (url.indexOf('/auth/reddit/callback') === 0 || /^(?:[a-z]+:)?\/\//i.test(url)) {
url = '/';
}
}, function (err) {
console.log('Failed to check whether /u/' + user.name + ' is a moderator.');
console.log(err);
req.session.validation = '';
return res.redirect(url);
});

});
})(req, res);
};
let modStatus = await Reddit.checkModeratorStatus(sails.config.reddit.adminRefreshToken, user.name, 'pokemontrades');
if (modStatus) { //User is a mod, set isMod to true
User.update(user.name, {isMod: true}).exec(function () {
/* Redirect to the mod authentication page, or to the desired url if this was mod authentication.*/
if (login_info.type !== 'mod') {
return res.redirect('/auth/reddit?loginType=mod' + (login_info.redirect ? '&redirect=' + encodeURIComponent(login_info.redirect) : ''));
}
return finishLogin();
});
}
else if (user.isMod) { // User is not a mod, but had isMod set for some reason (e.g. maybe the user used to be a mod). Set isMod to false.
User.update(user.name, {isMod: false}).exec(finishLogin);
} else { // Regular user
return finishLogin();
}
} catch (err) {
return res.serverError(err);
}
})(req, res);
}

};
Loading

0 comments on commit f2b720f

Please sign in to comment.