Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fail to parse @authorization rules in GraphQL Schema (Invalid argument: validate, error: String cannot represent a non string value) #5681

Closed
mzvdev opened this issue Oct 21, 2024 · 14 comments · Fixed by #5458
Assignees
Labels
bug report Something isn't working confirmed Confirmed bug

Comments

@mzvdev
Copy link

mzvdev commented Oct 21, 2024

Describe the bug
We found that when we delete the yarn lock file in our current project, we had an error parsing the GraphQL Schema.
It fails to parse @authorization rules (error message: Invalid argument: validate, error: String cannot represent a non string value)
By removing @authorization rules it worked.
Then we tried to isolate the problem in a separate repo, we still had the same issue.

Details
Run tests by executing following commands:

yarn install
./test.sh watch-test

Test should now fail with:

...snipped...
 FAIL  src/index.test.js [ src/index.test.js ]
[
  {
    stack: 'GraphQLError: Invalid argument: validate, error: String cannot represent a non string value.\n' +
      '    at createGraphQLError (/n4j-issue/node_modules/@neo4j/graphql/src/schema/validation/custom-rules/utils/document-validation-error.ts:83:12)\n' +
      '    at mapCustomRuleError (/n4j-issue/node_modules/@neo4j/graphql/src/schema/validation/utils/map-error.ts:61:34)\n' +
      '    at mapError (/n4j-issue/node_modules/@neo4j/graphql/src/schema/validation/utils/map-error.ts:29:16)\n' +
      '    at SDLValidationContext._onError (/n4j-issue/node_modules/@neo4j/graphql/src/schema/validation/validate-sdl.ts:34:37)\n' +
      '    at SDLValidationContext.reportError (/n4j-issue/node_modules/graphql/validation/ValidationContext.js:36:10)\n' +
      '    at Object.Directive (/n4j-issue/node_modules/@neo4j/graphql/src/schema/validation/custom-rules/directive-argument-of-correct-type.ts:100:33)\n' +
      '    at Object.enter (/n4j-issue/node_modules/graphql/language/visitor.js:301:32)\n' +
      '    at visit (/n4j-issue/node_modules/graphql/language/visitor.js:197:21)\n' +
      '    at validateSDL (/n4j-issue/node_modules/@neo4j/graphql/src/schema/validation/validate-sdl.ts:38:10)\n' +
      '    at validateUserDefinition (/n4j-issue/node_modules/@neo4j/graphql/src/schema/validation/schema-validation.ts:106:31)',
    message: 'Invalid argument: validate, error: String cannot represent a non string value.',
    name: 'GraphQLError',
    path: [
      'User',
      '@authorization',
      'validate',
      0,
      'where',
      'node',
      'userId'
    ],
    originalError: undefined,
    nodes: undefined,
    source: undefined,
    positions: undefined,
    locations: undefined,
    extensions: {},
    constructor: 'Function<GraphQLError>',
    toString: 'Function<toString>',
    toJSON: 'Function<toJSON>'
  },
  stacks: []
]
...snipped...

Now if you remove following @authorization in schema.graphql:

  @authorization(
    validate: [
      { where: { node: { userId: "$jwt.sub" } } }
      { where: { jwt: { roles_INCLUDES: "admin" } } }
    ]
  )

Tests will now pass...

To Reproduce
Steps to reproduce the behavior:

  1. Clone that repo: https://github.com/mzvdev/n4j-issues
  2. Install Yarn and Node.js
  3. Execute: ./test.sh watch-test
  4. See error

Expected behavior
No errors parsing the schema

Environment

  • OS: macOS
  • Node.js version: v20.17.0
  • @apollo/server: "^4.11.0",
  • @neo4j/graphql: "^5.9.0",
  • "graphql: "^16.9.0",
  • neo4j-driver: "^5.26.0"
@mzvdev mzvdev added the bug report Something isn't working label Oct 21, 2024
@darrellwarde darrellwarde linked a pull request Oct 21, 2024 that will close this issue
1 task
@darrellwarde darrellwarde added the confirmed Confirmed bug label Oct 21, 2024
@neo4j-team-graphql
Copy link
Collaborator

We've been able to confirm this bug using the steps to reproduce that you provided - many thanks @mzvdev! 🙏 We will now prioritise the bug and address it appropriately.

darrellwarde added a commit that referenced this issue Oct 21, 2024
@darrellwarde
Copy link
Contributor

Hey @mzvdev, I've been investigating this one and generally looking into the issues with the graphql-tools packages.

The issue here is actually in your type definitions! In your JWT you have defined sub as an integer (https://github.com/mzvdev/n4j-issues/blob/main/src/schema.graphql#L4) but then compare to it as a string (https://github.com/mzvdev/n4j-issues/blob/main/src/schema.graphql#L9).

This is a bit of a shortcoming of the authorization features because the $ string interpolation only really works with string variables. However, I have added a test to #5458 which proves that this all works when this definition is changed to String with the updated versions of graphql-tools.

@mzvdev
Copy link
Author

mzvdev commented Oct 21, 2024

@darrellwarde Oups, Sorry! Thank you for finding. Indeed a type mistake from our side in the repo.
But in the main project we have still that error, but the code is a bit different:
GraphQLError: String cannot represent value: { where: { node: [Object] } }

type JWT @jwt {
    roles: [String]
    id: String
    sub: String
}
@authorization(
        validate: [
            { where: { node: { admins: { authId: "$jwt.id" } } } }
            { where: { node: { ref: "$jwt.sub" } }, operations: [READ] }
            { where: { jwt: { roles_INCLUDES: "overlord" } } }
        ]
    ) 

Will try to reproduce it again in my isolated repo and share it with you.

@renovate renovate bot closed this as completed in #5458 Oct 21, 2024
renovate bot pushed a commit that referenced this issue Oct 21, 2024
@darrellwarde darrellwarde reopened this Oct 21, 2024
@mzvdev
Copy link
Author

mzvdev commented Oct 21, 2024

@darrellwarde Quick question: is it possible to somehow identify which line cause an error?
I have added the debug option, but not helpful.

I have this error, but I have many places where I use { where: { node: {...} }, tried to isolate one by one, but not able to find it.
GraphQLError: String cannot represent value: { where: { node: [Object] } }

@to-kn
Copy link

to-kn commented Oct 22, 2024

hi @darrellwarde @mzvdev ,
we are struggling with the same Symptom since nearly a month - and could not find any solution (yet)... We have only String/String Arrays in our JWT, what i found out just now, is: as soon as i habe a @customResolver() directive in the same typedefs (not necessarily on the same Object) i get that error... As in: if i enable test, generation fails...
Maybe this helps to solve the issue?

type JWT @jwt {
  uuid: String!
  roles: [String!]
}

type Organization @authorization(filter:[{where: { jwt: { roles_INCLUDES: "OMNIADMIN" } }}]) {
  uuid: ID! @unique
  displayName: String
#  test: String @customResolver(requires: "uuid")
}

@darrellwarde darrellwarde self-assigned this Oct 22, 2024
@mzvdev
Copy link
Author

mzvdev commented Oct 22, 2024

@to-kn I confirm If I remove all @customResolver from my project, the GraphQLError is gone. Thank you!

Trying to make a new issue repo with @customResolver

@to-kn
Copy link

to-kn commented Oct 22, 2024

@mzvdev i solved the issue in the meantime for us - we have a intermediate library to generate the schema.graphql from typedefs.graphql - there i had minor differences in the versions of neo4j/graphql and @graphql-tools. I brought both to the same (latest) version and now it is working in my case...

@mzvdev
Copy link
Author

mzvdev commented Oct 22, 2024

@to-kn Thank you for sharing your experience! Which intermediate library it's ? For now I just connect the Neo4J GraphQL schema to Apollo.
const neo4jGraphql = new Neo4jGraphQL({ typeDefs, features, resolvers, driver });

@darrellwarde
Copy link
Contributor

hi @darrellwarde @mzvdev , we are struggling with the same Symptom since nearly a month - and could not find any solution (yet)... We have only String/String Arrays in our JWT, what i found out just now, is: as soon as i habe a @customResolver() directive in the same typedefs (not necessarily on the same Object) i get that error... As in: if i enable test, generation fails... Maybe this helps to solve the issue?

type JWT @jwt {
  uuid: String!
  roles: [String!]
}

type Organization @authorization(filter:[{where: { jwt: { roles_INCLUDES: "OMNIADMIN" } }}]) {
  uuid: ID! @unique
  displayName: String
#  test: String @customResolver(requires: "uuid")
}

Hey @to-kn, can you try updating the library to 5.9.1 and try this again? I'm fairly sure I have this fixed for your particular case!

@darrellwarde
Copy link
Contributor

And @mzvdev, if your issues are all related to @customResolver, then I hope 5.9.1 might fix this for you also!

@mzvdev
Copy link
Author

mzvdev commented Oct 23, 2024

@darrellwarde On our side, it works correctly now! Thank you 🙏

@mzvdev
Copy link
Author

mzvdev commented Oct 23, 2024

@darrellwarde I just tested to downgrade to our previous version and doing a clean install without the yarn lockfile, it now compiling also 🤷‍♂️
I think it's because graphql-tools/utils is now 10.5.5

@darrellwarde
Copy link
Contributor

Okay great, I'm glad to hear things are working! I'll close this issue off, but please reopen if any issues persist.

@to-kn
Copy link

to-kn commented Oct 23, 2024

Hi @darrellwarde yes indeed the upgrade to 5.9.1 was the solution!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug report Something isn't working confirmed Confirmed bug
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants