better-auth 0.5.3-beta.1 → 0.5.3-beta.2

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,4 +1,4 @@
1
- import { A as Adapter } from '../auth-DhjJVba-.js';
1
+ import { A as Adapter } from '../auth-DFDxqxWC.js';
2
2
  import 'zod';
3
3
  import 'kysely';
4
4
  import '../schema-Dkt0LqYs.js';
@@ -1,5 +1,5 @@
1
1
  import { Kysely } from 'kysely';
2
- import { B as BetterAuthOptions, K as KyselyDatabaseType, F as FieldAttribute, A as Adapter } from '../auth-DhjJVba-.js';
2
+ import { B as BetterAuthOptions, K as KyselyDatabaseType, F as FieldAttribute, A as Adapter } from '../auth-DFDxqxWC.js';
3
3
  import 'zod';
4
4
  import '../schema-Dkt0LqYs.js';
5
5
  import 'better-call';
@@ -1,5 +1,5 @@
1
1
  import { Db } from 'mongodb';
2
- import { W as Where } from '../auth-DhjJVba-.js';
2
+ import { W as Where } from '../auth-DFDxqxWC.js';
3
3
  import 'zod';
4
4
  import 'kysely';
5
5
  import '../schema-Dkt0LqYs.js';
@@ -1,4 +1,4 @@
1
- import { A as Adapter } from '../auth-DhjJVba-.js';
1
+ import { A as Adapter } from '../auth-DFDxqxWC.js';
2
2
  import 'zod';
3
3
  import 'kysely';
4
4
  import '../schema-Dkt0LqYs.js';
package/dist/api.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { e as AuthEndpoint, f as AuthMiddleware, a1 as callbackOAuth, aj as changeEmail, ag as changePassword, d as createAuthEndpoint, c as createAuthMiddleware, ac as createEmailVerificationToken, ao as csrfMiddleware, ai as deleteUser, al as error, a9 as forgetPassword, aa as forgetPasswordCallback, ak as getCSRFToken, Z as getEndpoints, a2 as getSession, a3 as getSessionFromCtx, a5 as listSessions, am as ok, o as optionsMiddleware, ab as resetPassword, a6 as revokeSession, a7 as revokeSessions, _ as router, ad as sendVerificationEmail, a4 as sessionMiddleware, ah as setPassword, a0 as signInEmail, $ as signInOAuth, a8 as signOut, an as signUpEmail, af as updateUser, ae as verifyEmail } from './auth-DhjJVba-.js';
1
+ export { e as AuthEndpoint, f as AuthMiddleware, a1 as callbackOAuth, aj as changeEmail, ag as changePassword, d as createAuthEndpoint, c as createAuthMiddleware, ac as createEmailVerificationToken, ao as csrfMiddleware, ai as deleteUser, al as error, a9 as forgetPassword, aa as forgetPasswordCallback, ak as getCSRFToken, Z as getEndpoints, a2 as getSession, a3 as getSessionFromCtx, a5 as listSessions, am as ok, o as optionsMiddleware, ab as resetPassword, a6 as revokeSession, a7 as revokeSessions, _ as router, ad as sendVerificationEmail, a4 as sessionMiddleware, ah as setPassword, a0 as signInEmail, $ as signInOAuth, a8 as signOut, an as signUpEmail, af as updateUser, ae as verifyEmail } from './auth-DFDxqxWC.js';
2
2
  import './helper-DPDj8Nix.js';
3
3
  export { APIError } from 'better-call';
4
4
  import 'zod';
@@ -1251,12 +1251,12 @@ declare const signInOAuth: {
1251
1251
  /**
1252
1252
  * OAuth2 provider to use`
1253
1253
  */
1254
- provider: z.ZodEnum<["github", ...("github" | "apple" | "discord" | "facebook" | "microsoft" | "google" | "spotify" | "twitch" | "twitter")[]]>;
1254
+ provider: z.ZodEnum<["github", ...("apple" | "discord" | "facebook" | "github" | "google" | "microsoft" | "spotify" | "twitch" | "twitter")[]]>;
1255
1255
  }, "strip", z.ZodTypeAny, {
1256
- provider: "github" | "apple" | "discord" | "facebook" | "microsoft" | "google" | "spotify" | "twitch" | "twitter";
1256
+ provider: "apple" | "discord" | "facebook" | "github" | "google" | "microsoft" | "spotify" | "twitch" | "twitter";
1257
1257
  callbackURL?: string | undefined;
1258
1258
  }, {
1259
- provider: "github" | "apple" | "discord" | "facebook" | "microsoft" | "google" | "spotify" | "twitch" | "twitter";
1259
+ provider: "apple" | "discord" | "facebook" | "github" | "google" | "microsoft" | "spotify" | "twitch" | "twitter";
1260
1260
  callbackURL?: string | undefined;
1261
1261
  }>;
1262
1262
  use: better_call.Endpoint<better_call.Handler<string, better_call.EndpointOptions, void>, better_call.EndpointOptions>[];
@@ -1294,12 +1294,12 @@ declare const signInOAuth: {
1294
1294
  /**
1295
1295
  * OAuth2 provider to use`
1296
1296
  */
1297
- provider: z.ZodEnum<["github", ...("github" | "apple" | "discord" | "facebook" | "microsoft" | "google" | "spotify" | "twitch" | "twitter")[]]>;
1297
+ provider: z.ZodEnum<["github", ...("apple" | "discord" | "facebook" | "github" | "google" | "microsoft" | "spotify" | "twitch" | "twitter")[]]>;
1298
1298
  }, "strip", z.ZodTypeAny, {
1299
- provider: "github" | "apple" | "discord" | "facebook" | "microsoft" | "google" | "spotify" | "twitch" | "twitter";
1299
+ provider: "apple" | "discord" | "facebook" | "github" | "google" | "microsoft" | "spotify" | "twitch" | "twitter";
1300
1300
  callbackURL?: string | undefined;
1301
1301
  }, {
1302
- provider: "github" | "apple" | "discord" | "facebook" | "microsoft" | "google" | "spotify" | "twitch" | "twitter";
1302
+ provider: "apple" | "discord" | "facebook" | "github" | "google" | "microsoft" | "spotify" | "twitch" | "twitter";
1303
1303
  callbackURL?: string | undefined;
1304
1304
  }>;
1305
1305
  use: better_call.Endpoint<better_call.Handler<string, better_call.EndpointOptions, void>, better_call.EndpointOptions>[];
@@ -2651,12 +2651,12 @@ declare function getEndpoints<C extends AuthContext, Option extends BetterAuthOp
2651
2651
  }>>;
2652
2652
  body: zod.ZodObject<{
2653
2653
  callbackURL: zod.ZodOptional<zod.ZodString>;
2654
- provider: zod.ZodEnum<["github", ...("github" | "apple" | "discord" | "facebook" | "microsoft" | "google" | "spotify" | "twitch" | "twitter")[]]>;
2654
+ provider: zod.ZodEnum<["github", ...("apple" | "discord" | "facebook" | "github" | "google" | "microsoft" | "spotify" | "twitch" | "twitter")[]]>;
2655
2655
  }, "strip", zod.ZodTypeAny, {
2656
- provider: "github" | "apple" | "discord" | "facebook" | "microsoft" | "google" | "spotify" | "twitch" | "twitter";
2656
+ provider: "apple" | "discord" | "facebook" | "github" | "google" | "microsoft" | "spotify" | "twitch" | "twitter";
2657
2657
  callbackURL?: string | undefined;
2658
2658
  }, {
2659
- provider: "github" | "apple" | "discord" | "facebook" | "microsoft" | "google" | "spotify" | "twitch" | "twitter";
2659
+ provider: "apple" | "discord" | "facebook" | "github" | "google" | "microsoft" | "spotify" | "twitch" | "twitter";
2660
2660
  callbackURL?: string | undefined;
2661
2661
  }>;
2662
2662
  use: Endpoint<better_call.Handler<string, better_call.EndpointOptions, void>, better_call.EndpointOptions>[];
@@ -2684,12 +2684,12 @@ declare function getEndpoints<C extends AuthContext, Option extends BetterAuthOp
2684
2684
  }>>;
2685
2685
  body: zod.ZodObject<{
2686
2686
  callbackURL: zod.ZodOptional<zod.ZodString>;
2687
- provider: zod.ZodEnum<["github", ...("github" | "apple" | "discord" | "facebook" | "microsoft" | "google" | "spotify" | "twitch" | "twitter")[]]>;
2687
+ provider: zod.ZodEnum<["github", ...("apple" | "discord" | "facebook" | "github" | "google" | "microsoft" | "spotify" | "twitch" | "twitter")[]]>;
2688
2688
  }, "strip", zod.ZodTypeAny, {
2689
- provider: "github" | "apple" | "discord" | "facebook" | "microsoft" | "google" | "spotify" | "twitch" | "twitter";
2689
+ provider: "apple" | "discord" | "facebook" | "github" | "google" | "microsoft" | "spotify" | "twitch" | "twitter";
2690
2690
  callbackURL?: string | undefined;
2691
2691
  }, {
2692
- provider: "github" | "apple" | "discord" | "facebook" | "microsoft" | "google" | "spotify" | "twitch" | "twitter";
2692
+ provider: "apple" | "discord" | "facebook" | "github" | "google" | "microsoft" | "spotify" | "twitch" | "twitter";
2693
2693
  callbackURL?: string | undefined;
2694
2694
  }>;
2695
2695
  use: Endpoint<better_call.Handler<string, better_call.EndpointOptions, void>, better_call.EndpointOptions>[];
@@ -3903,12 +3903,12 @@ declare const router: <C extends AuthContext, Option extends BetterAuthOptions>(
3903
3903
  }>>;
3904
3904
  body: zod.ZodObject<{
3905
3905
  callbackURL: zod.ZodOptional<zod.ZodString>;
3906
- provider: zod.ZodEnum<["github", ...("github" | "apple" | "discord" | "facebook" | "microsoft" | "google" | "spotify" | "twitch" | "twitter")[]]>;
3906
+ provider: zod.ZodEnum<["github", ...("apple" | "discord" | "facebook" | "github" | "google" | "microsoft" | "spotify" | "twitch" | "twitter")[]]>;
3907
3907
  }, "strip", zod.ZodTypeAny, {
3908
- provider: "github" | "apple" | "discord" | "facebook" | "microsoft" | "google" | "spotify" | "twitch" | "twitter";
3908
+ provider: "apple" | "discord" | "facebook" | "github" | "google" | "microsoft" | "spotify" | "twitch" | "twitter";
3909
3909
  callbackURL?: string | undefined;
3910
3910
  }, {
3911
- provider: "github" | "apple" | "discord" | "facebook" | "microsoft" | "google" | "spotify" | "twitch" | "twitter";
3911
+ provider: "apple" | "discord" | "facebook" | "github" | "google" | "microsoft" | "spotify" | "twitch" | "twitter";
3912
3912
  callbackURL?: string | undefined;
3913
3913
  }>;
3914
3914
  use: Endpoint<better_call.Handler<string, better_call.EndpointOptions, void>, better_call.EndpointOptions>[];
@@ -3936,12 +3936,12 @@ declare const router: <C extends AuthContext, Option extends BetterAuthOptions>(
3936
3936
  }>>;
3937
3937
  body: zod.ZodObject<{
3938
3938
  callbackURL: zod.ZodOptional<zod.ZodString>;
3939
- provider: zod.ZodEnum<["github", ...("github" | "apple" | "discord" | "facebook" | "microsoft" | "google" | "spotify" | "twitch" | "twitter")[]]>;
3939
+ provider: zod.ZodEnum<["github", ...("apple" | "discord" | "facebook" | "github" | "google" | "microsoft" | "spotify" | "twitch" | "twitter")[]]>;
3940
3940
  }, "strip", zod.ZodTypeAny, {
3941
- provider: "github" | "apple" | "discord" | "facebook" | "microsoft" | "google" | "spotify" | "twitch" | "twitter";
3941
+ provider: "apple" | "discord" | "facebook" | "github" | "google" | "microsoft" | "spotify" | "twitch" | "twitter";
3942
3942
  callbackURL?: string | undefined;
3943
3943
  }, {
3944
- provider: "github" | "apple" | "discord" | "facebook" | "microsoft" | "google" | "spotify" | "twitch" | "twitter";
3944
+ provider: "apple" | "discord" | "facebook" | "github" | "google" | "microsoft" | "spotify" | "twitch" | "twitter";
3945
3945
  callbackURL?: string | undefined;
3946
3946
  }>;
3947
3947
  use: Endpoint<better_call.Handler<string, better_call.EndpointOptions, void>, better_call.EndpointOptions>[];
@@ -5157,12 +5157,12 @@ declare const betterAuth: <O extends BetterAuthOptions>(options: O) => {
5157
5157
  }>>;
5158
5158
  body: zod.ZodObject<{
5159
5159
  callbackURL: zod.ZodOptional<zod.ZodString>;
5160
- provider: zod.ZodEnum<["github", ...("github" | "apple" | "discord" | "facebook" | "microsoft" | "google" | "spotify" | "twitch" | "twitter")[]]>;
5160
+ provider: zod.ZodEnum<["github", ...("apple" | "discord" | "facebook" | "github" | "google" | "microsoft" | "spotify" | "twitch" | "twitter")[]]>;
5161
5161
  }, "strip", zod.ZodTypeAny, {
5162
- provider: "github" | "apple" | "discord" | "facebook" | "microsoft" | "google" | "spotify" | "twitch" | "twitter";
5162
+ provider: "apple" | "discord" | "facebook" | "github" | "google" | "microsoft" | "spotify" | "twitch" | "twitter";
5163
5163
  callbackURL?: string | undefined;
5164
5164
  }, {
5165
- provider: "github" | "apple" | "discord" | "facebook" | "microsoft" | "google" | "spotify" | "twitch" | "twitter";
5165
+ provider: "apple" | "discord" | "facebook" | "github" | "google" | "microsoft" | "spotify" | "twitch" | "twitter";
5166
5166
  callbackURL?: string | undefined;
5167
5167
  }>;
5168
5168
  use: Endpoint<better_call.Handler<string, better_call.EndpointOptions, void>, better_call.EndpointOptions>[];
@@ -5190,12 +5190,12 @@ declare const betterAuth: <O extends BetterAuthOptions>(options: O) => {
5190
5190
  }>>;
5191
5191
  body: zod.ZodObject<{
5192
5192
  callbackURL: zod.ZodOptional<zod.ZodString>;
5193
- provider: zod.ZodEnum<["github", ...("github" | "apple" | "discord" | "facebook" | "microsoft" | "google" | "spotify" | "twitch" | "twitter")[]]>;
5193
+ provider: zod.ZodEnum<["github", ...("apple" | "discord" | "facebook" | "github" | "google" | "microsoft" | "spotify" | "twitch" | "twitter")[]]>;
5194
5194
  }, "strip", zod.ZodTypeAny, {
5195
- provider: "github" | "apple" | "discord" | "facebook" | "microsoft" | "google" | "spotify" | "twitch" | "twitter";
5195
+ provider: "apple" | "discord" | "facebook" | "github" | "google" | "microsoft" | "spotify" | "twitch" | "twitter";
5196
5196
  callbackURL?: string | undefined;
5197
5197
  }, {
5198
- provider: "github" | "apple" | "discord" | "facebook" | "microsoft" | "google" | "spotify" | "twitch" | "twitter";
5198
+ provider: "apple" | "discord" | "facebook" | "github" | "google" | "microsoft" | "spotify" | "twitch" | "twitter";
5199
5199
  callbackURL?: string | undefined;
5200
5200
  }>;
5201
5201
  use: Endpoint<better_call.Handler<string, better_call.EndpointOptions, void>, better_call.EndpointOptions>[];
@@ -2,10 +2,10 @@ import * as nanostores from 'nanostores';
2
2
  import { A as AccessControl, S as StatementsPrimitive, R as Role } from '../statement-CfnyN34h.js';
3
3
  import * as _better_fetch_fetch from '@better-fetch/fetch';
4
4
  import { BetterFetchOption } from '@better-fetch/fetch';
5
- import { o as organization, l as Organization, M as Member, I as Invitation, u as username, m as magicLink, d as phoneNumber, e as anonymous, i as admin, j as genericOAuth, k as multiSession } from '../index-B5i5YhzD.js';
6
- export { g as getPasskeyActions, c as passkeyClient, a as twoFactorClient } from '../index-B5i5YhzD.js';
5
+ import { o as organization, l as Organization, M as Member, I as Invitation, u as username, m as magicLink, d as phoneNumber, e as anonymous, i as admin, j as genericOAuth, k as multiSession } from '../index-C5jX2KrN.js';
6
+ export { g as getPasskeyActions, c as passkeyClient, a as twoFactorClient } from '../index-C5jX2KrN.js';
7
7
  import { P as Prettify } from '../helper-DPDj8Nix.js';
8
- import { F as FieldAttribute, B as BetterAuthOptions, b as BetterAuthPlugin } from '../auth-DhjJVba-.js';
8
+ import { F as FieldAttribute, B as BetterAuthOptions, b as BetterAuthPlugin } from '../auth-DFDxqxWC.js';
9
9
  import 'zod';
10
10
  import '../schema-Dkt0LqYs.js';
11
11
  import 'better-call';
package/dist/client.d.ts CHANGED
@@ -6,7 +6,7 @@ import { BetterFetch, BetterFetchError, BetterFetchOption } from '@better-fetch/
6
6
  import { U as UnionToIntersection, P as Prettify, S as StripEmptyObjects } from './helper-DPDj8Nix.js';
7
7
  import { ClientOptions, InferClientAPI, InferActions, InferAdditionalFromClient, InferSessionFromClient, InferUserFromClient, BetterAuthClientPlugin, IsSignal } from './types.js';
8
8
  export { AtomListener, InferPluginsFromClient } from './types.js';
9
- import './auth-DhjJVba-.js';
9
+ import './auth-DFDxqxWC.js';
10
10
  import 'kysely';
11
11
  import './schema-Dkt0LqYs.js';
12
12
  import 'better-call';
package/dist/cookies.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import 'better-call';
2
- export { s as BetterAuthCookies, E as EligibleCookies, r as createCookieGetter, u as deleteSessionCookie, q as getCookies, w as parseCookies, v as parseSetCookieHeader, t as setSessionCookie } from './auth-DhjJVba-.js';
2
+ export { s as BetterAuthCookies, E as EligibleCookies, r as createCookieGetter, u as deleteSessionCookie, q as getCookies, w as parseCookies, v as parseSetCookieHeader, t as setSessionCookie } from './auth-DFDxqxWC.js';
3
3
  import 'zod';
4
4
  import 'kysely';
5
5
  import './schema-Dkt0LqYs.js';
package/dist/db.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { A as Adapter, B as BetterAuthOptions, W as Where, F as FieldAttribute, z as FieldType, K as KyselyDatabaseType } from './auth-DhjJVba-.js';
2
- export { X as BetterAuthDbSchema, J as FieldAttributeConfig, V as InferFieldsFromOptions, U as InferFieldsFromPlugins, O as InferFieldsInput, Q as InferFieldsInputClient, N as InferFieldsOutput, M as InferValueType, D as InternalAdapter, T as PluginFieldAttribute, L as createFieldAttribute, C as createInternalAdapter, Y as getAuthTables } from './auth-DhjJVba-.js';
1
+ import { A as Adapter, B as BetterAuthOptions, W as Where, F as FieldAttribute, z as FieldType, K as KyselyDatabaseType } from './auth-DFDxqxWC.js';
2
+ export { X as BetterAuthDbSchema, J as FieldAttributeConfig, V as InferFieldsFromOptions, U as InferFieldsFromPlugins, O as InferFieldsInput, Q as InferFieldsInputClient, N as InferFieldsOutput, M as InferValueType, D as InternalAdapter, T as PluginFieldAttribute, L as createFieldAttribute, C as createInternalAdapter, Y as getAuthTables } from './auth-DFDxqxWC.js';
3
3
  import { z } from 'zod';
4
4
  import 'kysely';
5
5
  import './schema-Dkt0LqYs.js';
package/dist/db.js CHANGED
@@ -1,4 +1,4 @@
1
- var q=(e,s="ms")=>new Date(Date.now()+(s==="sec"?e*1e3:e));var h=e=>{let s=e.plugins?.reduce((t,i)=>{let o=i.schema;if(!o)return t;for(let[l,u]of Object.entries(o))t[l]={fields:{...t[l]?.fields,...u.fields},tableName:u.tableName||l};return t},{}),a=e.rateLimit?.storage==="database",n={rateLimit:{tableName:e.rateLimit?.tableName||"rateLimit",fields:{key:{type:"string",fieldName:e.rateLimit?.fields?.key||"key"},count:{type:"number",fieldName:e.rateLimit?.fields?.count||"count"},lastRequest:{type:"number",fieldName:e.rateLimit?.fields?.lastRequest||"lastRequest"}}}},{user:d,session:r,account:c,...f}=s||{};return{user:{tableName:e.user?.modelName||"user",fields:{name:{type:"string",required:!0,fieldName:e.user?.fields?.name||"name"},email:{type:"string",unique:!0,required:!0,fieldName:e.user?.fields?.email||"email"},emailVerified:{type:"boolean",defaultValue:()=>!1,required:!0,fieldName:e.user?.fields?.emailVerified||"emailVerified"},image:{type:"string",required:!1,fieldName:e.user?.fields?.image||"image"},createdAt:{type:"date",defaultValue:()=>new Date,required:!0,fieldName:e.user?.fields?.createdAt||"createdAt"},updatedAt:{type:"date",defaultValue:()=>new Date,required:!0,fieldName:e.user?.fields?.updatedAt||"updatedAt"},...d?.fields,...e.user?.additionalFields},order:1},session:{tableName:e.session?.modelName||"session",fields:{expiresAt:{type:"date",required:!0,fieldName:e.session?.fields?.expiresAt||"expiresAt"},ipAddress:{type:"string",required:!1,fieldName:e.session?.fields?.ipAddress||"ipAddress"},userAgent:{type:"string",required:!1,fieldName:e.session?.fields?.userAgent||"userAgent"},userId:{type:"string",fieldName:e.session?.fields?.userId||"userId",references:{model:e.user?.modelName||"user",field:"id",onDelete:"cascade"},required:!0},...r?.fields,...e.session?.additionalFields},order:2},account:{tableName:e.account?.modelName||"account",fields:{accountId:{type:"string",required:!0,fieldName:e.account?.fields?.accountId||"accountId"},providerId:{type:"string",required:!0,fieldName:e.account?.fields?.providerId||"providerId"},userId:{type:"string",references:{model:e.user?.modelName||"user",field:"id",onDelete:"cascade"},required:!0,fieldName:e.account?.fields?.userId||"userId"},accessToken:{type:"string",required:!1,fieldName:e.account?.fields?.accessToken||"accessToken"},refreshToken:{type:"string",required:!1,fieldName:e.account?.fields?.refreshToken||"refreshToken"},idToken:{type:"string",required:!1,fieldName:e.account?.fields?.idToken||"idToken"},expiresAt:{type:"date",required:!1,fieldName:e.account?.fields?.expiresAt||"expiresAt"},password:{type:"string",required:!1,fieldName:e.account?.fields?.password||"password"},...c?.fields},order:3},verification:{tableName:e.verification?.modelName||"verification",fields:{identifier:{type:"string",required:!0,fieldName:e.verification?.fields?.identifier||"identifier"},value:{type:"string",required:!0,fieldName:e.verification?.fields?.value||"value"},expiresAt:{type:"date",required:!0,fieldName:e.verification?.fields?.expiresAt||"expiresAt"}},order:4},...f,...a?n:{}}};import{nanoid as E}from"nanoid";var A=e=>E(e);var F=class extends Error{constructor(s,a){super(s),this.name="BetterAuthError",this.message=s,this.cause=a,this.stack=""}};import{Kysely as S,MssqlDialect as L}from"kysely";import{MysqlDialect as R,PostgresDialect as B,SqliteDialect as V}from"kysely";function M(e){if("dialect"in e)return M(e.dialect);if("createDriver"in e){if(e instanceof V)return"sqlite";if(e instanceof R)return"mysql";if(e instanceof B)return"postgres";if(e instanceof L)return"mssql"}return"aggregate"in e?"sqlite":"getConnection"in e?"mysql":"connect"in e?"postgres":null}var k=async e=>{let s=e.database;if("db"in s)return{kysely:s.db,databaseType:s.type};if("dialect"in s)return{kysely:new S({dialect:s.dialect}),databaseType:s.type};let a,n=M(s);return"createDriver"in s&&(a=s),"aggregate"in s&&(a=new V({database:s})),"getConnection"in s&&(a=new R({pool:s})),"connect"in s&&(a=new B({pool:s})),{kysely:a?new S({dialect:a}):null,databaseType:n}};function N(e){if(!e)return{and:null,or:null};let s={and:[],or:[]};return e.forEach(a=>{let{field:n,value:d,operator:r="=",connector:c="AND"}=a,f=t=>r.toLowerCase()==="in"?t(n,"in",Array.isArray(d)?d:[d]):r==="contains"?t(n,"like",`%${d}%`):r==="starts_with"?t(n,"like",`${d}%`):r==="ends_with"?t(n,"like",`%${d}`):t(n,r,d);c==="OR"?s.or.push(f):s.and.push(f)}),{and:s.and.length?s.and:null,or:s.or.length?s.or:null}}function v(e,s,a){for(let n in e){let d=s[n]||Object.values(s).find(r=>r.fieldName===n);e[n]===0&&d.type==="boolean"&&a?.boolean&&(e[n]=!1),e[n]===1&&d?.type==="boolean"&&a?.boolean&&(e[n]=!0),d?.type==="date"&&(e[n]instanceof Date||(e[n]=new Date(e[n])))}return e}function U(e,s){for(let a in e)typeof e[a]=="boolean"&&s?.boolean&&(e[a]=e[a]?1:0),e[a]instanceof Date&&(e[a]=e[a].toISOString());return e}var K=(e,s)=>({id:"kysely",async create(a){let{model:n,data:d,select:r}=a;s?.transform&&(d=U(d,s.transform)),s?.generateId!==void 0&&(d.id=s.generateId?s.generateId():void 0);let c=await e.insertInto(n).values(d).returningAll().executeTakeFirst();if(s?.transform){let f=s.transform.schema[n];c=f?v(d,f,s.transform):c}return r?.length&&(c=c?r.reduce((t,i)=>c?.[i]?{...t,[i]:c[i]}:t,{}):null),c},async findOne(a){let{model:n,where:d,select:r}=a,{and:c,or:f}=N(d),t=e.selectFrom(n).selectAll();c&&(t=t.where(o=>o.and(c.map(l=>l(o))))),f&&(t=t.where(o=>o.or(f.map(l=>l(o)))));let i=await t.executeTakeFirst();if(r?.length&&(i=i?r.reduce((l,u)=>i?.[u]?{...l,[u]:i[u]}:l,{}):null),s?.transform){let o=s.transform.schema[n];return i=i&&o?v(i,o,s.transform):i,i||null}return i||null},async findMany(a){let{model:n,where:d,limit:r,offset:c,sortBy:f}=a,t=e.selectFrom(n),{and:i,or:o}=N(d);i&&(t=t.where(u=>u.and(i.map(m=>m(u))))),o&&(t=t.where(u=>u.or(o.map(m=>m(u))))),t=t.limit(r||100),c&&(t=t.offset(c)),f&&(t=t.orderBy(f.field,f.direction));let l=await t.selectAll().execute();if(s?.transform){let u=s.transform.schema[n];return u?l.map(m=>v(m,u,s.transform)):l}return l},async update(a){let{model:n,where:d,update:r}=a,{and:c,or:f}=N(d);s?.transform&&(r=U(r,s.transform)),r.id&&(r.id=void 0);let t=e.updateTable(n).set(r);c&&(t=t.where(o=>o.and(c.map(l=>l(o))))),f&&(t=t.where(o=>o.or(f.map(l=>l(o)))));let i=await t.returningAll().executeTakeFirst()||null;if(s?.transform){let o=s.transform.schema[n];return o?v(i,o,s.transform):i}return i},async delete(a){let{model:n,where:d}=a,{and:r,or:c}=N(d),f=e.deleteFrom(n);r&&(f=f.where(t=>t.and(r.map(i=>i(t))))),c&&(f=f.where(t=>t.or(c.map(i=>i(t))))),await f.execute()},async deleteMany(a){let{model:n,where:d}=a,{and:r,or:c}=N(d),f=e.deleteFrom(n);r&&(f=f.where(t=>t.and(r.map(i=>i(t))))),c&&(f=f.where(t=>t.or(c.map(i=>i(t))))),await f.execute()}});async function me(e){if(!e.database)throw new F("Database configuration is required");if("create"in e.database)return e.database;let{kysely:s,databaseType:a}=await k(e);if(!s)throw new F("Failed to initialize database adapter");let n=h(e),d={};for(let r of Object.values(n))d[r.tableName]=r.fields;return K(s,{transform:{schema:d,date:!0,boolean:a==="sqlite"},generateId:"generateId"in e.database?e.database.generateId:void 0})}function D(e,s){let a={id:s.id};for(let n in e){let d=e[n],r=s[n];a[d.fieldName||n]=r}return a}function g(e,s){if(!s)return null;let a={id:s.id};for(let[n,d]of Object.entries(e))a[n]=s[d.fieldName||n];return a}function C(e,s){let a=s.hooks,n=h(s.options);async function d(c,f,t){let i=c,o=n[f];for(let m of a||[]){let p=m[f]?.create?.before;if(p){let y=await p(c);if(y===!1)return null;typeof y=="object"&&"data"in y&&(i=y.data)}}let l=t?await t.fn(i):null,u=!t||t.executeMainFn?await e.create({model:o.tableName,data:{...D(o.fields,i),id:i.id||A()}}):l;for(let m of a||[]){let p=m[f]?.create?.after;p&&await p(u)}return g(o.fields,u)}async function r(c,f,t,i){let o=c;for(let m of a||[]){let p=m[t]?.update?.before;if(p){let y=await p(c);if(y===!1)return null;o=typeof y=="object"?y.data:y}}let l=i?await i.fn(o):null,u=!i||i.executeMainFn?await e.update({model:n[t].tableName,update:D(n[t].fields,o),where:f}):l;for(let m of a||[]){let p=m[t]?.update?.after;p&&await p(u)}return g(n[t].fields,u)}return{createWithHooks:d,updateWithHooks:r}}import{isTest as $}from"std-env";function j(e){let s="127.0.0.1";if($)return s;let a=["x-client-ip","x-forwarded-for","cf-connecting-ip","fastly-client-ip","x-real-ip","x-cluster-client-ip","x-forwarded","forwarded-for","forwarded"],n=e instanceof Request?e.headers:e;for(let d of a){let r=n.get(d);if(typeof r=="string"){let c=r.split(",")[0].trim();if(c)return c}}return null}var ve=(e,s)=>{let a=s.options,n=a.secondaryStorage,d=a.session?.expiresIn||60*60*24*7,r=h(a),{createWithHooks:c,updateWithHooks:f}=C(e,s);return{createOAuthUser:async(t,i)=>{try{let o=await c({id:A(),createdAt:new Date,updatedAt:new Date,...t},"user"),l=await c({id:A(),...i,userId:o.id||t.id},"account");return{user:o,account:l}}catch(o){return console.log(o),null}},createUser:async t=>await c({id:A(),createdAt:new Date,updatedAt:new Date,emailVerified:!1,...t},"user"),createAccount:async t=>await c({id:A(),createdAt:new Date,updatedAt:new Date,...t},"account"),listSessions:async t=>await e.findMany({model:r.session.tableName,where:[{field:r.session.fields.userId.fieldName||"userId",value:t}]}),listUsers:async(t,i,o,l)=>(await e.findMany({model:r.user.tableName,limit:t,offset:i,sortBy:o,where:l})).map(m=>g(r.user.fields,m)),deleteUser:async t=>{await e.delete({model:r.account.tableName,where:[{field:r.account.fields.userId.fieldName||"userId",value:t}]}),await e.deleteMany({model:r.session.tableName,where:[{field:r.session.fields.userId.fieldName||"userId",value:t}]}),await e.deleteMany({model:r.user.tableName,where:[{field:"id",value:t}]})},createSession:async(t,i,o,l)=>{let u=i instanceof Request?i.headers:i,m={id:A(),userId:t,expiresAt:o?q(60*60*24,"sec"):q(d,"sec"),ipAddress:i&&j(i)||"",userAgent:u?.get("user-agent")||"",...l};return await c(m,"session",n?{fn:async y=>{let b=await e.findOne({model:r.user.tableName,where:[{field:"id",value:t}]});return n.set(y.id,JSON.stringify({session:y,user:b}),d),y},executeMainFn:a.session?.storeSessionInDatabase}:void 0)},findSession:async t=>{if(n){let l=await n.get(t);if(l){let u=JSON.parse(l);return{session:{...u.session,expiresAt:new Date(u.session.expiresAt)},user:{...u.user,createdAt:new Date(u.user.createdAt),updatedAt:new Date(u.user.updatedAt)}}}}let i=await e.findOne({model:r.session.tableName,where:[{value:t,field:"id"}]});if(!i)return null;let o=await e.findOne({model:r.user.tableName,where:[{value:i.userId,field:"id"}]});return o?{session:g(r.session.fields,i),user:g(r.user.fields,o)}:null},findSessions:async t=>{if(n){let u=[];for(let m of t){let p=await n.get(m);if(p){let y=JSON.parse(p),b={session:{...y.session,expiresAt:new Date(y.session.expiresAt)},user:{...y.user,createdAt:new Date(y.user.createdAt),updatedAt:new Date(y.user.updatedAt)}};u.push(b)}}return u}let i=await e.findMany({model:r.session.tableName,where:[{field:"id",value:t,operator:"in"}]}),o=i.map(u=>u.userId),l=await e.findMany({model:r.user.tableName,where:[{field:"id",value:o,operator:"in"}]});return i.map(u=>{let m=l.find(p=>p.id===u.userId);return m?{session:g(r.session.fields,u),user:g(r.user.fields,m)}:null})},updateSession:async(t,i)=>await f(i,[{field:"id",value:t}],"session",n?{async fn(l){let u=await n.get(t),m=null;if(u){let p=JSON.parse(u);m={...p.session,...l},await n.set(t,JSON.stringify({session:m,user:p.user}),p.session.expiresAt?new Date(p.session.expiresAt).getTime():void 0)}else return null},executeMainFn:a.session?.storeSessionInDatabase}:void 0),deleteSession:async t=>{if(n){await n.delete(t),a.session?.storeSessionInDatabase&&await e.delete({model:r.session.tableName,where:[{field:"id",value:t}]});return}await e.delete({model:r.session.tableName,where:[{field:"id",value:t}]})},deleteSessions:async t=>{if(n){let i=await e.findMany({model:r.session.tableName,where:[{field:r.session.fields.userId.fieldName||"userId",value:t}]});for(let o of i)await n.delete(o.id);a.session?.storeSessionInDatabase&&await e.delete({model:r.session.tableName,where:[{field:r.session.fields.userId.fieldName||"userId",value:t}]});return}await e.delete({model:r.session.tableName,where:[{field:r.session.fields.userId.fieldName||"userId",value:t}]})},findUserByEmail:async(t,i)=>{let o=await e.findOne({model:r.user.tableName,where:[{value:t.toLowerCase(),field:r.user.fields.email.fieldName||"email"}]});if(!o)return null;if(i?.includeAccounts){let l=await e.findMany({model:r.account.tableName,where:[{value:o.id,field:r.account.fields.userId.fieldName||"userId"}]});return{user:g(r.user.fields,o),accounts:l.map(u=>g(r.account.fields,u))}}return{user:g(r.user.fields,o),accounts:[]}},findUserById:async t=>await e.findOne({model:r.user.tableName,where:[{field:"id",value:t}]}),linkAccount:async t=>await c({id:A(),...t},"account"),updateUser:async(t,i)=>await f(i,[{field:"id",value:t}],"user"),updateUserByEmail:async(t,i)=>await f(i,[{field:r.user.fields.email.fieldName||"email",value:t}],"user"),updatePassword:async(t,i)=>await f({password:i},[{field:r.account.fields.userId.fieldName||"userId",value:t},{field:r.account.fields.providerId.fieldName||"providerId",value:"credential"}],"account"),findAccounts:async t=>(await e.findMany({model:r.account.tableName,where:[{field:r.account.fields.userId.fieldName||"userId",value:t}]})).map(o=>g(r.account.fields,o)),updateAccount:async(t,i)=>await f(i,[{field:"id",value:t}],"account"),createVerificationValue:async t=>await c({id:A(),...t},"verification"),findVerificationValue:async t=>{let i=await e.findOne({model:r.verification.tableName,where:[{field:r.verification.fields.identifier.fieldName||"identifier",value:t}]});return g(r.verification.fields,i)},deleteVerificationValue:async t=>{await e.delete({model:r.verification.tableName,where:[{field:"id",value:t}]})},updateVerificationValue:async(t,i)=>await f(i,[{field:"id",value:t}],"verification")}};var qe=(e,s)=>({type:e,...s});import{z as I}from"zod";function Re(e){return I.object({...Object.keys(e).reduce((a,n)=>{let d=e[n];if(!d)return a;if(d.type==="string[]"||d.type==="number[]")return{...a,[n]:I.array(d.type==="string[]"?I.string():I.number())};let r=I[d.type]();return d?.required===!1&&(r=r.optional()),d?.returned===!1?a:{...a,[n]:r}},{})})}import"kysely";import{createConsola as W}from"consola";var w=W({formatOptions:{date:!1,colors:!0,compact:!0},defaults:{tag:"Better Auth"}}),H=e=>({log:(...s)=>{!e?.disabled&&w.log("",...s)},error:(...s)=>{!e?.disabled&&w.error("",...s)},warn:(...s)=>{!e?.disabled&&w.warn("",...s)},info:(...s)=>{!e?.disabled&&w.info("",...s)},debug:(...s)=>{!e?.disabled&&w.debug("",...s)},box:(...s)=>{!e?.disabled&&w.box("",...s)},success:(...s)=>{!e?.disabled&&w.success("",...s)},break:(...s)=>{!e?.disabled&&console.log(`
1
+ var q=(e,s="ms")=>new Date(Date.now()+(s==="sec"?e*1e3:e));var h=e=>{let s=e.plugins?.reduce((t,i)=>{let o=i.schema;if(!o)return t;for(let[l,u]of Object.entries(o))t[l]={fields:{...t[l]?.fields,...u.fields},tableName:u.tableName||l};return t},{}),a=e.rateLimit?.storage==="database",n={rateLimit:{tableName:e.rateLimit?.tableName||"rateLimit",fields:{key:{type:"string",fieldName:e.rateLimit?.fields?.key||"key"},count:{type:"number",fieldName:e.rateLimit?.fields?.count||"count"},lastRequest:{type:"number",fieldName:e.rateLimit?.fields?.lastRequest||"lastRequest"}}}},{user:d,session:r,account:c,...f}=s||{};return{user:{tableName:e.user?.modelName||"user",fields:{name:{type:"string",required:!0,fieldName:e.user?.fields?.name||"name"},email:{type:"string",unique:!0,required:!0,fieldName:e.user?.fields?.email||"email"},emailVerified:{type:"boolean",defaultValue:()=>!1,required:!0,fieldName:e.user?.fields?.emailVerified||"emailVerified"},image:{type:"string",required:!1,fieldName:e.user?.fields?.image||"image"},createdAt:{type:"date",defaultValue:()=>new Date,required:!0,fieldName:e.user?.fields?.createdAt||"createdAt"},updatedAt:{type:"date",defaultValue:()=>new Date,required:!0,fieldName:e.user?.fields?.updatedAt||"updatedAt"},...d?.fields,...e.user?.additionalFields},order:1},session:{tableName:e.session?.modelName||"session",fields:{expiresAt:{type:"date",required:!0,fieldName:e.session?.fields?.expiresAt||"expiresAt"},ipAddress:{type:"string",required:!1,fieldName:e.session?.fields?.ipAddress||"ipAddress"},userAgent:{type:"string",required:!1,fieldName:e.session?.fields?.userAgent||"userAgent"},userId:{type:"string",fieldName:e.session?.fields?.userId||"userId",references:{model:e.user?.modelName||"user",field:"id",onDelete:"cascade"},required:!0},...r?.fields,...e.session?.additionalFields},order:2},account:{tableName:e.account?.modelName||"account",fields:{accountId:{type:"string",required:!0,fieldName:e.account?.fields?.accountId||"accountId"},providerId:{type:"string",required:!0,fieldName:e.account?.fields?.providerId||"providerId"},userId:{type:"string",references:{model:e.user?.modelName||"user",field:"id",onDelete:"cascade"},required:!0,fieldName:e.account?.fields?.userId||"userId"},accessToken:{type:"string",required:!1,fieldName:e.account?.fields?.accessToken||"accessToken"},refreshToken:{type:"string",required:!1,fieldName:e.account?.fields?.refreshToken||"refreshToken"},idToken:{type:"string",required:!1,fieldName:e.account?.fields?.idToken||"idToken"},expiresAt:{type:"date",required:!1,fieldName:e.account?.fields?.expiresAt||"expiresAt"},password:{type:"string",required:!1,fieldName:e.account?.fields?.password||"password"},...c?.fields},order:3},verification:{tableName:e.verification?.modelName||"verification",fields:{identifier:{type:"string",required:!0,fieldName:e.verification?.fields?.identifier||"identifier"},value:{type:"string",required:!0,fieldName:e.verification?.fields?.value||"value"},expiresAt:{type:"date",required:!0,fieldName:e.verification?.fields?.expiresAt||"expiresAt"}},order:4},...f,...a?n:{}}};import{nanoid as E}from"nanoid";var A=e=>E(e);var F=class extends Error{constructor(s,a){super(s),this.name="BetterAuthError",this.message=s,this.cause=a,this.stack=""}};import{Kysely as S,MssqlDialect as L}from"kysely";import{MysqlDialect as R,PostgresDialect as B,SqliteDialect as V}from"kysely";function M(e){if("dialect"in e)return M(e.dialect);if("createDriver"in e){if(e instanceof V)return"sqlite";if(e instanceof R)return"mysql";if(e instanceof B)return"postgres";if(e instanceof L)return"mssql"}return"aggregate"in e?"sqlite":"getConnection"in e?"mysql":"connect"in e?"postgres":null}var k=async e=>{let s=e.database;if("db"in s)return{kysely:s.db,databaseType:s.type};if("dialect"in s)return{kysely:new S({dialect:s.dialect}),databaseType:s.type};let a,n=M(s);return"createDriver"in s&&(a=s),"aggregate"in s&&(a=new V({database:s})),"getConnection"in s&&(a=new R({pool:s})),"connect"in s&&(a=new B({pool:s})),{kysely:a?new S({dialect:a}):null,databaseType:n}};function N(e){if(!e)return{and:null,or:null};let s={and:[],or:[]};return e.forEach(a=>{let{field:n,value:d,operator:r="=",connector:c="AND"}=a,f=t=>r.toLowerCase()==="in"?t(n,"in",Array.isArray(d)?d:[d]):r==="contains"?t(n,"like",`%${d}%`):r==="starts_with"?t(n,"like",`${d}%`):r==="ends_with"?t(n,"like",`%${d}`):t(n,r,d);c==="OR"?s.or.push(f):s.and.push(f)}),{and:s.and.length?s.and:null,or:s.or.length?s.or:null}}function v(e,s,a){for(let n in e){let d=s[n]||Object.values(s).find(r=>r.fieldName===n);e[n]===0&&d.type==="boolean"&&a?.boolean&&(e[n]=!1),e[n]===1&&d?.type==="boolean"&&a?.boolean&&(e[n]=!0),d?.type==="date"&&(e[n]instanceof Date||(e[n]=new Date(e[n])))}return e}function U(e,s){for(let a in e)typeof e[a]=="boolean"&&s?.boolean&&(e[a]=e[a]?1:0),e[a]instanceof Date&&(e[a]=e[a].toISOString());return e}var K=(e,s)=>({id:"kysely",async create(a){let{model:n,data:d,select:r}=a;s?.transform&&(d=U(d,s.transform)),s?.generateId!==void 0&&(d.id=s.generateId?s.generateId():void 0);let c=await e.insertInto(n).values(d).returningAll().executeTakeFirst();if(s?.transform){let f=s.transform.schema[n];c=f?v(d,f,s.transform):c}return r?.length&&(c=c?r.reduce((t,i)=>c?.[i]?{...t,[i]:c[i]}:t,{}):null),c},async findOne(a){let{model:n,where:d,select:r}=a,{and:c,or:f}=N(d),t=e.selectFrom(n).selectAll();c&&(t=t.where(o=>o.and(c.map(l=>l(o))))),f&&(t=t.where(o=>o.or(f.map(l=>l(o)))));let i=await t.executeTakeFirst();if(r?.length&&(i=i?r.reduce((l,u)=>i?.[u]?{...l,[u]:i[u]}:l,{}):null),s?.transform){let o=s.transform.schema[n];return i=i&&o?v(i,o,s.transform):i,i||null}return i||null},async findMany(a){let{model:n,where:d,limit:r,offset:c,sortBy:f}=a,t=e.selectFrom(n),{and:i,or:o}=N(d);i&&(t=t.where(u=>u.and(i.map(m=>m(u))))),o&&(t=t.where(u=>u.or(o.map(m=>m(u))))),t=t.limit(r||100),c&&(t=t.offset(c)),f&&(t=t.orderBy(f.field,f.direction));let l=await t.selectAll().execute();if(s?.transform){let u=s.transform.schema[n];return u?l.map(m=>v(m,u,s.transform)):l}return l},async update(a){let{model:n,where:d,update:r}=a,{and:c,or:f}=N(d);s?.transform&&(r=U(r,s.transform)),r.id&&(r.id=void 0);let t=e.updateTable(n).set(r);c&&(t=t.where(o=>o.and(c.map(l=>l(o))))),f&&(t=t.where(o=>o.or(f.map(l=>l(o)))));let i=await t.returningAll().executeTakeFirst()||null;if(s?.transform){let o=s.transform.schema[n];return o?v(i,o,s.transform):i}return i},async delete(a){let{model:n,where:d}=a,{and:r,or:c}=N(d),f=e.deleteFrom(n);r&&(f=f.where(t=>t.and(r.map(i=>i(t))))),c&&(f=f.where(t=>t.or(c.map(i=>i(t))))),await f.execute()},async deleteMany(a){let{model:n,where:d}=a,{and:r,or:c}=N(d),f=e.deleteFrom(n);r&&(f=f.where(t=>t.and(r.map(i=>i(t))))),c&&(f=f.where(t=>t.or(c.map(i=>i(t))))),await f.execute()}});async function me(e){if(!e.database)throw new F("Database configuration is required");if("create"in e.database)return e.database;let{kysely:s,databaseType:a}=await k(e);if(!s)throw new F("Failed to initialize database adapter");let n=h(e),d={};for(let r of Object.values(n))d[r.tableName]=r.fields;return K(s,{transform:{schema:d,date:!0,boolean:a==="sqlite"},generateId:"generateId"in e.database?e.database.generateId:void 0})}function D(e,s){let a={id:s.id};for(let n in e){let d=e[n],r=s[n];a[d.fieldName||n]=r}return a}function g(e,s){if(!s)return null;let a={id:s.id};for(let[n,d]of Object.entries(e))a[n]=s[d.fieldName||n];return a}function C(e,s){let a=s.hooks,n=h(s.options);async function d(c,f,t){let i=c,o=n[f];for(let m of a||[]){let p=m[f]?.create?.before;if(p){let y=await p(c);if(y===!1)return null;typeof y=="object"&&"data"in y&&(i=y.data)}}let l=t?await t.fn(i):null,u=!t||t.executeMainFn?await e.create({model:o.tableName,data:{...D(o.fields,i),id:i.id||A()}}):l;for(let m of a||[]){let p=m[f]?.create?.after;p&&await p(u)}return g(o.fields,u)}async function r(c,f,t,i){let o=c;for(let m of a||[]){let p=m[t]?.update?.before;if(p){let y=await p(c);if(y===!1)return null;o=typeof y=="object"?y.data:y}}let l=i?await i.fn(o):null,u=!i||i.executeMainFn?await e.update({model:n[t].tableName,update:D(n[t].fields,o),where:f}):l;for(let m of a||[]){let p=m[t]?.update?.after;p&&await p(u)}return g(n[t].fields,u)}return{createWithHooks:d,updateWithHooks:r}}import{isTest as $}from"std-env";function j(e){let s="127.0.0.1";if($)return s;let a=["x-client-ip","x-forwarded-for","cf-connecting-ip","fastly-client-ip","x-real-ip","x-cluster-client-ip","x-forwarded","forwarded-for","forwarded"],n=e instanceof Request?e.headers:e;for(let d of a){let r=n.get(d);if(typeof r=="string"){let c=r.split(",")[0].trim();if(c)return c}}return null}var ve=(e,s)=>{let a=s.options,n=a.secondaryStorage,d=a.session?.expiresIn||60*60*24*7,r=h(a),{createWithHooks:c,updateWithHooks:f}=C(e,s);return{createOAuthUser:async(t,i)=>{try{let o=await c({id:A(),createdAt:new Date,updatedAt:new Date,...t},"user"),l=await c({id:A(),...i,userId:o.id||t.id},"account");return{user:o,account:l}}catch(o){return console.log(o),null}},createUser:async t=>await c({id:A(),createdAt:new Date,updatedAt:new Date,emailVerified:!1,...t},"user"),createAccount:async t=>await c({id:A(),createdAt:new Date,updatedAt:new Date,...t},"account"),listSessions:async t=>await e.findMany({model:r.session.tableName,where:[{field:r.session.fields.userId.fieldName||"userId",value:t}]}),listUsers:async(t,i,o,l)=>(await e.findMany({model:r.user.tableName,limit:t,offset:i,sortBy:o,where:l})).map(m=>g(r.user.fields,m)),deleteUser:async t=>{await e.delete({model:r.account.tableName,where:[{field:r.account.fields.userId.fieldName||"userId",value:t}]}),await e.deleteMany({model:r.session.tableName,where:[{field:r.session.fields.userId.fieldName||"userId",value:t}]}),await e.deleteMany({model:r.user.tableName,where:[{field:"id",value:t}]})},createSession:async(t,i,o,l)=>{let u=i instanceof Request?i.headers:i,m={id:A(),userId:t,expiresAt:o?q(60*60*24,"sec"):q(d,"sec"),ipAddress:i&&j(i)||"",userAgent:u?.get("user-agent")||"",...l};return await c(m,"session",n?{fn:async y=>{let b=await e.findOne({model:r.user.tableName,where:[{field:"id",value:t}]});return n.set(y.id,JSON.stringify({session:y,user:b}),d),y},executeMainFn:a.session?.storeSessionInDatabase}:void 0)},findSession:async t=>{if(n){let l=await n.get(t);if(l){let u=JSON.parse(l);return{session:{...u.session,expiresAt:new Date(u.session.expiresAt)},user:{...u.user,createdAt:new Date(u.user.createdAt),updatedAt:new Date(u.user.updatedAt)}}}}let i=await e.findOne({model:r.session.tableName,where:[{value:t,field:"id"}]});if(!i)return null;let o=await e.findOne({model:r.user.tableName,where:[{value:i.userId,field:"id"}]});return o?{session:g(r.session.fields,i),user:g(r.user.fields,o)}:null},findSessions:async t=>{if(n){let u=[];for(let m of t){let p=await n.get(m);if(p){let y=JSON.parse(p),b={session:{...y.session,expiresAt:new Date(y.session.expiresAt)},user:{...y.user,createdAt:new Date(y.user.createdAt),updatedAt:new Date(y.user.updatedAt)}};u.push(b)}}return u}let i=await e.findMany({model:r.session.tableName,where:[{field:"id",value:t,operator:"in"}]}),o=i.map(u=>u.userId);if(!o.length)return[];let l=await e.findMany({model:r.user.tableName,where:[{field:"id",value:o,operator:"in"}]});return i.map(u=>{let m=l.find(p=>p.id===u.userId);return m?{session:g(r.session.fields,u),user:g(r.user.fields,m)}:null})},updateSession:async(t,i)=>await f(i,[{field:"id",value:t}],"session",n?{async fn(l){let u=await n.get(t),m=null;if(u){let p=JSON.parse(u);m={...p.session,...l},await n.set(t,JSON.stringify({session:m,user:p.user}),p.session.expiresAt?new Date(p.session.expiresAt).getTime():void 0)}else return null},executeMainFn:a.session?.storeSessionInDatabase}:void 0),deleteSession:async t=>{if(n){await n.delete(t),a.session?.storeSessionInDatabase&&await e.delete({model:r.session.tableName,where:[{field:"id",value:t}]});return}await e.delete({model:r.session.tableName,where:[{field:"id",value:t}]})},deleteSessions:async t=>{if(n){let i=await e.findMany({model:r.session.tableName,where:[{field:r.session.fields.userId.fieldName||"userId",value:t}]});for(let o of i)await n.delete(o.id);a.session?.storeSessionInDatabase&&await e.delete({model:r.session.tableName,where:[{field:r.session.fields.userId.fieldName||"userId",value:t}]});return}await e.delete({model:r.session.tableName,where:[{field:r.session.fields.userId.fieldName||"userId",value:t}]})},findUserByEmail:async(t,i)=>{let o=await e.findOne({model:r.user.tableName,where:[{value:t.toLowerCase(),field:r.user.fields.email.fieldName||"email"}]});if(!o)return null;if(i?.includeAccounts){let l=await e.findMany({model:r.account.tableName,where:[{value:o.id,field:r.account.fields.userId.fieldName||"userId"}]});return{user:g(r.user.fields,o),accounts:l.map(u=>g(r.account.fields,u))}}return{user:g(r.user.fields,o),accounts:[]}},findUserById:async t=>await e.findOne({model:r.user.tableName,where:[{field:"id",value:t}]}),linkAccount:async t=>await c({id:A(),...t},"account"),updateUser:async(t,i)=>await f(i,[{field:"id",value:t}],"user"),updateUserByEmail:async(t,i)=>await f(i,[{field:r.user.fields.email.fieldName||"email",value:t}],"user"),updatePassword:async(t,i)=>await f({password:i},[{field:r.account.fields.userId.fieldName||"userId",value:t},{field:r.account.fields.providerId.fieldName||"providerId",value:"credential"}],"account"),findAccounts:async t=>(await e.findMany({model:r.account.tableName,where:[{field:r.account.fields.userId.fieldName||"userId",value:t}]})).map(o=>g(r.account.fields,o)),updateAccount:async(t,i)=>await f(i,[{field:"id",value:t}],"account"),createVerificationValue:async t=>await c({id:A(),...t},"verification"),findVerificationValue:async t=>{let i=await e.findOne({model:r.verification.tableName,where:[{field:r.verification.fields.identifier.fieldName||"identifier",value:t}]});return g(r.verification.fields,i)},deleteVerificationValue:async t=>{await e.delete({model:r.verification.tableName,where:[{field:"id",value:t}]})},updateVerificationValue:async(t,i)=>await f(i,[{field:"id",value:t}],"verification")}};var qe=(e,s)=>({type:e,...s});import{z as I}from"zod";function Re(e){return I.object({...Object.keys(e).reduce((a,n)=>{let d=e[n];if(!d)return a;if(d.type==="string[]"||d.type==="number[]")return{...a,[n]:I.array(d.type==="string[]"?I.string():I.number())};let r=I[d.type]();return d?.required===!1&&(r=r.optional()),d?.returned===!1?a:{...a,[n]:r}},{})})}import"kysely";import{createConsola as W}from"consola";var w=W({formatOptions:{date:!1,colors:!0,compact:!0},defaults:{tag:"Better Auth"}}),H=e=>({log:(...s)=>{!e?.disabled&&w.log("",...s)},error:(...s)=>{!e?.disabled&&w.error("",...s)},warn:(...s)=>{!e?.disabled&&w.warn("",...s)},info:(...s)=>{!e?.disabled&&w.info("",...s)},debug:(...s)=>{!e?.disabled&&w.debug("",...s)},box:(...s)=>{!e?.disabled&&w.box("",...s)},success:(...s)=>{!e?.disabled&&w.success("",...s)},break:(...s)=>{!e?.disabled&&console.log(`
2
2
  `)}}),O=H();function P(e){let s=h(e),a={};for(let n in s){let d=s[n],r=d.fields,c={};if(Object.entries(r).forEach(([f,t])=>{c[t.fieldName||f]=t}),a[d.tableName]){a[d.tableName].fields={...a[d.tableName].fields,...c};continue}a[d.tableName]={fields:c,order:d.order||1/0}}return a}var J={string:["character varying","text"],number:["int4","integer","bigint","smallint","numeric","real","double precision"],boolean:["bool","boolean"],date:["timestamp","date"]},Z={string:["varchar","text"],number:["integer","int","bigint","smallint","decimal","float","double"],boolean:["boolean"],date:["date","datetime"]},z={string:["TEXT"],number:["INTEGER","REAL"],boolean:["INTEGER","BOOLEAN"],date:["DATE","INTEGER"]},_={string:["nvarchar","varchar"],number:["int","bigint","smallint","decimal","float","double"],boolean:["bit","boolean"],date:["datetime","date"]},G={postgres:J,mysql:Z,sqlite:z,mssql:_};function X(e,s,a){return s==="string[]"||s==="number[]"?e.toLowerCase().includes("json"):G[a][s].map(c=>c.toLowerCase()).includes(e.toLowerCase())}async function Le(e){let s=P(e),{kysely:a,databaseType:n}=await k(e);n||(O.warn("Could not determine database type, defaulting to sqlite. Please provide a type in the database options to avoid this."),n="sqlite"),a||(O.error("Only kysely adapter is supported for migrations. You can use `generate` command to generate the schema, if you're using a different adapter."),process.exit(1));let d=await a.introspection.getTables(),r=[],c=[];for(let[l,u]of Object.entries(s)){let m=d.find(y=>y.name===l);if(!m){let y=r.findIndex(T=>T.table===l),b={table:l,fields:u.fields,order:u.order||1/0},x=r.findIndex(T=>(T.order||1/0)>b.order);x===-1?y===-1?r.push(b):r[y].fields={...r[y].fields,...u.fields}:r.splice(x,0,b);continue}let p={};for(let[y,b]of Object.entries(u.fields)){let x=m.columns.find(T=>T.name===y);if(!x){p[y]=b;continue}X(x.dataType,b.type,n)||O.warn(`Field ${y} in table ${l} has a different type in the database. Expected ${b.type} but got ${x.dataType}.`)}Object.keys(p).length>0&&c.push({table:l,fields:p,order:u.order||1/0})}let f=[];function t(l){let u={string:"text",boolean:"boolean",number:"integer",date:"date"};return n==="mysql"&&l==="string"?"varchar(255)":n==="sqlite"&&(l==="string[]"||l==="number[]")?"text":l==="string[]"||l==="number[]"?"jsonb":u[l]}if(c.length)for(let l of c)for(let[u,m]of Object.entries(l.fields)){let p=t(m.type),y=a.schema.alterTable(l.table).addColumn(u,p,b=>(b=m.required!==!1?b.notNull():b,m.references&&(b=b.references(`${m.references.model}.${m.references.field}`)),b));f.push(y)}if(r.length)for(let l of r){let u=a.schema.createTable(l.table).addColumn("id",t("string"),m=>m.primaryKey().notNull());for(let[m,p]of Object.entries(l.fields)){let y=t(p.type);u=u.addColumn(m,y,b=>(b=p.required!==!1?b.notNull():b,p.references&&(b=b.references(`${p.references.model}.${p.references.field}`)),p.unique&&(b=b.unique()),b))}f.push(u)}async function i(){for(let l of f)await l.execute()}async function o(){return f.map(u=>u.compile().sql).join(`;
3
3
 
4
4
  `)}return{toBeCreated:r,toBeAdded:c,runMigrations:i,compileMigrations:o}}export{g as convertFromDB,D as convertToDB,qe as createFieldAttribute,ve as createInternalAdapter,me as getAdapter,h as getAuthTables,Le as getMigrations,P as getSchema,C as getWithHooks,X as matchType,Re as toZodSchema};
@@ -5,7 +5,7 @@ import { P as Prettify } from './helper-DPDj8Nix.js';
5
5
  import { A as AccessControl, R as Role, S as StatementsPrimitive, g as defaultRoles } from './statement-CfnyN34h.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, p as AuthContext } from './auth-DhjJVba-.js';
8
+ import { H as HookEndpointContext, p as AuthContext } from './auth-DFDxqxWC.js';
9
9
  import * as nanostores from 'nanostores';
10
10
  import { atom } from 'nanostores';
11
11
  import * as _simplewebauthn_types from '@simplewebauthn/types';
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { A as Adapter, j as AdditionalSessionFieldsInput, k as AdditionalSessionFieldsOutput, h as AdditionalUserFieldsInput, i as AdditionalUserFieldsOutput, a as Auth, p as AuthContext, s as BetterAuthCookies, B as BetterAuthOptions, b as BetterAuthPlugin, E as EligibleCookies, G as GenericEndpointContext, H as HookEndpointContext, m as InferPluginTypes, l as InferSession, I as InferUser, P as PluginSchema, R as RateLimit, S as SecondaryStorage, W as Where, g as betterAuth, r as createCookieGetter, x as createLogger, u as deleteSessionCookie, q as getCookies, n as init, y as logger, w as parseCookies, v as parseSetCookieHeader, t as setSessionCookie } from './auth-DhjJVba-.js';
1
+ export { A as Adapter, j as AdditionalSessionFieldsInput, k as AdditionalSessionFieldsOutput, h as AdditionalUserFieldsInput, i as AdditionalUserFieldsOutput, a as Auth, p as AuthContext, s as BetterAuthCookies, B as BetterAuthOptions, b as BetterAuthPlugin, E as EligibleCookies, G as GenericEndpointContext, H as HookEndpointContext, m as InferPluginTypes, l as InferSession, I as InferUser, P as PluginSchema, R as RateLimit, S as SecondaryStorage, W as Where, g as betterAuth, r as createCookieGetter, x as createLogger, u as deleteSessionCookie, q as getCookies, n as init, y as logger, w as parseCookies, v as parseSetCookieHeader, t as setSessionCookie } from './auth-DFDxqxWC.js';
2
2
  export { D as DeepPartial, H as HasRequiredKeys, L as LiteralString, a as LiteralUnion, P as Prettify, R as RequiredKeysOf, S as StripEmptyObjects, U as UnionToIntersection, W as WithoutEmpty } from './helper-DPDj8Nix.js';
3
3
  export { AtomListener, BetterAuthClientPlugin, ClientOptions, InferActions, InferAdditionalFromClient, InferClientAPI, InferPluginsFromClient, InferSessionFromClient, InferUserFromClient, IsSignal } from './types.js';
4
4
  export { H as HIDE_METADATA } from './hide-metadata-DEHJp1rk.js';
package/dist/index.js CHANGED
@@ -80,4 +80,4 @@ Error: `,g),e.redirect(`${e.context.baseURL}/error?error=internal_server_error`)
80
80
  <div class="error-code">Error Code: <span id="errorCode">${e}</span></div>
81
81
  </div>
82
82
  </body>
83
- </html>`,xt=y("/error",{method:"GET",metadata:F},async e=>{let t=new URL(e.request?.url||"").searchParams.get("error")||"Unknown";return new Response(wr(t),{headers:{"Content-Type":"text/html"}})});var Tt=y("/ok",{method:"GET",metadata:F},async e=>e.json({ok:!0}));import{z as K}from"zod";import{APIError as $}from"better-call";var Ut=()=>y("/sign-up/email",{method:"POST",query:K.object({currentURL:K.string().optional()}).optional(),body:K.record(K.string(),K.any()),use:[U]},async e=>{if(!e.context.options.emailAndPassword?.enabled)throw new $("BAD_REQUEST",{message:"Email and password sign up is not enabled"});let t=e.body,{name:r,email:o,password:i,image:n,callbackURL:a,...c}=t;if(!K.string().email().safeParse(o).success)throw new $("BAD_REQUEST",{message:"Invalid email"});let d=e.context.password.config.minPasswordLength;if(i.length<d)throw e.context.logger.error("Password is too short"),new $("BAD_REQUEST",{message:"Password is too short"});let l=e.context.password.config.maxPasswordLength;if(i.length>l)throw e.context.logger.error("Password is too long"),new $("BAD_REQUEST",{message:"Password is too long"});if((await e.context.internalAdapter.findUserByEmail(o))?.user)throw e.context.logger.info(`Sign-up attempt for existing email: ${o}`),new $("UNPROCESSABLE_ENTITY",{message:"Failed to create user"});let u=ut(e.context.options,c),f=await e.context.internalAdapter.createUser({email:o.toLowerCase(),name:r,image:n,...u,emailVerified:!1});if(!f)throw new $("BAD_REQUEST",{message:"Failed to create user"});let m=await e.context.password.hash(i);if(await e.context.internalAdapter.linkAccount({userId:f.id,providerId:"credential",accountId:f.id,password:m,expiresAt:V(60*60*24*30,"sec")}),e.context.options.emailVerification?.sendOnSignUp){let g=await B(e.context.secret,f.email),x=`${e.context.baseURL}/verify-email?token=${g}&callbackURL=${t.callbackURL||e.query?.currentURL||"/"}`;await e.context.options.emailVerification?.sendVerificationEmail?.(f,x,g)}if(!e.context.options.emailAndPassword.autoSignIn||e.context.options.emailAndPassword.requireEmailVerification)return e.json({user:f,session:null},{body:t.callbackURL?{url:t.callbackURL,redirect:!0}:{user:f,session:null}});let h=await e.context.internalAdapter.createSession(f.id,e.request);if(!h)throw new $("BAD_REQUEST",{message:"Failed to create session"});return await L(e,h.id),e.json({user:f,session:h},{body:t.callbackURL?{url:t.callbackURL,redirect:!0}:{user:f,session:h}})});import{isTest as br}from"std-env";function ne(e){let t="127.0.0.1";if(br)return t;let r=["x-client-ip","x-forwarded-for","cf-connecting-ip","fastly-client-ip","x-real-ip","x-cluster-client-ip","x-forwarded","forwarded-for","forwarded"],o=e instanceof Request?e.headers:e;for(let i of r){let n=o.get(i);if(typeof n=="string"){let a=n.split(",")[0].trim();if(a)return a}}return null}function Ar(e,t,r){let o=Date.now(),i=t*1e3;return o-r.lastRequest<i&&r.count>=e}function kr(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 r=Date.now(),o=t*1e3;return Math.ceil((e+o-r)/1e3)}function xr(e,t){let r=t??"rateLimit",o=e.adapter;return{get:async i=>await o.findOne({model:r,where:[{field:"key",value:i}]}),set:async(i,n,a)=>{try{a?await o.update({model:t??"rateLimit",where:[{field:"key",value:i}],update:{count:n.count,lastRequest:n.lastRequest}}):await o.create({model:t??"rateLimit",data:{key:i,count:n.count,lastRequest:n.lastRequest}})}catch(c){b.error("Error setting rate limit",c)}}}}var Et=new Map;function Tr(e){return e.rateLimit.storage==="secondary-storage"?{get:async r=>{let o=await e.options.secondaryStorage?.get(r);return o?JSON.parse(o):void 0},set:async(r,o)=>{await e.options.secondaryStorage?.set?.(r,JSON.stringify(o))}}:e.rateLimit.storage==="memory"?{async get(r){return Et.get(r)},async set(r,o,i){Et.set(r,o)}}:xr(e,e.rateLimit.tableName)}async function vt(e,t){if(!t.rateLimit.enabled)return;let r=t.baseURL,o=e.url.replace(r,""),i=t.rateLimit.window,n=t.rateLimit.max,a=ne(e)+o,s=Ur().find(u=>u.pathMatcher(o));s&&(i=s.window,n=s.max);for(let u of t.options.plugins||[])if(u.rateLimit){let f=u.rateLimit.find(m=>m.pathMatcher(o));if(f){i=f.window,n=f.max;break}}if(t.rateLimit.customRules){let u=t.rateLimit.customRules[o];u&&(i=u.window,n=u.max)}let d=Tr(t),l=await d.get(a),p=Date.now();if(!l)await d.set(a,{key:a,count:1,lastRequest:p});else{let u=p-l.lastRequest;if(Ar(n,i,l)){let f=Rr(l.lastRequest,i);return kr(f)}else u>i*1e3?await d.set(a,{...l,count:1,lastRequest:p}):await d.set(a,{...l,count:l.count+1,lastRequest:p})}}function Ur(){return[{pathMatcher(t){return t.startsWith("/sign-in")||t.startsWith("/sign-up")},window:10,max:3}]}import{APIError as Ia}from"better-call";function fe(e,t){let r=t.plugins?.reduce((c,s)=>({...c,...s.endpoints}),{}),o=t.plugins?.map(c=>c.middlewares?.map(s=>{let d=async l=>s.middleware({...l,context:{...e,...l.context}});return d.path=s.path,d.options=s.middleware.options,d.headers=s.middleware.headers,{path:s.path,middleware:d}})).filter(c=>c!==void 0).flat()||[],n={...{signInOAuth:it,callbackOAuth:pt,getCSRFToken:Rt,getSession:ue(),signOut:ft,signUpEmail:Ut(),signInEmail:st,forgetPassword:mt,resetPassword:ht,verifyEmail:nt,sendVerificationEmail:ot,changeEmail:kt,changePassword:wt,setPassword:bt,updateUser:yt(),deleteUser:At,forgetPasswordCallback:gt,listSessions:et(),revokeSession:tt,revokeSessions:rt},...r,ok:Tt,error:xt},a={};for(let[c,s]of Object.entries(n))a[c]=async(d={})=>{let l=await e;for(let f of t.plugins||[])if(f.hooks?.before){for(let m of f.hooks.before)if(m.matcher({...s,...d,context:l})){let g=await m.handler({...d,context:{...l,...d?.context}});g&&"context"in g&&(l={...l,...g.context})}}let p;try{p=await s({...d,context:{...l,...d.context}})}catch(f){if(f instanceof Ot){let m=t.plugins?.map(g=>{if(g.hooks?.after)return g.hooks.after}).filter(g=>g!==void 0).flat();if(!m?.length)throw f;let h=new Response(JSON.stringify(f.body),{status:vr[f.status],headers:f.headers});for(let g of m||[])if(g.matcher(d)){let Z=Object.assign(d,{context:{...e,returned:h}}),N=await g.handler(Z);N&&"response"in N&&(h=N.response)}return h}throw f}let u=p;for(let f of t.plugins||[])if(f.hooks?.after){for(let m of f.hooks.after)if(m.matcher(d)){let g=Object.assign(d,{context:{...e,returned:u}}),x=await m.handler(g);x&&"response"in x&&(u=x.response)}}return u},a[c].path=s.path,a[c].method=s.method,a[c].options=s.options,a[c].headers=s.headers;return{api:a,middlewares:o}}var It=(e,t)=>{let{api:r,middlewares:o}=fe(e,t),i=new URL(e.baseURL).pathname;return Er(r,{extraContext:e,basePath:i,routerMiddleware:[{path:"/**",middleware:Pe},...o],async onRequest(n){for(let a of e.options.plugins||[])if(a.onRequest){let c=await a.onRequest(n,e);if(c)return c}return vt(n,e)},async onResponse(n){for(let a of e.options.plugins||[])if(a.onResponse){let c=await a.onResponse(n,e);if(c)return c.response}return n},onError(n){if(t.onAPIError?.throw)throw n;if(t.onAPIError?.onError){t.onAPIError.onError(n,e);return}let a=t.logger?.verboseLogging?b:void 0;t.logger?.disabled!==!0&&(n instanceof Ot?(n.status==="INTERNAL_SERVER_ERROR"&&b.error(n),a?.error(n.message)):b?.error(n))}})};var D=e=>{let t=e.plugins?.reduce((s,d)=>{let l=d.schema;if(!l)return s;for(let[p,u]of Object.entries(l))s[p]={fields:{...s[p]?.fields,...u.fields},tableName:u.tableName||p};return s},{}),r=e.rateLimit?.storage==="database",o={rateLimit:{tableName:e.rateLimit?.tableName||"rateLimit",fields:{key:{type:"string",fieldName:e.rateLimit?.fields?.key||"key"},count:{type:"number",fieldName:e.rateLimit?.fields?.count||"count"},lastRequest:{type:"number",fieldName:e.rateLimit?.fields?.lastRequest||"lastRequest"}}}},{user:i,session:n,account:a,...c}=t||{};return{user:{tableName:e.user?.modelName||"user",fields:{name:{type:"string",required:!0,fieldName:e.user?.fields?.name||"name"},email:{type:"string",unique:!0,required:!0,fieldName:e.user?.fields?.email||"email"},emailVerified:{type:"boolean",defaultValue:()=>!1,required:!0,fieldName:e.user?.fields?.emailVerified||"emailVerified"},image:{type:"string",required:!1,fieldName:e.user?.fields?.image||"image"},createdAt:{type:"date",defaultValue:()=>new Date,required:!0,fieldName:e.user?.fields?.createdAt||"createdAt"},updatedAt:{type:"date",defaultValue:()=>new Date,required:!0,fieldName:e.user?.fields?.updatedAt||"updatedAt"},...i?.fields,...e.user?.additionalFields},order:1},session:{tableName:e.session?.modelName||"session",fields:{expiresAt:{type:"date",required:!0,fieldName:e.session?.fields?.expiresAt||"expiresAt"},ipAddress:{type:"string",required:!1,fieldName:e.session?.fields?.ipAddress||"ipAddress"},userAgent:{type:"string",required:!1,fieldName:e.session?.fields?.userAgent||"userAgent"},userId:{type:"string",fieldName:e.session?.fields?.userId||"userId",references:{model:e.user?.modelName||"user",field:"id",onDelete:"cascade"},required:!0},...n?.fields,...e.session?.additionalFields},order:2},account:{tableName:e.account?.modelName||"account",fields:{accountId:{type:"string",required:!0,fieldName:e.account?.fields?.accountId||"accountId"},providerId:{type:"string",required:!0,fieldName:e.account?.fields?.providerId||"providerId"},userId:{type:"string",references:{model:e.user?.modelName||"user",field:"id",onDelete:"cascade"},required:!0,fieldName:e.account?.fields?.userId||"userId"},accessToken:{type:"string",required:!1,fieldName:e.account?.fields?.accessToken||"accessToken"},refreshToken:{type:"string",required:!1,fieldName:e.account?.fields?.refreshToken||"refreshToken"},idToken:{type:"string",required:!1,fieldName:e.account?.fields?.idToken||"idToken"},expiresAt:{type:"date",required:!1,fieldName:e.account?.fields?.expiresAt||"expiresAt"},password:{type:"string",required:!1,fieldName:e.account?.fields?.password||"password"},...a?.fields},order:3},verification:{tableName:e.verification?.modelName||"verification",fields:{identifier:{type:"string",required:!0,fieldName:e.verification?.fields?.identifier||"identifier"},value:{type:"string",required:!0,fieldName:e.verification?.fields?.value||"value"},expiresAt:{type:"date",required:!0,fieldName:e.verification?.fields?.expiresAt||"expiresAt"}},order:4},...c,...r?o:{}}};import{Kysely as St,MssqlDialect as Or}from"kysely";import{MysqlDialect as Pt,PostgresDialect as Lt,SqliteDialect as _t}from"kysely";function Ct(e){if("dialect"in e)return Ct(e.dialect);if("createDriver"in e){if(e instanceof _t)return"sqlite";if(e instanceof Pt)return"mysql";if(e instanceof Lt)return"postgres";if(e instanceof Or)return"mssql"}return"aggregate"in e?"sqlite":"getConnection"in e?"mysql":"connect"in e?"postgres":null}var W=async e=>{let t=e.database;if("db"in t)return{kysely:t.db,databaseType:t.type};if("dialect"in t)return{kysely:new St({dialect:t.dialect}),databaseType:t.type};let r,o=Ct(t);return"createDriver"in t&&(r=t),"aggregate"in t&&(r=new _t({database:t})),"getConnection"in t&&(r=new Pt({pool:t})),"connect"in t&&(r=new Lt({pool:t})),{kysely:r?new St({dialect:r}):null,databaseType:o}};function J(e){if(!e)return{and:null,or:null};let t={and:[],or:[]};return e.forEach(r=>{let{field:o,value:i,operator:n="=",connector:a="AND"}=r,c=s=>n.toLowerCase()==="in"?s(o,"in",Array.isArray(i)?i:[i]):n==="contains"?s(o,"like",`%${i}%`):n==="starts_with"?s(o,"like",`${i}%`):n==="ends_with"?s(o,"like",`%${i}`):s(o,n,i);a==="OR"?t.or.push(c):t.and.push(c)}),{and:t.and.length?t.and:null,or:t.or.length?t.or:null}}function ie(e,t,r){for(let o in e){let i=t[o]||Object.values(t).find(n=>n.fieldName===o);e[o]===0&&i.type==="boolean"&&r?.boolean&&(e[o]=!1),e[o]===1&&i?.type==="boolean"&&r?.boolean&&(e[o]=!0),i?.type==="date"&&(e[o]instanceof Date||(e[o]=new Date(e[o])))}return e}function Bt(e,t){for(let r in e)typeof e[r]=="boolean"&&t?.boolean&&(e[r]=e[r]?1:0),e[r]instanceof Date&&(e[r]=e[r].toISOString());return e}var Dt=(e,t)=>({id:"kysely",async create(r){let{model:o,data:i,select:n}=r;t?.transform&&(i=Bt(i,t.transform)),t?.generateId!==void 0&&(i.id=t.generateId?t.generateId():void 0);let a=await e.insertInto(o).values(i).returningAll().executeTakeFirst();if(t?.transform){let c=t.transform.schema[o];a=c?ie(i,c,t.transform):a}return n?.length&&(a=a?n.reduce((s,d)=>a?.[d]?{...s,[d]:a[d]}:s,{}):null),a},async findOne(r){let{model:o,where:i,select:n}=r,{and:a,or:c}=J(i),s=e.selectFrom(o).selectAll();a&&(s=s.where(l=>l.and(a.map(p=>p(l))))),c&&(s=s.where(l=>l.or(c.map(p=>p(l)))));let d=await s.executeTakeFirst();if(n?.length&&(d=d?n.reduce((p,u)=>d?.[u]?{...p,[u]:d[u]}:p,{}):null),t?.transform){let l=t.transform.schema[o];return d=d&&l?ie(d,l,t.transform):d,d||null}return d||null},async findMany(r){let{model:o,where:i,limit:n,offset:a,sortBy:c}=r,s=e.selectFrom(o),{and:d,or:l}=J(i);d&&(s=s.where(u=>u.and(d.map(f=>f(u))))),l&&(s=s.where(u=>u.or(l.map(f=>f(u))))),s=s.limit(n||100),a&&(s=s.offset(a)),c&&(s=s.orderBy(c.field,c.direction));let p=await s.selectAll().execute();if(t?.transform){let u=t.transform.schema[o];return u?p.map(f=>ie(f,u,t.transform)):p}return p},async update(r){let{model:o,where:i,update:n}=r,{and:a,or:c}=J(i);t?.transform&&(n=Bt(n,t.transform)),n.id&&(n.id=void 0);let s=e.updateTable(o).set(n);a&&(s=s.where(l=>l.and(a.map(p=>p(l))))),c&&(s=s.where(l=>l.or(c.map(p=>p(l)))));let d=await s.returningAll().executeTakeFirst()||null;if(t?.transform){let l=t.transform.schema[o];return l?ie(d,l,t.transform):d}return d},async delete(r){let{model:o,where:i}=r,{and:n,or:a}=J(i),c=e.deleteFrom(o);n&&(c=c.where(s=>s.and(n.map(d=>d(s))))),a&&(c=c.where(s=>s.or(a.map(d=>d(s))))),await c.execute()},async deleteMany(r){let{model:o,where:i}=r,{and:n,or:a}=J(i),c=e.deleteFrom(o);n&&(c=c.where(s=>s.and(n.map(d=>d(s))))),a&&(c=c.where(s=>s.or(a.map(d=>d(s))))),await c.execute()}});async function Ft(e){if(!e.database)throw new k("Database configuration is required");if("create"in e.database)return e.database;let{kysely:t,databaseType:r}=await W(e);if(!t)throw new k("Failed to initialize database adapter");let o=D(e),i={};for(let n of Object.values(o))i[n.tableName]=n.fields;return Dt(t,{transform:{schema:i,date:!0,boolean:r==="sqlite"},generateId:"generateId"in e.database?e.database.generateId:void 0})}function me(e,t){let r={id:t.id};for(let o in e){let i=e[o],n=t[o];r[i.fieldName||o]=n}return r}function O(e,t){if(!t)return null;let r={id:t.id};for(let[o,i]of Object.entries(e))r[o]=t[i.fieldName||o];return r}function Nt(e,t){let r=t.hooks,o=D(t.options);async function i(a,c,s){let d=a,l=o[c];for(let f of r||[]){let m=f[c]?.create?.before;if(m){let h=await m(a);if(h===!1)return null;typeof h=="object"&&"data"in h&&(d=h.data)}}let p=s?await s.fn(d):null,u=!s||s.executeMainFn?await e.create({model:l.tableName,data:{...me(l.fields,d),id:d.id||v()}}):p;for(let f of r||[]){let m=f[c]?.create?.after;m&&await m(u)}return O(l.fields,u)}async function n(a,c,s,d){let l=a;for(let f of r||[]){let m=f[s]?.update?.before;if(m){let h=await m(a);if(h===!1)return null;l=typeof h=="object"?h.data:h}}let p=d?await d.fn(l):null,u=!d||d.executeMainFn?await e.update({model:o[s].tableName,update:me(o[s].fields,l),where:c}):p;for(let f of r||[]){let m=f[s]?.update?.after;m&&await m(u)}return O(o[s].fields,u)}return{createWithHooks:i,updateWithHooks:n}}var ge=(e,t)=>{let r=t.options,o=r.secondaryStorage,i=r.session?.expiresIn||60*60*24*7,n=D(r),{createWithHooks:a,updateWithHooks:c}=Nt(e,t);return{createOAuthUser:async(s,d)=>{try{let l=await a({id:v(),createdAt:new Date,updatedAt:new Date,...s},"user"),p=await a({id:v(),...d,userId:l.id||s.id},"account");return{user:l,account:p}}catch(l){return console.log(l),null}},createUser:async s=>await a({id:v(),createdAt:new Date,updatedAt:new Date,emailVerified:!1,...s},"user"),createAccount:async s=>await a({id:v(),createdAt:new Date,updatedAt:new Date,...s},"account"),listSessions:async s=>await e.findMany({model:n.session.tableName,where:[{field:n.session.fields.userId.fieldName||"userId",value:s}]}),listUsers:async(s,d,l,p)=>(await e.findMany({model:n.user.tableName,limit:s,offset:d,sortBy:l,where:p})).map(f=>O(n.user.fields,f)),deleteUser:async s=>{await e.delete({model:n.account.tableName,where:[{field:n.account.fields.userId.fieldName||"userId",value:s}]}),await e.deleteMany({model:n.session.tableName,where:[{field:n.session.fields.userId.fieldName||"userId",value:s}]}),await e.deleteMany({model:n.user.tableName,where:[{field:"id",value:s}]})},createSession:async(s,d,l,p)=>{let u=d instanceof Request?d.headers:d,f={id:v(),userId:s,expiresAt:l?V(60*60*24,"sec"):V(i,"sec"),ipAddress:d&&ne(d)||"",userAgent:u?.get("user-agent")||"",...p};return await a(f,"session",o?{fn:async h=>{let g=await e.findOne({model:n.user.tableName,where:[{field:"id",value:s}]});return o.set(h.id,JSON.stringify({session:h,user:g}),i),h},executeMainFn:r.session?.storeSessionInDatabase}:void 0)},findSession:async s=>{if(o){let p=await o.get(s);if(p){let u=JSON.parse(p);return{session:{...u.session,expiresAt:new Date(u.session.expiresAt)},user:{...u.user,createdAt:new Date(u.user.createdAt),updatedAt:new Date(u.user.updatedAt)}}}}let d=await e.findOne({model:n.session.tableName,where:[{value:s,field:"id"}]});if(!d)return null;let l=await e.findOne({model:n.user.tableName,where:[{value:d.userId,field:"id"}]});return l?{session:O(n.session.fields,d),user:O(n.user.fields,l)}:null},findSessions:async s=>{if(o){let u=[];for(let f of s){let m=await o.get(f);if(m){let h=JSON.parse(m),g={session:{...h.session,expiresAt:new Date(h.session.expiresAt)},user:{...h.user,createdAt:new Date(h.user.createdAt),updatedAt:new Date(h.user.updatedAt)}};u.push(g)}}return u}let d=await e.findMany({model:n.session.tableName,where:[{field:"id",value:s,operator:"in"}]}),l=d.map(u=>u.userId),p=await e.findMany({model:n.user.tableName,where:[{field:"id",value:l,operator:"in"}]});return d.map(u=>{let f=p.find(m=>m.id===u.userId);return f?{session:O(n.session.fields,u),user:O(n.user.fields,f)}:null})},updateSession:async(s,d)=>await c(d,[{field:"id",value:s}],"session",o?{async fn(p){let u=await o.get(s),f=null;if(u){let m=JSON.parse(u);f={...m.session,...p},await o.set(s,JSON.stringify({session:f,user:m.user}),m.session.expiresAt?new Date(m.session.expiresAt).getTime():void 0)}else return null},executeMainFn:r.session?.storeSessionInDatabase}:void 0),deleteSession:async s=>{if(o){await o.delete(s),r.session?.storeSessionInDatabase&&await e.delete({model:n.session.tableName,where:[{field:"id",value:s}]});return}await e.delete({model:n.session.tableName,where:[{field:"id",value:s}]})},deleteSessions:async s=>{if(o){let d=await e.findMany({model:n.session.tableName,where:[{field:n.session.fields.userId.fieldName||"userId",value:s}]});for(let l of d)await o.delete(l.id);r.session?.storeSessionInDatabase&&await e.delete({model:n.session.tableName,where:[{field:n.session.fields.userId.fieldName||"userId",value:s}]});return}await e.delete({model:n.session.tableName,where:[{field:n.session.fields.userId.fieldName||"userId",value:s}]})},findUserByEmail:async(s,d)=>{let l=await e.findOne({model:n.user.tableName,where:[{value:s.toLowerCase(),field:n.user.fields.email.fieldName||"email"}]});if(!l)return null;if(d?.includeAccounts){let p=await e.findMany({model:n.account.tableName,where:[{value:l.id,field:n.account.fields.userId.fieldName||"userId"}]});return{user:O(n.user.fields,l),accounts:p.map(u=>O(n.account.fields,u))}}return{user:O(n.user.fields,l),accounts:[]}},findUserById:async s=>await e.findOne({model:n.user.tableName,where:[{field:"id",value:s}]}),linkAccount:async s=>await a({id:v(),...s},"account"),updateUser:async(s,d)=>await c(d,[{field:"id",value:s}],"user"),updateUserByEmail:async(s,d)=>await c(d,[{field:n.user.fields.email.fieldName||"email",value:s}],"user"),updatePassword:async(s,d)=>await c({password:d},[{field:n.account.fields.userId.fieldName||"userId",value:s},{field:n.account.fields.providerId.fieldName||"providerId",value:"credential"}],"account"),findAccounts:async s=>(await e.findMany({model:n.account.tableName,where:[{field:n.account.fields.userId.fieldName||"userId",value:s}]})).map(l=>O(n.account.fields,l)),updateAccount:async(s,d)=>await c(d,[{field:"id",value:s}],"account"),createVerificationValue:async s=>await a({id:v(),...s},"verification"),findVerificationValue:async s=>{let d=await e.findOne({model:n.verification.tableName,where:[{field:n.verification.fields.identifier.fieldName||"identifier",value:s}]});return O(n.verification.fields,d)},deleteVerificationValue:async s=>{await e.delete({model:n.verification.tableName,where:[{field:"id",value:s}]})},updateVerificationValue:async(s,d)=>await c(d,[{field:"id",value:s}],"verification")}};import{z as td}from"zod";import"kysely";import{env as we,isProduction as qt}from"std-env";import{defu as Sr}from"defu";import{env as j}from"std-env";function Ir(e){try{return new URL(e).pathname!=="/"}catch{throw new k(`Invalid base URL: ${e}. Please provide a valid base URL.`)}}function he(e,t="/api/auth"){return Ir(e)?e:(t=t.startsWith("/")?t:`/${t}`,`${e}${t}`)}function X(e,t){if(e)return he(e,t);let r=j.BETTER_AUTH_URL||j.NEXT_PUBLIC_BETTER_AUTH_URL||j.PUBLIC_BETTER_AUTH_URL||j.NUXT_PUBLIC_BETTER_AUTH_URL||j.NUXT_PUBLIC_AUTH_URL||(j.BASE_URL!=="/"?j.BASE_URL:void 0);if(r)return he(r,t);if(typeof window<"u")return he(window.location.origin,t)}var ye="better-auth-secret-123456789";var Vt=async e=>{let t=await Ft(e),r=e.plugins||[],o=Lr(e),{kysely:i}=await W(e),n=X(e.baseURL,e.basePath);if(!n)throw new k("Base URL can not be empty. Please add `BETTER_AUTH_URL` in your environment variables or pass it your auth config.");let a=e.secret||we.BETTER_AUTH_SECRET||we.AUTH_SECRET||ye;if(a===ye&&qt)throw new k("You are using the default secret. Please set `BETTER_AUTH_SECRET` or `AUTH_SECRET` in your environment variables or pass `secret` in your auth config.");e={...e,secret:a,baseURL:n?new URL(n).origin:"",basePath:e.basePath||"/api/auth",plugins:r.concat(o),emailAndPassword:{...e.emailAndPassword,enabled:e.emailAndPassword?.enabled??!1,autoSignIn:e.emailAndPassword?.autoSignIn??!0}};let c=Ne(e),s=D(e),d=Object.keys(e.socialProviders||{}).map(u=>{let f=e.socialProviders?.[u];return f.enabled===!1?null:((!f.clientId||!f.clientSecret)&&b.warn(`Social provider ${u} is missing clientId or clientSecret`),le[u](f))}).filter(u=>u!==null),l={appName:e.appName||"Better Auth",socialProviders:d,options:e,tables:s,trustedOrigins:_r(e),baseURL:n,sessionConfig:{updateAge:e.session?.updateAge||24*60*60,expiresIn:e.session?.expiresIn||60*60*24*7},secret:a,rateLimit:{...e.rateLimit,enabled:e.rateLimit?.enabled??qt,window:e.rateLimit?.window||10,max:e.rateLimit?.max||100,storage:e.rateLimit?.storage||e.secondaryStorage?"secondary-storage":"memory"},authCookies:c,logger:de({disabled:e.logger?.disabled||!1}),db:i,uuid:v,secondaryStorage:e.secondaryStorage,password:{hash:e.emailAndPassword?.password?.hash||ke,verify:e.emailAndPassword?.password?.verify||Re,config:{minPasswordLength:e.emailAndPassword?.minPasswordLength||8,maxPasswordLength:e.emailAndPassword?.maxPasswordLength||128}},adapter:t,internalAdapter:ge(t,{options:e,hooks:e.databaseHooks?[e.databaseHooks]:[]}),createAuthCookie:qe(e)},{context:p}=Pr(l);return p};function Pr(e){let t=e.options,r=t.plugins||[],o=e,i=[];for(let n of r)if(n.init){let a=n.init(e);typeof a=="object"&&(a.options&&(a.options.databaseHooks&&i.push(a.options.databaseHooks),t=Sr(t,a.options)),a.context&&(o={...o,...a.context}))}return i.push(t.databaseHooks),o.internalAdapter=ge(e.adapter,{options:t,hooks:i.filter(n=>n!==void 0)}),o.options=t,{context:o}}function Lr(e){let t=[];return e.advanced?.crossSubDomainCookies?.enabled,t}function _r(e){let t=X(e.baseURL,e.basePath);if(!t)throw new k("Base URL can not be empty. Please add `BETTER_AUTH_URL` in your environment variables or pass it in your auth config.");let r=[new URL(t).origin];e.trustedOrigins&&r.push(...e.trustedOrigins);let o=we.BETTER_AUTH_TRUSTED_ORIGINS;return o&&r.push(...o.split(",")),r}var zd=e=>{let t=Vt(e),{api:r}=fe(t,e);return{handler:async o=>{let i=await t,n=i.options.basePath||"/api/auth",a=new URL(o.url);if(!i.options.baseURL){let s=X(void 0,n)||`${a.origin}${n}`;i.options.baseURL=s,i.baseURL=s}if(!i.options.baseURL)return new Response("Base URL not set",{status:400});if(a.pathname===n||a.pathname===`${n}/`)return new Response("Welcome to BetterAuth",{status:200});let{handler:c}=It(i,e);return c(o)},api:r,options:e,$Infer:{}}};export{k as BetterAuthError,F as HIDE_METADATA,De as MissingDependencyError,zd as betterAuth,xn as capitalizeFirstLetter,qe as createCookieGetter,de as createLogger,G as deleteSessionCookie,v as generateId,Be as generateState,Ne as getCookies,b as logger,vo as parseCookies,Eo as parseSetCookieHeader,ae as parseState,L as setSessionCookie};
83
+ </html>`,xt=y("/error",{method:"GET",metadata:F},async e=>{let t=new URL(e.request?.url||"").searchParams.get("error")||"Unknown";return new Response(wr(t),{headers:{"Content-Type":"text/html"}})});var Tt=y("/ok",{method:"GET",metadata:F},async e=>e.json({ok:!0}));import{z as K}from"zod";import{APIError as $}from"better-call";var Ut=()=>y("/sign-up/email",{method:"POST",query:K.object({currentURL:K.string().optional()}).optional(),body:K.record(K.string(),K.any()),use:[U]},async e=>{if(!e.context.options.emailAndPassword?.enabled)throw new $("BAD_REQUEST",{message:"Email and password sign up is not enabled"});let t=e.body,{name:r,email:o,password:i,image:n,callbackURL:a,...c}=t;if(!K.string().email().safeParse(o).success)throw new $("BAD_REQUEST",{message:"Invalid email"});let d=e.context.password.config.minPasswordLength;if(i.length<d)throw e.context.logger.error("Password is too short"),new $("BAD_REQUEST",{message:"Password is too short"});let l=e.context.password.config.maxPasswordLength;if(i.length>l)throw e.context.logger.error("Password is too long"),new $("BAD_REQUEST",{message:"Password is too long"});if((await e.context.internalAdapter.findUserByEmail(o))?.user)throw e.context.logger.info(`Sign-up attempt for existing email: ${o}`),new $("UNPROCESSABLE_ENTITY",{message:"Failed to create user"});let u=ut(e.context.options,c),f=await e.context.internalAdapter.createUser({email:o.toLowerCase(),name:r,image:n,...u,emailVerified:!1});if(!f)throw new $("BAD_REQUEST",{message:"Failed to create user"});let m=await e.context.password.hash(i);if(await e.context.internalAdapter.linkAccount({userId:f.id,providerId:"credential",accountId:f.id,password:m,expiresAt:V(60*60*24*30,"sec")}),e.context.options.emailVerification?.sendOnSignUp){let g=await B(e.context.secret,f.email),x=`${e.context.baseURL}/verify-email?token=${g}&callbackURL=${t.callbackURL||e.query?.currentURL||"/"}`;await e.context.options.emailVerification?.sendVerificationEmail?.(f,x,g)}if(!e.context.options.emailAndPassword.autoSignIn||e.context.options.emailAndPassword.requireEmailVerification)return e.json({user:f,session:null},{body:t.callbackURL?{url:t.callbackURL,redirect:!0}:{user:f,session:null}});let h=await e.context.internalAdapter.createSession(f.id,e.request);if(!h)throw new $("BAD_REQUEST",{message:"Failed to create session"});return await L(e,h.id),e.json({user:f,session:h},{body:t.callbackURL?{url:t.callbackURL,redirect:!0}:{user:f,session:h}})});import{isTest as br}from"std-env";function ne(e){let t="127.0.0.1";if(br)return t;let r=["x-client-ip","x-forwarded-for","cf-connecting-ip","fastly-client-ip","x-real-ip","x-cluster-client-ip","x-forwarded","forwarded-for","forwarded"],o=e instanceof Request?e.headers:e;for(let i of r){let n=o.get(i);if(typeof n=="string"){let a=n.split(",")[0].trim();if(a)return a}}return null}function Ar(e,t,r){let o=Date.now(),i=t*1e3;return o-r.lastRequest<i&&r.count>=e}function kr(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 r=Date.now(),o=t*1e3;return Math.ceil((e+o-r)/1e3)}function xr(e,t){let r=t??"rateLimit",o=e.adapter;return{get:async i=>await o.findOne({model:r,where:[{field:"key",value:i}]}),set:async(i,n,a)=>{try{a?await o.update({model:t??"rateLimit",where:[{field:"key",value:i}],update:{count:n.count,lastRequest:n.lastRequest}}):await o.create({model:t??"rateLimit",data:{key:i,count:n.count,lastRequest:n.lastRequest}})}catch(c){b.error("Error setting rate limit",c)}}}}var Et=new Map;function Tr(e){return e.rateLimit.storage==="secondary-storage"?{get:async r=>{let o=await e.options.secondaryStorage?.get(r);return o?JSON.parse(o):void 0},set:async(r,o)=>{await e.options.secondaryStorage?.set?.(r,JSON.stringify(o))}}:e.rateLimit.storage==="memory"?{async get(r){return Et.get(r)},async set(r,o,i){Et.set(r,o)}}:xr(e,e.rateLimit.tableName)}async function vt(e,t){if(!t.rateLimit.enabled)return;let r=t.baseURL,o=e.url.replace(r,""),i=t.rateLimit.window,n=t.rateLimit.max,a=ne(e)+o,s=Ur().find(u=>u.pathMatcher(o));s&&(i=s.window,n=s.max);for(let u of t.options.plugins||[])if(u.rateLimit){let f=u.rateLimit.find(m=>m.pathMatcher(o));if(f){i=f.window,n=f.max;break}}if(t.rateLimit.customRules){let u=t.rateLimit.customRules[o];u&&(i=u.window,n=u.max)}let d=Tr(t),l=await d.get(a),p=Date.now();if(!l)await d.set(a,{key:a,count:1,lastRequest:p});else{let u=p-l.lastRequest;if(Ar(n,i,l)){let f=Rr(l.lastRequest,i);return kr(f)}else u>i*1e3?await d.set(a,{...l,count:1,lastRequest:p}):await d.set(a,{...l,count:l.count+1,lastRequest:p})}}function Ur(){return[{pathMatcher(t){return t.startsWith("/sign-in")||t.startsWith("/sign-up")},window:10,max:3}]}import{APIError as Ia}from"better-call";function fe(e,t){let r=t.plugins?.reduce((c,s)=>({...c,...s.endpoints}),{}),o=t.plugins?.map(c=>c.middlewares?.map(s=>{let d=async l=>s.middleware({...l,context:{...e,...l.context}});return d.path=s.path,d.options=s.middleware.options,d.headers=s.middleware.headers,{path:s.path,middleware:d}})).filter(c=>c!==void 0).flat()||[],n={...{signInOAuth:it,callbackOAuth:pt,getCSRFToken:Rt,getSession:ue(),signOut:ft,signUpEmail:Ut(),signInEmail:st,forgetPassword:mt,resetPassword:ht,verifyEmail:nt,sendVerificationEmail:ot,changeEmail:kt,changePassword:wt,setPassword:bt,updateUser:yt(),deleteUser:At,forgetPasswordCallback:gt,listSessions:et(),revokeSession:tt,revokeSessions:rt},...r,ok:Tt,error:xt},a={};for(let[c,s]of Object.entries(n))a[c]=async(d={})=>{let l=await e;for(let f of t.plugins||[])if(f.hooks?.before){for(let m of f.hooks.before)if(m.matcher({...s,...d,context:l})){let g=await m.handler({...d,context:{...l,...d?.context}});g&&"context"in g&&(l={...l,...g.context})}}let p;try{p=await s({...d,context:{...l,...d.context}})}catch(f){if(f instanceof Ot){let m=t.plugins?.map(g=>{if(g.hooks?.after)return g.hooks.after}).filter(g=>g!==void 0).flat();if(!m?.length)throw f;let h=new Response(JSON.stringify(f.body),{status:vr[f.status],headers:f.headers});for(let g of m||[])if(g.matcher(d)){let Z=Object.assign(d,{context:{...e,returned:h}}),N=await g.handler(Z);N&&"response"in N&&(h=N.response)}return h}throw f}let u=p;for(let f of t.plugins||[])if(f.hooks?.after){for(let m of f.hooks.after)if(m.matcher(d)){let g=Object.assign(d,{context:{...e,returned:u}}),x=await m.handler(g);x&&"response"in x&&(u=x.response)}}return u},a[c].path=s.path,a[c].method=s.method,a[c].options=s.options,a[c].headers=s.headers;return{api:a,middlewares:o}}var It=(e,t)=>{let{api:r,middlewares:o}=fe(e,t),i=new URL(e.baseURL).pathname;return Er(r,{extraContext:e,basePath:i,routerMiddleware:[{path:"/**",middleware:Pe},...o],async onRequest(n){for(let a of e.options.plugins||[])if(a.onRequest){let c=await a.onRequest(n,e);if(c)return c}return vt(n,e)},async onResponse(n){for(let a of e.options.plugins||[])if(a.onResponse){let c=await a.onResponse(n,e);if(c)return c.response}return n},onError(n){if(t.onAPIError?.throw)throw n;if(t.onAPIError?.onError){t.onAPIError.onError(n,e);return}let a=t.logger?.verboseLogging?b:void 0;t.logger?.disabled!==!0&&(n instanceof Ot?(n.status==="INTERNAL_SERVER_ERROR"&&b.error(n),a?.error(n.message)):b?.error(n))}})};var D=e=>{let t=e.plugins?.reduce((s,d)=>{let l=d.schema;if(!l)return s;for(let[p,u]of Object.entries(l))s[p]={fields:{...s[p]?.fields,...u.fields},tableName:u.tableName||p};return s},{}),r=e.rateLimit?.storage==="database",o={rateLimit:{tableName:e.rateLimit?.tableName||"rateLimit",fields:{key:{type:"string",fieldName:e.rateLimit?.fields?.key||"key"},count:{type:"number",fieldName:e.rateLimit?.fields?.count||"count"},lastRequest:{type:"number",fieldName:e.rateLimit?.fields?.lastRequest||"lastRequest"}}}},{user:i,session:n,account:a,...c}=t||{};return{user:{tableName:e.user?.modelName||"user",fields:{name:{type:"string",required:!0,fieldName:e.user?.fields?.name||"name"},email:{type:"string",unique:!0,required:!0,fieldName:e.user?.fields?.email||"email"},emailVerified:{type:"boolean",defaultValue:()=>!1,required:!0,fieldName:e.user?.fields?.emailVerified||"emailVerified"},image:{type:"string",required:!1,fieldName:e.user?.fields?.image||"image"},createdAt:{type:"date",defaultValue:()=>new Date,required:!0,fieldName:e.user?.fields?.createdAt||"createdAt"},updatedAt:{type:"date",defaultValue:()=>new Date,required:!0,fieldName:e.user?.fields?.updatedAt||"updatedAt"},...i?.fields,...e.user?.additionalFields},order:1},session:{tableName:e.session?.modelName||"session",fields:{expiresAt:{type:"date",required:!0,fieldName:e.session?.fields?.expiresAt||"expiresAt"},ipAddress:{type:"string",required:!1,fieldName:e.session?.fields?.ipAddress||"ipAddress"},userAgent:{type:"string",required:!1,fieldName:e.session?.fields?.userAgent||"userAgent"},userId:{type:"string",fieldName:e.session?.fields?.userId||"userId",references:{model:e.user?.modelName||"user",field:"id",onDelete:"cascade"},required:!0},...n?.fields,...e.session?.additionalFields},order:2},account:{tableName:e.account?.modelName||"account",fields:{accountId:{type:"string",required:!0,fieldName:e.account?.fields?.accountId||"accountId"},providerId:{type:"string",required:!0,fieldName:e.account?.fields?.providerId||"providerId"},userId:{type:"string",references:{model:e.user?.modelName||"user",field:"id",onDelete:"cascade"},required:!0,fieldName:e.account?.fields?.userId||"userId"},accessToken:{type:"string",required:!1,fieldName:e.account?.fields?.accessToken||"accessToken"},refreshToken:{type:"string",required:!1,fieldName:e.account?.fields?.refreshToken||"refreshToken"},idToken:{type:"string",required:!1,fieldName:e.account?.fields?.idToken||"idToken"},expiresAt:{type:"date",required:!1,fieldName:e.account?.fields?.expiresAt||"expiresAt"},password:{type:"string",required:!1,fieldName:e.account?.fields?.password||"password"},...a?.fields},order:3},verification:{tableName:e.verification?.modelName||"verification",fields:{identifier:{type:"string",required:!0,fieldName:e.verification?.fields?.identifier||"identifier"},value:{type:"string",required:!0,fieldName:e.verification?.fields?.value||"value"},expiresAt:{type:"date",required:!0,fieldName:e.verification?.fields?.expiresAt||"expiresAt"}},order:4},...c,...r?o:{}}};import{Kysely as St,MssqlDialect as Or}from"kysely";import{MysqlDialect as Pt,PostgresDialect as Lt,SqliteDialect as _t}from"kysely";function Ct(e){if("dialect"in e)return Ct(e.dialect);if("createDriver"in e){if(e instanceof _t)return"sqlite";if(e instanceof Pt)return"mysql";if(e instanceof Lt)return"postgres";if(e instanceof Or)return"mssql"}return"aggregate"in e?"sqlite":"getConnection"in e?"mysql":"connect"in e?"postgres":null}var W=async e=>{let t=e.database;if("db"in t)return{kysely:t.db,databaseType:t.type};if("dialect"in t)return{kysely:new St({dialect:t.dialect}),databaseType:t.type};let r,o=Ct(t);return"createDriver"in t&&(r=t),"aggregate"in t&&(r=new _t({database:t})),"getConnection"in t&&(r=new Pt({pool:t})),"connect"in t&&(r=new Lt({pool:t})),{kysely:r?new St({dialect:r}):null,databaseType:o}};function J(e){if(!e)return{and:null,or:null};let t={and:[],or:[]};return e.forEach(r=>{let{field:o,value:i,operator:n="=",connector:a="AND"}=r,c=s=>n.toLowerCase()==="in"?s(o,"in",Array.isArray(i)?i:[i]):n==="contains"?s(o,"like",`%${i}%`):n==="starts_with"?s(o,"like",`${i}%`):n==="ends_with"?s(o,"like",`%${i}`):s(o,n,i);a==="OR"?t.or.push(c):t.and.push(c)}),{and:t.and.length?t.and:null,or:t.or.length?t.or:null}}function ie(e,t,r){for(let o in e){let i=t[o]||Object.values(t).find(n=>n.fieldName===o);e[o]===0&&i.type==="boolean"&&r?.boolean&&(e[o]=!1),e[o]===1&&i?.type==="boolean"&&r?.boolean&&(e[o]=!0),i?.type==="date"&&(e[o]instanceof Date||(e[o]=new Date(e[o])))}return e}function Bt(e,t){for(let r in e)typeof e[r]=="boolean"&&t?.boolean&&(e[r]=e[r]?1:0),e[r]instanceof Date&&(e[r]=e[r].toISOString());return e}var Dt=(e,t)=>({id:"kysely",async create(r){let{model:o,data:i,select:n}=r;t?.transform&&(i=Bt(i,t.transform)),t?.generateId!==void 0&&(i.id=t.generateId?t.generateId():void 0);let a=await e.insertInto(o).values(i).returningAll().executeTakeFirst();if(t?.transform){let c=t.transform.schema[o];a=c?ie(i,c,t.transform):a}return n?.length&&(a=a?n.reduce((s,d)=>a?.[d]?{...s,[d]:a[d]}:s,{}):null),a},async findOne(r){let{model:o,where:i,select:n}=r,{and:a,or:c}=J(i),s=e.selectFrom(o).selectAll();a&&(s=s.where(l=>l.and(a.map(p=>p(l))))),c&&(s=s.where(l=>l.or(c.map(p=>p(l)))));let d=await s.executeTakeFirst();if(n?.length&&(d=d?n.reduce((p,u)=>d?.[u]?{...p,[u]:d[u]}:p,{}):null),t?.transform){let l=t.transform.schema[o];return d=d&&l?ie(d,l,t.transform):d,d||null}return d||null},async findMany(r){let{model:o,where:i,limit:n,offset:a,sortBy:c}=r,s=e.selectFrom(o),{and:d,or:l}=J(i);d&&(s=s.where(u=>u.and(d.map(f=>f(u))))),l&&(s=s.where(u=>u.or(l.map(f=>f(u))))),s=s.limit(n||100),a&&(s=s.offset(a)),c&&(s=s.orderBy(c.field,c.direction));let p=await s.selectAll().execute();if(t?.transform){let u=t.transform.schema[o];return u?p.map(f=>ie(f,u,t.transform)):p}return p},async update(r){let{model:o,where:i,update:n}=r,{and:a,or:c}=J(i);t?.transform&&(n=Bt(n,t.transform)),n.id&&(n.id=void 0);let s=e.updateTable(o).set(n);a&&(s=s.where(l=>l.and(a.map(p=>p(l))))),c&&(s=s.where(l=>l.or(c.map(p=>p(l)))));let d=await s.returningAll().executeTakeFirst()||null;if(t?.transform){let l=t.transform.schema[o];return l?ie(d,l,t.transform):d}return d},async delete(r){let{model:o,where:i}=r,{and:n,or:a}=J(i),c=e.deleteFrom(o);n&&(c=c.where(s=>s.and(n.map(d=>d(s))))),a&&(c=c.where(s=>s.or(a.map(d=>d(s))))),await c.execute()},async deleteMany(r){let{model:o,where:i}=r,{and:n,or:a}=J(i),c=e.deleteFrom(o);n&&(c=c.where(s=>s.and(n.map(d=>d(s))))),a&&(c=c.where(s=>s.or(a.map(d=>d(s))))),await c.execute()}});async function Ft(e){if(!e.database)throw new k("Database configuration is required");if("create"in e.database)return e.database;let{kysely:t,databaseType:r}=await W(e);if(!t)throw new k("Failed to initialize database adapter");let o=D(e),i={};for(let n of Object.values(o))i[n.tableName]=n.fields;return Dt(t,{transform:{schema:i,date:!0,boolean:r==="sqlite"},generateId:"generateId"in e.database?e.database.generateId:void 0})}function me(e,t){let r={id:t.id};for(let o in e){let i=e[o],n=t[o];r[i.fieldName||o]=n}return r}function O(e,t){if(!t)return null;let r={id:t.id};for(let[o,i]of Object.entries(e))r[o]=t[i.fieldName||o];return r}function Nt(e,t){let r=t.hooks,o=D(t.options);async function i(a,c,s){let d=a,l=o[c];for(let f of r||[]){let m=f[c]?.create?.before;if(m){let h=await m(a);if(h===!1)return null;typeof h=="object"&&"data"in h&&(d=h.data)}}let p=s?await s.fn(d):null,u=!s||s.executeMainFn?await e.create({model:l.tableName,data:{...me(l.fields,d),id:d.id||v()}}):p;for(let f of r||[]){let m=f[c]?.create?.after;m&&await m(u)}return O(l.fields,u)}async function n(a,c,s,d){let l=a;for(let f of r||[]){let m=f[s]?.update?.before;if(m){let h=await m(a);if(h===!1)return null;l=typeof h=="object"?h.data:h}}let p=d?await d.fn(l):null,u=!d||d.executeMainFn?await e.update({model:o[s].tableName,update:me(o[s].fields,l),where:c}):p;for(let f of r||[]){let m=f[s]?.update?.after;m&&await m(u)}return O(o[s].fields,u)}return{createWithHooks:i,updateWithHooks:n}}var ge=(e,t)=>{let r=t.options,o=r.secondaryStorage,i=r.session?.expiresIn||60*60*24*7,n=D(r),{createWithHooks:a,updateWithHooks:c}=Nt(e,t);return{createOAuthUser:async(s,d)=>{try{let l=await a({id:v(),createdAt:new Date,updatedAt:new Date,...s},"user"),p=await a({id:v(),...d,userId:l.id||s.id},"account");return{user:l,account:p}}catch(l){return console.log(l),null}},createUser:async s=>await a({id:v(),createdAt:new Date,updatedAt:new Date,emailVerified:!1,...s},"user"),createAccount:async s=>await a({id:v(),createdAt:new Date,updatedAt:new Date,...s},"account"),listSessions:async s=>await e.findMany({model:n.session.tableName,where:[{field:n.session.fields.userId.fieldName||"userId",value:s}]}),listUsers:async(s,d,l,p)=>(await e.findMany({model:n.user.tableName,limit:s,offset:d,sortBy:l,where:p})).map(f=>O(n.user.fields,f)),deleteUser:async s=>{await e.delete({model:n.account.tableName,where:[{field:n.account.fields.userId.fieldName||"userId",value:s}]}),await e.deleteMany({model:n.session.tableName,where:[{field:n.session.fields.userId.fieldName||"userId",value:s}]}),await e.deleteMany({model:n.user.tableName,where:[{field:"id",value:s}]})},createSession:async(s,d,l,p)=>{let u=d instanceof Request?d.headers:d,f={id:v(),userId:s,expiresAt:l?V(60*60*24,"sec"):V(i,"sec"),ipAddress:d&&ne(d)||"",userAgent:u?.get("user-agent")||"",...p};return await a(f,"session",o?{fn:async h=>{let g=await e.findOne({model:n.user.tableName,where:[{field:"id",value:s}]});return o.set(h.id,JSON.stringify({session:h,user:g}),i),h},executeMainFn:r.session?.storeSessionInDatabase}:void 0)},findSession:async s=>{if(o){let p=await o.get(s);if(p){let u=JSON.parse(p);return{session:{...u.session,expiresAt:new Date(u.session.expiresAt)},user:{...u.user,createdAt:new Date(u.user.createdAt),updatedAt:new Date(u.user.updatedAt)}}}}let d=await e.findOne({model:n.session.tableName,where:[{value:s,field:"id"}]});if(!d)return null;let l=await e.findOne({model:n.user.tableName,where:[{value:d.userId,field:"id"}]});return l?{session:O(n.session.fields,d),user:O(n.user.fields,l)}:null},findSessions:async s=>{if(o){let u=[];for(let f of s){let m=await o.get(f);if(m){let h=JSON.parse(m),g={session:{...h.session,expiresAt:new Date(h.session.expiresAt)},user:{...h.user,createdAt:new Date(h.user.createdAt),updatedAt:new Date(h.user.updatedAt)}};u.push(g)}}return u}let d=await e.findMany({model:n.session.tableName,where:[{field:"id",value:s,operator:"in"}]}),l=d.map(u=>u.userId);if(!l.length)return[];let p=await e.findMany({model:n.user.tableName,where:[{field:"id",value:l,operator:"in"}]});return d.map(u=>{let f=p.find(m=>m.id===u.userId);return f?{session:O(n.session.fields,u),user:O(n.user.fields,f)}:null})},updateSession:async(s,d)=>await c(d,[{field:"id",value:s}],"session",o?{async fn(p){let u=await o.get(s),f=null;if(u){let m=JSON.parse(u);f={...m.session,...p},await o.set(s,JSON.stringify({session:f,user:m.user}),m.session.expiresAt?new Date(m.session.expiresAt).getTime():void 0)}else return null},executeMainFn:r.session?.storeSessionInDatabase}:void 0),deleteSession:async s=>{if(o){await o.delete(s),r.session?.storeSessionInDatabase&&await e.delete({model:n.session.tableName,where:[{field:"id",value:s}]});return}await e.delete({model:n.session.tableName,where:[{field:"id",value:s}]})},deleteSessions:async s=>{if(o){let d=await e.findMany({model:n.session.tableName,where:[{field:n.session.fields.userId.fieldName||"userId",value:s}]});for(let l of d)await o.delete(l.id);r.session?.storeSessionInDatabase&&await e.delete({model:n.session.tableName,where:[{field:n.session.fields.userId.fieldName||"userId",value:s}]});return}await e.delete({model:n.session.tableName,where:[{field:n.session.fields.userId.fieldName||"userId",value:s}]})},findUserByEmail:async(s,d)=>{let l=await e.findOne({model:n.user.tableName,where:[{value:s.toLowerCase(),field:n.user.fields.email.fieldName||"email"}]});if(!l)return null;if(d?.includeAccounts){let p=await e.findMany({model:n.account.tableName,where:[{value:l.id,field:n.account.fields.userId.fieldName||"userId"}]});return{user:O(n.user.fields,l),accounts:p.map(u=>O(n.account.fields,u))}}return{user:O(n.user.fields,l),accounts:[]}},findUserById:async s=>await e.findOne({model:n.user.tableName,where:[{field:"id",value:s}]}),linkAccount:async s=>await a({id:v(),...s},"account"),updateUser:async(s,d)=>await c(d,[{field:"id",value:s}],"user"),updateUserByEmail:async(s,d)=>await c(d,[{field:n.user.fields.email.fieldName||"email",value:s}],"user"),updatePassword:async(s,d)=>await c({password:d},[{field:n.account.fields.userId.fieldName||"userId",value:s},{field:n.account.fields.providerId.fieldName||"providerId",value:"credential"}],"account"),findAccounts:async s=>(await e.findMany({model:n.account.tableName,where:[{field:n.account.fields.userId.fieldName||"userId",value:s}]})).map(l=>O(n.account.fields,l)),updateAccount:async(s,d)=>await c(d,[{field:"id",value:s}],"account"),createVerificationValue:async s=>await a({id:v(),...s},"verification"),findVerificationValue:async s=>{let d=await e.findOne({model:n.verification.tableName,where:[{field:n.verification.fields.identifier.fieldName||"identifier",value:s}]});return O(n.verification.fields,d)},deleteVerificationValue:async s=>{await e.delete({model:n.verification.tableName,where:[{field:"id",value:s}]})},updateVerificationValue:async(s,d)=>await c(d,[{field:"id",value:s}],"verification")}};import{z as td}from"zod";import"kysely";import{env as we,isProduction as qt}from"std-env";import{defu as Sr}from"defu";import{env as j}from"std-env";function Ir(e){try{return new URL(e).pathname!=="/"}catch{throw new k(`Invalid base URL: ${e}. Please provide a valid base URL.`)}}function he(e,t="/api/auth"){return Ir(e)?e:(t=t.startsWith("/")?t:`/${t}`,`${e}${t}`)}function X(e,t){if(e)return he(e,t);let r=j.BETTER_AUTH_URL||j.NEXT_PUBLIC_BETTER_AUTH_URL||j.PUBLIC_BETTER_AUTH_URL||j.NUXT_PUBLIC_BETTER_AUTH_URL||j.NUXT_PUBLIC_AUTH_URL||(j.BASE_URL!=="/"?j.BASE_URL:void 0);if(r)return he(r,t);if(typeof window<"u")return he(window.location.origin,t)}var ye="better-auth-secret-123456789";var Vt=async e=>{let t=await Ft(e),r=e.plugins||[],o=Lr(e),{kysely:i}=await W(e),n=X(e.baseURL,e.basePath);if(!n)throw new k("Base URL can not be empty. Please add `BETTER_AUTH_URL` in your environment variables or pass it your auth config.");let a=e.secret||we.BETTER_AUTH_SECRET||we.AUTH_SECRET||ye;if(a===ye&&qt)throw new k("You are using the default secret. Please set `BETTER_AUTH_SECRET` or `AUTH_SECRET` in your environment variables or pass `secret` in your auth config.");e={...e,secret:a,baseURL:n?new URL(n).origin:"",basePath:e.basePath||"/api/auth",plugins:r.concat(o),emailAndPassword:{...e.emailAndPassword,enabled:e.emailAndPassword?.enabled??!1,autoSignIn:e.emailAndPassword?.autoSignIn??!0}};let c=Ne(e),s=D(e),d=Object.keys(e.socialProviders||{}).map(u=>{let f=e.socialProviders?.[u];return f.enabled===!1?null:((!f.clientId||!f.clientSecret)&&b.warn(`Social provider ${u} is missing clientId or clientSecret`),le[u](f))}).filter(u=>u!==null),l={appName:e.appName||"Better Auth",socialProviders:d,options:e,tables:s,trustedOrigins:_r(e),baseURL:n,sessionConfig:{updateAge:e.session?.updateAge||24*60*60,expiresIn:e.session?.expiresIn||60*60*24*7},secret:a,rateLimit:{...e.rateLimit,enabled:e.rateLimit?.enabled??qt,window:e.rateLimit?.window||10,max:e.rateLimit?.max||100,storage:e.rateLimit?.storage||e.secondaryStorage?"secondary-storage":"memory"},authCookies:c,logger:de({disabled:e.logger?.disabled||!1}),db:i,uuid:v,secondaryStorage:e.secondaryStorage,password:{hash:e.emailAndPassword?.password?.hash||ke,verify:e.emailAndPassword?.password?.verify||Re,config:{minPasswordLength:e.emailAndPassword?.minPasswordLength||8,maxPasswordLength:e.emailAndPassword?.maxPasswordLength||128}},adapter:t,internalAdapter:ge(t,{options:e,hooks:e.databaseHooks?[e.databaseHooks]:[]}),createAuthCookie:qe(e)},{context:p}=Pr(l);return p};function Pr(e){let t=e.options,r=t.plugins||[],o=e,i=[];for(let n of r)if(n.init){let a=n.init(e);typeof a=="object"&&(a.options&&(a.options.databaseHooks&&i.push(a.options.databaseHooks),t=Sr(t,a.options)),a.context&&(o={...o,...a.context}))}return i.push(t.databaseHooks),o.internalAdapter=ge(e.adapter,{options:t,hooks:i.filter(n=>n!==void 0)}),o.options=t,{context:o}}function Lr(e){let t=[];return e.advanced?.crossSubDomainCookies?.enabled,t}function _r(e){let t=X(e.baseURL,e.basePath);if(!t)throw new k("Base URL can not be empty. Please add `BETTER_AUTH_URL` in your environment variables or pass it in your auth config.");let r=[new URL(t).origin];e.trustedOrigins&&r.push(...e.trustedOrigins);let o=we.BETTER_AUTH_TRUSTED_ORIGINS;return o&&r.push(...o.split(",")),r}var zd=e=>{let t=Vt(e),{api:r}=fe(t,e);return{handler:async o=>{let i=await t,n=i.options.basePath||"/api/auth",a=new URL(o.url);if(!i.options.baseURL){let s=X(void 0,n)||`${a.origin}${n}`;i.options.baseURL=s,i.baseURL=s}if(!i.options.baseURL)return new Response("Base URL not set",{status:400});if(a.pathname===n||a.pathname===`${n}/`)return new Response("Welcome to BetterAuth",{status:200});let{handler:c}=It(i,e);return c(o)},api:r,options:e,$Infer:{}}};export{k as BetterAuthError,F as HIDE_METADATA,De as MissingDependencyError,zd as betterAuth,xn as capitalizeFirstLetter,qe as createCookieGetter,de as createLogger,G as deleteSessionCookie,v as generateId,Be as generateState,Ne as getCookies,b as logger,vo as parseCookies,Eo as parseSetCookieHeader,ae as parseState,L as setSessionCookie};
package/dist/node.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import * as http from 'http';
2
2
  import { IncomingHttpHeaders } from 'http';
3
- import { a as Auth } from './auth-DhjJVba-.js';
3
+ import { a as Auth } from './auth-DFDxqxWC.js';
4
4
  import 'zod';
5
5
  import 'kysely';
6
6
  import './schema-Dkt0LqYs.js';
package/dist/plugins.d.ts CHANGED
@@ -1,7 +1,7 @@
1
- export { A as AnonymousOptions, O as OrganizationOptions, b as Passkey, P as PasskeyOptions, U as UserWithPhoneNumber, f as UserWithRole, i as admin, h as adminMiddleware, e as anonymous, j as genericOAuth, g as getPasskeyActions, m as magicLink, k as multiSession, o as organization, p as passkey, c as passkeyClient, d as phoneNumber, t as twoFactor, a as twoFactorClient, u as username } from './index-B5i5YhzD.js';
1
+ export { A as AnonymousOptions, O as OrganizationOptions, b as Passkey, P as PasskeyOptions, U as UserWithPhoneNumber, f as UserWithRole, i as admin, h as adminMiddleware, e as anonymous, j as genericOAuth, g as getPasskeyActions, m as magicLink, k as multiSession, o as organization, p as passkey, c as passkeyClient, d as phoneNumber, t as twoFactor, a as twoFactorClient, u as username } from './index-C5jX2KrN.js';
2
2
  export { i as ac } from './index-DfAHOgpj.js';
3
- import { H as HookEndpointContext, P as PluginSchema } from './auth-DhjJVba-.js';
4
- export { e as AuthEndpoint, f as AuthMiddleware, b as BetterAuthPlugin, d as createAuthEndpoint, c as createAuthMiddleware, o as optionsMiddleware } from './auth-DhjJVba-.js';
3
+ import { H as HookEndpointContext, P as PluginSchema } from './auth-DFDxqxWC.js';
4
+ export { e as AuthEndpoint, f as AuthMiddleware, b as BetterAuthPlugin, d as createAuthEndpoint, c as createAuthMiddleware, o as optionsMiddleware } from './auth-DFDxqxWC.js';
5
5
  export { H as HIDE_METADATA } from './hide-metadata-DEHJp1rk.js';
6
6
  import { U as User } from './schema-Dkt0LqYs.js';
7
7
  import * as better_call from 'better-call';
package/dist/plugins.js CHANGED
@@ -81,4 +81,4 @@ Error: `,h),e.redirect(`${e.context.baseURL}/error?error=internal_server_error`)
81
81
  </div>
82
82
  </body>
83
83
  </html>`,po=u("/error",{method:"GET",metadata:se},async e=>{let t=new URL(e.request?.url||"").searchParams.get("error")||"Unknown";return new Response(lo(t),{headers:{"Content-Type":"text/html"}})});var mo=u("/ok",{method:"GET",metadata:se},async e=>e.json({ok:!0}));import{z as Za}from"zod";import{APIError as od}from"better-call";var Pt=(e,t)=>{let r={};for(let[o,n]of Object.entries(e))r[o]=i=>n({...i,context:{...t,...i.context}}),r[o].path=n.path,r[o].method=n.method,r[o].options=n.options,r[o].headers=n.headers;return r};var Dt={};hr(Dt,{AccessControl:()=>Re,ParsingError:()=>ue,Role:()=>ye,adminAc:()=>Bt,createAccessControl:()=>Ct,defaultAc:()=>Fe,defaultRoles:()=>Je,defaultStatements:()=>_t,memberAc:()=>Lt,ownerAc:()=>zt,permissionFromString:()=>fo});var ue=class extends Error{path;constructor(t,r){super(t),this.path=r}},Re=class{constructor(t){this.s=t;this.statements=t}statements;newRole(t){return new ye(t)}},ye=class e{statements;constructor(t){this.statements=t}authorize(t,r){for(let[o,n]of Object.entries(t)){let i=this.statements[o];if(!i)return{success:!1,error:`You are not allowed to access resource: ${o}`};let a=r==="OR"?n.some(s=>i.includes(s)):n.every(s=>i.includes(s));return a?{success:a}:{success:!1,error:`unauthorized to access resource "${o}"`}}return{success:!1,error:"Not authorized"}}static fromString(t){let r=JSON.parse(t);if(typeof r!="object")throw new ue("statements is not an object",".");for(let[o,n]of Object.entries(r)){if(typeof o!="string")throw new ue("invalid resource identifier",o);if(!Array.isArray(n))throw new ue("actions is not an array",o);for(let i=0;i<n.length;i++)if(typeof n[i]!="string")throw new ue("action is not a string",`${o}[${i}]`)}return new e(r)}toString(){return JSON.stringify(this.statements)}};var Ct=e=>new Re(e),_t={organization:["update","delete"],member:["create","update","delete"],invitation:["create","cancel"]},Fe=Ct(_t),Bt=Fe.newRole({organization:["update"],invitation:["create","cancel"],member:["create","update","delete"]}),zt=Fe.newRole({organization:["update","delete"],member:["create","update","delete"],invitation:["create","cancel"]}),Lt=Fe.newRole({organization:[],member:[],invitation:[]}),Je={admin:Bt,owner:zt,member:Lt};var fo=e=>ye.fromString(e??"");var T=(e,t)=>{let r=e.adapter;return{findOrganizationBySlug:async o=>await r.findOne({model:"organization",where:[{field:"slug",value:o}]}),createOrganization:async o=>{let n=await r.create({model:"organization",data:{...o.organization,metadata:o.organization.metadata?JSON.stringify(o.organization.metadata):void 0}}),i=await r.create({model:"member",data:{id:P(),organizationId:n.id,userId:o.user.id,createdAt:new Date,email:o.user.email,role:t?.creatorRole||"owner"}});return{...n,metadata:n.metadata?JSON.parse(n.metadata):void 0,members:[{...i,user:{id:o.user.id,name:o.user.name,email:o.user.email,image:o.user.image}}]}},findMemberByEmail:async o=>{let n=await r.findOne({model:"member",where:[{field:"email",value:o.email},{field:"organizationId",value:o.organizationId}]});if(!n)return null;let i=await r.findOne({model:e.tables.user.tableName,where:[{field:"id",value:n.userId}]});return i?{...n,user:{id:i.id,name:i.name,email:i.email,image:i.image}}:null},findMemberByOrgId:async o=>{let[n,i]=await Promise.all([await r.findOne({model:"member",where:[{field:"userId",value:o.userId},{field:"organizationId",value:o.organizationId}]}),await r.findOne({model:e.tables.user.tableName,where:[{field:"id",value:o.userId}]})]);return!i||!n?null:{...n,user:{id:i.id,name:i.name,email:i.email,image:i.image}}},findMemberById:async o=>{let n=await r.findOne({model:"member",where:[{field:"id",value:o}]});if(!n)return null;let i=await r.findOne({model:e.tables.user.tableName,where:[{field:"id",value:n.userId}]});return i?{...n,user:{id:i.id,name:i.name,email:i.email,image:i.image}}:null},createMember:async o=>await r.create({model:"member",data:o}),updateMember:async(o,n)=>await r.update({model:"member",where:[{field:"id",value:o}],update:{role:n}}),deleteMember:async o=>await r.delete({model:"member",where:[{field:"id",value:o}]}),updateOrganization:async(o,n)=>await r.update({model:"organization",where:[{field:"id",value:o}],update:n}),deleteOrganization:async o=>(await r.delete({model:"member",where:[{field:"organizationId",value:o}]}),await r.delete({model:"invitation",where:[{field:"organizationId",value:o}]}),await r.delete({model:"organization",where:[{field:"id",value:o}]}),o),setActiveOrganization:async(o,n)=>await r.update({model:e.tables.session.tableName,where:[{field:"id",value:o}],update:{activeOrganizationId:n}}),findOrganizationById:async o=>await r.findOne({model:"organization",where:[{field:"id",value:o}]}),findFullOrganization:async(o,n)=>{let[i,a,s]=await Promise.all([r.findOne({model:"organization",where:[{field:"id",value:o}]}),r.findMany({model:"invitation",where:[{field:"organizationId",value:o}]}),r.findMany({model:"member",where:[{field:"organizationId",value:o}]})]);if(!i)return null;let d=s.map(f=>f.userId),c=await r.findMany({model:e.tables.user.tableName,where:[{field:"id",value:d,operator:"in"}]}),l=new Map(c.map(f=>[f.id,f])),p=s.map(f=>{let g=l.get(f.userId);if(!g)throw new $("Unexpected error: User not found for member");return{...f,user:{id:g.id,name:g.name,email:g.email,image:g.image}}});return{...i,invitations:a,members:p}},listOrganizations:async o=>{let n=await r.findMany({model:"member",where:[{field:"userId",value:o}]});if(!n||n.length===0)return[];let i=n.map(s=>s.organizationId);return await r.findMany({model:"organization",where:[{field:"id",value:i,operator:"in"}]})},createInvitation:async({invitation:o,user:n})=>{let a=Y(t?.invitationExpiresIn||1728e5);return await r.create({model:"invitation",data:{id:P(),email:o.email,role:o.role,organizationId:o.organizationId,status:"pending",expiresAt:a,inviterId:n.id}})},findInvitationById:async o=>await r.findOne({model:"invitation",where:[{field:"id",value:o}]}),findPendingInvitation:async o=>(await r.findMany({model:"invitation",where:[{field:"email",value:o.email},{field:"organizationId",value:o.organizationId},{field:"status",value:"pending"}]})).filter(i=>new Date(i.expiresAt)>new Date),updateInvitation:async o=>await r.update({model:"invitation",where:[{field:"id",value:o.invitationId}],update:{status:o.status}})}};import"better-call";import{APIError as Xd,createRouter as ec,statusCode as tc}from"better-call";import{APIError as Ge}from"better-call";import{z as xt}from"zod";var go=E({body:xt.object({csrfToken:xt.string().optional()}).optional()},async e=>{if(e.request?.method!=="POST"||e.context.options.advanced?.disableCSRFCheck)return;let t=e.headers?.get("origin")||"";if(t){let s=new URL(t).origin;if(e.context.trustedOrigins.includes(s))return}let r=e.body?.csrfToken;if(!r)throw new Ge("UNAUTHORIZED",{message:"CSRF Token is required"});let o=await e.getSignedCookie(e.context.authCookies.csrfToken.name,e.context.secret),[n,i]=o?.split("!")||[null,null];if(!r||!n||!i||n!==r)throw e.setCookie(e.context.authCookies.csrfToken.name,"",{maxAge:0}),new Ge("UNAUTHORIZED",{message:"Invalid CSRF Token"});let a=await G(e.context.secret,n);if(i!==a)throw e.setCookie(e.context.authCookies.csrfToken.name,"",{maxAge:0}),new Ge("UNAUTHORIZED",{message:"Invalid CSRF Token"})});import{isTest as Fd}from"std-env";import{APIError as M}from"better-call";var B=E(async e=>({})),x=E({use:[w]},async e=>({session:e.context.session}));import{z as W}from"zod";import{z as O}from"zod";var Me=O.enum(["admin","member","owner"]),ho=O.enum(["pending","accepted","rejected","canceled"]).default("pending"),vc=O.object({id:O.string(),name:O.string(),slug:O.string(),logo:O.string().optional(),metadata:O.record(O.string()).or(O.string().transform(e=>JSON.parse(e))).optional(),createdAt:O.date()}),Ic=O.object({id:O.string(),email:O.string(),organizationId:O.string(),userId:O.string(),role:Me,createdAt:O.date()}),Uc=O.object({id:O.string(),organizationId:O.string(),email:O.string(),role:Me,status:ho,inviterId:O.string(),expiresAt:O.date()});import{APIError as U}from"better-call";var jt=u("/organization/invite-member",{method:"POST",use:[B,x],body:W.object({email:W.string(),role:Me,organizationId:W.string().optional(),resend:W.boolean().optional()})},async e=>{if(!e.context.orgOptions.sendInvitationEmail)throw b.warn("Invitation email is not enabled. Pass `sendInvitationEmail` to the plugin options to enable it."),new U("BAD_REQUEST",{message:"Invitation email is not enabled"});let t=e.context.session,r=e.body.organizationId||t.session.activeOrganizationId;if(!r)throw new U("BAD_REQUEST",{message:"Organization not found"});let o=T(e.context,e.context.orgOptions),n=await o.findMemberByOrgId({userId:t.user.id,organizationId:r});if(!n)throw new U("BAD_REQUEST",{message:"Member not found!"});let i=e.context.roles[n.role];if(!i)throw new U("BAD_REQUEST",{message:"Role not found!"});if(i.authorize({invitation:["create"]}).error)throw new U("FORBIDDEN",{message:"You are not allowed to invite members"});if(await o.findMemberByEmail({email:e.body.email,organizationId:r}))throw new U("BAD_REQUEST",{message:"User is already a member of this organization"});if((await o.findPendingInvitation({email:e.body.email,organizationId:r})).length&&!e.body.resend)throw new U("BAD_REQUEST",{message:"User is already invited to this organization"});let c=await o.createInvitation({invitation:{role:e.body.role,email:e.body.email,organizationId:r},user:t.user}),l=await o.findOrganizationById(r);if(!l)throw new U("BAD_REQUEST",{message:"Organization not found"});return await e.context.orgOptions.sendInvitationEmail?.({id:c.id,role:c.role,email:c.email,organization:l,inviter:{...n,user:t.user}},e.request),e.json(c)}),Nt=u("/organization/accept-invitation",{method:"POST",body:W.object({invitationId:W.string()}),use:[B,x]},async e=>{let t=e.context.session,r=T(e.context,e.context.orgOptions),o=await r.findInvitationById(e.body.invitationId);if(!o||o.expiresAt<new Date||o.status!=="pending")throw new U("BAD_REQUEST",{message:"Invitation not found!"});if(o.email!==t.user.email)throw new U("FORBIDDEN",{message:"You are not the recipient of the invitation"});let n=await r.updateInvitation({invitationId:e.body.invitationId,status:"accepted"}),i=await r.createMember({id:P(),organizationId:o.organizationId,userId:t.user.id,email:o.email,role:o.role,createdAt:new Date});return await r.setActiveOrganization(t.session.id,o.organizationId),n?e.json({invitation:n,member:i}):e.json(null,{status:400,body:{message:"Invitation not found!"}})}),Ft=u("/organization/reject-invitation",{method:"POST",body:W.object({invitationId:W.string()}),use:[B,x]},async e=>{let t=e.context.session,r=T(e.context,e.context.orgOptions),o=await r.findInvitationById(e.body.invitationId);if(!o||o.expiresAt<new Date||o.status!=="pending")throw new U("BAD_REQUEST",{message:"Invitation not found!"});if(o.email!==t.user.email)throw new U("FORBIDDEN",{message:"You are not the recipient of the invitation"});let n=await r.updateInvitation({invitationId:e.body.invitationId,status:"rejected"});return e.json({invitation:n,member:null})}),Mt=u("/organization/cancel-invitation",{method:"POST",body:W.object({invitationId:W.string()}),use:[B,x]},async e=>{let t=e.context.session,r=T(e.context,e.context.orgOptions),o=await r.findInvitationById(e.body.invitationId);if(!o)throw new U("BAD_REQUEST",{message:"Invitation not found!"});let n=await r.findMemberByOrgId({userId:t.user.id,organizationId:o.organizationId});if(!n)throw new U("BAD_REQUEST",{message:"Member not found!"});if(e.context.roles[n.role].authorize({invitation:["cancel"]}).error)throw new U("FORBIDDEN",{message:"You are not allowed to cancel this invitation"});let a=await r.updateInvitation({invitationId:e.body.invitationId,status:"canceled"});return e.json(a)}),qt=u("/organization/get-invitation",{method:"GET",use:[B],requireHeaders:!0,query:W.object({id:W.string()})},async e=>{let t=await D(e);if(!t)throw new U("UNAUTHORIZED",{message:"Not authenticated"});let r=T(e.context,e.context.orgOptions),o=await r.findInvitationById(e.query.id);if(!o||o.status!=="pending"||o.expiresAt<new Date)throw new U("BAD_REQUEST",{message:"Invitation not found!"});if(o.email!==t.user.email)throw new U("FORBIDDEN",{message:"You are not the recipient of the invitation"});let n=await r.findOrganizationById(o.organizationId);if(!n)throw new U("BAD_REQUEST",{message:"Organization not found"});let i=await r.findMemberByOrgId({userId:o.inviterId,organizationId:o.organizationId});if(!i)throw new U("BAD_REQUEST",{message:"Inviter is no longer a member of the organization"});return e.json({...o,organizationName:n.name,organizationSlug:n.slug,inviterEmail:i.email})});import{z as le}from"zod";import{APIError as ve}from"better-call";var $t=u("/organization/remove-member",{method:"POST",body:le.object({memberIdOrEmail:le.string(),organizationId:le.string().optional()}),use:[B,x]},async e=>{let t=e.context.session,r=e.body.organizationId||t.session.activeOrganizationId;if(!r)return e.json(null,{status:400,body:{message:"No active organization found!"}});let o=T(e.context,e.context.orgOptions),n=await o.findMemberByOrgId({userId:t.user.id,organizationId:r});if(!n)throw new ve("BAD_REQUEST",{message:"Member not found!"});let i=e.context.roles[n.role];if(!i)throw new ve("BAD_REQUEST",{message:"Role not found!"});let a=t.user.email===e.body.memberIdOrEmail||n.id===e.body.memberIdOrEmail;if(a&&n.role===(e.context.orgOptions?.creatorRole||"owner"))throw new ve("BAD_REQUEST",{message:"You cannot leave the organization as the owner"});if(!(a||i.authorize({member:["delete"]}).success))throw new ve("UNAUTHORIZED",{message:"You are not allowed to delete this member"});let c=null;if(e.body.memberIdOrEmail.includes("@")?c=await o.findMemberByEmail({email:e.body.memberIdOrEmail,organizationId:r}):c=await o.findMemberById(e.body.memberIdOrEmail),c?.organizationId!==r)throw new ve("BAD_REQUEST",{message:"Member not found!"});return await o.deleteMember(c.id),t.user.id===c.userId&&t.session.activeOrganizationId===c.organizationId&&await o.setActiveOrganization(t.session.id,null),e.json({member:c})}),Vt=u("/organization/update-member-role",{method:"POST",body:le.object({role:le.enum(["admin","member","owner"]),memberId:le.string(),organizationId:le.string().optional()}),use:[B,x]},async e=>{let t=e.context.session,r=e.body.organizationId||t.session.activeOrganizationId;if(!r)return e.json(null,{status:400,body:{message:"No active organization found!"}});let o=T(e.context,e.context.orgOptions),n=await o.findMemberByOrgId({userId:t.user.id,organizationId:r});if(!n)return e.json(null,{status:400,body:{message:"Member not found!"}});let i=e.context.roles[n.role];if(!i)return e.json(null,{status:400,body:{message:"Role not found!"}});if(i.authorize({member:["update"]}).error||e.body.role==="owner"&&n.role!=="owner")return e.json(null,{body:{message:"You are not allowed to update this member"},status:403});let s=await o.updateMember(e.body.memberId,e.body.role);return s?e.json(s):e.json(null,{status:400,body:{message:"Member not found!"}})});import{z as S}from"zod";import{APIError as pe}from"better-call";var Ht=u("/organization/create",{method:"POST",body:S.object({name:S.string(),slug:S.string(),userId:S.string().optional(),logo:S.string().optional(),metadata:S.record(S.string()).optional()}),use:[B,x]},async e=>{let t=e.context.session.user;if(!t)return e.json(null,{status:401});let r=e.context.orgOptions;if(!(typeof r?.allowUserToCreateOrganization=="function"?await r.allowUserToCreateOrganization(t):r?.allowUserToCreateOrganization===void 0?!0:r.allowUserToCreateOrganization))throw new pe("FORBIDDEN",{message:"You are not allowed to create an organization"});let n=T(e.context,r),i=await n.listOrganizations(t.id);if(typeof r.organizationLimit=="number"?i.length>=r.organizationLimit:typeof r.organizationLimit=="function"?await r.organizationLimit(t):!1)throw new pe("FORBIDDEN",{message:"You have reached the organization limit"});if(await n.findOrganizationBySlug(e.body.slug))throw new pe("BAD_REQUEST",{message:"Organization with this slug already exists"});let d=await n.createOrganization({organization:{id:P(),slug:e.body.slug,name:e.body.name,logo:e.body.logo,createdAt:new Date,metadata:e.body.metadata},user:t});return e.json(d)}),Qt=u("/organization/update",{method:"POST",body:S.object({data:S.object({name:S.string().optional(),slug:S.string().optional()}).partial(),orgId:S.string().optional()}),requireHeaders:!0,use:[B]},async e=>{let t=await e.context.getSession(e);if(!t)throw new pe("UNAUTHORIZED",{message:"User not found"});let r=e.body.orgId||t.session.activeOrganizationId;if(!r)return e.json(null,{status:400,body:{message:"Organization id not found!"}});let o=T(e.context,e.context.orgOptions),n=await o.findMemberByOrgId({userId:t.user.id,organizationId:r});if(!n)return e.json(null,{status:400,body:{message:"User is not a member of this organization!"}});let i=e.context.roles[n.role];if(!i)return e.json(null,{status:400,body:{message:"Role not found!"}});if(i.authorize({organization:["update"]}).error)return e.json(null,{body:{message:"You are not allowed to update this organization"},status:403});let s=await o.updateOrganization(r,e.body.data);return e.json(s)}),Wt=u("/organization/delete",{method:"POST",body:S.object({orgId:S.string()}),requireHeaders:!0,use:[B]},async e=>{let t=await e.context.getSession(e);if(!t)return e.json(null,{status:401});let r=e.body.orgId;if(!r)return e.json(null,{status:400,body:{message:"Organization id not found!"}});let o=T(e.context,e.context.orgOptions),n=await o.findMemberByOrgId({userId:t.user.id,organizationId:r});if(!n)return e.json(null,{status:400,body:{message:"User is not a member of this organization!"}});let i=e.context.roles[n.role];if(!i)return e.json(null,{status:400,body:{message:"Role not found!"}});if(i.authorize({organization:["delete"]}).error)throw new pe("FORBIDDEN",{message:"You are not allowed to delete this organization"});return r===t.session.activeOrganizationId&&await o.setActiveOrganization(t.session.id,null),await o.deleteOrganization(r),e.json(r)}),Kt=u("/organization/get-full",{method:"GET",query:S.object({orgId:S.string().optional()}),requireHeaders:!0,use:[B,x]},async e=>{let t=e.context.session,r=e.query.orgId||t.session.activeOrganizationId;if(!r)return e.json(null,{status:400});let n=await T(e.context,e.context.orgOptions).findFullOrganization(r,e.context.db||void 0);if(!n)throw new pe("BAD_REQUEST",{message:"Organization not found"});return e.json(n)}),Zt=u("/organization/activate",{method:"POST",body:S.object({orgId:S.string().nullable().optional()}),use:[x,B]},async e=>{let t=T(e.context,e.context.orgOptions),r=e.context.session,o=e.body.orgId;if(o===null)return r.session.activeOrganizationId&&await t.setActiveOrganization(r.session.id,null),e.json(null);if(!o){let a=r.session.activeOrganizationId;if(!a)return e.json(null);o=a}if(!await t.findMemberByOrgId({userId:r.user.id,organizationId:o}))throw await t.setActiveOrganization(r.session.id,null),new pe("FORBIDDEN",{message:"You are not a member of this organization"});await t.setActiveOrganization(r.session.id,o);let i=await t.findFullOrganization(o,e.context.db||void 0);return e.json(i)}),Jt=u("/organization/list",{method:"GET",use:[B,x]},async e=>{let r=await T(e.context,e.context.orgOptions).listOrganizations(e.context.session.user.id);return e.json(r)});var du=e=>{let t={createOrganization:Ht,updateOrganization:Qt,deleteOrganization:Wt,setActiveOrganization:Zt,getFullOrganization:Kt,listOrganization:Jt,createInvitation:jt,cancelInvitation:Mt,acceptInvitation:Nt,getInvitation:qt,rejectInvitation:Ft,removeMember:$t,updateMemberRole:Vt},r={...Je,...e?.roles};return{id:"organization",endpoints:{...Pt(t,{orgOptions:e||{},roles:r,getSession:async n=>await D(n)}),hasPermission:u("/organization/has-permission",{method:"POST",requireHeaders:!0,body:Ie.object({permission:Ie.record(Ie.string(),Ie.array(Ie.string()))}),use:[x]},async n=>{if(!n.context.session.session.activeOrganizationId)throw new Gt("BAD_REQUEST",{message:"No active organization"});let a=await T(n.context).findMemberByOrgId({userId:n.context.session.user.id,organizationId:n.context.session.session.activeOrganizationId||""});if(!a)throw new Gt("UNAUTHORIZED",{message:"You are not a member of this organization"});let d=r[a.role].authorize(n.body.permission);return d.error?n.json({error:d.error,success:!1},{status:403}):n.json({error:null,success:!0})})},schema:{session:{fields:{activeOrganizationId:{type:"string",required:!1}}},organization:{fields:{name:{type:"string",required:!0},slug:{type:"string",unique:!0},logo:{type:"string",required:!1},createdAt:{type:"date",required:!0},metadata:{type:"string",required:!1}}},member:{fields:{organizationId:{type:"string",required:!0,references:{model:"organization",field:"id"}},userId:{type:"string",required:!0},email:{type:"string",required:!0},role:{type:"string",required:!0,defaultValue:"member"},createdAt:{type:"date",required:!0}}},invitation:{fields:{organizationId:{type:"string",required:!0,references:{model:"organization",field:"id"}},email:{type:"string",required:!0},role:{type:"string",required:!1},status:{type:"string",required:!0,defaultValue:"pending"},expiresAt:{type:"date",required:!0},inviterId:{type:"string",references:{model:"user",field:"id"},required:!0}}}},$Infer:{Organization:{},Invitation:{},Member:{},ActiveOrganization:{}}}};import{z as He}from"zod";import{z as Ee}from"zod";import{APIError as de}from"better-call";var qe="two-factor";var $e="trust-device";import{z as Yt}from"zod";var me=E({body:Yt.object({trustDevice:Yt.boolean().optional()})},async e=>{let t=await D(e);if(!t){let r=e.context.createAuthCookie(qe),o=await e.getSignedCookie(r.name,e.context.secret);if(!o)throw new de("UNAUTHORIZED",{message:"invalid two factor cookie"});let[n,i]=o.split("!");if(!n||!i)throw new de("UNAUTHORIZED",{message:"invalid two factor cookie"});let a=await e.context.adapter.findMany({model:e.context.tables.session.tableName,where:[{field:"userId",value:n}]});if(!a.length)throw new de("UNAUTHORIZED",{message:"invalid session"});let s=a.filter(d=>d.expiresAt>new Date);if(!s)throw new de("UNAUTHORIZED",{message:"invalid session"});for(let d of s){let c=await G(e.context.secret,d.id),l=await e.context.adapter.findOne({model:e.context.tables.user.tableName,where:[{field:"id",value:d.userId}]});if(!l)throw new de("UNAUTHORIZED",{message:"invalid session"});if(c===i)return{valid:async()=>{if(await A(e,d.id,!1),e.body.trustDevice){let p=e.context.createAuthCookie($e,{maxAge:2592e3}),f=await G(e.context.secret,`${l.id}!${d.id}`);await e.setSignedCookie(p.name,`${f}!${d.id}`,e.context.secret,p.options)}return e.json({session:d,user:l})},invalid:async()=>{throw new de("UNAUTHORIZED",{message:"invalid two factor authentication"})},session:{id:d.id,userId:d.userId,expiresAt:d.expiresAt,user:l}}}throw new de("UNAUTHORIZED",{message:"invalid two factor cookie"})}return{valid:async()=>e.json({session:t,user:t.user}),invalid:async()=>{throw new de("UNAUTHORIZED",{message:"invalid two factor authentication"})},session:t}});import{APIError as Ue}from"better-call";function wo(e){return Array.from({length:e?.amount??10}).fill(null).map(()=>H(e?.length??10,Q("a-z","0-9"))).map(t=>`${t.slice(0,5)}-${t.slice(5)}`)}async function Ye(e,t){let r=e,o=t?.customBackupCodesGenerate?t.customBackupCodesGenerate():wo(),n=await je({data:JSON.stringify(o),key:r});return{backupCodes:o,encryptedBackupCodes:n}}async function yo(e,t){let r=await Xt(e.backupCodes,t);return r?r.includes(e.code):!1}async function Xt(e,t){let r=Buffer.from(await Ne({key:t,data:e})).toString("utf-8"),o=JSON.parse(r),n=Ee.array(Ee.string()).safeParse(o);return n.success?n.data:null}var er=(e,t)=>({id:"backup_code",endpoints:{verifyBackupCode:u("/two-factor/verify-backup-code",{method:"POST",body:Ee.object({code:Ee.string(),disableSession:Ee.boolean().optional()}),use:[me]},async r=>{let o=r.context.session.user,n=await r.context.adapter.findOne({model:t,where:[{field:"userId",value:o.id}]});if(!n)throw new Ue("BAD_REQUEST",{message:"Backup codes aren't enabled"});if(!yo({backupCodes:n.backupCodes,code:r.body.code},r.context.secret))throw new Ue("BAD_REQUEST",{message:"Invalid backup code"});return r.body.disableSession||await A(r,r.context.session.id),r.json({user:o,session:r.context.session})}),generateBackupCodes:u("/two-factor/generate-backup-codes",{method:"POST",use:[w]},async r=>{if(!r.context.session.user.twoFactorEnabled)throw new Ue("BAD_REQUEST",{message:"Two factor isn't enabled"});let n=await Ye(r.context.secret,e);return await r.context.adapter.update({model:t,update:{backupCodes:n.encryptedBackupCodes},where:[{field:"userId",value:r.context.session.user.id}]}),r.json({status:!0,backupCodes:n.backupCodes})}),viewBackupCodes:u("/view/backup-codes",{method:"GET",use:[w]},async r=>{let o=r.context.session.user,n=await r.context.adapter.findOne({model:t,where:[{field:"userId",value:o.id}]});if(!n)throw new Ue("BAD_REQUEST",{message:"Backup codes aren't enabled"});let i=Xt(n.backupCodes,r.context.secret);if(!i)throw new Ue("BAD_REQUEST",{message:"Backup codes aren't enabled"});return r.json({status:!0,backupCodes:i})})}});import{APIError as Ve}from"better-call";import{TOTPController as bo}from"oslo/otp";import{z as tr}from"zod";import{TimeSpan as Ao}from"oslo";var rr=(e,t)=>{let r={...e,period:new Ao(e?.period||3,"m")},o=new bo({digits:6,period:r.period}),n=u("/two-factor/send-otp",{method:"POST",use:[me]},async a=>{if(!e||!e.sendOTP)throw a.context.logger.error("send otp isn't configured. Please configure the send otp function on otp options."),new Ve("BAD_REQUEST",{message:"otp isn't configured"});let s=a.context.session.user,d=await a.context.adapter.findOne({model:t,where:[{field:"userId",value:s.id}]});if(!d)throw new Ve("BAD_REQUEST",{message:"OTP isn't enabled"});let c=await o.generate(Buffer.from(d.secret));return await e.sendOTP(s,c),a.json({status:!0})}),i=u("/two-factor/verify-otp",{method:"POST",body:tr.object({code:tr.string()}),use:[me]},async a=>{let s=a.context.session.user;if(!s.twoFactorEnabled)throw new Ve("BAD_REQUEST",{message:"two factor isn't enabled"});let d=await a.context.adapter.findOne({model:t,where:[{field:"userId",value:s.id}]});if(!d)throw new Ve("BAD_REQUEST",{message:"OTP isn't enabled"});return await o.generate(Buffer.from(d.secret))===a.body.code?a.context.valid():a.context.invalid()});return{id:"otp",endpoints:{send2FaOTP:n,verifyOTP:i}}};import{APIError as be}from"better-call";import{TimeSpan as ko}from"oslo";import{TOTPController as or,createTOTPKeyURI as Oo}from"oslo/otp";import{z as nr}from"zod";var ir=(e,t)=>{let r={...e,digits:6,period:new ko(e?.period||30,"s")},o=u("/totp/generate",{method:"POST",use:[w]},async a=>{if(!e)throw a.context.logger.error("totp isn't configured. please pass totp option on two factor plugin to enable totp"),new be("BAD_REQUEST",{message:"totp isn't configured"});let s=a.context.session.user,d=await a.context.adapter.findOne({model:t,where:[{field:"userId",value:s.id}]});if(!d)throw new be("BAD_REQUEST",{message:"totp isn't enabled"});return{code:await new or(r).generate(Buffer.from(d.secret))}}),n=u("/two-factor/get-totp-uri",{method:"GET",use:[w]},async a=>{if(!e)throw a.context.logger.error("totp isn't configured. please pass totp option on two factor plugin to enable totp"),new be("BAD_REQUEST",{message:"totp isn't configured"});let s=a.context.session.user,d=await a.context.adapter.findOne({model:t,where:[{field:"userId",value:s.id}]});if(!d||!s.twoFactorEnabled)throw new be("BAD_REQUEST",{message:"totp isn't enabled"});return{totpURI:Oo(e?.issuer||"BetterAuth",s.email,Buffer.from(d.secret),r)}}),i=u("/two-factor/verify-totp",{method:"POST",body:nr.object({code:nr.string()}),use:[me]},async a=>{if(!e)throw a.context.logger.error("totp isn't configured. please pass totp option on two factor plugin to enable totp"),new be("BAD_REQUEST",{message:"totp isn't configured"});let s=a.context.session.user,d=await a.context.adapter.findOne({model:t,where:[{field:"userId",value:s.id}]});if(!d)throw new be("BAD_REQUEST",{message:"totp isn't enabled"});let c=new or(r),l=await Ne({key:a.context.secret,data:d.secret}),p=Buffer.from(l);return await c.verify(a.body.code,p)?(s.twoFactorEnabled||await a.context.internalAdapter.updateUser(s.id,{twoFactorEnabled:!0}),a.context.valid()):a.context.invalid()});return{id:"totp",endpoints:{generateTOTP:o,viewTOTPURI:n,verifyTOTP:i}}};async function Xe(e,t){let o=(await e.context.internalAdapter.findAccounts(t.userId))?.find(a=>a.providerId==="credential"),n=o?.password;return!o||!n?!1:await e.context.password.verify(n,t.password)}import{APIError as sr}from"better-call";import{createTOTPKeyURI as Ro}from"oslo/otp";import{TimeSpan as vo}from"oslo";var Wu=(e={redirect:!0,twoFactorPage:"/"})=>({id:"two-factor",$InferServerPlugin:{},atomListeners:[{matcher:t=>t.startsWith("/two-factor/"),signal:"_sessionSignal"}],pathMethods:{"/two-factor/disable":"POST","/two-factor/enable":"POST","/two-factor/send-otp":"POST","/two-factor/generate-backup-codes":"POST"},fetchPlugins:[{id:"two-factor",name:"two-factor",hooks:{async onSuccess(t){t.data?.twoFactorRedirect&&(e.redirect||e.twoFactorPage)&&typeof window<"u"&&(window.location.href=e.twoFactorPage)}}}]});var dl=e=>{let t={twoFactorTable:e?.twoFactorTable||"twoFactor"},r=ir({issuer:e?.issuer||"better-auth",...e?.totpOptions},t.twoFactorTable),o=er({...e?.backupCodeOptions},t.twoFactorTable),n=rr({...e?.otpOptions},t.twoFactorTable);return{id:"two-factor",endpoints:{...r.endpoints,...n.endpoints,...o.endpoints,enableTwoFactor:u("/two-factor/enable",{method:"POST",body:He.object({password:He.string().min(8)}),use:[w]},async i=>{let a=i.context.session.user,{password:s}=i.body;if(!await Xe(i,{password:s,userId:a.id}))throw new sr("BAD_REQUEST",{message:"Invalid password"});let c=H(16,Q("a-z","0-9","-")),l=await je({key:i.context.secret,data:c}),p=await Ye(i.context.secret,e?.backupCodeOptions);e?.skipVerificationOnEnable&&await i.context.internalAdapter.updateUser(a.id,{twoFactorEnabled:!0}),await i.context.adapter.deleteMany({model:t.twoFactorTable,where:[{field:"userId",value:a.id}]}),await i.context.adapter.create({model:t.twoFactorTable,data:{id:i.context.uuid(),secret:l,backupCodes:p.encryptedBackupCodes,userId:a.id}});let f=Ro(e?.issuer||"BetterAuth",a.email,Buffer.from(c),{digits:e?.totpOptions?.digits||6,period:new vo(e?.totpOptions?.period||30,"s")});return i.json({totpURI:f,backupCodes:p.backupCodes})}),disableTwoFactor:u("/two-factor/disable",{method:"POST",body:He.object({password:He.string().min(8)}),use:[w]},async i=>{let a=i.context.session.user,{password:s}=i.body;if(!await Xe(i,{password:s,userId:a.id}))throw new sr("BAD_REQUEST",{message:"Invalid password"});return await i.context.internalAdapter.updateUser(a.id,{twoFactorEnabled:!1}),await i.context.adapter.delete({model:t.twoFactorTable,where:[{field:"userId",value:a.id}]}),i.json({status:!0})})},options:e,hooks:{after:[{matcher(i){return i.path==="/sign-in/email"||i.path==="/sign-in/username"},handler:E(async i=>{let a=i.context.returned;if(a?.status!==200)return;let s=await a.clone().json();if(!s.user.twoFactorEnabled)return;let d=i.context.createAuthCookie($e,{maxAge:30*24*60*60}),c=await i.getSignedCookie(d.name,i.context.secret);if(c){let[g,R]=c.split("!"),z=await G(i.context.secret,`${s.user.id}!${R}`);if(g===z){let h=await G(i.context.secret,`${s.user.id}!${s.session.id}`);await i.setSignedCookie(d.name,`${h}!${s.session.id}`,i.context.secret,d.options);return}}i.setCookie(i.context.authCookies.sessionToken.name,"",{path:"/",sameSite:"lax",httpOnly:!0,secure:!1,maxAge:0});let l=await G(i.context.secret,s.session.id),p=i.context.createAuthCookie(qe,{maxAge:60*60*24});return await i.setSignedCookie(p.name,`${s.session.userId}!${l}`,i.context.secret,p.options),{response:new Response(JSON.stringify({twoFactorRedirect:!0}),{headers:i.responseHeader})}})}]},schema:{user:{fields:{twoFactorEnabled:{type:"boolean",required:!1,defaultValue:!1,input:!1}}},twoFactor:{tableName:t.twoFactorTable,fields:{secret:{type:"string",required:!0,returned:!1},backupCodes:{type:"string",required:!0,returned:!1},userId:{type:"string",required:!0,returned:!1,references:{model:"user",field:"id"}}}}},rateLimit:[{pathMatcher(i){return i.startsWith("/two-factor/")},window:10,max:3}]}};import{generateAuthenticationOptions as _o,generateRegistrationOptions as Bo,verifyAuthenticationResponse as zo,verifyRegistrationResponse as Lo}from"@simplewebauthn/server";import{APIError as ee}from"better-call";import{z as re}from"zod";import{env as Do}from"std-env";import{WebAuthnError as Eo,startAuthentication as To,startRegistration as So}from"@simplewebauthn/browser";import{createFetch as vl}from"@better-fetch/fetch";import{env as pl}from"std-env";function ar(e){return new URL(e).origin.replace("http://","").replace("https://","")}import"nanostores";import{betterFetch as hl}from"@better-fetch/fetch";import{atom as Ll}from"nanostores";import"@better-fetch/fetch";import{atom as Io,onMount as Uo}from"nanostores";var et=(e,t,r,o)=>{let n=Io({data:null,error:null,isPending:!1,isRefetching:!1}),i=()=>{let s=typeof o=="function"?o({data:n.get().data,error:n.get().error,isPending:n.get().isPending}):o;return r(t,{...s,onSuccess:async d=>{n.set({data:d.data,error:null,isPending:!1,isRefetching:!1}),await s?.onSuccess?.(d)},async onError(d){n.set({error:d.error,data:null,isPending:!1,isRefetching:!1}),await s?.onError?.(d)},async onRequest(d){let c=n.get();n.set({isPending:c.data===null,data:c.data,error:null,isRefetching:!0}),await s?.onRequest?.(d)}})};e=Array.isArray(e)?e:[e];let a=!1;for(let s of e)s.subscribe(()=>{a?i():Uo(n,()=>(i(),a=!0,()=>{n.off(),s.off()}))});return n};import{atom as Po}from"nanostores";var Co=(e,{_listPasskeys:t})=>({signIn:{passkey:async(n,i)=>{let a=await e("/passkey/generate-authenticate-options",{method:"POST",body:{email:n?.email}});if(!a.data)return a;try{let s=await To(a.data,n?.autoFill||!1),d=await e("/passkey/verify-authentication",{body:{response:s},...n?.fetchOptions,...i,method:"POST"});if(!d.data)return d}catch(s){console.log(s)}}},passkey:{addPasskey:async(n,i)=>{let a=await e("/passkey/generate-register-options",{method:"GET"});if(!a.data)return a;try{let s=await So(a.data),d=await e("/passkey/verify-registration",{...n?.fetchOptions,...i,body:{response:s,name:n?.name},method:"POST"});if(!d.data)return d;t.set(Math.random())}catch(s){return s instanceof Eo?s.code==="ERROR_AUTHENTICATOR_PREVIOUSLY_REGISTERED"?{data:null,error:{message:"previously registered",status:400,statusText:"BAD_REQUEST"}}:s.code==="ERROR_CEREMONY_ABORTED"?{data:null,error:{message:"registration cancelled",status:400,statusText:"BAD_REQUEST"}}:{data:null,error:{message:s.message,status:400,statusText:"BAD_REQUEST"}}:{data:null,error:{message:s instanceof Error?s.message:"unknown error",status:500,statusText:"INTERNAL_SERVER_ERROR"}}}}},$Infer:{}}),ep=()=>{let e=Po();return{id:"passkey",$InferServerPlugin:{},getActions:t=>Co(t,{_listPasskeys:e}),getAtoms(t){return{listPasskeys:et(e,"/passkey/list-user-passkeys",t,{method:"GET",credentials:"include"}),_listPasskeys:e}},pathMethods:{"/passkey/register":"POST","/passkey/authenticate":"POST"},atomListeners:[{matcher(t){return t==="/passkey/verify-registration"||t==="/passkey/delete-passkey"},signal:"_listPasskeys"}]}};var mp=e=>{let t=Do.BETTER_AUTH_URL,r=e?.rpID||t?.replace("http://","").replace("https://","").split(":")[0]||"localhost";if(!r)throw new $("passkey rpID not found. Please provide a rpID in the options or set the BETTER_AUTH_URL environment variable.");let o={origin:null,...e,rpID:r,advanced:{webAuthnChallengeCookie:"better-auth-passkey",...e?.advanced}},n=new Date(Date.now()+1e3*60*5),i=new Date,a=Math.floor((n.getTime()-i.getTime())/1e3);return{id:"passkey",endpoints:{generatePasskeyRegistrationOptions:u("/passkey/generate-register-options",{method:"GET",use:[w],metadata:{client:!1}},async s=>{let d=s.context.session,c=await s.context.adapter.findMany({model:"passkey",where:[{field:"userId",value:d.user.id}]}),l=new Uint8Array(Buffer.from(H(32,Q("a-z","0-9")))),p;p=await Bo({rpName:o.rpName||s.context.appName,rpID:o.rpID,userID:l,userName:d.user.email||d.user.id,attestationType:"none",excludeCredentials:c.map(g=>({id:g.id,transports:g.transports?.split(",")})),authenticatorSelection:{residentKey:"preferred",userVerification:"preferred",authenticatorAttachment:"platform"}});let f=P();return await s.setSignedCookie(o.advanced.webAuthnChallengeCookie,f,s.context.secret,{secure:!0,httpOnly:!0,sameSite:"lax",maxAge:a}),await s.context.internalAdapter.createVerificationValue({identifier:f,value:JSON.stringify({expectedChallenge:p.challenge,userData:{id:d.user.id}}),expiresAt:n}),s.json(p,{status:200})}),generatePasskeyAuthenticationOptions:u("/passkey/generate-authenticate-options",{method:"POST",body:re.object({email:re.string().optional()}).optional()},async s=>{let d=await D(s),c=[];d&&(c=await s.context.adapter.findMany({model:"passkey",where:[{field:"userId",value:d.user.id}]}));let l=await _o({rpID:o.rpID,userVerification:"preferred",...c.length?{allowCredentials:c.map(g=>({id:g.id,transports:g.transports?.split(",")}))}:{}}),p={expectedChallenge:l.challenge,userData:{id:d?.user.id||""}},f=P();return await s.setSignedCookie(o.advanced.webAuthnChallengeCookie,f,s.context.secret,{secure:!0,httpOnly:!0,sameSite:"lax",maxAge:a}),await s.context.internalAdapter.createVerificationValue({identifier:f,value:JSON.stringify(p),expiresAt:n}),s.json(l,{status:200})}),verifyPasskeyRegistration:u("/passkey/verify-registration",{method:"POST",body:re.object({response:re.any(),name:re.string().optional()}),use:[w]},async s=>{let d=e?.origin||s.headers?.get("origin")||"";if(!d)return s.json(null,{status:400});let c=s.body.response,l=await s.getSignedCookie(o.advanced.webAuthnChallengeCookie,s.context.secret);if(!l)throw new ee("BAD_REQUEST",{message:"Challenge not found"});let p=await s.context.internalAdapter.findVerificationValue(l);if(!p)return s.json(null,{status:400});let{expectedChallenge:f,userData:g}=JSON.parse(p.value);if(g.id!==s.context.session.user.id)throw new ee("UNAUTHORIZED",{message:"You are not authorized to register this passkey"});try{let R=await Lo({response:c,expectedChallenge:f,expectedOrigin:d,expectedRPID:e?.rpID}),{verified:z,registrationInfo:h}=R;if(!z||!h)return s.json(null,{status:400});let{credentialID:v,credentialPublicKey:q,counter:K,credentialDeviceType:k,credentialBackedUp:j}=h,ie=Buffer.from(q).toString("base64"),L=P(),Pe={name:s.body.name,userId:g.id,webauthnUserID:L,id:v,publicKey:ie,counter:K,deviceType:k,transports:c.response.transports.join(","),backedUp:j,createdAt:new Date},fr=await s.context.adapter.create({model:"passkey",data:Pe});return s.json(fr,{status:200})}catch(R){throw console.log(R),new ee("INTERNAL_SERVER_ERROR",{message:"Failed to verify registration"})}}),verifyPasskeyAuthentication:u("/passkey/verify-authentication",{method:"POST",body:re.object({response:re.any()})},async s=>{let d=e?.origin||s.headers?.get("origin")||"";if(!d)throw new ee("BAD_REQUEST",{message:"origin missing"});let c=s.body.response,l=await s.getSignedCookie(o.advanced.webAuthnChallengeCookie,s.context.secret);if(!l)throw new ee("BAD_REQUEST",{message:"Challenge not found"});let p=await s.context.internalAdapter.findVerificationValue(l);if(!p)throw new ee("BAD_REQUEST",{message:"Challenge not found"});let{expectedChallenge:f}=JSON.parse(p.value),g=await s.context.adapter.findOne({model:"passkey",where:[{field:"id",value:c.id}]});if(!g)throw new ee("UNAUTHORIZED",{message:"Passkey not found"});try{let R=await zo({response:c,expectedChallenge:f,expectedOrigin:d,expectedRPID:o.rpID,authenticator:{credentialID:g.id,credentialPublicKey:new Uint8Array(Buffer.from(g.publicKey,"base64")),counter:g.counter,transports:g.transports?.split(",")}}),{verified:z}=R;if(!z)throw new ee("UNAUTHORIZED",{message:"Authentication failed"});await s.context.adapter.update({model:"passkey",where:[{field:"id",value:g.id}],update:{counter:R.authenticationInfo.newCounter}});let h=await s.context.internalAdapter.createSession(g.userId,s.request);if(!h)throw new ee("INTERNAL_SERVER_ERROR",{message:"Unable to create session"});return await A(s,h.id),s.json({session:h},{status:200})}catch(R){throw s.context.logger.error(R),new ee("BAD_REQUEST",{message:"Failed to verify authentication"})}}),listPasskeys:u("/passkey/list-user-passkeys",{method:"GET",use:[w]},async s=>{let d=await s.context.adapter.findMany({model:"passkey",where:[{field:"userId",value:s.context.session.user.id}]});return s.json(d,{status:200})}),deletePasskey:u("/passkey/delete-passkey",{method:"POST",body:re.object({id:re.string()}),use:[w]},async s=>(await s.context.adapter.delete({model:"passkey",where:[{field:"id",value:s.body.id}]}),s.json(null,{status:200})))},schema:{passkey:{fields:{name:{type:"string",required:!1},publicKey:{type:"string",required:!0},userId:{type:"string",references:{model:"user",field:"id"},required:!0},webauthnUserID:{type:"string",required:!0},counter:{type:"number",required:!0},deviceType:{type:"string",required:!0},backedUp:{type:"boolean",required:!0},transports:{type:"string",required:!1},createdAt:{type:"date",defaultValue:new Date,required:!1}}}}}};import{z as Qe}from"zod";import{APIError as We}from"better-call";var dr=()=>({id:"username",endpoints:{signInUsername:u("/sign-in/username",{method:"POST",body:Qe.object({username:Qe.string(),password:Qe.string(),dontRememberMe:Qe.boolean().optional()})},async e=>{let t=await e.context.adapter.findOne({model:e.context.tables.user.tableName,where:[{field:"username",value:e.body.username}]});if(!t)throw await e.context.password.hash(e.body.password),e.context.logger.error("User not found",{username:dr}),new We("UNAUTHORIZED",{message:"Invalid username or password"});let r=await e.context.adapter.findOne({model:e.context.tables.account.tableName,where:[{field:e.context.tables.account.fields.userId.fieldName||"userId",value:t.id},{field:e.context.tables.account.fields.providerId.fieldName||"providerId",value:"credential"}]});if(!r)throw new We("UNAUTHORIZED",{message:"Invalid username or password"});let o=r?.password;if(!o)throw e.context.logger.error("Password not found",{username:dr}),new We("UNAUTHORIZED",{message:"Unexpected error"});if(!await e.context.password.verify(o,e.body.password))throw e.context.logger.error("Invalid password"),new We("UNAUTHORIZED",{message:"Invalid username or password"});let i=await e.context.internalAdapter.createSession(t.id,e.request);return i?(await e.setSignedCookie(e.context.authCookies.sessionToken.name,i.id,e.context.secret,e.body.dontRememberMe?{...e.context.authCookies.sessionToken.options,maxAge:void 0}:e.context.authCookies.sessionToken.options),e.json({user:t,session:i})):e.json(null,{status:500,body:{message:"Failed to create session",status:500}})})},schema:{user:{fields:{username:{type:"string",required:!1,unique:!0,returned:!0}}}}});import{serializeSigned as xo}from"better-call";var kp=()=>({id:"bearer",hooks:{before:[{matcher(e){return!!(e.request?.headers.get("authorization")||e.headers?.get("authorization"))},handler:async e=>{let t=e.request?.headers.get("authorization")?.replace("Bearer ","")||e.headers?.get("authorization")?.replace("Bearer ","");if(!t)return;let r="";return t.includes(".")?r=t:r=await xo("",t,e.context.secret),e.request&&e.request.headers.set("cookie",`${e.context.authCookies.sessionToken.name}=${r.replace("=","")}`),e.headers&&e.headers.set("cookie",`${e.context.authCookies.sessionToken.name}=${r.replace("=","")}`),{context:e}}}]}});import{z as Ae}from"zod";import{APIError as jo}from"better-call";var Sp=e=>({id:"magic-link",endpoints:{signInMagicLink:u("/sign-in/magic-link",{method:"POST",requireHeaders:!0,body:Ae.object({email:Ae.string().email(),callbackURL:Ae.string().optional()}),use:[C]},async t=>{let{email:r}=t.body,o=H(32,Q("a-z","A-Z"));await t.context.internalAdapter.createVerificationValue({identifier:o,value:r,expiresAt:new Date(Date.now()+(e.expiresIn||60*5)*1e3)});let n=`${t.context.baseURL}/magic-link/verify?token=${o}&callbackURL=${t.body.callbackURL||"/"}`;try{await e.sendMagicLink({email:r,url:n,token:o})}catch(i){throw t.context.logger.error("Failed to send magic link",i),new jo("INTERNAL_SERVER_ERROR",{message:"Failed to send magic link"})}return t.json({status:!0})}),magicLinkVerify:u("/magic-link/verify",{method:"GET",query:Ae.object({token:Ae.string(),callbackURL:Ae.string().optional()}),requireHeaders:!0},async t=>{let{token:r,callbackURL:o}=t.query,n=o?.startsWith("http")?o:o?`${t.context.options.baseURL}${o}`:t.context.options.baseURL,i=await t.context.internalAdapter.findVerificationValue(r);if(!i)throw t.redirect(`${n}?error=INVALID_TOKEN`);if(i.expiresAt<new Date)throw await t.context.internalAdapter.deleteVerificationValue(i.id),t.redirect(`${n}?error=EXPIRED_TOKEN`);await t.context.internalAdapter.deleteVerificationValue(i.id);let a=i.value,s=await t.context.internalAdapter.findUserByEmail(a),d=s?.user.id||"";if(!s){if(e.disableSignUp)throw t.redirect(`${n}?error=USER_NOT_FOUND`);if(d=(await t.context.internalAdapter.createUser({email:a,emailVerified:!0,name:a})).id,!d)throw t.redirect(`${n}?error=USER_NOT_CREATED`)}let c=await t.context.internalAdapter.createSession(d,t.headers);if(!c)throw t.redirect(`${n}?error=SESSION_NOT_CREATED`);if(await A(t,c.id),!o)return t.json({status:!0});throw t.redirect(o)})},rateLimit:[{pathMatcher(t){return t.startsWith("/sign-in/magic-link")||t.startsWith("/magic-link/verify")},window:e.rateLimit?.window||60,max:e.rateLimit?.max||5}]});import{z as fe}from"zod";import{APIError as oe}from"better-call";function No(e){return H(e,Q("0-9"))}var Np=e=>{let t={phoneNumber:"phoneNumber",phoneNumberVerified:"phoneNumberVerified",code:"code",createdAt:"createdAt",expiresIn:e?.expiresIn||300,otpLength:e?.otpLength||6};return{id:"phone-number",endpoints:{sendPhoneNumberOTP:u("/phone-number/send-otp",{method:"POST",body:fe.object({phoneNumber:fe.string()})},async r=>{if(!e?.sendOTP)throw b.warn("sendOTP not implemented"),new oe("NOT_IMPLEMENTED",{message:"sendOTP not implemented"});let o=No(t.otpLength);return await r.context.internalAdapter.createVerificationValue({value:o,identifier:r.body.phoneNumber,expiresAt:Y(t.expiresIn,"sec")}),await e.sendOTP(r.body.phoneNumber,o),r.json({code:o},{body:{message:"Code sent"}})}),verifyPhoneNumber:u("/phone-number/verify",{method:"POST",body:fe.object({phoneNumber:fe.string(),code:fe.string(),disableSession:fe.boolean().optional(),updatePhoneNumber:fe.boolean().optional()})},async r=>{let o=await r.context.internalAdapter.findVerificationValue(r.body.phoneNumber);if(!o||o.expiresAt<new Date)throw o&&o.expiresAt<new Date?(await r.context.internalAdapter.deleteVerificationValue(o.id),new oe("BAD_REQUEST",{message:"OTP expired"})):new oe("BAD_REQUEST",{message:"OTP not found"});if(o.value!==r.body.code)throw new oe("BAD_REQUEST",{message:"Invalid OTP"});if(await r.context.internalAdapter.deleteVerificationValue(o.id),r.body.updatePhoneNumber){let i=await D(r);if(!i)throw new oe("UNAUTHORIZED",{message:"Session not found"});let a=await r.context.internalAdapter.updateUser(i.user.id,{[t.phoneNumber]:r.body.phoneNumber,[t.phoneNumberVerified]:!0});return r.json({user:a,session:i.session})}let n=await r.context.adapter.findOne({model:r.context.tables.user.tableName,where:[{value:r.body.phoneNumber,field:t.phoneNumber}]});if(n)n=await r.context.internalAdapter.updateUser(n.id,{[t.phoneNumberVerified]:!0});else if(e?.signUpOnVerification){if(n=await r.context.internalAdapter.createUser({email:`temp-${r.body.phoneNumber}`,name:r.body.phoneNumber,[t.phoneNumber]:r.body.phoneNumber,[t.phoneNumberVerified]:!0}),!n)throw new oe("INTERNAL_SERVER_ERROR",{message:"Failed to create user"})}else throw new oe("BAD_REQUEST",{message:"Phone number not found"});if(!n)throw new oe("INTERNAL_SERVER_ERROR",{message:"Failed to update user"});if(!r.body.disableSession){let i=await r.context.internalAdapter.createSession(n.id,r.request);if(!i)throw new oe("INTERNAL_SERVER_ERROR",{message:"Failed to create session"});return await A(r,i.id),r.json({user:n,session:i})}return r.json({user:n,session:null})})},schema:{user:{fields:{phoneNumber:{type:"string",required:!1,unique:!0,returned:!0},phoneNumberVerified:{type:"boolean",required:!1,returned:!0,input:!1}}}}}};import{z as tt}from"zod";var Qp=e=>({id:"anonymous",endpoints:{signInAnonymous:u("/sign-in/anonymous",{method:"POST"},async t=>{let{emailDomainName:r=ar(t.context.baseURL)}=e||{},o=P(),n=`temp-${o}@${r}`,i=await t.context.internalAdapter.createUser({id:o,email:n,emailVerified:!1,isAnonymous:!0,name:"Anonymous",createdAt:new Date,updatedAt:new Date});if(!i)return t.json(null,{status:500,body:{message:"Failed to create user",status:500}});let a=await t.context.internalAdapter.createSession(i.id,t.request);return a?(await A(t,a.id),t.json({user:i,session:a})):t.json(null,{status:400,body:{message:"Could not create session"}})}),linkAnonymous:u("/user/link-anonymous",{method:"POST",body:tt.object({email:tt.string().email().optional(),password:tt.string().min(6)}),use:[w]},async t=>{let r=t.context.session.user.id,{email:o,password:n}=t.body,i=null;if(o&&n&&(i=await t.context.internalAdapter.updateUser(r,{email:o})),!i)return t.json(null,{status:500,body:{message:"Failed to update user",status:500}});let a=await t.context.password.hash(n);if(!await t.context.internalAdapter.linkAccount({userId:i.id,providerId:"credential",password:a,accountId:i.id}))return t.json(null,{status:500,body:{message:"Failed to update account",status:500}});let d=await t.context.internalAdapter.createSession(i.id,t.request);return d?(await A(t,d.id),t.json({session:d,user:i})):t.json(null,{status:400,body:{message:"Could not create session"}})})},schema:{user:{fields:{isAnonymous:{type:"boolean",defaultValue:!0,required:!1}}}}});import{z as m}from"zod";var te=E(async e=>{let t=await D(e);if(!t?.session)throw new M("UNAUTHORIZED");let r=t.user;if(r.role!=="admin")throw new M("FORBIDDEN",{message:"Only admins can access this endpoint"});return{session:{user:r,session:t.session}}}),Yp=e=>({id:"admin",init(t){return{options:{databaseHooks:{user:{create:{async before(r){if(e?.defaultRole!==!1)return{data:{role:e?.defaultRole??"user",...r}}}}},session:{create:{async before(r){let o=await t.internalAdapter.findUserById(r.userId);if(o.banned){if(o.banExpires&&o.banExpires<Date.now()){await t.internalAdapter.updateUser(r.userId,{banned:!1,banReason:null,banExpires:null});return}return!1}}}}}}}},hooks:{after:[{matcher(t){return t.path==="/user/list-sessions"},handler:E(async t=>{let r=t.context.returned;if(r){let n=(await r.json()).filter(a=>!a.impersonatedBy),i=new Response(JSON.stringify(n),{status:200,statusText:"OK",headers:r.headers});return t.json({response:i})}})}]},endpoints:{setRole:u("/admin/set-role",{method:"POST",body:m.object({userId:m.string(),role:m.string()}),use:[te]},async t=>{let r=await t.context.internalAdapter.updateUser(t.body.userId,{role:t.body.role});return t.json({user:r})}),createUser:u("/admin/create-user",{method:"POST",body:m.object({email:m.string(),password:m.string(),name:m.string(),role:m.string(),data:m.optional(m.record(m.any()))}),use:[te]},async t=>{if(await t.context.internalAdapter.findUserByEmail(t.body.email))throw new M("BAD_REQUEST",{message:"User already exists"});let o=await t.context.internalAdapter.createUser({email:t.body.email,name:t.body.name,role:t.body.role,...t.body.data});if(!o)throw new M("INTERNAL_SERVER_ERROR",{message:"Failed to create user"});let n=await t.context.password.hash(t.body.password);return await t.context.internalAdapter.linkAccount({accountId:o.id,providerId:"credential",password:n,userId:o.id}),t.json({user:o})}),listUsers:u("/admin/list-users",{method:"GET",use:[te],query:m.object({search:m.object({field:m.enum(["email","name"]),operator:m.enum(["contains","starts_with","ends_with"]).default("contains"),value:m.string()}).optional(),limit:m.string().or(m.number()).optional(),offset:m.string().or(m.number()).optional(),sortBy:m.string().optional(),sortDirection:m.enum(["asc","desc"]).optional(),filter:m.array(m.object({field:m.string(),value:m.string().or(m.number()).or(m.boolean()),operator:m.enum(["eq","ne","lt","lte","gt","gte"]),connector:m.enum(["AND","OR"]).optional()})).optional()})},async t=>{let r=[];t.query?.search&&r.push({field:t.query.search.field,operator:t.query.search.operator,value:t.query.search.value}),t.query?.filter&&r.push(...t.query.filter||[]);let o=await t.context.internalAdapter.listUsers(Number(t.query?.limit)||void 0,Number(t.query?.offset)||void 0,t.query?.sortBy?{field:t.query.sortBy,direction:t.query.sortDirection||"asc"}:void 0,r.length?r:void 0);return t.json({users:o})}),listUserSessions:u("/admin/list-user-sessions",{method:"POST",use:[te],body:m.object({userId:m.string()})},async t=>({sessions:await t.context.internalAdapter.listSessions(t.body.userId)})),unbanUser:u("/admin/unban-user",{method:"POST",body:m.object({userId:m.string()}),use:[te]},async t=>{let r=await t.context.internalAdapter.updateUser(t.body.userId,{banned:!1});return t.json({user:r})}),banUser:u("/admin/ban-user",{method:"POST",body:m.object({userId:m.string(),banReason:m.string().optional(),banExpiresIn:m.number().optional()}),use:[te]},async t=>{if(t.body.userId===t.context.session.user.id)throw new M("BAD_REQUEST",{message:"You cannot ban yourself"});let r=await t.context.internalAdapter.updateUser(t.body.userId,{banned:!0,banReason:t.body.banReason||e?.defaultBanReason||"No reason",banExpires:t.body.banExpiresIn?Date.now()+t.body.banExpiresIn*1e3:e?.defaultBanExpiresIn?Date.now()+e.defaultBanExpiresIn*1e3:void 0});return await t.context.internalAdapter.deleteSessions(t.body.userId),t.json({user:r})}),impersonateUser:u("/admin/impersonate-user",{method:"POST",body:m.object({userId:m.string()}),use:[te]},async t=>{let r=await t.context.internalAdapter.findUserById(t.body.userId);if(!r)throw new M("NOT_FOUND",{message:"User not found"});let o=await t.context.internalAdapter.createSession(r.id,void 0,!0,{impersonatedBy:t.context.session.user.id,expiresAt:e?.impersonationSessionDuration?Y(e.impersonationSessionDuration,"sec"):Y(60*60,"sec")});if(!o)throw new M("INTERNAL_SERVER_ERROR",{message:"Failed to create session"});return await A(t,o.id,!0),t.json({session:o,user:r})}),revokeUserSession:u("/admin/revoke-user-session",{method:"POST",body:m.object({sessionId:m.string()}),use:[te]},async t=>(await t.context.internalAdapter.deleteSession(t.body.sessionId),t.json({success:!0}))),revokeUserSessions:u("/admin/revoke-user-sessions",{method:"POST",body:m.object({userId:m.string()}),use:[te]},async t=>(await t.context.internalAdapter.deleteSessions(t.body.userId),t.json({success:!0}))),removeUser:u("/admin/remove-user",{method:"POST",body:m.object({userId:m.string()}),use:[te]},async t=>(await t.context.internalAdapter.deleteUser(t.body.userId),t.json({success:!0})))},schema:{user:{fields:{role:{type:"string",required:!1,input:!1},banned:{type:"boolean",defaultValue:!1,required:!1,input:!1},banReason:{type:"string",required:!1,input:!1},banExpires:{type:"number",required:!1,input:!1}}},session:{fields:{impersonatedBy:{type:"string",required:!1}}}}});import{z as ne}from"zod";import{APIError as Te}from"better-call";import{betterFetch as rt}from"@better-fetch/fetch";import{generateCodeVerifier as Fo}from"oslo/oauth2";import{parseJWT as Mo}from"oslo/jwt";async function qo(e,t,r){if(t==="oidc"&&e.idToken){let n=Mo(e.idToken);if(n?.payload)return n.payload}return r?(await rt(r,{method:"GET",headers:{Authorization:`Bearer ${e.accessToken}`}})).data:null}var gm=e=>({id:"generic-oauth",endpoints:{signInWithOAuth2:u("/sign-in/oauth2",{method:"POST",query:ne.object({currentURL:ne.string().optional()}).optional(),body:ne.object({providerId:ne.string(),callbackURL:ne.string().optional()}),use:[C]},async t=>{let{providerId:r}=t.body,o=e.config.find(L=>L.providerId===r);if(!o)throw new Te("BAD_REQUEST",{message:`No config found for provider ${r}`});let{discoveryUrl:n,authorizationUrl:i,tokenUrl:a,clientId:s,clientSecret:d,scopes:c,redirectURI:l,responseType:p,pkce:f,prompt:g,accessType:R}=o,z=i,h=a;if(n){let L=await rt(n,{onError(Pe){b.error(Pe.error,{discoveryUrl:n})}});L.data&&(z=L.data.authorization_endpoint,h=L.data.token_endpoint)}if(!z||!h)throw new Te("BAD_REQUEST",{message:"Invalid OAuth configuration."});let v=t.query?.currentURL?new URL(t.query?.currentURL):null,q=t.body.callbackURL?.startsWith("http")?t.body.callbackURL:`${v?.origin}${t.body.callbackURL||""}`,K=await Be(q||v?.origin||t.context.options.baseURL),k=t.context.authCookies;await t.setSignedCookie(k.state.name,K.hash,t.context.secret,k.state.options);let j=Fo();await t.setSignedCookie(k.pkCodeVerifier.name,j,t.context.secret,k.pkCodeVerifier.options);let ie=await _({id:r,options:{clientId:s,clientSecret:d,redirectURI:l},authorizationEndpoint:z,state:K.raw,codeVerifier:j,scopes:c||[],disablePkce:!f,redirectURI:`${t.context.baseURL}/oauth2/callback/${r}`});return p&&p!=="code"&&ie.searchParams.set("response_type",p),g&&ie.searchParams.set("prompt",g),R&&ie.searchParams.set("access_type",R),{url:ie.toString(),state:K,codeVerifier:j,redirect:!0}}),oAuth2Callback:u("/oauth2/callback/:providerId",{method:"GET",query:ne.object({code:ne.string().optional(),error:ne.string().optional(),state:ne.string()})},async t=>{if(t.query.error||!t.query.code){let j=ge(t.query.state).data?.currentURL||`${t.context.baseURL}/error`;throw t.context.logger.error(t.query.error,t.params.providerId),t.redirect(`${j}?error=${t.query.error||"oAuth_code_missing"}`)}let r=e.config.find(k=>k.providerId===t.params.providerId);if(!r)throw new Te("BAD_REQUEST",{message:`No config found for provider ${t.params.providerId}`});let o=await t.getSignedCookie(t.context.authCookies.pkCodeVerifier.name,t.context.secret),n,i=ge(t.query.state);if(!i.success)throw t.redirect(`${t.context.baseURL}/error?error=invalid_state`);let a=t.query.state,{data:{callbackURL:s,currentURL:d}}=i,c=t.query.code,l=i.data?.currentURL||`${t.context.baseURL}/error`,p=await t.getSignedCookie(t.context.authCookies.state.name,t.context.secret);if(!p)throw b.error("No stored state found"),t.redirect(`${l}?error=please_restart_the_process`);if(!await Ce(a,p))throw b.error("OAuth code mismatch"),t.redirect(`${l}?error=please_restart_the_process`);let g=r.tokenUrl,R=r.userInfoUrl;if(r.discoveryUrl){let k=await rt(r.discoveryUrl,{method:"GET"});k.data&&(g=k.data.token_endpoint,R=k.data.userinfo_endpoint)}try{if(!g)throw new Te("BAD_REQUEST",{message:"Invalid OAuth configuration."});n=await I({code:c,codeVerifier:o,redirectURI:`${t.context.baseURL}/oauth2/callback/${r.providerId}`,options:{clientId:r.clientId,clientSecret:r.clientSecret},tokenEndpoint:g})}catch(k){throw t.context.logger.error(k),t.redirect(`${l}?error=oauth_code_verification_failed`)}if(!n)throw new Te("BAD_REQUEST",{message:"Invalid OAuth configuration."});let z=r.getUserInfo?await r.getUserInfo(n):await qo(n,r.type||"oauth2",R),h=P(),v=z?Le.safeParse({...z,id:h}):null;if(!v?.success)throw t.redirect(`${l}?error=oauth_user_info_invalid`);let q=await t.context.internalAdapter.findUserByEmail(v.data.email).catch(k=>{throw b.error(`Better auth was unable to query your database.
84
- Error: `,k),t.redirect(`${l}?error=internal_server_error`)}),K=q?.user.id||h;if(q){let k=q.accounts.find(L=>L.providerId===r.providerId),j=t.context.options.account?.accountLinking?.trustedProviders,ie=j?j.includes(r.providerId):!0;if(!k&&(!v?.data.emailVerified||!ie)){let L;try{L=new URL(l),L.searchParams.set("error","account_not_linked")}catch{throw t.redirect(`${l}?error=account_not_linked`)}throw t.redirect(L.toString())}if(!k)try{await t.context.internalAdapter.linkAccount({providerId:r.providerId,accountId:v.data.id,id:`${r.providerId}:${v.data.id}`,userId:q.user.id,...he(n)})}catch(L){throw console.log(L),t.redirect(`${l}?error=failed_linking_account`)}}else try{await t.context.internalAdapter.createOAuthUser(v.data,{...he(n),id:`${r.providerId}:${v.data.id}`,providerId:r.providerId,accountId:v.data.id})}catch{let j=new URL(l);throw j.searchParams.set("error","unable_to_create_user"),t.setHeader("Location",j.toString()),t.redirect(j.toString())}try{let k=await t.context.internalAdapter.createSession(K||h,t.request);if(!k)throw t.redirect(`${l}?error=unable_to_create_session`);await A(t,k.id)}catch{throw t.redirect(`${l}?error=unable_to_create_session`)}throw t.redirect(s||d||"")})}});import{z as Se}from"zod";var cr={jwks:{fields:{publicKey:{type:"string",required:!0},privateKey:{type:"string",required:!0},createdAt:{type:"date",required:!0}}}},ym=Se.object({id:Se.string(),publicKey:Se.string(),privateKey:Se.string(),createdAt:Se.date()});var ot=e=>({getAllKeys:async()=>await e.findMany({model:"jwks"}),getLatestKey:async()=>(await e.findMany({model:"jwks",sortBy:{field:"createdAt",direction:"desc"},limit:1}))[0],createJwk:async t=>await e.create({model:"jwks",data:{...t,createdAt:new Date}})});import{exportJWK as mr,generateKeyPair as Wo,importJWK as Ko,SignJWT as Zo}from"jose";import{createCipheriv as $o,createDecipheriv as Vo,createHash as Ho,randomBytes as Qo}from"crypto";function ur(e){let t;return Buffer.byteLength(e,"utf8")===32?t=Buffer.from(e,"utf8"):t=Ho("sha256").update(e).digest(),t}function lr(e,t){let r=ur(t),o=Qo(12),n=$o("aes-256-gcm",r,o),i=n.update(e,"utf8","base64");i+=n.final("base64");let a=n.getAuthTag();return{encryptedPrivateKey:i,iv:o.toString("base64"),authTag:a.toString("base64")}}function pr(e,t){let r=ur(t),{encryptedPrivateKey:o,iv:n,authTag:i}=e,a=Buffer.from(n,"base64"),s=Buffer.from(i,"base64"),d=Vo("aes-256-gcm",r,a);d.setAuthTag(s);let c=d.update(o,"base64","utf8");return c+=d.final("utf8"),c}var Tm=e=>({id:"jwt",endpoints:{getJwks:u("/jwks",{method:"GET"},async t=>{let o=await ot(t.context.adapter).getAllKeys();return t.json({keys:o.map(n=>({...JSON.parse(n.publicKey),kid:n.id}))})}),getToken:u("/token",{method:"GET",requireHeaders:!0,use:[w]},async t=>{let r=ot(t.context.adapter),o=await r.getLatestKey(),n=!e?.jwks?.disablePrivateKeyEncryption;if(o===void 0){let{publicKey:c,privateKey:l}=await Wo(e?.jwks?.keyPairConfig?.alg??"EdDSA",e?.jwks?.keyPairConfig??{crv:"Ed25519"}),p=await mr(c),f=await mr(l),g=JSON.stringify(f),R={id:crypto.randomUUID(),publicKey:JSON.stringify(p),privateKey:n?JSON.stringify(lr(g,t.context.options.secret)):g,createdAt:new Date};o=await r.createJwk(R)}let i=n?pr(JSON.parse(o.privateKey),t.context.options.secret):o.privateKey,a=await Ko(JSON.parse(i)),s=e?.jwt?.definePayload?await e?.jwt.definePayload(t.context.session.user):t.context.session.user,d=await new Zo({...s,...t.context.session.session.impersonatedBy?{impersonatedBy:t.context.session.session.impersonatedBy}:{}}).setProtectedHeader({alg:e?.jwks?.keyPairConfig?.alg??"EdDSA",kid:o.id}).setIssuedAt().setIssuer(e?.jwt?.issuer??t.context.options.baseURL).setAudience(e?.jwt?.audience??t.context.options.baseURL).setExpirationTime(e?.jwt?.expirationTime??"15m").setSubject(t.context.session.user.id).sign(a);return t.json({token:d})})},schema:cr});import{z as Ke}from"zod";var Bm=e=>{let t={maximumSessions:5,...e},r=o=>o.includes("_multi-");return{id:"multi-session",endpoints:{listDeviceSessions:u("/multi-session/list-device-sessions",{method:"GET",requireHeaders:!0},async o=>{let n=o.headers?.get("cookie");if(!n)return o.json([]);let i=Object.fromEntries(ze(n)),a=(await Promise.all(Object.entries(i).filter(([c])=>r(c)).map(async([c])=>await o.getSignedCookie(c,o.context.secret)))).filter(c=>c!==void 0),d=(await o.context.internalAdapter.findSessions(a)).filter(c=>c&&c.session.expiresAt>new Date).filter((c,l,p)=>l===p.findIndex(f=>f.user.id===c.user.id));return Object.entries(i).filter(([c])=>r(c)).forEach(([c,l])=>{d.some(p=>p.session.id===l)||o.setCookie(c,"",{...o.context.authCookies.sessionToken.options,maxAge:0})}),o.json(d)}),setActiveSession:u("/multi-session/set-active",{method:"POST",body:Ke.object({sessionId:Ke.string()}),requireHeaders:!0,use:[w]},async o=>{let n=o.body.sessionId,i=`${o.context.authCookies.sessionToken.name}_multi-${n}`;if(!await o.getSignedCookie(i,o.context.secret))throw new M("UNAUTHORIZED",{message:"Invalid session id"});let s=await o.context.internalAdapter.findSession(n);if(!s||s.session.expiresAt<new Date)throw o.setCookie(i,"",{...o.context.authCookies.sessionToken.options,maxAge:0}),new M("UNAUTHORIZED",{message:"Invalid session id"});return await o.setSignedCookie(o.context.authCookies.sessionToken.name,n,o.context.secret,o.context.authCookies.sessionToken.options),o.json(s)}),revokeDeviceSession:u("/multi-session/revoke",{method:"POST",body:Ke.object({sessionId:Ke.string()}),requireHeaders:!0,use:[w]},async o=>{let n=o.body.sessionId,i=`${o.context.authCookies.sessionToken.name}_multi-${n}`;if(!await o.getSignedCookie(i,o.context.secret))throw new M("UNAUTHORIZED",{message:"Invalid session id"});return await o.context.internalAdapter.findSession(n)?(await o.context.internalAdapter.deleteSession(n),o.setCookie(i,"",{...o.context.authCookies.sessionToken.options,maxAge:0}),o.json({success:!0})):(o.setCookie(i,"",{...o.context.authCookies.sessionToken.options,maxAge:0}),o.json({success:!0}))})},hooks:{after:[{matcher:()=>!0,handler:E(async o=>{if(!o.context.returned||!(o.context.returned instanceof Response))return;let n=o.context.returned.headers.get("set-cookie");if(!n)return;let i=dt(n),a=o.context.authCookies.sessionToken,s=i.get(a.name)?.value;if(!s)return;let d=ze(o.headers?.get("cookie")||""),c=s.split(".")[0],l=`${a.name}_multi-${c}`;if(i.get(l)||d.get(l))return;if(Object.keys(Object.fromEntries(d)).filter(r).length+(n.includes("session_token")?1:0)>t.maximumSessions)throw new M("UNAUTHORIZED",{message:"Maximum number of device sessions reached."});await o.setSignedCookie(l,c,o.context.secret,a.options);let f=o.context.returned;return f.headers.append("Set-Cookie",o.responseHeader.get("set-cookie")),{response:f}})},{matcher:o=>o.path==="/sign-out",handler:E(async o=>{let n=o.headers?.get("cookie");if(!n)return;let i=Object.fromEntries(ze(n));await Promise.all(Object.entries(i).map(async([s,d])=>{if(r(s)){o.setCookie(s,"",{maxAge:0});let c=s.split("_multi-")[1];await o.context.internalAdapter.deleteSession(c).catch(l=>{})}}));let a=o.context.returned;return a?.headers.append("Set-Cookie",o.responseHeader.get("set-cookie")),{response:a}})}]}}};export{se as HIDE_METADATA,Dt as ac,Yp as admin,te as adminMiddleware,Qp as anonymous,kp as bearer,u as createAuthEndpoint,E as createAuthMiddleware,gm as genericOAuth,Co as getPasskeyActions,Tm as jwt,Sp as magicLink,Bm as multiSession,it as optionsMiddleware,du as organization,mp as passkey,ep as passkeyClient,Np as phoneNumber,dl as twoFactor,Wu as twoFactorClient,dr as username};
84
+ Error: `,k),t.redirect(`${l}?error=internal_server_error`)}),K=q?.user.id||h;if(q){let k=q.accounts.find(L=>L.providerId===r.providerId),j=t.context.options.account?.accountLinking?.trustedProviders,ie=j?j.includes(r.providerId):!0;if(!k&&(!v?.data.emailVerified||!ie)){let L;try{L=new URL(l),L.searchParams.set("error","account_not_linked")}catch{throw t.redirect(`${l}?error=account_not_linked`)}throw t.redirect(L.toString())}if(!k)try{await t.context.internalAdapter.linkAccount({providerId:r.providerId,accountId:v.data.id,id:`${r.providerId}:${v.data.id}`,userId:q.user.id,...he(n)})}catch(L){throw console.log(L),t.redirect(`${l}?error=failed_linking_account`)}}else try{await t.context.internalAdapter.createOAuthUser(v.data,{...he(n),id:`${r.providerId}:${v.data.id}`,providerId:r.providerId,accountId:v.data.id})}catch{let j=new URL(l);throw j.searchParams.set("error","unable_to_create_user"),t.setHeader("Location",j.toString()),t.redirect(j.toString())}try{let k=await t.context.internalAdapter.createSession(K||h,t.request);if(!k)throw t.redirect(`${l}?error=unable_to_create_session`);await A(t,k.id)}catch{throw t.redirect(`${l}?error=unable_to_create_session`)}throw t.redirect(s||d||"")})}});import{z as Se}from"zod";var cr={jwks:{fields:{publicKey:{type:"string",required:!0},privateKey:{type:"string",required:!0},createdAt:{type:"date",required:!0}}}},ym=Se.object({id:Se.string(),publicKey:Se.string(),privateKey:Se.string(),createdAt:Se.date()});var ot=e=>({getAllKeys:async()=>await e.findMany({model:"jwks"}),getLatestKey:async()=>(await e.findMany({model:"jwks",sortBy:{field:"createdAt",direction:"desc"},limit:1}))[0],createJwk:async t=>await e.create({model:"jwks",data:{...t,createdAt:new Date}})});import{exportJWK as mr,generateKeyPair as Wo,importJWK as Ko,SignJWT as Zo}from"jose";import{createCipheriv as $o,createDecipheriv as Vo,createHash as Ho,randomBytes as Qo}from"crypto";function ur(e){let t;return Buffer.byteLength(e,"utf8")===32?t=Buffer.from(e,"utf8"):t=Ho("sha256").update(e).digest(),t}function lr(e,t){let r=ur(t),o=Qo(12),n=$o("aes-256-gcm",r,o),i=n.update(e,"utf8","base64");i+=n.final("base64");let a=n.getAuthTag();return{encryptedPrivateKey:i,iv:o.toString("base64"),authTag:a.toString("base64")}}function pr(e,t){let r=ur(t),{encryptedPrivateKey:o,iv:n,authTag:i}=e,a=Buffer.from(n,"base64"),s=Buffer.from(i,"base64"),d=Vo("aes-256-gcm",r,a);d.setAuthTag(s);let c=d.update(o,"base64","utf8");return c+=d.final("utf8"),c}var Tm=e=>({id:"jwt",endpoints:{getJwks:u("/jwks",{method:"GET"},async t=>{let o=await ot(t.context.adapter).getAllKeys();return t.json({keys:o.map(n=>({...JSON.parse(n.publicKey),kid:n.id}))})}),getToken:u("/token",{method:"GET",requireHeaders:!0,use:[w]},async t=>{let r=ot(t.context.adapter),o=await r.getLatestKey(),n=!e?.jwks?.disablePrivateKeyEncryption;if(o===void 0){let{publicKey:c,privateKey:l}=await Wo(e?.jwks?.keyPairConfig?.alg??"EdDSA",e?.jwks?.keyPairConfig??{crv:"Ed25519"}),p=await mr(c),f=await mr(l),g=JSON.stringify(f),R={id:crypto.randomUUID(),publicKey:JSON.stringify(p),privateKey:n?JSON.stringify(lr(g,t.context.options.secret)):g,createdAt:new Date};o=await r.createJwk(R)}let i=n?pr(JSON.parse(o.privateKey),t.context.options.secret):o.privateKey,a=await Ko(JSON.parse(i)),s=e?.jwt?.definePayload?await e?.jwt.definePayload(t.context.session.user):t.context.session.user,d=await new Zo({...s,...t.context.session.session.impersonatedBy?{impersonatedBy:t.context.session.session.impersonatedBy}:{}}).setProtectedHeader({alg:e?.jwks?.keyPairConfig?.alg??"EdDSA",kid:o.id}).setIssuedAt().setIssuer(e?.jwt?.issuer??t.context.options.baseURL).setAudience(e?.jwt?.audience??t.context.options.baseURL).setExpirationTime(e?.jwt?.expirationTime??"15m").setSubject(t.context.session.user.id).sign(a);return t.json({token:d})})},schema:cr});import{z as Ke}from"zod";var Bm=e=>{let t={maximumSessions:5,...e},r=o=>o.includes("_multi-");return{id:"multi-session",endpoints:{listDeviceSessions:u("/multi-session/list-device-sessions",{method:"GET",requireHeaders:!0},async o=>{let n=o.headers?.get("cookie");if(!n)return o.json([]);let i=Object.fromEntries(ze(n)),a=(await Promise.all(Object.entries(i).filter(([c])=>r(c)).map(async([c])=>await o.getSignedCookie(c,o.context.secret)))).filter(c=>c!==void 0);if(!a.length)return o.json([]);let d=(await o.context.internalAdapter.findSessions(a)).filter(c=>c&&c.session.expiresAt>new Date).filter((c,l,p)=>l===p.findIndex(f=>f.user.id===c.user.id));return Object.entries(i).filter(([c])=>r(c)).forEach(([c,l])=>{d.some(p=>p.session.id===l)||o.setCookie(c,"",{...o.context.authCookies.sessionToken.options,maxAge:0})}),o.json(d)}),setActiveSession:u("/multi-session/set-active",{method:"POST",body:Ke.object({sessionId:Ke.string()}),requireHeaders:!0,use:[w]},async o=>{let n=o.body.sessionId,i=`${o.context.authCookies.sessionToken.name}_multi-${n}`;if(!await o.getSignedCookie(i,o.context.secret))throw new M("UNAUTHORIZED",{message:"Invalid session id"});let s=await o.context.internalAdapter.findSession(n);if(!s||s.session.expiresAt<new Date)throw o.setCookie(i,"",{...o.context.authCookies.sessionToken.options,maxAge:0}),new M("UNAUTHORIZED",{message:"Invalid session id"});return await o.setSignedCookie(o.context.authCookies.sessionToken.name,n,o.context.secret,o.context.authCookies.sessionToken.options),o.json(s)}),revokeDeviceSession:u("/multi-session/revoke",{method:"POST",body:Ke.object({sessionId:Ke.string()}),requireHeaders:!0,use:[w]},async o=>{let n=o.body.sessionId,i=`${o.context.authCookies.sessionToken.name}_multi-${n}`;if(!await o.getSignedCookie(i,o.context.secret))throw new M("UNAUTHORIZED",{message:"Invalid session id"});return await o.context.internalAdapter.findSession(n)?(await o.context.internalAdapter.deleteSession(n),o.setCookie(i,"",{...o.context.authCookies.sessionToken.options,maxAge:0}),o.json({success:!0})):(o.setCookie(i,"",{...o.context.authCookies.sessionToken.options,maxAge:0}),o.json({success:!0}))})},hooks:{after:[{matcher:()=>!0,handler:E(async o=>{if(!o.context.returned||!(o.context.returned instanceof Response))return;let n=o.context.returned.headers.get("set-cookie");if(!n)return;let i=dt(n),a=o.context.authCookies.sessionToken,s=i.get(a.name)?.value;if(!s)return;let d=ze(o.headers?.get("cookie")||""),c=s.split(".")[0],l=`${a.name}_multi-${c}`;if(i.get(l)||d.get(l))return;if(Object.keys(Object.fromEntries(d)).filter(r).length+(n.includes("session_token")?1:0)>t.maximumSessions)throw new M("UNAUTHORIZED",{message:"Maximum number of device sessions reached."});await o.setSignedCookie(l,c,o.context.secret,a.options);let f=o.context.returned;return f.headers.append("Set-Cookie",o.responseHeader.get("set-cookie")),{response:f}})},{matcher:o=>o.path==="/sign-out",handler:E(async o=>{let n=o.headers?.get("cookie");if(!n)return;let i=Object.fromEntries(ze(n));await Promise.all(Object.entries(i).map(async([s,d])=>{if(r(s)){o.setCookie(s,"",{maxAge:0});let c=s.split("_multi-")[1];await o.context.internalAdapter.deleteSession(c)}}));let a=o.context.returned;return a?.headers.append("Set-Cookie",o.responseHeader.get("set-cookie")),{response:a}})}]}}};export{se as HIDE_METADATA,Dt as ac,Yp as admin,te as adminMiddleware,Qp as anonymous,kp as bearer,u as createAuthEndpoint,E as createAuthMiddleware,gm as genericOAuth,Co as getPasskeyActions,Tm as jwt,Sp as magicLink,Bm as multiSession,it as optionsMiddleware,du as organization,mp as passkey,ep as passkeyClient,Np as phoneNumber,dl as twoFactor,Wu as twoFactorClient,dr as username};
package/dist/react.d.ts CHANGED
@@ -3,7 +3,7 @@ import * as _better_fetch_fetch from '@better-fetch/fetch';
3
3
  import { U as UnionToIntersection, P as Prettify, S as StripEmptyObjects } from './helper-DPDj8Nix.js';
4
4
  import { ClientOptions, InferClientAPI, InferActions, InferAdditionalFromClient, BetterAuthClientPlugin, IsSignal } from './types.js';
5
5
  import { useStore } from '@nanostores/react';
6
- import './auth-DhjJVba-.js';
6
+ import './auth-DFDxqxWC.js';
7
7
  import 'kysely';
8
8
  import './schema-Dkt0LqYs.js';
9
9
  import 'better-call';
@@ -1,4 +1,4 @@
1
- import { a as Auth } from './auth-DhjJVba-.js';
1
+ import { a as Auth } from './auth-DFDxqxWC.js';
2
2
  import 'zod';
3
3
  import 'kysely';
4
4
  import './schema-Dkt0LqYs.js';
package/dist/solid.d.ts CHANGED
@@ -3,7 +3,7 @@ import * as _better_fetch_fetch from '@better-fetch/fetch';
3
3
  import { U as UnionToIntersection, P as Prettify, S as StripEmptyObjects } from './helper-DPDj8Nix.js';
4
4
  import { ClientOptions, InferClientAPI, InferActions, InferAdditionalFromClient, BetterAuthClientPlugin, IsSignal } from './types.js';
5
5
  import { Accessor } from 'solid-js';
6
- import './auth-DhjJVba-.js';
6
+ import './auth-DFDxqxWC.js';
7
7
  import 'kysely';
8
8
  import './schema-Dkt0LqYs.js';
9
9
  import 'better-call';
@@ -1,4 +1,4 @@
1
- import { a as Auth, B as BetterAuthOptions } from './auth-DhjJVba-.js';
1
+ import { a as Auth, B as BetterAuthOptions } from './auth-DFDxqxWC.js';
2
2
  import 'zod';
3
3
  import 'kysely';
4
4
  import './schema-Dkt0LqYs.js';
package/dist/svelte.d.ts CHANGED
@@ -3,7 +3,7 @@ import * as nanostores from 'nanostores';
3
3
  import * as _better_fetch_fetch from '@better-fetch/fetch';
4
4
  import { U as UnionToIntersection, P as Prettify, S as StripEmptyObjects } from './helper-DPDj8Nix.js';
5
5
  import { ClientOptions, InferClientAPI, InferActions, InferAdditionalFromClient, BetterAuthClientPlugin, IsSignal } from './types.js';
6
- import './auth-DhjJVba-.js';
6
+ import './auth-DFDxqxWC.js';
7
7
  import 'kysely';
8
8
  import './schema-Dkt0LqYs.js';
9
9
  import 'better-call';
package/dist/types.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { b as BetterAuthPlugin, a as Auth, Q as InferFieldsInputClient, N as InferFieldsOutput } from './auth-DhjJVba-.js';
2
- export { A as Adapter, j as AdditionalSessionFieldsInput, k as AdditionalSessionFieldsOutput, h as AdditionalUserFieldsInput, i as AdditionalUserFieldsOutput, p as AuthContext, B as BetterAuthOptions, G as GenericEndpointContext, H as HookEndpointContext, m as InferPluginTypes, l as InferSession, I as InferUser, P as PluginSchema, R as RateLimit, S as SecondaryStorage, W as Where, n as init } from './auth-DhjJVba-.js';
1
+ import { b as BetterAuthPlugin, a as Auth, Q as InferFieldsInputClient, N as InferFieldsOutput } from './auth-DFDxqxWC.js';
2
+ export { A as Adapter, j as AdditionalSessionFieldsInput, k as AdditionalSessionFieldsOutput, h as AdditionalUserFieldsInput, i as AdditionalUserFieldsOutput, p as AuthContext, B as BetterAuthOptions, G as GenericEndpointContext, H as HookEndpointContext, m as InferPluginTypes, l as InferSession, I as InferUser, P as PluginSchema, R as RateLimit, S as SecondaryStorage, W as Where, n as init } from './auth-DFDxqxWC.js';
3
3
  import { U as UnionToIntersection, H as HasRequiredKeys, P as Prettify, S as StripEmptyObjects, L as LiteralString } from './helper-DPDj8Nix.js';
4
4
  export { D as DeepPartial, a as LiteralUnion, R as RequiredKeysOf, W as WithoutEmpty } from './helper-DPDj8Nix.js';
5
5
  import { BetterFetchOption, BetterFetchResponse, BetterFetch, BetterFetchPlugin } from '@better-fetch/fetch';
package/dist/vue.d.ts CHANGED
@@ -3,7 +3,7 @@ import * as _better_fetch_fetch from '@better-fetch/fetch';
3
3
  import { U as UnionToIntersection, P as Prettify, S as StripEmptyObjects } from './helper-DPDj8Nix.js';
4
4
  import { ClientOptions, InferClientAPI, InferActions, InferAdditionalFromClient, BetterAuthClientPlugin, IsSignal } from './types.js';
5
5
  import { Ref, DeepReadonly } from 'vue';
6
- import './auth-DhjJVba-.js';
6
+ import './auth-DFDxqxWC.js';
7
7
  import 'kysely';
8
8
  import './schema-Dkt0LqYs.js';
9
9
  import 'better-call';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "better-auth",
3
- "version": "0.5.3-beta.1",
3
+ "version": "0.5.3-beta.2",
4
4
  "description": "The most comprehensive authentication library for TypeScript.",
5
5
  "type": "module",
6
6
  "repository": {