Skip to content
This repository has been archived by the owner on May 26, 2022. It is now read-only.

next is not a function when @isAuthenticated is used on GraphQL type or field #8

Open
igokul1973 opened this issue Sep 24, 2019 · 2 comments

Comments

@igokul1973
Copy link

Hello!

Given I followed all the documentation regarding authentication on your site and added all the prerequisites for using the isAuthenticated directive, when an authenticated request (it happens ONLY when having access token in headers) involving a type or field annotated with @isAuthenticated is made, the following error comes back.

image

Here is the annotation:
image

In order to fix it, I added the check for the next() existence in the src/index.js isAuthenticatedDirective class of your library (closer to the end of it):

export class IsAuthenticatedDirective extends SchemaDirectiveVisitor {
    static getDirectiveDeclaration(directiveName, schema) {
        return new GraphQLDirective({
            name: "isAuthenticated",
            locations: [DirectiveLocation.FIELD_DEFINITION, DirectiveLocation.OBJECT]
        });
    }

    visitObject(obj) {
        const fields = obj.getFields();

        Object.keys(fields).forEach(fieldName => {
            const field = fields[fieldName];
            const next = field.resolve;

            field.resolve = function (result, args, context, info) {
                verifyAndDecodeToken({context}); // will throw error if not valid signed jwt
                if (next) {
                    return next(result, args, context, info);
                }
                return result[field.name];
            };
        });
    }
}

Please fix it in the next possible release.

FYI - using the latest version of your library in the scope of neo4j-graphql-js as of today:
image

@rdimicheleb
Copy link

Hi,

I was getting the same error but using the @hasRole directive.

I could see that the field.resolve returned undefined when the directive was applied.

Thanks @igokul1973 for share your solution to this issue.

In my case I added the if in two differents parts of the index.js


    key: "visitFieldDefinition",
.
.
.

        var roles = process.env.AUTH_DIRECTIVES_ROLE_KEY ? decoded[process.env.AUTH_DIRECTIVES_ROLE_KEY] || [] : decoded["Roles"] || decoded["roles"] || decoded["Role"] || decoded["role"] || [];

        if (expectedRoles.some(function (role) {
          return roles.indexOf(role) !== -1;
        })) {
          if (next) {
            return next(result, args, _objectSpread({}, context, {
              user: decoded
            }), info);
          }
          return result[field.name];
        }

and here

    key: "visitObject",
.
.
.
        if (expectedRoles.some(function (role) {
          return roles.indexOf(role) !== -1;
        })) {
          if (next) {
            return next(result, args, _objectSpread({}, context, {
              user: decoded
            }), info);
          }
          return result[field.name];
        }

version:
"neo4j-driver": "^1.7.6",
"neo4j-graphql-js": "^2.13.0",
"graphql-auth-directives@^2.2.0"

@ghost
Copy link

ghost commented Jun 16, 2021

Please merge nino-vrijman's pull request to fix directives on fields.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants