maticzav / graphql-shield

🛡 A GraphQL tool to ease the creation of permission layer.

Home Page:https://graphql-shield.com

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

"Not Authorised!"

enbermudas opened this issue · comments

commented

Bug report

  • I have checked other issues to make sure this is not a duplicate.

Describe the bug

I know that there is a pinned issue with this exact error message, but my problem is quite different.

I'm trying to use my isAdmin rule on a mutation called userCreate.

The problem is that even though the comparision of the roleId property in the user against the id property from the administrator role returns true, the mutation is giving me an error with the message: "Not Authorised!".

So, if I am returning true (tested with a console log by activating the apollo-server debug option), why is this happening?

To Reproduce

Steps to reproduce the behavior, please provide code snippets or a repository:

  1. This is my GraphQL Schema.
import { gql } from 'apollo-server';

const typeDefs = gql`
  type User {
    id: ID!
    roleId: ID!
    username: String!
    email: String!
    password: String!
    createdAt: String!
    updatedAt: String!
    threads: [Thread]
    replies: [Reply]
  }

  type Thread {
    id: ID!
    authorId: ID!
    title: String!
    body: String!
    createdAt: String!
    updatedAt: String!
    author: User!
    participants: [User]
    replies: [Reply]
  }

  type Reply {
    id: ID!
    authorId: ID!
    threadId: ID!
    body: String!
    createdAt: String!
    updatedAt: String!
    author: User!
    thread: Thread!
  }

  type Query {
    # Auth
    current: User!

    # User
    user(id: ID!): User!
    users: [User!]!

    # Thread
    thread(id: ID!): Thread!
    threads: [Thread!]!

    # Reply
    reply(id: ID!): Reply!
    replies: [Reply!]!
  }

  # ================================================================================ MUTATIONS

  type Mutation {
    # Auth
    register(username: String!, email: String!, password: String!): User!
    login(username: String!, password: String!): LoginResponse!

    # User
    userCreate(username: String!, email: String!, password: String!): User!

    # Thread
    threadCreate(authorId: ID!, title: String!, body: String!): Thread!

    # Reply
    replyCreate(authorId: ID!, threadId: ID!, body: String!): Reply!
  }

  # ================================================================================ RESPONSES

  # Auth
  type LoginResponse {
    token: String
    user: User
  }
`;

export default typeDefs;
  1. This is the invoked query
const isAdmin = rule({ cache: 'contextual' })(
  async (parent, args, ctx, info) => {
    const role = await Role.findOne({ slug: 'administrator' });
    return ctx.user.roleId === role.id;
  }
);
  1. I use these permissions
const permissions = shield({
  Query: {},
  Mutation: {
    // Auth
    login: not(isAuthenticated),
    register: not(isAuthenticated),

    // User
    userCreate: isAdmin,

    // Thread
    threadCreate: isAuthenticated,

    // Reply
    replyCreate: isAuthenticated
  }
});
  1. This is the error I see
{
  "errors": [
    {
      "message": "Not Authorised!",
      "locations": [
        {
          "line": 2,
          "column": 3
        }
      ],
      "path": [
        "userCreate"
      ],
      "extensions": {
        "code": "INTERNAL_SERVER_ERROR",
        "exception": {
          "stacktrace": [
            "Error: Not Authorised!",
            "    at normalizeOptions (/home/kike/prs/projects/rpbb/node_modules/graphql-shield/src/shield.ts:34:7)",
            "    at shield (/home/kike/prs/projects/rpbb/node_modules/graphql-shield/src/shield.ts:52:29)",
            "    at Object.<anonymous> (/home/kike/prs/projects/rpbb/src/server/config/shield.js:27:21)",
            "    at Module._compile (internal/modules/cjs/loader.js:774:30)",
            "    at Module._compile (/home/kike/prs/projects/rpbb/node_modules/pirates/lib/index.js:99:24)",
            "    at Module._extensions..js (internal/modules/cjs/loader.js:785:10)",
            "    at Object.newLoader [as .js] (/home/kike/prs/projects/rpbb/node_modules/pirates/lib/index.js:104:7)",
            "    at Module.load (internal/modules/cjs/loader.js:641:32)",
            "    at Function.Module._load (internal/modules/cjs/loader.js:556:12)",
            "    at Module.require (internal/modules/cjs/loader.js:681:19)",
            "    at require (internal/modules/cjs/helpers.js:16:16)",
            "    at Object.<anonymous> (/home/kike/prs/projects/rpbb/src/server/config/apollo.js:5:1)",
            "    at Module._compile (internal/modules/cjs/loader.js:774:30)",
            "    at Module._compile (/home/kike/prs/projects/rpbb/node_modules/pirates/lib/index.js:99:24)",
            "    at Module._extensions..js (internal/modules/cjs/loader.js:785:10)",
            "    at Object.newLoader [as .js] (/home/kike/prs/projects/rpbb/node_modules/pirates/lib/index.js:104:7)"
          ]
        }
      }
    }
  ],
  "data": null
}

Expected behavior

Get the id and username in the mutation response after inserting the user in the MongoDB users collection.

Actual behaviour

Returns an "Not Authorised!" error message.

Additional context

N/A

Hey,
As you mentioned, this is a duplicate. You have to allow User as well as payloads to get the correct result. I am confident that mutation is executed as expected, and Shield only blocks the return value.

Please refer to the other issue otherwise.