CoreID/app/controllers/api/v1/Reflect.controller.js
2020-05-20 21:17:07 -05:00

190 lines
6.2 KiB
JavaScript

const { Controller } = require('libflitter')
const uuid = require('uuid/v4')
class ReflectController extends Controller {
static get services() {
return [...super.services, 'routers', 'models']
}
async get_tokens(req, res, next) {
const Oauth2BearerToken = this.models.get('auth::Oauth2BearerToken')
const tokens = await Oauth2BearerToken.find({
expires: { $gt: new Date },
userID: req.user.id,
})
const Client = this.models.get('oauth:Client')
const data = []
for ( const token of tokens ) {
const client = await Client.findOne({ uuid: token.clientID })
let client_display = client && client.active ? client.name : '(Non-existent Client)'
data.push({
id: token.id,
token: token.accessToken,
client_id: token.clientID,
client_display,
expires: token.expires,
user_id: token.userID,
})
}
return res.api(data)
}
async get_token(req, res, next) {
const Oauth2BearerToken = this.models.get('auth::Oauth2BearerToken')
const token = await Oauth2BearerToken.findById(req.params.id)
if ( !token || token.userID !== req.user.id || token.expires <= new Date )
return res.status(404)
.message('Token not found with that ID, or expired.')
.api()
return res.api({
id: token.id,
token: token.accessToken,
client_id: token.clientID,
expires: token.expires,
user_id: token.userID,
})
}
async create_token(req, res, next) {
const Oauth2BearerToken = this.models.get('auth::Oauth2BearerToken')
if ( !req.body.client_id )
return res.status(400)
.message('Missing required field: client_id')
.api()
const Client = this.models.get('oauth:Client')
const client = await Client.findOne({uuid: req.body.client_id})
if ( !client || !client.active )
return res.status(400)
.message('Invalid client_id.')
.api()
if ( !req.user.can(`oauth:client:${client.id}:view`) )
return res.status(401)
.message('Insufficient permissions.')
.api()
const expires = new Date()
expires.setDate(expires.getDate() + 7)
const token = new Oauth2BearerToken({
accessToken: String(uuid()).replace(/-/g, ''),
clientID: client.uuid,
expires,
userID: req.user.id,
})
await token.save()
return res.api({
id: token.id,
token: token.accessToken,
client_id: token.clientID,
expires: token.expires,
user_id: token.userID,
})
}
async update_token(req, res, next) {
const Oauth2BearerToken = this.models.get('auth::Oauth2BearerToken')
const token = await Oauth2BearerToken.findById(req.params.id)
if ( !token || token.userID !== req.user.id || token.expires <= new Date )
return res.status(404)
.message('Token not found with that ID, or expired.')
.api()
if ( !req.body.client_id )
return res.status(400)
.message('Missing required field: client_id')
.api()
const Client = this.models.get('oauth:Client')
const client = await Client.findOne({uuid: req.body.client_id})
if ( !client || !client.active || !req.user.can(`oauth:client:${client.id}:view`) )
return res.status(400)
.message('Invalid client_id.')
.api()
token.client_id = client.uuid
await token.save()
return res.api()
}
async delete_token(req, res, next) {
const Oauth2BearerToken = this.models.get('auth::Oauth2BearerToken')
const token = await Oauth2BearerToken.findById(req.params.id)
if ( !token || token.userID !== req.user.id || token.expires <= new Date )
return res.status(404)
.message('Token not found with that ID, or expired.')
.api()
await token.delete()
return res.api()
}
api_scopes() {
const routers = this.routers.canonical_items
const scopes = []
for ( const prefix in routers ) {
if ( !routers.hasOwnProperty(prefix) ) continue
const router = routers[prefix].schema
const supported_verbs = ['get', 'post', 'put', 'delete', 'copy', 'patch']
for ( const verb of supported_verbs ) {
if ( typeof router[verb] === 'object' ) {
const defs = router[verb]
for ( const def of Object.values(defs) ) {
if ( Array.isArray(def) ) {
for ( const layer of def ) {
if ( Array.isArray(layer) && layer.length > 1 && layer[0] === 'middleware::api:Permission' ) {
if ( typeof layer[1] === 'object' && layer[1].check ) {
scopes.push(layer[1].check)
}
}
}
}
}
}
}
}
scopes.sort()
return scopes
}
async get_scopes(req, res, next) {
const scopes = this.api_scopes()
return res.api(scopes.map(x => {
return { scope: x }
}))
}
async check_permissions(req, res, next) {
if ( !req.body.permissions )
return res.status(400)
.message('Missing permissions to check.')
.api()
const parsed = typeof req.body.permissions === 'string' ? this.utility.infer(req.body.permissions) : req.body.permissions
const permissions = Array.isArray(parsed) ? parsed : [parsed]
const returns = {}
for ( const permission of permissions ) {
returns[permission] = req.user.can(permission)
}
return res.api(returns)
}
}
module.exports = exports = ReflectController