neo4jgraphqlneo4j-graphql-js

How to bind `$jwt.sub` on Create to property using Neo4j and GraphQL?


I'm currently using neo4j and graphql with an Apollo server.

I have the following type:

  type Person {
    id: ID! @id
    externalId: ID
    name: String!
  }

  extend type Person
    @auth(
      rules: [
        { operations: [CREATE, UPDATE], bind: { externalId: "$jwt.sub" } }
      ]
    )

And when I try to do the following mutation:

mutation Mutation($input: [PersonCreateInput!]!) {
  createPeople(input: [
    {
      "name": "abc"
    }
  ]) {
    people {
      name
    }
  }
}

I get a FORBIDDEN error from Neo4j.

I debugged a bit the code, and it looks like this is what's being transformed to:

CALL {\n' +
      'CREATE (this0:Person)\n' +
      'SET this0.id = randomUUID()\n' +
      'SET this0.name = $this0_name\n' +
      'WITH this0\n' +
      'CALL apoc.util.validate(NOT(this0.externalId IS NOT NULL AND this0.externalId = $this0_auth_bind0_externalId), "@neo4j/graphql/FORBIDDEN", [0])\n' +
      'RETURN this0\n' +
      '}\n' +
      'RETURN \n' +
      'this0 { .name } AS this0',

so if I understand this correctly, if externalID is NULL AND externalID is different from my jwt sub value, then it will throw the exception.

And basically what I'm trying to achieve is:

When creating a person node, assign the externalID value to the value of the sub property of my JWT.

What am I doing wrong here?


Solution

  • I think the double negative is causing some confusion with the predicate. The exception will be thrown if this0.externalId is null OR if this0.externalId does not equal $this0_auth_bind0_externalId due to the AND statement and surrounding NOT.

    Since you're creating this this0 above it will never have this0.externalId, so this predicate will always be true and the exception will always be thrown.

    I'm not strong in GraphQL, but I would think your mutation needs to set the externalId.