auth.js 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. const { SchemaDirectiveVisitor } = require('graphql-tools')
  2. const { defaultFieldResolver } = require('graphql')
  3. class AuthDirective extends SchemaDirectiveVisitor {
  4. visitObject(type) {
  5. this.ensureFieldsWrapped(type)
  6. type._requiredAuthScopes = this.args.requires
  7. }
  8. // Visitor methods for nested types like fields and arguments
  9. // also receive a details object that provides information about
  10. // the parent and grandparent types.
  11. visitFieldDefinition(field, details) {
  12. this.ensureFieldsWrapped(details.objectType)
  13. field._requiredAuthScopes = this.args.requires
  14. }
  15. visitArgumentDefinition(argument, details) {
  16. this.ensureFieldsWrapped(details.objectType)
  17. argument._requiredAuthScopes = this.args.requires
  18. }
  19. ensureFieldsWrapped(objectType) {
  20. // Mark the GraphQLObjectType object to avoid re-wrapping:
  21. if (objectType._authFieldsWrapped) return
  22. objectType._authFieldsWrapped = true
  23. const fields = objectType.getFields()
  24. Object.keys(fields).forEach(fieldName => {
  25. const field = fields[fieldName]
  26. const { resolve = defaultFieldResolver } = field
  27. field.resolve = async function (...args) {
  28. // Get the required scopes from the field first, falling back
  29. // to the objectType if no scopes is required by the field:
  30. const requiredScopes = field._requiredAuthScopes || objectType._requiredAuthScopes
  31. if (!requiredScopes) {
  32. return resolve.apply(this, args)
  33. }
  34. const context = args[2]
  35. console.info(context.req.user)
  36. // const user = await getUser(context.headers.authToken)
  37. // if (!user.hasRole(requiredScopes)) {
  38. // throw new Error('not authorized')
  39. // }
  40. return resolve.apply(this, args)
  41. }
  42. })
  43. }
  44. }
  45. module.exports = AuthDirective