better-auth 0.4.10-beta.2 → 0.4.10-beta.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- import { A as Adapter } from '../auth-Nmre53Xe.js';
1
+ import { A as Adapter } from '../auth-2pRFLprr.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 { f as BetterAuthOptions, K as KyselyDatabaseType, F as FieldAttribute, A as Adapter } from '../auth-Nmre53Xe.js';
2
+ import { f as BetterAuthOptions, K as KyselyDatabaseType, F as FieldAttribute, A as Adapter } from '../auth-2pRFLprr.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-Nmre53Xe.js';
2
+ import { W as Where } from '../auth-2pRFLprr.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-Nmre53Xe.js';
1
+ import { A as Adapter } from '../auth-2pRFLprr.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 { b as AuthEndpoint, d as AuthMiddleware, a0 as callbackOAuth, af as changePassword, a as createAuthEndpoint, c as createAuthMiddleware, ab as createEmailVerificationToken, am as csrfMiddleware, ah as deleteUser, aj as error, a8 as forgetPassword, a9 as forgetPasswordCallback, ai as getCSRFToken, Y as getEndpoints, a1 as getSession, a2 as getSessionFromCtx, a4 as listSessions, ak as ok, o as optionsMiddleware, aa as resetPassword, a5 as revokeSession, a6 as revokeSessions, Z as router, ac as sendVerificationEmail, a3 as sessionMiddleware, ag as setPassword, $ as signInEmail, _ as signInOAuth, a7 as signOut, al as signUpEmail, ae as updateUser, ad as verifyEmail } from './auth-Nmre53Xe.js';
1
+ export { b as AuthEndpoint, d as AuthMiddleware, a0 as callbackOAuth, af as changePassword, a as createAuthEndpoint, c as createAuthMiddleware, ab as createEmailVerificationToken, am as csrfMiddleware, ah as deleteUser, aj as error, a8 as forgetPassword, a9 as forgetPasswordCallback, ai as getCSRFToken, Y as getEndpoints, a1 as getSession, a2 as getSessionFromCtx, a4 as listSessions, ak as ok, o as optionsMiddleware, aa as resetPassword, a5 as revokeSession, a6 as revokeSessions, Z as router, ac as sendVerificationEmail, a3 as sessionMiddleware, ag as setPassword, $ as signInEmail, _ as signInOAuth, a7 as signOut, al as signUpEmail, ae as updateUser, ad as verifyEmail } from './auth-2pRFLprr.js';
2
2
  import './helper-DPDj8Nix.js';
3
3
  export { APIError } from 'better-call';
4
4
  import 'zod';
@@ -1173,12 +1173,12 @@ declare const signInOAuth: {
1173
1173
  /**
1174
1174
  * OAuth2 provider to use`
1175
1175
  */
1176
- provider: z.ZodEnum<["github", ...("apple" | "discord" | "facebook" | "github" | "google" | "microsoft" | "spotify" | "twitch" | "twitter")[]]>;
1176
+ provider: z.ZodEnum<["github", ...("github" | "apple" | "discord" | "facebook" | "microsoft" | "google" | "spotify" | "twitch" | "twitter")[]]>;
1177
1177
  }, "strip", z.ZodTypeAny, {
1178
- provider: "apple" | "discord" | "facebook" | "github" | "google" | "microsoft" | "spotify" | "twitch" | "twitter";
1178
+ provider: "github" | "apple" | "discord" | "facebook" | "microsoft" | "google" | "spotify" | "twitch" | "twitter";
1179
1179
  callbackURL?: string | undefined;
1180
1180
  }, {
1181
- provider: "apple" | "discord" | "facebook" | "github" | "google" | "microsoft" | "spotify" | "twitch" | "twitter";
1181
+ provider: "github" | "apple" | "discord" | "facebook" | "microsoft" | "google" | "spotify" | "twitch" | "twitter";
1182
1182
  callbackURL?: string | undefined;
1183
1183
  }>;
1184
1184
  use: better_call.Endpoint<better_call.Handler<string, better_call.EndpointOptions, void>, better_call.EndpointOptions>[];
@@ -1216,12 +1216,12 @@ declare const signInOAuth: {
1216
1216
  /**
1217
1217
  * OAuth2 provider to use`
1218
1218
  */
1219
- provider: z.ZodEnum<["github", ...("apple" | "discord" | "facebook" | "github" | "google" | "microsoft" | "spotify" | "twitch" | "twitter")[]]>;
1219
+ provider: z.ZodEnum<["github", ...("github" | "apple" | "discord" | "facebook" | "microsoft" | "google" | "spotify" | "twitch" | "twitter")[]]>;
1220
1220
  }, "strip", z.ZodTypeAny, {
1221
- provider: "apple" | "discord" | "facebook" | "github" | "google" | "microsoft" | "spotify" | "twitch" | "twitter";
1221
+ provider: "github" | "apple" | "discord" | "facebook" | "microsoft" | "google" | "spotify" | "twitch" | "twitter";
1222
1222
  callbackURL?: string | undefined;
1223
1223
  }, {
1224
- provider: "apple" | "discord" | "facebook" | "github" | "google" | "microsoft" | "spotify" | "twitch" | "twitter";
1224
+ provider: "github" | "apple" | "discord" | "facebook" | "microsoft" | "google" | "spotify" | "twitch" | "twitter";
1225
1225
  callbackURL?: string | undefined;
1226
1226
  }>;
1227
1227
  use: better_call.Endpoint<better_call.Handler<string, better_call.EndpointOptions, void>, better_call.EndpointOptions>[];
@@ -2417,12 +2417,12 @@ declare function getEndpoints<C extends AuthContext, Option extends BetterAuthOp
2417
2417
  }>>;
2418
2418
  body: zod.ZodObject<{
2419
2419
  callbackURL: zod.ZodOptional<zod.ZodString>;
2420
- provider: zod.ZodEnum<["github", ...("apple" | "discord" | "facebook" | "github" | "google" | "microsoft" | "spotify" | "twitch" | "twitter")[]]>;
2420
+ provider: zod.ZodEnum<["github", ...("github" | "apple" | "discord" | "facebook" | "microsoft" | "google" | "spotify" | "twitch" | "twitter")[]]>;
2421
2421
  }, "strip", zod.ZodTypeAny, {
2422
- provider: "apple" | "discord" | "facebook" | "github" | "google" | "microsoft" | "spotify" | "twitch" | "twitter";
2422
+ provider: "github" | "apple" | "discord" | "facebook" | "microsoft" | "google" | "spotify" | "twitch" | "twitter";
2423
2423
  callbackURL?: string | undefined;
2424
2424
  }, {
2425
- provider: "apple" | "discord" | "facebook" | "github" | "google" | "microsoft" | "spotify" | "twitch" | "twitter";
2425
+ provider: "github" | "apple" | "discord" | "facebook" | "microsoft" | "google" | "spotify" | "twitch" | "twitter";
2426
2426
  callbackURL?: string | undefined;
2427
2427
  }>;
2428
2428
  use: Endpoint<better_call.Handler<string, better_call.EndpointOptions, void>, better_call.EndpointOptions>[];
@@ -2450,12 +2450,12 @@ declare function getEndpoints<C extends AuthContext, Option extends BetterAuthOp
2450
2450
  }>>;
2451
2451
  body: zod.ZodObject<{
2452
2452
  callbackURL: zod.ZodOptional<zod.ZodString>;
2453
- provider: zod.ZodEnum<["github", ...("apple" | "discord" | "facebook" | "github" | "google" | "microsoft" | "spotify" | "twitch" | "twitter")[]]>;
2453
+ provider: zod.ZodEnum<["github", ...("github" | "apple" | "discord" | "facebook" | "microsoft" | "google" | "spotify" | "twitch" | "twitter")[]]>;
2454
2454
  }, "strip", zod.ZodTypeAny, {
2455
- provider: "apple" | "discord" | "facebook" | "github" | "google" | "microsoft" | "spotify" | "twitch" | "twitter";
2455
+ provider: "github" | "apple" | "discord" | "facebook" | "microsoft" | "google" | "spotify" | "twitch" | "twitter";
2456
2456
  callbackURL?: string | undefined;
2457
2457
  }, {
2458
- provider: "apple" | "discord" | "facebook" | "github" | "google" | "microsoft" | "spotify" | "twitch" | "twitter";
2458
+ provider: "github" | "apple" | "discord" | "facebook" | "microsoft" | "google" | "spotify" | "twitch" | "twitter";
2459
2459
  callbackURL?: string | undefined;
2460
2460
  }>;
2461
2461
  use: Endpoint<better_call.Handler<string, better_call.EndpointOptions, void>, better_call.EndpointOptions>[];
@@ -3511,12 +3511,12 @@ declare const router: <C extends AuthContext, Option extends BetterAuthOptions>(
3511
3511
  }>>;
3512
3512
  body: zod.ZodObject<{
3513
3513
  callbackURL: zod.ZodOptional<zod.ZodString>;
3514
- provider: zod.ZodEnum<["github", ...("apple" | "discord" | "facebook" | "github" | "google" | "microsoft" | "spotify" | "twitch" | "twitter")[]]>;
3514
+ provider: zod.ZodEnum<["github", ...("github" | "apple" | "discord" | "facebook" | "microsoft" | "google" | "spotify" | "twitch" | "twitter")[]]>;
3515
3515
  }, "strip", zod.ZodTypeAny, {
3516
- provider: "apple" | "discord" | "facebook" | "github" | "google" | "microsoft" | "spotify" | "twitch" | "twitter";
3516
+ provider: "github" | "apple" | "discord" | "facebook" | "microsoft" | "google" | "spotify" | "twitch" | "twitter";
3517
3517
  callbackURL?: string | undefined;
3518
3518
  }, {
3519
- provider: "apple" | "discord" | "facebook" | "github" | "google" | "microsoft" | "spotify" | "twitch" | "twitter";
3519
+ provider: "github" | "apple" | "discord" | "facebook" | "microsoft" | "google" | "spotify" | "twitch" | "twitter";
3520
3520
  callbackURL?: string | undefined;
3521
3521
  }>;
3522
3522
  use: Endpoint<better_call.Handler<string, better_call.EndpointOptions, void>, better_call.EndpointOptions>[];
@@ -3544,12 +3544,12 @@ declare const router: <C extends AuthContext, Option extends BetterAuthOptions>(
3544
3544
  }>>;
3545
3545
  body: zod.ZodObject<{
3546
3546
  callbackURL: zod.ZodOptional<zod.ZodString>;
3547
- provider: zod.ZodEnum<["github", ...("apple" | "discord" | "facebook" | "github" | "google" | "microsoft" | "spotify" | "twitch" | "twitter")[]]>;
3547
+ provider: zod.ZodEnum<["github", ...("github" | "apple" | "discord" | "facebook" | "microsoft" | "google" | "spotify" | "twitch" | "twitter")[]]>;
3548
3548
  }, "strip", zod.ZodTypeAny, {
3549
- provider: "apple" | "discord" | "facebook" | "github" | "google" | "microsoft" | "spotify" | "twitch" | "twitter";
3549
+ provider: "github" | "apple" | "discord" | "facebook" | "microsoft" | "google" | "spotify" | "twitch" | "twitter";
3550
3550
  callbackURL?: string | undefined;
3551
3551
  }, {
3552
- provider: "apple" | "discord" | "facebook" | "github" | "google" | "microsoft" | "spotify" | "twitch" | "twitter";
3552
+ provider: "github" | "apple" | "discord" | "facebook" | "microsoft" | "google" | "spotify" | "twitch" | "twitter";
3553
3553
  callbackURL?: string | undefined;
3554
3554
  }>;
3555
3555
  use: Endpoint<better_call.Handler<string, better_call.EndpointOptions, void>, better_call.EndpointOptions>[];
@@ -4607,12 +4607,12 @@ declare const betterAuth: <O extends BetterAuthOptions>(options: O) => {
4607
4607
  }>>;
4608
4608
  body: zod.ZodObject<{
4609
4609
  callbackURL: zod.ZodOptional<zod.ZodString>;
4610
- provider: zod.ZodEnum<["github", ...("apple" | "discord" | "facebook" | "github" | "google" | "microsoft" | "spotify" | "twitch" | "twitter")[]]>;
4610
+ provider: zod.ZodEnum<["github", ...("github" | "apple" | "discord" | "facebook" | "microsoft" | "google" | "spotify" | "twitch" | "twitter")[]]>;
4611
4611
  }, "strip", zod.ZodTypeAny, {
4612
- provider: "apple" | "discord" | "facebook" | "github" | "google" | "microsoft" | "spotify" | "twitch" | "twitter";
4612
+ provider: "github" | "apple" | "discord" | "facebook" | "microsoft" | "google" | "spotify" | "twitch" | "twitter";
4613
4613
  callbackURL?: string | undefined;
4614
4614
  }, {
4615
- provider: "apple" | "discord" | "facebook" | "github" | "google" | "microsoft" | "spotify" | "twitch" | "twitter";
4615
+ provider: "github" | "apple" | "discord" | "facebook" | "microsoft" | "google" | "spotify" | "twitch" | "twitter";
4616
4616
  callbackURL?: string | undefined;
4617
4617
  }>;
4618
4618
  use: Endpoint<better_call.Handler<string, better_call.EndpointOptions, void>, better_call.EndpointOptions>[];
@@ -4640,12 +4640,12 @@ declare const betterAuth: <O extends BetterAuthOptions>(options: O) => {
4640
4640
  }>>;
4641
4641
  body: zod.ZodObject<{
4642
4642
  callbackURL: zod.ZodOptional<zod.ZodString>;
4643
- provider: zod.ZodEnum<["github", ...("apple" | "discord" | "facebook" | "github" | "google" | "microsoft" | "spotify" | "twitch" | "twitter")[]]>;
4643
+ provider: zod.ZodEnum<["github", ...("github" | "apple" | "discord" | "facebook" | "microsoft" | "google" | "spotify" | "twitch" | "twitter")[]]>;
4644
4644
  }, "strip", zod.ZodTypeAny, {
4645
- provider: "apple" | "discord" | "facebook" | "github" | "google" | "microsoft" | "spotify" | "twitch" | "twitter";
4645
+ provider: "github" | "apple" | "discord" | "facebook" | "microsoft" | "google" | "spotify" | "twitch" | "twitter";
4646
4646
  callbackURL?: string | undefined;
4647
4647
  }, {
4648
- provider: "apple" | "discord" | "facebook" | "github" | "google" | "microsoft" | "spotify" | "twitch" | "twitter";
4648
+ provider: "github" | "apple" | "discord" | "facebook" | "microsoft" | "google" | "spotify" | "twitch" | "twitter";
4649
4649
  callbackURL?: string | undefined;
4650
4650
  }>;
4651
4651
  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, k 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 } from '../index-DhUJME0t.js';
6
- export { g as getPasskeyActions, c as passkeyClient, a as twoFactorClient } from '../index-DhUJME0t.js';
5
+ import { o as organization, k 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 } from '../index-C8A4Ste5.js';
6
+ export { g as getPasskeyActions, c as passkeyClient, a as twoFactorClient } from '../index-C8A4Ste5.js';
7
7
  import { P as Prettify } from '../helper-DPDj8Nix.js';
8
- import { F as FieldAttribute, f as BetterAuthOptions, B as BetterAuthPlugin } from '../auth-Nmre53Xe.js';
8
+ import { F as FieldAttribute, f as BetterAuthOptions, B as BetterAuthPlugin } from '../auth-2pRFLprr.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-Nmre53Xe.js';
9
+ import './auth-2pRFLprr.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, v as parseSetCookieHeader, t as setSessionCookie } from './auth-Nmre53Xe.js';
2
+ export { s as BetterAuthCookies, E as EligibleCookies, r as createCookieGetter, u as deleteSessionCookie, q as getCookies, v as parseSetCookieHeader, t as setSessionCookie } from './auth-2pRFLprr.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, f as BetterAuthOptions, W as Where, F as FieldAttribute, y as FieldType, K as KyselyDatabaseType } from './auth-Nmre53Xe.js';
2
- export { V as BetterAuthDbSchema, D as FieldAttributeConfig, U as InferFieldsFromOptions, T as InferFieldsFromPlugins, N as InferFieldsInput, O as InferFieldsInputClient, M as InferFieldsOutput, L as InferValueType, C as InternalAdapter, Q as PluginFieldAttribute, J as createFieldAttribute, z as createInternalAdapter, X as getAuthTables } from './auth-Nmre53Xe.js';
1
+ import { A as Adapter, f as BetterAuthOptions, W as Where, F as FieldAttribute, y as FieldType, K as KyselyDatabaseType } from './auth-2pRFLprr.js';
2
+ export { V as BetterAuthDbSchema, D as FieldAttributeConfig, U as InferFieldsFromOptions, T as InferFieldsFromPlugins, N as InferFieldsInput, O as InferFieldsInputClient, M as InferFieldsOutput, L as InferValueType, C as InternalAdapter, Q as PluginFieldAttribute, J as createFieldAttribute, z as createInternalAdapter, X as getAuthTables } from './auth-2pRFLprr.js';
3
3
  import { z } from 'zod';
4
4
  import 'kysely';
5
5
  import './schema-Dkt0LqYs.js';
@@ -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-Nmre53Xe.js';
8
+ import { H as HookEndpointContext, p as AuthContext } from './auth-2pRFLprr.js';
9
9
  import * as nanostores from 'nanostores';
10
10
  import { atom } from 'nanostores';
11
11
  import * as _simplewebauthn_types from '@simplewebauthn/types';
@@ -4187,6 +4187,24 @@ interface MagicLinkOptions {
4187
4187
  url: string;
4188
4188
  token: string;
4189
4189
  }) => Promise<void> | void;
4190
+ /**
4191
+ * Disable sign up if user is not found.
4192
+ *
4193
+ * @default false
4194
+ */
4195
+ disableSignUp?: boolean;
4196
+ /**
4197
+ * Rate limit configuration.
4198
+ *
4199
+ * @default {
4200
+ * window: 60,
4201
+ * max: 5,
4202
+ * }
4203
+ */
4204
+ rateLimit?: {
4205
+ window: number;
4206
+ max: number;
4207
+ };
4190
4208
  }
4191
4209
  declare const magicLink: (options: MagicLinkOptions) => {
4192
4210
  id: "magic-link";
@@ -4198,15 +4216,12 @@ declare const magicLink: (options: MagicLinkOptions) => {
4198
4216
  body: z.ZodObject<{
4199
4217
  email: z.ZodString;
4200
4218
  callbackURL: z.ZodOptional<z.ZodString>;
4201
- currentURL: z.ZodOptional<z.ZodString>;
4202
4219
  }, "strip", z.ZodTypeAny, {
4203
4220
  email: string;
4204
4221
  callbackURL?: string | undefined;
4205
- currentURL?: string | undefined;
4206
4222
  }, {
4207
4223
  email: string;
4208
4224
  callbackURL?: string | undefined;
4209
- currentURL?: string | undefined;
4210
4225
  }>;
4211
4226
  use: better_call.Endpoint<better_call.Handler<string, better_call.EndpointOptions, void>, better_call.EndpointOptions>[];
4212
4227
  }>]>(...ctx: C): Promise<C extends [{
@@ -4221,15 +4236,12 @@ declare const magicLink: (options: MagicLinkOptions) => {
4221
4236
  body: z.ZodObject<{
4222
4237
  email: z.ZodString;
4223
4238
  callbackURL: z.ZodOptional<z.ZodString>;
4224
- currentURL: z.ZodOptional<z.ZodString>;
4225
4239
  }, "strip", z.ZodTypeAny, {
4226
4240
  email: string;
4227
4241
  callbackURL?: string | undefined;
4228
- currentURL?: string | undefined;
4229
4242
  }, {
4230
4243
  email: string;
4231
4244
  callbackURL?: string | undefined;
4232
- currentURL?: string | undefined;
4233
4245
  }>;
4234
4246
  use: better_call.Endpoint<better_call.Handler<string, better_call.EndpointOptions, void>, better_call.EndpointOptions>[];
4235
4247
  };
@@ -4274,6 +4286,11 @@ declare const magicLink: (options: MagicLinkOptions) => {
4274
4286
  headers: Headers;
4275
4287
  };
4276
4288
  };
4289
+ rateLimit: {
4290
+ pathMatcher(path: string): boolean;
4291
+ window: number;
4292
+ max: number;
4293
+ }[];
4277
4294
  };
4278
4295
 
4279
4296
  interface UserWithPhoneNumber extends User {
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, e as Auth, p as AuthContext, s as BetterAuthCookies, f 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, w as createLogger, u as deleteSessionCookie, q as getCookies, n as init, x as logger, v as parseSetCookieHeader, t as setSessionCookie } from './auth-Nmre53Xe.js';
1
+ export { A as Adapter, j as AdditionalSessionFieldsInput, k as AdditionalSessionFieldsOutput, h as AdditionalUserFieldsInput, i as AdditionalUserFieldsOutput, e as Auth, p as AuthContext, s as BetterAuthCookies, f 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, w as createLogger, u as deleteSessionCookie, q as getCookies, n as init, x as logger, v as parseSetCookieHeader, t as setSessionCookie } from './auth-2pRFLprr.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/node.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as http from 'http';
2
- import { e as Auth } from './auth-Nmre53Xe.js';
2
+ import { e as Auth } from './auth-2pRFLprr.js';
3
3
  import 'zod';
4
4
  import 'kysely';
5
5
  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, o as organization, p as passkey, c as passkeyClient, d as phoneNumber, t as twoFactor, a as twoFactorClient, u as username } from './index-DhUJME0t.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, o as organization, p as passkey, c as passkeyClient, d as phoneNumber, t as twoFactor, a as twoFactorClient, u as username } from './index-C8A4Ste5.js';
2
2
  export { i as ac } from './index-DfAHOgpj.js';
3
- import { H as HookEndpointContext } from './auth-Nmre53Xe.js';
4
- export { b as AuthEndpoint, d as AuthMiddleware, B as BetterAuthPlugin, P as PluginSchema, a as createAuthEndpoint, c as createAuthMiddleware, o as optionsMiddleware } from './auth-Nmre53Xe.js';
3
+ import { H as HookEndpointContext } from './auth-2pRFLprr.js';
4
+ export { b as AuthEndpoint, d as AuthMiddleware, B as BetterAuthPlugin, P as PluginSchema, a as createAuthEndpoint, c as createAuthMiddleware, o as optionsMiddleware } from './auth-2pRFLprr.js';
5
5
  export { H as HIDE_METADATA } from './hide-metadata-DEHJp1rk.js';
6
6
  import 'zod';
7
7
  import './schema-Dkt0LqYs.js';
package/dist/plugins.js CHANGED
@@ -1,6 +1,6 @@
1
- var fr=Object.defineProperty;var gr=(e,r)=>{for(var t in r)fr(e,t,{get:r[t],enumerable:!0})};import{APIError as rr}from"better-call";import{z as _e}from"zod";import{createEndpointCreator as hr,createMiddleware as dt,createMiddlewareCreator as wr}from"better-call";var ct=dt(async()=>({})),z=wr({use:[ct,dt(async()=>({}))]}),c=hr({use:[ct]});import{APIError as de}from"better-call";import{generateCodeVerifier as Lr}from"oslo/oauth2";import{z as W}from"zod";import{generateState as yr}from"oslo/oauth2";import{z as je}from"zod";import{sha256 as ut}from"oslo/crypto";function Ke(e,r){let t=new Uint8Array(e),o=new Uint8Array(r);if(t.length!==o.length)return!1;let n=0;for(let s=0;s<t.length;s++)n|=t[s]^o[s];return n===0}async function lt(e){let r=await ut(typeof e=="string"?new TextEncoder().encode(e):e);return Buffer.from(r).toString("base64")}async function xe(e,r){let t=await ut(typeof e=="string"?new TextEncoder().encode(e):e),o=Buffer.from(r,"base64");return Ke(t,o)}async function Ne(e){let r=yr(),t=JSON.stringify({code:r,callbackURL:e}),o=await lt(t);return{raw:t,hash:o}}function ye(e){return je.object({code:je.string(),callbackURL:je.string().optional(),currentURL:je.string().optional()}).safeParse(JSON.parse(e))}import{TimeSpan as rn}from"oslo";var M=class extends Error{constructor(r,t){super(r),this.name="BetterAuthError",this.message=r,this.cause=t,this.stack=""}};async function y(e,r,t,o){let n=e.context.authCookies.sessionToken.options;n.maxAge=t?void 0:e.context.sessionConfig.expiresIn,await e.setSignedCookie(e.context.authCookies.sessionToken.name,r,e.context.secret,{...n,...o}),t&&await e.setSignedCookie(e.context.authCookies.dontRememberToken.name,"true",e.context.secret,e.context.authCookies.dontRememberToken.options)}function ke(e){e.setCookie(e.context.authCookies.sessionToken.name,"",{maxAge:0}),e.setCookie(e.context.authCookies.dontRememberToken.name,"",{maxAge:0})}import{APIError as pt}from"better-call";import{createConsola as br}from"consola";var le=br({formatOptions:{date:!1,colors:!0,compact:!0},defaults:{tag:"Better Auth"}}),Ar=e=>({log:(...r)=>{!e?.disabled&&le.log("",...r)},error:(...r)=>{!e?.disabled&&le.error("",...r)},warn:(...r)=>{!e?.disabled&&le.warn("",...r)},info:(...r)=>{!e?.disabled&&le.info("",...r)},debug:(...r)=>{!e?.disabled&&le.debug("",...r)},box:(...r)=>{!e?.disabled&&le.box("",...r)},success:(...r)=>{!e?.disabled&&le.success("",...r)},break:(...r)=>{!e?.disabled&&console.log(`
2
- `)}}),A=Ar();var j=z(async e=>{let r=e.body?.callbackURL||e.query?.callbackURL||e.query?.redirectTo||e.body?.redirectTo,t=e.headers?.get("referer"),o=e.query?.currentURL||t||e.context.baseURL,n=e.context.trustedOrigins;if(r?.includes("http")){let s=new URL(r).origin;if(!n.includes(s))throw A.error("Invalid callback URL",{callbackURL:r,trustedOrigins:n}),new pt("FORBIDDEN",{message:"Invalid callback URL"})}if(o!==e.context.baseURL){let s=new URL(o).origin;if(!n.includes(s))throw A.error("Invalid current URL",{currentURL:o,trustedOrigins:n}),new pt("FORBIDDEN",{message:"Invalid callback URL"})}});import{parseJWT as Ir}from"oslo/jwt";import{sha256 as Or}from"oslo/crypto";function Rr(e){try{return new URL(e).pathname!=="/"}catch{throw new M(`Invalid base URL: ${e}. Please provide a valid base URL.`)}}function Ye(e,r="/api/auth"){return Rr(e)?e:(r=r.startsWith("/")?r:`/${r}`,`${e}${r}`)}function Xe(e,r){if(e)return Ye(e,r);let t=typeof process<"u"?process.env:{},o=t.BETTER_AUTH_URL||t.NEXT_PUBLIC_BETTER_AUTH_URL||t.PUBLIC_BETTER_AUTH_URL||t.NUXT_PUBLIC_BETTER_AUTH_URL||t.NUXT_PUBLIC_AUTH_URL||(t.BASE_URL!=="/"?t.BASE_URL:void 0);if(o)return Ye(o,r);if(typeof window<"u")return Ye(window.location.origin,r)}function mt(e){return new URL(e).origin.replace("http://","").replace("https://","")}import{base64url as kr}from"oslo/encoding";function T(e,r){return r||`${Xe()}/callback/${e}`}async function ft(e){let r=await Or(new TextEncoder().encode(e));return kr.encode(new Uint8Array(r),{includePadding:!1})}function gt(e){return{tokenType:e.token_type,accessToken:e.access_token,refreshToken:e.refresh_token,accessTokenExpiresAt:e.expires_at?new Date((Date.now()+e.expires_in)*1e3):void 0,scopes:e.scope?.split(" ")||[],idToken:e.id_token}}async function B({id:e,options:r,authorizationEndpoint:t,state:o,codeVerifier:n,scopes:s,disablePkce:a}){let i=new URL(t);if(i.searchParams.set("response_type","code"),i.searchParams.set("client_id",r.clientId),i.searchParams.set("state",o),i.searchParams.set("scope",s.join(" ")),i.searchParams.set("redirect_uri",r.redirectURI||T(e)),!a&&n){let d=await ft(n);i.searchParams.set("code_challenge_method","S256"),i.searchParams.set("code_challenge",d)}return i}import{betterFetch as Ur}from"@better-fetch/fetch";async function v({code:e,codeVerifier:r,redirectURI:t,options:o,tokenEndpoint:n}){let s=new URLSearchParams;s.set("grant_type","authorization_code"),s.set("code",e),r&&s.set("code_verifier",r),s.set("redirect_uri",t),s.set("client_id",o.clientId),s.set("client_secret",o.clientSecret);let{data:a,error:i}=await Ur(n,{method:"POST",body:s,headers:{"content-type":"application/x-www-form-urlencoded",accept:"application/json","user-agent":"better-auth"}});if(i)throw i;return gt(a)}function be(e){let r=e.accessToken,t=e.refreshToken,o;try{o=e.accessTokenExpiresAt}catch{}return{accessToken:r,refreshToken:t,expiresAt:o}}var ht=e=>{let r="https://appleid.apple.com/auth/token";return{id:"apple",name:"Apple",createAuthorizationURL({state:t,scopes:o,redirectURI:n}){let s=e.scope||o||["email","name","openid"];return new URL(`https://appleid.apple.com/auth/authorize?client_id=${e.clientId}&response_type=code&redirect_uri=${n||e.redirectURI}&scope=${s.join(" ")}&state=${t}`)},validateAuthorizationCode:async(t,o,n)=>v({code:t,codeVerifier:o,redirectURI:n||T("apple",e.redirectURI),options:e,tokenEndpoint:r}),async getUserInfo(t){if(!t.idToken)return null;let o=Ir(t.idToken)?.payload;return o?{user:{id:o.sub,name:o.name,email:o.email,emailVerified:o.email_verified==="true"},data:o}:null}}};import{betterFetch as Tr}from"@better-fetch/fetch";var wt=e=>({id:"discord",name:"Discord",createAuthorizationURL({state:r,scopes:t}){let o=e.scope||t||["identify","email"];return new URL(`https://discord.com/api/oauth2/authorize?scope=${o.join("+")}&response_type=code&client_id=${e.clientId}&redirect_uri=${encodeURIComponent(T("discord",e.redirectURI))}&state=${r}`)},validateAuthorizationCode:async(r,t,o)=>v({code:r,redirectURI:o||T("discord",e.redirectURI),options:e,tokenEndpoint:"https://discord.com/api/oauth2/token"}),async getUserInfo(r){let{data:t,error:o}=await Tr("https://discord.com/api/users/@me",{headers:{authorization:`Bearer ${r.accessToken}`}});if(o)return null;if(t.avatar===null){let n=t.discriminator==="0"?Number(BigInt(t.id)>>BigInt(22))%6:parseInt(t.discriminator)%5;t.image_url=`https://cdn.discordapp.com/embed/avatars/${n}.png`}else{let n=t.avatar.startsWith("a_")?"gif":"png";t.image_url=`https://cdn.discordapp.com/avatars/${t.id}/${t.avatar}.${n}`}return{user:{id:t.id,name:t.display_name||t.username||"",email:t.email,emailVerified:t.verified,image:t.image_url},data:t}}});import{betterFetch as vr}from"@better-fetch/fetch";var yt=e=>({id:"facebook",name:"Facebook",async createAuthorizationURL({state:r,scopes:t,codeVerifier:o}){let n=e.scope||t||["email","public_profile"];return await B({id:"facebook",options:e,authorizationEndpoint:"https://www.facebook.com/v16.0/dialog/oauth",scopes:n,state:r,codeVerifier:o})},validateAuthorizationCode:async(r,t,o)=>v({code:r,codeVerifier:t,redirectURI:o||T("facebook",e.redirectURI),options:e,tokenEndpoint:"https://graph.facebook.com/v16.0/oauth/access_token"}),async getUserInfo(r){let{data:t,error:o}=await vr("https://graph.facebook.com/me",{auth:{type:"Bearer",token:r.accessToken}});return o?null:{user:{id:t.id,name:t.name,email:t.email,emailVerified:t.email_verified},data:t}}});import{betterFetch as bt}from"@better-fetch/fetch";var At=e=>{let r="https://github.com/login/oauth/access_token";return{id:"github",name:"Github",createAuthorizationURL({state:t,scopes:o,codeVerifier:n}){let s=e.scope||o||["user:email"];return B({id:"github",options:e,authorizationEndpoint:"https://github.com/login/oauth/authorize",scopes:s,state:t,codeVerifier:n})},validateAuthorizationCode:async(t,o,n)=>v({code:t,redirectURI:e.redirectURI||T("google",n),options:e,tokenEndpoint:r}),async getUserInfo(t){let{data:o,error:n}=await bt("https://api.github.com/user",{auth:{type:"Bearer",token:t.accessToken}});if(n)return null;let s=!1;if(!o.email){let{data:a,error:i}=await bt("https://api.github.com/user/emails",{auth:{type:"Bearer",token:t.accessToken}});i||(o.email=(a.find(d=>d.primary)??a[0])?.email,s=a.find(d=>d.email===o.email)?.verified??!1)}return{user:{id:o.id.toString(),name:o.name||o.login,email:o.email,image:o.avatar_url,emailVerified:s},data:o}}}};import{parseJWT as Er}from"oslo/jwt";var Rt=e=>({id:"google",name:"Google",createAuthorizationURL({state:r,scopes:t,codeVerifier:o,redirectURI:n}){if(!e.clientId||!e.clientSecret)throw A.error("Client Id and Client Secret is required for Google. Make sure to provide them in the options."),new M("CLIENT_ID_AND_SECRET_REQUIRED");if(!o)throw new M("codeVerifier is required for Google");let s=e.scope||t||["email","profile"];return B({id:"google",options:e,authorizationEndpoint:"https://accounts.google.com/o/oauth2/auth",scopes:s,state:r,codeVerifier:o})},validateAuthorizationCode:async(r,t,o)=>v({code:r,codeVerifier:t,redirectURI:o||T("google",e.redirectURI),options:e,tokenEndpoint:"https://oauth2.googleapis.com/token"}),async getUserInfo(r){if(!r.idToken)return null;let t=Er(r.idToken)?.payload;return{user:{id:t.sub,name:t.name,email:t.email,image:t.picture,emailVerified:t.email_verified},data:t}}});import{betterFetch as Sr}from"@better-fetch/fetch";import{parseJWT as Pr}from"oslo/jwt";var Ot=e=>{let r=e.tenantId||"common",t=`https://login.microsoftonline.com/${r}/oauth2/v2.0/authorize`,o=`https://login.microsoftonline.com/${r}/oauth2/v2.0/token`;return{id:"microsoft",name:"Microsoft EntraID",createAuthorizationURL(n){let s=e.scope||n.scopes||["openid","profile","email","User.Read"];return B({id:"microsoft",options:e,authorizationEndpoint:t,state:n.state,codeVerifier:n.codeVerifier,scopes:s})},validateAuthorizationCode(n,s,a){return v({code:n,codeVerifier:s,redirectURI:a||T("microsoft",e.redirectURI),options:e,tokenEndpoint:o})},async getUserInfo(n){if(!n.idToken)return null;let s=Pr(n.idToken)?.payload,a=e.profilePhotoSize||48;return await Sr(`https://graph.microsoft.com/v1.0/me/photos/${a}x${a}/$value`,{headers:{Authorization:`Bearer ${n.accessToken}`},async onResponse(i){if(!(e.disableProfilePhoto||!i.response.ok))try{let u=await i.response.clone().arrayBuffer(),l=Buffer.from(u).toString("base64");s.picture=`data:image/jpeg;base64, ${l}`}catch(d){A.error(d)}}}),{user:{id:s.sub,name:s.name,email:s.email,image:s.picture,emailVerified:!0},data:s}}}};import{betterFetch as _r}from"@better-fetch/fetch";var kt=e=>({id:"spotify",name:"Spotify",createAuthorizationURL({state:r,scopes:t,codeVerifier:o}){let n=e.scope||t||["user-read-email"];return B({id:"spotify",options:e,authorizationEndpoint:"https://accounts.spotify.com/authorize",scopes:n,state:r,codeVerifier:o})},validateAuthorizationCode:async(r,t,o)=>v({code:r,codeVerifier:t,redirectURI:o||T("spotify",e.redirectURI),options:e,tokenEndpoint:"https://accounts.spotify.com/api/token"}),async getUserInfo(r){let{data:t,error:o}=await _r("https://api.spotify.com/v1/me",{method:"GET",headers:{Authorization:`Bearer ${r.accessToken}`}});return o?null:{user:{id:t.id,name:t.display_name,email:t.email,image:t.images[0]?.url,emailVerified:!1},data:t}}});import{betterFetch as Cr}from"@better-fetch/fetch";var Ut=e=>({id:"twitch",name:"Twitch",createAuthorizationURL({state:r,scopes:t}){let o=e.scope||t||["activity:write","read"];return B({id:"twitch",options:e,authorizationEndpoint:"https://id.twitch.tv/oauth2/authorize",scopes:o,state:r})},validateAuthorizationCode:async(r,t,o)=>v({code:r,redirectURI:o||T("twitch",e.redirectURI),options:e,tokenEndpoint:"https://id.twitch.tv/oauth2/token"}),async getUserInfo(r){let{data:t,error:o}=await Cr("https://api.twitch.tv/helix/users",{method:"GET",headers:{Authorization:`Bearer ${r.accessToken}`}});return o?null:{user:{id:t.sub,name:t.preferred_username,email:t.email,image:t.picture,emailVerified:!1},data:t}}});import{betterFetch as zr}from"@better-fetch/fetch";var It=e=>({id:"twitter",name:"Twitter",createAuthorizationURL(r){let t=e.scope||r.scopes||["account_info.read"];return B({id:"twitter",options:e,authorizationEndpoint:"https://twitter.com/i/oauth2/authorize",scopes:t,state:r.state,codeVerifier:r.codeVerifier})},validateAuthorizationCode:async(r,t,o)=>v({code:r,codeVerifier:t,redirectURI:o||T("twitch",e.redirectURI),options:e,tokenEndpoint:"https://id.twitch.tv/oauth2/token"}),async getUserInfo(r){let{data:t,error:o}=await zr("https://api.x.com/2/users/me?user.fields=profile_image_url",{method:"GET",headers:{Authorization:`Bearer ${r.accessToken}`}});return o||!t.data.email?null:{user:{id:t.data.id,name:t.data.name,email:t.data.email,image:t.data.profile_image_url,emailVerified:t.data.verified||!1},data:t}}});var Br={apple:ht,discord:wt,facebook:yt,github:At,microsoft:Ot,google:Rt,spotify:kt,twitch:Ut,twitter:It},Tt=Object.keys(Br);var Dr=c("/sign-in/social",{method:"POST",requireHeaders:!0,query:W.object({currentURL:W.string().optional()}).optional(),body:W.object({callbackURL:W.string().optional(),provider:W.enum(Tt)}),use:[j]},async e=>{let r=e.context.socialProviders.find(d=>d.id===e.body.provider);if(!r)throw e.context.logger.error("Provider not found. Make sure to add the provider to your auth config",{provider:e.body.provider}),new de("NOT_FOUND",{message:"Provider not found"});let t=e.context.authCookies,o=e.query?.currentURL?new URL(e.query?.currentURL):null,n=e.body.callbackURL?.startsWith("http")?e.body.callbackURL:`${o?.origin}${e.body.callbackURL||""}`,s=await Ne(n||o?.origin||e.context.options.baseURL);await e.setSignedCookie(t.state.name,s.hash,e.context.secret,t.state.options);let a=Lr();await e.setSignedCookie(t.pkCodeVerifier.name,a,e.context.secret,t.pkCodeVerifier.options);let i=await r.createAuthorizationURL({state:s.raw,codeVerifier:a});return i.searchParams.set("redirect_uri",`${e.context.baseURL}/callback/${e.body.provider}`),e.json({url:i.toString(),state:s,codeVerifier:a,redirect:!0})}),xr=c("/sign-in/email",{method:"POST",body:W.object({email:W.string().email(),password:W.string(),callbackURL:W.string().optional(),dontRememberMe:W.boolean().default(!1).optional()}),use:[j]},async e=>{if(!e.context.options?.emailAndPassword?.enabled)throw e.context.logger.error("Email and password is not enabled. Make sure to enable it in the options on you `auth.ts` file. Check `https://better-auth.com/docs/authentication/email-password` for more!"),new de("BAD_REQUEST",{message:"Email and password is not enabled"});let{email:r,password:t}=e.body;if(!W.string().email().safeParse(r).success)throw new de("BAD_REQUEST",{message:"Invalid email"});let n=await e.context.internalAdapter.findUserByEmail(r,{includeAccounts:!0});if(!n)throw await e.context.password.hash(t),e.context.logger.error("User not found",{email:r}),new de("UNAUTHORIZED",{message:"Invalid email or password"});let s=n.accounts.find(u=>u.providerId==="credential");if(!s)throw e.context.logger.error("Credential account not found",{email:r}),new de("UNAUTHORIZED",{message:"Invalid email or password"});let a=s?.password;if(!a)throw e.context.logger.error("Password not found",{email:r}),new de("UNAUTHORIZED",{message:"Unexpected error"});if(!await e.context.password.verify(a,t))throw e.context.logger.error("Invalid password"),new de("UNAUTHORIZED",{message:"Invalid email or password"});let d=await e.context.internalAdapter.createSession(n.user.id,e.headers,e.body.dontRememberMe);if(!d)throw e.context.logger.error("Failed to create session"),new de("UNAUTHORIZED",{message:"Failed to create session"});return await y(e,d.id,e.body.dontRememberMe),e.json({user:n.user,session:d,redirect:!!e.body.callbackURL,url:e.body.callbackURL})});import{APIError as qr}from"better-call";import{z as Me}from"zod";import{z as w}from"zod";var xs=w.object({id:w.string(),providerId:w.string(),accountId:w.string(),userId:w.string(),accessToken:w.string().nullable().optional(),refreshToken:w.string().nullable().optional(),idToken:w.string().nullable().optional(),expiresAt:w.date().nullable().optional(),password:w.string().optional().nullable()}),Fe=w.object({id:w.string(),email:w.string().transform(e=>e.toLowerCase()),emailVerified:w.boolean().default(!1),name:w.string(),image:w.string().optional(),createdAt:w.date().default(new Date),updatedAt:w.date().default(new Date)}),js=w.object({id:w.string(),userId:w.string(),expiresAt:w.date(),ipAddress:w.string().optional(),userAgent:w.string().optional()}),Ns=w.object({id:w.string(),value:w.string(),expiresAt:w.date(),identifier:w.string()});function jr(e,r){let t=r.fields,o={};for(let n in t){if(n in e){if(t[n].input===!1){if(t[n].defaultValue){o[n]=t[n].defaultValue;continue}continue}o[n]=e[n];continue}if(t[n].defaultValue){o[n]=t[n].defaultValue;continue}}return o}function vt(e,r){let t={...e.user?.additionalFields};return jr(r||{},{fields:t})}function Nr(e){return e.toString(2).padStart(8,"0")}function Fr(e){return[...e].map(r=>Nr(r)).join("")}function Et(e){return parseInt(Fr(e),2)}function Mr(e){if(e<0||!Number.isInteger(e))throw new Error("Argument 'max' must be an integer greater than or equal to 0");let r=(e-1).toString(2).length,t=r%8,o=new Uint8Array(Math.ceil(r/8));crypto.getRandomValues(o),t!==0&&(o[0]&=(1<<t)-1);let n=Et(o);for(;n>=e;)crypto.getRandomValues(o),t!==0&&(o[0]&=(1<<t)-1),n=Et(o);return n}function $(e,r){let t="";for(let o=0;o<e;o++)t+=r[Mr(r.length)];return t}function V(...e){let r=new Set(e),t="";for(let o of r)o==="a-z"?t+="abcdefghijklmnopqrstuvwxyz":o==="A-Z"?t+="ABCDEFGHIJKLMNOPQRSTUVWXYZ":o==="0-9"?t+="0123456789":t+=o;return t}var _=e=>$(e||21,V("a-z","0-9","A-Z"));var ce={isAction:!1};var $r=c("/callback/:id",{method:"GET",query:Me.object({state:Me.string(),code:Me.string().optional(),error:Me.string().optional()}),metadata:ce},async e=>{if(e.query.error||!e.query.code){let h=ye(e.query.state).data?.callbackURL||`${e.context.baseURL}/error`;throw e.context.logger.error(e.query.error,e.params.id),e.redirect(`${h}?error=${e.query.error||"oAuth_code_missing"}`)}let r=e.context.socialProviders.find(f=>f.id===e.params.id);if(!r)throw e.context.logger.error("Oauth provider with id",e.params.id,"not found"),e.redirect(`${e.context.baseURL}/error?error=oauth_provider_not_found`);let t=ye(e.query.state);if(!t.success)throw e.context.logger.error("Unable to parse state"),e.redirect(`${e.context.baseURL}/error?error=please_restart_the_process`);let{data:{callbackURL:o,currentURL:n}}=t,s=await e.getSignedCookie(e.context.authCookies.state.name,e.context.secret);if(!s)throw A.error("No stored state found"),e.redirect(`${e.context.baseURL}/error?error=please_restart_the_process`);if(!await xe(e.query.state,s))throw A.error("OAuth state mismatch"),e.redirect(`${e.context.baseURL}/error?error=please_restart_the_process`);let i=await e.getSignedCookie(e.context.authCookies.pkCodeVerifier.name,e.context.secret),d;try{d=await r.validateAuthorizationCode(e.query.code,i,`${e.context.baseURL}/callback/${r.id}`)}catch(f){throw e.context.logger.error(f),e.redirect(`${e.context.baseURL}/error?error=please_restart_the_process`)}let u=await r.getUserInfo(d).then(f=>f?.user),l=_(),p=Fe.safeParse({...u,id:l});if(!u||p.success===!1)throw A.error("Unable to get user info",p.error),e.redirect(`${e.context.baseURL}/error?error=please_restart_the_process`);if(!o)throw e.redirect(`${e.context.baseURL}/error?error=please_restart_the_process`);let I=await e.context.internalAdapter.findUserByEmail(u.email,{includeAccounts:!0}).catch(f=>{throw A.error(`Better auth was unable to query your database.
3
- Error: `,f),e.redirect(`${e.context.baseURL}/error?error=internal_server_error`)}),m=I?.user.id;if(I){let f=I.accounts.find(k=>k.providerId===r.id),h=e.context.options.account?.accountLinking?.trustedProviders,O=h?h.includes(r.id):!0;if(!f&&(!u.emailVerified||!O)){let k;try{k=new URL(n||o),k.searchParams.set("error","account_not_linked")}catch{throw e.redirect(`${e.context.baseURL}/error?error=account_not_linked`)}throw e.redirect(k.toString())}if(!f)try{await e.context.internalAdapter.linkAccount({providerId:r.id,accountId:u.id.toString(),id:`${r.id}:${u.id}`,userId:I.user.id,...be(d)})}catch(k){throw console.log(k),e.redirect(`${e.context.baseURL}/error?error=failed_linking_account`)}}else try{await e.context.internalAdapter.createOAuthUser(p.data,{...be(d),id:`${r.id}:${u.id}`,providerId:r.id,accountId:u.id.toString(),userId:l})}catch{let h=new URL(n||o);throw h.searchParams.set("error","unable_to_create_user"),e.setHeader("Location",h.toString()),e.redirect(h.toString())}if(!m&&!l)throw new qr("INTERNAL_SERVER_ERROR",{message:"Unable to create user"});try{let f=await e.context.internalAdapter.createSession(m||l,e.request);if(!f){let h=new URL(n||o);throw h.searchParams.set("error","unable_to_create_session"),e.redirect(h.toString())}try{await y(e,f.id)}catch(h){e.context.logger.error("Unable to set session cookie",h);let O=new URL(n||o);throw O.searchParams.set("error","unable_to_create_session"),e.redirect(O.toString())}}catch{let f=new URL(n||o||"");throw f.searchParams.set("error","unable_to_create_session"),e.redirect(f.toString())}throw e.redirect(o)});import{APIError as Ue}from"better-call";var q=(e,r="ms")=>new Date(Date.now()+(r==="sec"?e*1e3:e));import{z as St}from"zod";var Pt=()=>c("/session",{method:"GET",requireHeaders:!0},async e=>{try{let r=await e.getSignedCookie(e.context.authCookies.sessionToken.name,e.context.secret);if(!r)return e.json(null,{status:401});let t=await e.context.internalAdapter.findSession(r);if(!t||t.session.expiresAt<new Date)return ke(e),t&&await e.context.internalAdapter.deleteSession(t.session.id),e.json(null,{status:401});if(await e.getSignedCookie(e.context.authCookies.dontRememberToken.name,e.context.secret))return e.json(t);let n=e.context.sessionConfig.expiresIn,s=e.context.sessionConfig.updateAge;if(t.session.expiresAt.valueOf()-n*1e3+s*1e3<=Date.now()){let d=await e.context.internalAdapter.updateSession(t.session.id,{expiresAt:q(e.context.sessionConfig.expiresIn,"sec")});if(!d)return ke(e),e.json(null,{status:401});let u=(d.expiresAt.valueOf()-Date.now())/1e3;return await y(e,d.id,!1,{maxAge:u}),e.json({session:d,user:t.user})}return e.json(t)}catch(r){return e.context.logger.error(r),e.json(null,{status:500})}}),G=async e=>await Pt()({...e,_flag:"json",headers:e.headers}),b=z(async e=>{let r=await G(e);if(!r?.session)throw new Ue("UNAUTHORIZED");return{session:r}});var Vr=c("/user/revoke-session",{method:"POST",body:St.object({id:St.string()}),use:[b],requireHeaders:!0},async e=>{let r=e.body.id,t=await e.context.internalAdapter.findSession(r);if(!t)throw new Ue("BAD_REQUEST",{message:"Session not found"});if(t.session.userId!==e.context.session.user.id)throw new Ue("UNAUTHORIZED");try{await e.context.internalAdapter.deleteSession(r)}catch(o){throw e.context.logger.error(o),new Ue("INTERNAL_SERVER_ERROR")}return e.json({status:!0})}),Qr=c("/user/revoke-sessions",{method:"POST",use:[b],requireHeaders:!0},async e=>{try{await e.context.internalAdapter.deleteSessions(e.context.session.user.id)}catch(r){throw e.context.logger.error(r),new Ue("INTERNAL_SERVER_ERROR")}return e.json({status:!0})});import"zod";import{APIError as Hr}from"better-call";var Wr=c("/sign-out",{method:"POST"},async e=>{let r=await e.getSignedCookie(e.context.authCookies.sessionToken.name,e.context.secret);if(!r)throw new Hr("BAD_REQUEST",{message:"Session not found"});return await e.context.internalAdapter.deleteSession(r),ke(e),e.json({success:!0})});import{TimeSpan as Gr}from"oslo";import{createJWT as Zr,parseJWT as Jr}from"oslo/jwt";import{validateJWT as _t}from"oslo/jwt";import{z as Q}from"zod";import{APIError as Ie}from"better-call";var Kr=c("/forget-password",{method:"POST",body:Q.object({email:Q.string().email(),redirectTo:Q.string()}),use:[j]},async e=>{if(!e.context.options.emailAndPassword?.sendResetPassword)throw e.context.logger.error("Reset password isn't enabled.Please pass an emailAndPassword.sendResetPasswordToken function to your auth config!"),new Ie("BAD_REQUEST",{message:"Reset password isn't enabled"});let{email:r,redirectTo:t}=e.body,o=await e.context.internalAdapter.findUserByEmail(r,{includeAccounts:!0});if(!o)return e.context.logger.error("Reset Password: User not found",{email:r}),e.json({status:!1},{body:{status:!0}});let n=await Zr("HS256",Buffer.from(e.context.secret),{email:o.user.email,redirectTo:t},{expiresIn:new Gr(1,"h"),issuer:"better-auth",subject:"forget-password",audiences:[o.user.email],includeIssuedTimestamp:!0}),s=`${e.context.baseURL}/reset-password/${n}`;return await e.context.options.emailAndPassword.sendResetPassword(s,o.user),e.json({status:!0})}),Yr=c("/reset-password/:token",{method:"GET"},async e=>{let{token:r}=e.params,t,o=Q.object({email:Q.string(),redirectTo:Q.string()});try{if(t=await _t("HS256",Buffer.from(e.context.secret),r),!t.expiresAt||t.expiresAt<new Date)throw Error("Token expired")}catch{let a=Jr(r),i=o.safeParse(a?.payload);throw i.success?e.redirect(`${i.data?.redirectTo}?error=invalid_token`):e.redirect(`${e.context.baseURL}/error?error=invalid_token`)}let{redirectTo:n}=o.parse(t.payload);throw e.redirect(`${n}?token=${r}`)}),Xr=c("/reset-password",{method:"POST",query:Q.object({currentURL:Q.string()}).optional(),body:Q.object({newPassword:Q.string(),callbackURL:Q.string().optional()})},async e=>{let r=e.query?.currentURL.split("?token=")[1];if(!r)throw new Ie("BAD_REQUEST",{message:"Token not found"});let{newPassword:t}=e.body;try{let o=await _t("HS256",Buffer.from(e.context.secret),r),n=Q.string().email().parse(o.payload.email),s=await e.context.internalAdapter.findUserByEmail(n);if(!s)return e.json({error:"User not found",data:null},{status:400,body:{message:"failed to reset password"}});if(t.length<(e.context.options.emailAndPassword?.minPasswordLength||8)||t.length>(e.context.options.emailAndPassword?.maxPasswordLength||32))throw new Ie("BAD_REQUEST",{message:"Password is too short or too long"});let a=await e.context.password.hash(t);if(!await e.context.internalAdapter.updatePassword(s.user.id,a))throw new Ie("BAD_REQUEST",{message:"Failed to update password"});return e.json({error:null,data:{status:!0,url:e.body.callbackURL,redirect:!!e.body.callbackURL}},{body:{status:!0,url:e.body.callbackURL,redirect:!!e.body.callbackURL}})}catch(o){throw e.context.logger.error("Failed to reset password",o),new Ie("BAD_REQUEST",{message:"Failed to reset password"})}});import{TimeSpan as eo}from"oslo";import{createJWT as to,validateJWT as ro}from"oslo/jwt";import{z as K}from"zod";import{APIError as Te}from"better-call";async function ve(e,r){return await to("HS256",Buffer.from(e),{email:r.toLowerCase()},{expiresIn:new eo(1,"h"),issuer:"better-auth",subject:"verify-email",audiences:[r],includeIssuedTimestamp:!0})}var oo=c("/send-verification-email",{method:"POST",query:K.object({currentURL:K.string().optional()}).optional(),body:K.object({email:K.string().email(),callbackURL:K.string().optional()}),use:[j]},async e=>{if(!e.context.options.emailAndPassword?.sendVerificationEmail)throw e.context.logger.error("Verification email isn't enabled. Pass `sendVerificationEmail` in `emailAndPassword` options to enable it."),new Te("BAD_REQUEST",{message:"Verification email isn't enabled"});let{email:r}=e.body,t=await e.context.internalAdapter.findUserByEmail(r);if(!t)throw new Te("BAD_REQUEST",{message:"User not found"});let o=await ve(e.context.secret,r),n=`${e.context.baseURL}/verify-email?token=${o}&callbackURL=${e.body.callbackURL||e.query?.currentURL||"/"}`;return await e.context.options.emailAndPassword.sendVerificationEmail(n,t.user,o),e.json({status:!0})}),no=c("/verify-email",{method:"GET",query:K.object({token:K.string(),callbackURL:K.string().optional()})},async e=>{let{token:r}=e.query,t;try{t=await ro("HS256",Buffer.from(e.context.secret),r)}catch(i){throw e.context.logger.error("Failed to verify email",i),new Te("BAD_REQUEST",{message:"Invalid token"})}let n=K.object({email:K.string().email()}).parse(t.payload),s=await e.context.internalAdapter.findUserByEmail(n.email,{includeAccounts:!0});if(!s)throw new Te("BAD_REQUEST",{message:"User not found"});if(!s.accounts.find(i=>i.providerId==="credential"))throw new Te("BAD_REQUEST",{message:"Account not found"});if(await e.context.internalAdapter.updateUserByEmail(n.email,{emailVerified:!0}),e.query.callbackURL)throw e.redirect(e.query.callbackURL);return e.json({status:!0})});import{z as Z}from"zod";import{APIError as Y}from"better-call";var so=c("/user/update",{method:"POST",body:Z.object({name:Z.string().optional(),image:Z.string().optional()}),use:[b,j]},async e=>{let{name:r,image:t}=e.body,o=e.context.session;if(!t&&!r)return e.json({user:o.user});let n=await e.context.internalAdapter.updateUserByEmail(o.user.email,{name:r,image:t});return e.json({user:n})}),io=c("/user/change-password",{method:"POST",body:Z.object({newPassword:Z.string(),currentPassword:Z.string(),revokeOtherSessions:Z.boolean().optional()}),use:[b]},async e=>{let{newPassword:r,currentPassword:t,revokeOtherSessions:o}=e.body,n=e.context.session,s=e.context.password.config.minPasswordLength;if(r.length<s)throw e.context.logger.error("Password is too short"),new Y("BAD_REQUEST",{message:"Password is too short"});let a=e.context.password.config.maxPasswordLength;if(r.length>a)throw e.context.logger.error("Password is too long"),new Y("BAD_REQUEST",{message:"Password too long"});let d=(await e.context.internalAdapter.findAccounts(n.user.id)).find(p=>p.providerId==="credential"&&p.password);if(!d||!d.password)throw new Y("BAD_REQUEST",{message:"User does not have a password"});let u=await e.context.password.hash(r);if(!await e.context.password.verify(d.password,t))throw new Y("BAD_REQUEST",{message:"Incorrect password"});if(await e.context.internalAdapter.updateAccount(d.id,{password:u}),o){await e.context.internalAdapter.deleteSessions(n.user.id);let p=await e.context.internalAdapter.createSession(n.user.id,e.headers);if(!p)throw new Y("INTERNAL_SERVER_ERROR",{message:"Unable to create session"});await y(e,p.id)}return e.json(n.user)}),ao=c("/user/set-password",{method:"POST",body:Z.object({newPassword:Z.string()}),use:[b]},async e=>{let{newPassword:r}=e.body,t=e.context.session,o=e.context.password.config.minPasswordLength;if(r.length<o)throw e.context.logger.error("Password is too short"),new Y("BAD_REQUEST",{message:"Password is too short"});let n=e.context.password.config.maxPasswordLength;if(r.length>n)throw e.context.logger.error("Password is too long"),new Y("BAD_REQUEST",{message:"Password too long"});let a=(await e.context.internalAdapter.findAccounts(t.user.id)).find(d=>d.providerId==="credential"&&d.password),i=await e.context.password.hash(r);if(!a)return await e.context.internalAdapter.linkAccount({userId:t.user.id,providerId:"credential",accountId:t.user.id,password:i}),e.json(t.user);throw new Y("BAD_REQUEST",{message:"user already has a password"})}),co=c("/user/delete",{method:"POST",body:Z.object({password:Z.string()}),use:[b]},async e=>{let{password:r}=e.body,t=e.context.session,n=(await e.context.internalAdapter.findAccounts(t.user.id)).find(a=>a.providerId==="credential"&&a.password);if(!n||!n.password)throw new Y("BAD_REQUEST",{message:"User does not have a password"});if(!await e.context.password.verify(n.password,r))throw new Y("BAD_REQUEST",{message:"Incorrect password"});return await e.context.internalAdapter.deleteUser(t.user.id),await e.context.internalAdapter.deleteSessions(t.user.id),e.json(null)});import{xchacha20poly1305 as Ct}from"@noble/ciphers/chacha";import{bytesToHex as uo,hexToBytes as lo,utf8ToBytes as po}from"@noble/ciphers/utils";import{managedNonce as zt}from"@noble/ciphers/webcrypto";import{sha256 as Bt}from"oslo/crypto";import{decodeHex as Vi,encodeHex as Qi}from"oslo/encoding";import{scryptAsync as Gi}from"@noble/hashes/scrypt";async function J(e,r){let t=new TextEncoder,o={name:"HMAC",hash:"SHA-256"},n=await crypto.subtle.importKey("raw",t.encode(e),o,!1,["sign","verify"]),s=await crypto.subtle.sign(o.name,n,t.encode(r));return btoa(String.fromCharCode(...new Uint8Array(s)))}var qe=async({key:e,data:r})=>{let t=await Bt(new TextEncoder().encode(e)),o=po(r),n=zt(Ct)(new Uint8Array(t));return uo(n.encrypt(o))},$e=async({key:e,data:r})=>{let t=await Bt(new TextEncoder().encode(e)),o=lo(r),n=zt(Ct)(new Uint8Array(t));return new TextDecoder().decode(n.decrypt(o))};var mo=c("/csrf",{method:"GET",metadata:ce},async e=>{let r=await e.getSignedCookie(e.context.authCookies.csrfToken.name,e.context.secret);if(r)return{csrfToken:r};let t=$(32,V("a-z","0-9","A-Z")),o=await J(e.context.secret,t),n=`${t}!${o}`;return await e.setSignedCookie(e.context.authCookies.csrfToken.name,n,e.context.secret,e.context.authCookies.csrfToken.options),{csrfToken:t}});var fo=(e="Unknown")=>`<!DOCTYPE html>
1
+ var mr=Object.defineProperty;var fr=(e,t)=>{for(var r in t)mr(e,r,{get:t[r],enumerable:!0})};import{APIError as tr}from"better-call";import{z as Pe}from"zod";import{createEndpointCreator as gr,createMiddleware as at,createMiddlewareCreator as hr}from"better-call";var dt=at(async()=>({})),z=hr({use:[dt,at(async()=>({}))]}),c=gr({use:[dt]});import{APIError as ae}from"better-call";import{generateCodeVerifier as Br}from"oslo/oauth2";import{z as W}from"zod";import{generateState as wr}from"oslo/oauth2";import{z as De}from"zod";import{sha256 as ct}from"oslo/crypto";function Ze(e,t){let r=new Uint8Array(e),o=new Uint8Array(t);if(r.length!==o.length)return!1;let n=0;for(let s=0;s<r.length;s++)n|=r[s]^o[s];return n===0}async function ut(e){let t=await ct(typeof e=="string"?new TextEncoder().encode(e):e);return Buffer.from(t).toString("base64")}async function Le(e,t){let r=await ct(typeof e=="string"?new TextEncoder().encode(e):e),o=Buffer.from(t,"base64");return Ze(r,o)}async function xe(e){let t=wr(),r=JSON.stringify({code:t,callbackURL:e}),o=await ut(r);return{raw:r,hash:o}}function we(e){return De.object({code:De.string(),callbackURL:De.string().optional(),currentURL:De.string().optional()}).safeParse(JSON.parse(e))}import{TimeSpan as tn}from"oslo";var $=class extends Error{constructor(t,r){super(t),this.name="BetterAuthError",this.message=t,this.cause=r,this.stack=""}};async function y(e,t,r,o){let n=e.context.authCookies.sessionToken.options;n.maxAge=r?void 0:e.context.sessionConfig.expiresIn,await e.setSignedCookie(e.context.authCookies.sessionToken.name,t,e.context.secret,{...n,...o}),r&&await e.setSignedCookie(e.context.authCookies.dontRememberToken.name,"true",e.context.secret,e.context.authCookies.dontRememberToken.options)}function ke(e){e.setCookie(e.context.authCookies.sessionToken.name,"",{maxAge:0}),e.setCookie(e.context.authCookies.dontRememberToken.name,"",{maxAge:0})}import{APIError as lt}from"better-call";import{createConsola as yr}from"consola";var ue=yr({formatOptions:{date:!1,colors:!0,compact:!0},defaults:{tag:"Better Auth"}}),br=e=>({log:(...t)=>{!e?.disabled&&ue.log("",...t)},error:(...t)=>{!e?.disabled&&ue.error("",...t)},warn:(...t)=>{!e?.disabled&&ue.warn("",...t)},info:(...t)=>{!e?.disabled&&ue.info("",...t)},debug:(...t)=>{!e?.disabled&&ue.debug("",...t)},box:(...t)=>{!e?.disabled&&ue.box("",...t)},success:(...t)=>{!e?.disabled&&ue.success("",...t)},break:(...t)=>{!e?.disabled&&console.log(`
2
+ `)}}),A=br();var j=z(async e=>{let t=e.body?.callbackURL||e.query?.callbackURL||e.query?.redirectTo||e.body?.redirectTo,r=e.headers?.get("referer"),o=e.query?.currentURL||r||e.context.baseURL,n=e.context.trustedOrigins;if(t?.includes("http")){let s=new URL(t).origin;if(!n.includes(s))throw A.error("Invalid callback URL",{callbackURL:t,trustedOrigins:n}),new lt("FORBIDDEN",{message:"Invalid callback URL"})}if(o!==e.context.baseURL){let s=new URL(o).origin;if(!n.includes(s))throw A.error("Invalid current URL",{currentURL:o,trustedOrigins:n}),new lt("FORBIDDEN",{message:"Invalid callback URL"})}});import{parseJWT as Ir}from"oslo/jwt";import{sha256 as Rr}from"oslo/crypto";function Ar(e){try{return new URL(e).pathname!=="/"}catch{throw new $(`Invalid base URL: ${e}. Please provide a valid base URL.`)}}function Je(e,t="/api/auth"){return Ar(e)?e:(t=t.startsWith("/")?t:`/${t}`,`${e}${t}`)}function Ke(e,t){if(e)return Je(e,t);let r=typeof process<"u"?process.env:{},o=r.BETTER_AUTH_URL||r.NEXT_PUBLIC_BETTER_AUTH_URL||r.PUBLIC_BETTER_AUTH_URL||r.NUXT_PUBLIC_BETTER_AUTH_URL||r.NUXT_PUBLIC_AUTH_URL||(r.BASE_URL!=="/"?r.BASE_URL:void 0);if(o)return Je(o,t);if(typeof window<"u")return Je(window.location.origin,t)}function pt(e){return new URL(e).origin.replace("http://","").replace("https://","")}import{base64url as Or}from"oslo/encoding";function T(e,t){return t||`${Ke()}/callback/${e}`}async function mt(e){let t=await Rr(new TextEncoder().encode(e));return Or.encode(new Uint8Array(t),{includePadding:!1})}function ft(e){return{tokenType:e.token_type,accessToken:e.access_token,refreshToken:e.refresh_token,accessTokenExpiresAt:e.expires_at?new Date((Date.now()+e.expires_in)*1e3):void 0,scopes:e.scope?.split(" ")||[],idToken:e.id_token}}async function B({id:e,options:t,authorizationEndpoint:r,state:o,codeVerifier:n,scopes:s,disablePkce:a}){let i=new URL(r);if(i.searchParams.set("response_type","code"),i.searchParams.set("client_id",t.clientId),i.searchParams.set("state",o),i.searchParams.set("scope",s.join(" ")),i.searchParams.set("redirect_uri",t.redirectURI||T(e)),!a&&n){let d=await mt(n);i.searchParams.set("code_challenge_method","S256"),i.searchParams.set("code_challenge",d)}return i}import{betterFetch as kr}from"@better-fetch/fetch";async function v({code:e,codeVerifier:t,redirectURI:r,options:o,tokenEndpoint:n}){let s=new URLSearchParams;s.set("grant_type","authorization_code"),s.set("code",e),t&&s.set("code_verifier",t),s.set("redirect_uri",r),s.set("client_id",o.clientId),s.set("client_secret",o.clientSecret);let{data:a,error:i}=await kr(n,{method:"POST",body:s,headers:{"content-type":"application/x-www-form-urlencoded",accept:"application/json","user-agent":"better-auth"}});if(i)throw i;return ft(a)}function ye(e){let t=e.accessToken,r=e.refreshToken,o;try{o=e.accessTokenExpiresAt}catch{}return{accessToken:t,refreshToken:r,expiresAt:o}}var gt=e=>{let t="https://appleid.apple.com/auth/token";return{id:"apple",name:"Apple",createAuthorizationURL({state:r,scopes:o,redirectURI:n}){let s=e.scope||o||["email","name","openid"];return new URL(`https://appleid.apple.com/auth/authorize?client_id=${e.clientId}&response_type=code&redirect_uri=${n||e.redirectURI}&scope=${s.join(" ")}&state=${r}`)},validateAuthorizationCode:async(r,o,n)=>v({code:r,codeVerifier:o,redirectURI:n||T("apple",e.redirectURI),options:e,tokenEndpoint:t}),async getUserInfo(r){if(!r.idToken)return null;let o=Ir(r.idToken)?.payload;return o?{user:{id:o.sub,name:o.name,email:o.email,emailVerified:o.email_verified==="true"},data:o}:null}}};import{betterFetch as Ur}from"@better-fetch/fetch";var ht=e=>({id:"discord",name:"Discord",createAuthorizationURL({state:t,scopes:r}){let o=e.scope||r||["identify","email"];return new URL(`https://discord.com/api/oauth2/authorize?scope=${o.join("+")}&response_type=code&client_id=${e.clientId}&redirect_uri=${encodeURIComponent(T("discord",e.redirectURI))}&state=${t}`)},validateAuthorizationCode:async(t,r,o)=>v({code:t,redirectURI:o||T("discord",e.redirectURI),options:e,tokenEndpoint:"https://discord.com/api/oauth2/token"}),async getUserInfo(t){let{data:r,error:o}=await Ur("https://discord.com/api/users/@me",{headers:{authorization:`Bearer ${t.accessToken}`}});if(o)return null;if(r.avatar===null){let n=r.discriminator==="0"?Number(BigInt(r.id)>>BigInt(22))%6:parseInt(r.discriminator)%5;r.image_url=`https://cdn.discordapp.com/embed/avatars/${n}.png`}else{let n=r.avatar.startsWith("a_")?"gif":"png";r.image_url=`https://cdn.discordapp.com/avatars/${r.id}/${r.avatar}.${n}`}return{user:{id:r.id,name:r.display_name||r.username||"",email:r.email,emailVerified:r.verified,image:r.image_url},data:r}}});import{betterFetch as Tr}from"@better-fetch/fetch";var wt=e=>({id:"facebook",name:"Facebook",async createAuthorizationURL({state:t,scopes:r,codeVerifier:o}){let n=e.scope||r||["email","public_profile"];return await B({id:"facebook",options:e,authorizationEndpoint:"https://www.facebook.com/v16.0/dialog/oauth",scopes:n,state:t,codeVerifier:o})},validateAuthorizationCode:async(t,r,o)=>v({code:t,codeVerifier:r,redirectURI:o||T("facebook",e.redirectURI),options:e,tokenEndpoint:"https://graph.facebook.com/v16.0/oauth/access_token"}),async getUserInfo(t){let{data:r,error:o}=await Tr("https://graph.facebook.com/me",{auth:{type:"Bearer",token:t.accessToken}});return o?null:{user:{id:r.id,name:r.name,email:r.email,emailVerified:r.email_verified},data:r}}});import{betterFetch as yt}from"@better-fetch/fetch";var bt=e=>{let t="https://github.com/login/oauth/access_token";return{id:"github",name:"Github",createAuthorizationURL({state:r,scopes:o,codeVerifier:n}){let s=e.scope||o||["user:email"];return B({id:"github",options:e,authorizationEndpoint:"https://github.com/login/oauth/authorize",scopes:s,state:r,codeVerifier:n})},validateAuthorizationCode:async(r,o,n)=>v({code:r,redirectURI:e.redirectURI||T("google",n),options:e,tokenEndpoint:t}),async getUserInfo(r){let{data:o,error:n}=await yt("https://api.github.com/user",{auth:{type:"Bearer",token:r.accessToken}});if(n)return null;let s=!1;if(!o.email){let{data:a,error:i}=await yt("https://api.github.com/user/emails",{auth:{type:"Bearer",token:r.accessToken}});i||(o.email=(a.find(d=>d.primary)??a[0])?.email,s=a.find(d=>d.email===o.email)?.verified??!1)}return{user:{id:o.id.toString(),name:o.name||o.login,email:o.email,image:o.avatar_url,emailVerified:s},data:o}}}};import{parseJWT as vr}from"oslo/jwt";var At=e=>({id:"google",name:"Google",createAuthorizationURL({state:t,scopes:r,codeVerifier:o,redirectURI:n}){if(!e.clientId||!e.clientSecret)throw A.error("Client Id and Client Secret is required for Google. Make sure to provide them in the options."),new $("CLIENT_ID_AND_SECRET_REQUIRED");if(!o)throw new $("codeVerifier is required for Google");let s=e.scope||r||["email","profile"];return B({id:"google",options:e,authorizationEndpoint:"https://accounts.google.com/o/oauth2/auth",scopes:s,state:t,codeVerifier:o})},validateAuthorizationCode:async(t,r,o)=>v({code:t,codeVerifier:r,redirectURI:o||T("google",e.redirectURI),options:e,tokenEndpoint:"https://oauth2.googleapis.com/token"}),async getUserInfo(t){if(!t.idToken)return null;let r=vr(t.idToken)?.payload;return{user:{id:r.sub,name:r.name,email:r.email,image:r.picture,emailVerified:r.email_verified},data:r}}});import{betterFetch as Er}from"@better-fetch/fetch";import{parseJWT as Sr}from"oslo/jwt";var Rt=e=>{let t=e.tenantId||"common",r=`https://login.microsoftonline.com/${t}/oauth2/v2.0/authorize`,o=`https://login.microsoftonline.com/${t}/oauth2/v2.0/token`;return{id:"microsoft",name:"Microsoft EntraID",createAuthorizationURL(n){let s=e.scope||n.scopes||["openid","profile","email","User.Read"];return B({id:"microsoft",options:e,authorizationEndpoint:r,state:n.state,codeVerifier:n.codeVerifier,scopes:s})},validateAuthorizationCode(n,s,a){return v({code:n,codeVerifier:s,redirectURI:a||T("microsoft",e.redirectURI),options:e,tokenEndpoint:o})},async getUserInfo(n){if(!n.idToken)return null;let s=Sr(n.idToken)?.payload,a=e.profilePhotoSize||48;return await Er(`https://graph.microsoft.com/v1.0/me/photos/${a}x${a}/$value`,{headers:{Authorization:`Bearer ${n.accessToken}`},async onResponse(i){if(!(e.disableProfilePhoto||!i.response.ok))try{let u=await i.response.clone().arrayBuffer(),l=Buffer.from(u).toString("base64");s.picture=`data:image/jpeg;base64, ${l}`}catch(d){A.error(d)}}}),{user:{id:s.sub,name:s.name,email:s.email,image:s.picture,emailVerified:!0},data:s}}}};import{betterFetch as Pr}from"@better-fetch/fetch";var Ot=e=>({id:"spotify",name:"Spotify",createAuthorizationURL({state:t,scopes:r,codeVerifier:o}){let n=e.scope||r||["user-read-email"];return B({id:"spotify",options:e,authorizationEndpoint:"https://accounts.spotify.com/authorize",scopes:n,state:t,codeVerifier:o})},validateAuthorizationCode:async(t,r,o)=>v({code:t,codeVerifier:r,redirectURI:o||T("spotify",e.redirectURI),options:e,tokenEndpoint:"https://accounts.spotify.com/api/token"}),async getUserInfo(t){let{data:r,error:o}=await Pr("https://api.spotify.com/v1/me",{method:"GET",headers:{Authorization:`Bearer ${t.accessToken}`}});return o?null:{user:{id:r.id,name:r.display_name,email:r.email,image:r.images[0]?.url,emailVerified:!1},data:r}}});import{betterFetch as _r}from"@better-fetch/fetch";var kt=e=>({id:"twitch",name:"Twitch",createAuthorizationURL({state:t,scopes:r}){let o=e.scope||r||["activity:write","read"];return B({id:"twitch",options:e,authorizationEndpoint:"https://id.twitch.tv/oauth2/authorize",scopes:o,state:t})},validateAuthorizationCode:async(t,r,o)=>v({code:t,redirectURI:o||T("twitch",e.redirectURI),options:e,tokenEndpoint:"https://id.twitch.tv/oauth2/token"}),async getUserInfo(t){let{data:r,error:o}=await _r("https://api.twitch.tv/helix/users",{method:"GET",headers:{Authorization:`Bearer ${t.accessToken}`}});return o?null:{user:{id:r.sub,name:r.preferred_username,email:r.email,image:r.picture,emailVerified:!1},data:r}}});import{betterFetch as Cr}from"@better-fetch/fetch";var It=e=>({id:"twitter",name:"Twitter",createAuthorizationURL(t){let r=e.scope||t.scopes||["account_info.read"];return B({id:"twitter",options:e,authorizationEndpoint:"https://twitter.com/i/oauth2/authorize",scopes:r,state:t.state,codeVerifier:t.codeVerifier})},validateAuthorizationCode:async(t,r,o)=>v({code:t,codeVerifier:r,redirectURI:o||T("twitch",e.redirectURI),options:e,tokenEndpoint:"https://id.twitch.tv/oauth2/token"}),async getUserInfo(t){let{data:r,error:o}=await Cr("https://api.x.com/2/users/me?user.fields=profile_image_url",{method:"GET",headers:{Authorization:`Bearer ${t.accessToken}`}});return o||!r.data.email?null:{user:{id:r.data.id,name:r.data.name,email:r.data.email,image:r.data.profile_image_url,emailVerified:r.data.verified||!1},data:r}}});var zr={apple:gt,discord:ht,facebook:wt,github:bt,microsoft:Rt,google:At,spotify:Ot,twitch:kt,twitter:It},Ut=Object.keys(zr);var Lr=c("/sign-in/social",{method:"POST",requireHeaders:!0,query:W.object({currentURL:W.string().optional()}).optional(),body:W.object({callbackURL:W.string().optional(),provider:W.enum(Ut)}),use:[j]},async e=>{let t=e.context.socialProviders.find(d=>d.id===e.body.provider);if(!t)throw e.context.logger.error("Provider not found. Make sure to add the provider to your auth config",{provider:e.body.provider}),new ae("NOT_FOUND",{message:"Provider not found"});let r=e.context.authCookies,o=e.query?.currentURL?new URL(e.query?.currentURL):null,n=e.body.callbackURL?.startsWith("http")?e.body.callbackURL:`${o?.origin}${e.body.callbackURL||""}`,s=await xe(n||o?.origin||e.context.options.baseURL);await e.setSignedCookie(r.state.name,s.hash,e.context.secret,r.state.options);let a=Br();await e.setSignedCookie(r.pkCodeVerifier.name,a,e.context.secret,r.pkCodeVerifier.options);let i=await t.createAuthorizationURL({state:s.raw,codeVerifier:a});return i.searchParams.set("redirect_uri",`${e.context.baseURL}/callback/${e.body.provider}`),e.json({url:i.toString(),state:s,codeVerifier:a,redirect:!0})}),Dr=c("/sign-in/email",{method:"POST",body:W.object({email:W.string().email(),password:W.string(),callbackURL:W.string().optional(),dontRememberMe:W.boolean().default(!1).optional()}),use:[j]},async e=>{if(!e.context.options?.emailAndPassword?.enabled)throw e.context.logger.error("Email and password is not enabled. Make sure to enable it in the options on you `auth.ts` file. Check `https://better-auth.com/docs/authentication/email-password` for more!"),new ae("BAD_REQUEST",{message:"Email and password is not enabled"});let{email:t,password:r}=e.body;if(!W.string().email().safeParse(t).success)throw new ae("BAD_REQUEST",{message:"Invalid email"});let n=await e.context.internalAdapter.findUserByEmail(t,{includeAccounts:!0});if(!n)throw await e.context.password.hash(r),e.context.logger.error("User not found",{email:t}),new ae("UNAUTHORIZED",{message:"Invalid email or password"});let s=n.accounts.find(u=>u.providerId==="credential");if(!s)throw e.context.logger.error("Credential account not found",{email:t}),new ae("UNAUTHORIZED",{message:"Invalid email or password"});let a=s?.password;if(!a)throw e.context.logger.error("Password not found",{email:t}),new ae("UNAUTHORIZED",{message:"Unexpected error"});if(!await e.context.password.verify(a,r))throw e.context.logger.error("Invalid password"),new ae("UNAUTHORIZED",{message:"Invalid email or password"});let d=await e.context.internalAdapter.createSession(n.user.id,e.headers,e.body.dontRememberMe);if(!d)throw e.context.logger.error("Failed to create session"),new ae("UNAUTHORIZED",{message:"Failed to create session"});return await y(e,d.id,e.body.dontRememberMe),e.json({user:n.user,session:d,redirect:!!e.body.callbackURL,url:e.body.callbackURL})});import{APIError as Mr}from"better-call";import{z as Ne}from"zod";import{z as w}from"zod";var Ds=w.object({id:w.string(),providerId:w.string(),accountId:w.string(),userId:w.string(),accessToken:w.string().nullable().optional(),refreshToken:w.string().nullable().optional(),idToken:w.string().nullable().optional(),expiresAt:w.date().nullable().optional(),password:w.string().optional().nullable()}),je=w.object({id:w.string(),email:w.string().transform(e=>e.toLowerCase()),emailVerified:w.boolean().default(!1),name:w.string(),image:w.string().optional(),createdAt:w.date().default(new Date),updatedAt:w.date().default(new Date)}),xs=w.object({id:w.string(),userId:w.string(),expiresAt:w.date(),ipAddress:w.string().optional(),userAgent:w.string().optional()}),js=w.object({id:w.string(),value:w.string(),expiresAt:w.date(),identifier:w.string()});function xr(e,t){let r=t.fields,o={};for(let n in r){if(n in e){if(r[n].input===!1){if(r[n].defaultValue){o[n]=r[n].defaultValue;continue}continue}o[n]=e[n];continue}if(r[n].defaultValue){o[n]=r[n].defaultValue;continue}}return o}function Tt(e,t){let r={...e.user?.additionalFields};return xr(t||{},{fields:r})}function jr(e){return e.toString(2).padStart(8,"0")}function Nr(e){return[...e].map(t=>jr(t)).join("")}function vt(e){return parseInt(Nr(e),2)}function Fr(e){if(e<0||!Number.isInteger(e))throw new Error("Argument 'max' must be an integer greater than or equal to 0");let t=(e-1).toString(2).length,r=t%8,o=new Uint8Array(Math.ceil(t/8));crypto.getRandomValues(o),r!==0&&(o[0]&=(1<<r)-1);let n=vt(o);for(;n>=e;)crypto.getRandomValues(o),r!==0&&(o[0]&=(1<<r)-1),n=vt(o);return n}function M(e,t){let r="";for(let o=0;o<e;o++)r+=t[Fr(t.length)];return r}function q(...e){let t=new Set(e),r="";for(let o of t)o==="a-z"?r+="abcdefghijklmnopqrstuvwxyz":o==="A-Z"?r+="ABCDEFGHIJKLMNOPQRSTUVWXYZ":o==="0-9"?r+="0123456789":r+=o;return r}var _=e=>M(e||21,q("a-z","0-9","A-Z"));var de={isAction:!1};var qr=c("/callback/:id",{method:"GET",query:Ne.object({state:Ne.string(),code:Ne.string().optional(),error:Ne.string().optional()}),metadata:de},async e=>{if(e.query.error||!e.query.code){let h=we(e.query.state).data?.callbackURL||`${e.context.baseURL}/error`;throw e.context.logger.error(e.query.error,e.params.id),e.redirect(`${h}?error=${e.query.error||"oAuth_code_missing"}`)}let t=e.context.socialProviders.find(f=>f.id===e.params.id);if(!t)throw e.context.logger.error("Oauth provider with id",e.params.id,"not found"),e.redirect(`${e.context.baseURL}/error?error=oauth_provider_not_found`);let r=we(e.query.state);if(!r.success)throw e.context.logger.error("Unable to parse state"),e.redirect(`${e.context.baseURL}/error?error=please_restart_the_process`);let{data:{callbackURL:o,currentURL:n}}=r,s=await e.getSignedCookie(e.context.authCookies.state.name,e.context.secret);if(!s)throw A.error("No stored state found"),e.redirect(`${e.context.baseURL}/error?error=please_restart_the_process`);if(!await Le(e.query.state,s))throw A.error("OAuth state mismatch"),e.redirect(`${e.context.baseURL}/error?error=please_restart_the_process`);let i=await e.getSignedCookie(e.context.authCookies.pkCodeVerifier.name,e.context.secret),d;try{d=await t.validateAuthorizationCode(e.query.code,i,`${e.context.baseURL}/callback/${t.id}`)}catch(f){throw e.context.logger.error(f),e.redirect(`${e.context.baseURL}/error?error=please_restart_the_process`)}let u=await t.getUserInfo(d).then(f=>f?.user),l=_(),p=je.safeParse({...u,id:l});if(!u||p.success===!1)throw A.error("Unable to get user info",p.error),e.redirect(`${e.context.baseURL}/error?error=please_restart_the_process`);if(!o)throw e.redirect(`${e.context.baseURL}/error?error=please_restart_the_process`);let U=await e.context.internalAdapter.findUserByEmail(u.email,{includeAccounts:!0}).catch(f=>{throw A.error(`Better auth was unable to query your database.
3
+ Error: `,f),e.redirect(`${e.context.baseURL}/error?error=internal_server_error`)}),m=U?.user.id;if(U){let f=U.accounts.find(k=>k.providerId===t.id),h=e.context.options.account?.accountLinking?.trustedProviders,O=h?h.includes(t.id):!0;if(!f&&(!u.emailVerified||!O)){let k;try{k=new URL(n||o),k.searchParams.set("error","account_not_linked")}catch{throw e.redirect(`${e.context.baseURL}/error?error=account_not_linked`)}throw e.redirect(k.toString())}if(!f)try{await e.context.internalAdapter.linkAccount({providerId:t.id,accountId:u.id.toString(),id:`${t.id}:${u.id}`,userId:U.user.id,...ye(d)})}catch(k){throw console.log(k),e.redirect(`${e.context.baseURL}/error?error=failed_linking_account`)}}else try{await e.context.internalAdapter.createOAuthUser(p.data,{...ye(d),id:`${t.id}:${u.id}`,providerId:t.id,accountId:u.id.toString(),userId:l})}catch{let h=new URL(n||o);throw h.searchParams.set("error","unable_to_create_user"),e.setHeader("Location",h.toString()),e.redirect(h.toString())}if(!m&&!l)throw new Mr("INTERNAL_SERVER_ERROR",{message:"Unable to create user"});try{let f=await e.context.internalAdapter.createSession(m||l,e.request);if(!f){let h=new URL(n||o);throw h.searchParams.set("error","unable_to_create_session"),e.redirect(h.toString())}try{await y(e,f.id)}catch(h){e.context.logger.error("Unable to set session cookie",h);let O=new URL(n||o);throw O.searchParams.set("error","unable_to_create_session"),e.redirect(O.toString())}}catch{let f=new URL(n||o||"");throw f.searchParams.set("error","unable_to_create_session"),e.redirect(f.toString())}throw e.redirect(o)});import{APIError as Ie}from"better-call";var V=(e,t="ms")=>new Date(Date.now()+(t==="sec"?e*1e3:e));import{z as Et}from"zod";var St=()=>c("/session",{method:"GET",requireHeaders:!0},async e=>{try{let t=await e.getSignedCookie(e.context.authCookies.sessionToken.name,e.context.secret);if(!t)return e.json(null,{status:401});let r=await e.context.internalAdapter.findSession(t);if(!r||r.session.expiresAt<new Date)return ke(e),r&&await e.context.internalAdapter.deleteSession(r.session.id),e.json(null,{status:401});if(await e.getSignedCookie(e.context.authCookies.dontRememberToken.name,e.context.secret))return e.json(r);let n=e.context.sessionConfig.expiresIn,s=e.context.sessionConfig.updateAge;if(r.session.expiresAt.valueOf()-n*1e3+s*1e3<=Date.now()){let d=await e.context.internalAdapter.updateSession(r.session.id,{expiresAt:V(e.context.sessionConfig.expiresIn,"sec")});if(!d)return ke(e),e.json(null,{status:401});let u=(d.expiresAt.valueOf()-Date.now())/1e3;return await y(e,d.id,!1,{maxAge:u}),e.json({session:d,user:r.user})}return e.json(r)}catch(t){return e.context.logger.error(t),e.json(null,{status:500})}}),G=async e=>await St()({...e,_flag:"json",headers:e.headers}),b=z(async e=>{let t=await G(e);if(!t?.session)throw new Ie("UNAUTHORIZED");return{session:t}});var $r=c("/user/revoke-session",{method:"POST",body:Et.object({id:Et.string()}),use:[b],requireHeaders:!0},async e=>{let t=e.body.id,r=await e.context.internalAdapter.findSession(t);if(!r)throw new Ie("BAD_REQUEST",{message:"Session not found"});if(r.session.userId!==e.context.session.user.id)throw new Ie("UNAUTHORIZED");try{await e.context.internalAdapter.deleteSession(t)}catch(o){throw e.context.logger.error(o),new Ie("INTERNAL_SERVER_ERROR")}return e.json({status:!0})}),Vr=c("/user/revoke-sessions",{method:"POST",use:[b],requireHeaders:!0},async e=>{try{await e.context.internalAdapter.deleteSessions(e.context.session.user.id)}catch(t){throw e.context.logger.error(t),new Ie("INTERNAL_SERVER_ERROR")}return e.json({status:!0})});import"zod";import{APIError as Qr}from"better-call";var Hr=c("/sign-out",{method:"POST"},async e=>{let t=await e.getSignedCookie(e.context.authCookies.sessionToken.name,e.context.secret);if(!t)throw new Qr("BAD_REQUEST",{message:"Session not found"});return await e.context.internalAdapter.deleteSession(t),ke(e),e.json({success:!0})});import{TimeSpan as Wr}from"oslo";import{createJWT as Gr,parseJWT as Zr}from"oslo/jwt";import{validateJWT as Pt}from"oslo/jwt";import{z as Q}from"zod";import{APIError as Ue}from"better-call";var Jr=c("/forget-password",{method:"POST",body:Q.object({email:Q.string().email(),redirectTo:Q.string()}),use:[j]},async e=>{if(!e.context.options.emailAndPassword?.sendResetPassword)throw e.context.logger.error("Reset password isn't enabled.Please pass an emailAndPassword.sendResetPasswordToken function to your auth config!"),new Ue("BAD_REQUEST",{message:"Reset password isn't enabled"});let{email:t,redirectTo:r}=e.body,o=await e.context.internalAdapter.findUserByEmail(t,{includeAccounts:!0});if(!o)return e.context.logger.error("Reset Password: User not found",{email:t}),e.json({status:!1},{body:{status:!0}});let n=await Gr("HS256",Buffer.from(e.context.secret),{email:o.user.email,redirectTo:r},{expiresIn:new Wr(1,"h"),issuer:"better-auth",subject:"forget-password",audiences:[o.user.email],includeIssuedTimestamp:!0}),s=`${e.context.baseURL}/reset-password/${n}`;return await e.context.options.emailAndPassword.sendResetPassword(s,o.user),e.json({status:!0})}),Kr=c("/reset-password/:token",{method:"GET"},async e=>{let{token:t}=e.params,r,o=Q.object({email:Q.string(),redirectTo:Q.string()});try{if(r=await Pt("HS256",Buffer.from(e.context.secret),t),!r.expiresAt||r.expiresAt<new Date)throw Error("Token expired")}catch{let a=Zr(t),i=o.safeParse(a?.payload);throw i.success?e.redirect(`${i.data?.redirectTo}?error=invalid_token`):e.redirect(`${e.context.baseURL}/error?error=invalid_token`)}let{redirectTo:n}=o.parse(r.payload);throw e.redirect(`${n}?token=${t}`)}),Yr=c("/reset-password",{method:"POST",query:Q.object({currentURL:Q.string()}).optional(),body:Q.object({newPassword:Q.string(),callbackURL:Q.string().optional()})},async e=>{let t=e.query?.currentURL.split("?token=")[1];if(!t)throw new Ue("BAD_REQUEST",{message:"Token not found"});let{newPassword:r}=e.body;try{let o=await Pt("HS256",Buffer.from(e.context.secret),t),n=Q.string().email().parse(o.payload.email),s=await e.context.internalAdapter.findUserByEmail(n);if(!s)return e.json({error:"User not found",data:null},{status:400,body:{message:"failed to reset password"}});if(r.length<(e.context.options.emailAndPassword?.minPasswordLength||8)||r.length>(e.context.options.emailAndPassword?.maxPasswordLength||32))throw new Ue("BAD_REQUEST",{message:"Password is too short or too long"});let a=await e.context.password.hash(r);if(!await e.context.internalAdapter.updatePassword(s.user.id,a))throw new Ue("BAD_REQUEST",{message:"Failed to update password"});return e.json({error:null,data:{status:!0,url:e.body.callbackURL,redirect:!!e.body.callbackURL}},{body:{status:!0,url:e.body.callbackURL,redirect:!!e.body.callbackURL}})}catch(o){throw e.context.logger.error("Failed to reset password",o),new Ue("BAD_REQUEST",{message:"Failed to reset password"})}});import{TimeSpan as Xr}from"oslo";import{createJWT as eo,validateJWT as to}from"oslo/jwt";import{z as K}from"zod";import{APIError as Te}from"better-call";async function Ye(e,t){return await eo("HS256",Buffer.from(e),{email:t.toLowerCase()},{expiresIn:new Xr(1,"h"),issuer:"better-auth",subject:"verify-email",audiences:[t],includeIssuedTimestamp:!0})}var ro=c("/send-verification-email",{method:"POST",query:K.object({currentURL:K.string().optional()}).optional(),body:K.object({email:K.string().email(),callbackURL:K.string().optional()}),use:[j]},async e=>{if(!e.context.options.emailAndPassword?.sendVerificationEmail)throw e.context.logger.error("Verification email isn't enabled. Pass `sendVerificationEmail` in `emailAndPassword` options to enable it."),new Te("BAD_REQUEST",{message:"Verification email isn't enabled"});let{email:t}=e.body,r=await e.context.internalAdapter.findUserByEmail(t);if(!r)throw new Te("BAD_REQUEST",{message:"User not found"});let o=await Ye(e.context.secret,t),n=`${e.context.baseURL}/verify-email?token=${o}&callbackURL=${e.body.callbackURL||e.query?.currentURL||"/"}`;return await e.context.options.emailAndPassword.sendVerificationEmail(n,r.user,o),e.json({status:!0})}),oo=c("/verify-email",{method:"GET",query:K.object({token:K.string(),callbackURL:K.string().optional()})},async e=>{let{token:t}=e.query,r;try{r=await to("HS256",Buffer.from(e.context.secret),t)}catch(i){throw e.context.logger.error("Failed to verify email",i),new Te("BAD_REQUEST",{message:"Invalid token"})}let n=K.object({email:K.string().email()}).parse(r.payload),s=await e.context.internalAdapter.findUserByEmail(n.email,{includeAccounts:!0});if(!s)throw new Te("BAD_REQUEST",{message:"User not found"});if(!s.accounts.find(i=>i.providerId==="credential"))throw new Te("BAD_REQUEST",{message:"Account not found"});if(await e.context.internalAdapter.updateUserByEmail(n.email,{emailVerified:!0}),e.query.callbackURL)throw e.redirect(e.query.callbackURL);return e.json({status:!0})});import{z as Z}from"zod";import{APIError as Y}from"better-call";var no=c("/user/update",{method:"POST",body:Z.object({name:Z.string().optional(),image:Z.string().optional()}),use:[b,j]},async e=>{let{name:t,image:r}=e.body,o=e.context.session;if(!r&&!t)return e.json({user:o.user});let n=await e.context.internalAdapter.updateUserByEmail(o.user.email,{name:t,image:r});return e.json({user:n})}),so=c("/user/change-password",{method:"POST",body:Z.object({newPassword:Z.string(),currentPassword:Z.string(),revokeOtherSessions:Z.boolean().optional()}),use:[b]},async e=>{let{newPassword:t,currentPassword:r,revokeOtherSessions:o}=e.body,n=e.context.session,s=e.context.password.config.minPasswordLength;if(t.length<s)throw e.context.logger.error("Password is too short"),new Y("BAD_REQUEST",{message:"Password is too short"});let a=e.context.password.config.maxPasswordLength;if(t.length>a)throw e.context.logger.error("Password is too long"),new Y("BAD_REQUEST",{message:"Password too long"});let d=(await e.context.internalAdapter.findAccounts(n.user.id)).find(p=>p.providerId==="credential"&&p.password);if(!d||!d.password)throw new Y("BAD_REQUEST",{message:"User does not have a password"});let u=await e.context.password.hash(t);if(!await e.context.password.verify(d.password,r))throw new Y("BAD_REQUEST",{message:"Incorrect password"});if(await e.context.internalAdapter.updateAccount(d.id,{password:u}),o){await e.context.internalAdapter.deleteSessions(n.user.id);let p=await e.context.internalAdapter.createSession(n.user.id,e.headers);if(!p)throw new Y("INTERNAL_SERVER_ERROR",{message:"Unable to create session"});await y(e,p.id)}return e.json(n.user)}),io=c("/user/set-password",{method:"POST",body:Z.object({newPassword:Z.string()}),use:[b]},async e=>{let{newPassword:t}=e.body,r=e.context.session,o=e.context.password.config.minPasswordLength;if(t.length<o)throw e.context.logger.error("Password is too short"),new Y("BAD_REQUEST",{message:"Password is too short"});let n=e.context.password.config.maxPasswordLength;if(t.length>n)throw e.context.logger.error("Password is too long"),new Y("BAD_REQUEST",{message:"Password too long"});let a=(await e.context.internalAdapter.findAccounts(r.user.id)).find(d=>d.providerId==="credential"&&d.password),i=await e.context.password.hash(t);if(!a)return await e.context.internalAdapter.linkAccount({userId:r.user.id,providerId:"credential",accountId:r.user.id,password:i}),e.json(r.user);throw new Y("BAD_REQUEST",{message:"user already has a password"})}),ao=c("/user/delete",{method:"POST",body:Z.object({password:Z.string()}),use:[b]},async e=>{let{password:t}=e.body,r=e.context.session,n=(await e.context.internalAdapter.findAccounts(r.user.id)).find(a=>a.providerId==="credential"&&a.password);if(!n||!n.password)throw new Y("BAD_REQUEST",{message:"User does not have a password"});if(!await e.context.password.verify(n.password,t))throw new Y("BAD_REQUEST",{message:"Incorrect password"});return await e.context.internalAdapter.deleteUser(r.user.id),await e.context.internalAdapter.deleteSessions(r.user.id),e.json(null)});import{xchacha20poly1305 as _t}from"@noble/ciphers/chacha";import{bytesToHex as co,hexToBytes as uo,utf8ToBytes as lo}from"@noble/ciphers/utils";import{managedNonce as Ct}from"@noble/ciphers/webcrypto";import{sha256 as zt}from"oslo/crypto";import{decodeHex as $i,encodeHex as Vi}from"oslo/encoding";import{scryptAsync as Wi}from"@noble/hashes/scrypt";async function J(e,t){let r=new TextEncoder,o={name:"HMAC",hash:"SHA-256"},n=await crypto.subtle.importKey("raw",r.encode(e),o,!1,["sign","verify"]),s=await crypto.subtle.sign(o.name,n,r.encode(t));return btoa(String.fromCharCode(...new Uint8Array(s)))}var Fe=async({key:e,data:t})=>{let r=await zt(new TextEncoder().encode(e)),o=lo(t),n=Ct(_t)(new Uint8Array(r));return co(n.encrypt(o))},Me=async({key:e,data:t})=>{let r=await zt(new TextEncoder().encode(e)),o=uo(t),n=Ct(_t)(new Uint8Array(r));return new TextDecoder().decode(n.decrypt(o))};var po=c("/csrf",{method:"GET",metadata:de},async e=>{let t=await e.getSignedCookie(e.context.authCookies.csrfToken.name,e.context.secret);if(t)return{csrfToken:t};let r=M(32,q("a-z","0-9","A-Z")),o=await J(e.context.secret,r),n=`${r}!${o}`;return await e.setSignedCookie(e.context.authCookies.csrfToken.name,n,e.context.secret,e.context.authCookies.csrfToken.options),{csrfToken:r}});var mo=(e="Unknown")=>`<!DOCTYPE html>
4
4
  <html lang="en">
5
5
  <head>
6
6
  <meta charset="UTF-8">
@@ -80,5 +80,5 @@ Error: `,f),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>`,go=c("/error",{method:"GET",metadata:ce},async e=>{let r=new URL(e.request?.url||"").searchParams.get("error")||"Unknown";return new Response(fo(r),{headers:{"Content-Type":"text/html"}})});var ho=c("/ok",{method:"GET",metadata:ce},async e=>e.json({ok:!0}));import{z as Ae}from"zod";import{APIError as pe}from"better-call";var Ee=()=>c("/sign-up/email",{method:"POST",query:Ae.object({currentURL:Ae.string().optional()}).optional(),body:Ae.record(Ae.string(),Ae.any()),use:[j]},async e=>{if(!e.context.options.emailAndPassword?.enabled)throw new pe("BAD_REQUEST",{message:"Email and password sign up is not enabled"});let r=e.body,{name:t,email:o,password:n,image:s,callbackURL:a,...i}=r;if(!Ae.string().email().safeParse(o).success)throw new pe("BAD_REQUEST",{message:"Invalid email"});let u=e.context.password.config.minPasswordLength;if(n.length<u)throw e.context.logger.error("Password is too short"),new pe("BAD_REQUEST",{message:"Password is too short"});let l=e.context.password.config.maxPasswordLength;if(n.length>l)throw e.context.logger.error("Password is too long"),new pe("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 pe("UNPROCESSABLE_ENTITY",{message:"The email has already been taken"});let I=vt(e.context.options,i),m=await e.context.internalAdapter.createUser({email:o.toLowerCase(),name:t,image:s,...I,emailVerified:!1});if(!m)throw new pe("BAD_REQUEST",{message:"Failed to create user"});let f=await e.context.password.hash(n);await e.context.internalAdapter.linkAccount({userId:m.id,providerId:"credential",accountId:m.id,password:f,expiresAt:q(60*60*24*30,"sec")});let h=await e.context.internalAdapter.createSession(m.id,e.request);if(!h)throw new pe("BAD_REQUEST",{message:"Failed to create session"});if(await y(e,h.id),e.context.options.emailAndPassword.sendEmailVerificationOnSignUp){let O=await ve(e.context.secret,m.email),k=`${e.context.baseURL}/verify-email?token=${O}&callbackURL=${r.callbackURL||e.query?.currentURL||"/"}`;await e.context.options.emailAndPassword.sendVerificationEmail?.(k,m,O)}return e.json({user:m,session:h,error:null},{body:r.callbackURL?{url:r.callbackURL,redirect:!0}:{user:m,session:h}})});var Lt=(e,r)=>{let t={};for(let[o,n]of Object.entries(e))t[o]=s=>n({...s,context:{...r,...s.context}}),t[o].path=n.path,t[o].method=n.method,t[o].options=n.options,t[o].headers=n.headers;return t};var Mt={};gr(Mt,{AccessControl:()=>Se,ParsingError:()=>me,Role:()=>Re,adminAc:()=>jt,createAccessControl:()=>Dt,defaultAc:()=>Ve,defaultRoles:()=>et,defaultStatements:()=>xt,memberAc:()=>Ft,ownerAc:()=>Nt,permissionFromString:()=>wo});var me=class extends Error{path;constructor(r,t){super(r),this.path=t}},Se=class{constructor(r){this.s=r;this.statements=r}statements;newRole(r){return new Re(r)}},Re=class e{statements;constructor(r){this.statements=r}authorize(r,t){for(let[o,n]of Object.entries(r)){let s=this.statements[o];if(!s)return{success:!1,error:`You are not allowed to access resource: ${o}`};let a=t==="OR"?n.some(i=>s.includes(i)):n.every(i=>s.includes(i));return a?{success:a}:{success:!1,error:`unauthorized to access resource "${o}"`}}return{success:!1,error:"Not authorized"}}static fromString(r){let t=JSON.parse(r);if(typeof t!="object")throw new me("statements is not an object",".");for(let[o,n]of Object.entries(t)){if(typeof o!="string")throw new me("invalid resource identifier",o);if(!Array.isArray(n))throw new me("actions is not an array",o);for(let s=0;s<n.length;s++)if(typeof n[s]!="string")throw new me("action is not a string",`${o}[${s}]`)}return new e(t)}toString(){return JSON.stringify(this.statements)}};var Dt=e=>new Se(e),xt={organization:["update","delete"],member:["create","update","delete"],invitation:["create","cancel"]},Ve=Dt(xt),jt=Ve.newRole({organization:["update"],invitation:["create","cancel"],member:["create","update","delete"]}),Nt=Ve.newRole({organization:["update","delete"],member:["create","update","delete"],invitation:["create","cancel"]}),Ft=Ve.newRole({organization:[],member:[],invitation:[]}),et={admin:jt,owner:Nt,member:Ft};var wo=e=>Re.fromString(e??"");var S=(e,r)=>({findOrganizationBySlug:async t=>await e.findOne({model:"organization",where:[{field:"slug",value:t}]}),createOrganization:async t=>{let o=await e.create({model:"organization",data:{...t.organization,metadata:t.organization.metadata?JSON.stringify(t.organization.metadata):void 0}}),n=await e.create({model:"member",data:{id:_(),organizationId:o.id,userId:t.user.id,createdAt:new Date,email:t.user.email,role:r?.creatorRole||"owner"}});return{...o,metadata:o.metadata?JSON.parse(o.metadata):void 0,members:[{...n,user:{id:t.user.id,name:t.user.name,email:t.user.email,image:t.user.image}}]}},findMemberByEmail:async t=>{let o=await e.findOne({model:"member",where:[{field:"email",value:t.email},{field:"organizationId",value:t.organizationId}]});if(!o)return null;let n=await e.findOne({model:"user",where:[{field:"id",value:o.userId}]});return n?{...o,user:{id:n.id,name:n.name,email:n.email,image:n.image}}:null},findMemberByOrgId:async t=>{let o=await e.findOne({model:"member",where:[{field:"userId",value:t.userId},{field:"organizationId",value:t.organizationId}]});if(!o)return null;let n=await e.findOne({model:"user",where:[{field:"id",value:o.userId}]});return n?{...o,user:{id:n.id,name:n.name,email:n.email,image:n.image}}:null},findMemberById:async t=>{let o=await e.findOne({model:"member",where:[{field:"id",value:t}]});if(!o)return null;let n=await e.findOne({model:"user",where:[{field:"id",value:o.userId}]});return n?{...o,user:{id:n.id,name:n.name,email:n.email,image:n.image}}:null},createMember:async t=>await e.create({model:"member",data:t}),updateMember:async(t,o)=>await e.update({model:"member",where:[{field:"id",value:t}],update:{role:o}}),deleteMember:async t=>await e.delete({model:"member",where:[{field:"id",value:t}]}),updateOrganization:async(t,o)=>await e.update({model:"organization",where:[{field:"id",value:t}],update:o}),deleteOrganization:async t=>(await e.delete({model:"member",where:[{field:"organizationId",value:t}]}),await e.delete({model:"invitation",where:[{field:"organizationId",value:t}]}),await e.delete({model:"organization",where:[{field:"id",value:t}]}),t),setActiveOrganization:async(t,o)=>await e.update({model:"session",where:[{field:"id",value:t}],update:{activeOrganizationId:o}}),findOrganizationById:async t=>await e.findOne({model:"organization",where:[{field:"id",value:t}]}),findFullOrganization:async(t,o)=>{let n=await e.findOne({model:"organization",where:[{field:"id",value:t}]});if(!n)return null;let s=await e.findMany({model:"invitation",where:[{field:"organizationId",value:t}]}),a=await e.findMany({model:"member",where:[{field:"organizationId",value:t}]}),i=await Promise.all(a.map(async u=>{let l=await e.findOne({model:"user",where:[{field:"id",value:u.userId}]});if(!l)throw new M("Unexpected error: User not found for member");return{...u,user:{id:l.id,name:l.name,email:l.email,image:l.image}}}));return{...n,invitations:s,members:i}},listOrganizations:async t=>{let n=(await e.findMany({model:"member",where:[{field:"userId",value:t}]}))?.map(a=>a.organizationId);if(!n)return[];let s=[];for(let a of n){let i=await e.findOne({model:"organization",where:[{field:"id",value:a}]});i&&s.push(i)}return s},createInvitation:async({invitation:t,user:o})=>{let s=q(r?.invitationExpiresIn||1728e5);return await e.create({model:"invitation",data:{id:_(),email:t.email,role:t.role,organizationId:t.organizationId,status:"pending",expiresAt:s,inviterId:o.id}})},findInvitationById:async t=>await e.findOne({model:"invitation",where:[{field:"id",value:t}]}),findPendingInvitation:async t=>(await e.findMany({model:"invitation",where:[{field:"email",value:t.email},{field:"organizationId",value:t.organizationId},{field:"status",value:"pending"}]})).filter(n=>new Date(n.expiresAt)>new Date),updateInvitation:async t=>await e.update({model:"invitation",where:[{field:"id",value:t.invitationId}],update:{status:t.status}})});import"better-call";import{APIError as yd,createRouter as bd}from"better-call";import{APIError as tt}from"better-call";import{z as qt}from"zod";var yo=z({body:qt.object({csrfToken:qt.string().optional()}).optional()},async e=>{if(e.request?.method!=="POST"||e.context.options.advanced?.disableCSRFCheck)return;let r=new URL(e.request.url);if(e.context.trustedOrigins.includes(r.origin))return;let t=e.body?.csrfToken;if(!t)throw new tt("UNAUTHORIZED",{message:"CSRF Token is required"});let o=await e.getSignedCookie(e.context.authCookies.csrfToken.name,e.context.secret),[n,s]=o?.split("!")||[null,null];if(!t||!o||!n||!s||o!==t)throw e.setCookie(e.context.authCookies.csrfToken.name,"",{maxAge:0}),new tt("UNAUTHORIZED",{message:"Invalid CSRF Token"});let a=await J(e.context.secret,n);if(s!==a)throw e.setCookie(e.context.authCookies.csrfToken.name,"",{maxAge:0}),new tt("UNAUTHORIZED",{message:"Invalid CSRF Token"})});import{APIError as ue}from"better-call";var L=z(async e=>({})),N=z({use:[b]},async e=>({session:e.context.session}));import{z as H}from"zod";import{z as U}from"zod";var Qe=U.enum(["admin","member","owner"]),bo=U.enum(["pending","accepted","rejected","canceled"]).default("pending"),qd=U.object({id:U.string(),name:U.string(),slug:U.string(),logo:U.string().optional(),metadata:U.record(U.string()).or(U.string().transform(e=>JSON.parse(e))).optional(),createdAt:U.date()}),$d=U.object({id:U.string(),email:U.string(),organizationId:U.string(),userId:U.string(),role:Qe,createdAt:U.date()}),Vd=U.object({id:U.string(),organizationId:U.string(),email:U.string(),role:Qe,status:bo,inviterId:U.string(),expiresAt:U.date()});import{APIError as E}from"better-call";var $t=c("/organization/invite-member",{method:"POST",use:[L,N],body:H.object({email:H.string(),role:Qe,organizationId:H.string().optional(),resend:H.boolean().optional()})},async e=>{if(!e.context.orgOptions.sendInvitationEmail)throw A.warn("Invitation email is not enabled. Pass `sendInvitationEmail` to the plugin options to enable it."),new E("BAD_REQUEST",{message:"Invitation email is not enabled"});let r=e.context.session,t=e.body.organizationId||r.session.activeOrganizationId;if(!t)throw new E("BAD_REQUEST",{message:"Organization not found"});let o=S(e.context.adapter,e.context.orgOptions),n=await o.findMemberByOrgId({userId:r.user.id,organizationId:t});if(!n)throw new E("BAD_REQUEST",{message:"Member not found!"});let s=e.context.roles[n.role];if(!s)throw new E("BAD_REQUEST",{message:"Role not found!"});if(s.authorize({invitation:["create"]}).error)throw new E("FORBIDDEN",{message:"You are not allowed to invite members"});if(await o.findMemberByEmail({email:e.body.email,organizationId:t}))throw new E("BAD_REQUEST",{message:"User is already a member of this organization"});if((await o.findPendingInvitation({email:e.body.email,organizationId:t})).length&&!e.body.resend)throw new E("BAD_REQUEST",{message:"User is already invited to this organization"});let u=await o.createInvitation({invitation:{role:e.body.role,email:e.body.email,organizationId:t},user:r.user}),l=await o.findOrganizationById(t);if(!l)throw new E("BAD_REQUEST",{message:"Organization not found"});return await e.context.orgOptions.sendInvitationEmail?.({id:u.id,role:u.role,email:u.email,organization:l,inviter:{...n,user:r.user}},e.request),e.json(u)}),Vt=c("/organization/accept-invitation",{method:"POST",body:H.object({invitationId:H.string()}),use:[L,N]},async e=>{let r=e.context.session,t=S(e.context.adapter,e.context.orgOptions),o=await t.findInvitationById(e.body.invitationId);if(!o||o.expiresAt<new Date||o.status!=="pending")throw new E("BAD_REQUEST",{message:"Invitation not found!"});if(o.email!==r.user.email)throw new E("FORBIDDEN",{message:"You are not the recipient of the invitation"});let n=await t.updateInvitation({invitationId:e.body.invitationId,status:"accepted"}),s=await t.createMember({id:_(),organizationId:o.organizationId,userId:r.user.id,email:o.email,role:o.role,createdAt:new Date});return await t.setActiveOrganization(r.session.id,o.organizationId),n?e.json({invitation:n,member:s}):e.json(null,{status:400,body:{message:"Invitation not found!"}})}),Qt=c("/organization/reject-invitation",{method:"POST",body:H.object({invitationId:H.string()}),use:[L,N]},async e=>{let r=e.context.session,t=S(e.context.adapter,e.context.orgOptions),o=await t.findInvitationById(e.body.invitationId);if(!o||o.expiresAt<new Date||o.status!=="pending")throw new E("BAD_REQUEST",{message:"Invitation not found!"});if(o.email!==r.user.email)throw new E("FORBIDDEN",{message:"You are not the recipient of the invitation"});let n=await t.updateInvitation({invitationId:e.body.invitationId,status:"rejected"});return e.json({invitation:n,member:null})}),Ht=c("/organization/cancel-invitation",{method:"POST",body:H.object({invitationId:H.string()}),use:[L,N]},async e=>{let r=e.context.session,t=S(e.context.adapter,e.context.orgOptions),o=await t.findInvitationById(e.body.invitationId);if(!o)throw new E("BAD_REQUEST",{message:"Invitation not found!"});let n=await t.findMemberByOrgId({userId:r.user.id,organizationId:o.organizationId});if(!n)throw new E("BAD_REQUEST",{message:"Member not found!"});if(e.context.roles[n.role].authorize({invitation:["cancel"]}).error)throw new E("FORBIDDEN",{message:"You are not allowed to cancel this invitation"});let a=await t.updateInvitation({invitationId:e.body.invitationId,status:"canceled"});return e.json(a)}),Wt=c("/organization/get-invitation",{method:"GET",use:[L],requireHeaders:!0,query:H.object({id:H.string()})},async e=>{let r=await G(e);if(!r)throw new E("UNAUTHORIZED",{message:"Not authenticated"});let t=S(e.context.adapter,e.context.orgOptions),o=await t.findInvitationById(e.query.id);if(!o||o.status!=="pending"||o.expiresAt<new Date)throw new E("BAD_REQUEST",{message:"Invitation not found!"});if(o.email!==r.user.email)throw new E("FORBIDDEN",{message:"You are not the recipient of the invitation"});let n=await t.findOrganizationById(o.organizationId);if(!n)throw new E("BAD_REQUEST",{message:"Organization not found"});let s=await t.findMemberByOrgId({userId:o.inviterId,organizationId:o.organizationId});if(!s)throw new E("BAD_REQUEST",{message:"Inviter is no longer a member of the organization"});return e.json({...o,organizationName:n.name,organizationSlug:n.slug,inviterEmail:s.email})});import{z as fe}from"zod";import{APIError as Pe}from"better-call";var Gt=c("/organization/remove-member",{method:"POST",body:fe.object({memberIdOrEmail:fe.string(),organizationId:fe.string().optional()}),use:[L,N]},async e=>{let r=e.context.session,t=e.body.organizationId||r.session.activeOrganizationId;if(!t)return e.json(null,{status:400,body:{message:"No active organization found!"}});let o=S(e.context.adapter,e.context.orgOptions),n=await o.findMemberByOrgId({userId:r.user.id,organizationId:t});if(!n)throw new Pe("BAD_REQUEST",{message:"Member not found!"});let s=e.context.roles[n.role];if(!s)throw new Pe("BAD_REQUEST",{message:"Role not found!"});let a=r.user.email===e.body.memberIdOrEmail||n.id===e.body.memberIdOrEmail;if(a&&n.role===(e.context.orgOptions?.creatorRole||"owner"))throw new Pe("BAD_REQUEST",{message:"You cannot leave the organization as the owner"});if(!(a||s.authorize({member:["delete"]}).success))throw new Pe("UNAUTHORIZED",{message:"You are not allowed to delete this member"});let u=null;if(e.body.memberIdOrEmail.includes("@")?u=await o.findMemberByEmail({email:e.body.memberIdOrEmail,organizationId:t}):u=await o.findMemberById(e.body.memberIdOrEmail),u?.organizationId!==t)throw new Pe("BAD_REQUEST",{message:"Member not found!"});return await o.deleteMember(u.id),r.user.id===u.userId&&r.session.activeOrganizationId===u.organizationId&&await o.setActiveOrganization(r.session.id,null),e.json({member:u})}),Zt=c("/organization/update-member-role",{method:"POST",body:fe.object({role:fe.enum(["admin","member","owner"]),memberId:fe.string(),organizationId:fe.string().optional()}),use:[L,N]},async e=>{let r=e.context.session,t=e.body.organizationId||r.session.activeOrganizationId;if(!t)return e.json(null,{status:400,body:{message:"No active organization found!"}});let o=S(e.context.adapter,e.context.orgOptions),n=await o.findMemberByOrgId({userId:r.user.id,organizationId:t});if(!n)return e.json(null,{status:400,body:{message:"Member not found!"}});let s=e.context.roles[n.role];if(!s)return e.json(null,{status:400,body:{message:"Role not found!"}});if(s.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 i=await o.updateMember(e.body.memberId,e.body.role);return i?e.json(i):e.json(null,{status:400,body:{message:"Member not found!"}})});import{z as P}from"zod";import{APIError as ge}from"better-call";var Jt=c("/organization/create",{method:"POST",body:P.object({name:P.string(),slug:P.string(),userId:P.string().optional(),logo:P.string().optional(),metadata:P.record(P.string()).optional()}),use:[L,N]},async e=>{let r=e.context.session.user;if(!r)return e.json(null,{status:401});let t=e.context.orgOptions;if(!(typeof t?.allowUserToCreateOrganization=="function"?await t.allowUserToCreateOrganization(r):t?.allowUserToCreateOrganization===void 0?!0:t.allowUserToCreateOrganization))throw new ge("FORBIDDEN",{message:"You are not allowed to create an organization"});let n=S(e.context.adapter,t),s=await n.listOrganizations(r.id);if(typeof t.organizationLimit=="number"?s.length>=t.organizationLimit:typeof t.organizationLimit=="function"?await t.organizationLimit(r):!1)throw new ge("FORBIDDEN",{message:"You have reached the organization limit"});if(await n.findOrganizationBySlug(e.body.slug))throw new ge("BAD_REQUEST",{message:"Organization with this slug already exists"});let d=await n.createOrganization({organization:{id:_(),slug:e.body.slug,name:e.body.name,logo:e.body.logo,createdAt:new Date,metadata:e.body.metadata},user:r});return e.json(d)}),Kt=c("/organization/update",{method:"POST",body:P.object({data:P.object({name:P.string().optional(),slug:P.string().optional()}).partial(),orgId:P.string().optional()}),requireHeaders:!0,use:[L]},async e=>{let r=await e.context.getSession(e);if(!r)throw new ge("UNAUTHORIZED",{message:"User not found"});let t=e.body.orgId||r.session.activeOrganizationId;if(!t)return e.json(null,{status:400,body:{message:"Organization id not found!"}});let o=S(e.context.adapter,e.context.orgOptions),n=await o.findMemberByOrgId({userId:r.user.id,organizationId:t});if(!n)return e.json(null,{status:400,body:{message:"User is not a member of this organization!"}});let s=e.context.roles[n.role];if(!s)return e.json(null,{status:400,body:{message:"Role not found!"}});if(s.authorize({organization:["update"]}).error)return e.json(null,{body:{message:"You are not allowed to update this organization"},status:403});let i=await o.updateOrganization(t,e.body.data);return e.json(i)}),Yt=c("/organization/delete",{method:"POST",body:P.object({orgId:P.string()}),requireHeaders:!0,use:[L]},async e=>{let r=await e.context.getSession(e);if(!r)return e.json(null,{status:401});let t=e.body.orgId;if(!t)return e.json(null,{status:400,body:{message:"Organization id not found!"}});let o=S(e.context.adapter,e.context.orgOptions),n=await o.findMemberByOrgId({userId:r.user.id,organizationId:t});if(!n)return e.json(null,{status:400,body:{message:"User is not a member of this organization!"}});let s=e.context.roles[n.role];if(!s)return e.json(null,{status:400,body:{message:"Role not found!"}});if(s.authorize({organization:["delete"]}).error)throw new ge("FORBIDDEN",{message:"You are not allowed to delete this organization"});return t===r.session.activeOrganizationId&&await o.setActiveOrganization(r.session.id,null),await o.deleteOrganization(t),e.json(t)}),Xt=c("/organization/get-full",{method:"GET",query:P.object({orgId:P.string().optional()}),requireHeaders:!0,use:[L,N]},async e=>{let r=e.context.session,t=e.query.orgId||r.session.activeOrganizationId;if(!t)return e.json(null,{status:400});let n=await S(e.context.adapter,e.context.orgOptions).findFullOrganization(t,e.context.db||void 0);if(!n)throw new ge("BAD_REQUEST",{message:"Organization not found"});return e.json(n)}),er=c("/organization/activate",{method:"POST",body:P.object({orgId:P.string().nullable().optional()}),use:[N,L]},async e=>{let r=S(e.context.adapter,e.context.orgOptions),t=e.context.session,o=e.body.orgId;if(o===null)return t.session.activeOrganizationId&&await r.setActiveOrganization(t.session.id,null),e.json(null);if(!o){let a=t.session.activeOrganizationId;if(!a)return e.json(null);o=a}if(!await r.findMemberByOrgId({userId:t.user.id,organizationId:o}))throw await r.setActiveOrganization(t.session.id,null),new ge("FORBIDDEN",{message:"You are not a member of this organization"});await r.setActiveOrganization(t.session.id,o);let s=await r.findFullOrganization(o,e.context.db||void 0);return e.json(s)}),tr=c("/organization/list",{method:"GET",use:[L,N]},async e=>{let t=await S(e.context.adapter,e.context.orgOptions).listOrganizations(e.context.session.user.id);return e.json(t)});var Tc=e=>{let r={createOrganization:Jt,updateOrganization:Kt,deleteOrganization:Yt,setActiveOrganization:er,getFullOrganization:Xt,listOrganization:tr,createInvitation:$t,cancelInvitation:Ht,acceptInvitation:Vt,getInvitation:Wt,rejectInvitation:Qt,removeMember:Gt,updateMemberRole:Zt},t={...et,...e?.roles};return{id:"organization",endpoints:{...Lt(r,{orgOptions:e||{},roles:t,getSession:async n=>await G(n)}),hasPermission:c("/organization/has-permission",{method:"POST",requireHeaders:!0,body:_e.object({permission:_e.record(_e.string(),_e.array(_e.string()))}),use:[N]},async n=>{if(!n.context.session.session.activeOrganizationId)throw new rr("BAD_REQUEST",{message:"No active organization"});let a=await S(n.context.adapter).findMemberByOrgId({userId:n.context.session.user.id,organizationId:n.context.session.session.activeOrganizationId||""});if(!a)throw new rr("UNAUTHORIZED",{message:"You are not a member of this organization"});let d=t[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 Ze}from"zod";import{z as ze}from"zod";import{APIError as he}from"better-call";var He="two-factor";var We="trust-device";import{z as or}from"zod";var we=z({body:or.object({trustDevice:or.boolean().optional()})},async e=>{let r=e.context.createAuthCookie(He),t=await e.getSignedCookie(r.name,e.context.secret);if(!t)throw new he("UNAUTHORIZED",{message:"invalid two factor cookie"});let[o,n]=t.split("!");if(!o||!n)throw new he("UNAUTHORIZED",{message:"invalid two factor cookie"});let s=await e.context.adapter.findMany({model:"session",where:[{field:"userId",value:o}]});if(!s.length)throw new he("UNAUTHORIZED",{message:"invalid session"});let a=s.filter(i=>i.expiresAt>new Date);if(!a)throw new he("UNAUTHORIZED",{message:"invalid session"});for(let i of a){let d=await J(e.context.secret,i.id),u=await e.context.adapter.findOne({model:"user",where:[{field:"id",value:i.userId}]});if(!u)throw new he("UNAUTHORIZED",{message:"invalid session"});if(d===n)return{valid:async()=>{if(await y(e,i.id,!1),e.body.trustDevice){let l=e.context.createAuthCookie(We,{maxAge:2592e3}),p=await J(e.context.secret,`${u.id}!${i.id}`);await e.setSignedCookie(l.name,`${p}!${i.id}`,e.context.secret,l.options)}return e.json({session:i,user:u})},invalid:async()=>{throw new he("UNAUTHORIZED",{message:"invalid two factor authentication"})},session:{id:i.id,userId:i.userId,expiresAt:i.expiresAt,user:u}}}throw new he("UNAUTHORIZED",{message:"invalid two factor authentication"})});import{APIError as Ce}from"better-call";function Ao(e){return Array.from({length:e?.amount??10}).fill(null).map(()=>$(e?.length??10,V("a-z","0-9"))).map(r=>`${r.slice(0,5)}-${r.slice(5)}`)}async function rt(e,r){let t=e,o=r?.customBackupCodesGenerate?r.customBackupCodesGenerate():Ao(),n=await qe({data:JSON.stringify(o),key:t});return{backupCodes:o,encryptedBackupCodes:n}}async function Ro(e,r){let t=await nr(e.backupCodes,r);return t?t.includes(e.code):!1}async function nr(e,r){let t=Buffer.from(await $e({key:r,data:e})).toString("utf-8"),o=JSON.parse(t),n=ze.array(ze.string()).safeParse(o);return n.success?n.data:null}var sr=(e,r)=>({id:"backup_code",endpoints:{verifyBackupCode:c("/two-factor/verify-backup-code",{method:"POST",body:ze.object({code:ze.string(),disableSession:ze.boolean().optional()}),use:[we]},async t=>{let o=t.context.session.user,n=await t.context.adapter.findOne({model:r,where:[{field:"userId",value:o.id}]});if(!n)throw new Ce("BAD_REQUEST",{message:"Backup codes aren't enabled"});if(!Ro({backupCodes:n.backupCodes,code:t.body.code},t.context.secret))throw new Ce("BAD_REQUEST",{message:"Invalid backup code"});return t.body.disableSession||await y(t,t.context.session.id),t.json({user:o,session:t.context.session})}),generateBackupCodes:c("/two-factor/generate-backup-codes",{method:"POST",use:[b]},async t=>{if(!t.context.session.user.twoFactorEnabled)throw new Ce("BAD_REQUEST",{message:"Two factor isn't enabled"});let n=await rt(t.context.secret,e);return await t.context.adapter.update({model:r,update:{backupCodes:n.encryptedBackupCodes},where:[{field:"userId",value:t.context.session.user.id}]}),t.json({status:!0,backupCodes:n.backupCodes})}),viewBackupCodes:c("/view/backup-codes",{method:"GET",use:[b]},async t=>{let o=t.context.session.user,n=await t.context.adapter.findOne({model:r,where:[{field:"userId",value:o.id}]});if(!n)throw new Ce("BAD_REQUEST",{message:"Backup codes aren't enabled"});let s=nr(n.backupCodes,t.context.secret);if(!s)throw new Ce("BAD_REQUEST",{message:"Backup codes aren't enabled"});return t.json({status:!0,backupCodes:s})})}});import{APIError as Ge}from"better-call";import{TOTPController as Oo}from"oslo/otp";import{z as ir}from"zod";import{TimeSpan as ko}from"oslo";var ar=(e,r)=>{let t={...e,period:new ko(e?.period||3,"m")},o=new Oo({digits:6,period:t.period}),n=c("/two-factor/send-otp",{method:"POST",use:[we]},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 Ge("BAD_REQUEST",{message:"otp isn't configured"});let i=a.context.session.user,d=await a.context.adapter.findOne({model:r,where:[{field:"userId",value:i.id}]});if(!d)throw new Ge("BAD_REQUEST",{message:"totp isn't enabled"});let u=await o.generate(Buffer.from(d.secret));return await e.sendOTP(i,u),a.json({status:!0})}),s=c("/two-factor/verify-otp",{method:"POST",body:ir.object({code:ir.string()}),use:[we]},async a=>{let i=a.context.session.user;if(!i.twoFactorEnabled)throw new Ge("BAD_REQUEST",{message:"two factor isn't enabled"});let d=await a.context.adapter.findOne({model:r,where:[{field:"userId",value:i.id}]});if(!d)throw new Ge("BAD_REQUEST",{message:"totp 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:s}}};import{APIError as Oe}from"better-call";import{TimeSpan as Uo}from"oslo";import{TOTPController as dr,createTOTPKeyURI as Io}from"oslo/otp";import{z as cr}from"zod";var ur=(e,r)=>{let t={...e,digits:6,period:new Uo(e?.period||30,"s")},o=c("/totp/generate",{method:"POST",use:[b]},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 Oe("BAD_REQUEST",{message:"totp isn't configured"});let i=a.context.session.user,d=await a.context.adapter.findOne({model:r,where:[{field:"userId",value:i.id}]});if(!d)throw new Oe("BAD_REQUEST",{message:"totp isn't enabled"});return{code:await new dr(t).generate(Buffer.from(d.secret))}}),n=c("/two-factor/get-totp-uri",{method:"GET",use:[b]},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 Oe("BAD_REQUEST",{message:"totp isn't configured"});let i=a.context.session.user,d=await a.context.adapter.findOne({model:r,where:[{field:"userId",value:i.id}]});if(!d||!i.twoFactorEnabled)throw new Oe("BAD_REQUEST",{message:"totp isn't enabled"});return{totpURI:Io(e?.issuer||"BetterAuth",i.email,Buffer.from(d.secret),t)}}),s=c("/two-factor/verify-totp",{method:"POST",body:cr.object({code:cr.string()}),use:[we]},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 Oe("BAD_REQUEST",{message:"totp isn't configured"});let i=a.context.session.user,d=await a.context.adapter.findOne({model:r,where:[{field:"userId",value:i.id}]});if(!d||!d.enabled)throw new Oe("BAD_REQUEST",{message:"totp isn't enabled"});let u=new dr(t),l=await $e({key:a.context.secret,data:d.secret}),p=Buffer.from(l);return await u.verify(a.body.code,p)?a.context.valid():a.context.invalid()});return{id:"totp",endpoints:{generateTOTP:o,viewTOTPURI:n,verifyTOTP:s}}};async function ot(e,r){let o=(await e.context.internalAdapter.findAccounts(r.userId))?.find(a=>a.providerId==="credential"),n=o?.password;return!o||!n?!1:await e.context.password.verify(n,r.password)}import{APIError as lr}from"better-call";var uu=(e={redirect:!0,twoFactorPage:"/"})=>({id:"two-factor",$InferServerPlugin:{},atomListeners:[{matcher:r=>r==="/two-factor/enable"||r==="/two-factor/send-otp"||r==="/two-factor/disable",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(r){r.data?.twoFactorRedirect&&(e.redirect||e.twoFactorPage)&&typeof window<"u"&&(window.location.href=e.twoFactorPage)}}}]});var ku=e=>{let r={twoFactorTable:e?.twoFactorTable||"twoFactor"},t=ur({issuer:e?.issuer||"better-auth",...e?.totpOptions},r.twoFactorTable),o=sr({...e?.backupCodeOptions},r.twoFactorTable),n=ar({...e?.otpOptions},r.twoFactorTable);return{id:"two-factor",endpoints:{...t.endpoints,...n.endpoints,...o.endpoints,enableTwoFactor:c("/two-factor/enable",{method:"POST",body:Ze.object({password:Ze.string().min(8)}),use:[b]},async s=>{let a=s.context.session.user,{password:i}=s.body;if(!await ot(s,{password:i,userId:a.id}))throw new lr("BAD_REQUEST",{message:"Invalid password"});let u=$(16,V("a-z","0-9","-")),l=await qe({key:s.context.secret,data:u}),p=await rt(s.context.secret,e?.backupCodeOptions);await s.context.internalAdapter.updateUser(a.id,{twoFactorEnabled:!0});let I=await s.context.adapter.create({model:r.twoFactorTable,data:{secret:l,backupCodes:p.encryptedBackupCodes,userId:a.id}});return s.json({status:!0})}),disableTwoFactor:c("/two-factor/disable",{method:"POST",body:Ze.object({password:Ze.string().min(8)}),use:[b]},async s=>{let a=s.context.session.user,{password:i}=s.body;if(!await ot(s,{password:i,userId:a.id}))throw new lr("BAD_REQUEST",{message:"Invalid password"});return await s.context.internalAdapter.updateUser(a.id,{twoFactorEnabled:!1}),await s.context.adapter.delete({model:r.twoFactorTable,where:[{field:"userId",value:a.id}]}),s.json({status:!0})})},options:e,hooks:{after:[{matcher(s){return s.path==="/sign-in/email"||s.path==="/sign-in/username"},handler:z(async s=>{let a=s.context.returned;if(a?.status!==200)return;let i=await a.clone().json();if(!i.user.twoFactorEnabled)return;let d=s.context.createAuthCookie(We,{maxAge:30*24*60*60}),u=await s.getSignedCookie(d.name,s.context.secret);if(u){let[m,f]=u.split("!"),h=await J(s.context.secret,`${i.user.id}!${f}`);if(m===h){let O=await J(s.context.secret,`${i.user.id}!${i.session.id}`);await s.setSignedCookie(d.name,`${O}!${i.session.id}`,s.context.secret,d.options);return}}s.setCookie(s.context.authCookies.sessionToken.name,"",{path:"/",sameSite:"lax",httpOnly:!0,secure:!1,maxAge:0});let l=await J(s.context.secret,i.session.id),p=s.context.createAuthCookie(He,{maxAge:60*60*24});return await s.setSignedCookie(p.name,`${i.session.userId}!${l}`,s.context.secret,p.options),{response:new Response(JSON.stringify({twoFactorRedirect:!0}),{headers:s.responseHeader})}})}]},schema:{user:{fields:{twoFactorEnabled:{type:"boolean",required:!1,defaultValue:!1}}},twoFactor:{tableName:r.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(s){return s.startsWith("/two-factor/")},window:10,max:3}]}};import{generateAuthenticationOptions as zo,generateRegistrationOptions as Bo,verifyAuthenticationResponse as Lo,verifyRegistrationResponse as Do}from"@simplewebauthn/server";import{APIError as X}from"better-call";import{z as oe}from"zod";import{WebAuthnError as Eo,startAuthentication as So,startRegistration as Po}from"@simplewebauthn/browser";import{createFetch as Bu}from"@better-fetch/fetch";import"nanostores";import{betterFetch as vu}from"@better-fetch/fetch";import{atom as Hu}from"nanostores";import"@better-fetch/fetch";import{atom as To,onMount as vo}from"nanostores";var nt=(e,r,t,o)=>{let n=To({data:null,error:null,isPending:!1,isRefetching:!1}),s=()=>{let i=typeof o=="function"?o({data:n.get().data,error:n.get().error,isPending:n.get().isPending}):o;return t(r,{...i,onSuccess:async d=>{n.set({data:d.data,error:null,isPending:!1,isRefetching:!1}),await i?.onSuccess?.(d)},async onError(d){n.set({error:d.error,data:null,isPending:!1,isRefetching:!1}),await i?.onError?.(d)},async onRequest(d){let u=n.get();n.set({isPending:u.data===null,data:u.data,error:null,isRefetching:!0}),await i?.onRequest?.(d)}})};e=Array.isArray(e)?e:[e];let a=!1;for(let i of e)i.subscribe(()=>{a?s():vo(n,()=>(s(),a=!0,()=>{n.off(),i.off()}))});return n};import{atom as _o}from"nanostores";var Co=(e,{_listPasskeys:r})=>({signIn:{passkey:async(n,s)=>{let a=await e("/passkey/generate-authenticate-options",{method:"POST",body:{email:n?.email}});if(!a.data)return a;try{let i=await So(a.data,n?.autoFill||!1),d=await e("/passkey/verify-authentication",{body:{response:i},...n?.fetchOptions,...s,method:"POST"});if(!d.data)return d}catch(i){console.log(i)}}},passkey:{addPasskey:async(n,s)=>{let a=await e("/passkey/generate-register-options",{method:"GET"});if(!a.data)return a;try{let i=await Po(a.data),d=await e("/passkey/verify-registration",{...n?.fetchOptions,...s,body:{response:i,name:n?.name},method:"POST"});if(!d.data)return d;r.set(Math.random())}catch(i){return i instanceof Eo?i.code==="ERROR_AUTHENTICATOR_PREVIOUSLY_REGISTERED"?{data:null,error:{message:"previously registered",status:400,statusText:"BAD_REQUEST"}}:i.code==="ERROR_CEREMONY_ABORTED"?{data:null,error:{message:"registration cancelled",status:400,statusText:"BAD_REQUEST"}}:{data:null,error:{message:i.message,status:400,statusText:"BAD_REQUEST"}}:{data:null,error:{message:i instanceof Error?i.message:"unknown error",status:500,statusText:"INTERNAL_SERVER_ERROR"}}}}},$Infer:{}}),ll=()=>{let e=_o();return{id:"passkey",$InferServerPlugin:{},getActions:r=>Co(r,{_listPasskeys:e}),getAtoms(r){return{listPasskeys:nt(e,"/passkey/list-user-passkeys",r,{method:"GET",credentials:"include"}),_listPasskeys:e}},pathMethods:{"/passkey/register":"POST","/passkey/authenticate":"POST"},atomListeners:[{matcher(r){return r==="/passkey/verify-registration"||r==="/passkey/delete-passkey"},signal:"_listPasskeys"}]}};var kl=e=>{let r=process.env.BETTER_AUTH_URL,t=e?.rpID||r?.replace("http://","").replace("https://","").split(":")[0]||"localhost";if(!t)throw new M("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:t,advanced:{webAuthnChallengeCookie:"better-auth-passkey",...e?.advanced}},n=new Date(Date.now()+1e3*60*5),s=new Date,a=Math.floor((n.getTime()-s.getTime())/1e3);return{id:"passkey",endpoints:{generatePasskeyRegistrationOptions:c("/passkey/generate-register-options",{method:"GET",use:[b],metadata:{client:!1}},async i=>{let d=i.context.session,u=await i.context.adapter.findMany({model:"passkey",where:[{field:"userId",value:d.user.id}]}),l=new Uint8Array(Buffer.from($(32,V("a-z","0-9")))),p;p=await Bo({rpName:o.rpName||i.context.appName,rpID:o.rpID,userID:l,userName:d.user.email||d.user.id,attestationType:"none",excludeCredentials:u.map(m=>({id:m.id,transports:m.transports?.split(",")})),authenticatorSelection:{residentKey:"preferred",userVerification:"preferred",authenticatorAttachment:"platform"}});let I=_();return await i.setSignedCookie(o.advanced.webAuthnChallengeCookie,I,i.context.secret,{secure:!0,httpOnly:!0,sameSite:"lax",maxAge:a}),await i.context.internalAdapter.createVerificationValue({identifier:I,value:JSON.stringify({expectedChallenge:p.challenge,userData:{id:d.user.id}}),expiresAt:n}),i.json(p,{status:200})}),generatePasskeyAuthenticationOptions:c("/passkey/generate-authenticate-options",{method:"POST",body:oe.object({email:oe.string().optional()}).optional()},async i=>{let d=await G(i),u=[];d&&(u=await i.context.adapter.findMany({model:"passkey",where:[{field:"userId",value:d.user.id}]}));let l=await zo({rpID:o.rpID,userVerification:"preferred",...u.length?{allowCredentials:u.map(m=>({id:m.id,transports:m.transports?.split(",")}))}:{}}),p={expectedChallenge:l.challenge,userData:{id:d?.user.id||""}},I=_();return await i.setSignedCookie(o.advanced.webAuthnChallengeCookie,I,i.context.secret,{secure:!0,httpOnly:!0,sameSite:"lax",maxAge:a}),await i.context.internalAdapter.createVerificationValue({identifier:I,value:JSON.stringify(p),expiresAt:n}),i.json(l,{status:200})}),verifyPasskeyRegistration:c("/passkey/verify-registration",{method:"POST",body:oe.object({response:oe.any(),name:oe.string().optional()}),use:[b]},async i=>{let d=e?.origin||i.headers?.get("origin")||"";if(!d)return i.json(null,{status:400});let u=i.body.response,l=await i.getSignedCookie(o.advanced.webAuthnChallengeCookie,i.context.secret);if(!l)throw new X("BAD_REQUEST",{message:"Challenge not found"});let p=await i.context.internalAdapter.findVerificationValue(l);if(!p)return i.json(null,{status:400});let{expectedChallenge:I,userData:m}=JSON.parse(p.value);if(m.id!==i.context.session.user.id)throw new X("UNAUTHORIZED",{message:"You are not authorized to register this passkey"});try{let f=await Do({response:u,expectedChallenge:I,expectedOrigin:d,expectedRPID:e?.rpID}),{verified:h,registrationInfo:O}=f;if(!h||!O)return i.json(null,{status:400});let{credentialID:k,credentialPublicKey:re,counter:ie,credentialDeviceType:R,credentialBackedUp:F}=O,ae=Buffer.from(re).toString("base64"),x=_(),De={name:i.body.name,userId:m.id,webauthnUserID:x,id:k,publicKey:ae,counter:ie,deviceType:R,transports:u.response.transports.join(","),backedUp:F,createdAt:new Date},mr=await i.context.adapter.create({model:"passkey",data:De});return i.json(mr,{status:200})}catch(f){throw console.log(f),new X("INTERNAL_SERVER_ERROR",{message:"Failed to verify registration"})}}),verifyPasskeyAuthentication:c("/passkey/verify-authentication",{method:"POST",body:oe.object({response:oe.any()})},async i=>{let d=e?.origin||i.headers?.get("origin")||"";if(!d)throw new X("BAD_REQUEST",{message:"origin missing"});let u=i.body.response,l=await i.getSignedCookie(o.advanced.webAuthnChallengeCookie,i.context.secret);if(!l)throw new X("BAD_REQUEST",{message:"Challenge not found"});let p=await i.context.internalAdapter.findVerificationValue(l);if(!p)throw new X("BAD_REQUEST",{message:"Challenge not found"});let{expectedChallenge:I}=JSON.parse(p.value),m=await i.context.adapter.findOne({model:"passkey",where:[{field:"id",value:u.id}]});if(!m)throw new X("UNAUTHORIZED",{message:"Passkey not found"});try{let f=await Lo({response:u,expectedChallenge:I,expectedOrigin:d,expectedRPID:o.rpID,authenticator:{credentialID:m.id,credentialPublicKey:new Uint8Array(Buffer.from(m.publicKey,"base64")),counter:m.counter,transports:m.transports?.split(",")}}),{verified:h}=f;if(!h)throw new X("UNAUTHORIZED",{message:"Authentication failed"});await i.context.adapter.update({model:"passkey",where:[{field:"id",value:m.id}],update:{counter:f.authenticationInfo.newCounter}});let O=await i.context.internalAdapter.createSession(m.userId,i.request);if(!O)throw new X("INTERNAL_SERVER_ERROR",{message:"Unable to create session"});return await y(i,O.id),i.json({session:O},{status:200})}catch(f){throw i.context.logger.error(f),new X("BAD_REQUEST",{message:"Failed to verify authentication"})}}),listPasskeys:c("/passkey/list-user-passkeys",{method:"GET",use:[b]},async i=>{let d=await i.context.adapter.findMany({model:"passkey",where:[{field:"userId",value:i.context.session.user.id}]});return i.json(d,{status:200})}),deletePasskey:c("/passkey/delete-passkey",{method:"POST",body:oe.object({id:oe.string()}),use:[b]},async i=>(await i.context.adapter.delete({model:"passkey",where:[{field:"id",value:i.body.id}]}),i.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 ee}from"zod";import{APIError as Je}from"better-call";var pr=()=>({id:"username",endpoints:{signInUsername:c("/sign-in/username",{method:"POST",body:ee.object({username:ee.string(),password:ee.string(),dontRememberMe:ee.boolean().optional()})},async e=>{let r=await e.context.adapter.findOne({model:"user",where:[{field:"username",value:e.body.username}]});if(!r)throw await e.context.password.hash(e.body.password),e.context.logger.error("User not found",{username:pr}),new Je("UNAUTHORIZED",{message:"Invalid username or password"});let t=await e.context.adapter.findOne({model:"account",where:[{field:"userId",value:r.id},{field:"providerId",value:"credential"}]});if(!t)throw new Je("UNAUTHORIZED",{message:"Invalid username or password"});let o=t?.password;if(!o)throw e.context.logger.error("Password not found",{username:pr}),new Je("UNAUTHORIZED",{message:"Unexpected error"});if(!await e.context.password.verify(o,e.body.password))throw e.context.logger.error("Invalid password"),new Je("UNAUTHORIZED",{message:"Invalid username or password"});let s=await e.context.internalAdapter.createSession(r.id,e.request);return s?(await e.setSignedCookie(e.context.authCookies.sessionToken.name,s.id,e.context.secret,e.body.dontRememberMe?{...e.context.authCookies.sessionToken.options,maxAge:void 0}:e.context.authCookies.sessionToken.options),e.json({user:r,session:s})):e.json(null,{status:500,body:{message:"Failed to create session",status:500}})}),signUpUsername:c("/sign-up/username",{method:"POST",body:ee.object({username:ee.string().min(3).max(20),name:ee.string(),email:ee.string().email(),password:ee.string(),image:ee.string().optional()})},async e=>{let r=await Ee()({...e,_flag:"json"});if(r.error)return e.json(null,{status:400,body:{message:r.error,status:400}});let t=await e.context.internalAdapter.updateUserByEmail(r.user?.email,{username:e.body.username});return e.json({user:t,session:r.session})})},schema:{user:{fields:{username:{type:"string",required:!1,unique:!0,returned:!0}}}}});import{serializeSigned as xo}from"better-call";var Cl=()=>({id:"bearer",hooks:{before:[{matcher(e){return!!(e.request?.headers.get("authorization")||e.headers?.get("authorization"))},handler:async e=>{let r=e.request?.headers.get("authorization")?.replace("Bearer ","")||e.headers?.get("authorization")?.replace("Bearer ","");if(!r)return;let t="";return r.includes(".")?t=r:t=await xo("",r,e.context.secret),e.request&&e.request.headers.set("cookie",`${e.context.authCookies.sessionToken.name}=${t.replace("=","")}`),e.headers&&e.headers.set("cookie",`${e.context.authCookies.sessionToken.name}=${t.replace("=","")}`),{context:e}}}]}});import{z as ne}from"zod";import{APIError as Be}from"better-call";import{validateJWT as jo}from"oslo/jwt";var Ml=e=>({id:"magic-link",endpoints:{signInMagicLink:c("/sign-in/magic-link",{method:"POST",requireHeaders:!0,body:ne.object({email:ne.string().email(),callbackURL:ne.string().optional(),currentURL:ne.string().optional()}),use:[j]},async r=>{let{email:t}=r.body;if(!await r.context.internalAdapter.findUserByEmail(t))throw new Be("UNAUTHORIZED",{message:"User not found"});let n=await ve(r.context.secret,t),s=`${r.context.baseURL}/magic-link/verify?token=${n}&callbackURL=${r.body.callbackURL||r.body.currentURL}`;try{await e.sendMagicLink({email:t,url:s,token:n})}catch(a){throw r.context.logger.error("Failed to send magic link",a),new Be("INTERNAL_SERVER_ERROR",{message:"Failed to send magic link"})}return r.json({status:!0})}),magicLinkVerify:c("/magic-link/verify",{method:"GET",query:ne.object({token:ne.string(),callbackURL:ne.string().optional()}),requireHeaders:!0},async r=>{let{token:t,callbackURL:o}=r.query,n;try{n=await jo("HS256",Buffer.from(r.context.secret),t)}catch(u){throw r.context.logger.error("Failed to verify email",u),o?r.redirect(`${o}?error=INVALID_TOKEN`):new Be("BAD_REQUEST",{message:"Invalid token"})}let a=ne.object({email:ne.string().email()}).parse(n.payload),i=await r.context.internalAdapter.findUserByEmail(a.email);if(!i)throw o?r.redirect(`${o}?error=USER_NOT_FOUND`):new Be("BAD_REQUEST",{message:"User not found"});let d=await r.context.internalAdapter.createSession(i.user.id,r.headers);if(!d)throw o?r.redirect(`${o}?error=SESSION_NOT_CREATED`):new Be("INTERNAL_SERVER_ERROR",{message:"Unable to create session"});if(await y(r,d.id),!o)return r.json({status:!0});throw r.redirect(o)})}});import{z as C}from"zod";import{APIError as D}from"better-call";function st(e){return $(e,V("0-9"))}var Yl=e=>{let r={phoneNumber:"phoneNumber",phoneNumberVerified:"phoneNumberVerified",otp:{code:"code",phoneNumber:"phoneNumber",createdAt:"createdAt",expiresIn:e?.otp?.expiresIn||300}};return{id:"phone-number",endpoints:{signInPhoneNumber:c("/sign-in/phone-number",{method:"POST",body:C.object({phoneNumber:C.string(),password:C.string(),dontRememberMe:C.boolean().optional()})},async t=>{let o=await t.context.adapter.findOne({model:"user",where:[{field:r.phoneNumber,value:t.body.phoneNumber}]});if(!o)throw await t.context.password.hash(t.body.password),new D("UNAUTHORIZED",{message:"Invalid email or password"});let n=await t.context.adapter.findOne({model:t.context.tables.account.tableName,where:[{field:"userId",value:o.id},{field:"providerId",value:"credential"}]});if(!n)throw new D("UNAUTHORIZED",{message:"Invalid email or password"});let s=n?.password;if(!s)throw t.context.logger.warn("Unexpectedly password is missing for the user",o),new D("UNAUTHORIZED",{message:"Unexpected error"});if(!await t.context.password.verify(s,t.body.password))throw t.context.logger.error("Invalid password"),new D("UNAUTHORIZED",{message:"Invalid email or password"});let i=await t.context.internalAdapter.createSession(o.id,t.request);return i?(await t.setSignedCookie(t.context.authCookies.sessionToken.name,i.id,t.context.secret,t.body.dontRememberMe?{...t.context.authCookies.sessionToken.options,maxAge:void 0}:t.context.authCookies.sessionToken.options),t.json({user:o,session:i})):t.json(null,{status:500,body:{message:"Failed to create session",status:500}})}),signUpPhoneNumber:c("/sign-up/phone-number",{method:"POST",body:C.object({phoneNumber:C.string().min(3).max(20),name:C.string(),email:C.string().email(),password:C.string(),image:C.string().optional()})},async t=>{if(e?.phoneNumberValidator&&!e.phoneNumberValidator(t.body.phoneNumber))throw new D("BAD_REQUEST",{message:"Invalid phone number"});if(await t.context.adapter.findOne({model:t.context.tables.user.tableName,where:[{field:r.phoneNumber,value:t.body.phoneNumber}]}))throw new D("BAD_REQUEST",{message:"Phone number already exists"});try{let n=await Ee()({...t,options:{...t.context.options},_flag:"json"});if(e?.otp?.sendOTPonSignUp){if(!e.otp.sendOTP)throw A.warn("sendOTP not implemented"),new D("NOT_IMPLEMENTED",{message:"sendOTP not implemented"});let a=st(e?.otp?.otpLength||6);await t.context.internalAdapter.createVerificationValue({value:a,identifier:t.body.phoneNumber,expiresAt:q(r.otp.expiresIn,"sec")}),await e.otp.sendOTP(t.body.phoneNumber,a)}let s=await t.context.internalAdapter.updateUserByEmail(n.user.email,{[r.phoneNumber]:t.body.phoneNumber});return t.json({user:s,session:n.session})}catch(n){throw n instanceof D?n:new D("INTERNAL_SERVER_ERROR",{message:"Failed to create user"})}}),sendVerificationCode:c("/phone-number/send-verification-code",{method:"POST",body:C.object({phoneNumber:C.string()})},async t=>{if(!e?.otp?.sendOTP)throw A.warn("sendOTP not implemented"),new D("NOT_IMPLEMENTED",{message:"sendOTP not implemented"});let o=st(e?.otp?.otpLength||6);return await t.context.internalAdapter.createVerificationValue({value:o,identifier:t.body.phoneNumber,expiresAt:q(r.otp.expiresIn,"sec")}),await e.otp.sendOTP(t.body.phoneNumber,o),t.json({code:o},{body:{message:"Code sent"}})}),verifyPhoneNumber:c("/phone-number/verify",{method:"POST",body:C.object({phoneNumber:C.string(),code:C.string()})},async t=>{let o=await t.context.internalAdapter.findVerificationValue(t.body.phoneNumber);if(!o||o.expiresAt<new Date)throw o&&o.expiresAt<new Date?(await t.context.internalAdapter.deleteVerificationValue(o.id),new D("BAD_REQUEST",{message:"OTP expired"})):new D("BAD_REQUEST",{message:"OTP not found"});if(o.value!==t.body.code)throw new D("BAD_REQUEST",{message:"Invalid OTP"});await t.context.internalAdapter.deleteVerificationValue(o.id);let n=await t.context.adapter.findOne({model:t.context.tables.user.tableName,where:[{value:t.body.phoneNumber,field:r.phoneNumber}]});if(!n)throw new D("NOT_FOUND",{message:"User with phone number not found"});let s=await t.context.internalAdapter.updateUser(n.id,{[r.phoneNumberVerified]:!0});if(e?.enableAutoSignIn&&!await G(t)){let i=await t.context.internalAdapter.createSession(n.id,t.request);if(!i)throw new D("INTERNAL_SERVER_ERROR",{message:"Failed to create session"});return await y(t,i.id),t.json({user:s,session:i})}return t.json({user:s,session:null})}),updatePhoneNumber:c("/phone-number/update",{method:"POST",body:C.object({phoneNumber:C.string()}),use:[b]},async t=>{if(e?.otp?.sendOTPonUpdate){if(!e.otp.sendOTP)throw A.warn("sendOTP not implemented"),new D("NOT_IMPLEMENTED",{message:"sendOTP not implemented"});let n=st(e?.otp?.otpLength||6);await t.context.adapter.create({model:t.context.tables.verification.tableName,data:{code:n,phoneNumber:t.body.phoneNumber,createdAt:q(r.otp.expiresIn,"sec")}}),await e.otp.sendOTP(t.body.phoneNumber,n)}let o=await t.context.internalAdapter.updateUser(t.context.session.user.id,{[r.phoneNumber]:t.body.phoneNumber,[r.phoneNumberVerified]:!1});return t.json({user:o})})},schema:{user:{fields:{phoneNumber:{type:"string",required:!1,unique:!0,returned:!0},phoneNumberVerified:{type:"boolean",required:!1,returned:!0}}}}}};import{z as it}from"zod";var sp=e=>({id:"anonymous",endpoints:{signInAnonymous:c("/sign-in/anonymous",{method:"POST"},async r=>{let{emailDomainName:t=mt(r.context.baseURL)}=e||{},o=_(),n=`temp-${o}@${t}`,s=await r.context.internalAdapter.createUser({id:o,email:n,emailVerified:!1,isAnonymous:!0,name:"Anonymous",createdAt:new Date,updatedAt:new Date});if(!s)return r.json(null,{status:500,body:{message:"Failed to create user",status:500}});let a=await r.context.internalAdapter.createSession(s.id,r.request);return a?(await y(r,a.id),r.json({user:s,session:a})):r.json(null,{status:400,body:{message:"Could not create session"}})}),linkAnonymous:c("/user/link-anonymous",{method:"POST",body:it.object({email:it.string().email().optional(),password:it.string().min(6)}),use:[b]},async r=>{let t=r.context.session.user.id,{email:o,password:n}=r.body,s=null;if(o&&n&&(s=await r.context.internalAdapter.updateUser(t,{email:o})),!s)return r.json(null,{status:500,body:{message:"Failed to update user",status:500}});let a=await r.context.password.hash(n);if(!await r.context.internalAdapter.linkAccount({userId:s.id,providerId:"credential",password:a,accountId:s.id}))return r.json(null,{status:500,body:{message:"Failed to update account",status:500}});let d=await r.context.internalAdapter.createSession(s.id,r.request);return d?(await y(r,d.id),r.json({session:d,user:s})):r.json(null,{status:400,body:{message:"Could not create session"}})})},schema:{user:{fields:{isAnonymous:{type:"boolean",defaultValue:!0,required:!1}}}}});import{z as g}from"zod";var te=z(async e=>{let r=await G(e);if(!r?.session)throw new ue("UNAUTHORIZED");let t=r.user;if(t.role!=="admin")throw new ue("FORBIDDEN",{message:"Only admins can access this endpoint"});return{session:{user:t,session:r.session}}}),lp=e=>({id:"admin",init(r){return{options:{databaseHooks:{user:{create:{async before(t){if(e?.defaultRole!==!1)return{data:{role:e?.defaultRole??"user",...t}}}}},session:{create:{async before(t){let o=await r.internalAdapter.findUserById(t.userId);if(o.banned){if(o.banExpires&&o.banExpires<Date.now()){await r.internalAdapter.updateUser(t.userId,{banned:!1,banReason:null,banExpires:null});return}return!1}}}}}}}},hooks:{after:[{matcher(r){return r.path==="/user/list-sessions"},handler:z(async r=>{let t=r.context.returned;if(t){let n=(await t.json()).filter(a=>!a.impersonatedBy),s=new Response(JSON.stringify(n),{status:200,statusText:"OK",headers:t.headers});return r.json({response:s})}})}]},endpoints:{setRole:c("/admin/set-role",{method:"POST",body:g.object({userId:g.string(),role:g.string()}),use:[te]},async r=>{let t=await r.context.internalAdapter.updateUser(r.body.userId,{role:r.body.role});return r.json({user:t})}),createUser:c("/admin/create-user",{method:"POST",body:g.object({email:g.string(),password:g.string(),name:g.string(),role:g.enum(["user","admin"]),data:g.optional(g.record(g.any()))}),use:[te]},async r=>{if(await r.context.internalAdapter.findUserByEmail(r.body.email))throw new ue("BAD_REQUEST",{message:"User already exists"});let o=await r.context.internalAdapter.createUser({email:r.body.email,name:r.body.name,role:r.body.role,...r.body.data});if(!o)throw new ue("INTERNAL_SERVER_ERROR",{message:"Failed to create user"});let n=await r.context.password.hash(r.body.password);return await r.context.internalAdapter.linkAccount({accountId:o.id,providerId:"credential",password:n,userId:o.id}),r.json({user:o})}),listUsers:c("/admin/list-users",{method:"GET",use:[te],query:g.object({limit:g.string().or(g.number()).optional(),offset:g.string().or(g.number()).optional(),sortBy:g.string().optional(),sortDirection:g.enum(["asc","desc"]).optional()})},async r=>{let t=await r.context.internalAdapter.listUsers(Number(r.query?.limit)||void 0,Number(r.query?.offset)||void 0,r.query?.sortBy?{field:r.query.sortBy,direction:r.query.sortDirection||"asc"}:void 0);return r.json({users:t})}),listUserSessions:c("/admin/list-user-sessions",{method:"POST",use:[te],body:g.object({userId:g.string()})},async r=>({sessions:await r.context.internalAdapter.listSessions(r.body.userId)})),unbanUser:c("/admin/unban-user",{method:"POST",body:g.object({userId:g.string()}),use:[te]},async r=>{let t=await r.context.internalAdapter.updateUser(r.body.userId,{banned:!1});return r.json({user:t})}),banUser:c("/admin/ban-user",{method:"POST",body:g.object({userId:g.string(),banReason:g.string().optional(),banExpiresIn:g.number().optional()}),use:[te]},async r=>{if(r.body.userId===r.context.session.user.id)throw new ue("BAD_REQUEST",{message:"You cannot ban yourself"});let t=await r.context.internalAdapter.updateUser(r.body.userId,{banned:!0,banReason:r.body.banReason||e?.defaultBanReason||"No reason",banExpires:r.body.banExpiresIn?Date.now()+r.body.banExpiresIn*1e3:e?.defaultBanExpiresIn?Date.now()+e.defaultBanExpiresIn*1e3:void 0});return await r.context.internalAdapter.deleteSessions(r.body.userId),r.json({user:t})}),impersonateUser:c("/admin/impersonate-user",{method:"POST",body:g.object({userId:g.string()}),use:[te]},async r=>{let t=await r.context.internalAdapter.findUserById(r.body.userId);if(!t)throw new ue("NOT_FOUND",{message:"User not found"});let o=await r.context.internalAdapter.createSession(t.id,void 0,!0,{impersonatedBy:r.context.session.user.id,expiresAt:e?.impersonationSessionDuration?q(e.impersonationSessionDuration,"sec"):q(60*60,"sec")});if(!o)throw new ue("INTERNAL_SERVER_ERROR",{message:"Failed to create session"});return await y(r,o.id,!0),r.json({session:o,user:t})}),revokeUserSession:c("/admin/revoke-user-session",{method:"POST",body:g.object({sessionId:g.string()}),use:[te]},async r=>(await r.context.internalAdapter.deleteSession(r.body.sessionId),r.json({success:!0}))),revokeUserSessions:c("/admin/revoke-user-sessions",{method:"POST",body:g.object({userId:g.string()}),use:[te]},async r=>(await r.context.internalAdapter.deleteSessions(r.body.userId),r.json({success:!0}))),removeUser:c("/admin/remove-user",{method:"POST",body:g.object({userId:g.string()}),use:[te]},async r=>(await r.context.internalAdapter.deleteUser(r.body.userId),r.json({success:!0})))},schema:{user:{fields:{role:{type:"string",required:!1},banned:{type:"boolean",defaultValue:!1,required:!1},banReason:{type:"string",required:!1},banExpires:{type:"number",required:!1}}},session:{fields:{impersonatedBy:{type:"string",required:!1,references:{model:"user",field:"id"}}}}}});import{z as se}from"zod";import{APIError as Le}from"better-call";import{betterFetch as at}from"@better-fetch/fetch";import{generateCodeVerifier as No}from"oslo/oauth2";import{parseJWT as Fo}from"oslo/jwt";async function Mo(e,r,t){if(r==="oidc"&&e.idToken){let n=Fo(e.idToken);if(n?.payload)return n.payload}return t?(await at(t,{method:"GET",headers:{Authorization:`Bearer ${e.accessToken}`}})).data:null}var Ep=e=>({id:"generic-oauth",endpoints:{signInWithOAuth2:c("/sign-in/oauth2",{method:"POST",query:se.object({currentURL:se.string().optional()}).optional(),body:se.object({providerId:se.string(),callbackURL:se.string().optional()}),use:[j]},async r=>{let{providerId:t}=r.body,o=e.config.find(x=>x.providerId===t);if(!o)throw new Le("BAD_REQUEST",{message:`No config found for provider ${t}`});let{discoveryUrl:n,authorizationUrl:s,tokenUrl:a,clientId:i,clientSecret:d,scopes:u,redirectURI:l,responseType:p,pkce:I,prompt:m,accessType:f}=o,h=s,O=a;if(n){let x=await at(n,{onError(De){A.error(De.error,{discoveryUrl:n})}});x.data&&(h=x.data.authorization_endpoint,O=x.data.token_endpoint)}if(!h||!O)throw new Le("BAD_REQUEST",{message:"Invalid OAuth configuration."});let k=r.query?.currentURL?new URL(r.query?.currentURL):null,re=r.body.callbackURL?.startsWith("http")?r.body.callbackURL:`${k?.origin}${r.body.callbackURL||""}`,ie=await Ne(re||k?.origin||r.context.options.baseURL),R=r.context.authCookies;await r.setSignedCookie(R.state.name,ie.hash,r.context.secret,R.state.options);let F=No();await r.setSignedCookie(R.pkCodeVerifier.name,F,r.context.secret,R.pkCodeVerifier.options);let ae=await B({id:t,options:{clientId:i,clientSecret:d,redirectURI:l||`${r.context.baseURL}/oauth2/callback/${t}`},authorizationEndpoint:h,state:ie.raw,codeVerifier:F,scopes:u||[],disablePkce:!I});return p&&p!=="code"&&ae.searchParams.set("response_type",p),m&&ae.searchParams.set("prompt",m),f&&ae.searchParams.set("access_type",f),{url:ae.toString(),state:ie,codeVerifier:F,redirect:!0}}),oAuth2Callback:c("/oauth2/callback/:providerId",{method:"GET",query:se.object({code:se.string().optional(),error:se.string().optional(),state:se.string()})},async r=>{if(r.query.error||!r.query.code){let F=ye(r.query.state).data?.currentURL||`${r.context.baseURL}/error`;throw r.context.logger.error(r.query.error,r.params.providerId),r.redirect(`${F}?error=${r.query.error||"oAuth_code_missing"}`)}let t=e.config.find(R=>R.providerId===r.params.providerId);if(!t)throw new Le("BAD_REQUEST",{message:`No config found for provider ${r.params.providerId}`});let o=await r.getSignedCookie(r.context.authCookies.pkCodeVerifier.name,r.context.secret),n,s=ye(r.query.state);if(!s.success)throw r.redirect(`${r.context.baseURL}/error?error=invalid_state`);let a=r.query.state,{data:{callbackURL:i,currentURL:d,code:u}}=s,l=s.data?.currentURL||`${r.context.baseURL}/error`,p=await r.getSignedCookie(r.context.authCookies.state.name,r.context.secret);if(!p)throw A.error("No stored state found"),r.redirect(`${l}?error=please_restart_the_process`);if(!await xe(a,p))throw A.error("OAuth code mismatch"),r.redirect(`${l}?error=please_restart_the_process`);let m=t.tokenUrl,f=t.userInfoUrl;if(t.discoveryUrl){let R=await at(t.discoveryUrl,{method:"GET"});R.data&&(m=R.data.token_endpoint,f=R.data.userinfo_endpoint)}try{if(!m)throw new Le("BAD_REQUEST",{message:"Invalid OAuth configuration."});n=await v({code:u,codeVerifier:o,redirectURI:`${r.context.baseURL}/oauth2/callback/${t.providerId}`,options:{clientId:t.clientId,clientSecret:t.clientSecret},tokenEndpoint:m})}catch(R){throw r.context.logger.error(R),r.redirect(`${l}?error=oauth_code_verification_failed`)}if(!n)throw new Le("BAD_REQUEST",{message:"Invalid OAuth configuration."});let h=t.getUserInfo?await t.getUserInfo(n):await Mo(n,t.type||"oauth2",f),O=_(),k=h?Fe.safeParse({...h,id:O}):null;if(!k?.success)throw r.redirect(`${l}?error=oauth_user_info_invalid`);let re=await r.context.internalAdapter.findUserByEmail(k.data.email).catch(R=>{throw A.error(`Better auth was unable to query your database.
84
- Error: `,R),r.redirect(`${l}?error=internal_server_error`)}),ie=re?.user.id||O;if(re){let R=re.accounts.find(x=>x.providerId===t.providerId),F=r.context.options.account?.accountLinking?.trustedProviders,ae=F?F.includes(t.providerId):!0;if(!R&&(!k?.data.emailVerified||!ae)){let x;try{x=new URL(l),x.searchParams.set("error","account_not_linked")}catch{throw r.redirect(`${l}?error=account_not_linked`)}throw r.redirect(x.toString())}if(!R)try{await r.context.internalAdapter.linkAccount({providerId:t.providerId,accountId:k.data.id,id:`${t.providerId}:${k.data.id}`,userId:re.user.id,...be(n)})}catch(x){throw console.log(x),r.redirect(`${l}?error=failed_linking_account`)}}else try{await r.context.internalAdapter.createOAuthUser(k.data,{...be(n),id:`${t.providerId}:${k.data.id}`,providerId:t.providerId,accountId:k.data.id,userId:ie})}catch{let F=new URL(l);throw F.searchParams.set("error","unable_to_create_user"),r.setHeader("Location",F.toString()),r.redirect(F.toString())}try{let R=await r.context.internalAdapter.createSession(ie||O,r.request);if(!R)throw r.redirect(`${l}?error=unable_to_create_session`);await y(r,R.id)}catch{throw r.redirect(`${l}?error=unable_to_create_session`)}throw r.redirect(i||d||"")})}});export{ce as HIDE_METADATA,Mt as ac,lp as admin,te as adminMiddleware,sp as anonymous,Cl as bearer,c as createAuthEndpoint,z as createAuthMiddleware,Ep as genericOAuth,Co as getPasskeyActions,Ml as magicLink,ct as optionsMiddleware,Tc as organization,kl as passkey,ll as passkeyClient,Yl as phoneNumber,ku as twoFactor,uu as twoFactorClient,pr as username};
83
+ </html>`,fo=c("/error",{method:"GET",metadata:de},async e=>{let t=new URL(e.request?.url||"").searchParams.get("error")||"Unknown";return new Response(mo(t),{headers:{"Content-Type":"text/html"}})});var go=c("/ok",{method:"GET",metadata:de},async e=>e.json({ok:!0}));import{z as be}from"zod";import{APIError as le}from"better-call";var ve=()=>c("/sign-up/email",{method:"POST",query:be.object({currentURL:be.string().optional()}).optional(),body:be.record(be.string(),be.any()),use:[j]},async e=>{if(!e.context.options.emailAndPassword?.enabled)throw new le("BAD_REQUEST",{message:"Email and password sign up is not enabled"});let t=e.body,{name:r,email:o,password:n,image:s,callbackURL:a,...i}=t;if(!be.string().email().safeParse(o).success)throw new le("BAD_REQUEST",{message:"Invalid email"});let u=e.context.password.config.minPasswordLength;if(n.length<u)throw e.context.logger.error("Password is too short"),new le("BAD_REQUEST",{message:"Password is too short"});let l=e.context.password.config.maxPasswordLength;if(n.length>l)throw e.context.logger.error("Password is too long"),new le("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 le("UNPROCESSABLE_ENTITY",{message:"The email has already been taken"});let U=Tt(e.context.options,i),m=await e.context.internalAdapter.createUser({email:o.toLowerCase(),name:r,image:s,...U,emailVerified:!1});if(!m)throw new le("BAD_REQUEST",{message:"Failed to create user"});let f=await e.context.password.hash(n);await e.context.internalAdapter.linkAccount({userId:m.id,providerId:"credential",accountId:m.id,password:f,expiresAt:V(60*60*24*30,"sec")});let h=await e.context.internalAdapter.createSession(m.id,e.request);if(!h)throw new le("BAD_REQUEST",{message:"Failed to create session"});if(await y(e,h.id),e.context.options.emailAndPassword.sendEmailVerificationOnSignUp){let O=await Ye(e.context.secret,m.email),k=`${e.context.baseURL}/verify-email?token=${O}&callbackURL=${t.callbackURL||e.query?.currentURL||"/"}`;await e.context.options.emailAndPassword.sendVerificationEmail?.(k,m,O)}return e.json({user:m,session:h,error:null},{body:t.callbackURL?{url:t.callbackURL,redirect:!0}:{user:m,session:h}})});var Bt=(e,t)=>{let r={};for(let[o,n]of Object.entries(e))r[o]=s=>n({...s,context:{...t,...s.context}}),r[o].path=n.path,r[o].method=n.method,r[o].options=n.options,r[o].headers=n.headers;return r};var Ft={};fr(Ft,{AccessControl:()=>Ee,ParsingError:()=>pe,Role:()=>Ae,adminAc:()=>xt,createAccessControl:()=>Lt,defaultAc:()=>qe,defaultRoles:()=>Xe,defaultStatements:()=>Dt,memberAc:()=>Nt,ownerAc:()=>jt,permissionFromString:()=>ho});var pe=class extends Error{path;constructor(t,r){super(t),this.path=r}},Ee=class{constructor(t){this.s=t;this.statements=t}statements;newRole(t){return new Ae(t)}},Ae=class e{statements;constructor(t){this.statements=t}authorize(t,r){for(let[o,n]of Object.entries(t)){let s=this.statements[o];if(!s)return{success:!1,error:`You are not allowed to access resource: ${o}`};let a=r==="OR"?n.some(i=>s.includes(i)):n.every(i=>s.includes(i));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 pe("statements is not an object",".");for(let[o,n]of Object.entries(r)){if(typeof o!="string")throw new pe("invalid resource identifier",o);if(!Array.isArray(n))throw new pe("actions is not an array",o);for(let s=0;s<n.length;s++)if(typeof n[s]!="string")throw new pe("action is not a string",`${o}[${s}]`)}return new e(r)}toString(){return JSON.stringify(this.statements)}};var Lt=e=>new Ee(e),Dt={organization:["update","delete"],member:["create","update","delete"],invitation:["create","cancel"]},qe=Lt(Dt),xt=qe.newRole({organization:["update"],invitation:["create","cancel"],member:["create","update","delete"]}),jt=qe.newRole({organization:["update","delete"],member:["create","update","delete"],invitation:["create","cancel"]}),Nt=qe.newRole({organization:[],member:[],invitation:[]}),Xe={admin:xt,owner:jt,member:Nt};var ho=e=>Ae.fromString(e??"");var S=(e,t)=>({findOrganizationBySlug:async r=>await e.findOne({model:"organization",where:[{field:"slug",value:r}]}),createOrganization:async r=>{let o=await e.create({model:"organization",data:{...r.organization,metadata:r.organization.metadata?JSON.stringify(r.organization.metadata):void 0}}),n=await e.create({model:"member",data:{id:_(),organizationId:o.id,userId:r.user.id,createdAt:new Date,email:r.user.email,role:t?.creatorRole||"owner"}});return{...o,metadata:o.metadata?JSON.parse(o.metadata):void 0,members:[{...n,user:{id:r.user.id,name:r.user.name,email:r.user.email,image:r.user.image}}]}},findMemberByEmail:async r=>{let o=await e.findOne({model:"member",where:[{field:"email",value:r.email},{field:"organizationId",value:r.organizationId}]});if(!o)return null;let n=await e.findOne({model:"user",where:[{field:"id",value:o.userId}]});return n?{...o,user:{id:n.id,name:n.name,email:n.email,image:n.image}}:null},findMemberByOrgId:async r=>{let o=await e.findOne({model:"member",where:[{field:"userId",value:r.userId},{field:"organizationId",value:r.organizationId}]});if(!o)return null;let n=await e.findOne({model:"user",where:[{field:"id",value:o.userId}]});return n?{...o,user:{id:n.id,name:n.name,email:n.email,image:n.image}}:null},findMemberById:async r=>{let o=await e.findOne({model:"member",where:[{field:"id",value:r}]});if(!o)return null;let n=await e.findOne({model:"user",where:[{field:"id",value:o.userId}]});return n?{...o,user:{id:n.id,name:n.name,email:n.email,image:n.image}}:null},createMember:async r=>await e.create({model:"member",data:r}),updateMember:async(r,o)=>await e.update({model:"member",where:[{field:"id",value:r}],update:{role:o}}),deleteMember:async r=>await e.delete({model:"member",where:[{field:"id",value:r}]}),updateOrganization:async(r,o)=>await e.update({model:"organization",where:[{field:"id",value:r}],update:o}),deleteOrganization:async r=>(await e.delete({model:"member",where:[{field:"organizationId",value:r}]}),await e.delete({model:"invitation",where:[{field:"organizationId",value:r}]}),await e.delete({model:"organization",where:[{field:"id",value:r}]}),r),setActiveOrganization:async(r,o)=>await e.update({model:"session",where:[{field:"id",value:r}],update:{activeOrganizationId:o}}),findOrganizationById:async r=>await e.findOne({model:"organization",where:[{field:"id",value:r}]}),findFullOrganization:async(r,o)=>{let n=await e.findOne({model:"organization",where:[{field:"id",value:r}]});if(!n)return null;let s=await e.findMany({model:"invitation",where:[{field:"organizationId",value:r}]}),a=await e.findMany({model:"member",where:[{field:"organizationId",value:r}]}),i=await Promise.all(a.map(async u=>{let l=await e.findOne({model:"user",where:[{field:"id",value:u.userId}]});if(!l)throw new $("Unexpected error: User not found for member");return{...u,user:{id:l.id,name:l.name,email:l.email,image:l.image}}}));return{...n,invitations:s,members:i}},listOrganizations:async r=>{let n=(await e.findMany({model:"member",where:[{field:"userId",value:r}]}))?.map(a=>a.organizationId);if(!n)return[];let s=[];for(let a of n){let i=await e.findOne({model:"organization",where:[{field:"id",value:a}]});i&&s.push(i)}return s},createInvitation:async({invitation:r,user:o})=>{let s=V(t?.invitationExpiresIn||1728e5);return await e.create({model:"invitation",data:{id:_(),email:r.email,role:r.role,organizationId:r.organizationId,status:"pending",expiresAt:s,inviterId:o.id}})},findInvitationById:async r=>await e.findOne({model:"invitation",where:[{field:"id",value:r}]}),findPendingInvitation:async r=>(await e.findMany({model:"invitation",where:[{field:"email",value:r.email},{field:"organizationId",value:r.organizationId},{field:"status",value:"pending"}]})).filter(n=>new Date(n.expiresAt)>new Date),updateInvitation:async r=>await e.update({model:"invitation",where:[{field:"id",value:r.invitationId}],update:{status:r.status}})});import"better-call";import{APIError as wd,createRouter as yd}from"better-call";import{APIError as et}from"better-call";import{z as Mt}from"zod";var wo=z({body:Mt.object({csrfToken:Mt.string().optional()}).optional()},async e=>{if(e.request?.method!=="POST"||e.context.options.advanced?.disableCSRFCheck)return;let t=new URL(e.request.url);if(e.context.trustedOrigins.includes(t.origin))return;let r=e.body?.csrfToken;if(!r)throw new et("UNAUTHORIZED",{message:"CSRF Token is required"});let o=await e.getSignedCookie(e.context.authCookies.csrfToken.name,e.context.secret),[n,s]=o?.split("!")||[null,null];if(!r||!o||!n||!s||o!==r)throw e.setCookie(e.context.authCookies.csrfToken.name,"",{maxAge:0}),new et("UNAUTHORIZED",{message:"Invalid CSRF Token"});let a=await J(e.context.secret,n);if(s!==a)throw e.setCookie(e.context.authCookies.csrfToken.name,"",{maxAge:0}),new et("UNAUTHORIZED",{message:"Invalid CSRF Token"})});import{APIError as ce}from"better-call";var L=z(async e=>({})),N=z({use:[b]},async e=>({session:e.context.session}));import{z as H}from"zod";import{z as I}from"zod";var $e=I.enum(["admin","member","owner"]),yo=I.enum(["pending","accepted","rejected","canceled"]).default("pending"),Md=I.object({id:I.string(),name:I.string(),slug:I.string(),logo:I.string().optional(),metadata:I.record(I.string()).or(I.string().transform(e=>JSON.parse(e))).optional(),createdAt:I.date()}),qd=I.object({id:I.string(),email:I.string(),organizationId:I.string(),userId:I.string(),role:$e,createdAt:I.date()}),$d=I.object({id:I.string(),organizationId:I.string(),email:I.string(),role:$e,status:yo,inviterId:I.string(),expiresAt:I.date()});import{APIError as E}from"better-call";var qt=c("/organization/invite-member",{method:"POST",use:[L,N],body:H.object({email:H.string(),role:$e,organizationId:H.string().optional(),resend:H.boolean().optional()})},async e=>{if(!e.context.orgOptions.sendInvitationEmail)throw A.warn("Invitation email is not enabled. Pass `sendInvitationEmail` to the plugin options to enable it."),new E("BAD_REQUEST",{message:"Invitation email is not enabled"});let t=e.context.session,r=e.body.organizationId||t.session.activeOrganizationId;if(!r)throw new E("BAD_REQUEST",{message:"Organization not found"});let o=S(e.context.adapter,e.context.orgOptions),n=await o.findMemberByOrgId({userId:t.user.id,organizationId:r});if(!n)throw new E("BAD_REQUEST",{message:"Member not found!"});let s=e.context.roles[n.role];if(!s)throw new E("BAD_REQUEST",{message:"Role not found!"});if(s.authorize({invitation:["create"]}).error)throw new E("FORBIDDEN",{message:"You are not allowed to invite members"});if(await o.findMemberByEmail({email:e.body.email,organizationId:r}))throw new E("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 E("BAD_REQUEST",{message:"User is already invited to this organization"});let u=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 E("BAD_REQUEST",{message:"Organization not found"});return await e.context.orgOptions.sendInvitationEmail?.({id:u.id,role:u.role,email:u.email,organization:l,inviter:{...n,user:t.user}},e.request),e.json(u)}),$t=c("/organization/accept-invitation",{method:"POST",body:H.object({invitationId:H.string()}),use:[L,N]},async e=>{let t=e.context.session,r=S(e.context.adapter,e.context.orgOptions),o=await r.findInvitationById(e.body.invitationId);if(!o||o.expiresAt<new Date||o.status!=="pending")throw new E("BAD_REQUEST",{message:"Invitation not found!"});if(o.email!==t.user.email)throw new E("FORBIDDEN",{message:"You are not the recipient of the invitation"});let n=await r.updateInvitation({invitationId:e.body.invitationId,status:"accepted"}),s=await r.createMember({id:_(),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:s}):e.json(null,{status:400,body:{message:"Invitation not found!"}})}),Vt=c("/organization/reject-invitation",{method:"POST",body:H.object({invitationId:H.string()}),use:[L,N]},async e=>{let t=e.context.session,r=S(e.context.adapter,e.context.orgOptions),o=await r.findInvitationById(e.body.invitationId);if(!o||o.expiresAt<new Date||o.status!=="pending")throw new E("BAD_REQUEST",{message:"Invitation not found!"});if(o.email!==t.user.email)throw new E("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})}),Qt=c("/organization/cancel-invitation",{method:"POST",body:H.object({invitationId:H.string()}),use:[L,N]},async e=>{let t=e.context.session,r=S(e.context.adapter,e.context.orgOptions),o=await r.findInvitationById(e.body.invitationId);if(!o)throw new E("BAD_REQUEST",{message:"Invitation not found!"});let n=await r.findMemberByOrgId({userId:t.user.id,organizationId:o.organizationId});if(!n)throw new E("BAD_REQUEST",{message:"Member not found!"});if(e.context.roles[n.role].authorize({invitation:["cancel"]}).error)throw new E("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)}),Ht=c("/organization/get-invitation",{method:"GET",use:[L],requireHeaders:!0,query:H.object({id:H.string()})},async e=>{let t=await G(e);if(!t)throw new E("UNAUTHORIZED",{message:"Not authenticated"});let r=S(e.context.adapter,e.context.orgOptions),o=await r.findInvitationById(e.query.id);if(!o||o.status!=="pending"||o.expiresAt<new Date)throw new E("BAD_REQUEST",{message:"Invitation not found!"});if(o.email!==t.user.email)throw new E("FORBIDDEN",{message:"You are not the recipient of the invitation"});let n=await r.findOrganizationById(o.organizationId);if(!n)throw new E("BAD_REQUEST",{message:"Organization not found"});let s=await r.findMemberByOrgId({userId:o.inviterId,organizationId:o.organizationId});if(!s)throw new E("BAD_REQUEST",{message:"Inviter is no longer a member of the organization"});return e.json({...o,organizationName:n.name,organizationSlug:n.slug,inviterEmail:s.email})});import{z as me}from"zod";import{APIError as Se}from"better-call";var Wt=c("/organization/remove-member",{method:"POST",body:me.object({memberIdOrEmail:me.string(),organizationId:me.string().optional()}),use:[L,N]},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=S(e.context.adapter,e.context.orgOptions),n=await o.findMemberByOrgId({userId:t.user.id,organizationId:r});if(!n)throw new Se("BAD_REQUEST",{message:"Member not found!"});let s=e.context.roles[n.role];if(!s)throw new Se("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 Se("BAD_REQUEST",{message:"You cannot leave the organization as the owner"});if(!(a||s.authorize({member:["delete"]}).success))throw new Se("UNAUTHORIZED",{message:"You are not allowed to delete this member"});let u=null;if(e.body.memberIdOrEmail.includes("@")?u=await o.findMemberByEmail({email:e.body.memberIdOrEmail,organizationId:r}):u=await o.findMemberById(e.body.memberIdOrEmail),u?.organizationId!==r)throw new Se("BAD_REQUEST",{message:"Member not found!"});return await o.deleteMember(u.id),t.user.id===u.userId&&t.session.activeOrganizationId===u.organizationId&&await o.setActiveOrganization(t.session.id,null),e.json({member:u})}),Gt=c("/organization/update-member-role",{method:"POST",body:me.object({role:me.enum(["admin","member","owner"]),memberId:me.string(),organizationId:me.string().optional()}),use:[L,N]},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=S(e.context.adapter,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 s=e.context.roles[n.role];if(!s)return e.json(null,{status:400,body:{message:"Role not found!"}});if(s.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 i=await o.updateMember(e.body.memberId,e.body.role);return i?e.json(i):e.json(null,{status:400,body:{message:"Member not found!"}})});import{z as P}from"zod";import{APIError as fe}from"better-call";var Zt=c("/organization/create",{method:"POST",body:P.object({name:P.string(),slug:P.string(),userId:P.string().optional(),logo:P.string().optional(),metadata:P.record(P.string()).optional()}),use:[L,N]},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 fe("FORBIDDEN",{message:"You are not allowed to create an organization"});let n=S(e.context.adapter,r),s=await n.listOrganizations(t.id);if(typeof r.organizationLimit=="number"?s.length>=r.organizationLimit:typeof r.organizationLimit=="function"?await r.organizationLimit(t):!1)throw new fe("FORBIDDEN",{message:"You have reached the organization limit"});if(await n.findOrganizationBySlug(e.body.slug))throw new fe("BAD_REQUEST",{message:"Organization with this slug already exists"});let d=await n.createOrganization({organization:{id:_(),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)}),Jt=c("/organization/update",{method:"POST",body:P.object({data:P.object({name:P.string().optional(),slug:P.string().optional()}).partial(),orgId:P.string().optional()}),requireHeaders:!0,use:[L]},async e=>{let t=await e.context.getSession(e);if(!t)throw new fe("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=S(e.context.adapter,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 s=e.context.roles[n.role];if(!s)return e.json(null,{status:400,body:{message:"Role not found!"}});if(s.authorize({organization:["update"]}).error)return e.json(null,{body:{message:"You are not allowed to update this organization"},status:403});let i=await o.updateOrganization(r,e.body.data);return e.json(i)}),Kt=c("/organization/delete",{method:"POST",body:P.object({orgId:P.string()}),requireHeaders:!0,use:[L]},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=S(e.context.adapter,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 s=e.context.roles[n.role];if(!s)return e.json(null,{status:400,body:{message:"Role not found!"}});if(s.authorize({organization:["delete"]}).error)throw new fe("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)}),Yt=c("/organization/get-full",{method:"GET",query:P.object({orgId:P.string().optional()}),requireHeaders:!0,use:[L,N]},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 S(e.context.adapter,e.context.orgOptions).findFullOrganization(r,e.context.db||void 0);if(!n)throw new fe("BAD_REQUEST",{message:"Organization not found"});return e.json(n)}),Xt=c("/organization/activate",{method:"POST",body:P.object({orgId:P.string().nullable().optional()}),use:[N,L]},async e=>{let t=S(e.context.adapter,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 fe("FORBIDDEN",{message:"You are not a member of this organization"});await t.setActiveOrganization(r.session.id,o);let s=await t.findFullOrganization(o,e.context.db||void 0);return e.json(s)}),er=c("/organization/list",{method:"GET",use:[L,N]},async e=>{let r=await S(e.context.adapter,e.context.orgOptions).listOrganizations(e.context.session.user.id);return e.json(r)});var Uc=e=>{let t={createOrganization:Zt,updateOrganization:Jt,deleteOrganization:Kt,setActiveOrganization:Xt,getFullOrganization:Yt,listOrganization:er,createInvitation:qt,cancelInvitation:Qt,acceptInvitation:$t,getInvitation:Ht,rejectInvitation:Vt,removeMember:Wt,updateMemberRole:Gt},r={...Xe,...e?.roles};return{id:"organization",endpoints:{...Bt(t,{orgOptions:e||{},roles:r,getSession:async n=>await G(n)}),hasPermission:c("/organization/has-permission",{method:"POST",requireHeaders:!0,body:Pe.object({permission:Pe.record(Pe.string(),Pe.array(Pe.string()))}),use:[N]},async n=>{if(!n.context.session.session.activeOrganizationId)throw new tr("BAD_REQUEST",{message:"No active organization"});let a=await S(n.context.adapter).findMemberByOrgId({userId:n.context.session.user.id,organizationId:n.context.session.session.activeOrganizationId||""});if(!a)throw new tr("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 We}from"zod";import{z as Ce}from"zod";import{APIError as ge}from"better-call";var Ve="two-factor";var Qe="trust-device";import{z as rr}from"zod";var he=z({body:rr.object({trustDevice:rr.boolean().optional()})},async e=>{let t=e.context.createAuthCookie(Ve),r=await e.getSignedCookie(t.name,e.context.secret);if(!r)throw new ge("UNAUTHORIZED",{message:"invalid two factor cookie"});let[o,n]=r.split("!");if(!o||!n)throw new ge("UNAUTHORIZED",{message:"invalid two factor cookie"});let s=await e.context.adapter.findMany({model:"session",where:[{field:"userId",value:o}]});if(!s.length)throw new ge("UNAUTHORIZED",{message:"invalid session"});let a=s.filter(i=>i.expiresAt>new Date);if(!a)throw new ge("UNAUTHORIZED",{message:"invalid session"});for(let i of a){let d=await J(e.context.secret,i.id),u=await e.context.adapter.findOne({model:"user",where:[{field:"id",value:i.userId}]});if(!u)throw new ge("UNAUTHORIZED",{message:"invalid session"});if(d===n)return{valid:async()=>{if(await y(e,i.id,!1),e.body.trustDevice){let l=e.context.createAuthCookie(Qe,{maxAge:2592e3}),p=await J(e.context.secret,`${u.id}!${i.id}`);await e.setSignedCookie(l.name,`${p}!${i.id}`,e.context.secret,l.options)}return e.json({session:i,user:u})},invalid:async()=>{throw new ge("UNAUTHORIZED",{message:"invalid two factor authentication"})},session:{id:i.id,userId:i.userId,expiresAt:i.expiresAt,user:u}}}throw new ge("UNAUTHORIZED",{message:"invalid two factor authentication"})});import{APIError as _e}from"better-call";function bo(e){return Array.from({length:e?.amount??10}).fill(null).map(()=>M(e?.length??10,q("a-z","0-9"))).map(t=>`${t.slice(0,5)}-${t.slice(5)}`)}async function tt(e,t){let r=e,o=t?.customBackupCodesGenerate?t.customBackupCodesGenerate():bo(),n=await Fe({data:JSON.stringify(o),key:r});return{backupCodes:o,encryptedBackupCodes:n}}async function Ao(e,t){let r=await or(e.backupCodes,t);return r?r.includes(e.code):!1}async function or(e,t){let r=Buffer.from(await Me({key:t,data:e})).toString("utf-8"),o=JSON.parse(r),n=Ce.array(Ce.string()).safeParse(o);return n.success?n.data:null}var nr=(e,t)=>({id:"backup_code",endpoints:{verifyBackupCode:c("/two-factor/verify-backup-code",{method:"POST",body:Ce.object({code:Ce.string(),disableSession:Ce.boolean().optional()}),use:[he]},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 _e("BAD_REQUEST",{message:"Backup codes aren't enabled"});if(!Ao({backupCodes:n.backupCodes,code:r.body.code},r.context.secret))throw new _e("BAD_REQUEST",{message:"Invalid backup code"});return r.body.disableSession||await y(r,r.context.session.id),r.json({user:o,session:r.context.session})}),generateBackupCodes:c("/two-factor/generate-backup-codes",{method:"POST",use:[b]},async r=>{if(!r.context.session.user.twoFactorEnabled)throw new _e("BAD_REQUEST",{message:"Two factor isn't enabled"});let n=await tt(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:c("/view/backup-codes",{method:"GET",use:[b]},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 _e("BAD_REQUEST",{message:"Backup codes aren't enabled"});let s=or(n.backupCodes,r.context.secret);if(!s)throw new _e("BAD_REQUEST",{message:"Backup codes aren't enabled"});return r.json({status:!0,backupCodes:s})})}});import{APIError as He}from"better-call";import{TOTPController as Ro}from"oslo/otp";import{z as sr}from"zod";import{TimeSpan as Oo}from"oslo";var ir=(e,t)=>{let r={...e,period:new Oo(e?.period||3,"m")},o=new Ro({digits:6,period:r.period}),n=c("/two-factor/send-otp",{method:"POST",use:[he]},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 He("BAD_REQUEST",{message:"otp isn't configured"});let i=a.context.session.user,d=await a.context.adapter.findOne({model:t,where:[{field:"userId",value:i.id}]});if(!d)throw new He("BAD_REQUEST",{message:"totp isn't enabled"});let u=await o.generate(Buffer.from(d.secret));return await e.sendOTP(i,u),a.json({status:!0})}),s=c("/two-factor/verify-otp",{method:"POST",body:sr.object({code:sr.string()}),use:[he]},async a=>{let i=a.context.session.user;if(!i.twoFactorEnabled)throw new He("BAD_REQUEST",{message:"two factor isn't enabled"});let d=await a.context.adapter.findOne({model:t,where:[{field:"userId",value:i.id}]});if(!d)throw new He("BAD_REQUEST",{message:"totp 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:s}}};import{APIError as Re}from"better-call";import{TimeSpan as ko}from"oslo";import{TOTPController as ar,createTOTPKeyURI as Io}from"oslo/otp";import{z as dr}from"zod";var cr=(e,t)=>{let r={...e,digits:6,period:new ko(e?.period||30,"s")},o=c("/totp/generate",{method:"POST",use:[b]},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 Re("BAD_REQUEST",{message:"totp isn't configured"});let i=a.context.session.user,d=await a.context.adapter.findOne({model:t,where:[{field:"userId",value:i.id}]});if(!d)throw new Re("BAD_REQUEST",{message:"totp isn't enabled"});return{code:await new ar(r).generate(Buffer.from(d.secret))}}),n=c("/two-factor/get-totp-uri",{method:"GET",use:[b]},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 Re("BAD_REQUEST",{message:"totp isn't configured"});let i=a.context.session.user,d=await a.context.adapter.findOne({model:t,where:[{field:"userId",value:i.id}]});if(!d||!i.twoFactorEnabled)throw new Re("BAD_REQUEST",{message:"totp isn't enabled"});return{totpURI:Io(e?.issuer||"BetterAuth",i.email,Buffer.from(d.secret),r)}}),s=c("/two-factor/verify-totp",{method:"POST",body:dr.object({code:dr.string()}),use:[he]},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 Re("BAD_REQUEST",{message:"totp isn't configured"});let i=a.context.session.user,d=await a.context.adapter.findOne({model:t,where:[{field:"userId",value:i.id}]});if(!d||!d.enabled)throw new Re("BAD_REQUEST",{message:"totp isn't enabled"});let u=new ar(r),l=await Me({key:a.context.secret,data:d.secret}),p=Buffer.from(l);return await u.verify(a.body.code,p)?a.context.valid():a.context.invalid()});return{id:"totp",endpoints:{generateTOTP:o,viewTOTPURI:n,verifyTOTP:s}}};async function rt(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 ur}from"better-call";var cu=(e={redirect:!0,twoFactorPage:"/"})=>({id:"two-factor",$InferServerPlugin:{},atomListeners:[{matcher:t=>t==="/two-factor/enable"||t==="/two-factor/send-otp"||t==="/two-factor/disable",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 Ou=e=>{let t={twoFactorTable:e?.twoFactorTable||"twoFactor"},r=cr({issuer:e?.issuer||"better-auth",...e?.totpOptions},t.twoFactorTable),o=nr({...e?.backupCodeOptions},t.twoFactorTable),n=ir({...e?.otpOptions},t.twoFactorTable);return{id:"two-factor",endpoints:{...r.endpoints,...n.endpoints,...o.endpoints,enableTwoFactor:c("/two-factor/enable",{method:"POST",body:We.object({password:We.string().min(8)}),use:[b]},async s=>{let a=s.context.session.user,{password:i}=s.body;if(!await rt(s,{password:i,userId:a.id}))throw new ur("BAD_REQUEST",{message:"Invalid password"});let u=M(16,q("a-z","0-9","-")),l=await Fe({key:s.context.secret,data:u}),p=await tt(s.context.secret,e?.backupCodeOptions);await s.context.internalAdapter.updateUser(a.id,{twoFactorEnabled:!0});let U=await s.context.adapter.create({model:t.twoFactorTable,data:{secret:l,backupCodes:p.encryptedBackupCodes,userId:a.id}});return s.json({status:!0})}),disableTwoFactor:c("/two-factor/disable",{method:"POST",body:We.object({password:We.string().min(8)}),use:[b]},async s=>{let a=s.context.session.user,{password:i}=s.body;if(!await rt(s,{password:i,userId:a.id}))throw new ur("BAD_REQUEST",{message:"Invalid password"});return await s.context.internalAdapter.updateUser(a.id,{twoFactorEnabled:!1}),await s.context.adapter.delete({model:t.twoFactorTable,where:[{field:"userId",value:a.id}]}),s.json({status:!0})})},options:e,hooks:{after:[{matcher(s){return s.path==="/sign-in/email"||s.path==="/sign-in/username"},handler:z(async s=>{let a=s.context.returned;if(a?.status!==200)return;let i=await a.clone().json();if(!i.user.twoFactorEnabled)return;let d=s.context.createAuthCookie(Qe,{maxAge:30*24*60*60}),u=await s.getSignedCookie(d.name,s.context.secret);if(u){let[m,f]=u.split("!"),h=await J(s.context.secret,`${i.user.id}!${f}`);if(m===h){let O=await J(s.context.secret,`${i.user.id}!${i.session.id}`);await s.setSignedCookie(d.name,`${O}!${i.session.id}`,s.context.secret,d.options);return}}s.setCookie(s.context.authCookies.sessionToken.name,"",{path:"/",sameSite:"lax",httpOnly:!0,secure:!1,maxAge:0});let l=await J(s.context.secret,i.session.id),p=s.context.createAuthCookie(Ve,{maxAge:60*60*24});return await s.setSignedCookie(p.name,`${i.session.userId}!${l}`,s.context.secret,p.options),{response:new Response(JSON.stringify({twoFactorRedirect:!0}),{headers:s.responseHeader})}})}]},schema:{user:{fields:{twoFactorEnabled:{type:"boolean",required:!1,defaultValue:!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(s){return s.startsWith("/two-factor/")},window:10,max:3}]}};import{generateAuthenticationOptions as Co,generateRegistrationOptions as zo,verifyAuthenticationResponse as Bo,verifyRegistrationResponse as Lo}from"@simplewebauthn/server";import{APIError as X}from"better-call";import{z as oe}from"zod";import{WebAuthnError as vo,startAuthentication as Eo,startRegistration as So}from"@simplewebauthn/browser";import{createFetch as zu}from"@better-fetch/fetch";import"nanostores";import{betterFetch as Tu}from"@better-fetch/fetch";import{atom as Qu}from"nanostores";import"@better-fetch/fetch";import{atom as Uo,onMount as To}from"nanostores";var ot=(e,t,r,o)=>{let n=Uo({data:null,error:null,isPending:!1,isRefetching:!1}),s=()=>{let i=typeof o=="function"?o({data:n.get().data,error:n.get().error,isPending:n.get().isPending}):o;return r(t,{...i,onSuccess:async d=>{n.set({data:d.data,error:null,isPending:!1,isRefetching:!1}),await i?.onSuccess?.(d)},async onError(d){n.set({error:d.error,data:null,isPending:!1,isRefetching:!1}),await i?.onError?.(d)},async onRequest(d){let u=n.get();n.set({isPending:u.data===null,data:u.data,error:null,isRefetching:!0}),await i?.onRequest?.(d)}})};e=Array.isArray(e)?e:[e];let a=!1;for(let i of e)i.subscribe(()=>{a?s():To(n,()=>(s(),a=!0,()=>{n.off(),i.off()}))});return n};import{atom as Po}from"nanostores";var _o=(e,{_listPasskeys:t})=>({signIn:{passkey:async(n,s)=>{let a=await e("/passkey/generate-authenticate-options",{method:"POST",body:{email:n?.email}});if(!a.data)return a;try{let i=await Eo(a.data,n?.autoFill||!1),d=await e("/passkey/verify-authentication",{body:{response:i},...n?.fetchOptions,...s,method:"POST"});if(!d.data)return d}catch(i){console.log(i)}}},passkey:{addPasskey:async(n,s)=>{let a=await e("/passkey/generate-register-options",{method:"GET"});if(!a.data)return a;try{let i=await So(a.data),d=await e("/passkey/verify-registration",{...n?.fetchOptions,...s,body:{response:i,name:n?.name},method:"POST"});if(!d.data)return d;t.set(Math.random())}catch(i){return i instanceof vo?i.code==="ERROR_AUTHENTICATOR_PREVIOUSLY_REGISTERED"?{data:null,error:{message:"previously registered",status:400,statusText:"BAD_REQUEST"}}:i.code==="ERROR_CEREMONY_ABORTED"?{data:null,error:{message:"registration cancelled",status:400,statusText:"BAD_REQUEST"}}:{data:null,error:{message:i.message,status:400,statusText:"BAD_REQUEST"}}:{data:null,error:{message:i instanceof Error?i.message:"unknown error",status:500,statusText:"INTERNAL_SERVER_ERROR"}}}}},$Infer:{}}),ul=()=>{let e=Po();return{id:"passkey",$InferServerPlugin:{},getActions:t=>_o(t,{_listPasskeys:e}),getAtoms(t){return{listPasskeys:ot(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 Ol=e=>{let t=process.env.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),s=new Date,a=Math.floor((n.getTime()-s.getTime())/1e3);return{id:"passkey",endpoints:{generatePasskeyRegistrationOptions:c("/passkey/generate-register-options",{method:"GET",use:[b],metadata:{client:!1}},async i=>{let d=i.context.session,u=await i.context.adapter.findMany({model:"passkey",where:[{field:"userId",value:d.user.id}]}),l=new Uint8Array(Buffer.from(M(32,q("a-z","0-9")))),p;p=await zo({rpName:o.rpName||i.context.appName,rpID:o.rpID,userID:l,userName:d.user.email||d.user.id,attestationType:"none",excludeCredentials:u.map(m=>({id:m.id,transports:m.transports?.split(",")})),authenticatorSelection:{residentKey:"preferred",userVerification:"preferred",authenticatorAttachment:"platform"}});let U=_();return await i.setSignedCookie(o.advanced.webAuthnChallengeCookie,U,i.context.secret,{secure:!0,httpOnly:!0,sameSite:"lax",maxAge:a}),await i.context.internalAdapter.createVerificationValue({identifier:U,value:JSON.stringify({expectedChallenge:p.challenge,userData:{id:d.user.id}}),expiresAt:n}),i.json(p,{status:200})}),generatePasskeyAuthenticationOptions:c("/passkey/generate-authenticate-options",{method:"POST",body:oe.object({email:oe.string().optional()}).optional()},async i=>{let d=await G(i),u=[];d&&(u=await i.context.adapter.findMany({model:"passkey",where:[{field:"userId",value:d.user.id}]}));let l=await Co({rpID:o.rpID,userVerification:"preferred",...u.length?{allowCredentials:u.map(m=>({id:m.id,transports:m.transports?.split(",")}))}:{}}),p={expectedChallenge:l.challenge,userData:{id:d?.user.id||""}},U=_();return await i.setSignedCookie(o.advanced.webAuthnChallengeCookie,U,i.context.secret,{secure:!0,httpOnly:!0,sameSite:"lax",maxAge:a}),await i.context.internalAdapter.createVerificationValue({identifier:U,value:JSON.stringify(p),expiresAt:n}),i.json(l,{status:200})}),verifyPasskeyRegistration:c("/passkey/verify-registration",{method:"POST",body:oe.object({response:oe.any(),name:oe.string().optional()}),use:[b]},async i=>{let d=e?.origin||i.headers?.get("origin")||"";if(!d)return i.json(null,{status:400});let u=i.body.response,l=await i.getSignedCookie(o.advanced.webAuthnChallengeCookie,i.context.secret);if(!l)throw new X("BAD_REQUEST",{message:"Challenge not found"});let p=await i.context.internalAdapter.findVerificationValue(l);if(!p)return i.json(null,{status:400});let{expectedChallenge:U,userData:m}=JSON.parse(p.value);if(m.id!==i.context.session.user.id)throw new X("UNAUTHORIZED",{message:"You are not authorized to register this passkey"});try{let f=await Lo({response:u,expectedChallenge:U,expectedOrigin:d,expectedRPID:e?.rpID}),{verified:h,registrationInfo:O}=f;if(!h||!O)return i.json(null,{status:400});let{credentialID:k,credentialPublicKey:re,counter:se,credentialDeviceType:R,credentialBackedUp:F}=O,ie=Buffer.from(re).toString("base64"),x=_(),Be={name:i.body.name,userId:m.id,webauthnUserID:x,id:k,publicKey:ie,counter:se,deviceType:R,transports:u.response.transports.join(","),backedUp:F,createdAt:new Date},pr=await i.context.adapter.create({model:"passkey",data:Be});return i.json(pr,{status:200})}catch(f){throw console.log(f),new X("INTERNAL_SERVER_ERROR",{message:"Failed to verify registration"})}}),verifyPasskeyAuthentication:c("/passkey/verify-authentication",{method:"POST",body:oe.object({response:oe.any()})},async i=>{let d=e?.origin||i.headers?.get("origin")||"";if(!d)throw new X("BAD_REQUEST",{message:"origin missing"});let u=i.body.response,l=await i.getSignedCookie(o.advanced.webAuthnChallengeCookie,i.context.secret);if(!l)throw new X("BAD_REQUEST",{message:"Challenge not found"});let p=await i.context.internalAdapter.findVerificationValue(l);if(!p)throw new X("BAD_REQUEST",{message:"Challenge not found"});let{expectedChallenge:U}=JSON.parse(p.value),m=await i.context.adapter.findOne({model:"passkey",where:[{field:"id",value:u.id}]});if(!m)throw new X("UNAUTHORIZED",{message:"Passkey not found"});try{let f=await Bo({response:u,expectedChallenge:U,expectedOrigin:d,expectedRPID:o.rpID,authenticator:{credentialID:m.id,credentialPublicKey:new Uint8Array(Buffer.from(m.publicKey,"base64")),counter:m.counter,transports:m.transports?.split(",")}}),{verified:h}=f;if(!h)throw new X("UNAUTHORIZED",{message:"Authentication failed"});await i.context.adapter.update({model:"passkey",where:[{field:"id",value:m.id}],update:{counter:f.authenticationInfo.newCounter}});let O=await i.context.internalAdapter.createSession(m.userId,i.request);if(!O)throw new X("INTERNAL_SERVER_ERROR",{message:"Unable to create session"});return await y(i,O.id),i.json({session:O},{status:200})}catch(f){throw i.context.logger.error(f),new X("BAD_REQUEST",{message:"Failed to verify authentication"})}}),listPasskeys:c("/passkey/list-user-passkeys",{method:"GET",use:[b]},async i=>{let d=await i.context.adapter.findMany({model:"passkey",where:[{field:"userId",value:i.context.session.user.id}]});return i.json(d,{status:200})}),deletePasskey:c("/passkey/delete-passkey",{method:"POST",body:oe.object({id:oe.string()}),use:[b]},async i=>(await i.context.adapter.delete({model:"passkey",where:[{field:"id",value:i.body.id}]}),i.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 ee}from"zod";import{APIError as Ge}from"better-call";var lr=()=>({id:"username",endpoints:{signInUsername:c("/sign-in/username",{method:"POST",body:ee.object({username:ee.string(),password:ee.string(),dontRememberMe:ee.boolean().optional()})},async e=>{let t=await e.context.adapter.findOne({model:"user",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:lr}),new Ge("UNAUTHORIZED",{message:"Invalid username or password"});let r=await e.context.adapter.findOne({model:"account",where:[{field:"userId",value:t.id},{field:"providerId",value:"credential"}]});if(!r)throw new Ge("UNAUTHORIZED",{message:"Invalid username or password"});let o=r?.password;if(!o)throw e.context.logger.error("Password not found",{username:lr}),new Ge("UNAUTHORIZED",{message:"Unexpected error"});if(!await e.context.password.verify(o,e.body.password))throw e.context.logger.error("Invalid password"),new Ge("UNAUTHORIZED",{message:"Invalid username or password"});let s=await e.context.internalAdapter.createSession(t.id,e.request);return s?(await e.setSignedCookie(e.context.authCookies.sessionToken.name,s.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:s})):e.json(null,{status:500,body:{message:"Failed to create session",status:500}})}),signUpUsername:c("/sign-up/username",{method:"POST",body:ee.object({username:ee.string().min(3).max(20),name:ee.string(),email:ee.string().email(),password:ee.string(),image:ee.string().optional()})},async e=>{let t=await ve()({...e,_flag:"json"});if(t.error)return e.json(null,{status:400,body:{message:t.error,status:400}});let r=await e.context.internalAdapter.updateUserByEmail(t.user?.email,{username:e.body.username});return e.json({user:r,session:t.session})})},schema:{user:{fields:{username:{type:"string",required:!1,unique:!0,returned:!0}}}}});import{serializeSigned as Do}from"better-call";var _l=()=>({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 Do("",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 Oe}from"zod";import{APIError as xo}from"better-call";var Nl=e=>({id:"magic-link",endpoints:{signInMagicLink:c("/sign-in/magic-link",{method:"POST",requireHeaders:!0,body:Oe.object({email:Oe.string().email(),callbackURL:Oe.string().optional()}),use:[j]},async t=>{let{email:r}=t.body,o=M(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(s){throw t.context.logger.error("Failed to send magic link",s),new xo("INTERNAL_SERVER_ERROR",{message:"Failed to send magic link"})}return t.json({status:!0})}),magicLinkVerify:c("/magic-link/verify",{method:"GET",query:Oe.object({token:Oe.string(),callbackURL:Oe.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,s=await t.context.internalAdapter.findVerificationValue(r);if(!s)throw t.redirect(`${n}?error=INVALID_TOKEN`);if(s.expiresAt<new Date)throw await t.context.internalAdapter.deleteVerificationValue(s.id),t.redirect(`${n}?error=EXPIRED_TOKEN`);await t.context.internalAdapter.deleteVerificationValue(s.id);let a=s.value,i=await t.context.internalAdapter.findUserByEmail(a),d=i?.user.id||"";if(!i){if(e.disableSignUp)throw t.redirect(`${n}?error=USER_NOT_FOUND`);if(d=(await t.context.internalAdapter.createUser({email:a,name:a})).id,!d)throw t.redirect(`${n}?error=USER_NOT_CREATED`)}let u=await t.context.internalAdapter.createSession(d,t.headers);if(!u)throw t.redirect(`${n}?error=SESSION_NOT_CREATED`);if(await y(t,u.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 C}from"zod";import{APIError as D}from"better-call";function nt(e){return M(e,q("0-9"))}var Jl=e=>{let t={phoneNumber:"phoneNumber",phoneNumberVerified:"phoneNumberVerified",otp:{code:"code",phoneNumber:"phoneNumber",createdAt:"createdAt",expiresIn:e?.otp?.expiresIn||300}};return{id:"phone-number",endpoints:{signInPhoneNumber:c("/sign-in/phone-number",{method:"POST",body:C.object({phoneNumber:C.string(),password:C.string(),dontRememberMe:C.boolean().optional()})},async r=>{let o=await r.context.adapter.findOne({model:"user",where:[{field:t.phoneNumber,value:r.body.phoneNumber}]});if(!o)throw await r.context.password.hash(r.body.password),new D("UNAUTHORIZED",{message:"Invalid email or password"});let n=await r.context.adapter.findOne({model:r.context.tables.account.tableName,where:[{field:"userId",value:o.id},{field:"providerId",value:"credential"}]});if(!n)throw new D("UNAUTHORIZED",{message:"Invalid email or password"});let s=n?.password;if(!s)throw r.context.logger.warn("Unexpectedly password is missing for the user",o),new D("UNAUTHORIZED",{message:"Unexpected error"});if(!await r.context.password.verify(s,r.body.password))throw r.context.logger.error("Invalid password"),new D("UNAUTHORIZED",{message:"Invalid email or password"});let i=await r.context.internalAdapter.createSession(o.id,r.request);return i?(await r.setSignedCookie(r.context.authCookies.sessionToken.name,i.id,r.context.secret,r.body.dontRememberMe?{...r.context.authCookies.sessionToken.options,maxAge:void 0}:r.context.authCookies.sessionToken.options),r.json({user:o,session:i})):r.json(null,{status:500,body:{message:"Failed to create session",status:500}})}),signUpPhoneNumber:c("/sign-up/phone-number",{method:"POST",body:C.object({phoneNumber:C.string().min(3).max(20),name:C.string(),email:C.string().email(),password:C.string(),image:C.string().optional()})},async r=>{if(e?.phoneNumberValidator&&!e.phoneNumberValidator(r.body.phoneNumber))throw new D("BAD_REQUEST",{message:"Invalid phone number"});if(await r.context.adapter.findOne({model:r.context.tables.user.tableName,where:[{field:t.phoneNumber,value:r.body.phoneNumber}]}))throw new D("BAD_REQUEST",{message:"Phone number already exists"});try{let n=await ve()({...r,options:{...r.context.options},_flag:"json"});if(e?.otp?.sendOTPonSignUp){if(!e.otp.sendOTP)throw A.warn("sendOTP not implemented"),new D("NOT_IMPLEMENTED",{message:"sendOTP not implemented"});let a=nt(e?.otp?.otpLength||6);await r.context.internalAdapter.createVerificationValue({value:a,identifier:r.body.phoneNumber,expiresAt:V(t.otp.expiresIn,"sec")}),await e.otp.sendOTP(r.body.phoneNumber,a)}let s=await r.context.internalAdapter.updateUserByEmail(n.user.email,{[t.phoneNumber]:r.body.phoneNumber});return r.json({user:s,session:n.session})}catch(n){throw n instanceof D?n:new D("INTERNAL_SERVER_ERROR",{message:"Failed to create user"})}}),sendVerificationCode:c("/phone-number/send-verification-code",{method:"POST",body:C.object({phoneNumber:C.string()})},async r=>{if(!e?.otp?.sendOTP)throw A.warn("sendOTP not implemented"),new D("NOT_IMPLEMENTED",{message:"sendOTP not implemented"});let o=nt(e?.otp?.otpLength||6);return await r.context.internalAdapter.createVerificationValue({value:o,identifier:r.body.phoneNumber,expiresAt:V(t.otp.expiresIn,"sec")}),await e.otp.sendOTP(r.body.phoneNumber,o),r.json({code:o},{body:{message:"Code sent"}})}),verifyPhoneNumber:c("/phone-number/verify",{method:"POST",body:C.object({phoneNumber:C.string(),code:C.string()})},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 D("BAD_REQUEST",{message:"OTP expired"})):new D("BAD_REQUEST",{message:"OTP not found"});if(o.value!==r.body.code)throw new D("BAD_REQUEST",{message:"Invalid OTP"});await r.context.internalAdapter.deleteVerificationValue(o.id);let n=await r.context.adapter.findOne({model:r.context.tables.user.tableName,where:[{value:r.body.phoneNumber,field:t.phoneNumber}]});if(!n)throw new D("NOT_FOUND",{message:"User with phone number not found"});let s=await r.context.internalAdapter.updateUser(n.id,{[t.phoneNumberVerified]:!0});if(e?.enableAutoSignIn&&!await G(r)){let i=await r.context.internalAdapter.createSession(n.id,r.request);if(!i)throw new D("INTERNAL_SERVER_ERROR",{message:"Failed to create session"});return await y(r,i.id),r.json({user:s,session:i})}return r.json({user:s,session:null})}),updatePhoneNumber:c("/phone-number/update",{method:"POST",body:C.object({phoneNumber:C.string()}),use:[b]},async r=>{if(e?.otp?.sendOTPonUpdate){if(!e.otp.sendOTP)throw A.warn("sendOTP not implemented"),new D("NOT_IMPLEMENTED",{message:"sendOTP not implemented"});let n=nt(e?.otp?.otpLength||6);await r.context.adapter.create({model:r.context.tables.verification.tableName,data:{code:n,phoneNumber:r.body.phoneNumber,createdAt:V(t.otp.expiresIn,"sec")}}),await e.otp.sendOTP(r.body.phoneNumber,n)}let o=await r.context.internalAdapter.updateUser(r.context.session.user.id,{[t.phoneNumber]:r.body.phoneNumber,[t.phoneNumberVerified]:!1});return r.json({user:o})})},schema:{user:{fields:{phoneNumber:{type:"string",required:!1,unique:!0,returned:!0},phoneNumberVerified:{type:"boolean",required:!1,returned:!0}}}}}};import{z as st}from"zod";var op=e=>({id:"anonymous",endpoints:{signInAnonymous:c("/sign-in/anonymous",{method:"POST"},async t=>{let{emailDomainName:r=pt(t.context.baseURL)}=e||{},o=_(),n=`temp-${o}@${r}`,s=await t.context.internalAdapter.createUser({id:o,email:n,emailVerified:!1,isAnonymous:!0,name:"Anonymous",createdAt:new Date,updatedAt:new Date});if(!s)return t.json(null,{status:500,body:{message:"Failed to create user",status:500}});let a=await t.context.internalAdapter.createSession(s.id,t.request);return a?(await y(t,a.id),t.json({user:s,session:a})):t.json(null,{status:400,body:{message:"Could not create session"}})}),linkAnonymous:c("/user/link-anonymous",{method:"POST",body:st.object({email:st.string().email().optional(),password:st.string().min(6)}),use:[b]},async t=>{let r=t.context.session.user.id,{email:o,password:n}=t.body,s=null;if(o&&n&&(s=await t.context.internalAdapter.updateUser(r,{email:o})),!s)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:s.id,providerId:"credential",password:a,accountId:s.id}))return t.json(null,{status:500,body:{message:"Failed to update account",status:500}});let d=await t.context.internalAdapter.createSession(s.id,t.request);return d?(await y(t,d.id),t.json({session:d,user:s})):t.json(null,{status:400,body:{message:"Could not create session"}})})},schema:{user:{fields:{isAnonymous:{type:"boolean",defaultValue:!0,required:!1}}}}});import{z as g}from"zod";var te=z(async e=>{let t=await G(e);if(!t?.session)throw new ce("UNAUTHORIZED");let r=t.user;if(r.role!=="admin")throw new ce("FORBIDDEN",{message:"Only admins can access this endpoint"});return{session:{user:r,session:t.session}}}),cp=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:z(async t=>{let r=t.context.returned;if(r){let n=(await r.json()).filter(a=>!a.impersonatedBy),s=new Response(JSON.stringify(n),{status:200,statusText:"OK",headers:r.headers});return t.json({response:s})}})}]},endpoints:{setRole:c("/admin/set-role",{method:"POST",body:g.object({userId:g.string(),role:g.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:c("/admin/create-user",{method:"POST",body:g.object({email:g.string(),password:g.string(),name:g.string(),role:g.enum(["user","admin"]),data:g.optional(g.record(g.any()))}),use:[te]},async t=>{if(await t.context.internalAdapter.findUserByEmail(t.body.email))throw new ce("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 ce("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:c("/admin/list-users",{method:"GET",use:[te],query:g.object({limit:g.string().or(g.number()).optional(),offset:g.string().or(g.number()).optional(),sortBy:g.string().optional(),sortDirection:g.enum(["asc","desc"]).optional()})},async t=>{let r=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);return t.json({users:r})}),listUserSessions:c("/admin/list-user-sessions",{method:"POST",use:[te],body:g.object({userId:g.string()})},async t=>({sessions:await t.context.internalAdapter.listSessions(t.body.userId)})),unbanUser:c("/admin/unban-user",{method:"POST",body:g.object({userId:g.string()}),use:[te]},async t=>{let r=await t.context.internalAdapter.updateUser(t.body.userId,{banned:!1});return t.json({user:r})}),banUser:c("/admin/ban-user",{method:"POST",body:g.object({userId:g.string(),banReason:g.string().optional(),banExpiresIn:g.number().optional()}),use:[te]},async t=>{if(t.body.userId===t.context.session.user.id)throw new ce("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:c("/admin/impersonate-user",{method:"POST",body:g.object({userId:g.string()}),use:[te]},async t=>{let r=await t.context.internalAdapter.findUserById(t.body.userId);if(!r)throw new ce("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?V(e.impersonationSessionDuration,"sec"):V(60*60,"sec")});if(!o)throw new ce("INTERNAL_SERVER_ERROR",{message:"Failed to create session"});return await y(t,o.id,!0),t.json({session:o,user:r})}),revokeUserSession:c("/admin/revoke-user-session",{method:"POST",body:g.object({sessionId:g.string()}),use:[te]},async t=>(await t.context.internalAdapter.deleteSession(t.body.sessionId),t.json({success:!0}))),revokeUserSessions:c("/admin/revoke-user-sessions",{method:"POST",body:g.object({userId:g.string()}),use:[te]},async t=>(await t.context.internalAdapter.deleteSessions(t.body.userId),t.json({success:!0}))),removeUser:c("/admin/remove-user",{method:"POST",body:g.object({userId:g.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},banned:{type:"boolean",defaultValue:!1,required:!1},banReason:{type:"string",required:!1},banExpires:{type:"number",required:!1}}},session:{fields:{impersonatedBy:{type:"string",required:!1,references:{model:"user",field:"id"}}}}}});import{z as ne}from"zod";import{APIError as ze}from"better-call";import{betterFetch as it}from"@better-fetch/fetch";import{generateCodeVerifier as jo}from"oslo/oauth2";import{parseJWT as No}from"oslo/jwt";async function Fo(e,t,r){if(t==="oidc"&&e.idToken){let n=No(e.idToken);if(n?.payload)return n.payload}return r?(await it(r,{method:"GET",headers:{Authorization:`Bearer ${e.accessToken}`}})).data:null}var Tp=e=>({id:"generic-oauth",endpoints:{signInWithOAuth2:c("/sign-in/oauth2",{method:"POST",query:ne.object({currentURL:ne.string().optional()}).optional(),body:ne.object({providerId:ne.string(),callbackURL:ne.string().optional()}),use:[j]},async t=>{let{providerId:r}=t.body,o=e.config.find(x=>x.providerId===r);if(!o)throw new ze("BAD_REQUEST",{message:`No config found for provider ${r}`});let{discoveryUrl:n,authorizationUrl:s,tokenUrl:a,clientId:i,clientSecret:d,scopes:u,redirectURI:l,responseType:p,pkce:U,prompt:m,accessType:f}=o,h=s,O=a;if(n){let x=await it(n,{onError(Be){A.error(Be.error,{discoveryUrl:n})}});x.data&&(h=x.data.authorization_endpoint,O=x.data.token_endpoint)}if(!h||!O)throw new ze("BAD_REQUEST",{message:"Invalid OAuth configuration."});let k=t.query?.currentURL?new URL(t.query?.currentURL):null,re=t.body.callbackURL?.startsWith("http")?t.body.callbackURL:`${k?.origin}${t.body.callbackURL||""}`,se=await xe(re||k?.origin||t.context.options.baseURL),R=t.context.authCookies;await t.setSignedCookie(R.state.name,se.hash,t.context.secret,R.state.options);let F=jo();await t.setSignedCookie(R.pkCodeVerifier.name,F,t.context.secret,R.pkCodeVerifier.options);let ie=await B({id:r,options:{clientId:i,clientSecret:d,redirectURI:l||`${t.context.baseURL}/oauth2/callback/${r}`},authorizationEndpoint:h,state:se.raw,codeVerifier:F,scopes:u||[],disablePkce:!U});return p&&p!=="code"&&ie.searchParams.set("response_type",p),m&&ie.searchParams.set("prompt",m),f&&ie.searchParams.set("access_type",f),{url:ie.toString(),state:se,codeVerifier:F,redirect:!0}}),oAuth2Callback:c("/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 F=we(t.query.state).data?.currentURL||`${t.context.baseURL}/error`;throw t.context.logger.error(t.query.error,t.params.providerId),t.redirect(`${F}?error=${t.query.error||"oAuth_code_missing"}`)}let r=e.config.find(R=>R.providerId===t.params.providerId);if(!r)throw new ze("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,s=we(t.query.state);if(!s.success)throw t.redirect(`${t.context.baseURL}/error?error=invalid_state`);let a=t.query.state,{data:{callbackURL:i,currentURL:d,code:u}}=s,l=s.data?.currentURL||`${t.context.baseURL}/error`,p=await t.getSignedCookie(t.context.authCookies.state.name,t.context.secret);if(!p)throw A.error("No stored state found"),t.redirect(`${l}?error=please_restart_the_process`);if(!await Le(a,p))throw A.error("OAuth code mismatch"),t.redirect(`${l}?error=please_restart_the_process`);let m=r.tokenUrl,f=r.userInfoUrl;if(r.discoveryUrl){let R=await it(r.discoveryUrl,{method:"GET"});R.data&&(m=R.data.token_endpoint,f=R.data.userinfo_endpoint)}try{if(!m)throw new ze("BAD_REQUEST",{message:"Invalid OAuth configuration."});n=await v({code:u,codeVerifier:o,redirectURI:`${t.context.baseURL}/oauth2/callback/${r.providerId}`,options:{clientId:r.clientId,clientSecret:r.clientSecret},tokenEndpoint:m})}catch(R){throw t.context.logger.error(R),t.redirect(`${l}?error=oauth_code_verification_failed`)}if(!n)throw new ze("BAD_REQUEST",{message:"Invalid OAuth configuration."});let h=r.getUserInfo?await r.getUserInfo(n):await Fo(n,r.type||"oauth2",f),O=_(),k=h?je.safeParse({...h,id:O}):null;if(!k?.success)throw t.redirect(`${l}?error=oauth_user_info_invalid`);let re=await t.context.internalAdapter.findUserByEmail(k.data.email).catch(R=>{throw A.error(`Better auth was unable to query your database.
84
+ Error: `,R),t.redirect(`${l}?error=internal_server_error`)}),se=re?.user.id||O;if(re){let R=re.accounts.find(x=>x.providerId===r.providerId),F=t.context.options.account?.accountLinking?.trustedProviders,ie=F?F.includes(r.providerId):!0;if(!R&&(!k?.data.emailVerified||!ie)){let x;try{x=new URL(l),x.searchParams.set("error","account_not_linked")}catch{throw t.redirect(`${l}?error=account_not_linked`)}throw t.redirect(x.toString())}if(!R)try{await t.context.internalAdapter.linkAccount({providerId:r.providerId,accountId:k.data.id,id:`${r.providerId}:${k.data.id}`,userId:re.user.id,...ye(n)})}catch(x){throw console.log(x),t.redirect(`${l}?error=failed_linking_account`)}}else try{await t.context.internalAdapter.createOAuthUser(k.data,{...ye(n),id:`${r.providerId}:${k.data.id}`,providerId:r.providerId,accountId:k.data.id,userId:se})}catch{let F=new URL(l);throw F.searchParams.set("error","unable_to_create_user"),t.setHeader("Location",F.toString()),t.redirect(F.toString())}try{let R=await t.context.internalAdapter.createSession(se||O,t.request);if(!R)throw t.redirect(`${l}?error=unable_to_create_session`);await y(t,R.id)}catch{throw t.redirect(`${l}?error=unable_to_create_session`)}throw t.redirect(i||d||"")})}});export{de as HIDE_METADATA,Ft as ac,cp as admin,te as adminMiddleware,op as anonymous,_l as bearer,c as createAuthEndpoint,z as createAuthMiddleware,Tp as genericOAuth,_o as getPasskeyActions,Nl as magicLink,dt as optionsMiddleware,Uc as organization,Ol as passkey,ul as passkeyClient,Jl as phoneNumber,Ou as twoFactor,cu as twoFactorClient,lr 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-Nmre53Xe.js';
6
+ import './auth-2pRFLprr.js';
7
7
  import 'kysely';
8
8
  import './schema-Dkt0LqYs.js';
9
9
  import 'better-call';
@@ -1,4 +1,4 @@
1
- import { e as Auth } from './auth-Nmre53Xe.js';
1
+ import { e as Auth } from './auth-2pRFLprr.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-Nmre53Xe.js';
6
+ import './auth-2pRFLprr.js';
7
7
  import 'kysely';
8
8
  import './schema-Dkt0LqYs.js';
9
9
  import 'better-call';
@@ -1,4 +1,4 @@
1
- import { e as Auth, f as BetterAuthOptions } from './auth-Nmre53Xe.js';
1
+ import { e as Auth, f as BetterAuthOptions } from './auth-2pRFLprr.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-Nmre53Xe.js';
6
+ import './auth-2pRFLprr.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, e as Auth, O as InferFieldsInputClient, M as InferFieldsOutput } from './auth-Nmre53Xe.js';
2
- export { A as Adapter, j as AdditionalSessionFieldsInput, k as AdditionalSessionFieldsOutput, h as AdditionalUserFieldsInput, i as AdditionalUserFieldsOutput, p as AuthContext, f 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-Nmre53Xe.js';
1
+ import { B as BetterAuthPlugin, e as Auth, O as InferFieldsInputClient, M as InferFieldsOutput } from './auth-2pRFLprr.js';
2
+ export { A as Adapter, j as AdditionalSessionFieldsInput, k as AdditionalSessionFieldsOutput, h as AdditionalUserFieldsInput, i as AdditionalUserFieldsOutput, p as AuthContext, f 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-2pRFLprr.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-Nmre53Xe.js';
6
+ import './auth-2pRFLprr.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.4.10-beta.2",
3
+ "version": "0.4.10-beta.4",
4
4
  "description": "The most comprehensive authentication library for TypeScript.",
5
5
  "type": "module",
6
6
  "repository": {
@@ -79,7 +79,7 @@
79
79
  "@noble/hashes": "^1.5.0",
80
80
  "@simplewebauthn/browser": "^10.0.0",
81
81
  "@simplewebauthn/server": "^10.0.1",
82
- "better-call": "0.2.6",
82
+ "better-call": "0.2.7",
83
83
  "consola": "^3.2.3",
84
84
  "defu": "^6.1.4",
85
85
  "kysely": "^0.27.4",