Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ Basic authentication requires validating a username and password combination. Th
included when `isValid` is `true`, but there are cases when the application needs to know who tried to authenticate even when it fails
(e.g. with authentication mode `'try'`).
- `allowEmptyUsername` - (optional) if `true`, allows making requests with an empty username. Defaults to `false`.
- `unauthorizedAttributes` - (optional) if set, passed directly to [Boom.unauthorized](https://github.com/hapijs/boom#boomunauthorizedmessage-scheme-attributes). Useful for setting realm attribute in WWW-Authenticate header. Defaults to `undefined`.

```javascript
const Bcrypt = require('bcrypt');
Expand Down
10 changes: 4 additions & 6 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,13 @@ internals.implementation = function (server, options) {
const req = request.raw.req;
const authorization = req.headers.authorization;
if (!authorization) {
return reply(Boom.unauthorized(null, 'Basic'));
return reply(Boom.unauthorized(null, 'Basic', settings.unauthorizedAttributes));
}

const parts = authorization.split(/\s+/);

if (parts[0].toLowerCase() !== 'basic') {
return reply(Boom.unauthorized(null, 'Basic'));
return reply(Boom.unauthorized(null, 'Basic', settings.unauthorizedAttributes));
}

if (parts.length !== 2) {
Expand All @@ -59,7 +59,7 @@ internals.implementation = function (server, options) {
const password = credentialsPart.slice(sep + 1);

if (!username && !settings.allowEmptyUsername) {
return reply(Boom.unauthorized('HTTP authentication header missing username', 'Basic'));
return reply(Boom.unauthorized('HTTP authentication header missing username', 'Basic', settings.unauthorizedAttributes));
}

settings.validateFunc(request, username, password, (err, isValid, credentials) => {
Expand All @@ -71,7 +71,7 @@ internals.implementation = function (server, options) {
}

if (!isValid) {
return reply(Boom.unauthorized('Bad username or password', 'Basic'), null, { credentials: credentials });
return reply(Boom.unauthorized('Bad username or password', 'Basic', settings.unauthorizedAttributes), null, { credentials: credentials });
}

if (!credentials ||
Expand All @@ -89,5 +89,3 @@ internals.implementation = function (server, options) {

return scheme;
};


35 changes: 35 additions & 0 deletions test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -741,6 +741,41 @@ it('accepts request object in validateFunc', (done) => {
});
});

it('includes additional attributes in WWW-Authenticate header', (done) => {

const server = new Hapi.Server();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing blank line here

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

off topic: what do you think about a separate PR to add .eslintrc with hapi config and .editorconfig to match?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is already built into lab. npm test runs the linter too.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was hoping lab defaulted to that. Doesn't look like it's catching the missing new line for the arrow function but correctly spots it for traditional function declaration. I'll open an issue with hapi-scope-start

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It caught it for me (and travis). That's how I knew about it ;)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Local issue 😳 rm -r node_modules/ && npm i && npm test caught it like it should have. found that hapi-scope-start has a nice test for exactly this

server.connection();
server.register(require('../'), (err) => {

expect(err).to.not.exist();
server.auth.strategy('default', 'basic', 'required', {
validateFunc: internals.user,
unauthorizedAttributes: { realm: 'hapi' }
});
server.route({
method: 'POST',
path: '/',
handler: function (request, reply) {

return reply('ok');
},
config: {
auth: 'default'
}
});

const request = { method: 'POST', url: '/' };

server.inject(request, (res) => {

const wwwAuth = 'www-authenticate';
expect(res.headers).to.include(wwwAuth);
expect(res.headers[wwwAuth]).to.equal('Basic realm=\"hapi\"');
done();
});
});
});


internals.header = function (username, password) {

Expand Down