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
			| 
								 
											3 years ago
										 
									 | 
							
								'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')
							 |