Repository: auth0/auth0.js
Pull request #258 (2016-12-05 17:21:58)

Tests + blacklist the user credentials to be sent to the authorize endpoint

codecov-io: ## [Current coverage](https://codecov.io/gh/auth0/auth0.js/pull/258?src=pr) is 99.87% (diff: 100%)
> Merging [#258](https://codecov.io/gh/auth0/auth0.js/pull/258?src=pr) into [v8](https://codecov.io/gh/auth0/auth0.js/branch/v8?src=pr) will not change coverage

```diff
@@                 v8       #258   diff @@
==========================================
  Files            26         26          
  Lines           804        804          
  Methods         143        143          
  Messages          0          0          
  Branches        107        107          
==========================================
  Hits            803        803          
  Misses            1          1          
  Partials          0          0          
```

> Powered by [Codecov](https://codecov.io?src=pr). Last update [7988a05...d495eed](https://codecov.io/gh/auth0/auth0.js/compare/7988a05f3983e7da5691cab9da08e83e10de617b...d495eed25473e68b21125dbf62cc63d28e2b7d04?src=pr)
codecov-io: ## [Current coverage](https://codecov.io/gh/auth0/auth0.js/pull/258?src=pr) is 99.87% (diff: 100%)
> Merging [#258](https://codecov.io/gh/auth0/auth0.js/pull/258?src=pr) into [v8](https://codecov.io/gh/auth0/auth0.js/branch/v8?src=pr) will not change coverage

```diff
@@                 v8       #258   diff @@
==========================================
  Files            26         26          
  Lines           804        804          
  Methods         143        143          
  Messages          0          0          
  Branches        107        107          
==========================================
  Hits            803        803          
  Misses            1          1          
  Partials          0          0          
```

> Powered by [Codecov](https://codecov.io?src=pr). Last update [5cfbdee...d495eed](https://codecov.io/gh/auth0/auth0.js/compare/5cfbdee6b43579d980a2827b011210cc9668cd69...d495eed25473e68b21125dbf62cc63d28e2b7d04?src=pr)
codecov-io: ## [Current coverage](https://codecov.io/gh/auth0/auth0.js/pull/258?src=pr) is 99.87% (diff: 93.75%)
> Merging [#258](https://codecov.io/gh/auth0/auth0.js/pull/258?src=pr) into [v8](https://codecov.io/gh/auth0/auth0.js/branch/v8?src=pr) will increase coverage by **<.01%**

```diff
@@                 v8       #258   diff @@
==========================================
  Files            26         26          
  Lines           804        810     +6   
  Methods         143        143          
  Messages          0          0          
  Branches        107        110     +3   
==========================================
+ Hits            803        809     +6   
  Misses            1          1          
  Partials          0          0          
```

> Powered by [Codecov](https://codecov.io?src=pr). Last update [dcdbcd5...8076e79](https://codecov.io/gh/auth0/auth0.js/compare/dcdbcd55d59fa8214c7cae64e1a5ba2c0e975f81...8076e7915a2ec6e4c1c76398b8ec8370d3864d25?src=pr)
codecov-io: ## [Current coverage](https://codecov.io/gh/auth0/auth0.js/pull/258?src=pr) is 99.87% (diff: 93.75%)
> Merging [#258](https://codecov.io/gh/auth0/auth0.js/pull/258?src=pr) into [v8](https://codecov.io/gh/auth0/auth0.js/branch/v8?src=pr) will increase coverage by **<.01%**

```diff
@@                 v8       #258   diff @@
==========================================
  Files            26         26          
  Lines           804        810     +6   
  Methods         143        143          
  Messages          0          0          
  Branches        107        110     +3   
==========================================
+ Hits            803        809     +6   
  Misses            1          1          
  Partials          0          0          
```

> Powered by [Codecov](https://codecov.io?src=pr). Last update [dcdbcd5...8076e79](https://codecov.io/gh/auth0/auth0.js/compare/dcdbcd55d59fa8214c7cae64e1a5ba2c0e975f81...8076e7915a2ec6e4c1c76398b8ec8370d3864d25?src=pr)

Patch:
diff --git a/README.md b/README.md
index cc5556d..e92b786 100644
--- a/README.md
+++ b/README.md
@@ -1,10 +1,17 @@
-# Auth0.js
+![](https://cdn.auth0.com/resources/oss-source-large-2x.png)
 
-[![Build Status](https://travis-ci.org/auth0/auth0.js.svg?branch=v8)](https://travis-ci.org/auth0/auth0.js)
-[![codecov.io](http://codecov.io/github/auth0/auth0.js/coverage.svg?branch=v8)](http://codecov.io/github/auth0/auth0.js/coverage.svg?branch=v8)
+# Auth0.js
+[![NPM version][npm-image]][npm-url]
+[![Build status][travis-image]][travis-url]
+[![Coverage](codecov-image)](codecov-image)
+[![Dependency Status][david-image]][david-url]
+[![License][license-image]][license-url]
+[![Downloads][downloads-image]][downloads-url]
 
 ## WebAuth
 
+Provides support for all the authentication flows
+
 ### Initialize
 
 ```js
@@ -15,21 +22,48 @@ var auth0 = new auth0.WebAuth({
 ```
 
 Parameters:
-- **domain {REQUIRED, string}**: Your Auth0 account domain
-- **client_id {REQUIRED, string}**: Your Auth0 client_id
+- **domain {REQUIRED, string}**: Your Auth0 account domain.
+- **client_id {REQUIRED, string}**: Your Auth0 client_id.
+- **redirectUri {OPTIONAL, string}**: The default redirectUri used.
+- **scope {OPTIONAL, string}**: The default scope used.
+- **audience {OPTIONAL, string}**: The default audience used.
+- **responseType {OPTIONAL, string}**: The default responseType used.
+- **responseMode {OPTIONAL, string}**: The default responseMode used.
+- **_disableDeprecationWarnings {OPTIONAL, boolean}**: Disables the deprecation warnings, defaults to `false`.
 
 ### API
 
-- **passwordlessStart**
+- **parseHash(hash, options)**:
+    + **hash {OPTIONAL, string}**: the url hash to parse. It will pick the `window.location.hash` if it is not provided
+    + **options {OPTIONAL, object}**:
+        * **options.nonce**: used to verify the token nonce if it was not autogenerated
+- **validateToken(id_token, state, nonce)**:
+        * **id_token**: the id_token received from Auth0
+        * **state**: the transaction state
+        * **nonce**: the nonce used to verify the token if it was not autogenerated
+- **renewAuth(options, cb)**: fetches a new access_token
+    + **options {object}**:
+        * **usePostMessage**: It will wait until the callback page sends the authentication result over `postMessage`. If false, it will attempt to parse the url hash.
+        * **scope**
+        * **audience**
+        * **nonce**
+        * **state**
+        * **redirectUri**
+        * **responseType**: defaults to `token`
+        * **respondeMode**: defaults to `fragment`
+- **changePassword(options, cb)**
+- **passwordlessStart(options, cb)**
+- **signup(options, cb)**
+- **login**
+- **logout**
+- **passwordlessVerify**
 - **redirect.login**
-- **redirect.passwordlessVerify**
-- **redirect.signup**
+- **redirect.signupAndLogin**
+- **popup.authorize**
+- **popup.preload**
 - **popup.login**
 - **popup.passwordlessVerify**
-- **popup.signup**
-- **changePassword**
-- **parseHash**
-- **renewAuth**
+- **popup.signupAndLogin**
 
 ## Authentication API
 
@@ -78,3 +112,20 @@ Parameters:
 - **getUser**:
 - **patchUserMetadata**:
 - **linkUsers**:
+
+
+<!-- Vaaaaarrrrsss -->
+
+[npm-image]: https://img.shields.io/npm/v/auth0-js.svg?style=flat-square
+[npm-url]: https://npmjs.org/package/auth0-js
+[travis-image]: https://travis-ci.org/auth0/auth0.js.svg?branch=master
+[travis-url]: https://travis-ci.org/auth0/auth0.js
+[coveralls-image]: https://img.shields.io/coveralls/auth0/auth0.js.svg?style=flat-square
+[codecov-image]: http://codecov.io/github/auth0/auth0.js/coverage.svg?branch=v8
+[coveralls-url]: https://coveralls.io/r/auth0/auth0.js?branch=master
+[david-image]: http://img.shields.io/david/auth0/auth0.js.svg?style=flat-square
+[david-url]: https://david-dm.org/auth0/auth0.js
+[license-image]: http://img.shields.io/npm/l/auth0-js.svg?style=flat-square
+[license-url]: #license
+[downloads-image]: http://img.shields.io/npm/dm/auth0-js.svg?style=flat-square
+[downloads-url]: https://npmjs.org/package/auth0-js
\ No newline at end of file
diff --git a/example/index.html b/example/index.html
index cb32867..0098938 100644
--- a/example/index.html
+++ b/example/index.html
@@ -6,6 +6,7 @@
     <script src="/webpack-dev-server.js"></script>
     <script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
     <script src="/auth0.js"></script>
+
     <style>
       .row {
         margin:10px 0;
@@ -241,7 +242,7 @@
 
     $('.login-hosted').click(function (e) {
       e.preventDefault();
-      webAuth.login({ });
+      webAuth.login({});
     });
 
     $('.login-twitter').click(function (e) {
@@ -291,6 +292,5 @@
       );
     });
     </script>
-
   </body>
 </html>
diff --git a/src/authentication/index.js b/src/authentication/index.js
index 624e77b..e38a401 100644
--- a/src/authentication/index.js
+++ b/src/authentication/index.js
@@ -5,6 +5,7 @@ var qs = require('../helper/qs');
 var objectHelper = require('../helper/object');
 var assert = require('../helper/assert');
 var responseHandler = require('../helper/response-handler');
+var parametersWhitelist = require('../helper/parameters-whitelist');
 var Warn = require('../helper/warn');
 
 var PasswordlessAuthentication = require('./passwordless-authentication');
@@ -80,6 +81,7 @@ Authentication.prototype.buildAuthorizeUrl = function (options) {
   }
 
   params = objectHelper.toSnakeCase(params, ['auth0Client']);
+  params = parametersWhitelist.oauthAuthorizeParams(params);
 
   qString = qs.build(params);
 
diff --git a/src/helper/information.js b/src/helper/information.js
deleted file mode 100644
index 3624a9b..0000000
--- a/src/helper/information.js
+++ /dev/null
@@ -1,7 +0,0 @@
-function error(message) {
-  console.error(message);
-}
-
-module.exports = {
-  error: error
-};
diff --git a/src/helper/parameters-whitelist.js b/src/helper/parameters-whitelist.js
new file mode 100644
index 0000000..4c64b50
--- /dev/null
+++ b/src/helper/parameters-whitelist.js
@@ -0,0 +1,39 @@
+var objectHelper = require('../helper/object');
+
+var authorize_params = [
+// auth0
+  'connection',
+  'auth0Client',
+  'owp',
+// oauth2
+  'client_id',
+  'response_type',
+  'response_mode',
+  'redirect_uri',
+  'audience',
+  'scope',
+  'state',
+  'nonce',
+  'display',
+  'prompt',
+  'max_age',
+  'ui_locales',
+  'claims_locales',
+  'id_token_hint',
+  'login_hint',
+  'acr_values',
+  'claims',
+  'registration',
+  'request',
+  'request_uri',
+  'code_challenge',
+  'code_challenge_method'
+];
+
+function oauthAuthorizeParams(params) {
+  return objectHelper.pick(params, authorize_params);
+}
+
+module.exports = {
+  oauthAuthorizeParams: oauthAuthorizeParams
+};
diff --git a/src/helper/popup-handler.js b/src/helper/popup-handler.js
index c26befb..3a55967 100644
--- a/src/helper/popup-handler.js
+++ b/src/helper/popup-handler.js
@@ -41,6 +41,7 @@ PopupHandler.prototype.calculatePosition = function (options) {
 
 PopupHandler.prototype.preload = function (options) {
   var _this = this;
+  var _window = windowHandler.getWindow();
   var popupPosition = this.calculatePosition(options.popupOptions || {});
   var popupOptions = objectHelper.merge(popupPosition).with(options.popupOptions);
   var url = options.url || 'about:blank';
@@ -50,7 +51,7 @@ PopupHandler.prototype.preload = function (options) {
     return this._current_popup;
   }
 
-  this._current_popup = window.open(url, 'auth0_signup_popup', windowFeatures);
+  this._current_popup = _window.open(url, 'auth0_signup_popup', windowFeatures);
 
   this._current_popup.kill = function () {
     this.close();
diff --git a/src/web-auth/index.js b/src/web-auth/index.js
index ddc3100..eee3e3f 100644
--- a/src/web-auth/index.js
+++ b/src/web-auth/index.js
@@ -72,7 +72,7 @@ WebAuth.prototype.parseHash = function (hash, options) {
   }
 
   if (parsedQs.id_token) {
-    token = this.validateToken(parsedQs.id_token, parsedQs.state, options);
+    token = this.validateToken(parsedQs.id_token, parsedQs.state || options.state, options.nonce);
     if (token.error) {
       return token;
     }
@@ -88,9 +88,10 @@ WebAuth.prototype.parseHash = function (hash, options) {
   };
 };
 
-WebAuth.prototype.validateToken = function (token, state) {
+WebAuth.prototype.validateToken = function (token, state, nonce) {
   var audiences;
   var transaction;
+  var transactionNonce;
   var tokenNonce;
   var prof = jwt.getPayload(token);
 
@@ -102,9 +103,10 @@ WebAuth.prototype.validateToken = function (token, state) {
   }
 
   transaction = this.transactionManager.getStoredTransaction(state);
+  transactionNonce = (transaction && transaction.nonce) || nonce;
   tokenNonce = prof.nonce || null;
 
-  if (transaction && tokenNonce && transaction.nonce !== tokenNonce) {
+  if (transactionNonce && tokenNonce && transactionNonce !== tokenNonce) {
     return error.invalidJwt('Nonce does not match');
   }
 
@@ -135,6 +137,9 @@ WebAuth.prototype.renewAuth = function (options, cb) {
     'audience'
   ]).with(options);
 
+  params.responseType = params.responseType || 'token';
+  params.responseMode = params.responseMode || 'fragment';
+
   params = this.transactionManager.process(params);
 
   assert.check(params, { type: 'object', message: 'options parameter is not valid' }, {
diff --git a/src/web-auth/popup.js b/src/web-auth/popup.js
index 82fb2af..2f68d38 100644
--- a/src/web-auth/popup.js
+++ b/src/web-auth/popup.js
@@ -23,11 +23,11 @@ Popup.prototype.preload = function (options) {
   return popup;
 };
 
-Popup.prototype.getPopupHandler = function (options) {
+Popup.prototype.getPopupHandler = function (options, preload) {
   if (options.popupHandler) {
     return options.popupHandler;
   }
-  return new PopupHandler();
+  return !!preload ? this.preload(options) : new PopupHandler();
 };
 
 Popup.prototype.authorize = function (options, cb) {
@@ -123,13 +123,15 @@ Popup.prototype.signupAndLogin = function (options, cb) {
   var _this = this;
 
   // Preload popup to avoid the browser to block it since the login happens later
-  var popup = this.getPopupHandler(options);
-  options.popupHandler = options;
+  var popupHandler = this.getPopupHandler(options, true);
+  options.popupHandler = popupHandler;
 
   return this.client.dbConnection.signup(objectHelper.blacklist(options, ['popupHandler']),
     function (err) {
       if (err) {
-        popupHandler._current_popup.kill();
+        if (popupHandler._current_popup) {
+          popupHandler._current_popup.kill();
+        }
         return cb(err);
       }
       _this.login(options, cb);
diff --git a/src/web-auth/silent-authentication-handler.js b/src/web-auth/silent-authentication-handler.js
index 6468a98..539719c 100644
--- a/src/web-auth/silent-authentication-handler.js
+++ b/src/web-auth/silent-authentication-handler.js
@@ -1,4 +1,3 @@
-var information = require('../helper/information');
 var IframeHandler = require('../helper/iframe-handler');
 
 function SilentAuthenticationHandler(auth0, authenticationUrl, timeout) {


Test patch:
diff --git a/test/authentication/authentication.test.js b/test/authentication/authentication.test.js
index 0ff6ec2..da263b6 100644
--- a/test/authentication/authentication.test.js
+++ b/test/authentication/authentication.test.js
@@ -73,7 +73,7 @@ describe('auth0.authentication', function () {
         state: '1234'
       });
 
-      expect(url).to.be('https://me.auth0.com/authorize?client_id=...&response_type=token&redirect_uri=http%3A%2F%2Fanotherpage.com%2Fcallback2&prompt=none&state=1234');
+      expect(url).to.be('https://me.auth0.com/authorize?client_id=...&response_type=token&redirect_uri=http%3A%2F%2Fanotherpage.com%2Fcallback2&state=1234&prompt=none');
     })
   })
 
@@ -95,7 +95,7 @@ describe('auth0.authentication', function () {
         state: '1234'
       });
 
-      expect(url).to.be('https://me.auth0.com/authorize?client_id=...&response_type=token&redirect_uri=http%3A%2F%2Fanotherpage.com%2Fcallback2&prompt=none&state=1234&auth0Client=' + telemetryInfo);
+      expect(url).to.be('https://me.auth0.com/authorize?auth0Client='+ telemetryInfo+'&client_id=...&response_type=token&redirect_uri=http%3A%2F%2Fanotherpage.com%2Fcallback2&state=1234&prompt=none');
     })
   })
 
diff --git a/test/helper/information.test.js b/test/helper/information.test.js
deleted file mode 100644
index 97e7d1a..0000000
--- a/test/helper/information.test.js
+++ /dev/null
@@ -1,22 +0,0 @@
-var expect = require('expect.js');
-var stub = require('sinon').stub;
-
-var information = require('../../src/helper/information');
-
-describe('helpers information', function () {
-  describe('error', function () {
-    beforeEach(function() {
-      stub(console, 'error', function (message) {
-        expect(message).to.be('some error message');
-      });
-    });
-
-    afterEach(function() {
-      console.error.restore();
-    });
-
-    it('should show an error in the console', function () {
-      information.error('some error message');
-    });
-  });
-});
diff --git a/test/web-auth/popup.test.js b/test/web-auth/popup.test.js
index 7d3a15d..254677c 100644
--- a/test/web-auth/popup.test.js
+++ b/test/web-auth/popup.test.js
@@ -5,6 +5,7 @@ var RequestMock = require('../mock/request-mock');
 var request = require('superagent');
 
 var PopupHandler = require('../../src/helper/popup-handler');
+var windowHandler = require('../../src/helper/window');
 var WebAuth = require('../../src/web-auth');
 
 describe('auth0.WebAuth.popup', function () {
@@ -84,7 +85,7 @@ describe('auth0.WebAuth.popup', function () {
 
     it('should open the authorize page in a popup', function (done) {
       stub(PopupHandler.prototype, 'load', function(url, relayUrl, options, cb) {
-        expect(url).to.be('https://me.auth0.com/authorize?client_id=...&response_type=id_token&redirect_uri=http%3A%2F%2Fpage.com%2Fcallback&connection=the_connection&nonce=123&state=456&owp=true');
+        expect(url).to.be('https://me.auth0.com/authorize?connection=the_connection&owp=true&client_id=...&response_type=id_token&redirect_uri=http%3A%2F%2Fpage.com%2Fcallback&state=456&nonce=123');
         expect(relayUrl).to.be('https://me.auth0.com/relay.html');
         expect(options).to.eql({});
         cb(null, {
@@ -367,17 +368,18 @@ describe('auth0.WebAuth.popup', function () {
         responseType: 'token',
         _sendTelemetry: false
       });
-    });
-
-    afterEach(function () {
-      request.post.restore();
-    });
 
-    after(function(){
-      PopupHandler.prototype.load.restore();
-    })
-
-    it('should call db-connection signup with all the options', function (done) {
+      stub(windowHandler, 'getWindow', function() {
+        return {
+          screenX: 500,
+          screenY: 500,
+          outerWidth: 2000,
+          outerHeight: 500,
+          open: function() { return {
+            close: function() {}
+          }; }
+        };
+      });
 
       stub(PopupHandler.prototype, 'load', function(url, relayUrl, options, cb) {
         expect(url).to.be('https://me.auth0.com/sso_dbconnection_popup/...');
@@ -394,6 +396,18 @@ describe('auth0.WebAuth.popup', function () {
 
         cb();
       });
+    });
+
+    afterEach(function () {
+      request.post.restore();
+    });
+
+    after(function(){
+      windowHandler.getWindow.restore();
+      PopupHandler.prototype.load.restore();
+    })
+
+    it('should call db-connection signup with all the options', function (done) {
 
       stub(request, 'post', function (url) {
         expect(url).to.eql('https://me.auth0.com/dbconnections/signup');
diff --git a/test/web-auth/redirect.test.js b/test/web-auth/redirect.test.js
index 53b6512..9dc5840 100644
--- a/test/web-auth/redirect.test.js
+++ b/test/web-auth/redirect.test.js
@@ -561,7 +561,7 @@ describe('auth0.WebAuth.redirect', function () {
 
     it('should redirect to authorize', function () {
       this.auth0.login({connection: 'facebook', state: '1234'})
-      expect(global.window.location).to.be('https://me.auth0.com/authorize?client_id=...&response_type=code&redirect_uri=http%3A%2F%2Fpage.com%2Fcallback&connection=facebook&state=1234');
+      expect(global.window.location).to.be('https://me.auth0.com/authorize?connection=facebook&client_id=...&response_type=code&redirect_uri=http%3A%2F%2Fpage.com%2Fcallback&state=1234');
     });
 
     it('should redirect to logout', function () {
diff --git a/test/web-auth/web-auth.test.js b/test/web-auth/web-auth.test.js
index 7f73418..bdc7726 100644
--- a/test/web-auth/web-auth.test.js
+++ b/test/web-auth/web-auth.test.js
@@ -3,7 +3,6 @@ var stub = require('sinon').stub;
 var request = require('superagent');
 
 var IframeHandler = require('../../src/helper/iframe-handler');
-var information = require('../../src/helper/information');
 
 var RequestMock = require('../mock/request-mock');
 
@@ -219,7 +218,7 @@ describe('auth0.WebAuth', function () {
 
     it('should pass the correct authorize url', function (done) {
       stub(IframeHandler.prototype, 'init', function(message) {
-        expect(this.url).to.be('https://me.auth0.com/authorize?client_id=...&response_type=id_token&redirect_uri=http%3A%2F%2Fpage.com%2Fcallback&scope=openid%20name%20read%3Ablog&audience=urn%3Asite%3Ademo%3Ablog&nonce=123&state=456&prompt=none');
+        expect(this.url).to.be('https://me.auth0.com/authorize?client_id=...&response_type=id_token&redirect_uri=http%3A%2F%2Fpage.com%2Fcallback&audience=urn%3Asite%3Ademo%3Ablog&scope=openid%20name%20read%3Ablog&state=456&nonce=123&prompt=none');
         this.timeoutCallback();
       });