From 98402835c29dff9930df9b04c87dfa55c7fe4752 Mon Sep 17 00:00:00 2001 From: Bereket Engida <86073083+Bekacru@users.noreply.github.com> Date: Sun, 29 Sep 2024 20:00:47 +0300 Subject: [PATCH] feat: Database adapters (#29) * feat: prisma adapter * feat: drizzle adapter * feat: mongod db adapter --- .github/workflows/ci.yml | 15 +- dev/express/tsconfig.json | 34 +-- docker-compose.yml | 40 +++ docs/components/mdx/database-tables.tsx | 75 ++++++ docs/content/docs/concepts/database.mdx | 140 ++++++++-- docs/content/docs/concepts/rate-limit.mdx | 30 +++ docs/content/docs/installation.mdx | 39 ++- docs/content/docs/integrations/astro.mdx | 57 +--- docs/content/docs/integrations/hono.mdx | 47 +--- docs/content/docs/integrations/next.mdx | 54 +--- docs/content/docs/integrations/node.mdx | 71 +---- docs/content/docs/integrations/nuxt.mdx | 44 +-- .../content/docs/integrations/solid-start.mdx | 49 +--- docs/content/docs/integrations/svelte-kit.mdx | 51 +--- docs/content/docs/plugins/2fa.mdx | 10 +- docs/content/docs/plugins/organization.mdx | 130 ++++++++- docs/content/docs/plugins/passkey.mdx | 64 +++++ docs/content/docs/plugins/rate-limit.mdx | 212 --------------- docs/content/docs/plugins/username.mdx | 15 ++ docs/mdx-components.tsx | 2 + packages/better-auth/package.json | 7 +- .../src/adapters/drizzzle-adapter/index.ts | 119 ++++++++ .../test/adapter.dirzzle.test.ts | 43 +++ .../adapters/drizzzle-adapter/test/schema.ts | 20 ++ packages/better-auth/src/adapters/index.ts | 1 + .../mongodb-adpter/adapter.mongo-db.test.ts | 29 ++ .../src/adapters/mongodb-adpter/index.ts | 133 +++++++++ .../prisma-adapter/adapter.prisma.test.ts | 20 ++ .../src/adapters/prisma-adapter/client.ts | 4 + .../src/adapters/prisma-adapter/index.ts | 111 ++++++++ .../src/adapters/prisma-adapter/schema.prisma | 17 ++ packages/better-auth/src/adapters/test.ts | 123 +++++++++ .../better-auth/src/db/internal-adapter.ts | 19 +- packages/better-auth/src/db/kysely.ts | 6 +- packages/better-auth/src/db/utils.ts | 5 + packages/better-auth/src/init.ts | 8 +- .../better-auth/src/plugins/admin/index.ts | 37 +++ packages/better-auth/src/types/options.ts | 4 +- pnpm-lock.yaml | 254 ++++++++++++++---- 39 files changed, 1424 insertions(+), 715 deletions(-) create mode 100644 docker-compose.yml create mode 100644 docs/components/mdx/database-tables.tsx delete mode 100644 docs/content/docs/plugins/rate-limit.mdx create mode 100644 packages/better-auth/src/adapters/drizzzle-adapter/index.ts create mode 100644 packages/better-auth/src/adapters/drizzzle-adapter/test/adapter.dirzzle.test.ts create mode 100644 packages/better-auth/src/adapters/drizzzle-adapter/test/schema.ts create mode 100644 packages/better-auth/src/adapters/index.ts create mode 100644 packages/better-auth/src/adapters/mongodb-adpter/adapter.mongo-db.test.ts create mode 100644 packages/better-auth/src/adapters/mongodb-adpter/index.ts create mode 100644 packages/better-auth/src/adapters/prisma-adapter/adapter.prisma.test.ts create mode 100644 packages/better-auth/src/adapters/prisma-adapter/client.ts create mode 100644 packages/better-auth/src/adapters/prisma-adapter/index.ts create mode 100644 packages/better-auth/src/adapters/prisma-adapter/schema.prisma create mode 100644 packages/better-auth/src/adapters/test.ts create mode 100644 packages/better-auth/src/plugins/admin/index.ts diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7c0ccf52..b0e22438 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -29,11 +29,20 @@ jobs: - name: Build run: pnpm build - - name: lint + - name: Start Docker Containers + run: | + docker compose up -d + # Wait for services to be ready (optional) + sleep 10 + + - name: Lint run: pnpm lint - - name: test + - name: Test run: pnpm test - - name: typecheck + - name: Typecheck run: pnpm typecheck + + - name: Stop Docker Containers + run: docker compose down diff --git a/dev/express/tsconfig.json b/dev/express/tsconfig.json index ffc08abf..e0abf845 100644 --- a/dev/express/tsconfig.json +++ b/dev/express/tsconfig.json @@ -1,27 +1,17 @@ { "compilerOptions": { - // Enable latest features - "lib": ["ESNext", "DOM"], - "target": "ESNext", - "module": "ESNext", - "moduleDetection": "force", - "jsx": "react-jsx", - "allowJs": true, - - // Bundler mode - "moduleResolution": "bundler", - "allowImportingTsExtensions": true, - "verbatimModuleSyntax": true, - "noEmit": true, - - // Best practices - "strict": true, + "esModuleInterop": true, "skipLibCheck": true, - "noFallthroughCasesInSwitch": true, - - // Some stricter flags (disabled by default) - "noUnusedLocals": false, - "noUnusedParameters": false, - "noPropertyAccessFromIndexSignature": false + "target": "es2022", + "allowJs": true, + "resolveJsonModule": true, + "moduleDetection": "force", + "isolatedModules": true, + "verbatimModuleSyntax": true, + "strict": true, + "moduleResolution": "Bundler", + "outDir": "dist", + "sourceMap": true, + "lib": ["es2022"] } } diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 00000000..4114a658 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,40 @@ +version: '3.8' + +services: + mongodb: + image: mongo:latest + container_name: mongodb + ports: + - "27017:27017" + volumes: + - mongodb_data:/data/db + + postgres: + image: postgres:latest + container_name: postgres + environment: + POSTGRES_USER: user + POSTGRES_PASSWORD: password + POSTGRES_DB: better_auth + ports: + - "5432:5432" + volumes: + - postgres_data:/var/lib/postgresql/data + + mysql: + image: mysql:latest + container_name: mysql + environment: + MYSQL_ROOT_PASSWORD: root_password + MYSQL_DATABASE: better_auth + MYSQL_USER: user + MYSQL_PASSWORD: password + ports: + - "3306:3306" + volumes: + - mysql_data:/var/lib/mysql + +volumes: + mongodb_data: + postgres_data: + mysql_data: \ No newline at end of file diff --git a/docs/components/mdx/database-tables.tsx b/docs/components/mdx/database-tables.tsx new file mode 100644 index 00000000..9b8b844b --- /dev/null +++ b/docs/components/mdx/database-tables.tsx @@ -0,0 +1,75 @@ +import { Card, CardContent } from "@/components/ui/card"; +import { + Table, + TableBody, + TableCell, + TableHead, + TableHeader, + TableRow, +} from "@/components/ui/table"; +import { Badge } from "@/components/ui/badge"; +import { Key, Link } from "lucide-react"; +import { Label } from "../ui/label"; + +interface Field { + name: string; + type: string; + description: string; + isPrimaryKey?: boolean; + isForeignKey?: boolean; +} + +interface DatabaseTableProps { + fields: Field[]; +} + +export default function DatabaseTable({ fields }: DatabaseTableProps) { + return ( +
+ + + + Field Name + Type + Key + Description + + + + {fields.map((field, index) => ( + + {field.name} + + {field.type} + + + {field.isPrimaryKey && ( + + + PK + + )} + {field.isForeignKey && ( + + + FK + + )} + {!field.isPrimaryKey && !field.isForeignKey && ( + - + )} + + {field.description} + + ))} + +
+
+ ); +} diff --git a/docs/content/docs/concepts/database.mdx b/docs/content/docs/concepts/database.mdx index 49222da3..22e1e7ed 100644 --- a/docs/content/docs/concepts/database.mdx +++ b/docs/content/docs/concepts/database.mdx @@ -74,31 +74,129 @@ If you prefer adding tables manually, you can do that as well. The core schema r ## Core Schema -Better auth requires the following tables to be present in the database: +Better auth requires the following tables to be present in the database. The types are in `typescript` format. You can use corresponding types in your database. -**user**: +### User -- `id`: (string) - The unique identifier of the user. -- `email`: (string) - The email address of the user. -- `name`: (string) - The name of the user. -- `image`: (string) - The image of the user. (optional) + Table Name: `user` -**session**: -- `id`: (string) - The unique identifier of the session. Also used as the session token. -- `userId`: (foregin-key: `user.id`) - The id of the user. -- `expiresAt`: (Date) - The time when the session expires. -- `ipAddress`: (string) - The IP address of the device. (optional) -- `userAgent`: (string) - The user agent information of the device. (optional) + -**account**: -- `id`: (string) - The unique identifier of the account. -- `userId`: (foregin-key: `user.id`) - The id of the user. -- `accountId`: (string) - The id of the account. (optional) -- `providerId`: (string) - The id of the provider. (optional) -- `accessToken`: (string) - The access token of the account. Returned by the provider. (optional) -- `refreshToken`: (string) - The refresh token of the account. Returned by the provider. (optional) -- `expiresAt`: (Date) - The time when the access token expires. (optional) -- `password`: (string) - The password of the account. Mainly used for email and password authentication. (optional) +### Session + +Table Name: `session` + + + +### Account + +Table Name: `account` + + ## Plugins Schema diff --git a/docs/content/docs/concepts/rate-limit.mdx b/docs/content/docs/concepts/rate-limit.mdx index 3213af9f..526bafcb 100644 --- a/docs/content/docs/concepts/rate-limit.mdx +++ b/docs/content/docs/concepts/rate-limit.mdx @@ -141,3 +141,33 @@ await client.signIn.email({ }) ``` +### Schema + +If you are using a database to store rate limit data you need this schema: + +Table Name: `rateLimit` + + \ No newline at end of file diff --git a/docs/content/docs/installation.mdx b/docs/content/docs/installation.mdx index 388130de..bd34cbc3 100644 --- a/docs/content/docs/installation.mdx +++ b/docs/content/docs/installation.mdx @@ -67,8 +67,7 @@ export const auth = betterAuth({ ### Configure Database -Better Auth requires a database to store user data. It uses Kysely under the hood to connect to your database. -`postgresql`, `mysql`, and `sqlite` are supported out of the box. +Better Auth requires a database to store user data. By default, it uses Kysely under the hood to connect and query your database. `postgresql`, `mysql`, and `sqlite` are supported out of the box. ```ts title="auth.ts" import { betterAuth } from "better-auth" @@ -96,8 +95,32 @@ export const auth = betterAuth({ }); ``` +**Adapters** + +If your database is not supported by Kysely, you can use an adapter to connect to your database. + +To use an adapter, import the adapter and pass it to the database option. + +Currently, 3 adapters are supported: +- **Prisma** +- **Drizzle** +- **MongoDB** + +```ts title="auth.ts" +import { prismaAdapter } from "better-auth/adapters"; // [!code highlight] +import { PrismaClient } from "@prisma/client"; + +const prisma = new PrismaClient(); + +export const auth = betterAuth({ + database: { + provider: prismaAdapter(prisma), // [!code highlight] + } +}) +``` + - Currently, Better Auth only support databases that are supported by Kysely. [vote this issue if you like to see non sql db support](https://github.com/better-auth/better-auth/issues/5) +We highly recommend using the built-in option if your database is supported by Kysely, as we use optimized queries for Kysely. @@ -105,16 +128,14 @@ export const auth = betterAuth({ ### Migrate Schema Better Auth includes a CLI tool to migrate the required schema to your database. It introspects the database and creates the required tables. Run the following command to perform the migration: + ```bash title="Terminal" npx better-auth migrate ``` - Better Auth automatically sets up the following tables in your database if they don't already exist: - - `user` - - `session` - - `account` - - For more details head over to [schema](/docs/concepts/database#core-schema) section. + + If you're using an adapter and your database is not supported by Kysely, you need to create required tables manually. You can find the core schema required in the [database section](/docs/concepts/database#core-schema). + diff --git a/docs/content/docs/integrations/astro.mdx b/docs/content/docs/integrations/astro.mdx index 129088cf..e57c1ee7 100644 --- a/docs/content/docs/integrations/astro.mdx +++ b/docs/content/docs/integrations/astro.mdx @@ -5,60 +5,7 @@ description: Integrate Better Auth with Astro Better auth comes with first class support for Astro. This guide will show you how to integrate better auth with Astro. -## Installation - -First, install Better Auth - -```package-install -npm install better-auth -``` - -## Set Environment Variables - -Create a `.env` file in the root of your project and add the following environment variables: - -**Set Secret** - -Random value used by the library for encryption and generating hashes. You can generate one using the button below or you can use something like openssl. -```txt title=".env" -BETTER_AUTH_SECRET= -``` - - - - -## Configure Better Auth - - -### Create Better Auth instance - -Create a `auth.ts` file in one of these directories: - -- `.` (root directory) -- `lib/` -- `src/` -- `utils/` - -This file will contain your Better Auth instance. - -```ts title="auth.ts" -import { BetterAuth } from "better-auth" - -export const auth = new BetterAuth({ - database: { - provider: "sqlite", //change this to your database provider - url: "./db.sqlite", // path to your database or connection string - }, -}) -``` - -### Migrate the database - -You'll need to run the migration command to create the necessary tables in the database. - -```bash -npx better-auth migrate -``` +Before you start, make sure you have a better auth instance configured. If you haven't done that yet, check out the [installation](/docs/installation). ### Mount the handler @@ -138,7 +85,7 @@ export const onRequest = defineMiddleware(async (context, next) => { }); ``` -## Getting session on the server inside .astro file +## Getting session on the server inside `.astro` file You can use `auth.api` to call the API from the server side. Here is an example of how you can get the session inside an `.astro` file: diff --git a/docs/content/docs/integrations/hono.mdx b/docs/content/docs/integrations/hono.mdx index f973babd..9c9c6585 100644 --- a/docs/content/docs/integrations/hono.mdx +++ b/docs/content/docs/integrations/hono.mdx @@ -5,52 +5,7 @@ description: Hono Integration Guide This integration guide is assuming you are using Hono with node server. -## Installation - -First, install Better Auth - -```package-install -npm install better-auth -``` - -## Set Environment Variables - -Create a `.env` file in the root of your project and add the following environment variables: - -**Set Base URL** -```txt title=".env" -BETTER_AUTH_URL=http://localhost:3000 # Base URL of your Next.js app -``` - -**Set Secret** - -Random value used by the library for encryption and generating hashes. You can generate one using the button below or you can use something like openssl. -```txt title=".env" -BETTER_AUTH_SECRET= -``` - - -## Configure Server - -### Create Better Auth instance - -We recommend to create `auth.ts` file inside your `lib/` directory. This file will contain your Better Auth instance. - -```ts twoslash title="auth.ts" -import { betterAuth } from "better-auth" - -export const auth = betterAuth({ - database: { - provider: "sqlite", //change this to your database provider - url: "./db.sqlite", // path to your database or connection string - } - // Refer to the api documentation for more configuration options -}) -``` - - -Better Auth currently supports only SQLite, MySQL, and PostgreSQL. It uses Kysely under the hood, so you can also pass any Kysely dialect directly to the database object. - +Before you start, make sure you have a better auth instance configured. If you haven't done that yet, check out the [installation](/docs/installation). ### Mount the handler diff --git a/docs/content/docs/integrations/next.mdx b/docs/content/docs/integrations/next.mdx index d42505c5..93b0972b 100644 --- a/docs/content/docs/integrations/next.mdx +++ b/docs/content/docs/integrations/next.mdx @@ -5,52 +5,7 @@ description: Learn how to integrate Better Auth with Next.js Better Auth can be easily integrated with Next.js. It'll also comes with utilities to make it easier to use Better Auth with Next.js. -## Installation - -First, install Better Auth - -```package-install -npm install better-auth -``` - -## Set Environment Variables - -Create a `.env` file in the root of your project and add the following environment variables: - -**Set Base URL** -```txt title=".env" -BETTER_AUTH_URL=http://localhost:3000 # Base URL of your app -``` - -**Set Secret** - -Random value used by the library for encryption and generating hashes. You can generate one using the button below or you can use something like openssl. -```txt title=".env" -BETTER_AUTH_SECRET= -``` - - -## Configure Server - -### Create Better Auth instance - -We recommend to create `auth.ts` file inside your `lib/` directory. This file will contain your Better Auth instance. - -```ts twoslash title="auth.ts" -import { betterAuth } from "better-auth" - -export const auth = betterAuth({ - database: { - provider: "sqlite", //change this to your database provider - url: "./db.sqlite", // path to your database or connection string - } - // Refer to the api documentation for more configuration options -}) -``` - - -Better Auth currently supports only SQLite, MySQL, and PostgreSQL. It uses Kysely under the hood, so you can also pass any Kysely dialect directly to the database object. - +Before you start, make sure you have a better auth instance configured. If you haven't done that yet, check out the [installation](/docs/installation). ### Create API Route @@ -80,13 +35,6 @@ export const { GET, POST } = toNextJsHandler(auth.handler); You can change the path on your better-auth configuration but it's recommended to keep it as `/api/[...auth]` -### Migrate the database -Run the following command to create the necessary tables in your database: - -```bash -npx better-auth migrate -``` - ## Create a client Create a client instance. You can name the file anything you want. Here we are creating `client.ts` file inside the `lib/` directory. diff --git a/docs/content/docs/integrations/node.mdx b/docs/content/docs/integrations/node.mdx index e20f5b5b..5a594954 100644 --- a/docs/content/docs/integrations/node.mdx +++ b/docs/content/docs/integrations/node.mdx @@ -5,76 +5,7 @@ description: Integrate Better Auth with Node backend Better auth can be integrated with node based backed frameworks. The guide below will show you how to integrate better auth with express. -## Installation - -First, install Better Auth - -```package-install -npm install better-auth -``` - - - -## Set Environment Variables - -Create a `.env` file in the root of your project and add the following environment variables: - -**Set Base URL** -```txt title=".env" -BETTER_AUTH_URL=http://localhost:3000 # Base URL of your application -``` - - -if you're using a custom path other than `/api/auth` make sure to provider the full path in the `BETTER_AUTH_URL` variable. For example, if you're using `/custom-path` as the path, you should set `BETTER_AUTH_URL=http://localhost:3000/custom-path`. You can also provide path directly in the better auth options. - - - -**Set Secret** - -Random value used by the library for encryption and generating hashes. You can generate one using the button below or you can use something like openssl. - -```txt title=".env" -BETTER_AUTH_SECRET= -``` - - - -## Configuring Better Auth - -### Create Better Auth instance - -Create a `auth.ts` file in one of these directories: - -- `.` (root directory) -- `lib/` -- `src/` -- `utils/` - -This file will contain your Better Auth instance. - -```ts title="auth.ts" -import { BetterAuth } from "better-auth" - -export const auth = new BetterAuth({ - database: { - provider: "sqlite", //change this to your database provider - url: "./db.sqlite", // path to your database or connection string - }, -}) -``` - - -Refer to the [api documentation](/docs/api) on how to configure better auth. - - -### Migrate the database - -You'll need to run the migration command to create the necessary tables in the database. - - -```bash -npx better-auth migrate -``` +Before you start, make sure you have a better auth instance configured. If you haven't done that yet, check out the [installation](/docs/installation). ### Mount the handler diff --git a/docs/content/docs/integrations/nuxt.mdx b/docs/content/docs/integrations/nuxt.mdx index 260c935c..a19d49ad 100644 --- a/docs/content/docs/integrations/nuxt.mdx +++ b/docs/content/docs/integrations/nuxt.mdx @@ -3,49 +3,7 @@ title: Nuxt.js Integration description: Learn how to integrate Better Auth with Nuxt.js --- - -## Installation - -First, install Better Auth - -```package-install -npm install better-auth -``` - -## Set Environment Variables - -Create a `.env` file in the root of your project and add the following environment variables: - -**Set Secret** - -Random value used by the library for encryption and generating hashes. You can generate one using the button below or you can use something like openssl. -```txt title=".env" -BETTER_AUTH_SECRET= -``` - - - -## Configure Server - -### Create Better Auth instance - -We recommend to create `auth.ts` file inside your `lib/` directory. This file will contain your Better Auth instance. - -```ts twoslash title="auth.ts" -import { betterAuth } from "better-auth" - -export const auth = betterAuth({ - database: { - provider: "sqlite", //change this to your database provider - url: "./db.sqlite", // path to your database or connection string - } - // Refer to the api documentation for more configuration options -}) -``` - - -Better Auth currently supports only SQLite, MySQL, and PostgreSQL. It uses Kysely under the hood, so you can also pass any Kysely dialect directly to the database object. - +Before you start, make sure you have a better auth instance configured. If you haven't done that yet, check out the [installation](/docs/installation). ### Create API Route diff --git a/docs/content/docs/integrations/solid-start.mdx b/docs/content/docs/integrations/solid-start.mdx index 21afbe52..6845dddf 100644 --- a/docs/content/docs/integrations/solid-start.mdx +++ b/docs/content/docs/integrations/solid-start.mdx @@ -3,54 +3,7 @@ title: Solid Start Integration description: Solid Start integratons guide --- - -## Installation - -First, install Better Auth - -```package-install -npm install better-auth -``` - -## Set Environment Variables - -Create a `.env` file in the root of your project and add the following environment variables: - -**Set Base URL** -```txt title=".env" -BETTER_AUTH_URL=http://localhost:3000 # Base URL of your Next.js app -``` - -**Set Secret** - -Random value used by the library for encryption and generating hashes. You can generate one using the button below or you can use something like openssl. -```txt title=".env" -BETTER_AUTH_SECRET= -``` - - - -## Configure Server - -### Create Better Auth instance - -We recommend to create `auth.ts` file inside your `lib/` directory. This file will contain your Better Auth instance. - -```ts twoslash title="auth.ts" -import { betterAuth } from "better-auth" - -export const auth = betterAuth({ - database: { - provider: "sqlite", //change this to your database provider - url: "./db.sqlite", // path to your database or connection string - } - // Refer to the api documentation for more configuration options -}) -``` - - -Better Auth currently supports only SQLite, MySQL, and PostgreSQL. It uses Kysely under the hood, so you can also pass any Kysely dialect directly to the database object. - +Before you start, make sure you have a better auth instance configured. If you haven't done that yet, check out the [installation](/docs/installation). ### Mount the handler diff --git a/docs/content/docs/integrations/svelte-kit.mdx b/docs/content/docs/integrations/svelte-kit.mdx index dcc49f5b..65b22524 100644 --- a/docs/content/docs/integrations/svelte-kit.mdx +++ b/docs/content/docs/integrations/svelte-kit.mdx @@ -2,56 +2,7 @@ title: Svelte Kit Integration description: Learn how to integrate Better Auth with Svelte Kit --- - -Better Auth has first class support for Svelte Kit. It provides utilities to make it easier to use Better Auth with Svelte Kit. - -## Installation - -First, install Better Auth - -```package-install -npm install better-auth -``` - -## Set Environment Variables - -Create a `.env` file in the root of your project and add the following environment variables: - -**Set Base URL** -```txt title=".env" -BETTER_AUTH_URL=http://localhost:3000 # Base URL of your Next.js app -``` - -**Set Secret** - -Random value used by the library for encryption and generating hashes. You can generate one using the button below or you can use something like openssl. -```txt title=".env" -BETTER_AUTH_SECRET= -``` - - - -## Configure Server - -### Create Better Auth instance - -We recommend to create `auth.ts` file inside your `lib/` directory. This file will contain your Better Auth instance. - -```ts twoslash title="auth.ts" -import { betterAuth } from "better-auth" - -export const auth = betterAuth({ - database: { - provider: "sqlite", //change this to your database provider - url: "./db.sqlite", // path to your database or connection string - } - // Refer to the api documentation for more configuration options -}) -``` - - -Better Auth currently supports only SQLite, MySQL, and PostgreSQL. It uses Kysely under the hood, so you can also pass any Kysely dialect directly to the database object. - +Before you start, make sure you have a better auth instance configured. If you haven't done that yet, check out the [installation](/docs/installation). ### Mount the handler diff --git a/docs/content/docs/plugins/2fa.mdx b/docs/content/docs/plugins/2fa.mdx index 5933ea11..a8462dcb 100644 --- a/docs/content/docs/plugins/2fa.mdx +++ b/docs/content/docs/plugins/2fa.mdx @@ -284,9 +284,13 @@ When `trustDevice` is set to `true`, the current device will be remembered for 6 The plugin requires 3 additional fields in the `user` table. -- `twoFactorEnabled`: (boolean) - a boolean value that will be set `true` or `false` when authenticated user enable or disable two factor. -- `twoFactorSecret`: (string) - Encrypted secret used to generate totp and otp. -- `twoFactorBackupCodes`: (string) - Encrypted list of backup codes stored as a string separted by comma. + ## Options diff --git a/docs/content/docs/plugins/organization.mdx b/docs/content/docs/plugins/organization.mdx index 1d1082e8..e229ccbd 100644 --- a/docs/content/docs/plugins/organization.mdx +++ b/docs/content/docs/plugins/organization.mdx @@ -502,6 +502,133 @@ the plugin providers easy way to define your own set of permission for each role +## Schema + +The organization plugin adds the following tables to the database: + +### Organization + +Table Name: `organization` + + + +### Member + +Table Name: `member` + + + +### Invitation + +Table Name: `invitation` + + + ## Options **allowUserToCreateOrganization**: `boolean` | `((user: User) => Promise | boolean)` - A function that determines whether a user can create an organization. By default, it's `true`. You can set it to `false` to restrict users from creating organizations. @@ -514,4 +641,5 @@ the plugin providers easy way to define your own set of permission for each role **sendInvitationEmail**: `async (data) => Promise` - A function that sends an invitation email to the user. -**invitationExpiresIn** : `number` - How long the invitation link is valid for in seconds. By default, it's 48 hours (2 days). \ No newline at end of file +**invitationExpiresIn** : `number` - How long the invitation link is valid for in seconds. By default, it's 48 hours (2 days). + diff --git a/docs/content/docs/plugins/passkey.mdx b/docs/content/docs/plugins/passkey.mdx index 444acdc4..889e3c54 100644 --- a/docs/content/docs/plugins/passkey.mdx +++ b/docs/content/docs/plugins/passkey.mdx @@ -97,6 +97,70 @@ Signin method accepts: const data = await client.signIn.passkey() ``` +## Schema + +The plugin require a new table in the database to store passkey data. + +Table Name: `passkey` + + + ## Options diff --git a/docs/content/docs/plugins/rate-limit.mdx b/docs/content/docs/plugins/rate-limit.mdx deleted file mode 100644 index 5c4cad38..00000000 --- a/docs/content/docs/plugins/rate-limit.mdx +++ /dev/null @@ -1,212 +0,0 @@ ---- -title: Rate Limiter -description: better auth rate limit plugin ---- - -The rate limit plugin allows you to limit the number of requests a user can make to the server in a given time period. - -## Installation - - - - ### Add the plugin to your auth config - - Add the rate limit plugin to your auth configuration and pass `enabled` to `true` to enable rate limiting. - - ```ts title="auth.ts" - import { betterAuth } from "better-auth" - import { rateLimiter } from "better-auth/plugins" - - export const auth = await betterAuth({ - //... other config options - plugins: [ - rateLimit({ // [!code highlight] - enabled: true, // [!code highlight] - }), // [!code highlight] - ], - }) - ``` - - - ### Migrate your database (optional) - If you are using the default database storage, you need to run the migration to add the required fields to the rate limit table. - - This will add the following fields to the **rateLimit** table: - - `key`: The key used for rate limiting. - - `count`: The number of requests made in the given time window. - - `lastRequest`: The timestamp of the last request made. - - - You can change the table name by providing table name on the storage configuration of the rate limit plugin. - - - ```bash - npx better-auth migrate - ``` - - - -## Configuration - -The rate limit plugin accepts the following options: - -### Enabled - -enable rate limiting. You can also pass a function to enable rate limiting for specific endpoints. - -```ts title="auth.ts" - -import { betterAuth } from "better-auth" -import { rateLimiter } from "better-auth/plugins" - -export const auth = await betterAuth({ - // - plugins: [ - rateLimit({ - enabled: true, // [!code highlight] - }), // [!code highlight] - ], -}) -``` - -### Window - -The time window in seconds for which the rate limit is enforced. Default is 15 minutes (15 * 60). - -```ts title="auth.ts" -import { betterAuth } from "better-auth" -import { rateLimiter } from "better-auth/plugins" - -export const auth = await betterAuth({ - // - plugins: [ - rateLimit({ - enabled: true, - window: 60 * 10, // [!code highlight] - }), - ], -}) -``` - -### Max - -The maximum number of requests a user can make in the given time window. Default is 100. - -```ts title="auth.ts" -import { betterAuth } from "better-auth" -import { rateLimiter } from "better-auth/plugins" - -export const auth = await betterAuth({ - // - plugins: [ - rateLimit({ - enabled: true, - window: 60 * 10, - max: 50, // [!code highlight] - }), - ], -}) -``` - -### Get Key - -A function that returns the key to use for rate limiting. By default, it uses the user's IP address if the user is not authenticated and the user's ID if the user is authenticated. - -```ts title="auth.ts" -import { betterAuth } from "better-auth" -import { rateLimiter } from "better-auth/plugins" - -export const auth = await betterAuth({ - // - plugins: [ - rateLimit({ - enabled: true, - window: 60 * 10, - max: 50, - getKey: (req) => req.headers['x-forwarded-for'] || req.connection.remoteAddress, // [!code highlight] - }), - ], -}) -``` - -### Storage - -The storage to use for rate limiting. By default, it uses database storage. - -```ts title="auth.ts" -import { betterAuth } from "better-auth" -import { rateLimiter } from "better-auth/plugins" - -export const auth = await betterAuth({ - // - plugins: [ - rateLimit({ - enabled: true, - window: 60 * 10, - max: 50, - getKey: (req) => req.headers['x-forwarded-for'] || req.connection.remoteAddress, - storage: { // [!code highlight] - provider: "memeory" // [!code highlight] - }, // [!code highlight] - }), - ], -}) -``` - -#### Custom Storage - -You can also pass a custom storage provider to the rate limit plugin. - -```ts title="auth.ts" -import { betterAuth } from "better-auth" -import { rateLimiter } from "better-auth/plugins" - -export const auth = await betterAuth({ - // - plugins: [ - rateLimit({ - enabled: true, - window: 60 * 10, - max: 50, - getKey: (req) => req.headers['x-forwarded-for'] || req.connection.remoteAddress, - storage: { // [!code highlight] - provider: "custom", // [!code highlight] - customStorage: { // [!code highlight] - get: async (key) => {}, // [!code highlight] - set: async (key, value) => {}, // [!code highlight] - }, // [!code highlight] - }, // [!code highlight] - }), - ], -}) -``` - -### Sepcial Rules - -Special rules are rules that allows yous to define custom rate limit counter for specific paths. -By default, `sign-in` and `sign-up` paths are rate limited have a count of `2` for each request as supposed to the default `1` for other paths. - -`matcher`: A function that returns a boolean value indicating whether the rule should be applied to the given path. - -`countValue`: The number of requests allowed for the given path. - -```ts title="auth.ts" -import { betterAuth } from "better-auth" -import { rateLimiter } from "better-auth/plugins" - -export const auth = await betterAuth({ - // - plugins: [ - rateLimit({ - specialRules: specialRules: [ - { - matcher(path) { - return path.startsWith("/sign-in") || path.startsWith("/sign-up"); - }, - countValue: 2, - }, - ], - }), - ], -}) -``` \ No newline at end of file diff --git a/docs/content/docs/plugins/username.mdx b/docs/content/docs/plugins/username.mdx index f388e98a..2c89b583 100644 --- a/docs/content/docs/plugins/username.mdx +++ b/docs/content/docs/plugins/username.mdx @@ -111,6 +111,21 @@ const data = await client.signIn.username({ }) ``` +## Schema + +The plugin requires 1 field to be added to the user table: + + + ## Options The username plugin doesn't require any configuration. It just needs to be added to the server and client. diff --git a/docs/mdx-components.tsx b/docs/mdx-components.tsx index 488a7c7a..4f1a6c83 100644 --- a/docs/mdx-components.tsx +++ b/docs/mdx-components.tsx @@ -10,6 +10,7 @@ import { Popup, PopupContent, PopupTrigger } from "fumadocs-ui/twoslash/popup"; import { TypeTable } from "fumadocs-ui/components/type-table"; import { Features } from "./components/blocks/features"; import { ForkButton } from "./components/fork-button"; +import DatabaseTable from "./components/mdx/database-tables"; export function useMDXComponents(components: MDXComponents): MDXComponents { return { @@ -33,6 +34,7 @@ export function useMDXComponents(components: MDXComponents): MDXComponents { TypeTable, Features, ForkButton, + DatabaseTable, iframe: (props) =>