facebook-stub 0.0.1.4 → 0.0.1.6
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/.rspec +2 -0
- data/Rakefile +23 -0
- data/facebook-stub.gemspec +12 -4
- data/lib/facebook-stub.js +5 -0
- data/lib/facebook-stub.rb +1 -54
- data/lib/facebook_stub.rb +55 -0
- data/{src/libs → lib/facebook_stub}/base64_encode.js +0 -0
- data/{src/libs → lib/facebook_stub}/cookie.js +0 -0
- data/{src/facebook.js → lib/facebook_stub/core.js} +100 -62
- data/lib/facebook_stub/rails/action_view_helper.rb +10 -0
- data/{src/libs → lib/facebook_stub}/sha256.js +0 -0
- data/{src/libs → lib/facebook_stub}/utf8_encode.js +0 -0
- data/lib/facebook_stub/version.rb +3 -0
- data/spec/acceptance/facebook-stub_spec.rb +301 -0
- data/spec/spec_helper.rb +41 -0
- data/test/config.ru +3 -0
- data/test/server.rb +20 -0
- data/test/views/test.haml +20 -0
- metadata +173 -62
- data/builder/concat +0 -8
- data/facebook-stub.js +0 -707
- data/lib/facebook-stub/rails/action_view_helper.rb +0 -20
- data/lib/facebook-stub/version.rb +0 -5
- data/test/test.html +0 -19
data/builder/concat
DELETED
data/facebook-stub.js
DELETED
@@ -1,707 +0,0 @@
|
|
1
|
-
;(function(window, undefined) {
|
2
|
-
|
3
|
-
//var standardPerms = '{"extended":["status_update","photo_upload","video_upload","offline_access","email","create_note","share_item","publish_stream","contact_email"],"user":["manage_friendlists","create_event","read_requests","manage_pages"],"friends":[]}';
|
4
|
-
|
5
|
-
// two globals for creating the cookie
|
6
|
-
// FB Functions
|
7
|
-
function init(data) {
|
8
|
-
FBWorld.initialized = true;
|
9
|
-
state('appId', data.appId);
|
10
|
-
}
|
11
|
-
|
12
|
-
function missingPermissions(desired){
|
13
|
-
var missing = [];
|
14
|
-
var perms = getStatus('standard').perms.split(',');
|
15
|
-
for (i=0; i<desired.length; i++){
|
16
|
-
if (perms.indexOf(desired[i]) == -1) {
|
17
|
-
missing.push(desired[i]);
|
18
|
-
}
|
19
|
-
}
|
20
|
-
return missing;
|
21
|
-
}
|
22
|
-
|
23
|
-
// login
|
24
|
-
function login(callback, options) {
|
25
|
-
if (calledBeforeInit('login')) return;
|
26
|
-
if (FBWorld.state('loggedIn')) {
|
27
|
-
console.log('FB.login() called when user is already connected.');
|
28
|
-
if (FBWorld.state('connected')) {
|
29
|
-
var missing = missingPermissions(options.scope.split(','));
|
30
|
-
if (missing.length === 0){
|
31
|
-
callback(getStatus('standard'));
|
32
|
-
}else{
|
33
|
-
options.missing_perms = missing;
|
34
|
-
promptToAddPermissions(options, callback);
|
35
|
-
}
|
36
|
-
}else{
|
37
|
-
promptToConnect(options, callback);
|
38
|
-
}
|
39
|
-
}else{
|
40
|
-
promptToLogin(options, callback);
|
41
|
-
}
|
42
|
-
}
|
43
|
-
|
44
|
-
// simulate prompt to login
|
45
|
-
function promptToLogin(options, callback) {
|
46
|
-
FBWorld.beingPromptedToLogin = true;
|
47
|
-
FBWorld.beingPromptedToLoginOptions = options;
|
48
|
-
FBWorld.beingPromptedToLoginCallback = callback;
|
49
|
-
}
|
50
|
-
|
51
|
-
// simulates resolving a login prompt in one of three ways
|
52
|
-
function resolveLoginPrompt(successfull, facebook_uid) {
|
53
|
-
if (!FBWorld.beingPromptedToLogin) throw "you are not being prompted to login";
|
54
|
-
var
|
55
|
-
options = FBWorld.beingPromptedToLoginOptions,
|
56
|
-
callback = FBWorld.beingPromptedToLoginCallback;
|
57
|
-
|
58
|
-
// reset the FBWorld state
|
59
|
-
FBWorld.beingPromptedToLogin = false;
|
60
|
-
FBWorld.beingPromptedToLoginOptions = undefined;
|
61
|
-
FBWorld.beingPromptedToLoginCallback = undefined;
|
62
|
-
|
63
|
-
if (successfull){
|
64
|
-
FBWorld.setUid(facebook_uid);
|
65
|
-
FBWorld.loggedIn();
|
66
|
-
|
67
|
-
if (!FBWorld.state('connected')) {
|
68
|
-
promptToConnect(options, callback);
|
69
|
-
} else {
|
70
|
-
FBWorld.state('perms', 'standard', options.perms);
|
71
|
-
callback(getStatus('standard'));
|
72
|
-
}
|
73
|
-
|
74
|
-
} else {
|
75
|
-
FBWorld.notLoggedIn();
|
76
|
-
callback(getStatus());
|
77
|
-
}
|
78
|
-
}
|
79
|
-
|
80
|
-
function successfullyLogin(facebook_uid){
|
81
|
-
resolveLoginPrompt(true, facebook_uid);
|
82
|
-
}
|
83
|
-
|
84
|
-
function failToLogin(){
|
85
|
-
resolveLoginPrompt(false);
|
86
|
-
}
|
87
|
-
|
88
|
-
function cancelLogin(){
|
89
|
-
resolveLoginPrompt(false);
|
90
|
-
}
|
91
|
-
|
92
|
-
|
93
|
-
// connect to app
|
94
|
-
|
95
|
-
// simulate prompt to connect
|
96
|
-
function promptToConnect(options, callback) {
|
97
|
-
FBWorld.beingPromptedToConnect = true;
|
98
|
-
FBWorld.beingPromptedToConnectOptions = options;
|
99
|
-
FBWorld.beingPromptedToConnectCallback = callback;
|
100
|
-
}
|
101
|
-
|
102
|
-
function resolvePromptToConnect(approved) {
|
103
|
-
if (!FBWorld.beingPromptedToConnect) throw "you are not being prompted to connect";
|
104
|
-
var
|
105
|
-
options = FBWorld.beingPromptedToConnectOptions,
|
106
|
-
callback = FBWorld.beingPromptedToConnectCallback;
|
107
|
-
|
108
|
-
// reset the FBWorld state
|
109
|
-
FBWorld.beingPromptedToConnect = false;
|
110
|
-
FBWorld.beingPromptedToConnectOptions = undefined;
|
111
|
-
FBWorld.beingPromptedToConnectCallback = undefined;
|
112
|
-
|
113
|
-
if (approved){
|
114
|
-
FBWorld.connected();
|
115
|
-
FBWorld.state('perms', 'standard', options.perms);
|
116
|
-
} else {
|
117
|
-
FBWorld.notConnected();
|
118
|
-
}
|
119
|
-
|
120
|
-
callback(getStatus('standard'));
|
121
|
-
}
|
122
|
-
|
123
|
-
function acceptPromptToConnect() {
|
124
|
-
resolvePromptToConnect(true);
|
125
|
-
}
|
126
|
-
|
127
|
-
function denyPromptToConnect() {
|
128
|
-
resolvePromptToConnect(false);
|
129
|
-
}
|
130
|
-
|
131
|
-
function cancelPromptToConnect() {
|
132
|
-
resolvePromptToConnect(false);
|
133
|
-
}
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
function promptToAddPermissions(options, callback){
|
138
|
-
FBWorld.beingPromptedToAddPermissions = true;
|
139
|
-
FBWorld.beingPromptedToAddPermissionsOptions = options;
|
140
|
-
FBWorld.beingPromptedToAddPermissionsCallback = callback;
|
141
|
-
}
|
142
|
-
|
143
|
-
function beingPromptedToAddThesePermissions(permissions){
|
144
|
-
// sort and stringify permissions arrays to make them easier to compare. maybe not fast, but succinct
|
145
|
-
return FBWorld.beingPromptedToAddPermissions && FBWorld.beingPromptedToAddPermissionsOptions.missing_perms.sort().toString() == permissions.split(',').sort().toString();
|
146
|
-
}
|
147
|
-
|
148
|
-
function resolvePromptToAddPermissions(approved, permissions) {
|
149
|
-
if (!FBWorld.beingPromptedToAddPermissions) throw "you are not being prompted to add permissions";
|
150
|
-
var
|
151
|
-
options = FBWorld.beingPromptedToAddPermissionsOptions,
|
152
|
-
callback = FBWorld.beingPromptedToAddPermissionsCallback;
|
153
|
-
|
154
|
-
// reset the FBWorld state
|
155
|
-
FBWorld.beingPromptedToAddPermissions = false;
|
156
|
-
FBWorld.beingPromptedToAddPermissionsOptions = undefined;
|
157
|
-
FBWorld.beingPromptedToAddPermissionsCallback = undefined;
|
158
|
-
|
159
|
-
if (approved){
|
160
|
-
FBWorld.state('perms', 'standard', permissions);
|
161
|
-
}
|
162
|
-
callback(getStatus('standard'));
|
163
|
-
}
|
164
|
-
|
165
|
-
function acceptPromptToAddPermissions(add) {
|
166
|
-
var perms = getStatus("standard").perms;
|
167
|
-
var separator = perms.length ? ',' : '';
|
168
|
-
resolvePromptToAddPermissions(true, perms + separator + add);
|
169
|
-
}
|
170
|
-
|
171
|
-
function denyPromptToAddPermissions() {
|
172
|
-
resolvePromptToAddPermissions(false);
|
173
|
-
}
|
174
|
-
|
175
|
-
function cancelPromptToAddPermissions() {
|
176
|
-
resolvePromptToAddPermissions(false);
|
177
|
-
}
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
function logout(callback) {
|
183
|
-
if (calledBeforeInit('logout')) return;
|
184
|
-
if (!FBWorld.state('loggedIn')) console.log('FB.logout() called without a session.');
|
185
|
-
FBWorld.notLoggedIn();
|
186
|
-
callback(getStatus());
|
187
|
-
}
|
188
|
-
|
189
|
-
function getLoginStatus(callback, perms) {
|
190
|
-
if (calledBeforeInit('getLoginStatus')) return;
|
191
|
-
callback(getStatus(perms ? 'extended' : false));
|
192
|
-
}
|
193
|
-
|
194
|
-
function getUserID() {
|
195
|
-
if (calledBeforeInit('getUserID')) return;
|
196
|
-
return uid();
|
197
|
-
}
|
198
|
-
|
199
|
-
|
200
|
-
function getSession() {
|
201
|
-
if (calledBeforeInit('getSession')) return false;
|
202
|
-
return getStatus().session;
|
203
|
-
}
|
204
|
-
|
205
|
-
function api(location, callback) {
|
206
|
-
if (!FBWorld.state('connected')) {
|
207
|
-
callback(undefined);
|
208
|
-
} else if (location == '/me/friends') {
|
209
|
-
callback({data:FBWorld.friendList()});
|
210
|
-
} else if (location == '/me/permissions') {
|
211
|
-
var theState = FBWorld.state();
|
212
|
-
var perms;
|
213
|
-
if (theState && theState.perms) {
|
214
|
-
perms = {data:[theState.perms.extended]}
|
215
|
-
}
|
216
|
-
callback( perms );
|
217
|
-
}
|
218
|
-
}
|
219
|
-
|
220
|
-
// FBWorld Functions
|
221
|
-
//3 states: loggedOut, loggedIn, connected
|
222
|
-
function state() {
|
223
|
-
var theState = JSON.parse(FBWorld.Helpers.makeMeACookie('fb-stub') || '{}');
|
224
|
-
if (arguments.length === 0) return theState;
|
225
|
-
if (arguments.length === 1) return theState[arguments[0]];
|
226
|
-
if (arguments.length === 2) {
|
227
|
-
theState[arguments[0]] = arguments[1];
|
228
|
-
FBWorld.Helpers.makeMeACookie('fb-stub', JSON.stringify(theState), cookieOptions);
|
229
|
-
return arguments[1];
|
230
|
-
}
|
231
|
-
if (arguments.length === 3) {
|
232
|
-
if(typeof(theState[arguments[0]]) == 'undefined') theState[arguments[0]] = {};
|
233
|
-
theState[arguments[0]][arguments[1]] = arguments[2];
|
234
|
-
FBWorld.Helpers.makeMeACookie('fb-stub', JSON.stringify(theState), cookieOptions);
|
235
|
-
return arguments[2];
|
236
|
-
}
|
237
|
-
}
|
238
|
-
|
239
|
-
function uid() {
|
240
|
-
return FBWorld.state('uid');
|
241
|
-
}
|
242
|
-
|
243
|
-
function setUid(newUid) {
|
244
|
-
return FBWorld.state('uid', newUid);
|
245
|
-
}
|
246
|
-
|
247
|
-
function setExtendedPermissions(newPermissions) {
|
248
|
-
return FBWorld.state('perms', 'extended', newPermissions);
|
249
|
-
}
|
250
|
-
|
251
|
-
function setSecret(newSecret) {
|
252
|
-
return state('secret', newSecret);
|
253
|
-
}
|
254
|
-
|
255
|
-
function loggedIn() {
|
256
|
-
createConnectedCookie();
|
257
|
-
FBWorld.state('loggedIn', true);
|
258
|
-
FBWorld.state('perms', 'standard', '');
|
259
|
-
return true;
|
260
|
-
}
|
261
|
-
|
262
|
-
function notLoggedIn() {
|
263
|
-
deleteConnectedCookie();
|
264
|
-
FBWorld.state('loggedIn', false);
|
265
|
-
}
|
266
|
-
|
267
|
-
function connected() {
|
268
|
-
createConnectedCookie();
|
269
|
-
FBWorld.state('connected', true);
|
270
|
-
}
|
271
|
-
|
272
|
-
function notConnected() {
|
273
|
-
deleteConnectedCookie();
|
274
|
-
FBWorld.state('connected', false);
|
275
|
-
}
|
276
|
-
|
277
|
-
function addFriend(id, name) {
|
278
|
-
var friends = FBWorld.friendList();
|
279
|
-
friends.push({id: id, name: name});
|
280
|
-
FBWorld.Helpers.makeMeACookie('fb_friends', JSON.stringify(friends));
|
281
|
-
}
|
282
|
-
|
283
|
-
function friendList() {
|
284
|
-
return JSON.parse(FBWorld.Helpers.makeMeACookie('fb_friends') || '[]');
|
285
|
-
}
|
286
|
-
|
287
|
-
|
288
|
-
// sharing
|
289
|
-
|
290
|
-
function ui(options, callback) {
|
291
|
-
if (options.method === 'feed'){
|
292
|
-
FBWorld.beingPromptedToShare = true;
|
293
|
-
FBWorld.beingPromptedToShareOptions = options;
|
294
|
-
FBWorld.beingPromptedToShareCallback = callback;
|
295
|
-
}
|
296
|
-
}
|
297
|
-
|
298
|
-
// simulate closing the share prompt by either sharing or canceling
|
299
|
-
function resolveSharePrompt(way) {
|
300
|
-
response = {};
|
301
|
-
if (way === 'share') response.post_id = Math.floor(Math.random() * 100000);
|
302
|
-
if (way === 'cancel');
|
303
|
-
|
304
|
-
if (typeof FBWorld.beingPromptedToShareCallback === 'function')
|
305
|
-
FBWorld.beingPromptedToShareCallback(response);
|
306
|
-
FBWorld.beingPromptedToShare = false;
|
307
|
-
FBWorld.beingPromptedToShareOptions = undefined;
|
308
|
-
FBWorld.beingPromptedToShareCallback = undefined;
|
309
|
-
};
|
310
|
-
|
311
|
-
function confirmSharePrompt(){
|
312
|
-
resolveSharePrompt('share');
|
313
|
-
}
|
314
|
-
|
315
|
-
function cancelSharePrompt(){
|
316
|
-
resolveSharePrompt('cancel');
|
317
|
-
}
|
318
|
-
|
319
|
-
var XFBML = {
|
320
|
-
parse: function(element, callback) {
|
321
|
-
callback();
|
322
|
-
}
|
323
|
-
};
|
324
|
-
|
325
|
-
FB = { // Emulates the FB API
|
326
|
-
getLoginStatus : getLoginStatus,
|
327
|
-
logout : logout,
|
328
|
-
login : login,
|
329
|
-
init : init,
|
330
|
-
getSession : getSession,
|
331
|
-
api : api,
|
332
|
-
XFBML : XFBML,
|
333
|
-
getUserID : getUserID,
|
334
|
-
ui : ui
|
335
|
-
};
|
336
|
-
|
337
|
-
FBWorld = { // used to set the state of Facebook
|
338
|
-
|
339
|
-
// the state of the Facebook World
|
340
|
-
state : state,
|
341
|
-
|
342
|
-
// Set the state of the Facebook World
|
343
|
-
loggedIn : loggedIn,
|
344
|
-
notLoggedIn : notLoggedIn,
|
345
|
-
setUid : setUid,
|
346
|
-
setSecret : setSecret,
|
347
|
-
uid : uid,
|
348
|
-
connected : connected,
|
349
|
-
notConnected : notConnected,
|
350
|
-
setExtendedPermissions : setExtendedPermissions,
|
351
|
-
|
352
|
-
initialized : false,
|
353
|
-
|
354
|
-
// Simulate interactions with Facebook
|
355
|
-
|
356
|
-
// login
|
357
|
-
beingPromptedToLogin : false,
|
358
|
-
beingPromptedToLoginOptions : undefined,
|
359
|
-
beingPromptedToLoginCallback : undefined,
|
360
|
-
successfullyLogin : successfullyLogin,
|
361
|
-
failToLogin : failToLogin,
|
362
|
-
cancelLogin : cancelLogin,
|
363
|
-
|
364
|
-
// connecting
|
365
|
-
beingPromptedToConnect : false,
|
366
|
-
beingPromptedToConnectOptions : undefined,
|
367
|
-
beingPromptedToConnectCallback : undefined,
|
368
|
-
acceptPromptToConnect : acceptPromptToConnect,
|
369
|
-
denyPromptToConnect : denyPromptToConnect,
|
370
|
-
cancelPromptToConnect : cancelPromptToConnect,
|
371
|
-
|
372
|
-
// adding permissions
|
373
|
-
beingPromptedToAddPermissions : false,
|
374
|
-
beingPromptedToAddThesePermissions : beingPromptedToAddThesePermissions,
|
375
|
-
beingPromptedToAddPermissionsOptions : undefined,
|
376
|
-
beingPromptedToAddPermissionsCallback : undefined,
|
377
|
-
acceptPromptToAddPermissions : acceptPromptToAddPermissions,
|
378
|
-
denyPromptToAddPermissions : denyPromptToAddPermissions,
|
379
|
-
cancelPromptToAddPermissions : cancelPromptToAddPermissions,
|
380
|
-
|
381
|
-
//sharing
|
382
|
-
beingPromptedToShare : false,
|
383
|
-
beingPromptedToShareOptions : undefined,
|
384
|
-
beingPromptedToShareCallback : undefined,
|
385
|
-
confirmSharePrompt : confirmSharePrompt,
|
386
|
-
cancelSharePrompt : cancelSharePrompt,
|
387
|
-
|
388
|
-
//friends
|
389
|
-
addFriend : addFriend,
|
390
|
-
friendList : friendList
|
391
|
-
};
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
// PRIVATE FUNCTIONS
|
400
|
-
|
401
|
-
function getStatus(permissions) {
|
402
|
-
var theState = FBWorld.state();
|
403
|
-
|
404
|
-
// Connected
|
405
|
-
if (theState.loggedIn && theState.connected) {
|
406
|
-
var status = {
|
407
|
-
status: "connected",
|
408
|
-
authResponse: createConnectedCookie()
|
409
|
-
};
|
410
|
-
|
411
|
-
if(typeof(permissions) != 'undefined') {
|
412
|
-
status.perms = permissions == 'extended' ? JSON.stringify(theState.perms) : theState.perms.standard;
|
413
|
-
}
|
414
|
-
return status;
|
415
|
-
}
|
416
|
-
|
417
|
-
// not connected
|
418
|
-
if (theState.loggedIn && !theState.connected) {
|
419
|
-
return {
|
420
|
-
perms: null,
|
421
|
-
authResponse: null,
|
422
|
-
status: 'notConnected'
|
423
|
-
};
|
424
|
-
}
|
425
|
-
|
426
|
-
// not logged in
|
427
|
-
if (!theState.loggedIn) {
|
428
|
-
return {
|
429
|
-
perms: null,
|
430
|
-
authResponse: null,
|
431
|
-
status: 'unknown'
|
432
|
-
};
|
433
|
-
}
|
434
|
-
|
435
|
-
};
|
436
|
-
|
437
|
-
function calledBeforeInit() {
|
438
|
-
if (FBWorld.initialized) return false;
|
439
|
-
console.log("FB."+meth+" called before FB.init");
|
440
|
-
return true;
|
441
|
-
}
|
442
|
-
|
443
|
-
var cookieOptions = { path: '/', domain: window.location.hostname.replace(/^www/, '')};
|
444
|
-
|
445
|
-
// cookie looks like this: (with the quotes): "access_token=theToken&base_domain=local-change.org&expires=0&secret=theSecret&session_key=theSessionKeysig=theSig-Hashed&uid=theUID"
|
446
|
-
function createConnectedCookie() {
|
447
|
-
var theState = {
|
448
|
-
user_id: state('uid'),
|
449
|
-
code: 'theAccessToken|hashData',
|
450
|
-
// We need to verify the timezone for this value. Traditionally FB uses PST8PDT, but it may be UTC.
|
451
|
-
issued_at: Math.floor(new Date().getTime() / 1000)
|
452
|
-
};
|
453
|
-
|
454
|
-
if (uid() != null) {
|
455
|
-
theState.uid = uid();
|
456
|
-
}
|
457
|
-
|
458
|
-
FBWorld.Helpers.makeMeACookie('fbsr_'+state('appId'), cookieToString(theState, state('secret')), cookieOptions);
|
459
|
-
return theState;
|
460
|
-
}
|
461
|
-
|
462
|
-
function cookieToString(theState, secret) {
|
463
|
-
// Set the algorithm here, to keep any changes here.
|
464
|
-
theState.algorithm = 'HMAC-SHA256';
|
465
|
-
|
466
|
-
var payload = JSON.stringify(theState),
|
467
|
-
encodedPayload = FBWorld.Helpers.base64_encode(payload),
|
468
|
-
shaObj = new FBWorld.Helpers.jsSHA(encodedPayload, "ASCII"),
|
469
|
-
b64Signature = shaObj.getHMAC(secret, "ASCII", "SHA-256", "B64");
|
470
|
-
|
471
|
-
// jsSHA uses an odd Base64 encoder, which uses + where FB has -. For now we'll just replace them,
|
472
|
-
// but if we find other inconsistencies, we should use the HEX value and encode it ourselves.
|
473
|
-
b64Signature.replace('+', '-');
|
474
|
-
|
475
|
-
return b64Signature + '.' + encodedPayload;
|
476
|
-
}
|
477
|
-
|
478
|
-
function deleteConnectedCookie() {
|
479
|
-
FBWorld.Helpers.makeMeACookie('fbsr_'+state('appId'), null, cookieOptions);
|
480
|
-
}
|
481
|
-
|
482
|
-
|
483
|
-
})(this);
|
484
|
-
FBWorld.Helpers = {};
|
485
|
-
setTimeout(function() { if (typeof fbAsyncInit === 'function') fbAsyncInit(); }, 1);
|
486
|
-
FBWorld.Helpers.base64_encode = function (data, utf8encode) {
|
487
|
-
// http://kevin.vanzonneveld.net
|
488
|
-
// + original by: Tyler Akins (http://rumkin.com)
|
489
|
-
// + improved by: Bayron Guevara
|
490
|
-
// + improved by: Thunder.m
|
491
|
-
// + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
|
492
|
-
// + bugfixed by: Pellentesque Malesuada
|
493
|
-
// + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
|
494
|
-
// + improved by: Rafał Kukawski (http://kukawski.pl)
|
495
|
-
// - depends on: utf8_encode
|
496
|
-
// * example 1: base64_encode('Kevin van Zonneveld');
|
497
|
-
// * returns 1: 'S2V2aW4gdmFuIFpvbm5ldmVsZA=='
|
498
|
-
// mozilla has this native
|
499
|
-
// - but breaks in 2.0.0.12!
|
500
|
-
//if (typeof this.window['atob'] == 'function') {
|
501
|
-
// return atob(data);
|
502
|
-
//}
|
503
|
-
var b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
|
504
|
-
var o1, o2, o3, h1, h2, h3, h4, bits, i = 0,
|
505
|
-
ac = 0,
|
506
|
-
enc = "",
|
507
|
-
tmp_arr = [];
|
508
|
-
|
509
|
-
if (!data) {
|
510
|
-
return data;
|
511
|
-
}
|
512
|
-
|
513
|
-
// Only do this if forced
|
514
|
-
if (utf8encode)
|
515
|
-
data = this.utf8_encode(data + '');
|
516
|
-
|
517
|
-
do { // pack three octets into four hexets
|
518
|
-
o1 = data.charCodeAt(i++);
|
519
|
-
o2 = data.charCodeAt(i++);
|
520
|
-
o3 = data.charCodeAt(i++);
|
521
|
-
|
522
|
-
bits = o1 << 16 | o2 << 8 | o3;
|
523
|
-
|
524
|
-
h1 = bits >> 18 & 0x3f;
|
525
|
-
h2 = bits >> 12 & 0x3f;
|
526
|
-
h3 = bits >> 6 & 0x3f;
|
527
|
-
h4 = bits & 0x3f;
|
528
|
-
|
529
|
-
// use hexets to index into b64, and append result to encoded string
|
530
|
-
tmp_arr[ac++] = b64.charAt(h1) + b64.charAt(h2) + b64.charAt(h3) + b64.charAt(h4);
|
531
|
-
} while (i < data.length);
|
532
|
-
|
533
|
-
enc = tmp_arr.join('');
|
534
|
-
|
535
|
-
var r = data.length % 3;
|
536
|
-
|
537
|
-
return (r ? enc.slice(0, r - 3) : enc) + '==='.slice(r || 3);
|
538
|
-
|
539
|
-
};
|
540
|
-
/**
|
541
|
-
* Cookie plugin
|
542
|
-
*
|
543
|
-
* Copyright (c) 2006 Klaus Hartl (stilbuero.de)
|
544
|
-
* Dual licensed under the MIT and GPL licenses:
|
545
|
-
* http://www.opensource.org/licenses/mit-license.php
|
546
|
-
* http://www.gnu.org/licenses/gpl.html
|
547
|
-
*
|
548
|
-
*/
|
549
|
-
|
550
|
-
/**
|
551
|
-
* Create a cookie with the given name and value and other optional parameters.
|
552
|
-
*
|
553
|
-
* @example $.cookie('the_cookie', 'the_value');
|
554
|
-
* @desc Set the value of a cookie.
|
555
|
-
* @example $.cookie('the_cookie', 'the_value', { expires: 7, path: '/', domain: 'jquery.com', secure: true });
|
556
|
-
* @desc Create a cookie with all available options.
|
557
|
-
* @example $.cookie('the_cookie', 'the_value');
|
558
|
-
* @desc Create a session cookie.
|
559
|
-
* @example $.cookie('the_cookie', null);
|
560
|
-
* @desc Delete a cookie by passing null as value. Keep in mind that you have to use the same path and domain
|
561
|
-
* used when the cookie was set.
|
562
|
-
*
|
563
|
-
* @param String name The name of the cookie.
|
564
|
-
* @param String value The value of the cookie.
|
565
|
-
* @param Object options An object literal containing key/value pairs to provide optional cookie attributes.
|
566
|
-
* @option Number|Date expires Either an integer specifying the expiration date from now on in days or a Date object.
|
567
|
-
* If a negative value is specified (e.g. a date in the past), the cookie will be deleted.
|
568
|
-
* If set to null or omitted, the cookie will be a session cookie and will not be retained
|
569
|
-
* when the the browser exits.
|
570
|
-
* @option String path The value of the path atribute of the cookie (default: path of page that created the cookie).
|
571
|
-
* @option String domain The value of the domain attribute of the cookie (default: domain of page that created the cookie).
|
572
|
-
* @option Boolean secure If true, the secure attribute of the cookie will be set and the cookie transmission will
|
573
|
-
* require a secure protocol (like HTTPS).
|
574
|
-
* @type undefined
|
575
|
-
*
|
576
|
-
* @name $.cookie
|
577
|
-
* @cat Plugins/Cookie
|
578
|
-
* @author Klaus Hartl/klaus.hartl@stilbuero.de
|
579
|
-
*/
|
580
|
-
|
581
|
-
/**
|
582
|
-
* Get the value of a cookie with the given name.
|
583
|
-
*
|
584
|
-
* @example $.cookie('the_cookie');
|
585
|
-
* @desc Get the value of a cookie.
|
586
|
-
*
|
587
|
-
* @param String name The name of the cookie.
|
588
|
-
* @return The value of the cookie.
|
589
|
-
* @type String
|
590
|
-
*
|
591
|
-
* @name $.cookie
|
592
|
-
* @cat Plugins/Cookie
|
593
|
-
* @author Klaus Hartl/klaus.hartl@stilbuero.de
|
594
|
-
*/
|
595
|
-
|
596
|
-
// Modified to make it not use jquery
|
597
|
-
FBWorld.Helpers.makeMeACookie = function(name, value, options) {
|
598
|
-
if (typeof value != 'undefined') { // name and value given, set cookie
|
599
|
-
options = options || {};
|
600
|
-
if (value === null) {
|
601
|
-
value = '';
|
602
|
-
options.expires = -1;
|
603
|
-
} else {
|
604
|
-
options.expires = 100; // 100 days from now
|
605
|
-
}
|
606
|
-
var expires = '';
|
607
|
-
if (options.expires && (typeof options.expires == 'number' || options.expires.toUTCString)) {
|
608
|
-
var date;
|
609
|
-
if (typeof options.expires == 'number') {
|
610
|
-
date = new Date();
|
611
|
-
date.setTime(date.getTime() + (options.expires * 24 * 60 * 60 * 1000));
|
612
|
-
} else {
|
613
|
-
date = options.expires;
|
614
|
-
}
|
615
|
-
expires = '; expires=' + date.toUTCString(); // use expires attribute, max-age is not supported by IE
|
616
|
-
}
|
617
|
-
// CAUTION: Needed to parenthesize options.path and options.domain
|
618
|
-
// in the following expressions, otherwise they evaluate to undefined
|
619
|
-
// in the packed version for some reason...
|
620
|
-
var path = options.path ? '; path=' + (options.path) : '';
|
621
|
-
var domain = options.domain ? '; domain=' + (options.domain) : '';
|
622
|
-
var secure = options.secure ? '; secure' : '';
|
623
|
-
document.cookie = [name, '=', encodeURIComponent(value), expires, path, domain, secure].join('');
|
624
|
-
} else { // only name given, get cookie
|
625
|
-
var cookieValue = null;
|
626
|
-
if (document.cookie && document.cookie != '') {
|
627
|
-
var cookies = document.cookie.split(';');
|
628
|
-
for (var i = 0; i < cookies.length; i++) {
|
629
|
-
var cookie = FBWorld.Helpers.trim(cookies[i]);
|
630
|
-
// Does this cookie string begin with the name we want?
|
631
|
-
if (cookie.substring(0, name.length + 1) == (name + '=')) {
|
632
|
-
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
|
633
|
-
break;
|
634
|
-
}
|
635
|
-
}
|
636
|
-
}
|
637
|
-
return cookieValue;
|
638
|
-
}
|
639
|
-
};
|
640
|
-
|
641
|
-
//Taken from jQuery
|
642
|
-
FBWorld.Helpers.trim = function( text ) {
|
643
|
-
return text == null ?
|
644
|
-
"" :
|
645
|
-
text.toString().replace( /^\s+/, "" ).replace( /\s+$/, "" );
|
646
|
-
};
|
647
|
-
/* A JavaScript implementation of the SHA family of hashes, as defined in FIPS
|
648
|
-
* PUB 180-2 as well as the corresponding HMAC implementation as defined in
|
649
|
-
* FIPS PUB 198a
|
650
|
-
*
|
651
|
-
* Version 1.3 Copyright Brian Turek 2008-2010
|
652
|
-
* Distributed under the BSD License
|
653
|
-
* See http://jssha.sourceforge.net/ for more information
|
654
|
-
*
|
655
|
-
* Several functions taken from Paul Johnson
|
656
|
-
*/
|
657
|
-
(function(){var charSize=8,b64pad="",hexCase=0,str2binb=function(a){var b=[],mask=(1<<charSize)-1,length=a.length*charSize,i;for(i=0;i<length;i+=charSize){b[i>>5]|=(a.charCodeAt(i/charSize)&mask)<<(32-charSize-(i%32))}return b},hex2binb=function(a){var b=[],length=a.length,i,num;for(i=0;i<length;i+=2){num=parseInt(a.substr(i,2),16);if(!isNaN(num)){b[i>>3]|=num<<(24-(4*(i%8)))}else{return"INVALID HEX STRING"}}return b},binb2hex=function(a){var b=(hexCase)?"0123456789ABCDEF":"0123456789abcdef",str="",length=a.length*4,i,srcByte;for(i=0;i<length;i+=1){srcByte=a[i>>2]>>((3-(i%4))*8);str+=b.charAt((srcByte>>4)&0xF)+b.charAt(srcByte&0xF)}return str},binb2b64=function(a){var b="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"+"0123456789+/",str="",length=a.length*4,i,j,triplet;for(i=0;i<length;i+=3){triplet=(((a[i>>2]>>8*(3-i%4))&0xFF)<<16)|(((a[i+1>>2]>>8*(3-(i+1)%4))&0xFF)<<8)|((a[i+2>>2]>>8*(3-(i+2)%4))&0xFF);for(j=0;j<4;j+=1){if(i*8+j*6<=a.length*32){str+=b.charAt((triplet>>6*(3-j))&0x3F)}else{str+=b64pad}}}return str},rotr=function(x,n){return(x>>>n)|(x<<(32-n))},shr=function(x,n){return x>>>n},ch=function(x,y,z){return(x&y)^(~x&z)},maj=function(x,y,z){return(x&y)^(x&z)^(y&z)},sigma0=function(x){return rotr(x,2)^rotr(x,13)^rotr(x,22)},sigma1=function(x){return rotr(x,6)^rotr(x,11)^rotr(x,25)},gamma0=function(x){return rotr(x,7)^rotr(x,18)^shr(x,3)},gamma1=function(x){return rotr(x,17)^rotr(x,19)^shr(x,10)},safeAdd_2=function(x,y){var a=(x&0xFFFF)+(y&0xFFFF),msw=(x>>>16)+(y>>>16)+(a>>>16);return((msw&0xFFFF)<<16)|(a&0xFFFF)},safeAdd_4=function(a,b,c,d){var e=(a&0xFFFF)+(b&0xFFFF)+(c&0xFFFF)+(d&0xFFFF),msw=(a>>>16)+(b>>>16)+(c>>>16)+(d>>>16)+(e>>>16);return((msw&0xFFFF)<<16)|(e&0xFFFF)},safeAdd_5=function(a,b,c,d,e){var f=(a&0xFFFF)+(b&0xFFFF)+(c&0xFFFF)+(d&0xFFFF)+(e&0xFFFF),msw=(a>>>16)+(b>>>16)+(c>>>16)+(d>>>16)+(e>>>16)+(f>>>16);return((msw&0xFFFF)<<16)|(f&0xFFFF)},coreSHA2=function(j,k,l){var a,b,c,d,e,f,g,h,T1,T2,H,lengthPosition,i,t,K,W=[],appendedMessageLength;if(l==="SHA-224"||l==="SHA-256"){lengthPosition=(((k+65)>>9)<<4)+15;K=[0x428A2F98,0x71374491,0xB5C0FBCF,0xE9B5DBA5,0x3956C25B,0x59F111F1,0x923F82A4,0xAB1C5ED5,0xD807AA98,0x12835B01,0x243185BE,0x550C7DC3,0x72BE5D74,0x80DEB1FE,0x9BDC06A7,0xC19BF174,0xE49B69C1,0xEFBE4786,0x0FC19DC6,0x240CA1CC,0x2DE92C6F,0x4A7484AA,0x5CB0A9DC,0x76F988DA,0x983E5152,0xA831C66D,0xB00327C8,0xBF597FC7,0xC6E00BF3,0xD5A79147,0x06CA6351,0x14292967,0x27B70A85,0x2E1B2138,0x4D2C6DFC,0x53380D13,0x650A7354,0x766A0ABB,0x81C2C92E,0x92722C85,0xA2BFE8A1,0xA81A664B,0xC24B8B70,0xC76C51A3,0xD192E819,0xD6990624,0xF40E3585,0x106AA070,0x19A4C116,0x1E376C08,0x2748774C,0x34B0BCB5,0x391C0CB3,0x4ED8AA4A,0x5B9CCA4F,0x682E6FF3,0x748F82EE,0x78A5636F,0x84C87814,0x8CC70208,0x90BEFFFA,0xA4506CEB,0xBEF9A3F7,0xC67178F2];if(l==="SHA-224"){H=[0xc1059ed8,0x367cd507,0x3070dd17,0xf70e5939,0xffc00b31,0x68581511,0x64f98fa7,0xbefa4fa4]}else{H=[0x6A09E667,0xBB67AE85,0x3C6EF372,0xA54FF53A,0x510E527F,0x9B05688C,0x1F83D9AB,0x5BE0CD19]}}j[k>>5]|=0x80<<(24-k%32);j[lengthPosition]=k;appendedMessageLength=j.length;for(i=0;i<appendedMessageLength;i+=16){a=H[0];b=H[1];c=H[2];d=H[3];e=H[4];f=H[5];g=H[6];h=H[7];for(t=0;t<64;t+=1){if(t<16){W[t]=j[t+i]}else{W[t]=safeAdd_4(gamma1(W[t-2]),W[t-7],gamma0(W[t-15]),W[t-16])}T1=safeAdd_5(h,sigma1(e),ch(e,f,g),K[t],W[t]);T2=safeAdd_2(sigma0(a),maj(a,b,c));h=g;g=f;f=e;e=safeAdd_2(d,T1);d=c;c=b;b=a;a=safeAdd_2(T1,T2)}H[0]=safeAdd_2(a,H[0]);H[1]=safeAdd_2(b,H[1]);H[2]=safeAdd_2(c,H[2]);H[3]=safeAdd_2(d,H[3]);H[4]=safeAdd_2(e,H[4]);H[5]=safeAdd_2(f,H[5]);H[6]=safeAdd_2(g,H[6]);H[7]=safeAdd_2(h,H[7])}switch(l){case"SHA-224":return[H[0],H[1],H[2],H[3],H[4],H[5],H[6]];case"SHA-256":return H;default:return[]}},jsSHA=function(a,b){this.sha224=null;this.sha256=null;this.strBinLen=null;this.strToHash=null;if("HEX"===b){if(0!==(a.length%2)){return"TEXT MUST BE IN BYTE INCREMENTS"}this.strBinLen=a.length*4;this.strToHash=hex2binb(a)}else if(("ASCII"===b)||('undefined'===typeof(b))){this.strBinLen=a.length*charSize;this.strToHash=str2binb(a)}else{return"UNKNOWN TEXT INPUT TYPE"}};jsSHA.prototype={getHash:function(a,b){var c=null,message=this.strToHash.slice();switch(b){case"HEX":c=binb2hex;break;case"B64":c=binb2b64;break;default:return"FORMAT NOT RECOGNIZED"}switch(a){case"SHA-224":if(null===this.sha224){this.sha224=coreSHA2(message,this.strBinLen,a)}return c(this.sha224);case"SHA-256":if(null===this.sha256){this.sha256=coreSHA2(message,this.strBinLen,a)}return c(this.sha256);default:return"HASH NOT RECOGNIZED"}},getHMAC:function(a,b,c,d){var e,keyToUse,i,retVal,keyBinLen,hashBitSize,keyWithIPad=[],keyWithOPad=[];switch(d){case"HEX":e=binb2hex;break;case"B64":e=binb2b64;break;default:return"FORMAT NOT RECOGNIZED"}switch(c){case"SHA-224":hashBitSize=224;break;case"SHA-256":hashBitSize=256;break;default:return"HASH NOT RECOGNIZED"}if("HEX"===b){if(0!==(a.length%2)){return"KEY MUST BE IN BYTE INCREMENTS"}keyToUse=hex2binb(a);keyBinLen=a.length*4}else if("ASCII"===b){keyToUse=str2binb(a);keyBinLen=a.length*charSize}else{return"UNKNOWN KEY INPUT TYPE"}if(64<(keyBinLen/8)){keyToUse=coreSHA2(keyToUse,keyBinLen,c);keyToUse[15]&=0xFFFFFF00}else if(64>(keyBinLen/8)){keyToUse[15]&=0xFFFFFF00}for(i=0;i<=15;i+=1){keyWithIPad[i]=keyToUse[i]^0x36363636;keyWithOPad[i]=keyToUse[i]^0x5C5C5C5C}retVal=coreSHA2(keyWithIPad.concat(this.strToHash),512+this.strBinLen,c);retVal=coreSHA2(keyWithOPad.concat(retVal),512+hashBitSize,c);return(e(retVal))}};window.FBWorld.Helpers.jsSHA=jsSHA}());
|
658
|
-
FBWorld.Helpers.utf8_encode = function (argString) {
|
659
|
-
// http://kevin.vanzonneveld.net
|
660
|
-
// + original by: Webtoolkit.info (http://www.webtoolkit.info/)
|
661
|
-
// + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
|
662
|
-
// + improved by: sowberry
|
663
|
-
// + tweaked by: Jack
|
664
|
-
// + bugfixed by: Onno Marsman
|
665
|
-
// + improved by: Yves Sucaet
|
666
|
-
// + bugfixed by: Onno Marsman
|
667
|
-
// + bugfixed by: Ulrich
|
668
|
-
// + bugfixed by: Rafal Kukawski
|
669
|
-
// * example 1: utf8_encode('Kevin van Zonneveld');
|
670
|
-
// * returns 1: 'Kevin van Zonneveld'
|
671
|
-
|
672
|
-
if (argString === null || typeof argString === "undefined") {
|
673
|
-
return "";
|
674
|
-
}
|
675
|
-
|
676
|
-
var string = (argString + ''); // .replace(/\r\n/g, "\n").replace(/\r/g, "\n");
|
677
|
-
var utftext = "",
|
678
|
-
start, end, stringl = 0;
|
679
|
-
|
680
|
-
start = end = 0;
|
681
|
-
stringl = string.length;
|
682
|
-
for (var n = 0; n < stringl; n++) {
|
683
|
-
var c1 = string.charCodeAt(n);
|
684
|
-
var enc = null;
|
685
|
-
|
686
|
-
if (c1 < 128) {
|
687
|
-
end++;
|
688
|
-
} else if (c1 > 127 && c1 < 2048) {
|
689
|
-
enc = String.fromCharCode((c1 >> 6) | 192) + String.fromCharCode((c1 & 63) | 128);
|
690
|
-
} else {
|
691
|
-
enc = String.fromCharCode((c1 >> 12) | 224) + String.fromCharCode(((c1 >> 6) & 63) | 128) + String.fromCharCode((c1 & 63) | 128);
|
692
|
-
}
|
693
|
-
if (enc !== null) {
|
694
|
-
if (end > start) {
|
695
|
-
utftext += string.slice(start, end);
|
696
|
-
}
|
697
|
-
utftext += enc;
|
698
|
-
start = end = n + 1;
|
699
|
-
}
|
700
|
-
}
|
701
|
-
|
702
|
-
if (end > start) {
|
703
|
-
utftext += string.slice(start, stringl);
|
704
|
-
}
|
705
|
-
|
706
|
-
return utftext;
|
707
|
-
}
|