const { Middleware } = require('libflitter') class APIRouteMiddleware extends Middleware { static get services() { return [...super.services, 'models'] } async test(req, res, next, { allow_token = true, allow_user = true }) { if ( !req.additional_api_log_data ) req.additional_api_log_data = {} // First, check if there is a user in the session. if ( allow_user && req.user ) { req.additional_api_log_data.authorized_by = 'user' return next() } else if ( allow_token ) { if ( !req.oauth ) req.oauth = {} req.additional_api_log_data.attempted_token_auth = true return req.app.oauth2.authorise()(req, res, async e => { if ( e ) return next(e) req.additional_api_log_data.authorized_by = 'token' // Look up the OAuth2 client an inject it into the route if ( req.user && req.user.id ) { const User = this.models.get('auth:User') const user = await User.findById(req.user.id) if ( !user ) return res.status(401) .message('The user this token is associated with no longer exists.') .api() req.user = user req.is_auth = true // Look up the token and the associated client const Oauth2BearerToken = this.models.get('auth::Oauth2BearerToken') const Client = this.models.get('oauth:Client') // e.g. "Bearer XYZ".split(' ')[1] -> "XYZ" const bearer = req.headers.authorization.split(' ')[1] const token = await Oauth2BearerToken.findOne({ accessToken: bearer }) if ( !token ) return res.status(401) .message('Unable to lookup OAuth2 token.') .api() const client = await Client.findOne({uuid: token.clientID}) if ( !client ) return res.status(401) .message('This OAuth2 client is no longer authorized.') .api() req.additional_api_log_data.token_client_id = client.uuid req.additional_api_log_data.token = bearer req.oauth.token = token req.oauth.client = client } else return res.status(401) .message('Unable to lookup user associated with that token.') .api() next() }) } else { return res.status(401).api() } } } module.exports = exports = APIRouteMiddleware