Skip to content

Type augmentation for namespace methods? #348

Open
@58bits

Description

@58bits

Prerequisites

  • I have written a descriptive issue title
  • I have searched existing issues to ensure the issue has not already been raised

Issue

EDIT: Simplifying this question a little.

We've created the following namespaced jwt plugin based on the docs here... https://github.com/fastify/fastify-jwt?tab=readme-ov-file#namespace

import fp from 'fastify-plugin'
import { FastifyPluginAsync, FastifyInstance } from 'fastify'
import fastifyJwt, { FastifyJWTOptions, JWT } from '@fastify/jwt'

// https://fastify.dev/docs/latest/Reference/TypeScript/#creating-a-typescript-fastify-plugin
declare module 'fastify' {
  interface FastifyInstance {
    jwt: {
      accessToken: JWT
      refreshToken: JWT
    }
  }

  interface FastifyReply {
    accessTokenSign: JWT['sign']
    refreshTokenSign: JWT['sign']
  }

  interface FastifyRequest {
    accessTokenVerify: JWT['verify']
    accessTokenDecode: JWT['decode']
    refreshTokenVerify: JWT['verify']
    refreshTokenDecode: JWT['decode']
  }
}

const jwtPlugin: FastifyPluginAsync<FastifyJWTOptions> = async (app: FastifyInstance, options) => {
  app.register<FastifyJWTOptions>(fastifyJwt, {
    // secret: Buffer.from(app.config.jwt.secret as string, 'base64'),
    secret: {
      private: app.config.jwt.access.secret.private,
      public: app.config.jwt.access.secret.public,
    },
    sign: {
      algorithm: 'RS256',
      iss: app.config.jwt.access.issuer,
      aud: app.config.jwt.access.audience,
      expiresIn: app.config.jwt.access.expiresIn,
    },
    verify: {
      algorithms: ['RS256'],
      allowedIss: app.config.jwt.access.issuer,
    },
    namespace: 'accessToken',
    jwtDecode: 'accessTokenDecode',
    jwtSign: 'accessTokenSign',
    jwtVerify: 'accessTokenVerify',
  })

  app.register<FastifyJWTOptions>(fastifyJwt, {
    // secret: Buffer.from(app.config.jwt.secret as string, 'base64'),
    secret: {
      private: app.config.jwt.refresh.secret.private,
      public: app.config.jwt.refresh.secret.public,
    },
    sign: {
      algorithm: 'RS256',
      iss: app.config.jwt.refresh.issuer,
      aud: app.config.jwt.refresh.audience,
      expiresIn: app.config.jwt.refresh.expiresIn,
    },
    verify: {
      algorithms: ['RS256'],
      allowedIss: app.config.jwt.refresh.issuer,
    },
    namespace: 'refreshToken',
    jwtDecode: 'refreshTokenDecode',
    jwtSign: 'refreshTokenSign',
    jwtVerify: 'refreshTokenVerify',
  })
}

export default fp(jwtPlugin)

With the above, when calling either of the namespaced sign methods, our augmented type definition above, and the signature on the actual method don't exactly match - which means we suspect, that

accessTokenSign: JWT['sign'] is not the correct way to assign a type to the accessTokenSign and other methods. - since the reply and request augmented methods are asynchronous - i.e. require either a callback, or return a promise.

accessTokenVerify: JWT['verify'] is also not the correct type annotation, as the request.accessTokenVerify method does not need a token as a parameter (it looks up the token from the request header).

And so our question really is - what's the correct way to augment the FastifyReply and FastifyRequest types with correct sign, verify and decode methods when using namespaces?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions