const { Controller } = require('libflitter') const is_absolute_url = require('is-absolute-url') class OAuthController extends Controller { static get services() { return [...super.services, 'models'] } async get_clients(req, res, next) { const Client = this.models.get('oauth:Client') const clients = await Client.find({ active: true }) const data = [] for ( const client of clients ) { if ( req.user.can(`oauth:client:${client.id}:view`) ) { data.push(await client.to_api()) } } return res.api(data) } async get_client(req, res, next) { const Client = this.models.get('oauth:Client') const client = await Client.findById(req.params.id) if ( !client || !client.active ) return res.status(404) .message('Client not found with that ID.') .api() if ( !req.user.can(`oauth:client:${client.id}:view`) ) return res.status(401) .message('Insufficient permissions.') .api() return res.api(await client.to_api()) } async create_client(req, res, next) { if ( !req.user.can('oauth:client:create') ) return res.status(401) .message('Insufficient permissions.') .api() const required_fields = ['name', 'api_scopes', 'redirect_url'] for ( const field of required_fields ) { if ( !req.body[field] ) return res.status(400) .message(`Missing required field: ${field}`) .api() } if ( !Array.isArray(req.body.api_scopes) ) { return res.status(400) .message(`Improperly formatted field: api_scopes (should be array)`) .api() } if ( !is_absolute_url(req.body.redirect_url) ) return res.status(400) .message(`Improperly formatted field: redirect_url (should be absolute URL)`) .api() const Client = this.models.get('oauth:Client') const client = new Client({ name: req.body.name, api_scopes: req.body.api_scopes, redirect_url: req.body.redirect_url, }) await client.save() return res.api(await client.to_api()) } async update_client(req, res, next) { const Client = this.models.get('oauth:Client') const client = await Client.findById(req.params.id) if ( !client || !client.active ) return res.status(404) .message('Client not found with that ID.') .api() if ( !req.user.can(`oauth:client:${client.id}:update`) ) return res.status(401) .message('Insufficient permissions.') .api() const required_fields = ['name', 'api_scopes', 'redirect_url'] for ( const field of required_fields ) { if ( !req.body[field] ) return res.status(400) .message(`Missing required field: ${field}`) .api() } if ( !Array.isArray(req.body.api_scopes) ) return res.status(400) .message(`Improperly formatted field: api_scopes (should be array)`) .api() if ( !is_absolute_url(req.body.redirect_url) ) return res.status(400) .message(`Improperly formatted field: redirect_url (should be absolute URL)`) .api() client.name = req.body.name client.api_scopes = req.body.api_scopes client.redirect_url = req.body.redirect_url await client.save() return res.api() } async delete_client(req, res, next) { const Client = this.models.get('oauth:Client') const client = await Client.findById(req.params.id) if ( !client || !client.active ) return res.status(404) .message('Client not found with that ID.') .api() if ( !req.user.can(`oauth:client:${client.id}:delete`) ) return res.status(401) .message('Insufficient permissions.') .api() client.active = false await client.save() return res.api() } } module.exports = exports = OAuthController