Skip to content

Instantly share code, notes, and snippets.

@shrirambalakrishnan
Created October 18, 2020 20:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save shrirambalakrishnan/8eb5ebce3b297241043f99038f75fac7 to your computer and use it in GitHub Desktop.
Save shrirambalakrishnan/8eb5ebce3b297241043f99038f75fac7 to your computer and use it in GitHub Desktop.
const { SchemaDirectiveVisitor } = require("apollo-server");
const { defaultFieldResolver } = require("graphql");
class AuthDirective extends SchemaDirectiveVisitor {
visitObject(type) {
this.ensureFieldsWrapped(type);
type._requiredAuthRole = 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._requiredAuthRole = 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 Role from the field first, falling back
// to the objectType if no Role is required by the field:
const requiredRole =
field._requiredAuthRole ||
objectType._requiredAuthRole;
if (! requiredRole) {
return resolve.apply(this, args);
}
const context = args[2];
const user = context.user;
//////////////////////////////////////////////////
// Check for user role here
const isUser = user.roles.includes(requiredRole);
console.log(`isUser = ${isUser}`);
if (! isUser ) {
throw new Error("not authorized");
}
//////////////////////////////////////////////////
return resolve.apply(this, args);
};
});
}
}
module.exports = {
AuthDirective
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment