diff --git a/README.md b/README.md index 987587d..c6f310f 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ JavaScript library for using OAuth 2.0 Implicit Grant flow (Client-Side Flow) or This creates an OAuth 2.0 Ember object class for handling authentication with OAuth 2.0 providers. -Current Version: **[1.0.0](https://github.com/amkirwan/ember-oauth2/releases/tag/v1.0.0)** +Current Version: **[1.0.1](https://github.com/amkirwan/ember-oauth2/releases/tag/v1.0.1)** The EmberCli addon [EmberTokenAuth](https://github.com/amkirwan/ember-token-auth) demonstrates how to use Ember-OAuth2 library for authentication. diff --git a/bower.json b/bower.json index 02d770f..a500822 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "ember-oauth2", - "version": "1.0.0", + "version": "1.0.1", "homepage": "https://github.com/amkirwan/ember-oauth2", "authors": [ "Anthony Kirwan " diff --git a/dist/ember-oauth2.amd.js b/dist/ember-oauth2.amd.js index 5d56188..71f22a2 100644 --- a/dist/ember-oauth2.amd.js +++ b/dist/ember-oauth2.amd.js @@ -8,7 +8,7 @@ define("ember-oauth2", * @overview OAuth2 library for Emberjs that stores tokens in the browsers localStorage * @license Licensed under MIT license * See https://raw.github.com/amkirwan/ember-oauth2/master/LICENSE - * @version 1.0.0 + * @version 1.0.1 * * @module ember-oauth2 * @class ember-oauth2 @@ -97,7 +97,6 @@ define("ember-oauth2", /** * @event redirect - * @param {function} The function that handles the redirect. */ this.on('redirect', this.handleRedirect); }, @@ -174,7 +173,7 @@ define("ember-oauth2", if (!this.get('redirectUri')) throw new Error('No redirect uri given.'); var authorizeUri = this.authUri(); this.clearStates(); - this.saveState(this.get('state'), this.requestObj()); + this.saveState(this.requestObj()); return this.openWindow(authorizeUri); }, @@ -246,7 +245,7 @@ define("ember-oauth2", var params = this.parseCallback(hash); if (this.authSuccess(params)) { - var stateObj = this.getState(params.state); + var stateObj = this.getState(); this.checkState(stateObj); if (this.get('responseType') === "token") { @@ -270,10 +269,15 @@ define("ember-oauth2", * * @method checkState * @param {Object} stateObj The object returned from localStorage + * @return {Boolean} Will return true if the states match otherwise it will throw an Error */ checkState: function(stateObj) { if (!stateObj) throw new Error("Could not find state."); - if (stateObj.state !== this.get('state')) throw new Error("State returned from the server did not match the local saved state."); + if (stateObj.state === this.get('state')) { + return true; + } else { + throw new Error("State returned from the server did not match the local saved state."); + } }, /** @@ -302,26 +306,25 @@ define("ember-oauth2", /** * @method saveState - * @param {String} state The state uuid * @param {Object} requestObj Properties of the request state to save in localStorage */ - saveState: function(state, requestObj) { + saveState: function(requestObj) { window.localStorage.setItem(this.stateKeyName(), JSON.stringify(requestObj)); }, /** - * Return the saved state and remove it from the localStoage. + * Return the saved state object and remove it from the localStoage. * * @method getState - * @param {String} state The state uuid to retreive from localStorage * @return {Object} Properties of the request state */ - getState: function(state) { - var keyName = state || this.stateKeyName(); - var obj = JSON.parse(window.localStorage.getItem(keyName)); - this.removeState(); + getState: function() { + var stateObj = JSON.parse(window.localStorage.getItem(this.stateKeyName())); + if (!stateObj) return null; + + this.removeState(this.stateKeyName()); - return obj; + return stateObj; }, /** @@ -459,7 +462,7 @@ define("ember-oauth2", * @property {String} VERSION * @final */ - var VERSION = "1.0.0"; + var VERSION = "1.0.1"; /** * @method version diff --git a/dist/ember-oauth2.amd.min.js b/dist/ember-oauth2.amd.min.js index 3ed61c0..9ebf67a 100644 --- a/dist/ember-oauth2.amd.min.js +++ b/dist/ember-oauth2.amd.min.js @@ -1,2 +1,2 @@ -/** ember-oauth2 | @version 1.0.0 | 07-08-2015 */ -define("ember-oauth2",["ember","exports"],function(a,b){"use strict";var c=a["default"];b["default"]=c.Object.extend(c.Evented,{init:function(){if(this._super(),c.OAuth2&&c.OAuth2.config&&Object.keys(c.OAuth2.config).length)c.Logger.warn("Ember.OAuth2.config is deprecated and will be removed in future versions. Set the config using window.ENV['ember-oauth2']"),this.set("config",c.OAuth2.config);else if(window.EmberENV&&window.EmberENV["ember-oauth2"])this.set("config",window.EmberENV["ember-oauth2"]);else{if(!window.ENV||!window.ENV["ember-oauth2"])throw new Error("Cannot find the ember-oauth2 config.");this.set("config",window.ENV["ember-oauth2"])}if(!this.get("config")[this.get("providerId")])throw new Error("Cannot find the providerId: '"+this.get("providerId")+"' in the config.");this.set("providerConfig",this.get("config")[this.get("providerId")]),this.set("statePrefix","state"),this.set("tokenPrefix","token"),this.set("responseType","token"),this.setProperties(this.providerConfig),this.on("redirect",this.handleRedirect)},version:function(){return d},uuid:function(){return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,function(a){var b=16*Math.random()|0,c="x"===a?b:3&b|8;return c.toString(16)})},now:function(){return Math.round((new Date).getTime()/1e3)},requestObj:function(){var a={};return a.response_type=this.get("responseType"),a.providerId=this.get("providerId"),a.state=this.get("state"),a.client_id=this.get("clientId"),a.state=this.get("state"),this.get("scope")&&(a.scope=this.get("scope")),a},authUri:function(){this.get("state")||this.set("state",this.uuid());var a=this.get("authBaseUri");return a+="?response_type="+encodeURIComponent(this.get("responseType"))+"&redirect_uri="+encodeURIComponent(this.get("redirectUri"))+"&client_id="+encodeURIComponent(this.get("clientId"))+"&state="+encodeURIComponent(this.get("state")),this.get("scope")&&(a+="&scope="+encodeURIComponent(this.get(".scope")).replace("%20","+")),a},authorize:function(){if(!this.get("providerId"))throw new Error("No provider id given.");if(!this.get("clientId"))throw new Error("No client id given.");if(!this.get("authBaseUri"))throw new Error("No auth base uri given.");if(!this.get("redirectUri"))throw new Error("No redirect uri given.");var a=this.authUri();return this.clearStates(),this.saveState(this.get("state"),this.requestObj()),this.openWindow(a)},openWindow:function(a){var b=window.open(a,"Authorize","height=600, width=450");return window.focus&&b&&b.focus(),new c.RSVP.Promise(function(a,c){b?a(b):c(new Error("Opening dialog login window failed."))})},authSuccess:function(a){return"token"===this.get("responseType")&&a.access_token||"code"===this.get("responseType")&&a.code},generateToken:function(a){var b={};return b.provider_id=this.get("providerId"),b.expires_in=this.expiresIn(a.expires_in),b.scope=this.get("scope"),b.access_token=a.access_token,b},expiresIn:function(a){return this.now()+parseInt(a,10)},handleRedirect:function(a,b){var c=this.parseCallback(a);if(this.authSuccess(c)){var d=this.getState(c.state);this.checkState(d),"token"===this.get("responseType")?(this.saveToken(this.generateToken(c)),this.trigger("success",d)):this.trigger("success",c.code)}else this.trigger("error",c);b&&"function"==typeof b&&b()},checkState:function(a){if(!a)throw new Error("Could not find state.");if(a.state!==this.get("state"))throw new Error("State returned from the server did not match the local saved state.")},parseCallback:function(a){for(var b,c={},d=a.substring(a.indexOf("?")),e=/([^#?&=]+)=([^&]*)/g;null!==(b=e.exec(d));)c[decodeURIComponent(b[1])]=decodeURIComponent(b[2]);return c},saveState:function(a,b){window.localStorage.setItem(this.stateKeyName(),JSON.stringify(b))},getState:function(a){var b=a||this.stateKeyName(),c=JSON.parse(window.localStorage.getItem(b));return this.removeState(),c},clearStates:function(){for(var a,b=new RegExp("^"+this.get("statePrefix")+"-.*","g"),c=[],d=0,e=window.localStorage.length;e>d;d++)a=window.localStorage.key(d),a.match(b)&&c.push(a);for(var f=0,g=c.length;g>f;f++)a=c[f],this.removeState(a);return c},stateKeyName:function(){return this.get("statePrefix")+"-"+this.get("state")},tokenKeyName:function(){return this.get("tokenPrefix")+"-"+this.get("providerId")},saveToken:function(a){window.localStorage.setItem(this.tokenKeyName(),JSON.stringify(a))},removeState:function(a){return a?window.localStorage.removeItem(a):window.localStorage.removeItem(this.stateKeyName())},removeToken:function(){return window.localStorage.removeItem(this.tokenKeyName())},getToken:function(){var a=JSON.parse(window.localStorage.getItem(this.tokenKeyName()));return a&&a.access_token?a:null},getAccessToken:function(){var a=this.getToken();return a?a.access_token:null},accessTokenIsExpired:function(){var a=this.getToken();return a?this.now()>=a.expires_in?!0:!1:!0},expireAccessToken:function(){var a=this.getToken();return a?(a.expires_in=0,void this.saveToken(a)):null}});var d="1.0.0";c.OAuth2&&(c.OAuth2.version=d)}); \ No newline at end of file +/** ember-oauth2 | @version 1.0.1 | 20-10-2015 */ +define("ember-oauth2",["ember","exports"],function(a,b){"use strict";var c=a["default"];b["default"]=c.Object.extend(c.Evented,{init:function(){if(this._super(),c.OAuth2&&c.OAuth2.config&&Object.keys(c.OAuth2.config).length)c.Logger.warn("Ember.OAuth2.config is deprecated and will be removed in future versions. Set the config using window.ENV['ember-oauth2']"),this.set("config",c.OAuth2.config);else if(window.EmberENV&&window.EmberENV["ember-oauth2"])this.set("config",window.EmberENV["ember-oauth2"]);else{if(!window.ENV||!window.ENV["ember-oauth2"])throw new Error("Cannot find the ember-oauth2 config.");this.set("config",window.ENV["ember-oauth2"])}if(!this.get("config")[this.get("providerId")])throw new Error("Cannot find the providerId: '"+this.get("providerId")+"' in the config.");this.set("providerConfig",this.get("config")[this.get("providerId")]),this.set("statePrefix","state"),this.set("tokenPrefix","token"),this.set("responseType","token"),this.setProperties(this.providerConfig),this.on("redirect",this.handleRedirect)},version:function(){return d},uuid:function(){return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,function(a){var b=16*Math.random()|0,c="x"===a?b:3&b|8;return c.toString(16)})},now:function(){return Math.round((new Date).getTime()/1e3)},requestObj:function(){var a={};return a.response_type=this.get("responseType"),a.providerId=this.get("providerId"),a.state=this.get("state"),a.client_id=this.get("clientId"),a.state=this.get("state"),this.get("scope")&&(a.scope=this.get("scope")),a},authUri:function(){this.get("state")||this.set("state",this.uuid());var a=this.get("authBaseUri");return a+="?response_type="+encodeURIComponent(this.get("responseType"))+"&redirect_uri="+encodeURIComponent(this.get("redirectUri"))+"&client_id="+encodeURIComponent(this.get("clientId"))+"&state="+encodeURIComponent(this.get("state")),this.get("scope")&&(a+="&scope="+encodeURIComponent(this.get(".scope")).replace("%20","+")),a},authorize:function(){if(!this.get("providerId"))throw new Error("No provider id given.");if(!this.get("clientId"))throw new Error("No client id given.");if(!this.get("authBaseUri"))throw new Error("No auth base uri given.");if(!this.get("redirectUri"))throw new Error("No redirect uri given.");var a=this.authUri();return this.clearStates(),this.saveState(this.requestObj()),this.openWindow(a)},openWindow:function(a){var b=window.open(a,"Authorize","height=600, width=450");return window.focus&&b&&b.focus(),new c.RSVP.Promise(function(a,c){b?a(b):c(new Error("Opening dialog login window failed."))})},authSuccess:function(a){return"token"===this.get("responseType")&&a.access_token||"code"===this.get("responseType")&&a.code},generateToken:function(a){var b={};return b.provider_id=this.get("providerId"),b.expires_in=this.expiresIn(a.expires_in),b.scope=this.get("scope"),b.access_token=a.access_token,b},expiresIn:function(a){return this.now()+parseInt(a,10)},handleRedirect:function(a,b){var c=this.parseCallback(a);if(this.authSuccess(c)){var d=this.getState();this.checkState(d),"token"===this.get("responseType")?(this.saveToken(this.generateToken(c)),this.trigger("success",d)):this.trigger("success",c.code)}else this.trigger("error",c);b&&"function"==typeof b&&b()},checkState:function(a){if(!a)throw new Error("Could not find state.");if(a.state===this.get("state"))return!0;throw new Error("State returned from the server did not match the local saved state.")},parseCallback:function(a){for(var b,c={},d=a.substring(a.indexOf("?")),e=/([^#?&=]+)=([^&]*)/g;null!==(b=e.exec(d));)c[decodeURIComponent(b[1])]=decodeURIComponent(b[2]);return c},saveState:function(a){window.localStorage.setItem(this.stateKeyName(),JSON.stringify(a))},getState:function(){var a=JSON.parse(window.localStorage.getItem(this.stateKeyName()));return a?(this.removeState(this.stateKeyName()),a):null},clearStates:function(){for(var a,b=new RegExp("^"+this.get("statePrefix")+"-.*","g"),c=[],d=0,e=window.localStorage.length;e>d;d++)a=window.localStorage.key(d),a.match(b)&&c.push(a);for(var f=0,g=c.length;g>f;f++)a=c[f],this.removeState(a);return c},stateKeyName:function(){return this.get("statePrefix")+"-"+this.get("state")},tokenKeyName:function(){return this.get("tokenPrefix")+"-"+this.get("providerId")},saveToken:function(a){window.localStorage.setItem(this.tokenKeyName(),JSON.stringify(a))},removeState:function(a){return a?window.localStorage.removeItem(a):window.localStorage.removeItem(this.stateKeyName())},removeToken:function(){return window.localStorage.removeItem(this.tokenKeyName())},getToken:function(){var a=JSON.parse(window.localStorage.getItem(this.tokenKeyName()));return a&&a.access_token?a:null},getAccessToken:function(){var a=this.getToken();return a?a.access_token:null},accessTokenIsExpired:function(){var a=this.getToken();return a?this.now()>=a.expires_in?!0:!1:!0},expireAccessToken:function(){var a=this.getToken();return a?(a.expires_in=0,void this.saveToken(a)):null}});var d="1.0.1";c.OAuth2&&(c.OAuth2.version=d)}); \ No newline at end of file diff --git a/dist/ember-oauth2.js b/dist/ember-oauth2.js index 44e5918..1f29544 100644 --- a/dist/ember-oauth2.js +++ b/dist/ember-oauth2.js @@ -4,7 +4,7 @@ import Ember from 'ember'; * @overview OAuth2 library for Emberjs that stores tokens in the browsers localStorage * @license Licensed under MIT license * See https://raw.github.com/amkirwan/ember-oauth2/master/LICENSE - * @version 1.0.0 + * @version 1.0.1 * * @module ember-oauth2 * @class ember-oauth2 @@ -93,7 +93,6 @@ export default Ember.Object.extend(Ember.Evented, { /** * @event redirect - * @param {function} The function that handles the redirect. */ this.on('redirect', this.handleRedirect); }, @@ -170,7 +169,7 @@ export default Ember.Object.extend(Ember.Evented, { if (!this.get('redirectUri')) throw new Error('No redirect uri given.'); var authorizeUri = this.authUri(); this.clearStates(); - this.saveState(this.get('state'), this.requestObj()); + this.saveState(this.requestObj()); return this.openWindow(authorizeUri); }, @@ -242,7 +241,7 @@ export default Ember.Object.extend(Ember.Evented, { var params = this.parseCallback(hash); if (this.authSuccess(params)) { - var stateObj = this.getState(params.state); + var stateObj = this.getState(); this.checkState(stateObj); if (this.get('responseType') === "token") { @@ -266,10 +265,15 @@ export default Ember.Object.extend(Ember.Evented, { * * @method checkState * @param {Object} stateObj The object returned from localStorage + * @return {Boolean} Will return true if the states match otherwise it will throw an Error */ checkState: function(stateObj) { if (!stateObj) throw new Error("Could not find state."); - if (stateObj.state !== this.get('state')) throw new Error("State returned from the server did not match the local saved state."); + if (stateObj.state === this.get('state')) { + return true; + } else { + throw new Error("State returned from the server did not match the local saved state."); + } }, /** @@ -298,26 +302,25 @@ export default Ember.Object.extend(Ember.Evented, { /** * @method saveState - * @param {String} state The state uuid * @param {Object} requestObj Properties of the request state to save in localStorage */ - saveState: function(state, requestObj) { + saveState: function(requestObj) { window.localStorage.setItem(this.stateKeyName(), JSON.stringify(requestObj)); }, /** - * Return the saved state and remove it from the localStoage. + * Return the saved state object and remove it from the localStoage. * * @method getState - * @param {String} state The state uuid to retreive from localStorage * @return {Object} Properties of the request state */ - getState: function(state) { - var keyName = state || this.stateKeyName(); - var obj = JSON.parse(window.localStorage.getItem(keyName)); - this.removeState(); + getState: function() { + var stateObj = JSON.parse(window.localStorage.getItem(this.stateKeyName())); + if (!stateObj) return null; + + this.removeState(this.stateKeyName()); - return obj; + return stateObj; }, /** @@ -455,7 +458,7 @@ export default Ember.Object.extend(Ember.Evented, { * @property {String} VERSION * @final */ -var VERSION = "1.0.0"; +var VERSION = "1.0.1"; /** * @method version diff --git a/lib/ember-oauth2.js b/lib/ember-oauth2.js index 0193178..1f29544 100644 --- a/lib/ember-oauth2.js +++ b/lib/ember-oauth2.js @@ -4,7 +4,7 @@ import Ember from 'ember'; * @overview OAuth2 library for Emberjs that stores tokens in the browsers localStorage * @license Licensed under MIT license * See https://raw.github.com/amkirwan/ember-oauth2/master/LICENSE - * @version 1.0.0 + * @version 1.0.1 * * @module ember-oauth2 * @class ember-oauth2 @@ -458,7 +458,7 @@ export default Ember.Object.extend(Ember.Evented, { * @property {String} VERSION * @final */ -var VERSION = "1.0.0"; +var VERSION = "1.0.1"; /** * @method version diff --git a/package.json b/package.json index a25d2a4..1e92854 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ember-oauth2", - "version": "1.0.0", + "version": "1.0.1", "description": "OAuth2 library for Emberjs that stores tokens in the browsers localStorage", "homepage": "https://github.com/amkirwan/ember-ouath2", "main": "dist/ember.oauth2.js", diff --git a/yuidoc.json b/yuidoc.json index af0ec39..139b2e4 100644 --- a/yuidoc.json +++ b/yuidoc.json @@ -1,7 +1,7 @@ { "name": "Ember.OAuth2", "description": "OAuth2 library for Emberjs that stores tokens in the browsers localStorage", - "version": "1.0.0", + "version": "1.0.1", "url": "https://github.com/amkirwan/ember-oauth2", "options": { "exclude": "node_modules,bower_components,scripts",