Skip to content

Commit

Permalink
Add optional payload authentication skip on credentials injection (#4274
Browse files Browse the repository at this point in the history
)
  • Loading branch information
jonathansamines committed Sep 10, 2021
1 parent c2107e9 commit ab40394
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 3 deletions.
4 changes: 4 additions & 0 deletions API.md
Original file line number Diff line number Diff line change
Expand Up @@ -1893,6 +1893,10 @@ injections, with some additional options and response properties:
and are validated directly as if they were received via an authentication scheme.
Defaults to no artifacts.

- `payload` - (optional) disables payload authentication when set to false.
Only required when an authentication strategy requires payload authentication.
Defaults to `true`.

- `app` - (optional) sets the initial value of `request.app`, defaults to `{}`.

- `plugins` - (optional) sets the initial value of `request.plugins`, defaults to `{}`.
Expand Down
3 changes: 2 additions & 1 deletion lib/auth.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ const Bounce = require('@hapi/bounce');
const Hoek = require('@hapi/hoek');

const Config = require('./config');
const Request = require('./request');


const internals = {
Expand Down Expand Up @@ -361,7 +362,7 @@ exports = module.exports = internals.Auth = class {

static async payload(request) {

if (!request.auth.isAuthenticated) {
if (!request.auth.isAuthenticated || !request.auth[Request.symbols.authPayload]) {
return;
}

Expand Down
4 changes: 4 additions & 0 deletions lib/request.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ exports = module.exports = internals.Request = class {
isAuthenticated: false,
isAuthorized: false,
isInjected: options.auth ? true : false,
[internals.Request.symbols.authPayload]: options.auth && options.auth.payload !== undefined ? options.auth.payload : true,
credentials: options.auth ? options.auth.credentials : null, // Special keys: 'app', 'user', 'scope'
artifacts: options.auth && options.auth.artifacts || null, // Scheme-specific artifacts
strategy: options.auth ? options.auth.strategy : null,
Expand Down Expand Up @@ -619,6 +620,9 @@ exports = module.exports = internals.Request = class {

internals.Request.reserved = internals.reserved;

internals.Request.symbols = {
authPayload: Symbol('auth.payload')
};

internals.Info = class {

Expand Down
26 changes: 24 additions & 2 deletions test/auth.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ describe('authentication', () => {
strategy: 'default',
mode: 'required',
error: null
});
}, { symbols: false });
});

it('disables authentication on a route', async () => {
Expand Down Expand Up @@ -1100,7 +1100,7 @@ describe('authentication', () => {
strategy: 'default',
mode: 'required',
error: null
});
}, { symbols: false });
});

it('matches scope (access array)', async () => {
Expand Down Expand Up @@ -1759,6 +1759,28 @@ describe('authentication', () => {
expect(res.statusCode).to.equal(204);
});

it('skips required payload authentication when disabled on injection', async () => {

const server = Hapi.server();
server.auth.scheme('custom', internals.implementation);
server.auth.strategy('default', 'custom');
server.auth.default('default');
server.route({
method: 'POST',
path: '/',
options: {
handler: (request) => null,
auth: {
mode: 'try',
payload: true
}
}
});

const res = await server.inject({ method: 'POST', url: '/', auth: { credentials: { payload: Boom.internal('payload error') }, payload: false, strategy: 'default' } });
expect(res.statusCode).to.equal(204);
});

it('errors on missing payload when required', async () => {

const server = Hapi.server();
Expand Down

0 comments on commit ab40394

Please sign in to comment.