@better-auth/expo 1.4.0-beta.15 → 1.4.0-beta.16
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/package.json +6 -8
- package/dist/chunk-CUT6urMc.cjs +0 -30
- package/dist/client.cjs +0 -277
- package/dist/client.d.cts +0 -158
- package/dist/index.cjs +0 -61
- package/dist/index.d.cts +0 -57
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@better-auth/expo",
|
|
3
|
-
"version": "1.4.0-beta.
|
|
3
|
+
"version": "1.4.0-beta.16",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Better Auth integration for Expo and React Native applications.",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -15,14 +15,12 @@
|
|
|
15
15
|
".": {
|
|
16
16
|
"better-auth-dev-source": "./src/index.ts",
|
|
17
17
|
"types": "./dist/index.d.ts",
|
|
18
|
-
"
|
|
19
|
-
"require": "./dist/index.cjs"
|
|
18
|
+
"default": "./dist/index.js"
|
|
20
19
|
},
|
|
21
20
|
"./client": {
|
|
22
21
|
"better-auth-dev-source": "./src/client.ts",
|
|
23
22
|
"types": "./dist/client.d.ts",
|
|
24
|
-
"
|
|
25
|
-
"require": "./dist/client.cjs"
|
|
23
|
+
"default": "./dist/client.js"
|
|
26
24
|
}
|
|
27
25
|
},
|
|
28
26
|
"typesVersions": {
|
|
@@ -57,8 +55,8 @@
|
|
|
57
55
|
"expo-web-browser": "~14.2.0",
|
|
58
56
|
"react-native": "~0.80.2",
|
|
59
57
|
"tsdown": "^0.15.11",
|
|
60
|
-
"@better-auth/core": "1.4.0-beta.
|
|
61
|
-
"better-auth": "1.4.0-beta.
|
|
58
|
+
"@better-auth/core": "1.4.0-beta.16",
|
|
59
|
+
"better-auth": "1.4.0-beta.16"
|
|
62
60
|
},
|
|
63
61
|
"peerDependencies": {
|
|
64
62
|
"expo-constants": ">=17.0.0",
|
|
@@ -66,7 +64,7 @@
|
|
|
66
64
|
"expo-linking": ">=7.0.0",
|
|
67
65
|
"expo-secure-store": ">=14.0.0",
|
|
68
66
|
"expo-web-browser": ">=14.0.0",
|
|
69
|
-
"@better-auth/core": "1.4.0-beta.
|
|
67
|
+
"@better-auth/core": "1.4.0-beta.16"
|
|
70
68
|
},
|
|
71
69
|
"dependencies": {
|
|
72
70
|
"@better-fetch/fetch": "1.1.18",
|
package/dist/chunk-CUT6urMc.cjs
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
//#region rolldown:runtime
|
|
2
|
-
var __create = Object.create;
|
|
3
|
-
var __defProp = Object.defineProperty;
|
|
4
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
-
var __copyProps = (to, from, except, desc) => {
|
|
9
|
-
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
10
|
-
key = keys[i];
|
|
11
|
-
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
|
|
12
|
-
get: ((k) => from[k]).bind(null, key),
|
|
13
|
-
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
14
|
-
});
|
|
15
|
-
}
|
|
16
|
-
return to;
|
|
17
|
-
};
|
|
18
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
19
|
-
value: mod,
|
|
20
|
-
enumerable: true
|
|
21
|
-
}) : target, mod));
|
|
22
|
-
|
|
23
|
-
//#endregion
|
|
24
|
-
|
|
25
|
-
Object.defineProperty(exports, '__toESM', {
|
|
26
|
-
enumerable: true,
|
|
27
|
-
get: function () {
|
|
28
|
-
return __toESM;
|
|
29
|
-
}
|
|
30
|
-
});
|
package/dist/client.cjs
DELETED
|
@@ -1,277 +0,0 @@
|
|
|
1
|
-
const require_chunk = require('./chunk-CUT6urMc.cjs');
|
|
2
|
-
let expo_constants = require("expo-constants");
|
|
3
|
-
expo_constants = require_chunk.__toESM(expo_constants);
|
|
4
|
-
let expo_linking = require("expo-linking");
|
|
5
|
-
expo_linking = require_chunk.__toESM(expo_linking);
|
|
6
|
-
let react_native = require("react-native");
|
|
7
|
-
react_native = require_chunk.__toESM(react_native);
|
|
8
|
-
|
|
9
|
-
//#region src/client.ts
|
|
10
|
-
function parseSetCookieHeader(header) {
|
|
11
|
-
const cookieMap = /* @__PURE__ */ new Map();
|
|
12
|
-
splitSetCookieHeader(header).forEach((cookie) => {
|
|
13
|
-
const [nameValue, ...attributes] = cookie.split(";").map((p) => p.trim());
|
|
14
|
-
const [name, ...valueParts] = nameValue.split("=");
|
|
15
|
-
const cookieObj = { value: valueParts.join("=") };
|
|
16
|
-
attributes.forEach((attr) => {
|
|
17
|
-
const [attrName, ...attrValueParts] = attr.split("=");
|
|
18
|
-
const attrValue = attrValueParts.join("=");
|
|
19
|
-
cookieObj[attrName.toLowerCase()] = attrValue;
|
|
20
|
-
});
|
|
21
|
-
cookieMap.set(name, cookieObj);
|
|
22
|
-
});
|
|
23
|
-
return cookieMap;
|
|
24
|
-
}
|
|
25
|
-
function splitSetCookieHeader(setCookie) {
|
|
26
|
-
const parts = [];
|
|
27
|
-
let buffer = "";
|
|
28
|
-
let i = 0;
|
|
29
|
-
while (i < setCookie.length) {
|
|
30
|
-
const char = setCookie[i];
|
|
31
|
-
if (char === ",") {
|
|
32
|
-
const recent = buffer.toLowerCase();
|
|
33
|
-
const hasExpires = recent.includes("expires=");
|
|
34
|
-
const hasGmt = /gmt/i.test(recent);
|
|
35
|
-
if (hasExpires && !hasGmt) {
|
|
36
|
-
buffer += char;
|
|
37
|
-
i += 1;
|
|
38
|
-
continue;
|
|
39
|
-
}
|
|
40
|
-
if (buffer.trim().length > 0) {
|
|
41
|
-
parts.push(buffer.trim());
|
|
42
|
-
buffer = "";
|
|
43
|
-
}
|
|
44
|
-
i += 1;
|
|
45
|
-
if (setCookie[i] === " ") i += 1;
|
|
46
|
-
continue;
|
|
47
|
-
}
|
|
48
|
-
buffer += char;
|
|
49
|
-
i += 1;
|
|
50
|
-
}
|
|
51
|
-
if (buffer.trim().length > 0) parts.push(buffer.trim());
|
|
52
|
-
return parts;
|
|
53
|
-
}
|
|
54
|
-
function getSetCookie(header, prevCookie) {
|
|
55
|
-
const parsed = parseSetCookieHeader(header);
|
|
56
|
-
let toSetCookie = {};
|
|
57
|
-
parsed.forEach((cookie, key) => {
|
|
58
|
-
const expiresAt = cookie["expires"];
|
|
59
|
-
const maxAge = cookie["max-age"];
|
|
60
|
-
const expires = maxAge ? new Date(Date.now() + Number(maxAge) * 1e3) : expiresAt ? new Date(String(expiresAt)) : null;
|
|
61
|
-
toSetCookie[key] = {
|
|
62
|
-
value: cookie["value"],
|
|
63
|
-
expires: expires ? expires.toISOString() : null
|
|
64
|
-
};
|
|
65
|
-
});
|
|
66
|
-
if (prevCookie) try {
|
|
67
|
-
toSetCookie = {
|
|
68
|
-
...JSON.parse(prevCookie),
|
|
69
|
-
...toSetCookie
|
|
70
|
-
};
|
|
71
|
-
} catch {}
|
|
72
|
-
return JSON.stringify(toSetCookie);
|
|
73
|
-
}
|
|
74
|
-
function getCookie(cookie) {
|
|
75
|
-
let parsed = {};
|
|
76
|
-
try {
|
|
77
|
-
parsed = JSON.parse(cookie);
|
|
78
|
-
} catch (e) {}
|
|
79
|
-
return Object.entries(parsed).reduce((acc, [key, value]) => {
|
|
80
|
-
if (value.expires && new Date(value.expires) < /* @__PURE__ */ new Date()) return acc;
|
|
81
|
-
return `${acc}; ${key}=${value.value}`;
|
|
82
|
-
}, "");
|
|
83
|
-
}
|
|
84
|
-
function getOrigin(scheme) {
|
|
85
|
-
return expo_linking.createURL("", { scheme });
|
|
86
|
-
}
|
|
87
|
-
/**
|
|
88
|
-
* Compare if session cookies have actually changed by comparing their values.
|
|
89
|
-
* Ignores expiry timestamps that naturally change on each request.
|
|
90
|
-
*
|
|
91
|
-
* @param prevCookie - Previous cookie JSON string
|
|
92
|
-
* @param newCookie - New cookie JSON string
|
|
93
|
-
* @returns true if session cookies have changed, false otherwise
|
|
94
|
-
*/
|
|
95
|
-
function hasSessionCookieChanged(prevCookie, newCookie) {
|
|
96
|
-
if (!prevCookie) return true;
|
|
97
|
-
try {
|
|
98
|
-
const prev = JSON.parse(prevCookie);
|
|
99
|
-
const next = JSON.parse(newCookie);
|
|
100
|
-
const sessionKeys = /* @__PURE__ */ new Set();
|
|
101
|
-
Object.keys(prev).forEach((key) => {
|
|
102
|
-
if (key.includes("session_token") || key.includes("session_data")) sessionKeys.add(key);
|
|
103
|
-
});
|
|
104
|
-
Object.keys(next).forEach((key) => {
|
|
105
|
-
if (key.includes("session_token") || key.includes("session_data")) sessionKeys.add(key);
|
|
106
|
-
});
|
|
107
|
-
for (const key of sessionKeys) if (prev[key]?.value !== next[key]?.value) return true;
|
|
108
|
-
return false;
|
|
109
|
-
} catch {
|
|
110
|
-
return true;
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
/**
|
|
114
|
-
* Check if the Set-Cookie header contains session-related better-auth cookies.
|
|
115
|
-
* Only triggers session updates when session_token or session_data cookies are present.
|
|
116
|
-
* This prevents infinite refetching when non-session cookies (like third-party cookies) change.
|
|
117
|
-
*
|
|
118
|
-
* Supports multiple cookie naming patterns:
|
|
119
|
-
* - Default: "better-auth.session_token", "__Secure-better-auth.session_token"
|
|
120
|
-
* - Custom prefix: "myapp.session_token", "__Secure-myapp.session_token"
|
|
121
|
-
* - Custom full names: "my_custom_session_token", "custom_session_data"
|
|
122
|
-
* - No prefix (cookiePrefix=""): "session_token", "my_session_token", etc.
|
|
123
|
-
*
|
|
124
|
-
* @param setCookieHeader - The Set-Cookie header value
|
|
125
|
-
* @param cookiePrefix - The cookie prefix to check for. Can be empty string for custom cookie names.
|
|
126
|
-
* @returns true if the header contains session-related cookies, false otherwise
|
|
127
|
-
*/
|
|
128
|
-
function hasBetterAuthCookies(setCookieHeader, cookiePrefix) {
|
|
129
|
-
const cookies = parseSetCookieHeader(setCookieHeader);
|
|
130
|
-
const sessionCookieSuffixes = ["session_token", "session_data"];
|
|
131
|
-
for (const name of cookies.keys()) {
|
|
132
|
-
const nameWithoutSecure = name.startsWith("__Secure-") ? name.slice(9) : name;
|
|
133
|
-
for (const suffix of sessionCookieSuffixes) if (cookiePrefix) {
|
|
134
|
-
if (nameWithoutSecure === `${cookiePrefix}.${suffix}`) return true;
|
|
135
|
-
} else if (nameWithoutSecure.endsWith(suffix)) return true;
|
|
136
|
-
}
|
|
137
|
-
return false;
|
|
138
|
-
}
|
|
139
|
-
/**
|
|
140
|
-
* Expo secure store does not support colons in the keys.
|
|
141
|
-
* This function replaces colons with underscores.
|
|
142
|
-
*
|
|
143
|
-
* @see https://github.com/better-auth/better-auth/issues/5426
|
|
144
|
-
*
|
|
145
|
-
* @param name cookie name to be saved in the storage
|
|
146
|
-
* @returns normalized cookie name
|
|
147
|
-
*/
|
|
148
|
-
function normalizeCookieName(name) {
|
|
149
|
-
return name.replace(/:/g, "_");
|
|
150
|
-
}
|
|
151
|
-
function storageAdapter(storage) {
|
|
152
|
-
return {
|
|
153
|
-
getItem: (name) => {
|
|
154
|
-
return storage.getItem(normalizeCookieName(name));
|
|
155
|
-
},
|
|
156
|
-
setItem: (name, value) => {
|
|
157
|
-
return storage.setItem(normalizeCookieName(name), value);
|
|
158
|
-
}
|
|
159
|
-
};
|
|
160
|
-
}
|
|
161
|
-
const expoClient = (opts) => {
|
|
162
|
-
let store = null;
|
|
163
|
-
const storagePrefix = opts?.storagePrefix || "better-auth";
|
|
164
|
-
const cookieName = `${storagePrefix}_cookie`;
|
|
165
|
-
const localCacheName = `${storagePrefix}_session_data`;
|
|
166
|
-
const storage = storageAdapter(opts?.storage);
|
|
167
|
-
const isWeb = react_native.Platform.OS === "web";
|
|
168
|
-
const cookiePrefix = opts?.cookiePrefix || "better-auth";
|
|
169
|
-
const rawScheme = opts?.scheme || expo_constants.default.expoConfig?.scheme || expo_constants.default.platform?.scheme;
|
|
170
|
-
const scheme = Array.isArray(rawScheme) ? rawScheme[0] : rawScheme;
|
|
171
|
-
if (!scheme && !isWeb) throw new Error("Scheme not found in app.json. Please provide a scheme in the options.");
|
|
172
|
-
return {
|
|
173
|
-
id: "expo",
|
|
174
|
-
getActions(_, $store) {
|
|
175
|
-
store = $store;
|
|
176
|
-
return { getCookie: () => {
|
|
177
|
-
return getCookie(storage.getItem(cookieName) || "{}");
|
|
178
|
-
} };
|
|
179
|
-
},
|
|
180
|
-
fetchPlugins: [{
|
|
181
|
-
id: "expo",
|
|
182
|
-
name: "Expo",
|
|
183
|
-
hooks: { async onSuccess(context) {
|
|
184
|
-
if (isWeb) return;
|
|
185
|
-
const setCookie = context.response.headers.get("set-cookie");
|
|
186
|
-
if (setCookie) {
|
|
187
|
-
if (hasBetterAuthCookies(setCookie, cookiePrefix)) {
|
|
188
|
-
const prevCookie = await storage.getItem(cookieName);
|
|
189
|
-
const toSetCookie = getSetCookie(setCookie || "", prevCookie ?? void 0);
|
|
190
|
-
if (hasSessionCookieChanged(prevCookie, toSetCookie)) {
|
|
191
|
-
await storage.setItem(cookieName, toSetCookie);
|
|
192
|
-
store?.notify("$sessionSignal");
|
|
193
|
-
} else await storage.setItem(cookieName, toSetCookie);
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
if (context.request.url.toString().includes("/get-session") && !opts?.disableCache) {
|
|
197
|
-
const data = context.data;
|
|
198
|
-
storage.setItem(localCacheName, JSON.stringify(data));
|
|
199
|
-
}
|
|
200
|
-
if (context.data?.redirect && (context.request.url.toString().includes("/sign-in") || context.request.url.toString().includes("/link-social")) && !context.request?.body.includes("idToken")) {
|
|
201
|
-
const to = JSON.parse(context.request.body)?.callbackURL;
|
|
202
|
-
const signInURL = context.data?.url;
|
|
203
|
-
let Browser = void 0;
|
|
204
|
-
try {
|
|
205
|
-
Browser = await import("expo-web-browser");
|
|
206
|
-
} catch (error) {
|
|
207
|
-
throw new Error("\"expo-web-browser\" is not installed as a dependency!", { cause: error });
|
|
208
|
-
}
|
|
209
|
-
const proxyURL = `${context.request.baseURL}/expo-authorization-proxy?authorizationURL=${encodeURIComponent(signInURL)}`;
|
|
210
|
-
const result = await Browser.openAuthSessionAsync(proxyURL, to);
|
|
211
|
-
if (result.type !== "success") return;
|
|
212
|
-
const url = new URL(result.url);
|
|
213
|
-
const cookie = String(url.searchParams.get("cookie"));
|
|
214
|
-
if (!cookie) return;
|
|
215
|
-
storage.setItem(cookieName, getSetCookie(cookie));
|
|
216
|
-
store?.notify("$sessionSignal");
|
|
217
|
-
}
|
|
218
|
-
} },
|
|
219
|
-
async init(url, options) {
|
|
220
|
-
if (isWeb) return {
|
|
221
|
-
url,
|
|
222
|
-
options
|
|
223
|
-
};
|
|
224
|
-
options = options || {};
|
|
225
|
-
const cookie = getCookie(storage.getItem(cookieName) || "{}");
|
|
226
|
-
options.credentials = "omit";
|
|
227
|
-
options.headers = {
|
|
228
|
-
...options.headers,
|
|
229
|
-
cookie,
|
|
230
|
-
"expo-origin": getOrigin(scheme),
|
|
231
|
-
"x-skip-oauth-proxy": "true"
|
|
232
|
-
};
|
|
233
|
-
if (options.body?.callbackURL) {
|
|
234
|
-
if (options.body.callbackURL.startsWith("/")) {
|
|
235
|
-
const url$1 = expo_linking.createURL(options.body.callbackURL, { scheme });
|
|
236
|
-
options.body.callbackURL = url$1;
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
|
-
if (options.body?.newUserCallbackURL) {
|
|
240
|
-
if (options.body.newUserCallbackURL.startsWith("/")) {
|
|
241
|
-
const url$1 = expo_linking.createURL(options.body.newUserCallbackURL, { scheme });
|
|
242
|
-
options.body.newUserCallbackURL = url$1;
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
if (options.body?.errorCallbackURL) {
|
|
246
|
-
if (options.body.errorCallbackURL.startsWith("/")) {
|
|
247
|
-
const url$1 = expo_linking.createURL(options.body.errorCallbackURL, { scheme });
|
|
248
|
-
options.body.errorCallbackURL = url$1;
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
if (url.includes("/sign-out")) {
|
|
252
|
-
await storage.setItem(cookieName, "{}");
|
|
253
|
-
store?.atoms.session?.set({
|
|
254
|
-
...store.atoms.session.get(),
|
|
255
|
-
data: null,
|
|
256
|
-
error: null,
|
|
257
|
-
isPending: false
|
|
258
|
-
});
|
|
259
|
-
storage.setItem(localCacheName, "{}");
|
|
260
|
-
}
|
|
261
|
-
return {
|
|
262
|
-
url,
|
|
263
|
-
options
|
|
264
|
-
};
|
|
265
|
-
}
|
|
266
|
-
}]
|
|
267
|
-
};
|
|
268
|
-
};
|
|
269
|
-
|
|
270
|
-
//#endregion
|
|
271
|
-
exports.expoClient = expoClient;
|
|
272
|
-
exports.getCookie = getCookie;
|
|
273
|
-
exports.getSetCookie = getSetCookie;
|
|
274
|
-
exports.hasBetterAuthCookies = hasBetterAuthCookies;
|
|
275
|
-
exports.normalizeCookieName = normalizeCookieName;
|
|
276
|
-
exports.parseSetCookieHeader = parseSetCookieHeader;
|
|
277
|
-
exports.storageAdapter = storageAdapter;
|
package/dist/client.d.cts
DELETED
|
@@ -1,158 +0,0 @@
|
|
|
1
|
-
import * as _better_fetch_fetch0 from "@better-fetch/fetch";
|
|
2
|
-
import { BetterFetchOption } from "@better-fetch/fetch";
|
|
3
|
-
import { ClientStore } from "@better-auth/core";
|
|
4
|
-
|
|
5
|
-
//#region src/client.d.ts
|
|
6
|
-
interface CookieAttributes {
|
|
7
|
-
value: string;
|
|
8
|
-
expires?: Date | undefined;
|
|
9
|
-
"max-age"?: number | undefined;
|
|
10
|
-
domain?: string | undefined;
|
|
11
|
-
path?: string | undefined;
|
|
12
|
-
secure?: boolean | undefined;
|
|
13
|
-
httpOnly?: boolean | undefined;
|
|
14
|
-
sameSite?: ("Strict" | "Lax" | "None") | undefined;
|
|
15
|
-
}
|
|
16
|
-
declare function parseSetCookieHeader(header: string): Map<string, CookieAttributes>;
|
|
17
|
-
interface ExpoClientOptions {
|
|
18
|
-
scheme?: string | undefined;
|
|
19
|
-
storage: {
|
|
20
|
-
setItem: (key: string, value: string) => any;
|
|
21
|
-
getItem: (key: string) => string | null;
|
|
22
|
-
};
|
|
23
|
-
/**
|
|
24
|
-
* Prefix for local storage keys (e.g., "my-app_cookie", "my-app_session_data")
|
|
25
|
-
* @default "better-auth"
|
|
26
|
-
*/
|
|
27
|
-
storagePrefix?: string | undefined;
|
|
28
|
-
/**
|
|
29
|
-
* Prefix for server cookie names to filter (e.g., "better-auth.session_token")
|
|
30
|
-
* This is used to identify which cookies belong to better-auth to prevent
|
|
31
|
-
* infinite refetching when third-party cookies are set.
|
|
32
|
-
* @default "better-auth"
|
|
33
|
-
*/
|
|
34
|
-
cookiePrefix?: string | undefined;
|
|
35
|
-
disableCache?: boolean | undefined;
|
|
36
|
-
}
|
|
37
|
-
declare function getSetCookie(header: string, prevCookie?: string | undefined): string;
|
|
38
|
-
declare function getCookie(cookie: string): string;
|
|
39
|
-
/**
|
|
40
|
-
* Check if the Set-Cookie header contains session-related better-auth cookies.
|
|
41
|
-
* Only triggers session updates when session_token or session_data cookies are present.
|
|
42
|
-
* This prevents infinite refetching when non-session cookies (like third-party cookies) change.
|
|
43
|
-
*
|
|
44
|
-
* Supports multiple cookie naming patterns:
|
|
45
|
-
* - Default: "better-auth.session_token", "__Secure-better-auth.session_token"
|
|
46
|
-
* - Custom prefix: "myapp.session_token", "__Secure-myapp.session_token"
|
|
47
|
-
* - Custom full names: "my_custom_session_token", "custom_session_data"
|
|
48
|
-
* - No prefix (cookiePrefix=""): "session_token", "my_session_token", etc.
|
|
49
|
-
*
|
|
50
|
-
* @param setCookieHeader - The Set-Cookie header value
|
|
51
|
-
* @param cookiePrefix - The cookie prefix to check for. Can be empty string for custom cookie names.
|
|
52
|
-
* @returns true if the header contains session-related cookies, false otherwise
|
|
53
|
-
*/
|
|
54
|
-
declare function hasBetterAuthCookies(setCookieHeader: string, cookiePrefix: string): boolean;
|
|
55
|
-
/**
|
|
56
|
-
* Expo secure store does not support colons in the keys.
|
|
57
|
-
* This function replaces colons with underscores.
|
|
58
|
-
*
|
|
59
|
-
* @see https://github.com/better-auth/better-auth/issues/5426
|
|
60
|
-
*
|
|
61
|
-
* @param name cookie name to be saved in the storage
|
|
62
|
-
* @returns normalized cookie name
|
|
63
|
-
*/
|
|
64
|
-
declare function normalizeCookieName(name: string): string;
|
|
65
|
-
declare function storageAdapter(storage: {
|
|
66
|
-
getItem: (name: string) => string | null;
|
|
67
|
-
setItem: (name: string, value: string) => void;
|
|
68
|
-
}): {
|
|
69
|
-
getItem: (name: string) => string | null;
|
|
70
|
-
setItem: (name: string, value: string) => void;
|
|
71
|
-
};
|
|
72
|
-
declare const expoClient: (opts: ExpoClientOptions) => {
|
|
73
|
-
id: "expo";
|
|
74
|
-
getActions(_: _better_fetch_fetch0.BetterFetch, $store: ClientStore): {
|
|
75
|
-
/**
|
|
76
|
-
* Get the stored cookie.
|
|
77
|
-
*
|
|
78
|
-
* You can use this to get the cookie stored in the device and use it in your fetch
|
|
79
|
-
* requests.
|
|
80
|
-
*
|
|
81
|
-
* @example
|
|
82
|
-
* ```ts
|
|
83
|
-
* const cookie = client.getCookie();
|
|
84
|
-
* fetch("https://api.example.com", {
|
|
85
|
-
* headers: {
|
|
86
|
-
* cookie,
|
|
87
|
-
* },
|
|
88
|
-
* });
|
|
89
|
-
*/
|
|
90
|
-
getCookie: () => string;
|
|
91
|
-
};
|
|
92
|
-
fetchPlugins: {
|
|
93
|
-
id: string;
|
|
94
|
-
name: string;
|
|
95
|
-
hooks: {
|
|
96
|
-
onSuccess(context: _better_fetch_fetch0.SuccessContext<any>): Promise<void>;
|
|
97
|
-
};
|
|
98
|
-
init(url: string, options: {
|
|
99
|
-
method?: string | undefined;
|
|
100
|
-
headers?: (HeadersInit & (HeadersInit | {
|
|
101
|
-
accept: "application/json" | "text/plain" | "application/octet-stream";
|
|
102
|
-
"content-type": "application/json" | "text/plain" | "application/x-www-form-urlencoded" | "multipart/form-data" | "application/octet-stream";
|
|
103
|
-
authorization: "Bearer" | "Basic";
|
|
104
|
-
})) | undefined;
|
|
105
|
-
redirect?: RequestRedirect | undefined;
|
|
106
|
-
cache?: RequestCache | undefined;
|
|
107
|
-
credentials?: RequestCredentials | undefined;
|
|
108
|
-
integrity?: string | undefined;
|
|
109
|
-
keepalive?: boolean | undefined;
|
|
110
|
-
mode?: RequestMode | undefined;
|
|
111
|
-
priority?: RequestPriority | undefined;
|
|
112
|
-
referrer?: string | undefined;
|
|
113
|
-
referrerPolicy?: ReferrerPolicy | undefined;
|
|
114
|
-
signal?: (AbortSignal | null) | undefined;
|
|
115
|
-
window?: null | undefined;
|
|
116
|
-
onRequest?: (<T extends Record<string, any>>(context: _better_fetch_fetch0.RequestContext<T>) => Promise<_better_fetch_fetch0.RequestContext | void> | _better_fetch_fetch0.RequestContext | void) | undefined;
|
|
117
|
-
onResponse?: ((context: _better_fetch_fetch0.ResponseContext) => Promise<Response | void | _better_fetch_fetch0.ResponseContext> | Response | _better_fetch_fetch0.ResponseContext | void) | undefined;
|
|
118
|
-
onSuccess?: ((context: _better_fetch_fetch0.SuccessContext<any>) => Promise<void> | void) | undefined;
|
|
119
|
-
onError?: ((context: _better_fetch_fetch0.ErrorContext) => Promise<void> | void) | undefined;
|
|
120
|
-
onRetry?: ((response: _better_fetch_fetch0.ResponseContext) => Promise<void> | void) | undefined;
|
|
121
|
-
hookOptions?: {
|
|
122
|
-
cloneResponse?: boolean;
|
|
123
|
-
} | undefined;
|
|
124
|
-
timeout?: number | undefined;
|
|
125
|
-
customFetchImpl?: _better_fetch_fetch0.FetchEsque | undefined;
|
|
126
|
-
plugins?: _better_fetch_fetch0.BetterFetchPlugin[] | undefined;
|
|
127
|
-
baseURL?: string | undefined;
|
|
128
|
-
throw?: boolean | undefined;
|
|
129
|
-
auth?: ({
|
|
130
|
-
type: "Bearer";
|
|
131
|
-
token: string | Promise<string | undefined> | (() => string | Promise<string | undefined> | undefined) | undefined;
|
|
132
|
-
} | {
|
|
133
|
-
type: "Basic";
|
|
134
|
-
username: string | (() => string | undefined) | undefined;
|
|
135
|
-
password: string | (() => string | undefined) | undefined;
|
|
136
|
-
} | {
|
|
137
|
-
type: "Custom";
|
|
138
|
-
prefix: string | (() => string | undefined) | undefined;
|
|
139
|
-
value: string | (() => string | undefined) | undefined;
|
|
140
|
-
}) | undefined;
|
|
141
|
-
body?: any;
|
|
142
|
-
query?: any;
|
|
143
|
-
params?: any;
|
|
144
|
-
duplex?: "full" | "half" | undefined;
|
|
145
|
-
jsonParser?: ((text: string) => Promise<any> | any) | undefined;
|
|
146
|
-
retry?: _better_fetch_fetch0.RetryOptions | undefined;
|
|
147
|
-
retryAttempt?: number | undefined;
|
|
148
|
-
output?: (_better_fetch_fetch0.StandardSchemaV1 | typeof Blob | typeof File) | undefined;
|
|
149
|
-
errorSchema?: _better_fetch_fetch0.StandardSchemaV1 | undefined;
|
|
150
|
-
disableValidation?: boolean | undefined;
|
|
151
|
-
} | undefined): Promise<{
|
|
152
|
-
url: string;
|
|
153
|
-
options: BetterFetchOption;
|
|
154
|
-
}>;
|
|
155
|
-
}[];
|
|
156
|
-
};
|
|
157
|
-
//#endregion
|
|
158
|
-
export { expoClient, getCookie, getSetCookie, hasBetterAuthCookies, normalizeCookieName, parseSetCookieHeader, storageAdapter };
|
package/dist/index.cjs
DELETED
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
const require_chunk = require('./chunk-CUT6urMc.cjs');
|
|
2
|
-
let __better_auth_core_api = require("@better-auth/core/api");
|
|
3
|
-
__better_auth_core_api = require_chunk.__toESM(__better_auth_core_api);
|
|
4
|
-
let better_call = require("better-call");
|
|
5
|
-
better_call = require_chunk.__toESM(better_call);
|
|
6
|
-
let zod = require("zod");
|
|
7
|
-
zod = require_chunk.__toESM(zod);
|
|
8
|
-
|
|
9
|
-
//#region src/index.ts
|
|
10
|
-
const expo = (options) => {
|
|
11
|
-
return {
|
|
12
|
-
id: "expo",
|
|
13
|
-
init: (ctx) => {
|
|
14
|
-
return { options: { trustedOrigins: process.env.NODE_ENV === "development" ? ["exp://"] : [] } };
|
|
15
|
-
},
|
|
16
|
-
async onRequest(request, ctx) {
|
|
17
|
-
if (options?.disableOriginOverride || request.headers.get("origin")) return;
|
|
18
|
-
/**
|
|
19
|
-
* To bypass origin check from expo, we need to set the origin
|
|
20
|
-
* header to the expo-origin header
|
|
21
|
-
*/
|
|
22
|
-
const expoOrigin = request.headers.get("expo-origin");
|
|
23
|
-
if (!expoOrigin) return;
|
|
24
|
-
const req = request.clone();
|
|
25
|
-
req.headers.set("origin", expoOrigin);
|
|
26
|
-
return { request: req };
|
|
27
|
-
},
|
|
28
|
-
hooks: { after: [{
|
|
29
|
-
matcher(context) {
|
|
30
|
-
return !!(context.path?.startsWith("/callback") || context.path?.startsWith("/oauth2/callback"));
|
|
31
|
-
},
|
|
32
|
-
handler: (0, __better_auth_core_api.createAuthMiddleware)(async (ctx) => {
|
|
33
|
-
const headers = ctx.context.responseHeaders;
|
|
34
|
-
const location = headers?.get("location");
|
|
35
|
-
if (!location) return;
|
|
36
|
-
if (location.includes("/oauth-proxy-callback")) return;
|
|
37
|
-
if (!ctx.context.trustedOrigins.filter((origin) => !origin.startsWith("http")).some((origin) => location?.startsWith(origin))) return;
|
|
38
|
-
const cookie = headers?.get("set-cookie");
|
|
39
|
-
if (!cookie) return;
|
|
40
|
-
const url = new URL(location);
|
|
41
|
-
url.searchParams.set("cookie", cookie);
|
|
42
|
-
ctx.setHeader("location", url.toString());
|
|
43
|
-
})
|
|
44
|
-
}] },
|
|
45
|
-
endpoints: { expoAuthorizationProxy: (0, __better_auth_core_api.createAuthEndpoint)("/expo-authorization-proxy", {
|
|
46
|
-
method: "GET",
|
|
47
|
-
query: zod.z.object({ authorizationURL: zod.z.string() }),
|
|
48
|
-
metadata: { isAction: false }
|
|
49
|
-
}, async (ctx) => {
|
|
50
|
-
const { authorizationURL } = ctx.query;
|
|
51
|
-
const state = new URL(authorizationURL).searchParams.get("state");
|
|
52
|
-
if (!state) throw new better_call.APIError("BAD_REQUEST", { message: "Unexpected error" });
|
|
53
|
-
const stateCookie = ctx.context.createAuthCookie("state", { maxAge: 300 * 1e3 });
|
|
54
|
-
await ctx.setSignedCookie(stateCookie.name, state, ctx.context.secret, stateCookie.attributes);
|
|
55
|
-
return ctx.redirect(ctx.query.authorizationURL);
|
|
56
|
-
}) }
|
|
57
|
-
};
|
|
58
|
-
};
|
|
59
|
-
|
|
60
|
-
//#endregion
|
|
61
|
-
exports.expo = expo;
|
package/dist/index.d.cts
DELETED
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
import * as better_auth0 from "better-auth";
|
|
2
|
-
import * as better_call0 from "better-call";
|
|
3
|
-
import { z } from "zod";
|
|
4
|
-
|
|
5
|
-
//#region src/index.d.ts
|
|
6
|
-
interface ExpoOptions {
|
|
7
|
-
/**
|
|
8
|
-
* Disable origin override for expo API routes
|
|
9
|
-
* When set to true, the origin header will not be overridden for expo API routes
|
|
10
|
-
*/
|
|
11
|
-
disableOriginOverride?: boolean | undefined;
|
|
12
|
-
}
|
|
13
|
-
declare const expo: (options?: ExpoOptions | undefined) => {
|
|
14
|
-
id: "expo";
|
|
15
|
-
init: (ctx: better_auth0.AuthContext) => {
|
|
16
|
-
options: {
|
|
17
|
-
trustedOrigins: string[];
|
|
18
|
-
};
|
|
19
|
-
};
|
|
20
|
-
onRequest(request: Request, ctx: better_auth0.AuthContext): Promise<{
|
|
21
|
-
request: Request;
|
|
22
|
-
} | undefined>;
|
|
23
|
-
hooks: {
|
|
24
|
-
after: {
|
|
25
|
-
matcher(context: better_auth0.HookEndpointContext): boolean;
|
|
26
|
-
handler: (inputContext: better_call0.MiddlewareInputContext<better_call0.MiddlewareOptions>) => Promise<void>;
|
|
27
|
-
}[];
|
|
28
|
-
};
|
|
29
|
-
endpoints: {
|
|
30
|
-
expoAuthorizationProxy: better_call0.StrictEndpoint<"/expo-authorization-proxy", {
|
|
31
|
-
method: "GET";
|
|
32
|
-
query: z.ZodObject<{
|
|
33
|
-
authorizationURL: z.ZodString;
|
|
34
|
-
}, z.core.$strip>;
|
|
35
|
-
metadata: {
|
|
36
|
-
isAction: boolean;
|
|
37
|
-
};
|
|
38
|
-
} & {
|
|
39
|
-
use: any[];
|
|
40
|
-
}, {
|
|
41
|
-
status: ("OK" | "CREATED" | "ACCEPTED" | "NO_CONTENT" | "MULTIPLE_CHOICES" | "MOVED_PERMANENTLY" | "FOUND" | "SEE_OTHER" | "NOT_MODIFIED" | "TEMPORARY_REDIRECT" | "BAD_REQUEST" | "UNAUTHORIZED" | "PAYMENT_REQUIRED" | "FORBIDDEN" | "NOT_FOUND" | "METHOD_NOT_ALLOWED" | "NOT_ACCEPTABLE" | "PROXY_AUTHENTICATION_REQUIRED" | "REQUEST_TIMEOUT" | "CONFLICT" | "GONE" | "LENGTH_REQUIRED" | "PRECONDITION_FAILED" | "PAYLOAD_TOO_LARGE" | "URI_TOO_LONG" | "UNSUPPORTED_MEDIA_TYPE" | "RANGE_NOT_SATISFIABLE" | "EXPECTATION_FAILED" | "I'M_A_TEAPOT" | "MISDIRECTED_REQUEST" | "UNPROCESSABLE_ENTITY" | "LOCKED" | "FAILED_DEPENDENCY" | "TOO_EARLY" | "UPGRADE_REQUIRED" | "PRECONDITION_REQUIRED" | "TOO_MANY_REQUESTS" | "REQUEST_HEADER_FIELDS_TOO_LARGE" | "UNAVAILABLE_FOR_LEGAL_REASONS" | "INTERNAL_SERVER_ERROR" | "NOT_IMPLEMENTED" | "BAD_GATEWAY" | "SERVICE_UNAVAILABLE" | "GATEWAY_TIMEOUT" | "HTTP_VERSION_NOT_SUPPORTED" | "VARIANT_ALSO_NEGOTIATES" | "INSUFFICIENT_STORAGE" | "LOOP_DETECTED" | "NOT_EXTENDED" | "NETWORK_AUTHENTICATION_REQUIRED") | better_call0.Status;
|
|
42
|
-
body: ({
|
|
43
|
-
message?: string;
|
|
44
|
-
code?: string;
|
|
45
|
-
cause?: unknown;
|
|
46
|
-
} & Record<string, any>) | undefined;
|
|
47
|
-
headers: HeadersInit;
|
|
48
|
-
statusCode: number;
|
|
49
|
-
name: string;
|
|
50
|
-
message: string;
|
|
51
|
-
stack?: string;
|
|
52
|
-
cause?: unknown;
|
|
53
|
-
}>;
|
|
54
|
-
};
|
|
55
|
-
};
|
|
56
|
-
//#endregion
|
|
57
|
-
export { ExpoOptions, expo };
|