You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
const { SchemaDirectiveVisitor } = require('graphql-tools') const { defaultFieldResolver } = require('graphql') const _ = require('lodash')
class AuthDirective extends SchemaDirectiveVisitor { visitObject(type) { this.ensureFieldsWrapped(type) type._requiredAuthScopes = this.args.requires } // Visitor methods for nested types like fields and arguments
// also receive a details object that provides information about
// the parent and grandparent types.
visitFieldDefinition(field, details) { this.ensureFieldsWrapped(details.objectType) field._requiredAuthScopes = this.args.requires }
visitArgumentDefinition(argument, details) { this.ensureFieldsWrapped(details.objectType) argument._requiredAuthScopes = this.args.requires }
ensureFieldsWrapped(objectType) { // Mark the GraphQLObjectType object to avoid re-wrapping:
if (objectType._authFieldsWrapped) return objectType._authFieldsWrapped = true
const fields = objectType.getFields()
Object.keys(fields).forEach(fieldName => { const field = fields[fieldName] const { resolve = defaultFieldResolver } = field field.resolve = async function (...args) { // Get the required scopes from the field first, falling back
// to the objectType if no scopes is required by the field:
const requiredScopes = field._requiredAuthScopes || objectType._requiredAuthScopes
if (!requiredScopes) { return resolve.apply(this, args) }
const context = args[2] if (!context.req.user) { throw new Error('Unauthorized') }
if (!_.some(context.req.user.permissions, pm => _.includes(requiredScopes, pm))) { throw new Error('Forbidden') }
return resolve.apply(this, args) } }) } }
module.exports = AuthDirective
|