PageRenderTime 55ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 0ms

/ajax/libs/satellizer/0.3.4/satellizer.js

https://gitlab.com/Mirros/cdnjs
JavaScript | 467 lines | 389 code | 73 blank | 5 comment | 21 complexity | f7f19c6db86b9c4b933514eda1771e8f MD5 | raw file
  1. /**
  2. * Satellizer
  3. * (c) 2014 Sahat Yalkabov <sahat@me.com>
  4. * License: MIT
  5. */
  6. (function(window, angular, undefined) {
  7. 'use strict';
  8. var config = {
  9. logoutRedirect: '/',
  10. loginRedirect: '/',
  11. loginUrl: '/auth/login',
  12. signupUrl: '/auth/signup',
  13. signupRedirect: '/login',
  14. loginRoute: '/login',
  15. signupRoute: '/signup',
  16. user: 'currentUser',
  17. tokenName: 'satellizerToken'
  18. };
  19. var providers = {
  20. google: {
  21. url: '/auth/google',
  22. authorizationEndpoint: 'https://accounts.google.com/o/oauth2/auth',
  23. redirectUri: window.location.origin,
  24. scope: 'openid profile email',
  25. scopeDelimiter: ' ',
  26. requiredUrlParams: ['scope'],
  27. optionalUrlParams: ['display'],
  28. display: 'popup',
  29. type: '2.0',
  30. popupOptions: {
  31. width: 452,
  32. height: 633
  33. }
  34. },
  35. facebook: {
  36. url: '/auth/facebook',
  37. authorizationEndpoint: 'https://www.facebook.com/dialog/oauth',
  38. redirectUri: window.location.origin + '/',
  39. scope: 'email',
  40. scopeDelimiter: ',',
  41. requiredUrlParams: ['display', 'scope'],
  42. display: 'popup',
  43. type: '2.0',
  44. popupOptions: {
  45. width: 481,
  46. height: 269
  47. }
  48. },
  49. linkedin: {
  50. url: '/auth/linkedin',
  51. authorizationEndpoint: 'https://www.linkedin.com/uas/oauth2/authorization',
  52. redirectUri: window.location.origin,
  53. requiredUrlParams: ['state'],
  54. scope: [],
  55. scopeDelimiter: ' ',
  56. state: 'STATE',
  57. type: '2.0',
  58. popupOptions: {
  59. width: 527,
  60. height: 582
  61. }
  62. },
  63. github: {
  64. name: 'github',
  65. url: '/auth/github',
  66. authorizationEndpoint: 'https://github.com/login/oauth/authorize',
  67. redirectUri: window.location.origin,
  68. scope: [],
  69. scopeDelimiter: ' ',
  70. type: '2.0',
  71. popupOptions: {
  72. width: 1020,
  73. height: 618
  74. }
  75. },
  76. twitter: {
  77. url: '/auth/twitter',
  78. type: '1.0'
  79. }
  80. };
  81. angular.module('Satellizer', [])
  82. .provider('$auth', function $auth() {
  83. this.config = config;
  84. this.providers = providers;
  85. this.facebook = function(params) {
  86. angular.extend(providers.facebook, params);
  87. };
  88. this.google = function(params) {
  89. angular.extend(providers.google, params);
  90. };
  91. this.linkedin = function(params) {
  92. angular.extend(providers.linkedin, params);
  93. };
  94. this.github = function(params) {
  95. angular.extend(providers.github, params);
  96. };
  97. this.twitter = function(params) {
  98. angular.extend(providers.twitter, params);
  99. };
  100. this.oauthBase = function(params) {
  101. providers[params.name] = providers[params.name] || {};
  102. angular.extend(providers[params.name], params);
  103. };
  104. this.oauth1 = function(params) {
  105. this.oauthBase(params);
  106. providers[params.name].type = '1.0';
  107. };
  108. this.oauth2 = function(params) {
  109. this.oauthBase(params);
  110. providers[params.name].type = '2.0';
  111. };
  112. this.$get = function($q, Oauth1, Oauth2, Local) {
  113. var $auth = {};
  114. $auth.authenticate = function(name) {
  115. var deferred = $q.defer();
  116. var provider = (providers[name].type === '1.0') ? Oauth1 : Oauth2;
  117. provider.open(providers[name])
  118. .then(function(response) {
  119. Local.parseUser(response.data.token, deferred);
  120. })
  121. .catch(function(response) {
  122. deferred.reject(response);
  123. });
  124. return deferred.promise;
  125. };
  126. $auth.login = function(user) {
  127. return Local.login(user);
  128. };
  129. $auth.signup = function(user) {
  130. return Local.signup(user);
  131. };
  132. $auth.logout = function() {
  133. return Local.logout();
  134. };
  135. $auth.isAuthenticated = function() {
  136. return Local.isAuthenticated();
  137. };
  138. return $auth;
  139. };
  140. })
  141. .factory('Local', function Local($q, $http, $rootScope, $location) {
  142. var local = {};
  143. local.parseUser = function(token, deferred) {
  144. var payload = JSON.parse(window.atob(token.split('.')[1]));
  145. localStorage.setItem(config.tokenName, token);
  146. $rootScope[config.user] = payload.user;
  147. $location.path(config.loginRedirect);
  148. deferred.resolve(payload.user);
  149. };
  150. local.login = function(user) {
  151. var deferred = $q.defer();
  152. $http.post(config.loginUrl, user)
  153. .then(function(response) {
  154. local.parseUser(response.data.token, deferred);
  155. })
  156. .catch(function(response) {
  157. deferred.reject(response);
  158. });
  159. return deferred.promise;
  160. };
  161. local.signup = function(user) {
  162. var deferred = $q.defer();
  163. $http.post(config.signupUrl, user)
  164. .then(function() {
  165. $location.path(config.signupRedirect);
  166. deferred.resolve();
  167. })
  168. .catch(function(response) {
  169. deferred.reject(response);
  170. });
  171. return deferred.promise;
  172. };
  173. local.logout = function() {
  174. var deferred = $q.defer();
  175. delete $rootScope[config.user];
  176. localStorage.removeItem(config.tokenName);
  177. $location.path(config.logoutRedirect);
  178. deferred.resolve();
  179. return deferred.promise;
  180. };
  181. local.isAuthenticated = function() {
  182. return Boolean($rootScope.currentUser);
  183. };
  184. return local;
  185. })
  186. .factory('Oauth2', function Oauth2($q, $http, Utils, Popup) {
  187. var defaults = {
  188. url: null,
  189. name: null,
  190. scope: null,
  191. scopeDelimiter: null,
  192. clientId: null,
  193. redirectUri: null,
  194. popupOptions: null,
  195. authorizationEndpoint: null,
  196. requiredUrlParams: null,
  197. optionalUrlParams: null,
  198. defaultUrlParams: ['response_type', 'client_id', 'redirect_uri'],
  199. responseType: 'code'
  200. };
  201. var oauth2 = {};
  202. oauth2.open = function(options) {
  203. angular.extend(defaults, options);
  204. var deferred = $q.defer();
  205. var url = oauth2.buildUrl();
  206. Popup.open(url, defaults.popupOptions)
  207. .then(function(oauthData) {
  208. oauth2.exchangeForToken(oauthData)
  209. .then(function(response) {
  210. deferred.resolve(response);
  211. })
  212. .catch(function(response) {
  213. deferred.reject(response);
  214. });
  215. })
  216. .catch(function(error) {
  217. deferred.reject(error);
  218. });
  219. return deferred.promise;
  220. };
  221. oauth2.exchangeForToken = function(oauthData) {
  222. return $http.post(defaults.url, {
  223. code: oauthData.code,
  224. clientId: defaults.clientId,
  225. redirectUri: defaults.redirectUri
  226. });
  227. };
  228. oauth2.buildUrl = function() {
  229. var baseUrl = defaults.authorizationEndpoint;
  230. var qs = oauth2.buildQueryString();
  231. return [baseUrl, qs].join('?');
  232. };
  233. oauth2.buildQueryString = function() {
  234. var keyValuePairs = [];
  235. var urlParams = ['defaultUrlParams', 'requiredUrlParams', 'optionalUrlParams'];
  236. angular.forEach(urlParams, function(params) {
  237. angular.forEach(defaults[params], function(paramName) {
  238. var camelizedName = Utils.camelCase(paramName);
  239. var paramValue = defaults[camelizedName];
  240. keyValuePairs.push([paramName, encodeURIComponent(paramValue)]);
  241. });
  242. });
  243. return keyValuePairs.map(function(pair) {
  244. return pair.join('=');
  245. }).join('&');
  246. };
  247. return oauth2;
  248. })
  249. .factory('Oauth1', function Oauth1($q, $http, Popup) {
  250. var defaults = {
  251. url: null,
  252. name: null,
  253. popupOptions: null
  254. };
  255. var oauth1 = {};
  256. oauth1.open = function(options) {
  257. angular.extend(defaults, options);
  258. var deferred = $q.defer();
  259. Popup.open(defaults.url).then(function(oauthData) {
  260. oauth1.exchangeForToken(oauthData).then(function(response) {
  261. deferred.resolve(response.data);
  262. });
  263. });
  264. return deferred.promise;
  265. };
  266. oauth1.exchangeForToken = function(oauthData) {
  267. oauthData = oauth1.buildQueryString(oauthData);
  268. return $http.get(defaults.url + '?' + oauthData);
  269. };
  270. oauth1.buildQueryString = function(obj) {
  271. var str = [];
  272. angular.forEach(obj, function(value, key) {
  273. str.push(encodeURIComponent(key) + '=' + encodeURIComponent(value));
  274. });
  275. return str.join('&');
  276. };
  277. return oauth1;
  278. })
  279. .factory('Popup', function Popup($q, $interval, $window) {
  280. var popupWindow = null;
  281. var polling = null;
  282. var popup = {};
  283. popup.popupWindow = popupWindow;
  284. popup.open = function(url, options) {
  285. var deferred = $q.defer();
  286. var optionsString = popup.stringifyOptions(popup.prepareOptions(options || {}));
  287. popupWindow = $window.open(url, '_blank', optionsString);
  288. popupWindow.focus();
  289. popup.postMessageHandler(deferred);
  290. popup.pollPopup(deferred);
  291. return deferred.promise;
  292. };
  293. popup.pollPopup = function(deferred) {
  294. polling = $interval(function() {
  295. if (popupWindow.closed) {
  296. $interval.cancel(polling);
  297. deferred.reject({ data: 'Authorization Failed' });
  298. }
  299. }, 35);
  300. };
  301. popup.postMessageHandler = function(deferred) {
  302. $window.addEventListener('message', function(event) {
  303. if (event.origin === $window.location.origin) {
  304. popupWindow.close();
  305. if (event.data.error) {
  306. deferred.reject({ data: event.data.error });
  307. } else {
  308. deferred.resolve(event.data);
  309. }
  310. }
  311. }, false);
  312. };
  313. popup.prepareOptions = function(options) {
  314. var width = options.width || 500;
  315. var height = options.height || 500;
  316. return angular.extend({
  317. width: width,
  318. height: height,
  319. left: $window.screenX + (($window.outerWidth - width) / 2),
  320. top: $window.screenY + (($window.outerHeight - height) / 2.5)
  321. }, options);
  322. };
  323. popup.stringifyOptions = function(options) {
  324. var parts = [];
  325. angular.forEach(options, function(value, key) {
  326. parts.push(key + '=' + value);
  327. });
  328. return parts.join(',');
  329. };
  330. return popup;
  331. })
  332. .factory('RunBlock', function RunBlock($rootScope, $window, $location, Utils) {
  333. return {
  334. run: function() {
  335. var token = $window.localStorage[config.tokenName];
  336. if (token) {
  337. var payload = JSON.parse($window.atob(token.split('.')[1]));
  338. $rootScope[config.user] = payload.user;
  339. }
  340. var params = $window.location.search.substring(1);
  341. var qs = Object.keys($location.search()).length ? $location.search() : Utils.parseQueryString(params);
  342. if ($window.opener && $window.opener.location.origin === $window.location.origin) {
  343. if (qs.oauth_token && qs.oauth_verifier) {
  344. $window.opener.postMessage({ oauth_token: qs.oauth_token, oauth_verifier: qs.oauth_verifier }, $window.location.origin);
  345. } else if (qs.code) {
  346. $window.opener.postMessage({ code: qs.code }, $window.location.origin);
  347. } else if (qs.error) {
  348. $window.opener.postMessage({ error: qs.error }, $window.location.origin);
  349. }
  350. }
  351. }
  352. };
  353. })
  354. .service('Utils', function Utils() {
  355. this.camelCase = function(name) {
  356. return name.replace(/([\:\-\_]+(.))/g, function(_, separator, letter, offset) {
  357. return offset ? letter.toUpperCase() : letter;
  358. });
  359. };
  360. this.parseQueryString = function(keyValue) {
  361. var obj = { }, key, value;
  362. angular.forEach((keyValue || '').split('&'), function(keyValue) {
  363. if (keyValue) {
  364. value = keyValue.split('=');
  365. key = decodeURIComponent(value[0]);
  366. obj[key] = angular.isDefined(value[1]) ? decodeURIComponent(value[1]) : true;
  367. }
  368. });
  369. return obj;
  370. };
  371. })
  372. .config(function httpInterceptor($httpProvider) {
  373. $httpProvider.interceptors.push(function($q, $window, $location) {
  374. return {
  375. request: function(httpConfig) {
  376. if ($window.localStorage[config.tokenName]) {
  377. httpConfig.headers.Authorization = 'Bearer ' + $window.localStorage[config.tokenName];
  378. }
  379. return httpConfig;
  380. },
  381. responseError: function(response) {
  382. if (response.status === 401) {
  383. delete $window.localStorage[config.tokenName];
  384. $location.path(config.loginRoute);
  385. }
  386. return $q.reject(response);
  387. }
  388. };
  389. });
  390. })
  391. .run(function onRun(RunBlock) {
  392. RunBlock.run();
  393. });
  394. })(window, window.angular);