Repository navigation
Update Routine updates - #376
Open
renovate[bot] wants to merge 1 commit into
Open
renovate[bot] wants to merge 1 commit into
renovate[bot] wants to merge 1 commit into
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
commit: |
renovate
Bot
force-pushed
the
renovate/routine-updates
branch
from
May 13, 2026 09:38
63dc237 to
87fb859
Compare
renovate
Bot
force-pushed
the
renovate/routine-updates
branch
from
May 14, 2026 18:34
87fb859 to
8e9ad8a
Compare
renovate
Bot
force-pushed
the
renovate/routine-updates
branch
from
May 14, 2026 20:25
8e9ad8a to
4d7b750
Compare
renovate
Bot
force-pushed
the
renovate/routine-updates
branch
from
May 15, 2026 01:29
4d7b750 to
1787003
Compare
renovate
Bot
force-pushed
the
renovate/routine-updates
branch
from
May 15, 2026 17:14
1787003 to
931f226
Compare
renovate
Bot
force-pushed
the
renovate/routine-updates
branch
from
May 16, 2026 12:42
931f226 to
267cd41
Compare
renovate
Bot
force-pushed
the
renovate/routine-updates
branch
from
May 16, 2026 17:23
267cd41 to
e56c97b
Compare
renovate
Bot
force-pushed
the
renovate/routine-updates
branch
from
May 16, 2026 21:10
e56c97b to
0351eb0
Compare
renovate
Bot
force-pushed
the
renovate/routine-updates
branch
from
May 17, 2026 09:36
0351eb0 to
1c30557
Compare
renovate
Bot
force-pushed
the
renovate/routine-updates
branch
from
May 18, 2026 01:28
1c30557 to
fe7ffe2
Compare
renovate
Bot
force-pushed
the
renovate/routine-updates
branch
from
May 18, 2026 11:11
fe7ffe2 to
8545fd6
Compare
renovate
Bot
force-pushed
the
renovate/routine-updates
branch
from
May 18, 2026 20:39
8545fd6 to
541d1b4
Compare
renovate
Bot
force-pushed
the
renovate/routine-updates
branch
from
May 19, 2026 01:42
541d1b4 to
470bc50
Compare
renovate
Bot
force-pushed
the
renovate/routine-updates
branch
from
May 22, 2026 09:53
f63f20d to
2d561dd
Compare
renovate
Bot
force-pushed
the
renovate/routine-updates
branch
from
May 22, 2026 15:47
2d561dd to
8ebc2c3
Compare
renovate
Bot
force-pushed
the
renovate/routine-updates
branch
from
May 22, 2026 17:57
8ebc2c3 to
c85954d
Compare
renovate
Bot
force-pushed
the
renovate/routine-updates
branch
from
May 22, 2026 23:08
c85954d to
1540bb6
Compare
renovate
Bot
force-pushed
the
renovate/routine-updates
branch
from
May 22, 2026 23:23
1540bb6 to
bc74f48
Compare
renovate
Bot
force-pushed
the
renovate/routine-updates
branch
from
May 23, 2026 09:56
bc74f48 to
6fea059
Compare
renovate
Bot
force-pushed
the
renovate/routine-updates
branch
from
May 23, 2026 12:24
6fea059 to
6c27629
Compare
renovate
Bot
force-pushed
the
renovate/routine-updates
branch
from
May 23, 2026 21:41
6c27629 to
8a95d30
Compare
renovate
Bot
force-pushed
the
renovate/routine-updates
branch
from
May 24, 2026 00:48
8a95d30 to
7ac7b81
Compare
renovate
Bot
force-pushed
the
renovate/routine-updates
branch
from
May 24, 2026 08:41
7ac7b81 to
2f2291a
Compare
renovate
Bot
force-pushed
the
renovate/routine-updates
branch
from
May 24, 2026 20:35
2f2291a to
9da4dbe
Compare
renovate
Bot
force-pushed
the
renovate/routine-updates
branch
from
May 25, 2026 01:58
9da4dbe to
21066f2
Compare
renovate
Bot
force-pushed
the
renovate/routine-updates
branch
from
May 26, 2026 15:43
21066f2 to
e4a7540
Compare
renovate
Bot
force-pushed
the
renovate/routine-updates
branch
from
May 27, 2026 01:41
e4a7540 to
940f01b
Compare
Contributor
Author
|
This branch was successfully deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Note
This PR body was truncated due to platform limits.
This PR contains the following updates:
1.6.15→1.7.71.7.10(+2)1.6.15→1.7.71.7.10(+2)1.1.21→1.3.23.3.5→3.3.79.39.4→9.39.51.60.0→1.64.01.64.14.3.0→4.3.31.168.60→1.169.11.169.22.0.13→2.0.1424.12.3→24.19.219.2.14→19.3.019.2.3→19.3.07.7.1→7.8.0de0fac2→d23441a48b55a0→2499707^0.5.16→^0.6.0>=1.6.11 <1.7.0→>=1.6.11 <1.8.01.7.10(+2)1.6.15→1.7.71.7.10(+2)10.0.3→10.0.69.39.4→9.39.510.3.0→10.12.016.2.6→16.4.016.4.2(+1)0.5.2→0.5.716.8.8→16.17.116.17.4(+2)16.8.8→16.17.116.17.4(+2)17.6.0→17.13.06.2.3→6.2.1216.2.6→16.4.016.4.2(+1)16.2.6→16.4.016.4.2(+1)0.0.71→0.0.918.5.14→8.5.303.8.3→3.9.10v2.1.2→v2.2.019.2.6→19.3.019.3.119.2.6→19.3.019.3.119.2.6→19.3.019.3.119.2.6→19.3.019.3.12.34.0→2.51.02.52.07.8.0→7.8.54.3.0→4.3.35.6.0→5.10.08.59.2→8.71.24.1.5→4.1.114.1.12v0.5.6→v0.6.4v0.7.1(+1)4.6.5→4.6.7Release Notes
better-auth/better-auth (@better-auth/core)
v1.7.7Compare Source
v1.7.6Compare Source
Patch Changes
631ac29Thanks @bytaesu! - Preserve logical model identity when a custom model name matches another schema key.v1.7.5Compare Source
Patch Changes
#11203
cb627ebThanks @dshukertjr! - Add adatabase.schemaNameoption for direct PostgreSQL connections. When set, the adapter and the CLI qualify every statement with that schema, soauth generatewrites a schema-qualified migration that creates the schema before its tables instead of relying on the connection'ssearch_path.#11290
dae97edThanks @bytaesu! - Restore database option type inference for projects that do not use Cloudflare Workers.v1.7.4Compare Source
Patch Changes
#11210
3ff842aThanks @bytaesu! - Prevent bundlers such as Metro from failing when the optional OpenTelemetry API is not installed.#11224
c1756a2Thanks @bytaesu! - Addexperimental.instrumentation.enabledto disable Better Auth OpenTelemetry span creation per auth instance. Instrumentation remains enabled by default and independent of usage reporting.v1.7.3Compare Source
Patch Changes
#11179
352d012Thanks @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 generatereports required fields that Better Auth never writes by reading the existing Prisma schema. Setadvanced.database.validateSchema: falseto disable runtime validation.#9908
76d311fThanks @harshil1712! - Add Cloudflare as a built-in social provider, with support for client-secret authentication and PKCE clients without a secret.#11101
3e9e197Thanks @bytaesu! - Add a custom token endpoint authentication strategy for providers that require non-standard request parameters.#11068
157ec8dThanks @bytaesu! - Improve request IP validation performance.#11102
baa08f4Thanks @bytaesu! - Fix TikTok sign-in and token refresh failing when configured with the documentedclientKeyandclientSecretoptions.#11129
9e36635Thanks @bytaesu! - Improve PayPal authorization code and refresh token requests, including PKCE parameter handling.#11178
be0e007Thanks @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: falseto disable runtime validation.auth migraterefuses to apply changes when required unwritten columns need manual repair.#11134
a2bae0cThanks @bytaesu! - Improve Reddit token requests with OAuth-compliant Basic authentication and redirect protection.#11189
1a1b7d5Thanks @bytaesu! - MakeconsumeOneandincrementOneoptional 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
2220ee7Thanks @bytaesu! - Restore sign-in compatibility with 1.6 databases by identifying accounts with(providerId, accountId)and removing theissuerrequirement 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
issuernullable or remove the column so sign-ups and account linking can succeed.auth migratedoes not perform this cleanup. Follow the upgrade guide for database-specific steps.v1.7.2Compare Source
Patch Changes
#10938
557e19bThanks @bytaesu! - Added synchronous auth endpoint context access withgetCurrentAuthEndpointContextand optional access withtryGetCurrentAuthEndpointContext. The existinggetCurrentAuthContextandgetCurrentAuthContextAsyncLocalStoragefunctions remain available as deprecated compatibility APIs.#10855
64da15bThanks @bytaesu! - Prevent async context loss in Cloudflare Workers bundles that enable multiple runtime conditions.#10982
b4ad5a1Thanks @bytaesu! - Built-in placeholder emails now consistently use the namespaced{identifier}@{namespace}.placeholder.invalidformat.#10979
fced1a5Thanks @bytaesu! - Allow relative callback and redirect URLs to use standard path, query, and fragment syntax while preserving open-redirect protections.#10939
e1d4011Thanks @bytaesu! - Logs emitted while handling auth requests now respect the configured custom logger, log level, and disabled setting.v1.7.1Patch Changes
#11612
fedd055Thanks @vhinayindia! - If your resource server verifies access tokens withverifyAccessTokenRequestorverifyBearerTokenand ajwksUrl, 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
remoteVerifyconfigured, such a failure no longer falls back to remote introspection.The OAuth provider's
/oauth2/introspect,/oauth2/userinfoand/oauth2/revokebehave the same way with the JWT plugin'sjwks.remoteUrl: they return 500 instead of reporting the token as invalid.#11805
bbd0a19Thanks @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 callverifyAccessTokenRequestorverifyBearerTokenwithjwksUrl. Previously every such token caused a new fetch: a remote request withjwksUrlorjwks.remoteUrl, or otherwise a read of thejwkstable. Anyone could send tokens with made-upkidvalues 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
JWKSTimeouterror 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
kidin that time. No configuration change is needed.v1.7.0Minor Changes
#10577
5c45abcThanks @gustavovalverde! - Client ID Metadata Documents now follow shared-cache freshness rules and fail closed when freshness is ambiguous. The plugin preferss-maxageovermax-ageandExpires, honorss-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_namewithout trimming a valid display name. Native private-use redirects require the RFC 8252 single-slash form, such ascom.example.app:/callback. Native HTTP redirects accept only exactlocalhost,127.0.0.1, or[::1]hosts; other127.0.0.0/8addresses 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. HTTPno-store,private, andVary: *behavior is unchanged and never feeds metadata or validators into the governor.Node.js deployments can import
fetchClientMetadataResourcefrom@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
763a267Thanks @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
3d04fabThanks @yordis! - feat(generic-oauth): addrefreshTokenParamsconfig to forward extra params on token refreshMulti-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 arefreshTokenParamsoption (object or sync/async function) that is merged into the refresh request body, withgrant_typeandrefresh_tokenprotected 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.refreshAccessTokennow accepts an optional secondctxargument; the change is backwards compatible because existing implementations that take onlyrefreshTokenremain valid. See #7554.#9368
430c895Thanks @GautamBytes! - Generic OAuth users can now sign out from the configured OpenID provider when they callauthClient.signOut(). When a provider exposes a discovered or configured logout endpoint, Better Auth redirects to it and includes the storedid_token_hintwhen available. PasscallbackURLor configurepostLogoutRedirectURIfor the return flow, with optionalstate, or setdisableRedirectto handle the returnedurlyourself. When multiple linked providers support logout, Better Auth selects the most recently updated account. SetdisableProviderLogout: trueto keep sign-out local.#10577
5c45abcThanks @gustavovalverde! - MCP clients that hit a scope wall now learn exactly which scopes to ask for. Missing protected scopes produce a403with an RFC 6750insufficient_scopeWWW-Authenticatechallenge that names every missing scope. Clients can union those scopes into one authorization request instead of opening one browser redirect per scope.requiredScopesthroughRequireMcpAuthOptionsor the matchingcreateMcpProtectedRequestHandlerverifier option. Exact membership remains the default;isScopeSatisfiedcan define hierarchical policies.createInsufficientScopeErrorwhen an operation determines its required scopes dynamically.createResourceServerChallengeconverts that signal and recognized token failures into safe RFC 6750 challenges.challengeScopesonly as the unauthenticated challenge hint.Handler-produced responses, ordinary permission denials, configuration failures, and unrelated thrown values keep their original status and identity.
#10403
dbd302eThanks @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.issuerbut preservesAccount.accountIdas the provider-assigned account identifier. Account-specific APIs select the localAccount.idthrough theaccountIdrequest property; token and provider-profile APIs can instead select the signed account cookie withuseAccountCookie: true. Credential accounts uselocal:credentialand the linked user's stableidas their provider identity.OAuth provider identity now comes from raw verified profiles. OpenID Connect discovery uses
sub, plain OAuth usesid, and providers can declareaccountSubjectfor another immutable field; Better Auth no longer switches betweensubandidat runtime.getUserInfo().userno longer carries provider identity, andmapProfileToUsercannot returnid. Read the selected identity fromaccountInfo.account.accountIdinstead ofaccountInfo.user.id. The genericmicrosoftEntraIdhelper 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
subclaim, and SAML uses the signedNameID;mapping.idis removed from both configurations. A manual SAML configuration without metadata XML must setidpMetadata.entityID, becausesamlConfig.issueridentifies 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
8784c1cThanks @ping-maxwell! - Database joins have moved out ofexperimentalinto a stable option atadvanced.database.joins(default:false).If you previously set
experimental: { joins: true }, update your config to: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
0683a5fThanks @GautamBytes! - Microsoft sign-in now identifies Entra accounts with the stableoidclaim in both the built-inmicrosoftprovider and the Generic OAuthmicrosoftEntraIdhelper. Tokens without a validoidare rejected, and the Generic OAuth helper refuses to initialize unless Microsoft discovery provides ID-token verification metadata. Existing Microsoft account rows created fromsubmust be migrated before upgrading.#9305
e7eb45bThanks @gustavovalverde! - feat(oauth): per-requestadditionalParamsandloginHintparity acrosssignIn.social,linkSocial, andsignIn.ssoUnified 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'sidentity_provider=Google, or Microsoft'sdomain_hintcould only be set as static server configuration.New capabilities
signIn.social,linkSocial, andsignIn.ssoacceptadditionalParams: Record<string, string>. Values are appended to the authorization URL as query parameters.linkSocialalso acceptsloginHint, matching the surface ofsignIn.socialandsignIn.sso.OAuthProvider.createAuthorizationURLgainsadditionalParamsin its input contract; every built-in provider forwards it to the shared helper.additionalParamswith the config-levelauthorizationUrlParams; call-time wins on key collision.identityProvider?: stringconfig option that maps to theidentity_providerquery parameter, avoiding magic strings.Security
createAuthorizationURLhelper silently drops any caller-supplied key inRESERVED_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.nonceis reserved so a caller cannot replace the OIDC nonce Better Auth generates when binding a discovery provider'sid_tokento the authorization request.wechat→appid,tiktok→client_key) additionally filter those keys so a caller cannot swap the configured OAuth app.atlassian→audience,notion→owner) are merged last so caller-suppliedadditionalParamscannot override them. Configured defaults that represent operator intent (e.g. Googleinclude_granted_scopes, CognitoidentityProvider) remain caller-overridable.signIn.ssorejectsadditionalParamswith 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
ZodRecordhandling to the OpenAPI generator soz.record()fields emittype: objectwith typedadditionalProperties. Incidentally fixes a long-standing bug whereadditionalDatawas rendered astype: string.Refactors
discord,roblox,zoom, andslackproviders now delegate to the sharedcreateAuthorizationURLhelper and inherit its RFC behavior and reserved-key guard.tiktokandwechatkeep their manual URL construction (non-standard OAuth2 parameter names and URL fragment requirements) but threadadditionalParamswith the same reserved-key filter.Closes #2351.
Closes #5441.
Closes #5592.
Closes #5604.
Supersedes #4992 and #5443.
#10127
7c7313cThanks @gustavovalverde! - OAuth sign-in, account linking, callback, and proxy flows now buildredirect_urifrom the current request base URL whenbaseURL.allowedHostsis configured. Built-in social providers and generic OAuth providers now use the resolved request host for redirects in multi-host deployments.Custom
OAuthProviderimplementations can omitcallbackPathwhen using the shared/callback/<provider-id>route. SetcallbackPathonly for custom callback routes.#10039
aedcb97Thanks @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_tokensat registration,dpop_jkton the authorization request, or by targeting a resource configured withdpopBoundAccessTokensRequired. Issued tokens carrycnf.jkt, returntoken_type: "DPoP", and stay bound through refresh-token rotation, introspection, and userinfo.Resource servers verify DPoP requests with
verifyAccessTokenRequest, which checks theAuthorization: DPoPscheme, 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.verifyAccessTokenRequestandrequireMcpAuthuse that store by default; build one withcreateDpopReplayStore(internalAdapter)or pass a customdpop.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
verifyAccessTokenis renamed toverifyBearerToken, both inbetter-auth/oauth2and as theoauthProviderResourceClientaction, and it rejects DPoP-bound tokens. UseverifyAccessTokenRequeston any endpoint that may receive them. The resource-request input type is renamed fromAccessTokenRequestInputtoResourceRequestInput, and the DPoP algorithm option issigningAlgorithmseverywhere.Run a schema migration for the DPoP token-binding fields: the
confirmationcolumn on the access-token and refresh-token tables. DPoP-bound clients also gaindpopBoundAccessTokensand resourcesdpopBoundAccessTokensRequired. No dedicated replay table is added; proof replay reuses the verification store.#9828
4f53b61Thanks @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-providerverifyIdTokenmethod. Each provider declares anidTokenconfig 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
idTokenconfig, and the client id_token path returnsID_TOKEN_NOT_SUPPORTED. PayPal sign-in through the redirect flow is unchanged.Custom providers that implement
UpstreamProviderdirectly replace the removedverifyIdTokenmethod with anidTokenconfig:For verification that cannot use a local JWKS, pass
idToken: { verify: async (token, nonce) => boolean }. TheverifyIdTokenanddisableIdTokenSignInprovider options are unchanged.#10065
2196ea6Thanks @gustavovalverde! - OAuth and device-authorization responses that carry credentials now consistently sendCache-Control: no-storeandPragma: 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/coreasNO_STORE_HEADERSfor responses built by hand.#9929
91f235fThanks @gustavovalverde! - AddrequireEmailVerificationto 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 return403EMAIL_NOT_VERIFIED. Verification emails follow the existingemailVerification.sendOnSignUp/sendOnSignInsettings.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 trustworthyemail_verifiedsignal.#8931
34558bcThanks @GautamBytes! - Add opt-in JWKS-backed asymmetric JWT support forsession_datacookie cache tokens, so services can verify cookie-cache JWTs with public keys instead of shared secrets. Enable it withjwt({ sessionCookieCache: true })alongsidesession.cookieCache.strategy = "jwt".#9657
1e5b808Thanks @gustavovalverde! - Hardenprivate_key_jwtand token endpoint client authentication, and add the helpers that make the fix structural.@better-auth/core/oauth2now exposesencodeBasicCredentialsanddecodeBasicCredentials, a round-trip-tested pair that follows RFC 6749 §2.3.1 (application/x-www-form-urlencodedeach 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_basicon 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 likebasic xxxorBasic xxxare accepted.createPrivateKeyJwtClientAssertionGettervalidates options eagerly. Unsupported algorithms (HS256,none), a JWK with no key material, and disagreement between an explicitalgorithmand the JWK-embeddedalgall throw at construction rather than on the first token request.signPrivateKeyJwtClientAssertionenforces the same checks for direct callers. Breaking: configurations that paired an unsupported JWKalgwith a different explicitalgorithmused to silently sign with the explicit option; they now fail at construction.Breaking:
@better-auth/oauth-provideraccepts clientjwksmetadata only as an RFC 7517 JWK Set object with a non-emptykeysarray. Replacejwks: [key]withjwks: { keys: [key] }in DCR payloads, administrative and user client creation, Client ID Metadata Documents, test fixtures, and generated client code. Remotely fetchedjwks_uriresponses must use the same object shape. EC keys must use P-256, P-384, or P-521; OKP keys must useEd25519. When a key declaresalg, it must be a supportedprivate_key_jwtalgorithm that matches the key type and curve; omitalgwhen the client chooses the algorithm in its assertion header. OAuth client rows previously written throughoauthToSchemaare 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_jwtflow redirects witherror_description=no_private_key_availablewhen aresolvePrivateKeycallback returns noprivateKeyJwkorprivateKeyPem. 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/testaddsgetHttpTestInstance, a counterpart togetTestInstancethat 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
93d3871Thanks @gustavovalverde! - Add client authentication configuration for token endpoint requests across the stack, includingprivate_key_jwt(RFC 7523).Generic OAuth providers now accept
tokenEndpointAuthfor token endpoint client authentication. Use `tokenEndpointAuth: { method: "private_key_jwt", getClientAssertionConfiguration
📅 Schedule: (in timezone America/Los_Angeles)
* * * * 1-5)🚦 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.
This PR was generated by Mend Renovate. View the repository job log.