Commit Graph
7030 Commits
Author SHA1 Message Date
Gustavo ValverdeandGitHub 2d9781a83d fix(organization): split invitation verification gates (#9877) 2026-06-02 16:45:44 -04:00
TaesuandGitHub 5a2d642bc7 fix: accept null for optional fields in generated schema (#9841) 2026-06-01 06:28:56 +00:00
TaesuandGitHub 840a56a8ce docs(organization): document clearing logo with null (#9858) 2026-06-01 06:12:01 +00:00
TaesuandGitHub 6c39075a31 chore: add postmortem for RSC header detection (#9857) 2026-06-01 04:51:56 +00:00
TaesuandGitHub 9d3450ae23 fix(cookies): prefer __Secure- cookie in getSessionCookie (#9806) 2026-06-01 04:05:40 +00:00
better-release[bot]andGitHub a5e2442e3c chore: release v1.7.0-beta.4 (#9534) @better-auth/api-key@1.7.0-beta.4 @better-auth/cimd@1.7.0-beta.4 @better-auth/core@1.7.0-beta.4 @better-auth/drizzle-adapter@1.7.0-beta.4 @better-auth/electron@1.7.0-beta.4 @better-auth/expo@1.7.0-beta.4 @better-auth/i18n@1.7.0-beta.4 @better-auth/kysely-adapter@1.7.0-beta.4 @better-auth/memory-adapter@1.7.0-beta.4 @better-auth/mongo-adapter@1.7.0-beta.4 @better-auth/oauth-provider@1.7.0-beta.4 @better-auth/passkey@1.7.0-beta.4 @better-auth/prisma-adapter@1.7.0-beta.4 @better-auth/redis-storage@1.7.0-beta.4 @better-auth/scim@1.7.0-beta.4 @better-auth/sso@1.7.0-beta.4 @better-auth/stripe@1.7.0-beta.4 @better-auth/telemetry@1.7.0-beta.4 @better-auth/test-utils@1.7.0-beta.4 auth@1.7.0-beta.4 better-auth@1.7.0-beta.4 v1.7.0-beta.4 2026-05-31 14:29:39 +01:00
Gustavo ValverdeandGitHub b4b086722c fix(oauth-provider)!: bind RFC 8707 resource indicators to the authorization grant (#9836) 2026-05-31 14:14:50 +01:00
Gustavo ValverdeandGitHub a8ea86e25e fix(scim)!: always bind personal SCIM connections to their creator (#9840) 2026-05-31 12:53:18 +00:00
Gustavo ValverdeandGitHub 2bde9f4cbd chore: sync main to next
chore: sync main to next
2026-05-31 13:47:54 +01:00
Gustavo Valverde 1f4ca6e1e4 chore: sync main to next
Pull in #9845 (runtime-safe redirect-uri validation and fragment rejection) now that it merged to main, so next gets the corrected validation directly instead of waiting for a later sync.
2026-05-31 13:39:57 +01:00
Gustavo ValverdeandGitHub 13abc7922b fix(core): make redirect-uri validation runtime-safe and reject fragments (#9845) 2026-05-31 13:37:39 +01:00
Gustavo Valverde 065f5ad72d chore: sync main to next
Brings the v1.6.13 stable fixes into next: redirect_uri scheme validation in oidc-provider and mcp (#9838), clientPrivileges enforcement on dynamic client registration (#9837), null organization logo support (#9842), the consumeOne non-numeric deleteMany guard (#9831), and the db-adapter guide alignment (#9830).

Conflicts were limited to release version bumps and CHANGELOG entries; resolved by keeping next's 1.7.0-beta.3 line. The ten changesets consumed by the v1.6.13 release are accepted as deleted, and no external dependencies changed.
2026-05-31 13:02:15 +01:00
better-release[bot]andGitHub a6f38c72ee chore: release v1.6.13 (#9804) @better-auth/api-key@1.6.13 @better-auth/core@1.6.13 @better-auth/drizzle-adapter@1.6.13 @better-auth/electron@1.6.13 @better-auth/expo@1.6.13 @better-auth/i18n@1.6.13 @better-auth/kysely-adapter@1.6.13 @better-auth/memory-adapter@1.6.13 @better-auth/mongo-adapter@1.6.13 @better-auth/oauth-provider@1.6.13 @better-auth/passkey@1.6.13 @better-auth/prisma-adapter@1.6.13 @better-auth/redis-storage@1.6.13 @better-auth/scim@1.6.13 @better-auth/sso@1.6.13 @better-auth/stripe@1.6.13 @better-auth/telemetry@1.6.13 @better-auth/test-utils@1.6.13 auth@1.6.13 better-auth@1.6.13 v1.6.13 2026-05-31 12:41:17 +01:00
Gustavo ValverdeandGitHub 17ab66c3a4 fix(oauth-provider): enforce clientPrivileges on dynamic client registration (#9837) 2026-05-31 11:02:27 +00:00
87c1a0cab2 fix(organization): allow null logo on create and update (#9842)
Co-authored-by: Maxwell <145994855+ping-maxwell@users.noreply.github.com>
2026-05-31 10:58:24 +00:00
Gustavo ValverdeandGitHub be32012ca3 fix(oauth): validate redirect_uri schemes in oidc-provider and mcp (#9838) 2026-05-31 11:38:52 +01:00
TaesuandGitHub df9e8b2951 docs: align db adapter guide with adapter contract (#9830) 2026-05-31 09:01:50 +00:00
TaesuandGitHub 5c3e248cbf fix(core): throw on non-numeric deleteMany in consumeOne fallback (#9831) 2026-05-31 09:00:18 +00:00
Gustavo ValverdeandGitHub 8dcddf786c chore: sync main to next
chore: sync main to next
2026-05-31 07:51:49 +01:00
Gustavo Valverde 51a122fa6d test(oidc-provider): align concurrent-redemption test to next's callback path (#9533)
The concurrent authorization-code redemption test (added on main for
GHSA-7w99-5wm4-3g79) exchanged the code against `/api/auth/oauth2/callback/test`,
but next renamed that callback path to `/api/auth/callback/test`. The merge
kept next's code-minting helper while preserving main's exchange path, so the
race winner failed redirect_uri validation and no caller minted a token,
tripping the "exactly one success" assertion.

Because that test threw before closing its listener on port 3000, the leaked
server poisoned the later EdDSA and HS256 oidc-jwt tests (stale server, code
not found on consume). Aligning the exchange path to next fixes all three.
2026-05-31 07:40:40 +01:00
Gustavo Valverde 68cb13896a test(generic-oauth): assert error=state_not_found on stateless callback (#9533) 2026-05-31 02:10:21 +01:00
Gustavo Valverde 9556e619e4 fix(oauth): emit error=state_not_found on missing callback state (#9533) 2026-05-31 02:03:55 +01:00
Gustavo Valverde 0fe3590e16 test(oauth-provider): adapt merged token/private-key-jwt tests to next's APIs (#9533)
These test files auto-merged main's additions onto next's refactored test
surface, producing runtime failures tsc could not catch:

- token.test.ts called main's sync createRefreshAccessTokenRequest, which next
  renamed to the async refreshAccessTokenRequest; the calls now await it and
  the concurrent-rotation helper is async.
- private-key-jwt-e2e.test.ts hit the merged-in #9578 gate: both the provider
  and RP test instances create the same default user, so the OAuth sign-in
  links to the RP's unverified local user and is blocked. The RP sets
  requireLocalEmailVerified: false so the test exercises private_key_jwt
  rather than the (separately covered) email-verification gate.
- utils/basic-auth.test.ts is removed: next made basicToClientCredentials
  private, and its colon-preservation coverage now lives in core's
  basic-credentials.test.ts.

Full oauth-provider suite green (24 files, 378 tests).
2026-05-31 01:51:34 +01:00
Gustavo Valverde a99a331376 chore: pin kysely and zod, regenerate lockfiles for merged deps (#9533)
Reconcile pnpm-lock.yaml (root) and demo/nextjs/pnpm-lock.yaml with the merged
package.json and pnpm-workspace.yaml overrides: next's workspace versions plus
main's security bumps (samlify 2.13.1, fast-xml-parser 5.8.0) and the #9820
transitive-version overrides. demo/nextjs is a standalone pnpm project whose
lockfile was resolved to next's during the merge while its workspace took
main's overrides, so it is regenerated to match.

Two root overrides pin dependencies to next's working versions:
- kysely 0.28.17 (main's resolved version). The catalog range permits 0.29,
  but kysely 0.29's ESM build dropped the migration-table exports the
  kysely-adapter node:sqlite introspector imports, breaking table discovery.
- zod 4.x to 4.3.6. better-call's zod peer otherwise resolves to 4.4.3, which
  produces a third zod copy that makes the docs app resolve zod to the 3.x
  line and fails react-hook-form's zodResolver type check.

main reaches these versions through its release-age policy; next pins them
explicitly because that policy does not resolve in every environment. Remove
the pins once the kysely 0.29 and zod 4.4 upgrades land with their fixes.

Verified: frozen install (root and all demos) under the strict policy, docs
tsc, build, and the OAuth/SSO/oauth-provider regression suites.
2026-05-31 01:36:10 +01:00
Gustavo Valverde 8bfd30f10a style: apply biome formatting to synced files (#9533) 2026-05-31 01:30:41 +01:00
Gustavo Valverde 71326af813 fix(sso): apply samlify 2.13.1 signed-assertion XML-injection fix on refactored routes (#9821)
Re-applies main's #9821 onto next's rebuilt SAML routes. next kept the
createSP/createIdP helpers and consolidated saml-pipeline, so the fix is
expressed there rather than in the inline construction main patched.

- normalizePem trims leading indentation from PEM private keys so samlify
  2.13.1 (OpenSSL 3 native parsing) loads keys pasted with surrounding
  whitespace; applied in the SP/IdP helpers.
- processSAMLResponse reads identity attributes through an attr() accessor
  that collapses samlify 2.13's string | string[] attribute values to the
  single-valued identity fields.
- the SLO LogoutResponse is built by passing the parsed request to samlify
  (filling InResponseTo/Issuer/IssueInstant/Destination/StatusCode) instead
  of manual template string replacement.

The samlify ^2.13.1 and fast-xml-parser ^5.8.0 bumps land via the merge.
saml.test.ts unions next's SAML suites with #9821's key-normalization and
SLO regression tests (120 passing).
2026-05-31 00:30:51 +01:00
Gustavo Valverde 9247cb8528 fix(sso): enforce SSRF validation, org-admin registration, SLO-by-token, and error encoding on refactored routes (#9574, #9220, #9818, #9722, #9702)
Re-applies five main fixes onto next's rebuilt SSO routes. next's refactor
kept the supporting helpers (the SSRF host check, the SAMLSessionRecord
token field) but dropped the call sites, so the merge left them present yet
unused. This wires them back.

- #9574: registerSSOProvider and updateSSOProvider now run
  validateSkipDiscoveryEndpoints on user-supplied OIDC endpoints, rejecting
  private/link-local hosts (for example 169.254.169.254). The merge included
  the helper but never called it, leaving advisory GHSA-5rr4-8452-hf4v open
  on next. Validation runs even without skipDiscovery.
- #9220: registering an SSO provider requires an organization owner/admin
  role when the organization plugin is active, blocking a low-privilege
  member from registering a malicious IdP.
- #9818: SAML Single Logout revokes the session by token; the SAML session
  record now carries the session token.
- #9722: the OIDC callback error redirect encodes the error value.
- #9702: a before-callback hook rejection in the OIDC and SAML callbacks
  redirects to the per-flow errorURL with the hook's code, instead of
  surfacing a raw response.

Two stale IDP-bounce assertions are updated to next's migrated state-error
vocabulary (state_not_found). All SSO regression suites pass (SSRF,
org-admin, SLO, hook-rejection, encoding).

(cherry picked from commit c3b238f71a6f66914f12db5f615504e2cf855bfc)
2026-05-31 00:10:48 +01:00
Gustavo Valverde 34060c7be4 test: adapt merged mcp and two-factor tests to next's breaking APIs
The merge auto-combined these test files without textual conflict, but they
referenced APIs next changed, so type checking failed:

- mcp.test.ts drove one (skipped) confidential-client test through the
  removed generic-oauth client (genericOAuthClient + signIn.oauth2). It now
  uses signIn.social like the surrounding tests.
- two-factor.security.test.ts read enrollment.totpURI directly; next's #9057
  made the enable response a discriminated { method } union, so the tests now
  narrow on method === "totp" before reading totpURI.

tsc --build is clean across the workspace.

(cherry picked from commit d3cd3c2eb39f0c7209f45ff27ac4b943250b93be)
2026-05-31 00:10:36 +01:00
Gustavo Valverde 62b589797e test(organization, username): union regression suites with next features (#9616, #9577, #9792, #9464)
Resolves the team and username test-file conflicts as the union of next's
new feature suites and main's regression tests, whose source fixes merged in
cleanly:

- team.test.ts keeps next's listUserTeams suites and adds main's
  comma-in-team-id rejection test (#9616), plus the
  databaseHooks.user.create.before -> emailVerified:true setup needed because
  the merged invitation gate now defaults on (#9577).
- username.test.ts keeps next's immutable-username suite and adds main's
  verify-email callbackURL encoding test (#9792); the admin createUser
  username validation (#9464) is orthogonal and merged cleanly.

team.test.ts 43 pass, username.test.ts 41 pass.

(cherry picked from commit ea3ed7af30c12901252085c5ddf43a7dca57f929)
2026-05-31 00:10:36 +01:00
Gustavo Valverde 3fbc2f3405 test(generic-oauth): port regression suites onto the social-provider rewrite (#9799, #9792, #9702, #9578)
next's #9069 rewrote generic-oauth to flow through the core social provider
and callback. The #9799 accessTokenExpiresIn source fix merged in cleanly
(its config field and the applyDefaultAccessTokenExpiry wiring land on the
three token paths); main's regression tests still targeted the old
signIn.oauth2 plugin API. This ports them onto signIn.social so they keep
guarding the behavior:

- #9799: getAccessToken refreshes once the accessTokenExpiresIn window passes
  when the provider omits expires_in, does not refresh when it is unset, and
  applies it to a custom getToken result.
- #9792: the verify-email link preserves the encoded callbackURL.
- #9702: a session hook throwing an APIError redirects to the cross-origin
  errorCallbackURL with the hook's code (proves the rewritten callback's
  hook-error forwarding).
- #9578: implicit-link tests mark the local user verified so linking is
  allowed under the default-on requireLocalEmailVerified gate.

A stale IDP-bounce assertion is updated to next's state-error vocabulary.
All 71 tests pass.

(cherry picked from commit 52adab0db3f463295a0c4e3152d770f4ce40b2d2)
2026-05-31 00:10:36 +01:00
Gustavo Valverde be653ab90d docs(two-factor): merge enforcement-scope clarification into OTP rewrite (#9607)
Layers main's #9607 clarification onto next's #9057 OTP-enablement rewrite.
The "Sign In with 2FA" section now states that 2FA sign-in enforcement
applies to the credential endpoints (/sign-in/email, /sign-in/username,
/sign-in/phone-number) and that passwordless flows are not gated by default,
with guidance to add custom hook handling to require it. The passwordless
callout and the allowPasswordless option note that the flag does not change
which sign-in methods are challenged. main's edit to the removed
skipVerificationOnEnable bullet is dropped, since next deleted that option.

(cherry picked from commit 6156cef51329e1c38544aa06eb5072d8a06ece7a)
2026-05-31 00:10:36 +01:00
Gustavo Valverde 027a10c566 fix(oauth-provider): gate DCR and serve path-prefixed issuer metadata (#9448, #9668)
Re-applies two main fixes onto next's refactored metadata layer.

- #9448: registration_endpoint is now advertised only when dynamic client
  registration is enabled. With DCR off, the field was still advertised in
  authorization-server and OpenID metadata while the endpoint itself was
  disabled, so clients attempted a registration that failed.
- #9668: the authorization-server and OpenID discovery documents are served
  again at their path-prefixed (RFC 8414 path-insertion and issuer-appended)
  aliases via an onRequest handler, with HEAD support and a 405 for
  non-GET/HEAD. next's refactor kept the server-only metadata endpoints but
  dropped the request handler that exposes them over HTTP. The handler is
  adapted to next's metadata (CIMD-aware public-client flag and merged
  discovery metadata) and metadataResponse is exported for it.

#9601 (preserve colons in Basic Auth secret) is already covered: next routes
Basic parsing through @better-auth/core decodeBasicCredentials, which splits
on the first colon, so no change to utils/index.ts.

The merged metadata test suite (union of next and main, including the
DCR-conditional and alias cases) passes.

(cherry picked from commit 66a7b0b62d76e36474ebdca189f59200daa3ec76)
2026-05-31 00:10:36 +01:00
Gustavo Valverde d309e5d2ba fix(oauth): forward hook errors and sync linked profiles on rewritten callback (#9702, #9788, #8758)
Re-applies three main fixes onto next's rewritten OAuth callback, which
now routes generic-oauth through the shared callback route.

- #9702/#9788: a before-callback hook that rejects sign-in (the banned-user
  guard is the flagship case) now redirects to the per-flow errorURL
  carrying the hook's machine-readable code and message, instead of
  surfacing a raw error response. handleOAuthUserInfo is wrapped in
  try/catch; the hook's APIError code is forwarded verbatim (it is
  app-defined, not a member of OAUTH_CALLBACK_ERROR_CODES) via next's
  local redirectOnError closure. The admin plugin's stale inline /callback
  redirect is removed so the banned-user path flows through that single
  forwarder and emits BANNED_USER with a URL-encoded description.
- #8758: accountLinking.updateUserInfoOnLink now applies on the explicit
  OAuth link path, not only id-token linking.

The regression tests (banned social sign-in emits error=BANNED_USER, the
cross-origin errorCallbackURL case, and the 403-JSON id-token case) arrived
via the merge and were red on the baseline; these source changes make them
pass.

(cherry picked from commit 1d893ae572277447025e29462946a7aeb11443ac)
2026-05-31 00:10:35 +01:00
Gustavo Valverde ef4fb0ff95 chore: merge main into next (#9533)
Sync main (through #9821/#9820/#9822/#9768) into next. Conflicting
package.json files keep next's version and intentional divergences (for
example the cli's c12 v4) while taking main's dependency updates, including
the samlify 2.13.1 and fast-xml-parser security bumps; the lockfile is
regenerated from the reconciled set. The 13 source/doc/test conflicts take
next's refactored architecture as the baseline; main's colliding fixes are
re-applied on top in the following per-domain commits.

Clean main fixes land via this merge, including the auto-restored
account-takeover defenses #9578 and #9577.
2026-05-31 00:10:16 +01:00
Gustavo ValverdeandGitHub 4c3bbc4e56 fix(sso): update samlify to 2.13.1 for signed-assertion XML injection (#9821) 2026-05-30 23:58:05 +01:00
Gustavo ValverdeandGitHub 9c8ded67b1 docs(two-factor): mark viewBackupCodes as server-only in its API comment (#9822) 2026-05-30 23:52:38 +01:00
Gustavo ValverdeandGitHub a1028d9f1f fix(deps): force patched transitive versions via pnpm overrides (#9820) 2026-05-30 23:40:38 +01:00
Gustavo ValverdeandGitHub e8696388bf docs(oauth-provider): align metadata routing guidance (#9768) 2026-05-30 22:32:09 +01:00
43c08a2bc7 fix(account): scope OAuth account identity and fix buggy internalAdapter helpers (#9818)
Co-authored-by: Krish Garg <kgarg@chapman.edu>
2026-05-30 20:48:10 +00:00
23d7cbfa79 fix(oauth): apply updateUserInfoOnLink in OAuth callback link flow (#8758)
Co-authored-by: Gustavo Valverde <g.valverde02@gmail.com>
2026-05-30 19:48:38 +01:00
Gustavo ValverdeandGitHub e24ddfd13b fix(expo): persist large account cookies by chunking device storage (#9815) 2026-05-30 18:24:14 +01:00
d3919dc1a5 feat(account): support server-side accountInfo calls without session headers (#9813)
Co-authored-by: Nathan Colosimo <nathancolosimo@gmail.com>
2026-05-30 12:45:40 +01:00
5f282bd382 fix(account): default storeStateStrategy to "database" when using secondaryStorage (#9591)
Co-authored-by: Gustavo Valverde <g.valverde02@gmail.com>
2026-05-30 11:05:28 +01:00
Gustavo ValverdeandGitHub 5ec3e761a3 fix(ci): use GitHub-hosted runners for fork pull requests (#9809) 2026-05-30 10:24:06 +01:00
TaesuandGitHub e131d3ac5b fix(api-key): verify non-default keys when configId is omitted (#9794) 2026-05-30 03:14:57 +00:00
better-release[bot]andGitHub c0c574ea50 chore: release v1.6.12 (#9590) @better-auth/core@1.6.12 @better-auth/drizzle-adapter@1.6.12 @better-auth/electron@1.6.12 @better-auth/expo@1.6.12 @better-auth/i18n@1.6.12 @better-auth/kysely-adapter@1.6.12 @better-auth/memory-adapter@1.6.12 @better-auth/mongo-adapter@1.6.12 @better-auth/oauth-provider@1.6.12 @better-auth/passkey@1.6.12 @better-auth/prisma-adapter@1.6.12 @better-auth/redis-storage@1.6.12 @better-auth/scim@1.6.12 @better-auth/sso@1.6.12 @better-auth/stripe@1.6.12 @better-auth/telemetry@1.6.12 @better-auth/test-utils@1.6.12 auth@1.6.12 better-auth@1.6.12 @better-auth/api-key@1.6.12 v1.6.12 2026-05-29 22:28:58 +01:00
Gustavo ValverdeandGitHub c5b9f93498 fix(generic-oauth): add accessTokenExpiresIn for providers that omit expires_in (#9799) 2026-05-29 20:49:59 +00:00
17cd433c66 fix(oauth-proxy): missing state-cookie skip for oauth-proxy (#9385)
Co-authored-by: Gustavo Valverde <g.valverde02@gmail.com>
2026-05-29 15:06:34 +00:00
Gustavo ValverdeandGitHub c92cd74162 fix: URL-encode callbackURL in verify-email links (#9792) 2026-05-29 08:08:42 +00:00
093115e162 docs(oauth): added Roblox provider and alphabetized "providers without email" table (#9786)
Co-authored-by: Taesu <bytaesu@gmail.com>
2026-05-29 03:16:35 +00:00