Skip to content

Commit

Permalink
Merge pull request #101 from foundersandcoders/add/refresh-token-request
Browse files Browse the repository at this point in the history
Add a refresh token request
  • Loading branch information
des-des authored Mar 4, 2018
2 parents 3c8bca4 + 8b640d5 commit 6686772
Show file tree
Hide file tree
Showing 11 changed files with 207 additions and 82 deletions.
27 changes: 27 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
"homepage": "https://github.com/foundersandcoders/OTP-Data-Entry#readme",
"dependencies": {
"aws-sdk": "^2.186.0",
"axios": "^0.17.1",
"body-parser": "^1.18.0",
"compression": "^1.7.1",
"cookie-parser": "^1.4.3",
Expand Down
20 changes: 12 additions & 8 deletions src/controllers/OAuth/token.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,34 +11,38 @@ module.exports = (req, res) => {
client_id: process.env.CLIENT_ID,
client_secret: process.env.CLIENT_SECRET,
redirect_uri: process.env.REDIRECT_URI,
grant_type: 'authorization_code'
grant_type: 'authorization_code',
};

const options = {
method: 'POST',
uri: oauthTokenBaseURL,
body: queryString.stringify(tokenQueries),
headers: {
'content-type': 'application/x-www-form-urlencoded'
}
'content-type': 'application/x-www-form-urlencoded',
},
};

if (req.query.state !== process.env.STATE) {
return res.redirect('error', {
statusCode: 400,
errorMessage: 'Something went wrong with your login information! please try again.'
errorMessage:
'Something went wrong with your login information! please try again.',
});
} else {
Request(options, (error, responseToken, body) => {
if (error || responseToken.statusCode !== 200) {
return res.redirect('error', {
statusCode: 500,
errorMessage: 'Server error!'
errorMessage: 'Server error!',
});
} else {
const parsedBody = JSON.parse(body);
const token = jwt.sign(parsedBody.access_token, process.env.JWT_SECRET);
res.cookie('token', token, {maxAge: 604800000});
const { access_token, refresh_token } = JSON.parse(body);
const token = jwt.sign(
{ access_token, refresh_token },
process.env.JWT_SECRET,
);
res.cookie('access', token, { maxAge: 604800000 });

if (req.cookies && req.cookies.referredUrl) {
res.redirect(req.cookies.referredUrl);
Expand Down
73 changes: 39 additions & 34 deletions src/controllers/events/delete_event.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,43 +3,48 @@ const { eventsURL } = require('../../constants/urls.json');
const jwt = require('jsonwebtoken');

module.exports = (req, res) => {
if (req.cookies && req.cookies.token) {
jwt.verify(req.cookies.token, process.env.JWT_SECRET, (error, decodedToken) => {
if (error) {
return res.render('error', {
statusCode: 500,
errorMessage: res.locals.localText.serverError
});
} else {
const reqOptions = {
url: `${eventsURL}/${req.params.id}`,
method: 'DELETE',
auth: {
'bearer': decodedToken
}
};
Request(reqOptions, (error, response) => {
if (error) {
return res.render('error', {
statusCode: 500,
errorMessage: res.locals.localText.serverError
});
}
if (response.statusCode !== 204) {
return res.render('error', {
statusCode: 400,
errorMessage: res.locals.localText.badRequest
});
} else {
res.redirect(`/${req.params.lang}/events`);
}
});
}
});
if (req.cookies && req.cookies.access) {
jwt.verify(
req.cookies.access,
process.env.JWT_SECRET,
(error, decodedToken) => {
if (error) {
return res.render('error', {
statusCode: 500,
errorMessage: res.locals.localText.serverError,
});
} else {
const reqOptions = {
url: `${eventsURL}/${req.params.id}`,
method: 'DELETE',
auth: {
bearer: decodedToken.access_token,
},
};

Request(reqOptions, (error, response, body) => {
if (error) {
return res.render('error', {
statusCode: 500,
errorMessage: res.locals.localText.serverError,
});
}
if (response.statusCode !== 204) {
return res.render('error', {
statusCode: 400,
errorMessage: res.locals.localText.badRequest,
});
} else {
res.redirect(`/${req.params.lang}/events`);
}
});
}
},
);
} else {
return res.redirect('error', {
statusCode: 500,
errorMessage: res.locals.localText.serverError
errorMessage: res.locals.localText.serverError,
});
}
};
70 changes: 43 additions & 27 deletions src/controllers/events/modify_content.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const Request = require('request');
const { eventsURL } = require('../../constants/urls.json');
const checkCookie = require('../../helpers/check_cookie.js');
const OTP = require('../../otp_sdk');

module.exports = (req, res) => {
const apiBody = {
Expand Down Expand Up @@ -32,43 +32,59 @@ module.exports = (req, res) => {
if (error) {
return res.status(500).send(res.locals.localText.serverError);
}
let url, urlEndpoint, correctResponseStatusCode, auth;
let headers;
const tools = {};
switch (req.body._method) {
case 'post':
url = eventsURL;
urlEndpoint = 'events';
correctResponseStatusCode = 201;
tools.url = eventsURL;
tools.urlEndpoint = 'events';
tools.correctResponseStatusCode = 201;
break;
case 'put':
url = `${eventsURL}/${req.params.id}`;
urlEndpoint = `event/${req.params.id}`;
correctResponseStatusCode = 200;
auth = {
bearer: decodedToken,
tools.url = `${eventsURL}/${req.params.id}`;
tools.urlEndpoint = `event/${req.params.id}`;
tools.correctResponseStatusCode = 200;
headers = {
Authorization: 'Bearer ' + decodedToken,
};
break;
default:
return res.status(500).send(res.locals.localText.serverError);
}

// adds the redirectUrls to the tools
tools.redirectUrl = JSON.stringify({
redirectUrl: `/${req.params.lang}/${tools.urlEndpoint}`,
});

const reqOptions = {
url,
url: tools.url,
method: req.body._method,
body: apiBody,
json: true,
auth,
data: apiBody,
responseType: 'json',
headers,
};
Request(reqOptions, (error, apiResponse, apiResponseBody) => {
if (error) {
return res.status(500).send(res.locals.localText.serverError);
} else if (apiResponse.statusCode !== correctResponseStatusCode) {
return res
.status(apiResponseBody.statusCode)
.send(apiResponseBody.message);
} else {
res.end(
JSON.stringify({ redirectUrl: `/${req.params.lang}/${urlEndpoint}` }),
);
}
});

OTP.events
.modify(reqOptions, tools)
.then(() => res.send(tools.redirectUrl))
.catch(err => {
if (err.Unauthorized) {
OTP.auth
.getRefreshToken(req.cookies)
.then(tokens => {
res.clearCookie('access');
res.cookie('access', tokens.token, { maxAge: 604800000 });
reqOptions.headers = {
Authorization: 'Bearer ' + tokens.access_token,
};
OTP.events
.modify(reqOptions, tools)
.then(() => res.send(tools.redirectUrl))
.catch(e => res.status(500).send('Server Error'));
})
.catch(e => res.status(500).send('Server Error'));
}
});
});
};
6 changes: 3 additions & 3 deletions src/helpers/check_cookie.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
const jwt = require('jsonwebtoken');

const checkCookie = (req, cb) => {
if (req.cookies && req.cookies.token) {
jwt.verify(req.cookies.token, process.env.JWT_SECRET, (error, decoded) => {
if (req.cookies && req.cookies.access) {
jwt.verify(req.cookies.access, process.env.JWT_SECRET, (error, decoded) => {
if (error) cb(error);
else {
cb(null, decoded);
cb(null, decoded.access_token);
}
});
} else {
Expand Down
15 changes: 15 additions & 0 deletions src/helpers/verify_token.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
const jwt = require('jsonwebtoken');

module.exports = reqCookiesObject => {
const { access } = reqCookiesObject && reqCookiesObject;

return new Promise((resolve, reject) => {
jwt.verify(access, process.env.JWT_SECRET, (error, decoded) => {
if (error) {
return reject(error);
} else {
return resolve(decoded);
}
});
});
};
17 changes: 7 additions & 10 deletions src/middleware/checkLoggedIn.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,17 @@
// referredUrl to know where to go back to after looged in!

const jwt = require('jsonwebtoken');
const verifyToken = require('../helpers/verify_token.js');

module.exports = (req, res, next) => {
const token = req.cookies && req.cookies.token;
const access = req.cookies && req.cookies.access;

if (token) {
jwt.verify(token, process.env.JWT_SECRET, (error) => {
if (error) {
return res.redirect(`/${req.params.lang}/login`);
} else {
return next();
}
});
if (access) {
verifyToken(req.cookies)
.then(() => next())
.catch(err => res.redirect(`/${req.params.lang}/login`));
} else {
res.cookie('referredUrl', req.url, {maxAge: 300000});
res.cookie('referredUrl', req.url, { maxAge: 300000 });
return res.redirect(`/${req.params.lang}/login`);
}
};
14 changes: 14 additions & 0 deletions src/otp_sdk/events.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
const axios = require('axios');

module.exports.modify = (options, tools) => {
return new Promise(async (resolve, reject) => {
try {
await axios(options);
resolve();
} catch (error) {
error.response.data.error === 'Unauthorized'
? reject({ Unauthorized: true })
: reject();
}
});
};
41 changes: 41 additions & 0 deletions src/otp_sdk/get_refresh_token.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
const verifyToken = require('../helpers/verify_token.js');
const axios = require('axios');
const qs = require('querystring');
const jwt = require('jsonwebtoken');
const { oauthTokenBaseURL } = require('../constants/urls.json');

module.exports = reqCookiesObject => {
const requestToken = async token => {
const tokenQueries = {
grant_type: 'refresh_token',
refresh_token: token.refresh_token,
client_id: process.env.CLIENT_ID,
client_secret: process.env.CLIENT_SECRET,
redirect_uri: process.env.REDIRECT_URI,
};

const options = {
method: 'post',
baseURL: oauthTokenBaseURL,
data: qs.stringify(tokenQueries),
};
try {
const apiTokenResponse = await axios(options);
const { access_token, refresh_token } = apiTokenResponse.data;
const token = await jwt.sign(
{ access_token, refresh_token },
process.env.JWT_SECRET,
);
return { access_token, token };
} catch (e) {
return e;
}
};

return new Promise((resolve, reject) => {
verifyToken(reqCookiesObject)
.then(requestToken)
.then(tokens => resolve(tokens))
.catch(reject);
});
};
5 changes: 5 additions & 0 deletions src/otp_sdk/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module.exports.events = require('./events.js');

module.exports.auth = {
getRefreshToken: require('./get_refresh_token.js'),
};

0 comments on commit 6686772

Please sign in to comment.