npm @nestjs/graphql 14.2.0
v14.2.0

3 hours ago

This release fixes several security issues and a range of correctness bugs in schema generation, resolver binding and the drivers. Upgrading is recommended for all users of @nestjs/graphql, @nestjs/apollo and @nestjs/mercurius.

Security

Advisory Severity Package Summary
GHSA-8www-f354-mh8p High @nestjs/graphql Unauthenticated requests can crash applications that enable GraphQL subscriptions
GHSA-f2pj-v3fc-65xp High @nestjs/graphql Guards, interceptors and pipes are silently skipped on resolvers registered with useFactory or useValue
GHSA-c658-2mxh-7pqx High @nestjs/graphql Guards of a subclass resolver can be bypassed when its base resolver is also registered
GHSA-m88h-g79w-v5mc Medium @nestjs/graphql DateTime and Timestamp scalars accept invalid input, so null and invalid dates reach non-null arguments
GHSA-qcfh-v6vh-p698 Medium @nestjs/mercurius MercuriusFederationDriver ignores subscription filters and delivers events to all subscribers
GHSA-fvxv-c29c-43xc Medium @nestjs/apollo Credentials of failed outgoing HTTP requests can be exposed in GraphQL error responses
GHSA-68rj-86jm-2jwh Medium @nestjs/graphql Guarded field resolvers can be dropped when the resolvers option defines the same type
GHSA-5mvw-93v2-cm4m Medium @nestjs/apollo, @nestjs/mercurius Context objects returned by a context function can be shared across requests
GHSA-9c65-35pp-rvj7 Medium @nestjs/graphql Subscription filters receive schema-named arguments, which can deliver other users' events
GHSA-5xqp-272w-2j3q Medium @nestjs/graphql Subscription resolve callbacks run without guards when the operation is sent over HTTP

Behaviour changes

Most applications need no changes. The fixes below either make silent misconfigurations fail loudly, or align runtime behaviour with what the schema and the documentation promise. Please review them before upgrading.

Startup errors for configurations that used to skip checks silently

  • Factory or value resolvers with class-referenced enhancers. A resolver registered with useFactory/useValue that uses guards, interceptors or pipes referenced by class now fails at startup; before, these enhancers never ran. Register the resolver as a class or with useClass, or pass enhancer instances.
  • Unattachable scoped enhancers and plugins. Request- or transient-scoped global enhancers that can't be attached to a resolver fail at startup, and so do request-scoped or transient @Plugin() classes.
  • Ambiguous handlers. Two unrelated classes (or two methods) resolving the same type and field fail at startup. A subclass overriding its parent is fine: the most-derived class wins.
  • Argument conflicts. These fail at schema build:
    • a renamed @ArgsType() property that collides with a named @Args();
    • the same argument declared in two @Args() with different types or defaults.
  • defaultValue: null on a non-null argument or field fails at schema build. Add nullable: true, or drop the default.
  • Extra required arguments. A @ResolveField() that adds a required argument the implemented interface field doesn't declare is a schema validation error.
  • isOneOf. Derived input types inherit isOneOf, and the @oneOf directive now sets it.
  • Ambiguous type names. Referencing a type by name (@Field(() => 'Name')) when two types share that name fails. Reference the class, or scope the types with registerIn.
  • MercuriusGatewayDriver with transformSchema fails at startup; the option used to be ignored.
  • Schema-first with both schema and typeDefs. resolverValidationOptions now apply to the merged schema.

Requests that are now rejected

  • Malformed dates. Malformed DateTime/Timestamp input is a validation error (HTTP 400). Valid date strings, Date instances and epoch-millisecond numbers keep working.
  • Custom scalars. A null result from a custom scalar's parseValue()/parseLiteral() is now treated as invalid input. Throw a GraphQLError for input your scalar can't parse.
  • Subscriptions over HTTP are refused by ApolloDriver, ApolloFederationDriver and MercuriusDriver. Use WebSocket.
  • Exact endpoint path on Express. The GraphQL endpoint matches its exact path: /graphql/<anything> returns 404, and path: '/' no longer catches every URL. A trailing slash still works.
  • 'graphql-ws': false now disables the WebSocket endpoint. A subscriptions object that enables no protocol no longer accepts upgrades.
  • IntersectionType(). A field shared by both classes is non-null unless both allow null.
  • graphql-ws operations now go through Apollo's validationRules and formatError.
  • Request start hooks. An async request start hook (ResolverDecoratorHost.setOnRequestStartHook()) is awaited, and if it rejects, the operation fails.

Schema changes

  • Renamed properties. A subclass that redeclares a property under another schema name no longer keeps the parent's field.
  • Mapped types. PickType(), OmitType(), PartialType() and IntersectionType() no longer include fields inherited from a parent of another kind (e.g. an @ObjectType() parent of an @InputType()).
  • @ResolveField() placement.
    • Field resolvers of a base resolver typed with a base or interface type appear only on the types actually served.
    • Handler-only fields no longer leak between include-scoped GraphQL modules.
  • include and @Global() modules. include no longer pulls in resolvers of @Global() modules; list them in include explicitly.
  • Undecorated overrides. An override of a handler that isn't decorated no longer produces a field.
  • Ordering.
    • Field order in the SDL can change for types that implement several interfaces.
    • Argument order for @ArgsType() chains three or more levels deep is now root-first.
  • Enums. Keys created by Infinity/NaN reverse mappings and namespace-merged members are no longer enum values.
  • CLI plugin.
    • It skips protected and #private members.
    • @HideField() also works when applied through a composed decorator.
  • Federation. Custom buildFederatedSchema callbacks receive only the __resolveReference resolvers; the other resolvers are attached separately.

Different resolvers or middleware for the same query

  • Object subtypes run the nearest ancestor's @ResolveField() handler, with its guards and middleware, instead of reading the property. To keep the old behaviour, declare a handler on the subtype.
  • Interfaces. When interfaces provide competing field resolvers, the most specific one wins, not the last one listed.
  • Model field middleware.
    • @Field({ middleware }) and @UseFieldMiddleware() on a model field also run when the field has a @ResolveField() handler, in the order global → model → handler, each once.
    • Global field middleware also runs on fields inherited from @InterfaceType() classes.
  • Unbound handler-only fields. A field declared only by a @ResolveField(), that ends up on a type with no bound handler, returns an error and is listed in a startup warning. Before, it read the parent's property unguarded.
  • __typename of subclasses. The default resolveType returns the most-derived class, so __typename names the subclass.
  • Bare @Resolver() subclasses inherit the parent's type.
  • Subscription/Mutation object types. @ResolveField() handlers on object types named Subscription or Mutation are treated as field resolvers.
  • Error conversion. Only real HttpException instances are converted to GraphQL errors.
  • Context objects. A context object returned by a context function is copied per request, so class contexts lose #private fields.
  • Defaults.
    • Omitted object argument defaults are completed with the input type's field defaults.
    • Array and object defaults are fresh copies on every request.
  • Class-level @Extensions() are inherited by subclasses.
  • directiveResolvers is deprecated and logs a warning. It has had no effect since v9.2.0.

What's Changed

  • fix(graphql): reject invalid dates and harden websocket upgrades (e29277b)
  • fix(graphql): build federated schemas with the code-first options (43be3d5)
  • fix(graphql): inherit fields of object and interface types consistently (2307121)
  • fix(graphql): merge field resolver metadata per host type (2d1a89c)
  • fix(graphql): resolve args and input fields by nearest declaration (cc19167)
  • fix(apollo,mercurius): share context and subscription handling (ed19e23)
  • fix(graphql): bind inherited field resolvers with their middleware (58189ba)
  • fix(graphql): run every resolver with its declared enhancers (1e678c7)
  • fix(graphql): complete resolver argument and hook handling (c69ff53)
  • fix(graphql): bind federated field resolvers like the code-first factory (263457c)
  • fix(graphql): emit the graphql type name as the __typename value by @RaphaelFakhri in #4218

New Contributors

Full Changelog: v14.1.2...v14.2.0

Don't miss a new graphql release

NewReleases is sending notifications on new releases.