fastify-basic-auth
Advanced tools
Comparing version 0.2.0 to 0.3.0
26
index.js
@@ -10,3 +10,3 @@ 'use strict' | ||
} | ||
const authenticateHeader = getAuthenticateHeader(opts.authenticate) | ||
const validate = opts.validate.bind(fastify) | ||
@@ -18,2 +18,5 @@ fastify.decorate('basicAuth', basicAuth) | ||
function basicAuth (req, reply, next) { | ||
if (authenticateHeader) { | ||
reply.header(authenticateHeader.key, authenticateHeader.value) | ||
} | ||
var credentials = auth(req) | ||
@@ -40,2 +43,23 @@ if (credentials == null) { | ||
function getAuthenticateHeader (authenticate) { | ||
if (!authenticate) return false | ||
if (authenticate === true) { | ||
return { | ||
key: 'WWW-Authenticate', | ||
value: 'Basic' | ||
} | ||
} | ||
if (typeof authenticate === 'object') { | ||
const realm = (authenticate.realm && typeof authenticate.realm === 'string') | ||
? authenticate.realm | ||
: '' | ||
return { | ||
key: 'WWW-Authenticate', | ||
value: 'Basic' + (realm ? ` realm="${realm}"` : '') | ||
} | ||
} | ||
throw Error('Basic Auth: Invalid authenticate option') | ||
} | ||
module.exports = fp(basicPlugin, { | ||
@@ -42,0 +66,0 @@ fastify: '>=1.0.0', |
{ | ||
"name": "fastify-basic-auth", | ||
"version": "0.2.0", | ||
"version": "0.3.0", | ||
"description": "Fastify basic auth plugin", | ||
@@ -28,3 +28,3 @@ "main": "index.js", | ||
"fastify": "^1.5.0", | ||
"fastify-auth": "^0.2.0", | ||
"fastify-auth": "^0.3.0", | ||
"standard": "^11.0.1", | ||
@@ -31,0 +31,0 @@ "tap": "^12.0.1" |
@@ -17,4 +17,4 @@ # fastify-basic-auth | ||
const fastify = require('fastify')() | ||
fastify.register(require('fastify-basic-auth'), { validate }) | ||
const authenticate = {realm: 'Westeros'} | ||
fastify.register(require('fastify-basic-auth'), { validate, authenticate }) | ||
// `this` inside validate is `fastify` | ||
@@ -41,4 +41,4 @@ function validate (username, password, req, reply, done) { | ||
const fastify = require('fastify')() | ||
fastify.register(require('fastify-basic-auth'), { validate }) | ||
const authenticate = {realm: 'Westeros'} | ||
fastify.register(require('fastify-basic-auth'), { validate, authenticate }) | ||
async function validate (username, password, req, reply) { | ||
@@ -51,7 +51,7 @@ if (username !== 'Tyrion' || password !== 'wine') { | ||
Use with `beforeHander`: | ||
Use with `beforeHandler`: | ||
```js | ||
const fastify = require('fastify')() | ||
fastify.register(require('fastify-basic-auth'), { validate, disableHook: true }) | ||
const authenticate = {realm: 'Westeros'} | ||
fastify.register(require('fastify-basic-auth'), { validate, authenticate, disableHook: true }) | ||
async function validate (username, password, req, reply) { | ||
@@ -78,5 +78,5 @@ if (username !== 'Tyrion' || password !== 'wine') { | ||
const fastify = require('fastify')() | ||
const authenticate = {realm: 'Westeros'} | ||
fastify.register(require('fastify-auth')) | ||
fastify.register(require('fastify-basic-auth'), { validate, disableHook: true }) | ||
fastify.register(require('fastify-basic-auth'), { validate, authenticate, disableHook: true }) | ||
async function validate (username, password, req, reply) { | ||
@@ -104,4 +104,52 @@ if (username !== 'Tyrion' || password !== 'wine') { | ||
## Options | ||
### `validate` <Function> (required) | ||
The `validate` function is called on each request made, | ||
and is passed the `username`, `password`, `req` and `reply` | ||
parameters in that order. An optional fifth parameter, `done` may be | ||
used to signify a valid request when called with no arguments, | ||
or an invalid request when called with an `Error` object. Alternatively, | ||
the `validate` function may return a promise, resolving for valid | ||
requests and rejecting for invalid. This can also be achieved using | ||
an `async/await` function, and throwing for invalid requests. | ||
See code above for examples. | ||
### `authenticate` <Boolean|Object> (optional, default: false) | ||
When supplied, the `authenticate` option will cause the | ||
[`WWW-Authenticate` header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/WWW-Authenticate) to be added. It may also be used to set the `realm` value. | ||
This can be useful in situations where we want to trigger client-side authentication interfaces - for instance the browser authentication dialog. | ||
As a boolean setting `authenticate` to `true` will set a header like so: `WWW-Authenticate: Basic`. When `false`, no header is added. This is the default. | ||
```js | ||
fastify.register(require('fastify-basic-auth'), { | ||
validate, | ||
authenticate: true // WWW-Authenticate: Basic | ||
}) | ||
fastify.register(require('fastify-basic-auth'), { | ||
validate, | ||
authenticate: false // no authenticate header, same as omitting authenticate option | ||
}) | ||
``` | ||
When supplied as an object the `authenticate` option may have a `realm` key. | ||
If the `realm` key is supplied, it will be appended to the header value: | ||
```js | ||
fastify.register(require('fastify-basic-auth'), { | ||
validate, | ||
authenticate: {realm: 'example'} // WWW-Authenticate: Basic realm="example" | ||
}) | ||
``` | ||
## License | ||
Licensed under [MIT](./LICENSE). |
78
test.js
@@ -166,2 +166,80 @@ 'use strict' | ||
test('WWW-Authenticate (authenticate: true)', t => { | ||
t.plan(3) | ||
const fastify = Fastify() | ||
const authenticate = true | ||
fastify.register(basicAuth, { validate, authenticate }) | ||
function validate (username, password, req, res, done) { | ||
if (username === 'user' && password === 'pwd') { | ||
done() | ||
} else { | ||
done(new Error('Unauthorized')) | ||
} | ||
} | ||
fastify.after(() => { | ||
fastify.route({ | ||
method: 'GET', | ||
url: '/', | ||
beforeHandler: fastify.basicAuth, | ||
handler: (req, reply) => { | ||
reply.send({ hello: 'world' }) | ||
} | ||
}) | ||
}) | ||
fastify.inject({ | ||
url: '/', | ||
method: 'GET', | ||
headers: { | ||
authorization: basicAuthHeader('user', 'pwd') | ||
} | ||
}, (err, res) => { | ||
t.is(res.headers['www-authenticate'], 'Basic') | ||
t.error(err) | ||
t.strictEqual(res.statusCode, 200) | ||
}) | ||
}) | ||
test('WWW-Authenticate Realm (authenticate: {realm: "example"})', t => { | ||
t.plan(3) | ||
const fastify = Fastify() | ||
const authenticate = {realm: 'example'} | ||
fastify.register(basicAuth, { validate, authenticate }) | ||
function validate (username, password, req, res, done) { | ||
if (username === 'user' && password === 'pwd') { | ||
done() | ||
} else { | ||
done(new Error('Unauthorized')) | ||
} | ||
} | ||
fastify.after(() => { | ||
fastify.route({ | ||
method: 'GET', | ||
url: '/', | ||
beforeHandler: fastify.basicAuth, | ||
handler: (req, reply) => { | ||
reply.send({ hello: 'world' }) | ||
} | ||
}) | ||
}) | ||
fastify.inject({ | ||
url: '/', | ||
method: 'GET', | ||
headers: { | ||
authorization: basicAuthHeader('user', 'pwd') | ||
} | ||
}, (err, res) => { | ||
t.is(res.headers['www-authenticate'], 'Basic realm="example"') | ||
t.error(err) | ||
t.strictEqual(res.statusCode, 200) | ||
}) | ||
}) | ||
test('Missing validate function', t => { | ||
@@ -168,0 +246,0 @@ t.plan(1) |
18102
458
151