better-auth 0.4.11-beta.2 → 0.4.11-beta.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/adapters/drizzle.d.ts +1 -1
- package/dist/adapters/kysely.d.ts +1 -1
- package/dist/adapters/mongodb.d.ts +1 -1
- package/dist/adapters/prisma.d.ts +1 -1
- package/dist/api.d.ts +1 -1
- package/dist/{auth-Q1HJFsHz.d.ts → auth-BGQTSAwN.d.ts} +1 -1
- package/dist/client/plugins.d.ts +3 -3
- package/dist/client.d.ts +1 -1
- package/dist/cookies.d.ts +1 -1
- package/dist/db.d.ts +2 -2
- package/dist/{index-CdYUesI6.d.ts → index-DgJ3JDtV.d.ts} +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/node.d.ts +1 -1
- package/dist/plugins.d.ts +153 -6
- package/dist/plugins.js +5 -5
- package/dist/react.d.ts +1 -1
- package/dist/solid-start.d.ts +1 -1
- package/dist/solid.d.ts +1 -1
- package/dist/svelte-kit.d.ts +1 -1
- package/dist/svelte.d.ts +1 -1
- package/dist/types.d.ts +2 -2
- package/dist/vue.d.ts +1 -1
- package/package.json +2 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Kysely } from 'kysely';
|
|
2
|
-
import {
|
|
2
|
+
import { B as BetterAuthOptions, K as KyselyDatabaseType, F as FieldAttribute, A as Adapter } from '../auth-BGQTSAwN.js';
|
|
3
3
|
import 'zod';
|
|
4
4
|
import '../schema-Dkt0LqYs.js';
|
|
5
5
|
import 'better-call';
|
package/dist/api.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { e as AuthEndpoint, f as AuthMiddleware, a0 as callbackOAuth, af as changePassword, d 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-BGQTSAwN.js';
|
|
2
2
|
import './helper-DPDj8Nix.js';
|
|
3
3
|
export { APIError } from 'better-call';
|
|
4
4
|
import 'zod';
|
|
@@ -5675,4 +5675,4 @@ type Auth = {
|
|
|
5675
5675
|
options: BetterAuthOptions;
|
|
5676
5676
|
};
|
|
5677
5677
|
|
|
5678
|
-
export { signInEmail as $, type Adapter as A, type
|
|
5678
|
+
export { signInEmail as $, type Adapter as A, type BetterAuthOptions as B, type InternalAdapter as C, type FieldAttributeConfig as D, type EligibleCookies as E, type FieldAttribute as F, type GenericEndpointContext as G, type HookEndpointContext as H, type InferUser as I, createFieldAttribute as J, type KyselyDatabaseType as K, type InferValueType as L, type InferFieldsOutput as M, type InferFieldsInput as N, type InferFieldsInputClient as O, type PluginSchema as P, type PluginFieldAttribute as Q, type RateLimit as R, type SecondaryStorage as S, type InferFieldsFromPlugins as T, type InferFieldsFromOptions as U, type BetterAuthDbSchema as V, type Where as W, getAuthTables as X, getEndpoints as Y, router as Z, signInOAuth as _, type Auth as a, callbackOAuth as a0, getSession as a1, getSessionFromCtx as a2, sessionMiddleware as a3, listSessions as a4, revokeSession as a5, revokeSessions as a6, signOut as a7, forgetPassword as a8, forgetPasswordCallback as a9, resetPassword as aa, createEmailVerificationToken as ab, sendVerificationEmail as ac, verifyEmail as ad, updateUser as ae, changePassword as af, setPassword as ag, deleteUser as ah, getCSRFToken as ai, error as aj, ok as ak, signUpEmail as al, csrfMiddleware as am, type BetterAuthPlugin as b, createAuthMiddleware as c, createAuthEndpoint as d, type AuthEndpoint as e, type AuthMiddleware as f, betterAuth as g, type AdditionalUserFieldsInput as h, type AdditionalUserFieldsOutput as i, type AdditionalSessionFieldsInput as j, type AdditionalSessionFieldsOutput as k, type InferSession as l, type InferPluginTypes as m, init as n, optionsMiddleware as o, type AuthContext as p, getCookies as q, createCookieGetter as r, type BetterAuthCookies as s, setSessionCookie as t, deleteSessionCookie as u, parseSetCookieHeader as v, createLogger as w, logger as x, type FieldType as y, createInternalAdapter as z };
|
package/dist/client/plugins.d.ts
CHANGED
|
@@ -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-
|
|
6
|
-
export { g as getPasskeyActions, c as passkeyClient, a as twoFactorClient } from '../index-
|
|
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-DgJ3JDtV.js';
|
|
6
|
+
export { g as getPasskeyActions, c as passkeyClient, a as twoFactorClient } from '../index-DgJ3JDtV.js';
|
|
7
7
|
import { P as Prettify } from '../helper-DPDj8Nix.js';
|
|
8
|
-
import { F as FieldAttribute,
|
|
8
|
+
import { F as FieldAttribute, B as BetterAuthOptions, b as BetterAuthPlugin } from '../auth-BGQTSAwN.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-
|
|
9
|
+
import './auth-BGQTSAwN.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-
|
|
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-BGQTSAwN.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,
|
|
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-
|
|
1
|
+
import { A as Adapter, B as BetterAuthOptions, W as Where, F as FieldAttribute, y as FieldType, K as KyselyDatabaseType } from './auth-BGQTSAwN.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-BGQTSAwN.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-
|
|
8
|
+
import { H as HookEndpointContext, p as AuthContext } from './auth-BGQTSAwN.js';
|
|
9
9
|
import * as nanostores from 'nanostores';
|
|
10
10
|
import { atom } from 'nanostores';
|
|
11
11
|
import * as _simplewebauthn_types from '@simplewebauthn/types';
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { A as Adapter, j as AdditionalSessionFieldsInput, k as AdditionalSessionFieldsOutput, h as AdditionalUserFieldsInput, i as AdditionalUserFieldsOutput,
|
|
1
|
+
export { A as Adapter, j as AdditionalSessionFieldsInput, k as AdditionalSessionFieldsOutput, h as AdditionalUserFieldsInput, i as AdditionalUserFieldsOutput, a as Auth, p as AuthContext, s as BetterAuthCookies, B as BetterAuthOptions, b as BetterAuthPlugin, E as EligibleCookies, G as GenericEndpointContext, H as HookEndpointContext, m as InferPluginTypes, l as InferSession, I as InferUser, P as PluginSchema, R as RateLimit, S as SecondaryStorage, W as Where, g as betterAuth, r as createCookieGetter, w as createLogger, u as deleteSessionCookie, q as getCookies, n as init, x as logger, v as parseSetCookieHeader, t as setSessionCookie } from './auth-BGQTSAwN.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
package/dist/plugins.d.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
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-
|
|
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-DgJ3JDtV.js';
|
|
2
2
|
export { i as ac } from './index-DfAHOgpj.js';
|
|
3
|
-
import { H as HookEndpointContext } from './auth-
|
|
4
|
-
export {
|
|
3
|
+
import { H as HookEndpointContext, P as PluginSchema } from './auth-BGQTSAwN.js';
|
|
4
|
+
export { e as AuthEndpoint, f as AuthMiddleware, b as BetterAuthPlugin, d as createAuthEndpoint, c as createAuthMiddleware, o as optionsMiddleware } from './auth-BGQTSAwN.js';
|
|
5
5
|
export { H as HIDE_METADATA } from './hide-metadata-DEHJp1rk.js';
|
|
6
|
+
import { U as User } from './schema-Dkt0LqYs.js';
|
|
7
|
+
import * as better_call from 'better-call';
|
|
6
8
|
import 'zod';
|
|
7
|
-
import './schema-Dkt0LqYs.js';
|
|
8
|
-
import 'better-call';
|
|
9
9
|
import './helper-DPDj8Nix.js';
|
|
10
10
|
import './statement-CfnyN34h.js';
|
|
11
11
|
import '@better-fetch/fetch';
|
|
@@ -32,4 +32,151 @@ declare const bearer: () => {
|
|
|
32
32
|
};
|
|
33
33
|
};
|
|
34
34
|
|
|
35
|
-
|
|
35
|
+
type JWKOptions = {
|
|
36
|
+
alg: "EdDSA";
|
|
37
|
+
crv?: "Ed25519" | "Ed448";
|
|
38
|
+
} | {
|
|
39
|
+
alg: "ES256";
|
|
40
|
+
crv?: never;
|
|
41
|
+
} | {
|
|
42
|
+
alg: "RS256";
|
|
43
|
+
modulusLength?: number;
|
|
44
|
+
} | {
|
|
45
|
+
alg: "PS256";
|
|
46
|
+
modulusLength?: number;
|
|
47
|
+
} | {
|
|
48
|
+
alg: "ECDH-ES";
|
|
49
|
+
crv?: "P-256" | "P-384" | "P-521";
|
|
50
|
+
} | {
|
|
51
|
+
alg: "ES512";
|
|
52
|
+
crv?: never;
|
|
53
|
+
};
|
|
54
|
+
interface JwtOptions {
|
|
55
|
+
jwks?: {
|
|
56
|
+
/**
|
|
57
|
+
* Key pair configuration
|
|
58
|
+
* @description A subset of the options available for the generateKeyPair function
|
|
59
|
+
*
|
|
60
|
+
* @see https://github.com/panva/jose/blob/main/src/runtime/node/generate.ts
|
|
61
|
+
*
|
|
62
|
+
* @default { alg: 'EdDSA', crv: 'Ed25519' }
|
|
63
|
+
*/
|
|
64
|
+
keyPairConfig?: JWKOptions;
|
|
65
|
+
/**
|
|
66
|
+
* Disable private key encryption
|
|
67
|
+
* @description Disable the encryption of the private key in the database
|
|
68
|
+
*
|
|
69
|
+
* @default false
|
|
70
|
+
*/
|
|
71
|
+
disablePrivateKeyEncryption?: boolean;
|
|
72
|
+
};
|
|
73
|
+
jwt?: {
|
|
74
|
+
issuer?: string;
|
|
75
|
+
audience?: string;
|
|
76
|
+
/**
|
|
77
|
+
* Set the "exp" (Expiration Time) Claim.
|
|
78
|
+
*
|
|
79
|
+
* - If a `number` is passed as an argument it is used as the claim directly.
|
|
80
|
+
* - If a `Date` instance is passed as an argument it is converted to unix timestamp and used as the
|
|
81
|
+
* claim.
|
|
82
|
+
* - If a `string` is passed as an argument it is resolved to a time span, and then added to the
|
|
83
|
+
* current unix timestamp and used as the claim.
|
|
84
|
+
*
|
|
85
|
+
* Format used for time span should be a number followed by a unit, such as "5 minutes" or "1
|
|
86
|
+
* day".
|
|
87
|
+
*
|
|
88
|
+
* Valid units are: "sec", "secs", "second", "seconds", "s", "minute", "minutes", "min", "mins",
|
|
89
|
+
* "m", "hour", "hours", "hr", "hrs", "h", "day", "days", "d", "week", "weeks", "w", "year",
|
|
90
|
+
* "years", "yr", "yrs", and "y". It is not possible to specify months. 365.25 days is used as an
|
|
91
|
+
* alias for a year.
|
|
92
|
+
*
|
|
93
|
+
* If the string is suffixed with "ago", or prefixed with a "-", the resulting time span gets
|
|
94
|
+
* subtracted from the current unix timestamp. A "from now" suffix can also be used for
|
|
95
|
+
* readability when adding to the current unix timestamp.
|
|
96
|
+
*
|
|
97
|
+
* @default 15m
|
|
98
|
+
*/
|
|
99
|
+
expirationTime?: number | string | Date;
|
|
100
|
+
definePayload?: (user: User) => Promise<Record<string, any>> | Record<string, any>;
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
declare const jwt: (options?: JwtOptions) => {
|
|
104
|
+
id: "jwt";
|
|
105
|
+
endpoints: {
|
|
106
|
+
getJwks: {
|
|
107
|
+
<C extends [(better_call.Context<"/jwks", {
|
|
108
|
+
method: "GET";
|
|
109
|
+
}> | undefined)?]>(...ctx: C): Promise<C extends [{
|
|
110
|
+
asResponse: true;
|
|
111
|
+
}] ? Response : {
|
|
112
|
+
keys: any[];
|
|
113
|
+
}>;
|
|
114
|
+
path: "/jwks";
|
|
115
|
+
options: {
|
|
116
|
+
method: "GET";
|
|
117
|
+
};
|
|
118
|
+
method: better_call.Method | better_call.Method[];
|
|
119
|
+
headers: Headers;
|
|
120
|
+
};
|
|
121
|
+
getToken: {
|
|
122
|
+
<C extends [better_call.Context<"/token", {
|
|
123
|
+
method: "GET";
|
|
124
|
+
requireHeaders: true;
|
|
125
|
+
use: better_call.Endpoint<better_call.Handler<string, better_call.EndpointOptions, {
|
|
126
|
+
session: {
|
|
127
|
+
session: {
|
|
128
|
+
id: string;
|
|
129
|
+
userId: string;
|
|
130
|
+
expiresAt: Date;
|
|
131
|
+
ipAddress?: string | undefined;
|
|
132
|
+
userAgent?: string | undefined;
|
|
133
|
+
};
|
|
134
|
+
user: {
|
|
135
|
+
id: string;
|
|
136
|
+
email: string;
|
|
137
|
+
emailVerified: boolean;
|
|
138
|
+
name: string;
|
|
139
|
+
createdAt: Date;
|
|
140
|
+
updatedAt: Date;
|
|
141
|
+
image?: string | undefined;
|
|
142
|
+
};
|
|
143
|
+
};
|
|
144
|
+
}>, better_call.EndpointOptions>[];
|
|
145
|
+
}>]>(...ctx: C): Promise<C extends [{
|
|
146
|
+
asResponse: true;
|
|
147
|
+
}] ? Response : {
|
|
148
|
+
token: string;
|
|
149
|
+
}>;
|
|
150
|
+
path: "/token";
|
|
151
|
+
options: {
|
|
152
|
+
method: "GET";
|
|
153
|
+
requireHeaders: true;
|
|
154
|
+
use: better_call.Endpoint<better_call.Handler<string, better_call.EndpointOptions, {
|
|
155
|
+
session: {
|
|
156
|
+
session: {
|
|
157
|
+
id: string;
|
|
158
|
+
userId: string;
|
|
159
|
+
expiresAt: Date;
|
|
160
|
+
ipAddress?: string | undefined;
|
|
161
|
+
userAgent?: string | undefined;
|
|
162
|
+
};
|
|
163
|
+
user: {
|
|
164
|
+
id: string;
|
|
165
|
+
email: string;
|
|
166
|
+
emailVerified: boolean;
|
|
167
|
+
name: string;
|
|
168
|
+
createdAt: Date;
|
|
169
|
+
updatedAt: Date;
|
|
170
|
+
image?: string | undefined;
|
|
171
|
+
};
|
|
172
|
+
};
|
|
173
|
+
}>, better_call.EndpointOptions>[];
|
|
174
|
+
};
|
|
175
|
+
method: better_call.Method | better_call.Method[];
|
|
176
|
+
headers: Headers;
|
|
177
|
+
};
|
|
178
|
+
};
|
|
179
|
+
schema: PluginSchema;
|
|
180
|
+
};
|
|
181
|
+
|
|
182
|
+
export { type JwtOptions, PluginSchema, bearer, jwt };
|
package/dist/plugins.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
var
|
|
2
|
-
`)}}),A=gr();var z=C(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 i=new URL(t).origin;if(!n.includes(i))throw A.error("Invalid callback URL",{callbackURL:t,trustedOrigins:n}),new dt("FORBIDDEN",{message:"Invalid callback URL"})}if(o!==e.context.baseURL){let i=new URL(o).origin;if(!n.includes(i))throw A.error("Invalid current URL",{currentURL:o,trustedOrigins:n}),new dt("FORBIDDEN",{message:"Invalid callback URL"})}});import{parseJWT as br}from"oslo/jwt";import{sha256 as hr}from"oslo/crypto";function ct(e){return new URL(e).origin.replace("http://","").replace("https://","")}import{base64url as wr}from"oslo/encoding";async function ut(e){let t=await hr(new TextEncoder().encode(e));return wr.encode(new Uint8Array(t),{includePadding:!1})}function lt(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:i,disablePkce:a,redirectURI:s}){let d=new URL(r);if(d.searchParams.set("response_type","code"),d.searchParams.set("client_id",t.clientId),d.searchParams.set("state",o),d.searchParams.set("scope",i.join(" ")),d.searchParams.set("redirect_uri",t.redirectURI||s),!a&&n){let u=await ut(n);d.searchParams.set("code_challenge_method","S256"),d.searchParams.set("code_challenge",u)}return d}import{betterFetch as yr}from"@better-fetch/fetch";async function T({code:e,codeVerifier:t,redirectURI:r,options:o,tokenEndpoint:n}){let i=new URLSearchParams;i.set("grant_type","authorization_code"),i.set("code",e),t&&i.set("code_verifier",t),i.set("redirect_uri",r),i.set("client_id",o.clientId),i.set("client_secret",o.clientSecret);let{data:a,error:s}=await yr(n,{method:"POST",body:i,headers:{"content-type":"application/x-www-form-urlencoded",accept:"application/json","user-agent":"better-auth"}});if(s)throw s;return lt(a)}function we(e){let t=e.accessToken,r=e.refreshToken,o;try{o=e.accessTokenExpiresAt}catch{}return{accessToken:t,refreshToken:r,expiresAt:o}}var pt=e=>{let t="https://appleid.apple.com/auth/token";return{id:"apple",name:"Apple",createAuthorizationURL({state:r,scopes:o,redirectURI:n}){let i=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=${i.join(" ")}&state=${r}`)},validateAuthorizationCode:async({code:r,codeVerifier:o,redirectURI:n})=>T({code:r,codeVerifier:o,redirectURI:e.redirectURI||n,options:e,tokenEndpoint:t}),async getUserInfo(r){if(!r.idToken)return null;let o=br(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 Ar}from"@better-fetch/fetch";var mt=e=>({id:"discord",name:"Discord",createAuthorizationURL({state:t,scopes:r,redirectURI:o}){let n=e.scope||r||["identify","email"];return new URL(`https://discord.com/api/oauth2/authorize?scope=${n.join("+")}&response_type=code&client_id=${e.clientId}&redirect_uri=${encodeURIComponent(e.redirectURI||o)}&state=${t}`)},validateAuthorizationCode:async({code:t,redirectURI:r})=>T({code:t,redirectURI:e.redirectURI||r,options:e,tokenEndpoint:"https://discord.com/api/oauth2/token"}),async getUserInfo(t){let{data:r,error:o}=await Ar("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 Or}from"@better-fetch/fetch";var ft=e=>({id:"facebook",name:"Facebook",async createAuthorizationURL({state:t,scopes:r,codeVerifier:o,redirectURI:n}){let i=e.scope||r||["email","public_profile"];return await B({id:"facebook",options:e,authorizationEndpoint:"https://www.facebook.com/v16.0/dialog/oauth",scopes:i,state:t,redirectURI:n,codeVerifier:o})},validateAuthorizationCode:async({code:t,codeVerifier:r,redirectURI:o})=>T({code:t,codeVerifier:r,redirectURI:e.redirectURI||o,options:e,tokenEndpoint:"https://graph.facebook.com/v16.0/oauth/access_token"}),async getUserInfo(t){let{data:r,error:o}=await Or("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 gt}from"@better-fetch/fetch";var ht=e=>{let t="https://github.com/login/oauth/access_token";return{id:"github",name:"Github",createAuthorizationURL({state:r,scopes:o,codeVerifier:n,redirectURI:i}){let a=e.scope||o||["user:email"];return B({id:"github",options:e,authorizationEndpoint:"https://github.com/login/oauth/authorize",scopes:a,state:r,redirectURI:i,codeVerifier:n})},validateAuthorizationCode:async({code:r,redirectURI:o})=>T({code:r,redirectURI:e.redirectURI||o,options:e,tokenEndpoint:t}),async getUserInfo(r){let{data:o,error:n}=await gt("https://api.github.com/user",{auth:{type:"Bearer",token:r.accessToken}});if(n)return null;let i=!1;if(!o.email){let{data:a,error:s}=await gt("https://api.github.com/user/emails",{auth:{type:"Bearer",token:r.accessToken}});s||(o.email=(a.find(d=>d.primary)??a[0])?.email,i=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:i},data:o}}}};import{parseJWT as Rr}from"oslo/jwt";var wt=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 i=e.scope||r||["email","profile"];return B({id:"google",options:e,authorizationEndpoint:"https://accounts.google.com/o/oauth2/auth",scopes:i,state:t,codeVerifier:o,redirectURI:n})},validateAuthorizationCode:async({code:t,codeVerifier:r,redirectURI:o})=>T({code:t,codeVerifier:r,redirectURI:e.redirectURI||o,options:e,tokenEndpoint:"https://oauth2.googleapis.com/token"}),async getUserInfo(t){if(!t.idToken)return null;let r=Rr(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 Ir}from"@better-fetch/fetch";import{parseJWT as kr}from"oslo/jwt";var yt=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 i=e.scope||n.scopes||["openid","profile","email","User.Read"];return B({id:"microsoft",options:e,authorizationEndpoint:r,state:n.state,codeVerifier:n.codeVerifier,scopes:i,redirectURI:n.redirectURI})},validateAuthorizationCode({code:n,codeVerifier:i,redirectURI:a}){return T({code:n,codeVerifier:i,redirectURI:e.redirectURI||a,options:e,tokenEndpoint:o})},async getUserInfo(n){if(!n.idToken)return null;let i=kr(n.idToken)?.payload,a=e.profilePhotoSize||48;return await Ir(`https://graph.microsoft.com/v1.0/me/photos/${a}x${a}/$value`,{headers:{Authorization:`Bearer ${n.accessToken}`},async onResponse(s){if(!(e.disableProfilePhoto||!s.response.ok))try{let u=await s.response.clone().arrayBuffer(),l=Buffer.from(u).toString("base64");i.picture=`data:image/jpeg;base64, ${l}`}catch(d){A.error(d)}}}),{user:{id:i.sub,name:i.name,email:i.email,image:i.picture,emailVerified:!0},data:i}}}};import{betterFetch as Ur}from"@better-fetch/fetch";var bt=e=>({id:"spotify",name:"Spotify",createAuthorizationURL({state:t,scopes:r,codeVerifier:o,redirectURI:n}){let i=e.scope||r||["user-read-email"];return B({id:"spotify",options:e,authorizationEndpoint:"https://accounts.spotify.com/authorize",scopes:i,state:t,codeVerifier:o,redirectURI:n})},validateAuthorizationCode:async({code:t,codeVerifier:r,redirectURI:o})=>T({code:t,codeVerifier:r,redirectURI:e.redirectURI||o,options:e,tokenEndpoint:"https://accounts.spotify.com/api/token"}),async getUserInfo(t){let{data:r,error:o}=await Ur("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 Tr}from"@better-fetch/fetch";var At=e=>({id:"twitch",name:"Twitch",createAuthorizationURL({state:t,scopes:r,redirectURI:o}){let n=e.scope||r||["activity:write","read"];return B({id:"twitch",redirectURI:o,options:e,authorizationEndpoint:"https://id.twitch.tv/oauth2/authorize",scopes:n,state:t})},validateAuthorizationCode:async({code:t,redirectURI:r})=>T({code:t,redirectURI:e.redirectURI||r,options:e,tokenEndpoint:"https://id.twitch.tv/oauth2/token"}),async getUserInfo(t){let{data:r,error:o}=await Tr("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 vr}from"@better-fetch/fetch";var Ot=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,redirectURI:t.redirectURI})},validateAuthorizationCode:async({code:t,codeVerifier:r,redirectURI:o})=>T({code:t,codeVerifier:r,redirectURI:e.redirectURI||o,options:e,tokenEndpoint:"https://id.twitch.tv/oauth2/token"}),async getUserInfo(t){let{data:r,error:o}=await vr("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 Er={apple:pt,discord:mt,facebook:ft,github:ht,microsoft:yt,google:wt,spotify:bt,twitch:At,twitter:Ot},Rt=Object.keys(Er);var Pr=c("/sign-in/social",{method:"POST",requireHeaders:!0,query:Q.object({currentURL:Q.string().optional()}).optional(),body:Q.object({callbackURL:Q.string().optional(),provider:Q.enum(Rt)}),use:[z]},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 se("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||""}`,i=await Le(n||o?.origin||e.context.options.baseURL);await e.setSignedCookie(r.state.name,i.hash,e.context.secret,r.state.options);let a=Sr();await e.setSignedCookie(r.pkCodeVerifier.name,a,e.context.secret,r.pkCodeVerifier.options);let s=await t.createAuthorizationURL({state:i.raw,codeVerifier:a,redirectURI:`${e.context.baseURL}/callback/${t.id}`});return e.json({url:s.toString(),state:i,codeVerifier:a,redirect:!0})}),_r=c("/sign-in/email",{method:"POST",body:Q.object({email:Q.string().email(),password:Q.string(),callbackURL:Q.string().optional(),dontRememberMe:Q.boolean().default(!1).optional()}),use:[z]},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 se("BAD_REQUEST",{message:"Email and password is not enabled"});let{email:t,password:r}=e.body;if(!Q.string().email().safeParse(t).success)throw new se("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 se("UNAUTHORIZED",{message:"Invalid email or password"});let i=n.accounts.find(u=>u.providerId==="credential");if(!i)throw e.context.logger.error("Credential account not found",{email:t}),new se("UNAUTHORIZED",{message:"Invalid email or password"});let a=i?.password;if(!a)throw e.context.logger.error("Password not found",{email:t}),new se("UNAUTHORIZED",{message:"Unexpected error"});if(!await e.context.password.verify(a,r))throw e.context.logger.error("Invalid password"),new se("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 se("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 Dr}from"better-call";import{z as xe}from"zod";import{z as w}from"zod";var Si=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()}),De=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)}),Pi=w.object({id:w.string(),userId:w.string(),expiresAt:w.date(),ipAddress:w.string().optional(),userAgent:w.string().optional()}),_i=w.object({id:w.string(),value:w.string(),expiresAt:w.date(),identifier:w.string()});function Cr(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 It(e,t){let r={...e.user?.additionalFields};return Cr(t||{},{fields:r})}function zr(e){return e.toString(2).padStart(8,"0")}function Br(e){return[...e].map(t=>zr(t)).join("")}function kt(e){return parseInt(Br(e),2)}function Lr(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=kt(o);for(;n>=e;)crypto.getRandomValues(o),r!==0&&(o[0]&=(1<<r)-1),n=kt(o);return n}function F(e,t){let r="";for(let o=0;o<e;o++)r+=t[Lr(t.length)];return r}function M(...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 P=e=>F(e||21,M("a-z","0-9","A-Z"));var ae={isAction:!1};var xr=c("/callback/:id",{method:"GET",query:xe.object({state:xe.string(),code:xe.string().optional(),error:xe.string().optional()}),metadata:ae},async e=>{if(e.query.error||!e.query.code){let h=he(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=he(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,i=await e.getSignedCookie(e.context.authCookies.state.name,e.context.secret);if(!i)throw A.error("No stored state found"),e.redirect(`${e.context.baseURL}/error?error=please_restart_the_process`);if(!await ze(e.query.state,i))throw A.error("OAuth state mismatch"),e.redirect(`${e.context.baseURL}/error?error=please_restart_the_process`);let s=await e.getSignedCookie(e.context.authCookies.pkCodeVerifier.name,e.context.secret),d;try{d=await t.validateAuthorizationCode({code:e.query.code,codeVerifier:s,redirectURI:`${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(),p=De.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(I=>I.providerId===t.id),h=e.context.options.account?.accountLinking?.trustedProviders,R=h?h.includes(t.id):!0;if(!f&&(!u.emailVerified||!R)){let I;try{I=new URL(n||o),I.searchParams.set("error","account_not_linked")}catch{throw e.redirect(`${e.context.baseURL}/error?error=account_not_linked`)}throw e.redirect(I.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,...we(d)})}catch(I){throw console.log(I),e.redirect(`${e.context.baseURL}/error?error=failed_linking_account`)}}else try{await e.context.internalAdapter.createOAuthUser(p.data,{...we(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 Dr("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 R=new URL(n||o);throw R.searchParams.set("error","unable_to_create_session"),e.redirect(R.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 q=(e,t="ms")=>new Date(Date.now()+(t==="sec"?e*1e3:e));import{z as Ut}from"zod";var Tt=()=>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 Re(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,i=e.context.sessionConfig.updateAge;if(r.session.expiresAt.valueOf()-n*1e3+i*1e3<=Date.now()){let d=await e.context.internalAdapter.updateSession(r.session.id,{expiresAt:q(e.context.sessionConfig.expiresIn,"sec")});if(!d)return Re(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})}}),H=async e=>await Tt()({...e,_flag:"json",headers:e.headers}),b=C(async e=>{let t=await H(e);if(!t?.session)throw new Ie("UNAUTHORIZED");return{session:t}});var Nr=c("/user/revoke-session",{method:"POST",body:Ut.object({id:Ut.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})}),jr=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 Fr}from"better-call";var Mr=c("/sign-out",{method:"POST"},async e=>{let t=await e.getSignedCookie(e.context.authCookies.sessionToken.name,e.context.secret);if(!t)throw new Fr("BAD_REQUEST",{message:"Session not found"});return await e.context.internalAdapter.deleteSession(t),Re(e),e.json({success:!0})});import{z as te}from"zod";import{APIError as Ne}from"better-call";var qr=c("/forget-password",{method:"POST",body:te.object({email:te.string().email(),redirectTo:te.string()}),use:[z]},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 Ne("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=60*60*1,i=new Date(Date.now()+1e3*(e.context.options.emailAndPassword.resetPasswordTokenExpiresIn||n)),a=e.context.uuid();await e.context.internalAdapter.createVerificationValue({value:o.user.id,identifier:`reset-password:${a}`,expiresAt:i});let s=`${e.context.baseURL}/reset-password/${a}?callbackURL=${r}`;return await e.context.options.emailAndPassword.sendResetPassword(s,o.user),e.json({status:!0})}),$r=c("/reset-password/:token",{method:"GET",query:te.object({callbackURL:te.string()}),use:[z]},async e=>{let{token:t}=e.params,r=e.query.callbackURL,o=r.startsWith("http")?r:`${e.context.options.baseURL}${r}`;if(!t||!r)throw e.redirect(`${e.context.baseURL}/error?error=INVALID_TOKEN`);let n=await e.context.internalAdapter.findVerificationValue(`reset-password:${t}`);throw!n||n.expiresAt<new Date?e.redirect(`${o}?error=INVALID_TOKEN`):e.redirect(`${o}?token=${t}`)}),Vr=c("/reset-password",{query:te.object({token:te.string()}).optional(),method:"POST",body:te.object({newPassword:te.string()})},async e=>{let t=e.query?.token;if(!t)throw new Ne("BAD_REQUEST",{message:"Token not found"});let{newPassword:r}=e.body,o=`reset-password:${t}`,n=await e.context.internalAdapter.findVerificationValue(o);if(!n||n.expiresAt<new Date)throw new Ne("BAD_REQUEST",{message:"Invalid token"});await e.context.internalAdapter.deleteVerificationValue(n.id);let i=n.value,a=await e.context.password.hash(r);if(!(await e.context.internalAdapter.findAccounts(i)).find(l=>l.providerId==="credential"))return await e.context.internalAdapter.createAccount({userId:i,providerId:"credential",password:a,accountId:e.context.uuid()}),e.json({status:!0});if(!await e.context.internalAdapter.updatePassword(i,a))throw new Ne("BAD_REQUEST",{message:"Failed to update password"});return e.json({status:!0})});import{TimeSpan as Qr}from"oslo";import{createJWT as Hr,validateJWT as Wr}from"oslo/jwt";import{z as Z}from"zod";import{APIError as ke}from"better-call";async function Ze(e,t){return await Hr("HS256",Buffer.from(e),{email:t.toLowerCase()},{expiresIn:new Qr(1,"h"),issuer:"better-auth",subject:"verify-email",audiences:[t],includeIssuedTimestamp:!0})}var Gr=c("/send-verification-email",{method:"POST",query:Z.object({currentURL:Z.string().optional()}).optional(),body:Z.object({email:Z.string().email(),callbackURL:Z.string().optional()}),use:[z]},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 ke("BAD_REQUEST",{message:"Verification email isn't enabled"});let{email:t}=e.body,r=await e.context.internalAdapter.findUserByEmail(t);if(!r)throw new ke("BAD_REQUEST",{message:"User not found"});let o=await Ze(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})}),Zr=c("/verify-email",{method:"GET",query:Z.object({token:Z.string(),callbackURL:Z.string().optional()})},async e=>{let{token:t}=e.query,r;try{r=await Wr("HS256",Buffer.from(e.context.secret),t)}catch(s){throw e.context.logger.error("Failed to verify email",s),new ke("BAD_REQUEST",{message:"Invalid token"})}let n=Z.object({email:Z.string().email()}).parse(r.payload),i=await e.context.internalAdapter.findUserByEmail(n.email,{includeAccounts:!0});if(!i)throw new ke("BAD_REQUEST",{message:"User not found"});if(!i.accounts.find(s=>s.providerId==="credential"))throw new ke("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 W}from"zod";import{APIError as K}from"better-call";var Kr=c("/user/update",{method:"POST",body:W.object({name:W.string().optional(),image:W.string().optional()}),use:[b,z]},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})}),Jr=c("/user/change-password",{method:"POST",body:W.object({newPassword:W.string(),currentPassword:W.string(),revokeOtherSessions:W.boolean().optional()}),use:[b]},async e=>{let{newPassword:t,currentPassword:r,revokeOtherSessions:o}=e.body,n=e.context.session,i=e.context.password.config.minPasswordLength;if(t.length<i)throw e.context.logger.error("Password is too short"),new K("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 K("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 K("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 K("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 K("INTERNAL_SERVER_ERROR",{message:"Unable to create session"});await y(e,p.id)}return e.json(n.user)}),Yr=c("/user/set-password",{method:"POST",body:W.object({newPassword:W.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 K("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 K("BAD_REQUEST",{message:"Password too long"});let a=(await e.context.internalAdapter.findAccounts(r.user.id)).find(d=>d.providerId==="credential"&&d.password),s=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:s}),e.json(r.user);throw new K("BAD_REQUEST",{message:"user already has a password"})}),Xr=c("/user/delete",{method:"POST",body:W.object({password:W.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 K("BAD_REQUEST",{message:"User does not have a password"});if(!await e.context.password.verify(n.password,t))throw new K("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 vt}from"@noble/ciphers/chacha";import{bytesToHex as eo,hexToBytes as to,utf8ToBytes as ro}from"@noble/ciphers/utils";import{managedNonce as Et}from"@noble/ciphers/webcrypto";import{sha256 as St}from"oslo/crypto";import{decodeHex as zs,encodeHex as Bs}from"oslo/encoding";import{scryptAsync as xs}from"@noble/hashes/scrypt";async function G(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"]),i=await crypto.subtle.sign(o.name,n,r.encode(t));return btoa(String.fromCharCode(...new Uint8Array(i)))}var je=async({key:e,data:t})=>{let r=await St(new TextEncoder().encode(e)),o=ro(t),n=Et(vt)(new Uint8Array(r));return eo(n.encrypt(o))},Fe=async({key:e,data:t})=>{let r=await St(new TextEncoder().encode(e)),o=to(t),n=Et(vt)(new Uint8Array(r));return new TextDecoder().decode(n.decrypt(o))};var oo=c("/csrf",{method:"GET",metadata:ae},async e=>{let t=await e.getSignedCookie(e.context.authCookies.csrfToken.name,e.context.secret);if(t)return{csrfToken:t};let r=F(32,M("a-z","0-9","A-Z")),o=await G(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 no=(e="Unknown")=>`<!DOCTYPE html>
|
|
1
|
+
var hr=Object.defineProperty;var wr=(e,t)=>{for(var r in t)hr(e,r,{get:t[r],enumerable:!0})};import{APIError as Xt}from"better-call";import{z as Ee}from"zod";import{createEndpointCreator as yr,createMiddleware as st,createMiddlewareCreator as br}from"better-call";var at=st(async()=>({})),_=br({use:[at,st(async()=>({}))]}),c=yr({use:[at]});import{APIError as se}from"better-call";import{generateCodeVerifier as Dr}from"oslo/oauth2";import{z as Q}from"zod";import{generateState as Ar}from"oslo/oauth2";import{z as Le}from"zod";import{sha256 as dt}from"oslo/crypto";function Ge(e,t){let r=new Uint8Array(e),o=new Uint8Array(t);if(r.length!==o.length)return!1;let n=0;for(let i=0;i<r.length;i++)n|=r[i]^o[i];return n===0}async function ct(e){let t=await dt(typeof e=="string"?new TextEncoder().encode(e):e);return Buffer.from(t).toString("base64")}async function Be(e,t){let r=await dt(typeof e=="string"?new TextEncoder().encode(e):e),o=Buffer.from(t,"base64");return Ge(r,o)}async function De(e){let t=Ar(),r=JSON.stringify({code:t,callbackURL:e}),o=await ct(r);return{raw:r,hash:o}}function he(e){return Le.object({code:Le.string(),callbackURL:Le.string().optional(),currentURL:Le.string().optional()}).safeParse(JSON.parse(e))}import{TimeSpan as dn}from"oslo";var $=class extends Error{constructor(t,r){super(t),this.name="BetterAuthError",this.message=t,this.cause=r,this.stack=""}};async function b(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 Oe(e){e.setCookie(e.context.authCookies.sessionToken.name,"",{maxAge:0}),e.setCookie(e.context.authCookies.dontRememberToken.name,"",{maxAge:0})}import{APIError as ut}from"better-call";import{createConsola as kr}from"consola";var ce=kr({formatOptions:{date:!1,colors:!0,compact:!0},defaults:{tag:"Better Auth"}}),Or=e=>({log:(...t)=>{!e?.disabled&&ce.log("",...t)},error:(...t)=>{!e?.disabled&&ce.error("",...t)},warn:(...t)=>{!e?.disabled&&ce.warn("",...t)},info:(...t)=>{!e?.disabled&&ce.info("",...t)},debug:(...t)=>{!e?.disabled&&ce.debug("",...t)},box:(...t)=>{!e?.disabled&&ce.box("",...t)},success:(...t)=>{!e?.disabled&&ce.success("",...t)},break:(...t)=>{!e?.disabled&&console.log(`
|
|
2
|
+
`)}}),A=Or();var 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 i=new URL(t).origin;if(!n.includes(i))throw A.error("Invalid callback URL",{callbackURL:t,trustedOrigins:n}),new ut("FORBIDDEN",{message:"Invalid callback URL"})}if(o!==e.context.baseURL){let i=new URL(o).origin;if(!n.includes(i))throw A.error("Invalid current URL",{currentURL:o,trustedOrigins:n}),new ut("FORBIDDEN",{message:"Invalid callback URL"})}});import{parseJWT as Ur}from"oslo/jwt";import{sha256 as Rr}from"oslo/crypto";function lt(e){return new URL(e).origin.replace("http://","").replace("https://","")}import{base64url as Ir}from"oslo/encoding";async function pt(e){let t=await Rr(new TextEncoder().encode(e));return Ir.encode(new Uint8Array(t),{includePadding:!1})}function mt(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:i,disablePkce:a,redirectURI:s}){let d=new URL(r);if(d.searchParams.set("response_type","code"),d.searchParams.set("client_id",t.clientId),d.searchParams.set("state",o),d.searchParams.set("scope",i.join(" ")),d.searchParams.set("redirect_uri",t.redirectURI||s),!a&&n){let u=await pt(n);d.searchParams.set("code_challenge_method","S256"),d.searchParams.set("code_challenge",u)}return d}import{betterFetch as vr}from"@better-fetch/fetch";async function U({code:e,codeVerifier:t,redirectURI:r,options:o,tokenEndpoint:n}){let i=new URLSearchParams;i.set("grant_type","authorization_code"),i.set("code",e),t&&i.set("code_verifier",t),i.set("redirect_uri",r),i.set("client_id",o.clientId),i.set("client_secret",o.clientSecret);let{data:a,error:s}=await vr(n,{method:"POST",body:i,headers:{"content-type":"application/x-www-form-urlencoded",accept:"application/json","user-agent":"better-auth"}});if(s)throw s;return mt(a)}function we(e){let t=e.accessToken,r=e.refreshToken,o;try{o=e.accessTokenExpiresAt}catch{}return{accessToken:t,refreshToken:r,expiresAt:o}}var ft=e=>{let t="https://appleid.apple.com/auth/token";return{id:"apple",name:"Apple",createAuthorizationURL({state:r,scopes:o,redirectURI:n}){let i=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=${i.join(" ")}&state=${r}`)},validateAuthorizationCode:async({code:r,codeVerifier:o,redirectURI:n})=>U({code:r,codeVerifier:o,redirectURI:e.redirectURI||n,options:e,tokenEndpoint:t}),async getUserInfo(r){if(!r.idToken)return null;let o=Ur(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 Tr}from"@better-fetch/fetch";var gt=e=>({id:"discord",name:"Discord",createAuthorizationURL({state:t,scopes:r,redirectURI:o}){let n=e.scope||r||["identify","email"];return new URL(`https://discord.com/api/oauth2/authorize?scope=${n.join("+")}&response_type=code&client_id=${e.clientId}&redirect_uri=${encodeURIComponent(e.redirectURI||o)}&state=${t}`)},validateAuthorizationCode:async({code:t,redirectURI:r})=>U({code:t,redirectURI:e.redirectURI||r,options:e,tokenEndpoint:"https://discord.com/api/oauth2/token"}),async getUserInfo(t){let{data:r,error:o}=await Tr("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 Er}from"@better-fetch/fetch";var ht=e=>({id:"facebook",name:"Facebook",async createAuthorizationURL({state:t,scopes:r,codeVerifier:o,redirectURI:n}){let i=e.scope||r||["email","public_profile"];return await B({id:"facebook",options:e,authorizationEndpoint:"https://www.facebook.com/v16.0/dialog/oauth",scopes:i,state:t,redirectURI:n,codeVerifier:o})},validateAuthorizationCode:async({code:t,codeVerifier:r,redirectURI:o})=>U({code:t,codeVerifier:r,redirectURI:e.redirectURI||o,options:e,tokenEndpoint:"https://graph.facebook.com/v16.0/oauth/access_token"}),async getUserInfo(t){let{data:r,error:o}=await Er("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 wt}from"@better-fetch/fetch";var yt=e=>{let t="https://github.com/login/oauth/access_token";return{id:"github",name:"Github",createAuthorizationURL({state:r,scopes:o,codeVerifier:n,redirectURI:i}){let a=e.scope||o||["user:email"];return B({id:"github",options:e,authorizationEndpoint:"https://github.com/login/oauth/authorize",scopes:a,state:r,redirectURI:i,codeVerifier:n})},validateAuthorizationCode:async({code:r,redirectURI:o})=>U({code:r,redirectURI:e.redirectURI||o,options:e,tokenEndpoint:t}),async getUserInfo(r){let{data:o,error:n}=await wt("https://api.github.com/user",{auth:{type:"Bearer",token:r.accessToken}});if(n)return null;let i=!1;if(!o.email){let{data:a,error:s}=await wt("https://api.github.com/user/emails",{auth:{type:"Bearer",token:r.accessToken}});s||(o.email=(a.find(d=>d.primary)??a[0])?.email,i=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:i},data:o}}}};import{parseJWT as Sr}from"oslo/jwt";var bt=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 i=e.scope||r||["email","profile"];return B({id:"google",options:e,authorizationEndpoint:"https://accounts.google.com/o/oauth2/auth",scopes:i,state:t,codeVerifier:o,redirectURI:n})},validateAuthorizationCode:async({code:t,codeVerifier:r,redirectURI:o})=>U({code:t,codeVerifier:r,redirectURI:e.redirectURI||o,options:e,tokenEndpoint:"https://oauth2.googleapis.com/token"}),async getUserInfo(t){if(!t.idToken)return null;let r=Sr(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 Pr}from"@better-fetch/fetch";import{parseJWT as Cr}from"oslo/jwt";var At=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 i=e.scope||n.scopes||["openid","profile","email","User.Read"];return B({id:"microsoft",options:e,authorizationEndpoint:r,state:n.state,codeVerifier:n.codeVerifier,scopes:i,redirectURI:n.redirectURI})},validateAuthorizationCode({code:n,codeVerifier:i,redirectURI:a}){return U({code:n,codeVerifier:i,redirectURI:e.redirectURI||a,options:e,tokenEndpoint:o})},async getUserInfo(n){if(!n.idToken)return null;let i=Cr(n.idToken)?.payload,a=e.profilePhotoSize||48;return await Pr(`https://graph.microsoft.com/v1.0/me/photos/${a}x${a}/$value`,{headers:{Authorization:`Bearer ${n.accessToken}`},async onResponse(s){if(!(e.disableProfilePhoto||!s.response.ok))try{let u=await s.response.clone().arrayBuffer(),l=Buffer.from(u).toString("base64");i.picture=`data:image/jpeg;base64, ${l}`}catch(d){A.error(d)}}}),{user:{id:i.sub,name:i.name,email:i.email,image:i.picture,emailVerified:!0},data:i}}}};import{betterFetch as _r}from"@better-fetch/fetch";var kt=e=>({id:"spotify",name:"Spotify",createAuthorizationURL({state:t,scopes:r,codeVerifier:o,redirectURI:n}){let i=e.scope||r||["user-read-email"];return B({id:"spotify",options:e,authorizationEndpoint:"https://accounts.spotify.com/authorize",scopes:i,state:t,codeVerifier:o,redirectURI:n})},validateAuthorizationCode:async({code:t,codeVerifier:r,redirectURI:o})=>U({code:t,codeVerifier:r,redirectURI:e.redirectURI||o,options:e,tokenEndpoint:"https://accounts.spotify.com/api/token"}),async getUserInfo(t){let{data:r,error:o}=await _r("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 zr}from"@better-fetch/fetch";var Ot=e=>({id:"twitch",name:"Twitch",createAuthorizationURL({state:t,scopes:r,redirectURI:o}){let n=e.scope||r||["activity:write","read"];return B({id:"twitch",redirectURI:o,options:e,authorizationEndpoint:"https://id.twitch.tv/oauth2/authorize",scopes:n,state:t})},validateAuthorizationCode:async({code:t,redirectURI:r})=>U({code:t,redirectURI:e.redirectURI||r,options:e,tokenEndpoint:"https://id.twitch.tv/oauth2/token"}),async getUserInfo(t){let{data:r,error:o}=await zr("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 Br}from"@better-fetch/fetch";var Rt=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,redirectURI:t.redirectURI})},validateAuthorizationCode:async({code:t,codeVerifier:r,redirectURI:o})=>U({code:t,codeVerifier:r,redirectURI:e.redirectURI||o,options:e,tokenEndpoint:"https://id.twitch.tv/oauth2/token"}),async getUserInfo(t){let{data:r,error:o}=await Br("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 Lr={apple:ft,discord:gt,facebook:ht,github:yt,microsoft:At,google:bt,spotify:kt,twitch:Ot,twitter:Rt},It=Object.keys(Lr);var xr=c("/sign-in/social",{method:"POST",requireHeaders:!0,query:Q.object({currentURL:Q.string().optional()}).optional(),body:Q.object({callbackURL:Q.string().optional(),provider:Q.enum(It)}),use:[z]},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 se("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||""}`,i=await De(n||o?.origin||e.context.options.baseURL);await e.setSignedCookie(r.state.name,i.hash,e.context.secret,r.state.options);let a=Dr();await e.setSignedCookie(r.pkCodeVerifier.name,a,e.context.secret,r.pkCodeVerifier.options);let s=await t.createAuthorizationURL({state:i.raw,codeVerifier:a,redirectURI:`${e.context.baseURL}/callback/${t.id}`});return e.json({url:s.toString(),state:i,codeVerifier:a,redirect:!0})}),jr=c("/sign-in/email",{method:"POST",body:Q.object({email:Q.string().email(),password:Q.string(),callbackURL:Q.string().optional(),dontRememberMe:Q.boolean().default(!1).optional()}),use:[z]},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 se("BAD_REQUEST",{message:"Email and password is not enabled"});let{email:t,password:r}=e.body;if(!Q.string().email().safeParse(t).success)throw new se("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 se("UNAUTHORIZED",{message:"Invalid email or password"});let i=n.accounts.find(u=>u.providerId==="credential");if(!i)throw e.context.logger.error("Credential account not found",{email:t}),new se("UNAUTHORIZED",{message:"Invalid email or password"});let a=i?.password;if(!a)throw e.context.logger.error("Password not found",{email:t}),new se("UNAUTHORIZED",{message:"Unexpected error"});if(!await e.context.password.verify(a,r))throw e.context.logger.error("Invalid password"),new se("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 se("UNAUTHORIZED",{message:"Failed to create session"});return await b(e,d.id,e.body.dontRememberMe),e.json({user:n.user,session:d,redirect:!!e.body.callbackURL,url:e.body.callbackURL})});import{APIError as $r}from"better-call";import{z as je}from"zod";import{z as w}from"zod";var $i=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()}),xe=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)}),Vi=w.object({id:w.string(),userId:w.string(),expiresAt:w.date(),ipAddress:w.string().optional(),userAgent:w.string().optional()}),Qi=w.object({id:w.string(),value:w.string(),expiresAt:w.date(),identifier:w.string()});function Nr(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 vt(e,t){let r={...e.user?.additionalFields};return Nr(t||{},{fields:r})}function Fr(e){return e.toString(2).padStart(8,"0")}function Mr(e){return[...e].map(t=>Fr(t)).join("")}function Ut(e){return parseInt(Mr(e),2)}function qr(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=Ut(o);for(;n>=e;)crypto.getRandomValues(o),r!==0&&(o[0]&=(1<<r)-1),n=Ut(o);return n}function F(e,t){let r="";for(let o=0;o<e;o++)r+=t[qr(t.length)];return r}function M(...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 P=e=>F(e||21,M("a-z","0-9","A-Z"));var ae={isAction:!1};var Vr=c("/callback/:id",{method:"GET",query:je.object({state:je.string(),code:je.string().optional(),error:je.string().optional()}),metadata:ae},async e=>{if(e.query.error||!e.query.code){let h=he(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=he(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,i=await e.getSignedCookie(e.context.authCookies.state.name,e.context.secret);if(!i)throw A.error("No stored state found"),e.redirect(`${e.context.baseURL}/error?error=please_restart_the_process`);if(!await Be(e.query.state,i))throw A.error("OAuth state mismatch"),e.redirect(`${e.context.baseURL}/error?error=please_restart_the_process`);let s=await e.getSignedCookie(e.context.authCookies.pkCodeVerifier.name,e.context.secret),d;try{d=await t.validateAuthorizationCode({code:e.query.code,codeVerifier:s,redirectURI:`${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(),p=xe.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 O=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=O?.user.id;if(O){let f=O.accounts.find(I=>I.providerId===t.id),h=e.context.options.account?.accountLinking?.trustedProviders,R=h?h.includes(t.id):!0;if(!f&&(!u.emailVerified||!R)){let I;try{I=new URL(n||o),I.searchParams.set("error","account_not_linked")}catch{throw e.redirect(`${e.context.baseURL}/error?error=account_not_linked`)}throw e.redirect(I.toString())}if(!f)try{await e.context.internalAdapter.linkAccount({providerId:t.id,accountId:u.id.toString(),id:`${t.id}:${u.id}`,userId:O.user.id,...we(d)})}catch(I){throw console.log(I),e.redirect(`${e.context.baseURL}/error?error=failed_linking_account`)}}else try{await e.context.internalAdapter.createOAuthUser(p.data,{...we(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 $r("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 b(e,f.id)}catch(h){e.context.logger.error("Unable to set session cookie",h);let R=new URL(n||o);throw R.searchParams.set("error","unable_to_create_session"),e.redirect(R.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 Re}from"better-call";var q=(e,t="ms")=>new Date(Date.now()+(t==="sec"?e*1e3:e));import{z as Tt}from"zod";var Et=()=>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 Oe(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,i=e.context.sessionConfig.updateAge;if(r.session.expiresAt.valueOf()-n*1e3+i*1e3<=Date.now()){let d=await e.context.internalAdapter.updateSession(r.session.id,{expiresAt:q(e.context.sessionConfig.expiresIn,"sec")});if(!d)return Oe(e),e.json(null,{status:401});let u=(d.expiresAt.valueOf()-Date.now())/1e3;return await b(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})}}),H=async e=>await Et()({...e,_flag:"json",headers:e.headers}),y=_(async e=>{let t=await H(e);if(!t?.session)throw new Re("UNAUTHORIZED");return{session:t}});var Qr=c("/user/revoke-session",{method:"POST",body:Tt.object({id:Tt.string()}),use:[y],requireHeaders:!0},async e=>{let t=e.body.id,r=await e.context.internalAdapter.findSession(t);if(!r)throw new Re("BAD_REQUEST",{message:"Session not found"});if(r.session.userId!==e.context.session.user.id)throw new Re("UNAUTHORIZED");try{await e.context.internalAdapter.deleteSession(t)}catch(o){throw e.context.logger.error(o),new Re("INTERNAL_SERVER_ERROR")}return e.json({status:!0})}),Hr=c("/user/revoke-sessions",{method:"POST",use:[y],requireHeaders:!0},async e=>{try{await e.context.internalAdapter.deleteSessions(e.context.session.user.id)}catch(t){throw e.context.logger.error(t),new Re("INTERNAL_SERVER_ERROR")}return e.json({status:!0})});import"zod";import{APIError as Wr}from"better-call";var Kr=c("/sign-out",{method:"POST"},async e=>{let t=await e.getSignedCookie(e.context.authCookies.sessionToken.name,e.context.secret);if(!t)throw new Wr("BAD_REQUEST",{message:"Session not found"});return await e.context.internalAdapter.deleteSession(t),Oe(e),e.json({success:!0})});import{z as te}from"zod";import{APIError as Ne}from"better-call";var Gr=c("/forget-password",{method:"POST",body:te.object({email:te.string().email(),redirectTo:te.string()}),use:[z]},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 Ne("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=60*60*1,i=new Date(Date.now()+1e3*(e.context.options.emailAndPassword.resetPasswordTokenExpiresIn||n)),a=e.context.uuid();await e.context.internalAdapter.createVerificationValue({value:o.user.id,identifier:`reset-password:${a}`,expiresAt:i});let s=`${e.context.baseURL}/reset-password/${a}?callbackURL=${r}`;return await e.context.options.emailAndPassword.sendResetPassword(s,o.user),e.json({status:!0})}),Jr=c("/reset-password/:token",{method:"GET",query:te.object({callbackURL:te.string()}),use:[z]},async e=>{let{token:t}=e.params,r=e.query.callbackURL,o=r.startsWith("http")?r:`${e.context.options.baseURL}${r}`;if(!t||!r)throw e.redirect(`${e.context.baseURL}/error?error=INVALID_TOKEN`);let n=await e.context.internalAdapter.findVerificationValue(`reset-password:${t}`);throw!n||n.expiresAt<new Date?e.redirect(`${o}?error=INVALID_TOKEN`):e.redirect(`${o}?token=${t}`)}),Zr=c("/reset-password",{query:te.object({token:te.string()}).optional(),method:"POST",body:te.object({newPassword:te.string()})},async e=>{let t=e.query?.token;if(!t)throw new Ne("BAD_REQUEST",{message:"Token not found"});let{newPassword:r}=e.body,o=`reset-password:${t}`,n=await e.context.internalAdapter.findVerificationValue(o);if(!n||n.expiresAt<new Date)throw new Ne("BAD_REQUEST",{message:"Invalid token"});await e.context.internalAdapter.deleteVerificationValue(n.id);let i=n.value,a=await e.context.password.hash(r);if(!(await e.context.internalAdapter.findAccounts(i)).find(l=>l.providerId==="credential"))return await e.context.internalAdapter.createAccount({userId:i,providerId:"credential",password:a,accountId:e.context.uuid()}),e.json({status:!0});if(!await e.context.internalAdapter.updatePassword(i,a))throw new Ne("BAD_REQUEST",{message:"Failed to update password"});return e.json({status:!0})});import{TimeSpan as Yr}from"oslo";import{createJWT as Xr,validateJWT as eo}from"oslo/jwt";import{z as G}from"zod";import{APIError as Ie}from"better-call";async function Je(e,t){return await Xr("HS256",Buffer.from(e),{email:t.toLowerCase()},{expiresIn:new Yr(1,"h"),issuer:"better-auth",subject:"verify-email",audiences:[t],includeIssuedTimestamp:!0})}var to=c("/send-verification-email",{method:"POST",query:G.object({currentURL:G.string().optional()}).optional(),body:G.object({email:G.string().email(),callbackURL:G.string().optional()}),use:[z]},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 Ie("BAD_REQUEST",{message:"Verification email isn't enabled"});let{email:t}=e.body,r=await e.context.internalAdapter.findUserByEmail(t);if(!r)throw new Ie("BAD_REQUEST",{message:"User not found"});let o=await Je(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})}),ro=c("/verify-email",{method:"GET",query:G.object({token:G.string(),callbackURL:G.string().optional()})},async e=>{let{token:t}=e.query,r;try{r=await eo("HS256",Buffer.from(e.context.secret),t)}catch(s){throw e.context.logger.error("Failed to verify email",s),new Ie("BAD_REQUEST",{message:"Invalid token"})}let n=G.object({email:G.string().email()}).parse(r.payload),i=await e.context.internalAdapter.findUserByEmail(n.email,{includeAccounts:!0});if(!i)throw new Ie("BAD_REQUEST",{message:"User not found"});if(!i.accounts.find(s=>s.providerId==="credential"))throw new Ie("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 W}from"zod";import{APIError as J}from"better-call";var oo=c("/user/update",{method:"POST",body:W.object({name:W.string().optional(),image:W.string().optional()}),use:[y,z]},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})}),no=c("/user/change-password",{method:"POST",body:W.object({newPassword:W.string(),currentPassword:W.string(),revokeOtherSessions:W.boolean().optional()}),use:[y]},async e=>{let{newPassword:t,currentPassword:r,revokeOtherSessions:o}=e.body,n=e.context.session,i=e.context.password.config.minPasswordLength;if(t.length<i)throw e.context.logger.error("Password is too short"),new J("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 J("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 J("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 J("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 J("INTERNAL_SERVER_ERROR",{message:"Unable to create session"});await b(e,p.id)}return e.json(n.user)}),io=c("/user/set-password",{method:"POST",body:W.object({newPassword:W.string()}),use:[y]},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 J("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 J("BAD_REQUEST",{message:"Password too long"});let a=(await e.context.internalAdapter.findAccounts(r.user.id)).find(d=>d.providerId==="credential"&&d.password),s=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:s}),e.json(r.user);throw new J("BAD_REQUEST",{message:"user already has a password"})}),so=c("/user/delete",{method:"POST",body:W.object({password:W.string()}),use:[y]},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 J("BAD_REQUEST",{message:"User does not have a password"});if(!await e.context.password.verify(n.password,t))throw new J("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 St}from"@noble/ciphers/chacha";import{bytesToHex as ao,hexToBytes as co,utf8ToBytes as uo}from"@noble/ciphers/utils";import{managedNonce as Pt}from"@noble/ciphers/webcrypto";import{sha256 as Ct}from"oslo/crypto";import{decodeHex as Ws,encodeHex as Ks}from"oslo/encoding";import{scryptAsync as Zs}from"@noble/hashes/scrypt";async function K(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"]),i=await crypto.subtle.sign(o.name,n,r.encode(t));return btoa(String.fromCharCode(...new Uint8Array(i)))}var Fe=async({key:e,data:t})=>{let r=await Ct(new TextEncoder().encode(e)),o=uo(t),n=Pt(St)(new Uint8Array(r));return ao(n.encrypt(o))},Me=async({key:e,data:t})=>{let r=await Ct(new TextEncoder().encode(e)),o=co(t),n=Pt(St)(new Uint8Array(r));return new TextDecoder().decode(n.decrypt(o))};var lo=c("/csrf",{method:"GET",metadata:ae},async e=>{let t=await e.getSignedCookie(e.context.authCookies.csrfToken.name,e.context.secret);if(t)return{csrfToken:t};let r=F(32,M("a-z","0-9","A-Z")),o=await K(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 po=(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>`,io=c("/error",{method:"GET",metadata:ae},async e=>{let t=new URL(e.request?.url||"").searchParams.get("error")||"Unknown";return new Response(no(t),{headers:{"Content-Type":"text/html"}})});var so=c("/ok",{method:"GET",metadata:ae},async e=>e.json({ok:!0}));import{z as ye}from"zod";import{APIError as ue}from"better-call";var Ue=()=>c("/sign-up/email",{method:"POST",query:ye.object({currentURL:ye.string().optional()}).optional(),body:ye.record(ye.string(),ye.any()),use:[z]},async e=>{if(!e.context.options.emailAndPassword?.enabled)throw new ue("BAD_REQUEST",{message:"Email and password sign up is not enabled"});let t=e.body,{name:r,email:o,password:n,image:i,callbackURL:a,...s}=t;if(!ye.string().email().safeParse(o).success)throw new ue("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 ue("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 ue("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 ue("UNPROCESSABLE_ENTITY",{message:"The email has already been taken"});let U=It(e.context.options,s),m=await e.context.internalAdapter.createUser({email:o.toLowerCase(),name:r,image:i,...U,emailVerified:!1});if(!m)throw new ue("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 ue("BAD_REQUEST",{message:"Failed to create session"});if(await y(e,h.id),e.context.options.emailAndPassword.sendEmailVerificationOnSignUp){let R=await Ze(e.context.secret,m.email),I=`${e.context.baseURL}/verify-email?token=${R}&callbackURL=${t.callbackURL||e.query?.currentURL||"/"}`;await e.context.options.emailAndPassword.sendVerificationEmail?.(I,m,R)}return e.json({user:m,session:h},{body:t.callbackURL?{url:t.callbackURL,redirect:!0}:{user:m,session:h}})});var Pt=(e,t)=>{let r={};for(let[o,n]of Object.entries(e))r[o]=i=>n({...i,context:{...t,...i.context}}),r[o].path=n.path,r[o].method=n.method,r[o].options=n.options,r[o].headers=n.headers;return r};var Dt={};ur(Dt,{AccessControl:()=>Te,ParsingError:()=>le,Role:()=>be,adminAc:()=>zt,createAccessControl:()=>_t,defaultAc:()=>Me,defaultRoles:()=>Ke,defaultStatements:()=>Ct,memberAc:()=>Lt,ownerAc:()=>Bt,permissionFromString:()=>ao});var le=class extends Error{path;constructor(t,r){super(t),this.path=r}},Te=class{constructor(t){this.s=t;this.statements=t}statements;newRole(t){return new be(t)}},be=class e{statements;constructor(t){this.statements=t}authorize(t,r){for(let[o,n]of Object.entries(t)){let i=this.statements[o];if(!i)return{success:!1,error:`You are not allowed to access resource: ${o}`};let a=r==="OR"?n.some(s=>i.includes(s)):n.every(s=>i.includes(s));return a?{success:a}:{success:!1,error:`unauthorized to access resource "${o}"`}}return{success:!1,error:"Not authorized"}}static fromString(t){let r=JSON.parse(t);if(typeof r!="object")throw new le("statements is not an object",".");for(let[o,n]of Object.entries(r)){if(typeof o!="string")throw new le("invalid resource identifier",o);if(!Array.isArray(n))throw new le("actions is not an array",o);for(let i=0;i<n.length;i++)if(typeof n[i]!="string")throw new le("action is not a string",`${o}[${i}]`)}return new e(r)}toString(){return JSON.stringify(this.statements)}};var _t=e=>new Te(e),Ct={organization:["update","delete"],member:["create","update","delete"],invitation:["create","cancel"]},Me=_t(Ct),zt=Me.newRole({organization:["update"],invitation:["create","cancel"],member:["create","update","delete"]}),Bt=Me.newRole({organization:["update","delete"],member:["create","update","delete"],invitation:["create","cancel"]}),Lt=Me.newRole({organization:[],member:[],invitation:[]}),Ke={admin:zt,owner:Bt,member:Lt};var ao=e=>be.fromString(e??"");var E=(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:P(),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 i=await e.findMany({model:"invitation",where:[{field:"organizationId",value:r}]}),a=await e.findMany({model:"member",where:[{field:"organizationId",value:r}]}),s=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:i,members:s}},listOrganizations:async r=>{let n=(await e.findMany({model:"member",where:[{field:"userId",value:r}]}))?.map(a=>a.organizationId);if(!n)return[];let i=[];for(let a of n){let s=await e.findOne({model:"organization",where:[{field:"id",value:a}]});s&&i.push(s)}return i},createInvitation:async({invitation:r,user:o})=>{let i=q(t?.invitationExpiresIn||1728e5);return await e.create({model:"invitation",data:{id:P(),email:r.email,role:r.role,organizationId:r.organizationId,status:"pending",expiresAt:i,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 ad,createRouter as dd}from"better-call";import{APIError as Je}from"better-call";import{z as xt}from"zod";var co=C({body:xt.object({csrfToken:xt.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 Je("UNAUTHORIZED",{message:"CSRF Token is required"});let o=await e.getSignedCookie(e.context.authCookies.csrfToken.name,e.context.secret),[n,i]=o?.split("!")||[null,null];if(!r||!o||!n||!i||o!==r)throw e.setCookie(e.context.authCookies.csrfToken.name,"",{maxAge:0}),new Je("UNAUTHORIZED",{message:"Invalid CSRF Token"});let a=await G(e.context.secret,n);if(i!==a)throw e.setCookie(e.context.authCookies.csrfToken.name,"",{maxAge:0}),new Je("UNAUTHORIZED",{message:"Invalid CSRF Token"})});import{APIError as de}from"better-call";var L=C(async e=>({})),N=C({use:[b]},async e=>({session:e.context.session}));import{z as V}from"zod";import{z as k}from"zod";var qe=k.enum(["admin","member","owner"]),uo=k.enum(["pending","accepted","rejected","canceled"]).default("pending"),_d=k.object({id:k.string(),name:k.string(),slug:k.string(),logo:k.string().optional(),metadata:k.record(k.string()).or(k.string().transform(e=>JSON.parse(e))).optional(),createdAt:k.date()}),Cd=k.object({id:k.string(),email:k.string(),organizationId:k.string(),userId:k.string(),role:qe,createdAt:k.date()}),zd=k.object({id:k.string(),organizationId:k.string(),email:k.string(),role:qe,status:uo,inviterId:k.string(),expiresAt:k.date()});import{APIError as v}from"better-call";var Nt=c("/organization/invite-member",{method:"POST",use:[L,N],body:V.object({email:V.string(),role:qe,organizationId:V.string().optional(),resend:V.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 v("BAD_REQUEST",{message:"Invitation email is not enabled"});let t=e.context.session,r=e.body.organizationId||t.session.activeOrganizationId;if(!r)throw new v("BAD_REQUEST",{message:"Organization not found"});let o=E(e.context.adapter,e.context.orgOptions),n=await o.findMemberByOrgId({userId:t.user.id,organizationId:r});if(!n)throw new v("BAD_REQUEST",{message:"Member not found!"});let i=e.context.roles[n.role];if(!i)throw new v("BAD_REQUEST",{message:"Role not found!"});if(i.authorize({invitation:["create"]}).error)throw new v("FORBIDDEN",{message:"You are not allowed to invite members"});if(await o.findMemberByEmail({email:e.body.email,organizationId:r}))throw new v("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 v("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 v("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)}),jt=c("/organization/accept-invitation",{method:"POST",body:V.object({invitationId:V.string()}),use:[L,N]},async e=>{let t=e.context.session,r=E(e.context.adapter,e.context.orgOptions),o=await r.findInvitationById(e.body.invitationId);if(!o||o.expiresAt<new Date||o.status!=="pending")throw new v("BAD_REQUEST",{message:"Invitation not found!"});if(o.email!==t.user.email)throw new v("FORBIDDEN",{message:"You are not the recipient of the invitation"});let n=await r.updateInvitation({invitationId:e.body.invitationId,status:"accepted"}),i=await r.createMember({id:P(),organizationId:o.organizationId,userId:t.user.id,email:o.email,role:o.role,createdAt:new Date});return await r.setActiveOrganization(t.session.id,o.organizationId),n?e.json({invitation:n,member:i}):e.json(null,{status:400,body:{message:"Invitation not found!"}})}),Ft=c("/organization/reject-invitation",{method:"POST",body:V.object({invitationId:V.string()}),use:[L,N]},async e=>{let t=e.context.session,r=E(e.context.adapter,e.context.orgOptions),o=await r.findInvitationById(e.body.invitationId);if(!o||o.expiresAt<new Date||o.status!=="pending")throw new v("BAD_REQUEST",{message:"Invitation not found!"});if(o.email!==t.user.email)throw new v("FORBIDDEN",{message:"You are not the recipient of the invitation"});let n=await r.updateInvitation({invitationId:e.body.invitationId,status:"rejected"});return e.json({invitation:n,member:null})}),Mt=c("/organization/cancel-invitation",{method:"POST",body:V.object({invitationId:V.string()}),use:[L,N]},async e=>{let t=e.context.session,r=E(e.context.adapter,e.context.orgOptions),o=await r.findInvitationById(e.body.invitationId);if(!o)throw new v("BAD_REQUEST",{message:"Invitation not found!"});let n=await r.findMemberByOrgId({userId:t.user.id,organizationId:o.organizationId});if(!n)throw new v("BAD_REQUEST",{message:"Member not found!"});if(e.context.roles[n.role].authorize({invitation:["cancel"]}).error)throw new v("FORBIDDEN",{message:"You are not allowed to cancel this invitation"});let a=await r.updateInvitation({invitationId:e.body.invitationId,status:"canceled"});return e.json(a)}),qt=c("/organization/get-invitation",{method:"GET",use:[L],requireHeaders:!0,query:V.object({id:V.string()})},async e=>{let t=await H(e);if(!t)throw new v("UNAUTHORIZED",{message:"Not authenticated"});let r=E(e.context.adapter,e.context.orgOptions),o=await r.findInvitationById(e.query.id);if(!o||o.status!=="pending"||o.expiresAt<new Date)throw new v("BAD_REQUEST",{message:"Invitation not found!"});if(o.email!==t.user.email)throw new v("FORBIDDEN",{message:"You are not the recipient of the invitation"});let n=await r.findOrganizationById(o.organizationId);if(!n)throw new v("BAD_REQUEST",{message:"Organization not found"});let i=await r.findMemberByOrgId({userId:o.inviterId,organizationId:o.organizationId});if(!i)throw new v("BAD_REQUEST",{message:"Inviter is no longer a member of the organization"});return e.json({...o,organizationName:n.name,organizationSlug:n.slug,inviterEmail:i.email})});import{z as pe}from"zod";import{APIError as ve}from"better-call";var $t=c("/organization/remove-member",{method:"POST",body:pe.object({memberIdOrEmail:pe.string(),organizationId:pe.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=E(e.context.adapter,e.context.orgOptions),n=await o.findMemberByOrgId({userId:t.user.id,organizationId:r});if(!n)throw new ve("BAD_REQUEST",{message:"Member not found!"});let i=e.context.roles[n.role];if(!i)throw new ve("BAD_REQUEST",{message:"Role not found!"});let a=t.user.email===e.body.memberIdOrEmail||n.id===e.body.memberIdOrEmail;if(a&&n.role===(e.context.orgOptions?.creatorRole||"owner"))throw new ve("BAD_REQUEST",{message:"You cannot leave the organization as the owner"});if(!(a||i.authorize({member:["delete"]}).success))throw new ve("UNAUTHORIZED",{message:"You are not allowed to delete this member"});let 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 ve("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})}),Vt=c("/organization/update-member-role",{method:"POST",body:pe.object({role:pe.enum(["admin","member","owner"]),memberId:pe.string(),organizationId:pe.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=E(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 i=e.context.roles[n.role];if(!i)return e.json(null,{status:400,body:{message:"Role not found!"}});if(i.authorize({member:["update"]}).error||e.body.role==="owner"&&n.role!=="owner")return e.json(null,{body:{message:"You are not allowed to update this member"},status:403});let s=await o.updateMember(e.body.memberId,e.body.role);return s?e.json(s):e.json(null,{status:400,body:{message:"Member not found!"}})});import{z as S}from"zod";import{APIError as me}from"better-call";var Qt=c("/organization/create",{method:"POST",body:S.object({name:S.string(),slug:S.string(),userId:S.string().optional(),logo:S.string().optional(),metadata:S.record(S.string()).optional()}),use:[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 me("FORBIDDEN",{message:"You are not allowed to create an organization"});let n=E(e.context.adapter,r),i=await n.listOrganizations(t.id);if(typeof r.organizationLimit=="number"?i.length>=r.organizationLimit:typeof r.organizationLimit=="function"?await r.organizationLimit(t):!1)throw new me("FORBIDDEN",{message:"You have reached the organization limit"});if(await n.findOrganizationBySlug(e.body.slug))throw new me("BAD_REQUEST",{message:"Organization with this slug already exists"});let d=await n.createOrganization({organization:{id:P(),slug:e.body.slug,name:e.body.name,logo:e.body.logo,createdAt:new Date,metadata:e.body.metadata},user:t});return e.json(d)}),Ht=c("/organization/update",{method:"POST",body:S.object({data:S.object({name:S.string().optional(),slug:S.string().optional()}).partial(),orgId:S.string().optional()}),requireHeaders:!0,use:[L]},async e=>{let t=await e.context.getSession(e);if(!t)throw new me("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=E(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 i=e.context.roles[n.role];if(!i)return e.json(null,{status:400,body:{message:"Role not found!"}});if(i.authorize({organization:["update"]}).error)return e.json(null,{body:{message:"You are not allowed to update this organization"},status:403});let s=await o.updateOrganization(r,e.body.data);return e.json(s)}),Wt=c("/organization/delete",{method:"POST",body:S.object({orgId:S.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=E(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 i=e.context.roles[n.role];if(!i)return e.json(null,{status:400,body:{message:"Role not found!"}});if(i.authorize({organization:["delete"]}).error)throw new me("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)}),Gt=c("/organization/get-full",{method:"GET",query:S.object({orgId:S.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 E(e.context.adapter,e.context.orgOptions).findFullOrganization(r,e.context.db||void 0);if(!n)throw new me("BAD_REQUEST",{message:"Organization not found"});return e.json(n)}),Zt=c("/organization/activate",{method:"POST",body:S.object({orgId:S.string().nullable().optional()}),use:[N,L]},async e=>{let t=E(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 me("FORBIDDEN",{message:"You are not a member of this organization"});await t.setActiveOrganization(r.session.id,o);let i=await t.findFullOrganization(o,e.context.db||void 0);return e.json(i)}),Kt=c("/organization/list",{method:"GET",use:[L,N]},async e=>{let r=await E(e.context.adapter,e.context.orgOptions).listOrganizations(e.context.session.user.id);return e.json(r)});var gc=e=>{let t={createOrganization:Qt,updateOrganization:Ht,deleteOrganization:Wt,setActiveOrganization:Zt,getFullOrganization:Gt,listOrganization:Kt,createInvitation:Nt,cancelInvitation:Mt,acceptInvitation:jt,getInvitation:qt,rejectInvitation:Ft,removeMember:$t,updateMemberRole:Vt},r={...Ke,...e?.roles};return{id:"organization",endpoints:{...Pt(t,{orgOptions:e||{},roles:r,getSession:async n=>await H(n)}),hasPermission:c("/organization/has-permission",{method:"POST",requireHeaders:!0,body:Ee.object({permission:Ee.record(Ee.string(),Ee.array(Ee.string()))}),use:[N]},async n=>{if(!n.context.session.session.activeOrganizationId)throw new Jt("BAD_REQUEST",{message:"No active organization"});let a=await E(n.context.adapter).findMemberByOrgId({userId:n.context.session.user.id,organizationId:n.context.session.session.activeOrganizationId||""});if(!a)throw new Jt("UNAUTHORIZED",{message:"You are not a member of this organization"});let d=r[a.role].authorize(n.body.permission);return d.error?n.json({error:d.error,success:!1},{status:403}):n.json({error:null,success:!0})})},schema:{session:{fields:{activeOrganizationId:{type:"string",required:!1}}},organization:{fields:{name:{type:"string",required:!0},slug:{type:"string",unique:!0},logo:{type:"string",required:!1},createdAt:{type:"date",required:!0},metadata:{type:"string",required:!1}}},member:{fields:{organizationId:{type:"string",required:!0,references:{model:"organization",field:"id"}},userId:{type:"string",required:!0},email:{type:"string",required:!0},role:{type:"string",required:!0,defaultValue:"member"},createdAt:{type:"date",required:!0}}},invitation:{fields:{organizationId:{type:"string",required:!0,references:{model:"organization",field:"id"}},email:{type:"string",required:!0},role:{type:"string",required:!1},status:{type:"string",required:!0,defaultValue:"pending"},expiresAt:{type:"date",required:!0},inviterId:{type:"string",references:{model:"user",field:"id"},required:!0}}}},$Infer:{Organization:{},Invitation:{},Member:{},ActiveOrganization:{}}}};import{z as He}from"zod";import{z as Pe}from"zod";import{APIError as fe}from"better-call";var $e="two-factor";var Ve="trust-device";import{z as Yt}from"zod";var ge=C({body:Yt.object({trustDevice:Yt.boolean().optional()})},async e=>{let t=e.context.createAuthCookie($e),r=await e.getSignedCookie(t.name,e.context.secret);if(!r)throw new fe("UNAUTHORIZED",{message:"invalid two factor cookie"});let[o,n]=r.split("!");if(!o||!n)throw new fe("UNAUTHORIZED",{message:"invalid two factor cookie"});let i=await e.context.adapter.findMany({model:"session",where:[{field:"userId",value:o}]});if(!i.length)throw new fe("UNAUTHORIZED",{message:"invalid session"});let a=i.filter(s=>s.expiresAt>new Date);if(!a)throw new fe("UNAUTHORIZED",{message:"invalid session"});for(let s of a){let d=await G(e.context.secret,s.id),u=await e.context.adapter.findOne({model:"user",where:[{field:"id",value:s.userId}]});if(!u)throw new fe("UNAUTHORIZED",{message:"invalid session"});if(d===n)return{valid:async()=>{if(await y(e,s.id,!1),e.body.trustDevice){let l=e.context.createAuthCookie(Ve,{maxAge:2592e3}),p=await G(e.context.secret,`${u.id}!${s.id}`);await e.setSignedCookie(l.name,`${p}!${s.id}`,e.context.secret,l.options)}return e.json({session:s,user:u})},invalid:async()=>{throw new fe("UNAUTHORIZED",{message:"invalid two factor authentication"})},session:{id:s.id,userId:s.userId,expiresAt:s.expiresAt,user:u}}}throw new fe("UNAUTHORIZED",{message:"invalid two factor authentication"})});import{APIError as Se}from"better-call";function lo(e){return Array.from({length:e?.amount??10}).fill(null).map(()=>F(e?.length??10,M("a-z","0-9"))).map(t=>`${t.slice(0,5)}-${t.slice(5)}`)}async function Ye(e,t){let r=e,o=t?.customBackupCodesGenerate?t.customBackupCodesGenerate():lo(),n=await je({data:JSON.stringify(o),key:r});return{backupCodes:o,encryptedBackupCodes:n}}async function po(e,t){let r=await Xt(e.backupCodes,t);return r?r.includes(e.code):!1}async function Xt(e,t){let r=Buffer.from(await Fe({key:t,data:e})).toString("utf-8"),o=JSON.parse(r),n=Pe.array(Pe.string()).safeParse(o);return n.success?n.data:null}var er=(e,t)=>({id:"backup_code",endpoints:{verifyBackupCode:c("/two-factor/verify-backup-code",{method:"POST",body:Pe.object({code:Pe.string(),disableSession:Pe.boolean().optional()}),use:[ge]},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 Se("BAD_REQUEST",{message:"Backup codes aren't enabled"});if(!po({backupCodes:n.backupCodes,code:r.body.code},r.context.secret))throw new Se("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 Se("BAD_REQUEST",{message:"Two factor isn't enabled"});let n=await Ye(r.context.secret,e);return await r.context.adapter.update({model:t,update:{backupCodes:n.encryptedBackupCodes},where:[{field:"userId",value:r.context.session.user.id}]}),r.json({status:!0,backupCodes:n.backupCodes})}),viewBackupCodes: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 Se("BAD_REQUEST",{message:"Backup codes aren't enabled"});let i=Xt(n.backupCodes,r.context.secret);if(!i)throw new Se("BAD_REQUEST",{message:"Backup codes aren't enabled"});return r.json({status:!0,backupCodes:i})})}});import{APIError as Qe}from"better-call";import{TOTPController as mo}from"oslo/otp";import{z as tr}from"zod";import{TimeSpan as fo}from"oslo";var rr=(e,t)=>{let r={...e,period:new fo(e?.period||3,"m")},o=new mo({digits:6,period:r.period}),n=c("/two-factor/send-otp",{method:"POST",use:[ge]},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 Qe("BAD_REQUEST",{message:"otp isn't configured"});let s=a.context.session.user,d=await a.context.adapter.findOne({model:t,where:[{field:"userId",value:s.id}]});if(!d)throw new Qe("BAD_REQUEST",{message:"totp isn't enabled"});let u=await o.generate(Buffer.from(d.secret));return await e.sendOTP(s,u),a.json({status:!0})}),i=c("/two-factor/verify-otp",{method:"POST",body:tr.object({code:tr.string()}),use:[ge]},async a=>{let s=a.context.session.user;if(!s.twoFactorEnabled)throw new Qe("BAD_REQUEST",{message:"two factor isn't enabled"});let d=await a.context.adapter.findOne({model:t,where:[{field:"userId",value:s.id}]});if(!d)throw new Qe("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:i}}};import{APIError as Ae}from"better-call";import{TimeSpan as go}from"oslo";import{TOTPController as or,createTOTPKeyURI as ho}from"oslo/otp";import{z as nr}from"zod";var ir=(e,t)=>{let r={...e,digits:6,period:new go(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 Ae("BAD_REQUEST",{message:"totp isn't configured"});let s=a.context.session.user,d=await a.context.adapter.findOne({model:t,where:[{field:"userId",value:s.id}]});if(!d)throw new Ae("BAD_REQUEST",{message:"totp isn't enabled"});return{code:await new or(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 Ae("BAD_REQUEST",{message:"totp isn't configured"});let s=a.context.session.user,d=await a.context.adapter.findOne({model:t,where:[{field:"userId",value:s.id}]});if(!d||!s.twoFactorEnabled)throw new Ae("BAD_REQUEST",{message:"totp isn't enabled"});return{totpURI:ho(e?.issuer||"BetterAuth",s.email,Buffer.from(d.secret),r)}}),i=c("/two-factor/verify-totp",{method:"POST",body:nr.object({code:nr.string()}),use:[ge]},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 Ae("BAD_REQUEST",{message:"totp isn't configured"});let s=a.context.session.user,d=await a.context.adapter.findOne({model:t,where:[{field:"userId",value:s.id}]});if(!d||!d.enabled)throw new Ae("BAD_REQUEST",{message:"totp isn't enabled"});let u=new or(r),l=await Fe({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:i}}};async function Xe(e,t){let o=(await e.context.internalAdapter.findAccounts(t.userId))?.find(a=>a.providerId==="credential"),n=o?.password;return!o||!n?!1:await e.context.password.verify(n,t.password)}import{APIError as sr}from"better-call";var Xc=(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 pu=e=>{let t={twoFactorTable:e?.twoFactorTable||"twoFactor"},r=ir({issuer:e?.issuer||"better-auth",...e?.totpOptions},t.twoFactorTable),o=er({...e?.backupCodeOptions},t.twoFactorTable),n=rr({...e?.otpOptions},t.twoFactorTable);return{id:"two-factor",endpoints:{...r.endpoints,...n.endpoints,...o.endpoints,enableTwoFactor:c("/two-factor/enable",{method:"POST",body:He.object({password:He.string().min(8)}),use:[b]},async i=>{let a=i.context.session.user,{password:s}=i.body;if(!await Xe(i,{password:s,userId:a.id}))throw new sr("BAD_REQUEST",{message:"Invalid password"});let u=F(16,M("a-z","0-9","-")),l=await je({key:i.context.secret,data:u}),p=await Ye(i.context.secret,e?.backupCodeOptions);return await i.context.internalAdapter.updateUser(a.id,{twoFactorEnabled:!0}),await i.context.adapter.create({model:t.twoFactorTable,data:{id:i.context.uuid(),secret:l,backupCodes:p.encryptedBackupCodes,userId:a.id}}),i.json({status:!0})}),disableTwoFactor:c("/two-factor/disable",{method:"POST",body:He.object({password:He.string().min(8)}),use:[b]},async i=>{let a=i.context.session.user,{password:s}=i.body;if(!await Xe(i,{password:s,userId:a.id}))throw new sr("BAD_REQUEST",{message:"Invalid password"});return await i.context.internalAdapter.updateUser(a.id,{twoFactorEnabled:!1}),await i.context.adapter.delete({model:t.twoFactorTable,where:[{field:"userId",value:a.id}]}),i.json({status:!0})})},options:e,hooks:{after:[{matcher(i){return i.path==="/sign-in/email"||i.path==="/sign-in/username"},handler:C(async i=>{let a=i.context.returned;if(a?.status!==200)return;let s=await a.clone().json();if(!s.user.twoFactorEnabled)return;let d=i.context.createAuthCookie(Ve,{maxAge:30*24*60*60}),u=await i.getSignedCookie(d.name,i.context.secret);if(u){let[m,f]=u.split("!"),h=await G(i.context.secret,`${s.user.id}!${f}`);if(m===h){let R=await G(i.context.secret,`${s.user.id}!${s.session.id}`);await i.setSignedCookie(d.name,`${R}!${s.session.id}`,i.context.secret,d.options);return}}i.setCookie(i.context.authCookies.sessionToken.name,"",{path:"/",sameSite:"lax",httpOnly:!0,secure:!1,maxAge:0});let l=await G(i.context.secret,s.session.id),p=i.context.createAuthCookie($e,{maxAge:60*60*24});return await i.setSignedCookie(p.name,`${s.session.userId}!${l}`,i.context.secret,p.options),{response:new Response(JSON.stringify({twoFactorRedirect:!0}),{headers:i.responseHeader})}})}]},schema:{user:{fields:{twoFactorEnabled:{type:"boolean",required:!1,defaultValue:!1}}},twoFactor:{tableName:t.twoFactorTable,fields:{secret:{type:"string",required:!0,returned:!1},backupCodes:{type:"string",required:!0,returned:!1},userId:{type:"string",required:!0,returned:!1,references:{model:"user",field:"id"}}}}},rateLimit:[{pathMatcher(i){return i.startsWith("/two-factor/")},window:10,max:3}]}};import{generateAuthenticationOptions as ko,generateRegistrationOptions as Uo,verifyAuthenticationResponse as To,verifyRegistrationResponse as vo}from"@simplewebauthn/server";import{APIError as J}from"better-call";import{z as re}from"zod";import{WebAuthnError as bo,startAuthentication as Ao,startRegistration as Oo}from"@simplewebauthn/browser";import{createFetch as ku}from"@better-fetch/fetch";import"nanostores";import{betterFetch as hu}from"@better-fetch/fetch";import{atom as Du}from"nanostores";import"@better-fetch/fetch";import{atom as wo,onMount as yo}from"nanostores";var et=(e,t,r,o)=>{let n=wo({data:null,error:null,isPending:!1,isRefetching:!1}),i=()=>{let s=typeof o=="function"?o({data:n.get().data,error:n.get().error,isPending:n.get().isPending}):o;return r(t,{...s,onSuccess:async d=>{n.set({data:d.data,error:null,isPending:!1,isRefetching:!1}),await s?.onSuccess?.(d)},async onError(d){n.set({error:d.error,data:null,isPending:!1,isRefetching:!1}),await s?.onError?.(d)},async onRequest(d){let u=n.get();n.set({isPending:u.data===null,data:u.data,error:null,isRefetching:!0}),await s?.onRequest?.(d)}})};e=Array.isArray(e)?e:[e];let a=!1;for(let s of e)s.subscribe(()=>{a?i():yo(n,()=>(i(),a=!0,()=>{n.off(),s.off()}))});return n};import{atom as Ro}from"nanostores";var Io=(e,{_listPasskeys:t})=>({signIn:{passkey:async(n,i)=>{let a=await e("/passkey/generate-authenticate-options",{method:"POST",body:{email:n?.email}});if(!a.data)return a;try{let s=await Ao(a.data,n?.autoFill||!1),d=await e("/passkey/verify-authentication",{body:{response:s},...n?.fetchOptions,...i,method:"POST"});if(!d.data)return d}catch(s){console.log(s)}}},passkey:{addPasskey:async(n,i)=>{let a=await e("/passkey/generate-register-options",{method:"GET"});if(!a.data)return a;try{let s=await Oo(a.data),d=await e("/passkey/verify-registration",{...n?.fetchOptions,...i,body:{response:s,name:n?.name},method:"POST"});if(!d.data)return d;t.set(Math.random())}catch(s){return s instanceof bo?s.code==="ERROR_AUTHENTICATOR_PREVIOUSLY_REGISTERED"?{data:null,error:{message:"previously registered",status:400,statusText:"BAD_REQUEST"}}:s.code==="ERROR_CEREMONY_ABORTED"?{data:null,error:{message:"registration cancelled",status:400,statusText:"BAD_REQUEST"}}:{data:null,error:{message:s.message,status:400,statusText:"BAD_REQUEST"}}:{data:null,error:{message:s instanceof Error?s.message:"unknown error",status:500,statusText:"INTERNAL_SERVER_ERROR"}}}}},$Infer:{}}),tl=()=>{let e=Ro();return{id:"passkey",$InferServerPlugin:{},getActions:t=>Io(t,{_listPasskeys:e}),getAtoms(t){return{listPasskeys:et(e,"/passkey/list-user-passkeys",t,{method:"GET",credentials:"include"}),_listPasskeys:e}},pathMethods:{"/passkey/register":"POST","/passkey/authenticate":"POST"},atomListeners:[{matcher(t){return t==="/passkey/verify-registration"||t==="/passkey/delete-passkey"},signal:"_listPasskeys"}]}};var ml=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),i=new Date,a=Math.floor((n.getTime()-i.getTime())/1e3);return{id:"passkey",endpoints:{generatePasskeyRegistrationOptions:c("/passkey/generate-register-options",{method:"GET",use:[b],metadata:{client:!1}},async s=>{let d=s.context.session,u=await s.context.adapter.findMany({model:"passkey",where:[{field:"userId",value:d.user.id}]}),l=new Uint8Array(Buffer.from(F(32,M("a-z","0-9")))),p;p=await Uo({rpName:o.rpName||s.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=P();return await s.setSignedCookie(o.advanced.webAuthnChallengeCookie,U,s.context.secret,{secure:!0,httpOnly:!0,sameSite:"lax",maxAge:a}),await s.context.internalAdapter.createVerificationValue({identifier:U,value:JSON.stringify({expectedChallenge:p.challenge,userData:{id:d.user.id}}),expiresAt:n}),s.json(p,{status:200})}),generatePasskeyAuthenticationOptions:c("/passkey/generate-authenticate-options",{method:"POST",body:re.object({email:re.string().optional()}).optional()},async s=>{let d=await H(s),u=[];d&&(u=await s.context.adapter.findMany({model:"passkey",where:[{field:"userId",value:d.user.id}]}));let l=await ko({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=P();return await s.setSignedCookie(o.advanced.webAuthnChallengeCookie,U,s.context.secret,{secure:!0,httpOnly:!0,sameSite:"lax",maxAge:a}),await s.context.internalAdapter.createVerificationValue({identifier:U,value:JSON.stringify(p),expiresAt:n}),s.json(l,{status:200})}),verifyPasskeyRegistration:c("/passkey/verify-registration",{method:"POST",body:re.object({response:re.any(),name:re.string().optional()}),use:[b]},async s=>{let d=e?.origin||s.headers?.get("origin")||"";if(!d)return s.json(null,{status:400});let u=s.body.response,l=await s.getSignedCookie(o.advanced.webAuthnChallengeCookie,s.context.secret);if(!l)throw new J("BAD_REQUEST",{message:"Challenge not found"});let p=await s.context.internalAdapter.findVerificationValue(l);if(!p)return s.json(null,{status:400});let{expectedChallenge:U,userData:m}=JSON.parse(p.value);if(m.id!==s.context.session.user.id)throw new J("UNAUTHORIZED",{message:"You are not authorized to register this passkey"});try{let f=await vo({response:u,expectedChallenge:U,expectedOrigin:d,expectedRPID:e?.rpID}),{verified:h,registrationInfo:R}=f;if(!h||!R)return s.json(null,{status:400});let{credentialID:I,credentialPublicKey:ee,counter:ne,credentialDeviceType:O,credentialBackedUp:j}=R,ie=Buffer.from(ee).toString("base64"),x=P(),Ce={name:s.body.name,userId:m.id,webauthnUserID:x,id:I,publicKey:ie,counter:ne,deviceType:O,transports:u.response.transports.join(","),backedUp:j,createdAt:new Date},dr=await s.context.adapter.create({model:"passkey",data:Ce});return s.json(dr,{status:200})}catch(f){throw console.log(f),new J("INTERNAL_SERVER_ERROR",{message:"Failed to verify registration"})}}),verifyPasskeyAuthentication:c("/passkey/verify-authentication",{method:"POST",body:re.object({response:re.any()})},async s=>{let d=e?.origin||s.headers?.get("origin")||"";if(!d)throw new J("BAD_REQUEST",{message:"origin missing"});let u=s.body.response,l=await s.getSignedCookie(o.advanced.webAuthnChallengeCookie,s.context.secret);if(!l)throw new J("BAD_REQUEST",{message:"Challenge not found"});let p=await s.context.internalAdapter.findVerificationValue(l);if(!p)throw new J("BAD_REQUEST",{message:"Challenge not found"});let{expectedChallenge:U}=JSON.parse(p.value),m=await s.context.adapter.findOne({model:"passkey",where:[{field:"id",value:u.id}]});if(!m)throw new J("UNAUTHORIZED",{message:"Passkey not found"});try{let f=await To({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 J("UNAUTHORIZED",{message:"Authentication failed"});await s.context.adapter.update({model:"passkey",where:[{field:"id",value:m.id}],update:{counter:f.authenticationInfo.newCounter}});let R=await s.context.internalAdapter.createSession(m.userId,s.request);if(!R)throw new J("INTERNAL_SERVER_ERROR",{message:"Unable to create session"});return await y(s,R.id),s.json({session:R},{status:200})}catch(f){throw s.context.logger.error(f),new J("BAD_REQUEST",{message:"Failed to verify authentication"})}}),listPasskeys:c("/passkey/list-user-passkeys",{method:"GET",use:[b]},async s=>{let d=await s.context.adapter.findMany({model:"passkey",where:[{field:"userId",value:s.context.session.user.id}]});return s.json(d,{status:200})}),deletePasskey:c("/passkey/delete-passkey",{method:"POST",body:re.object({id:re.string()}),use:[b]},async s=>(await s.context.adapter.delete({model:"passkey",where:[{field:"id",value:s.body.id}]}),s.json(null,{status:200})))},schema:{passkey:{fields:{name:{type:"string",required:!1},publicKey:{type:"string",required:!0},userId:{type:"string",references:{model:"user",field:"id"},required:!0},webauthnUserID:{type:"string",required:!0},counter:{type:"number",required:!0},deviceType:{type:"string",required:!0},backedUp:{type:"boolean",required:!0},transports:{type:"string",required:!1},createdAt:{type:"date",defaultValue:new Date,required:!1}}}}}};import{z as Y}from"zod";import{APIError as We}from"better-call";var ar=()=>({id:"username",endpoints:{signInUsername:c("/sign-in/username",{method:"POST",body:Y.object({username:Y.string(),password:Y.string(),dontRememberMe:Y.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:ar}),new We("UNAUTHORIZED",{message:"Invalid username or password"});let r=await e.context.adapter.findOne({model:"account",where:[{field:e.context.tables.account.fields.userId.fieldName||"userId",value:t.id},{field:e.context.tables.account.fields.type.fieldName||"providerId",value:"credential"}]});if(!r)throw new We("UNAUTHORIZED",{message:"Invalid username or password"});let o=r?.password;if(!o)throw e.context.logger.error("Password not found",{username:ar}),new We("UNAUTHORIZED",{message:"Unexpected error"});if(!await e.context.password.verify(o,e.body.password))throw e.context.logger.error("Invalid password"),new We("UNAUTHORIZED",{message:"Invalid username or password"});let i=await e.context.internalAdapter.createSession(t.id,e.request);return i?(await e.setSignedCookie(e.context.authCookies.sessionToken.name,i.id,e.context.secret,e.body.dontRememberMe?{...e.context.authCookies.sessionToken.options,maxAge:void 0}:e.context.authCookies.sessionToken.options),e.json({user:t,session:i})):e.json(null,{status:500,body:{message:"Failed to create session",status:500}})}),signUpUsername:c("/sign-up/username",{method:"POST",body:Y.object({username:Y.string().min(3).max(20),name:Y.string(),email:Y.string().email(),password:Y.string(),image:Y.string().optional()})},async e=>{let t=await Ue()({...e,_flag:"json"}),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 Eo}from"better-call";var Rl=()=>({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 Eo("",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 So}from"better-call";var Pl=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:[z]},async t=>{let{email:r}=t.body,o=F(32,M("a-z","A-Z"));await t.context.internalAdapter.createVerificationValue({identifier:o,value:r,expiresAt:new Date(Date.now()+(e.expiresIn||60*5)*1e3)});let n=`${t.context.baseURL}/magic-link/verify?token=${o}&callbackURL=${t.body.callbackURL||"/"}`;try{await e.sendMagicLink({email:r,url:n,token:o})}catch(i){throw t.context.logger.error("Failed to send magic link",i),new So("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,i=await t.context.internalAdapter.findVerificationValue(r);if(!i)throw t.redirect(`${n}?error=INVALID_TOKEN`);if(i.expiresAt<new Date)throw await t.context.internalAdapter.deleteVerificationValue(i.id),t.redirect(`${n}?error=EXPIRED_TOKEN`);await t.context.internalAdapter.deleteVerificationValue(i.id);let a=i.value,s=await t.context.internalAdapter.findUserByEmail(a),d=s?.user.id||"";if(!s){if(e.disableSignUp)throw t.redirect(`${n}?error=USER_NOT_FOUND`);if(d=(await t.context.internalAdapter.createUser({email:a,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 _}from"zod";import{APIError as D}from"better-call";function tt(e){return F(e,M("0-9"))}var Ml=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:_.object({phoneNumber:_.string(),password:_.string(),dontRememberMe:_.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:r.context.tables.account.fields.userId.fieldName||"userId",value:o.id},{field:r.context.tables.account.fields.providerId.fieldName||"providerId",value:"credential"}]});if(!n)throw new D("UNAUTHORIZED",{message:"Invalid email or password"});let i=n?.password;if(!i)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(i,r.body.password))throw r.context.logger.error("Invalid password"),new D("UNAUTHORIZED",{message:"Invalid email or password"});let s=await r.context.internalAdapter.createSession(o.id,r.request);return s?(await r.setSignedCookie(r.context.authCookies.sessionToken.name,s.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:s})):r.json(null,{status:500,body:{message:"Failed to create session",status:500}})}),signUpPhoneNumber:c("/sign-up/phone-number",{method:"POST",body:_.object({phoneNumber:_.string().min(3).max(20),name:_.string(),email:_.string().email(),password:_.string(),image:_.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 Ue()({...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=tt(e?.otp?.otpLength||6);await r.context.internalAdapter.createVerificationValue({value:a,identifier:r.body.phoneNumber,expiresAt:q(t.otp.expiresIn,"sec")}),await e.otp.sendOTP(r.body.phoneNumber,a)}let i=await r.context.internalAdapter.updateUserByEmail(n.user.email,{[t.phoneNumber]:r.body.phoneNumber});return r.json({user:i,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:_.object({phoneNumber:_.string()})},async r=>{if(!e?.otp?.sendOTP)throw A.warn("sendOTP not implemented"),new D("NOT_IMPLEMENTED",{message:"sendOTP not implemented"});let o=tt(e?.otp?.otpLength||6);return await r.context.internalAdapter.createVerificationValue({value:o,identifier:r.body.phoneNumber,expiresAt:q(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:_.object({phoneNumber:_.string(),code:_.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 i=await r.context.internalAdapter.updateUser(n.id,{[t.phoneNumberVerified]:!0});if(e?.enableAutoSignIn&&!await H(r)){let s=await r.context.internalAdapter.createSession(n.id,r.request);if(!s)throw new D("INTERNAL_SERVER_ERROR",{message:"Failed to create session"});return await y(r,s.id),r.json({user:i,session:s})}return r.json({user:i,session:null})}),updatePhoneNumber:c("/phone-number/update",{method:"POST",body:_.object({phoneNumber:_.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=tt(e?.otp?.otpLength||6);await r.context.adapter.create({model:r.context.tables.verification.tableName,data:{code:n,phoneNumber:r.body.phoneNumber,createdAt:q(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 rt}from"zod";var Gl=e=>({id:"anonymous",endpoints:{signInAnonymous:c("/sign-in/anonymous",{method:"POST"},async t=>{let{emailDomainName:r=ct(t.context.baseURL)}=e||{},o=P(),n=`temp-${o}@${r}`,i=await t.context.internalAdapter.createUser({id:o,email:n,emailVerified:!1,isAnonymous:!0,name:"Anonymous",createdAt:new Date,updatedAt:new Date});if(!i)return t.json(null,{status:500,body:{message:"Failed to create user",status:500}});let a=await t.context.internalAdapter.createSession(i.id,t.request);return a?(await y(t,a.id),t.json({user:i,session:a})):t.json(null,{status:400,body:{message:"Could not create session"}})}),linkAnonymous:c("/user/link-anonymous",{method:"POST",body:rt.object({email:rt.string().email().optional(),password:rt.string().min(6)}),use:[b]},async t=>{let r=t.context.session.user.id,{email:o,password:n}=t.body,i=null;if(o&&n&&(i=await t.context.internalAdapter.updateUser(r,{email:o})),!i)return t.json(null,{status:500,body:{message:"Failed to update user",status:500}});let a=await t.context.password.hash(n);if(!await t.context.internalAdapter.linkAccount({userId:i.id,providerId:"credential",password:a,accountId:i.id}))return t.json(null,{status:500,body:{message:"Failed to update account",status:500}});let d=await t.context.internalAdapter.createSession(i.id,t.request);return d?(await y(t,d.id),t.json({session:d,user:i})):t.json(null,{status:400,body:{message:"Could not create session"}})})},schema:{user:{fields:{isAnonymous:{type:"boolean",defaultValue:!0,required:!1}}}}});import{z as g}from"zod";var X=C(async e=>{let t=await H(e);if(!t?.session)throw new de("UNAUTHORIZED");let r=t.user;if(r.role!=="admin")throw new de("FORBIDDEN",{message:"Only admins can access this endpoint"});return{session:{user:r,session:t.session}}}),ep=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:C(async t=>{let r=t.context.returned;if(r){let n=(await r.json()).filter(a=>!a.impersonatedBy),i=new Response(JSON.stringify(n),{status:200,statusText:"OK",headers:r.headers});return t.json({response:i})}})}]},endpoints:{setRole:c("/admin/set-role",{method:"POST",body:g.object({userId:g.string(),role:g.string()}),use:[X]},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.string(),data:g.optional(g.record(g.any()))}),use:[X]},async t=>{if(await t.context.internalAdapter.findUserByEmail(t.body.email))throw new de("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 de("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:[X],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:[X],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:[X]},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:[X]},async t=>{if(t.body.userId===t.context.session.user.id)throw new de("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:[X]},async t=>{let r=await t.context.internalAdapter.findUserById(t.body.userId);if(!r)throw new de("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?q(e.impersonationSessionDuration,"sec"):q(60*60,"sec")});if(!o)throw new de("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:[X]},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:[X]},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:[X]},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 oe}from"zod";import{APIError as _e}from"better-call";import{betterFetch as ot}from"@better-fetch/fetch";import{generateCodeVerifier as Po}from"oslo/oauth2";import{parseJWT as _o}from"oslo/jwt";async function Co(e,t,r){if(t==="oidc"&&e.idToken){let n=_o(e.idToken);if(n?.payload)return n.payload}return r?(await ot(r,{method:"GET",headers:{Authorization:`Bearer ${e.accessToken}`}})).data:null}var wp=e=>({id:"generic-oauth",endpoints:{signInWithOAuth2:c("/sign-in/oauth2",{method:"POST",query:oe.object({currentURL:oe.string().optional()}).optional(),body:oe.object({providerId:oe.string(),callbackURL:oe.string().optional()}),use:[z]},async t=>{let{providerId:r}=t.body,o=e.config.find(x=>x.providerId===r);if(!o)throw new _e("BAD_REQUEST",{message:`No config found for provider ${r}`});let{discoveryUrl:n,authorizationUrl:i,tokenUrl:a,clientId:s,clientSecret:d,scopes:u,redirectURI:l,responseType:p,pkce:U,prompt:m,accessType:f}=o,h=i,R=a;if(n){let x=await ot(n,{onError(Ce){A.error(Ce.error,{discoveryUrl:n})}});x.data&&(h=x.data.authorization_endpoint,R=x.data.token_endpoint)}if(!h||!R)throw new _e("BAD_REQUEST",{message:"Invalid OAuth configuration."});let I=t.query?.currentURL?new URL(t.query?.currentURL):null,ee=t.body.callbackURL?.startsWith("http")?t.body.callbackURL:`${I?.origin}${t.body.callbackURL||""}`,ne=await Le(ee||I?.origin||t.context.options.baseURL),O=t.context.authCookies;await t.setSignedCookie(O.state.name,ne.hash,t.context.secret,O.state.options);let j=Po();await t.setSignedCookie(O.pkCodeVerifier.name,j,t.context.secret,O.pkCodeVerifier.options);let ie=await B({id:r,options:{clientId:s,clientSecret:d,redirectURI:l},authorizationEndpoint:h,state:ne.raw,codeVerifier:j,scopes:u||[],disablePkce:!U,redirectURI:`${t.context.baseURL}/oauth2/callback/${r}`});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:ne,codeVerifier:j,redirect:!0}}),oAuth2Callback:c("/oauth2/callback/:providerId",{method:"GET",query:oe.object({code:oe.string().optional(),error:oe.string().optional(),state:oe.string()})},async t=>{if(t.query.error||!t.query.code){let j=he(t.query.state).data?.currentURL||`${t.context.baseURL}/error`;throw t.context.logger.error(t.query.error,t.params.providerId),t.redirect(`${j}?error=${t.query.error||"oAuth_code_missing"}`)}let r=e.config.find(O=>O.providerId===t.params.providerId);if(!r)throw new _e("BAD_REQUEST",{message:`No config found for provider ${t.params.providerId}`});let o=await t.getSignedCookie(t.context.authCookies.pkCodeVerifier.name,t.context.secret),n,i=he(t.query.state);if(!i.success)throw t.redirect(`${t.context.baseURL}/error?error=invalid_state`);let a=t.query.state,{data:{callbackURL:s,currentURL:d,code:u}}=i,l=i.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 ze(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 O=await ot(r.discoveryUrl,{method:"GET"});O.data&&(m=O.data.token_endpoint,f=O.data.userinfo_endpoint)}try{if(!m)throw new _e("BAD_REQUEST",{message:"Invalid OAuth configuration."});n=await T({code:u,codeVerifier:o,redirectURI:`${t.context.baseURL}/oauth2/callback/${r.providerId}`,options:{clientId:r.clientId,clientSecret:r.clientSecret},tokenEndpoint:m})}catch(O){throw t.context.logger.error(O),t.redirect(`${l}?error=oauth_code_verification_failed`)}if(!n)throw new _e("BAD_REQUEST",{message:"Invalid OAuth configuration."});let h=r.getUserInfo?await r.getUserInfo(n):await Co(n,r.type||"oauth2",f),R=P(),I=h?De.safeParse({...h,id:R}):null;if(!I?.success)throw t.redirect(`${l}?error=oauth_user_info_invalid`);let ee=await t.context.internalAdapter.findUserByEmail(I.data.email).catch(O=>{throw A.error(`Better auth was unable to query your database.
|
|
84
|
-
Error: `,
|
|
83
|
+
</html>`,mo=c("/error",{method:"GET",metadata:ae},async e=>{let t=new URL(e.request?.url||"").searchParams.get("error")||"Unknown";return new Response(po(t),{headers:{"Content-Type":"text/html"}})});var fo=c("/ok",{method:"GET",metadata:ae},async e=>e.json({ok:!0}));import{z as ye}from"zod";import{APIError as ue}from"better-call";var ve=()=>c("/sign-up/email",{method:"POST",query:ye.object({currentURL:ye.string().optional()}).optional(),body:ye.record(ye.string(),ye.any()),use:[z]},async e=>{if(!e.context.options.emailAndPassword?.enabled)throw new ue("BAD_REQUEST",{message:"Email and password sign up is not enabled"});let t=e.body,{name:r,email:o,password:n,image:i,callbackURL:a,...s}=t;if(!ye.string().email().safeParse(o).success)throw new ue("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 ue("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 ue("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 ue("UNPROCESSABLE_ENTITY",{message:"The email has already been taken"});let O=vt(e.context.options,s),m=await e.context.internalAdapter.createUser({email:o.toLowerCase(),name:r,image:i,...O,emailVerified:!1});if(!m)throw new ue("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 ue("BAD_REQUEST",{message:"Failed to create session"});if(await b(e,h.id),e.context.options.emailAndPassword.sendEmailVerificationOnSignUp){let R=await Je(e.context.secret,m.email),I=`${e.context.baseURL}/verify-email?token=${R}&callbackURL=${t.callbackURL||e.query?.currentURL||"/"}`;await e.context.options.emailAndPassword.sendVerificationEmail?.(I,m,R)}return e.json({user:m,session:h},{body:t.callbackURL?{url:t.callbackURL,redirect:!0}:{user:m,session:h}})});var _t=(e,t)=>{let r={};for(let[o,n]of Object.entries(e))r[o]=i=>n({...i,context:{...t,...i.context}}),r[o].path=n.path,r[o].method=n.method,r[o].options=n.options,r[o].headers=n.headers;return r};var jt={};wr(jt,{AccessControl:()=>Ue,ParsingError:()=>le,Role:()=>be,adminAc:()=>Lt,createAccessControl:()=>zt,defaultAc:()=>qe,defaultRoles:()=>Ze,defaultStatements:()=>Bt,memberAc:()=>xt,ownerAc:()=>Dt,permissionFromString:()=>go});var le=class extends Error{path;constructor(t,r){super(t),this.path=r}},Ue=class{constructor(t){this.s=t;this.statements=t}statements;newRole(t){return new be(t)}},be=class e{statements;constructor(t){this.statements=t}authorize(t,r){for(let[o,n]of Object.entries(t)){let i=this.statements[o];if(!i)return{success:!1,error:`You are not allowed to access resource: ${o}`};let a=r==="OR"?n.some(s=>i.includes(s)):n.every(s=>i.includes(s));return a?{success:a}:{success:!1,error:`unauthorized to access resource "${o}"`}}return{success:!1,error:"Not authorized"}}static fromString(t){let r=JSON.parse(t);if(typeof r!="object")throw new le("statements is not an object",".");for(let[o,n]of Object.entries(r)){if(typeof o!="string")throw new le("invalid resource identifier",o);if(!Array.isArray(n))throw new le("actions is not an array",o);for(let i=0;i<n.length;i++)if(typeof n[i]!="string")throw new le("action is not a string",`${o}[${i}]`)}return new e(r)}toString(){return JSON.stringify(this.statements)}};var zt=e=>new Ue(e),Bt={organization:["update","delete"],member:["create","update","delete"],invitation:["create","cancel"]},qe=zt(Bt),Lt=qe.newRole({organization:["update"],invitation:["create","cancel"],member:["create","update","delete"]}),Dt=qe.newRole({organization:["update","delete"],member:["create","update","delete"],invitation:["create","cancel"]}),xt=qe.newRole({organization:[],member:[],invitation:[]}),Ze={admin:Lt,owner:Dt,member:xt};var go=e=>be.fromString(e??"");var E=(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:P(),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 i=await e.findMany({model:"invitation",where:[{field:"organizationId",value:r}]}),a=await e.findMany({model:"member",where:[{field:"organizationId",value:r}]}),s=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:i,members:s}},listOrganizations:async r=>{let n=(await e.findMany({model:"member",where:[{field:"userId",value:r}]}))?.map(a=>a.organizationId);if(!n)return[];let i=[];for(let a of n){let s=await e.findOne({model:"organization",where:[{field:"id",value:a}]});s&&i.push(s)}return i},createInvitation:async({invitation:r,user:o})=>{let i=q(t?.invitationExpiresIn||1728e5);return await e.create({model:"invitation",data:{id:P(),email:r.email,role:r.role,organizationId:r.organizationId,status:"pending",expiresAt:i,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 kd,createRouter as Od}from"better-call";import{APIError as Ye}from"better-call";import{z as Nt}from"zod";var ho=_({body:Nt.object({csrfToken:Nt.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 Ye("UNAUTHORIZED",{message:"CSRF Token is required"});let o=await e.getSignedCookie(e.context.authCookies.csrfToken.name,e.context.secret),[n,i]=o?.split("!")||[null,null];if(!r||!o||!n||!i||o!==r)throw e.setCookie(e.context.authCookies.csrfToken.name,"",{maxAge:0}),new Ye("UNAUTHORIZED",{message:"Invalid CSRF Token"});let a=await K(e.context.secret,n);if(i!==a)throw e.setCookie(e.context.authCookies.csrfToken.name,"",{maxAge:0}),new Ye("UNAUTHORIZED",{message:"Invalid CSRF Token"})});import{APIError as de}from"better-call";var L=_(async e=>({})),j=_({use:[y]},async e=>({session:e.context.session}));import{z as V}from"zod";import{z as v}from"zod";var $e=v.enum(["admin","member","owner"]),wo=v.enum(["pending","accepted","rejected","canceled"]).default("pending"),Qd=v.object({id:v.string(),name:v.string(),slug:v.string(),logo:v.string().optional(),metadata:v.record(v.string()).or(v.string().transform(e=>JSON.parse(e))).optional(),createdAt:v.date()}),Hd=v.object({id:v.string(),email:v.string(),organizationId:v.string(),userId:v.string(),role:$e,createdAt:v.date()}),Wd=v.object({id:v.string(),organizationId:v.string(),email:v.string(),role:$e,status:wo,inviterId:v.string(),expiresAt:v.date()});import{APIError as T}from"better-call";var Ft=c("/organization/invite-member",{method:"POST",use:[L,j],body:V.object({email:V.string(),role:$e,organizationId:V.string().optional(),resend:V.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 T("BAD_REQUEST",{message:"Invitation email is not enabled"});let t=e.context.session,r=e.body.organizationId||t.session.activeOrganizationId;if(!r)throw new T("BAD_REQUEST",{message:"Organization not found"});let o=E(e.context.adapter,e.context.orgOptions),n=await o.findMemberByOrgId({userId:t.user.id,organizationId:r});if(!n)throw new T("BAD_REQUEST",{message:"Member not found!"});let i=e.context.roles[n.role];if(!i)throw new T("BAD_REQUEST",{message:"Role not found!"});if(i.authorize({invitation:["create"]}).error)throw new T("FORBIDDEN",{message:"You are not allowed to invite members"});if(await o.findMemberByEmail({email:e.body.email,organizationId:r}))throw new T("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 T("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 T("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)}),Mt=c("/organization/accept-invitation",{method:"POST",body:V.object({invitationId:V.string()}),use:[L,j]},async e=>{let t=e.context.session,r=E(e.context.adapter,e.context.orgOptions),o=await r.findInvitationById(e.body.invitationId);if(!o||o.expiresAt<new Date||o.status!=="pending")throw new T("BAD_REQUEST",{message:"Invitation not found!"});if(o.email!==t.user.email)throw new T("FORBIDDEN",{message:"You are not the recipient of the invitation"});let n=await r.updateInvitation({invitationId:e.body.invitationId,status:"accepted"}),i=await r.createMember({id:P(),organizationId:o.organizationId,userId:t.user.id,email:o.email,role:o.role,createdAt:new Date});return await r.setActiveOrganization(t.session.id,o.organizationId),n?e.json({invitation:n,member:i}):e.json(null,{status:400,body:{message:"Invitation not found!"}})}),qt=c("/organization/reject-invitation",{method:"POST",body:V.object({invitationId:V.string()}),use:[L,j]},async e=>{let t=e.context.session,r=E(e.context.adapter,e.context.orgOptions),o=await r.findInvitationById(e.body.invitationId);if(!o||o.expiresAt<new Date||o.status!=="pending")throw new T("BAD_REQUEST",{message:"Invitation not found!"});if(o.email!==t.user.email)throw new T("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})}),$t=c("/organization/cancel-invitation",{method:"POST",body:V.object({invitationId:V.string()}),use:[L,j]},async e=>{let t=e.context.session,r=E(e.context.adapter,e.context.orgOptions),o=await r.findInvitationById(e.body.invitationId);if(!o)throw new T("BAD_REQUEST",{message:"Invitation not found!"});let n=await r.findMemberByOrgId({userId:t.user.id,organizationId:o.organizationId});if(!n)throw new T("BAD_REQUEST",{message:"Member not found!"});if(e.context.roles[n.role].authorize({invitation:["cancel"]}).error)throw new T("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)}),Vt=c("/organization/get-invitation",{method:"GET",use:[L],requireHeaders:!0,query:V.object({id:V.string()})},async e=>{let t=await H(e);if(!t)throw new T("UNAUTHORIZED",{message:"Not authenticated"});let r=E(e.context.adapter,e.context.orgOptions),o=await r.findInvitationById(e.query.id);if(!o||o.status!=="pending"||o.expiresAt<new Date)throw new T("BAD_REQUEST",{message:"Invitation not found!"});if(o.email!==t.user.email)throw new T("FORBIDDEN",{message:"You are not the recipient of the invitation"});let n=await r.findOrganizationById(o.organizationId);if(!n)throw new T("BAD_REQUEST",{message:"Organization not found"});let i=await r.findMemberByOrgId({userId:o.inviterId,organizationId:o.organizationId});if(!i)throw new T("BAD_REQUEST",{message:"Inviter is no longer a member of the organization"});return e.json({...o,organizationName:n.name,organizationSlug:n.slug,inviterEmail:i.email})});import{z as pe}from"zod";import{APIError as Te}from"better-call";var Qt=c("/organization/remove-member",{method:"POST",body:pe.object({memberIdOrEmail:pe.string(),organizationId:pe.string().optional()}),use:[L,j]},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=E(e.context.adapter,e.context.orgOptions),n=await o.findMemberByOrgId({userId:t.user.id,organizationId:r});if(!n)throw new Te("BAD_REQUEST",{message:"Member not found!"});let i=e.context.roles[n.role];if(!i)throw new Te("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 Te("BAD_REQUEST",{message:"You cannot leave the organization as the owner"});if(!(a||i.authorize({member:["delete"]}).success))throw new Te("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 Te("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})}),Ht=c("/organization/update-member-role",{method:"POST",body:pe.object({role:pe.enum(["admin","member","owner"]),memberId:pe.string(),organizationId:pe.string().optional()}),use:[L,j]},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=E(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 i=e.context.roles[n.role];if(!i)return e.json(null,{status:400,body:{message:"Role not found!"}});if(i.authorize({member:["update"]}).error||e.body.role==="owner"&&n.role!=="owner")return e.json(null,{body:{message:"You are not allowed to update this member"},status:403});let s=await o.updateMember(e.body.memberId,e.body.role);return s?e.json(s):e.json(null,{status:400,body:{message:"Member not found!"}})});import{z as S}from"zod";import{APIError as me}from"better-call";var Wt=c("/organization/create",{method:"POST",body:S.object({name:S.string(),slug:S.string(),userId:S.string().optional(),logo:S.string().optional(),metadata:S.record(S.string()).optional()}),use:[L,j]},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 me("FORBIDDEN",{message:"You are not allowed to create an organization"});let n=E(e.context.adapter,r),i=await n.listOrganizations(t.id);if(typeof r.organizationLimit=="number"?i.length>=r.organizationLimit:typeof r.organizationLimit=="function"?await r.organizationLimit(t):!1)throw new me("FORBIDDEN",{message:"You have reached the organization limit"});if(await n.findOrganizationBySlug(e.body.slug))throw new me("BAD_REQUEST",{message:"Organization with this slug already exists"});let d=await n.createOrganization({organization:{id:P(),slug:e.body.slug,name:e.body.name,logo:e.body.logo,createdAt:new Date,metadata:e.body.metadata},user:t});return e.json(d)}),Kt=c("/organization/update",{method:"POST",body:S.object({data:S.object({name:S.string().optional(),slug:S.string().optional()}).partial(),orgId:S.string().optional()}),requireHeaders:!0,use:[L]},async e=>{let t=await e.context.getSession(e);if(!t)throw new me("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=E(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 i=e.context.roles[n.role];if(!i)return e.json(null,{status:400,body:{message:"Role not found!"}});if(i.authorize({organization:["update"]}).error)return e.json(null,{body:{message:"You are not allowed to update this organization"},status:403});let s=await o.updateOrganization(r,e.body.data);return e.json(s)}),Gt=c("/organization/delete",{method:"POST",body:S.object({orgId:S.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=E(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 i=e.context.roles[n.role];if(!i)return e.json(null,{status:400,body:{message:"Role not found!"}});if(i.authorize({organization:["delete"]}).error)throw new me("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)}),Jt=c("/organization/get-full",{method:"GET",query:S.object({orgId:S.string().optional()}),requireHeaders:!0,use:[L,j]},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 E(e.context.adapter,e.context.orgOptions).findFullOrganization(r,e.context.db||void 0);if(!n)throw new me("BAD_REQUEST",{message:"Organization not found"});return e.json(n)}),Zt=c("/organization/activate",{method:"POST",body:S.object({orgId:S.string().nullable().optional()}),use:[j,L]},async e=>{let t=E(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 me("FORBIDDEN",{message:"You are not a member of this organization"});await t.setActiveOrganization(r.session.id,o);let i=await t.findFullOrganization(o,e.context.db||void 0);return e.json(i)}),Yt=c("/organization/list",{method:"GET",use:[L,j]},async e=>{let r=await E(e.context.adapter,e.context.orgOptions).listOrganizations(e.context.session.user.id);return e.json(r)});var Sc=e=>{let t={createOrganization:Wt,updateOrganization:Kt,deleteOrganization:Gt,setActiveOrganization:Zt,getFullOrganization:Jt,listOrganization:Yt,createInvitation:Ft,cancelInvitation:$t,acceptInvitation:Mt,getInvitation:Vt,rejectInvitation:qt,removeMember:Qt,updateMemberRole:Ht},r={...Ze,...e?.roles};return{id:"organization",endpoints:{..._t(t,{orgOptions:e||{},roles:r,getSession:async n=>await H(n)}),hasPermission:c("/organization/has-permission",{method:"POST",requireHeaders:!0,body:Ee.object({permission:Ee.record(Ee.string(),Ee.array(Ee.string()))}),use:[j]},async n=>{if(!n.context.session.session.activeOrganizationId)throw new Xt("BAD_REQUEST",{message:"No active organization"});let a=await E(n.context.adapter).findMemberByOrgId({userId:n.context.session.user.id,organizationId:n.context.session.session.activeOrganizationId||""});if(!a)throw new Xt("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 Pe}from"zod";import{APIError as fe}from"better-call";var Ve="two-factor";var Qe="trust-device";import{z as er}from"zod";var ge=_({body:er.object({trustDevice:er.boolean().optional()})},async e=>{let t=e.context.createAuthCookie(Ve),r=await e.getSignedCookie(t.name,e.context.secret);if(!r)throw new fe("UNAUTHORIZED",{message:"invalid two factor cookie"});let[o,n]=r.split("!");if(!o||!n)throw new fe("UNAUTHORIZED",{message:"invalid two factor cookie"});let i=await e.context.adapter.findMany({model:"session",where:[{field:"userId",value:o}]});if(!i.length)throw new fe("UNAUTHORIZED",{message:"invalid session"});let a=i.filter(s=>s.expiresAt>new Date);if(!a)throw new fe("UNAUTHORIZED",{message:"invalid session"});for(let s of a){let d=await K(e.context.secret,s.id),u=await e.context.adapter.findOne({model:"user",where:[{field:"id",value:s.userId}]});if(!u)throw new fe("UNAUTHORIZED",{message:"invalid session"});if(d===n)return{valid:async()=>{if(await b(e,s.id,!1),e.body.trustDevice){let l=e.context.createAuthCookie(Qe,{maxAge:2592e3}),p=await K(e.context.secret,`${u.id}!${s.id}`);await e.setSignedCookie(l.name,`${p}!${s.id}`,e.context.secret,l.options)}return e.json({session:s,user:u})},invalid:async()=>{throw new fe("UNAUTHORIZED",{message:"invalid two factor authentication"})},session:{id:s.id,userId:s.userId,expiresAt:s.expiresAt,user:u}}}throw new fe("UNAUTHORIZED",{message:"invalid two factor authentication"})});import{APIError as Se}from"better-call";function yo(e){return Array.from({length:e?.amount??10}).fill(null).map(()=>F(e?.length??10,M("a-z","0-9"))).map(t=>`${t.slice(0,5)}-${t.slice(5)}`)}async function Xe(e,t){let r=e,o=t?.customBackupCodesGenerate?t.customBackupCodesGenerate():yo(),n=await Fe({data:JSON.stringify(o),key:r});return{backupCodes:o,encryptedBackupCodes:n}}async function bo(e,t){let r=await tr(e.backupCodes,t);return r?r.includes(e.code):!1}async function tr(e,t){let r=Buffer.from(await Me({key:t,data:e})).toString("utf-8"),o=JSON.parse(r),n=Pe.array(Pe.string()).safeParse(o);return n.success?n.data:null}var rr=(e,t)=>({id:"backup_code",endpoints:{verifyBackupCode:c("/two-factor/verify-backup-code",{method:"POST",body:Pe.object({code:Pe.string(),disableSession:Pe.boolean().optional()}),use:[ge]},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 Se("BAD_REQUEST",{message:"Backup codes aren't enabled"});if(!bo({backupCodes:n.backupCodes,code:r.body.code},r.context.secret))throw new Se("BAD_REQUEST",{message:"Invalid backup code"});return r.body.disableSession||await b(r,r.context.session.id),r.json({user:o,session:r.context.session})}),generateBackupCodes:c("/two-factor/generate-backup-codes",{method:"POST",use:[y]},async r=>{if(!r.context.session.user.twoFactorEnabled)throw new Se("BAD_REQUEST",{message:"Two factor isn't enabled"});let n=await Xe(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:[y]},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 Se("BAD_REQUEST",{message:"Backup codes aren't enabled"});let i=tr(n.backupCodes,r.context.secret);if(!i)throw new Se("BAD_REQUEST",{message:"Backup codes aren't enabled"});return r.json({status:!0,backupCodes:i})})}});import{APIError as He}from"better-call";import{TOTPController as Ao}from"oslo/otp";import{z as or}from"zod";import{TimeSpan as ko}from"oslo";var nr=(e,t)=>{let r={...e,period:new ko(e?.period||3,"m")},o=new Ao({digits:6,period:r.period}),n=c("/two-factor/send-otp",{method:"POST",use:[ge]},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 s=a.context.session.user,d=await a.context.adapter.findOne({model:t,where:[{field:"userId",value:s.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(s,u),a.json({status:!0})}),i=c("/two-factor/verify-otp",{method:"POST",body:or.object({code:or.string()}),use:[ge]},async a=>{let s=a.context.session.user;if(!s.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:s.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:i}}};import{APIError as Ae}from"better-call";import{TimeSpan as Oo}from"oslo";import{TOTPController as ir,createTOTPKeyURI as Ro}from"oslo/otp";import{z as sr}from"zod";var ar=(e,t)=>{let r={...e,digits:6,period:new Oo(e?.period||30,"s")},o=c("/totp/generate",{method:"POST",use:[y]},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 Ae("BAD_REQUEST",{message:"totp isn't configured"});let s=a.context.session.user,d=await a.context.adapter.findOne({model:t,where:[{field:"userId",value:s.id}]});if(!d)throw new Ae("BAD_REQUEST",{message:"totp isn't enabled"});return{code:await new ir(r).generate(Buffer.from(d.secret))}}),n=c("/two-factor/get-totp-uri",{method:"GET",use:[y]},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 Ae("BAD_REQUEST",{message:"totp isn't configured"});let s=a.context.session.user,d=await a.context.adapter.findOne({model:t,where:[{field:"userId",value:s.id}]});if(!d||!s.twoFactorEnabled)throw new Ae("BAD_REQUEST",{message:"totp isn't enabled"});return{totpURI:Ro(e?.issuer||"BetterAuth",s.email,Buffer.from(d.secret),r)}}),i=c("/two-factor/verify-totp",{method:"POST",body:sr.object({code:sr.string()}),use:[ge]},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 Ae("BAD_REQUEST",{message:"totp isn't configured"});let s=a.context.session.user,d=await a.context.adapter.findOne({model:t,where:[{field:"userId",value:s.id}]});if(!d||!d.enabled)throw new Ae("BAD_REQUEST",{message:"totp isn't enabled"});let u=new ir(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:i}}};async function et(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 dr}from"better-call";var mu=(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 Uu=e=>{let t={twoFactorTable:e?.twoFactorTable||"twoFactor"},r=ar({issuer:e?.issuer||"better-auth",...e?.totpOptions},t.twoFactorTable),o=rr({...e?.backupCodeOptions},t.twoFactorTable),n=nr({...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:[y]},async i=>{let a=i.context.session.user,{password:s}=i.body;if(!await et(i,{password:s,userId:a.id}))throw new dr("BAD_REQUEST",{message:"Invalid password"});let u=F(16,M("a-z","0-9","-")),l=await Fe({key:i.context.secret,data:u}),p=await Xe(i.context.secret,e?.backupCodeOptions);return await i.context.internalAdapter.updateUser(a.id,{twoFactorEnabled:!0}),await i.context.adapter.create({model:t.twoFactorTable,data:{id:i.context.uuid(),secret:l,backupCodes:p.encryptedBackupCodes,userId:a.id}}),i.json({status:!0})}),disableTwoFactor:c("/two-factor/disable",{method:"POST",body:We.object({password:We.string().min(8)}),use:[y]},async i=>{let a=i.context.session.user,{password:s}=i.body;if(!await et(i,{password:s,userId:a.id}))throw new dr("BAD_REQUEST",{message:"Invalid password"});return await i.context.internalAdapter.updateUser(a.id,{twoFactorEnabled:!1}),await i.context.adapter.delete({model:t.twoFactorTable,where:[{field:"userId",value:a.id}]}),i.json({status:!0})})},options:e,hooks:{after:[{matcher(i){return i.path==="/sign-in/email"||i.path==="/sign-in/username"},handler:_(async i=>{let a=i.context.returned;if(a?.status!==200)return;let s=await a.clone().json();if(!s.user.twoFactorEnabled)return;let d=i.context.createAuthCookie(Qe,{maxAge:30*24*60*60}),u=await i.getSignedCookie(d.name,i.context.secret);if(u){let[m,f]=u.split("!"),h=await K(i.context.secret,`${s.user.id}!${f}`);if(m===h){let R=await K(i.context.secret,`${s.user.id}!${s.session.id}`);await i.setSignedCookie(d.name,`${R}!${s.session.id}`,i.context.secret,d.options);return}}i.setCookie(i.context.authCookies.sessionToken.name,"",{path:"/",sameSite:"lax",httpOnly:!0,secure:!1,maxAge:0});let l=await K(i.context.secret,s.session.id),p=i.context.createAuthCookie(Ve,{maxAge:60*60*24});return await i.setSignedCookie(p.name,`${s.session.userId}!${l}`,i.context.secret,p.options),{response:new Response(JSON.stringify({twoFactorRedirect:!0}),{headers:i.responseHeader})}})}]},schema:{user:{fields:{twoFactorEnabled:{type:"boolean",required:!1,defaultValue:!1}}},twoFactor:{tableName:t.twoFactorTable,fields:{secret:{type:"string",required:!0,returned:!1},backupCodes:{type:"string",required:!0,returned:!1},userId:{type:"string",required:!0,returned:!1,references:{model:"user",field:"id"}}}}},rateLimit:[{pathMatcher(i){return i.startsWith("/two-factor/")},window:10,max:3}]}};import{generateAuthenticationOptions as Co,generateRegistrationOptions as _o,verifyAuthenticationResponse as zo,verifyRegistrationResponse as Bo}from"@simplewebauthn/server";import{APIError as Z}from"better-call";import{z as re}from"zod";import{WebAuthnError as Uo,startAuthentication as To,startRegistration as Eo}from"@simplewebauthn/browser";import{createFetch as ju}from"@better-fetch/fetch";import"nanostores";import{betterFetch as Pu}from"@better-fetch/fetch";import{atom as Ju}from"nanostores";import"@better-fetch/fetch";import{atom as Io,onMount as vo}from"nanostores";var tt=(e,t,r,o)=>{let n=Io({data:null,error:null,isPending:!1,isRefetching:!1}),i=()=>{let s=typeof o=="function"?o({data:n.get().data,error:n.get().error,isPending:n.get().isPending}):o;return r(t,{...s,onSuccess:async d=>{n.set({data:d.data,error:null,isPending:!1,isRefetching:!1}),await s?.onSuccess?.(d)},async onError(d){n.set({error:d.error,data:null,isPending:!1,isRefetching:!1}),await s?.onError?.(d)},async onRequest(d){let u=n.get();n.set({isPending:u.data===null,data:u.data,error:null,isRefetching:!0}),await s?.onRequest?.(d)}})};e=Array.isArray(e)?e:[e];let a=!1;for(let s of e)s.subscribe(()=>{a?i():vo(n,()=>(i(),a=!0,()=>{n.off(),s.off()}))});return n};import{atom as So}from"nanostores";var Po=(e,{_listPasskeys:t})=>({signIn:{passkey:async(n,i)=>{let a=await e("/passkey/generate-authenticate-options",{method:"POST",body:{email:n?.email}});if(!a.data)return a;try{let s=await To(a.data,n?.autoFill||!1),d=await e("/passkey/verify-authentication",{body:{response:s},...n?.fetchOptions,...i,method:"POST"});if(!d.data)return d}catch(s){console.log(s)}}},passkey:{addPasskey:async(n,i)=>{let a=await e("/passkey/generate-register-options",{method:"GET"});if(!a.data)return a;try{let s=await Eo(a.data),d=await e("/passkey/verify-registration",{...n?.fetchOptions,...i,body:{response:s,name:n?.name},method:"POST"});if(!d.data)return d;t.set(Math.random())}catch(s){return s instanceof Uo?s.code==="ERROR_AUTHENTICATOR_PREVIOUSLY_REGISTERED"?{data:null,error:{message:"previously registered",status:400,statusText:"BAD_REQUEST"}}:s.code==="ERROR_CEREMONY_ABORTED"?{data:null,error:{message:"registration cancelled",status:400,statusText:"BAD_REQUEST"}}:{data:null,error:{message:s.message,status:400,statusText:"BAD_REQUEST"}}:{data:null,error:{message:s instanceof Error?s.message:"unknown error",status:500,statusText:"INTERNAL_SERVER_ERROR"}}}}},$Infer:{}}),gl=()=>{let e=So();return{id:"passkey",$InferServerPlugin:{},getActions:t=>Po(t,{_listPasskeys:e}),getAtoms(t){return{listPasskeys:tt(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 Tl=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),i=new Date,a=Math.floor((n.getTime()-i.getTime())/1e3);return{id:"passkey",endpoints:{generatePasskeyRegistrationOptions:c("/passkey/generate-register-options",{method:"GET",use:[y],metadata:{client:!1}},async s=>{let d=s.context.session,u=await s.context.adapter.findMany({model:"passkey",where:[{field:"userId",value:d.user.id}]}),l=new Uint8Array(Buffer.from(F(32,M("a-z","0-9")))),p;p=await _o({rpName:o.rpName||s.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 O=P();return await s.setSignedCookie(o.advanced.webAuthnChallengeCookie,O,s.context.secret,{secure:!0,httpOnly:!0,sameSite:"lax",maxAge:a}),await s.context.internalAdapter.createVerificationValue({identifier:O,value:JSON.stringify({expectedChallenge:p.challenge,userData:{id:d.user.id}}),expiresAt:n}),s.json(p,{status:200})}),generatePasskeyAuthenticationOptions:c("/passkey/generate-authenticate-options",{method:"POST",body:re.object({email:re.string().optional()}).optional()},async s=>{let d=await H(s),u=[];d&&(u=await s.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||""}},O=P();return await s.setSignedCookie(o.advanced.webAuthnChallengeCookie,O,s.context.secret,{secure:!0,httpOnly:!0,sameSite:"lax",maxAge:a}),await s.context.internalAdapter.createVerificationValue({identifier:O,value:JSON.stringify(p),expiresAt:n}),s.json(l,{status:200})}),verifyPasskeyRegistration:c("/passkey/verify-registration",{method:"POST",body:re.object({response:re.any(),name:re.string().optional()}),use:[y]},async s=>{let d=e?.origin||s.headers?.get("origin")||"";if(!d)return s.json(null,{status:400});let u=s.body.response,l=await s.getSignedCookie(o.advanced.webAuthnChallengeCookie,s.context.secret);if(!l)throw new Z("BAD_REQUEST",{message:"Challenge not found"});let p=await s.context.internalAdapter.findVerificationValue(l);if(!p)return s.json(null,{status:400});let{expectedChallenge:O,userData:m}=JSON.parse(p.value);if(m.id!==s.context.session.user.id)throw new Z("UNAUTHORIZED",{message:"You are not authorized to register this passkey"});try{let f=await Bo({response:u,expectedChallenge:O,expectedOrigin:d,expectedRPID:e?.rpID}),{verified:h,registrationInfo:R}=f;if(!h||!R)return s.json(null,{status:400});let{credentialID:I,credentialPublicKey:ee,counter:ne,credentialDeviceType:k,credentialBackedUp:N}=R,ie=Buffer.from(ee).toString("base64"),x=P(),ze={name:s.body.name,userId:m.id,webauthnUserID:x,id:I,publicKey:ie,counter:ne,deviceType:k,transports:u.response.transports.join(","),backedUp:N,createdAt:new Date},gr=await s.context.adapter.create({model:"passkey",data:ze});return s.json(gr,{status:200})}catch(f){throw console.log(f),new Z("INTERNAL_SERVER_ERROR",{message:"Failed to verify registration"})}}),verifyPasskeyAuthentication:c("/passkey/verify-authentication",{method:"POST",body:re.object({response:re.any()})},async s=>{let d=e?.origin||s.headers?.get("origin")||"";if(!d)throw new Z("BAD_REQUEST",{message:"origin missing"});let u=s.body.response,l=await s.getSignedCookie(o.advanced.webAuthnChallengeCookie,s.context.secret);if(!l)throw new Z("BAD_REQUEST",{message:"Challenge not found"});let p=await s.context.internalAdapter.findVerificationValue(l);if(!p)throw new Z("BAD_REQUEST",{message:"Challenge not found"});let{expectedChallenge:O}=JSON.parse(p.value),m=await s.context.adapter.findOne({model:"passkey",where:[{field:"id",value:u.id}]});if(!m)throw new Z("UNAUTHORIZED",{message:"Passkey not found"});try{let f=await zo({response:u,expectedChallenge:O,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 Z("UNAUTHORIZED",{message:"Authentication failed"});await s.context.adapter.update({model:"passkey",where:[{field:"id",value:m.id}],update:{counter:f.authenticationInfo.newCounter}});let R=await s.context.internalAdapter.createSession(m.userId,s.request);if(!R)throw new Z("INTERNAL_SERVER_ERROR",{message:"Unable to create session"});return await b(s,R.id),s.json({session:R},{status:200})}catch(f){throw s.context.logger.error(f),new Z("BAD_REQUEST",{message:"Failed to verify authentication"})}}),listPasskeys:c("/passkey/list-user-passkeys",{method:"GET",use:[y]},async s=>{let d=await s.context.adapter.findMany({model:"passkey",where:[{field:"userId",value:s.context.session.user.id}]});return s.json(d,{status:200})}),deletePasskey:c("/passkey/delete-passkey",{method:"POST",body:re.object({id:re.string()}),use:[y]},async s=>(await s.context.adapter.delete({model:"passkey",where:[{field:"id",value:s.body.id}]}),s.json(null,{status:200})))},schema:{passkey:{fields:{name:{type:"string",required:!1},publicKey:{type:"string",required:!0},userId:{type:"string",references:{model:"user",field:"id"},required:!0},webauthnUserID:{type:"string",required:!0},counter:{type:"number",required:!0},deviceType:{type:"string",required:!0},backedUp:{type:"boolean",required:!0},transports:{type:"string",required:!1},createdAt:{type:"date",defaultValue:new Date,required:!1}}}}}};import{z as Y}from"zod";import{APIError as Ke}from"better-call";var cr=()=>({id:"username",endpoints:{signInUsername:c("/sign-in/username",{method:"POST",body:Y.object({username:Y.string(),password:Y.string(),dontRememberMe:Y.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:cr}),new Ke("UNAUTHORIZED",{message:"Invalid username or password"});let r=await e.context.adapter.findOne({model:"account",where:[{field:e.context.tables.account.fields.userId.fieldName||"userId",value:t.id},{field:e.context.tables.account.fields.type.fieldName||"providerId",value:"credential"}]});if(!r)throw new Ke("UNAUTHORIZED",{message:"Invalid username or password"});let o=r?.password;if(!o)throw e.context.logger.error("Password not found",{username:cr}),new Ke("UNAUTHORIZED",{message:"Unexpected error"});if(!await e.context.password.verify(o,e.body.password))throw e.context.logger.error("Invalid password"),new Ke("UNAUTHORIZED",{message:"Invalid username or password"});let i=await e.context.internalAdapter.createSession(t.id,e.request);return i?(await e.setSignedCookie(e.context.authCookies.sessionToken.name,i.id,e.context.secret,e.body.dontRememberMe?{...e.context.authCookies.sessionToken.options,maxAge:void 0}:e.context.authCookies.sessionToken.options),e.json({user:t,session:i})):e.json(null,{status:500,body:{message:"Failed to create session",status:500}})}),signUpUsername:c("/sign-up/username",{method:"POST",body:Y.object({username:Y.string().min(3).max(20),name:Y.string(),email:Y.string().email(),password:Y.string(),image:Y.string().optional()})},async e=>{let t=await ve()({...e,_flag:"json"}),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 Lo}from"better-call";var Dl=()=>({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 Lo("",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 ke}from"zod";import{APIError as Do}from"better-call";var Vl=e=>({id:"magic-link",endpoints:{signInMagicLink:c("/sign-in/magic-link",{method:"POST",requireHeaders:!0,body:ke.object({email:ke.string().email(),callbackURL:ke.string().optional()}),use:[z]},async t=>{let{email:r}=t.body,o=F(32,M("a-z","A-Z"));await t.context.internalAdapter.createVerificationValue({identifier:o,value:r,expiresAt:new Date(Date.now()+(e.expiresIn||60*5)*1e3)});let n=`${t.context.baseURL}/magic-link/verify?token=${o}&callbackURL=${t.body.callbackURL||"/"}`;try{await e.sendMagicLink({email:r,url:n,token:o})}catch(i){throw t.context.logger.error("Failed to send magic link",i),new Do("INTERNAL_SERVER_ERROR",{message:"Failed to send magic link"})}return t.json({status:!0})}),magicLinkVerify:c("/magic-link/verify",{method:"GET",query:ke.object({token:ke.string(),callbackURL:ke.string().optional()}),requireHeaders:!0},async t=>{let{token:r,callbackURL:o}=t.query,n=o?.startsWith("http")?o:o?`${t.context.options.baseURL}${o}`:t.context.options.baseURL,i=await t.context.internalAdapter.findVerificationValue(r);if(!i)throw t.redirect(`${n}?error=INVALID_TOKEN`);if(i.expiresAt<new Date)throw await t.context.internalAdapter.deleteVerificationValue(i.id),t.redirect(`${n}?error=EXPIRED_TOKEN`);await t.context.internalAdapter.deleteVerificationValue(i.id);let a=i.value,s=await t.context.internalAdapter.findUserByEmail(a),d=s?.user.id||"";if(!s){if(e.disableSignUp)throw t.redirect(`${n}?error=USER_NOT_FOUND`);if(d=(await t.context.internalAdapter.createUser({email:a,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 b(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 rt(e){return F(e,M("0-9"))}var tp=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:r.context.tables.account.fields.userId.fieldName||"userId",value:o.id},{field:r.context.tables.account.fields.providerId.fieldName||"providerId",value:"credential"}]});if(!n)throw new D("UNAUTHORIZED",{message:"Invalid email or password"});let i=n?.password;if(!i)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(i,r.body.password))throw r.context.logger.error("Invalid password"),new D("UNAUTHORIZED",{message:"Invalid email or password"});let s=await r.context.internalAdapter.createSession(o.id,r.request);return s?(await r.setSignedCookie(r.context.authCookies.sessionToken.name,s.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:s})):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=rt(e?.otp?.otpLength||6);await r.context.internalAdapter.createVerificationValue({value:a,identifier:r.body.phoneNumber,expiresAt:q(t.otp.expiresIn,"sec")}),await e.otp.sendOTP(r.body.phoneNumber,a)}let i=await r.context.internalAdapter.updateUserByEmail(n.user.email,{[t.phoneNumber]:r.body.phoneNumber});return r.json({user:i,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=rt(e?.otp?.otpLength||6);return await r.context.internalAdapter.createVerificationValue({value:o,identifier:r.body.phoneNumber,expiresAt:q(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 i=await r.context.internalAdapter.updateUser(n.id,{[t.phoneNumberVerified]:!0});if(e?.enableAutoSignIn&&!await H(r)){let s=await r.context.internalAdapter.createSession(n.id,r.request);if(!s)throw new D("INTERNAL_SERVER_ERROR",{message:"Failed to create session"});return await b(r,s.id),r.json({user:i,session:s})}return r.json({user:i,session:null})}),updatePhoneNumber:c("/phone-number/update",{method:"POST",body:C.object({phoneNumber:C.string()}),use:[y]},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=rt(e?.otp?.otpLength||6);await r.context.adapter.create({model:r.context.tables.verification.tableName,data:{code:n,phoneNumber:r.body.phoneNumber,createdAt:q(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 ot}from"zod";var dp=e=>({id:"anonymous",endpoints:{signInAnonymous:c("/sign-in/anonymous",{method:"POST"},async t=>{let{emailDomainName:r=lt(t.context.baseURL)}=e||{},o=P(),n=`temp-${o}@${r}`,i=await t.context.internalAdapter.createUser({id:o,email:n,emailVerified:!1,isAnonymous:!0,name:"Anonymous",createdAt:new Date,updatedAt:new Date});if(!i)return t.json(null,{status:500,body:{message:"Failed to create user",status:500}});let a=await t.context.internalAdapter.createSession(i.id,t.request);return a?(await b(t,a.id),t.json({user:i,session:a})):t.json(null,{status:400,body:{message:"Could not create session"}})}),linkAnonymous:c("/user/link-anonymous",{method:"POST",body:ot.object({email:ot.string().email().optional(),password:ot.string().min(6)}),use:[y]},async t=>{let r=t.context.session.user.id,{email:o,password:n}=t.body,i=null;if(o&&n&&(i=await t.context.internalAdapter.updateUser(r,{email:o})),!i)return t.json(null,{status:500,body:{message:"Failed to update user",status:500}});let a=await t.context.password.hash(n);if(!await t.context.internalAdapter.linkAccount({userId:i.id,providerId:"credential",password:a,accountId:i.id}))return t.json(null,{status:500,body:{message:"Failed to update account",status:500}});let d=await t.context.internalAdapter.createSession(i.id,t.request);return d?(await b(t,d.id),t.json({session:d,user:i})):t.json(null,{status:400,body:{message:"Could not create session"}})})},schema:{user:{fields:{isAnonymous:{type:"boolean",defaultValue:!0,required:!1}}}}});import{z as g}from"zod";var X=_(async e=>{let t=await H(e);if(!t?.session)throw new de("UNAUTHORIZED");let r=t.user;if(r.role!=="admin")throw new de("FORBIDDEN",{message:"Only admins can access this endpoint"});return{session:{user:r,session:t.session}}}),fp=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:_(async t=>{let r=t.context.returned;if(r){let n=(await r.json()).filter(a=>!a.impersonatedBy),i=new Response(JSON.stringify(n),{status:200,statusText:"OK",headers:r.headers});return t.json({response:i})}})}]},endpoints:{setRole:c("/admin/set-role",{method:"POST",body:g.object({userId:g.string(),role:g.string()}),use:[X]},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.string(),data:g.optional(g.record(g.any()))}),use:[X]},async t=>{if(await t.context.internalAdapter.findUserByEmail(t.body.email))throw new de("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 de("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:[X],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:[X],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:[X]},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:[X]},async t=>{if(t.body.userId===t.context.session.user.id)throw new de("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:[X]},async t=>{let r=await t.context.internalAdapter.findUserById(t.body.userId);if(!r)throw new de("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?q(e.impersonationSessionDuration,"sec"):q(60*60,"sec")});if(!o)throw new de("INTERNAL_SERVER_ERROR",{message:"Failed to create session"});return await b(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:[X]},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:[X]},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:[X]},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 oe}from"zod";import{APIError as Ce}from"better-call";import{betterFetch as nt}from"@better-fetch/fetch";import{generateCodeVerifier as xo}from"oslo/oauth2";import{parseJWT as jo}from"oslo/jwt";async function No(e,t,r){if(t==="oidc"&&e.idToken){let n=jo(e.idToken);if(n?.payload)return n.payload}return r?(await nt(r,{method:"GET",headers:{Authorization:`Bearer ${e.accessToken}`}})).data:null}var Cp=e=>({id:"generic-oauth",endpoints:{signInWithOAuth2:c("/sign-in/oauth2",{method:"POST",query:oe.object({currentURL:oe.string().optional()}).optional(),body:oe.object({providerId:oe.string(),callbackURL:oe.string().optional()}),use:[z]},async t=>{let{providerId:r}=t.body,o=e.config.find(x=>x.providerId===r);if(!o)throw new Ce("BAD_REQUEST",{message:`No config found for provider ${r}`});let{discoveryUrl:n,authorizationUrl:i,tokenUrl:a,clientId:s,clientSecret:d,scopes:u,redirectURI:l,responseType:p,pkce:O,prompt:m,accessType:f}=o,h=i,R=a;if(n){let x=await nt(n,{onError(ze){A.error(ze.error,{discoveryUrl:n})}});x.data&&(h=x.data.authorization_endpoint,R=x.data.token_endpoint)}if(!h||!R)throw new Ce("BAD_REQUEST",{message:"Invalid OAuth configuration."});let I=t.query?.currentURL?new URL(t.query?.currentURL):null,ee=t.body.callbackURL?.startsWith("http")?t.body.callbackURL:`${I?.origin}${t.body.callbackURL||""}`,ne=await De(ee||I?.origin||t.context.options.baseURL),k=t.context.authCookies;await t.setSignedCookie(k.state.name,ne.hash,t.context.secret,k.state.options);let N=xo();await t.setSignedCookie(k.pkCodeVerifier.name,N,t.context.secret,k.pkCodeVerifier.options);let ie=await B({id:r,options:{clientId:s,clientSecret:d,redirectURI:l},authorizationEndpoint:h,state:ne.raw,codeVerifier:N,scopes:u||[],disablePkce:!O,redirectURI:`${t.context.baseURL}/oauth2/callback/${r}`});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:ne,codeVerifier:N,redirect:!0}}),oAuth2Callback:c("/oauth2/callback/:providerId",{method:"GET",query:oe.object({code:oe.string().optional(),error:oe.string().optional(),state:oe.string()})},async t=>{if(t.query.error||!t.query.code){let N=he(t.query.state).data?.currentURL||`${t.context.baseURL}/error`;throw t.context.logger.error(t.query.error,t.params.providerId),t.redirect(`${N}?error=${t.query.error||"oAuth_code_missing"}`)}let r=e.config.find(k=>k.providerId===t.params.providerId);if(!r)throw new Ce("BAD_REQUEST",{message:`No config found for provider ${t.params.providerId}`});let o=await t.getSignedCookie(t.context.authCookies.pkCodeVerifier.name,t.context.secret),n,i=he(t.query.state);if(!i.success)throw t.redirect(`${t.context.baseURL}/error?error=invalid_state`);let a=t.query.state,{data:{callbackURL:s,currentURL:d,code:u}}=i,l=i.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 Be(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 k=await nt(r.discoveryUrl,{method:"GET"});k.data&&(m=k.data.token_endpoint,f=k.data.userinfo_endpoint)}try{if(!m)throw new Ce("BAD_REQUEST",{message:"Invalid OAuth configuration."});n=await U({code:u,codeVerifier:o,redirectURI:`${t.context.baseURL}/oauth2/callback/${r.providerId}`,options:{clientId:r.clientId,clientSecret:r.clientSecret},tokenEndpoint:m})}catch(k){throw t.context.logger.error(k),t.redirect(`${l}?error=oauth_code_verification_failed`)}if(!n)throw new Ce("BAD_REQUEST",{message:"Invalid OAuth configuration."});let h=r.getUserInfo?await r.getUserInfo(n):await No(n,r.type||"oauth2",f),R=P(),I=h?xe.safeParse({...h,id:R}):null;if(!I?.success)throw t.redirect(`${l}?error=oauth_user_info_invalid`);let ee=await t.context.internalAdapter.findUserByEmail(I.data.email).catch(k=>{throw A.error(`Better auth was unable to query your database.
|
|
84
|
+
Error: `,k),t.redirect(`${l}?error=internal_server_error`)}),ne=ee?.user.id||R;if(ee){let k=ee.accounts.find(x=>x.providerId===r.providerId),N=t.context.options.account?.accountLinking?.trustedProviders,ie=N?N.includes(r.providerId):!0;if(!k&&(!I?.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(!k)try{await t.context.internalAdapter.linkAccount({providerId:r.providerId,accountId:I.data.id,id:`${r.providerId}:${I.data.id}`,userId:ee.user.id,...we(n)})}catch(x){throw console.log(x),t.redirect(`${l}?error=failed_linking_account`)}}else try{await t.context.internalAdapter.createOAuthUser(I.data,{...we(n),id:`${r.providerId}:${I.data.id}`,providerId:r.providerId,accountId:I.data.id,userId:ne})}catch{let N=new URL(l);throw N.searchParams.set("error","unable_to_create_user"),t.setHeader("Location",N.toString()),t.redirect(N.toString())}try{let k=await t.context.internalAdapter.createSession(ne||R,t.request);if(!k)throw t.redirect(`${l}?error=unable_to_create_session`);await b(t,k.id)}catch{throw t.redirect(`${l}?error=unable_to_create_session`)}throw t.redirect(s||d||"")})}});import{z as _e}from"zod";var ur={jwks:{fields:{publicKey:{type:"string",required:!0},privateKey:{type:"string",required:!0},createdAt:{type:"date",required:!0}}}},Bp=_e.object({id:_e.string(),publicKey:_e.string(),privateKey:_e.string(),createdAt:_e.date()});var it=e=>({getAllKeys:async()=>await e.findMany({model:"jwks"}),getLatestKey:async()=>(await e.findMany({model:"jwks",sortBy:{field:"createdAt",direction:"desc"},limit:1}))[0],createJwk:async t=>await e.create({model:"jwks",data:{...t,createdAt:new Date}})});import{exportJWK as fr,generateKeyPair as Vo,importJWK as Qo,SignJWT as Ho}from"jose";import{createCipheriv as Fo,createDecipheriv as Mo,createHash as qo,randomBytes as $o}from"crypto";function lr(e){let t;return Buffer.byteLength(e,"utf8")===32?t=Buffer.from(e,"utf8"):t=qo("sha256").update(e).digest(),t}function pr(e,t){let r=lr(t),o=$o(12),n=Fo("aes-256-gcm",r,o),i=n.update(e,"utf8","base64");i+=n.final("base64");let a=n.getAuthTag();return{encryptedPrivateKey:i,iv:o.toString("base64"),authTag:a.toString("base64")}}function mr(e,t){let r=lr(t),{encryptedPrivateKey:o,iv:n,authTag:i}=e,a=Buffer.from(n,"base64"),s=Buffer.from(i,"base64"),d=Mo("aes-256-gcm",r,a);d.setAuthTag(s);let u=d.update(o,"base64","utf8");return u+=d.final("utf8"),u}var Vp=e=>({id:"jwt",endpoints:{getJwks:c("/jwks",{method:"GET"},async t=>{let o=await it(t.context.adapter).getAllKeys();return t.json({keys:o.map(n=>({...JSON.parse(n.publicKey),kid:n.id}))})}),getToken:c("/token",{method:"GET",requireHeaders:!0,use:[y]},async t=>{let r=it(t.context.adapter),o=await r.getLatestKey(),n=!e?.jwks?.disablePrivateKeyEncryption;if(o===void 0){let{publicKey:u,privateKey:l}=await Vo(e?.jwks?.keyPairConfig?.alg??"EdDSA",e?.jwks?.keyPairConfig??{crv:"Ed25519"}),p=await fr(u),O=await fr(l),m=JSON.stringify(O),f={id:crypto.randomUUID(),publicKey:JSON.stringify(p),privateKey:n?JSON.stringify(pr(m,t.context.options.secret)):m,createdAt:new Date};o=await r.createJwk(f)}let i=n?mr(JSON.parse(o.privateKey),t.context.options.secret):o.privateKey,a=await Qo(JSON.parse(i)),s=e?.jwt?.definePayload?await e?.jwt.definePayload(t.context.session.user):t.context.session.user,d=await new Ho({...s,...t.context.session.session.impersonatedBy?{impersonatedBy:t.context.session.session.impersonatedBy}:{}}).setProtectedHeader({alg:e?.jwks?.keyPairConfig?.alg??"EdDSA"}).setIssuedAt().setIssuer(e?.jwt?.issuer??t.context.options.baseURL).setAudience(e?.jwt?.audience??t.context.options.baseURL).setExpirationTime(e?.jwt?.expirationTime??"15m").setSubject(t.context.session.user.id).sign(a);return t.json({token:d})})},schema:ur});export{ae as HIDE_METADATA,jt as ac,fp as admin,X as adminMiddleware,dp as anonymous,Dl as bearer,c as createAuthEndpoint,_ as createAuthMiddleware,Cp as genericOAuth,Po as getPasskeyActions,Vp as jwt,Vl as magicLink,at as optionsMiddleware,Sc as organization,Tl as passkey,gl as passkeyClient,tp as phoneNumber,Uu as twoFactor,mu as twoFactorClient,cr 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-
|
|
6
|
+
import './auth-BGQTSAwN.js';
|
|
7
7
|
import 'kysely';
|
|
8
8
|
import './schema-Dkt0LqYs.js';
|
|
9
9
|
import 'better-call';
|
package/dist/solid-start.d.ts
CHANGED
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-
|
|
6
|
+
import './auth-BGQTSAwN.js';
|
|
7
7
|
import 'kysely';
|
|
8
8
|
import './schema-Dkt0LqYs.js';
|
|
9
9
|
import 'better-call';
|
package/dist/svelte-kit.d.ts
CHANGED
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-
|
|
6
|
+
import './auth-BGQTSAwN.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 {
|
|
2
|
-
export { A as Adapter, j as AdditionalSessionFieldsInput, k as AdditionalSessionFieldsOutput, h as AdditionalUserFieldsInput, i as AdditionalUserFieldsOutput, p as AuthContext,
|
|
1
|
+
import { b as BetterAuthPlugin, a as Auth, O as InferFieldsInputClient, M as InferFieldsOutput } from './auth-BGQTSAwN.js';
|
|
2
|
+
export { A as Adapter, j as AdditionalSessionFieldsInput, k as AdditionalSessionFieldsOutput, h as AdditionalUserFieldsInput, i as AdditionalUserFieldsOutput, p as AuthContext, B as BetterAuthOptions, G as GenericEndpointContext, H as HookEndpointContext, m as InferPluginTypes, l as InferSession, I as InferUser, P as PluginSchema, R as RateLimit, S as SecondaryStorage, W as Where, n as init } from './auth-BGQTSAwN.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-
|
|
6
|
+
import './auth-BGQTSAwN.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.11-beta.
|
|
3
|
+
"version": "0.4.11-beta.3",
|
|
4
4
|
"description": "The most comprehensive authentication library for TypeScript.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|
|
@@ -86,6 +86,7 @@
|
|
|
86
86
|
"nanoid": "^5.0.7",
|
|
87
87
|
"nanostores": "^0.11.2",
|
|
88
88
|
"oslo": "^1.2.1",
|
|
89
|
+
"jose": "^5.9.4",
|
|
89
90
|
"zod": "^3.22.5"
|
|
90
91
|
},
|
|
91
92
|
"files": [
|