fastify / fastify-auth

Run multiple auth functions in Fastify
Other
341 stars 56 forks source link

Unable to use a Typescript generic for the Params property off of the request #207

Closed hershmire closed 6 months ago

hershmire commented 10 months ago

Prerequisites

Fastify version

4.13.0

Plugin version

4.3.0

Node.js version

18.17.1

Operating system

macOS

Operating system version (i.e. 20.04, 11.3, 10)

14.0

Description

I'm trying to use a generic on the Params property for a function that's sent to @fastify/auth. However, when I do this, I get the following Typescript error:

Type '(request: FastifyRequest<{    Params: Partial<GetUserRequestParams>;}>, reply: FastifyReply) => Promise<void>' is not assignable to type 'FastifyAuthFunction | FastifyAuthFunction[]'.
  Type '(request: FastifyRequest<{    Params: Partial<GetUserRequestParams>;}>, reply: FastifyReply) => Promise<void>' is not assignable to type 'FastifyAuthFunction'.
    Types of parameters 'request' and 'request' are incompatible.
      Type 'FastifyRequest<RouteGenericInterface, RawServerDefault, IncomingMessage, FastifySchema, FastifyTypeProviderDefault, unknown, FastifyBaseLogger, ResolveFastifyRequestType<...>>' is not assignable to type 'FastifyRequest<{ Params: Partial<{ userId: string; }>; }, RawServerDefault, IncomingMessage, FastifySchema, FastifyTypeProviderDefault, unknown, FastifyBaseLogger, ResolveFastifyRequestType<...>>'.
        Type 'RouteGenericInterface' is not assignable to type '{ Params: Partial<{ userId: string; }>; }'.
          Types of property 'Params' are incompatible.
            Type 'unknown' is not assignable to type 'Partial<{ userId: string; }>'.ts(2322)

I'm unsure if this is a bug or I'm doing this incorrectly.

Steps to Reproduce

Below is a snippet of what I'm doing:

import { 
  FastifyInstance,
  FastifyReply,
  FastifyRequest, 
} from 'fastify';
import { Static, Type } from '@sinclair/typebox';

const GetUserRequestParamsSchema = Type.Object({
  userId: Type.String(),
});

type GetUserRequestParams = Static<typeof GetUserRequestParamsSchema>;

const usersMutationAccessPolicy =
  (fastify: FastifyInstance) =>
  async (
    // Looking to extend Params so Typescript knows about `userId` (below)
    request: FastifyRequest<{
      Params: Partial<GetUserRequestParams>;
    }>,
    reply: FastifyReply,
  ): Promise<void> => {
    const { user } = request.identity;
    // Without extending request.params, it thinks the type is unknown
    const isOwner = user?.id === request.params.userId;

    // do more work below
  }

// Leaving out app startup code to keep this concise

export async function usersController(fastify: FastifyInstance): Promise<void> {
  fastify.patch<{
    Params: UserParams;
    Body: UserPatchBody;
  }>(
    `/:userId`,
    {
      schema: { ... },
      // Getting TS error 
      onRequest: fastify.auth([usersMutationAccessPolicy(fastify)]),
    },
    async (req, res) => {
      const user = await doPatchStuffWithUser();
      res.send(user);
    },
  );
}

Something to note. If I just added usersMutationAccessPolicy(fastify) to the onRequest directly, everything works as expected. Example:

export async function usersController(fastify: FastifyInstance): Promise<void> {
  fastify.patch<{
    Params: UserParams;
    Body: UserPatchBody;
  }>(
    `/:userId`,
    {
      schema: { ... },
      // Works as expected 
      onRequest: usersMutationAccessPolicy(fastify),
    },
    async (req, res) => {
      const user = await doPatchStuffWithUser();
      res.send(user);
    },
  );
}

However, I'm looking to use @fastify/auth to compose more access policy functions.

Expected Behavior

I don't receive any TS error when using

onRequest: fastify.auth([usersMutationAccessPolicy(fastify)]), from above.

mcollina commented 10 months ago

Thanks for reporting!

Can you provide steps to reproduce? We often need a reproducible example, e.g. some code that allows someone else to recreate your problem by just copying and pasting it. If it involves more than a couple of different file, create a new repository on GitHub and add a link to that.

hershmire commented 10 months ago

@mcollina here's a repo that reproduces this issue https://github.com/hershmire/fastify-auth-ts-bug.

hershmire commented 10 months ago

@mcollina any update on this?

mcollina commented 8 months ago

As you could imagine, I have been swamped. As things are, I'm not sure I'd have time to get to this bugs anytime soon. However, I'd love to see a PR that fixes this.

Puppo commented 7 months ago

Hey @mcollina and @hershmire, I created this small PR #211 to fix this issue. I hope it's ok; otherwise, let me know, and I'll fix it.