Skip to content

Update Routine updates - #376

Open
renovate[bot] wants to merge 1 commit into
mainfrom
renovate/routine-updates
Open

renovate[bot] wants to merge 1 commit into
mainfrom
renovate/routine-updates

Conversation

@renovate

@renovate renovate Bot commented May 12, 2026 •

Copy link
Copy Markdown
Contributor

Note

This PR body was truncated due to platform limits.

This PR contains the following updates:

Package Change Age Confidence Type Update Pending
@better-auth/core (source) 1.6.15 → 1.7.7 age confidence devDependencies minor 1.7.10 (+2)
@better-auth/test-utils (source) 1.6.15 → 1.7.7 age confidence devDependencies minor 1.7.10 (+2)
@better-fetch/fetch (source) 1.1.21 → 1.3.2 age confidence dependencies minor
@eslint/eslintrc 3.3.5 → 3.3.7 age confidence devDependencies patch
@eslint/js (source) 9.39.4 → 9.39.5 age confidence devDependencies patch
@playwright/test (source) 1.60.0 → 1.64.0 age confidence dependencies minor 1.64.1
@tailwindcss/postcss (source) 4.3.0 → 4.3.3 age confidence devDependencies patch
@tanstack/react-start (source) 1.168.60 → 1.169.1 age confidence devDependencies minor 1.169.2
@types/mdx (source) 2.0.13 → 2.0.14 age confidence devDependencies patch
@types/node (source) 24.12.3 → 24.19.2 age confidence devDependencies minor
@types/react (source) 19.2.14 → 19.3.0 age confidence devDependencies minor
@types/react-dom (source) 19.2.3 → 19.3.0 age confidence devDependencies minor
@types/semver (source) 7.7.1 → 7.8.0 age confidence devDependencies minor
actions/checkout (changelog) de0fac2 → d23441a action digest
actions/setup-node (changelog) 48b55a0 → 2499707 action digest
adm-zip ^0.5.16 → ^0.6.0 age confidence dependencies minor
better-auth (source) >=1.6.11 <1.7.0 → >=1.6.11 <1.8.0 age confidence peerDependencies minor 1.7.10 (+2)
better-auth (source) 1.6.15 → 1.7.7 age confidence devDependencies minor 1.7.10 (+2)
concurrently 10.0.3 → 10.0.6 age confidence devDependencies patch
eslint (source) 9.39.4 → 9.39.5 age confidence devDependencies patch
eslint (source) 10.3.0 → 10.12.0 age confidence devDependencies minor
eslint-config-next (source) 16.2.6 → 16.4.0 age confidence devDependencies minor 16.4.2 (+1)
eslint-plugin-react-refresh 0.5.2 → 0.5.7 age confidence devDependencies patch
fumadocs-core 16.8.8 → 16.17.1 age confidence dependencies minor 16.17.4 (+2)
fumadocs-ui 16.8.8 → 16.17.1 age confidence dependencies minor 16.17.4 (+2)
globals 17.6.0 → 17.13.0 age confidence devDependencies minor
jose 6.2.3 → 6.2.12 age confidence dependencies patch
next (source) 16.2.6 → 16.4.0 age confidence devDependencies minor 16.4.2 (+1)
next (source) 16.2.6 → 16.4.0 age confidence dependencies minor 16.4.2 (+1)
pkg-pr-new (source) 0.0.71 → 0.0.91 age confidence devDependencies patch
postcss (source) 8.5.14 → 8.5.30 age confidence devDependencies patch
prettier (source) 3.8.3 → 3.9.10 age confidence devDependencies minor
raven-actions/actionlint v2.1.2 → v2.2.0 age confidence action minor
react (source) 19.2.6 → 19.3.0 age confidence devDependencies minor 19.3.1
react (source) 19.2.6 → 19.3.0 age confidence dependencies minor 19.3.1
react-dom (source) 19.2.6 → 19.3.0 age confidence devDependencies minor 19.3.1
react-dom (source) 19.2.6 → 19.3.0 age confidence dependencies minor 19.3.1
remeda (source) 2.34.0 → 2.51.0 age confidence dependencies minor 2.52.0
semver 7.8.0 → 7.8.5 age confidence dependencies patch
tailwindcss (source) 4.3.0 → 4.3.3 age confidence devDependencies patch
type-fest 5.6.0 → 5.10.0 age confidence dependencies minor
typescript-eslint (source) 8.59.2 → 8.71.2 age confidence devDependencies minor
vitest (source) 4.1.5 → 4.1.11 age confidence devDependencies patch 4.1.12
zizmorcore/zizmor-action v0.5.6 → v0.6.4 age confidence action minor v0.7.1 (+1)
zod (source) 4.6.5 → 4.6.7 age confidence dependencies patch

Release Notes

better-auth/better-auth (@​better-auth/core)

v1.7.7

Compare Source

v1.7.6

Compare Source

Patch Changes

v1.7.5

Compare Source

Patch Changes
  • #​11203 cb627eb Thanks @​dshukertjr! - Add a database.schemaName option for direct PostgreSQL connections. When set, the adapter and the CLI qualify every statement with that schema, so auth generate writes a schema-qualified migration that creates the schema before its tables instead of relying on the connection's search_path.

  • #​11290 dae97ed Thanks @​bytaesu! - Restore database option type inference for projects that do not use Cloudflare Workers.

v1.7.4

Compare Source

Patch Changes
  • #​11210 3ff842a Thanks @​bytaesu! - Prevent bundlers such as Metro from failing when the optional OpenTelemetry API is not installed.

  • #​11224 c1756a2 Thanks @​bytaesu! - Add experimental.instrumentation.enabled to disable Better Auth OpenTelemetry span creation per auth instance. Instrumentation remains enabled by default and independent of usage reporting.

v1.7.3

Compare Source

Patch Changes
  • #​11179 352d012 Thanks @​bytaesu! - Validate Drizzle schema objects and generated Prisma client models during initialization, including in production, and report mismatches with guidance for fixing them. These checks do not query the database and cannot detect unapplied migrations.

    For Prisma clients whose model metadata omits nullability, auth generate reports required fields that Better Auth never writes by reading the existing Prisma schema. Set advanced.database.validateSchema: false to disable runtime validation.

  • #​9908 76d311f Thanks @​harshil1712! - Add Cloudflare as a built-in social provider, with support for client-secret authentication and PKCE clients without a secret.

  • #​11101 3e9e197 Thanks @​bytaesu! - Add a custom token endpoint authentication strategy for providers that require non-standard request parameters.

  • #​11068 157ec8d Thanks @​bytaesu! - Improve request IP validation performance.

  • #​11102 baa08f4 Thanks @​bytaesu! - Fix TikTok sign-in and token refresh failing when configured with the documented clientKey and clientSecret options.

  • #​11129 9e36635 Thanks @​bytaesu! - Improve PayPal authorization code and refresh token requests, including PKCE parameter handling.

  • #​11178 be0e007 Thanks @​bytaesu! - Report missing tables, missing columns, and required columns Better Auth never writes during initialization, with guidance for fixing them. Kysely checks the live database schema. Authentication requests await the same check and are rejected if the schema does not match.

    Validation is enabled by default, including in production. Set advanced.database.validateSchema: false to disable runtime validation. auth migrate refuses to apply changes when required unwritten columns need manual repair.

  • #​11134 a2bae0c Thanks @​bytaesu! - Improve Reddit token requests with OAuth-compliant Basic authentication and redirect protection.

  • #​11189 1a1b7d5 Thanks @​bytaesu! - Make consumeOne and incrementOne optional again for custom database adapters, using guarded fallbacks when native methods are absent. Fallbacks require atomic conditional writes and accurate affected-row counts. Fallback increments can fail when contention exhausts their retries.

  • #​11153 2220ee7 Thanks @​bytaesu! - Restore sign-in compatibility with 1.6 databases by identifying accounts with (providerId, accountId) and removing the issuer requirement introduced in 1.7.0. Upgrading from 1.6 no longer requires an account schema migration. Ambiguous account keys are rejected instead of selecting an arbitrary account.

    If you applied the 1.7.0 through 1.7.2 account schema, remove its issuer unique index before upgrading. For SQL databases, also make issuer nullable or remove the column so sign-ups and account linking can succeed. auth migrate does not perform this cleanup. Follow the upgrade guide for database-specific steps.

v1.7.2

Compare Source

Patch Changes
  • #​10938 557e19b Thanks @​bytaesu! - Added synchronous auth endpoint context access with getCurrentAuthEndpointContext and optional access with tryGetCurrentAuthEndpointContext. The existing getCurrentAuthContext and getCurrentAuthContextAsyncLocalStorage functions remain available as deprecated compatibility APIs.

  • #​10855 64da15b Thanks @​bytaesu! - Prevent async context loss in Cloudflare Workers bundles that enable multiple runtime conditions.

  • #​10982 b4ad5a1 Thanks @​bytaesu! - Built-in placeholder emails now consistently use the namespaced {identifier}@{namespace}.placeholder.invalid format.

  • #​10979 fced1a5 Thanks @​bytaesu! - Allow relative callback and redirect URLs to use standard path, query, and fragment syntax while preserving open-redirect protections.

  • #​10939 e1d4011 Thanks @​bytaesu! - Logs emitted while handling auth requests now respect the configured custom logger, log level, and disabled setting.

v1.7.1

Patch Changes
  • #​11612 fedd055 Thanks @​vhinayindia! - If your resource server verifies access tokens with verifyAccessTokenRequest or verifyBearerToken and a jwksUrl, including through the MCP plugin, a key set that cannot be reached at all, for example a refused connection, now throws an error. Before, the token was rejected as invalid with 401 "no token payload", which hid the outage. A key set that answers with an HTTP error already threw.

    With remoteVerify configured, such a failure no longer falls back to remote introspection.

    The OAuth provider's /oauth2/introspect, /oauth2/userinfo and /oauth2/revoke behave the same way with the JWT plugin's jwks.remoteUrl: they return 500 instead of reporting the token as invalid.

  • #​11805 bbd0a19 Thanks @​gustavovalverde! - Servers that verify JWTs against a key set now refetch that key set at most once every 30 seconds per server process when a token names a key ID (kid) the cached set does not contain. This covers the OAuth provider plugin's introspection, revocation, UserInfo, and logout endpoints, and resource servers that call verifyAccessTokenRequest or verifyBearerToken with jwksUrl. Previously every such token caused a new fetch: a remote request with jwksUrl or jwks.remoteUrl, or otherwise a read of the jwks table. Anyone could send tokens with made-up kid values to force one fetch per request, and the UserInfo endpoint needs no client credentials.

    Concurrent verifications now share one fetch, and a key set fetch that takes longer than 5 seconds fails with a JWKSTimeout error instead of waiting indefinitely.

    A token signed with a newly published key still verifies without waiting for the 5-minute cache to expire. It can be rejected for up to 30 seconds if the key set was already refetched for another unknown kid in that time. No configuration change is needed.

v1.7.0

Minor Changes
  • #​10577 5c45abc Thanks @​gustavovalverde! - Client ID Metadata Documents now follow shared-cache freshness rules and fail closed when freshness is ambiguous. The plugin prefers s-maxage over max-age and Expires, honors s-maxage=0, conditionally revalidates with ETag or Last-Modified, and treats invalid or duplicate freshness directives as immediately stale. Concurrent refreshes converge on one client-resource link instead of failing on its unique constraint.

    Shared OAuth metadata validation now rejects a blank client_name without trimming a valid display name. Native private-use redirects require the RFC 8252 single-slash form, such as com.example.app:/callback. Native HTTP redirects accept only exact localhost, 127.0.0.1, or [::1] hosts; other 127.0.0.0/8 addresses and localhost subdomains are rejected.

    CIMD now bounds metadata request amplification through metadataFetchPolicy: same-client fetches coalesce, per-client pacing and global/per-origin concurrency reject immediately, and rolling 60-second budgets cap unique-client sprays. HTTP no-store, private, and Vary: * behavior is unchanged and never feeds metadata or validators into the governor.

    Node.js deployments can import fetchClientMetadataResource from @better-auth/cimd/node. The transport resolves once, rejects any non-public DNS answer, pins the approved connection without using the global HTTPS pool, preserves Host and TLS certificate identity, and returns redirects and response bodies without buffering. Other runtimes remain responsible for providing an equivalent secure transport.

    Unknown draft-02 metadata members are now ignored and never persisted. Recognized secrets, privilege fields, and server controls remain fatal, while generic internal aliases and nonstandard client-credentials authority spellings are stripped.

  • #​10402 763a267 Thanks @​gustavovalverde! - Plugin database schemas can now define named or generated table-level indexes across multiple fields. SQL migrations and generated Drizzle or Prisma schemas resolve configured table and column names consistently, while the MongoDB adapter creates the same indexes before the first index-enforcing write.

  • #​9948 3d04fab Thanks @​yordis! - feat(generic-oauth): add refreshTokenParams config to forward extra params on token refresh

    Multi-tenant OIDC providers (Zitadel multi-org, Auth0 with audience) need to send extra body params on the refresh call to rescope tokens without a full authorization redirect. The generic-oauth plugin now accepts a refreshTokenParams option (object or sync/async function) that is merged into the refresh request body, with grant_type and refresh_token protected from override. The function form receives request metadata for the request that triggered the refresh, so request-scoped data (headers, cookies) is available without out-of-band state like AsyncLocalStorage.

    UpstreamProvider.refreshAccessToken now accepts an optional second ctx argument; the change is backwards compatible because existing implementations that take only refreshToken remain valid. See #​7554.

  • #​9368 430c895 Thanks @​GautamBytes! - Generic OAuth users can now sign out from the configured OpenID provider when they call authClient.signOut(). When a provider exposes a discovered or configured logout endpoint, Better Auth redirects to it and includes the stored id_token_hint when available. Pass callbackURL or configure postLogoutRedirectURI for the return flow, with optional state, or set disableRedirect to handle the returned url yourself. When multiple linked providers support logout, Better Auth selects the most recently updated account. Set disableProviderLogout: true to keep sign-out local.

  • #​10577 5c45abc Thanks @​gustavovalverde! - MCP clients that hit a scope wall now learn exactly which scopes to ask for. Missing protected scopes produce a 403 with an RFC 6750 insufficient_scope WWW-Authenticate challenge that names every missing scope. Clients can union those scopes into one authorization request instead of opening one browser redirect per scope.

    • Configure protected scopes with requiredScopes through RequireMcpAuthOptions or the matching createMcpProtectedRequestHandler verifier option. Exact membership remains the default; isScopeSatisfied can define hierarchical policies.
    • Use createInsufficientScopeError when an operation determines its required scopes dynamically. createResourceServerChallenge converts that signal and recognized token failures into safe RFC 6750 challenges.
    • Use challengeScopes only as the unauthenticated challenge hint.

    Handler-produced responses, ordinary permission denials, configuration failures, and unrelated thrown values keep their original status and identity.

  • #​10403 dbd302e Thanks @​gustavovalverde! - Scope account identity by trusted issuer instead of provider configuration. Accounts now use the unique (issuer, accountId) key, so aliases for one OpenID Connect issuer deduplicate one external identity while equal subjects from different issuers remain separate. This identity deduplication does not introduce independent grant or provider lifecycle records for aliases.

    This release requires Account.issuer but preserves Account.accountId as the provider-assigned account identifier. Account-specific APIs select the local Account.id through the accountId request property; token and provider-profile APIs can instead select the signed account cookie with useAccountCookie: true. Credential accounts use local:credential and the linked user's stable id as their provider identity.

    OAuth provider identity now comes from raw verified profiles. OpenID Connect discovery uses sub, plain OAuth uses id, and providers can declare accountSubject for another immutable field; Better Auth no longer switches between sub and id at runtime. getUserInfo().user no longer carries provider identity, and mapProfileToUser cannot return id. Read the selected identity from accountInfo.account.accountId instead of accountInfo.user.id. The generic microsoftEntraId helper now requires a concrete tenant GUID; use the built-in Microsoft provider for multi-tenant authorities.

    SSO account subjects are now protocol-defined. OIDC uses the verified sub claim, and SAML uses the signed NameID; mapping.id is removed from both configurations. A manual SAML configuration without metadata XML must set idpMetadata.entityID, because samlConfig.issuer identifies the service provider and no longer acts as the IdP identity.

    Apply the reviewed account-identity backfill in the Better Auth 1.7 upgrade guide before deploying. The generated schema migration cannot assign trusted issuers or resolve existing identity collisions automatically.

  • #​10359 8784c1c Thanks @​ping-maxwell! - Database joins have moved out of experimental into a stable option at advanced.database.joins (default: false).

    If you previously set experimental: { joins: true }, update your config to:

    advanced: {
      database: {
        joins: true,
      },
    }

    Adapters that support native joins use them when enabled. If an adapter cannot return joined data for a query, Better Auth falls back to additional queries and combines the results. Drizzle and Prisma users should ensure their schema includes the required relations (npx auth@latest generate).

  • #​10204 0683a5f Thanks @​GautamBytes! - Microsoft sign-in now identifies Entra accounts with the stable oid claim in both the built-in microsoft provider and the Generic OAuth microsoftEntraId helper. Tokens without a valid oid are rejected, and the Generic OAuth helper refuses to initialize unless Microsoft discovery provides ID-token verification metadata. Existing Microsoft account rows created from sub must be migrated before upgrading.

  • #​9305 e7eb45b Thanks @​gustavovalverde! - feat(oauth): per-request additionalParams and loginHint parity across signIn.social, linkSocial, and signIn.sso

    Unified escape hatch for customizing the provider authorization URL on a per-request basis. Previously, dynamic parameters like Google's access_type=offline / prompt=consent, Cognito's identity_provider=Google, or Microsoft's domain_hint could only be set as static server configuration.

New capabilities
  • signIn.social, linkSocial, and signIn.sso accept additionalParams: Record<string, string>. Values are appended to the authorization URL as query parameters.
  • linkSocial also accepts loginHint, matching the surface of signIn.social and signIn.sso.
  • OAuthProvider.createAuthorizationURL gains additionalParams in its input contract; every built-in provider forwards it to the shared helper.
  • Generic-OAuth providers merge call-time additionalParams with the config-level authorizationUrlParams; call-time wins on key collision.
  • Cognito exposes a typed identityProvider?: string config option that maps to the identity_provider query parameter, avoiding magic strings.
Security
  • The shared createAuthorizationURL helper silently drops any caller-supplied key in RESERVED_AUTHORIZATION_PARAMS (state, client_id, redirect_uri, response_type, code_challenge, code_challenge_method, nonce, scope). The request-body Zod schema rejects the same keys with 400, so misuse is visible at the edge rather than silently overriding security-critical parameters. nonce is reserved so a caller cannot replace the OIDC nonce Better Auth generates when binding a discovery provider's id_token to the authorization request.
  • Providers that use non-standard client identifiers (wechat → appid, tiktok → client_key) additionally filter those keys so a caller cannot swap the configured OAuth app.
  • Provider protocol constants that are required for the integration to function (atlassian → audience, notion → owner) are merged last so caller-supplied additionalParams cannot override them. Configured defaults that represent operator intent (e.g. Google include_granted_scopes, Cognito identityProvider) remain caller-overridable.
  • signIn.sso rejects additionalParams with 400 when the resolved provider is SAML; the SAML AuthnRequest is signed and cannot carry caller-supplied query parameters, so silently dropping them would mislead integrators.
OpenAPI
  • Added ZodRecord handling to the OpenAPI generator so z.record() fields emit type: object with typed additionalProperties. Incidentally fixes a long-standing bug where additionalData was rendered as type: string.
Refactors
  • discord, roblox, zoom, and slack providers now delegate to the shared createAuthorizationURL helper and inherit its RFC behavior and reserved-key guard.
  • tiktok and wechat keep their manual URL construction (non-standard OAuth2 parameter names and URL fragment requirements) but thread additionalParams with the same reserved-key filter.

Closes #​2351.
Closes #​5441.
Closes #​5592.
Closes #​5604.
Supersedes #​4992 and #​5443.

  • #​10127 7c7313c Thanks @​gustavovalverde! - OAuth sign-in, account linking, callback, and proxy flows now build redirect_uri from the current request base URL when baseURL.allowedHosts is configured. Built-in social providers and generic OAuth providers now use the resolved request host for redirects in multi-host deployments.

    Custom OAuthProvider implementations can omit callbackPath when using the shared /callback/<provider-id> route. Set callbackPath only for custom callback routes.

  • #​10039 aedcb97 Thanks @​gustavovalverde! - feat(oauth-provider)!: DPoP-bound access tokens (RFC 9449)

    OAuth provider integrations can issue and verify DPoP sender-constrained tokens. Clients request them with dpop_bound_access_tokens at registration, dpop_jkt on the authorization request, or by targeting a resource configured with dpopBoundAccessTokensRequired. Issued tokens carry cnf.jkt, return token_type: "DPoP", and stay bound through refresh-token rotation, introspection, and userinfo.

    Resource servers verify DPoP requests with verifyAccessTokenRequest, which checks the Authorization: DPoP scheme, the proof, the request target, the access-token hash, and proof replay. The MCP package advertises DPoP in protected resource metadata and verifies DPoP-bound requests. Proof replay is rejected through the database-backed verification store, so anti-replay holds across instances. verifyAccessTokenRequest and requireMcpAuth use that store by default; build one with createDpopReplayStore(internalAdapter) or pass a custom dpop.replayStore. This needs database-backed verification storage: a secondary-storage-only deployment rejects DPoP requests rather than skipping replay protection.

    Breaking: the raw-token verifier verifyAccessToken is renamed to verifyBearerToken, both in better-auth/oauth2 and as the oauthProviderResourceClient action, and it rejects DPoP-bound tokens. Use verifyAccessTokenRequest on any endpoint that may receive them. The resource-request input type is renamed from AccessTokenRequestInput to ResourceRequestInput, and the DPoP algorithm option is signingAlgorithms everywhere.

    Run a schema migration for the DPoP token-binding fields: the confirmation column on the access-token and refresh-token tables. DPoP-bound clients also gain dpopBoundAccessTokens and resources dpopBoundAccessTokensRequired. No dedicated replay table is added; proof replay reuses the verification store.

  • #​9828 4f53b61 Thanks @​gustavovalverde! - Verify social-provider id_tokens with a single shared verifier.

    Client-submitted id_token sign-in (signIn.social({ idToken }) and account linking) is verified by one function instead of a per-provider verifyIdToken method. Each provider declares an idToken config with a JWKS source, issuer, and audience, and the core verifier runs the signature, issuer, audience, and nonce checks. A provider that declares no config rejects the client id_token path.

    PayPal previously accepted any decodable id_token without verifying its signature. PayPal derives identity from the access token, so it now declares no idToken config, and the client id_token path returns ID_TOKEN_NOT_SUPPORTED. PayPal sign-in through the redirect flow is unchanged.

    Custom providers that implement UpstreamProvider directly replace the removed verifyIdToken method with an idToken config:

    idToken: {
    	jwks: createRemoteJWKSet(new URL("https://issuer.example/.well-known/jwks.json")),
    	issuer: "https://issuer.example",
    	audience: clientId,
    },

    For verification that cannot use a local JWKS, pass idToken: { verify: async (token, nonce) => boolean }. The verifyIdToken and disableIdTokenSignIn provider options are unchanged.

  • #​10065 2196ea6 Thanks @​gustavovalverde! - OAuth and device-authorization responses that carry credentials now consistently send Cache-Control: no-store and Pragma: no-cache, so proxies, CDNs, and browsers never cache them. This covers the token, introspection, and userinfo endpoints, dynamic and admin client registration, client secret rotation, and the device code and device token responses, including the error responses from those endpoints.

    Endpoints declare this with metadata: { noStore: true }, and the header set is exported from @better-auth/core as NO_STORE_HEADERS for responses built by hand.

  • #​9929 91f235f Thanks @​gustavovalverde! - Add requireEmailVerification to OAuth provider options, for built-in social providers and the Generic OAuth plugin. When a provider reports an unverified email, the user and account are still created or linked, but no session is issued: the OAuth callback redirects with ?error=email_not_verified, and ID token and One Tap sign-in return 403 EMAIL_NOT_VERIFIED. Verification emails follow the existing emailVerification.sendOnSignUp / sendOnSignIn settings.

    It is opt-in per provider and does not inherit emailAndPassword.requireEmailVerification, so existing social logins keep working. The gate checks the local user's verification state, so a user verified through another method keeps access. Only enable it for providers that report a trustworthy email_verified signal.

  • #​8931 34558bc Thanks @​GautamBytes! - Add opt-in JWKS-backed asymmetric JWT support for session_data cookie cache tokens, so services can verify cookie-cache JWTs with public keys instead of shared secrets. Enable it with jwt({ sessionCookieCache: true }) alongside session.cookieCache.strategy = "jwt".

  • #​9657 1e5b808 Thanks @​gustavovalverde! - Harden private_key_jwt and token endpoint client authentication, and add the helpers that make the fix structural.

    @better-auth/core/oauth2 now exposes encodeBasicCredentials and decodeBasicCredentials, a round-trip-tested pair that follows RFC 6749 §2.3.1 (application/x-www-form-urlencoded each value, split on the first : only). The decoder accepts the scheme case-insensitively and tolerates one or more spaces before the credentials per RFC 7235 §2.1. client_secret_basic on the client side and the Better Auth OAuth provider on the server side both go through these helpers, so credentials containing reserved characters round-trip cleanly across the stack and headers like basic xxx or Basic xxx are accepted.

    createPrivateKeyJwtClientAssertionGetter validates options eagerly. Unsupported algorithms (HS256, none), a JWK with no key material, and disagreement between an explicit algorithm and the JWK-embedded alg all throw at construction rather than on the first token request. signPrivateKeyJwtClientAssertion enforces the same checks for direct callers. Breaking: configurations that paired an unsupported JWK alg with a different explicit algorithm used to silently sign with the explicit option; they now fail at construction.

    Breaking: @better-auth/oauth-provider accepts client jwks metadata only as an RFC 7517 JWK Set object with a non-empty keys array. Replace jwks: [key] with jwks: { keys: [key] } in DCR payloads, administrative and user client creation, Client ID Metadata Documents, test fixtures, and generated client code. Remotely fetched jwks_uri responses must use the same object shape. EC keys must use P-256, P-384, or P-521; OKP keys must use Ed25519. When a key declares alg, it must be a supported private_key_jwt algorithm that matches the key type and curve; omit alg when the client chooses the algorithm in its assertion header. OAuth client rows previously written through oauthToSchema are already stored as JWK Set objects, so this is a request, configuration, and type migration rather than another database rewrite; audit rows written outside Better Auth separately.

    The SSO private_key_jwt flow redirects with error_description=no_private_key_available when a resolvePrivateKey callback returns no privateKeyJwk or privateKeyPem. The redirect path previously short-circuited only when the resolver was absent entirely; an empty resolver return fell through into an internal signing error.

    better-auth/test adds getHttpTestInstance, a counterpart to getTestInstance that binds a real HTTP listener on an OS-assigned port and constructs the auth instance against the discovered URL. It removes the temp-server-then-rebind race that test files have been individually copy-pasting.

  • #​8836 93d3871 Thanks @​gustavovalverde! - Add client authentication configuration for token endpoint requests across the stack, including private_key_jwt (RFC 7523).

    Generic OAuth providers now accept tokenEndpointAuth for token endpoint client authentication. Use `tokenEndpointAuth: { method: "private_key_jwt", getClientAssertion

[!IMPORTANT]
✂ PR body was truncated to here.


Configuration

📅 Schedule: (in timezone America/Los_Angeles)

  • Branch creation
    • Monday through Friday (* * * * 1-5)
  • Automerge
    • At any time (no schedule defined)

🚦 Automerge: Enabled.

♻ Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

👻 Immortal: This PR will be recreated if closed unmerged. Get config help if that's undesired.


  • If you want to rebase/retry this PR, check this box

This PR was generated by Mend Renovate. View the repository job log.

@vercel

vercel Bot commented May 12, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
better-auth Ready Ready Preview Oct 16, 2026 12:47am UTC

Request Review

@pkg-pr-new

pkg-pr-new Bot commented May 12, 2026 •

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/@convex-dev/better-auth@376

commit: 5fab04d

@renovate
renovate Bot force-pushed the renovate/routine-updates branch from 63dc237 to 87fb859 Compare May 13, 2026 09:38
@renovate renovate Bot changed the title Update Routine updates to v1.6.10 Update Routine updates May 13, 2026
@renovate
renovate Bot force-pushed the renovate/routine-updates branch from 87fb859 to 8e9ad8a Compare May 14, 2026 18:34
@renovate
renovate Bot force-pushed the renovate/routine-updates branch from 8e9ad8a to 4d7b750 Compare May 14, 2026 20:25
@renovate
renovate Bot force-pushed the renovate/routine-updates branch from 4d7b750 to 1787003 Compare May 15, 2026 01:29
@renovate
renovate Bot force-pushed the renovate/routine-updates branch from 1787003 to 931f226 Compare May 15, 2026 17:14
@renovate
renovate Bot force-pushed the renovate/routine-updates branch from 931f226 to 267cd41 Compare May 16, 2026 12:42
@renovate
renovate Bot force-pushed the renovate/routine-updates branch from 267cd41 to e56c97b Compare May 16, 2026 17:23
@renovate
renovate Bot force-pushed the renovate/routine-updates branch from e56c97b to 0351eb0 Compare May 16, 2026 21:10
@renovate
renovate Bot force-pushed the renovate/routine-updates branch from 0351eb0 to 1c30557 Compare May 17, 2026 09:36
@renovate
renovate Bot force-pushed the renovate/routine-updates branch from 1c30557 to fe7ffe2 Compare May 18, 2026 01:28
@renovate
renovate Bot force-pushed the renovate/routine-updates branch from fe7ffe2 to 8545fd6 Compare May 18, 2026 11:11
@renovate
renovate Bot force-pushed the renovate/routine-updates branch from 8545fd6 to 541d1b4 Compare May 18, 2026 20:39
@renovate
renovate Bot force-pushed the renovate/routine-updates branch from 541d1b4 to 470bc50 Compare May 19, 2026 01:42
@renovate
renovate Bot force-pushed the renovate/routine-updates branch from f63f20d to 2d561dd Compare May 22, 2026 09:53
@renovate
renovate Bot force-pushed the renovate/routine-updates branch from 2d561dd to 8ebc2c3 Compare May 22, 2026 15:47
@renovate
renovate Bot force-pushed the renovate/routine-updates branch from 8ebc2c3 to c85954d Compare May 22, 2026 17:57
@renovate
renovate Bot force-pushed the renovate/routine-updates branch from c85954d to 1540bb6 Compare May 22, 2026 23:08
@renovate
renovate Bot force-pushed the renovate/routine-updates branch from 1540bb6 to bc74f48 Compare May 22, 2026 23:23
@renovate
renovate Bot force-pushed the renovate/routine-updates branch from bc74f48 to 6fea059 Compare May 23, 2026 09:56
@renovate
renovate Bot force-pushed the renovate/routine-updates branch from 6fea059 to 6c27629 Compare May 23, 2026 12:24
@renovate
renovate Bot force-pushed the renovate/routine-updates branch from 6c27629 to 8a95d30 Compare May 23, 2026 21:41
@renovate
renovate Bot force-pushed the renovate/routine-updates branch from 8a95d30 to 7ac7b81 Compare May 24, 2026 00:48
@renovate
renovate Bot force-pushed the renovate/routine-updates branch from 7ac7b81 to 2f2291a Compare May 24, 2026 08:41
@renovate
renovate Bot force-pushed the renovate/routine-updates branch from 2f2291a to 9da4dbe Compare May 24, 2026 20:35
@renovate
renovate Bot force-pushed the renovate/routine-updates branch from 9da4dbe to 21066f2 Compare May 25, 2026 01:58
@renovate
renovate Bot force-pushed the renovate/routine-updates branch from 21066f2 to e4a7540 Compare May 26, 2026 15:43
@renovate
renovate Bot force-pushed the renovate/routine-updates branch from e4a7540 to 940f01b Compare May 27, 2026 01:41
@renovate

renovate Bot commented Sep 3, 2026 •

Copy link
Copy Markdown
Contributor Author

⚠️ Artifact update problem

Renovate failed to update an artifact related to this branch. You probably do not want to merge this PR as-is.

♻ Renovate will retry this branch, including artifacts, only when one of the following happens:

  • any of the package files in this branch needs updating, or
  • the branch becomes conflicted, or
  • you click the rebase/retry checkbox if found above, or
  • you rename this PR's title to start with "rebase!" to trigger it manually

The artifact failure details are included below:

File name: package-lock.json
npm warn ERESOLVE overriding peer dependency
npm warn While resolving: @better-auth/drizzle-adapter@1.6.15
npm warn Found: @better-auth/utils@0.4.2
npm warn node_modules/@better-auth/utils
npm warn   peer @better-auth/utils@"0.4.2" from @better-auth/core@1.7.7
npm warn   node_modules/@better-auth/core
npm warn     dev @better-auth/core@"1.7.7" from the root project
npm warn     7 more (@better-auth/drizzle-adapter, ...)
npm warn   1 more (better-auth)
npm warn
npm warn Could not resolve dependency:
npm warn peer @better-auth/utils@"0.4.1" from @better-auth/drizzle-adapter@1.6.15
npm warn node_modules/@better-auth/drizzle-adapter
npm warn
npm warn Conflicting peer dependency: @better-auth/utils@0.4.1
npm warn node_modules/@better-auth/utils
npm warn   peer @better-auth/utils@"0.4.1" from @better-auth/drizzle-adapter@1.6.15
npm warn   node_modules/@better-auth/drizzle-adapter
npm warn ERESOLVE overriding peer dependency
npm warn While resolving: @better-auth/kysely-adapter@1.6.15
npm warn Found: @better-auth/utils@0.4.2
npm warn node_modules/@better-auth/utils
npm warn   peer @better-auth/utils@"0.4.2" from @better-auth/core@1.7.7
npm warn   node_modules/@better-auth/core
npm warn     dev @better-auth/core@"1.7.7" from the root project
npm warn     7 more (@better-auth/drizzle-adapter, ...)
npm warn   1 more (better-auth)
npm warn
npm warn Could not resolve dependency:
npm warn peer @better-auth/utils@"0.4.1" from @better-auth/kysely-adapter@1.6.15
npm warn node_modules/@better-auth/kysely-adapter
npm warn
npm warn Conflicting peer dependency: @better-auth/utils@0.4.1
npm warn node_modules/@better-auth/utils
npm warn   peer @better-auth/utils@"0.4.1" from @better-auth/kysely-adapter@1.6.15
npm warn   node_modules/@better-auth/kysely-adapter
npm warn ERESOLVE overriding peer dependency
npm warn While resolving: @better-auth/memory-adapter@1.6.15
npm warn Found: @better-auth/utils@0.4.2
npm warn node_modules/@better-auth/utils
npm warn   peer @better-auth/utils@"0.4.2" from @better-auth/core@1.7.7
npm warn   node_modules/@better-auth/core
npm warn     dev @better-auth/core@"1.7.7" from the root project
npm warn     7 more (@better-auth/drizzle-adapter, ...)
npm warn   1 more (better-auth)
npm warn
npm warn Could not resolve dependency:
npm warn peer @better-auth/utils@"0.4.1" from @better-auth/memory-adapter@1.6.15
npm warn node_modules/@better-auth/memory-adapter
npm warn
npm warn Conflicting peer dependency: @better-auth/utils@0.4.1
npm warn node_modules/@better-auth/utils
npm warn   peer @better-auth/utils@"0.4.1" from @better-auth/memory-adapter@1.6.15
npm warn   node_modules/@better-auth/memory-adapter
npm warn ERESOLVE overriding peer dependency
npm warn While resolving: @better-auth/mongo-adapter@1.6.15
npm warn Found: @better-auth/utils@0.4.2
npm warn node_modules/@better-auth/utils
npm warn   peer @better-auth/utils@"0.4.2" from @better-auth/core@1.7.7
npm warn   node_modules/@better-auth/core
npm warn     dev @better-auth/core@"1.7.7" from the root project
npm warn     7 more (@better-auth/drizzle-adapter, ...)
npm warn   1 more (better-auth)
npm warn
npm warn Could not resolve dependency:
npm warn peer @better-auth/utils@"0.4.1" from @better-auth/mongo-adapter@1.6.15
npm warn node_modules/@better-auth/mongo-adapter
npm warn
npm warn Conflicting peer dependency: @better-auth/utils@0.4.1
npm warn node_modules/@better-auth/utils
npm warn   peer @better-auth/utils@"0.4.1" from @better-auth/mongo-adapter@1.6.15
npm warn   node_modules/@better-auth/mongo-adapter
npm warn ERESOLVE overriding peer dependency
npm warn While resolving: @better-auth/prisma-adapter@1.6.15
npm warn Found: @better-auth/utils@0.4.2
npm warn node_modules/@better-auth/utils
npm warn   peer @better-auth/utils@"0.4.2" from @better-auth/core@1.7.7
npm warn   node_modules/@better-auth/core
npm warn     dev @better-auth/core@"1.7.7" from the root project
npm warn     7 more (@better-auth/drizzle-adapter, ...)
npm warn   1 more (better-auth)
npm warn
npm warn Could not resolve dependency:
npm warn peer @better-auth/utils@"0.4.1" from @better-auth/prisma-adapter@1.6.15
npm warn node_modules/@better-auth/prisma-adapter
npm warn
npm warn Conflicting peer dependency: @better-auth/utils@0.4.1
npm warn node_modules/@better-auth/utils
npm warn   peer @better-auth/utils@"0.4.1" from @better-auth/prisma-adapter@1.6.15
npm warn   node_modules/@better-auth/prisma-adapter
npm error Cannot read properties of null (reading 'edgesOut')
npm error A complete log of this run can be found in: /runner/cache/others/npm/_logs/2026-10-16T00_46_02_718Z-debug-0.log

This branch was successfully deployed

1 active deployment
Preview — 77c18b89 Deployed Oct 16, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants