better-auth 0.2.3-beta.8 → 0.2.4
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/access.js +125 -1
- package/dist/adapters.d.ts +1 -2
- package/dist/adapters.js +1155 -14
- package/dist/api.js +2458 -4
- package/dist/cli.js +1010 -3
- package/dist/client/plugins.js +527 -2
- package/dist/client.js +382 -1
- package/dist/index.js +3670 -5
- package/dist/next-js.js +34 -1
- package/dist/node.js +8 -1
- package/dist/plugins.js +5529 -4
- package/dist/react.js +393 -1
- package/dist/social.js +586 -2
- package/dist/solid-start.js +13 -1
- package/dist/solid.js +389 -1
- package/dist/svelte-kit.js +34 -1
- package/dist/svelte.js +380 -1
- package/dist/utils.js +453 -2
- package/dist/vue.js +389 -1
- package/package.json +5 -3
package/dist/utils.js
CHANGED
|
@@ -1,2 +1,453 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
// src/utils/shim.ts
|
|
2
|
+
var shimContext = (originalObject, newContext) => {
|
|
3
|
+
const shimmedObj = {};
|
|
4
|
+
for (const [key, value] of Object.entries(originalObject)) {
|
|
5
|
+
shimmedObj[key] = (ctx) => {
|
|
6
|
+
return value({
|
|
7
|
+
...ctx,
|
|
8
|
+
context: {
|
|
9
|
+
...newContext,
|
|
10
|
+
...ctx.context
|
|
11
|
+
}
|
|
12
|
+
});
|
|
13
|
+
};
|
|
14
|
+
shimmedObj[key].path = value.path;
|
|
15
|
+
shimmedObj[key].method = value.method;
|
|
16
|
+
shimmedObj[key].options = value.options;
|
|
17
|
+
shimmedObj[key].headers = value.headers;
|
|
18
|
+
}
|
|
19
|
+
return shimmedObj;
|
|
20
|
+
};
|
|
21
|
+
var shimEndpoint = (ctx, value) => {
|
|
22
|
+
return async (context) => {
|
|
23
|
+
for (const plugin of ctx.options.plugins || []) {
|
|
24
|
+
if (plugin.hooks?.before) {
|
|
25
|
+
for (const hook of plugin.hooks.before) {
|
|
26
|
+
const match = hook.matcher({
|
|
27
|
+
...context,
|
|
28
|
+
...value
|
|
29
|
+
});
|
|
30
|
+
if (match) {
|
|
31
|
+
const hookRes = await hook.handler(context);
|
|
32
|
+
if (hookRes && "context" in hookRes) {
|
|
33
|
+
context = {
|
|
34
|
+
...context,
|
|
35
|
+
...hookRes.context,
|
|
36
|
+
...value
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
const endpointRes = value({
|
|
44
|
+
...context,
|
|
45
|
+
context: {
|
|
46
|
+
...ctx,
|
|
47
|
+
...context.context
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
let response = endpointRes;
|
|
51
|
+
for (const plugin of ctx.options.plugins || []) {
|
|
52
|
+
if (plugin.hooks?.after) {
|
|
53
|
+
for (const hook of plugin.hooks.after) {
|
|
54
|
+
const match = hook.matcher(context);
|
|
55
|
+
if (match) {
|
|
56
|
+
const obj = Object.assign(context, {
|
|
57
|
+
returned: endpointRes
|
|
58
|
+
});
|
|
59
|
+
const hookRes = await hook.handler(obj);
|
|
60
|
+
if (hookRes && "response" in hookRes) {
|
|
61
|
+
response = hookRes.response;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return response;
|
|
68
|
+
};
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
// src/error/better-auth-error.ts
|
|
72
|
+
var BetterAuthError = class extends Error {
|
|
73
|
+
constructor(message, cause, docsLink) {
|
|
74
|
+
super(message);
|
|
75
|
+
this.name = "BetterAuthError";
|
|
76
|
+
this.message = message;
|
|
77
|
+
this.cause = cause;
|
|
78
|
+
this.stack = "";
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
// src/utils/base-url.ts
|
|
83
|
+
function checkHasPath(url) {
|
|
84
|
+
try {
|
|
85
|
+
const parsedUrl = new URL(url);
|
|
86
|
+
return parsedUrl.pathname !== "/";
|
|
87
|
+
} catch (error) {
|
|
88
|
+
throw new BetterAuthError(
|
|
89
|
+
`Invalid base URL: ${url}. Please provide a valid base URL.`
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
function withPath(url, path = "/api/auth") {
|
|
94
|
+
const hasPath = checkHasPath(url);
|
|
95
|
+
if (hasPath) {
|
|
96
|
+
return url;
|
|
97
|
+
}
|
|
98
|
+
path = path.startsWith("/") ? path : `/${path}`;
|
|
99
|
+
return `${url}${path}`;
|
|
100
|
+
}
|
|
101
|
+
function getBaseURL(url, path) {
|
|
102
|
+
if (url) {
|
|
103
|
+
return withPath(url, path);
|
|
104
|
+
}
|
|
105
|
+
const env = process?.env || {};
|
|
106
|
+
const fromEnv = env.BETTER_AUTH_URL || env.NEXT_PUBLIC_BETTER_AUTH_URL || env.PUBLIC_BETTER_AUTH_URL || env.NUXT_PUBLIC_BETTER_AUTH_URL || env.NUXT_PUBLIC_AUTH_URL || (env.BASE_URL !== "/" ? env.BASE_URL : void 0);
|
|
107
|
+
if (fromEnv) {
|
|
108
|
+
return withPath(fromEnv, path);
|
|
109
|
+
}
|
|
110
|
+
if (typeof window !== "undefined") {
|
|
111
|
+
return withPath(window.location.origin, path);
|
|
112
|
+
}
|
|
113
|
+
return void 0;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// src/utils/clone.ts
|
|
117
|
+
var cloneBase = (object, base) => {
|
|
118
|
+
for (const key in object) {
|
|
119
|
+
if (!object.hasOwnProperty(key)) continue;
|
|
120
|
+
const value = object[key];
|
|
121
|
+
if (typeof value === "object" && value !== null) {
|
|
122
|
+
base[key] = cloneBase(value, value.constructor());
|
|
123
|
+
} else {
|
|
124
|
+
base[key] = value;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
return base;
|
|
128
|
+
};
|
|
129
|
+
var clone = (object) => {
|
|
130
|
+
return cloneBase(object, object.constructor());
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
// src/utils/cookies.ts
|
|
134
|
+
import { TimeSpan } from "oslo";
|
|
135
|
+
function getCookies(options) {
|
|
136
|
+
const secure = !!options.advanced?.useSecureCookies || process.env.NODE_ENV !== "development" && process.env.NODE_ENV !== "test";
|
|
137
|
+
const secureCookiePrefix = secure ? "__Secure-" : "";
|
|
138
|
+
const cookiePrefix = "better-auth";
|
|
139
|
+
const sessionMaxAge = new TimeSpan(7, "d").seconds();
|
|
140
|
+
return {
|
|
141
|
+
sessionToken: {
|
|
142
|
+
name: `${secureCookiePrefix}${cookiePrefix}.session_token`,
|
|
143
|
+
options: {
|
|
144
|
+
httpOnly: true,
|
|
145
|
+
sameSite: "lax",
|
|
146
|
+
path: "/",
|
|
147
|
+
secure: !!secureCookiePrefix,
|
|
148
|
+
maxAge: sessionMaxAge
|
|
149
|
+
}
|
|
150
|
+
},
|
|
151
|
+
csrfToken: {
|
|
152
|
+
name: `${secureCookiePrefix ? "__Host-" : ""}${cookiePrefix}.csrf_token`,
|
|
153
|
+
options: {
|
|
154
|
+
httpOnly: true,
|
|
155
|
+
sameSite: "lax",
|
|
156
|
+
path: "/",
|
|
157
|
+
secure: !!secureCookiePrefix,
|
|
158
|
+
maxAge: 60 * 60 * 24 * 7
|
|
159
|
+
}
|
|
160
|
+
},
|
|
161
|
+
state: {
|
|
162
|
+
name: `${secureCookiePrefix}${cookiePrefix}.state`,
|
|
163
|
+
options: {
|
|
164
|
+
httpOnly: true,
|
|
165
|
+
sameSite: "lax",
|
|
166
|
+
path: "/",
|
|
167
|
+
secure: !!secureCookiePrefix,
|
|
168
|
+
maxAge: 60 * 15
|
|
169
|
+
// 15 minutes in seconds
|
|
170
|
+
}
|
|
171
|
+
},
|
|
172
|
+
pkCodeVerifier: {
|
|
173
|
+
name: `${secureCookiePrefix}${cookiePrefix}.pk_code_verifier`,
|
|
174
|
+
options: {
|
|
175
|
+
httpOnly: true,
|
|
176
|
+
sameSite: "lax",
|
|
177
|
+
path: "/",
|
|
178
|
+
secure: !!secureCookiePrefix,
|
|
179
|
+
maxAge: 60 * 15
|
|
180
|
+
// 15 minutes in seconds
|
|
181
|
+
}
|
|
182
|
+
},
|
|
183
|
+
dontRememberToken: {
|
|
184
|
+
name: `${secureCookiePrefix}${cookiePrefix}.dont_remember`,
|
|
185
|
+
options: {
|
|
186
|
+
httpOnly: true,
|
|
187
|
+
sameSite: "lax",
|
|
188
|
+
path: "/",
|
|
189
|
+
secure: !!secureCookiePrefix
|
|
190
|
+
//no max age so it expires when the browser closes
|
|
191
|
+
}
|
|
192
|
+
},
|
|
193
|
+
nonce: {
|
|
194
|
+
name: `${secureCookiePrefix}${cookiePrefix}.nonce`,
|
|
195
|
+
options: {
|
|
196
|
+
httpOnly: true,
|
|
197
|
+
sameSite: "lax",
|
|
198
|
+
path: "/",
|
|
199
|
+
secure: !!secureCookiePrefix,
|
|
200
|
+
maxAge: 60 * 15
|
|
201
|
+
// 15 minutes in seconds
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
function createCookieGetter(options) {
|
|
207
|
+
const secure = !!options.advanced?.useSecureCookies || process.env.NODE_ENV === "production";
|
|
208
|
+
const secureCookiePrefix = secure ? "__Secure-" : "";
|
|
209
|
+
const cookiePrefix = "better-auth";
|
|
210
|
+
function getCookie(cookieName, options2) {
|
|
211
|
+
return {
|
|
212
|
+
name: process.env.NODE_ENV === "production" ? `${secureCookiePrefix}${cookiePrefix}.${cookieName}` : `${cookiePrefix}.${cookieName}`,
|
|
213
|
+
options: {
|
|
214
|
+
secure: !!secureCookiePrefix,
|
|
215
|
+
sameSite: "lax",
|
|
216
|
+
path: "/",
|
|
217
|
+
maxAge: 60 * 15,
|
|
218
|
+
// 15 minutes in seconds
|
|
219
|
+
...options2
|
|
220
|
+
}
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
return getCookie;
|
|
224
|
+
}
|
|
225
|
+
async function setSessionCookie(ctx, sessionToken, dontRememberMe, overrides) {
|
|
226
|
+
const options = ctx.context.authCookies.sessionToken.options;
|
|
227
|
+
options.maxAge = dontRememberMe ? void 0 : options.maxAge;
|
|
228
|
+
await ctx.setSignedCookie(
|
|
229
|
+
ctx.context.authCookies.sessionToken.name,
|
|
230
|
+
sessionToken,
|
|
231
|
+
ctx.context.secret,
|
|
232
|
+
options
|
|
233
|
+
);
|
|
234
|
+
if (dontRememberMe) {
|
|
235
|
+
await ctx.setSignedCookie(
|
|
236
|
+
ctx.context.authCookies.dontRememberToken.name,
|
|
237
|
+
"true",
|
|
238
|
+
ctx.context.secret,
|
|
239
|
+
ctx.context.authCookies.dontRememberToken.options
|
|
240
|
+
);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
function deleteSessionCookie(ctx) {
|
|
244
|
+
ctx.setCookie(ctx.context.authCookies.sessionToken.name, "", {
|
|
245
|
+
maxAge: 0
|
|
246
|
+
});
|
|
247
|
+
ctx.setCookie(ctx.context.authCookies.dontRememberToken.name, "", {
|
|
248
|
+
maxAge: 0
|
|
249
|
+
});
|
|
250
|
+
}
|
|
251
|
+
function parseSetCookieHeader(header) {
|
|
252
|
+
const cookieMap = /* @__PURE__ */ new Map();
|
|
253
|
+
const cookies = header.split(", ");
|
|
254
|
+
cookies.forEach((cookie) => {
|
|
255
|
+
const [nameValue, ...attributes] = cookie.split("; ");
|
|
256
|
+
const [name, value] = nameValue.split("=");
|
|
257
|
+
const cookieObj = { value };
|
|
258
|
+
attributes.forEach((attr) => {
|
|
259
|
+
const [attrName, attrValue] = attr.split("=");
|
|
260
|
+
cookieObj[attrName.toLowerCase()] = attrValue || true;
|
|
261
|
+
});
|
|
262
|
+
cookieMap.set(name, cookieObj);
|
|
263
|
+
});
|
|
264
|
+
return cookieMap;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
// src/utils/date.ts
|
|
268
|
+
var getDate = (span, isSeconds = false) => {
|
|
269
|
+
const date = /* @__PURE__ */ new Date();
|
|
270
|
+
return new Date(date.getTime() + (isSeconds ? span * 1e3 : span));
|
|
271
|
+
};
|
|
272
|
+
|
|
273
|
+
// src/utils/get-request-ip.ts
|
|
274
|
+
function getIp(req) {
|
|
275
|
+
const testIP = "127.0.0.1";
|
|
276
|
+
if (process.env.NODE_ENV === "test") {
|
|
277
|
+
return testIP;
|
|
278
|
+
}
|
|
279
|
+
const headers = [
|
|
280
|
+
"x-client-ip",
|
|
281
|
+
"x-forwarded-for",
|
|
282
|
+
"cf-connecting-ip",
|
|
283
|
+
"fastly-client-ip",
|
|
284
|
+
"x-real-ip",
|
|
285
|
+
"x-cluster-client-ip",
|
|
286
|
+
"x-forwarded",
|
|
287
|
+
"forwarded-for",
|
|
288
|
+
"forwarded"
|
|
289
|
+
];
|
|
290
|
+
for (const header of headers) {
|
|
291
|
+
const value = req.headers.get(header);
|
|
292
|
+
if (typeof value === "string") {
|
|
293
|
+
const ip = value.split(",")[0].trim();
|
|
294
|
+
if (ip) return ip;
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
return null;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
// src/utils/hide-metadata.ts
|
|
301
|
+
var HIDE_METADATA = {
|
|
302
|
+
isAction: false
|
|
303
|
+
};
|
|
304
|
+
|
|
305
|
+
// src/utils/id.ts
|
|
306
|
+
import { alphabet, generateRandomString } from "oslo/crypto";
|
|
307
|
+
var generateId = () => {
|
|
308
|
+
return generateRandomString(36, alphabet("a-z", "0-9"));
|
|
309
|
+
};
|
|
310
|
+
|
|
311
|
+
// src/utils/logger.ts
|
|
312
|
+
import { createConsola } from "consola";
|
|
313
|
+
var consola = createConsola({
|
|
314
|
+
formatOptions: {
|
|
315
|
+
date: false,
|
|
316
|
+
colors: true,
|
|
317
|
+
compact: true
|
|
318
|
+
},
|
|
319
|
+
defaults: {
|
|
320
|
+
tag: "Better Auth"
|
|
321
|
+
}
|
|
322
|
+
});
|
|
323
|
+
var createLogger = (options) => {
|
|
324
|
+
return {
|
|
325
|
+
log: (...args) => {
|
|
326
|
+
!options?.disabled && consola.log("", ...args);
|
|
327
|
+
},
|
|
328
|
+
error: (...args) => {
|
|
329
|
+
!options?.disabled && consola.error("", ...args);
|
|
330
|
+
},
|
|
331
|
+
warn: (...args) => {
|
|
332
|
+
!options?.disabled && consola.warn("", ...args);
|
|
333
|
+
},
|
|
334
|
+
info: (...args) => {
|
|
335
|
+
!options?.disabled && consola.info("", ...args);
|
|
336
|
+
},
|
|
337
|
+
debug: (...args) => {
|
|
338
|
+
!options?.disabled && consola.debug("", ...args);
|
|
339
|
+
},
|
|
340
|
+
box: (...args) => {
|
|
341
|
+
!options?.disabled && consola.box("", ...args);
|
|
342
|
+
},
|
|
343
|
+
success: (...args) => {
|
|
344
|
+
!options?.disabled && consola.success("", ...args);
|
|
345
|
+
},
|
|
346
|
+
break: (...args) => {
|
|
347
|
+
!options?.disabled && console.log("\n");
|
|
348
|
+
}
|
|
349
|
+
};
|
|
350
|
+
};
|
|
351
|
+
var logger = createLogger();
|
|
352
|
+
|
|
353
|
+
// src/utils/merger.ts
|
|
354
|
+
var mergeObjects = (target, source) => {
|
|
355
|
+
for (const key in source) {
|
|
356
|
+
if (!source.hasOwnProperty(key)) continue;
|
|
357
|
+
if (key === "constructor" || key === "prototype" || key === "__proto__")
|
|
358
|
+
continue;
|
|
359
|
+
const value = source[key];
|
|
360
|
+
if (isPrimitive(value)) {
|
|
361
|
+
if (value !== void 0 || !(key in target)) {
|
|
362
|
+
target[key] = value;
|
|
363
|
+
}
|
|
364
|
+
} else if (!target[key] || isArray(value)) {
|
|
365
|
+
target[key] = clone(value);
|
|
366
|
+
} else {
|
|
367
|
+
target[key] = mergeObjects(target[key], value);
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
return target;
|
|
371
|
+
};
|
|
372
|
+
var isArray = (value) => {
|
|
373
|
+
return Array.isArray(value);
|
|
374
|
+
};
|
|
375
|
+
var isPrimitive = (value) => {
|
|
376
|
+
if (value === null) return true;
|
|
377
|
+
const type = typeof value;
|
|
378
|
+
return type !== "object" && type !== "function";
|
|
379
|
+
};
|
|
380
|
+
var merge = (objects) => {
|
|
381
|
+
const target = clone(objects[0]);
|
|
382
|
+
for (let i = 1, l = objects.length; i < l; i++) {
|
|
383
|
+
mergeObjects(target, objects[i]);
|
|
384
|
+
}
|
|
385
|
+
return target;
|
|
386
|
+
};
|
|
387
|
+
|
|
388
|
+
// src/utils/misc.ts
|
|
389
|
+
function capitalizeFirstLetter(str) {
|
|
390
|
+
return str.charAt(0).toUpperCase() + str.slice(1);
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
// src/utils/password.ts
|
|
394
|
+
async function validatePassword(ctx, data) {
|
|
395
|
+
const accounts = await ctx.context.internalAdapter.findAccounts(data.userId);
|
|
396
|
+
const credentialAccount = accounts?.find(
|
|
397
|
+
(account) => account.providerId === "credential"
|
|
398
|
+
);
|
|
399
|
+
const currentPassword = credentialAccount?.password;
|
|
400
|
+
if (!credentialAccount || !currentPassword) {
|
|
401
|
+
return false;
|
|
402
|
+
}
|
|
403
|
+
const compare = await ctx.context.password.verify(
|
|
404
|
+
currentPassword,
|
|
405
|
+
data.password
|
|
406
|
+
);
|
|
407
|
+
return compare;
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
// src/utils/state.ts
|
|
411
|
+
import { generateState as generateStateOAuth } from "oslo/oauth2";
|
|
412
|
+
import { z } from "zod";
|
|
413
|
+
function generateState(callbackURL, currentURL, dontRememberMe) {
|
|
414
|
+
const code = generateStateOAuth();
|
|
415
|
+
const state = JSON.stringify({
|
|
416
|
+
code,
|
|
417
|
+
callbackURL,
|
|
418
|
+
currentURL,
|
|
419
|
+
dontRememberMe
|
|
420
|
+
});
|
|
421
|
+
return { state, code };
|
|
422
|
+
}
|
|
423
|
+
function parseState(state) {
|
|
424
|
+
const data = z.object({
|
|
425
|
+
code: z.string(),
|
|
426
|
+
callbackURL: z.string().optional(),
|
|
427
|
+
currentURL: z.string().optional(),
|
|
428
|
+
dontRememberMe: z.boolean().optional()
|
|
429
|
+
}).safeParse(JSON.parse(state));
|
|
430
|
+
return data;
|
|
431
|
+
}
|
|
432
|
+
export {
|
|
433
|
+
HIDE_METADATA,
|
|
434
|
+
capitalizeFirstLetter,
|
|
435
|
+
clone,
|
|
436
|
+
createCookieGetter,
|
|
437
|
+
createLogger,
|
|
438
|
+
deleteSessionCookie,
|
|
439
|
+
generateId,
|
|
440
|
+
generateState,
|
|
441
|
+
getBaseURL,
|
|
442
|
+
getCookies,
|
|
443
|
+
getDate,
|
|
444
|
+
getIp,
|
|
445
|
+
logger,
|
|
446
|
+
merge,
|
|
447
|
+
parseSetCookieHeader,
|
|
448
|
+
parseState,
|
|
449
|
+
setSessionCookie,
|
|
450
|
+
shimContext,
|
|
451
|
+
shimEndpoint,
|
|
452
|
+
validatePassword
|
|
453
|
+
};
|