Skip to content

Commit 7d3b6e8

Browse files
authored
Merge pull request #35 from LearnTeachCode/issue15
Better solution for #15: simplify auth flow, more like Gatekeeper!
2 parents 4128486 + 7c020be commit 7d3b6e8

File tree

2 files changed

+12
-129
lines changed

2 files changed

+12
-129
lines changed

Diff for: public/local.js

+9-100
Original file line numberDiff line numberDiff line change
@@ -55,28 +55,22 @@ var currentGistView = document.getElementById('currentgist');
5555
---------------------------------------------------- */
5656

5757
// If GitHub tempcode is available as a parameter, get access_token from server and log in!
58-
if (getAllUrlParams().tempcode) {
59-
60-
let tempCode = getAllUrlParams().tempcode;
58+
if ( window.location.href.match(/\?code=(.*)/) ) {
59+
// Code for matching URL param from https://github.com/prose/gatekeeper
60+
let tempCode = window.location.href.match(/\?code=(.*)/)[1];
6161

6262
// Remove parameter from URL, updating this entry in the client's browser history
6363
history.replaceState(null, '', '/');
6464

6565
// TODO: show loading animation while waiting???
66-
// TODO: refactor getAllUrlParams(), don't need it, just need ONE param!
6766

68-
// Send tempCode to server in exchange for GitHub access token sent via headers
69-
getTokenFromServer(tempCode)
70-
.then(function(access_token){
71-
72-
// Save the access token as a global variable for now
67+
// Send tempCode to server in exchange for GitHub access token
68+
get('/github-auth?code=' + tempCode).then(function(access_token){
69+
// Save to local state
7370
currentAccessToken = access_token;
74-
75-
// Authenticate with GitHub!
76-
getJSON('https://api.github.com/user?access_token=' + currentAccessToken)
77-
.then(loginUser).catch(handleError);
78-
79-
}, handleError).catch(handleError);
71+
// Get user data
72+
return getJSON('https://api.github.com/user?access_token=' + currentAccessToken);
73+
}).then(loginUser).catch(handleError);
8074

8175
// Otherwise, if user has not yet started the login process,
8276
} else {
@@ -609,27 +603,6 @@ function get(url) {
609603
});
610604
}
611605

612-
function getTokenFromServer(tempCode) {
613-
return new Promise(function(succeed, fail) {
614-
var req = new XMLHttpRequest();
615-
req.open("GET", '/github-token', true);
616-
617-
// Set header:
618-
req.setRequestHeader('GitHub-Temp-Code', tempCode);
619-
620-
req.addEventListener("load", function() {
621-
if (req.status < 400)
622-
succeed(req.getResponseHeader('GitHub-Token'));
623-
else
624-
fail(new Error("Request failed: " + req.statusText));
625-
});
626-
req.addEventListener("error", function() {
627-
fail(new Error("Network error"));
628-
});
629-
req.send(null);
630-
});
631-
}
632-
633606
// Returns a promise for a POST request, similar to get() above
634607
function postWithGitHubToken(url, postDataObject) {
635608
return new Promise(function(succeed, fail) {
@@ -666,70 +639,6 @@ function handleError(error) {
666639
console.log("Error: " + error);
667640
};
668641

669-
// Returns an object containing URL parameters
670-
// via https://www.sitepoint.com/get-url-parameters-with-javascript/
671-
function getAllUrlParams(url) {
672-
673-
// get query string from url (optional) or window
674-
var queryString = url ? url.split('?')[1] : window.location.search.slice(1);
675-
676-
// we'll store the parameters here
677-
var obj = {};
678-
679-
// if query string exists
680-
if (queryString) {
681-
682-
// stuff after # is not part of query string, so get rid of it
683-
queryString = queryString.split('#')[0];
684-
685-
// split our query string into its component parts
686-
var arr = queryString.split('&');
687-
688-
for (var i=0; i<arr.length; i++) {
689-
// separate the keys and the values
690-
var a = arr[i].split('=');
691-
692-
// in case params look like: list[]=thing1&list[]=thing2
693-
var paramNum = undefined;
694-
var paramName = a[0].replace(/\[\d*\]/, function(v) {
695-
paramNum = v.slice(1,-1);
696-
return '';
697-
});
698-
699-
// set parameter value (use 'true' if empty)
700-
var paramValue = typeof(a[1])==='undefined' ? true : a[1];
701-
702-
// (optional) keep case consistent
703-
paramName = paramName.toLowerCase();
704-
paramValue = paramValue.toLowerCase();
705-
706-
// if parameter name already exists
707-
if (obj[paramName]) {
708-
// convert value to array (if still string)
709-
if (typeof obj[paramName] === 'string') {
710-
obj[paramName] = [obj[paramName]];
711-
}
712-
// if no array index number specified...
713-
if (typeof paramNum === 'undefined') {
714-
// put the value on the end of the array
715-
obj[paramName].push(paramValue);
716-
}
717-
// if array index number specified...
718-
else {
719-
// put the value at that index number
720-
obj[paramName][paramNum] = paramValue;
721-
}
722-
}
723-
// if param name doesn't exist yet, set it
724-
else {
725-
obj[paramName] = paramValue;
726-
}
727-
}
728-
}
729-
730-
return obj;
731-
}
732-
733642
function changeTurn() {
734643
gameState.turnIndex = (gameState.turnIndex + 1) % gameState.players.length;
735644
}

Diff for: server.js

+3-29
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,14 @@ var port = process.env.PORT || 8000; // Set the default port number to 8000, or
1111
// Use Express to serve everything in the "public" folder as static files
1212
app.use(express.static('public'));
1313

14-
// Save table of temp codes and access tokens, for sending access tokens to the corresponding clients via headers
15-
let clientTokens = {};
16-
1714
// Pass GITHUB_CLIENT_ID to client when requested (using AJAX for now)
1815
// TODO (later): mess around with templating engines and Express .render()?
1916
app.get('/github-client', function (req, res) {
2017
console.log('Request received for /github-client route. Sending response: GITHUB_CLIENT_ID');
2118
res.end(process.env.GITHUB_CLIENT_ID);
2219
});
2320

24-
// Handle GitHub authentication at this route, then redirect to homepage
21+
// Handle GitHub authentication at this route, then pass token back to client
2522
app.get('/github-auth', authenticateUser);
2623

2724
function authenticateUser (req, res) {
@@ -47,42 +44,19 @@ function authenticateUser (req, res) {
4744
githubResponseBody += chunk;
4845
});
4946
response.on('end', function() {
50-
//console.log('\n*****done receiving response data:\n' + githubResponseBody + '\n');
5147

5248
// TODO (later): check the scopes, because users can authorize less than what my app requested!
5349

54-
// Save received access token to clientTokens to keep it associated with this client
55-
clientTokens[req.query.code] = JSON.parse(githubResponseBody).access_token;
56-
57-
// Redirect to home page again, with the temp code as a URL param
58-
// TODO (later): can I use server-side rendering to accomplish this also???
59-
res.redirect('/?tempcode=' + req.query.code);
50+
// Send GitHub access token back to client
51+
res.end( JSON.parse(githubResponseBody).access_token );
6052

6153
});
6254
});
6355

6456
request.write(postRequestBody);
6557
request.end();
66-
6758
}
6859

69-
// Pass GitHub access token to corresponding client, if it matches client's temp code
70-
app.get('/github-token', function (req, res) {
71-
72-
let tempCode = req.header('GitHub-Temp-Code');
73-
74-
console.log('Request received for /github-token route for temp code: ' + tempCode);
75-
76-
if ( clientTokens.hasOwnProperty(tempCode) ) {
77-
console.log('\t Temp code MATCHES! Sending access token in response header!');
78-
res.header('GitHub-Token', clientTokens[tempCode]);
79-
}
80-
res.end(); // Double check: can I use res.end() with no body?
81-
82-
console.log("\nclientTokens:\n");
83-
console.log(clientTokens);
84-
});
85-
8660
// Activate the server and listen on our specified port number
8761
server.listen(port, function() {
8862
// Display this message in the server console once the server is active

0 commit comments

Comments
 (0)