Every release shipped to Better Auth, straight from GitHub.
Every release shipped to Better Auth, straight from GitHub.
better-authaccountInfo calls with an optional userId parameter, allowing trusted callers to read provider profiles without constructing session headers (#9813)viewBackupCodes is a server-only function not accessible via HTTP in its API documentation (#9822)storeStateStrategy defaulting to "cookie" instead of "database" when only secondaryStorage is configured, preventing oversized-cookie errors on platforms like AWS Lambda (#9591)updateUserInfoOnLink not being applied when linking accounts through the standard OAuth redirect flow (#8758)oidc-provider and mcp plugins accepting invalid redirect_uri schemes such as javascript: and data: (#9838)logo not accepting null, preventing users from clearing an existing logo on create and update (#9842)For detailed changes, see CHANGELOG
@better-auth/ssointernalAdapter helper methods that could silently match the wrong account or wipe all sessions for a user (#9818)samlify to 2.13.1 (GHSA-34r5-q4jw-r36m) (#9821)For detailed changes, see CHANGELOG
@better-auth/api-keyverifyApiKey rejecting keys created under a non-default configId when the request omitted configId (#9794)For detailed changes, see CHANGELOG
@better-auth/coreconsumeOne when an adapter's deleteMany returned a non-numeric value, now surfacing a clear error (#9831)For detailed changes, see CHANGELOG
@better-auth/expoFor detailed changes, see CHANGELOG
@better-auth/oauth-providerPOST /oauth2/register bypassing the clientPrivileges create check, allowing unauthorized dynamic client registration (#9837)For detailed changes, see CHANGELOG
Thanks to everyone who contributed to this release:
@bytaesu, @gustavovalverde, @Vishesh-Verma-07
Full changelog: v1.6.12...v1.6.13
better-authgetMigration migrations. (#9691)changeEmail to return an error when emailVerification.sendVerificationEmail is missing, and URL-encoded callbackURL in verify-email links. (#9614)callbackURL URL-encoding in verify-email links for OAuth account linking and username sign-in. (#9792)role.authorize to reject empty action lists and correctly evaluate OR conditions on unknown resources. (#9603)AdminClientOptions and OrganizationClientOptions. (#9642)parseJSON to properly decode escape sequences in quoted strings. (#9617)getTrustedOrigins to respect the dynamic baseURL protocol option. (#9644)sendVerificationEmail callback. (#9619)accessTokenExpiresIn config option to genericOAuth for providers that omit expires_in in their token response. (#9799)user_creation_failed. (#9723)state_mismatch when production and preview environments use different secrets. (#9385)state_not_found, state_invalid, state_mismatch) instead of the generic please_restart_the_process code. (#9788)errorCallbackURL instead of the default error page. (#9789)operationIds for endpoints that expose multiple HTTP methods. (#9721)deleteOrganization and removeMember to roll back on failure instead of leaving orphaned rows. (#9630)session_token and session_data cookies to be captured and replayed to bypass 2FA when cookie caching is enabled. (#9639)createUser endpoint. (#9464)For detailed changes, see CHANGELOG
@better-auth/oauth-providerregistration_endpoint to be hidden from .well-known metadata unless dynamic client registration is enabled. (#9448)client_secret values containing colons. (#9601)NOT_FOUND when the referenced client no longer exists. (#9600)For detailed changes, see CHANGELOG
@better-auth/coretoCamelCase, toSnakeCase, toPascalCase, and toKebabCase utilities to @better-auth/core/utils/string. (#9727) – 
verifyAccessToken to return proper unauthorized errors for invalid token verification failures. (#9655)For detailed changes, see CHANGELOG
@better-auth/ssoerrorCallbackURL instead of returning a JSON error. (#9702)For detailed changes, see CHANGELOG
@better-auth/drizzle-adapterFor detailed changes, see CHANGELOG
@better-auth/passkeytransports is undefined. (#9746)For detailed changes, see CHANGELOG
@better-auth/api-keyTS4023 declaration emit errors by adding better-call as a peer dependency. (#9759)For detailed changes, see CHANGELOG
@better-auth/electronFor detailed changes, see CHANGELOG
@better-auth/kysely-adapterBunSqliteDialect, NodeSqliteDialect) incorrectly reporting tables as views. (#9615)For detailed changes, see CHANGELOG
@better-auth/stripeFor detailed changes, see CHANGELOG
Thanks to everyone who contributed to this release:
@bytaesu, @chdanielmueller, @cyphercodes, @gustavovalverde, @jsj, @kgarg2468, @Paola3stefania, @ping-maxwell, @reslear
Full changelog: v1.6.11...v1.6.12
better-authchange-email-disabled response to help clients identify the rejection reason (#8948)onLinkAccount when email verification triggers auto sign-in (#9548)oidc-provider and mcp plugins to require client_secret for confidential clients on refresh token grants and use constant-time secret comparison (#9576)oidc-provider and mcp plugins to follow OAuth 2.1: removed "none" from advertised signing algorithms, defaulted plain PKCE off, and rejected incomplete PKCE parameters (#9575)requireEmailVerificationOnInvitation by default and extending the verification gate to getInvitation and listUserInvitations (#9577)For detailed changes, see CHANGELOG
@better-auth/oauth-providerunique constraint on oauthRefreshToken.tokenFor detailed changes, see CHANGELOG
@better-auth/coreadvanced.ipAddress.ipv6Subnet to accept any valid IPv6 prefix length (0-128) instead of a narrow set of values (#9545)For detailed changes, see CHANGELOG
@better-auth/scimgenerateSCIMToken to reject providerId values that collide with built-in account providers, preventing tokens from authenticating against unintended accounts (#9579)For detailed changes, see CHANGELOG
@better-auth/ssoFor detailed changes, see CHANGELOG
authclaimOne adapter primitive for consuming database rows without race conditions (#9560)claimOne adapter primitive to consumeOne and added internalAdapter.consumeVerificationValue for atomically consuming verification rows (#9568)For detailed changes, see CHANGELOG
@better-auth/api-keyFor detailed changes, see CHANGELOG
Thanks to everyone who contributed to this release:
@dipan-ck, @GautamBytes, @gustavovalverde, @Kvizas, @ping-maxwell, @stewartjarod
Full changelog: v1.6.10...v1.6.11
better-authrefreshUserSessions on the internal adapter (#7764)POST /sign-in/social mis-declaring required fields (#9268)useSession not revalidating after admin impersonation starts or stops (#9402)Set-Cookie headers being emitted on redirect responses from social sign-in and magic-link endpoints (#9497)emailAndPassword.autoSignIn is false (#8839)TypeError caused by non-ASCII characters in OAuth error descriptions on redirect (#9065)internalAdapter.deleteAccount parameter from accountId to id to reflect that it queries by primary key (#9503)undefined id (#9456)cancelPendingInvitationsOnReInvite having no effect, where re-inviting the same email always returned USER_IS_ALREADY_INVITED_TO_THIS_ORGANIZATION (#9453)additionalFields in the organization plugin (#9349)useActiveMemberRole retaining a previous user's role after sign-out in SPA flows (#9440)setActiveTeam to only accept teams from the currently active organization (#9239)authClient.siwe.getNonce() as a compatibility alias for the SIWE nonce endpoint (#9461)callbackURL being ignored on signIn.username, so it now redirects correctly like signIn.email (#9475)For detailed changes, see CHANGELOG
@better-auth/oauth-providersessionId typing in refresh token types to be optional, matching the schema (#9324)prompt=login consent continuations not completing after a forced loginprompt=login not being honored after consent continuation, preventing session bypass (#9344)For detailed changes, see CHANGELOG
@better-auth/stripeonSubscriptionUpdate to receive the raw stripeSubscription object, and fixed onSubscriptionCancel to receive the post-update subscription row instead of a stale snapshot (#9354)getCheckoutSessionParams overriding internally managed Stripe Checkout Session fields such as success_url, cancel_url, customer, and line_items (#9481)onSubscriptionDeleted, onTrialEnd, and onTrialExpired receiving a stale pre-update subscription snapshot instead of the post-update row (#9356)getCheckoutSessionParams overriding free trial and internal metadata, which could hide trial periods and create duplicate subscription rows on webhook (#9474)For detailed changes, see CHANGELOG
@better-auth/api-keyapi.verifyApiKey not validating the key's configId against the request body (#9393)For detailed changes, see CHANGELOG
@better-auth/coreFor detailed changes, see CHANGELOG
@better-auth/passkeyFor detailed changes, see CHANGELOG
@better-auth/sso/sso/saml2/sp/metadata throwing NOT_FOUND for providers configured via defaultSSO (#9398)For detailed changes, see CHANGELOG
authauth init generating broken MySQL and PostgreSQL Kysely database configs (#9455)For detailed changes, see CHANGELOG
Thanks to everyone who contributed to this release:
@bytaesu, @Craga89, @cyphercodes, @dipan-ck, @dvanmali, @GautamBytes, @gustavovalverde, @IcanDivideBy0, @jaydeep-pipaliya, @mausic, @onmax, @ping-maxwell, @programming-with-ia, @zllovesuki
Full changelog: v1.6.9...v1.6.10
better-authFor detailed changes, see CHANGELOG
Thanks to everyone who contributed to this release:
@erquhart
Full changelog: v1.6.8...v1.6.9
better-authmapProfileToUser fallback for OAuth providers that may omit email from their profile response (#9331)id through beforeCreateTeam and beforeCreateInvitation hooks (#9253)For detailed changes, see CHANGELOG
@better-auth/oauth-providerstate parameter (#9328)For detailed changes, see CHANGELOG
@better-auth/passkeyexactOptionalPropertyTypes compiler option (#9270)For detailed changes, see CHANGELOG
Thanks to everyone who contributed to this release:
@baptisteArno, @gustavovalverde, @ping-maxwell
Full changelog: v1.6.7...v1.6.8
better-authAPIError is thrown (#9211)./instrumentation module in those environments (#9281)callbackOnVerification not being called when updatePhoneNumber is enabled (#4894)For detailed changes, see CHANGELOG
@better-auth/oauth-providerAuthorization header from request context when using auth.api (#9244)For detailed changes, see CHANGELOG
@better-auth/passkeyFor detailed changes, see CHANGELOG
Thanks to everyone who contributed to this release:
@gustavovalverde, @Kinfe123, @ouwargui, @ramonclaudio, @stewartjarod, @TanishValesha
Full changelog: v1.6.6...v1.6.7
better-authPartitioned attribute when forwarding Set-Cookie headers (#9235)disableRefresh query parameter in custom session validation (#9214)updateUser({ phoneNumber: null }) (#9219)For detailed changes, see CHANGELOG
@better-auth/coremapConcurrent, a bounded-concurrency async utility, at @better-auth/core/utils/async (#9227) – 
@opentelemetry/api an optional peer dependency (#9111) – 
For detailed changes, see CHANGELOG
@better-auth/api-keyFor detailed changes, see CHANGELOG
@better-auth/expoSecureStore on app startup, eliminating the login screen flash for returning users (#8953)For detailed changes, see CHANGELOG
@better-auth/oauth-providerFor detailed changes, see CHANGELOG
@better-auth/ssoFor detailed changes, see CHANGELOG
Thanks to everyone who contributed to this release:
@bytaesu, @gustavovalverde, @jonathansamines, @ping-maxwell, @terijaki
Full changelog: v1.6.5...v1.6.6
better-auth/change-password and /revoke-other-sessions (#9087)For detailed changes, see CHANGELOG
@better-auth/oauth-provider@better-auth/oauth-provider where unprivileged authenticated users could create OAuth clients when deployments relied on clientPrivileges to restrict client creation.
– 
@better-auth/oauth-provider@1.6.5.
–

1.7.0-beta.0 and 1.7.0-beta.1) remains affected until a fixed beta release is published.For detailed changes, see CHANGELOG
Thanks to everyone who contributed to this release:
@GautamBytes, @ramonclaudio
Full changelog: v1.6.4...v1.6.5
better-authforceAllowId UUIDs set in database hooks being ignored on PostgreSQL adapters when advanced.database.generateId is set to "uuid" (#9068)For detailed changes, see CHANGELOG
Thanks to everyone who contributed to this release:
@GautamBytes, @gustavovalverde
Full changelog: v1.6.3...v1.6.4
better-authoperationId for the requestPasswordResetCallback endpoint in the OpenAPI spec (#9072)baseURL resolution from request headers for direct auth.api calls (#9113)isMounted race condition that caused excessive requests per second in the client (#9078)storeBackupCodes storage strategy after verification (#7231)For detailed changes, see CHANGELOG
@better-auth/oauth-providercustomTokenResponseFields callback for injecting custom fields into token endpoint responses, and hardened authorization code validation (#9118)baseURL resolution for direct auth.api calls and plugin metadata helpers (#9131)For detailed changes, see CHANGELOG
@better-auth/ssoFor detailed changes, see CHANGELOG
@better-auth/stripeFor detailed changes, see CHANGELOG
authFor detailed changes, see CHANGELOG
Thanks to everyone who contributed to this release:
@bytaesu, @Byte-Biscuit, @gustavovalverde, @Oluwatobi-Mustapha, @ping-maxwell, @ramonclaudio
Full changelog: v1.6.2...v1.6.3
better-authMigration: Schema migration required.
Add the
verifiedcolumn to thetwoFactortable, then regenerate/apply your ORM migration.
- Prisma: run
npx auth@latest generate, thennpx prisma migrate dev(ornpx prisma db push) andnpx prisma generate.- Drizzle: run
npx auth@latest generate, thennpx drizzle-kit generateandnpx drizzle-kit migrate.
Existing rows do not need a backfill because the column defaults to
true.
nextCookies() by replacing cookie probe with header-based RSC detection (#9059)RelayState in signed SAML AuthnRequests (#9058)For detailed changes, see CHANGELOG
@better-auth/oauth-providerskip_consent at schema level in dynamic client registration (#8998)For detailed changes, see CHANGELOG
@better-auth/ssoFor detailed changes, see CHANGELOG
Thanks to everyone who contributed to this release:
@aarmful, @cyphercodes, @dvanmali, @gustavovalverde, @jaydeep-pipaliya, @ping-maxwell
Full changelog: v1.6.1...v1.6.2
better-authINVALID_PASSWORD for all checkPassword failures (#8902)getSession accessibility in generic Auth<O> context (#9017)For detailed changes, see CHANGELOG
Thanks to everyone who contributed to this release:
@bytaesu, @jonathansamines, @ping-maxwell
Full changelog: v1.6.0...v1.6.1
Blog post: Better Auth 1.6
better-authfreshAge calculation with session creation time instead of update time (#8762)Migration:
session.freshAgenow calculates fromcreatedAt. Setsession: { freshAge: 0 }to disable the check entirely.
resendStrategy option to reuse existing OTP in email-otp plugin (#8560)enable option for HaveIBeenPwned plugin (#8728)sendMagicLink callback (#8571)secret option to OAuth proxy to reduce shared key exposure (#8699)organizationId parameter in team endpoints (#5062)twoFactorPage config option for custom 2FA page routing (#5329)oidc-provider plugin in favor of @better-auth/oauth-provider (#8985) – 
accountId instead of internal id (#8786)skipOriginCheck array handling (#8582)user field through idToken sign-in body for Apple name support (#8417)operationId in admin plugin endpoints (#8570)sendOTP failures instead of silently swallowing them (#8842)cookieCache maxAge to match session.expiresIn (#8648)autoSignIn: false without requireEmailVerification (#8521)accountInfo endpoint to use accountId instead of internal id (#8346)createAdapter and type exports for backwards compatibility (#8461)Response return for HTTP request contexts (#7521)throw: true handling in client session refresh (#8610)generateId: "uuid" over adapter customIdGenerator (#8679)safeJSONParse for pre-parsed objects (#8248)CREATE INDEX (#8538)sessionSignal after requesting email change in email-otp (#8816)/magic-link/verify (#7223)form_post (#8895)storeIdentifier is hashed (#8980)redirect_uri validation for prompt=none in oidc-provider (#8398)listUserInvitations (#8694)twoFactorTable option to schema modelName (#8443)any from collapsing auth.$Infer and client inference types (#8981)updateUser to not overwrite unrelated username fields (#7570)updateUser (#8731)For detailed changes, see CHANGELOG
@better-auth/ssoMigration: Set
sso({ saml: { enableInResponseToValidation: false } })to restore the previous behavior.
node-forge vulnerability via samlify pin (#8838)sub claim correctly (#8276)provisionUser inconsistency and added provisionUserOnEveryLogin option (#8818)internalAdapter (#8353)For detailed changes, see CHANGELOG
@better-auth/mongo-adapterMigration: New documents use native BSON UUIDs. Existing string UUIDs continue to work. No data migration required.
For detailed changes, see CHANGELOG
@better-auth/oauth-providerisLocalhost function (#8286)customIdTokenClaims to override standard claims (#7865)baseURL config handling in init (#8649)oauth_query in client plugin (#8320)customIdTokenClaims to override acr and auth_time (#8633)auth_time timestamps across adapter shapes (#8761)skip_consent (#8632)prompt=none support (#8554)For detailed changes, see CHANGELOG
@better-auth/stripeprorationBehavior per plan (#8525)customerType check (#8609){CHECKOUT_SESSION_ID} placeholder in success callbackURL (#8568)priceId for annual subscriptions in list (#8810)For detailed changes, see CHANGELOG
@better-auth/drizzle-adaptermode: "insensitive") (#8556)IS NULL / IS NOT NULL for null value comparisons (#8660)For detailed changes, see CHANGELOG
@better-auth/exporequire issue (#8253)For detailed changes, see CHANGELOG
@better-auth/prisma-adapterupdateMany fallback for non-unique updates (#8524)deleteMany when deleting by non-unique field (#8314)For detailed changes, see CHANGELOG
authmcp.better-auth.com (#8747)required as true in Drizzle and Prisma generators (#8614)For detailed changes, see CHANGELOG
@better-auth/electronsafeStorage encryption failures gracefully (#8530)For detailed changes, see CHANGELOG
@better-auth/passkeyFor detailed changes, see CHANGELOG
@better-auth/test-utils@better-auth/test-utils/adapter (#8564) – 
using keyword for runtime compatibility (#8756)For detailed changes, see CHANGELOG
@better-auth/api-keyFor detailed changes, see CHANGELOG
@better-auth/coreAPIErrors as span errors in OpenTelemetry traces (#8850)For detailed changes, see CHANGELOG
@better-auth/kysely-adapternumUpdatedOrDeletedRows from D1 dialect (#8798)For detailed changes, see CHANGELOG
@better-auth/telemetryFor detailed changes, see CHANGELOG
Thanks to everyone who contributed to this release:
@aarmful, @bytaesu, @dvanmali, @Eric-Song-Nop, @formatlos, @GautamBytes, @GoPro16, @gustavovalverde, @himself65, @jonathansamines, @jslno, @mrgrauel, @NathanColosimo, @okisdev, @olliethedev, @Oluwatobi-Mustapha, @OscarCornish, @ping-maxwell, @raihanbrillmark, @sicarius97, @Sigmabrogz, @wuzgood98, @xiaoyu2er, @YevheniiKotyrlo
Full changelog: v1.5.6...v1.6.0


resendStrategy option to reuse existing OTP – 



organizationId in team endpoints –


prorationBehavior per plan – 
@better-auth/test-utils/adapter – 
twoFactorPage in config – 
skipOriginCheck array – 

user field through idToken sign-in body for Apple name support – 






autoSignIn: false without requireEmailVerification – 





CREATE INDEX for postgres migration – 
















require – 
