Skip to content

Instantly share code, notes, and snippets.

@pcoady
Last active August 29, 2015 14:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pcoady/eb1fb101056c6749a4c1 to your computer and use it in GitHub Desktop.
Save pcoady/eb1fb101056c6749a4c1 to your computer and use it in GitHub Desktop.
Cognito-Phonegap-Tutorial-OpenFB
/**
* OpenFB is a micro-library that lets you integrate your JavaScript application with Facebook.
* OpenFB works for both BROWSER-BASED apps and CORDOVA/PHONEGAP apps.
* This library has no dependency: You don't need (and shouldn't use) the Facebook SDK with this library. Whe running in
* Cordova, you also don't need the Facebook Cordova plugin. There is also no dependency on jQuery.
* OpenFB allows you to login to Facebook and execute any Facebook Graph API request.
* @author Christophe Coenraets @ccoenraets
* @version 0.4
*/
var openFB = (function () {
var FB_LOGIN_URL = 'https://www.facebook.com/dialog/oauth',
FB_LOGOUT_URL = 'https://www.facebook.com/logout.php',
// By default we store fbtoken in sessionStorage. This can be overridden in init()
tokenStore = window.sessionStorage,
fbAppId,
context = window.location.pathname.substring(0, window.location.pathname.indexOf("/",2)),
baseURL = location.protocol + '//' + location.hostname + (location.port ? ':' + location.port : '') + context,
oauthRedirectURL = baseURL + '/oauthcallback.html',
logoutRedirectURL = baseURL + '/logoutcallback.html',
// Because the OAuth login spans multiple processes, we need to keep the login callback function as a variable
// inside the module instead of keeping it local within the login function.
loginCallback,
// Indicates if the app is running inside Cordova
runningInCordova,
// Used in the exit event handler to identify if the login has already been processed elsewhere (in the oauthCallback function)
loginProcessed;
console.log(oauthRedirectURL);
console.log(logoutRedirectURL);
document.addEventListener("deviceready", function () {
runningInCordova = true;
}, false);
/**
* Initialize the OpenFB module. You must use this function and initialize the module with an appId before you can
* use any other function.
* @param params - init paramters
* appId: The id of the Facebook app,
* tokenStore: The store used to save the Facebook token. Optional. If not provided, we use sessionStorage.
*/
function init(params) {
if (params.appId) {
fbAppId = params.appId;
if (params.cordova!=null){
runningInCordova = params.cordova;
}
} else {
throw 'appId parameter not set in init()';
}
if (params.tokenStore) {
tokenStore = params.tokenStore;
}
}
/**
* Checks if the user has logged in with openFB and currently has a session api token.
* @param callback the function that receives the loginstatus
*/
function getLoginStatus(callback) {
var token = tokenStore['fbtoken'],
loginStatus = {};
if (token) {
loginStatus.status = 'connected';
loginStatus.authResponse = {token: token};
} else {
loginStatus.status = 'unknown';
}
if (callback) callback(loginStatus);
}
/**
* Login to Facebook using OAuth. If running in a Browser, the OAuth workflow happens in a a popup window.
* If running in Cordova container, it happens using the In-App Browser. Don't forget to install the In-App Browser
* plugin in your Cordova project: cordova plugins add org.apache.cordova.inappbrowser.
*
* @param callback - Callback function to invoke when the login process succeeds
* @param options - options.scope: The set of Facebook permissions requested
* @returns {*}
*/
function login(callback, options) {
var loginWindow,
startTime,
scope = '';
if (!fbAppId) {
return callback({status: 'unknown', error: 'Facebook App Id not set.'});
}
// Inappbrowser load start handler: Used when running in Cordova only
function loginWindow_loadStartHandler(event) {
var url = event.url;
if (url.indexOf("access_token=") > 0 || url.indexOf("error=") > 0) {
// When we get the access token fast, the login window (inappbrowser) is still opening with animation
// in the Cordova app, and trying to close it while it's animating generates an exception. Wait a little...
var timeout = 600 - (new Date().getTime() - startTime);
setTimeout(function () {
loginWindow.close();
}, timeout > 0 ? timeout : 0);
oauthCallback(url);
}
}
// Inappbrowser exit handler: Used when running in Cordova only
function loginWindow_exitHandler() {
console.log('exit and remove listeners');
// Handle the situation where the user closes the login window manually before completing the login process
deferredLogin.reject({error: 'user_cancelled', error_description: 'User cancelled login process', error_reason: "user_cancelled"});
loginWindow.removeEventListener('loadstop', loginWindow_loadStartHandler);
loginWindow.removeEventListener('exit', loginWindow_exitHandler);
loginWindow = null;
console.log('done removing listeners');
}
if (options && options.scope) {
scope = options.scope;
}
loginCallback = callback;
loginProcessed = false;
// logout();
if (runningInCordova) {
oauthRedirectURL = "https://www.facebook.com/connect/login_success.html";
}
startTime = new Date().getTime();
loginWindow = window.open(FB_LOGIN_URL + '?client_id=' + fbAppId + '&redirect_uri=' + oauthRedirectURL +
'&response_type=token&scope=' + scope, '_blank', 'location=yes');
// If the app is running in Cordova, listen to URL changes in the InAppBrowser until we get a URL with an access_token or an error
if (runningInCordova) {
loginWindow.addEventListener('loadstart', loginWindow_loadStartHandler);
loginWindow.addEventListener('exit', loginWindow_exitHandler);
}
// Note: if the app is running in the browser the loginWindow dialog will call back by invoking the
// oauthCallback() function. See oauthcallback.html for details.
}
/**
* Called either by oauthcallback.html (when the app is running the browser) or by the loginWindow loadstart event
* handler defined in the login() function (when the app is running in the Cordova/PhoneGap container).
* @param url - The oautchRedictURL called by Facebook with the access_token in the querystring at the ned of the
* OAuth workflow.
*/
function oauthCallback(url) {
// Parse the OAuth data received from Facebook
var queryString,
obj;
loginProcessed = true;
if (url.indexOf("access_token=") > 0) {
queryString = url.substr(url.indexOf('#') + 1);
obj = parseQueryString(queryString);
tokenStore['fbtoken'] = obj['access_token'];
if (loginCallback) loginCallback({status: 'connected', authResponse: {token: obj['access_token']}});
} else if (url.indexOf("error=") > 0) {
queryString = url.substring(url.indexOf('?') + 1, url.indexOf('#'));
obj = parseQueryString(queryString);
if (loginCallback) loginCallback({status: 'not_authorized', error: obj.error});
} else {
if (loginCallback) loginCallback({status: 'not_authorized'});
}
}
/**
* Logout from Facebook, and remove the token.
* IMPORTANT: For the Facebook logout to work, the logoutRedirectURL must be on the domain specified in "Site URL" in your Facebook App Settings
*
*/
function logout(callback) {
var logoutWindow,
token = tokenStore['fbtoken'];
/* Remove token. Will fail silently if does not exist */
tokenStore.removeItem('fbtoken');
if (token) {
logoutWindow = window.open(FB_LOGOUT_URL + '?access_token=' + token + '&next=' + logoutRedirectURL, '_blank', 'location=yes');
if (runningInCordova) {
setTimeout(function() {
logoutWindow.close();
}, 700);
}
}
if (callback) {
callback();
}
}
/**
* Lets you make any Facebook Graph API request.
* @param obj - Request configuration object. Can include:
* method: HTTP method: GET, POST, etc. Optional - Default is 'GET'
* path: path in the Facebook graph: /me, /me.friends, etc. - Required
* params: queryString parameters as a map - Optional
* success: callback function when operation succeeds - Optional
* error: callback function when operation fails - Optional
*/
function api(obj) {
var method = obj.method || 'GET',
params = obj.params || {},
xhr = new XMLHttpRequest(),
url;
params['access_token'] = tokenStore['fbtoken'];
url = 'https://graph.facebook.com' + obj.path + '?' + toQueryString(params);
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
if (obj.success) obj.success(JSON.parse(xhr.responseText));
} else {
var error = xhr.responseText ? JSON.parse(xhr.responseText).error : {message: 'An error has occurred'};
if (obj.error) obj.error(error);
}
}
};
xhr.open(method, url, true);
xhr.send();
}
/**
* Helper function to de-authorize the app
* @param success
* @param error
* @returns {*}
*/
function revokePermissions(success, error) {
return api({method: 'DELETE',
path: '/me/permissions',
success: function () {
tokenStore['fbtoken'] = undefined;
success();
},
error: error});
}
function parseQueryString(queryString) {
var qs = decodeURIComponent(queryString),
obj = {},
params = qs.split('&');
params.forEach(function (param) {
var splitter = param.split('=');
obj[splitter[0]] = splitter[1];
});
return obj;
}
function toQueryString(obj) {
var parts = [];
for (var i in obj) {
if (obj.hasOwnProperty(i)) {
parts.push(encodeURIComponent(i) + "=" + encodeURIComponent(obj[i]));
}
}
return parts.join("&");
}
// The public API
return {
init: init,
login: login,
logout: logout,
revokePermissions: revokePermissions,
api: api,
oauthCallback: oauthCallback,
getLoginStatus: getLoginStatus
}
}());
@pcoady
Copy link
Author

pcoady commented Sep 12, 2014

This is the file from the tutorial at http://backspace.technology/learn-aws-cognito.html

@pcoady
Copy link
Author

pcoady commented Apr 3, 2015

The blog for this code is now maintained at http://blog.backspace.academy

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment