-
-
Notifications
You must be signed in to change notification settings - Fork 26
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
preHandler types conflict with package @fastify/auth
#5
Comments
cc @fastify/typescript could you take a look? |
Could you create a repo with the setup that is not working? |
thx, I'll take a look asap |
@fastify/typescript can you take a look as well? I'm kind of unsure what's the problem. |
@kibertoad @fox1t @Eomm could you take a look? |
on it |
Any news about it? |
First of all, sorry for the late response. I've just looked into this, and it turns out that the issue is indeed the `@fastify/auth arguments fastify instance with auth method that is a preHandlerHookHandler that uses the default type provider https://github.com/fastify/fastify-auth/blob/master/auth.d.ts#L18 Unfortunately, at the moment, I don't have a solution. I will look more deeply into this and return if anything comes to mind. |
@mcollina @TheWashiba Hi. Had a brief look at this the other day. The issue appears to be caused by the Unfortunately, because the WorkaroundIn the interim, the following should offer a workaround if using Type Providers (albeit a not ideal solution with the import { Type } from '@sinclair/typebox'
import { TypeBoxTypeProvider } from '@fastify/type-provider-typebox'
import fastifyAuth from '@fastify/auth'
import fastify from 'fastify'
import fp from 'fastify-plugin'
// --------------------------------------------------------------------------------
// Plugin
// --------------------------------------------------------------------------------
export const plugin = fp(
(fastify) => {
const instance = fastify.withTypeProvider<TypeBoxTypeProvider>();
instance.route({
method: 'GET',
url: '/plugin',
schema: {
body: Type.Object({
a: Type.Number(),
b: Type.Number()
})
},
preHandler: instance.auth([]) as any, // todo: review global module augmentation of the server auth() function.
handler: async (req, res) => {
const { a, b } = req.body
},
});
},
{
name: 'example',
}
);
// --------------------------------------------------------------------------------
// Index
// --------------------------------------------------------------------------------
const server = fastify().withTypeProvider<TypeBoxTypeProvider>();
server.register(fastifyAuth);
server.register(plugin)
server.route({
method: 'GET',
url: '/',
schema: {
body: Type.Object({
x: Type.Number(),
y: Type.Number()
})
},
preHandler: server.auth([]) as any, // todo: review global module augmentation of the server auth() function.
handler: async (req, res) => {
const { x, y } = req.body
},
}); Possible Next StepsI think probably the best way forward is spending some time taking a look at the way the current In terms of TypeScript, the ideal way to allow types to propagate would be to chain calls to const server = fastify()
.withTypeProvider<TypeBoxTypeProvider>() // remap to generic TypeBoxTypeProvider
.register(fastifyAuth) // augment instance with `.auth()` function.
.register(plugin) // augment with user defined functionality.
.route({ // route: configured with the above
method: 'GET',
url: '/',
schema: {
body: Type.Object({
x: Type.Number(),
y: Type.Number()
})
},
preHandler: server.auth([]),
handler: a sync (req, res) => {
const { x, y } = req.body
}
}); Although there may be additional options to explore with the following PR's fastify/fastify#3952 - Global augmentation of FastifyTypeProviderDefault Hope that helps! |
@fox1t @climba03003 could any of you take ownership of this? it looks like it's the final step for our TS definitions. |
The declare module 'fastify' {
interface FastifyInstance<RawServer, RawRequest, RawReply, Logger, TypeProvider> {
auth(
functions: FastifyAuthFunction[],
options?: {
relation?: 'and' | 'or',
run?: 'all'
}
): preHandlerHookHandler<RawServer, RawRequest, RawReply, RouteGenericInterface, ContextConfigDefault, FastifySchema, TypeProvider>;
}
} |
Maybe open a tracking issue on Fastify? It could be the basis of Fastify v5. Regarding the fix on fastify-auth, go for it. It seems the generic one is better, but that's my 2 cents. |
The change in fastify landed. I would like to close this and move the discussion about the follow-up in Fastify proper. Could you open such an issue @climba03003? |
Hi, I have searched and searched but It seems there is no clear solution to this specific problem yet. Do you know a way to avoid having to put "as any" everywhere? |
Hi, just wanted to add onto this ticket here, I'm also unable to get it working without using export const fastify = FastifyServer({}).withTypeProvider<ZodTypeProvider>();
fastify.decorate('verifyServerSecret', async (request: FastifyRequest) => {
if (request.headers.authorization !== `Bearer ${env.SERVER_SECRET}`) {
throw new UNAUTHORIZED("You don't have access to this endpoint");
}
});
fastify.register(fastifyAuth);
declare module 'fastify' {
interface FastifyInstance {
verifyServerSecret: FastifyAuthFunction; // technically this typing is wrong because I use `async/await` but it still works
}
}
export type FastifyInstance = typeof fastify; And then used like so: fastify.route({
method: 'POST',
url: '/test',
schema: {
body: z.object({
record: z.object({
id: z.string(),
}),
}),
response: {
200: z.object({}),
},
},
preHandler: fastify.auth([fastify.verifyServerSecret]), // adding `as any` here fixes it but doesn't seem right
async handler(req) {
const {
record: { id },
} = req.body; // ERROR: typed incorrectly :(
return {};
},
}); |
Ideally I want to get more complicated and do something like this: fastify.decorate('authenticateUser', async (request: FastifyRequest) => {
// check headers and fetch user
req.user = {} as User
}); where fastify.route({
// ...
preHandler: fastify.auth([fastify.authenticateUser]),
async handler(req) {
// req.user works and is correctly typed but only on routes that define the `preHandler`
},
}); it this a possibility? |
Hi, to prevent my self confused again. fastify.route({
// ...
preHandler: [] as never,
// ...
}); |
Guys, do that and your types will work as expected. export const yourPreHandler = async <
Request extends FastifyRequest,
Reply extends FastifyReply
>(
request: Request,
reply: Reply
) => {
// Your code here
}; |
Prerequisites
Fastify version
4.0.0-rc.3
Plugin version
No response
Node.js version
16.x
Operating system
Linux
Operating system version (i.e. 20.04, 11.3, 10)
Ubuntu 20.04
Description
I'm having TypeScript issues in the route
preHandler
when the package@fastify/auth
^3.0.0 is being used altogether. I'm unsure if this an issue of that package or this, but I've began experiencing issues once.withTypeProvider<TypeBoxTypeProvider>()
is called. The error received:Steps to Reproduce
Install
fastify@4
,@fastify/auth@3
and.1.0-beta.1
version of this plugin in a TypeScript environment. Calling thefastify.auth([])
in the routepreHandler
will give a type error.Expected Behavior
No response
The text was updated successfully, but these errors were encountered: