@better-auth/infra 0.4.0 → 0.4.1
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 +7 -0
- package/README.md +4 -0
- package/dist/client.d.mts +1 -2
- package/dist/client.mjs +9 -7
- package/dist/{constants-CcJHk5SE.mjs → constants-CtvGRrlI.mjs} +1 -1
- package/dist/{crypto-CAdWFWEz.mjs → crypto-CV91nSbp.mjs} +21 -6
- package/dist/email.mjs +1 -1
- package/dist/{identify-client-options-RI-JiXQx.d.mts → identify-client-options-CgijjwVT.d.mts} +1 -2
- package/dist/index.d.mts +3 -3
- package/dist/index.mjs +516 -452
- package/dist/native.d.mts +1 -2
- package/dist/native.mjs +7 -6
- package/dist/{pow-retry-DZhZiYd_.mjs → pow-retry-7sPi32Ow.mjs} +3 -2
- package/dist/{saml-policy-BTVLoTyS.mjs → saml-policy-DQR0MBLk.mjs} +2 -2
- package/dist/{types-B673lCib.d.mts → types-Ddk4r5x9.d.mts} +0 -1
- package/package.json +3 -2
package/CHANGELOG.md
CHANGED
|
@@ -5,8 +5,15 @@ 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.1] - 2026-08-19
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
|
|
12
|
+
- **React Native / Hermes crypto** — SHA-256 (including Sentinel PoW challenge solve/verify) no longer requires `crypto.subtle`. Prefers Web Crypto when present; otherwise falls back to `@noble/hashes`.
|
|
13
|
+
|
|
8
14
|
## [0.4.0] - 2026-08-14
|
|
9
15
|
|
|
16
|
+
|
|
10
17
|
### Added
|
|
11
18
|
|
|
12
19
|
- **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.
|
package/README.md
CHANGED
|
@@ -80,6 +80,10 @@ Use this plugin for your React Native / Expo app. This plugin is designed to wor
|
|
|
80
80
|
pnpm add react-native @react-native-async-storage/async-storage
|
|
81
81
|
# Optional, for richer device metadata in the identify payload:
|
|
82
82
|
pnpm add expo-constants expo-device
|
|
83
|
+
# Optional, secure visitor-id RNG (Expo):
|
|
84
|
+
pnpm add expo-crypto
|
|
85
|
+
# Or plain React Native — first import in the app entry:
|
|
86
|
+
# import "react-native-get-random-values";
|
|
83
87
|
```
|
|
84
88
|
|
|
85
89
|
`@react-native-async-storage/async-storage` is optional; if it is not installed, a session-only in-memory visitor id is used. For production, install it or pass `storage` (for example secure storage).
|
package/dist/client.d.mts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
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-
|
|
2
|
-
|
|
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-CgijjwVT.mjs";
|
|
3
2
|
//#region src/sentinel/client.d.ts
|
|
4
3
|
interface SentinelClientOptions {
|
|
5
4
|
/**
|
package/dist/client.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { n as hash, o as createKV } from "./crypto-
|
|
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-
|
|
1
|
+
import { n as hash, o as createKV } from "./crypto-CV91nSbp.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-7sPi32Ow.mjs";
|
|
3
3
|
import { env } from "@better-auth/core/env";
|
|
4
4
|
//#region src/sentinel/fingerprint.ts
|
|
5
5
|
function murmurhash3(str, seed = 0) {
|
|
@@ -325,7 +325,8 @@ async function generateVisitorId(components) {
|
|
|
325
325
|
fonts: components.fonts,
|
|
326
326
|
maxTouchPoints: components.maxTouchPoints
|
|
327
327
|
};
|
|
328
|
-
|
|
328
|
+
const dataString = JSON.stringify(stableData);
|
|
329
|
+
return (await hash(dataString)).slice(0, 20);
|
|
329
330
|
}
|
|
330
331
|
function calculateConfidence(components) {
|
|
331
332
|
const weights = {
|
|
@@ -435,11 +436,12 @@ function appendIdentification(headers, fingerprint) {
|
|
|
435
436
|
const MAX_POW_CHALLENGE_ROUNDS = 2;
|
|
436
437
|
const sentinelClient = (options) => {
|
|
437
438
|
const autoSolve = options?.autoSolveChallenge !== false;
|
|
439
|
+
const identifyUrl = resolveSentinelClientIdentifyUrl({
|
|
440
|
+
identifyUrl: options?.identifyUrl,
|
|
441
|
+
envKvUrl: env.BETTER_AUTH_KV_URL
|
|
442
|
+
});
|
|
438
443
|
const $kv = createKV({
|
|
439
|
-
kvUrl:
|
|
440
|
-
identifyUrl: options?.identifyUrl,
|
|
441
|
-
envKvUrl: env.BETTER_AUTH_KV_URL
|
|
442
|
-
}),
|
|
444
|
+
kvUrl: identifyUrl,
|
|
443
445
|
timeout: options?.identifyOptions?.timeout ?? options?.kvTimeout
|
|
444
446
|
}, {
|
|
445
447
|
throw: true,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { i as INFRA_USER_AGENT } from "./constants-
|
|
1
|
+
import { i as INFRA_USER_AGENT } from "./constants-CtvGRrlI.mjs";
|
|
2
2
|
import { createFetch } from "@better-fetch/fetch";
|
|
3
|
+
import { sha256 } from "@noble/hashes/sha2.js";
|
|
3
4
|
//#region src/fetch.ts
|
|
4
5
|
function createAPI(options, fetchOptions) {
|
|
5
6
|
return createFetch({
|
|
@@ -32,19 +33,33 @@ function randomBytes(length) {
|
|
|
32
33
|
function bytesToHex(bytes) {
|
|
33
34
|
return Array.from(bytes).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
34
35
|
}
|
|
36
|
+
function getSubtle() {
|
|
37
|
+
try {
|
|
38
|
+
const c = globalThis.crypto;
|
|
39
|
+
if (c && typeof c.subtle === "object" && c.subtle != null) return c.subtle;
|
|
40
|
+
} catch {}
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
/** SHA-256 hex digest. Prefers Web Crypto; falls back to `@noble/hashes`. */
|
|
35
44
|
async function hash(message) {
|
|
36
|
-
const
|
|
37
|
-
const
|
|
38
|
-
|
|
45
|
+
const data = new TextEncoder().encode(message);
|
|
46
|
+
const subtle = getSubtle();
|
|
47
|
+
if (subtle) {
|
|
48
|
+
const hashBuffer = await subtle.digest("SHA-256", data);
|
|
49
|
+
return bytesToHex(new Uint8Array(hashBuffer));
|
|
50
|
+
}
|
|
51
|
+
return bytesToHex(sha256(data));
|
|
39
52
|
}
|
|
40
53
|
/** Keyed HMAC-SHA256 for blinded fingerprints (e.g. failed-login passwords). */
|
|
41
54
|
async function hmacSha256Hex(key, message) {
|
|
42
55
|
const encoder = new TextEncoder();
|
|
43
|
-
const
|
|
56
|
+
const subtle = getSubtle();
|
|
57
|
+
if (!subtle) throw new Error("[@better-auth/infra] crypto.subtle is required for HMAC-SHA256");
|
|
58
|
+
const cryptoKey = await subtle.importKey("raw", encoder.encode(key), {
|
|
44
59
|
name: "HMAC",
|
|
45
60
|
hash: "SHA-256"
|
|
46
61
|
}, false, ["sign"]);
|
|
47
|
-
const signature = await
|
|
62
|
+
const signature = await subtle.sign("HMAC", cryptoKey, encoder.encode(message));
|
|
48
63
|
return bytesToHex(new Uint8Array(signature));
|
|
49
64
|
}
|
|
50
65
|
//#endregion
|
package/dist/email.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { i as INFRA_USER_AGENT, n as INFRA_API_URL } from "./constants-
|
|
1
|
+
import { i as INFRA_USER_AGENT, n as INFRA_API_URL } from "./constants-CtvGRrlI.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";
|
package/dist/{identify-client-options-RI-JiXQx.d.mts → identify-client-options-CgijjwVT.d.mts}
RENAMED
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import { m as KvRetryOptions } from "./types-
|
|
1
|
+
import { m as KvRetryOptions } from "./types-Ddk4r5x9.mjs";
|
|
2
2
|
import { BetterAuthClientOptions, ClientStore } from "better-auth";
|
|
3
3
|
import { BetterFetch } from "@better-fetch/fetch";
|
|
4
|
-
|
|
5
4
|
//#region src/dash-client.d.ts
|
|
6
5
|
interface DashAuditLog {
|
|
7
6
|
eventType: string;
|
package/dist/index.d.mts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { C as ImpossibleTravelResult, D as SecurityVerdict, E as SecurityOptions, O as StaleUserResult, S as CredentialStuffingResult, T as SecurityEventType, _ as LocationDataContext, a as DashOptionsInternal, b as sentinel, c as EndpointOptions, d as InfraPluginConnectionOptionsInternal, f as KvOptions, g as LocationData, h as KvRetryOptionsResolved, i as DashOptions, k as ThresholdConfig, l as InfraEndpointContext, m as KvRetryOptions, n as ApiOptions, o as DashOptionsResolved, p as KvOptionsResolved, r as ApiOptionsResolved, s as Endpoint, t as APIError, u as InfraPluginConnectionOptions, v as SentinelOptions, w as SecurityEvent, x as CompromisedPasswordResult, y as SentinelOptionsInternal } from "./types-
|
|
1
|
+
import { C as ImpossibleTravelResult, D as SecurityVerdict, E as SecurityOptions, O as StaleUserResult, S as CredentialStuffingResult, T as SecurityEventType, _ as LocationDataContext, a as DashOptionsInternal, b as sentinel, c as EndpointOptions, d as InfraPluginConnectionOptionsInternal, f as KvOptions, g as LocationData, h as KvRetryOptionsResolved, i as DashOptions, k as ThresholdConfig, l as InfraEndpointContext, m as KvRetryOptions, n as ApiOptions, o as DashOptionsResolved, p as KvOptionsResolved, r as ApiOptionsResolved, s as Endpoint, t as APIError, u as InfraPluginConnectionOptions, v as SentinelOptions, w as SecurityEvent, x as CompromisedPasswordResult, y as SentinelOptionsInternal } from "./types-Ddk4r5x9.mjs";
|
|
2
2
|
import { EMAIL_TEMPLATES, EmailConfig, EmailTemplateId, EmailTemplateVariables, SendBulkEmailsOptions, SendBulkEmailsResult, SendEmailOptions, SendEmailResult, createEmailSender, sendBulkEmails, sendEmail } from "./email.mjs";
|
|
3
3
|
import { Account, AuthContext, GenericEndpointContext, Session, User } from "better-auth";
|
|
4
|
-
import z
|
|
4
|
+
import z from "zod";
|
|
5
5
|
import { DBFieldAttribute } from "better-auth/db";
|
|
6
6
|
import { Invitation, Member, Organization, Team, TeamMember } from "better-auth/plugins";
|
|
7
|
+
import "better-auth/types";
|
|
7
8
|
export type * from "better-call";
|
|
8
|
-
|
|
9
9
|
//#region src/pow.d.ts
|
|
10
10
|
/**
|
|
11
11
|
* Proof of Work Challenge System - Client Side
|