Files
Oliver Dunk 5bf419b385 Reorganize directory structure (#825)
* Remove docs folder.

This was a redirect from a GitHub pages site that does not appear
to be in use.

* Rename api folder to api-samples.

* Move examples to functional-samples folder.

* Move cookbook sample to functional-samples.

* Move tutorials to functional-samples folder.

* Move mv2 and apps folders to _archive.

* Rename tools folder to .repo.

* Move reference folder to functional-samples.

* Update README.

Update README with new relative links for reorg.

* Update README.md

Co-authored-by: amysteamdev <37001393+AmySteam@users.noreply.github.com>

---------

Co-authored-by: amysteamdev <37001393+AmySteam@users.noreply.github.com>
2023-02-03 10:58:04 -06:00

278 lines
8.5 KiB
JavaScript

var gh = (function() {
'use strict';
var signin_button;
var revoke_button;
var user_info_div;
var tokenFetcher = (function() {
// Replace clientId and clientSecret with values obtained by you for your
// application https://github.com/settings/applications.
var clientId = '11442b0924c8d6a98fb7';
// Note that in a real-production app, you may not want to store
// clientSecret in your App code.
var clientSecret = 'a1499b1a5780c8a21ed560b839741e803c4cc936';
var redirectUri = chrome.identity.getRedirectURL('provider_cb');
var redirectRe = new RegExp(redirectUri + '[#\?](.*)');
var access_token = null;
return {
getToken: function(interactive, callback) {
// In case we already have an access_token cached, simply return it.
if (access_token) {
callback(null, access_token);
return;
}
var options = {
'interactive': interactive,
'url': 'https://github.com/login/oauth/authorize' +
'?client_id=' + clientId +
'&redirect_uri=' + encodeURIComponent(redirectUri)
}
chrome.identity.launchWebAuthFlow(options, function(redirectUri) {
console.log('launchWebAuthFlow completed', chrome.runtime.lastError,
redirectUri);
if (chrome.runtime.lastError) {
callback(new Error(chrome.runtime.lastError));
return;
}
// Upon success the response is appended to redirectUri, e.g.
// https://{app_id}.chromiumapp.org/provider_cb#access_token={value}
// &refresh_token={value}
// or:
// https://{app_id}.chromiumapp.org/provider_cb#code={value}
var matches = redirectUri.match(redirectRe);
if (matches && matches.length > 1)
handleProviderResponse(parseRedirectFragment(matches[1]));
else
callback(new Error('Invalid redirect URI'));
});
function parseRedirectFragment(fragment) {
var pairs = fragment.split(/&/);
var values = {};
pairs.forEach(function(pair) {
var nameval = pair.split(/=/);
values[nameval[0]] = nameval[1];
});
return values;
}
function handleProviderResponse(values) {
console.log('providerResponse', values);
if (values.hasOwnProperty('access_token'))
setAccessToken(values.access_token);
// If response does not have an access_token, it might have the code,
// which can be used in exchange for token.
else if (values.hasOwnProperty('code'))
exchangeCodeForToken(values.code);
else
callback(new Error('Neither access_token nor code avialable.'));
}
function exchangeCodeForToken(code) {
var xhr = new XMLHttpRequest();
xhr.open('GET',
'https://github.com/login/oauth/access_token?' +
'client_id=' + clientId +
'&client_secret=' + clientSecret +
'&redirect_uri=' + redirectUri +
'&code=' + code);
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.setRequestHeader('Accept', 'application/json');
xhr.onload = function () {
// When exchanging code for token, the response comes as json, which
// can be easily parsed to an object.
if (this.status === 200) {
var response = JSON.parse(this.responseText);
console.log(response);
if (response.hasOwnProperty('access_token')) {
setAccessToken(response.access_token);
} else {
callback(new Error('Cannot obtain access_token from code.'));
}
} else {
console.log('code exchange status:', this.status);
callback(new Error('Code exchange failed'));
}
};
xhr.send();
}
function setAccessToken(token) {
access_token = token;
console.log('Setting access_token: ', access_token);
callback(null, access_token);
}
},
removeCachedToken: function(token_to_remove) {
if (access_token == token_to_remove)
access_token = null;
}
}
})();
function xhrWithAuth(method, url, interactive, callback) {
var retry = true;
var access_token;
console.log('xhrWithAuth', method, url, interactive);
getToken();
function getToken() {
tokenFetcher.getToken(interactive, function(error, token) {
console.log('token fetch', error, token);
if (error) {
callback(error);
return;
}
access_token = token;
requestStart();
});
}
function requestStart() {
var xhr = new XMLHttpRequest();
xhr.open(method, url);
xhr.setRequestHeader('Authorization', 'Bearer ' + access_token);
xhr.onload = requestComplete;
xhr.send();
}
function requestComplete() {
console.log('requestComplete', this.status, this.response);
if ( ( this.status < 200 || this.status >=300 ) && retry) {
retry = false;
tokenFetcher.removeCachedToken(access_token);
access_token = null;
getToken();
} else {
callback(null, this.status, this.response);
}
}
}
function getUserInfo(interactive) {
xhrWithAuth('GET',
'https://api.github.com/user',
interactive,
onUserInfoFetched);
}
// Functions updating the User Interface:
function showButton(button) {
button.style.display = 'inline';
button.disabled = false;
}
function hideButton(button) {
button.style.display = 'none';
}
function disableButton(button) {
button.disabled = true;
}
function onUserInfoFetched(error, status, response) {
if (!error && status == 200) {
console.log("Got the following user info: " + response);
var user_info = JSON.parse(response);
populateUserInfo(user_info);
hideButton(signin_button);
showButton(revoke_button);
fetchUserRepos(user_info["repos_url"]);
} else {
console.log('infoFetch failed', error, status);
showButton(signin_button);
}
}
function populateUserInfo(user_info) {
var elem = user_info_div;
var nameElem = document.createElement('div');
nameElem.innerHTML = "<b>Hello " + user_info.name + "</b><br>"
+ "Your github page is: " + user_info.html_url;
elem.appendChild(nameElem);
}
function fetchUserRepos(repoUrl) {
xhrWithAuth('GET', repoUrl, false, onUserReposFetched);
}
function onUserReposFetched(error, status, response) {
var elem = document.querySelector('#user_repos');
elem.value='';
if (!error && status == 200) {
console.log("Got the following user repos:", response);
var user_repos = JSON.parse(response);
user_repos.forEach(function(repo) {
if (repo.private) {
elem.value += "[private repo]";
} else {
elem.value += repo.name;
}
elem.value += '\n';
});
} else {
console.log('infoFetch failed', error, status);
}
}
// Handlers for the buttons's onclick events.
function interactiveSignIn() {
disableButton(signin_button);
tokenFetcher.getToken(true, function(error, access_token) {
if (error) {
showButton(signin_button);
} else {
getUserInfo(true);
}
});
}
function revokeToken() {
// We are opening the web page that allows user to revoke their token.
window.open('https://github.com/settings/applications');
// And then clear the user interface, showing the Sign in button only.
// If the user revokes the app authorization, they will be prompted to log
// in again. If the user dismissed the page they were presented with,
// Sign in button will simply sign them in.
user_info_div.textContent = '';
hideButton(revoke_button);
showButton(signin_button);
}
return {
onload: function () {
signin_button = document.querySelector('#signin');
signin_button.onclick = interactiveSignIn;
revoke_button = document.querySelector('#revoke');
revoke_button.onclick = revokeToken;
user_info_div = document.querySelector('#user_info');
console.log(signin_button, revoke_button, user_info_div);
showButton(signin_button);
getUserInfo(false);
}
};
})();
window.onload = gh.onload;