@better-auth/expo 1.7.3 → 1.7.5
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/dist/client.d.ts +34 -29
- package/dist/client.js +366 -222
- package/dist/index.js +1 -1
- package/dist/plugins/index.js +1 -1
- package/dist/{version-DddGjO8z.js → version-Db7MRDhd.js} +1 -1
- package/package.json +7 -7
package/dist/client.d.ts
CHANGED
|
@@ -5,6 +5,35 @@ import * as _$_better_fetch_fetch0 from "@better-fetch/fetch";
|
|
|
5
5
|
import { ClientFetchOption, ClientStore } from "@better-auth/core";
|
|
6
6
|
import * as SecureStore from "expo-secure-store";
|
|
7
7
|
|
|
8
|
+
//#region src/client-storage.d.ts
|
|
9
|
+
/**
|
|
10
|
+
* Storage used by the Expo client for cookies and cached session data.
|
|
11
|
+
* Async access is coordinated through the provided object, so reuse it across
|
|
12
|
+
* clients that access the same stored data.
|
|
13
|
+
*/
|
|
14
|
+
type ExpoClientStorage = Pick<typeof SecureStore, "setItem" | "setItemAsync" | "getItem" | "getItemAsync">;
|
|
15
|
+
/**
|
|
16
|
+
* Expo secure store does not support colons in the keys.
|
|
17
|
+
* This function replaces colons with underscores.
|
|
18
|
+
*
|
|
19
|
+
* @see https://github.com/better-auth/better-auth/issues/5426
|
|
20
|
+
*
|
|
21
|
+
* @param name cookie name to be saved in the storage
|
|
22
|
+
* @returns normalized cookie name
|
|
23
|
+
*/
|
|
24
|
+
declare function normalizeCookieName(name: string): string;
|
|
25
|
+
interface ExpoStorageAdapter {
|
|
26
|
+
getItem(name: string): string | null;
|
|
27
|
+
getItemAsync(name: string): Promise<string | null>;
|
|
28
|
+
setItem(name: string, value: string): void;
|
|
29
|
+
setItemAsync(name: string, value: string): Promise<void>;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Wraps Expo storage with chunking, recoverable writes, and serialized async
|
|
33
|
+
* access.
|
|
34
|
+
*/
|
|
35
|
+
declare function storageAdapter(storage: ExpoClientStorage): ExpoStorageAdapter;
|
|
36
|
+
//#endregion
|
|
8
37
|
//#region src/focus-manager.d.ts
|
|
9
38
|
declare function setupExpoFocusManager(): FocusManager;
|
|
10
39
|
//#endregion
|
|
@@ -12,12 +41,6 @@ declare function setupExpoFocusManager(): FocusManager;
|
|
|
12
41
|
declare function setupExpoOnlineManager(): OnlineManager;
|
|
13
42
|
//#endregion
|
|
14
43
|
//#region src/client.d.ts
|
|
15
|
-
/**
|
|
16
|
-
* Storage used by the Expo client for cookies and cached session data.
|
|
17
|
-
* Write coordination is scoped to the provided object, so reuse it across
|
|
18
|
-
* clients that access the same stored data.
|
|
19
|
-
*/
|
|
20
|
-
type ExpoClientStorage = Pick<typeof SecureStore, "setItem" | "setItemAsync" | "getItem" | "getItemAsync">;
|
|
21
44
|
interface ExpoClientOptions {
|
|
22
45
|
scheme?: string | undefined;
|
|
23
46
|
storage: ExpoClientStorage;
|
|
@@ -76,27 +99,6 @@ declare function getCookie(cookie: string | null): string;
|
|
|
76
99
|
* @returns true if the header contains better-auth cookies, false otherwise
|
|
77
100
|
*/
|
|
78
101
|
declare function hasBetterAuthCookies(setCookieHeader: string, cookiePrefix: string | string[]): boolean;
|
|
79
|
-
/**
|
|
80
|
-
* Expo secure store does not support colons in the keys.
|
|
81
|
-
* This function replaces colons with underscores.
|
|
82
|
-
*
|
|
83
|
-
* @see https://github.com/better-auth/better-auth/issues/5426
|
|
84
|
-
*
|
|
85
|
-
* @param name cookie name to be saved in the storage
|
|
86
|
-
* @returns normalized cookie name
|
|
87
|
-
*/
|
|
88
|
-
declare function normalizeCookieName(name: string): string;
|
|
89
|
-
interface ExpoStorageAdapter {
|
|
90
|
-
getItem(name: string): string | null;
|
|
91
|
-
getItemAsync(name: string): Promise<string | null>;
|
|
92
|
-
setItem(name: string, value: string): void;
|
|
93
|
-
setItemAsync(name: string, value: string): Promise<void>;
|
|
94
|
-
}
|
|
95
|
-
/**
|
|
96
|
-
* Wraps Expo storage with chunking, recoverable writes, and serialized async
|
|
97
|
-
* updates.
|
|
98
|
-
*/
|
|
99
|
-
declare function storageAdapter(storage: ExpoClientStorage): ExpoStorageAdapter;
|
|
100
102
|
declare const expoClient: (opts: ExpoClientOptions) => {
|
|
101
103
|
id: "expo";
|
|
102
104
|
version: string;
|
|
@@ -123,7 +125,6 @@ declare const expoClient: (opts: ExpoClientOptions) => {
|
|
|
123
125
|
onSuccess(context: _$_better_fetch_fetch0.SuccessContext<any>): Promise<void>;
|
|
124
126
|
};
|
|
125
127
|
init(url: string, options: ({
|
|
126
|
-
priority?: RequestPriority | undefined;
|
|
127
128
|
method?: string | undefined;
|
|
128
129
|
redirect?: RequestRedirect | undefined;
|
|
129
130
|
window?: null | undefined;
|
|
@@ -132,9 +133,11 @@ declare const expoClient: (opts: ExpoClientOptions) => {
|
|
|
132
133
|
integrity?: string | undefined;
|
|
133
134
|
keepalive?: boolean | undefined;
|
|
134
135
|
mode?: RequestMode | undefined;
|
|
136
|
+
priority?: RequestPriority | undefined;
|
|
135
137
|
referrer?: string | undefined;
|
|
136
138
|
referrerPolicy?: ReferrerPolicy | undefined;
|
|
137
139
|
signal?: (AbortSignal | null) | undefined;
|
|
140
|
+
} & {
|
|
138
141
|
onRequest?: (<T extends Record<string, any>>(context: _$_better_fetch_fetch0.RequestContext<T>) => Promise<_$_better_fetch_fetch0.RequestContext | void> | _$_better_fetch_fetch0.RequestContext | void) | undefined;
|
|
139
142
|
onResponse?: ((context: _$_better_fetch_fetch0.ResponseContext) => Promise<Response | void | _$_better_fetch_fetch0.ResponseContext> | Response | _$_better_fetch_fetch0.ResponseContext | void) | undefined;
|
|
140
143
|
onSuccess?: ((context: _$_better_fetch_fetch0.SuccessContext<any>) => Promise<void> | void) | undefined;
|
|
@@ -173,9 +176,11 @@ declare const expoClient: (opts: ExpoClientOptions) => {
|
|
|
173
176
|
jsonParser?: ((text: string) => Promise<any> | any) | undefined;
|
|
174
177
|
retry?: _$_better_fetch_fetch0.RetryOptions | undefined;
|
|
175
178
|
retryAttempt?: number | undefined;
|
|
179
|
+
method?: ("POST" | "PUT" | "DELETE" | "PATCH" | "GET" | "HEAD" | "OPTIONS" | (string & {})) | undefined;
|
|
176
180
|
output?: (_$_better_fetch_fetch0.StandardSchemaV1 | typeof Blob | typeof File) | undefined;
|
|
177
181
|
errorSchema?: _$_better_fetch_fetch0.StandardSchemaV1 | undefined;
|
|
178
182
|
disableValidation?: boolean | undefined;
|
|
183
|
+
signal?: (AbortSignal | null) | undefined;
|
|
179
184
|
} & Record<string, any>) | undefined): Promise<{
|
|
180
185
|
url: string;
|
|
181
186
|
options: ClientFetchOption;
|
|
@@ -183,4 +188,4 @@ declare const expoClient: (opts: ExpoClientOptions) => {
|
|
|
183
188
|
}[];
|
|
184
189
|
};
|
|
185
190
|
//#endregion
|
|
186
|
-
export { ExpoClientStorage, expoClient, getCookie, getSetCookie, hasBetterAuthCookies, normalizeCookieName, parseSetCookieHeader, setupExpoFocusManager, setupExpoOnlineManager, storageAdapter };
|
|
191
|
+
export { type ExpoClientStorage, expoClient, getCookie, getSetCookie, hasBetterAuthCookies, normalizeCookieName, parseSetCookieHeader, setupExpoFocusManager, setupExpoOnlineManager, storageAdapter };
|
package/dist/client.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import { t as PACKAGE_VERSION } from "./version-
|
|
1
|
+
import { t as PACKAGE_VERSION } from "./version-Db7MRDhd.js";
|
|
2
2
|
import { safeJSONParse } from "@better-auth/core/utils/json";
|
|
3
3
|
import { SECURE_COOKIE_PREFIX, parseSetCookieHeader, parseSetCookieHeader as parseSetCookieHeader$1, stripSecureCookiePrefix } from "better-auth/cookies/utils";
|
|
4
4
|
import Constants from "expo-constants";
|
|
5
5
|
import * as Linking from "expo-linking";
|
|
6
6
|
import { AppState, Platform } from "react-native";
|
|
7
|
+
import { logger } from "@better-auth/core/env";
|
|
7
8
|
import { kFocusManager, kOnlineManager } from "better-auth/client";
|
|
8
9
|
//#region \0rolldown/runtime.js
|
|
9
10
|
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, { get: (a, b) => (typeof require !== "undefined" ? require : a)[b] }) : x)(function(x) {
|
|
@@ -11,178 +12,7 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
|
|
|
11
12
|
throw Error("Calling `require` for \"" + x + "\" in an environment that doesn't expose the `require` function. See https://rolldown.rs/in-depth/bundling-cjs#require-external-modules for more details.");
|
|
12
13
|
});
|
|
13
14
|
//#endregion
|
|
14
|
-
//#region src/
|
|
15
|
-
var ExpoFocusManager = class {
|
|
16
|
-
listeners = /* @__PURE__ */ new Set();
|
|
17
|
-
subscription;
|
|
18
|
-
isFocused;
|
|
19
|
-
subscribe(listener) {
|
|
20
|
-
this.listeners.add(listener);
|
|
21
|
-
return () => {
|
|
22
|
-
this.listeners.delete(listener);
|
|
23
|
-
};
|
|
24
|
-
}
|
|
25
|
-
setFocused(focused) {
|
|
26
|
-
if (this.isFocused === focused) return;
|
|
27
|
-
this.isFocused = focused;
|
|
28
|
-
this.listeners.forEach((listener) => listener(focused));
|
|
29
|
-
}
|
|
30
|
-
setup() {
|
|
31
|
-
this.subscription = AppState.addEventListener("change", (state) => {
|
|
32
|
-
this.setFocused(state === "active");
|
|
33
|
-
});
|
|
34
|
-
return () => {
|
|
35
|
-
this.subscription?.remove();
|
|
36
|
-
};
|
|
37
|
-
}
|
|
38
|
-
};
|
|
39
|
-
function setupExpoFocusManager() {
|
|
40
|
-
if (!globalThis[kFocusManager]) globalThis[kFocusManager] = new ExpoFocusManager();
|
|
41
|
-
return globalThis[kFocusManager];
|
|
42
|
-
}
|
|
43
|
-
//#endregion
|
|
44
|
-
//#region src/online-manager.ts
|
|
45
|
-
var ExpoOnlineManager = class {
|
|
46
|
-
listeners = /* @__PURE__ */ new Set();
|
|
47
|
-
isOnline = true;
|
|
48
|
-
unsubscribe;
|
|
49
|
-
subscribe(listener) {
|
|
50
|
-
this.listeners.add(listener);
|
|
51
|
-
return () => {
|
|
52
|
-
this.listeners.delete(listener);
|
|
53
|
-
};
|
|
54
|
-
}
|
|
55
|
-
setOnline(online) {
|
|
56
|
-
if (this.isOnline === online) return;
|
|
57
|
-
this.isOnline = online;
|
|
58
|
-
this.listeners.forEach((listener) => listener(online));
|
|
59
|
-
}
|
|
60
|
-
setup() {
|
|
61
|
-
import("expo-network").then(({ addNetworkStateListener }) => {
|
|
62
|
-
const subscription = addNetworkStateListener((state) => {
|
|
63
|
-
this.setOnline(!!state.isInternetReachable);
|
|
64
|
-
});
|
|
65
|
-
this.unsubscribe = () => subscription.remove();
|
|
66
|
-
}).catch(() => {
|
|
67
|
-
this.setOnline(true);
|
|
68
|
-
});
|
|
69
|
-
return () => {
|
|
70
|
-
this.unsubscribe?.();
|
|
71
|
-
};
|
|
72
|
-
}
|
|
73
|
-
};
|
|
74
|
-
function setupExpoOnlineManager() {
|
|
75
|
-
if (!globalThis[kOnlineManager]) globalThis[kOnlineManager] = new ExpoOnlineManager();
|
|
76
|
-
return globalThis[kOnlineManager];
|
|
77
|
-
}
|
|
78
|
-
//#endregion
|
|
79
|
-
//#region src/client.ts
|
|
80
|
-
if (Platform.OS !== "web") {
|
|
81
|
-
setupExpoFocusManager();
|
|
82
|
-
setupExpoOnlineManager();
|
|
83
|
-
}
|
|
84
|
-
function defineExpoClientPlugin(plugin) {
|
|
85
|
-
return plugin;
|
|
86
|
-
}
|
|
87
|
-
function getSetCookie(header, prevCookie) {
|
|
88
|
-
const parsed = parseSetCookieHeader$1(header);
|
|
89
|
-
const toSetCookie = safeJSONParse(prevCookie) ?? {};
|
|
90
|
-
parsed.forEach((cookie, key) => {
|
|
91
|
-
const expiresAt = cookie["expires"];
|
|
92
|
-
const maxAge = cookie["max-age"];
|
|
93
|
-
if (maxAge !== void 0 && Number(maxAge) <= 0) {
|
|
94
|
-
delete toSetCookie[key];
|
|
95
|
-
return;
|
|
96
|
-
}
|
|
97
|
-
const expires = maxAge ? new Date(Date.now() + Number(maxAge) * 1e3) : expiresAt ? new Date(String(expiresAt)) : null;
|
|
98
|
-
if (expires && expires.getTime() <= Date.now()) {
|
|
99
|
-
delete toSetCookie[key];
|
|
100
|
-
return;
|
|
101
|
-
}
|
|
102
|
-
toSetCookie[key] = {
|
|
103
|
-
value: cookie["value"],
|
|
104
|
-
expires: expires ? expires.toISOString() : null
|
|
105
|
-
};
|
|
106
|
-
});
|
|
107
|
-
return JSON.stringify(toSetCookie);
|
|
108
|
-
}
|
|
109
|
-
function getCookie(cookie) {
|
|
110
|
-
const parsed = safeJSONParse(cookie) ?? {};
|
|
111
|
-
return Object.entries(parsed).reduce((acc, [key, value]) => {
|
|
112
|
-
if (value.expires && new Date(value.expires) < /* @__PURE__ */ new Date()) return acc;
|
|
113
|
-
return acc ? `${acc}; ${key}=${value.value}` : `${key}=${value.value}`;
|
|
114
|
-
}, "");
|
|
115
|
-
}
|
|
116
|
-
function getOAuthStateValue(cookieJson, cookiePrefix) {
|
|
117
|
-
if (!cookieJson) return null;
|
|
118
|
-
const parsed = safeJSONParse(cookieJson);
|
|
119
|
-
if (!parsed) return null;
|
|
120
|
-
const prefixes = Array.isArray(cookiePrefix) ? cookiePrefix : [cookiePrefix];
|
|
121
|
-
for (const prefix of prefixes) {
|
|
122
|
-
const candidates = [`${SECURE_COOKIE_PREFIX}${prefix}.oauth_state`, `${prefix}.oauth_state`];
|
|
123
|
-
for (const name of candidates) {
|
|
124
|
-
const value = parsed?.[name]?.value;
|
|
125
|
-
if (value) return value;
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
return null;
|
|
129
|
-
}
|
|
130
|
-
function getOrigin(scheme) {
|
|
131
|
-
return Linking.createURL("", { scheme });
|
|
132
|
-
}
|
|
133
|
-
/**
|
|
134
|
-
* Compare if session cookies have actually changed by comparing their values.
|
|
135
|
-
* Ignores expiry timestamps that naturally change on each request.
|
|
136
|
-
*
|
|
137
|
-
* @param prevCookie - Previous cookie JSON string
|
|
138
|
-
* @param newCookie - New cookie JSON string
|
|
139
|
-
* @returns true if session cookies have changed, false otherwise
|
|
140
|
-
*/
|
|
141
|
-
function hasSessionCookieChanged(prevCookie, newCookie) {
|
|
142
|
-
if (!prevCookie) return true;
|
|
143
|
-
try {
|
|
144
|
-
const prev = JSON.parse(prevCookie);
|
|
145
|
-
const next = JSON.parse(newCookie);
|
|
146
|
-
const sessionKeys = /* @__PURE__ */ new Set();
|
|
147
|
-
Object.keys(prev).forEach((key) => {
|
|
148
|
-
if (key.includes("session_token") || key.includes("session_data")) sessionKeys.add(key);
|
|
149
|
-
});
|
|
150
|
-
Object.keys(next).forEach((key) => {
|
|
151
|
-
if (key.includes("session_token") || key.includes("session_data")) sessionKeys.add(key);
|
|
152
|
-
});
|
|
153
|
-
for (const key of sessionKeys) if (prev[key]?.value !== next[key]?.value) return true;
|
|
154
|
-
return false;
|
|
155
|
-
} catch {
|
|
156
|
-
return true;
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
/**
|
|
160
|
-
* Check if the Set-Cookie header contains better-auth cookies.
|
|
161
|
-
* This prevents infinite refetching when non-better-auth cookies (like third-party cookies) change.
|
|
162
|
-
*
|
|
163
|
-
* Supports multiple cookie naming patterns:
|
|
164
|
-
* - Default: "better-auth.session_token", "better-auth-passkey", "__Secure-better-auth.session_token"
|
|
165
|
-
* - Custom prefix: "myapp.session_token", "myapp-passkey", "__Secure-myapp.session_token"
|
|
166
|
-
* - Custom full names: "my_custom_session_token", "custom_session_data"
|
|
167
|
-
* - No prefix (cookiePrefix=""): matches any cookie with known suffixes
|
|
168
|
-
* - Multiple prefixes: ["better-auth", "my-app"] matches cookies starting with any of the prefixes
|
|
169
|
-
*
|
|
170
|
-
* @param setCookieHeader - The Set-Cookie header value
|
|
171
|
-
* @param cookiePrefix - The cookie prefix(es) to check for. Can be a string, array of strings, or empty string.
|
|
172
|
-
* @returns true if the header contains better-auth cookies, false otherwise
|
|
173
|
-
*/
|
|
174
|
-
function hasBetterAuthCookies(setCookieHeader, cookiePrefix) {
|
|
175
|
-
const cookies = parseSetCookieHeader$1(setCookieHeader);
|
|
176
|
-
const cookieSuffixes = ["session_token", "session_data"];
|
|
177
|
-
const prefixes = Array.isArray(cookiePrefix) ? cookiePrefix : [cookiePrefix];
|
|
178
|
-
for (const name of cookies.keys()) {
|
|
179
|
-
const nameWithoutSecure = stripSecureCookiePrefix(name);
|
|
180
|
-
for (const prefix of prefixes) if (prefix) {
|
|
181
|
-
if (nameWithoutSecure.startsWith(prefix)) return true;
|
|
182
|
-
} else for (const suffix of cookieSuffixes) if (nameWithoutSecure.endsWith(suffix)) return true;
|
|
183
|
-
}
|
|
184
|
-
return false;
|
|
185
|
-
}
|
|
15
|
+
//#region src/client-storage.ts
|
|
186
16
|
/**
|
|
187
17
|
* Expo secure store does not support colons in the keys.
|
|
188
18
|
* This function replaces colons with underscores.
|
|
@@ -196,15 +26,38 @@ function normalizeCookieName(name) {
|
|
|
196
26
|
return name.replace(/:/g, "_");
|
|
197
27
|
}
|
|
198
28
|
/**
|
|
199
|
-
*
|
|
200
|
-
*
|
|
201
|
-
* so a larger value is split across keys here. Mirrors the server's
|
|
202
|
-
* `chunkCookie`/`joinChunks` in `session-store.ts`; keep the two in sync.
|
|
29
|
+
* UTF-8 byte budget per stored chunk. Some native stores reject large values,
|
|
30
|
+
* so larger strings are split across keys.
|
|
203
31
|
*
|
|
204
32
|
* @see https://github.com/better-auth/better-auth/issues/9151
|
|
205
33
|
*/
|
|
206
34
|
const STORAGE_VALUE_LIMIT = 1800;
|
|
207
35
|
const MAX_STORAGE_CHUNKS = 100;
|
|
36
|
+
function getUtf8ByteLength(character) {
|
|
37
|
+
const codePoint = character.codePointAt(0) ?? 0;
|
|
38
|
+
if (codePoint <= 127) return 1;
|
|
39
|
+
if (codePoint <= 2047) return 2;
|
|
40
|
+
if (codePoint <= 65535) return 3;
|
|
41
|
+
return 4;
|
|
42
|
+
}
|
|
43
|
+
function splitStorageValue(value) {
|
|
44
|
+
const chunks = [];
|
|
45
|
+
let start = 0;
|
|
46
|
+
let end = 0;
|
|
47
|
+
let bytes = 0;
|
|
48
|
+
for (const character of value) {
|
|
49
|
+
const characterBytes = getUtf8ByteLength(character);
|
|
50
|
+
if (bytes + characterBytes > STORAGE_VALUE_LIMIT) {
|
|
51
|
+
chunks.push(value.slice(start, end));
|
|
52
|
+
start = end;
|
|
53
|
+
bytes = 0;
|
|
54
|
+
}
|
|
55
|
+
bytes += characterBytes;
|
|
56
|
+
end += character.length;
|
|
57
|
+
}
|
|
58
|
+
chunks.push(value.slice(start));
|
|
59
|
+
return chunks;
|
|
60
|
+
}
|
|
208
61
|
/**
|
|
209
62
|
* Marks a base key whose value is split across multiple storage keys. Legacy
|
|
210
63
|
* markers contain only the chunk count. Current markers also identify the
|
|
@@ -213,6 +66,11 @@ const MAX_STORAGE_CHUNKS = 100;
|
|
|
213
66
|
* @see https://github.com/better-auth/better-auth/issues/11082
|
|
214
67
|
*/
|
|
215
68
|
const CHUNK_MARKER = "ba-chunks:";
|
|
69
|
+
const CHUNK_SLOTS = [
|
|
70
|
+
null,
|
|
71
|
+
0,
|
|
72
|
+
1
|
|
73
|
+
];
|
|
216
74
|
function parseChunkCount(value) {
|
|
217
75
|
if (value === void 0) return null;
|
|
218
76
|
const count = Number(value);
|
|
@@ -254,7 +112,7 @@ function readChunks(storage, key, marker) {
|
|
|
254
112
|
let value = "";
|
|
255
113
|
for (let i = 0; i < marker.count; i++) {
|
|
256
114
|
const chunk = storage.getItem(getChunkKey(key, marker, i));
|
|
257
|
-
if (chunk
|
|
115
|
+
if (!chunk) return null;
|
|
258
116
|
value += chunk;
|
|
259
117
|
}
|
|
260
118
|
return value;
|
|
@@ -263,7 +121,7 @@ async function readChunksAsync(storage, key, marker) {
|
|
|
263
121
|
let value = "";
|
|
264
122
|
for (let i = 0; i < marker.count; i++) {
|
|
265
123
|
const chunk = await storage.getItemAsync(getChunkKey(key, marker, i));
|
|
266
|
-
if (chunk
|
|
124
|
+
if (!chunk) return null;
|
|
267
125
|
value += chunk;
|
|
268
126
|
}
|
|
269
127
|
return value;
|
|
@@ -292,11 +150,15 @@ async function readStoredValueAsync(storage, key, baseValue) {
|
|
|
292
150
|
fallbackCount: null
|
|
293
151
|
});
|
|
294
152
|
}
|
|
295
|
-
function
|
|
296
|
-
if (value.length <= STORAGE_VALUE_LIMIT) return [[key, value]];
|
|
297
|
-
const count = Math.ceil(value.length / STORAGE_VALUE_LIMIT);
|
|
298
|
-
if (count > MAX_STORAGE_CHUNKS) throw new Error(`Storage value requires ${count} chunks, exceeding the limit of ${MAX_STORAGE_CHUNKS}`);
|
|
153
|
+
function getStorageWritePlan(key, value, currentBaseValue) {
|
|
299
154
|
const currentMarker = currentBaseValue?.startsWith(CHUNK_MARKER) ? parseChunkMarker(currentBaseValue) : null;
|
|
155
|
+
const chunks = splitStorageValue(value);
|
|
156
|
+
if (chunks.length === 1) return {
|
|
157
|
+
writes: [[key, value]],
|
|
158
|
+
cleanup: getUnusedChunkRanges(key, currentMarker, null)
|
|
159
|
+
};
|
|
160
|
+
const count = chunks.length;
|
|
161
|
+
if (count > MAX_STORAGE_CHUNKS) throw new Error(`Storage value requires ${count} chunks, exceeding the limit of ${MAX_STORAGE_CHUNKS}`);
|
|
300
162
|
const marker = {
|
|
301
163
|
count,
|
|
302
164
|
slot: currentMarker?.slot === 0 ? 1 : 0,
|
|
@@ -307,82 +169,190 @@ function getStorageWrites(key, value, currentBaseValue) {
|
|
|
307
169
|
...currentMarker,
|
|
308
170
|
fallbackCount: null
|
|
309
171
|
})]);
|
|
310
|
-
for (
|
|
311
|
-
const start = i * STORAGE_VALUE_LIMIT;
|
|
312
|
-
writes.push([getChunkKey(key, marker, i), value.slice(start, start + STORAGE_VALUE_LIMIT)]);
|
|
313
|
-
}
|
|
172
|
+
for (const [index, chunk] of chunks.entries()) writes.push([getChunkKey(key, marker, index), chunk]);
|
|
314
173
|
writes.push([key, serializeChunkMarker(marker)]);
|
|
315
|
-
return writes;
|
|
316
|
-
}
|
|
317
|
-
function createKeyedWriteQueue() {
|
|
318
|
-
const tails = /* @__PURE__ */ new Map();
|
|
319
174
|
return {
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
175
|
+
writes,
|
|
176
|
+
cleanup: getUnusedChunkRanges(key, currentMarker, marker)
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
function getSlotChunkCount(marker, slot) {
|
|
180
|
+
if (!marker) return 0;
|
|
181
|
+
if (marker.slot === slot) return marker.count;
|
|
182
|
+
if (marker.slot === null || slot === null) return 0;
|
|
183
|
+
return marker.fallbackCount ?? 0;
|
|
184
|
+
}
|
|
185
|
+
function getUnusedChunkRanges(key, previousMarker, marker) {
|
|
186
|
+
return CHUNK_SLOTS.map((slot) => ({
|
|
187
|
+
prefix: slot === null ? key : `${key}.${slot}`,
|
|
188
|
+
start: getSlotChunkCount(marker, slot),
|
|
189
|
+
end: getSlotChunkCount(previousMarker, slot)
|
|
190
|
+
}));
|
|
191
|
+
}
|
|
192
|
+
const storageStates = /* @__PURE__ */ new WeakMap();
|
|
193
|
+
function getStorageState(storage, key) {
|
|
194
|
+
let states = storageStates.get(storage);
|
|
195
|
+
if (!states) {
|
|
196
|
+
states = /* @__PURE__ */ new Map();
|
|
197
|
+
storageStates.set(storage, states);
|
|
198
|
+
}
|
|
199
|
+
let state = states.get(key);
|
|
200
|
+
if (!state) {
|
|
201
|
+
state = {
|
|
202
|
+
pending: null,
|
|
203
|
+
pendingWrites: 0,
|
|
204
|
+
activeRead: null,
|
|
205
|
+
cleanupComplete: false
|
|
206
|
+
};
|
|
207
|
+
states.set(key, state);
|
|
208
|
+
}
|
|
209
|
+
return state;
|
|
210
|
+
}
|
|
211
|
+
function enqueueStorageOperation(state, operation) {
|
|
212
|
+
const queued = (state.pending ?? Promise.resolve()).then(operation, operation);
|
|
213
|
+
state.pending = queued;
|
|
214
|
+
const cleanup = () => {
|
|
215
|
+
if (state.pending === queued) state.pending = null;
|
|
332
216
|
};
|
|
217
|
+
queued.then(cleanup, cleanup);
|
|
218
|
+
return queued;
|
|
333
219
|
}
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
220
|
+
function enqueueStorageWrite(state, operation) {
|
|
221
|
+
state.pendingWrites++;
|
|
222
|
+
return enqueueStorageOperation(state, async () => {
|
|
223
|
+
try {
|
|
224
|
+
return await operation();
|
|
225
|
+
} finally {
|
|
226
|
+
state.pendingWrites--;
|
|
227
|
+
}
|
|
228
|
+
});
|
|
341
229
|
}
|
|
230
|
+
/** @internal */
|
|
342
231
|
function createManagedStorage(storage) {
|
|
343
|
-
const writeQueue = getStorageWriteQueue(storage);
|
|
344
232
|
const logWriteError = (key, error) => {
|
|
345
|
-
|
|
233
|
+
logger.error(`[better-auth/expo] failed to persist "${key}" to storage`, error);
|
|
234
|
+
};
|
|
235
|
+
const logCleanupError = (key, error) => {
|
|
236
|
+
logger.error(`[better-auth/expo] failed to clear unused chunks for "${key}"`, error);
|
|
346
237
|
};
|
|
347
238
|
const getItem = (name) => {
|
|
348
239
|
const key = normalizeCookieName(name);
|
|
349
240
|
return readStoredValue(storage, key, storage.getItem(key));
|
|
350
241
|
};
|
|
351
|
-
const getItemAsync =
|
|
242
|
+
const getItemAsync = (name) => {
|
|
352
243
|
const key = normalizeCookieName(name);
|
|
353
|
-
|
|
244
|
+
const state = getStorageState(storage, key);
|
|
245
|
+
return enqueueStorageOperation(state, async () => {
|
|
246
|
+
const read = { snapshot: null };
|
|
247
|
+
state.activeRead = read;
|
|
248
|
+
try {
|
|
249
|
+
const value = await readStoredValueAsync(storage, key, await storage.getItemAsync(key));
|
|
250
|
+
return read.snapshot ? read.snapshot.value : value;
|
|
251
|
+
} finally {
|
|
252
|
+
state.activeRead = null;
|
|
253
|
+
}
|
|
254
|
+
});
|
|
354
255
|
};
|
|
355
256
|
const writeItem = (key, value, currentBaseValue) => {
|
|
356
|
-
|
|
257
|
+
const state = getStorageState(storage, key);
|
|
258
|
+
const { writes, cleanup } = getStorageWritePlan(key, value, currentBaseValue);
|
|
259
|
+
for (const [writeKey, writeValue] of writes) storage.setItem(writeKey, writeValue);
|
|
260
|
+
try {
|
|
261
|
+
const scanContiguousOrphans = !state.cleanupComplete;
|
|
262
|
+
for (const { prefix, start, end } of cleanup) {
|
|
263
|
+
if (scanContiguousOrphans) {
|
|
264
|
+
const orphanStart = Math.max(start, end);
|
|
265
|
+
let orphanEnd = orphanStart;
|
|
266
|
+
for (; orphanEnd < MAX_STORAGE_CHUNKS; orphanEnd++) if (!storage.getItem(`${prefix}.${orphanEnd}`)) break;
|
|
267
|
+
for (let i = orphanEnd - 1; i >= orphanStart; i--) storage.setItem(`${prefix}.${i}`, "");
|
|
268
|
+
}
|
|
269
|
+
for (let i = end - 1; i >= start; i--) storage.setItem(`${prefix}.${i}`, "");
|
|
270
|
+
}
|
|
271
|
+
state.cleanupComplete = true;
|
|
272
|
+
} catch (error) {
|
|
273
|
+
state.cleanupComplete = false;
|
|
274
|
+
logCleanupError(key, error);
|
|
275
|
+
}
|
|
357
276
|
};
|
|
358
277
|
const writeItemAsync = async (key, value, currentBaseValue) => {
|
|
359
|
-
|
|
278
|
+
const state = getStorageState(storage, key);
|
|
279
|
+
const { writes, cleanup } = getStorageWritePlan(key, value, currentBaseValue);
|
|
280
|
+
for (const [writeKey, writeValue] of writes) await storage.setItemAsync(writeKey, writeValue);
|
|
281
|
+
try {
|
|
282
|
+
const scanContiguousOrphans = !state.cleanupComplete;
|
|
283
|
+
for (const { prefix, start, end } of cleanup) {
|
|
284
|
+
if (scanContiguousOrphans) {
|
|
285
|
+
const orphanStart = Math.max(start, end);
|
|
286
|
+
let orphanEnd = orphanStart;
|
|
287
|
+
for (; orphanEnd < MAX_STORAGE_CHUNKS; orphanEnd++) if (!await storage.getItemAsync(`${prefix}.${orphanEnd}`)) break;
|
|
288
|
+
for (let i = orphanEnd - 1; i >= orphanStart; i--) await storage.setItemAsync(`${prefix}.${i}`, "");
|
|
289
|
+
}
|
|
290
|
+
for (let i = end - 1; i >= start; i--) await storage.setItemAsync(`${prefix}.${i}`, "");
|
|
291
|
+
}
|
|
292
|
+
state.cleanupComplete = true;
|
|
293
|
+
} catch (error) {
|
|
294
|
+
state.cleanupComplete = false;
|
|
295
|
+
logCleanupError(key, error);
|
|
296
|
+
}
|
|
360
297
|
};
|
|
361
298
|
const setItem = (name, value) => {
|
|
362
299
|
const key = normalizeCookieName(name);
|
|
363
|
-
|
|
300
|
+
const state = getStorageState(storage, key);
|
|
301
|
+
if (state.pendingWrites > 0) {
|
|
364
302
|
logWriteError(key, /* @__PURE__ */ new Error("Cannot write synchronously while an async write is pending"));
|
|
365
303
|
return;
|
|
366
304
|
}
|
|
305
|
+
let currentBaseValue = null;
|
|
367
306
|
try {
|
|
368
|
-
|
|
307
|
+
currentBaseValue = storage.getItem(key);
|
|
369
308
|
} catch (error) {
|
|
309
|
+
state.cleanupComplete = false;
|
|
310
|
+
if (splitStorageValue(value).length > 1) {
|
|
311
|
+
logWriteError(key, error);
|
|
312
|
+
return;
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
const read = state.activeRead;
|
|
316
|
+
if (read && read.snapshot === null) try {
|
|
317
|
+
read.snapshot = { value: readStoredValue(storage, key, currentBaseValue) };
|
|
318
|
+
} catch {
|
|
319
|
+
read.snapshot = { value: null };
|
|
320
|
+
}
|
|
321
|
+
try {
|
|
322
|
+
writeItem(key, value, currentBaseValue);
|
|
323
|
+
} catch (error) {
|
|
324
|
+
state.cleanupComplete = false;
|
|
370
325
|
logWriteError(key, error);
|
|
326
|
+
return;
|
|
371
327
|
}
|
|
328
|
+
if (read) read.snapshot = { value };
|
|
372
329
|
};
|
|
373
330
|
const setItemAsync = (name, value) => {
|
|
374
331
|
const key = normalizeCookieName(name);
|
|
375
|
-
|
|
332
|
+
const state = getStorageState(storage, key);
|
|
333
|
+
return enqueueStorageWrite(state, async () => {
|
|
334
|
+
let currentBaseValue = null;
|
|
335
|
+
try {
|
|
336
|
+
currentBaseValue = await storage.getItemAsync(key);
|
|
337
|
+
} catch (error) {
|
|
338
|
+
state.cleanupComplete = false;
|
|
339
|
+
if (splitStorageValue(value).length > 1) {
|
|
340
|
+
logWriteError(key, error);
|
|
341
|
+
return;
|
|
342
|
+
}
|
|
343
|
+
}
|
|
376
344
|
try {
|
|
377
|
-
await writeItemAsync(key, value,
|
|
345
|
+
await writeItemAsync(key, value, currentBaseValue);
|
|
378
346
|
} catch (error) {
|
|
347
|
+
state.cleanupComplete = false;
|
|
379
348
|
logWriteError(key, error);
|
|
380
349
|
}
|
|
381
350
|
});
|
|
382
351
|
};
|
|
383
352
|
const updateItemAsync = (name, update) => {
|
|
384
353
|
const key = normalizeCookieName(name);
|
|
385
|
-
|
|
354
|
+
const state = getStorageState(storage, key);
|
|
355
|
+
return enqueueStorageWrite(state, async () => {
|
|
386
356
|
try {
|
|
387
357
|
const currentBaseValue = await storage.getItemAsync(key);
|
|
388
358
|
const previousValue = await readStoredValueAsync(storage, key, currentBaseValue);
|
|
@@ -393,6 +363,7 @@ function createManagedStorage(storage) {
|
|
|
393
363
|
value
|
|
394
364
|
};
|
|
395
365
|
} catch (error) {
|
|
366
|
+
state.cleanupComplete = false;
|
|
396
367
|
logWriteError(key, error);
|
|
397
368
|
return null;
|
|
398
369
|
}
|
|
@@ -408,7 +379,7 @@ function createManagedStorage(storage) {
|
|
|
408
379
|
}
|
|
409
380
|
/**
|
|
410
381
|
* Wraps Expo storage with chunking, recoverable writes, and serialized async
|
|
411
|
-
*
|
|
382
|
+
* access.
|
|
412
383
|
*/
|
|
413
384
|
function storageAdapter(storage) {
|
|
414
385
|
const managedStorage = createManagedStorage(storage);
|
|
@@ -419,6 +390,179 @@ function storageAdapter(storage) {
|
|
|
419
390
|
setItemAsync: managedStorage.setItemAsync
|
|
420
391
|
};
|
|
421
392
|
}
|
|
393
|
+
//#endregion
|
|
394
|
+
//#region src/focus-manager.ts
|
|
395
|
+
var ExpoFocusManager = class {
|
|
396
|
+
listeners = /* @__PURE__ */ new Set();
|
|
397
|
+
subscription;
|
|
398
|
+
isFocused;
|
|
399
|
+
subscribe(listener) {
|
|
400
|
+
this.listeners.add(listener);
|
|
401
|
+
return () => {
|
|
402
|
+
this.listeners.delete(listener);
|
|
403
|
+
};
|
|
404
|
+
}
|
|
405
|
+
setFocused(focused) {
|
|
406
|
+
if (this.isFocused === focused) return;
|
|
407
|
+
this.isFocused = focused;
|
|
408
|
+
this.listeners.forEach((listener) => listener(focused));
|
|
409
|
+
}
|
|
410
|
+
setup() {
|
|
411
|
+
this.subscription = AppState.addEventListener("change", (state) => {
|
|
412
|
+
this.setFocused(state === "active");
|
|
413
|
+
});
|
|
414
|
+
return () => {
|
|
415
|
+
this.subscription?.remove();
|
|
416
|
+
};
|
|
417
|
+
}
|
|
418
|
+
};
|
|
419
|
+
function setupExpoFocusManager() {
|
|
420
|
+
if (!globalThis[kFocusManager]) globalThis[kFocusManager] = new ExpoFocusManager();
|
|
421
|
+
return globalThis[kFocusManager];
|
|
422
|
+
}
|
|
423
|
+
//#endregion
|
|
424
|
+
//#region src/online-manager.ts
|
|
425
|
+
var ExpoOnlineManager = class {
|
|
426
|
+
listeners = /* @__PURE__ */ new Set();
|
|
427
|
+
isOnline = true;
|
|
428
|
+
unsubscribe;
|
|
429
|
+
subscribe(listener) {
|
|
430
|
+
this.listeners.add(listener);
|
|
431
|
+
return () => {
|
|
432
|
+
this.listeners.delete(listener);
|
|
433
|
+
};
|
|
434
|
+
}
|
|
435
|
+
setOnline(online) {
|
|
436
|
+
if (this.isOnline === online) return;
|
|
437
|
+
this.isOnline = online;
|
|
438
|
+
this.listeners.forEach((listener) => listener(online));
|
|
439
|
+
}
|
|
440
|
+
setup() {
|
|
441
|
+
import("expo-network").then(({ addNetworkStateListener }) => {
|
|
442
|
+
const subscription = addNetworkStateListener((state) => {
|
|
443
|
+
this.setOnline(!!state.isInternetReachable);
|
|
444
|
+
});
|
|
445
|
+
this.unsubscribe = () => subscription.remove();
|
|
446
|
+
}).catch(() => {
|
|
447
|
+
this.setOnline(true);
|
|
448
|
+
});
|
|
449
|
+
return () => {
|
|
450
|
+
this.unsubscribe?.();
|
|
451
|
+
};
|
|
452
|
+
}
|
|
453
|
+
};
|
|
454
|
+
function setupExpoOnlineManager() {
|
|
455
|
+
if (!globalThis[kOnlineManager]) globalThis[kOnlineManager] = new ExpoOnlineManager();
|
|
456
|
+
return globalThis[kOnlineManager];
|
|
457
|
+
}
|
|
458
|
+
//#endregion
|
|
459
|
+
//#region src/client.ts
|
|
460
|
+
if (Platform.OS !== "web") {
|
|
461
|
+
setupExpoFocusManager();
|
|
462
|
+
setupExpoOnlineManager();
|
|
463
|
+
}
|
|
464
|
+
function defineExpoClientPlugin(plugin) {
|
|
465
|
+
return plugin;
|
|
466
|
+
}
|
|
467
|
+
function getSetCookie(header, prevCookie) {
|
|
468
|
+
const parsed = parseSetCookieHeader$1(header);
|
|
469
|
+
const toSetCookie = safeJSONParse(prevCookie) ?? {};
|
|
470
|
+
parsed.forEach((cookie, key) => {
|
|
471
|
+
const expiresAt = cookie["expires"];
|
|
472
|
+
const maxAge = cookie["max-age"];
|
|
473
|
+
if (maxAge !== void 0 && Number(maxAge) <= 0) {
|
|
474
|
+
delete toSetCookie[key];
|
|
475
|
+
return;
|
|
476
|
+
}
|
|
477
|
+
const expires = maxAge ? new Date(Date.now() + Number(maxAge) * 1e3) : expiresAt ? new Date(String(expiresAt)) : null;
|
|
478
|
+
if (expires && expires.getTime() <= Date.now()) {
|
|
479
|
+
delete toSetCookie[key];
|
|
480
|
+
return;
|
|
481
|
+
}
|
|
482
|
+
toSetCookie[key] = {
|
|
483
|
+
value: cookie["value"],
|
|
484
|
+
expires: expires ? expires.toISOString() : null
|
|
485
|
+
};
|
|
486
|
+
});
|
|
487
|
+
return JSON.stringify(toSetCookie);
|
|
488
|
+
}
|
|
489
|
+
function getCookie(cookie) {
|
|
490
|
+
const parsed = safeJSONParse(cookie) ?? {};
|
|
491
|
+
return Object.entries(parsed).reduce((acc, [key, value]) => {
|
|
492
|
+
if (value.expires && new Date(value.expires) < /* @__PURE__ */ new Date()) return acc;
|
|
493
|
+
return acc ? `${acc}; ${key}=${value.value}` : `${key}=${value.value}`;
|
|
494
|
+
}, "");
|
|
495
|
+
}
|
|
496
|
+
function getOAuthStateValue(cookieJson, cookiePrefix) {
|
|
497
|
+
if (!cookieJson) return null;
|
|
498
|
+
const parsed = safeJSONParse(cookieJson);
|
|
499
|
+
if (!parsed) return null;
|
|
500
|
+
const prefixes = Array.isArray(cookiePrefix) ? cookiePrefix : [cookiePrefix];
|
|
501
|
+
for (const prefix of prefixes) {
|
|
502
|
+
const candidates = [`${SECURE_COOKIE_PREFIX}${prefix}.oauth_state`, `${prefix}.oauth_state`];
|
|
503
|
+
for (const name of candidates) {
|
|
504
|
+
const value = parsed?.[name]?.value;
|
|
505
|
+
if (value) return value;
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
return null;
|
|
509
|
+
}
|
|
510
|
+
function getOrigin(scheme) {
|
|
511
|
+
return Linking.createURL("", { scheme });
|
|
512
|
+
}
|
|
513
|
+
/**
|
|
514
|
+
* Compare if session cookies have actually changed by comparing their values.
|
|
515
|
+
* Ignores expiry timestamps that naturally change on each request.
|
|
516
|
+
*
|
|
517
|
+
* @param prevCookie - Previous cookie JSON string
|
|
518
|
+
* @param newCookie - New cookie JSON string
|
|
519
|
+
* @returns true if session cookies have changed, false otherwise
|
|
520
|
+
*/
|
|
521
|
+
function hasSessionCookieChanged(prevCookie, newCookie) {
|
|
522
|
+
if (!prevCookie) return true;
|
|
523
|
+
try {
|
|
524
|
+
const prev = JSON.parse(prevCookie);
|
|
525
|
+
const next = JSON.parse(newCookie);
|
|
526
|
+
const sessionKeys = /* @__PURE__ */ new Set();
|
|
527
|
+
Object.keys(prev).forEach((key) => {
|
|
528
|
+
if (key.includes("session_token") || key.includes("session_data")) sessionKeys.add(key);
|
|
529
|
+
});
|
|
530
|
+
Object.keys(next).forEach((key) => {
|
|
531
|
+
if (key.includes("session_token") || key.includes("session_data")) sessionKeys.add(key);
|
|
532
|
+
});
|
|
533
|
+
for (const key of sessionKeys) if (prev[key]?.value !== next[key]?.value) return true;
|
|
534
|
+
return false;
|
|
535
|
+
} catch {
|
|
536
|
+
return true;
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
/**
|
|
540
|
+
* Check if the Set-Cookie header contains better-auth cookies.
|
|
541
|
+
* This prevents infinite refetching when non-better-auth cookies (like third-party cookies) change.
|
|
542
|
+
*
|
|
543
|
+
* Supports multiple cookie naming patterns:
|
|
544
|
+
* - Default: "better-auth.session_token", "better-auth-passkey", "__Secure-better-auth.session_token"
|
|
545
|
+
* - Custom prefix: "myapp.session_token", "myapp-passkey", "__Secure-myapp.session_token"
|
|
546
|
+
* - Custom full names: "my_custom_session_token", "custom_session_data"
|
|
547
|
+
* - No prefix (cookiePrefix=""): matches any cookie with known suffixes
|
|
548
|
+
* - Multiple prefixes: ["better-auth", "my-app"] matches cookies starting with any of the prefixes
|
|
549
|
+
*
|
|
550
|
+
* @param setCookieHeader - The Set-Cookie header value
|
|
551
|
+
* @param cookiePrefix - The cookie prefix(es) to check for. Can be a string, array of strings, or empty string.
|
|
552
|
+
* @returns true if the header contains better-auth cookies, false otherwise
|
|
553
|
+
*/
|
|
554
|
+
function hasBetterAuthCookies(setCookieHeader, cookiePrefix) {
|
|
555
|
+
const cookies = parseSetCookieHeader$1(setCookieHeader);
|
|
556
|
+
const cookieSuffixes = ["session_token", "session_data"];
|
|
557
|
+
const prefixes = Array.isArray(cookiePrefix) ? cookiePrefix : [cookiePrefix];
|
|
558
|
+
for (const name of cookies.keys()) {
|
|
559
|
+
const nameWithoutSecure = stripSecureCookiePrefix(name);
|
|
560
|
+
for (const prefix of prefixes) if (prefix) {
|
|
561
|
+
if (nameWithoutSecure.startsWith(prefix)) return true;
|
|
562
|
+
} else for (const suffix of cookieSuffixes) if (nameWithoutSecure.endsWith(suffix)) return true;
|
|
563
|
+
}
|
|
564
|
+
return false;
|
|
565
|
+
}
|
|
422
566
|
const expoClient = (opts) => {
|
|
423
567
|
let store = null;
|
|
424
568
|
const storagePrefix = opts?.storagePrefix || "better-auth";
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as PACKAGE_VERSION } from "./version-
|
|
1
|
+
import { t as PACKAGE_VERSION } from "./version-Db7MRDhd.js";
|
|
2
2
|
import { createAuthMiddleware } from "@better-auth/core/api";
|
|
3
3
|
import { HIDE_METADATA } from "better-auth";
|
|
4
4
|
import { APIError, createAuthEndpoint } from "better-auth/api";
|
package/dist/plugins/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@better-auth/expo",
|
|
3
|
-
"version": "1.7.
|
|
3
|
+
"version": "1.7.5",
|
|
4
4
|
"description": "Better Auth integration for Expo and React Native applications.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -58,12 +58,12 @@
|
|
|
58
58
|
}
|
|
59
59
|
},
|
|
60
60
|
"dependencies": {
|
|
61
|
-
"@better-fetch/fetch": "1.3.
|
|
61
|
+
"@better-fetch/fetch": "1.3.2",
|
|
62
62
|
"better-call": "1.4.0",
|
|
63
63
|
"zod": "^4.5.4"
|
|
64
64
|
},
|
|
65
65
|
"devDependencies": {
|
|
66
|
-
"@better-fetch/fetch": "1.3.
|
|
66
|
+
"@better-fetch/fetch": "1.3.2",
|
|
67
67
|
"expo-constants": "~56.0.18",
|
|
68
68
|
"expo-linking": "~56.0.14",
|
|
69
69
|
"expo-network": "~56.0.5",
|
|
@@ -71,8 +71,8 @@
|
|
|
71
71
|
"expo-web-browser": "~56.0.5",
|
|
72
72
|
"react-native": "~0.86.0",
|
|
73
73
|
"tsdown": "0.21.10",
|
|
74
|
-
"@better-auth/core": "1.7.
|
|
75
|
-
"better-auth": "1.7.
|
|
74
|
+
"@better-auth/core": "1.7.5",
|
|
75
|
+
"better-auth": "1.7.5"
|
|
76
76
|
},
|
|
77
77
|
"peerDependencies": {
|
|
78
78
|
"expo-constants": ">=17.0.0",
|
|
@@ -80,8 +80,8 @@
|
|
|
80
80
|
"expo-network": ">=8.0.7",
|
|
81
81
|
"expo-secure-store": ">=12.5.0",
|
|
82
82
|
"expo-web-browser": ">=14.0.0",
|
|
83
|
-
"@better-auth/core": "^1.7.
|
|
84
|
-
"better-auth": "^1.7.
|
|
83
|
+
"@better-auth/core": "^1.7.5",
|
|
84
|
+
"better-auth": "^1.7.5"
|
|
85
85
|
},
|
|
86
86
|
"peerDependenciesMeta": {
|
|
87
87
|
"expo-constants": {
|