mirror of
https://github.com/LukeHagar/better-auth.git
synced 2025-12-10 04:19:32 +00:00
docs: minor updates to docs
This commit is contained in:
2
.github/workflows/discord.yml
vendored
2
.github/workflows/discord.yml
vendored
@@ -10,7 +10,7 @@ jobs:
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
- name: Github Releases To Discord
|
||||
- name: GitHub Releases To Discord
|
||||
uses: SethCohen/github-releases-to-discord@v1.15.1
|
||||
with:
|
||||
webhook_url: ${{ secrets.WEBHOOK_URL }}
|
||||
|
||||
@@ -37,7 +37,7 @@ export default async function Home() {
|
||||
<div className="border-y py-2 border-dotted bg-secondary/60 opacity-80">
|
||||
<div className="text-xs flex items-center gap-2 justify-center text-muted-foreground ">
|
||||
<span className="text-center">
|
||||
All features on this demo are Implemented with better auth
|
||||
All features on this demo are implemented with Better Auth
|
||||
without any custom backend code
|
||||
</span>
|
||||
</div>
|
||||
|
||||
@@ -149,7 +149,7 @@ export default function SignIn() {
|
||||
d="M12 2A10 10 0 0 0 2 12c0 4.42 2.87 8.17 6.84 9.5c.5.08.66-.23.66-.5v-1.69c-2.77.6-3.36-1.34-3.36-1.34c-.46-1.16-1.11-1.47-1.11-1.47c-.91-.62.07-.6.07-.6c1 .07 1.53 1.03 1.53 1.03c.87 1.52 2.34 1.07 2.91.83c.09-.65.35-1.09.63-1.34c-2.22-.25-4.55-1.11-4.55-4.92c0-1.11.38-2 1.03-2.71c-.1-.25-.45-1.29.1-2.64c0 0 .84-.27 2.75 1.02c.79-.22 1.65-.33 2.5-.33s1.71.11 2.5.33c1.91-1.29 2.75-1.02 2.75-1.02c.55 1.35.2 2.39.1 2.64c.65.71 1.03 1.6 1.03 2.71c0 3.82-2.34 4.66-4.57 4.91c.36.31.69.92.69 1.85V21c0 .27.16.59.67.5C19.14 20.16 22 16.42 22 12A10 10 0 0 0 12 2"
|
||||
></path>
|
||||
</svg>
|
||||
Sign in with Github
|
||||
Sign in with GitHub
|
||||
</Button>
|
||||
<Button
|
||||
variant="outline"
|
||||
|
||||
@@ -22,7 +22,7 @@ export const ResetPasswordEmail = ({
|
||||
username,
|
||||
resetLink,
|
||||
}: BetterAuthResetPasswordEmailProps) => {
|
||||
const previewText = `Reset your BetterAuth password`;
|
||||
const previewText = `Reset your Better Auth password`;
|
||||
return (
|
||||
<Html>
|
||||
<Head />
|
||||
|
||||
@@ -10,7 +10,7 @@ export default function CommunityHeader() {
|
||||
</h1>
|
||||
<p className="dark:text-gray-400 max-w-md mx-auto text-stone-800">
|
||||
join <span className="italic font-bold">better-auth</span> community
|
||||
to get help, share ideas, and stay up-to-date.
|
||||
to get help, share ideas, and stay up to date.
|
||||
</p>
|
||||
<div className="flex justify-center items-center mt-6 space-x-6">
|
||||
<IconLink
|
||||
|
||||
@@ -38,8 +38,8 @@ const grid = [
|
||||
description: "Manage user accounts and sessions with ease",
|
||||
},
|
||||
{
|
||||
title: "Built In Rate Limiter",
|
||||
description: "Built in rate limiter with custom rules",
|
||||
title: "Built-In Rate Limiter",
|
||||
description: "Built-in rate limiter with custom rules",
|
||||
},
|
||||
{
|
||||
title: "Automatic Database Management",
|
||||
|
||||
@@ -100,7 +100,7 @@ const frameworks = [
|
||||
),
|
||||
},
|
||||
{
|
||||
title: "Solid Start",
|
||||
title: "SolidStart",
|
||||
description: "Fine-grained reactivity goes fullstack",
|
||||
Icon: () => (
|
||||
<svg
|
||||
|
||||
@@ -329,7 +329,7 @@ export const contents: Content[] = [
|
||||
),
|
||||
},
|
||||
{
|
||||
title: "Typescript",
|
||||
title: "TypeScript",
|
||||
href: "/docs/concepts/typescript",
|
||||
icon: () => (
|
||||
<svg
|
||||
@@ -1070,7 +1070,7 @@ C0.7,239.6,62.1,0.5,62.2,0.4c0,0,54,13.8,119.9,30.8S302.1,62,302.2,62c0.2,0,0.2,
|
||||
href: "/docs/integrations/svelte-kit",
|
||||
},
|
||||
{
|
||||
title: "Solid Start",
|
||||
title: "SolidStart",
|
||||
icon: Icons.solidStart,
|
||||
href: "/docs/integrations/solid-start",
|
||||
},
|
||||
@@ -1812,7 +1812,7 @@ export const examples: Content[] = [
|
||||
icon: Icons.remix,
|
||||
},
|
||||
{
|
||||
title: "Next JS",
|
||||
title: "Next.js",
|
||||
href: "/docs/examples/next-js",
|
||||
icon: Icons.nextJS,
|
||||
},
|
||||
|
||||
@@ -19,7 +19,7 @@ export const techStackIcons: TechStackIconType = {
|
||||
icon: <Icons.svelteKit className="w-10 h-10" />,
|
||||
},
|
||||
solidStart: {
|
||||
name: "Solid Start",
|
||||
name: "SolidStart",
|
||||
icon: <Icons.solidStart className="w-10 h-10" />,
|
||||
},
|
||||
react: {
|
||||
|
||||
@@ -101,7 +101,7 @@ Read the [Organization Plugin docs](/docs/plugins/organization#teams) for more i
|
||||
|
||||
### **Init CLI**
|
||||
|
||||
The CLI now includes an `init` command to add better auth to your project.
|
||||
The CLI now includes an `init` command to add Better Auth to your project.
|
||||
|
||||
```bash title="terminal"
|
||||
npx @better-auth/cli init
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
title: v1.0
|
||||
description: Built in CLI for managing your project.
|
||||
description: Built-in CLI for managing your project.
|
||||
date: 2021-10-01
|
||||
---
|
||||
|
||||
|
||||
@@ -91,7 +91,7 @@ await authClient.signOut({
|
||||
To enable email verification, you need to pass a function that sends a verification email with a link. The `sendVerificationEmail` function takes a data object with the following properties:
|
||||
|
||||
- `user`: The user object.
|
||||
- `url`: The url to send to the user which contains the token.
|
||||
- `url`: The URL to send to the user which contains the token.
|
||||
- `token`: A verification token used to complete the email verification.
|
||||
|
||||
and a `request` object as the second parameter.
|
||||
@@ -171,7 +171,7 @@ await authClient.sendVerificationEmail({
|
||||
To allow users to reset a password first you need to provide `sendResetPassword` function to the email and password authenticator. The `sendResetPassword` function takes a data object with the following properties:
|
||||
|
||||
- `user`: The user object.
|
||||
- `url`: The url to send to the user which contains the token.
|
||||
- `url`: The URL to send to the user which contains the token.
|
||||
- `token`: A verification token used to complete the password reset.
|
||||
|
||||
and a `request` object as the second parameter.
|
||||
|
||||
@@ -52,7 +52,7 @@ const authClient = createAuthClient();
|
||||
const signIn = async () => {
|
||||
const data = await authClient.signIn.social({
|
||||
provider: "microsoft",
|
||||
callbackURL: "/dashboard", //the url to redirect to after the sign in
|
||||
callbackURL: "/dashboard", // The URL to redirect to after the sign in
|
||||
});
|
||||
};
|
||||
```
|
||||
|
||||
@@ -35,8 +35,8 @@ const { data, error } = await authClient.signUp.email({
|
||||
email, // user email address
|
||||
password, // user password -> min 8 characters by default
|
||||
name, // user display name
|
||||
image, // user image url (optional)
|
||||
callbackURL: "/dashboard" // a url to redirect to after the user verifies their email (optional)
|
||||
image, // User image URL (optional)
|
||||
callbackURL: "/dashboard" // A URL to redirect to after the user verifies their email (optional)
|
||||
}, {
|
||||
onRequest: (ctx) => {
|
||||
//show loading
|
||||
@@ -80,7 +80,7 @@ const { data, error } = await authClient.signIn.email({
|
||||
*/
|
||||
password,
|
||||
/**
|
||||
* a url to redirect to after the user verifies their email (optional)
|
||||
* A URL to redirect to after the user verifies their email (optional)
|
||||
*/
|
||||
callbackURL: "/dashboard",
|
||||
/**
|
||||
@@ -134,7 +134,7 @@ export const auth = betterAuth({
|
||||
})
|
||||
```
|
||||
|
||||
### Signin with social providers
|
||||
### Sign in with social providers
|
||||
|
||||
To sign in using a social provider you need to call `signIn.social`. It takes an object with the following properties:
|
||||
|
||||
@@ -148,16 +148,16 @@ await authClient.signIn.social({
|
||||
*/
|
||||
provider: "github",
|
||||
/**
|
||||
* a url to redirect after the user authenticates with the provider
|
||||
* A URL to redirect after the user authenticates with the provider
|
||||
* @default "/"
|
||||
*/
|
||||
callbackURL: "/dashboard",
|
||||
/**
|
||||
* a url to redirect if an error occurs during the sign in process
|
||||
* A URL to redirect if an error occurs during the sign in process
|
||||
*/
|
||||
errorCallbackURL: "/error",
|
||||
/**
|
||||
* a url to redirect if the user is newly registered
|
||||
* A URL to redirect if the user is newly registered
|
||||
*/
|
||||
newUserCallbackURL: "/welcome",
|
||||
/**
|
||||
@@ -296,8 +296,8 @@ The server provides a `session` object that you can use to access the session da
|
||||
|
||||
**Example: Using some popular frameworks**
|
||||
|
||||
<Tabs items={["NextJs", "Nuxt", "Svelte", "Astro", "Hono", "TanStack"]}>
|
||||
<Tab value="NextJs">
|
||||
<Tabs items={["Next.js", "Nuxt", "Svelte", "Astro", "Hono", "TanStack"]}>
|
||||
<Tab value="Next.js">
|
||||
```ts title="server.ts"
|
||||
import { auth } from "./auth"; // path to your Better Auth server instance
|
||||
import { headers } from "next/headers";
|
||||
|
||||
@@ -3,7 +3,7 @@ title: API
|
||||
description: Better Auth API.
|
||||
---
|
||||
|
||||
When you create a new Better Auth instance, it provides you with an `api` object. This object exposes every endpoint that exist in your better auth instance. And you can use this to interact with Better Auth server side.
|
||||
When you create a new Better Auth instance, it provides you with an `api` object. This object exposes every endpoint that exist in your Better Auth instance. And you can use this to interact with Better Auth server side.
|
||||
|
||||
Any endpoint added to Better Auth, whether from plugins or the core, will be accessible through the `api` object.
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
title: CLI
|
||||
description: Built in CLI for managing your project.
|
||||
description: Built-in CLI for managing your project.
|
||||
---
|
||||
|
||||
Better Auth comes with a built-in CLI to help you manage the database schemas, initialize your project, and generate a secret key for your application.
|
||||
|
||||
@@ -28,7 +28,7 @@ If you're using a different base path other than `/api/auth`, make sure to pass
|
||||
```ts title="lib/auth-client.ts"
|
||||
import { createAuthClient } from "better-auth/client"
|
||||
export const authClient = createAuthClient({
|
||||
baseURL: "http://localhost:3000" // the base url of your auth server // [!code highlight]
|
||||
baseURL: "http://localhost:3000" // The base URL of your auth server // [!code highlight]
|
||||
})
|
||||
```
|
||||
</Tab>
|
||||
@@ -36,7 +36,7 @@ If you're using a different base path other than `/api/auth`, make sure to pass
|
||||
```ts title="lib/auth-client.ts"
|
||||
import { createAuthClient } from "better-auth/react"
|
||||
export const authClient = createAuthClient({
|
||||
baseURL: "http://localhost:3000" // the base url of your auth server // [!code highlight]
|
||||
baseURL: "http://localhost:3000" // The base URL of your auth server // [!code highlight]
|
||||
})
|
||||
```
|
||||
</Tab>
|
||||
@@ -44,7 +44,7 @@ If you're using a different base path other than `/api/auth`, make sure to pass
|
||||
```ts title="lib/auth-client.ts"
|
||||
import { createAuthClient } from "better-auth/vue"
|
||||
export const authClient = createAuthClient({
|
||||
baseURL: "http://localhost:3000" // the base url of your auth server // [!code highlight]
|
||||
baseURL: "http://localhost:3000" // The base URL of your auth server // [!code highlight]
|
||||
})
|
||||
```
|
||||
</Tab>
|
||||
@@ -52,7 +52,7 @@ If you're using a different base path other than `/api/auth`, make sure to pass
|
||||
```ts title="lib/auth-client.ts"
|
||||
import { createAuthClient } from "better-auth/svelte"
|
||||
export const authClient = createAuthClient({
|
||||
baseURL: "http://localhost:3000" // the base url of your auth server // [!code highlight]
|
||||
baseURL: "http://localhost:3000" // The base URL of your auth server // [!code highlight]
|
||||
})
|
||||
```
|
||||
</Tab>
|
||||
@@ -60,7 +60,7 @@ If you're using a different base path other than `/api/auth`, make sure to pass
|
||||
```ts title="lib/auth-client.ts"
|
||||
import { createAuthClient } from "better-auth/solid"
|
||||
export const authClient = createAuthClient({
|
||||
baseURL: "http://localhost:3000" // the base url of your auth server // [!code highlight]
|
||||
baseURL: "http://localhost:3000" // The base URL of your auth server // [!code highlight]
|
||||
})
|
||||
```
|
||||
</Tab>
|
||||
@@ -121,7 +121,7 @@ On top of normal methods, the client provides hooks to easily access different r
|
||||
<button v-if="!session.data" @click="() => authClient.signIn.social({
|
||||
provider: 'github'
|
||||
})">
|
||||
Continue with github
|
||||
Continue with GitHub
|
||||
</button>
|
||||
<div>
|
||||
<pre>{{ session.data }}</pre>
|
||||
@@ -169,7 +169,7 @@ On top of normal methods, the client provides hooks to easily access different r
|
||||
});
|
||||
}}
|
||||
>
|
||||
Continue with github
|
||||
Continue with GitHub
|
||||
</button>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
@@ -434,7 +434,7 @@ res.user.lang; // > "fr"
|
||||
|
||||
<Callout>
|
||||
See the
|
||||
[Typescript](/docs/concepts/typescript#inferring-additional-fields-on-client)
|
||||
[TypeScript](/docs/concepts/typescript#inferring-additional-fields-on-client)
|
||||
documentation for more information on how to infer additional fields on the
|
||||
client side.
|
||||
</Callout>
|
||||
@@ -585,4 +585,4 @@ To add new tables and columns to your database, you have two options:
|
||||
`CLI`: Use the migrate or generate command. These commands will scan your database and guide you through adding any missing tables or columns.
|
||||
`Manual Method`: Follow the instructions in the plugin documentation to manually add tables and columns.
|
||||
|
||||
Both methods ensure your database schema stays up-to-date with your plugins' requirements.
|
||||
Both methods ensure your database schema stays up to date with your plugins' requirements.
|
||||
|
||||
@@ -6,7 +6,7 @@ description: Better Auth Hooks let you customize BetterAuth's behavior
|
||||
Hooks in Better Auth let you "hook into" the lifecycle and execute custom logic. They provide a way to customize Better Auth's behavior without writing a full plugin.
|
||||
|
||||
<Callout>
|
||||
We highly recommend using hooks if you need to make custom adjustments to an endpoint rather than making another endpoint outside of better auth.
|
||||
We highly recommend using hooks if you need to make custom adjustments to an endpoint rather than making another endpoint outside of Better Auth.
|
||||
</Callout>
|
||||
|
||||
## Before Hooks
|
||||
@@ -227,7 +227,7 @@ The password object provider `hash` and `verify`
|
||||
|
||||
#### Adapter
|
||||
|
||||
Adapter exposes the adapter methods used by better auth. Including `findOne`, `findMany`, `create`, `delete`, `update` and `updateMany`. You generally should use your actually `db` instance from your orm rather than this adapter.
|
||||
Adapter exposes the adapter methods used by Better Auth. Including `findOne`, `findMany`, `create`, `delete`, `update` and `updateMany`. You generally should use your actually `db` instance from your orm rather than this adapter.
|
||||
|
||||
|
||||
#### Internal Adapter
|
||||
|
||||
@@ -506,7 +506,7 @@ const myPluginClient = {
|
||||
} satisfies BetterAuthClientPlugin
|
||||
```
|
||||
|
||||
See built in plugins for examples of how to use atoms properly.
|
||||
See built-in plugins for examples of how to use atoms properly.
|
||||
|
||||
### Path methods
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ description: Better Auth TypeScript integration.
|
||||
Better Auth is designed to be type-safe. Both the client and server are built with TypeScript, allowing you to easily infer types.
|
||||
|
||||
|
||||
## Typescript Config
|
||||
## TypeScript Config
|
||||
|
||||
### Strict Mode
|
||||
|
||||
|
||||
@@ -138,7 +138,7 @@ export const auth = betterAuth({
|
||||
|
||||
**How callback verification works:**
|
||||
|
||||
- **Callback URL**: The url provided in `sendDeleteAccountVerification` is a pre-generated link that deletes the user data when accessed.
|
||||
- **Callback URL**: The URL provided in `sendDeleteAccountVerification` is a pre-generated link that deletes the user data when accessed.
|
||||
|
||||
```ts title="delete-user.ts"
|
||||
await authClient.deleteUser({
|
||||
|
||||
@@ -20,7 +20,7 @@ See [Demo](https://demo.better-auth.com)
|
||||
borderRadius: "4px",
|
||||
overflow: "hidden"
|
||||
}}
|
||||
title="Better Auth Next Js Example"
|
||||
title="Better Auth Next.js Example"
|
||||
allow="accelerometer; ambient-light-sensor; camera; encrypted-media; geolocation; gyroscope; hid; microphone; midi; payment; usb; vr; xr-spatial-tracking"
|
||||
sandbox="allow-forms allow-modals allow-popups allow-presentation allow-same-origin allow-scripts"
|
||||
>
|
||||
|
||||
@@ -10,7 +10,7 @@ If you would like to view a completed example, you can check out the <Link href=
|
||||
<Callout type="warn">
|
||||
The Plasmo framework does not provide a backend for the browser extension.
|
||||
This guide assumes you have{" "}
|
||||
<Link href="/docs/integrations/hono">a backend setup</Link> of BetterAuth and
|
||||
<Link href="/docs/integrations/hono">a backend setup</Link> of Better Auth and
|
||||
are ready to create a browser extension to connect to it.
|
||||
</Callout>
|
||||
|
||||
@@ -25,7 +25,7 @@ If you would like to view a completed example, you can check out the <Link href=
|
||||
pnpm create plasmo --with-tailwindcss --with-src
|
||||
```
|
||||
|
||||
Then, install the BetterAuth package.
|
||||
Then, install the Better Auth package.
|
||||
|
||||
```bash
|
||||
pnpm add better-auth
|
||||
@@ -79,7 +79,7 @@ If you would like to view a completed example, you can check out the <Link href=
|
||||
import { createAuthClient } from "better-auth/react"
|
||||
|
||||
export const authClient = createAuthClient({
|
||||
baseURL: "http://localhost:3000" /* base url of your Better Auth backend. */,
|
||||
baseURL: "http://localhost:3000" /* Base URL of your Better Auth backend. */,
|
||||
plugins: [],
|
||||
});
|
||||
```
|
||||
@@ -88,7 +88,7 @@ If you would like to view a completed example, you can check out the <Link href=
|
||||
<Step>
|
||||
## Configure the manifest
|
||||
|
||||
We must ensure the extension knows the URL to the BetterAuth backend.
|
||||
We must ensure the extension knows the URL to the Better Auth backend.
|
||||
|
||||
Head to your package.json file, and add the following code.
|
||||
|
||||
@@ -108,11 +108,11 @@ If you would like to view a completed example, you can check out the <Link href=
|
||||
<Step>
|
||||
## You're now ready!
|
||||
|
||||
You have now setup BetterAuth for your browser extension.
|
||||
You have now set up Better Auth for your browser extension.
|
||||
|
||||
Add your desired UI and create your dream extension!
|
||||
|
||||
To learn more about the client BetterAuth API, check out the <Link href="/docs/concepts/client">client documentation</Link>.
|
||||
To learn more about the client Better Auth API, check out the <Link href="/docs/concepts/client">client documentation</Link>.
|
||||
|
||||
|
||||
Here’s a quick example 😎
|
||||
@@ -195,9 +195,9 @@ If you would like to view a completed example, you can check out the <Link href=
|
||||
|
||||
## Wrapping Up
|
||||
|
||||
Congratulations! You’ve successfully created a browser extension using BetterAuth and Plasmo.
|
||||
Congratulations! You’ve successfully created a browser extension using Better Auth and Plasmo.
|
||||
We highly recommend you visit the <Link href="https://docs.plasmo.com/">Plasmo documentation</Link> to learn more about the framework.
|
||||
|
||||
If you would like to view a completed example, you can check out the <Link href="https://github.com/better-auth/better-auth/tree/main/examples/browser-extension-example">browser extension example</Link>.
|
||||
|
||||
If you have any questions, feel free to open an issue on our <Link href="https://github.com/better-auth/better-auth/issues">Github repo</Link>, or join our <Link href="https://discord.gg/6jHcdYMzyq">Discord server</Link> for support.
|
||||
If you have any questions, feel free to open an issue on our <Link href="https://github.com/better-auth/better-auth/issues">GitHub repo</Link>, or join our <Link href="https://discord.gg/6jHcdYMzyq">Discord server</Link> for support.
|
||||
|
||||
@@ -32,7 +32,7 @@ Read more about [cookie caching](/docs/concepts/session-management#cookie-cache)
|
||||
|
||||
Here are examples of how you can do caching in different frameworks and environments:
|
||||
|
||||
<Tabs items={["NextJs", "Remix", "Solid Start", "React Query"]}>
|
||||
<Tabs items={["Next.js", "Remix", "SolidStart", "React Query"]}>
|
||||
<Tab value="NextJS">
|
||||
Since Next v15, we can use the `"use cache"` directive to cache the response of a server function.
|
||||
|
||||
@@ -68,8 +68,8 @@ Here are examples of how you can do caching in different frameworks and environm
|
||||
|
||||
</Tab>
|
||||
|
||||
<Tab value="Solid Start">
|
||||
In Solid Start, you can use the `query` function to cache data. Here’s an example:
|
||||
<Tab value="SolidStart">
|
||||
In SolidStart, you can use the `query` function to cache data. Here’s an example:
|
||||
|
||||
```tsx
|
||||
const getUsers = query(
|
||||
@@ -78,7 +78,7 @@ Here are examples of how you can do caching in different frameworks and environm
|
||||
);
|
||||
```
|
||||
|
||||
Learn more about Solid Start `query` function <Link href="https://docs.solidjs.com/solid-router/reference/data-apis/query">here</Link>.
|
||||
Learn more about SolidStart `query` function <Link href="https://docs.solidjs.com/solid-router/reference/data-apis/query">here</Link>.
|
||||
|
||||
</Tab>
|
||||
<Tab value="React Query">
|
||||
|
||||
@@ -125,7 +125,7 @@ This tables will be created on the `public` schema.
|
||||
<Step>
|
||||
### Copy the migration script
|
||||
|
||||
Now that we have the necessary tables in our database, we can run the migration script to migrate the users and accounts from supabase to better auth.
|
||||
Now that we have the necessary tables in our database, we can run the migration script to migrate the users and accounts from Supabase to Better Auth.
|
||||
|
||||
Start by creating a `.ts` file in your project.
|
||||
|
||||
@@ -259,7 +259,7 @@ migrateFromSupabase();
|
||||
<Step>
|
||||
### Run the migration script
|
||||
|
||||
Run the migration script to migrate the users and accounts from supabase to better auth.
|
||||
Run the migration script to migrate the users and accounts from Supabase to Better Auth.
|
||||
|
||||
```bash title="Terminal"
|
||||
bun migration.ts # or use node, ts-node, etc.
|
||||
@@ -268,9 +268,9 @@ bun migration.ts # or use node, ts-node, etc.
|
||||
<Step>
|
||||
### Update your code
|
||||
|
||||
Update your codebase from supabase auth calls to better auth api.
|
||||
Update your codebase from Supabase auth calls to Better Auth API.
|
||||
|
||||
Here's a list of the supabase auth api calls and their better auth counterparts.
|
||||
Here's a list of the Supabase auth API calls and their Better Auth counterparts.
|
||||
|
||||
- `supabase.auth.signUp` -> `authClient.signUp.email`
|
||||
- `supabase.auth.signInWithPassword` -> `authClient.signIn.email`
|
||||
|
||||
@@ -86,7 +86,7 @@ export const birthdayPlugin = () =>
|
||||
|
||||
<Step>
|
||||
### Authorization logic
|
||||
For this example guide, we’ll setup authentication logic to check and ensure that the user who signs-up is older than 5.
|
||||
For this example guide, we’ll set up authentication logic to check and ensure that the user who signs-up is older than 5.
|
||||
But the same concept could be applied for something like verifying users agreeing to the TOS or anything alike.
|
||||
|
||||
To do this, we’ll utilize <Link href="/docs/concepts/plugins#hooks">Hooks</Link>, which allows us to run code `before` or `after` an action is performed.
|
||||
|
||||
@@ -228,7 +228,7 @@ You can use even more authentication methods like [passkey](/docs/plugins/passke
|
||||
|
||||
<Step>
|
||||
### Mount Handler
|
||||
To handle api requests, you need to set up a route handler on your server.
|
||||
To handle API requests, you need to set up a route handler on your server.
|
||||
|
||||
Create a new file or route in your framework's designated catch-all route handler. This route should handle requests for the path `/api/auth/*` (unless you've configured a different base path).
|
||||
|
||||
@@ -391,10 +391,10 @@ The client-side library helps you interact with the auth server. Better Auth com
|
||||
|
||||
1. Import `createAuthClient` from the package for your framework (e.g., "better-auth/react" for React).
|
||||
2. Call the function to create your client.
|
||||
3. Pass the base url of your auth server. (If the auth server is running on the same domain as your client, you can skip this step.)
|
||||
3. Pass the base URL of your auth server. (If the auth server is running on the same domain as your client, you can skip this step.)
|
||||
|
||||
<Callout type="info">
|
||||
If you're using a different base path other than `/api/auth` make sure to pass the whole url including the path. (e.g. `http://localhost:3000/custom-path/auth`)
|
||||
If you're using a different base path other than `/api/auth` make sure to pass the whole URL including the path. (e.g. `http://localhost:3000/custom-path/auth`)
|
||||
</Callout>
|
||||
|
||||
<Tabs items={["react", "vue", "svelte", "solid",
|
||||
@@ -403,7 +403,7 @@ If you're using a different base path other than `/api/auth` make sure to pass t
|
||||
```ts title="lib/auth-client.ts"
|
||||
import { createAuthClient } from "better-auth/client"
|
||||
export const authClient = createAuthClient({
|
||||
/** the base url of the server (optional if you're using the same domain) */ // [!code highlight]
|
||||
/** The base URL of the server (optional if you're using the same domain) */ // [!code highlight]
|
||||
baseURL: "http://localhost:3000" // [!code highlight]
|
||||
})
|
||||
```
|
||||
@@ -412,7 +412,7 @@ If you're using a different base path other than `/api/auth` make sure to pass t
|
||||
```ts title="lib/auth-client.ts"
|
||||
import { createAuthClient } from "better-auth/react"
|
||||
export const authClient = createAuthClient({
|
||||
/** the base url of the server (optional if you're using the same domain) */ // [!code highlight]
|
||||
/** The base URL of the server (optional if you're using the same domain) */ // [!code highlight]
|
||||
baseURL: "http://localhost:3000" // [!code highlight]
|
||||
})
|
||||
```
|
||||
@@ -421,7 +421,7 @@ If you're using a different base path other than `/api/auth` make sure to pass t
|
||||
```ts title="lib/auth-client.ts"
|
||||
import { createAuthClient } from "better-auth/vue"
|
||||
export const authClient = createAuthClient({
|
||||
/** the base url of the server (optional if you're using the same domain) */ // [!code highlight]
|
||||
/** The base URL of the server (optional if you're using the same domain) */ // [!code highlight]
|
||||
baseURL: "http://localhost:3000" // [!code highlight]
|
||||
})
|
||||
```
|
||||
@@ -430,7 +430,7 @@ If you're using a different base path other than `/api/auth` make sure to pass t
|
||||
```ts title="lib/auth-client.ts"
|
||||
import { createAuthClient } from "better-auth/svelte"
|
||||
export const authClient = createAuthClient({
|
||||
/** the base url of the server (optional if you're using the same domain) */ // [!code highlight]
|
||||
/** The base URL of the server (optional if you're using the same domain) */ // [!code highlight]
|
||||
baseURL: "http://localhost:3000" // [!code highlight]
|
||||
})
|
||||
```
|
||||
@@ -439,7 +439,7 @@ If you're using a different base path other than `/api/auth` make sure to pass t
|
||||
```ts title="lib/auth-client.ts"
|
||||
import { createAuthClient } from "better-auth/solid"
|
||||
export const authClient = createAuthClient({
|
||||
/** the base url of the server (optional if you're using the same domain) */ // [!code highlight]
|
||||
/** The base URL of the server (optional if you're using the same domain) */ // [!code highlight]
|
||||
baseURL: "http://localhost:3000" // [!code highlight]
|
||||
})
|
||||
```
|
||||
|
||||
@@ -69,7 +69,7 @@ Expo is a popular framework for building cross-platform apps with React Native.
|
||||
<Step>
|
||||
## Initialize Better Auth Client
|
||||
|
||||
To initialize Better Auth in your Expo app, you need to call `createAuthClient` with the base url of your Better Auth backend. Make sure to import the client from `/react`.
|
||||
To initialize Better Auth in your Expo app, you need to call `createAuthClient` with the base URL of your Better Auth backend. Make sure to import the client from `/react`.
|
||||
|
||||
You need to also import client plugin from `@better-auth/expo/client` and pass it to the `plugins` array when initializing the auth client.
|
||||
|
||||
@@ -84,7 +84,7 @@ Expo is a popular framework for building cross-platform apps with React Native.
|
||||
import * as SecureStore from "expo-secure-store";
|
||||
|
||||
export const authClient = createAuthClient({
|
||||
baseURL: "http://localhost:8081", /* base url of your Better Auth backend. */
|
||||
baseURL: "http://localhost:8081", /* Base URL of your Better Auth backend. */
|
||||
plugins: [
|
||||
expoClient({
|
||||
scheme: "myapp",
|
||||
@@ -126,7 +126,7 @@ Expo is a popular framework for building cross-platform apps with React Native.
|
||||
<Step>
|
||||
## Configure Metro Bundler
|
||||
|
||||
To resolve better auth exports you'll need to enable `unstable_enablePackageExports` in your metro config.
|
||||
To resolve Better Auth exports you'll need to enable `unstable_enablePackageExports` in your metro config.
|
||||
|
||||
```js title="metro.config.js"
|
||||
const { getDefaultConfig } = require("expo/metro-config");
|
||||
|
||||
@@ -73,7 +73,7 @@ Here's an example of how to use `getSession` in an Express route:
|
||||
|
||||
```ts title="server.ts"
|
||||
import { fromNodeHeaders } from "better-auth/node";
|
||||
import { auth } from "./auth"; //your better auth instance
|
||||
import { auth } from "./auth"; // Your Better Auth instance
|
||||
|
||||
app.get("/api/me", async (req, res) => {
|
||||
const session = await auth.api.getSession({
|
||||
|
||||
@@ -78,7 +78,7 @@ npx prisma db push
|
||||
|
||||
Follow steps 1 & 2 from the [installation guide](/docs/installation) to install Better Auth in your Nitro application & set up the environment variables.
|
||||
|
||||
Once that is done, create your better auth instance within the `server/utils/auth.ts` file.
|
||||
Once that is done, create your Better Auth instance within the `server/utils/auth.ts` file.
|
||||
|
||||
```ts title="server/utils/auth.ts"
|
||||
import { betterAuth } from "better-auth";
|
||||
|
||||
@@ -56,7 +56,7 @@ const session = authClient.useSession()
|
||||
<button v-if="!session?.data" @click="() => authClient.signIn.social({
|
||||
provider: 'github'
|
||||
})">
|
||||
Continue with github
|
||||
Continue with GitHub
|
||||
</button>
|
||||
<div>
|
||||
<pre>{{ session.data }}</pre>
|
||||
@@ -127,5 +127,5 @@ export default defineNuxtRouteMiddleware(async (to, from) => {
|
||||
### Resources & Examples
|
||||
|
||||
- [Nuxt and Nuxt Hub example](https://github.com/atinux/nuxthub-better-auth) on GitHub.
|
||||
- [NuxtZzle is Nuxt,Drizzle ORM example](https://github.com/leamsigc/nuxt-better-auth-drizzle) on github [preview](https://nuxt-better-auth.giessen.dev/)
|
||||
- [NuxtZzle is Nuxt,Drizzle ORM example](https://github.com/leamsigc/nuxt-better-auth-drizzle) on GitHub [preview](https://nuxt-better-auth.giessen.dev/)
|
||||
- [Nuxt example](https://stackblitz.com/github/better-auth/better-auth/tree/main/examples/nuxt-example) on StackBlitz.
|
||||
|
||||
@@ -61,7 +61,7 @@ Some of the actions are reactive. The client use [nano-store](https://github.com
|
||||
});
|
||||
}}
|
||||
>
|
||||
Continue with github
|
||||
Continue with GitHub
|
||||
</button>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
@@ -7,7 +7,7 @@ Better Auth is a framework-agnostic authentication and authorization framework f
|
||||
|
||||
## Why Better Auth?
|
||||
|
||||
*Authentication in the TypeScript ecosystem has long been a half-solved problem. Other open-source libraries often require a lot of additional code for anything beyond basic authentication features. Rather than just pushing third-party services as the solution, I believe we can do better as a community—hence, Better Auth*
|
||||
*Authentication in the TypeScript ecosystem has long been a half-solved problem. Other open-source libraries often require a lot of additional code for anything beyond basic authentication features. Rather than just pushing third-party services as the solution, I believe we can do better as a community—hence, Better Auth.*
|
||||
|
||||
## Features
|
||||
|
||||
|
||||
@@ -535,7 +535,7 @@ console.log(apiKey.metadata.plan); // "premium"
|
||||
|
||||
`apiKeyHeaders` <span className="opacity-70">`string | string[];`</span>
|
||||
|
||||
The header name to check for api key. Default is `x-api-key`.
|
||||
The header name to check for API key. Default is `x-api-key`.
|
||||
|
||||
|
||||
`customAPIKeyGetter` <span className="opacity-70">`(ctx: GenericEndpointContext) => string | null`</span>
|
||||
@@ -656,7 +656,7 @@ Customize the rate-limiting.
|
||||
|
||||
`schema` <span className="opacity-70">`InferOptionSchema<ReturnType<typeof apiKeySchema>>`</span>
|
||||
|
||||
Custom schema for the api key plugin.
|
||||
Custom schema for the API key plugin.
|
||||
|
||||
`disableSessionForAPIKeys` <span className="opacity-70">`boolean`</span>
|
||||
|
||||
@@ -687,7 +687,7 @@ Table: `apiKey`
|
||||
{
|
||||
name: "id",
|
||||
type: "string",
|
||||
description: "The ID of the api key.",
|
||||
description: "The ID of the API key.",
|
||||
isUnique: true,
|
||||
isPrimaryKey: true,
|
||||
},
|
||||
|
||||
@@ -3,7 +3,7 @@ title: Email OTP
|
||||
description: Email OTP plugin for Better Auth.
|
||||
---
|
||||
|
||||
The Email OTP plugin allows user to sign-in, verify their email, or reset their password using a one-time password (OTP) sent to their email address.
|
||||
The Email OTP plugin allows user to sign in, verify their email, or reset their password using a one-time password (OTP) sent to their email address.
|
||||
|
||||
|
||||
## Installation
|
||||
@@ -59,7 +59,7 @@ const { data, error } = await authClient.emailOtp.sendVerificationOtp({
|
||||
})
|
||||
```
|
||||
|
||||
### SignIn with OTP
|
||||
### Sign in with OTP
|
||||
|
||||
Once the user provides the OTP, you can sign in the user using the `signIn.emailOTP()` method.
|
||||
|
||||
|
||||
@@ -122,8 +122,8 @@ async function validateToken(token: string) {
|
||||
new URL('http://localhost:3000/api/auth/jwks')
|
||||
)
|
||||
const { payload } = await jwtVerify(token, JWKS, {
|
||||
issuer: 'http://localhost:3000', // Should match your JWT issuer which is the BASE_URL
|
||||
audience: 'http://localhost:3000', // Should match your JWT audience which is the BASE_URL by default
|
||||
issuer: 'http://localhost:3000', // Should match your JWT issuer, which is the BASE_URL
|
||||
audience: 'http://localhost:3000', // Should match your JWT audience, which is the BASE_URL by default
|
||||
})
|
||||
return payload
|
||||
} catch (error) {
|
||||
@@ -158,8 +158,8 @@ async function validateToken(token: string) {
|
||||
keys: storedJWKS.data?.keys!,
|
||||
})
|
||||
const { payload } = await jwtVerify(token, JWKS, {
|
||||
issuer: 'http://localhost:3000', // Should match your JWT issuer which is the BASE_URL
|
||||
audience: 'http://localhost:3000', // Should match your JWT audience which is the BASE_URL by default
|
||||
issuer: 'http://localhost:3000', // Should match your JWT issuer, which is the BASE_URL
|
||||
audience: 'http://localhost:3000', // Should match your JWT audience, which is the BASE_URL by default
|
||||
})
|
||||
return payload
|
||||
} catch (error) {
|
||||
|
||||
@@ -70,7 +70,7 @@ When you send the URL generated by the `sendMagicLink` function to a user, click
|
||||
If no `callbackURL` is provided, the user will be redirected to the root URL.
|
||||
</Callout>
|
||||
|
||||
If you want to handle the verification manually, (e.g, if you send the user a different url), you can use the `verify` function.
|
||||
If you want to handle the verification manually, (e.g, if you send the user a different URL), you can use the `verify` function.
|
||||
|
||||
```ts title="magic-link.ts"
|
||||
const { data, error } = await authClient.magicLink.verify({
|
||||
@@ -85,8 +85,8 @@ const { data, error } = await authClient.magicLink.verify({
|
||||
**sendMagicLink**: The `sendMagicLink` function is called when a user requests a magic link. It takes an object with the following properties:
|
||||
|
||||
- `email`: The email address of the user.
|
||||
- `url`: The url to be sent to the user. This url contains the token.
|
||||
- `token`: The token if you want to send the token with custom url.
|
||||
- `url`: The URL to be sent to the user. This URL contains the token.
|
||||
- `token`: The token if you want to send the token with custom URL.
|
||||
|
||||
and a `request` object as the second parameter.
|
||||
|
||||
|
||||
@@ -58,7 +58,7 @@ await authClient.signIn.social({
|
||||
When the OAuth provider returns the user to your server, the plugin automatically redirects them to the intended callback URL.
|
||||
|
||||
<Callout>
|
||||
To share cookies between the proxy server and your main server it uses url query parameters to pass the cookies encrypted in the URL. This is secure as the cookies are encrypted and can only be decrypted by the server.
|
||||
To share cookies between the proxy server and your main server it uses URL query parameters to pass the cookies encrypted in the URL. This is secure as the cookies are encrypted and can only be decrypted by the server.
|
||||
</Callout>
|
||||
|
||||
## Options
|
||||
|
||||
@@ -5,7 +5,7 @@ description: Passkey
|
||||
|
||||
Passkeys are a secure, passwordless authentication method using cryptographic key pairs, supported by WebAuthn and FIDO2 standards in web browsers. They replace passwords with unique key pairs: a private key stored on the user’s device and a public key shared with the website. Users can log in using biometrics, PINs, or security keys, providing strong, phishing-resistant authentication without traditional passwords.
|
||||
|
||||
The passkey plugin implementation is powered by [simple-web-authn](https://simplewebauthn.dev/) behind the scenes.
|
||||
The passkey plugin implementation is powered by [SimpleWebAuthn](https://simplewebauthn.dev/) behind the scenes.
|
||||
|
||||
## Installation
|
||||
|
||||
@@ -20,7 +20,7 @@ The passkey plugin implementation is powered by [simple-web-authn](https://simpl
|
||||
|
||||
`rpName`: Human-readable title for your website
|
||||
|
||||
`origin`: The URL at which registrations and authentications should occur. 'http://localhost' and 'http://localhost:PORT' are also valid. Do **NOT** include any trailing /
|
||||
`origin`: The URL at which registrations and authentications should occur. `http://localhost` and `http://localhost:PORT` are also valid. Do **NOT** include any trailing /
|
||||
|
||||
`authenticatorSelection`: Allows customization of WebAuthn authenticator selection criteria. Leave unspecified for default settings.
|
||||
- `authenticatorAttachment`: Specifies the type of authenticator
|
||||
@@ -109,7 +109,7 @@ const { data, error } = await authClient.passkey.addPasskey();
|
||||
|
||||
This will prompt the user to register a passkey. And it'll add the passkey to the user's account.
|
||||
|
||||
You can also specify the type of authenticator you want to register. The authenticatorAttachment can be either `platform` or `cross-platform`.
|
||||
You can also specify the type of authenticator you want to register. The `authenticatorAttachment` can be either `platform` or `cross-platform`.
|
||||
|
||||
```ts title="auth-client.ts"
|
||||
// Register a cross-platform passkey showing only a QR code
|
||||
@@ -119,9 +119,9 @@ const { data, error } = await authClient.passkey.addPasskey({
|
||||
});
|
||||
```
|
||||
|
||||
### Signin with a passkey
|
||||
### Sign in with a passkey
|
||||
|
||||
To signin with a passkey you can use the passkeySignIn method. This will prompt the user to sign in with their passkey.
|
||||
To sign in with a passkey you can use the passkeySignIn method. This will prompt the user to sign in with their passkey.
|
||||
|
||||
Signin method accepts:
|
||||
|
||||
@@ -267,6 +267,6 @@ Table Name: `passkey`
|
||||
|
||||
**rpName**: Human-readable title for your website.
|
||||
|
||||
**origin**: The URL at which registrations and authentications should occur. 'http://localhost' and 'http://localhost:PORT' are also valid. Do NOT include any trailing /.
|
||||
**origin**: The URL at which registrations and authentications should occur. `http://localhost` and `http://localhost:PORT` are also valid. Do NOT include any trailing /.
|
||||
|
||||
**authenticatorSelection**: Allows customization of WebAuthn authenticator selection criteria. When unspecified, both platform and cross-platform authenticators are allowed with `preferred` settings for `residentKey` and `userVerification`.
|
||||
@@ -111,7 +111,7 @@ export const auth = betterAuth({
|
||||
})
|
||||
```
|
||||
|
||||
### SignIn with Phone number
|
||||
### Sign In with Phone Number
|
||||
|
||||
In addition to signing in a user using send-verify flow, you can also use phone number as an identifier and sign in a user using phone number and password.
|
||||
|
||||
|
||||
@@ -170,7 +170,7 @@ const res = await authClient.signIn.sso({
|
||||
});
|
||||
```
|
||||
|
||||
To use the server api you can use `signInSSO`
|
||||
To use the server API you can use `signInSSO`
|
||||
|
||||
```ts title="sign-in-org.ts"
|
||||
const res = await auth.api.signInSSO({
|
||||
@@ -216,7 +216,7 @@ The plugin requires additional fields in the `ssoProvider` table to store the pr
|
||||
{ name: "domain", type: "string", description: "The domain of the provider", isRequired: true },
|
||||
{ name: "oidcConfig", type: "string", description: "The OIDC configuration", isRequired: false },
|
||||
{ name: "userId", type: "string", description: "The user id", isRequired: true, references: { model: "user", field: "id" } },
|
||||
{ name: "providerId", type: "string", description: "The provider id. Used to identify a provider and to generate a redirect url.", isRequired: true, isUnique: true },
|
||||
{ name: "providerId", type: "string", description: "The provider id. Used to identify a provider and to generate a redirect URL.", isRequired: true, isUnique: true },
|
||||
{ name: "organizationId", type: "string", description: "The organization Id. If provider is linked to an organization.", isRequired: false },
|
||||
]}
|
||||
/>
|
||||
|
||||
@@ -59,7 +59,7 @@ The username plugin wraps the email and password authenticator and adds username
|
||||
|
||||
## Usage
|
||||
|
||||
### Signup with username
|
||||
### Sign up with username
|
||||
|
||||
To sign up a user with username, you can use the existing `signUp.email` function provided by the client. The `signUp` function should take a new `username` property in the object.
|
||||
|
||||
@@ -72,9 +72,9 @@ const data = await authClient.signUp.email({
|
||||
})
|
||||
```
|
||||
|
||||
### Signin with username
|
||||
### Sign in with username
|
||||
|
||||
To signin a user with username, you can use the `signIn.username` function provided by the client. The `signIn` function takes an object with the following properties:
|
||||
To sign in a user with username, you can use the `signIn.username` function provided by the client. The `signIn` function takes an object with the following properties:
|
||||
|
||||
- `username`: The username of the user.
|
||||
- `password`: The password of the user.
|
||||
|
||||
@@ -137,7 +137,7 @@ We welcome contributions to support more frameworks:
|
||||
|
||||
- Fix typos and errors
|
||||
- Add examples and clarify existing content
|
||||
- Ensure documentation is up-to-date with code changes
|
||||
- Ensure documentation is up to date with code changes
|
||||
|
||||
## Testing
|
||||
|
||||
|
||||
@@ -78,7 +78,7 @@ For all other situations where you shouldn't use `useSession`, is when you shoul
|
||||
</Callout>
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Common Typescript Errors">
|
||||
<Accordion title="Common TypeScript Errors">
|
||||
If you're facing typescript errors, make sure your tsconfig has `strict` set to `true`:
|
||||
```json title="tsconfig.json"
|
||||
{
|
||||
@@ -97,7 +97,7 @@ if you can't set strict to true, you can enable strictNullChecks:
|
||||
}
|
||||
```
|
||||
|
||||
You can learn more in our <Link href="/docs/concepts/typescript#typescript-config">Typescript docs</Link>.
|
||||
You can learn more in our <Link href="/docs/concepts/typescript#typescript-config">TypeScript docs</Link>.
|
||||
</Accordion>
|
||||
|
||||
</Accordions>
|
||||
|
||||
@@ -59,7 +59,7 @@ export default function Index() {
|
||||
}}
|
||||
>
|
||||
<Ionicons name="github" size={16} />
|
||||
<Text>Sign In with Github</Text>
|
||||
<Text>Sign In with GitHub</Text>
|
||||
</Button>
|
||||
</View>
|
||||
<View className="flex-row gap-2 w-full items-center px-6 my-4">
|
||||
|
||||
@@ -43,7 +43,7 @@ const { data: session } = await useSession(useFetch);
|
||||
<div class="border-y py-2 border-dotted bg-secondary/60 opacity-80">
|
||||
<div class="text-xs flex items-center gap-2 justify-center text-muted-foreground">
|
||||
<span class="text-center">
|
||||
All features on this demo are Implemented with better auth without
|
||||
All features on this demo are Implemented with Better Auth without
|
||||
any custom backend code
|
||||
</span>
|
||||
</div>
|
||||
|
||||
@@ -31,7 +31,7 @@ $: to = $session.data ? "/dashboard" : "/sign-in";
|
||||
class="text-xs flex items-center gap-2 justify-center text-muted-foreground"
|
||||
>
|
||||
<span class="text-center">
|
||||
All features on this demo are Implemented with better auth without
|
||||
All features on this demo are Implemented with Better Auth without
|
||||
any custom backend code
|
||||
</span>
|
||||
</div>
|
||||
|
||||
@@ -518,7 +518,7 @@ describe("api-key", async () => {
|
||||
expect(apiKey.metadata.test).toEqual(metadata.test);
|
||||
});
|
||||
|
||||
it("create api key with with metadata when metadata is disabled (should fail)", async () => {
|
||||
it("create API key with with metadata when metadata is disabled (should fail)", async () => {
|
||||
const { client, auth, signInWithTestUser } = await getTestInstance(
|
||||
{
|
||||
plugins: [
|
||||
@@ -673,7 +673,7 @@ describe("api-key", async () => {
|
||||
// VERIFY API KEY
|
||||
// =========================================================================
|
||||
|
||||
it("verify api key without key and userId", async () => {
|
||||
it("verify API key without key and userId", async () => {
|
||||
const apiKey = await auth.api.verifyApiKey({
|
||||
body: {
|
||||
key: firstApiKey.key,
|
||||
@@ -683,7 +683,7 @@ describe("api-key", async () => {
|
||||
expect(apiKey.valid).toBe(true);
|
||||
});
|
||||
|
||||
it("verify api key with invalid key (should fail)", async () => {
|
||||
it("verify API key with invalid key (should fail)", async () => {
|
||||
const apiKey = await auth.api.verifyApiKey({
|
||||
body: {
|
||||
key: "invalid",
|
||||
@@ -719,7 +719,7 @@ describe("api-key", async () => {
|
||||
|
||||
const { headers: rateLimitUserHeaders } = await rateLimitTestUser();
|
||||
|
||||
it("should fail to verify api key 20 times in a row due to rate-limit", async () => {
|
||||
it("should fail to verify API key 20 times in a row due to rate-limit", async () => {
|
||||
const { data: apiKey2 } = await rateLimitClient.apiKey.create(
|
||||
{},
|
||||
{ headers: rateLimitUserHeaders },
|
||||
@@ -741,7 +741,7 @@ describe("api-key", async () => {
|
||||
}
|
||||
});
|
||||
|
||||
it("should allow us to verify api key after rate-limit window has passed", async () => {
|
||||
it("should allow us to verify API key after rate-limit window has passed", async () => {
|
||||
vi.useFakeTimers();
|
||||
await vi.advanceTimersByTimeAsync(1000);
|
||||
const response = await rateLimitAuth.api.verifyApiKey({
|
||||
@@ -754,7 +754,7 @@ describe("api-key", async () => {
|
||||
expect(response?.valid).toBe(true);
|
||||
});
|
||||
|
||||
it("should check if verifying an api key's remaining count does go down", async () => {
|
||||
it("should check if verifying an API key's remaining count does go down", async () => {
|
||||
const remaining = 10;
|
||||
const { data: apiKey } = await client.apiKey.create(
|
||||
{
|
||||
@@ -781,7 +781,7 @@ describe("api-key", async () => {
|
||||
expect(afterVerificationTwice?.key?.remaining).toEqual(remaining - 2);
|
||||
});
|
||||
|
||||
it("should fail if the api key has no remaining", async () => {
|
||||
it("should fail if the API key has no remaining", async () => {
|
||||
const apiKey = await auth.api.createApiKey({
|
||||
body: {
|
||||
remaining: 1,
|
||||
@@ -805,7 +805,7 @@ describe("api-key", async () => {
|
||||
expect(afterVerification.error?.code).toBe("USAGE_EXCEEDED");
|
||||
});
|
||||
|
||||
it("should fail if the api key is expired", async () => {
|
||||
it("should fail if the API key is expired", async () => {
|
||||
vi.useRealTimers();
|
||||
const { headers } = await signInWithTestUser();
|
||||
const apiKey2 = await client.apiKey.create(
|
||||
@@ -830,7 +830,7 @@ describe("api-key", async () => {
|
||||
// UPDATE API KEY
|
||||
// =========================================================================
|
||||
|
||||
it("should fail to update api key name without headers or userId", async () => {
|
||||
it("should fail to update API key name without headers or userId", async () => {
|
||||
let error: APIError | null = null;
|
||||
await auth.api
|
||||
.updateApiKey({
|
||||
@@ -846,7 +846,7 @@ describe("api-key", async () => {
|
||||
expect(error).toBeInstanceOf(APIError);
|
||||
});
|
||||
|
||||
it("should update api key name with headers", async () => {
|
||||
it("should update API key name with headers", async () => {
|
||||
const newName = "Hello World";
|
||||
const apiKey = await auth.api.updateApiKey({
|
||||
body: {
|
||||
@@ -860,7 +860,7 @@ describe("api-key", async () => {
|
||||
expect(apiKey.name).toEqual(newName);
|
||||
});
|
||||
|
||||
it("should fail to update api key name with a length larger than the allowed maximum", async () => {
|
||||
it("should fail to update API key name with a length larger than the allowed maximum", async () => {
|
||||
let error: APIError | null = null;
|
||||
await auth.api
|
||||
.updateApiKey({
|
||||
@@ -880,7 +880,7 @@ describe("api-key", async () => {
|
||||
expect(error).not.toBeNull();
|
||||
});
|
||||
|
||||
it("should fail to update api key name with a length smaller than the allowed minimum", async () => {
|
||||
it("should fail to update API key name with a length smaller than the allowed minimum", async () => {
|
||||
let error: APIError | null = null;
|
||||
await auth.api
|
||||
.updateApiKey({
|
||||
@@ -900,7 +900,7 @@ describe("api-key", async () => {
|
||||
expect(error).not.toBeNull();
|
||||
});
|
||||
|
||||
it("should fail to update api key with no values to update", async () => {
|
||||
it("should fail to update API key with no values to update", async () => {
|
||||
let error: APIError | null = null;
|
||||
await auth.api
|
||||
.updateApiKey({
|
||||
@@ -919,7 +919,7 @@ describe("api-key", async () => {
|
||||
expect(error).not.toBeNull();
|
||||
});
|
||||
|
||||
it("should update api key expiresIn value", async () => {
|
||||
it("should update API key expiresIn value", async () => {
|
||||
const expiresIn = 60 * 60 * 24 * 7; // 7 days
|
||||
const expectedResult = new Date().getTime() + expiresIn;
|
||||
const apiKey = await auth.api.updateApiKey({
|
||||
@@ -1156,7 +1156,7 @@ describe("api-key", async () => {
|
||||
expect(apiKey.refillAmount).toEqual(refillAmount);
|
||||
});
|
||||
|
||||
it("should update api key enable value", async () => {
|
||||
it("should update API key enable value", async () => {
|
||||
const newValue = false;
|
||||
const apiKey = await auth.api.updateApiKey({
|
||||
body: {
|
||||
@@ -1211,7 +1211,7 @@ describe("api-key", async () => {
|
||||
expect(apiKey.metadata).toEqual(metadata);
|
||||
});
|
||||
|
||||
it("update api key's returned metadata should be an object", async () => {
|
||||
it("update API key's returned metadata should be an object", async () => {
|
||||
const metadata = {
|
||||
test: "test-12345",
|
||||
};
|
||||
@@ -1334,7 +1334,7 @@ describe("api-key", async () => {
|
||||
expect(session?.session).toBeDefined();
|
||||
});
|
||||
|
||||
it("should get session from an API key with custom api key getter", async () => {
|
||||
it("should get session from an API key with custom API key getter", async () => {
|
||||
const { client, auth, signInWithTestUser } = await getTestInstance(
|
||||
{
|
||||
plugins: [
|
||||
@@ -1367,7 +1367,7 @@ describe("api-key", async () => {
|
||||
expect(session?.session).toBeDefined();
|
||||
});
|
||||
|
||||
it("should fail to get session from an API key with invalid api key", async () => {
|
||||
it("should fail to get session from an API key with invalid API key", async () => {
|
||||
const headers = new Headers();
|
||||
headers.set("x-api-key", "invalid");
|
||||
|
||||
|
||||
@@ -85,7 +85,7 @@ export function verifyApiKey({
|
||||
],
|
||||
});
|
||||
|
||||
// No api key found
|
||||
// No API key found
|
||||
if (!apiKey) {
|
||||
return ctx.json({
|
||||
valid: false,
|
||||
|
||||
@@ -3,16 +3,16 @@ import type { Statements } from "../access";
|
||||
import type { apiKeySchema } from "./schema";
|
||||
export interface ApiKeyOptions {
|
||||
/**
|
||||
* The header name to check for api key
|
||||
* The header name to check for API key
|
||||
* @default "x-api-key"
|
||||
*/
|
||||
apiKeyHeaders?: string | string[];
|
||||
/**
|
||||
* The function to get the api key from the context
|
||||
* The function to get the API key from the context
|
||||
*/
|
||||
customAPIKeyGetter?: (ctx: GenericEndpointContext) => string | null;
|
||||
/**
|
||||
* A custom function to validate the api key
|
||||
* A custom function to validate the API key
|
||||
*/
|
||||
customAPIKeyValidator?: (options: {
|
||||
ctx: GenericEndpointContext;
|
||||
@@ -154,7 +154,7 @@ export interface ApiKeyOptions {
|
||||
maxRequests?: number;
|
||||
};
|
||||
/**
|
||||
* custom schema for the api key plugin
|
||||
* custom schema for the API key plugin
|
||||
*/
|
||||
schema?: InferOptionSchema<ReturnType<typeof apiKeySchema>>;
|
||||
/**
|
||||
@@ -242,7 +242,7 @@ export type ApiKey = {
|
||||
*/
|
||||
requestCount: number;
|
||||
/**
|
||||
* Remaining requests (every time api key is used this should updated and should be updated on refill as well)
|
||||
* Remaining requests (every time API key is used this should updated and should be updated on refill as well)
|
||||
*/
|
||||
remaining: number | null;
|
||||
/**
|
||||
@@ -266,7 +266,7 @@ export type ApiKey = {
|
||||
*/
|
||||
metadata: Record<string, any> | null;
|
||||
/**
|
||||
* Permissions for the api key
|
||||
* Permissions for the API key
|
||||
*/
|
||||
permissions?: {
|
||||
[key: string]: string[];
|
||||
|
||||
@@ -101,7 +101,7 @@ describe("magic link", async () => {
|
||||
);
|
||||
});
|
||||
|
||||
it("should signup with magic link", async () => {
|
||||
it("should sign up with magic link", async () => {
|
||||
const email = "new-email@email.com";
|
||||
await client.signIn.magicLink({
|
||||
email,
|
||||
|
||||
@@ -7,7 +7,7 @@ describe("open-api", async (it) => {
|
||||
plugins: [openAPI()],
|
||||
});
|
||||
|
||||
it("should generate open api schema", async () => {
|
||||
it("should generate OpenAPI schema", async () => {
|
||||
const schema = await auth.api.generateOpenAPISchema();
|
||||
expect(schema).toBeDefined();
|
||||
});
|
||||
|
||||
@@ -661,7 +661,7 @@ describe("organization", async (it) => {
|
||||
name: "name",
|
||||
};
|
||||
|
||||
// test api method
|
||||
// test API method
|
||||
const newUser = await auth.api.signUpEmail({
|
||||
body: {
|
||||
email: userOverLimit.email,
|
||||
|
||||
@@ -55,7 +55,7 @@ export interface PasskeyOptions {
|
||||
rpName?: string;
|
||||
/**
|
||||
* The URL at which registrations and authentications should occur.
|
||||
* 'http://localhost' and 'http://localhost:PORT' are also valid.
|
||||
* `http://localhost` and `http://localhost:PORT` are also valid.
|
||||
* Do NOT include any trailing /
|
||||
*
|
||||
* if this isn't provided. The client itself will
|
||||
|
||||
@@ -140,7 +140,7 @@ describe("SSO", async () => {
|
||||
}
|
||||
});
|
||||
|
||||
it("should signin with SSO provider with email matching", async () => {
|
||||
it("should sign in with SSO provider with email matching", async () => {
|
||||
const res = await auth.api.signInSSO({
|
||||
body: {
|
||||
email: "my-email@localhost.com",
|
||||
@@ -156,7 +156,7 @@ describe("SSO", async () => {
|
||||
expect(callbackURL).toContain("/dashboard");
|
||||
});
|
||||
|
||||
it("should signin with SSO provider with domain", async () => {
|
||||
it("should sign in with SSO provider with domain", async () => {
|
||||
const res = await auth.api.signInSSO({
|
||||
body: {
|
||||
email: "my-email@test.com",
|
||||
@@ -173,7 +173,7 @@ describe("SSO", async () => {
|
||||
expect(callbackURL).toContain("/dashboard");
|
||||
});
|
||||
|
||||
it("should signin with SSO provider with providerId", async () => {
|
||||
it("should sign in with SSO provider with providerId", async () => {
|
||||
const res = await auth.api.signInSSO({
|
||||
body: {
|
||||
providerId: "test",
|
||||
@@ -463,7 +463,7 @@ describe("provisioning", async (ctx) => {
|
||||
});
|
||||
});
|
||||
|
||||
it("should signin with SSO provide with org slug", async () => {
|
||||
it("should sign in with SSO provide with org slug", async () => {
|
||||
const res = await auth.api.signInSSO({
|
||||
body: {
|
||||
organizationSlug: "localhost",
|
||||
|
||||
@@ -424,7 +424,7 @@ describe("two factor", async () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("two factor auth api", async () => {
|
||||
describe("two factor auth API", async () => {
|
||||
let OTP = "";
|
||||
const sendOTP = vi.fn();
|
||||
const { auth, signInWithTestUser, testUser } = await getTestInstance({
|
||||
|
||||
@@ -19,7 +19,7 @@ describe("username", async (it) => {
|
||||
},
|
||||
);
|
||||
|
||||
it("should signup with username", async () => {
|
||||
it("should sign up with username", async () => {
|
||||
const headers = new Headers();
|
||||
await client.signUp.email(
|
||||
{
|
||||
|
||||
@@ -13,9 +13,9 @@ export interface RobloxProfile extends Record<string, any> {
|
||||
name: string;
|
||||
/** the account creation date as a unix timestamp in seconds */
|
||||
created_at: number;
|
||||
/** the user's profile url */
|
||||
/** the user's profile URL */
|
||||
profile: string;
|
||||
/** the user's avatar url */
|
||||
/** the user's avatar URL */
|
||||
picture: string;
|
||||
}
|
||||
|
||||
|
||||
@@ -215,7 +215,7 @@ describe("Social Providers", async (c) => {
|
||||
});
|
||||
});
|
||||
|
||||
it("should use callback url if the user is already registered", async () => {
|
||||
it("Should use callback URL if the user is already registered", async () => {
|
||||
const signInRes = await client.signIn.social({
|
||||
provider: "google",
|
||||
callbackURL: "/callback",
|
||||
|
||||
@@ -29,7 +29,7 @@ export type BetterAuthOptions = {
|
||||
*/
|
||||
appName?: string;
|
||||
/**
|
||||
* Base URL for the better auth. This is typically the
|
||||
* Base URL for the Better Auth. This is typically the
|
||||
* root URL where your application server is hosted.
|
||||
* If not explicitly set,
|
||||
* the system will check the following environment variable:
|
||||
@@ -40,9 +40,9 @@ export type BetterAuthOptions = {
|
||||
*/
|
||||
baseURL?: string;
|
||||
/**
|
||||
* Base path for the better auth. This is typically
|
||||
* Base path for the Better Auth. This is typically
|
||||
* the path where the
|
||||
* better auth routes are mounted.
|
||||
* Better Auth routes are mounted.
|
||||
*
|
||||
* @default "/api/auth"
|
||||
*/
|
||||
@@ -51,7 +51,7 @@ export type BetterAuthOptions = {
|
||||
* The secret to use for encryption,
|
||||
* signing and hashing.
|
||||
*
|
||||
* By default better auth will look for
|
||||
* By default Better Auth will look for
|
||||
* the following environment variables:
|
||||
* process.env.BETTER_AUTH_SECRET,
|
||||
* process.env.AUTH_SECRET
|
||||
@@ -125,7 +125,7 @@ export type BetterAuthOptions = {
|
||||
/**
|
||||
* @param user the user to send the
|
||||
* verification email to
|
||||
* @param url the url to send the verification email to
|
||||
* @param url the URL to send the verification email to
|
||||
* it contains the token as well
|
||||
* @param token the token to send the verification email to
|
||||
*/
|
||||
@@ -207,7 +207,7 @@ export type BetterAuthOptions = {
|
||||
/**
|
||||
* @param user the user to send the
|
||||
* reset password email to
|
||||
* @param url the url to send the reset password email to
|
||||
* @param url the URL to send the reset password email to
|
||||
* @param token the token to send to the user (could be used instead of sending the url
|
||||
* if you need to redirect the user to custom route)
|
||||
*/
|
||||
@@ -938,9 +938,9 @@ export type BetterAuthOptions = {
|
||||
*/
|
||||
onError?: (error: unknown, ctx: AuthContext) => void | Promise<void>;
|
||||
/**
|
||||
* The url to redirect to on error
|
||||
* The URL to redirect to on error
|
||||
*
|
||||
* When errorURL is provided, the error will be added to the url as a query parameter
|
||||
* When errorURL is provided, the error will be added to the URL as a query parameter
|
||||
* and the user will be redirected to the errorURL.
|
||||
*
|
||||
* @default - "/api/auth/error"
|
||||
|
||||
@@ -28,7 +28,7 @@ import { generateAuthConfig } from "../generators/auth-config";
|
||||
import { getTsconfigInfo } from "../utils/get-tsconfig-info";
|
||||
|
||||
/**
|
||||
* Should only use any database that is core DBs, and supports the BetterAuth CLI generate functionality.
|
||||
* Should only use any database that is core DBs, and supports the Better Auth CLI generate functionality.
|
||||
*/
|
||||
const supportedDatabases = [
|
||||
// Built-in kysely
|
||||
@@ -549,7 +549,7 @@ export async function initAction(opts: any) {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
s.stop(`Better Auth dependencies are ${chalk.greenBright(`up-to-date`)}!`);
|
||||
s.stop(`Better Auth dependencies are ${chalk.greenBright(`up to date`)}!`);
|
||||
}
|
||||
|
||||
// ===== appName =====
|
||||
|
||||
@@ -3,7 +3,7 @@ import type { BetterAuthOptions } from "better-auth";
|
||||
import { logger } from "better-auth";
|
||||
import path from "path";
|
||||
// @ts-ignore
|
||||
import babelPresetTypescript from "@babel/preset-typescript";
|
||||
import babelPresetTypeScript from "@babel/preset-typescript";
|
||||
// @ts-ignore
|
||||
import babelPresetReact from "@babel/preset-react";
|
||||
import fs, { existsSync } from "fs";
|
||||
@@ -72,7 +72,7 @@ const jitiOptions = (cwd: string) => {
|
||||
babel: {
|
||||
presets: [
|
||||
[
|
||||
babelPresetTypescript,
|
||||
babelPresetTypeScript,
|
||||
{
|
||||
isTSX: true,
|
||||
allExtensions: true,
|
||||
|
||||
@@ -3,7 +3,7 @@ import { createAuthMiddleware } from "better-auth/api";
|
||||
|
||||
export interface ExpoOptions {
|
||||
/**
|
||||
* Override origin header for expo api routes
|
||||
* Override origin header for expo API routes
|
||||
*/
|
||||
overrideOrigin?: boolean;
|
||||
}
|
||||
|
||||
@@ -145,12 +145,12 @@ export const stripe = <O extends StripeOptions>(options: O) => {
|
||||
})
|
||||
.optional(),
|
||||
/**
|
||||
* Success url to redirect back after successful subscription
|
||||
* Success URL to redirect back after successful subscription
|
||||
*/
|
||||
successUrl: z
|
||||
.string({
|
||||
description:
|
||||
"callback url to redirect back after successful subscription",
|
||||
"Callback URL to redirect back after successful subscription",
|
||||
})
|
||||
.default("/"),
|
||||
/**
|
||||
@@ -159,7 +159,7 @@ export const stripe = <O extends StripeOptions>(options: O) => {
|
||||
cancelUrl: z
|
||||
.string({
|
||||
description:
|
||||
"callback url to redirect back after successful subscription",
|
||||
"Callback URL to redirect back after successful subscription",
|
||||
})
|
||||
.default("/"),
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user