hayes / pothos

Pothos GraphQL is library for creating GraphQL schemas in typescript using a strongly typed code first approach
https://pothos-graphql.dev
ISC License
2.32k stars 158 forks source link

Pitfall when calling a schema locally from another schema using auth scopes #1207

Open macrozone opened 4 months ago

macrozone commented 4 months ago

this is a funky one.

i have this scenario:


// this is a function that is called in schemaA
export const myFunc = async (userId: string, ctx: Context) => {
  return await graphql({
    schema: schemaB
    source: `
        query GetUserInfo($userId: String!) {
            user(userId: $userId) {
                id
                firstName
                lastName
            }
        }
        `,
    variableValues: {
      userId,
    },
    contextValue: ctx,
  });
};

the ctx here is the context from the graphql server

So the funky bit is this:

the auth scopes of schemaB are now resolved with a cached version of schemaA's scope values.

the reason is that there is a global cache in pothos which uses the context object as key:

https://github.com/hayes/pothos/blob/main/packages/plugin-scope-auth/src/request-cache.ts#L21

since i pass the same context object to schemaB using the graphql function above, it will reuse the cache, but now with a different schema.

The workaround is to make sure to pass a new context object:


export const getUserInfo = async (userId: string, ctx: Context) => {
  return await graphql({
    schema,
    source: `
        query GetUserInfo($userId: String!) {
            user(userId: $userId) {
                id
                firstName
                lastName
            }
        }
        `,
    variableValues: {
      userId,
    },
    contextValue: {
      ...ctx, // important to create a new one!
    },
  });
};

Possible fix:

this is certainly an edge case, but one that is very hard to find with very weird consequences (i spent nearly an afternoon and had to fire up the node debugger to find it)

I am not totally sure how to fix it correctly, but i guess the builder or schema "instance" (if something like this exists) should be part of the cache key here: https://github.com/hayes/pothos/blob/main/packages/core/src/utils/context-cache.ts#L20