Skip to content
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

feat(frameworks): add @auth/fastify #9587

Open
wants to merge 38 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 24 commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
11731a4
feat: add fastify framework
hillac Jan 9, 2024
426a87c
test: add session, request and response tests.
hillac Jan 9, 2024
a3835dc
docs: add docs
hillac Jan 9, 2024
0bd850e
Merge branch 'main' into main
ndom91 Jan 15, 2024
f94310a
clean up plugin and extend login test
hillac Jan 15, 2024
bc8372a
Merge branch 'main' of github.com:hillac/next-auth into main
hillac Jan 15, 2024
65632ff
Merge branch 'main' into main
ndom91 Jan 15, 2024
dc17fd0
fix some test expectations silently not running
hillac Jan 18, 2024
83bde07
support redirectProxyUrl
hillac Jan 18, 2024
4e21a20
Merge remote-tracking branch 'upstream/main' into main
hillac Mar 22, 2024
54856ff
change to latest config style
hillac Mar 22, 2024
49dff8b
change tests to vitest
hillac Mar 22, 2024
270dd13
create docs for fastify
hillac Mar 25, 2024
6ab3479
register @fastify/formbody in plugin
hillac Mar 26, 2024
32d647e
move formbody to dependencies
hillac Mar 27, 2024
825bdbd
Merge branch 'main' into auth-fastify
hillac May 12, 2024
4f89aaf
prettier format
hillac May 12, 2024
1ab4a57
configure new docs for fastify
hillac May 12, 2024
ed3a279
Merge branch 'main' into auth-fastify
hillac May 24, 2024
b49097d
docs: add fastify code tabs + add installation page code
hillac May 24, 2024
0ee816d
docs: add session managment docs
hillac May 24, 2024
eaaa907
docs: fix highlighting fastify docs
hillac May 24, 2024
5f458ff
docs: add api vs protecting note
hillac May 24, 2024
36497fd
Merge branch 'main' into auth-fastify
hillac Jun 19, 2024
8fd04e6
Merge branch 'main' into auth-fastify
Jul 11, 2024
b9583f6
Merge branch 'main' into main
ndom91 Jul 23, 2024
c88c12f
fix(docs): Code component for Fastify
ndom91 Jul 23, 2024
a17c080
chore: add fastify to turbo.json docs#build
ndom91 Jul 23, 2024
979e0b5
Merge branch 'main' into auth-fastify
Sep 29, 2024
87edcf5
lint + fix get session action url
Sep 29, 2024
3f68fee
update fastify + export config type
Sep 30, 2024
e4a355e
fix port not in hostname
Sep 30, 2024
9079f1f
fastify dev app
Sep 30, 2024
16af091
update pnpm lock + fix type
Sep 30, 2024
d171f75
feat: add fastify example
songkeys Sep 30, 2024
83d971b
fix for reviews
songkeys Oct 1, 2024
4a404b3
Merge pull request #1 from songkeys/main
hillac Oct 1, 2024
302eb31
remove unnecessary type from #1 + simplify type
Oct 1, 2024
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
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,10 @@ docs/docs/reference/solidstart
# Express
docs/docs/reference/express

# Fastify
docs/docs/reference/fastify



# Adapters
docs/docs/reference/adapter
Expand Down
3 changes: 3 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ packages/frameworks-sveltekit/vite.config.{js,ts}.timestamp-*
# @auth/express
packages/frameworks-express/providers

# @auth/fastify
packages/frameworks-fastify/providers

# next-auth
packages/next-auth/src/providers/oauth-types.ts
packages/next-auth/css/index.css
Expand Down
7 changes: 7 additions & 0 deletions docs/components/Code/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,14 @@ Code.NextClient = NextClientCode
Code.Svelte = SvelteCode
// Code.Solid = SolidCode;
Code.Express = ExpressCode
Code.Fastify = FastifyCode

const baseFrameworks = {
[NextCode.name]: "Next.js",
[SvelteCode.name]: "SvelteKit",
[ExpressCode.name]: "Express",
// [SolidCode.name]: "SolidStart",
[FastifyCode.name]: "Fastify",
}

const allFrameworks = {
Expand All @@ -28,6 +30,7 @@ const allFrameworks = {
[SvelteCode.name]: "SvelteKit",
// [SolidCode.name]: "SolidStart",
[ExpressCode.name]: "Express",
[FastifyCode.name]: "Fastify",
}

const findTabIndex = (frameworks: Record<string, string>, tab: string) => {
Expand Down Expand Up @@ -124,3 +127,7 @@ function SvelteCode({ children }: ChildrenProps) {
function ExpressCode({ children }: ChildrenProps) {
return <Tabs.Tab>{children}</Tabs.Tab>
}

function FastifyCode({ children }: ChildrenProps) {
return <Tabs.Tab>{children}</Tabs.Tab>
}
24 changes: 24 additions & 0 deletions docs/pages/getting-started/installation.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,13 @@ Start by installing the appropriate package for your framework.
```

</Code.Express>
<Code.Fastify>

```bash npm2yarn
npm install @auth/fastify
```

</Code.Fastify>
</Code>

<Callout type="info">
Expand Down Expand Up @@ -148,6 +155,23 @@ app.use("/auth/*", ExpressAuth({ providers: [] }))
Note this creates the Auth.js API, but does not yet protect resources. Continue on to [protecting resources](/getting-started/session-management/protecting) for more details.

</Code.Express>
<Code.Fastify>

1. Start by importing `FastifyAuth` registering it to your auth API route.

```ts filename="./src/routes/auth.route.ts" {1, 7}
import { FastifyAuth } from "@auth/fastify"
import Fastify from "fastify"

// If your app is served through a proxy
// trust the proxy to allow us to read the `X-Forwarded-*` headers
const fastify = Fastify({ trustProxy: true })
fastify.register(FastifyAuth({ providers: [] }), { prefix: "/auth" })
```

Note this creates the Auth.js API, but does not yet protect resources. Continue on to [protecting resources](/getting-started/session-management/protecting) for more details.

</Code.Fastify>
</Code>

### Setup Authentication Methods
Expand Down
1 change: 1 addition & 0 deletions docs/pages/getting-started/integrations.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ Here are the state of planned and released integrations under the `@auth/*` and
| `@auth/sveltekit` | Released (experimental) - [docs](https://sveltekit.authjs.dev) |
| `@auth/express` | Released (experimental) - [docs](https://express.authjs.dev) |
| `@auth/solid-start` | Released (experimental) |
| `@auth/fastify` | Released (experimental) - [docs](https://fastify.authjs.dev) |
| `@auth/remix` | Planned |
| `@auth/astro` | Planned |
| `@auth/nuxt` | Planned |
Expand Down
21 changes: 21 additions & 0 deletions docs/pages/getting-started/session-management/custom-pages.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,27 @@ app.use(
```

</Code.Express>
<Code.Fastify>

```ts filename="src/routes/auth.route.ts" {10-12}
import { FastifyAuth } from "@auth/fastify"
import Fastify from "fastify"
import GitHub from "@auth/fastify/providers/github"

const fastify = Fastify({ trustProxy: true })

fastify.register(
FastifyAuth({
providers: [GitHub],
pages: {
signIn: "/signin",
},
}),
{ prefix: "/auth" }
)
```

</Code.Fastify>
</Code>

To continue setting up the custom page, checkout our [guide on custom pages](/guides/pages/signin).
25 changes: 25 additions & 0 deletions docs/pages/getting-started/session-management/get-session.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,31 @@ app.get("/", (req, res) => {
```

</Code.Express>
<Code.Fastify>

```ts filename="app.ts"
import { getSession } from "@auth/fastify"

// Decorating the reply is not required but will optimise performance
// Only decorate the reply with a value type like null, as reference types like objects are shared among all requests, creating a security risk.
fastify.decorateReply("session", null)

export async function authSession(req: FastifyRequest, reply: FastifyReply) {
reply.session = await getSession(req, authConfig)
}

fastify.addHook("preHandler", authSession)

// Now in your route
fastify.get("/", (req, reply) => {
const session = reply.session
reply.view("index", { user: session?.user })
})
```

Note for TypeScript, you may want to augment the Fastify types to include the `session` property on the reply object.

</Code.Fastify>
</Code>

If you'd like to extend your session with more fields from your OAuth provider, for example, please check out our ["extending the session" guide](/guides/extending-the-session).
10 changes: 10 additions & 0 deletions docs/pages/getting-started/session-management/login.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,11 @@ Just like in other frameworks, you can also pass a provider to the `signIn` func
The Express package runs server-side and therefore it doesn't make sense to create a "SignIn button component". However, to signin or signout with Express, send a request to the appropriate [REST API Endpoints](/reference/core/types#authaction) from your client (i.e. `/auth/signin`, `/auth/signout`, etc.).

</Code.Express>
<Code.Fastify>

The Fastify package runs server-side and therefore it doesn't make sense to create a "SignIn button component". However, to signin or signout with Fastify, send a request to the appropriate [REST API Endpoints](/reference/core/types#authaction) from your client (i.e. `/auth/signin`, `/auth/signout`, etc.).

</Code.Fastify>
</Code>

You can also pass a provider to the `signIn` function which will attempt to login directly with that provider. Otherwise, when clicking this button in your application, the user will be redirected to the configured sign in page. If you did not setup a [custom sign in page](/guides/pages/signin), the user will be redirected to the default signin page at `/[basePath]/signin`.
Expand Down Expand Up @@ -281,6 +286,11 @@ Client-side is a bit simpler as we just need to import a button `on:click` handl
The Express package runs server-side and therefore it doesn't make sense to create a "SignIn button component". However, to signin or signout with Express, send a request to the appropriate [REST API Endpoints](/reference/core/types#authaction) from your client (i.e. `/auth/signin`, `/auth/signout`, etc.).

</Code.Express>
<Code.Fastify>

The Fastify package runs server-side and therefore it doesn't make sense to create a "SignIn button component". However, to signin or signout with Fastify, send a request to the appropriate [REST API Endpoints](/reference/core/types#authaction) from your client (i.e. `/auth/signin`, `/auth/signout`, etc.).

</Code.Fastify>
</Code>

<Callout>
Expand Down
64 changes: 64 additions & 0 deletions docs/pages/getting-started/session-management/protecting.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,65 @@ app.use("/", root)
```

</Code.Express>
<Code.Fastify>

You can protect routes by checking for the presence of a session and then redirect to a login page if the session is not present. This can either be done per route, or for a group of routes using a middleware such as the following:

```ts filename="lib.ts"
import { getSession } from "@auth/fastify"

export async function authenticatedUser(
req: FastifyRequest,
reply: FastifyReply
) {
reply.session ??= await getSession(req, authConfig)
if (!reply.session?.user) {
res.redirect("/login")
}
}
```

To protect a single route, simply register the preHandler hook to the route as follows:

```ts filename="app.ts"
import { authenticatedUser } from "./lib.ts"

// This route is protected
fastify.get("/profile", { preHandler: [authenticatedUser] }, (req, reply) => {
const session = reply.session
reply.view("profile", { user: session?.user })
})

// This route is not protected
fastify.get("/", (req, reply) => {
reply.view("index")
})
```

To protect a group of routes, create a plugin and register the authenication hook and routes to the instance as follows:

```ts filename="app.ts"
import { authenticatedUser } from "./lib.ts"

fastify.register(
async (instance) => {
// All routes on this instance will be protected because of the preHandler hook
instance.addHook("preHandler", authenticatedUser)

instance.get("/", (req, reply) => {
reply.view("protected")
})

// Example api route
instance.get("/me", (req, reply) => {
reply.send(reply.session?.user)
})
},
{ prefix: "/protected" }
)
```

</Code.Fastify>
</Code>

### API Routes
Expand Down Expand Up @@ -208,6 +267,11 @@ export const GET: RequestHandler = async (event) => {
API Routes are protected in the same way as any other route in Express, see [the examples above](/getting-started/session-management/protecting?framework=express#pages).

</Code.Express>
<Code.Fastify>

API Routes are protected in the same way as any other route in Fastify, see [the examples above](/getting-started/session-management/protecting?framework=fastify#pages).

</Code.Fastify>
</Code>

### Next.js Middleware
Expand Down
1 change: 1 addition & 0 deletions docs/pages/reference/_meta.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export default {
sveltekit: "@auth/sveltekit",
express: "@auth/express",
"solid-start": "@auth/solid-start",
fastify: "@auth/fastify",
warnings: "Warnings",
errors: {
title: "Errors",
Expand Down
5 changes: 5 additions & 0 deletions docs/vercel.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,11 @@
"has": [{ "type": "host", "value": "express.authjs.dev" }],
"destination": "https://authjs.dev/reference/express"
},
{
"source": "/",
"has": [{ "type": "host", "value": "fastify.authjs.dev" }],
"destination": "https://authjs.dev/reference/fastify"
},
{
"source": "/:path(.*)",
"has": [{ "type": "host", "value": "nextjs.authjs.dev" }],
Expand Down
24 changes: 24 additions & 0 deletions packages/frameworks-fastify/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<p align="center">
<br/>
<a href="https://authjs.dev" target="_blank"><img width="150px" src="https://authjs.dev/img/logo/logo-sm.png" /></a>
<h3 align="center">Fastify Auth</a></h3>
<h4 align="center">Authentication for Fastify.</h4>
<p align="center" style="align: center;">
<a href="https://npm.im/next-auth">
<img src="https://img.shields.io/badge/TypeScript-blue?style=flat-square" alt="TypeScript" />
</a>
<a href="https://npm.im/@auth/fastify">
<img alt="npm" src="https://img.shields.io/npm/v/@auth/fastify?color=green&label=@auth/fastify&style=flat-square">
</a>
<a href="https://www.npmtrends.com/@auth/fastify">
<img src="https://img.shields.io/npm/dm/@auth/fastify?label=%20downloads&style=flat-square" alt="Downloads" />
</a>
<a href="https://github.com/nextauthjs/next-auth/stargazers">
<img src="https://img.shields.io/github/stars/nextauthjs/next-auth?style=flat-square" alt="Github Stars" />
</a>
</p>
</p>F

---

Check out the documentation at [fastify.authjs.dev](https://fastify.authjs.dev).
62 changes: 62 additions & 0 deletions packages/frameworks-fastify/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
{
"name": "@auth/fastify",
"description": "Authentication for Fastify.",
"version": "0.0.1",
"type": "module",
"files": [
"*.js",
"*.d.ts*",
"lib",
"providers",
"src"
],
"exports": {
".": {
"types": "./index.d.ts",
"import": "./index.js"
},
"./providers": {
"types": "./providers/index.d.ts"
},
"./adapters": {
"types": "./adapters.d.ts"
},
"./providers/*": {
"types": "./providers/*.d.ts",
"import": "./providers/*.js"
},
"./package.json": "./package.json"
},
"scripts": {
"build": "pnpm clean && pnpm providers && tsc",
"clean": "rm -rf lib index.* src/lib/providers",
"test": "vitest run -c ../utils/vitest.config.ts",
"test:debug": "vitest --inspect --inspect-brk --pool threads --poolOptions.threads.singleThread run -c ../utils/vitest.config.ts",
"providers": "node ../utils/scripts/providers"
},
"publishConfig": {
"access": "public"
},
"dependencies": {
"@auth/core": "workspace:*",
"@fastify/formbody": "^7.4.0"
},
"devDependencies": {
"@auth/core": "workspace:experimental",
"fastify": "^4.25.2"
},
"peerDependencies": {
"fastify": "^4.25.2"
},
"keywords": [
"Fastify",
"Auth.js"
],
"author": "Lachie Hill <lachiehill46@gmail.com>",
"contributors": [
"Rexford Essilfie <rexfordessilfie09@gmail.com",
"Lachie Hill <lachiehill46@gmail.com>"
],
"repository": "https://github.com/nextauthjs/next-auth",
"license": "ISC"
}
1 change: 1 addition & 0 deletions packages/frameworks-fastify/src/adapters.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export type * from "@auth/core/adapters"

Check warning on line 1 in packages/frameworks-fastify/src/adapters.ts

View check run for this annotation

Codecov / codecov/patch

packages/frameworks-fastify/src/adapters.ts#L1

Added line #L1 was not covered by tests
Loading
Loading