fastify / fastify-auth Goto Github PK
View Code? Open in Web Editor NEWRun multiple auth functions in Fastify
License: Other
Run multiple auth functions in Fastify
License: Other
Latest npm package version still is 4.2.0
But you did important fix in 4.3.0 when we can expect this package to be published to npm?
4.21.0
4.3.0
18.x
macOS
Monterey
Trying to migrate JS->TS for a NodeJS backend service. After changing index.js -> index.ts all my fastify plugins are fine (e.g. FastifyOpenapiDocs, FastifyMultipart, FastifySentry), but FastifyAuth has this error:
No overload matches this call.
Overload 1 of 3, '(plugin: FastifyPluginCallback<{ defaultRelation: string; }, RawServerDefault, FastifyTypeProvider, FastifyBaseLogger>, opts?: FastifyRegisterOptions<...>): FastifyInstance<...> & PromiseLike<...>', gave the following error.
Argument of type 'typeof fastifyAuth' is not assignable to parameter of type 'FastifyPluginCallback<{ defaultRelation: string; }, RawServerDefault, FastifyTypeProvider, FastifyBaseLogger>'.
Type 'typeof fastifyAuth' provides no match for the signature '(instance: FastifyInstance<RawServerDefault, FastifyTypeProvider, FastifyBaseLogger>'.
Type 'typeof fastifyAuth' provides no match for the signature '(instance: FastifyInstance<RawServerDefault, IncomingMessage, ServerResponse<IncomingMessage>, FastifyBaseLogger, FastifyTypeProvider>, opts: { ...; }, done: (err?: Error) => void): void'.
Overload 2 of 3, '(plugin: FastifyPluginAsync<{ defaultRelation: string; }, RawServerDefault, FastifyTypeProvider, FastifyBaseLogger>, opts?: FastifyRegisterOptions<...>): FastifyInstance<...> & PromiseLike<...>', gave the following error.
Argument of type 'typeof fastifyAuth' is not assignable to parameter of type 'FastifyPluginAsync<{ defaultRelation: string; }, RawServerDefault, FastifyTypeProvider, FastifyBaseLogger>'.
Type 'typeof fastifyAuth' provides no match for the signature '(instance: FastifyInstance<RawServerDefault, IncomingMessage, ServerResponse<IncomingMessage>, FastifyBaseLogger, FastifyTypeProvider>, opts: { ...; }): Promise<...>'.
Overload 3 of 3, '(plugin: FastifyPluginCallback<{ defaultRelation: string; }, RawServerDefault, FastifyTypeProvider, FastifyBaseLogger> | FastifyPluginAsync<...> | Promise<...> | Promise<...>, opts?: FastifyRegisterOptions<...>): FastifyInstance<...> & PromiseLike<...>', gave the following error.
Argument of type 'typeof fastifyAuth' is not assignable to parameter of type 'FastifyPluginCallback<{ defaultRelation: string; }, RawServerDefault, FastifyTypeProvider, FastifyBaseLogger> | FastifyPluginAsync<...> | Promise<...> | Promise<...>'.ts(2769)
Code looks something like:
// index.ts
import * as FastifyAuth from '@fastify/auth';
fastify.decorate('authfunc1', authfunc1);
fastify.decorate('authfunc2', authfunc2);
await fastify.register(FastifyAuth, { defaultRelation: 'and' }); //error under `FastifyAuth`
No response
It seems that composite authentication should allow the or
relation for sub-arrays, not only and
.
It's currently stated in the docs that:
The arrays within an array always have an AND relationship.
but this feels like a limiting and unnecessary constraint.
It seems natural for the relation inside an auth subarray to be the opposite of the main array relation.
The only current use-case for composite auth looks like this:
fastify.auth([f1, f2, [f3, f4]], { relation: 'or' })
which results in the f1 OR f2 OR (f3 AND f4)
logical expression.
However, it might be also useful to allow composite auth when relation
is 'and', so that the code below
fastify.auth([f1, f2, [f3, f4]], { relation: 'and' })
would result in the following logical expression: f1 AND f2 AND (f3 OR f4)
.
Basically, when the main (default) array relation is and
we want the relation for sub-arrays to be or
, and vice versa (like with the current implementation): when the main array relation is or
the relation inside subarrays is and
.
Current implementation of composite auth only allows a single use-case:
preHandler: fastify.auth([
[fastify.f1, fastify.f2], // relation inside is AND
fastify.f3
], {
relation: 'or'
}),
It would be great to allow also the oppisite use-case:
preHandler: fastify.auth([
[fastify.f1, fastify.f2], // relation inside is OR
fastify.f3
], {
relation: 'and'
}),
Increase coverage to reach 100%
To see what happens to your code in Node.js 10, Greenkeeper has created a branch with the following changes:
.travis.yml
If youβre interested in upgrading this repo to Node.js 10, you can open a PR with these changes. Please note that this issue is just intended as a friendly reminder and the PR as a possible starting point for getting your code running on Node.js 10.
Greenkeeper has checked the engines
key in any package.json
file, the .nvmrc
file, and the .travis.yml
file, if present.
engines
was only updated if it defined a single version, not a range..nvmrc
was updated to Node.js 10.travis.yml
was only changed if there was a root-level node_js
that didnβt already include Node.js 10, such as node
or lts/*
. In this case, the new version was appended to the list. We didnβt touch job or matrix configurations because these tend to be quite specific and complex, and itβs difficult to infer what the intentions were.For many simpler .travis.yml
configurations, this PR should suffice as-is, but depending on what youβre doing it may require additional work or may not be applicable at all. Weβre also aware that you may have good reasons to not update to Node.js 10, which is why this was sent as an issue and not a pull request. Feel free to delete it without comment, Iβm a humble robot and wonβt feel rejected π€
There is a collection of frequently asked questions. If those donβt help, you can always ask the humans behind Greenkeeper.
Your Greenkeeper Bot π΄
4.25.2
4.4.0
20.9.0
macOS
14.2.1
I came across a weird bug today when I was building my API. Basically when using @fastify/auth
plugin along with fastify-type-provider-zod
package typescript complains. I get the following error:
Type 'preHandlerHookHandler<RawServerDefault, IncomingMessage, ServerResponse<IncomingMessage>, RouteGenericInterface, unknown, FastifySchema, FastifyTypeProviderDefault, FastifyBaseLogger>' is not assignable to type 'onRequestHookHandler<RawServerDefault, IncomingMessage, ServerResponse<IncomingMessage>, RouteGenericInterface, unknown, FastifySchema, ZodTypeProvider, FastifyBaseLogger> | onRequestHookHandler<...>[] | undefined'.
Type 'preHandlerHookHandler<RawServerDefault, IncomingMessage, ServerResponse<IncomingMessage>, RouteGenericInterface, unknown, FastifySchema, FastifyTypeProviderDefault, FastifyBaseLogger>' is not assignable to type 'onRequestHookHandler<RawServerDefault, IncomingMessage, ServerResponse<IncomingMessage>, RouteGenericInterface, unknown, FastifySchema, ZodTypeProvider, FastifyBaseLogger>'.
The 'this' types of each signature are incompatible.
Type 'FastifyInstance<RawServerDefault, IncomingMessage, ServerResponse<IncomingMessage>, FastifyBaseLogger, ZodTypeProvider>' is not assignable to type 'FastifyInstance<RawServerDefault, IncomingMessage, ServerResponse<IncomingMessage>, FastifyBaseLogger, FastifyTypeProviderDefault>'.
The types returned by 'after()' are incompatible between these types.
Type 'FastifyInstance<RawServerDefault, IncomingMessage, ServerResponse<IncomingMessage>, FastifyBaseLogger, ZodTypeProvider> & PromiseLike<...>' is not assignable to type 'FastifyInstance<RawServerDefault, IncomingMessage, ServerResponse<IncomingMessage>, FastifyBaseLogger, FastifyTypeProviderDefault> & PromiseLike<...>'.
Type 'FastifyInstance<RawServerDefault, IncomingMessage, ServerResponse<IncomingMessage>, FastifyBaseLogger, ZodTypeProvider> & PromiseLike<...>' is not assignable to type 'FastifyInstance<RawServerDefault, IncomingMessage, ServerResponse<IncomingMessage>, FastifyBaseLogger, FastifyTypeProviderDefault>'.
The types of 'addSchema(...).addHook' are incompatible between these types.
Type '{ <RouteGeneric extends import("/Users/geovla/Developer/Projects/apps/taskmaster/api/node_modules/.pnpm/[email protected]/node_modules/fastify/types/route").RouteGenericInterface = import("/Users/geovla/Developer/Projects/apps/taskmaster/api/node_modules/.pnpm/[email protected]/node_modules/fastify/types/route").RouteGene...' is not assignable to type '{ <RouteGeneric extends import("/Users/geovla/Developer/Projects/apps/taskmaster/api/node_modules/.pnpm/[email protected]/node_modules/fastify/types/route").RouteGenericInterface = import("/Users/geovla/Developer/Projects/apps/taskmaster/api/node_modules/.pnpm/[email protected]/node_modules/fastify/types/route").RouteGene...'. Two different types with this name exist, but they are unrelated.
Types of parameters 'hook' and 'hook' are incompatible.
Types of parameters 'opts' and 'opts' are incompatible.
Type 'RouteOptions<RawServerDefault, IncomingMessage, ServerResponse<IncomingMessage>, any, any, any, ZodTypeProvider, FastifyBaseLogger> & { ...; }' is not assignable to type 'RouteOptions<RawServerDefault, IncomingMessage, ServerResponse<IncomingMessage>, any, any, any, FastifyTypeProviderDefault, FastifyBaseLogger> & { ...; }'.
Type 'RouteOptions<RawServerDefault, IncomingMessage, ServerResponse<IncomingMessage>, any, any, any, ZodTypeProvider, FastifyBaseLogger> & { ...; }' is not assignable to type 'RouteOptions<RawServerDefault, IncomingMessage, ServerResponse<IncomingMessage>, any, any, any, FastifyTypeProviderDefault, FastifyBaseLogger>'.
Types of property 'handler' are incompatible.
Type 'RouteHandlerMethod<RawServerDefault, IncomingMessage, ServerResponse<IncomingMessage>, any, any, any, ZodTypeProvider, FastifyBaseLogger>' is not assignable to type 'RouteHandlerMethod<RawServerDefault, IncomingMessage, ServerResponse<IncomingMessage>, any, any, any, FastifyTypeProviderDefault, FastifyBaseLogger>'.
Type 'FastifyTypeProviderDefault' is not assignable to type 'ZodTypeProvider'.
The error is shown both in onRequest
and preHandler
hooks. I should mention that the error does not show up if I remove the app.auth()
function and use the auth functions on their own or in an array.
Create a fastify server and install the mentioned packages along with zod
. Create two auth functions and try to use them in either onRequest
or preHandler
hooks.
export default async function routes(app: FastifyInstance) {
app
.withTypeProvider<ZodTypeProvider>()
.route({
method: 'GET',
url: '/',
schema: {
description: 'Get all users',
tags: ['User'],
response: {
200: userResponseSchema.array(),
},
},
onRequest: app.auth([app.authenticate, app.guard]),
handler: getUsersHandler,
});
}
I would like to use this package without this typescript error like this:
onRequest: app.auth([app.authenticate, app.guard])
4.0.0
4.5.0
18.18.0
Linux
Fedora 39
When you define a body schema in the fastify route options, you get Typescript type completion in the handler function.
However, adding the fastify auth function to the onRequest
or preHandler
hook removes these definitions, and makes body of type unknown
.
Take the following route for example:
fastify.route({
method: "POST",
url: "/",
schema: {
body: CreateTodo,
response: {
201: ReturnTodo,
},
},
onRequest: fastify.auth([fastify.verifyJWT]),
handler: async ({ body }, reply) => {
const result = await fastify.prisma.todo.create({ data: body }); // error here: "body is of type `unknown`"
const todo = {
...result,
createdAt: result.createdAt.toISOString(),
updatedAt: result.updatedAt.toISOString(),
};
reply.code(201);
return todo;
},
});
However, when we remove the onRequest
hook, the error disappears.
The type definitions from the schema should carry on through the hook where the fastify auth function is used, and should apply to the actual handler function.
Hello,
any TypeScript support planned for this plugin?
I'm looking to add some CASL authorisation to my routes and I thought it would be less verbose if I could set the default relationship as "and" instead of "or". That way I can run my authentication check first, then the authorisation check, without appending: { relation: 'and' }
to every route.
Less verbose if I never intend to use "or"
app.register(require('@fastify/auth'), {
defaultRelation: 'and'
})
4.13.0
4.3.0
18.17.1
macOS
14.0
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.
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.
I don't receive any TS error when using
onRequest: fastify.auth([usersMutationAccessPolicy(fastify)]),
from above.
Allow an auth handler to inform the plugin the this auth does not apply and skip to the next handler (if any)
Creating an abitrary error is clunky and hard to read
From sample repo: https://github.com/cliedeman/fastify-anonymous-example/blob/master/src/app.ts#L40
await app.decorate(
'allowAnonymous',
function (
request: FastifyRequest,
_reply: FastifyReply,
done: DoneFuncWithErrOrRes
) {
if (!request.headers.authorization) {
return done();
}
// Noisy Error
return done(new Error('not anonymous'));
}
);
await app.decorate(
'allowBearerAuth',
function (
request: FastifyRequest,
_reply: FastifyReply,
done: DoneFuncWithErrOrRes
) {
if (request.headers.authorization) {
...
return done();
}
// Noisy Error
return done(new Error('anonymous'));
}
);
Please provide an example for how this feature would be used.
import {default as fastifyAuth, errNextAuth } from 'fastify-auth';
...
await app.decorate(
'allowAnonymous',
function (
request: FastifyRequest,
_reply: FastifyReply,
done: DoneFuncWithErrOrRes
) {
if (!request.headers.authorization) {
return done();
}
return done(errNextAuth);
}
);
await app.decorate(
'allowBearerAuth',
function (
request: FastifyRequest,
_reply: FastifyReply,
done: DoneFuncWithErrOrRes
) {
if (request.headers.authorization) {
...
return done();
}
return done(errNextAuth);
}
);
This will also allow the plugin to report a different error if no handler accepted the request.
3.x
1.1.0
14.x
Windows
10
When trying to use this import in TS using the latest fastify-auth version:
import fastifyAuth from 'fastify-auth';
app
.register(fastifyJwt, { secret: 'secret' })
.register(fastifyAuth)
, it actually doesn't work anymore and throws an error:
error TS2339: Property 'auth' does not exist on type 'FastifyInstance'.
This is not a problem when using the older version.
I see a similar issue was posted for fastify-jwt here which still replicates.
Try to import plugin using named import in TypeScript.
Named import should work.
4.25.2
4.4.0
20.9.0
macOS
14.2.1
I came across a weird bug today when I was building my API. Basically when using @fastify/auth
plugin along with fastify-type-provider-zod
package typescript complains. I get the following error:
Type 'preHandlerHookHandler<RawServerDefault, IncomingMessage, ServerResponse<IncomingMessage>, RouteGenericInterface, unknown, FastifySchema, FastifyTypeProviderDefault, FastifyBaseLogger>' is not assignable to type 'onRequestHookHandler<RawServerDefault, IncomingMessage, ServerResponse<IncomingMessage>, RouteGenericInterface, unknown, FastifySchema, ZodTypeProvider, FastifyBaseLogger> | onRequestHookHandler<...>[] | undefined'.
Type 'preHandlerHookHandler<RawServerDefault, IncomingMessage, ServerResponse<IncomingMessage>, RouteGenericInterface, unknown, FastifySchema, FastifyTypeProviderDefault, FastifyBaseLogger>' is not assignable to type 'onRequestHookHandler<RawServerDefault, IncomingMessage, ServerResponse<IncomingMessage>, RouteGenericInterface, unknown, FastifySchema, ZodTypeProvider, FastifyBaseLogger>'.
The 'this' types of each signature are incompatible.
Type 'FastifyInstance<RawServerDefault, IncomingMessage, ServerResponse<IncomingMessage>, FastifyBaseLogger, ZodTypeProvider>' is not assignable to type 'FastifyInstance<RawServerDefault, IncomingMessage, ServerResponse<IncomingMessage>, FastifyBaseLogger, FastifyTypeProviderDefault>'.
The types returned by 'after()' are incompatible between these types.
Type 'FastifyInstance<RawServerDefault, IncomingMessage, ServerResponse<IncomingMessage>, FastifyBaseLogger, ZodTypeProvider> & PromiseLike<...>' is not assignable to type 'FastifyInstance<RawServerDefault, IncomingMessage, ServerResponse<IncomingMessage>, FastifyBaseLogger, FastifyTypeProviderDefault> & PromiseLike<...>'.
Type 'FastifyInstance<RawServerDefault, IncomingMessage, ServerResponse<IncomingMessage>, FastifyBaseLogger, ZodTypeProvider> & PromiseLike<...>' is not assignable to type 'FastifyInstance<RawServerDefault, IncomingMessage, ServerResponse<IncomingMessage>, FastifyBaseLogger, FastifyTypeProviderDefault>'.
The types of 'addSchema(...).addHook' are incompatible between these types.
Type '{ <RouteGeneric extends import("/Users/geovla/Developer/Projects/apps/taskmaster/api/node_modules/.pnpm/[email protected]/node_modules/fastify/types/route").RouteGenericInterface = import("/Users/geovla/Developer/Projects/apps/taskmaster/api/node_modules/.pnpm/[email protected]/node_modules/fastify/types/route").RouteGene...' is not assignable to type '{ <RouteGeneric extends import("/Users/geovla/Developer/Projects/apps/taskmaster/api/node_modules/.pnpm/[email protected]/node_modules/fastify/types/route").RouteGenericInterface = import("/Users/geovla/Developer/Projects/apps/taskmaster/api/node_modules/.pnpm/[email protected]/node_modules/fastify/types/route").RouteGene...'. Two different types with this name exist, but they are unrelated.
Types of parameters 'hook' and 'hook' are incompatible.
Types of parameters 'opts' and 'opts' are incompatible.
Type 'RouteOptions<RawServerDefault, IncomingMessage, ServerResponse<IncomingMessage>, any, any, any, ZodTypeProvider, FastifyBaseLogger> & { ...; }' is not assignable to type 'RouteOptions<RawServerDefault, IncomingMessage, ServerResponse<IncomingMessage>, any, any, any, FastifyTypeProviderDefault, FastifyBaseLogger> & { ...; }'.
Type 'RouteOptions<RawServerDefault, IncomingMessage, ServerResponse<IncomingMessage>, any, any, any, ZodTypeProvider, FastifyBaseLogger> & { ...; }' is not assignable to type 'RouteOptions<RawServerDefault, IncomingMessage, ServerResponse<IncomingMessage>, any, any, any, FastifyTypeProviderDefault, FastifyBaseLogger>'.
Types of property 'handler' are incompatible.
Type 'RouteHandlerMethod<RawServerDefault, IncomingMessage, ServerResponse<IncomingMessage>, any, any, any, ZodTypeProvider, FastifyBaseLogger>' is not assignable to type 'RouteHandlerMethod<RawServerDefault, IncomingMessage, ServerResponse<IncomingMessage>, any, any, any, FastifyTypeProviderDefault, FastifyBaseLogger>'.
Type 'FastifyTypeProviderDefault' is not assignable to type 'ZodTypeProvider'.
The error is shown both in onRequest
and preHandler
hooks. I should mention that the error does not show up if I remove the app.auth()
function and use the auth functions on their own or in an array.
Create a fastify server and install the mentioned packages along with zod
. Create two auth functions and try to use them in either onRequest
or preHandler
hooks.
export default async function routes(app: FastifyInstance) {
app
.withTypeProvider<ZodTypeProvider>()
.route({
method: 'GET',
url: '/',
schema: {
description: 'Get all users',
tags: ['User'],
response: {
200: userResponseSchema.array(),
},
},
onRequest: app.auth([app.authenticate, app.guard]),
handler: getUsersHandler,
});
}
I would like to use this package without this typescript error like this:
onRequest: app.auth([app.authenticate, app.guard])
i have some apis needs to be accessed with some higher grants than auth only
for ordinary auth check, i have a JWT based identify solution, but for the higher grants i might needs to add a new and strict solution based on JWT
the current support for multiple auth solution of fastify-auth is the relaction of OR
, while my needs might need the relation AND
is it possible for you guys to adds a options to toggle that?
like
fastify.post('/api/ordinary', { preHandler: fastify.auth([fastify.jwtcheck, fastify.userpasscheck], {relation: 'or'}) }, handler_ordinary)
fastify.post('/api/strict', { preHandler: fastify.auth([[fastify.jwtcheck, fastify.userpasscheck], fastify.highergrantscheck], {relation: 'and'}) }, handler_ordinary)
When an user is successfully authenticated, how can I pass the user to the route handler?
The names of the hooks are changed, and we can now run auth in onRequest
Β as well.
Branch | Build failing π¨ |
---|---|
Dependency | fastify |
Current Version | 1.7.0 |
Type | devDependency |
This version is covered by your current version range and after updating it in your project the build failed.
fastify is a devDependency of this project. It might not break your production code or affect downstream projects, but probably breaks your build or test tools, which may prevent deploying or publishing.
Features
Fixes
Docs
Typescript
Internals
The new version differs by 19 commits.
55fc867
Bumped v1.8.0
e58c627
test: add test case for request.id (#1030)
7f734fd
Add test for checking multipart request using form-data module (#1026)
4949a9c
Configure request id header key (#1024)
7476cb4
Update Ecosystem.md (#874)
42d10f6
New instructions have been added for use with fastif-cli (#1020)
a137087
add-chinese-doc-link (#1021)
92ee7db
Support case insensitivity. (#1017)
0dfb356
Update Middlewares.md (#996)
8955f27
Resolves issue #1006 (#1008)
dd337fd
Feature/#713 beforeHandler for setNotFoundHandler (#1005)
1b92295
Rename swaggergen to openapi glue (#1013)
2f96a80
fix listen ts types (#1000)
68114ee
Add fastify-wamp-router plugin to docs/Ecosystem.md (#1002)
724199f
Update Reply.md (#1003)
There are 19 commits in total.
See the full diff
There is a collection of frequently asked questions. If those donβt help, you can always ask the humans behind Greenkeeper.
Your Greenkeeper Bot π΄
2.7.0
to 2.7.1
.π¨ View failing branch.
This version is covered by your current version range and after updating it in your project the build failed.
rimraf is a devDependency of this project. It might not break your production code or affect downstream projects, but probably breaks your build or test tools, which may prevent deploying or publishing.
There is a collection of frequently asked questions. If those donβt help, you can always ask the humans behind Greenkeeper.
Your Greenkeeper Bot π΄
I'm using fastify-jwt to verify JWT but. but when i combine it with fastify-auth the auth method just stalled and i did not get any response. what could go wrong?
my server.js
const fastify = require("fastify")({
logger: {
prettyPrint: true,
prettifier: require('pino-pretty')
}
});
fastify
.register(require('fastify-cors'), {
origin: true
})
.register(require("./plugins/db"), {
url: "mongodb://localhost:27017/vfcms"
})
.register(require('fastify-jwt'), {
secret: 'supersecret',
maxAge: '1d'
})
.register(require('fastify-auth'))
fastify.decorate('verifyJWT', async (req, reply) => {
try {
await req.jwtVerify()
} catch (error) {
reply.send(error)
}
})
fastify.register(require("./services/root"));
fastify.register(require("./services/user"));
fastify.listen(3000, function(err, address) {
if (err) {
fastify.log.error(err);
process.exit(1);
}
fastify.log.info(`server listening on ${address}`);
});
my root.js
async function routes(fastify, options) {
fastify.route({
method: 'GET',
url: '/',
handler: (req, reply) => {
reply.code(200).send({ api: "ready"})
}
})
fastify.route({
method: 'GET',
url: '/dashboard',
beforeHandler: fastify.auth([
fastify.verifyJWT
]),
handler: (req, reply) => {
reply.code(200).send({ imVerified: "ready"})
}
})
}
module.exports = routes;
a complete repo my project are on github.
but if I'm not using beforeHandler: fastify.auth([ fastify.verifyJWT ])
and just beforeHandler: [ fastify.verifyJWT ]
it pass perfectly, any advice?
I may wanna check auth in order in some cases. And in other cases it could be run in parallel, and in this way i may get a faster response by an auth cache maybe. :)
π¨ You need to enable Continuous Integration on all branches of this repository. π¨
To enable Greenkeeper, you need to make sure that a commit status is reported on all branches. This is required by Greenkeeper because we are using your CI build statuses to figure out when to notify you about breaking changes.
Since we did not receive a CI status on the greenkeeper/initial
branch, we assume that you still need to configure it.
If you have already set up a CI for this repository, you might need to check your configuration. Make sure it will run on all new branches. If you donβt want it to run on every branch, you can whitelist branches starting with greenkeeper/
.
We recommend using Travis CI, but Greenkeeper will work with every other CI service as well.
Once you have installed CI on this repository, youβll need to re-trigger Greenkeeperβs initial Pull Request. To do this, please delete the greenkeeper/initial
branch in this repository, and then remove and re-add this repository to the Greenkeeper integrationβs white list on Github. You'll find this list on your repo or organiszationβs settings page, under Installed GitHub Apps.
3.27.1
3.0.1
14.17.6
Linux
Ubuntu 20.04.3 LTS
I'am trying to build an authentication plugin using fastify, fastify-auth, and aws cognito.
The fastify application is generated using create-fastify-app
module.exports = async function (fastify, opts) {
fastify
.post(
'/service',
{ ...options, schema: { ...options.schema, body: { ...schema, } } },
fastify.auth([fastify.verify]),
crudController.addNew
)
const fp = require('fastify-plugin')
const jwt = require('jsonwebtoken')
const jwkToPem = require('jwk-to-pem')
module.exports = fp(async (fastify, opts) => {
fastify
.register(require('fastify-auth'))
.decorate("jwk", { keys: [{ ... //all the secrets here }] })
.decorate("verify", verifyJWT)
function verifyJWT(request, reply) {
const pemjwk = jwkToPem(fastify.jwk.keys[0])
if (request.body && request.body.failureWithReply) {
reply.code(401).send({ error: 'Unauthorized' })
return Promise.reject(new Error())
}
if (!request.headers.token) {
reply
.type('application/json')
.code(401)
.send({ error: 'Missing token header' })
return Promise.reject(new Error('Missing token header'))
}
return new Promise((resolve, reject) => {
jwt.verify(request.headers.token, pemjwk, { algorithms: ['RS256'] }, (err, payload) => {
if (err) {
return reject(err)
}
resolve(payload)
})
}).then((payload) => {
fastify.log.info(`User ${payload['cognito:username']} authenticated !`)
}).catch((error) => {
reply
.code(401)
.send(error)
throw new Error(error)
})
}
})
**fastify.verify**
decorator just verify the JWT token, return the payload if user is authentic otherwise throw an error.
Fastify log the message "user authenticated!" everything works perfect so far.
But when the request is completed, I got the following error that crash the application:
22:06:35 β¨ incoming request POST xxx /api/v1/auth/login
22:06:37 β¨ request completed 1.4s
22:06:48 β¨ incoming request POST xxx /api/v1/service
22:06:48 β¨ User ousssddfs authenticated !
TypeError: that.done is not a function
at Auth.completeAuth (/workstation/dev/haflago/backend/node_modules/fastify-auth/auth.js:115:12)
at Auth.onAuth (/workstation/dev/haflago/backend/node_modules/fastify-auth/auth.js:89:21)
at /workstation/dev/haflago/backend/node_modules/fastify-auth/auth.js:79:43
at processTicksAndRejections (internal/process/task_queues.js:95:5)
[nodemon] app crashed - waiting for file changes before starting...
I also compared my code with their test example, and it looks pretty similar !!
Did anybody get this error before ?
const fp = require('fastify-plugin')
const jwt = require('jsonwebtoken')
const jwkToPem = require('jwk-to-pem')
module.exports = fp(async (fastify, opts) => {
fastify
.register(require('fastify-auth'))
.decorate("verify", async (request, reply) => {
if (request.body && request.body.failureWithReply) {
reply.code(401).send({ error: 'Unauthorized' })
return Promise.reject(new Error())
}
if (!request.headers.token) {
reply
.type('application/json')
.code(401)
.send({ error: 'Missing token header' })
return Promise.reject(new Error('Missing token header'))
}
return new Promise((resolve, reject) => {
jwt.verify(request.headers.token, pemjwk, { algorithms: ['RS256'] }, (err, payload) => {
if (err) {
return reject(err)
}
resolve(payload)
})
}).then((payload) => {
fastify.log.info(`User ${payload.user is authenticated !`)
reply
.code(200)
.send({ message: "Authentication successful !" })
return reply
}).catch((error) => {
reply
.code(401)
.send(error)
throw new Error(error)
})
})
})
preHandler
as fastify-auth :module.exports = async function (fastify, opts) {
fastify
.post(
'/service',
fastify.auth([fastify.verify]),
crudController.addNew
)
[nodemon] starting `fastify start ./src/index.js`
22:33:28 β¨ DB is provided at : mongodb://localhost:27028/halago
22:33:28 β¨ Database is connected
22:33:28 β¨ Server listening at http://127.0.0.1:9898
22:33:34 β¨ incoming request POST xxx /api/v1/service
TypeError: that.done is not a function
at Auth.completeAuth (/workstation/dev/haflago/backend/node_modules/fastify-auth/auth.js:115:12)
at Auth.onAuth (/workstation/dev/haflago/backend/node_modules/fastify-auth/auth.js:89:21)
at /workstation/dev/haflago/backend/node_modules/fastify-auth/auth.js:79:43
at processTicksAndRejections (internal/process/task_queues.js:95:5)
[nodemon] app crashed - waiting for file changes before starting...
Fastify-auth decorator log the decoded JWT token and app doesn't crash.
4.10.2
4.2.0
18.12.1
macOS
13.1
The result of these exports...
module.exports = fp(fastifyAuth, {
fastify: '4.x',
name: '@fastify/auth'
})
module.exports.default = fastifyAuth
module.exports.fastifyAuth = fastifyAuth
...when imported into ESM is that you wind up with two instances of fastifyAuth
and no plugin, whereas default
is, as so named, the default import. If you try doing import * as fastifyAuthPlugin
, you still wind up with just the default
and fastifyAuth
properties.
For compatibility with modern JavaScript it should really be:
module.exports.default = fp(fastifyAuth, {
fastify: '4.x',
name: '@fastify/auth'
})
module.exports.fastifyAuth = fastifyAuth
See above.
For the plugin to be the default export.
Dear fastify-auth maintainers,
Thank you for your contribution to the open-source community.
This issue was automatically created to inform you a new version (1.2.0) of fastify-auth was published without a matching tag in this repo.
As part of our efforts to fight software supply chain attacks, we would like to verify this release is known and intended, and not a result of an unauthorized activity.
If you find this behavior legitimate, kindly close and ignore this issue. Read more
13.1.0
to 14.0.0-1
.π¨ View failing branch.
This version is covered by your current version range and after updating it in your project the build failed.
standard is a devDependency of this project. It might not break your production code or affect downstream projects, but probably breaks your build or test tools, which may prevent deploying or publishing.
The new version differs by 70 commits.
7117e53
14.0.0-1
c1ebec6
Disallow spaces inside of curly braces in JSX expressions in children (react/jsx-curly-spacing)
2d619f3
Require linebreaks in curly braces in JSX attributes and expressions to be consistent (react/jsx-curly-newline)
5dfdc83
Require JSX event handler names to follow conventions (react/jsx-handler-names)
ff4ef49
Require JSX attributes and logical expressions to be indented correctly (react/jsx-indent)
13e4bee
Disallow missing key
prop in JSX elements that likely require a key
prop (react/jsx-key)
29861dc
Disallow accidental comments in JSX from being inserted as text nodes (react/jsx-no-comment-textnodes)
c852a11
Prevent usage of unsafe target='_blank' (react/jsx-no-target-blank)
30eddfa
Disallow unnecessary curly braces in JSX props and children. (react/jsx-curly-brace-presence)
d3d14a5
Require PascalCase for user-defined JSX components (react/jsx-pascal-case)
93027d9
Require shorthand form for JSX fragments (react/jsx-fragments)
093b7f0
Disallow multiple spaces between inline JSX props (react/jsx-props-no-multi-spaces)
6ee9fb1
alphabetize rules
d179362
remove rule which already shipped
f8551e9
Require JSX closing bracket to be aligned with the opening tag (react/jsx-closing-bracket-location)
There are 70 commits in total.
See the full diff
There is a collection of frequently asked questions. If those donβt help, you can always ask the humans behind Greenkeeper.
Your Greenkeeper Bot π΄
Npm module fastify-auth has issue and thus relation: 'and'
is not working for multiple auth handler inside a route.
Steps to reproduce the behavior:
preHandler: fastifyApp.auth([fastifyApp.verifyJWT, fastifyApp.verifyOauth], { relation: 'and' }),
Both verifyJWT & verifyOauth should get called and should be passed before a route is handled.
Paste the results here:
Only first auth handler is called.
When npm module fastify-auth gets installed it has different code than what is in src. When i replaced node_modules/fastify-auth/fastify-auth.js, it started working
fastify-auth is currently incompatible with 1.0-rc.1, throws the following error:
fastify-plugin - expected '>=0.13.1' fastify version, '1.0.0-rc.1' is installed
1 | // npm packages
2 | const initFastify = require('fastify');
> 3 | const fastifyAuth = require('fastify-auth');
Updating fastify-plugin should probably fix this, right? Should I send a PR?
hi.
it seems that i'm missing something.
this is my code:
module.exports = function (fastify, opts, next) {
fastify.register(require('fastify-auth'));
fastify.decorate('verifyUserAndPassword', function (request, reply, done) {
console.log(request);
done(new Error('err'));
});
fastify.ready(err => {
if (err) throw err;
fastify.addHook('preHandler', fastify.auth([fastify.verifyUserAndPassword]));
});
fastify.get('/', async function (req, reply) {
reply.send({ message: 'hi' });
})
fastify.register(require('./users'));
next();
};
but it doesn't have any effect. the above piece of code is a plugin registered as the parent of all of my routes, and i'm throwing an error in done
callback, but all the routes are working without any error.
thanks.
4.26.1
4.5.0
20.11.0
macOS
14.3.1 (23D60)
#217 introduced new rules for auth.
The main problem is that now both paths (in or
relation) going in parallel instead of waiting until the first path will fail.
I commented all tests except one that clearly showing a problem (and my own production code solution too).
cd fastify-auth
)npm i
)npm t
)or
relation "THIS IS A SECOND AUTH PATH SHOULD NOT BE CALLED" but you SHOULDN'T.fastify.route({
method: "POST",
url: "/check-two-sub-arrays-or",
preHandler: fastify.auth(
[[fastify.verifyBigAsync], [fastify.verifyOddAsync]],
{ relation: "or" }
),
handler: (req, reply) => {
req.log.info("Auth route");
reply.send({ hello: "world" });
},
});
function verifyBigAsync(request, reply) {
console.log("If you see it β IT IS OK");
return new Promise((resolve, reject) => {
verifyBig(request, reply, (err) => {
if (err) {
console.log("FIRST_ERROR", err);
reject(err);
}
resolve();
});
});
}
function verifyOddAsync(request, reply) {
console.log("THIS IS A SECOND AUTH PATH SHOULD NOT BE CALLED");
return new Promise((resolve, reject) => {
verifyOdd(request, reply, (err) => {
if (err) reject(err);
resolve();
});
});
}
// A function behind "verifyBigAsync"
function verifyBig(request, reply, done) {
const n = request.body.n;
if (typeof n !== "number" || n < 100) {
request.big = false;
return done(new Error("`n` is not big"));
}
request.big = true;
return done();
}
test("Two sub-arrays Or Relation success", (t) => {
t.plan(2);
fastify.inject(
{
method: "POST",
url: "/check-two-sub-arrays-or",
payload: {
n: 110, // previously 11 which less than 100
},
},
(err, res) => {
t.error(err);
const payload = JSON.parse(res.payload);
t.same(payload, { hello: "world" });
}
);
});
npm t
> @fastify/[email protected] test
> npm run test:unit && npm run test:typescript
> @fastify/[email protected] test:unit
> tap
PASS β ./test/auth.test.js 29 OK 37.593ms
PASS β ./test/example-async.test.js 18 OK 50.854ms
./test/example-composited.test.js 1> If you see it β IT IS OK
./test/example-composited.test.js 1> THIS IS A SECOND AUTH PATH SHOULD NOT BE CALLED
PASS β ./test/example-composited.test.js 2 OK 17.401ms
PASS β ./test/example.test.js 20 OK 46.829ms
No response
Hey, thanks for the lovely work.
I was playing around with fastify-auth
and I can't actually create a steady case with multiple strategies. Apparently, something does not work as expected. Using the example below the authentication flow does not pass by bar()
strategy.
const Fastify = require('fastify');
const build = (opts = {}) => {
const fastify = Fastify(opts);
const routes = () => {
fastify.get(
'/',
{
beforeHandler: fastify.auth([fastify.foo, fastify.bar])
},
(request, reply) => ({hello: 'world'})
);
};
return fastify
.register(require('fastify-auth'))
.decorate('foo', (req, rep, done) => {
console.log('foo');
done();
})
.decorate('bar', (req, rep, done) => {
console.log('bar');
done();
})
.after(routes);
};
const fastify = build();
fastify.listen(3000, err => {
if (err) throw err;
console.log(`Server listenting at http://localhost:${fastify.server.address().port}`);
});
Any help will be highly appreciated.
The Typescript type for fastify.auth
is missing the optional second parameter that allows us to change the relationship between the authentication functions from or
to and
(as described in the readme).
Steps to reproduce the behavior:
Use fastify-auth with Typescript. Attempt to change the relation between two auth functions.
fastify.get(
'/auth-test',
{
schema: authSchema,
preHandler: fastify.auth([fastify.jwtTokenCheck, fastify.userIsAdmin], {relation: 'and'}),
},
async () => {
return { status: 'ok' };
},
);
We would expect this to work as in the readme, but Typescript expects only one parameter for the function.
Paste the results here:
error TS2554: Expected 1 arguments, but got 2.
In hapi you can do this. Pretty straight forward.
Any idea how to do this with fastify?
await server.register(require('hapi-auth-basic'));
server.auth.strategy('simple', 'basic', { validate });
server.auth.default('simple');
server.route({
method: 'GET',
path: '/',
handler: function (request, h) {
return 'welcome';
}
});
await server.start();
Hi, I just found this plugin and would like to know how can it help me to implement an auth mechanism in my application but I'm a little bit confused
This module does not provide an authentication strategy, but it provides a very fast utility to handle authentication (also multiple strategies) in your routes, without adding overhead.
Marketing boom!
The documentation is really complex and it is hard to find an intro. In my opinion, it looks like that this plugin only helps to run an array of auth functions and respond with 401 when an error was passed. I really expect something different when I read fastify-auth
. This is just my personal feedback and as always I'm engaged to help you with that.
It would be great to provide an interface to implement different auth strategys similiar to hapi so that the implementation details are not visible for the route definition.
fastify.route({
method: 'POST',
auth: 'basic',
url: '/auth',
handler: ....
})
onAddRoute
hook to build the beforeHandler
for the specific auth strategy at startup time.function fastifyAuth(fastify, opts, done) {
fastify.addHook('onAddRoute', (route, done) => {
if(opts.auth === 'basic') {
route.beforeHandler.add(require('fastify-basic-auth'))
}
done()
})
}
The ability to customize the decorator name, we can keep auth
as default, but would be nice to have a way to change this via server options.
May I do my first fastify related PR or do you guys think not worth it?
Thank you!
I already have an auth
decorator on my application.
No response
For a valid auth series, the status code returned with and
is always 401.
I tested it also if this feature is not released yet and the test cases don't check the statusCode
of the response.
const fastify = require('fastify')()
function authFactory (id) {
return function (request, reply, done) {
console.log(id)
if (request.query.name === id || request.query.name === 'all') {
done()
} else {
done(new Error('query ' + id))
}
}
}
fastify.register(require('fastify-auth'))
.after(() => {
fastify.addHook('preHandler', fastify.auth([authFactory('one'), authFactory('two')], { relation: 'and' }))
fastify.get('/', (req, res) => res.send(42))
})
fastify.listen(3000)
Calling curl -X GET 'http://localhost:3000/?name=all'
The response code should be 200, not 401 since all the validation are done()
Paste the results here:
$ curl -v http://localhost:3000?name=all
* Trying ::1:3000...
* TCP_NODELAY set
* Trying 127.0.0.1:3000...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 3000 (#0)
> GET /?name=all HTTP/1.1
> Host: localhost:3000
> User-Agent: curl/7.65.3
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 401 Unauthorized
< content-type: application/json; charset=utf-8
< content-length: 2
< Connection: keep-alive
<
42
Add a new parameter to execute all the auth handler in any case.
Right now if the relation is or
it will stop at the first success if it is and
it will stop at the first error.
The user may want to get all the info from the request and act accordingly in the setErrorHandler
function.
In my case, I have a request with many tokens and I need to parse them all
fastify.route({
method: 'POST',
url: '/auth-multiple',
preHandler: fastify.auth([
fastify.verifyAdmin,
fastify.verifyReputation
], {
relation: 'and',
run: 'all'
}),
handler: (req, reply) => {
req.log.info('Auth route')
reply.send({ hello: 'world' })
}
})
Hello,
I don't know if this is a bug or feature, but it seems that fastify-auth
does not currently support async authentication strategies:
https://github.com/PP-etc/fastify-auth-with-async-pre-handler/blob/master/__tests__/stucks.test.js#L8
Declaration above will never be resolved, since done
is not passed and not called.
While originally preHandler
(and it's father beforeHandler
) do support async
:
https://www.fastify.io/docs/latest/Hooks/#respond-to-a-request-from-a-hook
Should this be fixed?
An auth "pipeline" could dirty the reply
status code and when the handler execute, the status code returned is in an bad status.
const fastify = require('fastify')()
function authFactory (id, status) {
return function (request, reply, done) {
console.log(id)
if (request.query.name === id || request.query.name === 'all') {
done()
} else {
reply.code(status)
done(new Error('query ' + id))
}
}
}
fastify.register(require('fastify-auth'))
.after(() => {
fastify.addHook('preHandler', fastify.auth([authFactory('one', 501), authFactory('two', 502)], { relation: 'or' }))
fastify.get('/', (req, res) => res.send(42))
})
fastify.listen(3000)
Calling curl -X GET 'http://localhost:3000/?name=two'
I would expect 200 but I receive 501
that was set by the first auth handler that has dirtier the replay
, I think we should restore the status code across the auth handler execution.
$ curl -v http://localhost:3000?name=two
* Trying ::1:3000...
* TCP_NODELAY set
* Trying 127.0.0.1:3000...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 3000 (#0)
> GET /?name=two HTTP/1.1
> Host: localhost:3000
> User-Agent: curl/7.65.3
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 501 Not Implemented
< content-type: application/json; charset=utf-8
< content-length: 2
< Connection: keep-alive
<
42
A declarative, efficient, and flexible JavaScript library for building user interfaces.
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. πππ
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google β€οΈ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.