Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 21 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -501,31 +501,35 @@ fastify.listen(3000, function (err) {
})
```

#### Typescript
#### TypeScript

To simplify the use of namespaces in TypeScript you can use the `FastifyJwtNamespace` helper type:
To describe namespaced JWT decorators in TypeScript you can use the
`FastifyJwtNamespace` helper type directly:

```typescript
declare module 'fastify' {
interface FastifyInstance extends
FastifyJwtNamespace<{namespace: 'security'}> {
}
}
type SecurityJwt = FastifyJwtNamespace<{ namespace: 'security' }>

declare const securityJwt: SecurityJwt

securityJwt.securityJwtDecode
securityJwt.securityJwtSign
securityJwt.securityJwtVerify
```

Alternatively you can type each key explicitly:

```typescript
declare module 'fastify' {
interface FastifyInstance extends
FastifyJwtNamespace<{
jwtDecode: 'securityJwtDecode',
jwtSign: 'securityJwtSign',
jwtVerify: 'securityJwtVerify',
}> { }
}
type SecurityJwt = FastifyJwtNamespace<{
jwtDecode: 'securityJwtDecode',
jwtSign: 'securityJwtSign',
jwtVerify: 'securityJwtVerify',
}>
```

When you rename JWT decorators with `namespace`, `decoratorName`, `jwtVerify`,
`jwtDecode`, or `jwtSign`, declare those renamed properties explicitly in your
own local types.

### `messages`
For your convenience, you can override the default HTTP response messages sent when an unauthorized or bad request error occurs. You can choose the specific messages to override and the rest will fallback to the default messages. The object must be in the format specified in the example below.

Expand Down Expand Up @@ -872,6 +876,8 @@ fastify.listen({ port: 3000 })

This plugin has two available exports, the default plugin function `fastifyJwt` and the plugin options object `FastifyJWTOptions`.

When you register `@fastify/jwt` with the default decorator names, Fastify can also infer `fastify.jwt`, `request.jwtVerify()`, `request.jwtDecode()`, and `reply.jwtSign()` from that registered instance. If you customize `namespace`, `decoratorName`, `jwtVerify`, `jwtDecode`, or `jwtSign`, keep using declaration merging helpers for the renamed decorators.

Import them like so:

```ts
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@
"@types/node": "^25.0.3",
"c8": "^11.0.0",
"eslint": "^9.17.0",
"fastify": "^5.0.0",
"fastify": "github:fastify/fastify#feat/typed-decorators",
"neostandard": "^0.13.0",
"tsd": "^0.33.0"
},
Expand Down
77 changes: 46 additions & 31 deletions types/jwt.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,40 +8,14 @@ import {
VerifierOptions
} from 'fast-jwt'
import {
AnyFastifyInstance,
ApplyDecorators,
FastifyPluginCallback,
FastifyRequest
FastifyRequest,
UnEncapsulatedPlugin
} from 'fastify'

declare module 'fastify' {
interface FastifyInstance {
jwt: fastifyJwt.JWT
}

interface FastifyReply {
jwtSign(payload: fastifyJwt.SignPayloadType, options?: fastifyJwt.FastifyJwtSignOptions): Promise<string>
jwtSign(payload: fastifyJwt.SignPayloadType, callback: SignerCallback): void
jwtSign(payload: fastifyJwt.SignPayloadType, options: fastifyJwt.FastifyJwtSignOptions, callback: SignerCallback): void
jwtSign(payload: fastifyJwt.SignPayloadType, options?: Partial<fastifyJwt.SignOptions>): Promise<string>
jwtSign(payload: fastifyJwt.SignPayloadType, options: Partial<fastifyJwt.SignOptions>, callback: SignerCallback): void
}

interface FastifyRequest {
jwtVerify<Decoded extends fastifyJwt.VerifyPayloadType>(options?: fastifyJwt.FastifyJwtVerifyOptions): Promise<Decoded>
// eslint-disable-next-line @typescript-eslint/no-unused-vars
jwtVerify<Decoded extends fastifyJwt.VerifyPayloadType>(callback: VerifierCallback): void
// eslint-disable-next-line @typescript-eslint/no-unused-vars
jwtVerify<Decoded extends fastifyJwt.VerifyPayloadType>(options: fastifyJwt.FastifyJwtVerifyOptions, callback: VerifierCallback): void
jwtVerify<Decoded extends fastifyJwt.VerifyPayloadType>(options?: Partial<fastifyJwt.VerifyOptions>): Promise<Decoded>
// eslint-disable-next-line @typescript-eslint/no-unused-vars
jwtVerify<Decoded extends fastifyJwt.VerifyPayloadType>(options: Partial<fastifyJwt.VerifyOptions>, callback: VerifierCallback): void
jwtDecode<Decoded extends fastifyJwt.DecodePayloadType>(options?: fastifyJwt.FastifyJwtDecodeOptions): Promise<Decoded>
jwtDecode<Decoded extends fastifyJwt.DecodePayloadType>(callback: fastifyJwt.DecodeCallback<Decoded>): void
jwtDecode<Decoded extends fastifyJwt.DecodePayloadType>(options: fastifyJwt.FastifyJwtDecodeOptions, callback: fastifyJwt.DecodeCallback<Decoded>): void
user: fastifyJwt.UserType
}
}

type FastifyJwt = FastifyPluginCallback<fastifyJwt.FastifyJWTOptions>
type FastifyJwt = fastifyJwt.FastifyJwtPlugin

declare namespace fastifyJwt {

Expand Down Expand Up @@ -72,6 +46,47 @@ declare namespace fastifyJwt {
: never,
JWT['verify']>

export interface FastifyJwtReplyDecorators {
jwtSign(payload: fastifyJwt.SignPayloadType, options?: fastifyJwt.FastifyJwtSignOptions): Promise<string>
jwtSign(payload: fastifyJwt.SignPayloadType, callback: SignerCallback): void
jwtSign(payload: fastifyJwt.SignPayloadType, options: fastifyJwt.FastifyJwtSignOptions, callback: SignerCallback): void
jwtSign(payload: fastifyJwt.SignPayloadType, options?: Partial<fastifyJwt.SignOptions>): Promise<string>
jwtSign(payload: fastifyJwt.SignPayloadType, options: Partial<fastifyJwt.SignOptions>, callback: SignerCallback): void
}

export interface FastifyJwtRequestDecorators {
jwtVerify<Decoded extends fastifyJwt.VerifyPayloadType>(options?: fastifyJwt.FastifyJwtVerifyOptions): Promise<Decoded>
// eslint-disable-next-line @typescript-eslint/no-unused-vars
jwtVerify<Decoded extends fastifyJwt.VerifyPayloadType>(callback: VerifierCallback): void
// eslint-disable-next-line @typescript-eslint/no-unused-vars
jwtVerify<Decoded extends fastifyJwt.VerifyPayloadType>(options: fastifyJwt.FastifyJwtVerifyOptions, callback: VerifierCallback): void
jwtVerify<Decoded extends fastifyJwt.VerifyPayloadType>(options?: Partial<fastifyJwt.VerifyOptions>): Promise<Decoded>
// eslint-disable-next-line @typescript-eslint/no-unused-vars
jwtVerify<Decoded extends fastifyJwt.VerifyPayloadType>(options: Partial<fastifyJwt.VerifyOptions>, callback: VerifierCallback): void
jwtDecode<Decoded extends fastifyJwt.DecodePayloadType>(options?: fastifyJwt.FastifyJwtDecodeOptions): Promise<Decoded>
jwtDecode<Decoded extends fastifyJwt.DecodePayloadType>(callback: fastifyJwt.DecodeCallback<Decoded>): void
jwtDecode<Decoded extends fastifyJwt.DecodePayloadType>(options: fastifyJwt.FastifyJwtDecodeOptions, callback: fastifyJwt.DecodeCallback<Decoded>): void
user: fastifyJwt.UserType
}

export interface FastifyJwtInstanceDecorators {
jwt: fastifyJwt.JWT
}

export type FastifyJwtPluginDecorators = {
fastify: FastifyJwtInstanceDecorators;
request: FastifyJwtRequestDecorators;
reply: FastifyJwtReplyDecorators;
}

export type FastifyJwtPlugin<TInstance extends AnyFastifyInstance = AnyFastifyInstance> = UnEncapsulatedPlugin<
FastifyPluginCallback<
fastifyJwt.FastifyJWTOptions,
TInstance,
ApplyDecorators<TInstance, FastifyJwtPluginDecorators>
>
>

/**
* for declaration merging
* @example
Expand Down
Loading
Loading