better-auth 0.2.2 → 0.2.3-beta.10

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.
@@ -1,11 +1,11 @@
1
- import { U as User, S as Session } from './schema-D9o3OF80.js';
1
+ import { U as User, S as Session } from './index-CE92ti2Z.js';
2
2
  import * as better_call from 'better-call';
3
3
  import { z, ZodObject, ZodOptional, ZodArray, ZodLiteral } from 'zod';
4
4
  import { P as Prettify } from './helper-C1ihmerM.js';
5
5
  import { A as AccessControl, R as Role, S as StatementsPrimitive, g as defaultRoles } from './statement-CU-fdHXK.js';
6
6
  import * as _better_fetch_fetch from '@better-fetch/fetch';
7
7
  import { BetterFetch, BetterFetchOption } from '@better-fetch/fetch';
8
- import { H as HookEndpointContext } from './index-D_ohe9r9.js';
8
+ import { H as HookEndpointContext } from './index-gO-yM4kI.js';
9
9
  import * as nanostores from 'nanostores';
10
10
  import { atom } from 'nanostores';
11
11
  import * as _simplewebauthn_types from '@simplewebauthn/types';
@@ -2357,6 +2357,7 @@ declare const organization: <O extends OrganizationOptions>(options?: O) => {
2357
2357
  fields: {
2358
2358
  name: {
2359
2359
  type: "string";
2360
+ required: true;
2360
2361
  };
2361
2362
  slug: {
2362
2363
  type: "string";
@@ -2430,6 +2431,7 @@ declare const organization: <O extends OrganizationOptions>(options?: O) => {
2430
2431
  model: string;
2431
2432
  field: string;
2432
2433
  };
2434
+ required: true;
2433
2435
  };
2434
2436
  };
2435
2437
  };
@@ -4009,6 +4011,7 @@ declare const passkey: (options?: PasskeyOptions) => {
4009
4011
  };
4010
4012
  publicKey: {
4011
4013
  type: "string";
4014
+ required: true;
4012
4015
  };
4013
4016
  userId: {
4014
4017
  type: "string";
@@ -4016,18 +4019,23 @@ declare const passkey: (options?: PasskeyOptions) => {
4016
4019
  model: string;
4017
4020
  field: string;
4018
4021
  };
4022
+ required: true;
4019
4023
  };
4020
4024
  webauthnUserID: {
4021
4025
  type: "string";
4026
+ required: true;
4022
4027
  };
4023
4028
  counter: {
4024
4029
  type: "number";
4030
+ required: true;
4025
4031
  };
4026
4032
  deviceType: {
4027
4033
  type: "string";
4034
+ required: true;
4028
4035
  };
4029
4036
  backedUp: {
4030
4037
  type: "boolean";
4038
+ required: true;
4031
4039
  };
4032
4040
  transports: {
4033
4041
  type: "string";
@@ -1,14 +1,75 @@
1
1
  import * as kysely from 'kysely';
2
2
  import { Kysely, Migration, Dialect } from 'kysely';
3
- import { U as User, A as Account, S as Session } from './schema-D9o3OF80.js';
3
+ import { S as Session, U as User, A as Account, O as OAuthProvider, a as AppleProfile, D as DiscordProfile, F as FacebookProfile, G as GithubProfile, b as GoogleProfile, c as SpotifyProfile, T as TwitchProfile, d as TwitterProfile, e as SocialProviders, f as OAuthProviderList } from './index-CE92ti2Z.js';
4
4
  import * as better_call from 'better-call';
5
5
  import { ContextTools, CookieOptions, Endpoint, EndpointResponse, Context, Prettify as Prettify$1 } from 'better-call';
6
6
  import * as zod from 'zod';
7
7
  import { ZodSchema, z } from 'zod';
8
8
  import { L as LiteralString, U as UnionToIntersection, P as Prettify } from './helper-C1ihmerM.js';
9
- import { OAuthProvider, AppleProfile, DiscordProfile, FacebookProfile, GithubProfile, GoogleProfile, SpotifyProfile, TwitchProfile, TwitterProfile, SocialProviders, OAuthProviderList } from './social.js';
10
9
  import * as arctic from 'arctic';
11
- import { A as Adapter } from './adapter-D-m9-hQp.js';
10
+
11
+ /**
12
+ * Adapter where clause
13
+ */
14
+ type Where = {
15
+ operator?: "eq" | "ne" | "lt" | "lte" | "gt" | "gte";
16
+ value: string;
17
+ field: string;
18
+ connector?: "AND" | "OR";
19
+ };
20
+ /**
21
+ * Adapter Interface
22
+ */
23
+ interface Adapter {
24
+ id: string;
25
+ create: <T, R = T>(data: {
26
+ model: string;
27
+ data: T;
28
+ select?: string[];
29
+ }) => Promise<R>;
30
+ findOne: <T>(data: {
31
+ model: string;
32
+ where: Where[];
33
+ select?: string[];
34
+ }) => Promise<T | null>;
35
+ findMany: <T>(data: {
36
+ model: string;
37
+ where?: Where[];
38
+ }) => Promise<T[]>;
39
+ update: <T>(data: {
40
+ model: string;
41
+ where: Where[];
42
+ update: Record<string, any>;
43
+ }) => Promise<T | null>;
44
+ delete: <T>(data: {
45
+ model: string;
46
+ where: Where[];
47
+ }) => Promise<void>;
48
+ /**
49
+ *
50
+ * @param options
51
+ * @param file - file path if provided by the user
52
+ * @returns
53
+ */
54
+ createSchema?: (options: BetterAuthOptions, file?: string) => Promise<{
55
+ code: string;
56
+ fileName: string;
57
+ append?: boolean;
58
+ }>;
59
+ }
60
+ interface SessionAdapter {
61
+ create: (data: {
62
+ userId: string;
63
+ expiresAt: Date;
64
+ }) => Promise<Session>;
65
+ findOne: (data: {
66
+ userId: string;
67
+ }) => Promise<Session | null>;
68
+ update: (data: Session) => Promise<Session>;
69
+ delete: (data: {
70
+ sessionId: string;
71
+ }) => Promise<void>;
72
+ }
12
73
 
13
74
  declare const createInternalAdapter: (adapter: Adapter, options: BetterAuthOptions) => {
14
75
  createOAuthUser: (user: User, account: Account) => Promise<{
@@ -225,117 +286,13 @@ type RequiredKeysOf<BaseType extends object> = Exclude<{
225
286
  }[keyof BaseType], undefined>;
226
287
  type HasRequiredKeys<BaseType extends object> = RequiredKeysOf<BaseType> extends never ? false : true;
227
288
 
228
- declare const getAuthTables: (options: BetterAuthOptions) => {
229
- rateLimit?: {
230
- tableName: string;
231
- fields: {
232
- key: {
233
- type: "string";
234
- };
235
- count: {
236
- type: "number";
237
- };
238
- lastRequest: {
239
- type: "number";
240
- };
241
- };
242
- } | undefined;
243
- user: {
244
- tableName: string;
245
- fields: {
246
- name: {
247
- type: "string";
248
- };
249
- email: {
250
- type: "string";
251
- };
252
- emailVerified: {
253
- type: "boolean";
254
- defaultValue: () => false;
255
- };
256
- image: {
257
- type: "string";
258
- required: false;
259
- };
260
- createdAt: {
261
- type: "date";
262
- defaultValue: () => Date;
263
- };
264
- updatedAt: {
265
- type: "date";
266
- defaultValue: () => Date;
267
- };
268
- };
269
- order: number;
270
- };
271
- session: {
272
- tableName: string;
273
- fields: {
274
- expiresAt: {
275
- type: "date";
276
- };
277
- ipAddress: {
278
- type: "string";
279
- required: false;
280
- };
281
- userAgent: {
282
- type: "string";
283
- required: false;
284
- };
285
- userId: {
286
- type: "string";
287
- references: {
288
- model: string;
289
- field: string;
290
- onDelete: "cascade";
291
- };
292
- };
293
- };
294
- order: number;
295
- };
296
- account: {
297
- tableName: string;
298
- fields: {
299
- accountId: {
300
- type: "string";
301
- };
302
- providerId: {
303
- type: "string";
304
- };
305
- userId: {
306
- type: "string";
307
- references: {
308
- model: string;
309
- field: string;
310
- onDelete: "cascade";
311
- };
312
- };
313
- accessToken: {
314
- type: "string";
315
- required: false;
316
- };
317
- refreshToken: {
318
- type: "string";
319
- required: false;
320
- };
321
- idToken: {
322
- type: "string";
323
- required: false;
324
- };
325
- expiresAt: {
326
- type: "date";
327
- required: false;
328
- };
329
- password: {
330
- type: "string";
331
- required: false;
332
- };
333
- };
334
- order: number;
335
- };
336
- };
337
-
338
- declare function getAdapter(options: BetterAuthOptions): Adapter;
289
+ type BetterAuthDbSchema = Record<string, {
290
+ tableName: string;
291
+ fields: Record<string, FieldAttribute>;
292
+ disableMigrations?: boolean;
293
+ order?: number;
294
+ }>;
295
+ declare const getAuthTables: (options: BetterAuthOptions) => BetterAuthDbSchema;
339
296
 
340
297
  type HookEndpointContext<C extends Record<string, any> = {}> = ContextTools & {
341
298
  context: AuthContext & C;
@@ -438,7 +395,7 @@ declare const logger: {
438
395
  break: (...args: any[]) => void;
439
396
  };
440
397
 
441
- declare const init: (opts: BetterAuthOptions) => {
398
+ declare const init: (opts: BetterAuthOptions) => Promise<{
442
399
  appName: string;
443
400
  baseURL: string;
444
401
  socialProviders: OAuthProvider<Record<string, any>>[] | ({
@@ -610,7 +567,7 @@ declare const init: (opts: BetterAuthOptions) => {
610
567
  max: number;
611
568
  storage: "memory" | "database";
612
569
  } & BetterAuthOptions["rateLimit"];
613
- adapter: ReturnType<typeof getAdapter>;
570
+ adapter: Adapter;
614
571
  internalAdapter: ReturnType<typeof createInternalAdapter>;
615
572
  createAuthCookie: ReturnType<typeof createCookieGetter>;
616
573
  secret: string;
@@ -717,7 +674,7 @@ declare const init: (opts: BetterAuthOptions) => {
717
674
  }; };
718
675
  };
719
676
  };
720
- };
677
+ }>;
721
678
  type AuthContext = {
722
679
  options: BetterAuthOptions;
723
680
  appName: string;
@@ -732,7 +689,7 @@ type AuthContext = {
732
689
  max: number;
733
690
  storage: "memory" | "database";
734
691
  } & BetterAuthOptions["rateLimit"];
735
- adapter: ReturnType<typeof getAdapter>;
692
+ adapter: Adapter;
736
693
  internalAdapter: ReturnType<typeof createInternalAdapter>;
737
694
  createAuthCookie: ReturnType<typeof createCookieGetter>;
738
695
  secret: string;
@@ -2420,7 +2377,7 @@ declare const csrfMiddleware: better_call.Endpoint<better_call.Handler<string, {
2420
2377
  method: "*";
2421
2378
  }>;
2422
2379
 
2423
- declare function getEndpoints<C extends AuthContext, Option extends BetterAuthOptions>(ctx: C, options: Option): {
2380
+ declare function getEndpoints<C extends AuthContext, Option extends BetterAuthOptions>(ctx: Promise<C> | C, options: Option): {
2424
2381
  api: {
2425
2382
  ok: {
2426
2383
  (ctx_0?: Context<"/ok", {
@@ -5421,4 +5378,4 @@ type Auth = {
5421
5378
  options: BetterAuthOptions;
5422
5379
  };
5423
5380
 
5424
- export { betterAuth as $, type AuthEndpoint as A, type BetterAuthPlugin as B, sessionMiddleware as C, listSessions as D, revokeSession as E, type FieldAttribute as F, type GenericEndpointContext as G, type HookEndpointContext as H, type InferFieldOutput as I, revokeSessions as J, signOut as K, forgetPassword as L, forgetPasswordCallback as M, resetPassword as N, createEmailVerificationToken as O, type PluginSchema as P, sendVerificationEmail as Q, type RateLimit as R, verifyEmail as S, updateUser as T, changePassword as U, setPassword as V, getCSRFToken as W, error as X, ok as Y, signUpEmail as Z, csrfMiddleware as _, createAuthEndpoint as a, type AuthMiddleware as b, createAuthMiddleware as c, type Auth as d, type BetterAuthOptions as e, type AuthContext as f, getCookies as g, createCookieGetter as h, type BetterAuthCookies as i, deleteSessionCookie as j, createLogger as k, logger as l, type InferSession as m, type InferUser as n, optionsMiddleware as o, parseSetCookieHeader as p, type InferPluginTypes as q, init as r, setSessionCookie as s, getEndpoints as t, router as u, signInOAuth as v, signInEmail as w, callbackOAuth as x, getSession as y, getSessionFromCtx as z };
5381
+ export { ok as $, type AuthEndpoint as A, type BetterAuthPlugin as B, getSessionFromCtx as C, sessionMiddleware as D, listSessions as E, type FieldAttribute as F, type GenericEndpointContext as G, type HookEndpointContext as H, type InferFieldOutput as I, revokeSession as J, revokeSessions as K, signOut as L, forgetPassword as M, forgetPasswordCallback as N, resetPassword as O, type PluginSchema as P, createEmailVerificationToken as Q, type RateLimit as R, type SessionAdapter as S, sendVerificationEmail as T, verifyEmail as U, updateUser as V, type Where as W, changePassword as X, setPassword as Y, getCSRFToken as Z, error as _, createAuthEndpoint as a, signUpEmail as a0, csrfMiddleware as a1, betterAuth as a2, type AuthMiddleware as b, createAuthMiddleware as c, type Auth as d, type BetterAuthOptions as e, type Adapter as f, type AuthContext as g, getCookies as h, createCookieGetter as i, type BetterAuthCookies as j, deleteSessionCookie as k, createLogger as l, logger as m, type InferSession as n, optionsMiddleware as o, parseSetCookieHeader as p, type InferUser as q, type InferPluginTypes as r, setSessionCookie as s, init as t, getEndpoints as u, router as v, signInOAuth as w, signInEmail as x, callbackOAuth as y, getSession as z };
package/dist/index.d.ts CHANGED
@@ -1,9 +1,7 @@
1
- export { d as Auth, $ as betterAuth } from './index-D_ohe9r9.js';
1
+ export { d as Auth, a2 as betterAuth } from './index-gO-yM4kI.js';
2
2
  import 'kysely';
3
- import './schema-D9o3OF80.js';
3
+ import './index-CE92ti2Z.js';
4
+ import 'arctic';
4
5
  import 'zod';
5
- import 'better-call';
6
6
  import './helper-C1ihmerM.js';
7
- import './social.js';
8
- import 'arctic';
9
- import './adapter-D-m9-hQp.js';
7
+ import 'better-call';
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
- var Ot=Object.defineProperty,_t=Object.defineProperties;var Et=Object.getOwnPropertyDescriptors;var K=Object.getOwnPropertySymbols;var Re=Object.prototype.hasOwnProperty,Te=Object.prototype.propertyIsEnumerable;var ke=(e,t,n)=>t in e?Ot(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,g=(e,t)=>{for(var n in t||(t={}))Re.call(t,n)&&ke(e,n,t[n]);if(K)for(var n of K(t))Te.call(t,n)&&ke(e,n,t[n]);return e},k=(e,t)=>_t(e,Et(t));var W=(e,t)=>{var n={};for(var o in e)Re.call(e,o)&&t.indexOf(o)<0&&(n[o]=e[o]);if(e!=null&&K)for(var o of K(e))t.indexOf(o)<0&&Te.call(e,o)&&(n[o]=e[o]);return n};var u=(e,t,n)=>new Promise((o,r)=>{var s=d=>{try{a(n.next(d))}catch(l){r(l)}},i=d=>{try{a(n.throw(d))}catch(l){r(l)}},a=d=>d.done?o(d.value):Promise.resolve(d.value).then(s,i);a((n=n.apply(e,t)).next())});import{APIError as xr,createRouter as Pr}from"better-call";import{APIError as Pe}from"better-call";import{z as ve}from"zod";import{xchacha20poly1305 as Vr}from"@noble/ciphers/chacha";import{bytesToHex as Mr,hexToBytes as Hr,utf8ToBytes as Gr}from"@noble/ciphers/utils";import{managedNonce as Wr}from"@noble/ciphers/webcrypto";import{sha256 as Zr}from"@noble/hashes/sha256";function J(e,t){return u(this,null,function*(){let n=new TextEncoder,o={name:"HMAC",hash:"SHA-256"},r=yield crypto.subtle.importKey("raw",n.encode(e),o,!1,["sign","verify"]),s=yield crypto.subtle.sign(o.name,r,n.encode(t));return btoa(String.fromCharCode(...new Uint8Array(s)))})}import{createEndpointCreator as Ct,createMiddleware as Ue,createMiddlewareCreator as Bt}from"better-call";var xe=Ue(()=>u(void 0,null,function*(){return{}})),Z=Bt({use:[xe,Ue(()=>u(void 0,null,function*(){return{}}))]}),y=Ct({use:[xe]});var Ie=Z({body:ve.object({csrfToken:ve.string().optional()}).optional()},e=>u(void 0,null,function*(){var a,d,l,c;if(((a=e.request)==null?void 0:a.method)!=="POST"||(d=e.context.options.advanced)!=null&&d.disableCSRFCheck)return;let t=new URL(e.request.url);if(t.origin===new URL(e.context.baseURL).origin||(l=e.context.options.trustedOrigins)!=null&&l.includes(t.origin))return;let n=(c=e.body)==null?void 0:c.csrfToken,o=yield e.getSignedCookie(e.context.authCookies.csrfToken.name,e.context.secret),[r,s]=(o==null?void 0:o.split("!"))||[null,null];if(!n||!o||!r||!s||o!==n)throw e.setCookie(e.context.authCookies.csrfToken.name,"",{maxAge:0}),new Pe("UNAUTHORIZED",{message:"Invalid CSRF Token"});let i=yield J(e.context.secret,r);if(s!==i)throw e.setCookie(e.context.authCookies.csrfToken.name,"",{maxAge:0}),new Pe("UNAUTHORIZED",{message:"Invalid CSRF Token"})}));import{APIError as C}from"better-call";import{generateCodeVerifier as nr}from"oslo/oauth2";import{z as S}from"zod";import"arctic";import{parseJWT as $t}from"oslo/jwt";import"@better-fetch/fetch";var I=class extends Error{constructor(t,n,o){super(t),this.name="BetterAuthError",this.message=t,this.cause=n}};import{OAuth2Tokens as Dt}from"arctic";function jt(e){try{return new URL(e).pathname!=="/"}catch(t){throw new I(`Invalid base URL: ${e}. Please provide a valid base URL.`)}}function ne(e,t="/api/auth"){return jt(e)?e:(t=t.startsWith("/")?t:`/${t}`,`${e}${t}`)}function Q(e,t){if(e)return ne(e,t);let n=(process==null?void 0:process.env)||{},o=n.BETTER_AUTH_URL||n.NEXT_PUBLIC_BETTER_AUTH_URL||n.PUBLIC_BETTER_AUTH_URL||n.NUXT_PUBLIC_BETTER_AUTH_URL||n.NUXT_PUBLIC_AUTH_URL||(n.BASE_URL!=="/"?n.BASE_URL:void 0);if(o)return ne(o,t);if(typeof window!="undefined")return ne(window.location.origin,t)}import{betterFetch as qt}from"@better-fetch/fetch";function R(e,t){return t||`${Q()}/callback/${e}`}function x(s){return u(this,arguments,function*({code:e,codeVerifier:t,redirectURI:n,options:o,tokenEndpoint:r}){let i=new URLSearchParams;i.set("grant_type","authorization_code"),i.set("code",e),t&&i.set("code_verifier",t),i.set("redirect_uri",n),i.set("client_id",o.clientId),i.set("client_secret",o.clientSecret);let{data:a,error:d}=yield qt(r,{method:"POST",body:i,headers:{"content-type":"application/x-www-form-urlencoded",accept:"application/json","user-agent":"better-auth"}});if(d)throw d;return new Dt(a)})}var Se=e=>{let t="https://appleid.apple.com/auth/token";return{id:"apple",name:"Apple",createAuthorizationURL({state:o,scopes:r,redirectURI:s}){let i=r||["email","name","openid"];return new URL(`https://appleid.apple.com/auth/authorize?client_id=${e.clientId}&response_type=code&redirect_uri=${s||e.redirectURI}&scope=${i.join(" ")}&state=${o}`)},validateAuthorizationCode:(o,r,s)=>u(void 0,null,function*(){return x({code:o,codeVerifier:r,redirectURI:s||R("apple",e.redirectURI),options:e,tokenEndpoint:t})}),getUserInfo(o){return u(this,null,function*(){var s;let r=(s=$t(o.idToken()))==null?void 0:s.payload;return r?{user:{id:r.sub,name:r.name,email:r.email,emailVerified:r.email_verified==="true"},data:r}:null})}}};import{betterFetch as Nt}from"@better-fetch/fetch";import{Discord as Ft}from"arctic";var Le=e=>{let t=new Ft(e.clientId,e.clientSecret,R("discord",e.redirectURI));return{id:"discord",name:"Discord",createAuthorizationURL({state:o,scopes:r}){let s=r||["email"];return t.createAuthorizationURL(o,s)},validateAuthorizationCode:(o,r,s)=>u(void 0,null,function*(){return x({code:o,codeVerifier:r,redirectURI:s||R("discord",e.redirectURI),options:e,tokenEndpoint:"https://discord.com/api/oauth2/token"})}),getUserInfo(o){return u(this,null,function*(){let{data:r,error:s}=yield Nt("https://discord.com/api/users/@me",{auth:{type:"Bearer",token:o.accessToken()}});return s?null:{user:{id:r.id,name:r.display_name||r.username||"",email:r.email,emailVerified:r.verified},data:r}})}}};import{betterFetch as Vt}from"@better-fetch/fetch";import{Facebook as zt}from"arctic";var Oe=e=>{let t=new zt(e.clientId,e.clientSecret,R("facebook",e.redirectURI));return{id:"facebook",name:"Facebook",createAuthorizationURL({state:o,scopes:r}){let s=r||["email","public_profile"];return t.createAuthorizationURL(o,s)},validateAuthorizationCode:(o,r,s)=>u(void 0,null,function*(){return x({code:o,codeVerifier:r,redirectURI:s||R("facebook",e.redirectURI),options:e,tokenEndpoint:"https://graph.facebook.com/v16.0/oauth/access_token"})}),getUserInfo(o){return u(this,null,function*(){let{data:r,error:s}=yield Vt("https://graph.facebook.com/me",{auth:{type:"Bearer",token:o.accessToken()}});return s?null:{user:{id:r.id,name:r.name,email:r.email,emailVerified:r.email_verified},data:r}})}}};import{betterFetch as _e}from"@better-fetch/fetch";import{GitHub as Mt}from"arctic";var Ee=({clientId:e,clientSecret:t,redirectURI:n})=>{let o=new Mt(e,t,R("github",n));return{id:"github",name:"Github",createAuthorizationURL({state:s,scopes:i}){let a=i||["user:email"];return o.createAuthorizationURL(s,a)},validateAuthorizationCode:s=>u(void 0,null,function*(){return yield o.validateAuthorizationCode(s)}),getUserInfo(s){return u(this,null,function*(){var l,c,p,m;let{data:i,error:a}=yield _e("https://api.github.com/user",{auth:{type:"Bearer",token:s.accessToken()}});if(a)return null;let d=!1;if(!i.email){let{data:f,error:h}=yield _e("https://api.github.com/user/emails",{auth:{type:"Bearer",token:s.accessToken()}});h||(i.email=(c=(l=f.find(w=>w.primary))!=null?l:f[0])==null?void 0:c.email,d=(m=(p=f.find(w=>w.email===i.email))==null?void 0:p.verified)!=null?m:!1)}return{user:{id:i.id,name:i.name,email:i.email,image:i.avatar_url,emailVerified:d,createdAt:new Date,updatedAt:new Date},data:i}})}}};import{Google as Gt}from"arctic";import{parseJWT as Kt}from"oslo/jwt";import{createConsola as Ht}from"consola";var q=Ht({formatOptions:{date:!1,colors:!0,compact:!0},defaults:{tag:"Better Auth"}}),se=e=>({log:(...t)=>{!(e!=null&&e.disabled)&&q.log("",...t)},error:(...t)=>{!(e!=null&&e.disabled)&&q.error("",...t)},warn:(...t)=>{!(e!=null&&e.disabled)&&q.warn("",...t)},info:(...t)=>{!(e!=null&&e.disabled)&&q.info("",...t)},debug:(...t)=>{!(e!=null&&e.disabled)&&q.debug("",...t)},box:(...t)=>{!(e!=null&&e.disabled)&&q.box("",...t)},success:(...t)=>{!(e!=null&&e.disabled)&&q.success("",...t)},break:(...t)=>{!(e!=null&&e.disabled)&&console.log(`
2
- `)}}),O=se();var Ce=e=>{let t=new Gt(e.clientId,e.clientSecret,R("google",e.redirectURI));return{id:"google",name:"Google",createAuthorizationURL({state:o,scopes:r,codeVerifier:s,redirectURI:i}){if(!e.clientId||!e.clientSecret)throw O.error("Client Id and Client Secret is required for Google. Make sure to provide them in the options."),new I("CLIENT_ID_AND_SECRET_REQUIRED");if(!s)throw new I("codeVerifier is required for Google");let a=r||["email","profile"];return t.createAuthorizationURL(o,s,a)},validateAuthorizationCode:(o,r,s)=>u(void 0,null,function*(){return x({code:o,codeVerifier:r,redirectURI:s||R("google",e.redirectURI),options:e,tokenEndpoint:"https://oauth2.googleapis.com/token"})}),getUserInfo(o){return u(this,null,function*(){var s;if(!o.idToken)return null;let r=(s=Kt(o.idToken()))==null?void 0:s.payload;return{user:{id:r.sub,name:r.name,email:r.email,image:r.picture,emailVerified:r.email_verified},data:r}})}}};import{betterFetch as Wt}from"@better-fetch/fetch";import{Spotify as Jt}from"arctic";var Be=e=>{let t=new Jt(e.clientId,e.clientSecret,R("spotify",e.redirectURI));return{id:"spotify",name:"Spotify",createAuthorizationURL({state:o,scopes:r}){let s=r||["user-read-email"];return t.createAuthorizationURL(o,s)},validateAuthorizationCode:(o,r,s)=>u(void 0,null,function*(){return x({code:o,codeVerifier:r,redirectURI:s||R("spotify",e.redirectURI),options:e,tokenEndpoint:"https://accounts.spotify.com/api/token"})}),getUserInfo(o){return u(this,null,function*(){var i;let{data:r,error:s}=yield Wt("https://api.spotify.com/v1/me",{method:"GET",headers:{Authorization:`Bearer ${o.accessToken()}`}});return s?null:{user:{id:r.id,name:r.display_name,email:r.email,image:(i=r.images[0])==null?void 0:i.url,emailVerified:!1},data:r}})}}};import{betterFetch as Zt}from"@better-fetch/fetch";import{Twitch as Qt}from"arctic";var je=e=>{let t=new Qt(e.clientId,e.clientSecret,R("twitch",e.redirectURI));return{id:"twitch",name:"Twitch",createAuthorizationURL({state:o,scopes:r}){let s=r||["activity:write","read"];return t.createAuthorizationURL(o,s)},validateAuthorizationCode:(o,r,s)=>u(void 0,null,function*(){return x({code:o,codeVerifier:r,redirectURI:s||R("twitch",e.redirectURI),options:e,tokenEndpoint:"https://id.twitch.tv/oauth2/token"})}),getUserInfo(o){return u(this,null,function*(){let{data:r,error:s}=yield Zt("https://api.twitch.tv/helix/users",{method:"GET",headers:{Authorization:`Bearer ${o.accessToken()}`}});return s?null:{user:{id:r.sub,name:r.preferred_username,email:r.email,image:r.picture,emailVerified:!1},data:r}})}}};import{betterFetch as Xt}from"@better-fetch/fetch";import{Twitter as Yt}from"arctic";var De=e=>{let t=new Yt(e.clientId,e.clientSecret,R("twitter",e.redirectURI));return{id:"twitter",name:"Twitter",createAuthorizationURL(o){let r=o.scopes||["account_info.read"];return t.createAuthorizationURL(o.state,o.codeVerifier,r)},validateAuthorizationCode:(o,r,s)=>u(void 0,null,function*(){return x({code:o,codeVerifier:r,redirectURI:s||R("twitch",e.redirectURI),options:e,tokenEndpoint:"https://id.twitch.tv/oauth2/token"})}),getUserInfo(o){return u(this,null,function*(){let{data:r,error:s}=yield Xt("https://api.x.com/2/users/me?user.fields=profile_image_url",{method:"GET",headers:{Authorization:`Bearer ${o.accessToken()}`}});return s||!r.data.email?null:{user:{id:r.data.id,name:r.data.name,email:r.data.email,image:r.data.profile_image_url,emailVerified:r.data.verified||!1},data:r}})}}};import"arctic";var ie={apple:Se,discord:Le,facebook:Oe,github:Ee,google:Ce,spotify:Be,twitch:je,twitter:De},qe=Object.keys(ie);import{generateState as er}from"oslo/oauth2";import{z}from"zod";function $e(e,t,n){let o=er();return{state:JSON.stringify({code:o,callbackURL:e,currentURL:t,dontRememberMe:n}),code:o}}function ae(e){return z.object({code:z.string(),callbackURL:z.string().optional(),currentURL:z.string().optional(),dontRememberMe:z.boolean().optional()}).safeParse(JSON.parse(e))}import{APIError as rr}from"better-call";var M=(e,t=!1)=>{let n=new Date;return new Date(n.getTime()+(t?e*1e3:e))};import{TimeSpan as tr}from"oslo";function Ne(e){var s;let n=!!((s=e.advanced)!=null&&s.useSecureCookies)||process.env.NODE_ENV!=="development"&&process.env.NODE_ENV!=="test"?"__Secure-":"",o="better-auth",r=new tr(7,"d").seconds();return{sessionToken:{name:`${n}${o}.session_token`,options:{httpOnly:!0,sameSite:"lax",path:"/",secure:!!n,maxAge:r}},csrfToken:{name:`${n?"__Host-":""}${o}.csrf_token`,options:{httpOnly:!0,sameSite:"lax",path:"/",secure:!!n,maxAge:60*60*24*7}},state:{name:`${n}${o}.state`,options:{httpOnly:!0,sameSite:"lax",path:"/",secure:!!n,maxAge:60*15}},pkCodeVerifier:{name:`${n}${o}.pk_code_verifier`,options:{httpOnly:!0,sameSite:"lax",path:"/",secure:!!n,maxAge:60*15}},dontRememberToken:{name:`${n}${o}.dont_remember`,options:{httpOnly:!0,sameSite:"lax",path:"/",secure:!!n}},nonce:{name:`${n}${o}.nonce`,options:{httpOnly:!0,sameSite:"lax",path:"/",secure:!!n,maxAge:60*15}}}}function Fe(e){var s;let n=!!((s=e.advanced)!=null&&s.useSecureCookies)||process.env.NODE_ENV==="production"?"__Secure-":"",o="better-auth";function r(i,a){return{name:process.env.NODE_ENV==="production"?`${n}${o}.${i}`:`${o}.${i}`,options:g({secure:!!n,sameSite:"lax",path:"/",maxAge:60*15},a)}}return r}function _(e,t,n,o){return u(this,null,function*(){let r=e.context.authCookies.sessionToken.options;r.maxAge=n?void 0:r.maxAge,yield e.setSignedCookie(e.context.authCookies.sessionToken.name,t,e.context.secret,r),n&&(yield e.setSignedCookie(e.context.authCookies.dontRememberToken.name,"true",e.context.secret,e.context.authCookies.dontRememberToken.options))})}function H(e){e.setCookie(e.context.authCookies.sessionToken.name,"",{maxAge:0}),e.setCookie(e.context.authCookies.dontRememberToken.name,"",{maxAge:0})}import{z as Ve}from"zod";function X(e){let t="127.0.0.1";if(process.env.NODE_ENV==="test")return t;let n=["x-client-ip","x-forwarded-for","cf-connecting-ip","fastly-client-ip","x-real-ip","x-cluster-client-ip","x-forwarded","forwarded-for","forwarded"];for(let o of n){let r=e.headers.get(o);if(typeof r=="string"){let s=r.split(",")[0].trim();if(s)return s}}return null}var de=new Map;function or(e,t){if(!e.request)return"";let{method:n,url:o,headers:r}=e.request,s=e.request.headers.get("User-Agent")||"",i=X(e.request)||"",a=JSON.stringify(r);return`${n}:${o}:${a}:${s}:${i}:${t}`}var ce=()=>y("/session",{method:"GET",requireHeaders:!0},e=>u(void 0,null,function*(){try{let t=yield e.getSignedCookie(e.context.authCookies.sessionToken.name,e.context.secret);if(!t)return e.json(null,{status:401});let n=or(e,t),o=de.get(n);if(o){if(o.expiresAt>Date.now())return e.json(o.data);de.delete(n)}let r=yield e.context.internalAdapter.findSession(t);if(!r||r.session.expiresAt<new Date)return H(e),r&&(yield e.context.internalAdapter.deleteSession(r.session.id)),e.json(null,{status:401});if(yield e.getSignedCookie(e.context.authCookies.dontRememberToken.name,e.context.secret))return e.json(r);let i=e.context.sessionConfig.expiresIn,a=e.context.sessionConfig.updateAge;if(r.session.expiresAt.valueOf()-i*1e3+a*1e3<=Date.now()){let c=yield e.context.internalAdapter.updateSession(r.session.id,{expiresAt:M(e.context.sessionConfig.expiresIn,!0)});if(!c)return H(e),e.json(null,{status:401});let p=(c.expiresAt.valueOf()-Date.now())/1e3;return yield _(e,c.id,!1,{maxAge:p}),e.json({session:c,user:r.user})}return de.set(n,{data:r,expiresAt:Date.now()+5e3}),e.json(r)}catch(t){return e.context.logger.error(t),e.json(null,{status:500})}})),ue=e=>u(void 0,null,function*(){return yield ce()(k(g({},e),{_flag:void 0}))}),$=Z(e=>u(void 0,null,function*(){let t=yield ue(e);if(!(t!=null&&t.session))throw new rr("UNAUTHORIZED");return{session:t}})),ze=()=>y("/user/list-sessions",{method:"GET",use:[$],requireHeaders:!0},e=>u(void 0,null,function*(){let n=(yield e.context.adapter.findMany({model:e.context.tables.session.tableName,where:[{field:"userId",value:e.context.session.user.id}]})).filter(o=>o.expiresAt>new Date);return e.json(n)})),Me=y("/user/revoke-session",{method:"POST",body:Ve.object({id:Ve.string()}),use:[$],requireHeaders:!0},e=>u(void 0,null,function*(){let t=e.body.id,n=yield e.context.internalAdapter.findSession(t);if(!n)return e.json(null,{status:400});if(n.session.userId!==e.context.session.user.id)return e.json(null,{status:403});try{yield e.context.internalAdapter.deleteSession(t)}catch(o){return e.context.logger.error(o),e.json(null,{status:500})}return e.json({status:!0})})),He=y("/user/revoke-sessions",{method:"POST",use:[$],requireHeaders:!0},e=>u(void 0,null,function*(){try{yield e.context.internalAdapter.deleteSessions(e.context.session.user.id)}catch(t){return e.context.logger.error(t),e.json(null,{status:500})}return e.json({status:!0})}));var Ge=y("/sign-in/social",{method:"POST",requireHeaders:!0,query:S.object({currentURL:S.string().optional()}).optional(),body:S.object({callbackURL:S.string().optional(),provider:S.enum(qe),dontRememberMe:S.boolean().default(!1).optional()})},e=>u(void 0,null,function*(){var i,a,d,l;let t=e.context.socialProviders.find(c=>c.id===e.body.provider);if(!t)throw e.context.logger.error("Provider not found. Make sure to add the provider to your auth config",{provider:e.body.provider}),new C("NOT_FOUND",{message:"Provider not found"});let n=e.context.authCookies,o=(i=e.query)!=null&&i.currentURL?new URL((a=e.query)==null?void 0:a.currentURL):null,r=(d=e.body.callbackURL)!=null&&d.startsWith("http")?e.body.callbackURL:`${o==null?void 0:o.origin}${e.body.callbackURL||""}`,s=$e(r||(o==null?void 0:o.origin)||e.context.baseURL,(l=e.query)==null?void 0:l.currentURL);try{yield e.setSignedCookie(n.state.name,s.code,e.context.secret,n.state.options);let c=nr();yield e.setSignedCookie(n.pkCodeVerifier.name,c,e.context.secret,n.pkCodeVerifier.options);let p=t.createAuthorizationURL({state:s.state,codeVerifier:c});return p.searchParams.set("redirect_uri",`${e.context.baseURL}/callback/${e.body.provider}`),{url:p.toString(),state:s.state,codeVerifier:c,redirect:!0}}catch(c){throw new C("INTERNAL_SERVER_ERROR")}})),Ke=y("/sign-in/email",{method:"POST",body:S.object({email:S.string().email(),password:S.string(),callbackURL:S.string().optional(),dontRememberMe:S.boolean().default(!1).optional()})},e=>u(void 0,null,function*(){var c,p;if(!((p=(c=e.context.options)==null?void 0:c.emailAndPassword)!=null&&p.enabled))throw e.context.logger.error("Email and password is not enabled. Make sure to enable it in the options on you `auth.ts` file. Check `https://better-auth.com/docs/authentication/email-password` for more!"),new C("BAD_REQUEST",{message:"Email and password is not enabled"});let t=yield ue(e);t&&(yield e.context.internalAdapter.deleteSession(t.session.id));let{email:n,password:o}=e.body;if(!S.string().email().safeParse(n).success)throw new C("BAD_REQUEST",{message:"Invalid email"});let s=yield e.context.internalAdapter.findUserByEmail(n);if(!s)throw yield e.context.password.hash(o),e.context.logger.error("User not found",{email:n}),new C("UNAUTHORIZED",{message:"Invalid email or password"});let i=s.accounts.find(m=>m.providerId==="credential");if(!i)throw e.context.logger.error("Credential account not found",{email:n}),new C("UNAUTHORIZED",{message:"Invalid email or password"});let a=i==null?void 0:i.password;if(!a)throw e.context.logger.error("Password not found",{email:n}),new C("UNAUTHORIZED",{message:"Unexpected error"});if(!(yield e.context.password.verify(a,o)))throw e.context.logger.error("Invalid password"),new C("UNAUTHORIZED",{message:"Invalid email or password"});let l=yield e.context.internalAdapter.createSession(s.user.id,e.headers,e.body.dontRememberMe);if(!l)throw e.context.logger.error("Failed to create session"),new C("INTERNAL_SERVER_ERROR");return yield _(e,l.id,e.body.dontRememberMe),e.json({user:s.user,session:l,redirect:!!e.body.callbackURL,url:e.body.callbackURL})}));import{APIError as ar}from"better-call";import{z as Y}from"zod";import{z as A}from"zod";var ds=A.object({id:A.string(),providerId:A.string(),accountId:A.string(),userId:A.string(),accessToken:A.string().nullable().optional(),refreshToken:A.string().nullable().optional(),idToken:A.string().nullable().optional(),expiresAt:A.date().nullable().optional(),password:A.string().optional().nullable()}),We=A.object({id:A.string(),email:A.string().transform(e=>e.toLowerCase()),emailVerified:A.boolean().default(!1),name:A.string(),image:A.string().optional(),createdAt:A.date().default(new Date),updatedAt:A.date().default(new Date)}),cs=A.object({id:A.string(),userId:A.string(),expiresAt:A.date(),ipAddress:A.string().optional(),userAgent:A.string().optional()});import{alphabet as sr,generateRandomString as ir}from"oslo/crypto";var Je=()=>ir(36,sr("a-z","0-9"));var D={isAction:!1};function le(e){let t=e.accessToken(),n=e.hasRefreshToken()?e.refreshToken():void 0,o;try{o=e.accessTokenExpiresAt()}catch(r){}return{accessToken:t,refreshToken:n,expiresAt:o}}var Ze=y("/callback/:id",{method:"GET",query:Y.object({state:Y.string(),code:Y.string().optional(),error:Y.string().optional()}),metadata:D},e=>u(void 0,null,function*(){var h,w,U;if(e.query.error||!e.query.code){let T=((h=ae(e.query.state).data)==null?void 0:h.callbackURL)||`${e.context.baseURL}/error`;throw e.context.logger.error(e.query.error,e.params.id),e.redirect(`${T}?error=${e.query.error||"oAuth_code_missing"}`)}let t=e.context.socialProviders.find(b=>b.id===e.params.id);if(!t)throw e.context.logger.error("Oauth provider with id",e.params.id,"not found"),e.redirect(`${e.context.baseURL}/error?error=oauth_provider_not_found`);let n=yield e.getSignedCookie(e.context.authCookies.pkCodeVerifier.name,e.context.secret),o;try{o=yield t.validateAuthorizationCode(e.query.code,n,`${e.context.baseURL}/callback/${t.id}`)}catch(b){throw e.context.logger.error(b),e.redirect(`${e.context.baseURL}/error?error=oauth_code_verification_failed`)}let r=yield t.getUserInfo(o).then(b=>b==null?void 0:b.user),s=Je(),i=We.safeParse(k(g({},r),{id:s})),a=ae(e.query.state);if(!a.success)throw e.context.logger.error("Unable to parse state"),e.redirect(`${e.context.baseURL}/error?error=invalid_state_parameter`);let{callbackURL:d,currentURL:l,dontRememberMe:c}=a.data;if(!r||i.success===!1)throw e.redirect(`${e.context.baseURL}/error?error=oauth_validation_failed`);if(!d)throw e.redirect(`${e.context.baseURL}/error?error=oauth_callback_url_not_found`);let p=yield e.context.internalAdapter.findUserByEmail(r.email),m=p==null?void 0:p.user.id;if(p){let b=p.accounts.find(v=>v.providerId===t.id),T=(U=(w=e.context.options.account)==null?void 0:w.accountLinking)==null?void 0:U.trustedProviders,P=T?T.includes(t.id):!0;if(!b&&(!r.emailVerified||!P)){let v;try{v=new URL(l||d),v.searchParams.set("error","account_not_linked")}catch(oe){throw e.redirect(`${e.context.baseURL}/error?error=account_not_linked`)}throw e.redirect(v.toString())}if(!b)try{yield e.context.internalAdapter.linkAccount(g({providerId:t.id,accountId:r.id,id:`${t.id}:${r.id}`,userId:p.user.id},le(o)))}catch(v){throw console.log(v),e.redirect(`${e.context.baseURL}/error?error=failed_linking_account`)}}else try{yield e.context.internalAdapter.createOAuthUser(i.data,k(g({},le(o)),{id:`${t.id}:${r.id}`,providerId:t.id,accountId:r.id,userId:s}))}catch(b){let T=new URL(l||d);throw T.searchParams.set("error","unable_to_create_user"),e.setHeader("Location",T.toString()),e.redirect(T.toString())}if(!m&&!s)throw new ar("INTERNAL_SERVER_ERROR",{message:"Unable to create user"});let f=yield e.context.internalAdapter.createSession(m||s,e.request,c);if(!f){let b=new URL(l||d);throw b.searchParams.set("error","unable_to_create_session"),e.redirect(b.toString())}try{yield _(e,f.id,c)}catch(b){e.context.logger.error("Unable to set session cookie",b);let T=new URL(l||d);throw T.searchParams.set("error","unable_to_create_session"),e.redirect(T.toString())}throw e.redirect(d)}));import{z as pe}from"zod";var Qe=y("/sign-out",{method:"POST",body:pe.optional(pe.object({callbackURL:pe.string().optional()}))},e=>u(void 0,null,function*(){var n,o;let t=yield e.getSignedCookie(e.context.authCookies.sessionToken.name,e.context.secret);return t?(yield e.context.internalAdapter.deleteSession(t),H(e),e.json(null,{body:{redirect:!!((n=e.body)!=null&&n.callbackURL),url:(o=e.body)==null?void 0:o.callbackURL}})):e.json(null)}));import{TimeSpan as dr}from"oslo";import{createJWT as cr,parseJWT as ur}from"oslo/jwt";import{validateJWT as Xe}from"oslo/jwt";import{z as L}from"zod";var Ye=y("/forget-password",{method:"POST",body:L.object({email:L.string().email(),redirectTo:L.string()})},e=>u(void 0,null,function*(){var s;if(!((s=e.context.options.emailAndPassword)!=null&&s.sendResetPassword))return e.context.logger.error("Reset password isn't enabled.Please pass an emailAndPassword.sendResetPasswordToken function to your auth config!"),e.json(null,{status:400,statusText:"RESET_PASSWORD_EMAIL_NOT_SENT",body:{message:"Reset password isn't enabled"}});let{email:t}=e.body,n=yield e.context.internalAdapter.findUserByEmail(t);if(!n)return e.json({status:!1},{body:{status:!0}});let o=yield cr("HS256",Buffer.from(e.context.secret),{email:n.user.email,redirectTo:e.body.redirectTo},{expiresIn:new dr(1,"h"),issuer:"better-auth",subject:"forget-password",audiences:[n.user.email],includeIssuedTimestamp:!0}),r=`${e.context.baseURL}/reset-password/${o}`;return yield e.context.options.emailAndPassword.sendResetPassword(r,n.user),e.json({status:!0})})),et=y("/reset-password/:token",{method:"GET"},e=>u(void 0,null,function*(){var s;let{token:t}=e.params,n,o=L.object({email:L.string(),redirectTo:L.string()});try{if(n=yield Xe("HS256",Buffer.from(e.context.secret),t),!n.expiresAt||n.expiresAt<new Date)throw Error("Token expired")}catch(i){let a=ur(t),d=o.safeParse(a==null?void 0:a.payload);throw d.success?e.redirect(`${(s=d.data)==null?void 0:s.redirectTo}?error=invalid_token`):e.redirect(`${e.context.baseURL}/error?error=invalid_token`)}let{redirectTo:r}=o.parse(n.payload);throw e.redirect(`${r}?token=${t}`)})),tt=y("/reset-password",{method:"POST",query:L.object({currentURL:L.string()}).optional(),body:L.object({newPassword:L.string(),callbackURL:L.string().optional()})},e=>u(void 0,null,function*(){var o,r,s;let t=(o=e.query)==null?void 0:o.currentURL.split("?token=")[1];if(!t)return e.json({error:"Invalid token",data:null},{status:400,statusText:"INVALID_TOKEN",body:{message:"Invalid token"}});let{newPassword:n}=e.body;try{let i=yield Xe("HS256",Buffer.from(e.context.secret),t),a=L.string().email().parse(i.payload.email),d=yield e.context.internalAdapter.findUserByEmail(a);if(!d)return e.json({error:"User not found",data:null},{status:400,body:{message:"failed to reset password"}});if(n.length<(((r=e.context.options.emailAndPassword)==null?void 0:r.minPasswordLength)||8)||n.length>(((s=e.context.options.emailAndPassword)==null?void 0:s.maxPasswordLength)||32))return e.json({data:null,error:"password is too short or too long"},{status:400,statusText:"INVALID_PASSWORD_LENGTH",body:{message:"password is too short or too long"}});let l=yield e.context.password.hash(n);return(yield e.context.internalAdapter.updatePassword(d.user.id,l))?e.json({error:null,data:{status:!0,url:e.body.callbackURL,redirect:!!e.body.callbackURL}},{body:{status:!0,url:e.body.callbackURL,redirect:!!e.body.callbackURL}}):e.json(null,{status:400,statusText:"USER_NOT_FOUND",body:{message:"User doesn't have a credential account"}})}catch(i){return console.log(i),e.json({error:"Invalid token",data:null},{status:400,statusText:"INVALID_TOKEN",body:{message:"Invalid token"}})}}));import{TimeSpan as lr}from"oslo";import{createJWT as pr,validateJWT as mr}from"oslo/jwt";import{z as E}from"zod";function me(e,t){return u(this,null,function*(){return yield pr("HS256",Buffer.from(e),{email:t.toLowerCase()},{expiresIn:new lr(1,"h"),issuer:"better-auth",subject:"verify-email",audiences:[t],includeIssuedTimestamp:!0})})}var rt=y("/send-verification-email",{method:"POST",query:E.object({currentURL:E.string().optional()}).optional(),body:E.object({email:E.string().email(),callbackURL:E.string().optional()})},e=>u(void 0,null,function*(){var r,s;if(!((r=e.context.options.emailAndPassword)!=null&&r.sendVerificationEmail))return e.context.logger.error("Verification email isn't enabled. Pass `sendVerificationEmail` in `emailAndPassword` options to enable it."),e.json(null,{status:400,statusText:"VERIFICATION_EMAIL_NOT_SENT",body:{message:"Verification email isn't enabled"}});let{email:t}=e.body,n=yield me(e.context.secret,t),o=`${e.context.baseURL}/verify-email?token=${n}&callbackURL=${e.body.callbackURL||((s=e.query)==null?void 0:s.currentURL)||"/"}`;return yield e.context.options.emailAndPassword.sendVerificationEmail(t,o,n),e.json({status:!0})})),ot=y("/verify-email",{method:"GET",query:E.object({token:E.string(),callbackURL:E.string().optional()})},e=>u(void 0,null,function*(){let{token:t}=e.query,n;try{n=yield mr("HS256",Buffer.from(e.context.secret),t)}catch(a){return e.context.logger.error("Failed to verify email",a),e.json(null,{status:400,statusText:"INVALID_TOKEN",body:{message:"Invalid token"}})}let r=E.object({email:E.string().email()}).parse(n.payload),s=yield e.context.internalAdapter.findUserByEmail(r.email);if(!s)return e.json(null,{status:400,statusText:"USER_NOT_FOUND",body:{message:"User not found"}});if(!s.accounts.find(a=>a.providerId==="credential"))throw e.redirect;if(yield e.context.internalAdapter.updateUserByEmail(r.email,{emailVerified:!0}),e.query.callbackURL)throw console.log("Redirecting to",e.query.callbackURL),e.redirect("/");return e.json({status:!0})}));import{z as B}from"zod";import{alphabet as fr,generateRandomString as gr}from"oslo/crypto";import"better-call";var nt=y("/user/update",{method:"POST",body:B.object({name:B.string().optional(),image:B.string().optional()}),use:[$]},e=>u(void 0,null,function*(){let{name:t,image:n}=e.body,o=e.context.session;if(!n&&!t)return e.json(o.user);let r=yield e.context.internalAdapter.updateUserByEmail(o.user.email,{name:t,image:n});return e.json(r)})),st=y("/user/change-password",{method:"POST",body:B.object({newPassword:B.string(),currentPassword:B.string(),revokeOtherSessions:B.boolean().optional()}),use:[$]},e=>u(void 0,null,function*(){let{newPassword:t,currentPassword:n,revokeOtherSessions:o}=e.body,r=e.context.session,s=e.context.password.config.minPasswordLength;if(t.length<s)return e.context.logger.error("Password is too short"),e.json(null,{status:400,body:{message:"Password is too short"}});let i=e.context.password.config.maxPasswordLength;if(t.length>i)return e.context.logger.error("Password is too long"),e.json(null,{status:400,body:{message:"Password is too long"}});let d=(yield e.context.internalAdapter.findAccounts(r.user.id)).find(p=>p.providerId==="credential"&&p.password);if(!d||!d.password)return e.json(null,{status:400,body:{message:"User does not have a password"}});let l=yield e.context.password.hash(t);if(!(yield e.context.password.verify(d.password,n)))return e.json(null,{status:400,body:{message:"Invalid password"}});if(yield e.context.internalAdapter.updateAccount(d.id,{password:l}),o){yield e.context.internalAdapter.deleteSessions(r.user.id);let p=yield e.context.internalAdapter.createSession(r.user.id,e.headers);if(!p)return e.json(null,{status:500,body:{message:"Failed to create session"}});yield _(e,p.id)}return e.json(r.user)})),it=y("/user/set-password",{method:"POST",body:B.object({newPassword:B.string()}),use:[$]},e=>u(void 0,null,function*(){let{newPassword:t}=e.body,n=e.context.session,o=e.context.password.config.minPasswordLength;if(t.length<o)return e.context.logger.error("Password is too short"),e.json(null,{status:400,body:{message:"Password is too short"}});let r=e.context.password.config.maxPasswordLength;if(t.length>r)return e.context.logger.error("Password is too long"),e.json(null,{status:400,body:{message:"Password is too long"}});let i=(yield e.context.internalAdapter.findAccounts(n.user.id)).find(d=>d.providerId==="credential"&&d.password),a=yield e.context.password.hash(t);return i?e.json(null,{status:400,body:{message:"User already has a password"}}):(yield e.context.internalAdapter.linkAccount({id:gr(32,fr("a-z","0-9","A-Z")),userId:n.user.id,providerId:"credential",accountId:n.user.id,password:a}),e.json(n.user))}));import{alphabet as hr,generateRandomString as yr}from"oslo/crypto";var at=y("/csrf",{method:"GET",metadata:D},e=>u(void 0,null,function*(){let t=yield e.getSignedCookie(e.context.authCookies.csrfToken.name,e.context.secret);if(t)return{csrfToken:t};let n=yr(32,hr("a-z","0-9","A-Z")),o=yield J(e.context.secret,n),r=`${n}!${o}`;return yield e.setSignedCookie(e.context.authCookies.csrfToken.name,r,e.context.secret,e.context.authCookies.csrfToken.options),{csrfToken:n}}));var br=(e="Unknown")=>`<!DOCTYPE html>
1
+ import{APIError as ir,createRouter as ar}from"better-call";import{APIError as ce}from"better-call";import{z as le}from"zod";import{xchacha20poly1305 as xr}from"@noble/ciphers/chacha";import{bytesToHex as Pr,hexToBytes as vr,utf8ToBytes as Ir}from"@noble/ciphers/utils";import{managedNonce as Or}from"@noble/ciphers/webcrypto";import{sha256 as Cr}from"@noble/hashes/sha256";async function F(e,t){let o=new TextEncoder,r={name:"HMAC",hash:"SHA-256"},n=await crypto.subtle.importKey("raw",o.encode(e),r,!1,["sign","verify"]),s=await crypto.subtle.sign(r.name,n,o.encode(t));return btoa(String.fromCharCode(...new Uint8Array(s)))}import{createEndpointCreator as gt,createMiddleware as ae,createMiddlewareCreator as ht}from"better-call";var de=ae(async()=>({})),M=ht({use:[de,ae(async()=>({}))]}),g=gt({use:[de]});var ue=M({body:le.object({csrfToken:le.string().optional()}).optional()},async e=>{if(e.request?.method!=="POST"||e.context.options.advanced?.disableCSRFCheck)return;let t=new URL(e.request.url);if(t.origin===new URL(e.context.baseURL).origin||e.context.options.trustedOrigins?.includes(t.origin))return;let o=e.body?.csrfToken,r=await e.getSignedCookie(e.context.authCookies.csrfToken.name,e.context.secret),[n,s]=r?.split("!")||[null,null];if(!o||!r||!n||!s||r!==o)throw e.setCookie(e.context.authCookies.csrfToken.name,"",{maxAge:0}),new ce("UNAUTHORIZED",{message:"Invalid CSRF Token"});let i=await F(e.context.secret,n);if(s!==i)throw e.setCookie(e.context.authCookies.csrfToken.name,"",{maxAge:0}),new ce("UNAUTHORIZED",{message:"Invalid CSRF Token"})});import{APIError as I}from"better-call";import{generateCodeVerifier as Nt}from"oslo/oauth2";import{z as x}from"zod";import"arctic";import{parseJWT as At}from"oslo/jwt";import"@better-fetch/fetch";var k=class extends Error{constructor(t,o,r){super(t),this.name="BetterAuthError",this.message=t,this.cause=o}};import{OAuth2Tokens as bt}from"arctic";function yt(e){try{return new URL(e).pathname!=="/"}catch{throw new k(`Invalid base URL: ${e}. Please provide a valid base URL.`)}}function J(e,t="/api/auth"){return yt(e)?e:(t=t.startsWith("/")?t:`/${t}`,`${e}${t}`)}function z(e,t){if(e)return J(e,t);let o=process?.env||{},r=o.BETTER_AUTH_URL||o.NEXT_PUBLIC_BETTER_AUTH_URL||o.PUBLIC_BETTER_AUTH_URL||o.NUXT_PUBLIC_BETTER_AUTH_URL||o.NUXT_PUBLIC_AUTH_URL||(o.BASE_URL!=="/"?o.BASE_URL:void 0);if(r)return J(r,t);if(typeof window<"u")return J(window.location.origin,t)}import{betterFetch as wt}from"@better-fetch/fetch";function w(e,t){return t||`${z()}/callback/${e}`}async function R({code:e,codeVerifier:t,redirectURI:o,options:r,tokenEndpoint:n}){let s=new URLSearchParams;s.set("grant_type","authorization_code"),s.set("code",e),t&&s.set("code_verifier",t),s.set("redirect_uri",o),s.set("client_id",r.clientId),s.set("client_secret",r.clientSecret);let{data:i,error:a}=await wt(n,{method:"POST",body:s,headers:{"content-type":"application/x-www-form-urlencoded",accept:"application/json","user-agent":"better-auth"}});if(a)throw a;return new bt(i)}var pe=e=>{let t="https://appleid.apple.com/auth/token";return{id:"apple",name:"Apple",createAuthorizationURL({state:o,scopes:r,redirectURI:n}){let s=r||["email","name","openid"];return new URL(`https://appleid.apple.com/auth/authorize?client_id=${e.clientId}&response_type=code&redirect_uri=${n||e.redirectURI}&scope=${s.join(" ")}&state=${o}`)},validateAuthorizationCode:async(o,r,n)=>R({code:o,codeVerifier:r,redirectURI:n||w("apple",e.redirectURI),options:e,tokenEndpoint:t}),async getUserInfo(o){let r=At(o.idToken())?.payload;return r?{user:{id:r.sub,name:r.name,email:r.email,emailVerified:r.email_verified==="true"},data:r}:null}}};import{betterFetch as kt}from"@better-fetch/fetch";import{Discord as Rt}from"arctic";var me=e=>{let t=new Rt(e.clientId,e.clientSecret,w("discord",e.redirectURI));return{id:"discord",name:"Discord",createAuthorizationURL({state:o,scopes:r}){let n=r||["email"];return t.createAuthorizationURL(o,n)},validateAuthorizationCode:async(o,r,n)=>R({code:o,codeVerifier:r,redirectURI:n||w("discord",e.redirectURI),options:e,tokenEndpoint:"https://discord.com/api/oauth2/token"}),async getUserInfo(o){let{data:r,error:n}=await kt("https://discord.com/api/users/@me",{auth:{type:"Bearer",token:o.accessToken()}});return n?null:{user:{id:r.id,name:r.display_name||r.username||"",email:r.email,emailVerified:r.verified},data:r}}}};import{betterFetch as Tt}from"@better-fetch/fetch";import{Facebook as xt}from"arctic";var fe=e=>{let t=new xt(e.clientId,e.clientSecret,w("facebook",e.redirectURI));return{id:"facebook",name:"Facebook",createAuthorizationURL({state:o,scopes:r}){let n=r||["email","public_profile"];return t.createAuthorizationURL(o,n)},validateAuthorizationCode:async(o,r,n)=>R({code:o,codeVerifier:r,redirectURI:n||w("facebook",e.redirectURI),options:e,tokenEndpoint:"https://graph.facebook.com/v16.0/oauth/access_token"}),async getUserInfo(o){let{data:r,error:n}=await Tt("https://graph.facebook.com/me",{auth:{type:"Bearer",token:o.accessToken()}});return n?null:{user:{id:r.id,name:r.name,email:r.email,emailVerified:r.email_verified},data:r}}}};import{betterFetch as ge}from"@better-fetch/fetch";import{GitHub as Ut}from"arctic";var he=({clientId:e,clientSecret:t,redirectURI:o})=>{let r=new Ut(e,t,w("github",o));return{id:"github",name:"Github",createAuthorizationURL({state:n,scopes:s}){let i=s||["user:email"];return r.createAuthorizationURL(n,i)},validateAuthorizationCode:async n=>await r.validateAuthorizationCode(n),async getUserInfo(n){let{data:s,error:i}=await ge("https://api.github.com/user",{auth:{type:"Bearer",token:n.accessToken()}});if(i)return null;let a=!1;if(!s.email){let{data:d,error:c}=await ge("https://api.github.com/user/emails",{auth:{type:"Bearer",token:n.accessToken()}});c||(s.email=(d.find(l=>l.primary)??d[0])?.email,a=d.find(l=>l.email===s.email)?.verified??!1)}return{user:{id:s.id,name:s.name,email:s.email,image:s.avatar_url,emailVerified:a,createdAt:new Date,updatedAt:new Date},data:s}}}};import{Google as vt}from"arctic";import{parseJWT as It}from"oslo/jwt";import{createConsola as Pt}from"consola";var E=Pt({formatOptions:{date:!1,colors:!0,compact:!0},defaults:{tag:"Better Auth"}}),Z=e=>({log:(...t)=>{!e?.disabled&&E.log("",...t)},error:(...t)=>{!e?.disabled&&E.error("",...t)},warn:(...t)=>{!e?.disabled&&E.warn("",...t)},info:(...t)=>{!e?.disabled&&E.info("",...t)},debug:(...t)=>{!e?.disabled&&E.debug("",...t)},box:(...t)=>{!e?.disabled&&E.box("",...t)},success:(...t)=>{!e?.disabled&&E.success("",...t)},break:(...t)=>{!e?.disabled&&console.log(`
2
+ `)}}),T=Z();var ye=e=>{let t=new vt(e.clientId,e.clientSecret,w("google",e.redirectURI));return{id:"google",name:"Google",createAuthorizationURL({state:o,scopes:r,codeVerifier:n,redirectURI:s}){if(!e.clientId||!e.clientSecret)throw T.error("Client Id and Client Secret is required for Google. Make sure to provide them in the options."),new k("CLIENT_ID_AND_SECRET_REQUIRED");if(!n)throw new k("codeVerifier is required for Google");let i=r||["email","profile"];return t.createAuthorizationURL(o,n,i)},validateAuthorizationCode:async(o,r,n)=>R({code:o,codeVerifier:r,redirectURI:n||w("google",e.redirectURI),options:e,tokenEndpoint:"https://oauth2.googleapis.com/token"}),async getUserInfo(o){if(!o.idToken)return null;let r=It(o.idToken())?.payload;return{user:{id:r.sub,name:r.name,email:r.email,image:r.picture,emailVerified:r.email_verified},data:r}}}};import{betterFetch as St}from"@better-fetch/fetch";import{Spotify as Ot}from"arctic";var be=e=>{let t=new Ot(e.clientId,e.clientSecret,w("spotify",e.redirectURI));return{id:"spotify",name:"Spotify",createAuthorizationURL({state:o,scopes:r}){let n=r||["user-read-email"];return t.createAuthorizationURL(o,n)},validateAuthorizationCode:async(o,r,n)=>R({code:o,codeVerifier:r,redirectURI:n||w("spotify",e.redirectURI),options:e,tokenEndpoint:"https://accounts.spotify.com/api/token"}),async getUserInfo(o){let{data:r,error:n}=await St("https://api.spotify.com/v1/me",{method:"GET",headers:{Authorization:`Bearer ${o.accessToken()}`}});return n?null:{user:{id:r.id,name:r.display_name,email:r.email,image:r.images[0]?.url,emailVerified:!1},data:r}}}};import{betterFetch as Lt}from"@better-fetch/fetch";import{Twitch as Ct}from"arctic";var we=e=>{let t=new Ct(e.clientId,e.clientSecret,w("twitch",e.redirectURI));return{id:"twitch",name:"Twitch",createAuthorizationURL({state:o,scopes:r}){let n=r||["activity:write","read"];return t.createAuthorizationURL(o,n)},validateAuthorizationCode:async(o,r,n)=>R({code:o,codeVerifier:r,redirectURI:n||w("twitch",e.redirectURI),options:e,tokenEndpoint:"https://id.twitch.tv/oauth2/token"}),async getUserInfo(o){let{data:r,error:n}=await Lt("https://api.twitch.tv/helix/users",{method:"GET",headers:{Authorization:`Bearer ${o.accessToken()}`}});return n?null:{user:{id:r.sub,name:r.preferred_username,email:r.email,image:r.picture,emailVerified:!1},data:r}}}};import{betterFetch as Et}from"@better-fetch/fetch";import{Twitter as _t}from"arctic";var Ae=e=>{let t=new _t(e.clientId,e.clientSecret,w("twitter",e.redirectURI));return{id:"twitter",name:"Twitter",createAuthorizationURL(o){let r=o.scopes||["account_info.read"];return t.createAuthorizationURL(o.state,o.codeVerifier,r)},validateAuthorizationCode:async(o,r,n)=>R({code:o,codeVerifier:r,redirectURI:n||w("twitch",e.redirectURI),options:e,tokenEndpoint:"https://id.twitch.tv/oauth2/token"}),async getUserInfo(o){let{data:r,error:n}=await Et("https://api.x.com/2/users/me?user.fields=profile_image_url",{method:"GET",headers:{Authorization:`Bearer ${o.accessToken()}`}});return n||!r.data.email?null:{user:{id:r.data.id,name:r.data.name,email:r.data.email,image:r.data.profile_image_url,emailVerified:r.data.verified||!1},data:r}}}};import"arctic";var Q={apple:pe,discord:me,facebook:fe,github:he,google:ye,spotify:be,twitch:we,twitter:Ae},ke=Object.keys(Q);import{generateState as Bt}from"oslo/oauth2";import{z as D}from"zod";function Re(e,t,o){let r=Bt();return{state:JSON.stringify({code:r,callbackURL:e,currentURL:t,dontRememberMe:o}),code:r}}function X(e){return D.object({code:D.string(),callbackURL:D.string().optional(),currentURL:D.string().optional(),dontRememberMe:D.boolean().optional()}).safeParse(JSON.parse(e))}import{APIError as jt}from"better-call";var N=(e,t=!1)=>{let o=new Date;return new Date(o.getTime()+(t?e*1e3:e))};import{TimeSpan as qt}from"oslo";function Te(e){let o=!!e.advanced?.useSecureCookies||process.env.NODE_ENV!=="development"&&process.env.NODE_ENV!=="test"?"__Secure-":"",r="better-auth",n=new qt(7,"d").seconds();return{sessionToken:{name:`${o}${r}.session_token`,options:{httpOnly:!0,sameSite:"lax",path:"/",secure:!!o,maxAge:n}},csrfToken:{name:`${o?"__Host-":""}${r}.csrf_token`,options:{httpOnly:!0,sameSite:"lax",path:"/",secure:!!o,maxAge:60*60*24*7}},state:{name:`${o}${r}.state`,options:{httpOnly:!0,sameSite:"lax",path:"/",secure:!!o,maxAge:60*15}},pkCodeVerifier:{name:`${o}${r}.pk_code_verifier`,options:{httpOnly:!0,sameSite:"lax",path:"/",secure:!!o,maxAge:60*15}},dontRememberToken:{name:`${o}${r}.dont_remember`,options:{httpOnly:!0,sameSite:"lax",path:"/",secure:!!o}},nonce:{name:`${o}${r}.nonce`,options:{httpOnly:!0,sameSite:"lax",path:"/",secure:!!o,maxAge:60*15}}}}function xe(e){let o=!!e.advanced?.useSecureCookies||process.env.NODE_ENV==="production"?"__Secure-":"",r="better-auth";function n(s,i){return{name:process.env.NODE_ENV==="production"?`${o}${r}.${s}`:`${r}.${s}`,options:{secure:!!o,sameSite:"lax",path:"/",maxAge:60*15,...i}}}return n}async function P(e,t,o,r){let n=e.context.authCookies.sessionToken.options;n.maxAge=o?void 0:n.maxAge,await e.setSignedCookie(e.context.authCookies.sessionToken.name,t,e.context.secret,n),o&&await e.setSignedCookie(e.context.authCookies.dontRememberToken.name,"true",e.context.secret,e.context.authCookies.dontRememberToken.options)}function $(e){e.setCookie(e.context.authCookies.sessionToken.name,"",{maxAge:0}),e.setCookie(e.context.authCookies.dontRememberToken.name,"",{maxAge:0})}import{z as Ue}from"zod";function V(e){let t="127.0.0.1";if(process.env.NODE_ENV==="test")return t;let o=["x-client-ip","x-forwarded-for","cf-connecting-ip","fastly-client-ip","x-real-ip","x-cluster-client-ip","x-forwarded","forwarded-for","forwarded"];for(let r of o){let n=e.headers.get(r);if(typeof n=="string"){let s=n.split(",")[0].trim();if(s)return s}}return null}var Y=new Map;function Dt(e,t){if(!e.request)return"";let{method:o,url:r,headers:n}=e.request,s=e.request.headers.get("User-Agent")||"",i=V(e.request)||"",a=JSON.stringify(n);return`${o}:${r}:${a}:${s}:${i}:${t}`}var ee=()=>g("/session",{method:"GET",requireHeaders:!0},async e=>{try{let t=await e.getSignedCookie(e.context.authCookies.sessionToken.name,e.context.secret);if(!t)return e.json(null,{status:401});let o=Dt(e,t),r=Y.get(o);if(r){if(r.expiresAt>Date.now())return e.json(r.data);Y.delete(o)}let n=await e.context.internalAdapter.findSession(t);if(!n||n.session.expiresAt<new Date)return $(e),n&&await e.context.internalAdapter.deleteSession(n.session.id),e.json(null,{status:401});if(await e.getSignedCookie(e.context.authCookies.dontRememberToken.name,e.context.secret))return e.json(n);let i=e.context.sessionConfig.expiresIn,a=e.context.sessionConfig.updateAge;if(n.session.expiresAt.valueOf()-i*1e3+a*1e3<=Date.now()){let l=await e.context.internalAdapter.updateSession(n.session.id,{expiresAt:N(e.context.sessionConfig.expiresIn,!0)});if(!l)return $(e),e.json(null,{status:401});let u=(l.expiresAt.valueOf()-Date.now())/1e3;return await P(e,l.id,!1,{maxAge:u}),e.json({session:l,user:n.user})}return Y.set(o,{data:n,expiresAt:Date.now()+5e3}),e.json(n)}catch(t){return e.context.logger.error(t),e.json(null,{status:500})}}),te=async e=>await ee()({...e,_flag:void 0}),_=M(async e=>{let t=await te(e);if(!t?.session)throw new jt("UNAUTHORIZED");return{session:t}}),Pe=()=>g("/user/list-sessions",{method:"GET",use:[_],requireHeaders:!0},async e=>{let o=(await e.context.adapter.findMany({model:e.context.tables.session.tableName,where:[{field:"userId",value:e.context.session.user.id}]})).filter(r=>r.expiresAt>new Date);return e.json(o)}),ve=g("/user/revoke-session",{method:"POST",body:Ue.object({id:Ue.string()}),use:[_],requireHeaders:!0},async e=>{let t=e.body.id,o=await e.context.internalAdapter.findSession(t);if(!o)return e.json(null,{status:400});if(o.session.userId!==e.context.session.user.id)return e.json(null,{status:403});try{await e.context.internalAdapter.deleteSession(t)}catch(r){return e.context.logger.error(r),e.json(null,{status:500})}return e.json({status:!0})}),Ie=g("/user/revoke-sessions",{method:"POST",use:[_],requireHeaders:!0},async e=>{try{await e.context.internalAdapter.deleteSessions(e.context.session.user.id)}catch(t){return e.context.logger.error(t),e.json(null,{status:500})}return e.json({status:!0})});var Se=g("/sign-in/social",{method:"POST",requireHeaders:!0,query:x.object({currentURL:x.string().optional()}).optional(),body:x.object({callbackURL:x.string().optional(),provider:x.enum(ke),dontRememberMe:x.boolean().default(!1).optional()})},async e=>{let t=e.context.socialProviders.find(i=>i.id===e.body.provider);if(!t)throw e.context.logger.error("Provider not found. Make sure to add the provider to your auth config",{provider:e.body.provider}),new I("NOT_FOUND",{message:"Provider not found"});let o=e.context.authCookies,r=e.query?.currentURL?new URL(e.query?.currentURL):null,n=e.body.callbackURL?.startsWith("http")?e.body.callbackURL:`${r?.origin}${e.body.callbackURL||""}`,s=Re(n||r?.origin||e.context.baseURL,e.query?.currentURL);try{await e.setSignedCookie(o.state.name,s.code,e.context.secret,o.state.options);let i=Nt();await e.setSignedCookie(o.pkCodeVerifier.name,i,e.context.secret,o.pkCodeVerifier.options);let a=t.createAuthorizationURL({state:s.state,codeVerifier:i});return a.searchParams.set("redirect_uri",`${e.context.baseURL}/callback/${e.body.provider}`),{url:a.toString(),state:s.state,codeVerifier:i,redirect:!0}}catch{throw new I("INTERNAL_SERVER_ERROR")}}),Oe=g("/sign-in/email",{method:"POST",body:x.object({email:x.string().email(),password:x.string(),callbackURL:x.string().optional(),dontRememberMe:x.boolean().default(!1).optional()})},async e=>{if(!e.context.options?.emailAndPassword?.enabled)throw e.context.logger.error("Email and password is not enabled. Make sure to enable it in the options on you `auth.ts` file. Check `https://better-auth.com/docs/authentication/email-password` for more!"),new I("BAD_REQUEST",{message:"Email and password is not enabled"});let t=await te(e);t&&await e.context.internalAdapter.deleteSession(t.session.id);let{email:o,password:r}=e.body;if(!x.string().email().safeParse(o).success)throw new I("BAD_REQUEST",{message:"Invalid email"});let s=await e.context.internalAdapter.findUserByEmail(o);if(!s)throw await e.context.password.hash(r),e.context.logger.error("User not found",{email:o}),new I("UNAUTHORIZED",{message:"Invalid email or password"});let i=s.accounts.find(l=>l.providerId==="credential");if(!i)throw e.context.logger.error("Credential account not found",{email:o}),new I("UNAUTHORIZED",{message:"Invalid email or password"});let a=i?.password;if(!a)throw e.context.logger.error("Password not found",{email:o}),new I("UNAUTHORIZED",{message:"Unexpected error"});if(!await e.context.password.verify(a,r))throw e.context.logger.error("Invalid password"),new I("UNAUTHORIZED",{message:"Invalid email or password"});let c=await e.context.internalAdapter.createSession(s.user.id,e.headers,e.body.dontRememberMe);if(!c)throw e.context.logger.error("Failed to create session"),new I("INTERNAL_SERVER_ERROR");return await P(e,c.id,e.body.dontRememberMe),e.json({user:s.user,session:c,redirect:!!e.body.callbackURL,url:e.body.callbackURL})});import{APIError as Mt}from"better-call";import{z as H}from"zod";import{z as b}from"zod";var Sn=b.object({id:b.string(),providerId:b.string(),accountId:b.string(),userId:b.string(),accessToken:b.string().nullable().optional(),refreshToken:b.string().nullable().optional(),idToken:b.string().nullable().optional(),expiresAt:b.date().nullable().optional(),password:b.string().optional().nullable()}),Le=b.object({id:b.string(),email:b.string().transform(e=>e.toLowerCase()),emailVerified:b.boolean().default(!1),name:b.string(),image:b.string().optional(),createdAt:b.date().default(new Date),updatedAt:b.date().default(new Date)}),On=b.object({id:b.string(),userId:b.string(),expiresAt:b.date(),ipAddress:b.string().optional(),userAgent:b.string().optional()});import{alphabet as $t,generateRandomString as Ft}from"oslo/crypto";var Ce=()=>Ft(36,$t("a-z","0-9"));var L={isAction:!1};function re(e){let t=e.accessToken(),o=e.hasRefreshToken()?e.refreshToken():void 0,r;try{r=e.accessTokenExpiresAt()}catch{}return{accessToken:t,refreshToken:o,expiresAt:r}}var Ee=g("/callback/:id",{method:"GET",query:H.object({state:H.string(),code:H.string().optional(),error:H.string().optional()}),metadata:L},async e=>{if(e.query.error||!e.query.code){let y=X(e.query.state).data?.callbackURL||`${e.context.baseURL}/error`;throw e.context.logger.error(e.query.error,e.params.id),e.redirect(`${y}?error=${e.query.error||"oAuth_code_missing"}`)}let t=e.context.socialProviders.find(f=>f.id===e.params.id);if(!t)throw e.context.logger.error("Oauth provider with id",e.params.id,"not found"),e.redirect(`${e.context.baseURL}/error?error=oauth_provider_not_found`);let o=await e.getSignedCookie(e.context.authCookies.pkCodeVerifier.name,e.context.secret),r;try{r=await t.validateAuthorizationCode(e.query.code,o,`${e.context.baseURL}/callback/${t.id}`)}catch(f){throw e.context.logger.error(f),e.redirect(`${e.context.baseURL}/error?error=oauth_code_verification_failed`)}let n=await t.getUserInfo(r).then(f=>f?.user),s=Ce(),i=Le.safeParse({...n,id:s}),a=X(e.query.state);if(!a.success)throw e.context.logger.error("Unable to parse state"),e.redirect(`${e.context.baseURL}/error?error=invalid_state_parameter`);let{callbackURL:d,currentURL:c,dontRememberMe:l}=a.data;if(!n||i.success===!1)throw e.redirect(`${e.context.baseURL}/error?error=oauth_validation_failed`);if(!d)throw e.redirect(`${e.context.baseURL}/error?error=oauth_callback_url_not_found`);let u=await e.context.internalAdapter.findUserByEmail(n.email),p=u?.user.id;if(u){let f=u.accounts.find(A=>A.providerId===t.id),y=e.context.options.account?.accountLinking?.trustedProviders,h=y?y.includes(t.id):!0;if(!f&&(!n.emailVerified||!h)){let A;try{A=new URL(c||d),A.searchParams.set("error","account_not_linked")}catch{throw e.redirect(`${e.context.baseURL}/error?error=account_not_linked`)}throw e.redirect(A.toString())}if(!f)try{await e.context.internalAdapter.linkAccount({providerId:t.id,accountId:n.id,id:`${t.id}:${n.id}`,userId:u.user.id,...re(r)})}catch(A){throw console.log(A),e.redirect(`${e.context.baseURL}/error?error=failed_linking_account`)}}else try{await e.context.internalAdapter.createOAuthUser(i.data,{...re(r),id:`${t.id}:${n.id}`,providerId:t.id,accountId:n.id,userId:s})}catch{let y=new URL(c||d);throw y.searchParams.set("error","unable_to_create_user"),e.setHeader("Location",y.toString()),e.redirect(y.toString())}if(!p&&!s)throw new Mt("INTERNAL_SERVER_ERROR",{message:"Unable to create user"});let m=await e.context.internalAdapter.createSession(p||s,e.request,l);if(!m){let f=new URL(c||d);throw f.searchParams.set("error","unable_to_create_session"),e.redirect(f.toString())}try{await P(e,m.id,l)}catch(f){e.context.logger.error("Unable to set session cookie",f);let y=new URL(c||d);throw y.searchParams.set("error","unable_to_create_session"),e.redirect(y.toString())}throw e.redirect(d)});import{z as oe}from"zod";var _e=g("/sign-out",{method:"POST",body:oe.optional(oe.object({callbackURL:oe.string().optional()}))},async e=>{let t=await e.getSignedCookie(e.context.authCookies.sessionToken.name,e.context.secret);return t?(await e.context.internalAdapter.deleteSession(t),$(e),e.json(null,{body:{redirect:!!e.body?.callbackURL,url:e.body?.callbackURL}})):e.json(null)});import{TimeSpan as zt}from"oslo";import{createJWT as Vt,parseJWT as Ht}from"oslo/jwt";import{validateJWT as Be}from"oslo/jwt";import{z as U}from"zod";var qe=g("/forget-password",{method:"POST",body:U.object({email:U.string().email(),redirectTo:U.string()})},async e=>{if(!e.context.options.emailAndPassword?.sendResetPassword)return e.context.logger.error("Reset password isn't enabled.Please pass an emailAndPassword.sendResetPasswordToken function to your auth config!"),e.json(null,{status:400,statusText:"RESET_PASSWORD_EMAIL_NOT_SENT",body:{message:"Reset password isn't enabled"}});let{email:t}=e.body,o=await e.context.internalAdapter.findUserByEmail(t);if(!o)return e.json({status:!1},{body:{status:!0}});let r=await Vt("HS256",Buffer.from(e.context.secret),{email:o.user.email,redirectTo:e.body.redirectTo},{expiresIn:new zt(1,"h"),issuer:"better-auth",subject:"forget-password",audiences:[o.user.email],includeIssuedTimestamp:!0}),n=`${e.context.baseURL}/reset-password/${r}`;return await e.context.options.emailAndPassword.sendResetPassword(n,o.user),e.json({status:!0})}),je=g("/reset-password/:token",{method:"GET"},async e=>{let{token:t}=e.params,o,r=U.object({email:U.string(),redirectTo:U.string()});try{if(o=await Be("HS256",Buffer.from(e.context.secret),t),!o.expiresAt||o.expiresAt<new Date)throw Error("Token expired")}catch{let i=Ht(t),a=r.safeParse(i?.payload);throw a.success?e.redirect(`${a.data?.redirectTo}?error=invalid_token`):e.redirect(`${e.context.baseURL}/error?error=invalid_token`)}let{redirectTo:n}=r.parse(o.payload);throw e.redirect(`${n}?token=${t}`)}),De=g("/reset-password",{method:"POST",query:U.object({currentURL:U.string()}).optional(),body:U.object({newPassword:U.string(),callbackURL:U.string().optional()})},async e=>{let t=e.query?.currentURL.split("?token=")[1];if(!t)return e.json({error:"Invalid token",data:null},{status:400,statusText:"INVALID_TOKEN",body:{message:"Invalid token"}});let{newPassword:o}=e.body;try{let r=await Be("HS256",Buffer.from(e.context.secret),t),n=U.string().email().parse(r.payload.email),s=await e.context.internalAdapter.findUserByEmail(n);if(!s)return e.json({error:"User not found",data:null},{status:400,body:{message:"failed to reset password"}});if(o.length<(e.context.options.emailAndPassword?.minPasswordLength||8)||o.length>(e.context.options.emailAndPassword?.maxPasswordLength||32))return e.json({data:null,error:"password is too short or too long"},{status:400,statusText:"INVALID_PASSWORD_LENGTH",body:{message:"password is too short or too long"}});let i=await e.context.password.hash(o);return await e.context.internalAdapter.updatePassword(s.user.id,i)?e.json({error:null,data:{status:!0,url:e.body.callbackURL,redirect:!!e.body.callbackURL}},{body:{status:!0,url:e.body.callbackURL,redirect:!!e.body.callbackURL}}):e.json(null,{status:400,statusText:"USER_NOT_FOUND",body:{message:"User doesn't have a credential account"}})}catch(r){return console.log(r),e.json({error:"Invalid token",data:null},{status:400,statusText:"INVALID_TOKEN",body:{message:"Invalid token"}})}});import{TimeSpan as Gt}from"oslo";import{createJWT as Kt,validateJWT as Wt}from"oslo/jwt";import{z as v}from"zod";async function ne(e,t){return await Kt("HS256",Buffer.from(e),{email:t.toLowerCase()},{expiresIn:new Gt(1,"h"),issuer:"better-auth",subject:"verify-email",audiences:[t],includeIssuedTimestamp:!0})}var Ne=g("/send-verification-email",{method:"POST",query:v.object({currentURL:v.string().optional()}).optional(),body:v.object({email:v.string().email(),callbackURL:v.string().optional()})},async e=>{if(!e.context.options.emailAndPassword?.sendVerificationEmail)return e.context.logger.error("Verification email isn't enabled. Pass `sendVerificationEmail` in `emailAndPassword` options to enable it."),e.json(null,{status:400,statusText:"VERIFICATION_EMAIL_NOT_SENT",body:{message:"Verification email isn't enabled"}});let{email:t}=e.body,o=await ne(e.context.secret,t),r=`${e.context.baseURL}/verify-email?token=${o}&callbackURL=${e.body.callbackURL||e.query?.currentURL||"/"}`;return await e.context.options.emailAndPassword.sendVerificationEmail(t,r,o),e.json({status:!0})}),$e=g("/verify-email",{method:"GET",query:v.object({token:v.string(),callbackURL:v.string().optional()})},async e=>{let{token:t}=e.query,o;try{o=await Wt("HS256",Buffer.from(e.context.secret),t)}catch(a){return e.context.logger.error("Failed to verify email",a),e.json(null,{status:400,statusText:"INVALID_TOKEN",body:{message:"Invalid token"}})}let n=v.object({email:v.string().email()}).parse(o.payload),s=await e.context.internalAdapter.findUserByEmail(n.email);if(!s)return e.json(null,{status:400,statusText:"USER_NOT_FOUND",body:{message:"User not found"}});if(!s.accounts.find(a=>a.providerId==="credential"))throw e.redirect;if(await e.context.internalAdapter.updateUserByEmail(n.email,{emailVerified:!0}),e.query.callbackURL)throw console.log("Redirecting to",e.query.callbackURL),e.redirect("/");return e.json({status:!0})});import{z as S}from"zod";import{alphabet as Jt,generateRandomString as Zt}from"oslo/crypto";import"better-call";var Fe=g("/user/update",{method:"POST",body:S.object({name:S.string().optional(),image:S.string().optional()}),use:[_]},async e=>{let{name:t,image:o}=e.body,r=e.context.session;if(!o&&!t)return e.json(r.user);let n=await e.context.internalAdapter.updateUserByEmail(r.user.email,{name:t,image:o});return e.json(n)}),Me=g("/user/change-password",{method:"POST",body:S.object({newPassword:S.string(),currentPassword:S.string(),revokeOtherSessions:S.boolean().optional()}),use:[_]},async e=>{let{newPassword:t,currentPassword:o,revokeOtherSessions:r}=e.body,n=e.context.session,s=e.context.password.config.minPasswordLength;if(t.length<s)return e.context.logger.error("Password is too short"),e.json(null,{status:400,body:{message:"Password is too short"}});let i=e.context.password.config.maxPasswordLength;if(t.length>i)return e.context.logger.error("Password is too long"),e.json(null,{status:400,body:{message:"Password is too long"}});let d=(await e.context.internalAdapter.findAccounts(n.user.id)).find(u=>u.providerId==="credential"&&u.password);if(!d||!d.password)return e.json(null,{status:400,body:{message:"User does not have a password"}});let c=await e.context.password.hash(t);if(!await e.context.password.verify(d.password,o))return e.json(null,{status:400,body:{message:"Invalid password"}});if(await e.context.internalAdapter.updateAccount(d.id,{password:c}),r){await e.context.internalAdapter.deleteSessions(n.user.id);let u=await e.context.internalAdapter.createSession(n.user.id,e.headers);if(!u)return e.json(null,{status:500,body:{message:"Failed to create session"}});await P(e,u.id)}return e.json(n.user)}),ze=g("/user/set-password",{method:"POST",body:S.object({newPassword:S.string()}),use:[_]},async e=>{let{newPassword:t}=e.body,o=e.context.session,r=e.context.password.config.minPasswordLength;if(t.length<r)return e.context.logger.error("Password is too short"),e.json(null,{status:400,body:{message:"Password is too short"}});let n=e.context.password.config.maxPasswordLength;if(t.length>n)return e.context.logger.error("Password is too long"),e.json(null,{status:400,body:{message:"Password is too long"}});let i=(await e.context.internalAdapter.findAccounts(o.user.id)).find(d=>d.providerId==="credential"&&d.password),a=await e.context.password.hash(t);return i?e.json(null,{status:400,body:{message:"User already has a password"}}):(await e.context.internalAdapter.linkAccount({id:Zt(32,Jt("a-z","0-9","A-Z")),userId:o.user.id,providerId:"credential",accountId:o.user.id,password:a}),e.json(o.user))});import{alphabet as Qt,generateRandomString as Xt}from"oslo/crypto";var Ve=g("/csrf",{method:"GET",metadata:L},async e=>{let t=await e.getSignedCookie(e.context.authCookies.csrfToken.name,e.context.secret);if(t)return{csrfToken:t};let o=Xt(32,Qt("a-z","0-9","A-Z")),r=await F(e.context.secret,o),n=`${o}!${r}`;return await e.setSignedCookie(e.context.authCookies.csrfToken.name,n,e.context.secret,e.context.authCookies.csrfToken.options),{csrfToken:o}});var Yt=(e="Unknown")=>`<!DOCTYPE html>
3
3
  <html lang="en">
4
4
  <head>
5
5
  <meta charset="UTF-8">
@@ -79,4 +79,6 @@ var Ot=Object.defineProperty,_t=Object.defineProperties;var Et=Object.getOwnProp
79
79
  <div class="error-code">Error Code: <span id="errorCode">${e}</span></div>
80
80
  </div>
81
81
  </body>
82
- </html>`,dt=y("/error",{method:"GET",metadata:D},e=>u(void 0,null,function*(){var n;let t=new URL(((n=e.request)==null?void 0:n.url)||"").searchParams.get("error")||"Unknown";return new Response(br(t),{headers:{"Content-Type":"text/html"}})}));var ct=y("/ok",{method:"GET",metadata:D},e=>u(void 0,null,function*(){return e.json({ok:!0})}));import{alphabet as ut,generateRandomString as lt}from"oslo/crypto";import{z as j}from"zod";var pt=y("/sign-up/email",{method:"POST",query:j.object({currentURL:j.string().optional()}).optional(),body:j.object({name:j.string(),email:j.string(),password:j.string(),image:j.string().optional(),callbackURL:j.string().optional()})},e=>u(void 0,null,function*(){var m,f,h,w;if(!((m=e.context.options.emailAndPassword)!=null&&m.enabled))return e.json(null,{status:400,body:{message:"Email and password is not enabled"}});let{name:t,email:n,password:o,image:r}=e.body;if(!j.string().email().safeParse(n).success)return e.json(null,{status:400,body:{message:"Invalid email address"}});let i=e.context.password.config.minPasswordLength;if(o.length<i)return e.context.logger.error("Password is too short"),e.json(null,{status:400,body:{message:"Password is too short"}});let a=e.context.password.config.maxPasswordLength;if(o.length>a)return e.context.logger.error("Password is too long"),e.json(null,{status:400,body:{message:"Password is too long"}});let d=yield e.context.internalAdapter.findUserByEmail(n),l=yield e.context.password.hash(o);if(d!=null&&d.user)return e.json(null,{status:400,body:{message:"User already exists"}});let c=yield e.context.internalAdapter.createUser({id:lt(32,ut("a-z","0-9","A-Z")),email:n.toLowerCase(),name:t,image:r,emailVerified:!1,createdAt:new Date,updatedAt:new Date});if(!c)return e.json(null,{status:400,body:{message:"Could not create user"}});yield e.context.internalAdapter.linkAccount({id:lt(32,ut("a-z","0-9","A-Z")),userId:c.id,providerId:"credential",accountId:c.id,password:l});let p=yield e.context.internalAdapter.createSession(c.id,e.request);if(!p)return e.json(null,{status:400,body:{message:"Could not create session"}});if(yield _(e,p.id),e.context.options.emailAndPassword.sendEmailVerificationOnSignUp){let U=yield me(e.context.secret,c.email),b=`${e.context.baseURL}/verify-email?token=${U}&callbackURL=${e.body.callbackURL||((f=e.query)==null?void 0:f.currentURL)||"/"}`;yield(w=(h=e.context.options.emailAndPassword).sendVerificationEmail)==null?void 0:w.call(h,c.email,b,U)}return e.json({user:c,session:p},{body:e.body.callbackURL?{url:e.body.callbackURL,redirect:!0}:{user:c,session:p}})}));import fe from"chalk";function wr(e,t,n){let o=Date.now(),r=t*1e3;return o-n.lastRequest<r&&n.count>=e}function Ar(e){return new Response(JSON.stringify({message:"Too many requests. Please try again later."}),{status:429,statusText:"Too Many Requests",headers:{"X-Retry-After":e.toString()}})}function kr(e,t){let n=Date.now(),o=t*1e3;return Math.ceil((e+o-n)/1e3)}function Rr(e,t){let n=t!=null?t:"rateLimit",o=e.adapter;return{get:r=>u(this,null,function*(){return yield o.findOne({model:n,where:[{field:"key",value:r}]})}),set:(r,s,i)=>u(this,null,function*(){try{i?yield o.update({model:t!=null?t:"rateLimit",where:[{field:"key",value:r}],update:{count:s.count,lastRequest:s.lastRequest}}):yield o.create({model:t!=null?t:"rateLimit",data:{key:r,count:s.count,lastRequest:s.lastRequest}})}catch(a){O.error("Error setting rate limit",a)}})}}var mt=new Map;function Tr(e){if(e.rateLimit.customStorage)return e.rateLimit.customStorage;if(e.rateLimit.storage==="memory"){let n;return{get(o){return u(this,null,function*(){return mt.get(o)})},set(o,r,s){return u(this,null,function*(){mt.set(o,r)})}}}return Rr(e,e.rateLimit.tableName)}function ft(e,t){return u(this,null,function*(){if(!t.rateLimit.enabled)return;let n=t.baseURL,o=e.url.replace(n,""),r=t.rateLimit.window,s=t.rateLimit.max,i=X(e)+o,d=Ur().find(m=>m.pathMatcher(o));d&&(r=d.window,s=d.max);for(let m of t.options.plugins||[])if(m.rateLimit){let f=m.rateLimit.find(h=>h.pathMatcher(o));if(f){r=f.window,s=f.max;break}}if(t.rateLimit.customRules){let m=t.rateLimit.customRules[o];m&&(r=m.window,s=m.max)}let l=Tr(t),c=yield l.get(i),p=Date.now();if(!c)yield l.set(i,{key:i,count:1,lastRequest:p});else{let m=p-c.lastRequest;if(wr(s,r,c)){let f=kr(c.lastRequest,r);return Ar(f)}else m>r*1e3?yield l.set(i,k(g({},c),{count:1,lastRequest:p})):yield l.set(i,k(g({},c),{count:c.count+1,lastRequest:p}))}})}function Ur(){return[{pathMatcher(t){return t.startsWith("/sign-in")||t.startsWith("/sign-up")},window:10,max:7}]}function ge(e,t){var a,d;let n=(a=e.options.plugins)==null?void 0:a.reduce((l,c)=>g(g({},l),c.endpoints),{}),o=((d=e.options.plugins)==null?void 0:d.map(l=>{var c;return(c=l.middlewares)==null?void 0:c.map(p=>{let m=f=>u(this,null,function*(){return p.middleware(k(g({},f),{context:g(g({},e),f.context)}))});return m.path=p.path,m.options=p.middleware.options,m.headers=p.middleware.headers,{path:p.path,middleware:m}})}).filter(l=>l!==void 0).flat())||[],r={signInOAuth:Ge,callbackOAuth:Ze,getCSRFToken:at,getSession:ce(),signOut:Qe,signUpEmail:pt,signInEmail:Ke,forgetPassword:Ye,resetPassword:tt,verifyEmail:ot,sendVerificationEmail:rt,changePassword:st,setPassword:it,updateUser:nt,forgetPasswordCallback:et,listSessions:ze(),revokeSession:Me,revokeSessions:He},s=k(g(g({},r),n),{ok:ct,error:dt}),i={};for(let[l,c]of Object.entries(s))i[l]=p=>u(this,null,function*(){var h;let f=yield c(k(g({},p),{context:g(g({},e),p.context)}));for(let w of e.options.plugins||[])if((h=w.hooks)!=null&&h.after){for(let U of w.hooks.after)if(U.matcher(p)){let T=Object.assign(p,{context:k(g({},e),{returned:f})}),P=yield U.handler(T);P&&"response"in P&&(f=P.response)}}return f}),i[l].path=c.path,i[l].method=c.method,i[l].options=c.options,i[l].headers=c.headers;return{api:i,middlewares:o}}var gt=(e,t)=>{let{api:n,middlewares:o}=ge(e,t),r=new URL(e.baseURL).pathname;return Pr(n,{extraContext:e,basePath:r,routerMiddleware:[{path:"/**",middleware:Ie},...o],onRequest(i){return u(this,null,function*(){for(let a of e.options.plugins||[])if(a.onRequest){let d=yield a.onRequest(i,e);if(d)return d}return ft(i,e)})},onResponse(i){return u(this,null,function*(){for(let a of e.options.plugins||[])if(a.onResponse){let d=yield a.onResponse(i,e);if(d)return d.response}return i})},onError(i){var d,l,c,p;let a=(d=t.logger)!=null&&d.verboseLogging?O:void 0;if(((l=t.logger)==null?void 0:l.disabled)!==!0)if(i instanceof xr)a==null||a.warn(i);else if(typeof i=="object"&&i!==null&&"message"in i){let m=i.message;if(!m||typeof m!="string"){a==null||a.error(i);return}m.includes("no such table")?(c=O)==null||c.error(`Please run ${fe.green("npx better-auth migrate")} to create the tables. There are missing tables in your SQLite database.`):m.includes("relation")&&m.includes("does not exist")?O.error(`Please run ${fe.green("npx better-auth migrate")} to create the tables. There are missing tables in your PostgreSQL database.`):m.includes("Table")&&m.includes("doesn't exist")?(p=O)==null||p.error(`Please run ${fe.green("npx better-auth migrate")} to create the tables. There are missing tables in your MySQL database.`):a==null||a.error(i)}else a==null||a.error(i)}})};var N=e=>{var d,l,c,m,f,h;let t=(d=e.plugins)==null?void 0:d.reduce((w,U)=>{var T;let b=U.schema;if(!b)return w;for(let[P,v]of Object.entries(b))w[P]={fields:g(g({},(T=w[P])==null?void 0:T.fields),v.fields),tableName:P};return w},{}),n=((l=e.rateLimit)==null?void 0:l.storage)==="database",o={rateLimit:{tableName:((c=e.rateLimit)==null?void 0:c.tableName)||"rateLimit",fields:{key:{type:"string"},count:{type:"number"},lastRequest:{type:"number"}}}},p=t||{},{user:r,session:s,account:i}=p,a=W(p,["user","session","account"]);return g(g({user:{tableName:((m=e.user)==null?void 0:m.modelName)||"user",fields:g({name:{type:"string"},email:{type:"string"},emailVerified:{type:"boolean",defaultValue:()=>!1},image:{type:"string",required:!1},createdAt:{type:"date",defaultValue:()=>new Date},updatedAt:{type:"date",defaultValue:()=>new Date}},r==null?void 0:r.fields),order:0},session:{tableName:((f=e.session)==null?void 0:f.modelName)||"session",fields:g({expiresAt:{type:"date"},ipAddress:{type:"string",required:!1},userAgent:{type:"string",required:!1},userId:{type:"string",references:{model:"user",field:"id",onDelete:"cascade"}}},s==null?void 0:s.fields),order:1},account:{tableName:((h=e.account)==null?void 0:h.modelName)||"account",fields:g({accountId:{type:"string"},providerId:{type:"string"},userId:{type:"string",references:{model:"user",field:"id",onDelete:"cascade"}},accessToken:{type:"string",required:!1},refreshToken:{type:"string",required:!1},idToken:{type:"string",required:!1},expiresAt:{type:"date",required:!1},password:{type:"string",required:!1}},i==null?void 0:i.fields),order:2}},a),n?o:{})};import vr from"better-sqlite3";import{Kysely as Ir}from"kysely";import{MysqlDialect as yt,PostgresDialect as bt,SqliteDialect as wt}from"kysely";import{createPool as Sr}from"mysql2";import Lr from"pg";var{Pool:Or}=Lr;function ee(e){if(!e)return{and:null,or:null};let t=e==null?void 0:e.filter(o=>o.connector==="AND"||!o.connector).reduce((o,r)=>k(g({},o),{[r.field]:r.value}),{}),n=e==null?void 0:e.filter(o=>o.connector==="OR").reduce((o,r)=>k(g({},o),{[r.field]:r.value}),{});return{and:Object.keys(t).length?t:null,or:Object.keys(n).length?n:null}}function te(e,t,n){var o,r,s;for(let i in e)e[i]===0&&((o=t[i])==null?void 0:o.type)==="boolean"&&(n!=null&&n.boolean)&&(e[i]=!1),e[i]===1&&((r=t[i])==null?void 0:r.type)==="boolean"&&(n!=null&&n.boolean)&&(e[i]=!0),((s=t[i])==null?void 0:s.type)==="date"&&(e[i]instanceof Date||(e[i]=new Date(e[i])));return e}function ht(e,t){for(let n in e)typeof e[n]=="boolean"&&(t!=null&&t.boolean)&&(e[n]=e[n]?1:0),e[n]instanceof Date&&(e[n]=e[n].toISOString());return e}var At=(e,t)=>({create(o){return u(this,null,function*(){let{model:r,data:s,select:i}=o;t!=null&&t.transform&&(s=ht(s,t.transform));let a=yield e.insertInto(r).values(s).returningAll().executeTakeFirst();if(t!=null&&t.transform){let d=t.transform.schema[r];a=d?te(s,d,t.transform):a}return i!=null&&i.length&&(a=a?i.reduce((l,c)=>a!=null&&a[c]?k(g({},l),{[c]:a[c]}):l,{}):null),a})},findOne(o){return u(this,null,function*(){let{model:r,where:s,select:i}=o,{and:a,or:d}=ee(s),l=e.selectFrom(r).selectAll();d&&(l=l.where(p=>p.or(d))),a&&(l=l.where(p=>p.and(a)));let c=yield l.executeTakeFirst();if(i!=null&&i.length&&(c=c?i.reduce((m,f)=>c!=null&&c[f]?k(g({},m),{[f]:c[f]}):m,{}):null),t!=null&&t.transform){let p=t.transform.schema[r];return c=c&&p?te(c,p,t.transform):c,c||null}return c||null})},findMany(o){return u(this,null,function*(){let{model:r,where:s}=o,i=e.selectFrom(r),{and:a,or:d}=ee(s);a&&(i=i.where(c=>c.and(a))),d&&(i=i.where(c=>c.or(d)));let l=yield i.selectAll().execute();if(t!=null&&t.transform){let c=t.transform.schema[r];return c?l.map(p=>te(p,c,t.transform)):l}return l})},update(o){return u(this,null,function*(){let{model:r,where:s,update:i}=o,{and:a,or:d}=ee(s);t!=null&&t.transform&&(i=ht(i,t.transform));let l=e.updateTable(r).set(i);a&&(l=l.where(p=>p.and(a))),d&&(l=l.where(p=>p.or(d)));let c=(yield l.returningAll().executeTakeFirst())||null;if(t!=null&&t.transform){let p=t.transform.schema[r];return p?te(c,p,t.transform):c}return c})},delete(o){return u(this,null,function*(){let{model:r,where:s}=o,{and:i,or:a}=ee(s),d=e.deleteFrom(r);i&&(d=d.where(l=>l.and(i))),a&&(d=d.where(l=>l.or(a))),yield d.execute()})}}),_r=e=>{var n,o;if(!e.database)return;if("createDriver"in e.database)return e.database;let t;if("provider"in e.database){let r=e.database.provider,s=(o=(n=e.database)==null?void 0:n.url)==null?void 0:o.trim();if(r==="postgres"&&(t=new bt({pool:new Or({connectionString:s})})),r==="mysql")try{let i=new URL(s),a=Sr({host:i.hostname,user:i.username,password:i.password,database:i.pathname.split("/")[1],port:Number(i.port)});t=new yt({pool:a})}catch(i){if(i instanceof TypeError)throw new I("Invalid database URL")}if(r==="sqlite"){let i=new vr(s);t=new wt({database:i})}}return t},re=e=>{let t=_r(e);return t&&new Ir({dialect:t})},kt=e=>{if("provider"in e.database)return e.database.provider;if("dialect"in e.database){if(e.database.dialect instanceof bt)return"postgres";if(e.database.dialect instanceof yt)return"mysql";if(e.database.dialect instanceof wt)return"sqlite"}return"sqlite"};function Rt(e){if(!e.database)throw new I("Database configuration is required");if("create"in e.database)return e.database;let t=re(e);if(!t)throw new I("Failed to initialize database adapter");let n=N(e),o={};for(let r of Object.values(n))o[r.tableName]=r.fields;return At(t,{transform:{schema:o,date:!0,boolean:kt(e)==="sqlite"}})}import{scrypt as Er}from"node:crypto";import{decodeHex as Cr,encodeHex as Tt}from"oslo/encoding";import{constantTimeEqual as Br}from"oslo/crypto";var F={N:16384,r:16,p:1,dkLen:64};function Ut(e,t){return u(this,null,function*(){return yield new Promise((n,o)=>{Er(e.normalize("NFKC"),t,F.dkLen,{N:F.N,p:F.p,r:F.r,maxmem:128*F.N*F.r*2},(r,s)=>r?o(r):n(s))})})}var xt=e=>u(void 0,null,function*(){let t=Tt(crypto.getRandomValues(new Uint8Array(16))),n=yield Ut(e,t);return`${t}:${Tt(n)}`}),Pt=(e,t)=>u(void 0,null,function*(){let[n,o]=e.split(":"),r=yield Ut(t,n);return Br(r,Cr(o))});import{alphabet as jr,generateRandomString as Dr}from"oslo/crypto";var vt=(e,t)=>{var i;let n=((i=t.session)==null?void 0:i.expiresIn)||604800,o=N(t),r=t.databaseHooks;function s(a,d){return u(this,null,function*(){var p,m,f,h;let l=a;if((m=(p=r==null?void 0:r[d])==null?void 0:p.create)!=null&&m.before){let w=yield r[d].create.before(a);if(w===!1)return null;l=typeof w=="object"?w.data:w}let c=yield e.create({model:d,data:a});return(h=(f=r==null?void 0:r[d])==null?void 0:f.create)!=null&&h.after&&c&&(yield r[d].create.after(c)),c})}return{createOAuthUser:(a,d)=>u(void 0,null,function*(){try{let l=yield s(a,"user"),c=yield s(d,"account");return{user:l,account:c}}catch(l){return console.log(l),null}}),createUser:a=>u(void 0,null,function*(){return yield s(a,"user")}),createSession:(a,d,l)=>u(void 0,null,function*(){let c=d instanceof Request?d.headers:d,p={id:Dr(32,jr("a-z","0-9","A-Z")),userId:a,expiresAt:l?M(1e3*60*60*24):M(n,!0),ipAddress:(c==null?void 0:c.get("x-forwarded-for"))||"",userAgent:(c==null?void 0:c.get("user-agent"))||""};return yield s(p,"session")}),findSession:a=>u(void 0,null,function*(){let d=yield e.findOne({model:o.session.tableName,where:[{value:a,field:"id"}]});if(!d)return null;let l=yield e.findOne({model:o.user.tableName,where:[{value:d.userId,field:"id"}]});return l?{session:d,user:l}:null}),updateSession:(a,d)=>u(void 0,null,function*(){var c,p,m,f;if((p=(c=r==null?void 0:r.session)==null?void 0:c.update)!=null&&p.before){let h=yield r.session.update.before(d);if(h===!1)return null;d=typeof h=="object"?h.data:h}let l=yield e.update({model:o.session.tableName,where:[{field:"id",value:a}],update:d});return(f=(m=r==null?void 0:r.session)==null?void 0:m.update)!=null&&f.after&&l&&(yield r.session.update.after(l)),l}),deleteSession:a=>u(void 0,null,function*(){return yield e.delete({model:o.session.tableName,where:[{field:"id",value:a}]})}),deleteSessions:a=>u(void 0,null,function*(){return yield e.delete({model:o.session.tableName,where:[{field:"userId",value:a}]})}),findUserByEmail:a=>u(void 0,null,function*(){let d=yield e.findOne({model:o.user.tableName,where:[{value:a.toLowerCase(),field:"email"}]});if(!d)return null;let l=yield e.findMany({model:o.account.tableName,where:[{value:d.id,field:"userId"}]});return{user:d,accounts:l}}),findUserById:a=>u(void 0,null,function*(){return yield e.findOne({model:o.user.tableName,where:[{field:"id",value:a}]})}),linkAccount:a=>u(void 0,null,function*(){return yield s(a,"account")}),updateUserByEmail:(a,d)=>u(void 0,null,function*(){var c,p,m,f;if((p=(c=r==null?void 0:r.user)==null?void 0:c.update)!=null&&p.before){let h=yield r.user.update.before(d);if(h===!1)return null;d=typeof h=="object"?h.data:h}let l=yield e.update({model:o.user.tableName,where:[{value:a,field:"email"}],update:d});return(f=(m=r==null?void 0:r.user)==null?void 0:m.update)!=null&&f.after&&l&&(yield r.user.update.after(l)),l}),updatePassword:(a,d)=>u(void 0,null,function*(){return yield e.update({model:o.account.tableName,where:[{value:a,field:"userId"},{field:"providerId",value:"credential"}],update:{password:d}})}),findAccounts:a=>u(void 0,null,function*(){return yield e.findMany({model:o.account.tableName,where:[{field:"userId",value:a}]})}),updateAccount:(a,d)=>u(void 0,null,function*(){var c,p,m,f;if((p=(c=r==null?void 0:r.account)==null?void 0:c.update)!=null&&p.before){let h=yield r.account.update.before(d);if(h===!1)return null;d=typeof h=="object"?h.data:h}let l=yield e.update({model:o.account.tableName,where:[{field:"id",value:a}],update:d});return(f=(m=r==null?void 0:r.account)==null?void 0:m.update)!=null&&f.after&&l&&(yield r.account.update.after(l)),l})}};var It="better-auth-secret-123456789";var St=e=>({id:"cross-subdomain-cookies",onResponse(n,o){return u(this,null,function*(){let r=n.headers.get("set-cookie");if(!r)return;let s=o.baseURL,i=r.split(";"),a=(e==null?void 0:e.domainName)||new URL(s).hostname,d=o.authCookies,l=[d.sessionToken.name,d.csrfToken.name,d.dontRememberToken.name];if(!l.some(p=>r.includes(p)))return;let c=i.map(p=>{if(!l.some(f=>p.toLowerCase().includes(f.toLowerCase())))return p;let m=p.trim();return m.toLowerCase().startsWith("domain=")?`Domain=${a}`:m.toLowerCase().includes("domain=")?m:`${m}; Domain=${a}`}).filter((p,m,f)=>m===f.findIndex(h=>h.split(";")[0]===p.split(";")[0])).join("; ");return n.headers.set("set-cookie",c),{response:n}})}});var Lt=e=>{var m,f,h,w,U,b,T,P,v,oe,he,ye,be,we;let{options:t,context:n}=qr(e),o=t.plugins||[],r=$r(t),s=Rt(t),i=re(t),a=Q(t.baseURL,t.basePath)||"",d=t.secret||process.env.BETTER_AUTH_SECRET||process.env.AUTH_SECRET||It,l=Ne(t),c=N(t),p=Object.keys(t.socialProviders||{}).map(V=>{var Ae;let G=(Ae=t.socialProviders)==null?void 0:Ae[V];return G.enabled===!1?null:((!G.clientId||!G.clientSecret)&&O.warn(`Social provider ${V} is missing clientId or clientSecret`),ie[V](G))}).filter(V=>V!==null);return g({appName:t.appName||"Better Auth",socialProviders:p,options:k(g({},t),{baseURL:a?new URL(a).origin:"",basePath:t.basePath||"/api/auth",plugins:o.concat(r)}),tables:c,baseURL:a,sessionConfig:{updateAge:((m=t.session)==null?void 0:m.updateAge)||24*60*60,expiresIn:((f=t.session)==null?void 0:f.expiresIn)||60*60*24*7},secret:d,rateLimit:k(g({},t.rateLimit),{enabled:(w=(h=t.rateLimit)==null?void 0:h.enabled)!=null?w:process.env.NODE_ENV!=="development",window:((U=t.rateLimit)==null?void 0:U.window)||60,max:((b=t.rateLimit)==null?void 0:b.max)||100,storage:((T=t.rateLimit)==null?void 0:T.storage)||"memory"}),authCookies:l,logger:se({disabled:((P=t.logger)==null?void 0:P.disabled)||!1}),db:i,password:{hash:((oe=(v=t.emailAndPassword)==null?void 0:v.password)==null?void 0:oe.hash)||xt,verify:((ye=(he=t.emailAndPassword)==null?void 0:he.password)==null?void 0:ye.verify)||Pt,config:{minPasswordLength:((be=t.emailAndPassword)==null?void 0:be.minPasswordLength)||8,maxPasswordLength:((we=t.emailAndPassword)==null?void 0:we.maxPasswordLength)||128}},adapter:s,internalAdapter:vt(s,t),createAuthCookie:Fe(t)},n)};function qr(e){let t=e.plugins||[],n={};for(let i of t)if(i.init){let a=i.init(e);typeof a=="object"&&(a.options&&(e=g(g({},e),a.options)),n=g({},a))}let s=n,{options:o}=s,r=W(s,["options"]);return{options:e,context:r}}function $r(e){var n,o;let t=[];return(o=(n=e.advanced)==null?void 0:n.crossSubDomainCookies)!=null&&o.enabled&&t.push(St({eligibleCookies:e.advanced.crossSubDomainCookies.eligibleCookies})),t}var Td=e=>{let t=Lt(e),{api:n}=ge(t,e);return{handler:o=>u(void 0,null,function*(){let r=t.options.basePath,s=new URL(o.url);if(!t.options.baseURL){let a=`${s.origin}/api/auth`;t.options.baseURL=a,t.baseURL=a}if(!t.options.baseURL)return new Response("Base URL not set",{status:400});if(s.pathname===r||s.pathname===`${r}/`)return new Response("Welcome to BetterAuth",{status:200});let{handler:i}=gt(t,e);return i(o)}),api:n,options:t.options,$Infer:{}}};export{Td as betterAuth};
82
+ </html>`,He=g("/error",{method:"GET",metadata:L},async e=>{let t=new URL(e.request?.url||"").searchParams.get("error")||"Unknown";return new Response(Yt(t),{headers:{"Content-Type":"text/html"}})});var Ge=g("/ok",{method:"GET",metadata:L},async e=>e.json({ok:!0}));import{alphabet as Ke,generateRandomString as We}from"oslo/crypto";import{z as O}from"zod";var Je=g("/sign-up/email",{method:"POST",query:O.object({currentURL:O.string().optional()}).optional(),body:O.object({name:O.string(),email:O.string(),password:O.string(),image:O.string().optional(),callbackURL:O.string().optional()})},async e=>{if(!e.context.options.emailAndPassword?.enabled)return e.json(null,{status:400,body:{message:"Email and password is not enabled"}});let{name:t,email:o,password:r,image:n}=e.body;if(!O.string().email().safeParse(o).success)return e.json(null,{status:400,body:{message:"Invalid email address"}});let i=e.context.password.config.minPasswordLength;if(r.length<i)return e.context.logger.error("Password is too short"),e.json(null,{status:400,body:{message:"Password is too short"}});let a=e.context.password.config.maxPasswordLength;if(r.length>a)return e.context.logger.error("Password is too long"),e.json(null,{status:400,body:{message:"Password is too long"}});let d=await e.context.internalAdapter.findUserByEmail(o),c=await e.context.password.hash(r);if(d?.user)return e.json(null,{status:400,body:{message:"User already exists"}});let l=await e.context.internalAdapter.createUser({id:We(32,Ke("a-z","0-9","A-Z")),email:o.toLowerCase(),name:t,image:n,emailVerified:!1,createdAt:new Date,updatedAt:new Date});if(!l)return e.json(null,{status:400,body:{message:"Could not create user"}});await e.context.internalAdapter.linkAccount({id:We(32,Ke("a-z","0-9","A-Z")),userId:l.id,providerId:"credential",accountId:l.id,password:c});let u=await e.context.internalAdapter.createSession(l.id,e.request);if(!u)return e.json(null,{status:400,body:{message:"Could not create session"}});if(await P(e,u.id),e.context.options.emailAndPassword.sendEmailVerificationOnSignUp){let p=await ne(e.context.secret,l.email),m=`${e.context.baseURL}/verify-email?token=${p}&callbackURL=${e.body.callbackURL||e.query?.currentURL||"/"}`;await e.context.options.emailAndPassword.sendVerificationEmail?.(l.email,m,p)}return e.json({user:l,session:u},{body:e.body.callbackURL?{url:e.body.callbackURL,redirect:!0}:{user:l,session:u}})});import se from"chalk";function er(e,t,o){let r=Date.now(),n=t*1e3;return r-o.lastRequest<n&&o.count>=e}function tr(e){return new Response(JSON.stringify({message:"Too many requests. Please try again later."}),{status:429,statusText:"Too Many Requests",headers:{"X-Retry-After":e.toString()}})}function rr(e,t){let o=Date.now(),r=t*1e3;return Math.ceil((e+r-o)/1e3)}function or(e,t){let o=t??"rateLimit",r=e.adapter;return{get:async n=>await r.findOne({model:o,where:[{field:"key",value:n}]}),set:async(n,s,i)=>{try{i?await r.update({model:t??"rateLimit",where:[{field:"key",value:n}],update:{count:s.count,lastRequest:s.lastRequest}}):await r.create({model:t??"rateLimit",data:{key:n,count:s.count,lastRequest:s.lastRequest}})}catch(a){T.error("Error setting rate limit",a)}}}}var Ze=new Map;function nr(e){return e.rateLimit.customStorage?e.rateLimit.customStorage:e.rateLimit.storage==="memory"?{async get(o){return Ze.get(o)},async set(o,r,n){Ze.set(o,r)}}:or(e,e.rateLimit.tableName)}async function Qe(e,t){if(!t.rateLimit.enabled)return;let o=t.baseURL,r=e.url.replace(o,""),n=t.rateLimit.window,s=t.rateLimit.max,i=V(e)+r,d=sr().find(p=>p.pathMatcher(r));d&&(n=d.window,s=d.max);for(let p of t.options.plugins||[])if(p.rateLimit){let m=p.rateLimit.find(f=>f.pathMatcher(r));if(m){n=m.window,s=m.max;break}}if(t.rateLimit.customRules){let p=t.rateLimit.customRules[r];p&&(n=p.window,s=p.max)}let c=nr(t),l=await c.get(i),u=Date.now();if(!l)await c.set(i,{key:i,count:1,lastRequest:u});else{let p=u-l.lastRequest;if(er(s,n,l)){let m=rr(l.lastRequest,n);return tr(m)}else p>n*1e3?await c.set(i,{...l,count:1,lastRequest:u}):await c.set(i,{...l,count:l.count+1,lastRequest:u})}}function sr(){return[{pathMatcher(t){return t.startsWith("/sign-in")||t.startsWith("/sign-up")},window:10,max:7}]}function ie(e,t){let o=t.plugins?.reduce((a,d)=>({...a,...d.endpoints}),{}),r=t.plugins?.map(a=>a.middlewares?.map(d=>{let c=async l=>d.middleware({...l,context:{...e,...l.context}});return c.path=d.path,c.options=d.middleware.options,c.headers=d.middleware.headers,{path:d.path,middleware:c}})).filter(a=>a!==void 0).flat()||[],s={...{signInOAuth:Se,callbackOAuth:Ee,getCSRFToken:Ve,getSession:ee(),signOut:_e,signUpEmail:Je,signInEmail:Oe,forgetPassword:qe,resetPassword:De,verifyEmail:$e,sendVerificationEmail:Ne,changePassword:Me,setPassword:ze,updateUser:Fe,forgetPasswordCallback:je,listSessions:Pe(),revokeSession:ve,revokeSessions:Ie},...o,ok:Ge,error:He},i={};for(let[a,d]of Object.entries(s))i[a]=async c=>{let l=await e,p=await d({...c,context:{...l,...c.context}});for(let m of t.plugins||[])if(m.hooks?.after){for(let f of m.hooks.after)if(f.matcher(c)){let h=Object.assign(c,{context:{...e,returned:p}}),A=await f.handler(h);A&&"response"in A&&(p=A.response)}}return p},i[a].path=d.path,i[a].method=d.method,i[a].options=d.options,i[a].headers=d.headers;return{api:i,middlewares:r}}var Xe=(e,t)=>{let{api:o,middlewares:r}=ie(e,t),n=new URL(e.baseURL).pathname;return ar(o,{extraContext:e,basePath:n,routerMiddleware:[{path:"/**",middleware:ue},...r],async onRequest(s){for(let i of e.options.plugins||[])if(i.onRequest){let a=await i.onRequest(s,e);if(a)return a}return Qe(s,e)},async onResponse(s){for(let i of e.options.plugins||[])if(i.onResponse){let a=await i.onResponse(s,e);if(a)return a.response}return s},onError(s){let i=t.logger?.verboseLogging?T:void 0;if(t.logger?.disabled!==!0)if(s instanceof ir)i?.warn(s);else if(typeof s=="object"&&s!==null&&"message"in s){let a=s.message;if(!a||typeof a!="string"){i?.error(s);return}a.includes("no such table")?T?.error(`Please run ${se.green("npx better-auth migrate")} to create the tables. There are missing tables in your SQLite database.`):a.includes("relation")&&a.includes("does not exist")?T.error(`Please run ${se.green("npx better-auth migrate")} to create the tables. There are missing tables in your PostgreSQL database.`):a.includes("Table")&&a.includes("doesn't exist")?T?.error(`Please run ${se.green("npx better-auth migrate")} to create the tables. There are missing tables in your MySQL database.`):i?.error(s)}else i?.error(s)}})};var C=e=>{let t=e.plugins?.reduce((d,c)=>{let l=c.schema;if(!l)return d;for(let[u,p]of Object.entries(l))d[u]={fields:{...d[u]?.fields,...p.fields},tableName:u};return d},{}),o=e.rateLimit?.storage==="database",r={rateLimit:{tableName:e.rateLimit?.tableName||"rateLimit",fields:{key:{type:"string"},count:{type:"number"},lastRequest:{type:"number"}}}},{user:n,session:s,account:i,...a}=t||{};return{user:{tableName:e.user?.modelName||"user",fields:{name:{type:"string",required:!0},email:{type:"string",unique:!0,required:!0},emailVerified:{type:"boolean",defaultValue:()=>!1,required:!0},image:{type:"string",required:!1},createdAt:{type:"date",defaultValue:()=>new Date,required:!0},updatedAt:{type:"date",defaultValue:()=>new Date,required:!0},...n?.fields},order:0},session:{tableName:e.session?.modelName||"session",fields:{expiresAt:{type:"date",required:!0},ipAddress:{type:"string",required:!1},userAgent:{type:"string",required:!1},userId:{type:"string",references:{model:"user",field:"id",onDelete:"cascade"},required:!0},...s?.fields},order:1},account:{tableName:e.account?.modelName||"account",fields:{accountId:{type:"string",required:!0},providerId:{type:"string",required:!0},userId:{type:"string",references:{model:"user",field:"id",onDelete:"cascade"},required:!0},accessToken:{type:"string",required:!1},refreshToken:{type:"string",required:!1},idToken:{type:"string",required:!1},expiresAt:{type:"date",required:!1},password:{type:"string",required:!1},...i?.fields},order:2},...a,...o?r:{}}};import{Kysely as dr}from"kysely";import{MysqlDialect as Ye,PostgresDialect as et,SqliteDialect as tt}from"kysely";var cr=async e=>{if(!e.database)return;if("createDriver"in e.database)return e.database;let t;if("provider"in e.database){let o=e.database.provider,r=e.database?.url?.trim();if(o==="postgres"){let s=(await import("pg").catch(i=>{throw new k("Please install `pg` to use postgres database")})).Pool;t=new et({pool:new s({connectionString:r})})}if(o==="mysql")try{let{createPool:n}=await import("mysql2/promise").catch(a=>{throw new k("Please install `mysql2` to use mysql database")}),s=new URL(r),i=n({host:s.hostname,user:s.username,password:s.password,database:s.pathname.split("/")[1],port:Number(s.port)});t=new Ye({pool:i})}catch(n){throw n instanceof TypeError?new k("Invalid database URL"):n}if(o==="sqlite")try{let n=await import("better-sqlite3"),s=n.default||n;if(!s)throw new k("Failed to import better-sqlite3. Make sure `better-sqlite3` is properly installed.");let i=new s(r);t=new tt({database:i})}catch(n){throw console.error(n),new k("Failed to initialize SQLite. Make sure `better-sqlite3` is properly installed.")}}return t},q=async e=>{let t=await cr(e);return t&&new dr({dialect:t})},G=e=>{if("provider"in e.database)return e.database.provider;if("dialect"in e.database){if(e.database.dialect instanceof et)return"postgres";if(e.database.dialect instanceof Ye)return"mysql";if(e.database.dialect instanceof tt)return"sqlite"}return"sqlite"};import"kysely";function lr(e){return e.plugins?.flatMap(o=>Object.keys(o.schema||{}).map(r=>{let s=(o.schema||{})[r];if(!s?.disableMigration)return{tableName:r,fields:s?.fields}}).filter(r=>r!==void 0))||[]}function rt(e){let t=C(e),o=lr(e);return[t.user,t.session,t.account,...o].reduce((n,s)=>(n[s.tableName]={fields:{...n[s.tableName]?.fields,...s.fields}},n),{})}var ur={string:["character varying","text"],number:["int4","integer","bigint","smallint","numeric","real","double precision"],boolean:["bool","boolean"],date:["timestamp","date"]},pr={string:["varchar","text"],number:["integer","int","bigint","smallint","decimal","float","double"],boolean:["boolean"],date:["date","datetime"]},mr={string:["TEXT"],number:["INTEGER","REAL"],boolean:["INTEGER","BOOLEAN"],date:["DATE","INTEGER"]},fr={postgres:ur,mysql:pr,sqlite:mr};function gr(e,t,o){return fr[o][t].map(i=>i.toLowerCase()).includes(e.toLowerCase())}async function ot(e){let t=rt(e),o=G(e),r=await q(e);r||(T.error("Invalid database configuration."),process.exit(1));let n=await r.introspection.getTables(),s=[],i=[];for(let[u,p]of Object.entries(t)){let m=n.find(y=>y.name===u);if(!m){let y=s.findIndex(B=>B.table===u),h={table:u,fields:p.fields,order:p.order||1/0},A=s.findIndex(B=>(B.order||1/0)>h.order);A===-1?y===-1?s.push(h):s[y].fields={...s[y].fields,...p.fields}:s.splice(A,0,h);continue}let f={};for(let[y,h]of Object.entries(p.fields)){let A=m.columns.find(B=>B.name===y);if(!A){f[y]=h;continue}gr(A.dataType,h.type,o)||T.warn(`Field ${y} in table ${u} has a different type in the database. Expected ${h.type} but got ${A.dataType}.`)}Object.keys(f).length>0&&i.push({table:u,fields:f,order:p.order||1/0})}let a=[];function d(u){let p={string:"text",boolean:"boolean",number:"integer",date:"date"};return o==="mysql"&&u==="string"?"varchar(255)":p[u]}if(i.length)for(let u of i)for(let[p,m]of Object.entries(u.fields)){let f=d(m.type),y=r.schema.alterTable(u.table).addColumn(p,f,h=>(h=m.required!==!1?h.notNull():h,m.references&&(h=h.references(`${m.references.model}.${m.references.field}`)),h));a.push(y)}if(s.length)for(let u of s){let p=r.schema.createTable(u.table).addColumn("id",d("string"),m=>m.primaryKey());for(let[m,f]of Object.entries(u.fields)){let y=d(f.type);p=p.addColumn(m,y,h=>(h=f.required!==!1?h.notNull():h,f.references&&(h=h.references(`${f.references.model}.${f.references.field}`)),f.unique&&(h=h.unique()),h))}a.push(p)}async function c(){for(let u of a)await u.execute()}async function l(){return a.map(p=>p.compile().sql).join(`;
83
+
84
+ `)}return{toBeCreated:s,toBeAdded:i,runMigrations:c,compileMigrations:l}}function K(e){if(!e)return{and:null,or:null};let t=e?.filter(r=>r.connector==="AND"||!r.connector).reduce((r,n)=>({...r,[n.field]:n.value}),{}),o=e?.filter(r=>r.connector==="OR").reduce((r,n)=>({...r,[n.field]:n.value}),{});return{and:Object.keys(t).length?t:null,or:Object.keys(o).length?o:null}}function W(e,t,o){for(let r in e)e[r]===0&&t[r]?.type==="boolean"&&o?.boolean&&(e[r]=!1),e[r]===1&&t[r]?.type==="boolean"&&o?.boolean&&(e[r]=!0),t[r]?.type==="date"&&(e[r]instanceof Date||(e[r]=new Date(e[r])));return e}function nt(e,t){for(let o in e)typeof e[o]=="boolean"&&t?.boolean&&(e[o]=e[o]?1:0),e[o]instanceof Date&&(e[o]=e[o].toISOString());return e}var st=(e,t)=>({id:"kysely",async create(o){let{model:r,data:n,select:s}=o;t?.transform&&(n=nt(n,t.transform));let i=await e.insertInto(r).values(n).returningAll().executeTakeFirst();if(t?.transform){let a=t.transform.schema[r];i=a?W(n,a,t.transform):i}return s?.length&&(i=i?s.reduce((d,c)=>i?.[c]?{...d,[c]:i[c]}:d,{}):null),i},async findOne(o){let{model:r,where:n,select:s}=o,{and:i,or:a}=K(n),d=e.selectFrom(r).selectAll();a&&(d=d.where(l=>l.or(a))),i&&(d=d.where(l=>l.and(i)));let c=await d.executeTakeFirst();if(s?.length&&(c=c?s.reduce((u,p)=>c?.[p]?{...u,[p]:c[p]}:u,{}):null),t?.transform){let l=t.transform.schema[r];return c=c&&l?W(c,l,t.transform):c,c||null}return c||null},async findMany(o){let{model:r,where:n}=o,s=e.selectFrom(r),{and:i,or:a}=K(n);i&&(s=s.where(c=>c.and(i))),a&&(s=s.where(c=>c.or(a)));let d=await s.selectAll().execute();if(t?.transform){let c=t.transform.schema[r];return c?d.map(l=>W(l,c,t.transform)):d}return d},async update(o){let{model:r,where:n,update:s}=o,{and:i,or:a}=K(n);t?.transform&&(s=nt(s,t.transform));let d=e.updateTable(r).set(s);i&&(d=d.where(l=>l.and(i))),a&&(d=d.where(l=>l.or(a)));let c=await d.returningAll().executeTakeFirst()||null;if(t?.transform){let l=t.transform.schema[r];return l?W(c,l,t.transform):c}return c},async delete(o){let{model:r,where:n}=o,{and:s,or:i}=K(n),a=e.deleteFrom(r);s&&(a=a.where(d=>d.and(s))),i&&(a=a.where(d=>d.or(i))),await a.execute()},async createSchema(o){let{compileMigrations:r}=await ot(o);return console.log(r),{code:await r(),fileName:`./better-auth_migrations/${new Date().toISOString()}.sql`}}});async function it(e){if(!e.database)throw new k("Database configuration is required");if("create"in e.database)return e.database;let t=await q(e);if(!t)throw new k("Failed to initialize database adapter");let o=C(e),r={};for(let n of Object.values(o))r[n.tableName]=n.fields;return st(t,{transform:{schema:r,date:!0,boolean:G(e)==="sqlite"}})}import{scrypt as hr}from"node:crypto";import{decodeHex as yr,encodeHex as at}from"oslo/encoding";import{constantTimeEqual as br}from"oslo/crypto";var j={N:16384,r:16,p:1,dkLen:64};async function dt(e,t){return await new Promise((o,r)=>{hr(e.normalize("NFKC"),t,j.dkLen,{N:j.N,p:j.p,r:j.r,maxmem:128*j.N*j.r*2},(n,s)=>n?r(n):o(s))})}var ct=async e=>{let t=at(crypto.getRandomValues(new Uint8Array(16))),o=await dt(e,t);return`${t}:${at(o)}`},lt=async(e,t)=>{let[o,r]=e.split(":"),n=await dt(t,o);return br(n,yr(r))};import{alphabet as wr,generateRandomString as Ar}from"oslo/crypto";var ut=(e,t)=>{let o=t.session?.expiresIn||604800,r=C(t),n=t.databaseHooks;async function s(i,a){let d=i;if(n?.[a]?.create?.before){let l=await n[a].create.before(i);if(l===!1)return null;d=typeof l=="object"?l.data:l}let c=await e.create({model:a,data:i});return n?.[a]?.create?.after&&c&&await n[a].create.after(c),c}return{createOAuthUser:async(i,a)=>{try{let d=await s(i,"user"),c=await s(a,"account");return{user:d,account:c}}catch(d){return console.log(d),null}},createUser:async i=>await s(i,"user"),createSession:async(i,a,d)=>{let c=a instanceof Request?a.headers:a,l={id:Ar(32,wr("a-z","0-9","A-Z")),userId:i,expiresAt:d?N(1e3*60*60*24):N(o,!0),ipAddress:c?.get("x-forwarded-for")||"",userAgent:c?.get("user-agent")||""};return await s(l,"session")},findSession:async i=>{let a=await e.findOne({model:r.session.tableName,where:[{value:i,field:"id"}]});if(!a)return null;let d=await e.findOne({model:r.user.tableName,where:[{value:a.userId,field:"id"}]});return d?{session:a,user:d}:null},updateSession:async(i,a)=>{if(n?.session?.update?.before){let c=await n.session.update.before(a);if(c===!1)return null;a=typeof c=="object"?c.data:c}let d=await e.update({model:r.session.tableName,where:[{field:"id",value:i}],update:a});return n?.session?.update?.after&&d&&await n.session.update.after(d),d},deleteSession:async i=>await e.delete({model:r.session.tableName,where:[{field:"id",value:i}]}),deleteSessions:async i=>await e.delete({model:r.session.tableName,where:[{field:"userId",value:i}]}),findUserByEmail:async i=>{let a=await e.findOne({model:r.user.tableName,where:[{value:i.toLowerCase(),field:"email"}]});if(!a)return null;let d=await e.findMany({model:r.account.tableName,where:[{value:a.id,field:"userId"}]});return{user:a,accounts:d}},findUserById:async i=>await e.findOne({model:r.user.tableName,where:[{field:"id",value:i}]}),linkAccount:async i=>await s(i,"account"),updateUserByEmail:async(i,a)=>{if(n?.user?.update?.before){let c=await n.user.update.before(a);if(c===!1)return null;a=typeof c=="object"?c.data:c}let d=await e.update({model:r.user.tableName,where:[{value:i,field:"email"}],update:a});return n?.user?.update?.after&&d&&await n.user.update.after(d),d},updatePassword:async(i,a)=>await e.update({model:r.account.tableName,where:[{value:i,field:"userId"},{field:"providerId",value:"credential"}],update:{password:a}}),findAccounts:async i=>await e.findMany({model:r.account.tableName,where:[{field:"userId",value:i}]}),updateAccount:async(i,a)=>{if(n?.account?.update?.before){let c=await n.account.update.before(a);if(c===!1)return null;a=typeof c=="object"?c.data:c}let d=await e.update({model:r.account.tableName,where:[{field:"id",value:i}],update:a});return n?.account?.update?.after&&d&&await n.account.update.after(d),d}}};var pt="better-auth-secret-123456789";var mt=e=>({id:"cross-subdomain-cookies",async onResponse(t,o){let r=t.headers.get("set-cookie");if(!r)return;let n=o.baseURL,s=r.split(";"),i=e?.domainName||new URL(n).hostname,a=o.authCookies,d=[a.sessionToken.name,a.csrfToken.name,a.dontRememberToken.name];if(!d.some(l=>r.includes(l)))return;let c=s.map(l=>{if(!d.some(p=>l.toLowerCase().includes(p.toLowerCase())))return l;let u=l.trim();return u.toLowerCase().startsWith("domain=")?`Domain=${i}`:u.toLowerCase().includes("domain=")?u:`${u}; Domain=${i}`}).filter((l,u,p)=>u===p.findIndex(m=>m.split(";")[0]===l.split(";")[0])).join("; ");return t.headers.set("set-cookie",c),{response:t}}});var ft=async e=>{let{options:t,context:o}=kr(e),r=t.plugins||[],n=Rr(t),s=await it(t),i=await q(t),a=z(t.baseURL,t.basePath)||"",d=t.secret||process.env.BETTER_AUTH_SECRET||process.env.AUTH_SECRET||pt,c=Te(t),l=C(t),u=Object.keys(t.socialProviders||{}).map(p=>{let m=t.socialProviders?.[p];return m.enabled===!1?null:((!m.clientId||!m.clientSecret)&&T.warn(`Social provider ${p} is missing clientId or clientSecret`),Q[p](m))}).filter(p=>p!==null);return{appName:t.appName||"Better Auth",socialProviders:u,options:{...t,baseURL:a?new URL(a).origin:"",basePath:t.basePath||"/api/auth",plugins:r.concat(n)},tables:l,baseURL:a,sessionConfig:{updateAge:t.session?.updateAge||24*60*60,expiresIn:t.session?.expiresIn||60*60*24*7},secret:d,rateLimit:{...t.rateLimit,enabled:t.rateLimit?.enabled??process.env.NODE_ENV!=="development",window:t.rateLimit?.window||60,max:t.rateLimit?.max||100,storage:t.rateLimit?.storage||"memory"},authCookies:c,logger:Z({disabled:t.logger?.disabled||!1}),db:i,password:{hash:t.emailAndPassword?.password?.hash||ct,verify:t.emailAndPassword?.password?.verify||lt,config:{minPasswordLength:t.emailAndPassword?.minPasswordLength||8,maxPasswordLength:t.emailAndPassword?.maxPasswordLength||128}},adapter:s,internalAdapter:ut(s,t),createAuthCookie:xe(t),...o}};function kr(e){let t=e.plugins||[],o={};for(let s of t)if(s.init){let i=s.init(e);typeof i=="object"&&(i.options&&(e={...e,...i.options}),o={...i})}let{options:r,...n}=o;return{options:e,context:n}}function Rr(e){let t=[];return e.advanced?.crossSubDomainCookies?.enabled&&t.push(mt({eligibleCookies:e.advanced.crossSubDomainCookies.eligibleCookies})),t}var La=e=>{let t=ft(e),{api:o}=ie(t,e);return{handler:async r=>{let n=await t,s=n.options.basePath,i=new URL(r.url);if(!n.options.baseURL){let d=`${i.origin}/api/auth`;n.options.baseURL=d,n.baseURL=d}if(!n.options.baseURL)return new Response("Base URL not set",{status:400});if(i.pathname===s||i.pathname===`${s}/`)return new Response("Welcome to BetterAuth",{status:200});let{handler:a}=Xe(n,e);return a(r)},api:o,options:e,$Infer:{}}};export{La as betterAuth};