diff --git a/.changeset/25096-better-auth-1-7-12.md b/.changeset/25096-better-auth-1-7-12.md new file mode 100644 index 00000000000..2e716be2a18 --- /dev/null +++ b/.changeset/25096-better-auth-1-7-12.md @@ -0,0 +1,37 @@ +--- +'@objectstack/plugin-auth': patch +'@objectstack/spec': patch +'@objectstack/cli': patch +'@objectstack/service-datasource': patch +--- + +fix(plugin-auth)!: lift the better-auth family from 1.7.3 to 1.7.12 for the security fixes published since + +`@objectstack/plugin-auth` declares the better-auth family exactly, so a fresh install resolves what this package tested. All five declared ranges (`better-auth`, `@better-auth/core`, `@better-auth/oauth-provider`, `@better-auth/scim`, `@better-auth/sso`) move from `1.7.3` to `1.7.12`, still exact. The lift takes the fixes published in 1.7.4 to 1.7.12 for packages this plugin mounts: GHSA-965c-763c-88jm and GHSA-r4xp-prcw-77qf (1.7.7), and the oauth-provider, SSO, SCIM, JWT and password-reset fixes up to 1.7.12. Every symbol this package imports from the family is still exported. It also pulls in `better-call` 1.4.4, `@better-auth/utils` 0.5.0 and `@better-fetch/fetch` 1.3.2, the versions 1.7.12 declares. + +Clause-②: no (narrowing) +Metadata-protocol: none + + + +**BREAKING** (the auth endpoints refuse some requests 1.7.3 accepted, and some refusals change status), shipped as `patch` under ruling A: it changes nothing a metadata author can write, and a non-protocol breaking change ships `patch` while keeping this BREAKING banner and its ADR-0087 disposition. + +- **FROM:** a Magic Link, OAuth or social sign-in, SAML or account-linking flow started before the upgrade could complete after it. + **TO:** it fails, and the user starts it again. 1.7.7 stores Magic Link and OAuth-state verification rows under new identifier prefixes and keys the OAuth state cookie per purpose, so a link or a pending identity-provider round-trip minted by 1.7.3 is not found: a Magic Link answers `?error=INVALID_TOKEN`, an OAuth callback answers a state mismatch. +- **FROM:** an OIDC SSO provider whose configured issuer differed from its discovery document's `issuer`, for example only by a trailing slash, signed users in. + **TO:** the provider is refused with `issuer_mismatch`. 1.7.12 also refuses an OIDC ID token that carries no `exp` or `iat`. +- **FROM:** `POST /api/v1/auth/oauth2/token` with a PKCE `code_verifier` that does not match the challenge answered `401`. + **TO:** it answers `400` with `error: 'invalid_grant'`. +- **FROM:** `GET /api/v1/auth/get-session` answered `401 UNAUTHENTICATED` ("Sign in first") when the session store could not be read, the same answer a signed-out browser gets, and an in-process `api.getSession` resolved `null`. + **TO:** it answers `500` with `code: 'FAILED_TO_GET_SESSION'` and keeps the session cookie, and the in-process read rejects. Callers that treat a failed read as anonymous on purpose (the request-context resolution in `@objectstack/core` and `@objectstack/runtime`) still do. +- **FROM:** `POST /api/v1/auth/sign-in/email` with a password longer than the configured maximum answered as an ordinary failed sign-in. + **TO:** it answers `400` with `code: 'PASSWORD_TOO_LONG'` before any account is looked up. It still counts as a failed attempt for the account lockout. +- **FROM:** a DPoP proof sent to the token endpoint was checked against the URL of the request as it reached the server. + **TO:** it is checked against the configured public base URL plus the request path. Behind a proxy that rewrites the host, a proof bound to the public URL is now accepted and a proof bound to the internal URL is refused with `invalid_dpop_proof`. +- **FROM:** `GET /api/v1/auth/get-session` with a cookie for a session that no longer exists answered `401` and left the cookie in place. + **TO:** the same `401` also clears the stale session cookies. +- **New route:** `POST /api/v1/auth/oauth2/client/rotate-keys` (`private_key_jwt` key rotation) is now published, and refused with `403 access_denied` because this package does not enable client key rotation. +- **Unchanged:** the package's exports and configuration; sign-up, sign-in and session cookies (`HttpOnly; SameSite=Lax; Path=/`, no `Secure` on plain HTTP); the active organization stamped on a new session; implicit account linking and its unlink records; single-use reservations (a replayed DPoP proof or client assertion is still refused); and where sessions and verification values are stored with or without a host `secondaryStorage`. +- **`@objectstack/spec` and `@objectstack/cli` (patch, text only, not breaking):** the TSDoc on the organization schema's optional `updatedAt` now records that its better-auth measurement still holds on 1.7.12, and the `os migrate account-issuer` description no longer names a better-auth version. No schema, type, flag or behaviour changes in either package. +- **`@objectstack/service-datasource` (patch, text only, not breaking):** the `resolveSqliteDriver` docs now describe the error better-sqlite3 13 actually throws for an addon that was never built: its loader's `require()` of the absent `build/Release/better_sqlite3.node`, which Node answers with `MODULE_NOT_FOUND`. The docs used to name a helper package's message that 13.x no longer produces. Development still steps down to wasm SQLite on that error, as before. No code changes. +- **What to do as an operator:** tell users that a Magic Link, social, SSO or account-linking sign-in begun before the upgrade must be started again after it. Check each OIDC SSO provider's configured issuer against its discovery document and set it to the exact `issuer` string the document publishes. An OAuth client that branched on `401` for a PKCE failure should branch on `400 invalid_grant`. A browser client that read every non-`200` `/get-session` answer as "signed out" should treat a `500` as "try again". diff --git a/packages/cli/src/commands/migrate/account-issuer.ts b/packages/cli/src/commands/migrate/account-issuer.ts index 261c386e66d..7153993f79a 100644 --- a/packages/cli/src/commands/migrate/account-issuer.ts +++ b/packages/cli/src/commands/migrate/account-issuer.ts @@ -68,7 +68,7 @@ export default class MigrateAccountIssuer extends Command { static override description = 'Pre-flight the retirement of sys_account.issuer: report every (provider_id, account_id) ' + 'key held by more than one row — the class that is legal under the retired (issuer, account_id) key ' + - 'and is ONE account under the key better-auth 1.7.3 restored. Read-only; exits non-zero when the ' + + 'and is ONE account under the (provider_id, account_id) key better-auth restored. Read-only; exits non-zero when the ' + 'drop must not proceed.'; static override examples = [ diff --git a/packages/plugins/plugin-auth/package.json b/packages/plugins/plugin-auth/package.json index 3be56d7784e..f44652d3895 100644 --- a/packages/plugins/plugin-auth/package.json +++ b/packages/plugins/plugin-auth/package.json @@ -31,10 +31,10 @@ "gen:test-typecheck-debt": "tsx ../../../scripts/check-test-typecheck.mts --update --package packages/plugins/plugin-auth --project tsconfig.test.json" }, "dependencies": { - "@better-auth/core": "1.7.3", - "@better-auth/oauth-provider": "1.7.3", - "@better-auth/scim": "1.7.3", - "@better-auth/sso": "1.7.3", + "@better-auth/core": "1.7.12", + "@better-auth/oauth-provider": "1.7.12", + "@better-auth/scim": "1.7.12", + "@better-auth/sso": "1.7.12", "@noble/hashes": "^2.4.0", "@objectstack/core": "workspace:*", "@objectstack/platform-objects": "workspace:*", @@ -42,7 +42,7 @@ "@objectstack/service-messaging": "workspace:*", "@objectstack/spec": "workspace:*", "@objectstack/types": "workspace:*", - "better-auth": "1.7.3", + "better-auth": "1.7.12", "jose": "^6.2.12" }, "devDependencies": { diff --git a/packages/plugins/plugin-auth/src/account-invitation-marker.ts b/packages/plugins/plugin-auth/src/account-invitation-marker.ts index de941fab232..06fb0a518a2 100644 --- a/packages/plugins/plugin-auth/src/account-invitation-marker.ts +++ b/packages/plugins/plugin-auth/src/account-invitation-marker.ts @@ -11,7 +11,8 @@ * is what creates the row's credential on first set. But better-auth hands the * resulting link only to `sendResetPassword({ user, url, token }, ctx.request)`; * `requestPasswordReset` itself answers `{ status, message }` and nothing else - * (installed better-auth 1.7.3, `dist/api/routes/password.mjs`). So the import + * (better-auth 1.7.12, `dist/api/routes/password.mjs`, re-measured 2026-10-21 + * for #25096). So the import * never holds the link, and the template choice can only be made inside * `sendResetPassword` (`auth-manager.ts`). Without a marker that callback * cannot tell an administrator's invitation from a user who forgot their @@ -65,8 +66,8 @@ * * better-auth runs `sendResetPassword` through `runInBackgroundOrAwait`, which * CATCHES and logs whatever the send throws, and `requestPasswordReset` still - * answers `{ status: true }` (installed 1.7.3, `dist/context/create-context.mjs` - * and `dist/api/routes/password.mjs`). That is right for the public door — the + * answers `{ status: true }` (better-auth 1.7.12, `dist/context/create-context.mjs` + * and `dist/api/routes/password.mjs`, re-measured 2026-10-21 for #25096). That is right for the public door — the * answer must not say whether an address exists or whether its mail went out — * and it means a throw inside the send can never reach the import. No * better-auth option makes the call rethrow: `advanced.backgroundTasks.handler` diff --git a/packages/plugins/plugin-auth/src/admin-import-users-invite-delivery-failure.test.ts b/packages/plugins/plugin-auth/src/admin-import-users-invite-delivery-failure.test.ts index 8873a99d148..984a26f89e9 100644 --- a/packages/plugins/plugin-auth/src/admin-import-users-invite-delivery-failure.test.ts +++ b/packages/plugins/plugin-auth/src/admin-import-users-invite-delivery-failure.test.ts @@ -6,7 +6,8 @@ * The import invites an email row by asking better-auth for a password reset, * and better-auth runs `sendResetPassword` through `runInBackgroundOrAwait`, * which catches and logs whatever the send throws and still answers - * `{ status: true }` (installed 1.7.3, `dist/context/create-context.mjs`). So a + * `{ status: true }` (better-auth 1.7.12, `dist/context/create-context.mjs`, + * re-measured 2026-10-21 for #25096). So a * throw inside the send can never reach the import. `sendResetPassword` now * settles a delivery receipt the import's own request carries * (`account-invitation-marker.ts`), and the import reads it after the request diff --git a/packages/plugins/plugin-auth/src/auth-email-locale.test.ts b/packages/plugins/plugin-auth/src/auth-email-locale.test.ts index 338f8623ab6..b5666cf7427 100644 --- a/packages/plugins/plugin-auth/src/auth-email-locale.test.ts +++ b/packages/plugins/plugin-auth/src/auth-email-locale.test.ts @@ -867,8 +867,8 @@ describe("#14641 — an invitation reads the INVITEE's own sys_user.locale", () * recipient-keyed engine, not by asserting it about this send alone. * * Two branches, because a magic link is BOTH a sign-in for an existing account - * and a sign-up for a new address (re-measured 2026-09-11 in the installed - * better-auth 1.7.3, unchanged from 1.7.2: the `/sign-in/magic-link` handler + * and a sign-up for a new address (re-measured 2026-10-21 for #25096 on + * better-auth 1.7.12, unchanged since 1.7.2: the `/sign-in/magic-link` handler * takes `email` straight off the body, stores a verification value and calls * `sendMagicLink` — no user lookup on that path at all — while * `/magic-link/verify` reads `findUserByEmail` and, finding nobody, calls @@ -1003,8 +1003,8 @@ describe("#15106 — the magic link reads the recipient's own sys_user.locale", }); it('matches the address better-auth itself will resolve the link with — lowercased', async () => { - // ⚠️ Measured against the installed better-auth 1.7.3 (2026-09-11), not - // assumed, and unchanged from the 1.7.2 reading this replaces: + // ⚠️ Measured against better-auth 1.7.12 (2026-10-21, #25096), not + // assumed, and unchanged since the 1.7.2 reading: // `signInMagicLinkBodySchema` declares `email: z.email()` with no case // transform, so a typed `Ada@Example.com` arrives here verbatim, while // `internalAdapter.findUserByEmail` — what `/magic-link/verify` resolves diff --git a/packages/plugins/plugin-auth/src/auth-manager.ts b/packages/plugins/plugin-auth/src/auth-manager.ts index 9bf5c29d981..32d727067e6 100644 --- a/packages/plugins/plugin-auth/src/auth-manager.ts +++ b/packages/plugins/plugin-auth/src/auth-manager.ts @@ -1799,8 +1799,9 @@ export class AuthManager { // The deployment's product name, from the one authority every auth // email already reads (`getAppName()`: the `branding.workspace_name` // override, else the configured `appName`, else 'ObjectStack'). - // better-auth 1.7.3 reads this key once, into its context's `appName` - // (unset ⇒ "Better Auth"), and reads that in exactly two places: the + // better-auth 1.7.12 (re-read 2026-10-21 for #25096) reads this key once, + // into its context's `appName` (unset ⇒ "Better Auth"), and reads that + // in exactly two places: the // issuer and label prefix of the otpauth URI that `/two-factor/enable` // and `/two-factor/get-totp-uri` answer. No cookie name derives from it // (the prefix is the literal "better-auth") and nothing stores it, so an @@ -2058,8 +2059,8 @@ export class AuthManager { ); } // The lifetime the token in `url` really has: better-auth mints it - // with `resetPasswordTokenExpiresIn || 3600` seconds (installed - // 1.7.3 `routes/password.mjs`) — `||`, so a configured `0` is its + // with `resetPasswordTokenExpiresIn || 3600` seconds (better-auth + // 1.7.12 `routes/password.mjs`, re-measured 2026-10-21 for #25096) — `||`, so a configured `0` is its // default too, and the mail must not say "0 minutes" for it. const ttlSec = this.config.emailAndPassword?.resetPasswordTokenExpiresIn || 60 * 60; // [#23343] An account an administrator created (the identity @@ -2081,7 +2082,8 @@ export class AuthManager { // commit 35e94c96b — the ladder's stored rung. It matters most HERE: an // admin-initiated send (`admin-import-users.ts` calls // `requestPasswordReset` server-side) reaches this callback with NO - // request at all (measured on 1.7.3, #23343), so without this rung + // request at all (measured on 1.7.3, #23343; unchanged on 1.7.12, + // re-read for #25096), so without this rung // the user's mail carries only the deployment default. Best-effort; // `undefined` leaves the #14319 ladder exactly as it was. const storedLocale = await this.storedRecipientLocale({ id: user.id }); @@ -4723,8 +4725,8 @@ export class AuthManager { // // Handing better-auth no `database` makes it build its own in-memory store // in `getBaseAdapter`, and that store is keyed by the schema KEY while - // every read resolves by `modelName`. Re-measured 2026-09-11 on the - // installed better-auth 1.7.3, unchanged from the 1.7.2 reading it replaces + // every read resolves by `modelName`. Re-measured 2026-10-21 for #25096 on + // better-auth 1.7.12, unchanged since the 1.7.2 reading // (`db/adapter-base.mjs` builds the store by schema KEY; // `@better-auth/memory-adapter` throws on the lookup, naming the model): // @@ -9698,7 +9700,8 @@ export class AuthManager { * (plus `id`), or `undefined` when the identifier names no account. * * It asks exactly what better-auth's `/sign-in/email` credential check asks - * (1.7.3: `internalAdapter.findUserByEmail(email.toLowerCase())`, an + * (1.7.12, re-read 2026-10-21 for #25096: + * `internalAdapter.findUserByEmail(email.toLowerCase())`, an * equality match of the `email` column against the lower-cased address, * which is also the spelling `internalAdapter.createUser` stores), so the * gate, the counter, the ledger and the credential check name one account diff --git a/packages/plugins/plugin-auth/src/auth-route-ledger.ts b/packages/plugins/plugin-auth/src/auth-route-ledger.ts index 75e17329bd3..20984305737 100644 --- a/packages/plugins/plugin-auth/src/auth-route-ledger.ts +++ b/packages/plugins/plugin-auth/src/auth-route-ledger.ts @@ -382,6 +382,13 @@ export const BETTER_AUTH_MOUNTED_SURFACE: readonly string[] = [ 'POST /api/v1/auth/get-session', 'POST /api/v1/auth/link-social', 'POST /api/v1/auth/oauth2/authorize', + // `private_key_jwt` client key rotation. Added to `@better-auth/oauth-provider` + // after 1.7.3 and published here since the 1.7.12 lift (#25096). The handler + // refuses before it reads anything unless the plugin is given + // `allowClientKeyRotation`, and `auth-manager.ts` does not set it, so every + // call answers 403 `access_denied` ("Client key rotation is disabled"), + // measured on this stack for #25096. Turning it on is its own decision. + 'POST /api/v1/auth/oauth2/client/rotate-keys', 'POST /api/v1/auth/oauth2/client/rotate-secret', 'POST /api/v1/auth/oauth2/consent', 'POST /api/v1/auth/oauth2/continue', diff --git a/packages/plugins/plugin-auth/src/auth-schema-config.ts b/packages/plugins/plugin-auth/src/auth-schema-config.ts index d66b4690e9b..bc38c1dde37 100644 --- a/packages/plugins/plugin-auth/src/auth-schema-config.ts +++ b/packages/plugins/plugin-auth/src/auth-schema-config.ts @@ -953,12 +953,12 @@ export const buildOidcProviderPluginSchema = buildOauthProviderPluginSchema; // NOTE: there is intentionally no scim mapping constant here, and no // `buildScimPluginSchema()`. `@better-auth/scim` hardcodes its models and exposes -// NO `schema` option — still true of the installed stable `@better-auth/scim@1.7.3` -// (re-read 2026-09-11: `SCIMOptions` declares no `schema` / `modelName` / `fields` +// NO `schema` option — still true of the installed stable `@better-auth/scim@1.7.12` +// (re-read 2026-10-21 for #25096: `SCIMOptions` declares no `schema` / `modelName` / `fields` // member at all — its six members are still connections, authentication, // managedConnections, identity, projection, compatibility; measured 2026-08-19 on // the rc, re-measured 2026-08-27 on stable 1.7.1, again 2026-08-31 on 1.7.2 for -// #13940, and again on 1.7.3 with the family lift), so +// #13940, again on 1.7.3 with the family lift, and on 1.7.12 with #25096), so // there is nowhere to hand one. This is no longer true // of `@better-auth/sso@1.7.1`, which now accepts one (#8224) — for scim, and for // scim alone, the ADAPTER layer is the only available route. diff --git a/packages/plugins/plugin-auth/src/implicit-account-linking.ts b/packages/plugins/plugin-auth/src/implicit-account-linking.ts index be82116f00f..7d3994eae4a 100644 --- a/packages/plugins/plugin-auth/src/implicit-account-linking.ts +++ b/packages/plugins/plugin-auth/src/implicit-account-linking.ts @@ -42,7 +42,7 @@ * * ## Why the enforcement point is `user.validateUserInfo` * - * Measured against the installed better-auth `1.7.3` + * Measured against better-auth `1.7.12` (re-measured 2026-10-21 for #25096) * (`dist/oauth2/link-account.mjs`, `handleOAuthUserInfo`): * * - The library's own gate refuses an implicit link when @@ -63,7 +63,8 @@ * implicitly (`/callback/:id`, `/sign-in/social` with an id token, * one-tap, oauth-proxy, and the SSO plugin, which share the function). * - The EXPLICIT link (`/link-social` → `/callback/:id` with `link` in the - * OAuth state) passes the same `action: 'link-account'`. It is told apart + * OAuth state) passes the same `action: 'link-account'` (1.7.12 routes it + * through `linkOAuthAccount`, in the same file). It is told apart * by the OAuth state the callback parsed (`getOAuthState().link`), which * the server writes from the session at `/link-social`; `generateState` * places `link` AFTER the client-supplied `additionalData`, so a client diff --git a/packages/plugins/plugin-auth/src/in-process-redispatch.ts b/packages/plugins/plugin-auth/src/in-process-redispatch.ts index 2630df2167e..d823066cffc 100644 --- a/packages/plugins/plugin-auth/src/in-process-redispatch.ts +++ b/packages/plugins/plugin-auth/src/in-process-redispatch.ts @@ -27,7 +27,8 @@ * renewing — there is no cookie to fall behind. * * better-auth reads the flag from the query on both kinds of re-dispatch - * (1.7.3, measured by `in-process-session-renewal.pin.test.ts`): the + * (1.7.12, re-measured 2026-10-21 for #25096 by + * `in-process-session-renewal.pin.test.ts`): the * `/get-session` route declares it (`getSessionQuerySchema`, coerced), and * `getSessionFromCtx` — which `sessionMiddleware` and this plugin's own * before-hooks call — spreads the route's `ctx.query` into the read it makes, diff --git a/packages/plugins/plugin-auth/src/internal-field-readback.ts b/packages/plugins/plugin-auth/src/internal-field-readback.ts index 50dec6899e7..65aab815166 100644 --- a/packages/plugins/plugin-auth/src/internal-field-readback.ts +++ b/packages/plugins/plugin-auth/src/internal-field-readback.ts @@ -194,7 +194,8 @@ const READBACK_FIELDS: Readonly> = { // that no generic exit — the data path, and the compliance ledger's CRUD // mirror that honours the same flag — carries it, and each is here because a // better-auth route reads it back OFF a row its storage adapter returned - // (traced in the installed better-auth / @better-auth/* dist, 1.7.3): + // (traced in the then-installed better-auth / @better-auth/* dist, 1.7.3; + // ⚠️ [#25096] NOT re-stamped for 1.7.12 — see the `identifier` note below): // // - `sys_jwks.private_key` — the jwt plugin's key read (`findMany`, no // projection) feeds signing. MEASURED before this row existed: the flag @@ -206,6 +207,11 @@ const READBACK_FIELDS: Readonly> = { // adapter's `consumeOne` re-attaches through this table too). // `required: true`. `identifier` is deliberately absent: no flow reads it // back off a row — it is only ever the lookup key. + // ⚠️ [#25096] That census is wrong, on 1.7.3 and on 1.7.12 alike: + // `@better-auth/sso`'s `/sso/verify-domain` builds the TXT record it + // expects from `identifier` read back off the row, so on this store it + // expects `undefined=TOKEN`. Measured and reported on #25096; nothing + // here is changed by that card. // - `sys_two_factor.secret` (`required: true`) and `.backup_codes` (empty // until generated) — TOTP and backup-code verification read both off the // enrolment row. diff --git a/packages/plugins/plugin-auth/src/invite-role-not-found-code.ts b/packages/plugins/plugin-auth/src/invite-role-not-found-code.ts index cb8a65dc5ed..71be2e6f557 100644 --- a/packages/plugins/plugin-auth/src/invite-role-not-found-code.ts +++ b/packages/plugins/plugin-auth/src/invite-role-not-found-code.ts @@ -12,8 +12,8 @@ * * new APIError("BAD_REQUEST", { message: `${ROLE_NOT_FOUND}: ${unknownRoles}` }) * - * (`dist/plugins/organization/routes/crud-invites.mjs`, measured against the - * installed better-auth `1.7.3`). Its sibling `update-member-role` + * (`dist/plugins/organization/routes/crud-invites.mjs`, measured against + * better-auth `1.7.12`, re-measured 2026-10-21 for #25096). Its sibling `update-member-role` * (`routes/crud-members.mjs`) throws the SAME refusal with * `code: ROLE_NOT_FOUND` beside the identical message — so one vendor * condition reached the wire coded on one door and uncoded on the other. The diff --git a/packages/plugins/plugin-auth/src/list-user-invitations-verification.ts b/packages/plugins/plugin-auth/src/list-user-invitations-verification.ts index a761e4ed63d..a8d7c389296 100644 --- a/packages/plugins/plugin-auth/src/list-user-invitations-verification.ts +++ b/packages/plugins/plugin-auth/src/list-user-invitations-verification.ts @@ -7,9 +7,9 @@ * * ## The defect, and where it is minted * - * Not here: it comes out of the pinned vendor. Re-measured 2026-09-11 against - * the installed better-auth `1.7.3` (unchanged from the `1.7.2` reading this - * replaces), `dist/plugins/organization/routes/crud-invites.mjs`: + * Not here: it comes out of the pinned vendor. Re-measured 2026-10-21 for + * #25096 against better-auth `1.7.12` (unchanged since the `1.7.2` reading), + * `dist/plugins/organization/routes/crud-invites.mjs`: * the three id-addressed routes ask * `shouldRequireVerifiedEmailForInvitationIdAction({ organizationOptions, … })`, * whose first line is diff --git a/packages/plugins/plugin-auth/src/organization-delete.ts b/packages/plugins/plugin-auth/src/organization-delete.ts index 8aff7beba35..5dd4c47fad9 100644 --- a/packages/plugins/plugin-auth/src/organization-delete.ts +++ b/packages/plugins/plugin-auth/src/organization-delete.ts @@ -7,7 +7,7 @@ * * ## What better-auth does, and what it leaves * - * `POST /organization/delete` (better-auth 1.7.3, + * `POST /organization/delete` (better-auth 1.7.12, re-read 2026-10-21 for #25096, * `plugins/organization/routes/crud-org.mjs`) authorizes the caller, clears the * caller's active organization, calls `organizationHooks.beforeDeleteOrganization`, * and then `adapter.deleteOrganization`, which deletes `member`, then diff --git a/packages/plugins/plugin-auth/src/session-envelope-completion.ts b/packages/plugins/plugin-auth/src/session-envelope-completion.ts index e701c4763ee..dd8651ded2e 100644 --- a/packages/plugins/plugin-auth/src/session-envelope-completion.ts +++ b/packages/plugins/plugin-auth/src/session-envelope-completion.ts @@ -18,12 +18,12 @@ * `secondaryStorage` — see `auth-manager.ts`'s `deleteUser` note), and * `internalAdapter.createSession` is `await`-ed to completion — including the * database write — before the sign-in/sign-up ENDPOINT returns - * `{ token, user }` at all (`better-auth@1.7.3` - * `dist/db/internal-adapter.mjs:247-319`). So by the time this repo's global + * `{ token, user }` at all (`better-auth@1.7.12`, re-read 2026-10-21 for #25096, + * `dist/db/internal-adapter.mjs:259-332`). So by the time this repo's global * `after` hook runs (`ctx.context.returned` already holds the endpoint's * answer), the row the token names is not merely creatABLE — it is already * committed. Reading it back is exactly what `/get-session` already does - * (`internalAdapter.findSession`, `dist/db/internal-adapter.mjs:321-358`), so + * (`internalAdapter.findSession`, `dist/db/internal-adapter.mjs:333-370`), so * this produces the SAME shape `data.session` already carries on that route * (`auth-get-session-envelope.test.ts`), not a second declaration of it. * diff --git a/packages/plugins/plugin-auth/src/session-read-failure-answer.test.ts b/packages/plugins/plugin-auth/src/session-read-failure-answer.test.ts new file mode 100644 index 00000000000..79f68d2d3ce --- /dev/null +++ b/packages/plugins/plugin-auth/src/session-read-failure-answer.test.ts @@ -0,0 +1,157 @@ +// Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. + +/** + * [#25096] A session lookup the store cannot answer is a FAILURE, never a + * signed-out caller. + * + * plugin-auth mounts better-auth's `customSession` whenever a data engine is + * configured, so `GET /get-session` and every in-process `api.getSession` run + * its override. Up to 1.7.7 that override caught whatever the inner session + * read threw and answered `null`, so a store outage read exactly like "nobody + * is signed in": over HTTP `anonymous-session-refusal.ts` then turned that + * `null` into its 401 `UNAUTHENTICATED`, telling a signed-in browser to sign in + * again. From 1.7.8 (better-auth/better-auth#11391) the override lets the + * read's error through, so the store failure reaches the caller as + * better-auth's own 500 `FAILED_TO_GET_SESSION`, which that seam passes + * through untouched (it converts a `200` + `null` only). + * + * That is the right answer for this platform (AGENTS.md, "Absence must be + * loud" and the degradation-log-level rule): a failure the caller is told + * about is not a silent degradation, and the browser can tell "retry later" + * from "sign in again". The in-process callers that want the old reading keep + * it on purpose: `resolveSessionData` (runtime) and `resolveRequestExecutionContext` + * (core) catch the throw themselves and treat the request as anonymous. + * + * Real stack: `ObjectQL` over `@objectstack/driver-sql` + better-sqlite3, the + * objects from this plugin's manifest and a real `AuthManager`. The fault is + * injected at the engine, on the `sys_session` reads alone, after the sign-up + * wrote the session, so every other read the request makes is the real one. + * + * Pinned: + * - the store failure answers 500 `FAILED_TO_GET_SESSION` over HTTP and + * rejects the in-process read, and it does not clear the session cookie; + * - the two controls the failure must stay distinguishable from: the healthy + * store answers the session, and a token the store does not hold is signed + * out (401 `UNAUTHENTICATED` over HTTP, `null` in process). + */ + +import { describe, it, expect, afterEach, vi } from 'vitest'; +import { ObjectQL } from '@objectstack/objectql'; +import { SqlDriver } from '@objectstack/driver-sql'; +import { AuthManager } from './auth-manager.js'; +import { authIdentityObjects } from './manifest.js'; + +const BASE = 'http://localhost:3000'; +const AUTH = `${BASE}/api/v1/auth`; +const SECRET = 'test-secret-at-least-32-chars-long-25096'; +const PASSWORD = 'S3cure!Passw0rd-25096'; +const SESSION_OBJECT = 'sys_session'; + +const engines: ObjectQL[] = []; +afterEach(async () => { + vi.restoreAllMocks(); + while (engines.length) { + try { await engines.pop()!.destroy(); } catch { /* noop */ } + } +}); + +async function bootEngine(): Promise { + const engine = new ObjectQL(); + engines.push(engine); + engine.registerDriver(new SqlDriver({ client: 'better-sqlite3', connection: { filename: ':memory:' }, useNullAsDefault: true }), true); + await engine.init(); + for (const object of authIdentityObjects) engine.registry.registerObject(object as never, '@objectstack/plugin-auth'); + await engine.syncSchemas(); + return engine; +} + +const cookieFrom = (response: Response): string => + (response.headers.getSetCookie?.() ?? [response.headers.get('set-cookie') ?? '']) + .map((c) => c.split(';')[0]) + .filter(Boolean) + .join('; '); + +const getSession = (manager: AuthManager, cookie: string) => + manager.handleRequest(new Request(`${AUTH}/get-session`, { headers: { cookie } })); + +/** A signed-up user's session cookie, on a manager over a real engine. */ +async function signedIn(): Promise<{ engine: ObjectQL; manager: AuthManager; cookie: string }> { + const engine = await bootEngine(); + const manager = new AuthManager({ secret: SECRET, baseUrl: BASE, dataEngine: engine as never } as never); + const signedUp = await manager.handleRequest(new Request(`${AUTH}/sign-up/email`, { + method: 'POST', + headers: { 'Content-Type': 'application/json', origin: BASE }, + body: JSON.stringify({ email: 'reader@example.com', password: PASSWORD, name: 'Reader' }), + })); + expect(signedUp.status, await signedUp.clone().text()).toBe(200); + const cookie = cookieFrom(signedUp); + expect(cookie, 'the sign-up set a session cookie').toMatch(/session_token=/); + return { engine, manager, cookie }; +} + +/** Every engine read of `sys_session` throws from here on; every other read is the real one. */ +function failSessionStore(engine: ObjectQL): { attempts: () => number } { + let attempts = 0; + const target = engine as unknown as Record<'find' | 'findOne', (object: string, ...rest: unknown[]) => Promise>; + for (const method of ['find', 'findOne'] as const) { + const real = target[method].bind(engine); + vi.spyOn(target, method).mockImplementation(async (object: string, ...rest: unknown[]) => { + if (object === SESSION_OBJECT) { + attempts += 1; + throw new Error('session store unavailable (injected)'); + } + return real(object, ...rest); + }); + } + return { attempts: () => attempts }; +} + +describe('[#25096] a session lookup the store cannot answer is a failure, never a signed-out caller', () => { + it('CONTROL: the healthy store answers the signed-in session', async () => { + const { manager, cookie } = await signedIn(); + const res = await getSession(manager, cookie); + expect(res.status).toBe(200); + const body = (await res.json()) as { user?: { email?: string } } | null; + expect(body?.user?.email).toBe('reader@example.com'); + }); + + it('CONTROL: a token the store does not hold is signed out, 401 UNAUTHENTICATED over HTTP and null in process', async () => { + const { manager } = await signedIn(); + const stranger = 'better-auth.session_token=not-a-session-the-store-holds.sig'; + const res = await getSession(manager, stranger); + const text = await res.clone().text(); + expect(res.status, text).toBe(401); + expect(JSON.stringify(JSON.parse(text))).toContain('UNAUTHENTICATED'); + const api = await manager.getApi(); + expect(await api.getSession({ headers: new Headers({ cookie: stranger }) } as never)).toBeNull(); + }); + + it('over HTTP: the store failure answers 500 FAILED_TO_GET_SESSION and keeps the session cookie', async () => { + vi.spyOn(console, 'error').mockImplementation(() => {}); + const { engine, manager, cookie } = await signedIn(); + const fault = failSessionStore(engine); + + const res = await getSession(manager, cookie); + + expect(fault.attempts(), 'the request really reached the session store').toBeGreaterThan(0); + const text = await res.clone().text(); + expect(res.status, text).toBe(500); + expect((JSON.parse(text) as { code?: string }).code).toBe('FAILED_TO_GET_SESSION'); + // Nothing tells the browser to drop its credential: the session still + // exists, the store just could not read it. + const cleared = (res.headers.getSetCookie?.() ?? []).filter((c) => /session_token=;|session_token=\s*;|Max-Age=0/i.test(c)); + expect(cleared).toEqual([]); + }); + + it('in process: the store failure rejects `api.getSession` instead of resolving null', async () => { + vi.spyOn(console, 'error').mockImplementation(() => {}); + const { engine, manager, cookie } = await signedIn(); + const api = await manager.getApi(); + const fault = failSessionStore(engine); + + const read = api.getSession({ headers: new Headers({ cookie }) } as never); + + await expect(read).rejects.toMatchObject({ statusCode: 500, body: { code: 'FAILED_TO_GET_SESSION' } }); + expect(fault.attempts()).toBeGreaterThan(0); + }); +}); diff --git a/packages/plugins/plugin-auth/src/two-factor-totp-issuer.test.ts b/packages/plugins/plugin-auth/src/two-factor-totp-issuer.test.ts index 0dbb461b5a7..49bfa8c2522 100644 --- a/packages/plugins/plugin-auth/src/two-factor-totp-issuer.test.ts +++ b/packages/plugins/plugin-auth/src/two-factor-totp-issuer.test.ts @@ -8,8 +8,9 @@ // `appName`, so better-auth fell back to its own name, and every user's // authenticator app listed the account under "Better Auth". // -// What better-auth 1.7.3 does with the name, read off its dist rather than its -// docs, decides what these pins have to cover: +// What better-auth 1.7.12 does with the name (re-read 2026-10-21 for #25096, +// unchanged since 1.7.3), read off its dist rather than its docs, decides +// what these pins have to cover: // - the config's `appName` is read ONCE, into the context's `appName` // (`context/create-context.mjs`, unset ⇒ "Better Auth"); // - that context value is read in exactly TWO places, both otpauth URIs: diff --git a/packages/plugins/plugin-auth/src/verification-reservation-single-use.test.ts b/packages/plugins/plugin-auth/src/verification-reservation-single-use.test.ts new file mode 100644 index 00000000000..ee125330d0b --- /dev/null +++ b/packages/plugins/plugin-auth/src/verification-reservation-single-use.test.ts @@ -0,0 +1,109 @@ +// Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. + +/** + * [#25096] The ObjectQL adapter keeps the primary key better-auth forces on a + * single-use reservation, so a replayed reservation is refused. + * + * better-auth's replay checks (DPoP proof `jti`s, `private_key_jwt` client + * assertions, SAML assertion ids, SIWE nonces) all go through + * `internalAdapter.reserveVerificationValue`. It inserts a `verification` row + * whose `id` is derived from the guarded value (SHA-256 of + * `reserve:IDENTIFIER`), with `forceAllowId: true`, and reads a failed insert + * as "already taken" only when a row with THAT id exists. So the whole check + * rests on one property of the adapter underneath: the forced id must land as + * the row's primary key. An adapter or engine that swaps in an id of its own + * lets every insert succeed, and every replay with it. + * + * 1.7.8 (better-auth/better-auth#11625) fixed that for `generateId: "uuid"`, + * where the id field used to replace the non-UUID digest. plugin-auth sets no + * `generateId`, so better-auth's own generator runs and the forced digest is + * passed through as base64url (`encodeDeterministicId`). What this file pins is + * the half better-auth cannot see: that the ObjectQL adapter, the engine and + * the SQL driver keep it. + * + * Real stack: `ObjectQL` over `@objectstack/driver-sql` + better-sqlite3, the + * objects from this plugin's manifest and a real `AuthManager`; the + * reservation is better-auth's own, read off the instance's `$context`. + */ + +import { describe, it, expect, afterEach } from 'vitest'; +import { createHash } from 'node:crypto'; +import { ObjectQL } from '@objectstack/objectql'; +import { SqlDriver } from '@objectstack/driver-sql'; +import { AuthManager } from './auth-manager.js'; +import { authIdentityObjects } from './manifest.js'; + +const BASE = 'http://localhost:3000'; +const SECRET = 'test-secret-at-least-32-chars-long-25096'; +const VERIFICATION_OBJECT = 'sys_verification'; + +type Row = Record; + +interface ReservingContext { + internalAdapter: { + reserveVerificationValue(data: { identifier: string; value: string; expiresAt: Date }): Promise; + }; +} + +const engines: ObjectQL[] = []; +afterEach(async () => { + while (engines.length) { + try { await engines.pop()!.destroy(); } catch { /* noop */ } + } +}); + +async function boot(): Promise<{ engine: ObjectQL; context: ReservingContext }> { + const engine = new ObjectQL(); + engines.push(engine); + engine.registerDriver(new SqlDriver({ client: 'better-sqlite3', connection: { filename: ':memory:' }, useNullAsDefault: true }), true); + await engine.init(); + for (const object of authIdentityObjects) engine.registry.registerObject(object as never, '@objectstack/plugin-auth'); + await engine.syncSchemas(); + const manager = new AuthManager({ secret: SECRET, baseUrl: BASE, dataEngine: engine as never } as never); + const auth = (await manager.getAuthInstance()) as unknown as { $context: Promise }; + return { engine, context: await auth.$context }; +} + +/** Rows at DRIVER level, below the engine, with the identifier the reservation stored. */ +async function reservationRows(engine: ObjectQL, identifier: string): Promise { + const driver = (engine as unknown as { getDriver(o: string): { find(o: string, q: unknown): Promise } }) + .getDriver(VERIFICATION_OBJECT); + const found = await driver.find(VERIFICATION_OBJECT, { where: { identifier } }); + return (Array.isArray(found) ? found : [found]).filter(Boolean) as Row[]; +} + +/** better-auth's deterministic reservation id without a `generateId` strategy: base64url SHA-256, unpadded. */ +const reservationId = (identifier: string): string => + createHash('sha256').update(`reserve:${identifier}`).digest('base64url'); + +const expiresAt = () => new Date(Date.now() + 5 * 60_000); + +describe('[#25096] a single-use reservation refuses its replay through the ObjectQL adapter', () => { + it('the first reservation wins and is stored under the id better-auth forced', async () => { + const { engine, context } = await boot(); + const identifier = 'replay-probe:first'; + + expect(await context.internalAdapter.reserveVerificationValue({ identifier, value: 'v', expiresAt: expiresAt() })).toBe(true); + + const rows = await reservationRows(engine, identifier); + expect(rows).toHaveLength(1); + expect(rows[0]!.id, 'the engine kept the forced primary key').toBe(reservationId(identifier)); + }); + + it('the replay of the same value is refused, and leaves one row', async () => { + const { engine, context } = await boot(); + const identifier = 'replay-probe:replayed'; + + expect(await context.internalAdapter.reserveVerificationValue({ identifier, value: 'v', expiresAt: expiresAt() })).toBe(true); + expect(await context.internalAdapter.reserveVerificationValue({ identifier, value: 'v', expiresAt: expiresAt() })).toBe(false); + + expect(await reservationRows(engine, identifier)).toHaveLength(1); + }); + + it('CONTROL: a different value is its own reservation and wins', async () => { + const { context } = await boot(); + + expect(await context.internalAdapter.reserveVerificationValue({ identifier: 'replay-probe:a', value: 'v', expiresAt: expiresAt() })).toBe(true); + expect(await context.internalAdapter.reserveVerificationValue({ identifier: 'replay-probe:b', value: 'v', expiresAt: expiresAt() })).toBe(true); + }); +}); diff --git a/packages/services/service-datasource/src/__tests__/sqlite-driver-fallback-file-open-failure.test.ts b/packages/services/service-datasource/src/__tests__/sqlite-driver-fallback-file-open-failure.test.ts index 84ce07ca50c..44afd66b44c 100644 --- a/packages/services/service-datasource/src/__tests__/sqlite-driver-fallback-file-open-failure.test.ts +++ b/packages/services/service-datasource/src/__tests__/sqlite-driver-fallback-file-open-failure.test.ts @@ -18,14 +18,15 @@ * It is faked at the seam where `better-sqlite3` loads its addon: the knex * better-sqlite3 client's `acquireRawConnection` (`new Database(file)`). * The fake throws a REAL load error: Node's own `ERR_DLOPEN_FAILED`, or the - * `bindings` package's own "not built" error. + * `MODULE_NOT_FOUND` better-sqlite3's own loader meets when its addon was + * never built. */ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; import { existsSync, mkdirSync, mkdtempSync, rmSync, writeFileSync } from 'node:fs'; import { createRequire } from 'node:module'; import { tmpdir } from 'node:os'; -import { dirname, join } from 'node:path'; +import { join } from 'node:path'; import { SqlDriver } from '@objectstack/driver-sql'; import { NATIVE_SQLITE_WASM_FALLBACK_WARNING, @@ -87,21 +88,24 @@ function realDlopenFailure(): Error { } /** - * The real error `better-sqlite3` throws when its addon was never built: the - * `bindings` package it loads the addon through, asked for an addon that is - * not there. It carries no code. + * The real error `better-sqlite3` throws when its addon was never built. Its + * 13.x loader (`lib/binding.js`) takes no helper package: with no prebuilt + * binary for the platform it `require()`s `build/Release/better_sqlite3.node` + * under its own module root, and Node answers `MODULE_NOT_FOUND`. Produced + * here by that same require, made from the installed package, against a + * module root that was never built. */ function realNotBuiltFailure(): Error { const fromHere = createRequire(import.meta.url); const fromDriver = createRequire(fromHere.resolve('@objectstack/driver-sql')); const betterSqlite3 = fromDriver.resolve('better-sqlite3/package.json'); - const bindings = createRequire(betterSqlite3)('bindings'); + const neverBuilt = join(dir, 'never-built', 'build', 'Release', 'better_sqlite3.node'); try { - bindings({ bindings: 'os_24950_never_built.node', module_root: dirname(betterSqlite3) }); + createRequire(betterSqlite3)(neverBuilt); } catch (error) { return error as Error; } - throw new Error('bindings located an addon that was never built'); + throw new Error('required an addon that was never built'); } /** @@ -170,9 +174,9 @@ describe('resolveSqliteDriver in development: a native addon that cannot load st expect(await resolved.driver.execute('SELECT 1 AS one')).toEqual([{ one: 1 }]); }); - it('an addon that was never built (no code) steps down to wasm SQLite', async () => { + it('an addon that was never built (MODULE_NOT_FOUND) steps down to wasm SQLite', async () => { const loadError = realNotBuiltFailure(); - expect((loadError as any).code).toBeUndefined(); + expect((loadError as any).code).toBe('MODULE_NOT_FOUND'); await failNativeAddonLoad(loadError); const resolved = await resolveDev(join(dir, 'dev.db')); diff --git a/packages/services/service-datasource/src/sqlite-driver-fallback.ts b/packages/services/service-datasource/src/sqlite-driver-fallback.ts index 6e42085d451..cd3fd64524f 100644 --- a/packages/services/service-datasource/src/sqlite-driver-fallback.ts +++ b/packages/services/service-datasource/src/sqlite-driver-fallback.ts @@ -39,9 +39,10 @@ * * - **The addon cannot load — steps down.** An ABI mismatch (Node's * `ERR_DLOPEN_FAILED`, a `NODE_MODULE_VERSION` message), an addon that was - * never built (`bindings`' "Could not locate the bindings file", which has - * no code), or a missing `better-sqlite3` package. Today's path, - * unchanged. + * never built (better-sqlite3 13's loader `require()`s the absent + * `build/Release/better_sqlite3.node`, and Node answers + * `MODULE_NOT_FOUND`), or a missing `better-sqlite3` package. Today's + * path, unchanged. * - **The database FILE cannot be opened or created, or is not a database — * re-thrown, as in production.** A path under a regular file, a parent * directory the driver cannot make, a permission refusal, a directory where @@ -164,8 +165,9 @@ function isEphemeralFilename(filename: string): boolean { * An addon that cannot load never carries any of these. It surfaces at the * probe's `SELECT 1`, whose failure `SqlDriver.execute()` hands back as * `DATABASE_ERROR`, with the load error as its `cause`: Node's - * `ERR_DLOPEN_FAILED`, `MODULE_NOT_FOUND`, or no code at all (`bindings`' - * "Could not locate the bindings file"). A missing `better-sqlite3` package + * `ERR_DLOPEN_FAILED`, or `MODULE_NOT_FOUND` (an addon that was never built: + * better-sqlite3 13's loader `require()`s the absent + * `build/Release/better_sqlite3.node`). A missing `better-sqlite3` package * fails at construction with knex's install hint, which has no code. None of * these matches. * diff --git a/packages/spec/src/identity/organization.zod.ts b/packages/spec/src/identity/organization.zod.ts index da528144b87..8e602b1d261 100644 --- a/packages/spec/src/identity/organization.zod.ts +++ b/packages/spec/src/identity/organization.zod.ts @@ -92,7 +92,9 @@ export const OrganizationSchema = lazySchema(() => z.object({ * produced by better-auth's own serializer and its documented shape carries * no `updatedAt`, then for those routes the spec aligns to the documented * wire (`updatedAt` optional there)」. Both halves measured against the - * installed better-auth 1.7.3, so fallback A applies: + * installed better-auth 1.7.3 (re-measured on 1.7.12 for #25096: the + * organization plugin schema is byte-identical and `transformOutput` still + * projects declared fields only), so fallback A applies: * * - **The serializer is the vendor's.** The `organization/*` routes are * better-auth's own endpoints, mounted through plugin-auth's single diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index eb8b5fcda52..9edeba45548 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -11,17 +11,17 @@ overrides: form-data@<5.0.0: '>=4.0.6' undici@>=7.23.0 <8.0.0: ^7.29.1 undici@>=8.1.0 <9.0.0: ^8.10.2 - better-auth@<2.0.0: 1.7.3 - '@better-auth/core@<2.0.0': 1.7.3 - '@better-auth/scim@<2.0.0': 1.7.3 - '@better-auth/oauth-provider@<2.0.0': 1.7.3 - '@better-auth/sso@<2.0.0': 1.7.3 - '@better-auth/drizzle-adapter@<2.0.0': 1.7.3 - '@better-auth/kysely-adapter@<2.0.0': 1.7.3 - '@better-auth/memory-adapter@<2.0.0': 1.7.3 - '@better-auth/mongo-adapter@<2.0.0': 1.7.3 - '@better-auth/prisma-adapter@<2.0.0': 1.7.3 - '@better-auth/telemetry@<2.0.0': 1.7.3 + better-auth@<2.0.0: 1.7.12 + '@better-auth/core@<2.0.0': 1.7.12 + '@better-auth/scim@<2.0.0': 1.7.12 + '@better-auth/oauth-provider@<2.0.0': 1.7.12 + '@better-auth/sso@<2.0.0': 1.7.12 + '@better-auth/drizzle-adapter@<2.0.0': 1.7.12 + '@better-auth/kysely-adapter@<2.0.0': 1.7.12 + '@better-auth/memory-adapter@<2.0.0': 1.7.12 + '@better-auth/mongo-adapter@<2.0.0': 1.7.12 + '@better-auth/prisma-adapter@<2.0.0': 1.7.12 + '@better-auth/telemetry@<2.0.0': 1.7.12 uuid@<12.0.0: ^11.1.1 postcss@<9.0.0: ^8.5.10 cookie@<0.8.0: ^0.7.0 @@ -405,7 +405,7 @@ importers: version: 6.0.3 vitest: specifier: ^4.1.11 - version: 4.1.11(@opentelemetry/api@1.9.1)(@types/node@26.6.3)(@vitest/coverage-v8@4.1.11)(happy-dom@20.10.2)(jsdom@30.1.1(@noble/hashes@2.4.0))(msw@2.14.6(@types/node@26.6.3)(typescript@6.0.3))(vite@8.3.4(@types/node@26.6.3)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.15(patch_hash=4d1d35da1809be2a945519cb26890e48107810b9b66c6913a6a89abb5ad6a1e6))(yaml@2.9.1)) + version: 4.1.11(@opentelemetry/api@1.9.1)(@types/node@26.6.3)(@vitest/coverage-v8@4.1.11)(happy-dom@20.10.2)(jsdom@30.1.1(@noble/hashes@2.4.0))(msw@2.14.6(@types/node@26.6.3)(typescript@6.0.3))(vite@8.3.4(@types/node@26.6.3)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.23.15(patch_hash=4d1d35da1809be2a945519cb26890e48107810b9b66c6913a6a89abb5ad6a1e6))(yaml@2.9.1)) packages/apps/setup: dependencies: @@ -427,7 +427,7 @@ importers: version: 6.0.3 vitest: specifier: ^4.1.11 - version: 4.1.11(@opentelemetry/api@1.9.1)(@types/node@26.6.3)(@vitest/coverage-v8@4.1.11)(happy-dom@20.10.2)(jsdom@30.1.1(@noble/hashes@2.4.0))(msw@2.14.6(@types/node@26.6.3)(typescript@6.0.3))(vite@8.3.4(@types/node@26.6.3)(esbuild@0.28.1)(jiti@2.7.0)(tsx@4.23.15(patch_hash=4d1d35da1809be2a945519cb26890e48107810b9b66c6913a6a89abb5ad6a1e6))(yaml@2.9.1)) + version: 4.1.11(@opentelemetry/api@1.9.1)(@types/node@26.6.3)(@vitest/coverage-v8@4.1.11)(happy-dom@20.10.2)(jsdom@30.1.1(@noble/hashes@2.4.0))(msw@2.14.6(@types/node@26.6.3)(typescript@6.0.3))(vite@8.3.4(@types/node@26.6.3)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.15(patch_hash=4d1d35da1809be2a945519cb26890e48107810b9b66c6913a6a89abb5ad6a1e6))(yaml@2.9.1)) packages/apps/studio: dependencies: @@ -1692,17 +1692,17 @@ importers: packages/plugins/plugin-auth: dependencies: '@better-auth/core': - specifier: 1.7.3 - version: 1.7.3(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@cloudflare/workers-types@4.20260520.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.5))(jose@6.2.12)(kysely@0.29.4)(nanostores@1.4.0) + specifier: 1.7.12 + version: 1.7.12(@better-auth/utils@0.5.0)(@better-fetch/fetch@1.3.2)(@opentelemetry/api@1.9.1)(better-call@1.4.4(zod@4.6.5))(jose@6.2.12)(kysely@0.29.4)(nanostores@1.4.0) '@better-auth/oauth-provider': - specifier: 1.7.3 - version: 1.7.3(@better-auth/core@1.7.3(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@cloudflare/workers-types@4.20260520.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.5))(jose@6.2.12)(kysely@0.29.4)(nanostores@1.4.0))(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(better-auth@1.7.3(@cloudflare/workers-types@4.20260520.1)(@opentelemetry/api@1.9.1)(better-sqlite3@12.11.1)(mongodb@7.7.0(socks@2.8.9))(mysql2@3.24.4(@types/node@26.6.3))(next@16.3.8(@opentelemetry/api@1.9.1)(@playwright/test@1.63.0)(@types/node@26.6.3)(react-dom@19.3.0(react@19.3.0))(react@19.3.0))(pg@8.23.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(svelte@5.57.1(@typescript-eslint/types@8.70.1))(vitest@4.1.11))(better-call@1.4.0(zod@4.6.5)) + specifier: 1.7.12 + version: 1.7.12(@better-auth/core@1.7.12(@better-auth/utils@0.5.0)(@better-fetch/fetch@1.3.2)(@opentelemetry/api@1.9.1)(better-call@1.4.4(zod@4.6.5))(jose@6.2.12)(kysely@0.29.4)(nanostores@1.4.0))(@better-auth/utils@0.5.0)(@better-fetch/fetch@1.3.2)(better-auth@1.7.12(@opentelemetry/api@1.9.1)(mongodb@7.7.0(socks@2.8.9))(mysql2@3.24.4(@types/node@26.6.3))(next@16.3.8(@opentelemetry/api@1.9.1)(@playwright/test@1.63.0)(@types/node@26.6.3)(react-dom@19.3.0(react@19.3.0))(react@19.3.0))(pg@8.23.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(svelte@5.57.1(@typescript-eslint/types@8.70.1))(vitest@4.1.11))(better-call@1.4.4(zod@4.6.5)) '@better-auth/scim': - specifier: 1.7.3 - version: 1.7.3(@better-auth/core@1.7.3(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@cloudflare/workers-types@4.20260520.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.5))(jose@6.2.12)(kysely@0.29.4)(nanostores@1.4.0))(@better-auth/utils@0.4.2)(better-auth@1.7.3(@cloudflare/workers-types@4.20260520.1)(@opentelemetry/api@1.9.1)(better-sqlite3@12.11.1)(mongodb@7.7.0(socks@2.8.9))(mysql2@3.24.4(@types/node@26.6.3))(next@16.3.8(@opentelemetry/api@1.9.1)(@playwright/test@1.63.0)(@types/node@26.6.3)(react-dom@19.3.0(react@19.3.0))(react@19.3.0))(pg@8.23.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(svelte@5.57.1(@typescript-eslint/types@8.70.1))(vitest@4.1.11))(better-call@1.4.0(zod@4.6.5)) + specifier: 1.7.12 + version: 1.7.12(@better-auth/core@1.7.12(@better-auth/utils@0.5.0)(@better-fetch/fetch@1.3.2)(@opentelemetry/api@1.9.1)(better-call@1.4.4(zod@4.6.5))(jose@6.2.12)(kysely@0.29.4)(nanostores@1.4.0))(@better-auth/utils@0.5.0)(better-auth@1.7.12(@opentelemetry/api@1.9.1)(mongodb@7.7.0(socks@2.8.9))(mysql2@3.24.4(@types/node@26.6.3))(next@16.3.8(@opentelemetry/api@1.9.1)(@playwright/test@1.63.0)(@types/node@26.6.3)(react-dom@19.3.0(react@19.3.0))(react@19.3.0))(pg@8.23.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(svelte@5.57.1(@typescript-eslint/types@8.70.1))(vitest@4.1.11))(better-call@1.4.4(zod@4.6.5)) '@better-auth/sso': - specifier: 1.7.3 - version: 1.7.3(@better-auth/core@1.7.3(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@cloudflare/workers-types@4.20260520.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.5))(jose@6.2.12)(kysely@0.29.4)(nanostores@1.4.0))(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(better-auth@1.7.3(@cloudflare/workers-types@4.20260520.1)(@opentelemetry/api@1.9.1)(better-sqlite3@12.11.1)(mongodb@7.7.0(socks@2.8.9))(mysql2@3.24.4(@types/node@26.6.3))(next@16.3.8(@opentelemetry/api@1.9.1)(@playwright/test@1.63.0)(@types/node@26.6.3)(react-dom@19.3.0(react@19.3.0))(react@19.3.0))(pg@8.23.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(svelte@5.57.1(@typescript-eslint/types@8.70.1))(vitest@4.1.11))(better-call@1.4.0(zod@4.6.5)) + specifier: 1.7.12 + version: 1.7.12(@better-auth/core@1.7.12(@better-auth/utils@0.5.0)(@better-fetch/fetch@1.3.2)(@opentelemetry/api@1.9.1)(better-call@1.4.4(zod@4.6.5))(jose@6.2.12)(kysely@0.29.4)(nanostores@1.4.0))(@better-auth/utils@0.5.0)(@better-fetch/fetch@1.3.2)(better-auth@1.7.12(@opentelemetry/api@1.9.1)(mongodb@7.7.0(socks@2.8.9))(mysql2@3.24.4(@types/node@26.6.3))(next@16.3.8(@opentelemetry/api@1.9.1)(@playwright/test@1.63.0)(@types/node@26.6.3)(react-dom@19.3.0(react@19.3.0))(react@19.3.0))(pg@8.23.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(svelte@5.57.1(@typescript-eslint/types@8.70.1))(vitest@4.1.11))(better-call@1.4.4(zod@4.6.5)) '@noble/hashes': specifier: ^2.4.0 version: 2.4.0 @@ -1725,8 +1725,8 @@ importers: specifier: workspace:* version: link:../../types better-auth: - specifier: 1.7.3 - version: 1.7.3(@cloudflare/workers-types@4.20260520.1)(@opentelemetry/api@1.9.1)(better-sqlite3@12.11.1)(mongodb@7.7.0(socks@2.8.9))(mysql2@3.24.4(@types/node@26.6.3))(next@16.3.8(@opentelemetry/api@1.9.1)(@playwright/test@1.63.0)(@types/node@26.6.3)(react-dom@19.3.0(react@19.3.0))(react@19.3.0))(pg@8.23.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(svelte@5.57.1(@typescript-eslint/types@8.70.1))(vitest@4.1.11) + specifier: 1.7.12 + version: 1.7.12(@opentelemetry/api@1.9.1)(mongodb@7.7.0(socks@2.8.9))(mysql2@3.24.4(@types/node@26.6.3))(next@16.3.8(@opentelemetry/api@1.9.1)(@playwright/test@1.63.0)(@types/node@26.6.3)(react-dom@19.3.0(react@19.3.0))(react@19.3.0))(pg@8.23.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(svelte@5.57.1(@typescript-eslint/types@8.70.1))(vitest@4.1.11) jose: specifier: ^6.2.12 version: 6.2.12 @@ -3510,73 +3510,70 @@ packages: resolution: {integrity: sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==} engines: {node: '>=18'} - '@better-auth/core@1.7.3': - resolution: {integrity: sha512-JdP7lOkyE83jgjn7RilJj1XvZ7n2JjRsErKJuaXchjyuNo6cf1iVd3GtbhAtiUyJJkWdk8yL+LaUBKT80H0zLA==} + '@better-auth/core@1.7.12': + resolution: {integrity: sha512-SUStBGHJ13KnSO6+7U/1DSlfuOtln4jtOrFZqzQtxZVHZIrAoMjwHNGitlF+s7hvKbuC3Z14xjnqfLLqIqGfxw==} peerDependencies: - '@better-auth/utils': 0.4.2 - '@better-fetch/fetch': 1.3.1 - '@cloudflare/workers-types': '>=4' + '@better-auth/utils': ^0.4.2 || ^0.5.0 + '@better-fetch/fetch': 1.3.2 '@opentelemetry/api': ^1.9.0 - better-call: 1.4.0 + better-call: 1.4.4 jose: ^6.1.0 kysely: ^0.28.5 || ^0.29.0 nanostores: ^1.0.1 peerDependenciesMeta: - '@cloudflare/workers-types': - optional: true '@opentelemetry/api': optional: true - '@better-auth/drizzle-adapter@1.7.3': - resolution: {integrity: sha512-S+nQRlxbUhkR43LrSv8c98ZvOvmv3nrtOnHkiZXkdDkr60PWp7maC2cqgzZ2C9exCC1a+4TugJlx2jRL+r+/9A==} + '@better-auth/drizzle-adapter@1.7.12': + resolution: {integrity: sha512-Qzoyuf05aK01Pc0k3EXv8Xj3XCT2m2dCWc5HoB7x+xX6N3Pm2eQsca+UIArsJcbuNEWWP3L51oIebnBoHJ5DTw==} peerDependencies: - '@better-auth/core': 1.7.3 - '@better-auth/utils': 0.4.2 + '@better-auth/core': 1.7.12 + '@better-auth/utils': ^0.4.2 || ^0.5.0 drizzle-orm: ^0.45.2 || >=1.0.0-rc.1 <2.0.0 peerDependenciesMeta: drizzle-orm: optional: true - '@better-auth/kysely-adapter@1.7.3': - resolution: {integrity: sha512-UIsyJMIrjUnT+yTaS6dkCxYYmtPwxFHxwSJ8+CLty2II5w9BewlDxDA0/QzhoL/InYCPxQ5Y6xIgLHZG1dhwRA==} + '@better-auth/kysely-adapter@1.7.12': + resolution: {integrity: sha512-1PaFXktLv4n3DmrGbPaCj5SsvcT40NnWw7NLua5/J1+8/A051N5ZzqOwJifXEIQX5k6NdwvmymwDQxKytduEAQ==} peerDependencies: - '@better-auth/core': 1.7.3 - '@better-auth/utils': 0.4.2 + '@better-auth/core': 1.7.12 + '@better-auth/utils': ^0.4.2 || ^0.5.0 kysely: ^0.28.17 || ^0.29.0 peerDependenciesMeta: kysely: optional: true - '@better-auth/memory-adapter@1.7.3': - resolution: {integrity: sha512-WdLANFY/QWC3G351RCzxU+Y9YlW+BQ1oG9NwBTSOUWQw5rZ87ws+weU8tvAMO7sQ4C9gKIlkOKBKUKXrSt91Tw==} + '@better-auth/memory-adapter@1.7.12': + resolution: {integrity: sha512-glaDwXzDptnddHqRuu7fj47FAssUcOzLNgdlTGJoEPrspkX69x2vnXwgAzNuApjZI21WLtPH/rQ6CN+DQGybPA==} peerDependencies: - '@better-auth/core': 1.7.3 - '@better-auth/utils': 0.4.2 + '@better-auth/core': 1.7.12 + '@better-auth/utils': ^0.4.2 || ^0.5.0 - '@better-auth/mongo-adapter@1.7.3': - resolution: {integrity: sha512-YL9m01tNogmFmRvOWJ46M9WwE6HirCXHDell29mtsQB/Qs1TPNLrgj7ybGMMGhQuyj6S218+8Wbls8m9s+i8RQ==} + '@better-auth/mongo-adapter@1.7.12': + resolution: {integrity: sha512-HKV4sgYSw/Gdt9AuHlESMkiKL72SWdGweDy1Wsyxoh06BpG7aNu4aSJ7marNpMdKZteyRbxWWqQkA9ediA8qFw==} peerDependencies: - '@better-auth/core': 1.7.3 - '@better-auth/utils': 0.4.2 + '@better-auth/core': 1.7.12 + '@better-auth/utils': ^0.4.2 || ^0.5.0 mongodb: ^6.0.0 || ^7.0.0 peerDependenciesMeta: mongodb: optional: true - '@better-auth/oauth-provider@1.7.3': - resolution: {integrity: sha512-Eoajj68F1ETmp4NBM98tgj1Uiip4cZiFqFsijAWIvOEQTejr/67PWK1/92N8PiNdLf03ezUWU538W93rd9fyIw==} + '@better-auth/oauth-provider@1.7.12': + resolution: {integrity: sha512-XzjlApbWtuuoEK63CUNHbgs8zpr3AjlQeGbT1vWEPqvOvI2z4lOaIvIsogomfqFAgj/jgB0zMGYjt0MRyW0T7w==} peerDependencies: - '@better-auth/core': 1.7.3 - '@better-auth/utils': 0.4.2 - '@better-fetch/fetch': 1.3.1 - better-auth: 1.7.3 - better-call: 1.4.0 + '@better-auth/core': 1.7.12 + '@better-auth/utils': ^0.4.2 || ^0.5.0 + '@better-fetch/fetch': 1.3.2 + better-auth: 1.7.12 + better-call: 1.4.4 - '@better-auth/prisma-adapter@1.7.3': - resolution: {integrity: sha512-TJ/DhlU7oLzrC626/1wfYA1Pl+lVsXa/zXBZ8d7Rlc2YO5fGd5fsAYJdRrYMyA51iZEo+rWLXMhZ0cez1BamsQ==} + '@better-auth/prisma-adapter@1.7.12': + resolution: {integrity: sha512-FZRX6ORbwhDmeYE1Tl0IPtUn8v3BlVFgbJxDnm/DCNHxuFRf+0t4HfddUgYeYehHFR8aSDsdYX44fEFWM9877w==} peerDependencies: - '@better-auth/core': 1.7.3 - '@better-auth/utils': 0.4.2 + '@better-auth/core': 1.7.12 + '@better-auth/utils': ^0.4.2 || ^0.5.0 '@prisma/client': ^5.0.0 || ^6.0.0 || ^7.0.0 prisma: ^5.0.0 || ^6.0.0 || ^7.0.0 peerDependenciesMeta: @@ -3585,38 +3582,35 @@ packages: prisma: optional: true - '@better-auth/scim@1.7.3': - resolution: {integrity: sha512-1/L7zIEUAb1jxlzWKkqbDAD4Jz7u83yZg15TSaIaKcFe1dpCdNxkzQRrjbPLUfnVtBh/vnk10uLxVFCtbMdrdg==} + '@better-auth/scim@1.7.12': + resolution: {integrity: sha512-mmDGQr9tu6z0mUhuQ5zGlutU0wmg3zujuP2uz02FqVil7RdEsHuYI6THeahF2EQEmCQ4E241SI8Lp94OruQw3A==} peerDependencies: - '@better-auth/core': 1.7.3 - '@better-auth/utils': 0.4.2 - better-auth: 1.7.3 - better-call: 1.4.0 + '@better-auth/core': 1.7.12 + '@better-auth/utils': ^0.4.2 || ^0.5.0 + better-auth: 1.7.12 + better-call: 1.4.4 - '@better-auth/sso@1.7.3': - resolution: {integrity: sha512-inxETRuOfyy8m0uEJSfi9uhScp4RkQ7ZYI+GRj+Jtz6ml/p5wTzNOjYZsG43TroUTDfrElF6CYQON5/Xk1XdmA==} + '@better-auth/sso@1.7.12': + resolution: {integrity: sha512-fxUD9+MjNRhuT+nVtFgqPvWAvwWJVacuIijdf4x2nCHqR44xfFgYYWK2iB6vOiin9Qxof9kTPKvRl7ZCJHdwFQ==} peerDependencies: - '@better-auth/core': 1.7.3 - '@better-auth/utils': 0.4.2 - '@better-fetch/fetch': 1.3.1 - better-auth: 1.7.3 - better-call: 1.4.0 + '@better-auth/core': 1.7.12 + '@better-auth/utils': ^0.4.2 || ^0.5.0 + '@better-fetch/fetch': 1.3.2 + better-auth: 1.7.12 + better-call: 1.4.4 - '@better-auth/telemetry@1.7.3': - resolution: {integrity: sha512-aixgHbJhGvS8PRczX/LR3murYyBnIvOGmJw37ZZBMg6ZtLR/UBJAkufbDi1HYn5THSuTJ3D5DtY85Ahh/ABQtw==} + '@better-auth/telemetry@1.7.12': + resolution: {integrity: sha512-DaDkKNnI99vKGGbWq9KJg2uYeaOjsK9nIBw9T2m2KG/RkxpvQRjYkZ00++up2bZQkR5pB1nukGbplza3UJG/Xg==} peerDependencies: - '@better-auth/core': 1.7.3 - '@better-auth/utils': 0.4.2 - '@better-fetch/fetch': 1.3.1 - - '@better-auth/utils@0.4.2': - resolution: {integrity: sha512-AUxrvu+HaaODsUyzDxFgwd/8RZ1yZaYo42LXKSrU2oGgR38pS1ij8nqQKNgtTWoYGpNevNXtCfgTy6loHveW9A==} + '@better-auth/core': 1.7.12 + '@better-auth/utils': ^0.4.2 || ^0.5.0 + '@better-fetch/fetch': 1.3.2 '@better-auth/utils@0.5.0': resolution: {integrity: sha512-BL8W4EfIZFwlu0r54m3v1ztjDhu6dDe/amLTm0xybmbZaNgYUqhD3SjpAsnq0q8YD6/ki4iwIgxJNLP/N3TxiA==} - '@better-fetch/fetch@1.3.1': - resolution: {integrity: sha512-ABkD1WhyfPZprKRQI3bhATjeiFuNWC9PXhfGWqL+sg/gKrM977oFrYkdb4msM3hgUGonr7KlOsOFT5TU2rht9g==} + '@better-fetch/fetch@1.3.2': + resolution: {integrity: sha512-Gs7n99b5tqUC6cQAPbV0uED3IraHB6xQbHLQ/C3l7ZFafHScOx9pQ+DYmP5blbLFShVWLqxNUlI9wi4xU/X+ow==} '@braintree/sanitize-url@7.1.2': resolution: {integrity: sha512-jigsZK+sMF/cuiB7sERuo9V7N9jx+dhmHHnQyDSVdpZwVutaBu7WvNYqMDLSgFgfB30n452TP3vjDAvFC973mA==} @@ -3703,9 +3697,6 @@ packages: resolution: {integrity: sha512-dlT1m5e/0yUL0kRNcQn7yGLVThkgbB0Ga/1AmfDDC/8ik6AIiSf2QLQO2zPYvefsHP0aFgxO93cVLCCfDp7kzQ==} engines: {node: '>= 20.12.0'} - '@cloudflare/workers-types@4.20260520.1': - resolution: {integrity: sha512-wdmf9Fwabp06OgK9ZyCl8Q77GZ94k9J7OA9qA65FbgxZ/hd3hYRkVNiY7Bvsx4tKim+sWmKqGOblecZInAvoRg==} - '@csstools/color-helpers@6.1.2': resolution: {integrity: sha512-grhRy3OKmniaAEKXMjua5z/EODX0MSqBGjunw8+j/3HQjOnahs2AGhvEOIYVUWcU6ScApbhLhVrQTX8XqrMrow==} engines: {node: '>=20.19.0'} @@ -4577,10 +4568,6 @@ packages: cpu: [x64] os: [win32] - '@noble/ciphers@2.3.0': - resolution: {integrity: sha512-Clu/xdfgVTf9o7ngLOURaxePwR0j8sjclKEtVij10/jGulwFsPWCvvRgG/XjUVf8Nei+jLG6uwyXzUTGY1DQrw==} - engines: {node: '>= 20.19.0'} - '@noble/ciphers@2.4.0': resolution: {integrity: sha512-AnjFn0Jv92laAkvMrghlFZq4qQCIN/4DxFV/eooqtC2YTjB7kBeLMS2T9KJX4Dn+ZVXLOwK0lSgqDtx9gvxtiw==} engines: {node: '>= 20.19.0'} @@ -4612,10 +4599,6 @@ packages: resolution: {integrity: sha512-gLyJlPHPZYdAk1JENA9LeHejZe1Ti77/pTeFm/nMXmQH/HFZlcS/O2XJB+L8fkbrNSqhdtlvjBVjxwUYanNH5Q==} engines: {node: '>=8.0.0'} - '@opentelemetry/semantic-conventions@1.43.0': - resolution: {integrity: sha512-eSYWTm620tTk45EKSedaUL8MFYI8hW164hIXsgIHyxu3VobUB3fFCu5t0hQby6OoWRPsG1KkKUG2M5UadiLiVg==} - engines: {node: '>=14'} - '@oxc-project/types@0.154.0': resolution: {integrity: sha512-KYOUGQFlLWR+s4QMV2Q9ko38TZm7EdO87Qm7rvZLqk/webse/cDjtyxKhg/47l0byCbs/k46LT8qc4PKjAikzA==} @@ -6029,15 +6012,14 @@ packages: engines: {node: '>=6.0.0'} hasBin: true - better-auth@1.7.3: - resolution: {integrity: sha512-8xGp68JQ+l36kniDEgP8bP99TLi1GdEv0NTEUBkyqnYnus/cgFUZseUfqUHKzr2BAsg2O6aD88I9f0U68shanQ==} + better-auth@1.7.12: + resolution: {integrity: sha512-f1fEG0QdTslzbmFA+vOGFFW/XXCWkG4kBxLeH9n1vp1otTH9+ZzV6EJ6797GStWeiYYgS5Vnt9xqE12KwSyAAw==} peerDependencies: '@lynx-js/react': '*' '@prisma/client': ^5.0.0 || ^6.0.0 || ^7.0.0 '@sveltejs/kit': ^2.69.1 '@tanstack/react-start': ^1.0.0 '@tanstack/solid-start': ^1.0.0 - better-sqlite3: ^12.0.0 drizzle-kit: '>=0.31.4 || >=1.0.0-beta.1' drizzle-orm: ^0.45.2 || >=1.0.0-rc.1 <2.0.0 mongodb: ^6.0.0 || ^7.0.0 @@ -6049,7 +6031,7 @@ packages: react-dom: ^18.0.0 || ^19.0.0 solid-js: ^1.0.0 svelte: ^5.55.7 - vitest: ^2.0.0 || ^3.0.0 || ^4.0.0 + vitest: ^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.0.0 vue: ^3.0.0 peerDependenciesMeta: '@lynx-js/react': @@ -6062,8 +6044,6 @@ packages: optional: true '@tanstack/solid-start': optional: true - better-sqlite3: - optional: true drizzle-kit: optional: true drizzle-orm: @@ -6091,18 +6071,14 @@ packages: vue: optional: true - better-call@1.4.0: - resolution: {integrity: sha512-bBKOT4vv1kZLDgxVePdilk/Jwkn+dtRRsmi3DzHcDP+WnswyVl6dR59l2HEeP/0cB+bDoopASAesWDPIdd/zZA==} + better-call@1.4.4: + resolution: {integrity: sha512-Gq4XdGFy4dmUxFEAX2nj0ycFcFbD9ZWh8YROouZoyXeF1M11TpYbplk0pDByTFF8Wz+MYa6W9052c9m7dD+mfw==} peerDependencies: zod: ^4.0.0 peerDependenciesMeta: zod: optional: true - better-sqlite3@12.11.1: - resolution: {integrity: sha512-dq9AtApgg5PGFtBzPFSBl3HZQjHok5gaQCM6zh2Yk0aSmDCs1CbnVI8/HgASQkNKsWFpseIO9beg5xxpYhbIfA==} - engines: {node: 20.x || 22.x || 23.x || 24.x || 25.x || 26.x} - better-sqlite3@13.0.3: resolution: {integrity: sha512-RbOBxmLBG8uvFUc15X9+9SFemKcQ0WBuISBVkpuiaUB2qblC8UWlHEjdWVoZ8AdhSwmoEgsiXKfopX0CQxaACQ==} engines: {node: '>=22'} @@ -6117,9 +6093,6 @@ packages: binary@0.3.0: resolution: {integrity: sha512-D4H1y5KYwpJgK8wk1Cue5LLPgmwHKYSChkbspQg5JtVuR5ulGckxfR62H3AE9UDkdMC8yyXlqYihuz3Aqg2XZg==} - bindings@1.5.0: - resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==} - bl@4.1.0: resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} @@ -6246,9 +6219,6 @@ packages: resolution: {integrity: sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==} engines: {node: '>= 20.19.0'} - chownr@1.1.4: - resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==} - class-variance-authority@0.7.1: resolution: {integrity: sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==} @@ -6589,14 +6559,6 @@ packages: decode-named-character-reference@1.3.0: resolution: {integrity: sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q==} - decompress-response@6.0.0: - resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==} - engines: {node: '>=10'} - - deep-extend@0.6.0: - resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==} - engines: {node: '>=4.0.0'} - deep-is@0.1.4: resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} @@ -6862,10 +6824,6 @@ packages: resolution: {integrity: sha512-XctvKaEMaj1Ii9oDOqbW/6e1gXknSY4g/aLCDicOXqBE4M0nRWkUu0PTp++UPNzoFY12BNHMfs/VadKIS6llvg==} engines: {node: '>=8.3.0'} - expand-template@2.0.3: - resolution: {integrity: sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==} - engines: {node: '>=6'} - expect-type@1.4.0: resolution: {integrity: sha512-KfYbmpRm0VbLjEvVa9yGwCi9GI34xvi7A/HXYWQO65CSD2u3MczUJSuwXKFIxlGsgBQizV9q5J9NHj4VG0n+pA==} engines: {node: '>=12.0.0'} @@ -6942,9 +6900,6 @@ packages: file-entry-cache@11.1.5: resolution: {integrity: sha512-+PFTHITI08JIGhnNpGNI8T8inUpgZfk3GNEqfT9R2zZV2iFXg3CvqzSl/uEhs7TSGujYRELEANyDvS8Fj7+S7Q==} - file-uri-to-path@1.0.0: - resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==} - finalhandler@2.1.1: resolution: {integrity: sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==} engines: {node: '>= 18.0.0'} @@ -7159,9 +7114,6 @@ packages: getopts@2.3.0: resolution: {integrity: sha512-5eDf9fuSXwxBL6q5HX+dhDj+dslFGWzU5thZ9kNKUkcPtaPdatmUFKwHFrLb/uf/WpA4BHET+AX3Scl56cAjpA==} - github-from-package@0.0.0: - resolution: {integrity: sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==} - github-slugger@2.0.0: resolution: {integrity: sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==} @@ -7313,9 +7265,6 @@ packages: inherits@2.0.4: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} - ini@1.3.8: - resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} - inline-style-parser@0.2.7: resolution: {integrity: sha512-Nb2ctOyNR8DqQoR0OwRG95uNWIC0C1lCgf5Naz5H6Ji72KZ8OcFZLz2P5sNgwlyoJ8Yif11oMuYs5pBQa86csA==} @@ -8050,10 +7999,6 @@ packages: resolution: {integrity: sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==} engines: {node: '>=18'} - mimic-response@3.1.0: - resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} - engines: {node: '>=10'} - mingo@7.2.4: resolution: {integrity: sha512-KrxHKzMMguL+G1lBC6YbU5UTXdw2viwVHNTPzNYVfEQfSAoetC3M1a7rlveOksn/96oNy+QwBlIXvx/q6rWyxQ==} @@ -8072,9 +8017,6 @@ packages: resolution: {integrity: sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==} engines: {node: '>=16 || 14 >=14.17'} - mkdirp-classic@0.5.3: - resolution: {integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==} - mkdirp@0.5.6: resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==} hasBin: true @@ -8218,9 +8160,6 @@ packages: resolution: {integrity: sha512-i0tloweeudshAEuddpDxcg9Ik6pkPfVsHIgKyf143JrgG7/MOh0+q7BypdLXZPoOP7fOYt1eTcwGkyiVmhJFkA==} engines: {node: ^20.0.0 || >=22.0.0} - napi-build-utils@2.0.0: - resolution: {integrity: sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==} - native-duplexpair@1.0.0: resolution: {integrity: sha512-E7QQoM+3jvNtlmyfqRZ0/U75VFgCls+fSkbml2MpgWkWyz3ox8Y58gNhfuziuQYGNNQAbFZJQck55LHCnCK6CA==} @@ -8262,10 +8201,6 @@ packages: sass: optional: true - node-abi@3.96.0: - resolution: {integrity: sha512-rebQ/lz7i0EkoLzUVSrKRzA69zMkwLp95kKMWoMDkkM00Suxz0D7zEQPwRml5fQum24mj7bPvmlgLAmu2JCiYg==} - engines: {node: '>=10'} - node-addon-api@8.9.2: resolution: {integrity: sha512-VijLXbi3UACN69I0JVXJsX4tjACjNoQDgv2gTF6sx2wWEi8tkSg2eX8p5gSIFi8z2+DL3oHmY6OyKce38SDolg==} engines: {node: ^18 || ^20 || >= 21} @@ -8538,12 +8473,6 @@ packages: resolution: {integrity: sha512-dM0jVuXJPsDN6DvRpea484tCUaMiXWjuCn++HGTqUWzGDjv5tZkEZldAJ/UMlqRYGFrD/etByo4/xOuC/snX2A==} engines: {node: '>=20'} - prebuild-install@7.1.3: - resolution: {integrity: sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==} - engines: {node: '>=10'} - deprecated: No longer maintained. Please contact the author of the relevant native addon; alternatives are available. - hasBin: true - prelude-ls@1.2.1: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} engines: {node: '>= 0.8.0'} @@ -8569,9 +8498,6 @@ packages: resolution: {integrity: sha512-5nnx0yGyVUcY6t9RnWcARWtwT9F1D8O9rt08htPvnd49W1IgZtmLkhu9WfMzQj1cFxjHIO6connUNVW5k7AVyQ==} engines: {node: '>= 0.10'} - pump@3.0.4: - resolution: {integrity: sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA==} - punycode@2.3.1: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} @@ -8602,10 +8528,6 @@ packages: resolution: {integrity: sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==} engines: {node: '>= 0.10'} - rc@1.2.8: - resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==} - hasBin: true - react-dom@19.2.8: resolution: {integrity: sha512-rVprimfGBG3DR+Tq0IQG2DT5PxKth1WIGDmj5yPmlzr4YBe7uyE+Du4oVqTDXZSHGGGXRtTJEGSSePyQCMBglQ==} peerDependencies: @@ -8906,12 +8828,6 @@ packages: resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} engines: {node: '>=14'} - simple-concat@1.0.1: - resolution: {integrity: sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==} - - simple-get@4.0.1: - resolution: {integrity: sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==} - sisteransi@1.0.5: resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} @@ -8991,10 +8907,6 @@ packages: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} engines: {node: '>=8'} - strip-json-comments@2.0.1: - resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==} - engines: {node: '>=0.10.0'} - strnum@2.4.1: resolution: {integrity: sha512-M9eUSMT2dCB2cTNPG7UYj6KuK7RJR2SN2+yCV/fTW3xzTCS6EaGZ5pSMgDIjB7r8zSfTGk+dvvn9rTjpVS9Mwg==} @@ -9055,9 +8967,6 @@ packages: resolution: {integrity: sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A==} engines: {node: '>=6'} - tar-fs@2.1.5: - resolution: {integrity: sha512-OboTd8mmMhZDNPV+UjQcK9yKAatXu2aJ+r1w4im1Otd4M4fl2hwvdoXUxIYHFTHWK/3y3FarBP70v3vwmGlOxw==} - tar-stream@2.2.0: resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==} engines: {node: '>=6'} @@ -9115,17 +9024,10 @@ packages: tldts-core@7.4.16: resolution: {integrity: sha512-MDolfaSJtlSK5Y0A1xl3277ekubZwobpBjugknDizI9O5Rm60a1m8k4ICK+MRsCDzPygT81mp3BBf5RKDlFRfA==} - tldts-core@7.4.9: - resolution: {integrity: sha512-DxKfPBI52p2msTEu7MPhdpdDTBhhVQg1a/8PjQckeyAvO13eMYElX545grIp6nnTGIMZlRvFZPvFhvI/WIz2Vg==} - tldts@7.4.16: resolution: {integrity: sha512-QwBER5KMR86IIjpIiO7H/Z3IMJPsZ1A6RKPAqzTTgOyUQUSt9FdnKcqhTaJmkY6HVrgouZHZR0ncK5QxvmnQeg==} hasBin: true - tldts@7.4.9: - resolution: {integrity: sha512-3kZ8wQQ/k5DrChD4X4FVvr2D7E5uoRgAqkPyLpSCGUvqOvqu+JEdr3mwMUaVWb+vMHZaKhF5fp2PBigKsui7hA==} - hasBin: true - tmp@0.2.7: resolution: {integrity: sha512-e0votIpp4Uo2AJYSzVHV6xCcawuiez3DzqDAbrTc3YxBkplN6e+dM13ZeIcZnDg/QpSuU2zfZ3rzwY8ukEnaXw==} engines: {node: '>=14.14'} @@ -9202,9 +9104,6 @@ packages: engines: {node: '>=18.0.0'} hasBin: true - tunnel-agent@0.6.0: - resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==} - turbo@2.11.5: resolution: {integrity: sha512-qLXheqz3TUvJpHIV6MUBwkNkvwKxMVG/QsimyiKT9DfNWPHJ294G/i5nDaH+fbHJt3UH7orubNNxAqYkbUNGAQ==} hasBin: true @@ -9973,98 +9872,92 @@ snapshots: '@bcoe/v8-coverage@1.0.2': {} - '@better-auth/core@1.7.3(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@cloudflare/workers-types@4.20260520.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.5))(jose@6.2.12)(kysely@0.29.4)(nanostores@1.4.0)': + '@better-auth/core@1.7.12(@better-auth/utils@0.5.0)(@better-fetch/fetch@1.3.2)(@opentelemetry/api@1.9.1)(better-call@1.4.4(zod@4.6.5))(jose@6.2.12)(kysely@0.29.4)(nanostores@1.4.0)': dependencies: - '@better-auth/utils': 0.4.2 - '@better-fetch/fetch': 1.3.1 - '@opentelemetry/semantic-conventions': 1.43.0 + '@better-auth/utils': 0.5.0 + '@better-fetch/fetch': 1.3.2 '@standard-schema/spec': 1.1.0 - better-call: 1.4.0(zod@4.6.5) + better-call: 1.4.4(zod@4.6.5) jose: 6.2.12 kysely: 0.29.4 nanostores: 1.4.0 zod: 4.6.5 optionalDependencies: - '@cloudflare/workers-types': 4.20260520.1 '@opentelemetry/api': 1.9.1 - '@better-auth/drizzle-adapter@1.7.3(@better-auth/core@1.7.3(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@cloudflare/workers-types@4.20260520.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.5))(jose@6.2.12)(kysely@0.29.4)(nanostores@1.4.0))(@better-auth/utils@0.4.2)': + '@better-auth/drizzle-adapter@1.7.12(@better-auth/core@1.7.12(@better-auth/utils@0.5.0)(@better-fetch/fetch@1.3.2)(@opentelemetry/api@1.9.1)(better-call@1.4.4(zod@4.6.5))(jose@6.2.12)(kysely@0.29.4)(nanostores@1.4.0))(@better-auth/utils@0.5.0)': dependencies: - '@better-auth/core': 1.7.3(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@cloudflare/workers-types@4.20260520.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.5))(jose@6.2.12)(kysely@0.29.4)(nanostores@1.4.0) - '@better-auth/utils': 0.4.2 + '@better-auth/core': 1.7.12(@better-auth/utils@0.5.0)(@better-fetch/fetch@1.3.2)(@opentelemetry/api@1.9.1)(better-call@1.4.4(zod@4.6.5))(jose@6.2.12)(kysely@0.29.4)(nanostores@1.4.0) + '@better-auth/utils': 0.5.0 - '@better-auth/kysely-adapter@1.7.3(@better-auth/core@1.7.3(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@cloudflare/workers-types@4.20260520.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.5))(jose@6.2.12)(kysely@0.29.4)(nanostores@1.4.0))(@better-auth/utils@0.4.2)(kysely@0.29.4)': + '@better-auth/kysely-adapter@1.7.12(@better-auth/core@1.7.12(@better-auth/utils@0.5.0)(@better-fetch/fetch@1.3.2)(@opentelemetry/api@1.9.1)(better-call@1.4.4(zod@4.6.5))(jose@6.2.12)(kysely@0.29.4)(nanostores@1.4.0))(@better-auth/utils@0.5.0)(kysely@0.29.4)': dependencies: - '@better-auth/core': 1.7.3(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@cloudflare/workers-types@4.20260520.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.5))(jose@6.2.12)(kysely@0.29.4)(nanostores@1.4.0) - '@better-auth/utils': 0.4.2 + '@better-auth/core': 1.7.12(@better-auth/utils@0.5.0)(@better-fetch/fetch@1.3.2)(@opentelemetry/api@1.9.1)(better-call@1.4.4(zod@4.6.5))(jose@6.2.12)(kysely@0.29.4)(nanostores@1.4.0) + '@better-auth/utils': 0.5.0 optionalDependencies: kysely: 0.29.4 - '@better-auth/memory-adapter@1.7.3(@better-auth/core@1.7.3(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@cloudflare/workers-types@4.20260520.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.5))(jose@6.2.12)(kysely@0.29.4)(nanostores@1.4.0))(@better-auth/utils@0.4.2)': + '@better-auth/memory-adapter@1.7.12(@better-auth/core@1.7.12(@better-auth/utils@0.5.0)(@better-fetch/fetch@1.3.2)(@opentelemetry/api@1.9.1)(better-call@1.4.4(zod@4.6.5))(jose@6.2.12)(kysely@0.29.4)(nanostores@1.4.0))(@better-auth/utils@0.5.0)': dependencies: - '@better-auth/core': 1.7.3(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@cloudflare/workers-types@4.20260520.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.5))(jose@6.2.12)(kysely@0.29.4)(nanostores@1.4.0) - '@better-auth/utils': 0.4.2 + '@better-auth/core': 1.7.12(@better-auth/utils@0.5.0)(@better-fetch/fetch@1.3.2)(@opentelemetry/api@1.9.1)(better-call@1.4.4(zod@4.6.5))(jose@6.2.12)(kysely@0.29.4)(nanostores@1.4.0) + '@better-auth/utils': 0.5.0 - '@better-auth/mongo-adapter@1.7.3(@better-auth/core@1.7.3(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@cloudflare/workers-types@4.20260520.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.5))(jose@6.2.12)(kysely@0.29.4)(nanostores@1.4.0))(@better-auth/utils@0.4.2)(mongodb@7.7.0(socks@2.8.9))': + '@better-auth/mongo-adapter@1.7.12(@better-auth/core@1.7.12(@better-auth/utils@0.5.0)(@better-fetch/fetch@1.3.2)(@opentelemetry/api@1.9.1)(better-call@1.4.4(zod@4.6.5))(jose@6.2.12)(kysely@0.29.4)(nanostores@1.4.0))(@better-auth/utils@0.5.0)(mongodb@7.7.0(socks@2.8.9))': dependencies: - '@better-auth/core': 1.7.3(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@cloudflare/workers-types@4.20260520.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.5))(jose@6.2.12)(kysely@0.29.4)(nanostores@1.4.0) - '@better-auth/utils': 0.4.2 + '@better-auth/core': 1.7.12(@better-auth/utils@0.5.0)(@better-fetch/fetch@1.3.2)(@opentelemetry/api@1.9.1)(better-call@1.4.4(zod@4.6.5))(jose@6.2.12)(kysely@0.29.4)(nanostores@1.4.0) + '@better-auth/utils': 0.5.0 optionalDependencies: mongodb: 7.7.0(socks@2.8.9) - '@better-auth/oauth-provider@1.7.3(@better-auth/core@1.7.3(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@cloudflare/workers-types@4.20260520.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.5))(jose@6.2.12)(kysely@0.29.4)(nanostores@1.4.0))(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(better-auth@1.7.3(@cloudflare/workers-types@4.20260520.1)(@opentelemetry/api@1.9.1)(better-sqlite3@12.11.1)(mongodb@7.7.0(socks@2.8.9))(mysql2@3.24.4(@types/node@26.6.3))(next@16.3.8(@opentelemetry/api@1.9.1)(@playwright/test@1.63.0)(@types/node@26.6.3)(react-dom@19.3.0(react@19.3.0))(react@19.3.0))(pg@8.23.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(svelte@5.57.1(@typescript-eslint/types@8.70.1))(vitest@4.1.11))(better-call@1.4.0(zod@4.6.5))': + '@better-auth/oauth-provider@1.7.12(@better-auth/core@1.7.12(@better-auth/utils@0.5.0)(@better-fetch/fetch@1.3.2)(@opentelemetry/api@1.9.1)(better-call@1.4.4(zod@4.6.5))(jose@6.2.12)(kysely@0.29.4)(nanostores@1.4.0))(@better-auth/utils@0.5.0)(@better-fetch/fetch@1.3.2)(better-auth@1.7.12(@opentelemetry/api@1.9.1)(mongodb@7.7.0(socks@2.8.9))(mysql2@3.24.4(@types/node@26.6.3))(next@16.3.8(@opentelemetry/api@1.9.1)(@playwright/test@1.63.0)(@types/node@26.6.3)(react-dom@19.3.0(react@19.3.0))(react@19.3.0))(pg@8.23.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(svelte@5.57.1(@typescript-eslint/types@8.70.1))(vitest@4.1.11))(better-call@1.4.4(zod@4.6.5))': dependencies: - '@better-auth/core': 1.7.3(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@cloudflare/workers-types@4.20260520.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.5))(jose@6.2.12)(kysely@0.29.4)(nanostores@1.4.0) - '@better-auth/utils': 0.4.2 - '@better-fetch/fetch': 1.3.1 - better-auth: 1.7.3(@cloudflare/workers-types@4.20260520.1)(@opentelemetry/api@1.9.1)(better-sqlite3@12.11.1)(mongodb@7.7.0(socks@2.8.9))(mysql2@3.24.4(@types/node@26.6.3))(next@16.3.8(@opentelemetry/api@1.9.1)(@playwright/test@1.63.0)(@types/node@26.6.3)(react-dom@19.3.0(react@19.3.0))(react@19.3.0))(pg@8.23.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(svelte@5.57.1(@typescript-eslint/types@8.70.1))(vitest@4.1.11) - better-call: 1.4.0(zod@4.6.5) + '@better-auth/core': 1.7.12(@better-auth/utils@0.5.0)(@better-fetch/fetch@1.3.2)(@opentelemetry/api@1.9.1)(better-call@1.4.4(zod@4.6.5))(jose@6.2.12)(kysely@0.29.4)(nanostores@1.4.0) + '@better-auth/utils': 0.5.0 + '@better-fetch/fetch': 1.3.2 + better-auth: 1.7.12(@opentelemetry/api@1.9.1)(mongodb@7.7.0(socks@2.8.9))(mysql2@3.24.4(@types/node@26.6.3))(next@16.3.8(@opentelemetry/api@1.9.1)(@playwright/test@1.63.0)(@types/node@26.6.3)(react-dom@19.3.0(react@19.3.0))(react@19.3.0))(pg@8.23.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(svelte@5.57.1(@typescript-eslint/types@8.70.1))(vitest@4.1.11) + better-call: 1.4.4(zod@4.6.5) jose: 6.2.12 zod: 4.6.5 - '@better-auth/prisma-adapter@1.7.3(@better-auth/core@1.7.3(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@cloudflare/workers-types@4.20260520.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.5))(jose@6.2.12)(kysely@0.29.4)(nanostores@1.4.0))(@better-auth/utils@0.4.2)': + '@better-auth/prisma-adapter@1.7.12(@better-auth/core@1.7.12(@better-auth/utils@0.5.0)(@better-fetch/fetch@1.3.2)(@opentelemetry/api@1.9.1)(better-call@1.4.4(zod@4.6.5))(jose@6.2.12)(kysely@0.29.4)(nanostores@1.4.0))(@better-auth/utils@0.5.0)': dependencies: - '@better-auth/core': 1.7.3(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@cloudflare/workers-types@4.20260520.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.5))(jose@6.2.12)(kysely@0.29.4)(nanostores@1.4.0) - '@better-auth/utils': 0.4.2 + '@better-auth/core': 1.7.12(@better-auth/utils@0.5.0)(@better-fetch/fetch@1.3.2)(@opentelemetry/api@1.9.1)(better-call@1.4.4(zod@4.6.5))(jose@6.2.12)(kysely@0.29.4)(nanostores@1.4.0) + '@better-auth/utils': 0.5.0 - '@better-auth/scim@1.7.3(@better-auth/core@1.7.3(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@cloudflare/workers-types@4.20260520.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.5))(jose@6.2.12)(kysely@0.29.4)(nanostores@1.4.0))(@better-auth/utils@0.4.2)(better-auth@1.7.3(@cloudflare/workers-types@4.20260520.1)(@opentelemetry/api@1.9.1)(better-sqlite3@12.11.1)(mongodb@7.7.0(socks@2.8.9))(mysql2@3.24.4(@types/node@26.6.3))(next@16.3.8(@opentelemetry/api@1.9.1)(@playwright/test@1.63.0)(@types/node@26.6.3)(react-dom@19.3.0(react@19.3.0))(react@19.3.0))(pg@8.23.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(svelte@5.57.1(@typescript-eslint/types@8.70.1))(vitest@4.1.11))(better-call@1.4.0(zod@4.6.5))': + '@better-auth/scim@1.7.12(@better-auth/core@1.7.12(@better-auth/utils@0.5.0)(@better-fetch/fetch@1.3.2)(@opentelemetry/api@1.9.1)(better-call@1.4.4(zod@4.6.5))(jose@6.2.12)(kysely@0.29.4)(nanostores@1.4.0))(@better-auth/utils@0.5.0)(better-auth@1.7.12(@opentelemetry/api@1.9.1)(mongodb@7.7.0(socks@2.8.9))(mysql2@3.24.4(@types/node@26.6.3))(next@16.3.8(@opentelemetry/api@1.9.1)(@playwright/test@1.63.0)(@types/node@26.6.3)(react-dom@19.3.0(react@19.3.0))(react@19.3.0))(pg@8.23.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(svelte@5.57.1(@typescript-eslint/types@8.70.1))(vitest@4.1.11))(better-call@1.4.4(zod@4.6.5))': dependencies: - '@better-auth/core': 1.7.3(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@cloudflare/workers-types@4.20260520.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.5))(jose@6.2.12)(kysely@0.29.4)(nanostores@1.4.0) - '@better-auth/utils': 0.4.2 + '@better-auth/core': 1.7.12(@better-auth/utils@0.5.0)(@better-fetch/fetch@1.3.2)(@opentelemetry/api@1.9.1)(better-call@1.4.4(zod@4.6.5))(jose@6.2.12)(kysely@0.29.4)(nanostores@1.4.0) + '@better-auth/utils': 0.5.0 '@noble/hashes': 2.4.0 - better-auth: 1.7.3(@cloudflare/workers-types@4.20260520.1)(@opentelemetry/api@1.9.1)(better-sqlite3@12.11.1)(mongodb@7.7.0(socks@2.8.9))(mysql2@3.24.4(@types/node@26.6.3))(next@16.3.8(@opentelemetry/api@1.9.1)(@playwright/test@1.63.0)(@types/node@26.6.3)(react-dom@19.3.0(react@19.3.0))(react@19.3.0))(pg@8.23.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(svelte@5.57.1(@typescript-eslint/types@8.70.1))(vitest@4.1.11) - better-call: 1.4.0(zod@4.6.5) + better-auth: 1.7.12(@opentelemetry/api@1.9.1)(mongodb@7.7.0(socks@2.8.9))(mysql2@3.24.4(@types/node@26.6.3))(next@16.3.8(@opentelemetry/api@1.9.1)(@playwright/test@1.63.0)(@types/node@26.6.3)(react-dom@19.3.0(react@19.3.0))(react@19.3.0))(pg@8.23.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(svelte@5.57.1(@typescript-eslint/types@8.70.1))(vitest@4.1.11) + better-call: 1.4.4(zod@4.6.5) zod: 4.6.5 - '@better-auth/sso@1.7.3(@better-auth/core@1.7.3(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@cloudflare/workers-types@4.20260520.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.5))(jose@6.2.12)(kysely@0.29.4)(nanostores@1.4.0))(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(better-auth@1.7.3(@cloudflare/workers-types@4.20260520.1)(@opentelemetry/api@1.9.1)(better-sqlite3@12.11.1)(mongodb@7.7.0(socks@2.8.9))(mysql2@3.24.4(@types/node@26.6.3))(next@16.3.8(@opentelemetry/api@1.9.1)(@playwright/test@1.63.0)(@types/node@26.6.3)(react-dom@19.3.0(react@19.3.0))(react@19.3.0))(pg@8.23.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(svelte@5.57.1(@typescript-eslint/types@8.70.1))(vitest@4.1.11))(better-call@1.4.0(zod@4.6.5))': + '@better-auth/sso@1.7.12(@better-auth/core@1.7.12(@better-auth/utils@0.5.0)(@better-fetch/fetch@1.3.2)(@opentelemetry/api@1.9.1)(better-call@1.4.4(zod@4.6.5))(jose@6.2.12)(kysely@0.29.4)(nanostores@1.4.0))(@better-auth/utils@0.5.0)(@better-fetch/fetch@1.3.2)(better-auth@1.7.12(@opentelemetry/api@1.9.1)(mongodb@7.7.0(socks@2.8.9))(mysql2@3.24.4(@types/node@26.6.3))(next@16.3.8(@opentelemetry/api@1.9.1)(@playwright/test@1.63.0)(@types/node@26.6.3)(react-dom@19.3.0(react@19.3.0))(react@19.3.0))(pg@8.23.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(svelte@5.57.1(@typescript-eslint/types@8.70.1))(vitest@4.1.11))(better-call@1.4.4(zod@4.6.5))': dependencies: - '@better-auth/core': 1.7.3(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@cloudflare/workers-types@4.20260520.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.5))(jose@6.2.12)(kysely@0.29.4)(nanostores@1.4.0) - '@better-auth/utils': 0.4.2 - '@better-fetch/fetch': 1.3.1 + '@better-auth/core': 1.7.12(@better-auth/utils@0.5.0)(@better-fetch/fetch@1.3.2)(@opentelemetry/api@1.9.1)(better-call@1.4.4(zod@4.6.5))(jose@6.2.12)(kysely@0.29.4)(nanostores@1.4.0) + '@better-auth/utils': 0.5.0 + '@better-fetch/fetch': 1.3.2 '@xmldom/xmldom': 0.9.12 - better-auth: 1.7.3(@cloudflare/workers-types@4.20260520.1)(@opentelemetry/api@1.9.1)(better-sqlite3@12.11.1)(mongodb@7.7.0(socks@2.8.9))(mysql2@3.24.4(@types/node@26.6.3))(next@16.3.8(@opentelemetry/api@1.9.1)(@playwright/test@1.63.0)(@types/node@26.6.3)(react-dom@19.3.0(react@19.3.0))(react@19.3.0))(pg@8.23.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(svelte@5.57.1(@typescript-eslint/types@8.70.1))(vitest@4.1.11) - better-call: 1.4.0(zod@4.6.5) + better-auth: 1.7.12(@opentelemetry/api@1.9.1)(mongodb@7.7.0(socks@2.8.9))(mysql2@3.24.4(@types/node@26.6.3))(next@16.3.8(@opentelemetry/api@1.9.1)(@playwright/test@1.63.0)(@types/node@26.6.3)(react-dom@19.3.0(react@19.3.0))(react@19.3.0))(pg@8.23.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(svelte@5.57.1(@typescript-eslint/types@8.70.1))(vitest@4.1.11) + better-call: 1.4.4(zod@4.6.5) fast-xml-parser: 5.10.1 jose: 6.2.12 samlify: 2.13.1 - tldts: 7.4.9 + tldts: 7.4.16 zod: 4.6.5 - '@better-auth/telemetry@1.7.3(@better-auth/core@1.7.3(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@cloudflare/workers-types@4.20260520.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.5))(jose@6.2.12)(kysely@0.29.4)(nanostores@1.4.0))(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)': - dependencies: - '@better-auth/core': 1.7.3(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@cloudflare/workers-types@4.20260520.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.5))(jose@6.2.12)(kysely@0.29.4)(nanostores@1.4.0) - '@better-auth/utils': 0.4.2 - '@better-fetch/fetch': 1.3.1 - - '@better-auth/utils@0.4.2': + '@better-auth/telemetry@1.7.12(@better-auth/core@1.7.12(@better-auth/utils@0.5.0)(@better-fetch/fetch@1.3.2)(@opentelemetry/api@1.9.1)(better-call@1.4.4(zod@4.6.5))(jose@6.2.12)(kysely@0.29.4)(nanostores@1.4.0))(@better-auth/utils@0.5.0)(@better-fetch/fetch@1.3.2)': dependencies: - '@noble/hashes': 2.4.0 + '@better-auth/core': 1.7.12(@better-auth/utils@0.5.0)(@better-fetch/fetch@1.3.2)(@opentelemetry/api@1.9.1)(better-call@1.4.4(zod@4.6.5))(jose@6.2.12)(kysely@0.29.4)(nanostores@1.4.0) + '@better-auth/utils': 0.5.0 + '@better-fetch/fetch': 1.3.2 '@better-auth/utils@0.5.0': dependencies: '@noble/hashes': 2.4.0 - '@better-fetch/fetch@1.3.1': {} + '@better-fetch/fetch@1.3.2': {} '@braintree/sanitize-url@7.1.2': {} @@ -10202,9 +10095,6 @@ snapshots: fast-wrap-ansi: 0.2.2 sisteransi: 1.0.5 - '@cloudflare/workers-types@4.20260520.1': - optional: true - '@csstools/color-helpers@6.1.2': {} '@csstools/css-calc@3.4.1(@csstools/css-parser-algorithms@4.0.1(@csstools/css-tokenizer@4.0.2))(@csstools/css-tokenizer@4.0.2)': @@ -10870,8 +10760,6 @@ snapshots: '@next/swc-win32-x64-msvc@16.3.8': optional: true - '@noble/ciphers@2.3.0': {} - '@noble/ciphers@2.4.0': {} '@noble/hashes@2.4.0': {} @@ -10917,8 +10805,6 @@ snapshots: '@opentelemetry/api@1.9.1': optional: true - '@opentelemetry/semantic-conventions@1.43.0': {} - '@oxc-project/types@0.154.0': {} '@playwright/test@1.63.0': @@ -12213,27 +12099,26 @@ snapshots: baseline-browser-mapping@2.11.14: {} - better-auth@1.7.3(@cloudflare/workers-types@4.20260520.1)(@opentelemetry/api@1.9.1)(better-sqlite3@12.11.1)(mongodb@7.7.0(socks@2.8.9))(mysql2@3.24.4(@types/node@26.6.3))(next@16.3.8(@opentelemetry/api@1.9.1)(@playwright/test@1.63.0)(@types/node@26.6.3)(react-dom@19.3.0(react@19.3.0))(react@19.3.0))(pg@8.23.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(svelte@5.57.1(@typescript-eslint/types@8.70.1))(vitest@4.1.11): - dependencies: - '@better-auth/core': 1.7.3(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@cloudflare/workers-types@4.20260520.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.5))(jose@6.2.12)(kysely@0.29.4)(nanostores@1.4.0) - '@better-auth/drizzle-adapter': 1.7.3(@better-auth/core@1.7.3(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@cloudflare/workers-types@4.20260520.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.5))(jose@6.2.12)(kysely@0.29.4)(nanostores@1.4.0))(@better-auth/utils@0.4.2) - '@better-auth/kysely-adapter': 1.7.3(@better-auth/core@1.7.3(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@cloudflare/workers-types@4.20260520.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.5))(jose@6.2.12)(kysely@0.29.4)(nanostores@1.4.0))(@better-auth/utils@0.4.2)(kysely@0.29.4) - '@better-auth/memory-adapter': 1.7.3(@better-auth/core@1.7.3(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@cloudflare/workers-types@4.20260520.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.5))(jose@6.2.12)(kysely@0.29.4)(nanostores@1.4.0))(@better-auth/utils@0.4.2) - '@better-auth/mongo-adapter': 1.7.3(@better-auth/core@1.7.3(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@cloudflare/workers-types@4.20260520.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.5))(jose@6.2.12)(kysely@0.29.4)(nanostores@1.4.0))(@better-auth/utils@0.4.2)(mongodb@7.7.0(socks@2.8.9)) - '@better-auth/prisma-adapter': 1.7.3(@better-auth/core@1.7.3(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@cloudflare/workers-types@4.20260520.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.5))(jose@6.2.12)(kysely@0.29.4)(nanostores@1.4.0))(@better-auth/utils@0.4.2) - '@better-auth/telemetry': 1.7.3(@better-auth/core@1.7.3(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@cloudflare/workers-types@4.20260520.1)(@opentelemetry/api@1.9.1)(better-call@1.4.0(zod@4.6.5))(jose@6.2.12)(kysely@0.29.4)(nanostores@1.4.0))(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1) - '@better-auth/utils': 0.4.2 - '@better-fetch/fetch': 1.3.1 - '@noble/ciphers': 2.3.0 + better-auth@1.7.12(@opentelemetry/api@1.9.1)(mongodb@7.7.0(socks@2.8.9))(mysql2@3.24.4(@types/node@26.6.3))(next@16.3.8(@opentelemetry/api@1.9.1)(@playwright/test@1.63.0)(@types/node@26.6.3)(react-dom@19.3.0(react@19.3.0))(react@19.3.0))(pg@8.23.0)(react-dom@19.3.0(react@19.3.0))(react@19.3.0)(svelte@5.57.1(@typescript-eslint/types@8.70.1))(vitest@4.1.11): + dependencies: + '@better-auth/core': 1.7.12(@better-auth/utils@0.5.0)(@better-fetch/fetch@1.3.2)(@opentelemetry/api@1.9.1)(better-call@1.4.4(zod@4.6.5))(jose@6.2.12)(kysely@0.29.4)(nanostores@1.4.0) + '@better-auth/drizzle-adapter': 1.7.12(@better-auth/core@1.7.12(@better-auth/utils@0.5.0)(@better-fetch/fetch@1.3.2)(@opentelemetry/api@1.9.1)(better-call@1.4.4(zod@4.6.5))(jose@6.2.12)(kysely@0.29.4)(nanostores@1.4.0))(@better-auth/utils@0.5.0) + '@better-auth/kysely-adapter': 1.7.12(@better-auth/core@1.7.12(@better-auth/utils@0.5.0)(@better-fetch/fetch@1.3.2)(@opentelemetry/api@1.9.1)(better-call@1.4.4(zod@4.6.5))(jose@6.2.12)(kysely@0.29.4)(nanostores@1.4.0))(@better-auth/utils@0.5.0)(kysely@0.29.4) + '@better-auth/memory-adapter': 1.7.12(@better-auth/core@1.7.12(@better-auth/utils@0.5.0)(@better-fetch/fetch@1.3.2)(@opentelemetry/api@1.9.1)(better-call@1.4.4(zod@4.6.5))(jose@6.2.12)(kysely@0.29.4)(nanostores@1.4.0))(@better-auth/utils@0.5.0) + '@better-auth/mongo-adapter': 1.7.12(@better-auth/core@1.7.12(@better-auth/utils@0.5.0)(@better-fetch/fetch@1.3.2)(@opentelemetry/api@1.9.1)(better-call@1.4.4(zod@4.6.5))(jose@6.2.12)(kysely@0.29.4)(nanostores@1.4.0))(@better-auth/utils@0.5.0)(mongodb@7.7.0(socks@2.8.9)) + '@better-auth/prisma-adapter': 1.7.12(@better-auth/core@1.7.12(@better-auth/utils@0.5.0)(@better-fetch/fetch@1.3.2)(@opentelemetry/api@1.9.1)(better-call@1.4.4(zod@4.6.5))(jose@6.2.12)(kysely@0.29.4)(nanostores@1.4.0))(@better-auth/utils@0.5.0) + '@better-auth/telemetry': 1.7.12(@better-auth/core@1.7.12(@better-auth/utils@0.5.0)(@better-fetch/fetch@1.3.2)(@opentelemetry/api@1.9.1)(better-call@1.4.4(zod@4.6.5))(jose@6.2.12)(kysely@0.29.4)(nanostores@1.4.0))(@better-auth/utils@0.5.0)(@better-fetch/fetch@1.3.2) + '@better-auth/utils': 0.5.0 + '@better-fetch/fetch': 1.3.2 + '@noble/ciphers': 2.4.0 '@noble/hashes': 2.4.0 - better-call: 1.4.0(zod@4.6.5) + better-call: 1.4.4(zod@4.6.5) defu: 6.1.7 jose: 6.2.12 kysely: 0.29.4 nanostores: 1.4.0 zod: 4.6.5 optionalDependencies: - better-sqlite3: 12.11.1 mongodb: 7.7.0(socks@2.8.9) mysql2: 3.24.4(@types/node@26.6.3) next: 16.3.8(@opentelemetry/api@1.9.1)(@playwright/test@1.63.0)(@types/node@26.6.3)(react-dom@19.3.0(react@19.3.0))(react@19.3.0) @@ -12243,24 +12128,17 @@ snapshots: svelte: 5.57.1(@typescript-eslint/types@8.70.1) vitest: 4.1.11(@opentelemetry/api@1.9.1)(@types/node@26.6.3)(@vitest/coverage-v8@4.1.11)(happy-dom@20.10.2)(jsdom@30.1.1(@noble/hashes@2.4.0))(msw@2.14.6(@types/node@26.6.3)(typescript@6.0.3))(vite@8.3.4(@types/node@26.6.3)(esbuild@0.28.2)(jiti@2.7.0)(tsx@4.23.15(patch_hash=4d1d35da1809be2a945519cb26890e48107810b9b66c6913a6a89abb5ad6a1e6))(yaml@2.9.1)) transitivePeerDependencies: - - '@cloudflare/workers-types' - '@opentelemetry/api' - better-call@1.4.0(zod@4.6.5): + better-call@1.4.4(zod@4.6.5): dependencies: '@better-auth/utils': 0.5.0 - '@better-fetch/fetch': 1.3.1 + '@better-fetch/fetch': 1.3.2 rou3: 0.9.2 set-cookie-parser: 3.1.2 optionalDependencies: zod: 4.6.5 - better-sqlite3@12.11.1: - dependencies: - bindings: 1.5.0 - prebuild-install: 7.1.3 - optional: true - better-sqlite3@13.0.3: dependencies: node-addon-api: 8.9.2 @@ -12276,11 +12154,6 @@ snapshots: buffers: 0.1.1 chainsaw: 0.1.0 - bindings@1.5.0: - dependencies: - file-uri-to-path: 1.0.0 - optional: true - bl@4.1.0: dependencies: buffer: 5.7.1 @@ -12411,9 +12284,6 @@ snapshots: dependencies: readdirp: 5.0.0 - chownr@1.1.4: - optional: true - class-variance-authority@0.7.1: dependencies: clsx: 2.1.1 @@ -12743,14 +12613,6 @@ snapshots: dependencies: character-entities: 2.0.2 - decompress-response@6.0.0: - dependencies: - mimic-response: 3.1.0 - optional: true - - deep-extend@0.6.0: - optional: true - deep-is@0.1.4: {} default-browser-id@5.0.1: {} @@ -13071,9 +12933,6 @@ snapshots: unzipper: 0.10.14 uuid: 11.1.1 - expand-template@2.0.3: - optional: true - expect-type@1.4.0: {} express-rate-limit@8.6.1(express@5.2.1): @@ -13180,9 +13039,6 @@ snapshots: dependencies: flat-cache: 6.1.23 - file-uri-to-path@1.0.0: - optional: true - finalhandler@2.1.1: dependencies: debug: 4.4.3(supports-color@8.1.1) @@ -13392,9 +13248,6 @@ snapshots: getopts@2.3.0: {} - github-from-package@0.0.0: - optional: true - github-slugger@2.0.0: {} glob-parent@6.0.2: @@ -13632,9 +13485,6 @@ snapshots: inherits@2.0.4: {} - ini@1.3.8: - optional: true - inline-style-parser@0.2.7: {} internmap@1.0.1: {} @@ -14566,9 +14416,6 @@ snapshots: dependencies: mime-db: 1.54.0 - mimic-response@3.1.0: - optional: true - mingo@7.2.4: {} minimatch@10.2.3: @@ -14583,9 +14430,6 @@ snapshots: minipass@7.1.3: {} - mkdirp-classic@0.5.3: - optional: true - mkdirp@0.5.6: dependencies: minimist: 1.2.8 @@ -14748,9 +14592,6 @@ snapshots: nanostores@1.4.0: {} - napi-build-utils@2.0.0: - optional: true - native-duplexpair@1.0.0: {} natural-compare@1.4.0: {} @@ -14825,11 +14666,6 @@ snapshots: - babel-plugin-macros optional: true - node-abi@3.96.0: - dependencies: - semver: 7.8.5 - optional: true - node-addon-api@8.9.2: {} node-rsa@1.1.1: @@ -15068,22 +14904,6 @@ snapshots: powershell-utils@0.1.0: {} - prebuild-install@7.1.3: - dependencies: - detect-libc: 2.1.2 - expand-template: 2.0.3 - github-from-package: 0.0.0 - minimist: 1.2.8 - mkdirp-classic: 0.5.3 - napi-build-utils: 2.0.0 - node-abi: 3.96.0 - pump: 3.0.4 - rc: 1.2.8 - simple-get: 4.0.1 - tar-fs: 2.1.5 - tunnel-agent: 0.6.0 - optional: true - prelude-ls@1.2.1: {} pretty-format@27.5.1: @@ -15105,12 +14925,6 @@ snapshots: forwarded: 0.2.0 ipaddr.js: 1.9.1 - pump@3.0.4: - dependencies: - end-of-stream: 1.4.5 - once: 1.4.0 - optional: true - punycode@2.3.1: {} pure-rand@8.4.2: {} @@ -15145,14 +14959,6 @@ snapshots: iconv-lite: 0.7.3 unpipe: 1.0.0 - rc@1.2.8: - dependencies: - deep-extend: 0.6.0 - ini: 1.3.8 - minimist: 1.2.8 - strip-json-comments: 2.0.1 - optional: true - react-dom@19.2.8(react@19.2.8): dependencies: react: 19.2.8 @@ -15598,16 +15404,6 @@ snapshots: signal-exit@4.1.0: optional: true - simple-concat@1.0.1: - optional: true - - simple-get@4.0.1: - dependencies: - decompress-response: 6.0.0 - once: 1.4.0 - simple-concat: 1.0.1 - optional: true - sisteransi@1.0.5: {} smart-buffer@4.2.0: @@ -15682,9 +15478,6 @@ snapshots: dependencies: ansi-regex: 5.0.1 - strip-json-comments@2.0.1: - optional: true - strnum@2.4.1: dependencies: anynum: 1.0.1 @@ -15759,14 +15552,6 @@ snapshots: tapable@2.3.3: {} - tar-fs@2.1.5: - dependencies: - chownr: 1.1.4 - mkdirp-classic: 0.5.3 - pump: 3.0.4 - tar-stream: 2.2.0 - optional: true - tar-stream@2.2.0: dependencies: bl: 4.1.0 @@ -15843,16 +15628,10 @@ snapshots: tldts-core@7.4.16: {} - tldts-core@7.4.9: {} - tldts@7.4.16: dependencies: tldts-core: 7.4.16 - tldts@7.4.9: - dependencies: - tldts-core: 7.4.9 - tmp@0.2.7: {} toidentifier@1.0.1: {} @@ -15926,11 +15705,6 @@ snapshots: optionalDependencies: fsevents: 2.3.3 - tunnel-agent@0.6.0: - dependencies: - safe-buffer: 5.2.1 - optional: true - turbo@2.11.5: optionalDependencies: '@turbo/darwin-64': 2.11.5 diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index ecbd0f4bfde..d9b99fcddf1 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -187,7 +187,7 @@ patchedDependencies: # undici above). # IMPORTANT: these overrides do NOT ship with published packages — a # downstream `npx create-objectstack` install resolves plugin-auth's own -# declared ranges. plugin-auth therefore declares the same exact `1.7.2` +# declared ranges. plugin-auth therefore declares the same exact target # in its dependencies (a `^1.6.23` range there resolved to the broken # 1.6.23 mix and 500'd every fresh 15.1.0 project; a `^1.7.2` range there # resolved to 1.7.3 and made every fresh 17.1.0–17.3.0 project unloadable, @@ -238,12 +238,24 @@ overrides: # all. The selectors keep their `<2.0.0` major boundary, so lifting the # family later is still a target-only edit. # - # The target IS 1.7.3 since #17440: the platform adopted the vendor's + # The target was 1.7.3 from #17440: the platform adopted the vendor's # rollback rather than owning a fork of a model its author abandoned, so # nothing here imports the two deleted names any more and `sys_account` # no longer carries the column they served. What did NOT change is the rule - # above — the exact target stays exact for the reason 1.7.3 demonstrated, - # and 1.7.4 (published) is the next reviewed one-line lift, not a float. + # above — the exact target stays exact for the reason 1.7.3 demonstrated. + # + # The target IS 1.7.12 since #25096, a reviewed lift of the whole family at + # once, made for the security fixes published after 1.7.3 in packages + # plugin-auth mounts (GHSA-965c-763c-88jm and GHSA-r4xp-prcw-77qf in 1.7.7, + # and fixes in oauth-provider, sso, scim and core up to 1.7.12). Measured on + # the lift, not assumed: every symbol plugin-auth imports is still exported + # (`pnpm check:vendor-export-contract`), and only what the family pulls in + # moved with it: better-call 1.4.0 -> 1.4.4, @better-auth/utils 0.4.2 -> + # 0.5.0 (one copy left), @better-fetch/fetch 1.3.1 -> 1.3.2, and the copies + # 1.7.12 no longer asks for (the better-sqlite3 12 peer, + # @cloudflare/workers-types, core's @opentelemetry/semantic-conventions) + # left the lockfile. The 1.8 line is a separate decision; the next lift is + # again a reviewed edit, never a float. # # These targets are held EQUAL to the ranges `@objectstack/plugin-auth` # declares (`scripts/check-override-consistency.mjs` cross-checks that the @@ -251,8 +263,8 @@ overrides: # requires the declared range to be exact and to export what we import). # Move all eleven together, in one commit, or better-auth init throws and # every auth endpoint 500s. - 'better-auth@<2.0.0': '1.7.3' - '@better-auth/core@<2.0.0': '1.7.3' + 'better-auth@<2.0.0': '1.7.12' + '@better-auth/core@<2.0.0': '1.7.12' # scim carries the family's target — see the @better-auth/scim note # above. It was held at 1.7.1 EXACT, one deliberate step behind `^1.7.1`, # because `^1.7.1` then resolved scim to 1.7.2 while the installed family @@ -283,15 +295,15 @@ overrides: # a lift whose new version drops a symbol `plugin-auth` imports. # What stays true: the whole family still moves as ONE line, and a bump that # moves scim alone is still the mistake the #3653 ruling named. - '@better-auth/scim@<2.0.0': '1.7.3' - '@better-auth/oauth-provider@<2.0.0': '1.7.3' - '@better-auth/sso@<2.0.0': '1.7.3' - '@better-auth/drizzle-adapter@<2.0.0': '1.7.3' - '@better-auth/kysely-adapter@<2.0.0': '1.7.3' - '@better-auth/memory-adapter@<2.0.0': '1.7.3' - '@better-auth/mongo-adapter@<2.0.0': '1.7.3' - '@better-auth/prisma-adapter@<2.0.0': '1.7.3' - '@better-auth/telemetry@<2.0.0': '1.7.3' + '@better-auth/scim@<2.0.0': '1.7.12' + '@better-auth/oauth-provider@<2.0.0': '1.7.12' + '@better-auth/sso@<2.0.0': '1.7.12' + '@better-auth/drizzle-adapter@<2.0.0': '1.7.12' + '@better-auth/kysely-adapter@<2.0.0': '1.7.12' + '@better-auth/memory-adapter@<2.0.0': '1.7.12' + '@better-auth/mongo-adapter@<2.0.0': '1.7.12' + '@better-auth/prisma-adapter@<2.0.0': '1.7.12' + '@better-auth/telemetry@<2.0.0': '1.7.12' 'uuid@<12.0.0': '^11.1.1' 'postcss@<9.0.0': '^8.5.10' 'cookie@<0.8.0': '^0.7.0'