@better-auth/infra 0.3.7 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -5,6 +5,29 @@ All notable changes to `@better-auth/infra` are documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [0.4.0] - 2026-08-14
9
+
10
+ ### Added
11
+
12
+ - **Managed SCIM directory sync** — Opt-in `dash({ managedDirectorySync: { enabled: true } })` control plane for Better Auth 1.7+ managed connections. Adds dashboard lifecycle endpoints to create, list, get, rotate credentials, revoke credentials, list events, unpair, and decommission organization directories, plus schema for `directorySyncConnection` / membership provenance, optional SSO pairing hooks, and SCIM → organization membership projection.
13
+ - **Issuer-scoped accounts** — Dashboard user create, set-password, and account unlink paths work with Better Auth 1.7 issuer-scoped account identity (`issuer` + subject) while remaining compatible with pre-issuer schemas.
14
+ - **Configurable API / KV client options** — Shared `apiOptions` / `kvOptions` (timeout and KV retry/backoff) on `dash` and `sentinel`. Legacy `apiTimeout` / `kvTimeout` remain supported as deprecated aliases.
15
+ - **`GET /dash/config` joins insight** — Config insights report `hasJoinsEnabled` from `advanced.database.joins` (and pre-1.7 `experimental.joins` when applicable).
16
+
17
+ ### Changed
18
+
19
+ - **Better Auth 1.7 RC compatibility** — Support matrix and runtime paths updated through 1.7 rc.4 (issuer-scoped accounts, session lifecycle hooks, SSO domain verification contracts).
20
+ - **SSO domain verification TXT records** — Dashboard domain verification uses the SSO plugin `tokenPrefix` and the `_` + prefix + provider id TXT name shape expected by Better Auth domain verification.
21
+ - **Session lifecycle event tracking** — Sign-in / session-created / impersonation tracking deferred correctly when session creation runs before the user is available on the request context (Better Auth 1.7 rc.2+).
22
+ - **Directory list mode split** — Legacy pre-1.7 SCIM provider listing stays on the legacy surface; managed connection APIs only run when managed directory sync is enabled.
23
+ - **Account unlink body** — `unlinkAccount` requires `accountId` (local account row id) together with `providerId`.
24
+
25
+ ### Fixed
26
+
27
+ - **SSO domain verify errors** — `verify-domain` maps provider-changed, already-verified, and missing-DNS cases to stable dashboard responses instead of leaking raw API errors.
28
+ - **Sentinel stale-account handling** — Stale-user blocks clear the session cookie and surface a consistent `STALE_ACCOUNT` error after the endpoint runs, not only inside DB hooks.
29
+ - **SCIM token redaction** — Sensitive SCIM credential fields stay redacted in dash config / plugin option dumps.
30
+
8
31
  ## [0.3.7] - 2026-07-20
9
32
 
10
33
  ### Added
@@ -144,6 +167,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
144
167
 
145
168
  [0.3.7]: https://github.com/better-auth/infrastructure/compare/infra@v0.3.6...infra@v0.3.7
146
169
  [0.3.6]: https://github.com/better-auth/infrastructure/compare/infra@v0.3.5...infra@v0.3.6
170
+ [0.4.0]: https://github.com/better-auth/infrastructure/compare/infra@v0.3.7...infra@v0.4.0
147
171
  [0.3.5]: https://github.com/better-auth/infrastructure/compare/infra@v0.3.4...infra@v0.3.5
148
172
  [0.3.4]: https://github.com/better-auth/infrastructure/compare/infra@v0.3.3...infra@v0.3.4
149
173
  [0.3.3]: https://github.com/better-auth/infrastructure/compare/infra@v0.3.2...infra@v0.3.3
package/README.md CHANGED
@@ -104,7 +104,9 @@ export const authClient = createAuthClient({
104
104
 
105
105
  ### Options (`sentinelNativeClient`)
106
106
 
107
- - `identifyUrl?: string` — KV identify endpoint base (defaults to `BETTER_AUTH_KV_URL` from env, then `https://kv.better-auth.com`).
107
+ - `identifyUrl?: string` — identify endpoint base (defaults to `BETTER_AUTH_KV_URL` from env, then `https://kv.better-auth.com`).
108
+ - `identifyOptions?: { timeout?: number; retry?: { attempts?: number; baseDelay?: number; maxDelay?: number } }` — identify HTTP timeout (ms, default `1000`) and POST retry (defaults `2` / `400` / `600`).
109
+ - `kvTimeout?: number` — **deprecated**, use `identifyOptions.timeout`.
108
110
  - `autoSolveChallenge?: boolean` — When `true` (default), `423` responses that include `X-PoW-Challenge` are solved and the request is retried once with `X-PoW-Solution`.
109
111
  - `onChallengeReceived?` / `onChallengeSolved?` / `onChallengeFailed?` — PoW lifecycle hooks (reason string, solve time in ms, or error).
110
112
  - `storage?: { getItem, setItem }` — Async key/value storage for a stable per-install visitor id (recommended for production).
@@ -270,7 +272,12 @@ The `dash()` plugin registers these event endpoints:
270
272
  - `apiUrl?: string`
271
273
  - `kvUrl?: string`
272
274
  - `apiKey?: string`
275
+ - `apiOptions?: { timeout?: number }` (ms, default `3000`)
276
+ - `kvOptions?: { timeout?: number; retry?: { attempts?: number; baseDelay?: number; maxDelay?: number } }` — KV timeout default `1000`; retry defaults `2` / `400` / `600`
277
+ - `apiTimeout?: number` — **deprecated**, use `apiOptions.timeout`
278
+ - `kvTimeout?: number` — **deprecated**, use `kvOptions.timeout`
273
279
  - `activityTracking?: { enabled?: boolean; updateInterval?: number }`
280
+ - `managedDirectorySync?: { enabled?: boolean; ssoPairing?: boolean; membershipProjection?: { enabled?: boolean; role?: string } }` — opt into the 1.7+ managed directory-sync control plane (schema + reservation APIs). `enabled` alone turns on reservation tables/APIs. When enabled, dash `init` can also wire sibling-plugin callbacks: `ssoPairing` installs SSO `resolveUser` / `guardProviderMutation` (needed only for paired directories; requires `sso({})` or richer options — bare `sso()` leaves `options` undefined), and `membershipProjection` installs SCIM `projection.reconcileUser` for org membership sync. Defaults: `enabled: false`, `ssoPairing: true`, `membershipProjection.enabled: true`, `membershipProjection.role: "member"`. Required with `scim({ managedConnections })` for managed mode; does not affect or replace legacy pre-1.7 SCIM directory sync.
274
281
 
275
282
  `dash()` no longer accepts sentinel security config.
276
283
 
@@ -279,6 +286,10 @@ The `dash()` plugin registers these event endpoints:
279
286
  - `apiUrl?: string`
280
287
  - `kvUrl?: string`
281
288
  - `apiKey?: string`
289
+ - `apiOptions?: { timeout?: number }` — same as `DashOptions`
290
+ - `kvOptions?: { timeout?: number; retry?: { attempts?: number; baseDelay?: number; maxDelay?: number } }` — same as `DashOptions`
291
+ - `apiTimeout?: number` — **deprecated**, use `apiOptions.timeout`
292
+ - `kvTimeout?: number` — **deprecated**, use `kvOptions.timeout`
282
293
  - `security?: SecurityOptions`
283
294
 
284
295
  All security configuration now belongs in `sentinel()`.
package/dist/client.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { a as DashGetAuditLogsInput, i as DashGetAllAuditLogsInput, n as DashAuditLogsResponse, o as dashClient, r as DashClientOptions, t as DashAuditLog } from "./dash-client-DXuu2ctl.mjs";
1
+ import { a as DashGetAllAuditLogsInput, i as DashClientOptions, n as DashAuditLog, o as DashGetAuditLogsInput, r as DashAuditLogsResponse, s as dashClient, t as IdentifyClientOptions } from "./identify-client-options-RI-JiXQx.mjs";
2
2
 
3
3
  //#region src/sentinel/client.d.ts
4
4
  interface SentinelClientOptions {
@@ -8,8 +8,13 @@ interface SentinelClientOptions {
8
8
  */
9
9
  identifyUrl?: string;
10
10
  /**
11
- * Timeout for KV identify and related HTTP requests (milliseconds).
11
+ * Identify HTTP client options.
12
+ */
13
+ identifyOptions?: IdentifyClientOptions;
14
+ /**
15
+ * Timeout for identify and related HTTP requests (milliseconds).
12
16
  * @default 1000
17
+ * @deprecated Use `identifyOptions.timeout` instead.
13
18
  */
14
19
  kvTimeout?: number;
15
20
  /**
package/dist/client.mjs CHANGED
@@ -1,5 +1,5 @@
1
- import { n as hash, o as createKV } from "./crypto--3ycICW4.mjs";
2
- import { a as resolveSentinelClientIdentifyUrl, c as dashClient, i as solvePoWChallenge, n as decodePoWChallenge, o as generateRequestId, r as encodePoWSolution, s as identify, t as createPowRetryTimeout } from "./pow-retry-Dy1D-TKx.mjs";
1
+ import { n as hash, o as createKV } from "./crypto-CAdWFWEz.mjs";
2
+ import { a as resolveSentinelClientIdentifyUrl, c as identify, i as solvePoWChallenge, l as dashClient, n as decodePoWChallenge, o as resolveIdentifyClientRetry, r as encodePoWSolution, s as generateRequestId, t as createPowRetryTimeout } from "./pow-retry-DZhZiYd_.mjs";
3
3
  import { env } from "@better-auth/core/env";
4
4
  //#region src/sentinel/fingerprint.ts
5
5
  function murmurhash3(str, seed = 0) {
@@ -440,20 +440,10 @@ const sentinelClient = (options) => {
440
440
  identifyUrl: options?.identifyUrl,
441
441
  envKvUrl: env.BETTER_AUTH_KV_URL
442
442
  }),
443
- kvTimeout: options?.kvTimeout
443
+ timeout: options?.identifyOptions?.timeout ?? options?.kvTimeout
444
444
  }, {
445
445
  throw: true,
446
- retry: {
447
- type: "exponential",
448
- attempts: 2,
449
- baseDelay: 400,
450
- maxDelay: 600,
451
- shouldRetry(response) {
452
- if (response === null) return true;
453
- if (response.status === 429) return true;
454
- return response.status >= 500;
455
- }
456
- }
446
+ retry: resolveIdentifyClientRetry(options?.identifyOptions?.retry)
457
447
  });
458
448
  if (typeof window !== "undefined") {
459
449
  const scheduleIdentify = () => {
@@ -1,7 +1,7 @@
1
1
  import { env } from "@better-auth/core/env";
2
2
  //#endregion
3
3
  //#region src/version.ts
4
- const PLUGIN_VERSION = "0.3.7";
4
+ const PLUGIN_VERSION = "0.4.0";
5
5
  //#endregion
6
6
  //#region src/constants.ts
7
7
  /**
@@ -1,4 +1,4 @@
1
- import { i as INFRA_USER_AGENT } from "./constants-AfApXLhx.mjs";
1
+ import { i as INFRA_USER_AGENT } from "./constants-CcJHk5SE.mjs";
2
2
  import { createFetch } from "@better-fetch/fetch";
3
3
  //#region src/fetch.ts
4
4
  function createAPI(options, fetchOptions) {
@@ -8,7 +8,7 @@ function createAPI(options, fetchOptions) {
8
8
  "user-agent": INFRA_USER_AGENT,
9
9
  "x-api-key": options.apiKey
10
10
  },
11
- timeout: options.apiTimeout,
11
+ timeout: options.apiOptions.timeout,
12
12
  ...fetchOptions
13
13
  });
14
14
  }
@@ -18,7 +18,7 @@ function createKV(options, fetchOptions) {
18
18
  return createFetch({
19
19
  baseURL: options.kvUrl,
20
20
  headers,
21
- timeout: options.kvTimeout ?? 1e3,
21
+ timeout: options.timeout ?? 1e3,
22
22
  ...fetchOptions
23
23
  });
24
24
  }
package/dist/email.d.mts CHANGED
@@ -146,9 +146,20 @@ interface SendEmailResult {
146
146
  interface EmailConfig {
147
147
  apiKey?: string;
148
148
  apiUrl?: string;
149
+ /**
150
+ * Dash API HTTP client options.
151
+ */
152
+ apiOptions?: {
153
+ /**
154
+ * Timeout for Dash email API HTTP requests (milliseconds).
155
+ * @default 3000
156
+ */
157
+ timeout?: number;
158
+ };
149
159
  /**
150
160
  * Timeout for Dash email API HTTP requests (milliseconds).
151
161
  * @default 3000
162
+ * @deprecated Use `apiOptions.timeout` instead.
152
163
  */
153
164
  apiTimeout?: number;
154
165
  }
package/dist/email.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { i as INFRA_USER_AGENT, n as INFRA_API_URL } from "./constants-AfApXLhx.mjs";
1
+ import { i as INFRA_USER_AGENT, n as INFRA_API_URL } from "./constants-CcJHk5SE.mjs";
2
2
  import { logger } from "better-auth";
3
3
  import { env } from "@better-auth/core/env";
4
4
  import { createFetch } from "@better-fetch/fetch";
@@ -41,7 +41,7 @@ function createEmailSender(config) {
41
41
  "user-agent": INFRA_USER_AGENT,
42
42
  Authorization: `Bearer ${apiKey}`
43
43
  },
44
- timeout: config?.apiTimeout ?? 3e3
44
+ timeout: config?.apiOptions?.timeout ?? config?.apiTimeout ?? 3e3
45
45
  });
46
46
  /**
47
47
  * Send an email using a template from Better Auth Infra
@@ -1,3 +1,4 @@
1
+ import { m as KvRetryOptions } from "./types-B673lCib.mjs";
1
2
  import { BetterAuthClientOptions, ClientStore } from "better-auth";
2
3
  import { BetterFetch } from "@better-fetch/fetch";
3
4
 
@@ -91,4 +92,18 @@ declare const dashClient: (options?: DashClientOptions) => {
91
92
  };
92
93
  };
93
94
  //#endregion
94
- export { DashGetAuditLogsInput as a, DashGetAllAuditLogsInput as i, DashAuditLogsResponse as n, dashClient as o, DashClientOptions as r, DashAuditLog as t };
95
+ //#region src/sentinel/identify-client-options.d.ts
96
+ type IdentifyClientOptions = {
97
+ /**
98
+ * Timeout for identify and related HTTP requests (milliseconds).
99
+ * @default 1000
100
+ */
101
+ timeout?: number;
102
+ /**
103
+ * Retry/backoff for identify POST requests.
104
+ * @default { attempts: 2, baseDelay: 400, maxDelay: 600 }
105
+ */
106
+ retry?: KvRetryOptions;
107
+ };
108
+ //#endregion
109
+ export { DashGetAllAuditLogsInput as a, DashClientOptions as i, DashAuditLog as n, DashGetAuditLogsInput as o, DashAuditLogsResponse as r, dashClient as s, IdentifyClientOptions as t };