yabaas
Version:
Yet Another Backend as a Service
119 lines (94 loc) • 4.07 kB
JavaScript
// Authentication JWT passport
//
const debug = require('debug')('yabaas:authentication') // eslint-disable-line
const jsonAuthentication = require(process.cwd() + '/spec/json-authentication')
const express = require('express')
const passport = require('passport')
// const _ = require('lodash')
const jwt = require('jsonwebtoken')
const passportJWT = require('passport-jwt')
const users = require('./user')
const secretOrKey = 'api_secret_key'
const jwtOptions = {}
jwtOptions.secretOrKey = secretOrKey
jwtOptions.jwtFromRequest = passportJWT.ExtractJwt.fromAuthHeaderAsBearerToken()
const jwtStrategy = new passportJWT.Strategy(jwtOptions, function (jwtPayload, done) {
users.readOne({ email: jwtPayload.email, password: jwtPayload.password })
.then((user) => {
debug('jwtStrategy() user found ' + JSON.stringify(user))
return done(null, user)
})
.catch((error) => {
debug('jwtStrategy() ' + error)
return done(error, false)
})
})
passport.use(jwtStrategy)
express().use(passport.initialize())
exports.requireLogin = function (req, res, next) {
debug('requireLogin() ' + req.originalUrl)
const isEqual = jsonAuthentication.api.authentication.equal_to.some((query, index) => {
const method = query.method
query = query.path
debug('requireLogin() ' + req.originalUrl + ' equal_to ' + query)
if (req.originalUrl === query && (method === req.method || typeof method === 'undefined')) {
debug('requireLogin() ' + req.originalUrl + ' equal_to ' + query + ' No authentication needed')
return true
}
return false
})
if (isEqual) {
debug('requireLogin() ' + req.originalUrl + ' Authentication is not needed because of equal_to configuration')
return next()
}
const startBy = jsonAuthentication.api.authentication.start_by.some((query, index) => {
const method = query.method
query = query.path
debug('requireLogin() ' + req.originalUrl + ' -start_by ' + query)
debug('requireLogin() start_by method %s %s', req.method, method)
if (new RegExp('^' + query, 'i').test(req.originalUrl) && (method === req.method || typeof method === 'undefined')) {
debug('requireLogin() ' + req.originalUrl + ' start_by ' + query + ' No authentication needed')
return true
}
return false
})
if (startBy) {
debug('requireLogin() ' + req.originalUrl + ' Authentication is not needed because of start_by configuration')
return next()
}
passport.authenticate('jwt', { session: false }, (err, user, info) => {
if (err) {
debug('requireLogin() ' + req.originalUrl + ' ' + err)
return next(err)
}
debug('requireLogin() ' + req.originalUrl + ' user=' + JSON.stringify(user) + ' info=' + info)
if (!user) {
debug('requireLogin() ' + req.originalUrl + ' user not found')
return res.status(401).json('Unauthorized')
}
let isNotOwner = jsonAuthentication.api.authentication.is_owner.some((query, index) => {
const method = query.method
query = query.path
debug('requireLogin() owner originalUrl=' + req.originalUrl + ' query=' + query)
const route = query.replace(':user', '')
if (new RegExp('^' + route, 'i').test(req.originalUrl) === false && (method === req.method || typeof method === 'undefined')) {
debug('requireLogin() owner No need to check ownership in ' + req.originalUrl + ' route=' + route)
return false
}
const fullRoute = query.replace(':user', user.email)
debug('requireLogin() owner fullRoute=' + fullRoute)
if (new RegExp('^' + fullRoute, 'i').test(req.originalUrl) === false) {
debug('requireLogin() owner You are not the owner ' + req.originalUrl + ' fullRoute=' + fullRoute)
return true
}
return false
})
if (isNotOwner) {
return res.status(401).json('Unauthorized')
}
return next()
})(req, res, next)
}
exports.getToken = function (identifier) {
return jwt.sign({ email: identifier.email, password: identifier.password }, secretOrKey)
}