You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

122 lines
2.8 KiB

'use strict'
const fp = require('fastify-plugin')
const reusify = require('reusify')
function checkAuth (fastify, opts, next) {
fastify.decorate('auth', auth)
next()
}
function auth (functions, opts) {
if (!Array.isArray(functions)) {
throw new Error('You must give an array of functions to the auth function')
}
if (!functions.length) {
throw new Error('Missing auth functions')
}
const options = Object.assign({
relation: 'or',
run: null
}, opts)
if (options.relation !== 'or' && options.relation !== 'and') {
throw new Error('The value of options.relation should be one of [\'or\', \'and\']')
}
if (options.run && options.run !== 'all') {
throw new Error('The value of options.run must be \'all\'')
}
/* eslint-disable-next-line no-var */
for (var i = 0; i < functions.length; i++) {
functions[i] = functions[i].bind(this)
}
const instance = reusify(Auth)
function _auth (request, reply, done) {
const obj = instance.get()
obj.request = request
obj.reply = reply
obj.done = done
obj.functions = this.functions
obj.options = this.options
obj.i = 0
obj.start = true
obj.firstResult = null
obj.nextAuth()
}
return _auth.bind({ functions, options })
function Auth () {
this.next = null
this.i = 0
this.start = true
this.functions = []
this.options = {}
this.request = null
this.reply = null
this.done = null
this.firstResult = null
const that = this
this.nextAuth = function nextAuth (err) {
const func = that.functions[that.i++]
if (!func) {
that.completeAuth(err)
return
}
const maybePromise = func(that.request, that.reply, that.onAuth)
if (maybePromise && typeof maybePromise.then === 'function') {
maybePromise.then(results => that.onAuth(null, results), that.onAuth)
}
}
this.onAuth = function onAuth (err, results) {
if (that.options.relation === 'or') {
if (err) {
return that.nextAuth(err)
}
return that.completeAuth()
} else {
if (err) {
return that.completeAuth(err)
}
return that.nextAuth(err)
}
}
this.completeAuth = function (err) {
if (that.start) {
that.start = false
that.firstResult = err
}
if (that.options.run === 'all' && that.i < that.functions.length) {
return that.nextAuth(err)
}
if (that.firstResult && (!that.reply.raw.statusCode || that.reply.raw.statusCode < 400)) {
that.reply.code(401)
} else if (!that.firstResult && that.reply.raw.statusCode && that.reply.raw.statusCode >= 400) {
that.reply.code(200)
}
that.done(that.firstResult)
instance.release(that)
}
}
}
module.exports = fp(checkAuth, '3.x')