You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I realise graphql-modules has moved on from schemaVisitor, but we had a lot of directives built with this pattern when it was dropped and haven't had a chance to look into how to migrate. Just hoping there are others in same boat who might be able to assist.
We have directives all working fine but when we try and run then against an input field, the 'visitInputFieldDefinition' is called but both the subscribe and resolve fields are undefined, so the directive is never called for those fields.
Some code: this is an authorisation directive that allows a check for authroisation and puses the authgraph for the users request into the params to be used further by the providers etc. the problem is that 'const { resolve, subscribe } = field;' both resolve and subscribe are undefined when it's an input field
directive
import { SchemaDirectiveVisitor } from '@graphql-tools/utils'
import { ForbiddenError } from 'apollo-server-lambda';
import { find, isString } from 'lodash';
import { Authorisation } from '../providers';
const dot = require('dot-object');
class isAuthorisedDirective extends SchemaDirectiveVisitor {
visitInputFieldDefinition(field: any) {
this.processField(field);
}
visitFieldDefinition(field: any) {
this.processField(field);
}
processField(field: any) {
const { resolve, subscribe } = field;
const next = resolve || subscribe;
let { contextKey, idKey, type, roleNames, roles, graphOnly } = this.args;
const getAuthGraph = async function (...params) {
const [root, args, { injector, user }, info] = params;
const id = idKey ? dot.pick(idKey, args) : undefined;
const context = contextKey ? dot.pick(contextKey, args) : type || id ? { type, id } : undefined;
roleNames = isString(roleNames) ? dot.pick(roleNames, args) : roleNames
try {
const authGraph = await injector.get(Authorisation).isAuthorised({ context, roleNames, roles, user: user.id, graphOnly });
//this may need to be expanded to handle directioves on objects. for now only works with fields
if (info.fieldName && root) {
params[2].user.authGraph = {
...(params[2].user.authGraph || {}),
fields: {
...(params[2].user.authGraph.fields || {}),
[info.fieldName]: authGraph
}
}
} else {
//otherwise this is a query, mutation, sub level directive
params[2].user.authGraph = authGraph
}
return next.apply(this, params);
} catch (e) {
throw e;
}
};
field.resolve = field.resolve ? getAuthGraph : field.resolve;
field.subscribe = field.subscribe ? getAuthGraph : field.subscribe;
}
}
export { isAuthorisedDirective as default }
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
-
I realise graphql-modules has moved on from schemaVisitor, but we had a lot of directives built with this pattern when it was dropped and haven't had a chance to look into how to migrate. Just hoping there are others in same boat who might be able to assist.
We have directives all working fine but when we try and run then against an input field, the 'visitInputFieldDefinition' is called but both the subscribe and resolve fields are undefined, so the directive is never called for those fields.
Some code: this is an authorisation directive that allows a check for authroisation and puses the authgraph for the users request into the params to be used further by the providers etc. the problem is that 'const { resolve, subscribe } = field;' both resolve and subscribe are undefined when it's an input field
directive
the schema definition
The main App (applying the directives)
And then we finally use
before passing the schema to apollo
Any assitsance greatly appreciated
Beta Was this translation helpful? Give feedback.
All reactions