-
Notifications
You must be signed in to change notification settings - Fork 171
/
Copy pathopenfb-angular.js
253 lines (208 loc) · 9.58 KB
/
openfb-angular.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
/**
* 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.2
*/
angular.module('openfb', [])
.factory('OpenFB', function ($rootScope, $q, $window, $http) {
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 overriden 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 success/error handlers as variables
// inside the module instead of keeping them local within the login function.
deferredLogin,
// 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 appId - The id of the Facebook app
* @param redirectURL - The OAuth redirect URL. Optional. If not provided, we use sensible defaults.
* @param store - The store used to save the Facebook token. Optional. If not provided, we use sessionStorage.
*/
function init(appId, redirectURL, store) {
fbAppId = appId;
if (redirectURL) oauthRedirectURL = redirectURL;
if (store) tokenStore = store;
}
/**
* 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 fbScope - The set of Facebook permissions requested
*/
function login(fbScope) {
if (!fbAppId) {
return error({error: 'Facebook App Id not set.'});
}
var loginWindow;
fbScope = fbScope || '';
deferredLogin = $q.defer();
loginProcessed = false;
// logout();
if (runningInCordova) {
oauthRedirectURL = 'https://www.facebook.com/connect/login_success.html';
}
loginWindow = window.open(FB_LOGIN_URL + '?client_id=' + fbAppId + '&redirect_uri=' + oauthRedirectURL +
'&response_type=token&display=popup&scope=' + fbScope, '_blank', 'location=no,clearcache=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', function (event) {
var url = event.url;
if (url.indexOf("access_token=") > 0 || url.indexOf("error=") > 0) {
loginWindow.close();
oauthCallback(url);
}
});
loginWindow.addEventListener('exit', function () {
// 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"});
});
}
// 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.
return deferredLogin.promise;
}
/**
* 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'];
deferredLogin.resolve();
} else if (url.indexOf("error=") > 0) {
queryString = url.substring(url.indexOf('?') + 1, url.indexOf('#'));
obj = parseQueryString(queryString);
deferredLogin.reject(obj);
} else {
deferredLogin.reject();
}
}
/**
* Application-level logout: we simply discard the token.
*/
function logout() {
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=no,clearcache=yes');
if (runningInCordova) {
setTimeout(function() {
logoutWindow.close();
}, 700);
}
}
}
/**
* Helper function to de-authorize the app
* @param success
* @param error
* @returns {*}
*/
function revokePermissions() {
return api({method: 'DELETE', path: '/me/permissions'})
.success(function () {
console.log('Permissions revoked');
});
}
/**
* 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
*/
function api(obj) {
var method = obj.method || 'GET',
params = obj.params || {};
params['access_token'] = tokenStore['fbtoken'];
return $http({method: method, url: 'https://graph.facebook.com' + obj.path + '?' + toQueryString(params), params: params})
.error(function(data, status, headers, config) {
if (data.error && data.error.type === 'OAuthException') {
$rootScope.$emit('OAuthException');
}
});
}
/**
* Helper function for a POST call into the Graph API
* @param path
* @param params
* @returns {*}
*/
function post(path, params) {
return api({method: 'POST', path: path, params: params});
}
/**
* Helper function for a GET call into the Graph API
* @param path
* @param params
* @returns {*}
*/
function get(path, params) {
return api({method: 'GET', path: path, params: params});
}
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("&");
}
return {
init: init,
login: login,
logout: logout,
revokePermissions: revokePermissions,
api: api,
post: post,
get: get,
oauthCallback: oauthCallback
}
});
// Global function called back by the OAuth login dialog
function oauthCallback(url) {
var injector = angular.element(document.getElementById('main')).injector();
injector.invoke(function (OpenFB) {
OpenFB.oauthCallback(url);
});
}