better-auth
❗ Breaking Changes
-
feat(two-factor)!: add OTP enablement and discriminated response (#9057)
enableTwoFactornow accepts amethodparameter ("otp" | "totp", default"totp") and returns a discriminated response with amethodfield.method: "otp"- Sets
twoFactorEnabled: trueimmediately. - Returns
{ method: "otp" }. - Requires
otpOptions.sendOTPto be configured on the server; rejects withOTP_NOT_CONFIGUREDotherwise.
method: "totp"(default)- Returns
{ method: "totp", totpURI, backupCodes }. - Rejects with
TOTP_NOT_CONFIGUREDiftotpOptions.disableis set.
Breaking changes
- Removed
skipVerificationOnEnable: usemethod: "otp"for immediate activation, or the standard TOTP verification flow. - Response shape changed:
enableTwoFactorincludes amethodfield in the response ("otp"or"totp").
- Sets
Features
- feat(stripe): support Stripe SDK v21 and v22 (#9084)
Bug Fixes
- fix: incorrect
operationIdin password reset callback endpoint (#9072) - fix(open-api): correct get-session nullable schema for OAS 3.1 (#8389)
- fix(stripe): omit quantity for metered prices in checkout and upgrades (#8926)
For detailed changes, see CHANGELOG
@better-auth/sso
❗ Breaking Changes
-
fix(sso)!: harden SAML response validation (InResponseTo, Audience, SessionIndex) (#9055)
Breaking Changes
allowIdpInitiatednow defaults tofalse— IdP-initiated SSO (unsolicited SAML responses) is disabled by default. Setsaml.allowIdpInitiated: trueto restore the previous behavior. This aligns with the SAML2Int interoperability profile which recommends against IdP-initiated SSO due to its susceptibility to injection attacks.
Bug Fixes
- InResponseTo validation was completely non-functional — The code read
extract.inResponseTo(alwaysundefined) instead of samlify's actual pathextract.response.inResponseTo. SP-initiated InResponseTo validation now works as intended in both ACS handlers. - Audience Restriction was never validated — SAML assertions issued for a different service provider were accepted without checking the
<AudienceRestriction>element. Audience is now validated against the configuredsamlConfig.audiencevalue per SAML 2.0 Core §2.5.1. - SessionIndex stored as object instead of string — samlify returns
sessionIndexfrom login responses as{ authnInstant, sessionNotOnOrAfter, sessionIndex }, but the code stored the whole object. SLO session-index comparisons always failed silently. The correct innersessionIndexstring is now extracted.
Improvements
- Extracted shared
validateInResponseTo()andvalidateAudience()intopackages/sso/src/saml/response-validation.ts, eliminating ~160 lines of duplicated validation logic between the two ACS handlers. - Fixed
SAMLAssertionExtracttype to match samlify's actual extractor output shape.
Bug Fixes
- fix(sso): unify SAML response processing and fix bugs (#9097)
For detailed changes, see CHANGELOG
@better-auth/oauth-provider
Features
- feat(oauth): add
private_key_jwtclient authentication (RFC 7523) (#8836)
For detailed changes, see CHANGELOG
auth
Bug Fixes
- fix(cli): handle extends and mid-path wildcards in tsconfig paths (#9032)
For detailed changes, see CHANGELOG
Contributors
Thanks to everyone who contributed to this release:
@bytaesu, @gustavovalverde, @Oluwatobi-Mustapha, @ramonclaudio
Full changelog: v1.6.2...v1.7.0-beta.0