From 05b590dd5b115c8d0ca4208e847dc02b0db424ab Mon Sep 17 00:00:00 2001 From: Arda TANRIKULU Date: Thu, 9 May 2024 17:12:22 +0300 Subject: [PATCH 1/2] fix: do not allow reserved context keys in ServerContext or UserContext --- .changeset/eight-poets-run.md | 18 +++++++++ packages/graphql-yoga/src/server.ts | 15 +++++--- packages/graphql-yoga/type-api-check.ts | 50 ++++++++++++++++++++++++- 3 files changed, 76 insertions(+), 7 deletions(-) create mode 100644 .changeset/eight-poets-run.md diff --git a/.changeset/eight-poets-run.md b/.changeset/eight-poets-run.md new file mode 100644 index 0000000000..66304b4876 --- /dev/null +++ b/.changeset/eight-poets-run.md @@ -0,0 +1,18 @@ +--- +'graphql-yoga': patch +--- + +Do not allow reserved context keys in UserContext and ServerContext if they don't match + +For example, you cannot have `request` as a key in UserContext or ServerContext unless it is `Request` like below; +```ts +// @ts-expect-error Not allowed +createYoga<{ + request: FastifyRequest +}>(/* ... */); + +// But allowed +createYoga<{ + req: FastifyRequest +}>(/* ... */); +``` diff --git a/packages/graphql-yoga/src/server.ts b/packages/graphql-yoga/src/server.ts index 46d54dc9e0..e291dc53e9 100644 --- a/packages/graphql-yoga/src/server.ts +++ b/packages/graphql-yoga/src/server.ts @@ -602,20 +602,23 @@ export class YogaServer< }; } +export type ContextBase = { + [key: Exclude]: unknown; +} & Partial; + /* eslint-disable */ export type YogaServerInstance< - TServerContext extends Record, - TUserContext extends Record, + TServerContext extends ContextBase, + TUserContext extends ContextBase, > = ServerAdapter>; export function createYoga< - TServerContext extends Record = {}, - TUserContext extends Record = {}, + TServerContext extends ContextBase = {}, + TUserContext extends ContextBase = {}, >(options: YogaServerOptions) { const server = new YogaServer(options); return createServerAdapter>(server, { fetchAPI: server.fetchAPI, plugins: server['plugins'], - }) as unknown as YogaServerInstance; - // TODO: Fix in @whatwg-node/server later + }); } diff --git a/packages/graphql-yoga/type-api-check.ts b/packages/graphql-yoga/type-api-check.ts index f8f74fefb0..a2f1fdf7af 100644 --- a/packages/graphql-yoga/type-api-check.ts +++ b/packages/graphql-yoga/type-api-check.ts @@ -2,7 +2,7 @@ import { ClientRequest } from 'node:http'; import type { GraphQLSchema } from 'graphql'; import { IResolvers } from '@graphql-tools/utils'; -import { createSchema, createYoga, YogaInitialContext } from './src/index.js'; +import { createSchema, createYoga, GraphQLParams, YogaInitialContext } from './src/index.js'; // eslint-disable-next-line @typescript-eslint/no-explicit-any const schema: GraphQLSchema = null as any; @@ -41,6 +41,54 @@ const request: Request = null as any; server.handleRequest(request, { req: clientRequest }); } +// Do not allow reserved context keys +{ + // @ts-expect-error ServerContext type cannot contain reserved key 'request'. + createYoga<{}, { request: { myParam: string } }>({ + schema, + }); +} +{ + // @ts-expect-error ServerContext type cannot contain reserved key 'params'. + createYoga<{}, { params: { myParam: string } }>({ + schema, + }); +} +{ + // @ts-expect-error ServerContext type cannot contain reserved key 'request'. + createYoga<{}, { request: { myParam: string } }>({ + schema, + }); +} +{ + // @ts-expect-error ServerContext type cannot contain reserved key 'params'. + createYoga<{ params: { myParam: string } }>({ + schema, + }); +} +// Allow reserved context keys if they match in ServerContext +{ + createYoga<{ request: Request }>({ + schema, + }); +} +{ + createYoga<{ params: GraphQLParams }>({ + schema, + }); +} +// Allow reserved context keys if they match in UserContext +{ + createYoga<{}, { request: Request }>({ + schema, + }); +} +{ + createYoga<{}, { params: GraphQLParams }>({ + schema, + }); +} + /** * Context + Resolvers */ From e78e15c77a27e36f53d76b841851f92c1dad90e8 Mon Sep 17 00:00:00 2001 From: Arda TANRIKULU Date: Thu, 9 May 2024 17:13:44 +0300 Subject: [PATCH 2/2] Improve changeset --- .changeset/eight-poets-run.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.changeset/eight-poets-run.md b/.changeset/eight-poets-run.md index 66304b4876..403f48d274 100644 --- a/.changeset/eight-poets-run.md +++ b/.changeset/eight-poets-run.md @@ -15,4 +15,9 @@ createYoga<{ createYoga<{ req: FastifyRequest }>(/* ... */); + +// Also allowed +createYoga<{ + request: Request // From Fetch API +}>(/* ... */); ```