UNPKG

yabaas

Version:

Yet Another Backend as a Service

119 lines (94 loc) 4.07 kB
// 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) }