PageRenderTime 28ms CodeModel.GetById 9ms RepoModel.GetById 1ms app.codeStats 0ms

/files/oauthjs/0.1/oauth.js

https://gitlab.com/Mirros/jsdelivr
JavaScript | 644 lines | 495 code | 71 blank | 78 comment | 114 complexity | fa0aba88285cd14c16bc128942c860e2 MD5 | raw file
  1. (function() {
  2. "use strict";
  3. var config = {
  4. oauthd_url: 'https://oauth.io/auth'
  5. };
  6. if ( ! window.OAuth) {
  7. if (typeof jQuery == 'undefined')
  8. {
  9. var _preloadcalls = [];
  10. var e = document.createElement("script");
  11. e.src = "http://code.jquery.com/jquery.min.js";
  12. e.type = "text/javascript";
  13. e.onload = function() {
  14. buildOAuth(jQuery);
  15. console.log(_preloadcalls);
  16. for (var i in _preloadcalls)
  17. window.OAuth[_preloadcalls[i].method].apply(window.OAuth, _preloadcalls[i].args);
  18. };
  19. document.getElementsByTagName("head")[0].appendChild(e);
  20. var methods = ["initialize", "popup", "redirect", "callback", "http"];
  21. window.OAuth = {};
  22. var push_method = function(method) {
  23. window.OAuth[method] = function() {
  24. var args_copy = [];
  25. for (var arg in arguments)
  26. args_copy[arg] = arguments[arg];
  27. _preloadcalls.push({method:method, args:args_copy});
  28. };
  29. };
  30. for (var i in methods)
  31. push_method(methods[i]);
  32. }
  33. else
  34. buildOAuth(jQuery);
  35. }
  36. config.oauthd_base = getAbsUrl(config.oauthd_url).match(/^.{2,5}:\/\/[^/]+/)[0];
  37. var client_states = [];
  38. var oauth_result;
  39. (function parse_urlfragment() {
  40. var results = /[\\#&]oauthio=([^&]*)/.exec(document.location.hash);
  41. if (results) {
  42. document.location.hash = '';
  43. oauth_result = decodeURIComponent(results[1].replace(/\+/g, " "));
  44. var cookie_state = readCookie("oauthio_state");
  45. if (cookie_state) {
  46. client_states.push(cookie_state);
  47. eraseCookie("oauthio_state");
  48. }
  49. }
  50. })();
  51. function getAbsUrl(url) {
  52. if (url[0] === '/')
  53. url = document.location.protocol + '//' + document.location.host + url;
  54. else if ( ! url.match(/^.{2,5}:\/\//))
  55. url = document.location.protocol + '//' + document.location.host + document.location.pathname + '/' + url;
  56. return url;
  57. }
  58. function replaceParam(param, rep) {
  59. return param.replace(/\{\{(.*?)\}\}/g, function(m,v) {
  60. return rep[v] || "";
  61. });
  62. }
  63. function sendCallback(opts) {
  64. var data;
  65. var err;
  66. try {
  67. data = JSON.parse(opts.data);
  68. } catch (e) {}
  69. if ( ! data || ! data.provider)
  70. return;
  71. if (opts.provider && data.provider.toLowerCase() !== opts.provider.toLowerCase())
  72. return;
  73. if (data.status === 'error' || data.status === 'fail') {
  74. err = new Error(data.message);
  75. err.body = data.data;
  76. return opts.callback(err);
  77. }
  78. if (data.status !== 'success' || ! data.data) {
  79. err = new Error();
  80. err.body = data.data;
  81. return opts.callback(err);
  82. }
  83. if ( ! data.state || client_states.indexOf(data.state) == -1)
  84. return opts.callback(new Error('State is not matching'));
  85. if ( ! opts.provider)
  86. data.data.provider = data.provider;
  87. function make_res(provider, tokens, request, method) {
  88. return function(opts) {
  89. var options = {};
  90. if (typeof opts === 'string')
  91. options = {url:opts};
  92. else if (typeof opts === 'object')
  93. for (var i in opts) { options[i] = opts[i]; }
  94. options.type = options.type || method;
  95. options.oauthio = {provider:provider, tokens:tokens, request:request};
  96. return OAuth.http(options);
  97. };
  98. }
  99. var res = data.data;
  100. var request = res.request;
  101. delete res.request;
  102. var tokens;
  103. if (res.access_token)
  104. tokens = { access_token: res.access_token };
  105. else if (res.oauth_token && res.oauth_token_secret)
  106. tokens = { oauth_token: res.oauth_token, oauth_token_secret: res.oauth_token_secret};
  107. res.get = make_res(data.provider, tokens, request, 'GET');
  108. res.post = make_res(data.provider, tokens, request, 'POST');
  109. res.put = make_res(data.provider, tokens, request, 'PUT');
  110. res.patch = make_res(data.provider, tokens, request, 'PATCH');
  111. res.del = make_res(data.provider, tokens, request, 'DELETE');
  112. return opts.callback(null, res, request);
  113. }
  114. function buildOAuth($) {
  115. window.OAuth = {
  116. initialize: function(public_key) {
  117. config.key = public_key;
  118. },
  119. popup: function(provider, opts, callback) {
  120. var wnd;
  121. if ( ! config.key)
  122. return callback(new Error('OAuth object must be initialized'));
  123. if (arguments.length == 2) {
  124. callback = opts;
  125. opts = {};
  126. }
  127. if ( ! opts.state) {
  128. opts.state = create_hash();
  129. opts.state_type = "client";
  130. }
  131. client_states.push(opts.state);
  132. var url = config.oauthd_base + '/auth/' + provider + "?k=" + config.key;
  133. url += '&d=' + encodeURIComponent(getAbsUrl('/'));
  134. if (opts)
  135. url += "&opts=" + encodeURIComponent(JSON.stringify(opts));
  136. // create popup
  137. var wnd_settings = {
  138. width: Math.floor(window.outerWidth * 0.8),
  139. height: Math.floor(window.outerHeight * 0.5)
  140. };
  141. if (wnd_settings.height < 350)
  142. wnd_settings.height = 350;
  143. if (wnd_settings.width < 800)
  144. wnd_settings.width = 800;
  145. wnd_settings.left = window.screenX + (window.outerWidth - wnd_settings.width) / 2;
  146. wnd_settings.top = window.screenY + (window.outerHeight - wnd_settings.height) / 8;
  147. var wnd_options = "width=" + wnd_settings.width + ",height=" + wnd_settings.height;
  148. wnd_options += ",toolbar=0,scrollbars=1,status=1,resizable=1,location=1,menuBar=0";
  149. wnd_options += ",left=" + wnd_settings.left + ",top=" + wnd_settings.top;
  150. opts = {provider:provider};
  151. function getMessage(e) {
  152. if (e.source !== wnd || e.origin !== config.oauthd_base)
  153. return;
  154. opts.data = e.data;
  155. return sendCallback(opts);
  156. }
  157. opts.callback = function(e, r) {
  158. if (window.removeEventListener)
  159. window.removeEventListener("message", getMessage, false);
  160. else if (window.detachEvent)
  161. window.detachEvent("onmessage", getMessage);
  162. else if (document.detachEvent)
  163. document.detachEvent("onmessage", getMessage);
  164. opts.callback = function() {};
  165. return callback(e,r);
  166. };
  167. if (window.attachEvent)
  168. window.attachEvent("onmessage", getMessage);
  169. else if (document.attachEvent)
  170. document.attachEvent("onmessage", getMessage);
  171. else if (window.addEventListener)
  172. window.addEventListener("message", getMessage, false);
  173. setTimeout(function() {
  174. opts.callback(new Error('Authorization timed out'));
  175. }, 600 * 1000);
  176. wnd = window.open(url, "Authorization", wnd_options);
  177. if (wnd)
  178. wnd.focus();
  179. },
  180. redirect: function(provider, opts, url) {
  181. if (arguments.length == 2) {
  182. url = opts;
  183. opts = {};
  184. }
  185. if ( ! opts.state) {
  186. opts.state = create_hash();
  187. opts.state_type = "client";
  188. }
  189. createCookie("oauthio_state", opts.state);
  190. var redirect_uri = encodeURIComponent(getAbsUrl(url));
  191. url = config.oauthd_base + '/auth/' + provider + "?k=" + config.key;
  192. url += "&redirect_uri=" + redirect_uri;
  193. if (opts)
  194. url += "&opts=" + encodeURIComponent(JSON.stringify(opts));
  195. document.location.href = url;
  196. },
  197. callback: function(provider, callback) {
  198. if ( ! oauth_result)
  199. return;
  200. if (arguments.length === 1)
  201. return sendCallback({data:oauth_result, callback:provider});
  202. return sendCallback({data:oauth_result, provider:provider, callback:callback});
  203. },
  204. http: function(opts) {
  205. var options = {};
  206. var i;
  207. for (i in opts) { options[i] = opts[i]; }
  208. if ( ! options.oauthio.request.cors) {
  209. if (options.url && options.url[0] != '/' )
  210. options.url = '/' + options.url;
  211. options.url = config.oauthd_base + '/request/' + options.oauthio.provider + options.url;
  212. options.headers = options.headers || {};
  213. options.headers.oauthio = 'k=' + config.key;
  214. if (options.oauthio.tokens.oauth_token && options.oauthio.tokens.oauth_token_secret)
  215. options.headers.oauthio += '&oauthv=1'; // make sure to use oauth 1
  216. for (var k in options.oauthio.tokens)
  217. options.headers.oauthio += '&' + encodeURIComponent(k) + '=' + encodeURIComponent(options.oauthio.tokens[k]);
  218. delete options.oauthio;
  219. return $.ajax(options);
  220. }
  221. if (options.oauthio.tokens.access_token) {
  222. if ( ! options.url.match(/^[a-z]{2,16}:\/\//)) {
  223. if (options.url[0] !== '/')
  224. options.url = '/' + options.url;
  225. options.url = options.oauthio.request.url + options.url;
  226. }
  227. var qs = [];
  228. for (i in (options.oauthio.request.query||{}))
  229. qs.push(encodeURIComponent(i) + '=' + encodeURIComponent(
  230. replaceParam(options.oauthio.request.query[i], {
  231. token: options.oauthio.tokens.access_token
  232. })
  233. ));
  234. qs = qs.join('&');
  235. if (options.url.indexOf('?') !== -1)
  236. options.url += '&' + qs;
  237. else
  238. options.url += '?' + qs;
  239. for (i in (options.oauthio.request.headers||{}))
  240. options.headers[i] = replaceParam(options.oauthio.request.headers[i], {
  241. token: options.oauthio.tokens.access_token
  242. });
  243. delete options.oauthio;
  244. return $.ajax(options);
  245. }
  246. }
  247. };
  248. }
  249. function create_hash() {
  250. var hash = b64_sha1((new Date()).getTime() + ':' + Math.floor(Math.random()*9999999));
  251. return hash.replace(/\+/g, '-').replace(/\//g, '_').replace(/\=+$/, '');
  252. }
  253. function createCookie(name, value) {
  254. eraseCookie(name);
  255. var date = new Date();
  256. date.setTime(date.getTime() + 600000); // +10 mins
  257. var expires = "; expires="+date.toGMTString();
  258. document.cookie = name+"="+value+expires+"; path=/";
  259. }
  260. function readCookie(name) {
  261. var nameEQ = name + "=";
  262. var ca = document.cookie.split(';');
  263. for(var i = 0; i < ca.length; i++) {
  264. var c = ca[i];
  265. while (c.charAt(0) === ' ') c = c.substring(1,c.length);
  266. if (c.indexOf(nameEQ) === 0) return c.substring(nameEQ.length,c.length);
  267. }
  268. return null;
  269. }
  270. function eraseCookie(name) {
  271. var date = new Date();
  272. date.setTime(date.getTime() - 86400000);
  273. document.cookie = name+"=; expires="+date.toGMTString()+"; path=/";
  274. }
  275. /*
  276. * A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined
  277. * in FIPS 180-1
  278. * Version 2.2 Copyright Paul Johnston 2000 - 2009.
  279. * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
  280. * Distributed under the BSD License
  281. * See http://pajhome.org.uk/crypt/md5 for details.
  282. */
  283. /*
  284. * Configurable variables. You may need to tweak these to be compatible with
  285. * the server-side, but the defaults work in most cases.
  286. */
  287. var hexcase = 0; /* hex output format. 0 - lowercase; 1 - uppercase */
  288. var b64pad = ""; /* base-64 pad character. "=" for strict RFC compliance */
  289. /*
  290. * These are the functions you'll usually want to call
  291. * They take string arguments and return either hex or base-64 encoded strings
  292. */
  293. function hex_sha1(s) { return rstr2hex(rstr_sha1(str2rstr_utf8(s))); }
  294. function b64_sha1(s) { return rstr2b64(rstr_sha1(str2rstr_utf8(s))); }
  295. function any_sha1(s, e) { return rstr2any(rstr_sha1(str2rstr_utf8(s)), e); }
  296. function hex_hmac_sha1(k, d)
  297. { return rstr2hex(rstr_hmac_sha1(str2rstr_utf8(k), str2rstr_utf8(d))); }
  298. function b64_hmac_sha1(k, d)
  299. { return rstr2b64(rstr_hmac_sha1(str2rstr_utf8(k), str2rstr_utf8(d))); }
  300. function any_hmac_sha1(k, d, e)
  301. { return rstr2any(rstr_hmac_sha1(str2rstr_utf8(k), str2rstr_utf8(d)), e); }
  302. /*
  303. * Perform a simple self-test to see if the VM is working
  304. */
  305. function sha1_vm_test()
  306. {
  307. return hex_sha1("abc").toLowerCase() == "a9993e364706816aba3e25717850c26c9cd0d89d";
  308. }
  309. /*
  310. * Calculate the SHA1 of a raw string
  311. */
  312. function rstr_sha1(s)
  313. {
  314. return binb2rstr(binb_sha1(rstr2binb(s), s.length * 8));
  315. }
  316. /*
  317. * Calculate the HMAC-SHA1 of a key and some data (raw strings)
  318. */
  319. function rstr_hmac_sha1(key, data)
  320. {
  321. var bkey = rstr2binb(key);
  322. if(bkey.length > 16) bkey = binb_sha1(bkey, key.length * 8);
  323. var ipad = Array(16), opad = Array(16);
  324. for(var i = 0; i < 16; i++)
  325. {
  326. ipad[i] = bkey[i] ^ 0x36363636;
  327. opad[i] = bkey[i] ^ 0x5C5C5C5C;
  328. }
  329. var hash = binb_sha1(ipad.concat(rstr2binb(data)), 512 + data.length * 8);
  330. return binb2rstr(binb_sha1(opad.concat(hash), 512 + 160));
  331. }
  332. /*
  333. * Convert a raw string to a hex string
  334. */
  335. function rstr2hex(input)
  336. {
  337. try { hexcase } catch(e) { hexcase=0; }
  338. var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
  339. var output = "";
  340. var x;
  341. for(var i = 0; i < input.length; i++)
  342. {
  343. x = input.charCodeAt(i);
  344. output += hex_tab.charAt((x >>> 4) & 0x0F)
  345. + hex_tab.charAt( x & 0x0F);
  346. }
  347. return output;
  348. }
  349. /*
  350. * Convert a raw string to a base-64 string
  351. */
  352. function rstr2b64(input)
  353. {
  354. try { b64pad } catch(e) { b64pad=''; }
  355. var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  356. var output = "";
  357. var len = input.length;
  358. for(var i = 0; i < len; i += 3)
  359. {
  360. var triplet = (input.charCodeAt(i) << 16)
  361. | (i + 1 < len ? input.charCodeAt(i+1) << 8 : 0)
  362. | (i + 2 < len ? input.charCodeAt(i+2) : 0);
  363. for(var j = 0; j < 4; j++)
  364. {
  365. if(i * 8 + j * 6 > input.length * 8) output += b64pad;
  366. else output += tab.charAt((triplet >>> 6*(3-j)) & 0x3F);
  367. }
  368. }
  369. return output;
  370. }
  371. /*
  372. * Convert a raw string to an arbitrary string encoding
  373. */
  374. function rstr2any(input, encoding)
  375. {
  376. var divisor = encoding.length;
  377. var remainders = Array();
  378. var i, q, x, quotient;
  379. /* Convert to an array of 16-bit big-endian values, forming the dividend */
  380. var dividend = Array(Math.ceil(input.length / 2));
  381. for(i = 0; i < dividend.length; i++)
  382. {
  383. dividend[i] = (input.charCodeAt(i * 2) << 8) | input.charCodeAt(i * 2 + 1);
  384. }
  385. /*
  386. * Repeatedly perform a long division. The binary array forms the dividend,
  387. * the length of the encoding is the divisor. Once computed, the quotient
  388. * forms the dividend for the next step. We stop when the dividend is zero.
  389. * All remainders are stored for later use.
  390. */
  391. while(dividend.length > 0)
  392. {
  393. quotient = Array();
  394. x = 0;
  395. for(i = 0; i < dividend.length; i++)
  396. {
  397. x = (x << 16) + dividend[i];
  398. q = Math.floor(x / divisor);
  399. x -= q * divisor;
  400. if(quotient.length > 0 || q > 0)
  401. quotient[quotient.length] = q;
  402. }
  403. remainders[remainders.length] = x;
  404. dividend = quotient;
  405. }
  406. /* Convert the remainders to the output string */
  407. var output = "";
  408. for(i = remainders.length - 1; i >= 0; i--)
  409. output += encoding.charAt(remainders[i]);
  410. /* Append leading zero equivalents */
  411. var full_length = Math.ceil(input.length * 8 /
  412. (Math.log(encoding.length) / Math.log(2)))
  413. for(i = output.length; i < full_length; i++)
  414. output = encoding[0] + output;
  415. return output;
  416. }
  417. /*
  418. * Encode a string as utf-8.
  419. * For efficiency, this assumes the input is valid utf-16.
  420. */
  421. function str2rstr_utf8(input)
  422. {
  423. var output = "";
  424. var i = -1;
  425. var x, y;
  426. while(++i < input.length)
  427. {
  428. /* Decode utf-16 surrogate pairs */
  429. x = input.charCodeAt(i);
  430. y = i + 1 < input.length ? input.charCodeAt(i + 1) : 0;
  431. if(0xD800 <= x && x <= 0xDBFF && 0xDC00 <= y && y <= 0xDFFF)
  432. {
  433. x = 0x10000 + ((x & 0x03FF) << 10) + (y & 0x03FF);
  434. i++;
  435. }
  436. /* Encode output as utf-8 */
  437. if(x <= 0x7F)
  438. output += String.fromCharCode(x);
  439. else if(x <= 0x7FF)
  440. output += String.fromCharCode(0xC0 | ((x >>> 6 ) & 0x1F),
  441. 0x80 | ( x & 0x3F));
  442. else if(x <= 0xFFFF)
  443. output += String.fromCharCode(0xE0 | ((x >>> 12) & 0x0F),
  444. 0x80 | ((x >>> 6 ) & 0x3F),
  445. 0x80 | ( x & 0x3F));
  446. else if(x <= 0x1FFFFF)
  447. output += String.fromCharCode(0xF0 | ((x >>> 18) & 0x07),
  448. 0x80 | ((x >>> 12) & 0x3F),
  449. 0x80 | ((x >>> 6 ) & 0x3F),
  450. 0x80 | ( x & 0x3F));
  451. }
  452. return output;
  453. }
  454. /*
  455. * Encode a string as utf-16
  456. */
  457. function str2rstr_utf16le(input)
  458. {
  459. var output = "";
  460. for(var i = 0; i < input.length; i++)
  461. output += String.fromCharCode( input.charCodeAt(i) & 0xFF,
  462. (input.charCodeAt(i) >>> 8) & 0xFF);
  463. return output;
  464. }
  465. function str2rstr_utf16be(input)
  466. {
  467. var output = "";
  468. for(var i = 0; i < input.length; i++)
  469. output += String.fromCharCode((input.charCodeAt(i) >>> 8) & 0xFF,
  470. input.charCodeAt(i) & 0xFF);
  471. return output;
  472. }
  473. /*
  474. * Convert a raw string to an array of big-endian words
  475. * Characters >255 have their high-byte silently ignored.
  476. */
  477. function rstr2binb(input)
  478. {
  479. var output = Array(input.length >> 2);
  480. for(var i = 0; i < output.length; i++)
  481. output[i] = 0;
  482. for(var i = 0; i < input.length * 8; i += 8)
  483. output[i>>5] |= (input.charCodeAt(i / 8) & 0xFF) << (24 - i % 32);
  484. return output;
  485. }
  486. /*
  487. * Convert an array of big-endian words to a string
  488. */
  489. function binb2rstr(input)
  490. {
  491. var output = "";
  492. for(var i = 0; i < input.length * 32; i += 8)
  493. output += String.fromCharCode((input[i>>5] >>> (24 - i % 32)) & 0xFF);
  494. return output;
  495. }
  496. /*
  497. * Calculate the SHA-1 of an array of big-endian words, and a bit length
  498. */
  499. function binb_sha1(x, len)
  500. {
  501. /* append padding */
  502. x[len >> 5] |= 0x80 << (24 - len % 32);
  503. x[((len + 64 >> 9) << 4) + 15] = len;
  504. var w = Array(80);
  505. var a = 1732584193;
  506. var b = -271733879;
  507. var c = -1732584194;
  508. var d = 271733878;
  509. var e = -1009589776;
  510. for(var i = 0; i < x.length; i += 16)
  511. {
  512. var olda = a;
  513. var oldb = b;
  514. var oldc = c;
  515. var oldd = d;
  516. var olde = e;
  517. for(var j = 0; j < 80; j++)
  518. {
  519. if(j < 16) w[j] = x[i + j];
  520. else w[j] = bit_rol(w[j-3] ^ w[j-8] ^ w[j-14] ^ w[j-16], 1);
  521. var t = safe_add(safe_add(bit_rol(a, 5), sha1_ft(j, b, c, d)),
  522. safe_add(safe_add(e, w[j]), sha1_kt(j)));
  523. e = d;
  524. d = c;
  525. c = bit_rol(b, 30);
  526. b = a;
  527. a = t;
  528. }
  529. a = safe_add(a, olda);
  530. b = safe_add(b, oldb);
  531. c = safe_add(c, oldc);
  532. d = safe_add(d, oldd);
  533. e = safe_add(e, olde);
  534. }
  535. return Array(a, b, c, d, e);
  536. }
  537. /*
  538. * Perform the appropriate triplet combination function for the current
  539. * iteration
  540. */
  541. function sha1_ft(t, b, c, d)
  542. {
  543. if(t < 20) return (b & c) | ((~b) & d);
  544. if(t < 40) return b ^ c ^ d;
  545. if(t < 60) return (b & c) | (b & d) | (c & d);
  546. return b ^ c ^ d;
  547. }
  548. /*
  549. * Determine the appropriate additive constant for the current iteration
  550. */
  551. function sha1_kt(t)
  552. {
  553. return (t < 20) ? 1518500249 : (t < 40) ? 1859775393 :
  554. (t < 60) ? -1894007588 : -899497514;
  555. }
  556. /*
  557. * Add integers, wrapping at 2^32. This uses 16-bit operations internally
  558. * to work around bugs in some JS interpreters.
  559. */
  560. function safe_add(x, y)
  561. {
  562. var lsw = (x & 0xFFFF) + (y & 0xFFFF);
  563. var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
  564. return (msw << 16) | (lsw & 0xFFFF);
  565. }
  566. /*
  567. * Bitwise rotate a 32-bit number to the left.
  568. */
  569. function bit_rol(num, cnt)
  570. {
  571. return (num << cnt) | (num >>> (32 - cnt));
  572. }
  573. })();