import { defaultFieldResolver } from 'graphql' ; import { SchemaDirectiveVisitor } from 'apollo-server' ; import { getUserRole } from '../../common/middleware/auth-middleware' ; import { UnAuthorizedError } from '../errors' ; class AuthDirective extends SchemaDirectiveVisitor { public visitObject ( type ) { this . ensureFieldsWrapped ( type ) ; type . _requiredAuthRole = this . args . requires ; } public visitFieldDefinition ( field , details ) { this . ensureFieldsWrapped ( details . objectType ) ; field . _requiredAuthRole = this . args . requires ; } public ensureFieldsWrapped ( objectType ) { 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 ) { const requiredRole = field . _requiredAuthRole || objectType . _requiredAuthRole ; if ( ! requiredRole ) { return resolve . apply ( this , args ) ; } const context = args [ 2 ] ; const role = await getUserRole ( context ) ; if ( role !== requiredRole ) { throw new UnAuthorizedError ( { data : { error_code : 'AUTH01' } } ) ; } return resolve . apply ( this , args ) ; } ; } ) ; } } export default AuthDirective ;