From dd6528f45b5593f77ee3503abd760beb5605e651 Mon Sep 17 00:00:00 2001 From: Taesu <166604494+bytaesu@users.noreply.github.com> Date: Tue, 14 Apr 2026 20:36:59 +0900 Subject: [PATCH 1/8] docs(guides): move dynamic base url from concepts to guides and options (#9145) Co-authored-by: Maxwell <145994855+ping-maxwell@users.noreply.github.com> --- docs/components/sidebar-content.tsx | 12 +- docs/content/blogs/1-5.mdx | 2 +- .../docs/concepts/dynamic-base-url.mdx | 261 ------------------ docs/content/docs/guides/dynamic-base-url.mdx | 155 +++++++++++ docs/content/docs/reference/options.mdx | 39 ++- 5 files changed, 200 insertions(+), 269 deletions(-) delete mode 100644 docs/content/docs/concepts/dynamic-base-url.mdx create mode 100644 docs/content/docs/guides/dynamic-base-url.mdx diff --git a/docs/components/sidebar-content.tsx b/docs/components/sidebar-content.tsx index 785cbe5fca..801e3a588e 100644 --- a/docs/components/sidebar-content.tsx +++ b/docs/components/sidebar-content.tsx @@ -17,8 +17,8 @@ import { LucideAArrowDown, Mail, Mailbox, - Navigation, Phone, + Route, ScanFace, ScrollTextIcon, Server, @@ -446,11 +446,6 @@ export const contents: Content[] = [ ), }, - { - title: "Dynamic Base URL", - href: "/docs/concepts/dynamic-base-url", - icon: () => , - }, ], Icon: () => ( ), }, + { + title: "Dynamic Base URL", + href: "/docs/guides/dynamic-base-url", + icon: () => , + }, { title: "SAML SSO with Okta", href: "/docs/guides/saml-sso-with-okta", diff --git a/docs/content/blogs/1-5.mdx b/docs/content/blogs/1-5.mdx index 9586d2fe45..4e8bc2a86c 100644 --- a/docs/content/blogs/1-5.mdx +++ b/docs/content/blogs/1-5.mdx @@ -390,7 +390,7 @@ hooks: { Better Auth can now resolve the base URL dynamically from incoming requests, making it work seamlessly with Vercel preview deployments, multi-domain setups, and reverse proxies. -[👉 Read more about dynamic base URL](https://www.better-auth.com/docs/concepts/dynamic-base-url) +[👉 Read more about dynamic base URL](https://www.better-auth.com/docs/guides/dynamic-base-url) ```tsx import { betterAuth } from "better-auth"; diff --git a/docs/content/docs/concepts/dynamic-base-url.mdx b/docs/content/docs/concepts/dynamic-base-url.mdx deleted file mode 100644 index 5ea9bcccef..0000000000 --- a/docs/content/docs/concepts/dynamic-base-url.mdx +++ /dev/null @@ -1,261 +0,0 @@ ---- -title: Dynamic Base URL -description: Configure Better Auth to work with multiple domains and preview deployments. ---- - -When deploying to platforms like Vercel, your application can run on multiple URLs simultaneously: - -* Custom domains (e.g., `myapp.com`, `www.myapp.com`) -* Preview deployments (e.g., `my-app-abc123.vercel.app`) -* Branch previews (e.g., `feature-branch.myapp.com`) - -Better Auth supports dynamic base URL resolution using an **allowlist-based approach** that determines the correct URL from each incoming request. - -## Basic Usage - -Configure `baseURL` as an object with an `allowedHosts` array: - -```ts title="auth.ts" -import { betterAuth } from "better-auth" - -export const auth = betterAuth({ - baseURL: { - allowedHosts: [ - "myapp.com", - "www.myapp.com", - "*.vercel.app", - ], - }, -}) -``` - -When a request comes in, Better Auth extracts the host from the `x-forwarded-host` or `host` header and validates it against your allowlist. If the host matches, that URL is used as the base URL for the request. - -## Wildcard Patterns - -The `allowedHosts` array supports wildcard patterns: - -| Pattern | Matches | -| --------------------- | ----------------------------------- | -| `myapp.com` | Exact match only | -| `*.vercel.app` | Any subdomain of vercel.app | -| `preview-*.myapp.com` | Subdomains starting with `preview-` | -| `localhost:*` | localhost on any port | - -```ts title="auth.ts" -export const auth = betterAuth({ - baseURL: { - allowedHosts: [ - "myapp.com", // Production - "*.vercel.app", // All Vercel previews - "preview-*.myapp.com", // Custom preview subdomains - "localhost:3000", // Local development - ], - }, -}) -``` - -## Fallback URL - -By default, if the incoming host doesn't match any pattern in `allowedHosts`, Better Auth throws an error. You can provide a fallback URL instead: - -```ts title="auth.ts" -export const auth = betterAuth({ - baseURL: { - allowedHosts: ["myapp.com", "*.vercel.app"], - fallback: "https://myapp.com", - }, -}) -``` - -With a fallback configured: - -* Matching hosts use the derived URL -* Non-matching hosts use the fallback URL (no error thrown) - - - Use fallbacks carefully. Silent fallbacks can mask misconfigurations. Consider whether throwing an error (the default) is more appropriate for your use case. - - -## Protocol Configuration - -Control the protocol used when constructing URLs: - -```ts title="auth.ts" -export const auth = betterAuth({ - baseURL: { - allowedHosts: ["myapp.com", "localhost:3000"], - protocol: "https", // Always use HTTPS - }, -}) -``` - -| Value | Behavior | -| --------- | --------------------------------------------------------------------------------------------------- | -| `"https"` | Always use HTTPS | -| `"http"` | Always use HTTP | -| `"auto"` | Derive from `x-forwarded-proto` header, then request URL; defaults to HTTPS if neither is available | -| Not set | Same as `"auto"` | - - - The `protocol` setting controls how the **URL is constructed** for each request. For the cookie `Secure` flag, Better Auth uses `protocol: "https"` → secure, `protocol: "http"` → not secure, and for `"auto"` or unset → falls back to `NODE_ENV === "production"`. You can always override this with `advanced.useSecureCookies`. - - -For mixed environments (local dev + production), you can use environment variables: - -```ts title="auth.ts" -export const auth = betterAuth({ - baseURL: { - allowedHosts: ["myapp.com", "localhost:3000"], - protocol: process.env.NODE_ENV === "development" ? "http" : "https", - }, -}) -``` - -## Trusted Origins Integration - -When you configure `allowedHosts`, Better Auth automatically adds them to `trustedOrigins`. This means: - -```ts title="auth.ts" -export const auth = betterAuth({ - baseURL: { - allowedHosts: ["myapp.com", "*.vercel.app"], - }, -}) - -// Automatically adds to trustedOrigins: -// - "https://myapp.com" -// - "https://*.vercel.app" -``` - -You don't need to duplicate your allowed hosts in both configurations. - -## Static Base URL (Backwards Compatible) - -The traditional static string configuration still works: - -```ts title="auth.ts" -export const auth = betterAuth({ - baseURL: "https://myapp.com", -}) -``` - -This is recommended when your application runs on a single, known URL. - -## Common Patterns - -### Vercel Deployment - -```ts title="auth.ts" -export const auth = betterAuth({ - baseURL: { - allowedHosts: [ - "myapp.com", // Production custom domain - "www.myapp.com", // WWW variant - "*.vercel.app", // All preview deployments - ], - }, -}) -``` - -### Development + Production - -```ts title="auth.ts" -export const auth = betterAuth({ - baseURL: { - allowedHosts: [ - "localhost:3000", - "localhost:5173", - "myapp.com", - "*.vercel.app", - ], - protocol: process.env.NODE_ENV === "development" ? "http" : "https", - }, -}) -``` - -### Multiple Production Domains - -```ts title="auth.ts" -export const auth = betterAuth({ - baseURL: { - allowedHosts: [ - "myapp.com", - "myapp.co.uk", - "myapp.eu", - ], - }, -}) -``` - -## Cross-Subdomain Cookies - -If you need to share cookies across subdomains, you can enable `crossSubDomainCookies` without specifying a static `domain`. Better Auth automatically derives the cookie domain from the resolved host of each request. - -```ts title="auth.ts" -import { betterAuth } from "better-auth" - -export const auth = betterAuth({ - baseURL: { - allowedHosts: [ - "auth.example1.com", - "auth.example2.com", - ], - protocol: "https", - }, - advanced: { - crossSubDomainCookies: { - enabled: true, - }, - }, -}) -``` - -With this configuration: - -* A request to `auth.example1.com` sets cookies with `Domain=auth.example1.com` -* A request to `auth.example2.com` sets cookies with `Domain=auth.example2.com` - -If you want to use the same domain for all hosts, you can set `domain` explicitly: - -```ts title="auth.ts" -import { betterAuth } from "better-auth" - -export const auth = betterAuth({ - baseURL: { - allowedHosts: ["auth.example1.com", "auth.example2.com"], - protocol: "https", - }, - advanced: { - crossSubDomainCookies: { - enabled: true, - domain: ".example.com", // always use this domain regardless of host - }, - }, -}) -``` - - - With a static `baseURL` string, `crossSubDomainCookies` derives the domain from that string at init time. With dynamic base URL, the domain is computed per-request from the resolved host. Learn more about cross-subdomain cookies in the [Cookies](/docs/concepts/cookies#cross-subdomain-cookies) documentation. - - -## Security Considerations - - - Dynamic base URL uses an **allowlist-based approach** for security. Only hosts explicitly listed in `allowedHosts` are accepted. - - -1. **Allowlist is mandatory** - You cannot accept arbitrary hosts -2. **Headers are validated** - The `x-forwarded-host` and `host` headers are sanitized before use -3. **Explicit patterns only** - No automatic platform detection; you must add each pattern -4. **Clear errors** - Unknown hosts throw descriptive errors (unless fallback is set) - -This differs from some other auth libraries that auto-trust platforms or accept any header value. Better Auth prioritizes security over convenience. - -## Configuration Reference - -| Property | Type | Default | Description | -| -------------- | ----------------------------- | -------- | --------------------------------------------------------------------------------------- | -| `allowedHosts` | `string[]` | Required | List of allowed host patterns | -| `fallback` | `string` | - | URL to use when host doesn't match | -| `protocol` | `"http" \| "https" \| "auto"` | `"auto"` | Protocol for URL construction. `"auto"` derives from request headers, defaults to HTTPS | diff --git a/docs/content/docs/guides/dynamic-base-url.mdx b/docs/content/docs/guides/dynamic-base-url.mdx new file mode 100644 index 0000000000..f8763f6fe3 --- /dev/null +++ b/docs/content/docs/guides/dynamic-base-url.mdx @@ -0,0 +1,155 @@ +--- +title: Dynamic Base URL +description: Configure Better Auth for preview deployments, multiple domains, and per-request URL resolution. +--- + +Use dynamic base URL when your app is served from more than one hostname, such as: + +* custom domains like `myapp.com` and `www.myapp.com` +* preview deployments like `my-app-abc123.vercel.app` +* branch environments like `feature-branch.myapp.com` + +The configuration itself lives on the [`baseURL` option](/docs/reference/options#baseurl). This guide focuses on when to use it and how to structure it safely. + +## Basic Setup + +Configure `baseURL` as an object with an `allowedHosts` allowlist: + +```ts title="auth.ts" +import { betterAuth } from "better-auth" + +export const auth = betterAuth({ + baseURL: { + allowedHosts: [ + "myapp.com", + "www.myapp.com", + "*.vercel.app", + ], + }, +}) +``` + +When a request comes in, Better Auth extracts the host from `x-forwarded-host`, `host` header, or the request URL (in that order), validates it against `allowedHosts`, and uses the matched value to build the request-specific base URL. + +## Common Deployment Patterns + +### Vercel Deployment + +```ts title="auth.ts" +export const auth = betterAuth({ + baseURL: { + allowedHosts: [ + "myapp.com", + "www.myapp.com", + "*.vercel.app", + ], + }, +}) +``` + +### Development + Production + +```ts title="auth.ts" +export const auth = betterAuth({ + baseURL: { + allowedHosts: [ + "localhost:3000", + "localhost:5173", + "myapp.com", + "*.vercel.app", + ], + protocol: process.env.NODE_ENV === "development" ? "http" : "https", + }, +}) +``` + +### Multiple Production Domains + +```ts title="auth.ts" +export const auth = betterAuth({ + baseURL: { + allowedHosts: [ + "myapp.com", + "myapp.co.uk", + "myapp.eu", + ], + protocol: "https", + }, +}) +``` + +## Choosing a Fallback + +By default, Better Auth throws if the incoming host does not match `allowedHosts`. That is usually the safer default because it exposes proxy or deployment mistakes immediately. + +If you need a fallback, set one explicitly: + +```ts title="auth.ts" +export const auth = betterAuth({ + baseURL: { + allowedHosts: ["myapp.com", "*.vercel.app"], + fallback: "https://myapp.com", + }, +}) +``` + +Use this only when falling back to a canonical domain is clearly preferable to failing the request. + +## Cookies Across Subdomains + +If you need to share cookies across subdomains, you can enable `crossSubDomainCookies` while still using dynamic base URL. Better Auth will derive the cookie domain from the resolved host unless you set `domain` explicitly. + +```ts title="auth.ts" +import { betterAuth } from "better-auth" + +export const auth = betterAuth({ + baseURL: { + allowedHosts: [ + "auth.example1.com", + "auth.example2.com", + ], + protocol: "https", + }, + advanced: { + crossSubDomainCookies: { + enabled: true, + }, + }, +}) +``` + +If you want to force a shared parent domain instead, set it directly: + +```ts title="auth.ts" +import { betterAuth } from "better-auth" + +export const auth = betterAuth({ + baseURL: { + allowedHosts: ["auth.example1.com", "auth.example2.com"], + protocol: "https", + }, + advanced: { + crossSubDomainCookies: { + enabled: true, + domain: ".example.com", + }, + }, +}) +``` + +See [Cookies](/docs/concepts/cookies#cross-subdomain-cookies) for the full cookie behavior. + +## Security Model + +Dynamic base URL uses an allowlist model: + +1. Only hosts listed in `allowedHosts` are accepted +2. `x-forwarded-host` and `host` headers are sanitized and validated before use +3. Unknown hosts throw unless you provide `fallback` +4. `allowedHosts` are automatically added to [`trustedOrigins`](/docs/reference/options#trustedorigins) (localhost entries get both `http` and `https`) + +This keeps multi-domain support explicit instead of trusting arbitrary headers or platform-specific behavior. + +## Reference + +For the exact option shape and property-level behavior, see [`baseURL` in the options reference](/docs/reference/options#baseurl). diff --git a/docs/content/docs/reference/options.mdx b/docs/content/docs/reference/options.mdx index e24cb1f6c2..9305052fbb 100644 --- a/docs/content/docs/reference/options.mdx +++ b/docs/content/docs/reference/options.mdx @@ -20,7 +20,12 @@ export const auth = betterAuth({ ## `baseURL` -Base URL for Better Auth. This is typically the root URL where your application server is hosted. Note: If you include a path in the baseURL, it will take precedence over the default path. +Base URL for Better Auth. This is typically the root URL where your application server is hosted. You can configure it as either: + +* a static string for single-domain deployments +* an object for dynamic per-request resolution across multiple allowed hosts + +If you include a path in the baseURL string, it will take precedence over the default path. ```ts import { betterAuth } from "better-auth"; @@ -35,6 +40,38 @@ If not explicitly set, the system will check for the environment variable `BETTE Relying on request inference is not recommended. For security and stability, always set `baseURL` explicitly in your config or via the `BETTER_AUTH_URL` environment variable. +### Dynamic Base URL + +Use the object form when your app can be reached through multiple domains, such as preview deployments, branch environments, or multiple production hosts. Better Auth derives the host from the incoming request, validates it against `allowedHosts`, and constructs the request-specific base URL from that match. + +```ts +import { betterAuth } from "better-auth"; + +export const auth = betterAuth({ + baseURL: { + allowedHosts: [ + "myapp.com", + "www.myapp.com", + "*.vercel.app", + ], + protocol: "https", + fallback: "https://myapp.com", + }, +}) +``` + +* `allowedHosts`: List of accepted host patterns. Supports exact matches (`myapp.com`), wildcards (`*.vercel.app`, `preview-*.myapp.com`), and port wildcards (`localhost:*`). Automatically added to [`trustedOrigins`](#trustedorigins) (localhost entries get both `http` and `https`) +* `protocol`: Protocol for URL construction. `"http"`, `"https"`, or `"auto"` (default). `"auto"` derives from `x-forwarded-proto`, then request URL, then defaults to HTTPS. Also affects the cookie `Secure` flag: `"https"` → secure, `"http"` → not secure, `"auto"` or unset → `NODE_ENV === "production"`. Override with `advanced.useSecureCookies` +* `fallback`: URL to use when the incoming host does not match. Without it, unknown hosts throw. Its origin is also added to `trustedOrigins` + + + Use `fallback` carefully. It can hide deployment or proxy misconfiguration that would otherwise fail loudly. + + +When `crossSubDomainCookies` is enabled, the cookie domain is derived from the resolved request host unless you set `domain` explicitly. + +For deployment patterns and end-to-end examples, see the [Dynamic Base URL guide](/docs/guides/dynamic-base-url). + ## `basePath` Base path for Better Auth. This is typically the path where the Better Auth routes are mounted. It will be overridden if there is a path component within `baseURL`. From acbd6ef69f88ea54174446ac0465a426bad7ca09 Mon Sep 17 00:00:00 2001 From: Gautam Manchandani Date: Tue, 14 Apr 2026 18:35:11 +0530 Subject: [PATCH 2/8] fix: honor forceAllowId UUIDs on postgres adapters (#9068) Co-authored-by: Maxwell <145994855+ping-maxwell@users.noreply.github.com> --- .changeset/force-allow-id-uuid.md | 5 ++ .../adapter-factory/adapter-factory.test.ts | 35 +++++++++++++ packages/better-auth/src/db/db.test.ts | 51 +++++++++++++++++++ packages/core/src/db/adapter/get-id-field.ts | 4 +- 4 files changed, 93 insertions(+), 2 deletions(-) create mode 100644 .changeset/force-allow-id-uuid.md diff --git a/.changeset/force-allow-id-uuid.md b/.changeset/force-allow-id-uuid.md new file mode 100644 index 0000000000..83a5374f30 --- /dev/null +++ b/.changeset/force-allow-id-uuid.md @@ -0,0 +1,5 @@ +--- +"better-auth": patch +--- + +Fix forced UUID user IDs from create hooks being ignored on PostgreSQL adapters when `advanced.database.generateId` is set to `"uuid"`. diff --git a/e2e/adapter/test/adapter-factory/adapter-factory.test.ts b/e2e/adapter/test/adapter-factory/adapter-factory.test.ts index b0b3eeb5e8..6d1c56bbe8 100644 --- a/e2e/adapter/test/adapter-factory/adapter-factory.test.ts +++ b/e2e/adapter/test/adapter-factory/adapter-factory.test.ts @@ -232,6 +232,41 @@ describe("Create Adapter Helper", async () => { expect(ids.size).toBe(10); }); + test("Should preserve a forced UUID when the adapter supports native UUIDs", async () => { + const existingId = "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d"; + const adapter = await createTestAdapter({ + config: { + supportsUUIDs: true, + }, + options: { + advanced: { + database: { + generateId: "uuid", + }, + }, + }, + adapter() { + return { + async create(data) { + expect(data.data.id).toBe(existingId); + return data.data; + }, + }; + }, + }); + + const result = await adapter.create({ + model: "user", + data: { + id: existingId, + name: "test-name", + }, + forceAllowId: true, + }); + + expect(result.id).toBe(existingId); + }); + describe("Checking for the results of an adapter call, as well as the parameters passed into the adapter call", () => { describe("create", () => { test("Should fill in the missing fields in the result", async () => { diff --git a/packages/better-auth/src/db/db.test.ts b/packages/better-auth/src/db/db.test.ts index bb1f881bea..ec81734405 100644 --- a/packages/better-auth/src/db/db.test.ts +++ b/packages/better-auth/src/db/db.test.ts @@ -1,5 +1,6 @@ import { describe, expect, it, vi } from "vitest"; import { getTestInstance } from "../test-utils/test-instance"; +import type { User } from "../types"; describe("db", async () => { it("should work with custom model names", async () => { @@ -73,6 +74,56 @@ describe("db", async () => { expect(callback).toBe(true); }); + it("db hooks should preserve a forced UUID on postgres when generateId is uuid", async () => { + const existingId = "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d"; + const email = `forced-id-${crypto.randomUUID()}@test.com`; + const { auth, db } = await getTestInstance( + { + advanced: { + database: { + generateId: "uuid", + }, + }, + databaseHooks: { + user: { + create: { + async before(user) { + return { + data: { + ...user, + id: existingId, + }, + }; + }, + }, + }, + }, + }, + { + testWith: "postgres", + disableTestUser: true, + }, + ); + + const result = await auth.api.signUpEmail({ + body: { + email, + name: "forced-id-user", + password: "password", + }, + }); + + expect(result.user.id).toBe(existingId); + + const createdUser = await db.findOne({ + model: "user", + where: [{ field: "id", value: existingId }], + }); + + expect(createdUser?.id).toBe(existingId); + expect(createdUser?.email).toBe(email); + }); + it("should work with custom field names", async () => { const { client } = await getTestInstance({ user: { diff --git a/packages/core/src/db/adapter/get-id-field.ts b/packages/core/src/db/adapter/get-id-field.ts index c4f76a5d2c..3186c87536 100644 --- a/packages/core/src/db/adapter/get-id-field.ts +++ b/packages/core/src/db/adapter/get-id-field.ts @@ -108,8 +108,6 @@ export const initGetIdField = ({ // if it's generated by us, then we should return the value as is. if (shouldGenerateId && !forceAllowId) return value; if (disableIdGeneration) return undefined; - // if DB will handle UUID generation, then we should return undefined. - if (supportsUUIDs) return undefined; // if forceAllowId is true, it means we should be using the ID provided during the adapter call. if (forceAllowId && typeof value === "string") { const uuidRegex = @@ -129,6 +127,8 @@ export const initGetIdField = ({ ); } } + // if DB will handle UUID generation, then we should return undefined. + if (supportsUUIDs) return undefined; // if the value is not a string, and the database doesn't support generating it's own UUIDs, then we should be generating the UUID. if (typeof value !== "string" && !supportsUUIDs) { return crypto.randomUUID(); From 7be52d9403407378b9c2434d9f7419b51495b308 Mon Sep 17 00:00:00 2001 From: Jonathan Samines Date: Tue, 14 Apr 2026 14:21:36 -0600 Subject: [PATCH 3/8] docs: add docs email normalization on sentinel (#9188) --- .../docs/infrastructure/plugins/sentinel.mdx | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/docs/content/docs/infrastructure/plugins/sentinel.mdx b/docs/content/docs/infrastructure/plugins/sentinel.mdx index 02a1fd9460..7b5ce4b414 100644 --- a/docs/content/docs/infrastructure/plugins/sentinel.mdx +++ b/docs/content/docs/infrastructure/plugins/sentinel.mdx @@ -45,6 +45,7 @@ interface SecurityOptions { freeTrialAbuse?: FreeTrialAbuseConfig; compromisedPassword?: CompromisedPasswordConfig; emailValidation?: EmailValidationConfig; + emailNormalization?: { enabled?: boolean }; staleUsers?: StaleUsersConfig; challengeDifficulty?: number; } @@ -274,6 +275,26 @@ sentinel({ * `medium` - Also check for valid MX records * `high` - Additional heuristic checks +### Email normalization + +Sentinel can normalize email addresses before sign-up and sign-in so aliases and provider quirks do not create duplicate accounts or mismatched logins. Normalization includes lowercasing, stripping plus-address tags on common providers (for example `user+tag@gmail.com` → `user@gmail.com`), removing dots in Gmail-style addresses, and mapping `googlemail.com` to `gmail.com`. + +Use `security.emailNormalization` when you want to control this separately from disposable-domain validation (`emailValidation`): + +```ts +sentinel({ + apiKey: process.env.BETTER_AUTH_API_KEY, + security: { + emailValidation: { + enabled: false, // skip disposable / MX checks + }, + emailNormalization: { + enabled: true, // still normalize for deduplication and consistent sign-in + }, + }, +}), +``` + ## Proof-of-Work Challenges When a security check results in a "challenge" action, Sentinel issues a Proof-of-Work (PoW) challenge that must be solved by the client. From a0caa1f6f8b2b9028b2917c8515280426ed2dbe4 Mon Sep 17 00:00:00 2001 From: Taesu <166604494+bytaesu@users.noreply.github.com> Date: Wed, 15 Apr 2026 08:36:23 +0900 Subject: [PATCH 4/8] docs(device-authorization): fix approval page query param (#9197) --- docs/content/docs/plugins/device-authorization.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/content/docs/plugins/device-authorization.mdx b/docs/content/docs/plugins/device-authorization.mdx index e0432b1778..ac27ff2ecd 100644 --- a/docs/content/docs/plugins/device-authorization.mdx +++ b/docs/content/docs/plugins/device-authorization.mdx @@ -293,7 +293,7 @@ Users must be authenticated to approve or deny device authorization requests: export default function DeviceApprovalPage() { const { user } = useAuth(); // Must be authenticated const searchParams = useSearchParams(); - const userCode = searchParams.get("userCode"); + const userCode = searchParams.get("user_code"); const [isProcessing, setIsProcessing] = useState(false); const handleApprove = async () => { From 9aed910499eb4cbc3dd0c395ff5534893daab7a4 Mon Sep 17 00:00:00 2001 From: Gustavo Valverde Date: Wed, 15 Apr 2026 11:59:53 +0100 Subject: [PATCH 5/8] fix(two-factor): revert enforcement broadening from #9122 (#9205) --- .changeset/fix-revert-2fa-broadening.md | 9 +++++ .../src/plugins/two-factor/index.ts | 11 ++---- .../src/plugins/two-factor/two-factor.test.ts | 35 +++++++++++-------- 3 files changed, 32 insertions(+), 23 deletions(-) create mode 100644 .changeset/fix-revert-2fa-broadening.md diff --git a/.changeset/fix-revert-2fa-broadening.md b/.changeset/fix-revert-2fa-broadening.md new file mode 100644 index 0000000000..32a5f0cb70 --- /dev/null +++ b/.changeset/fix-revert-2fa-broadening.md @@ -0,0 +1,9 @@ +--- +"better-auth": patch +--- + +fix(two-factor): revert enforcement broadening from #9122 + +Restores the pre-#9122 enforcement scope. 2FA is challenged only on `/sign-in/email`, `/sign-in/username`, and `/sign-in/phone-number`, matching the behavior that shipped through v1.6.2. Non-credential sign-in flows (magic link, email OTP, OAuth, SSO, passkey, SIWE, one-tap, phone-number OTP, device authorization, email-verification auto-sign-in) are no longer gated by a 2FA challenge by default. + +A broader enforcement scope with per-method opt-outs and alignment to NIST SP 800-63B-4 authenticator assurance levels is planned for a future minor release. diff --git a/packages/better-auth/src/plugins/two-factor/index.ts b/packages/better-auth/src/plugins/two-factor/index.ts index 5c4dbeaada..213422cabc 100644 --- a/packages/better-auth/src/plugins/two-factor/index.ts +++ b/packages/better-auth/src/plugins/two-factor/index.ts @@ -378,8 +378,9 @@ export const twoFactor = (options?: O) => { { matcher(context) { return ( - context.context.newSession != null && - !context.path?.startsWith("/two-factor/") + context.path === "/sign-in/email" || + context.path === "/sign-in/username" || + context.path === "/sign-in/phone-number" ); }, handler: createAuthMiddleware(async (ctx) => { @@ -392,12 +393,6 @@ export const twoFactor = (options?: O) => { return; } - // Skip if the request already had an authenticated session - // (session refresh, updateUser, etc. are not sign-in flows) - if (ctx.context.session) { - return; - } - const trustDeviceCookieAttrs = ctx.context.createAuthCookie( TRUST_DEVICE_COOKIE_NAME, { diff --git a/packages/better-auth/src/plugins/two-factor/two-factor.test.ts b/packages/better-auth/src/plugins/two-factor/two-factor.test.ts index f4d35d8dae..b91b78dee2 100644 --- a/packages/better-auth/src/plugins/two-factor/two-factor.test.ts +++ b/packages/better-auth/src/plugins/two-factor/two-factor.test.ts @@ -2349,9 +2349,14 @@ describe("twoFactorMethods in sign-in response", () => { }); /** - * @see https://github.com/better-auth/better-auth/issues/8627 + * @see https://github.com/better-auth/better-auth/pull/9205 + * + * 2FA enforcement is intentionally scoped to credential sign-in paths + * only. These tests lock that scope in so a future refactor does not + * accidentally broaden enforcement to non-credential sign-in flows + * without a dedicated release. */ -describe("2FA enforcement on non-credential sign-in paths", async () => { +describe("2FA enforcement scope", async () => { let magicLinkURL = ""; const { auth, signInWithTestUser, testUser } = await getTestInstance({ secret: DEFAULT_SECRET, @@ -2370,7 +2375,7 @@ describe("2FA enforcement on non-credential sign-in paths", async () => { ], }); - it("should enforce 2FA on magic-link sign-in", async () => { + it("should not challenge 2FA on magic-link sign-in", async () => { const { headers } = await signInWithTestUser(); await auth.api.enableTwoFactor({ body: { password: testUser.password }, @@ -2393,14 +2398,14 @@ describe("2FA enforcement on non-credential sign-in paths", async () => { }); const json = await verifyRes.json(); - expect(json.twoFactorRedirect).toBe(true); + expect(json.twoFactorRedirect).toBeUndefined(); }); - it("should not enforce 2FA on authenticated non-sign-in endpoints", async () => { + it("should not challenge 2FA on authenticated non-sign-in endpoints", async () => { const { - auth: a, + auth: instance, signInWithTestUser: signIn, - testUser: tu, + testUser: user, } = await getTestInstance({ secret: DEFAULT_SECRET, plugins: [ @@ -2410,20 +2415,20 @@ describe("2FA enforcement on non-credential sign-in paths", async () => { }), ], }); - let { headers: h } = await signIn(); - const enableRes = await a.api.enableTwoFactor({ - body: { password: tu.password }, - headers: h, + let { headers } = await signIn(); + const enableRes = await instance.api.enableTwoFactor({ + body: { password: user.password }, + headers, asResponse: true, }); - h = convertSetCookieToCookie(enableRes.headers); + headers = convertSetCookieToCookie(enableRes.headers); - const session = await a.api.getSession({ headers: h }); + const session = await instance.api.getSession({ headers }); expect(session?.user.twoFactorEnabled).toBe(true); - const updateRes = await a.api.updateUser({ + const updateRes = await instance.api.updateUser({ body: { name: "updated-name" }, - headers: h, + headers, asResponse: true, }); From ba03fb59f4d1ce4309ddf5fa315d4b2d82951990 Mon Sep 17 00:00:00 2001 From: Gustavo Valverde Date: Wed, 15 Apr 2026 12:24:20 +0100 Subject: [PATCH 6/8] chore(deps): bump electron and next devDependencies to patched versions (#9166) --- packages/better-auth/package.json | 2 +- packages/electron/package.json | 2 +- pnpm-lock.yaml | 184 ++++-------------------------- 3 files changed, 23 insertions(+), 165 deletions(-) diff --git a/packages/better-auth/package.json b/packages/better-auth/package.json index 05ceb9fc3a..205a606b4f 100644 --- a/packages/better-auth/package.json +++ b/packages/better-auth/package.json @@ -522,7 +522,7 @@ "happy-dom": "^20.8.9", "listhen": "^1.9.0", "msw": "^2.12.10", - "next": "^16.2.0", + "next": "^16.2.3", "oauth2-mock-server": "^8.2.2", "react": "catalog:react19", "react-dom": "catalog:react19", diff --git a/packages/electron/package.json b/packages/electron/package.json index 0caa8dad6f..77f55e7697 100644 --- a/packages/electron/package.json +++ b/packages/electron/package.json @@ -89,7 +89,7 @@ "@types/better-sqlite3": "^7.6.13", "better-auth": "workspace:*", "better-sqlite3": "^12.6.2", - "electron": "^38.8.4", + "electron": "^38.8.6", "tsdown": "catalog:" }, "peerDependencies": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 30e8834366..09db7aaaec 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -311,7 +311,7 @@ importers: version: 11.13.0 next: specifier: 16.2.3 - version: 16.2.3(@opentelemetry/api@1.9.0)(@playwright/test@1.58.2)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.97.1) + version: 16.2.3(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.58.2)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.97.1) next-themes: specifier: ^0.4.6 version: 0.4.6(react-dom@19.2.4(react@19.2.4))(react@19.2.4) @@ -933,8 +933,8 @@ importers: specifier: ^2.12.10 version: 2.12.10(@types/node@25.6.0)(typescript@5.9.3) next: - specifier: ^16.2.0 - version: 16.2.0(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.58.2)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.97.1) + specifier: ^16.2.3 + version: 16.2.3(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.58.2)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.97.1) oauth2-mock-server: specifier: ^8.2.2 version: 8.2.2 @@ -1155,8 +1155,8 @@ importers: specifier: ^12.6.2 version: 12.6.2 electron: - specifier: ^38.8.4 - version: 38.8.4 + specifier: ^38.8.6 + version: 38.8.6 tsdown: specifier: 'catalog:' version: 0.21.1(@arethetypeswrong/core@0.18.2)(oxc-resolver@11.19.0)(publint@0.3.17)(synckit@0.11.11)(typescript@5.9.3) @@ -4473,43 +4473,21 @@ packages: resolution: {integrity: sha512-dyJeuggzQM8+Dsi0T8Z9UjfLJ6vCmNC36W6WE2aqzfTdTw4wPkh2xlEu4LoD75+TGuYK7jIhEoU2QcCXOzfyAQ==} engines: {node: ^18.14.0 || >=20} - '@next/env@16.2.0': - resolution: {integrity: sha512-OZIbODWWAi0epQRCRjNe1VO45LOFBzgiyqmTLzIqWq6u1wrxKnAyz1HH6tgY/Mc81YzIjRPoYsPAEr4QV4l9TA==} - '@next/env@16.2.3': resolution: {integrity: sha512-ZWXyj4uNu4GCWQw9cjRxWlbD+33mcDszIo9iQxFnBX3Wmgq9ulaSJcl6VhuWx5pCWqqD+9W6Wfz7N0lM5lYPMA==} - '@next/swc-darwin-arm64@16.2.0': - resolution: {integrity: sha512-/JZsqKzKt01IFoiLLAzlNqys7qk2F3JkcUhj50zuRhKDQkZNOz9E5N6wAQWprXdsvjRP4lTFj+/+36NSv5AwhQ==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [darwin] - '@next/swc-darwin-arm64@16.2.3': resolution: {integrity: sha512-u37KDKTKQ+OQLvY+z7SNXixwo4Q2/IAJFDzU1fYe66IbCE51aDSAzkNDkWmLN0yjTUh4BKBd+hb69jYn6qqqSg==} engines: {node: '>= 10'} cpu: [arm64] os: [darwin] - '@next/swc-darwin-x64@16.2.0': - resolution: {integrity: sha512-/hV8erWq4SNlVgglUiW5UmQ5Hwy5EW/AbbXlJCn6zkfKxTy/E/U3V8U1Ocm2YCTUoFgQdoMxRyRMOW5jYy4ygg==} - engines: {node: '>= 10'} - cpu: [x64] - os: [darwin] - '@next/swc-darwin-x64@16.2.3': resolution: {integrity: sha512-gHjL/qy6Q6CG3176FWbAKyKh9IfntKZTB3RY/YOJdDFpHGsUDXVH38U4mMNpHVGXmeYW4wj22dMp1lTfmu/bTQ==} engines: {node: '>= 10'} cpu: [x64] os: [darwin] - '@next/swc-linux-arm64-gnu@16.2.0': - resolution: {integrity: sha512-GkjL/Q7MWOwqWR9zoxu1TIHzkOI2l2BHCf7FzeQG87zPgs+6WDh+oC9Sw9ARuuL/FUk6JNCgKRkA6rEQYadUaw==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [linux] - libc: [glibc] - '@next/swc-linux-arm64-gnu@16.2.3': resolution: {integrity: sha512-U6vtblPtU/P14Y/b/n9ZY0GOxbbIhTFuaFR7F4/uMBidCi2nSdaOFhA0Go81L61Zd6527+yvuX44T4ksnf8T+Q==} engines: {node: '>= 10'} @@ -4517,13 +4495,6 @@ packages: os: [linux] libc: [glibc] - '@next/swc-linux-arm64-musl@16.2.0': - resolution: {integrity: sha512-1ffhC6KY5qWLg5miMlKJp3dZbXelEfjuXt1qcp5WzSCQy36CV3y+JT7OC1WSFKizGQCDOcQbfkH/IjZP3cdRNA==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [linux] - libc: [musl] - '@next/swc-linux-arm64-musl@16.2.3': resolution: {integrity: sha512-/YV0LgjHUmfhQpn9bVoGc4x4nan64pkhWR5wyEV8yCOfwwrH630KpvRg86olQHTwHIn1z59uh6JwKvHq1h4QEw==} engines: {node: '>= 10'} @@ -4531,13 +4502,6 @@ packages: os: [linux] libc: [musl] - '@next/swc-linux-x64-gnu@16.2.0': - resolution: {integrity: sha512-FmbDcZQ8yJRq93EJSL6xaE0KK/Rslraf8fj1uViGxg7K4CKBCRYSubILJPEhjSgZurpcPQq12QNOJQ0DRJl6Hg==} - engines: {node: '>= 10'} - cpu: [x64] - os: [linux] - libc: [glibc] - '@next/swc-linux-x64-gnu@16.2.3': resolution: {integrity: sha512-/HiWEcp+WMZ7VajuiMEFGZ6cg0+aYZPqCJD3YJEfpVWQsKYSjXQG06vJP6F1rdA03COD9Fef4aODs3YxKx+RDQ==} engines: {node: '>= 10'} @@ -4545,13 +4509,6 @@ packages: os: [linux] libc: [glibc] - '@next/swc-linux-x64-musl@16.2.0': - resolution: {integrity: sha512-HzjIHVkmGAwRbh/vzvoBWWEbb8BBZPxBvVbDQDvzHSf3D8RP/4vjw7MNLDXFF9Q1WEzeQyEj2zdxBtVAHu5Oyw==} - engines: {node: '>= 10'} - cpu: [x64] - os: [linux] - libc: [musl] - '@next/swc-linux-x64-musl@16.2.3': resolution: {integrity: sha512-Kt44hGJfZSefebhk/7nIdivoDr3Ugp5+oNz9VvF3GUtfxutucUIHfIO0ZYO8QlOPDQloUVQn4NVC/9JvHRk9hw==} engines: {node: '>= 10'} @@ -4559,24 +4516,12 @@ packages: os: [linux] libc: [musl] - '@next/swc-win32-arm64-msvc@16.2.0': - resolution: {integrity: sha512-UMiFNQf5H7+1ZsZPxEsA064WEuFbRNq/kEXyepbCnSErp4f5iut75dBA8UeerFIG3vDaQNOfCpevnERPp2V+nA==} - engines: {node: '>= 10'} - cpu: [arm64] - os: [win32] - '@next/swc-win32-arm64-msvc@16.2.3': resolution: {integrity: sha512-O2NZ9ie3Tq6xj5Z5CSwBT3+aWAMW2PIZ4egUi9MaWLkwaehgtB7YZjPm+UpcNpKOme0IQuqDcor7BsW6QBiQBw==} engines: {node: '>= 10'} cpu: [arm64] os: [win32] - '@next/swc-win32-x64-msvc@16.2.0': - resolution: {integrity: sha512-DRrNJKW+/eimrZgdhVN1uvkN1OI4j6Lpefwr44jKQ0YQzztlmOBUUzHuV5GxOMPK3nmodAYElUVCY8ZXo/IWeA==} - engines: {node: '>= 10'} - cpu: [x64] - os: [win32] - '@next/swc-win32-x64-msvc@16.2.3': resolution: {integrity: sha512-Ibm29/GgB/ab5n7XKqlStkm54qqZE8v2FnijUPBgrd67FWrac45o/RsNlaOWjme/B5UqeWt/8KM4aWBwA1D2Kw==} engines: {node: '>= 10'} @@ -7890,11 +7835,6 @@ packages: base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} - baseline-browser-mapping@2.10.0: - resolution: {integrity: sha512-lIyg0szRfYbiy67j9KN8IyeD7q7hcmqnJ1ddWmNt19ItGpNN64mnllmxUNFIOdOm6by97jlL6wfpTTJrmnjWAA==} - engines: {node: '>=6.0.0'} - hasBin: true - baseline-browser-mapping@2.10.17: resolution: {integrity: sha512-HdrkN8eVG2CXxeifv/VdJ4A4RSra1DTW8dc/hdxzhGHN8QePs6gKaWM9pHPcpCoxYZJuOZ8drHmbdpLHjCYjLA==} engines: {node: '>=6.0.0'} @@ -8110,9 +8050,6 @@ packages: camelize@1.0.1: resolution: {integrity: sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==} - caniuse-lite@1.0.30001774: - resolution: {integrity: sha512-DDdwPGz99nmIEv216hKSgLD+D4ikHQHjBC/seF98N9CPqRX4M5mSxT9eTV6oyisnJcuzxtZy4n17yKKQYmYQOA==} - caniuse-lite@1.0.30001787: resolution: {integrity: sha512-mNcrMN9KeI68u7muanUpEejSLghOKlVhRqS/Za2IeyGllJ9I9otGpR9g3nsw7n4W378TE/LyIteA0+/FOZm4Kg==} @@ -9226,8 +9163,8 @@ packages: electron-to-chromium@1.5.334: resolution: {integrity: sha512-mgjZAz7Jyx1SRCwEpy9wefDS7GvNPazLthHg8eQMJ76wBdGQQDW33TCrUTvQ4wzpmOrv2zrFoD3oNufMdyMpog==} - electron@38.8.4: - resolution: {integrity: sha512-vYZ2SH2OhzkCmkbRaijtZLIEJRMnLUL2KQmcAM/7kamf4++3AKSNCBjE1epmQnYFY1M4oKjOUcS3G02ayxR5Bw==} + electron@38.8.6: + resolution: {integrity: sha512-lyBhcVi9QYAZL6FO6r5twAWAjWnYomo3iVDvrb5SJZlq928BGemHOKG0tPIq41NOLaCu9f3XdEEjMkjQPjprRg==} engines: {node: '>= 12.20.55'} hasBin: true @@ -12044,27 +11981,6 @@ packages: react: ^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc react-dom: ^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc - next@16.2.0: - resolution: {integrity: sha512-NLBVrJy1pbV1Yn00L5sU4vFyAHt5XuSjzrNyFnxo6Com0M0KrL6hHM5B99dbqXb2bE9pm4Ow3Zl1xp6HVY9edQ==} - engines: {node: '>=20.9.0'} - hasBin: true - peerDependencies: - '@opentelemetry/api': ^1.1.0 - '@playwright/test': ^1.51.1 - babel-plugin-react-compiler: '*' - react: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0 - react-dom: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0 - sass: ^1.3.0 - peerDependenciesMeta: - '@opentelemetry/api': - optional: true - '@playwright/test': - optional: true - babel-plugin-react-compiler: - optional: true - sass: - optional: true - next@16.2.3: resolution: {integrity: sha512-9V3zV4oZFza3PVev5/poB9g0dEafVcgNyQ8eTRop8GvxZjV2G15FC5ARuG1eFD42QgeYkzJBJzHghNP8Ad9xtA==} engines: {node: '>=20.9.0'} @@ -18455,55 +18371,29 @@ snapshots: '@netlify/runtime-utils@2.2.1': optional: true - '@next/env@16.2.0': {} - '@next/env@16.2.3': {} - '@next/swc-darwin-arm64@16.2.0': - optional: true - '@next/swc-darwin-arm64@16.2.3': optional: true - '@next/swc-darwin-x64@16.2.0': - optional: true - '@next/swc-darwin-x64@16.2.3': optional: true - '@next/swc-linux-arm64-gnu@16.2.0': - optional: true - '@next/swc-linux-arm64-gnu@16.2.3': optional: true - '@next/swc-linux-arm64-musl@16.2.0': - optional: true - '@next/swc-linux-arm64-musl@16.2.3': optional: true - '@next/swc-linux-x64-gnu@16.2.0': - optional: true - '@next/swc-linux-x64-gnu@16.2.3': optional: true - '@next/swc-linux-x64-musl@16.2.0': - optional: true - '@next/swc-linux-x64-musl@16.2.3': optional: true - '@next/swc-win32-arm64-msvc@16.2.0': - optional: true - '@next/swc-win32-arm64-msvc@16.2.3': optional: true - '@next/swc-win32-x64-msvc@16.2.0': - optional: true - '@next/swc-win32-x64-msvc@16.2.3': optional: true @@ -21457,7 +21347,7 @@ snapshots: dependencies: '@types/http-cache-semantics': 4.2.0 '@types/keyv': 3.1.4 - '@types/node': 25.5.0 + '@types/node': 25.6.0 '@types/responselike': 1.0.3 '@types/chai@5.2.3': @@ -21623,7 +21513,7 @@ snapshots: '@types/graceful-fs@4.1.9': dependencies: - '@types/node': 25.5.0 + '@types/node': 25.6.0 '@types/hast@3.0.4': dependencies: @@ -21651,7 +21541,7 @@ snapshots: '@types/keyv@3.1.4': dependencies: - '@types/node': 25.5.0 + '@types/node': 25.6.0 '@types/mdast@4.0.4': dependencies: @@ -21722,7 +21612,7 @@ snapshots: '@types/responselike@1.0.3': dependencies: - '@types/node': 25.5.0 + '@types/node': 25.6.0 '@types/semver@7.7.1': {} @@ -21771,7 +21661,7 @@ snapshots: '@types/yauzl@2.10.3': dependencies: - '@types/node': 25.5.0 + '@types/node': 25.6.0 optional: true '@typespec/ts-http-runtime@0.3.3': @@ -21818,7 +21708,7 @@ snapshots: optionalDependencies: '@remix-run/react': 2.17.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3) '@sveltejs/kit': 2.57.1(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.1(svelte@5.53.5)(vite@7.3.2(@types/node@25.5.0)(jiti@2.6.1)(less@4.5.1)(lightningcss@1.32.0)(sass@1.97.1)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)))(svelte@5.53.5)(typescript@5.9.3)(vite@7.3.2(@types/node@25.5.0)(jiti@2.6.1)(less@4.5.1)(lightningcss@1.32.0)(sass@1.97.1)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3)) - next: 16.2.3(@opentelemetry/api@1.9.0)(@playwright/test@1.58.2)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.97.1) + next: 16.2.3(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.58.2)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.97.1) react: 19.2.4 svelte: 5.53.5 vue: 3.5.29(typescript@5.9.3) @@ -22532,8 +22422,6 @@ snapshots: base64-js@1.5.1: {} - baseline-browser-mapping@2.10.0: {} - baseline-browser-mapping@2.10.17: {} basic-auth@2.0.1: @@ -22824,8 +22712,6 @@ snapshots: camelize@1.0.1: {} - caniuse-lite@1.0.30001774: {} - caniuse-lite@1.0.30001787: {} ccount@2.0.1: {} @@ -22933,7 +22819,7 @@ snapshots: chrome-launcher@0.15.2: dependencies: - '@types/node': 25.5.0 + '@types/node': 25.6.0 escape-string-regexp: 4.0.0 is-wsl: 2.2.0 lighthouse-logger: 1.4.2 @@ -22942,7 +22828,7 @@ snapshots: chromium-edge-launcher@0.2.0: dependencies: - '@types/node': 25.5.0 + '@types/node': 25.6.0 escape-string-regexp: 4.0.0 is-wsl: 2.2.0 lighthouse-logger: 1.4.2 @@ -23879,7 +23765,7 @@ snapshots: electron-to-chromium@1.5.334: {} - electron@38.8.4: + electron@38.8.6: dependencies: '@electron/get': 2.0.3 '@types/node': 22.19.13 @@ -24817,7 +24703,7 @@ snapshots: '@types/react': 19.2.14 algoliasearch: 5.46.2 lucide-react: 1.7.0(react@19.2.4) - next: 16.2.3(@opentelemetry/api@1.9.0)(@playwright/test@1.58.2)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.97.1) + next: 16.2.3(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.58.2)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.97.1) react: 19.2.4 react-dom: 19.2.4(react@19.2.4) zod: 4.3.6 @@ -24849,7 +24735,7 @@ snapshots: '@types/mdx': 2.0.13 '@types/react': 19.2.14 mdast-util-directive: 3.1.0 - next: 16.2.3(@opentelemetry/api@1.9.0)(@playwright/test@1.58.2)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.97.1) + next: 16.2.3(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.58.2)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.97.1) react: 19.2.4 vite: 7.3.2(@types/node@25.5.0)(jiti@2.6.1)(less@4.5.1)(lightningcss@1.32.0)(sass@1.97.1)(terser@5.46.1)(tsx@4.21.0)(yaml@2.8.3) transitivePeerDependencies: @@ -24907,7 +24793,7 @@ snapshots: optionalDependencies: '@types/mdx': 2.0.13 '@types/react': 19.2.14 - next: 16.2.3(@opentelemetry/api@1.9.0)(@playwright/test@1.58.2)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.97.1) + next: 16.2.3(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.58.2)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.97.1) shiki: 4.0.1 transitivePeerDependencies: - '@emotion/is-prop-valid' @@ -24918,7 +24804,7 @@ snapshots: geist@1.7.0(next@16.2.3(@opentelemetry/api@1.9.0)(@playwright/test@1.58.2)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.97.1)): dependencies: - next: 16.2.3(@opentelemetry/api@1.9.0)(@playwright/test@1.58.2)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.97.1) + next: 16.2.3(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.58.2)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.97.1) gel@2.2.0: dependencies: @@ -27679,35 +27565,7 @@ snapshots: react: 19.2.4 react-dom: 19.2.4(react@19.2.4) - next@16.2.0(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.58.2)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.97.1): - dependencies: - '@next/env': 16.2.0 - '@swc/helpers': 0.5.15 - baseline-browser-mapping: 2.10.0 - caniuse-lite: 1.0.30001774 - postcss: 8.4.31 - react: 19.2.4 - react-dom: 19.2.4(react@19.2.4) - styled-jsx: 5.1.6(@babel/core@7.29.0)(react@19.2.4) - optionalDependencies: - '@next/swc-darwin-arm64': 16.2.0 - '@next/swc-darwin-x64': 16.2.0 - '@next/swc-linux-arm64-gnu': 16.2.0 - '@next/swc-linux-arm64-musl': 16.2.0 - '@next/swc-linux-x64-gnu': 16.2.0 - '@next/swc-linux-x64-musl': 16.2.0 - '@next/swc-win32-arm64-msvc': 16.2.0 - '@next/swc-win32-x64-msvc': 16.2.0 - '@opentelemetry/api': 1.9.0 - '@playwright/test': 1.58.2 - babel-plugin-react-compiler: 1.0.0 - sass: 1.97.1 - sharp: 0.34.5 - transitivePeerDependencies: - - '@babel/core' - - babel-plugin-macros - - next@16.2.3(@opentelemetry/api@1.9.0)(@playwright/test@1.58.2)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.97.1): + next@16.2.3(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.58.2)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(sass@1.97.1): dependencies: '@next/env': 16.2.3 '@swc/helpers': 0.5.15 From 39d6af2a392dc41018a036d1d909dc48c09749c9 Mon Sep 17 00:00:00 2001 From: Gustavo Valverde Date: Wed, 15 Apr 2026 12:37:50 +0100 Subject: [PATCH 7/8] chore(adapters): require patched drizzle-orm and kysely peer versions (#9165) Co-authored-by: Maxwell <145994855+ping-maxwell@users.noreply.github.com> --- .changeset/tighten-adapter-peerdeps.md | 9 ++ packages/better-auth/package.json | 2 +- packages/drizzle-adapter/package.json | 2 +- packages/kysely-adapter/package.json | 2 +- pnpm-lock.yaml | 115 +------------------------ 5 files changed, 14 insertions(+), 116 deletions(-) create mode 100644 .changeset/tighten-adapter-peerdeps.md diff --git a/.changeset/tighten-adapter-peerdeps.md b/.changeset/tighten-adapter-peerdeps.md new file mode 100644 index 0000000000..4c10c83b97 --- /dev/null +++ b/.changeset/tighten-adapter-peerdeps.md @@ -0,0 +1,9 @@ +--- +"@better-auth/drizzle-adapter": patch +"@better-auth/kysely-adapter": patch +"better-auth": patch +--- + +chore(adapters): require patched `drizzle-orm` and `kysely` peer versions + +Narrows the `drizzle-orm` peer to `^0.45.2` and the `kysely` peer to `^0.28.14`. Both new ranges track the minor line that carries the vulnerability fix and nothing newer, so the adapters only advertise support for versions that have actually been tested against. Consumers on older ORM releases see an install-time warning and can upgrade alongside the adapter; the peer is marked optional, so installs do not hard-fail. diff --git a/packages/better-auth/package.json b/packages/better-auth/package.json index 205a606b4f..341a27800c 100644 --- a/packages/better-auth/package.json +++ b/packages/better-auth/package.json @@ -541,7 +541,7 @@ "@tanstack/solid-start": "^1.0.0", "better-sqlite3": "^12.0.0", "drizzle-kit": ">=0.31.4", - "drizzle-orm": ">=0.41.0", + "drizzle-orm": "^0.45.2", "mongodb": "^6.0.0 || ^7.0.0", "mysql2": "^3.0.0", "next": "^14.0.0 || ^15.0.0 || ^16.0.0", diff --git a/packages/drizzle-adapter/package.json b/packages/drizzle-adapter/package.json index 03d9fe2fca..b79fe86797 100644 --- a/packages/drizzle-adapter/package.json +++ b/packages/drizzle-adapter/package.json @@ -45,7 +45,7 @@ "peerDependencies": { "@better-auth/core": "workspace:^", "@better-auth/utils": "catalog:", - "drizzle-orm": ">=0.41.0" + "drizzle-orm": "^0.45.2" }, "peerDependenciesMeta": { "drizzle-orm": { diff --git a/packages/kysely-adapter/package.json b/packages/kysely-adapter/package.json index 7b2dc59fc8..a4735bd650 100644 --- a/packages/kysely-adapter/package.json +++ b/packages/kysely-adapter/package.json @@ -50,7 +50,7 @@ "peerDependencies": { "@better-auth/core": "workspace:^", "@better-auth/utils": "catalog:", - "kysely": "^0.27.0 || ^0.28.0" + "kysely": "^0.28.14" }, "peerDependenciesMeta": { "kysely": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 09db7aaaec..2c252ad70c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -860,8 +860,8 @@ importers: specifier: '>=0.31.4' version: 0.31.9 drizzle-orm: - specifier: '>=0.41.0' - version: 0.45.1(@cloudflare/workers-types@4.20260226.1)(@electric-sql/pglite@0.3.15)(@libsql/client@0.17.0(encoding@0.1.13))(@opentelemetry/api@1.9.0)(@prisma/client@7.4.1(prisma@7.4.1(@types/react@19.2.14)(better-sqlite3@12.6.2)(magicast@0.3.5)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3))(typescript@5.9.3))(@types/better-sqlite3@7.6.13)(@types/pg@8.16.0)(@upstash/redis@1.36.4)(better-sqlite3@12.6.2)(bun-types@1.3.9)(gel@2.2.0)(kysely@0.28.14)(mysql2@3.18.2(@types/node@25.6.0))(pg@8.19.0)(postgres@3.4.8)(prisma@7.4.1(@types/react@19.2.14)(better-sqlite3@12.6.2)(magicast@0.3.5)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3)) + specifier: ^0.45.2 + version: 0.45.2(@cloudflare/workers-types@4.20260226.1)(@electric-sql/pglite@0.3.15)(@libsql/client@0.17.0(encoding@0.1.13))(@opentelemetry/api@1.9.0)(@prisma/client@7.4.1(prisma@7.4.1(@types/react@19.2.14)(better-sqlite3@12.6.2)(magicast@0.3.5)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3))(typescript@5.9.3))(@types/better-sqlite3@7.6.13)(@types/pg@8.16.0)(@upstash/redis@1.36.4)(better-sqlite3@12.6.2)(bun-types@1.3.9)(gel@2.2.0)(kysely@0.28.14)(mysql2@3.18.2(@types/node@25.6.0))(pg@8.19.0)(postgres@3.4.8)(prisma@7.4.1(@types/react@19.2.14)(better-sqlite3@12.6.2)(magicast@0.3.5)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3)) jose: specifier: ^6.1.3 version: 6.1.3 @@ -8940,98 +8940,6 @@ packages: resolution: {integrity: sha512-GViD3IgsXn7trFyBUUHyTFBpH/FsHTxYJ66qdbVggxef4UBPHRYxQaRzYLTuekYnk9i5FIEL9pbBIwMqX/Uwrg==} hasBin: true - drizzle-orm@0.45.1: - resolution: {integrity: sha512-Te0FOdKIistGNPMq2jscdqngBRfBpC8uMFVwqjf6gtTVJHIQ/dosgV/CLBU2N4ZJBsXL5savCba9b0YJskKdcA==} - peerDependencies: - '@aws-sdk/client-rds-data': '>=3' - '@cloudflare/workers-types': '>=4' - '@electric-sql/pglite': '>=0.2.0' - '@libsql/client': '>=0.10.0' - '@libsql/client-wasm': '>=0.10.0' - '@neondatabase/serverless': '>=0.10.0' - '@op-engineering/op-sqlite': '>=2' - '@opentelemetry/api': ^1.4.1 - '@planetscale/database': '>=1.13' - '@prisma/client': '*' - '@tidbcloud/serverless': '*' - '@types/better-sqlite3': '*' - '@types/pg': '*' - '@types/sql.js': '*' - '@upstash/redis': '>=1.34.7' - '@vercel/postgres': '>=0.8.0' - '@xata.io/client': '*' - better-sqlite3: '>=7' - bun-types: '*' - expo-sqlite: '>=14.0.0' - gel: '>=2' - knex: '*' - kysely: '*' - mysql2: '>=2' - pg: '>=8' - postgres: '>=3' - prisma: '*' - sql.js: '>=1' - sqlite3: '>=5' - peerDependenciesMeta: - '@aws-sdk/client-rds-data': - optional: true - '@cloudflare/workers-types': - optional: true - '@electric-sql/pglite': - optional: true - '@libsql/client': - optional: true - '@libsql/client-wasm': - optional: true - '@neondatabase/serverless': - optional: true - '@op-engineering/op-sqlite': - optional: true - '@opentelemetry/api': - optional: true - '@planetscale/database': - optional: true - '@prisma/client': - optional: true - '@tidbcloud/serverless': - optional: true - '@types/better-sqlite3': - optional: true - '@types/pg': - optional: true - '@types/sql.js': - optional: true - '@upstash/redis': - optional: true - '@vercel/postgres': - optional: true - '@xata.io/client': - optional: true - better-sqlite3: - optional: true - bun-types: - optional: true - expo-sqlite: - optional: true - gel: - optional: true - knex: - optional: true - kysely: - optional: true - mysql2: - optional: true - pg: - optional: true - postgres: - optional: true - prisma: - optional: true - sql.js: - optional: true - sqlite3: - optional: true - drizzle-orm@0.45.2: resolution: {integrity: sha512-kY0BSaTNYWnoDMVoyY8uxmyHjpJW1geOmBMdSSicKo9CIIWkSxMIj2rkeSR51b8KAPB7m+qysjuHme5nKP+E5Q==} peerDependencies: @@ -23671,25 +23579,6 @@ snapshots: transitivePeerDependencies: - supports-color - drizzle-orm@0.45.1(@cloudflare/workers-types@4.20260226.1)(@electric-sql/pglite@0.3.15)(@libsql/client@0.17.0(encoding@0.1.13))(@opentelemetry/api@1.9.0)(@prisma/client@7.4.1(prisma@7.4.1(@types/react@19.2.14)(better-sqlite3@12.6.2)(magicast@0.3.5)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3))(typescript@5.9.3))(@types/better-sqlite3@7.6.13)(@types/pg@8.16.0)(@upstash/redis@1.36.4)(better-sqlite3@12.6.2)(bun-types@1.3.9)(gel@2.2.0)(kysely@0.28.14)(mysql2@3.18.2(@types/node@25.6.0))(pg@8.19.0)(postgres@3.4.8)(prisma@7.4.1(@types/react@19.2.14)(better-sqlite3@12.6.2)(magicast@0.3.5)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3)): - optionalDependencies: - '@cloudflare/workers-types': 4.20260226.1 - '@electric-sql/pglite': 0.3.15 - '@libsql/client': 0.17.0(encoding@0.1.13) - '@opentelemetry/api': 1.9.0 - '@prisma/client': 7.4.1(prisma@7.4.1(@types/react@19.2.14)(better-sqlite3@12.6.2)(magicast@0.3.5)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3))(typescript@5.9.3) - '@types/better-sqlite3': 7.6.13 - '@types/pg': 8.16.0 - '@upstash/redis': 1.36.4 - better-sqlite3: 12.6.2 - bun-types: 1.3.9 - gel: 2.2.0 - kysely: 0.28.14 - mysql2: 3.18.2(@types/node@25.6.0) - pg: 8.19.0 - postgres: 3.4.8 - prisma: 7.4.1(@types/react@19.2.14)(better-sqlite3@12.6.2)(magicast@0.3.5)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3) - drizzle-orm@0.45.2(@cloudflare/workers-types@4.20260226.1)(@electric-sql/pglite@0.3.15)(@libsql/client@0.17.0(encoding@0.1.13))(@opentelemetry/api@1.9.0)(@prisma/client@7.4.1(prisma@7.4.1(@types/react@19.2.14)(better-sqlite3@12.6.2)(magicast@0.3.5)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3))(typescript@5.9.3))(@types/better-sqlite3@7.6.13)(@types/pg@8.16.0)(@upstash/redis@1.36.4)(better-sqlite3@12.6.2)(bun-types@1.3.9)(gel@2.2.0)(kysely@0.28.14)(mysql2@3.18.2(@types/node@25.6.0))(pg@8.19.0)(postgres@3.4.8)(prisma@7.4.1(@types/react@19.2.14)(better-sqlite3@12.6.2)(magicast@0.3.5)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3)): optionalDependencies: '@cloudflare/workers-types': 4.20260226.1 From 9ec849ff7147f672a2759515e2aae8af7736962c Mon Sep 17 00:00:00 2001 From: "better-release[bot]" <273320539+better-release[bot]@users.noreply.github.com> Date: Wed, 15 Apr 2026 13:00:42 +0100 Subject: [PATCH 8/8] chore: release v1.6.4 (#9175) --- .changeset/fix-revert-2fa-broadening.md | 9 --------- .changeset/force-allow-id-uuid.md | 5 ----- .changeset/tighten-adapter-peerdeps.md | 9 --------- packages/api-key/CHANGELOG.md | 8 ++++++++ packages/api-key/package.json | 2 +- packages/better-auth/CHANGELOG.md | 25 +++++++++++++++++++++++++ packages/better-auth/package.json | 2 +- packages/cli/CHANGELOG.md | 9 +++++++++ packages/cli/package.json | 2 +- packages/core/CHANGELOG.md | 2 ++ packages/core/package.json | 2 +- packages/drizzle-adapter/CHANGELOG.md | 11 +++++++++++ packages/drizzle-adapter/package.json | 2 +- packages/electron/CHANGELOG.md | 8 ++++++++ packages/electron/package.json | 2 +- packages/expo/CHANGELOG.md | 8 ++++++++ packages/expo/package.json | 2 +- packages/i18n/CHANGELOG.md | 8 ++++++++ packages/i18n/package.json | 2 +- packages/kysely-adapter/CHANGELOG.md | 11 +++++++++++ packages/kysely-adapter/package.json | 2 +- packages/memory-adapter/CHANGELOG.md | 7 +++++++ packages/memory-adapter/package.json | 2 +- packages/mongo-adapter/CHANGELOG.md | 7 +++++++ packages/mongo-adapter/package.json | 2 +- packages/oauth-provider/CHANGELOG.md | 8 ++++++++ packages/oauth-provider/package.json | 2 +- packages/passkey/CHANGELOG.md | 8 ++++++++ packages/passkey/package.json | 2 +- packages/prisma-adapter/CHANGELOG.md | 7 +++++++ packages/prisma-adapter/package.json | 2 +- packages/redis-storage/CHANGELOG.md | 7 +++++++ packages/redis-storage/package.json | 2 +- packages/scim/CHANGELOG.md | 8 ++++++++ packages/scim/package.json | 2 +- packages/sso/CHANGELOG.md | 8 ++++++++ packages/sso/package.json | 2 +- packages/stripe/CHANGELOG.md | 8 ++++++++ packages/stripe/package.json | 2 +- packages/telemetry/CHANGELOG.md | 7 +++++++ packages/telemetry/package.json | 2 +- packages/test-utils/CHANGELOG.md | 8 ++++++++ packages/test-utils/package.json | 2 +- 43 files changed, 193 insertions(+), 43 deletions(-) delete mode 100644 .changeset/fix-revert-2fa-broadening.md delete mode 100644 .changeset/force-allow-id-uuid.md delete mode 100644 .changeset/tighten-adapter-peerdeps.md diff --git a/.changeset/fix-revert-2fa-broadening.md b/.changeset/fix-revert-2fa-broadening.md deleted file mode 100644 index 32a5f0cb70..0000000000 --- a/.changeset/fix-revert-2fa-broadening.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -"better-auth": patch ---- - -fix(two-factor): revert enforcement broadening from #9122 - -Restores the pre-#9122 enforcement scope. 2FA is challenged only on `/sign-in/email`, `/sign-in/username`, and `/sign-in/phone-number`, matching the behavior that shipped through v1.6.2. Non-credential sign-in flows (magic link, email OTP, OAuth, SSO, passkey, SIWE, one-tap, phone-number OTP, device authorization, email-verification auto-sign-in) are no longer gated by a 2FA challenge by default. - -A broader enforcement scope with per-method opt-outs and alignment to NIST SP 800-63B-4 authenticator assurance levels is planned for a future minor release. diff --git a/.changeset/force-allow-id-uuid.md b/.changeset/force-allow-id-uuid.md deleted file mode 100644 index 83a5374f30..0000000000 --- a/.changeset/force-allow-id-uuid.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"better-auth": patch ---- - -Fix forced UUID user IDs from create hooks being ignored on PostgreSQL adapters when `advanced.database.generateId` is set to `"uuid"`. diff --git a/.changeset/tighten-adapter-peerdeps.md b/.changeset/tighten-adapter-peerdeps.md deleted file mode 100644 index 4c10c83b97..0000000000 --- a/.changeset/tighten-adapter-peerdeps.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -"@better-auth/drizzle-adapter": patch -"@better-auth/kysely-adapter": patch -"better-auth": patch ---- - -chore(adapters): require patched `drizzle-orm` and `kysely` peer versions - -Narrows the `drizzle-orm` peer to `^0.45.2` and the `kysely` peer to `^0.28.14`. Both new ranges track the minor line that carries the vulnerability fix and nothing newer, so the adapters only advertise support for versions that have actually been tested against. Consumers on older ORM releases see an install-time warning and can upgrade alongside the adapter; the peer is marked optional, so installs do not hard-fail. diff --git a/packages/api-key/CHANGELOG.md b/packages/api-key/CHANGELOG.md index d35bd8719b..a7a019b18e 100644 --- a/packages/api-key/CHANGELOG.md +++ b/packages/api-key/CHANGELOG.md @@ -1,5 +1,13 @@ # @better-auth/api-key +## 1.6.4 + +### Patch Changes + +- Updated dependencies [[`9aed910`](https://github.com/better-auth/better-auth/commit/9aed910499eb4cbc3dd0c395ff5534893daab7a4), [`acbd6ef`](https://github.com/better-auth/better-auth/commit/acbd6ef69f88ea54174446ac0465a426bad7ca09), [`39d6af2`](https://github.com/better-auth/better-auth/commit/39d6af2a392dc41018a036d1d909dc48c09749c9)]: + - better-auth@1.6.4 + - @better-auth/core@1.6.4 + ## 1.6.3 ### Patch Changes diff --git a/packages/api-key/package.json b/packages/api-key/package.json index ce7e17d5d1..496a3e955d 100644 --- a/packages/api-key/package.json +++ b/packages/api-key/package.json @@ -1,6 +1,6 @@ { "name": "@better-auth/api-key", - "version": "1.6.3", + "version": "1.6.4", "description": "API Key plugin for Better Auth.", "type": "module", "license": "MIT", diff --git a/packages/better-auth/CHANGELOG.md b/packages/better-auth/CHANGELOG.md index aed85b226b..d6e23c80d6 100644 --- a/packages/better-auth/CHANGELOG.md +++ b/packages/better-auth/CHANGELOG.md @@ -1,5 +1,30 @@ # better-auth +## 1.6.4 + +### Patch Changes + +- [#9205](https://github.com/better-auth/better-auth/pull/9205) [`9aed910`](https://github.com/better-auth/better-auth/commit/9aed910499eb4cbc3dd0c395ff5534893daab7a4) Thanks [@gustavovalverde](https://github.com/gustavovalverde)! - fix(two-factor): revert enforcement broadening from [#9122](https://github.com/better-auth/better-auth/issues/9122) + + Restores the pre-[#9122](https://github.com/better-auth/better-auth/issues/9122) enforcement scope. 2FA is challenged only on `/sign-in/email`, `/sign-in/username`, and `/sign-in/phone-number`, matching the behavior that shipped through v1.6.2. Non-credential sign-in flows (magic link, email OTP, OAuth, SSO, passkey, SIWE, one-tap, phone-number OTP, device authorization, email-verification auto-sign-in) are no longer gated by a 2FA challenge by default. + + A broader enforcement scope with per-method opt-outs and alignment to NIST SP 800-63B-4 authenticator assurance levels is planned for a future minor release. + +- [#9068](https://github.com/better-auth/better-auth/pull/9068) [`acbd6ef`](https://github.com/better-auth/better-auth/commit/acbd6ef69f88ea54174446ac0465a426bad7ca09) Thanks [@GautamBytes](https://github.com/GautamBytes)! - Fix forced UUID user IDs from create hooks being ignored on PostgreSQL adapters when `advanced.database.generateId` is set to `"uuid"`. + +- [#9165](https://github.com/better-auth/better-auth/pull/9165) [`39d6af2`](https://github.com/better-auth/better-auth/commit/39d6af2a392dc41018a036d1d909dc48c09749c9) Thanks [@gustavovalverde](https://github.com/gustavovalverde)! - chore(adapters): require patched `drizzle-orm` and `kysely` peer versions + + Narrows the `drizzle-orm` peer to `^0.45.2` and the `kysely` peer to `^0.28.14`. Both new ranges track the minor line that carries the vulnerability fix and nothing newer, so the adapters only advertise support for versions that have actually been tested against. Consumers on older ORM releases see an install-time warning and can upgrade alongside the adapter; the peer is marked optional, so installs do not hard-fail. + +- Updated dependencies [[`39d6af2`](https://github.com/better-auth/better-auth/commit/39d6af2a392dc41018a036d1d909dc48c09749c9)]: + - @better-auth/drizzle-adapter@1.6.4 + - @better-auth/kysely-adapter@1.6.4 + - @better-auth/core@1.6.4 + - @better-auth/memory-adapter@1.6.4 + - @better-auth/mongo-adapter@1.6.4 + - @better-auth/prisma-adapter@1.6.4 + - @better-auth/telemetry@1.6.4 + ## 1.6.3 ### Patch Changes diff --git a/packages/better-auth/package.json b/packages/better-auth/package.json index 341a27800c..7498ce0a2b 100644 --- a/packages/better-auth/package.json +++ b/packages/better-auth/package.json @@ -1,6 +1,6 @@ { "name": "better-auth", - "version": "1.6.3", + "version": "1.6.4", "description": "The most comprehensive authentication framework for TypeScript.", "type": "module", "license": "MIT", diff --git a/packages/cli/CHANGELOG.md b/packages/cli/CHANGELOG.md index 0c7fcc7dcb..447f523a2c 100644 --- a/packages/cli/CHANGELOG.md +++ b/packages/cli/CHANGELOG.md @@ -1,5 +1,14 @@ # auth +## 1.6.4 + +### Patch Changes + +- Updated dependencies [[`9aed910`](https://github.com/better-auth/better-auth/commit/9aed910499eb4cbc3dd0c395ff5534893daab7a4), [`acbd6ef`](https://github.com/better-auth/better-auth/commit/acbd6ef69f88ea54174446ac0465a426bad7ca09), [`39d6af2`](https://github.com/better-auth/better-auth/commit/39d6af2a392dc41018a036d1d909dc48c09749c9)]: + - better-auth@1.6.4 + - @better-auth/core@1.6.4 + - @better-auth/telemetry@1.6.4 + ## 1.6.3 ### Patch Changes diff --git a/packages/cli/package.json b/packages/cli/package.json index a269abd9e8..0729223ff1 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "auth", - "version": "1.6.3", + "version": "1.6.4", "description": "The CLI for Better Auth", "type": "module", "license": "MIT", diff --git a/packages/core/CHANGELOG.md b/packages/core/CHANGELOG.md index 6777f5f58f..85f895df01 100644 --- a/packages/core/CHANGELOG.md +++ b/packages/core/CHANGELOG.md @@ -1,5 +1,7 @@ # @better-auth/core +## 1.6.4 + ## 1.6.3 ## 1.6.2 diff --git a/packages/core/package.json b/packages/core/package.json index 78929b6c68..ab15270410 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,6 +1,6 @@ { "name": "@better-auth/core", - "version": "1.6.3", + "version": "1.6.4", "description": "The most comprehensive authentication framework for TypeScript.", "type": "module", "license": "MIT", diff --git a/packages/drizzle-adapter/CHANGELOG.md b/packages/drizzle-adapter/CHANGELOG.md index b55ca95a3d..9d368fc346 100644 --- a/packages/drizzle-adapter/CHANGELOG.md +++ b/packages/drizzle-adapter/CHANGELOG.md @@ -1,5 +1,16 @@ # @better-auth/drizzle-adapter +## 1.6.4 + +### Patch Changes + +- [#9165](https://github.com/better-auth/better-auth/pull/9165) [`39d6af2`](https://github.com/better-auth/better-auth/commit/39d6af2a392dc41018a036d1d909dc48c09749c9) Thanks [@gustavovalverde](https://github.com/gustavovalverde)! - chore(adapters): require patched `drizzle-orm` and `kysely` peer versions + + Narrows the `drizzle-orm` peer to `^0.45.2` and the `kysely` peer to `^0.28.14`. Both new ranges track the minor line that carries the vulnerability fix and nothing newer, so the adapters only advertise support for versions that have actually been tested against. Consumers on older ORM releases see an install-time warning and can upgrade alongside the adapter; the peer is marked optional, so installs do not hard-fail. + +- Updated dependencies []: + - @better-auth/core@1.6.4 + ## 1.6.3 ### Patch Changes diff --git a/packages/drizzle-adapter/package.json b/packages/drizzle-adapter/package.json index b79fe86797..5e75a0f608 100644 --- a/packages/drizzle-adapter/package.json +++ b/packages/drizzle-adapter/package.json @@ -1,6 +1,6 @@ { "name": "@better-auth/drizzle-adapter", - "version": "1.6.3", + "version": "1.6.4", "description": "Drizzle adapter for Better Auth", "type": "module", "license": "MIT", diff --git a/packages/electron/CHANGELOG.md b/packages/electron/CHANGELOG.md index 480e2495f6..e58f083844 100644 --- a/packages/electron/CHANGELOG.md +++ b/packages/electron/CHANGELOG.md @@ -1,5 +1,13 @@ # @better-auth/electron +## 1.6.4 + +### Patch Changes + +- Updated dependencies [[`9aed910`](https://github.com/better-auth/better-auth/commit/9aed910499eb4cbc3dd0c395ff5534893daab7a4), [`acbd6ef`](https://github.com/better-auth/better-auth/commit/acbd6ef69f88ea54174446ac0465a426bad7ca09), [`39d6af2`](https://github.com/better-auth/better-auth/commit/39d6af2a392dc41018a036d1d909dc48c09749c9)]: + - better-auth@1.6.4 + - @better-auth/core@1.6.4 + ## 1.6.3 ### Patch Changes diff --git a/packages/electron/package.json b/packages/electron/package.json index 77f55e7697..826dc2a139 100644 --- a/packages/electron/package.json +++ b/packages/electron/package.json @@ -1,6 +1,6 @@ { "name": "@better-auth/electron", - "version": "1.6.3", + "version": "1.6.4", "description": "Better Auth integration for Electron applications.", "type": "module", "license": "MIT", diff --git a/packages/expo/CHANGELOG.md b/packages/expo/CHANGELOG.md index 4dd0287d6b..090f85960d 100644 --- a/packages/expo/CHANGELOG.md +++ b/packages/expo/CHANGELOG.md @@ -1,5 +1,13 @@ # @better-auth/expo +## 1.6.4 + +### Patch Changes + +- Updated dependencies [[`9aed910`](https://github.com/better-auth/better-auth/commit/9aed910499eb4cbc3dd0c395ff5534893daab7a4), [`acbd6ef`](https://github.com/better-auth/better-auth/commit/acbd6ef69f88ea54174446ac0465a426bad7ca09), [`39d6af2`](https://github.com/better-auth/better-auth/commit/39d6af2a392dc41018a036d1d909dc48c09749c9)]: + - better-auth@1.6.4 + - @better-auth/core@1.6.4 + ## 1.6.3 ### Patch Changes diff --git a/packages/expo/package.json b/packages/expo/package.json index 82d06a89ba..7617bbbb1b 100644 --- a/packages/expo/package.json +++ b/packages/expo/package.json @@ -1,6 +1,6 @@ { "name": "@better-auth/expo", - "version": "1.6.3", + "version": "1.6.4", "description": "Better Auth integration for Expo and React Native applications.", "type": "module", "license": "MIT", diff --git a/packages/i18n/CHANGELOG.md b/packages/i18n/CHANGELOG.md index d805c607e0..e14d548e83 100644 --- a/packages/i18n/CHANGELOG.md +++ b/packages/i18n/CHANGELOG.md @@ -1,5 +1,13 @@ # @better-auth/i18n +## 1.6.4 + +### Patch Changes + +- Updated dependencies [[`9aed910`](https://github.com/better-auth/better-auth/commit/9aed910499eb4cbc3dd0c395ff5534893daab7a4), [`acbd6ef`](https://github.com/better-auth/better-auth/commit/acbd6ef69f88ea54174446ac0465a426bad7ca09), [`39d6af2`](https://github.com/better-auth/better-auth/commit/39d6af2a392dc41018a036d1d909dc48c09749c9)]: + - better-auth@1.6.4 + - @better-auth/core@1.6.4 + ## 1.6.3 ### Patch Changes diff --git a/packages/i18n/package.json b/packages/i18n/package.json index f02fc9fc24..1634bc2885 100644 --- a/packages/i18n/package.json +++ b/packages/i18n/package.json @@ -1,6 +1,6 @@ { "name": "@better-auth/i18n", - "version": "1.6.3", + "version": "1.6.4", "description": "i18n plugin for Better Auth - translate error messages", "type": "module", "license": "MIT", diff --git a/packages/kysely-adapter/CHANGELOG.md b/packages/kysely-adapter/CHANGELOG.md index 93f3291173..2a60af3b86 100644 --- a/packages/kysely-adapter/CHANGELOG.md +++ b/packages/kysely-adapter/CHANGELOG.md @@ -1,5 +1,16 @@ # @better-auth/kysely-adapter +## 1.6.4 + +### Patch Changes + +- [#9165](https://github.com/better-auth/better-auth/pull/9165) [`39d6af2`](https://github.com/better-auth/better-auth/commit/39d6af2a392dc41018a036d1d909dc48c09749c9) Thanks [@gustavovalverde](https://github.com/gustavovalverde)! - chore(adapters): require patched `drizzle-orm` and `kysely` peer versions + + Narrows the `drizzle-orm` peer to `^0.45.2` and the `kysely` peer to `^0.28.14`. Both new ranges track the minor line that carries the vulnerability fix and nothing newer, so the adapters only advertise support for versions that have actually been tested against. Consumers on older ORM releases see an install-time warning and can upgrade alongside the adapter; the peer is marked optional, so installs do not hard-fail. + +- Updated dependencies []: + - @better-auth/core@1.6.4 + ## 1.6.3 ### Patch Changes diff --git a/packages/kysely-adapter/package.json b/packages/kysely-adapter/package.json index a4735bd650..16b7922dd9 100644 --- a/packages/kysely-adapter/package.json +++ b/packages/kysely-adapter/package.json @@ -1,6 +1,6 @@ { "name": "@better-auth/kysely-adapter", - "version": "1.6.3", + "version": "1.6.4", "description": "Kysely adapter for Better Auth", "type": "module", "license": "MIT", diff --git a/packages/memory-adapter/CHANGELOG.md b/packages/memory-adapter/CHANGELOG.md index 094b44a3b4..c1a6774a1f 100644 --- a/packages/memory-adapter/CHANGELOG.md +++ b/packages/memory-adapter/CHANGELOG.md @@ -1,5 +1,12 @@ # @better-auth/memory-adapter +## 1.6.4 + +### Patch Changes + +- Updated dependencies []: + - @better-auth/core@1.6.4 + ## 1.6.3 ### Patch Changes diff --git a/packages/memory-adapter/package.json b/packages/memory-adapter/package.json index 57255b7ae0..b0b5d31444 100644 --- a/packages/memory-adapter/package.json +++ b/packages/memory-adapter/package.json @@ -1,6 +1,6 @@ { "name": "@better-auth/memory-adapter", - "version": "1.6.3", + "version": "1.6.4", "description": "Memory adapter for Better Auth", "type": "module", "license": "MIT", diff --git a/packages/mongo-adapter/CHANGELOG.md b/packages/mongo-adapter/CHANGELOG.md index 687799c80c..e02237196d 100644 --- a/packages/mongo-adapter/CHANGELOG.md +++ b/packages/mongo-adapter/CHANGELOG.md @@ -1,5 +1,12 @@ # @better-auth/mongo-adapter +## 1.6.4 + +### Patch Changes + +- Updated dependencies []: + - @better-auth/core@1.6.4 + ## 1.6.3 ### Patch Changes diff --git a/packages/mongo-adapter/package.json b/packages/mongo-adapter/package.json index e92d13e269..7ffa697543 100644 --- a/packages/mongo-adapter/package.json +++ b/packages/mongo-adapter/package.json @@ -1,6 +1,6 @@ { "name": "@better-auth/mongo-adapter", - "version": "1.6.3", + "version": "1.6.4", "description": "Mongo adapter for Better Auth", "type": "module", "license": "MIT", diff --git a/packages/oauth-provider/CHANGELOG.md b/packages/oauth-provider/CHANGELOG.md index 383832ec92..40c38e1aef 100644 --- a/packages/oauth-provider/CHANGELOG.md +++ b/packages/oauth-provider/CHANGELOG.md @@ -1,5 +1,13 @@ # @better-auth/oauth-provider +## 1.6.4 + +### Patch Changes + +- Updated dependencies [[`9aed910`](https://github.com/better-auth/better-auth/commit/9aed910499eb4cbc3dd0c395ff5534893daab7a4), [`acbd6ef`](https://github.com/better-auth/better-auth/commit/acbd6ef69f88ea54174446ac0465a426bad7ca09), [`39d6af2`](https://github.com/better-auth/better-auth/commit/39d6af2a392dc41018a036d1d909dc48c09749c9)]: + - better-auth@1.6.4 + - @better-auth/core@1.6.4 + ## 1.6.3 ### Patch Changes diff --git a/packages/oauth-provider/package.json b/packages/oauth-provider/package.json index d577f61e3d..dc9c9aad30 100644 --- a/packages/oauth-provider/package.json +++ b/packages/oauth-provider/package.json @@ -1,6 +1,6 @@ { "name": "@better-auth/oauth-provider", - "version": "1.6.3", + "version": "1.6.4", "description": "An oauth provider plugin for Better Auth", "type": "module", "license": "MIT", diff --git a/packages/passkey/CHANGELOG.md b/packages/passkey/CHANGELOG.md index eb8979089a..917504b9b8 100644 --- a/packages/passkey/CHANGELOG.md +++ b/packages/passkey/CHANGELOG.md @@ -1,5 +1,13 @@ # @better-auth/passkey +## 1.6.4 + +### Patch Changes + +- Updated dependencies [[`9aed910`](https://github.com/better-auth/better-auth/commit/9aed910499eb4cbc3dd0c395ff5534893daab7a4), [`acbd6ef`](https://github.com/better-auth/better-auth/commit/acbd6ef69f88ea54174446ac0465a426bad7ca09), [`39d6af2`](https://github.com/better-auth/better-auth/commit/39d6af2a392dc41018a036d1d909dc48c09749c9)]: + - better-auth@1.6.4 + - @better-auth/core@1.6.4 + ## 1.6.3 ### Patch Changes diff --git a/packages/passkey/package.json b/packages/passkey/package.json index 17654d4eaf..8892f0a26c 100644 --- a/packages/passkey/package.json +++ b/packages/passkey/package.json @@ -1,6 +1,6 @@ { "name": "@better-auth/passkey", - "version": "1.6.3", + "version": "1.6.4", "description": "Passkey plugin for Better Auth", "type": "module", "license": "MIT", diff --git a/packages/prisma-adapter/CHANGELOG.md b/packages/prisma-adapter/CHANGELOG.md index 9505c065c7..9df5f4c7e9 100644 --- a/packages/prisma-adapter/CHANGELOG.md +++ b/packages/prisma-adapter/CHANGELOG.md @@ -1,5 +1,12 @@ # @better-auth/prisma-adapter +## 1.6.4 + +### Patch Changes + +- Updated dependencies []: + - @better-auth/core@1.6.4 + ## 1.6.3 ### Patch Changes diff --git a/packages/prisma-adapter/package.json b/packages/prisma-adapter/package.json index 226ce87c57..d685c25552 100644 --- a/packages/prisma-adapter/package.json +++ b/packages/prisma-adapter/package.json @@ -1,6 +1,6 @@ { "name": "@better-auth/prisma-adapter", - "version": "1.6.3", + "version": "1.6.4", "description": "Prisma adapter for Better Auth", "type": "module", "license": "MIT", diff --git a/packages/redis-storage/CHANGELOG.md b/packages/redis-storage/CHANGELOG.md index c21d57d2f3..d3efe9da46 100644 --- a/packages/redis-storage/CHANGELOG.md +++ b/packages/redis-storage/CHANGELOG.md @@ -1,5 +1,12 @@ # @better-auth/redis-storage +## 1.6.4 + +### Patch Changes + +- Updated dependencies []: + - @better-auth/core@1.6.4 + ## 1.6.3 ### Patch Changes diff --git a/packages/redis-storage/package.json b/packages/redis-storage/package.json index c971e39fe5..7afc1a6152 100644 --- a/packages/redis-storage/package.json +++ b/packages/redis-storage/package.json @@ -1,6 +1,6 @@ { "name": "@better-auth/redis-storage", - "version": "1.6.3", + "version": "1.6.4", "description": "Redis storage for Better Auth secondary storage", "type": "module", "license": "MIT", diff --git a/packages/scim/CHANGELOG.md b/packages/scim/CHANGELOG.md index bbf91cae04..8f319464b4 100644 --- a/packages/scim/CHANGELOG.md +++ b/packages/scim/CHANGELOG.md @@ -1,5 +1,13 @@ # @better-auth/scim +## 1.6.4 + +### Patch Changes + +- Updated dependencies [[`9aed910`](https://github.com/better-auth/better-auth/commit/9aed910499eb4cbc3dd0c395ff5534893daab7a4), [`acbd6ef`](https://github.com/better-auth/better-auth/commit/acbd6ef69f88ea54174446ac0465a426bad7ca09), [`39d6af2`](https://github.com/better-auth/better-auth/commit/39d6af2a392dc41018a036d1d909dc48c09749c9)]: + - better-auth@1.6.4 + - @better-auth/core@1.6.4 + ## 1.6.3 ### Patch Changes diff --git a/packages/scim/package.json b/packages/scim/package.json index 9ed8517250..df831f108f 100644 --- a/packages/scim/package.json +++ b/packages/scim/package.json @@ -1,6 +1,6 @@ { "name": "@better-auth/scim", - "version": "1.6.3", + "version": "1.6.4", "description": "SCIM plugin for Better Auth", "type": "module", "license": "MIT", diff --git a/packages/sso/CHANGELOG.md b/packages/sso/CHANGELOG.md index 6815d1a9e3..3b452c8fc7 100644 --- a/packages/sso/CHANGELOG.md +++ b/packages/sso/CHANGELOG.md @@ -1,5 +1,13 @@ # @better-auth/sso +## 1.6.4 + +### Patch Changes + +- Updated dependencies [[`9aed910`](https://github.com/better-auth/better-auth/commit/9aed910499eb4cbc3dd0c395ff5534893daab7a4), [`acbd6ef`](https://github.com/better-auth/better-auth/commit/acbd6ef69f88ea54174446ac0465a426bad7ca09), [`39d6af2`](https://github.com/better-auth/better-auth/commit/39d6af2a392dc41018a036d1d909dc48c09749c9)]: + - better-auth@1.6.4 + - @better-auth/core@1.6.4 + ## 1.6.3 ### Patch Changes diff --git a/packages/sso/package.json b/packages/sso/package.json index c99cbef575..cf035bc576 100644 --- a/packages/sso/package.json +++ b/packages/sso/package.json @@ -1,6 +1,6 @@ { "name": "@better-auth/sso", - "version": "1.6.3", + "version": "1.6.4", "description": "SSO plugin for Better Auth", "type": "module", "license": "MIT", diff --git a/packages/stripe/CHANGELOG.md b/packages/stripe/CHANGELOG.md index bf09467d7b..875c6ed100 100644 --- a/packages/stripe/CHANGELOG.md +++ b/packages/stripe/CHANGELOG.md @@ -1,5 +1,13 @@ # @better-auth/stripe +## 1.6.4 + +### Patch Changes + +- Updated dependencies [[`9aed910`](https://github.com/better-auth/better-auth/commit/9aed910499eb4cbc3dd0c395ff5534893daab7a4), [`acbd6ef`](https://github.com/better-auth/better-auth/commit/acbd6ef69f88ea54174446ac0465a426bad7ca09), [`39d6af2`](https://github.com/better-auth/better-auth/commit/39d6af2a392dc41018a036d1d909dc48c09749c9)]: + - better-auth@1.6.4 + - @better-auth/core@1.6.4 + ## 1.6.3 ### Patch Changes diff --git a/packages/stripe/package.json b/packages/stripe/package.json index 5f681c6912..d7ff79dda9 100644 --- a/packages/stripe/package.json +++ b/packages/stripe/package.json @@ -1,6 +1,6 @@ { "name": "@better-auth/stripe", - "version": "1.6.3", + "version": "1.6.4", "description": "Stripe plugin for Better Auth", "type": "module", "license": "MIT", diff --git a/packages/telemetry/CHANGELOG.md b/packages/telemetry/CHANGELOG.md index a7b19b2545..608c76a334 100644 --- a/packages/telemetry/CHANGELOG.md +++ b/packages/telemetry/CHANGELOG.md @@ -1,5 +1,12 @@ # @better-auth/telemetry +## 1.6.4 + +### Patch Changes + +- Updated dependencies []: + - @better-auth/core@1.6.4 + ## 1.6.3 ### Patch Changes diff --git a/packages/telemetry/package.json b/packages/telemetry/package.json index fe9cf454f5..9b7ddb92dd 100644 --- a/packages/telemetry/package.json +++ b/packages/telemetry/package.json @@ -1,6 +1,6 @@ { "name": "@better-auth/telemetry", - "version": "1.6.3", + "version": "1.6.4", "description": "Telemetry package for Better Auth", "type": "module", "license": "MIT", diff --git a/packages/test-utils/CHANGELOG.md b/packages/test-utils/CHANGELOG.md index c425c1b6fc..44073044c1 100644 --- a/packages/test-utils/CHANGELOG.md +++ b/packages/test-utils/CHANGELOG.md @@ -1,5 +1,13 @@ # @better-auth/test-utils +## 1.6.4 + +### Patch Changes + +- Updated dependencies [[`9aed910`](https://github.com/better-auth/better-auth/commit/9aed910499eb4cbc3dd0c395ff5534893daab7a4), [`acbd6ef`](https://github.com/better-auth/better-auth/commit/acbd6ef69f88ea54174446ac0465a426bad7ca09), [`39d6af2`](https://github.com/better-auth/better-auth/commit/39d6af2a392dc41018a036d1d909dc48c09749c9)]: + - better-auth@1.6.4 + - @better-auth/core@1.6.4 + ## 1.6.3 ### Patch Changes diff --git a/packages/test-utils/package.json b/packages/test-utils/package.json index 7b9cd0f7e0..822a75180d 100644 --- a/packages/test-utils/package.json +++ b/packages/test-utils/package.json @@ -1,6 +1,6 @@ { "name": "@better-auth/test-utils", - "version": "1.6.3", + "version": "1.6.4", "description": "Testing utilities for Better Auth adapter development", "type": "module", "license": "MIT",