From 3e8fb374f390adcb057b5a40a973272c67be8d99 Mon Sep 17 00:00:00 2001 From: Martijn Date: Thu, 30 Jan 2025 09:08:25 +0100 Subject: [PATCH 1/2] feat(harden-plugin): Allow skipping complexity check --- .../src/middleware/query-complexity-plugin.ts | 10 +++++++--- packages/harden-plugin/src/types.ts | 13 +++++++++++++ 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/packages/harden-plugin/src/middleware/query-complexity-plugin.ts b/packages/harden-plugin/src/middleware/query-complexity-plugin.ts index f626de7177..872d9688d0 100644 --- a/packages/harden-plugin/src/middleware/query-complexity-plugin.ts +++ b/packages/harden-plugin/src/middleware/query-complexity-plugin.ts @@ -20,11 +20,15 @@ import { HardenPluginOptions } from '../types'; export class QueryComplexityPlugin implements ApolloServerPlugin { constructor(private options: HardenPluginOptions) {} - async requestDidStart({ schema }: GraphQLRequestContext): Promise> { + async requestDidStart(ctx: GraphQLRequestContext): Promise> { const maxQueryComplexity = this.options.maxQueryComplexity ?? 1000; return { didResolveOperation: async ({ request, document }) => { - if (isAdminApi(schema)) { + if (this.options.skip?.(ctx)) { + // Given skip function tells use we should not check this request for complexity + return; + } + if (isAdminApi(ctx.schema)) { // We don't want to apply the cost analysis on the // Admin API, since any expensive operations would require // an authenticated session. @@ -41,7 +45,7 @@ export class QueryComplexityPlugin implements ApolloServerPlugin { ); } const complexity = getComplexity({ - schema, + schema: ctx.schema, query, variables: request.variables, estimators: this.options.queryComplexityEstimators ?? [ diff --git a/packages/harden-plugin/src/types.ts b/packages/harden-plugin/src/types.ts index 096f266422..f235b2d765 100644 --- a/packages/harden-plugin/src/types.ts +++ b/packages/harden-plugin/src/types.ts @@ -1,3 +1,4 @@ +import { GraphQLRequestContext } from '@apollo/server'; import { ComplexityEstimator } from 'graphql-query-complexity'; /** @@ -79,4 +80,16 @@ export interface HardenPluginOptions { * @default 'prod' */ apiMode?: 'dev' | 'prod'; + /** + * @description + * Allows you to skip the complexity check for certain requests. + * + * @example + * ```ts + * HardenPlugin.init({ + * skip: (ctx) => ctx.request.http.headers['x-storefront-ssr-auth'] === 'some-secret-token' + * }), + * ``` + */ + skip?: (ctx: GraphQLRequestContext) => boolean; } From c36943bc75f534a90eb52609802c82570ebc6563 Mon Sep 17 00:00:00 2001 From: Martijn Date: Thu, 30 Jan 2025 11:15:12 +0100 Subject: [PATCH 2/2] feat(harden-plugin): Allow returning a promise from skip function --- .../harden-plugin/src/middleware/query-complexity-plugin.ts | 2 +- packages/harden-plugin/src/types.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/harden-plugin/src/middleware/query-complexity-plugin.ts b/packages/harden-plugin/src/middleware/query-complexity-plugin.ts index 872d9688d0..eae72bfc80 100644 --- a/packages/harden-plugin/src/middleware/query-complexity-plugin.ts +++ b/packages/harden-plugin/src/middleware/query-complexity-plugin.ts @@ -24,7 +24,7 @@ export class QueryComplexityPlugin implements ApolloServerPlugin { const maxQueryComplexity = this.options.maxQueryComplexity ?? 1000; return { didResolveOperation: async ({ request, document }) => { - if (this.options.skip?.(ctx)) { + if (await this.options.skip?.(ctx)) { // Given skip function tells use we should not check this request for complexity return; } diff --git a/packages/harden-plugin/src/types.ts b/packages/harden-plugin/src/types.ts index f235b2d765..8c7ea04bdd 100644 --- a/packages/harden-plugin/src/types.ts +++ b/packages/harden-plugin/src/types.ts @@ -91,5 +91,5 @@ export interface HardenPluginOptions { * }), * ``` */ - skip?: (ctx: GraphQLRequestContext) => boolean; + skip?: (ctx: GraphQLRequestContext) => Promise | boolean; }