From d171f75eefaa59a1613f760bc758d6e4ec2b97b3 Mon Sep 17 00:00:00 2001 From: Songkeys Date: Tue, 1 Oct 2024 02:39:42 +0800 Subject: [PATCH 1/2] feat: add fastify example --- apps/dev/fastify/.env.example | 7 + apps/dev/fastify/.gitignore | 21 +++ apps/dev/fastify/.prettierignore | 14 ++ apps/dev/fastify/README.md | 28 ++++ apps/dev/fastify/api/index.js | 3 + apps/dev/fastify/package.json | 34 +++++ apps/dev/fastify/public/css/style.css | 5 + apps/dev/fastify/src/app.ts | 81 +++++++++++ apps/dev/fastify/src/config/auth.config.ts | 69 +++++++++ apps/dev/fastify/src/errors.ts | 14 ++ .../fastify/src/middleware/auth.middleware.ts | 28 ++++ .../src/middleware/error.middleware.ts | 22 +++ apps/dev/fastify/src/server.ts | 18 +++ apps/dev/fastify/tsconfig.json | 16 +++ apps/dev/fastify/views/error.pug | 5 + apps/dev/fastify/views/index.pug | 11 ++ apps/dev/fastify/views/layout.pug | 34 +++++ apps/dev/fastify/views/protected.pug | 15 ++ apps/examples/fastify/package.json | 2 +- .../fastify/src/config/auth.config.ts | 123 ++++++++-------- docs/vercel.json | 2 +- package.json | 1 + packages/frameworks-fastify/src/index.ts | 29 ++-- pnpm-lock.yaml | 135 ++++++++++++++++++ 24 files changed, 637 insertions(+), 80 deletions(-) create mode 100644 apps/dev/fastify/.env.example create mode 100644 apps/dev/fastify/.gitignore create mode 100644 apps/dev/fastify/.prettierignore create mode 100644 apps/dev/fastify/README.md create mode 100644 apps/dev/fastify/api/index.js create mode 100644 apps/dev/fastify/package.json create mode 100644 apps/dev/fastify/public/css/style.css create mode 100644 apps/dev/fastify/src/app.ts create mode 100644 apps/dev/fastify/src/config/auth.config.ts create mode 100644 apps/dev/fastify/src/errors.ts create mode 100644 apps/dev/fastify/src/middleware/auth.middleware.ts create mode 100644 apps/dev/fastify/src/middleware/error.middleware.ts create mode 100644 apps/dev/fastify/src/server.ts create mode 100644 apps/dev/fastify/tsconfig.json create mode 100644 apps/dev/fastify/views/error.pug create mode 100644 apps/dev/fastify/views/index.pug create mode 100644 apps/dev/fastify/views/layout.pug create mode 100644 apps/dev/fastify/views/protected.pug diff --git a/apps/dev/fastify/.env.example b/apps/dev/fastify/.env.example new file mode 100644 index 0000000000..6959cc6e03 --- /dev/null +++ b/apps/dev/fastify/.env.example @@ -0,0 +1,7 @@ +AUTH_SECRET= + +AUTH_GITHUB_ID= +AUTH_GITHUB_SECRET= + +AUTH_GOOGLE_ID= +AUTH_GOOGLE_SECRET= \ No newline at end of file diff --git a/apps/dev/fastify/.gitignore b/apps/dev/fastify/.gitignore new file mode 100644 index 0000000000..01fd4ed6db --- /dev/null +++ b/apps/dev/fastify/.gitignore @@ -0,0 +1,21 @@ +# API keys and secrets +.env + +# Dependency directory +node_modules + +# Editors +.idea +*.iml +.vscode/settings.json + +# OS metadata +.DS_Store +Thumbs.db + +# Ignore built ts files +dist/**/* + +# Ignore built css files +/public/css/output.css + diff --git a/apps/dev/fastify/.prettierignore b/apps/dev/fastify/.prettierignore new file mode 100644 index 0000000000..f97e266fdd --- /dev/null +++ b/apps/dev/fastify/.prettierignore @@ -0,0 +1,14 @@ + +.DS_Store +node_modules +/dist +/.turbo +/package +.env +.env.* +!.env.example + +# Ignore files for PNPM, NPM and YARN +pnpm-lock.yaml +package-lock.json +yarn.lock diff --git a/apps/dev/fastify/README.md b/apps/dev/fastify/README.md new file mode 100644 index 0000000000..b8124cc9f9 --- /dev/null +++ b/apps/dev/fastify/README.md @@ -0,0 +1,28 @@ +> The example repository is maintained from a [monorepo](https://github.com/nextauthjs/next-auth/tree/main/apps/examples/fastify). Pull Requests should be opened against [`nextauthjs/next-auth`](https://github.com/nextauthjs/next-auth). + +
+ Open Source. Full Stack. Own Your Data. +
+ + + +# Documentation + +- [fastify.authjs.dev](https://fastify.authjs.dev) diff --git a/apps/dev/fastify/api/index.js b/apps/dev/fastify/api/index.js new file mode 100644 index 0000000000..37795e6772 --- /dev/null +++ b/apps/dev/fastify/api/index.js @@ -0,0 +1,3 @@ +import { app } from "../src/app.js" + +export default app diff --git a/apps/dev/fastify/package.json b/apps/dev/fastify/package.json new file mode 100644 index 0000000000..1c27aba00e --- /dev/null +++ b/apps/dev/fastify/package.json @@ -0,0 +1,34 @@ +{ + "name": "fastify-auth-app", + "description": "Fastify + Auth.js Developer app", + "type": "module", + "private": true, + "scripts": { + "start": "node dist/server.js", + "clean": "rm -rf dist", + "build": "pnpm build:ts && pnpm build:css", + "build:ts": "tsc", + "build:css": "tailwindcss -i ./public/css/style.css -o ./public/css/output.css", + "dev": "tsx watch --env-file=.env src/server.ts & pnpm build:css -w", + "debug": "tsx watch --inspect --env-file=.env src/server.ts & pnpm build:css -w", + "lint": "eslint src/*.ts --fix", + "prettier": "prettier src/*.ts --write" + }, + "author": "Songkeys (https://github.com/songkeys)", + "license": "MIT", + "dependencies": { + "@auth/fastify": "workspace:*", + "fastify": "^5.0.0", + "@fastify/view": "^10.0.1", + "@fastify/static": "^8.0.1", + "pug": "^3.0.2", + "tailwindcss": "^3.4.3" + }, + "devDependencies": { + "@prettier/plugin-pug": "^3.0.0", + "@types/morgan": "^1.9.9", + "@types/pug": "^2.0.10", + "tsx": "^4.7.3", + "typescript": "5.4.5" + } +} diff --git a/apps/dev/fastify/public/css/style.css b/apps/dev/fastify/public/css/style.css new file mode 100644 index 0000000000..7f393742af --- /dev/null +++ b/apps/dev/fastify/public/css/style.css @@ -0,0 +1,5 @@ +@tailwind base; + +@tailwind components; + +@tailwind utilities; diff --git a/apps/dev/fastify/src/app.ts b/apps/dev/fastify/src/app.ts new file mode 100644 index 0000000000..c46f53bdbe --- /dev/null +++ b/apps/dev/fastify/src/app.ts @@ -0,0 +1,81 @@ +import Fastify from "fastify" + +import * as path from "node:path" +import { + errorHandler, + errorNotFoundHandler, +} from "./middleware/error.middleware.js" +import { + authenticatedApi, + authenticatedPage, + currentSession, +} from "./middleware/auth.middleware.js" + +import { FastifyAuth } from "@auth/fastify" +import { authConfig } from "./config/auth.config.js" + +import * as pug from "pug" +import fastifyView from "@fastify/view" +import fastifyStatic from "@fastify/static" + +// Trust Proxy for Proxies (Heroku, Render.com, Docker behind Nginx, etc) +export const fastify = Fastify({ trustProxy: true, logger: true }) + +// 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) + +fastify.register(fastifyView, { + engine: { + pug, + }, + root: path.join(import.meta.dirname, "..", "views"), +}) + +// Serve static files +// NB: Uncomment this out if you want Fastify to serve static files for you vs. using a +// hosting provider which does so for you (for example through a CDN). +fastify.register(fastifyStatic, { + root: path.join(import.meta.dirname, "..", "public"), +}) + +// Set session in reply +fastify.addHook("preHandler", currentSession) + +// Set up FastifyAuth to handle authentication +// IMPORTANT: It is highly encouraged set up rate limiting on this route +fastify.register(FastifyAuth(authConfig), { prefix: "/api/auth" }) + +// Routes +fastify.get( + "/protected", + { preHandler: [authenticatedPage] }, + async (req, reply) => { + return reply.view("protected", { session: reply.session }) + } +) + +fastify.get( + "/api/protected", + { preHandler: [authenticatedApi] }, + async (req, reply) => { + return reply.send(reply.session) + } +) + +fastify.get("/", async (_req, reply) => { + return reply.view("index", { + title: "Fastify Auth Example", + user: reply.session?.user, + }) +}) + +fastify.get("/2", async (_req, reply) => { + return reply.view("index", { + title: "Fastify Auth Example", + user: reply.session?.user, + }) +}) + +fastify.setErrorHandler(errorHandler) +fastify.setNotFoundHandler(errorNotFoundHandler) diff --git a/apps/dev/fastify/src/config/auth.config.ts b/apps/dev/fastify/src/config/auth.config.ts new file mode 100644 index 0000000000..a85bb2d1f7 --- /dev/null +++ b/apps/dev/fastify/src/config/auth.config.ts @@ -0,0 +1,69 @@ +import Apple from "@auth/express/providers/apple" +import Auth0 from "@auth/express/providers/auth0" +import AzureB2C from "@auth/express/providers/azure-ad-b2c" +import BoxyHQSAML from "@auth/express/providers/boxyhq-saml" +import Cognito from "@auth/express/providers/cognito" +import Coinbase from "@auth/express/providers/coinbase" +import Discord from "@auth/express/providers/discord" +import Dropbox from "@auth/express/providers/dropbox" +import Facebook from "@auth/express/providers/facebook" +import GitHub from "@auth/express/providers/github" +import Gitlab from "@auth/express/providers/gitlab" +import Google from "@auth/express/providers/google" +import Hubspot from "@auth/express/providers/hubspot" +import Keycloak from "@auth/express/providers/keycloak" +import LinkedIn from "@auth/express/providers/linkedin" +import Netlify from "@auth/express/providers/netlify" +import Okta from "@auth/express/providers/okta" +import Passage from "@auth/express/providers/passage" +import Pinterest from "@auth/express/providers/pinterest" +import Reddit from "@auth/express/providers/reddit" +import Slack from "@auth/express/providers/slack" +import Spotify from "@auth/express/providers/spotify" +import Twitch from "@auth/express/providers/twitch" +import Twitter from "@auth/express/providers/twitter" +import WorkOS from "@auth/express/providers/workos" +import Zoom from "@auth/express/providers/zoom" + +export const authConfig = { + trustHost: true, + debug: process.env.NODE_ENV !== "production" ? true : false, + providers: [ + Apple, + Auth0, + AzureB2C({ + clientId: process.env.AUTH_AZURE_AD_B2C_ID, + clientSecret: process.env.AUTH_AZURE_AD_B2C_SECRET, + issuer: process.env.AUTH_AZURE_AD_B2C_ISSUER, + }), + BoxyHQSAML({ + clientId: "dummy", + clientSecret: "dummy", + issuer: process.env.AUTH_BOXYHQ_SAML_ISSUER, + }), + Cognito, + Coinbase, + Discord, + Dropbox, + Facebook, + GitHub, + Gitlab, + Google, + Hubspot, + Keycloak, + LinkedIn, + Netlify, + Okta, + Passage, + Pinterest, + Reddit, + Slack, + Spotify, + Twitch, + Twitter, + WorkOS({ + connection: process.env.AUTH_WORKOS_CONNECTION!, + }), + Zoom, + ], +} diff --git a/apps/dev/fastify/src/errors.ts b/apps/dev/fastify/src/errors.ts new file mode 100644 index 0000000000..43853cfe84 --- /dev/null +++ b/apps/dev/fastify/src/errors.ts @@ -0,0 +1,14 @@ +export class HttpError extends Error { + status: number + constructor(status: number, message: string) { + super(message) + this.status = status + } +} + +export class NotFoundError extends HttpError { + constructor(message: string, status = 404) { + super(status, message) + this.name = "NotFoundError" + } +} diff --git a/apps/dev/fastify/src/middleware/auth.middleware.ts b/apps/dev/fastify/src/middleware/auth.middleware.ts new file mode 100644 index 0000000000..498cf82012 --- /dev/null +++ b/apps/dev/fastify/src/middleware/auth.middleware.ts @@ -0,0 +1,28 @@ +//// @ts-nocheck +import { getSession } from "@auth/fastify" +import { authConfig } from "../config/auth.config.js" +import { FastifyReply, FastifyRequest } from "fastify" + +export async function authenticatedApi( + req: FastifyRequest, + reply: FastifyReply +) { + reply.session ??= (await getSession(req, authConfig)) ?? null + if (!reply.session) { + reply.status(401).send({ message: "Not Authenticated" }) + } +} + +export async function authenticatedPage( + req: FastifyRequest, + reply: FastifyReply +) { + reply.session ??= (await getSession(req, authConfig)) ?? null + if (!reply.session) { + return reply.view("unauthenticated") + } +} + +export async function currentSession(req: FastifyRequest, reply: FastifyReply) { + reply.session = (await getSession(req, authConfig)) ?? null +} diff --git a/apps/dev/fastify/src/middleware/error.middleware.ts b/apps/dev/fastify/src/middleware/error.middleware.ts new file mode 100644 index 0000000000..701e77ffd2 --- /dev/null +++ b/apps/dev/fastify/src/middleware/error.middleware.ts @@ -0,0 +1,22 @@ +//// @ts-nocheck +import { HttpError, NotFoundError } from "../errors.js" +import { FastifyReply, FastifyRequest } from "fastify" + +export const errorHandler = ( + err: HttpError | Error, + _req: FastifyRequest, + _reply: FastifyReply +): void => { + const statusCode = (err instanceof HttpError && err.status) || 500 + _reply.status(statusCode).view("error", { + title: err instanceof HttpError ? err.status : err.name, + message: err.message, + }) +} + +export const errorNotFoundHandler = ( + _req: FastifyRequest, + _reply: FastifyReply +): void => { + new NotFoundError("Not Found") +} diff --git a/apps/dev/fastify/src/server.ts b/apps/dev/fastify/src/server.ts new file mode 100644 index 0000000000..1e0a75062c --- /dev/null +++ b/apps/dev/fastify/src/server.ts @@ -0,0 +1,18 @@ +const { fastify } = await import("./app.js") + +// const address = fastify.server.address() +// const port = (typeof address === "object" && address?.port) || 3000 + +const port = Number(process.env.PORT) || 3000 + +const start = async () => { + try { + await fastify.listen({ port }) + fastify.log.info(`server listening on ${fastify.server.address()}`) + } catch (err) { + fastify.log.error(err) + process.exit(1) + } +} + +start() diff --git a/apps/dev/fastify/tsconfig.json b/apps/dev/fastify/tsconfig.json new file mode 100644 index 0000000000..6b8858be5f --- /dev/null +++ b/apps/dev/fastify/tsconfig.json @@ -0,0 +1,16 @@ +{ + "compilerOptions": { + "module": "NodeNext", + "esModuleInterop": true, + "target": "esnext", + "noImplicitAny": true, + "moduleResolution": "NodeNext", + "sourceMap": true, + "outDir": "dist", + "baseUrl": ".", + "skipLibCheck": true, + "strict": true + }, + "include": ["src/**/*.ts"], + "exclude": ["node_modules"] +} diff --git a/apps/dev/fastify/views/error.pug b/apps/dev/fastify/views/error.pug new file mode 100644 index 0000000000..4d62885b53 --- /dev/null +++ b/apps/dev/fastify/views/error.pug @@ -0,0 +1,5 @@ +extends layout + +block content + h1=title + p=message diff --git a/apps/dev/fastify/views/index.pug b/apps/dev/fastify/views/index.pug new file mode 100644 index 0000000000..46708a98ee --- /dev/null +++ b/apps/dev/fastify/views/index.pug @@ -0,0 +1,11 @@ +extends layout + +block content + h1=title + p + | This is an example site to demonstrate how to use #{ ' ' } + a(href="https://expressjs.com/") Express + | #{ ' ' } with #{ ' ' } + a(href="https://authjs.dev/reference/express") Express Auth + | + | for authentication. diff --git a/apps/dev/fastify/views/layout.pug b/apps/dev/fastify/views/layout.pug new file mode 100644 index 0000000000..ed1bf74915 --- /dev/null +++ b/apps/dev/fastify/views/layout.pug @@ -0,0 +1,34 @@ +doctype html +html + head + title=title + meta(name="viewport" content="width=device-width, initial-scale=1.0") + body + div + div + if session + div + if session.user.image + img(src=`${session.user.image}` style="width:64px;border-radius:50%;") + span + | Signed in as #{ ' ' } + strong= session.user.email || session.user.name + a( + href="/api/auth/signout" + ) Sign out + else + span You are not signed in #{ ' ' } + a#sign-indiv( + href="/api/auth/signin" + ) Sign in + + nav + ul + li + a(href="/") Home + li + a(href="/protected") Protected + li + a(href="/api/protected") Protected (API) + + block content diff --git a/apps/dev/fastify/views/protected.pug b/apps/dev/fastify/views/protected.pug new file mode 100644 index 0000000000..97790e3b32 --- /dev/null +++ b/apps/dev/fastify/views/protected.pug @@ -0,0 +1,15 @@ +extends layout + +block content + if session + h1 Protected page + p + | This is a protected content. You can access this content because you are + | signed in. + p Session expiry: #{ session.expires ? session.expires : '' } + else + h1 Access Denied + p + | You must be #{ ' ' } + a(href="/api/auth/signin") signed in + | #{ ' ' } to view this page diff --git a/apps/examples/fastify/package.json b/apps/examples/fastify/package.json index 7195a07718..905e542a7f 100644 --- a/apps/examples/fastify/package.json +++ b/apps/examples/fastify/package.json @@ -32,4 +32,4 @@ "tsx": "^4.7.0", "typescript": "5.3.3" } -} \ No newline at end of file +} diff --git a/apps/examples/fastify/src/config/auth.config.ts b/apps/examples/fastify/src/config/auth.config.ts index db4708f04c..a85bb2d1f7 100644 --- a/apps/examples/fastify/src/config/auth.config.ts +++ b/apps/examples/fastify/src/config/auth.config.ts @@ -1,68 +1,69 @@ -import Apple from "@auth/fastify/providers/apple" -import Auth0 from "@auth/fastify/providers/auth0" -import AzureB2C from "@auth/fastify/providers/azure-ad-b2c" -import BoxyHQSAML from "@auth/fastify/providers/boxyhq-saml" -import Cognito from "@auth/fastify/providers/cognito" -import Coinbase from "@auth/fastify/providers/coinbase" -import Discord from "@auth/fastify/providers/discord" -import Dropbox from "@auth/fastify/providers/dropbox" -import Facebook from "@auth/fastify/providers/facebook" -import GitHub from "@auth/fastify/providers/github" -import GitLab from "@auth/fastify/providers/gitlab" -import Google from "@auth/fastify/providers/google" -import Hubspot from "@auth/fastify/providers/hubspot" -import Keycloak from "@auth/fastify/providers/keycloak" -import LinkedIn from "@auth/fastify/providers/linkedin" -import Netlify from "@auth/fastify/providers/netlify" -import Okta from "@auth/fastify/providers/okta" -import Passage from "@auth/fastify/providers/passage" -import Pinterest from "@auth/fastify/providers/pinterest" -import Reddit from "@auth/fastify/providers/reddit" -import Slack from "@auth/fastify/providers/slack" -import Spotify from "@auth/fastify/providers/spotify" -import Twitch from "@auth/fastify/providers/twitch" -import Twitter from "@auth/fastify/providers/twitter" -import WorkOS from "@auth/fastify/providers/workos" -import Zoom from "@auth/fastify/providers/zoom" +import Apple from "@auth/express/providers/apple" +import Auth0 from "@auth/express/providers/auth0" +import AzureB2C from "@auth/express/providers/azure-ad-b2c" +import BoxyHQSAML from "@auth/express/providers/boxyhq-saml" +import Cognito from "@auth/express/providers/cognito" +import Coinbase from "@auth/express/providers/coinbase" +import Discord from "@auth/express/providers/discord" +import Dropbox from "@auth/express/providers/dropbox" +import Facebook from "@auth/express/providers/facebook" +import GitHub from "@auth/express/providers/github" +import Gitlab from "@auth/express/providers/gitlab" +import Google from "@auth/express/providers/google" +import Hubspot from "@auth/express/providers/hubspot" +import Keycloak from "@auth/express/providers/keycloak" +import LinkedIn from "@auth/express/providers/linkedin" +import Netlify from "@auth/express/providers/netlify" +import Okta from "@auth/express/providers/okta" +import Passage from "@auth/express/providers/passage" +import Pinterest from "@auth/express/providers/pinterest" +import Reddit from "@auth/express/providers/reddit" +import Slack from "@auth/express/providers/slack" +import Spotify from "@auth/express/providers/spotify" +import Twitch from "@auth/express/providers/twitch" +import Twitter from "@auth/express/providers/twitter" +import WorkOS from "@auth/express/providers/workos" +import Zoom from "@auth/express/providers/zoom" export const authConfig = { trustHost: true, + debug: process.env.NODE_ENV !== "production" ? true : false, providers: [ - // Apple, - // Auth0, - // AzureB2C({ - // clientId: process.env.AUTH_AZURE_AD_B2C_ID, - // clientSecret: process.env.AUTH_AZURE_AD_B2C_SECRET, - // issuer: process.env.AUTH_AZURE_AD_B2C_ISSUER, - // }), - // BoxyHQSAML({ - // clientId: "dummy", - // clientSecret: "dummy", - // issuer: process.env.AUTH_BOXYHQ_SAML_ISSUER, - // }), - // Cognito, - // Coinbase, - // Discord, - // Dropbox, - // Facebook, - // GitHub, - // GitLab, + Apple, + Auth0, + AzureB2C({ + clientId: process.env.AUTH_AZURE_AD_B2C_ID, + clientSecret: process.env.AUTH_AZURE_AD_B2C_SECRET, + issuer: process.env.AUTH_AZURE_AD_B2C_ISSUER, + }), + BoxyHQSAML({ + clientId: "dummy", + clientSecret: "dummy", + issuer: process.env.AUTH_BOXYHQ_SAML_ISSUER, + }), + Cognito, + Coinbase, + Discord, + Dropbox, + Facebook, + GitHub, + Gitlab, Google, - // Hubspot, - // Keycloak, - // LinkedIn, - // Netlify, - // Okta, - // Passage, - // Pinterest, - // Reddit, - // Slack, - // Spotify, - // Twitch, - // Twitter, - // WorkOS({ - // connection: process.env.AUTH_WORKOS_CONNECTION!, - // }), - // Zoom, + Hubspot, + Keycloak, + LinkedIn, + Netlify, + Okta, + Passage, + Pinterest, + Reddit, + Slack, + Spotify, + Twitch, + Twitter, + WorkOS({ + connection: process.env.AUTH_WORKOS_CONNECTION!, + }), + Zoom, ], } diff --git a/docs/vercel.json b/docs/vercel.json index 8097bc349c..76fd1c16dd 100644 --- a/docs/vercel.json +++ b/docs/vercel.json @@ -30,4 +30,4 @@ "schedule": "42 */2 * * *" } ] -} \ No newline at end of file +} diff --git a/package.json b/package.json index 4a1cebe2c3..768801c0c8 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,7 @@ "dev:sveltekit": "turbo run dev --parallel --continue --filter=sveltekit-auth-app...", "dev:express": "turbo run dev --parallel --continue --filter=express-auth-app...", "dev:qwik": "turbo run dev --parallel --continue --filter=qwik-auth-app...", + "dev:fastify": "turbo run dev --parallel --continue --filter=fastify-auth-app...", "dev:docs": "turbo run dev --filter=docs", "email": "fake-smtp-server", "lint": "eslint --cache .", diff --git a/packages/frameworks-fastify/src/index.ts b/packages/frameworks-fastify/src/index.ts index 74cba331d9..bb504718cf 100644 --- a/packages/frameworks-fastify/src/index.ts +++ b/packages/frameworks-fastify/src/index.ts @@ -45,7 +45,7 @@ * * ```ts title="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) @@ -62,18 +62,7 @@ * reply.view("index.pug", { user: session?.user }) * }) * ``` - * - * Note for TypeScript, you may want to augment the Fastify types to include the `session` property on the reply object. This can be done by creating a @types/fastify/index.d.ts file: - * - * ```ts title="@types/fastify/index.d.ts" - * import { Session } from "@auth/core/types"; - * declare module "fastify" { - * interface FastifyReply { - * session: Session | null; - * } - * } - * ``` - * + * * You may need to add `"typeRoots": ["@types"]` to `compilerOptions` in your tsconfig.json. * * ## Authorization @@ -99,13 +88,13 @@ * const session = reply.session; * reply.view("profile.pug", { user: session?.user }) * }); - * + * * // This route is not protected * fastify.get("/", (req, reply) => { * reply.view("index"); * }); * ``` - * + * * ### Per Group of Routes * To protect a group of routes, create a plugin and register the authenication hook and routes to the instance as follows: * @@ -114,11 +103,11 @@ * 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.pug") * }) - * + * * instance.get("/me", (req, reply) => { * reply.send(reply.session?.user) * }) @@ -141,6 +130,12 @@ import type { FastifyRequest, FastifyPluginAsync } from "fastify" import formbody from "@fastify/formbody" import { toWebRequest, toFastifyReply } from "./lib/index.js" +declare module "fastify" { + interface FastifyReply { + session: Session | null + } +} + export type FastifyAuthConfig = Omit