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
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')
|