Keine Beschreibung

satellizer.js 43KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944
  1. /**
  2. * Satellizer 0.15.4
  3. * (c) 2016 Sahat Yalkabov
  4. * License: MIT
  5. */
  6. (function (global, factory) {
  7. typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
  8. typeof define === 'function' && define.amd ? define(factory) :
  9. (global.satellizer = factory());
  10. }(this, function () { 'use strict';
  11. var Config = (function () {
  12. function Config() {
  13. this.baseUrl = '/';
  14. this.loginUrl = '/auth/login';
  15. this.signupUrl = '/auth/signup';
  16. this.unlinkUrl = '/auth/unlink/';
  17. this.tokenName = 'token';
  18. this.tokenPrefix = 'satellizer';
  19. this.tokenHeader = 'Authorization';
  20. this.tokenType = 'Bearer';
  21. this.storageType = 'localStorage';
  22. this.tokenRoot = null;
  23. this.withCredentials = false;
  24. this.providers = {
  25. facebook: {
  26. name: 'facebook',
  27. url: '/auth/facebook',
  28. authorizationEndpoint: 'https://www.facebook.com/v2.5/dialog/oauth',
  29. redirectUri: window.location.origin + '/',
  30. requiredUrlParams: ['display', 'scope'],
  31. scope: ['email'],
  32. scopeDelimiter: ',',
  33. display: 'popup',
  34. oauthType: '2.0',
  35. popupOptions: { width: 580, height: 400 }
  36. },
  37. google: {
  38. name: 'google',
  39. url: '/auth/google',
  40. authorizationEndpoint: 'https://accounts.google.com/o/oauth2/auth',
  41. redirectUri: window.location.origin,
  42. requiredUrlParams: ['scope'],
  43. optionalUrlParams: ['display', 'state'],
  44. scope: ['profile', 'email'],
  45. scopePrefix: 'openid',
  46. scopeDelimiter: ' ',
  47. display: 'popup',
  48. oauthType: '2.0',
  49. popupOptions: { width: 452, height: 633 },
  50. state: function () { return encodeURIComponent(Math.random().toString(36).substr(2)); }
  51. },
  52. github: {
  53. name: 'github',
  54. url: '/auth/github',
  55. authorizationEndpoint: 'https://github.com/login/oauth/authorize',
  56. redirectUri: window.location.origin,
  57. optionalUrlParams: ['scope'],
  58. scope: ['user:email'],
  59. scopeDelimiter: ' ',
  60. oauthType: '2.0',
  61. popupOptions: { width: 1020, height: 618 }
  62. },
  63. instagram: {
  64. name: 'instagram',
  65. url: '/auth/instagram',
  66. authorizationEndpoint: 'https://api.instagram.com/oauth/authorize',
  67. redirectUri: window.location.origin,
  68. requiredUrlParams: ['scope'],
  69. scope: ['basic'],
  70. scopeDelimiter: '+',
  71. oauthType: '2.0'
  72. },
  73. linkedin: {
  74. name: 'linkedin',
  75. url: '/auth/linkedin',
  76. authorizationEndpoint: 'https://www.linkedin.com/uas/oauth2/authorization',
  77. redirectUri: window.location.origin,
  78. requiredUrlParams: ['state'],
  79. scope: ['r_emailaddress'],
  80. scopeDelimiter: ' ',
  81. state: 'STATE',
  82. oauthType: '2.0',
  83. popupOptions: { width: 527, height: 582 }
  84. },
  85. twitter: {
  86. name: 'twitter',
  87. url: '/auth/twitter',
  88. authorizationEndpoint: 'https://api.twitter.com/oauth/authenticate',
  89. redirectUri: window.location.origin,
  90. oauthType: '1.0',
  91. popupOptions: { width: 495, height: 645 }
  92. },
  93. twitch: {
  94. name: 'twitch',
  95. url: '/auth/twitch',
  96. authorizationEndpoint: 'https://api.twitch.tv/kraken/oauth2/authorize',
  97. redirectUri: window.location.origin,
  98. requiredUrlParams: ['scope'],
  99. scope: ['user_read'],
  100. scopeDelimiter: ' ',
  101. display: 'popup',
  102. oauthType: '2.0',
  103. popupOptions: { width: 500, height: 560 }
  104. },
  105. live: {
  106. name: 'live',
  107. url: '/auth/live',
  108. authorizationEndpoint: 'https://login.live.com/oauth20_authorize.srf',
  109. redirectUri: window.location.origin,
  110. requiredUrlParams: ['display', 'scope'],
  111. scope: ['wl.emails'],
  112. scopeDelimiter: ' ',
  113. display: 'popup',
  114. oauthType: '2.0',
  115. popupOptions: { width: 500, height: 560 }
  116. },
  117. yahoo: {
  118. name: 'yahoo',
  119. url: '/auth/yahoo',
  120. authorizationEndpoint: 'https://api.login.yahoo.com/oauth2/request_auth',
  121. redirectUri: window.location.origin,
  122. scope: [],
  123. scopeDelimiter: ',',
  124. oauthType: '2.0',
  125. popupOptions: { width: 559, height: 519 }
  126. },
  127. bitbucket: {
  128. name: 'bitbucket',
  129. url: '/auth/bitbucket',
  130. authorizationEndpoint: 'https://bitbucket.org/site/oauth2/authorize',
  131. redirectUri: window.location.origin + '/',
  132. requiredUrlParams: ['scope'],
  133. scope: ['email'],
  134. scopeDelimiter: ' ',
  135. oauthType: '2.0',
  136. popupOptions: { width: 1028, height: 529 }
  137. }
  138. };
  139. this.httpInterceptor = function () { return true; };
  140. }
  141. Object.defineProperty(Config, "getConstant", {
  142. get: function () {
  143. return new Config();
  144. },
  145. enumerable: true,
  146. configurable: true
  147. });
  148. return Config;
  149. }());
  150. ;
  151. var AuthProvider = (function () {
  152. function AuthProvider(SatellizerConfig) {
  153. this.SatellizerConfig = SatellizerConfig;
  154. }
  155. Object.defineProperty(AuthProvider.prototype, "baseUrl", {
  156. get: function () { return this.SatellizerConfig.baseUrl; },
  157. set: function (value) { this.SatellizerConfig.baseUrl = value; },
  158. enumerable: true,
  159. configurable: true
  160. });
  161. Object.defineProperty(AuthProvider.prototype, "loginUrl", {
  162. get: function () { return this.SatellizerConfig.loginUrl; },
  163. set: function (value) { this.SatellizerConfig.loginUrl = value; },
  164. enumerable: true,
  165. configurable: true
  166. });
  167. Object.defineProperty(AuthProvider.prototype, "signupUrl", {
  168. get: function () { return this.SatellizerConfig.signupUrl; },
  169. set: function (value) { this.SatellizerConfig.signupUrl = value; },
  170. enumerable: true,
  171. configurable: true
  172. });
  173. Object.defineProperty(AuthProvider.prototype, "unlinkUrl", {
  174. get: function () { return this.SatellizerConfig.unlinkUrl; },
  175. set: function (value) { this.SatellizerConfig.unlinkUrl = value; },
  176. enumerable: true,
  177. configurable: true
  178. });
  179. Object.defineProperty(AuthProvider.prototype, "tokenRoot", {
  180. get: function () { return this.SatellizerConfig.tokenRoot; },
  181. set: function (value) { this.SatellizerConfig.tokenRoot = value; },
  182. enumerable: true,
  183. configurable: true
  184. });
  185. Object.defineProperty(AuthProvider.prototype, "tokenName", {
  186. get: function () { return this.SatellizerConfig.tokenName; },
  187. set: function (value) { this.SatellizerConfig.tokenName = value; },
  188. enumerable: true,
  189. configurable: true
  190. });
  191. Object.defineProperty(AuthProvider.prototype, "tokenPrefix", {
  192. get: function () { return this.SatellizerConfig.tokenPrefix; },
  193. set: function (value) { this.SatellizerConfig.tokenPrefix = value; },
  194. enumerable: true,
  195. configurable: true
  196. });
  197. Object.defineProperty(AuthProvider.prototype, "tokenHeader", {
  198. get: function () { return this.SatellizerConfig.tokenHeader; },
  199. set: function (value) { this.SatellizerConfig.tokenHeader = value; },
  200. enumerable: true,
  201. configurable: true
  202. });
  203. Object.defineProperty(AuthProvider.prototype, "tokenType", {
  204. get: function () { return this.SatellizerConfig.tokenType; },
  205. set: function (value) { this.SatellizerConfig.tokenType = value; },
  206. enumerable: true,
  207. configurable: true
  208. });
  209. Object.defineProperty(AuthProvider.prototype, "withCredentials", {
  210. get: function () { return this.SatellizerConfig.withCredentials; },
  211. set: function (value) { this.SatellizerConfig.withCredentials = value; },
  212. enumerable: true,
  213. configurable: true
  214. });
  215. Object.defineProperty(AuthProvider.prototype, "storageType", {
  216. get: function () { return this.SatellizerConfig.storageType; },
  217. set: function (value) { this.SatellizerConfig.storageType = value; },
  218. enumerable: true,
  219. configurable: true
  220. });
  221. Object.defineProperty(AuthProvider.prototype, "httpInterceptor", {
  222. get: function () { return this.SatellizerConfig.httpInterceptor; },
  223. set: function (value) {
  224. if (typeof value === 'function') {
  225. this.SatellizerConfig.httpInterceptor = value;
  226. }
  227. else {
  228. this.SatellizerConfig.httpInterceptor = function () { return value; };
  229. }
  230. },
  231. enumerable: true,
  232. configurable: true
  233. });
  234. AuthProvider.prototype.facebook = function (options) {
  235. angular.extend(this.SatellizerConfig.providers.facebook, options);
  236. };
  237. AuthProvider.prototype.google = function (options) {
  238. angular.extend(this.SatellizerConfig.providers.google, options);
  239. };
  240. AuthProvider.prototype.github = function (options) {
  241. angular.extend(this.SatellizerConfig.providers.github, options);
  242. };
  243. AuthProvider.prototype.instagram = function (options) {
  244. angular.extend(this.SatellizerConfig.providers.instagram, options);
  245. };
  246. AuthProvider.prototype.linkedin = function (options) {
  247. angular.extend(this.SatellizerConfig.providers.linkedin, options);
  248. };
  249. AuthProvider.prototype.twitter = function (options) {
  250. angular.extend(this.SatellizerConfig.providers.twitter, options);
  251. };
  252. AuthProvider.prototype.twitch = function (options) {
  253. angular.extend(this.SatellizerConfig.providers.twitch, options);
  254. };
  255. AuthProvider.prototype.live = function (options) {
  256. angular.extend(this.SatellizerConfig.providers.live, options);
  257. };
  258. AuthProvider.prototype.yahoo = function (options) {
  259. angular.extend(this.SatellizerConfig.providers.yahoo, options);
  260. };
  261. AuthProvider.prototype.bitbucket = function (options) {
  262. angular.extend(this.SatellizerConfig.providers.bitbucket, options);
  263. };
  264. AuthProvider.prototype.oauth1 = function (options) {
  265. this.SatellizerConfig.providers[options.name] = angular.extend(options, {
  266. oauthType: '1.0'
  267. });
  268. };
  269. AuthProvider.prototype.oauth2 = function (options) {
  270. this.SatellizerConfig.providers[options.name] = angular.extend(options, {
  271. oauthType: '2.0'
  272. });
  273. };
  274. AuthProvider.prototype.$get = function (SatellizerShared, SatellizerLocal, SatellizerOAuth) {
  275. return {
  276. login: function (user, options) { return SatellizerLocal.login(user, options); },
  277. signup: function (user, options) { return SatellizerLocal.signup(user, options); },
  278. logout: function () { return SatellizerShared.logout(); },
  279. authenticate: function (name, data) { return SatellizerOAuth.authenticate(name, data); },
  280. link: function (name, data) { return SatellizerOAuth.authenticate(name, data); },
  281. unlink: function (name, options) { return SatellizerOAuth.unlink(name, options); },
  282. isAuthenticated: function () { return SatellizerShared.isAuthenticated(); },
  283. getPayload: function () { return SatellizerShared.getPayload(); },
  284. getToken: function () { return SatellizerShared.getToken(); },
  285. setToken: function (token) { return SatellizerShared.setToken({ access_token: token }); },
  286. removeToken: function () { return SatellizerShared.removeToken(); },
  287. setStorageType: function (type) { return SatellizerShared.setStorageType(type); }
  288. };
  289. };
  290. AuthProvider.$inject = ['SatellizerConfig'];
  291. return AuthProvider;
  292. }());
  293. AuthProvider.prototype.$get.$inject = ['SatellizerShared', 'SatellizerLocal', 'SatellizerOAuth'];
  294. function joinUrl(baseUrl, url) {
  295. if (/^(?:[a-z]+:)?\/\//i.test(url)) {
  296. return url;
  297. }
  298. var joined = [baseUrl, url].join('/');
  299. var normalize = function (str) {
  300. return str
  301. .replace(/[\/]+/g, '/')
  302. .replace(/\/\?/g, '?')
  303. .replace(/\/\#/g, '#')
  304. .replace(/\:\//g, '://');
  305. };
  306. return normalize(joined);
  307. }
  308. function getFullUrlPath(location) {
  309. var isHttps = location.protocol === 'https:';
  310. return location.protocol + '//' + location.hostname +
  311. ':' + (location.port || (isHttps ? '443' : '80')) +
  312. (/^\//.test(location.pathname) ? location.pathname : '/' + location.pathname);
  313. }
  314. function parseQueryString(str) {
  315. var obj = {};
  316. var key;
  317. var value;
  318. angular.forEach((str || '').split('&'), function (keyValue) {
  319. if (keyValue) {
  320. value = keyValue.split('=');
  321. key = decodeURIComponent(value[0]);
  322. obj[key] = angular.isDefined(value[1]) ? decodeURIComponent(value[1]) : true;
  323. }
  324. });
  325. return obj;
  326. }
  327. function decodeBase64(str) {
  328. var buffer;
  329. if (typeof module !== 'undefined' && module.exports) {
  330. try {
  331. buffer = require('buffer').Buffer;
  332. }
  333. catch (err) {
  334. }
  335. }
  336. var fromCharCode = String.fromCharCode;
  337. var re_btou = new RegExp([
  338. '[\xC0-\xDF][\x80-\xBF]',
  339. '[\xE0-\xEF][\x80-\xBF]{2}',
  340. '[\xF0-\xF7][\x80-\xBF]{3}'
  341. ].join('|'), 'g');
  342. var cb_btou = function (cccc) {
  343. switch (cccc.length) {
  344. case 4:
  345. var cp = ((0x07 & cccc.charCodeAt(0)) << 18)
  346. | ((0x3f & cccc.charCodeAt(1)) << 12)
  347. | ((0x3f & cccc.charCodeAt(2)) << 6)
  348. | (0x3f & cccc.charCodeAt(3));
  349. var offset = cp - 0x10000;
  350. return (fromCharCode((offset >>> 10) + 0xD800)
  351. + fromCharCode((offset & 0x3FF) + 0xDC00));
  352. case 3:
  353. return fromCharCode(((0x0f & cccc.charCodeAt(0)) << 12)
  354. | ((0x3f & cccc.charCodeAt(1)) << 6)
  355. | (0x3f & cccc.charCodeAt(2)));
  356. default:
  357. return fromCharCode(((0x1f & cccc.charCodeAt(0)) << 6)
  358. | (0x3f & cccc.charCodeAt(1)));
  359. }
  360. };
  361. var btou = function (b) {
  362. return b.replace(re_btou, cb_btou);
  363. };
  364. var _decode = buffer ? function (a) {
  365. return (a.constructor === buffer.constructor
  366. ? a : new buffer(a, 'base64')).toString();
  367. }
  368. : function (a) {
  369. return btou(atob(a));
  370. };
  371. return _decode(String(str).replace(/[-_]/g, function (m0) {
  372. return m0 === '-' ? '+' : '/';
  373. })
  374. .replace(/[^A-Za-z0-9\+\/]/g, ''));
  375. }
  376. var Shared = (function () {
  377. function Shared($q, $window, $log, SatellizerConfig, SatellizerStorage) {
  378. this.$q = $q;
  379. this.$window = $window;
  380. this.$log = $log;
  381. this.SatellizerConfig = SatellizerConfig;
  382. this.SatellizerStorage = SatellizerStorage;
  383. var _a = this.SatellizerConfig, tokenName = _a.tokenName, tokenPrefix = _a.tokenPrefix;
  384. this.prefixedTokenName = tokenPrefix ? [tokenPrefix, tokenName].join('_') : tokenName;
  385. }
  386. Shared.prototype.getToken = function () {
  387. return this.SatellizerStorage.get(this.prefixedTokenName);
  388. };
  389. Shared.prototype.getPayload = function () {
  390. var token = this.SatellizerStorage.get(this.prefixedTokenName);
  391. if (token && token.split('.').length === 3) {
  392. try {
  393. var base64Url = token.split('.')[1];
  394. var base64 = base64Url.replace('-', '+').replace('_', '/');
  395. return JSON.parse(decodeBase64(base64));
  396. }
  397. catch (e) {
  398. }
  399. }
  400. };
  401. Shared.prototype.setToken = function (response) {
  402. if (!response) {
  403. return this.$log.warn('Can\'t set token without passing a value');
  404. }
  405. var token;
  406. var accessToken = response && response.access_token;
  407. if (accessToken) {
  408. if (angular.isObject(accessToken) && angular.isObject(accessToken.data)) {
  409. response = accessToken;
  410. }
  411. else if (angular.isString(accessToken)) {
  412. token = accessToken;
  413. }
  414. }
  415. if (!token && response) {
  416. var tokenRootData = this.SatellizerConfig.tokenRoot && this.SatellizerConfig.tokenRoot.split('.').reduce(function (o, x) { return o[x]; }, response.data);
  417. token = tokenRootData ? tokenRootData[this.SatellizerConfig.tokenName] : response.data && response.data[this.SatellizerConfig.tokenName];
  418. }
  419. if (!token) {
  420. var tokenPath = this.SatellizerConfig.tokenRoot ? this.SatellizerConfig.tokenRoot + '.' + this.SatellizerConfig.tokenName : this.SatellizerConfig.tokenName;
  421. return this.$log.warn('Expecting a token named "' + tokenPath);
  422. }
  423. this.SatellizerStorage.set(this.prefixedTokenName, token);
  424. };
  425. Shared.prototype.removeToken = function () {
  426. this.SatellizerStorage.remove(this.prefixedTokenName);
  427. };
  428. Shared.prototype.isAuthenticated = function () {
  429. var token = this.SatellizerStorage.get(this.prefixedTokenName);
  430. if (token) {
  431. if (token.split('.').length === 3) {
  432. try {
  433. var base64Url = token.split('.')[1];
  434. var base64 = base64Url.replace('-', '+').replace('_', '/');
  435. var exp = JSON.parse(this.$window.atob(base64)).exp;
  436. if (exp) {
  437. return (Math.round(new Date().getTime() / 1000) >= exp) ? false : true;
  438. }
  439. }
  440. catch (e) {
  441. return true; // Pass: Non-JWT token that looks like JWT
  442. }
  443. }
  444. return true; // Pass: All other tokens
  445. }
  446. return false; // Fail: No token at all
  447. };
  448. Shared.prototype.logout = function () {
  449. this.SatellizerStorage.remove(this.prefixedTokenName);
  450. return this.$q.when();
  451. };
  452. Shared.prototype.setStorageType = function (type) {
  453. this.SatellizerConfig.storageType = type;
  454. };
  455. Shared.$inject = ['$q', '$window', '$log', 'SatellizerConfig', 'SatellizerStorage'];
  456. return Shared;
  457. }());
  458. var Local = (function () {
  459. function Local($http, SatellizerConfig, SatellizerShared) {
  460. this.$http = $http;
  461. this.SatellizerConfig = SatellizerConfig;
  462. this.SatellizerShared = SatellizerShared;
  463. }
  464. Local.prototype.login = function (user, options) {
  465. var _this = this;
  466. if (options === void 0) { options = {}; }
  467. options.url = options.url ? options.url : joinUrl(this.SatellizerConfig.baseUrl, this.SatellizerConfig.loginUrl);
  468. options.data = user || options.data;
  469. options.method = options.method || 'POST';
  470. options.withCredentials = options.withCredentials || this.SatellizerConfig.withCredentials;
  471. return this.$http(options).then(function (response) {
  472. _this.SatellizerShared.setToken(response);
  473. return response;
  474. });
  475. };
  476. Local.prototype.signup = function (user, options) {
  477. if (options === void 0) { options = {}; }
  478. options.url = options.url ? options.url : joinUrl(this.SatellizerConfig.baseUrl, this.SatellizerConfig.signupUrl);
  479. options.data = user || options.data;
  480. options.method = options.method || 'POST';
  481. options.withCredentials = options.withCredentials || this.SatellizerConfig.withCredentials;
  482. return this.$http(options);
  483. };
  484. Local.$inject = ['$http', 'SatellizerConfig', 'SatellizerShared'];
  485. return Local;
  486. }());
  487. var Popup = (function () {
  488. function Popup($interval, $window, $q) {
  489. this.$interval = $interval;
  490. this.$window = $window;
  491. this.$q = $q;
  492. this.popup = null;
  493. this.url = 'about:blank'; // TODO remove
  494. this.defaults = {
  495. redirectUri: null
  496. };
  497. }
  498. Popup.prototype.stringifyOptions = function (options) {
  499. var parts = [];
  500. angular.forEach(options, function (value, key) {
  501. parts.push(key + '=' + value);
  502. });
  503. return parts.join(',');
  504. };
  505. Popup.prototype.open = function (url, name, popupOptions) {
  506. this.url = url; // TODO remove
  507. var width = popupOptions.width || 500;
  508. var height = popupOptions.height || 500;
  509. var options = this.stringifyOptions({
  510. width: width,
  511. height: height,
  512. top: this.$window.screenY + ((this.$window.outerHeight - height) / 2.5),
  513. left: this.$window.screenX + ((this.$window.outerWidth - width) / 2)
  514. });
  515. var popupName = this.$window['cordova'] || this.$window.navigator.userAgent.indexOf('CriOS') > -1 ? '_blank' : name;
  516. this.popup = window.open(this.url, popupName, options);
  517. if (this.popup && this.popup.focus) {
  518. this.popup.focus();
  519. }
  520. //
  521. // if (this.$window['cordova']) {
  522. // return this.eventListener(this.defaults.redirectUri); // TODO pass redirect uri
  523. // } else {
  524. // return this.polling(redirectUri);
  525. // }
  526. };
  527. Popup.prototype.polling = function (redirectUri) {
  528. var _this = this;
  529. return this.$q(function (resolve, reject) {
  530. var redirectUriParser = document.createElement('a');
  531. redirectUriParser.href = redirectUri;
  532. var redirectUriPath = getFullUrlPath(redirectUriParser);
  533. var polling = _this.$interval(function () {
  534. if (!_this.popup || _this.popup.closed || _this.popup.closed === undefined) {
  535. _this.$interval.cancel(polling);
  536. reject(new Error('The popup window was closed'));
  537. }
  538. try {
  539. var popupWindowPath = getFullUrlPath(_this.popup.location);
  540. if (popupWindowPath === redirectUriPath) {
  541. if (_this.popup.location.search || _this.popup.location.hash) {
  542. var query = parseQueryString(_this.popup.location.search.substring(1).replace(/\/$/, ''));
  543. var hash = parseQueryString(_this.popup.location.hash.substring(1).replace(/[\/$]/, ''));
  544. var params = angular.extend({}, query, hash);
  545. if (params.error) {
  546. reject(new Error(params.error));
  547. }
  548. else {
  549. resolve(params);
  550. }
  551. }
  552. else {
  553. reject(new Error('OAuth redirect has occurred but no query or hash parameters were found. ' +
  554. 'They were either not set during the redirect, or were removed—typically by a ' +
  555. 'routing library—before Satellizer could read it.'));
  556. }
  557. _this.$interval.cancel(polling);
  558. _this.popup.close();
  559. }
  560. }
  561. catch (error) {
  562. }
  563. }, 500);
  564. });
  565. };
  566. Popup.prototype.eventListener = function (redirectUri) {
  567. var _this = this;
  568. return this.$q(function (resolve, reject) {
  569. _this.popup.addEventListener('loadstart', function (event) {
  570. if (!event.url.includes(redirectUri)) {
  571. return;
  572. }
  573. var parser = document.createElement('a');
  574. parser.href = event.url;
  575. if (parser.search || parser.hash) {
  576. var query = parseQueryString(parser.search.substring(1).replace(/\/$/, ''));
  577. var hash = parseQueryString(parser.hash.substring(1).replace(/[\/$]/, ''));
  578. var params = angular.extend({}, query, hash);
  579. if (params.error) {
  580. reject(new Error(params.error));
  581. }
  582. else {
  583. resolve(params);
  584. }
  585. _this.popup.close();
  586. }
  587. });
  588. _this.popup.addEventListener('loaderror', function () {
  589. reject(new Error('Authorization failed'));
  590. });
  591. _this.popup.addEventListener('exit', function () {
  592. reject(new Error('The popup window was closed'));
  593. });
  594. });
  595. };
  596. Popup.$inject = ['$interval', '$window', '$q'];
  597. return Popup;
  598. }());
  599. var OAuth1 = (function () {
  600. function OAuth1($http, $window, SatellizerConfig, SatellizerPopup) {
  601. this.$http = $http;
  602. this.$window = $window;
  603. this.SatellizerConfig = SatellizerConfig;
  604. this.SatellizerPopup = SatellizerPopup;
  605. this.defaults = {
  606. name: null,
  607. url: null,
  608. authorizationEndpoint: null,
  609. scope: null,
  610. scopePrefix: null,
  611. scopeDelimiter: null,
  612. redirectUri: null,
  613. requiredUrlParams: null,
  614. defaultUrlParams: null,
  615. oauthType: '1.0',
  616. popupOptions: { width: null, height: null }
  617. };
  618. }
  619. ;
  620. OAuth1.prototype.init = function (options, userData) {
  621. var _this = this;
  622. angular.extend(this.defaults, options);
  623. if (!this.$window['cordova']) {
  624. this.SatellizerPopup.open('about:blank', options.name, options.popupOptions);
  625. }
  626. return this.getRequestToken().then(function (response) {
  627. return _this.openPopup(options, response).then(function (popupResponse) {
  628. return _this.exchangeForToken(popupResponse, userData);
  629. });
  630. });
  631. };
  632. OAuth1.prototype.openPopup = function (options, response) {
  633. var popupUrl = [options.authorizationEndpoint, this.buildQueryString(response.data)].join('?');
  634. if (this.$window['cordova']) {
  635. this.SatellizerPopup.open(popupUrl, options.name, options.popupOptions);
  636. return this.SatellizerPopup.eventListener(this.defaults.redirectUri);
  637. }
  638. else {
  639. this.SatellizerPopup.popup.location = popupUrl;
  640. return this.SatellizerPopup.polling(this.defaults.redirectUri);
  641. }
  642. };
  643. OAuth1.prototype.getRequestToken = function () {
  644. var url = this.SatellizerConfig.baseUrl ? joinUrl(this.SatellizerConfig.baseUrl, this.defaults.url) : this.defaults.url;
  645. return this.$http.post(url, this.defaults);
  646. };
  647. OAuth1.prototype.exchangeForToken = function (oauthData, userData) {
  648. var payload = angular.extend({}, userData, oauthData);
  649. var exchangeForTokenUrl = this.SatellizerConfig.baseUrl ? joinUrl(this.SatellizerConfig.baseUrl, this.defaults.url) : this.defaults.url;
  650. return this.$http.post(exchangeForTokenUrl, payload, { withCredentials: this.SatellizerConfig.withCredentials });
  651. };
  652. OAuth1.prototype.buildQueryString = function (obj) {
  653. var str = [];
  654. angular.forEach(obj, function (value, key) {
  655. str.push(encodeURIComponent(key) + '=' + encodeURIComponent(value));
  656. });
  657. return str.join('&');
  658. };
  659. OAuth1.$inject = ['$http', '$window', 'SatellizerConfig', 'SatellizerPopup'];
  660. return OAuth1;
  661. }());
  662. var OAuth2 = (function () {
  663. function OAuth2($http, $window, $timeout, $q, SatellizerConfig, SatellizerPopup, SatellizerStorage) {
  664. this.$http = $http;
  665. this.$window = $window;
  666. this.$timeout = $timeout;
  667. this.$q = $q;
  668. this.SatellizerConfig = SatellizerConfig;
  669. this.SatellizerPopup = SatellizerPopup;
  670. this.SatellizerStorage = SatellizerStorage;
  671. this.defaults = {
  672. name: null,
  673. url: null,
  674. clientId: null,
  675. authorizationEndpoint: null,
  676. redirectUri: null,
  677. scope: null,
  678. scopePrefix: null,
  679. scopeDelimiter: null,
  680. state: null,
  681. requiredUrlParams: null,
  682. defaultUrlParams: ['response_type', 'client_id', 'redirect_uri'],
  683. responseType: 'code',
  684. responseParams: {
  685. code: 'code',
  686. clientId: 'clientId',
  687. redirectUri: 'redirectUri'
  688. },
  689. oauthType: '2.0',
  690. popupOptions: { width: null, height: null }
  691. };
  692. }
  693. OAuth2.camelCase = function (name) {
  694. return name.replace(/([\:\-\_]+(.))/g, function (_, separator, letter, offset) {
  695. return offset ? letter.toUpperCase() : letter;
  696. });
  697. };
  698. OAuth2.prototype.init = function (options, userData) {
  699. var _this = this;
  700. return this.$q(function (resolve, reject) {
  701. angular.extend(_this.defaults, options);
  702. _this.$timeout(function () {
  703. var stateName = _this.defaults.name + '_state';
  704. var _a = _this.defaults, name = _a.name, state = _a.state, popupOptions = _a.popupOptions, redirectUri = _a.redirectUri, responseType = _a.responseType;
  705. if (typeof state === 'function') {
  706. _this.SatellizerStorage.set(stateName, state());
  707. }
  708. else if (typeof state === 'string') {
  709. _this.SatellizerStorage.set(stateName, state);
  710. }
  711. var url = [_this.defaults.authorizationEndpoint, _this.buildQueryString()].join('?');
  712. _this.SatellizerPopup.open(url, name, popupOptions);
  713. _this.SatellizerPopup.polling(redirectUri).then(function (oauth) {
  714. if (responseType === 'token' || !url) {
  715. return resolve(oauth);
  716. }
  717. if (oauth.state && oauth.state !== _this.SatellizerStorage.get(stateName)) {
  718. return reject(new Error('The value returned in the state parameter does not match the state value from your original ' +
  719. 'authorization code request.'));
  720. }
  721. resolve(_this.exchangeForToken(oauth, userData));
  722. })
  723. .catch(function (error) { return reject(error); });
  724. });
  725. });
  726. };
  727. OAuth2.prototype.exchangeForToken = function (oauthData, userData) {
  728. var _this = this;
  729. var payload = angular.extend({}, userData);
  730. angular.forEach(this.defaults.responseParams, function (value, key) {
  731. switch (key) {
  732. case 'code':
  733. payload[value] = oauthData.code;
  734. break;
  735. case 'clientId':
  736. payload[value] = _this.defaults.clientId;
  737. break;
  738. case 'redirectUri':
  739. payload[value] = _this.defaults.redirectUri;
  740. break;
  741. default:
  742. payload[value] = oauthData[key];
  743. }
  744. });
  745. if (oauthData.state) {
  746. payload.state = oauthData.state;
  747. }
  748. var exchangeForTokenUrl = this.SatellizerConfig.baseUrl ?
  749. joinUrl(this.SatellizerConfig.baseUrl, this.defaults.url) :
  750. this.defaults.url;
  751. return this.$http.post(exchangeForTokenUrl, payload, { withCredentials: this.SatellizerConfig.withCredentials });
  752. };
  753. OAuth2.prototype.buildQueryString = function () {
  754. var _this = this;
  755. var keyValuePairs = [];
  756. var urlParamsCategories = ['defaultUrlParams', 'requiredUrlParams', 'optionalUrlParams'];
  757. angular.forEach(urlParamsCategories, function (paramsCategory) {
  758. angular.forEach(_this.defaults[paramsCategory], function (paramName) {
  759. var camelizedName = OAuth2.camelCase(paramName);
  760. var paramValue = angular.isFunction(_this.defaults[paramName]) ? _this.defaults[paramName]() : _this.defaults[camelizedName];
  761. if (paramName === 'redirect_uri' && !paramValue) {
  762. return;
  763. }
  764. if (paramName === 'state') {
  765. var stateName = _this.defaults.name + '_state';
  766. paramValue = encodeURIComponent(_this.SatellizerStorage.get(stateName));
  767. }
  768. if (paramName === 'scope' && Array.isArray(paramValue)) {
  769. paramValue = paramValue.join(_this.defaults.scopeDelimiter);
  770. if (_this.defaults.scopePrefix) {
  771. paramValue = [_this.defaults.scopePrefix, paramValue].join(_this.defaults.scopeDelimiter);
  772. }
  773. }
  774. keyValuePairs.push([paramName, paramValue]);
  775. });
  776. });
  777. return keyValuePairs.map(function (pair) { return pair.join('='); }).join('&');
  778. };
  779. OAuth2.$inject = ['$http', '$window', '$timeout', '$q', 'SatellizerConfig', 'SatellizerPopup', 'SatellizerStorage'];
  780. return OAuth2;
  781. }());
  782. var OAuth = (function () {
  783. function OAuth($http, $window, $timeout, $q, SatellizerConfig, SatellizerPopup, SatellizerStorage, SatellizerShared, SatellizerOAuth1, SatellizerOAuth2) {
  784. this.$http = $http;
  785. this.$window = $window;
  786. this.$timeout = $timeout;
  787. this.$q = $q;
  788. this.SatellizerConfig = SatellizerConfig;
  789. this.SatellizerPopup = SatellizerPopup;
  790. this.SatellizerStorage = SatellizerStorage;
  791. this.SatellizerShared = SatellizerShared;
  792. this.SatellizerOAuth1 = SatellizerOAuth1;
  793. this.SatellizerOAuth2 = SatellizerOAuth2;
  794. }
  795. OAuth.prototype.authenticate = function (name, userData) {
  796. var _this = this;
  797. return this.$q(function (resolve, reject) {
  798. var provider = _this.SatellizerConfig.providers[name];
  799. var oauth = null;
  800. switch (provider.oauthType) {
  801. case '1.0':
  802. oauth = new OAuth1(_this.$http, _this.$window, _this.SatellizerConfig, _this.SatellizerPopup);
  803. break;
  804. case '2.0':
  805. oauth = new OAuth2(_this.$http, _this.$window, _this.$timeout, _this.$q, _this.SatellizerConfig, _this.SatellizerPopup, _this.SatellizerStorage);
  806. break;
  807. default:
  808. return reject(new Error('Unknown OAuth Type'));
  809. }
  810. return oauth.init(provider, userData).then(function (response) {
  811. if (provider.url) {
  812. _this.SatellizerShared.setToken(response);
  813. }
  814. resolve(response);
  815. }).catch(function (error) {
  816. reject(error);
  817. });
  818. });
  819. };
  820. OAuth.prototype.unlink = function (provider, httpOptions) {
  821. if (httpOptions === void 0) { httpOptions = {}; }
  822. httpOptions.url = httpOptions.url ? httpOptions.url : joinUrl(this.SatellizerConfig.baseUrl, this.SatellizerConfig.unlinkUrl);
  823. httpOptions.data = { provider: provider } || httpOptions.data;
  824. httpOptions.method = httpOptions.method || 'POST';
  825. httpOptions.withCredentials = httpOptions.withCredentials || this.SatellizerConfig.withCredentials;
  826. return this.$http(httpOptions);
  827. };
  828. OAuth.$inject = [
  829. '$http',
  830. '$window',
  831. '$timeout',
  832. '$q',
  833. 'SatellizerConfig',
  834. 'SatellizerPopup',
  835. 'SatellizerStorage',
  836. 'SatellizerShared',
  837. 'SatellizerOAuth1',
  838. 'SatellizerOAuth2'
  839. ];
  840. return OAuth;
  841. }());
  842. var Storage = (function () {
  843. function Storage($window, SatellizerConfig) {
  844. this.$window = $window;
  845. this.SatellizerConfig = SatellizerConfig;
  846. this.memoryStore = {};
  847. }
  848. Storage.prototype.get = function (key) {
  849. try {
  850. return this.$window[this.SatellizerConfig.storageType].getItem(key);
  851. }
  852. catch (e) {
  853. return this.memoryStore[key];
  854. }
  855. };
  856. Storage.prototype.set = function (key, value) {
  857. try {
  858. this.$window[this.SatellizerConfig.storageType].setItem(key, value);
  859. }
  860. catch (e) {
  861. this.memoryStore[key] = value;
  862. }
  863. };
  864. Storage.prototype.remove = function (key) {
  865. try {
  866. this.$window[this.SatellizerConfig.storageType].removeItem(key);
  867. }
  868. catch (e) {
  869. delete this.memoryStore[key];
  870. }
  871. };
  872. Storage.$inject = ['$window', 'SatellizerConfig'];
  873. return Storage;
  874. }());
  875. var Interceptor = (function () {
  876. function Interceptor(SatellizerConfig, SatellizerShared, SatellizerStorage) {
  877. var _this = this;
  878. this.SatellizerConfig = SatellizerConfig;
  879. this.SatellizerShared = SatellizerShared;
  880. this.SatellizerStorage = SatellizerStorage;
  881. this.request = function (config) {
  882. if (config['skipAuthorization']) {
  883. return config;
  884. }
  885. if (_this.SatellizerShared.isAuthenticated() && _this.SatellizerConfig.httpInterceptor()) {
  886. var tokenName = _this.SatellizerConfig.tokenPrefix ?
  887. [_this.SatellizerConfig.tokenPrefix, _this.SatellizerConfig.tokenName].join('_') : _this.SatellizerConfig.tokenName;
  888. var token = _this.SatellizerStorage.get(tokenName);
  889. if (_this.SatellizerConfig.tokenHeader && _this.SatellizerConfig.tokenType) {
  890. token = _this.SatellizerConfig.tokenType + ' ' + token;
  891. }
  892. config.headers[_this.SatellizerConfig.tokenHeader] = token;
  893. }
  894. return config;
  895. };
  896. }
  897. Interceptor.Factory = function (SatellizerConfig, SatellizerShared, SatellizerStorage) {
  898. return new Interceptor(SatellizerConfig, SatellizerShared, SatellizerStorage);
  899. };
  900. Interceptor.$inject = ['SatellizerConfig', 'SatellizerShared', 'SatellizerStorage'];
  901. return Interceptor;
  902. }());
  903. Interceptor.Factory.$inject = ['SatellizerConfig', 'SatellizerShared', 'SatellizerStorage'];
  904. var HttpProviderConfig = (function () {
  905. function HttpProviderConfig($httpProvider) {
  906. this.$httpProvider = $httpProvider;
  907. $httpProvider.interceptors.push(Interceptor.Factory);
  908. }
  909. HttpProviderConfig.$inject = ['$httpProvider'];
  910. return HttpProviderConfig;
  911. }());
  912. angular.module('satellizer', [])
  913. .provider('$auth', ['SatellizerConfig', function (SatellizerConfig) { return new AuthProvider(SatellizerConfig); }])
  914. .constant('SatellizerConfig', Config.getConstant)
  915. .service('SatellizerShared', Shared)
  916. .service('SatellizerLocal', Local)
  917. .service('SatellizerPopup', Popup)
  918. .service('SatellizerOAuth', OAuth)
  919. .service('SatellizerOAuth2', OAuth2)
  920. .service('SatellizerOAuth1', OAuth1)
  921. .service('SatellizerStorage', Storage)
  922. .service('SatellizerInterceptor', Interceptor)
  923. .config(['$httpProvider', function ($httpProvider) { return new HttpProviderConfig($httpProvider); }]);
  924. var ng1 = 'satellizer';
  925. return ng1;
  926. }));
  927. //# sourceMappingURL=satellizer.js.map