diff --git a/lib/handlers/authenticate-handler.js b/lib/handlers/authenticate-handler.js index b02b123..3521a7a 100644 --- a/lib/handlers/authenticate-handler.js +++ b/lib/handlers/authenticate-handler.js @@ -90,6 +90,12 @@ AuthenticateHandler.prototype.handle = function(request, response) { // @see https://tools.ietf.org/html/rfc6750#section-3.1 if (e instanceof UnauthorizedRequestError) { response.set('WWW-Authenticate', 'Bearer realm="Service"'); + } else if (e instanceof InvalidRequestError) { + response.set('WWW-Authenticate', 'Bearer realm="Service",error="invalid_request"'); + } else if (e instanceof InvalidTokenError) { + response.set('WWW-Authenticate', 'Bearer realm="Service",error="invalid_token"'); + } else if (e instanceof InsufficientScopeError) { + response.set('WWW-Authenticate', 'Bearer realm="Service",error="insufficient_scope"'); } if (!(e instanceof OAuthError)) { diff --git a/test/integration/handlers/authenticate-handler_test.js b/test/integration/handlers/authenticate-handler_test.js index 3e0eefd..151ada3 100644 --- a/test/integration/handlers/authenticate-handler_test.js +++ b/test/integration/handlers/authenticate-handler_test.js @@ -132,6 +132,57 @@ describe('AuthenticateHandler integration', function() { }); }); + it('should set the `WWW-Authenticate` header if an InvalidRequestError is thrown', function() { + const model = { + getAccessToken: function() { + throw new InvalidRequestError(); + } + }; + const handler = new AuthenticateHandler({ model: model }); + const request = new Request({ body: {}, headers: { 'Authorization': 'Bearer foo' }, method: {}, query: {} }); + const response = new Response({ body: {}, headers: {} }); + + return handler.handle(request, response) + .then(should.fail) + .catch(function() { + response.get('WWW-Authenticate').should.equal('Bearer realm="Service",error="invalid_request"'); + }); + }); + + it('should set the `WWW-Authenticate` header if an InvalidTokenError is thrown', function() { + const model = { + getAccessToken: function() { + throw new InvalidTokenError(); + } + }; + const handler = new AuthenticateHandler({ model: model }); + const request = new Request({ body: {}, headers: { 'Authorization': 'Bearer foo' }, method: {}, query: {} }); + const response = new Response({ body: {}, headers: {} }); + + return handler.handle(request, response) + .then(should.fail) + .catch(function() { + response.get('WWW-Authenticate').should.equal('Bearer realm="Service",error="invalid_token"'); + }); + }); + + it('should set the `WWW-Authenticate` header if an InsufficientScopeError is thrown', function() { + const model = { + getAccessToken: function() { + throw new InsufficientScopeError(); + } + }; + const handler = new AuthenticateHandler({ model: model }); + const request = new Request({ body: {}, headers: { 'Authorization': 'Bearer foo' }, method: {}, query: {} }); + const response = new Response({ body: {}, headers: {} }); + + return handler.handle(request, response) + .then(should.fail) + .catch(function() { + response.get('WWW-Authenticate').should.equal('Bearer realm="Service",error="insufficient_scope"'); + }); + }); + it('should throw the error if an oauth error is thrown', function() { const model = { getAccessToken: function() {