appos 0.4.1-0 → 0.4.3-0
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/exports/api/index.d.mts +5 -4
- package/dist/exports/api/index.mjs +88 -11
- package/dist/exports/api/orm.d.mts +1 -1
- package/dist/exports/api/orm.mjs +1 -1
- package/dist/exports/api/workflows/index.d.mts +4 -3
- package/dist/exports/api/workflows/index.mjs +2 -2
- package/dist/exports/app-context-B1VJ9qnH.mjs +3 -0
- package/dist/exports/auth-By0xx0MI.d.mts +759 -0
- package/dist/exports/cli/index.d.mts +4 -3
- package/dist/exports/cli/index.mjs +82 -103
- package/dist/exports/{index-B3m3Uvsl.d.mts → index-Bpo5QE7k.d.mts} +469 -875
- package/dist/exports/{instrumentation-CTl5Q8ky.mjs → instrumentation-DkoLNAtz.mjs} +14 -8
- package/dist/exports/instrumentation.d.mts +1 -1
- package/dist/exports/instrumentation.mjs +1 -1
- package/dist/exports/{mock-CURQkGUm.mjs → mock-2jMk5l3y.mjs} +1 -1
- package/dist/exports/{openapi-C7QT3gNU.mjs → openapi-crG3j4xx.mjs} +113 -11
- package/dist/exports/{orm-CQk1S10H.d.mts → orm-CJrd147z.d.mts} +1 -1
- package/dist/exports/{orm-BYSfGzG0.mjs → orm-COJ9l6sS.mjs} +1 -1
- package/dist/exports/{send-email-Do8SjZL7.mjs → send-email-Bgcdjy-e.mjs} +13 -1
- package/dist/exports/{server-6XZo256O.mjs → server-BlNxgHUc.mjs} +11 -9
- package/dist/exports/ssr-BsfNjYlJ.mjs +16 -0
- package/dist/exports/tests/api.d.mts +4 -3
- package/dist/exports/tests/api.mjs +7 -7
- package/dist/exports/tests/mock.mjs +1 -1
- package/dist/exports/vite/index.mjs +1 -1
- package/dist/exports/web/index.d.ts +919 -461
- package/dist/exports/web/index.js +809 -299
- package/dist/exports/web/routes.d.mts +137 -0
- package/dist/exports/web/routes.mjs +137 -0
- package/dist/exports/web/ssr.d.mts +7 -200
- package/dist/exports/web/ssr.mjs +2 -2
- package/package.json +9 -2
- package/src/web/routes/auth/_layout.tsx +19 -7
- package/src/web/routes/auth/forgot-password.tsx +3 -1
- package/src/web/routes/auth/phone-otp.tsx +1 -2
- package/src/web/routes/auth/utils.ts +30 -170
- package/src/web/ui/locales/en/ui.json +37 -3
- package/src/web/ui/locales/zh-CN/ui.json +37 -3
- package/src/web/ui/locales/zh-TW/ui.json +37 -3
- package/dist/exports/app-context-deZa7oJC.mjs +0 -3
- package/dist/exports/ssr-CVebWWYi.mjs +0 -163
- /package/dist/exports/{app-context-DoFRTUi5.mjs → app-context-LF4QmPUC.mjs} +0 -0
- /package/dist/exports/{chunk-Db_DmN2K.mjs → chunk-CHSICr2d.mjs} +0 -0
- /package/dist/exports/{constants-DbBfpyC3.mjs → constants-BePPc_yF.mjs} +0 -0
- /package/dist/exports/{instrumentation-B0Ev9PvT.d.mts → instrumentation-CFIspF8-.d.mts} +0 -0
- /package/dist/exports/{vite-compat-CeAU9UrA.mjs → vite-compat-CICObU9F.mjs} +0 -0
- /package/dist/exports/{youch-handler-BEWxHUsu.mjs → youch-handler-CHwX0Fou.mjs} +0 -0
|
@@ -0,0 +1,759 @@
|
|
|
1
|
+
import { betterAuth } from "better-auth";
|
|
2
|
+
import { Role, createAccessControl } from "better-auth/plugins/access";
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
import * as drizzle_orm0 from "drizzle-orm";
|
|
5
|
+
import { AnyRelations, EmptyRelations } from "drizzle-orm";
|
|
6
|
+
import { PgTable } from "drizzle-orm/pg-core";
|
|
7
|
+
import * as drizzle_orm_node_postgres0 from "drizzle-orm/node-postgres";
|
|
8
|
+
import * as pg0 from "pg";
|
|
9
|
+
import pg from "pg";
|
|
10
|
+
import pino, { LoggerOptions } from "pino";
|
|
11
|
+
import { MigrationConfig } from "drizzle-orm/migrator";
|
|
12
|
+
|
|
13
|
+
//#region src/api/logger.d.ts
|
|
14
|
+
/**
|
|
15
|
+
* Extended logger options with OpenTelemetry support.
|
|
16
|
+
*/
|
|
17
|
+
interface DefineLoggerOptions extends LoggerOptions {}
|
|
18
|
+
/**
|
|
19
|
+
* The logger instance type.
|
|
20
|
+
*/
|
|
21
|
+
type Logger = Awaited<ReturnType<typeof defineLogger>>;
|
|
22
|
+
/**
|
|
23
|
+
* Define the logger instance.
|
|
24
|
+
*
|
|
25
|
+
* @param opts - The options.
|
|
26
|
+
* @returns The logger.
|
|
27
|
+
*/
|
|
28
|
+
declare function defineLogger(opts: DefineLoggerOptions): Promise<pino.Logger<never, boolean>>;
|
|
29
|
+
//#endregion
|
|
30
|
+
//#region src/api/database.d.ts
|
|
31
|
+
type PoolConfig = pg.PoolConfig;
|
|
32
|
+
/**
|
|
33
|
+
* Extract qualified table names from db object.
|
|
34
|
+
*/
|
|
35
|
+
type QualifiedTableNames<TDb> = { [K in keyof TDb]: TDb[K] extends {
|
|
36
|
+
_: {
|
|
37
|
+
fullSchema: infer S;
|
|
38
|
+
};
|
|
39
|
+
} ? `${K & string}.${keyof S & string}` : never }[keyof TDb];
|
|
40
|
+
/**
|
|
41
|
+
* The schema used for migrations.
|
|
42
|
+
*/
|
|
43
|
+
declare const migrationsSchema = "public";
|
|
44
|
+
/**
|
|
45
|
+
* The type of migration (schema or data).
|
|
46
|
+
*/
|
|
47
|
+
type MigrationType = "schema" | "data";
|
|
48
|
+
/**
|
|
49
|
+
* Get the migration options for a specific database.
|
|
50
|
+
*
|
|
51
|
+
* @param name Name of the database to get migration options for
|
|
52
|
+
* @param type Type of migration (schema or data), defaults to "schema"
|
|
53
|
+
* @returns Migration configuration for drizzle-orm
|
|
54
|
+
*/
|
|
55
|
+
declare function defineMigrationOpts(name: string, type?: MigrationType): MigrationConfig;
|
|
56
|
+
/**
|
|
57
|
+
* Options for defining the database.
|
|
58
|
+
*/
|
|
59
|
+
interface DefineDatabaseOptions<TSchema extends Record<string, unknown> = Record<string, never>, TRelations extends AnyRelations = EmptyRelations> {
|
|
60
|
+
logger: Logger;
|
|
61
|
+
poolConfig: PoolConfig;
|
|
62
|
+
relations?: TRelations;
|
|
63
|
+
schema?: TSchema;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* The database type.
|
|
67
|
+
*/
|
|
68
|
+
type Database = Awaited<ReturnType<typeof defineDatabase>>;
|
|
69
|
+
/**
|
|
70
|
+
* Generate old and new row JSONB representations for delete/insert/update queries.
|
|
71
|
+
* Uses PostgreSQL 18's OLD/NEW support in RETURNING clause.
|
|
72
|
+
*
|
|
73
|
+
* @param table The table to generate changes for.
|
|
74
|
+
* @returns Object containing `_table`, `old` and `new` JSONB columns.
|
|
75
|
+
*/
|
|
76
|
+
declare function dbChanges<T extends PgTable>(table: T): {
|
|
77
|
+
_table: drizzle_orm0.SQL.Aliased<string>;
|
|
78
|
+
old: drizzle_orm0.SQL.Aliased<({ [Key in keyof T["_"]["columns"] & string]: T["_"]["columns"][Key]["_"]["notNull"] extends true ? T["_"]["columns"][Key]["_"]["data"] : T["_"]["columns"][Key]["_"]["data"] | null } extends infer T_1 ? { [K in keyof T_1]: T_1[K] } : never) | null>;
|
|
79
|
+
new: drizzle_orm0.SQL.Aliased<({ [Key in keyof T["_"]["columns"] & string]: T["_"]["columns"][Key]["_"]["notNull"] extends true ? T["_"]["columns"][Key]["_"]["data"] : T["_"]["columns"][Key]["_"]["data"] | null } extends infer T_2 ? { [K in keyof T_2]: T_2[K] } : never) | null>;
|
|
80
|
+
};
|
|
81
|
+
/**
|
|
82
|
+
* Define the database with the provided options.
|
|
83
|
+
*
|
|
84
|
+
* Algorithm:
|
|
85
|
+
* 1. Create a connection pool with sensible defaults
|
|
86
|
+
* 2. Initialize drizzle ORM with schema and relations
|
|
87
|
+
*
|
|
88
|
+
* @param opts The options for defining the database, including pool configuration, relations, and schema.
|
|
89
|
+
* @template TSchema The schema type for the database.
|
|
90
|
+
* @template TRelations The relations type for the database.
|
|
91
|
+
* @returns The defined database instance.
|
|
92
|
+
*/
|
|
93
|
+
declare function defineDatabase<TSchema extends Record<string, unknown> = Record<string, never>, TRelations extends AnyRelations = EmptyRelations>(opts: DefineDatabaseOptions<TSchema, TRelations>): Promise<drizzle_orm_node_postgres0.NodePgDatabase<TSchema, TRelations> & {
|
|
94
|
+
$client: pg0.Pool;
|
|
95
|
+
}>;
|
|
96
|
+
/**
|
|
97
|
+
* Options for defining a test database.
|
|
98
|
+
*/
|
|
99
|
+
interface DefineTestDatabaseOptions<TSchema extends Record<string, unknown> = Record<string, never>, TRelations extends AnyRelations = EmptyRelations> {
|
|
100
|
+
connectionString: string;
|
|
101
|
+
logger: Logger;
|
|
102
|
+
name: string;
|
|
103
|
+
schema: TSchema;
|
|
104
|
+
relations: TRelations;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Create a single test database with isolated schema.
|
|
108
|
+
*
|
|
109
|
+
* @param connectionString - Database connection string
|
|
110
|
+
* @param name - Name of the test database
|
|
111
|
+
* @returns Test database instance and cleanup function
|
|
112
|
+
*/
|
|
113
|
+
declare function defineTestDatabase<TSchema extends Record<string, unknown> = Record<string, never>, TRelations extends AnyRelations = EmptyRelations>(opts: DefineTestDatabaseOptions<TSchema, TRelations>): Promise<{
|
|
114
|
+
cleanUp: () => Promise<void>;
|
|
115
|
+
db: drizzle_orm_node_postgres0.NodePgDatabase<TSchema, TRelations> & {
|
|
116
|
+
$client: pg0.Pool;
|
|
117
|
+
};
|
|
118
|
+
dbName: string;
|
|
119
|
+
}>;
|
|
120
|
+
//#endregion
|
|
121
|
+
//#region src/web/client/auth-paths.d.ts
|
|
122
|
+
/**
|
|
123
|
+
* Configuration for authentication route paths.
|
|
124
|
+
*
|
|
125
|
+
* All paths should be absolute (starting with "/").
|
|
126
|
+
* These paths are used for both route generation and navigation.
|
|
127
|
+
*/
|
|
128
|
+
interface AuthPaths {
|
|
129
|
+
/**
|
|
130
|
+
* Path to the login page.
|
|
131
|
+
*
|
|
132
|
+
* @default "/login"
|
|
133
|
+
*/
|
|
134
|
+
login: string;
|
|
135
|
+
/**
|
|
136
|
+
* Path to the signup/registration page.
|
|
137
|
+
*
|
|
138
|
+
* @default "/signup"
|
|
139
|
+
*/
|
|
140
|
+
signup: string;
|
|
141
|
+
/**
|
|
142
|
+
* Path to the email verification page.
|
|
143
|
+
* Only used when email verification is enabled.
|
|
144
|
+
*
|
|
145
|
+
* @default "/verify-email"
|
|
146
|
+
*/
|
|
147
|
+
verifyEmail: string;
|
|
148
|
+
/**
|
|
149
|
+
* Path to the forgot password page.
|
|
150
|
+
*
|
|
151
|
+
* @default "/forgot-password"
|
|
152
|
+
*/
|
|
153
|
+
forgotPassword: string;
|
|
154
|
+
/**
|
|
155
|
+
* Path to the password reset page.
|
|
156
|
+
*
|
|
157
|
+
* @default "/reset-password"
|
|
158
|
+
*/
|
|
159
|
+
resetPassword: string;
|
|
160
|
+
/**
|
|
161
|
+
* Path to the phone OTP login page.
|
|
162
|
+
* Only generated when phone OTP is enabled in auth config.
|
|
163
|
+
*
|
|
164
|
+
* @default "/phone-login"
|
|
165
|
+
*/
|
|
166
|
+
phoneOtp: string;
|
|
167
|
+
/**
|
|
168
|
+
* Path to the email OTP login page.
|
|
169
|
+
* Only generated when email OTP is enabled in auth config.
|
|
170
|
+
*
|
|
171
|
+
* @default "/email-login"
|
|
172
|
+
*/
|
|
173
|
+
emailOtp: string;
|
|
174
|
+
}
|
|
175
|
+
//#endregion
|
|
176
|
+
//#region src/api/auth.d.ts
|
|
177
|
+
/**
|
|
178
|
+
* Type for access controller created via createAccessControl().
|
|
179
|
+
* Used for RBAC on both server and client.
|
|
180
|
+
*/
|
|
181
|
+
type AccessController = ReturnType<typeof createAccessControl>;
|
|
182
|
+
/**
|
|
183
|
+
* Type for roles created via ac.newRole().
|
|
184
|
+
*/
|
|
185
|
+
type AccessControlRoles = Record<string, Role>;
|
|
186
|
+
/**
|
|
187
|
+
* Standard audit log actions following OCSF/CADF standards. Zod enum provides
|
|
188
|
+
* both runtime validation and TypeScript type.
|
|
189
|
+
*
|
|
190
|
+
* Actions:
|
|
191
|
+
* - Data ops: INSERT, UPDATE, DELETE, TRUNCATE, SELECT
|
|
192
|
+
* - Auth ops: LOGIN, LOGOUT, LOGIN_FAILED, PASSWORD_CHANGE
|
|
193
|
+
* - Custom: CUSTOM (use customAction field for app-specific events)
|
|
194
|
+
*/
|
|
195
|
+
declare const auditActionSchema: z.ZodEnum<{
|
|
196
|
+
DELETE: "DELETE";
|
|
197
|
+
LOGIN: "LOGIN";
|
|
198
|
+
LOGOUT: "LOGOUT";
|
|
199
|
+
INSERT: "INSERT";
|
|
200
|
+
PASSWORD_CHANGE: "PASSWORD_CHANGE";
|
|
201
|
+
TRUNCATE: "TRUNCATE";
|
|
202
|
+
UPDATE: "UPDATE";
|
|
203
|
+
}>;
|
|
204
|
+
/**
|
|
205
|
+
* TypeScript type extracted from Zod enum.
|
|
206
|
+
*/
|
|
207
|
+
type AuditAction = z.infer<typeof auditActionSchema>;
|
|
208
|
+
/**
|
|
209
|
+
* Type-safe audit log options for defineAuth().
|
|
210
|
+
*
|
|
211
|
+
* @template TDb - Database record type for table name inference
|
|
212
|
+
*/
|
|
213
|
+
type AuditLogOptions<TDb> = {
|
|
214
|
+
/**
|
|
215
|
+
* Tables to exclude from audit logging.
|
|
216
|
+
*/
|
|
217
|
+
excludeTables?: QualifiedTableNames<TDb>[];
|
|
218
|
+
/**
|
|
219
|
+
* Cron expression for purge schedule.
|
|
220
|
+
*
|
|
221
|
+
* @default "0 0 * * *"
|
|
222
|
+
*/
|
|
223
|
+
purgeCron?: string;
|
|
224
|
+
/**
|
|
225
|
+
* Retention period in days. Audit logs older than this are auto-deleted.
|
|
226
|
+
* @default 90
|
|
227
|
+
*/
|
|
228
|
+
retentionDays?: number;
|
|
229
|
+
};
|
|
230
|
+
/**
|
|
231
|
+
* Neutral auth configuration - shared between server and client.
|
|
232
|
+
* Contains ONLY fields that affect both sides (UI + server features).
|
|
233
|
+
*
|
|
234
|
+
* PRESENCE-BASED CONFIG: If a key exists, it's enabled. No redundant `enabled` fields.
|
|
235
|
+
* Server-only fields (appName, session) are passed via DefineAuthOptions.
|
|
236
|
+
*/
|
|
237
|
+
interface AuthConfig {
|
|
238
|
+
/**
|
|
239
|
+
* Base URL where auth server is hosted.
|
|
240
|
+
*
|
|
241
|
+
* @default "" (same origin - client uses relative URLs)
|
|
242
|
+
* @example "http://localhost:8000" for cross-origin
|
|
243
|
+
*/
|
|
244
|
+
baseURL?: string;
|
|
245
|
+
/**
|
|
246
|
+
* Base path for auth routes.
|
|
247
|
+
*
|
|
248
|
+
* @default "/auth"
|
|
249
|
+
*/
|
|
250
|
+
basePath?: string;
|
|
251
|
+
/**
|
|
252
|
+
* Custom paths for authentication pages.
|
|
253
|
+
*
|
|
254
|
+
* @example
|
|
255
|
+
* ```typescript
|
|
256
|
+
* paths: {
|
|
257
|
+
* login: "/signin",
|
|
258
|
+
* signup: "/register",
|
|
259
|
+
* }
|
|
260
|
+
* ```
|
|
261
|
+
*/
|
|
262
|
+
paths?: Partial<AuthPaths>;
|
|
263
|
+
/**
|
|
264
|
+
* Authentication methods - if defined, it's enabled.
|
|
265
|
+
**/
|
|
266
|
+
methods?: {
|
|
267
|
+
/**
|
|
268
|
+
* Email/password auth. If defined, enabled.
|
|
269
|
+
**/
|
|
270
|
+
emailPassword?: {
|
|
271
|
+
requireEmailVerification?: boolean;
|
|
272
|
+
minPasswordLength?: number;
|
|
273
|
+
maxPasswordLength?: number;
|
|
274
|
+
};
|
|
275
|
+
/**
|
|
276
|
+
* Magic link auth. If defined, enabled.
|
|
277
|
+
**/
|
|
278
|
+
magicLink?: {
|
|
279
|
+
expiresIn?: number;
|
|
280
|
+
};
|
|
281
|
+
/**
|
|
282
|
+
* Passkey auth. If defined (even as empty object), enabled.
|
|
283
|
+
**/
|
|
284
|
+
passkey?: Record<string, never>;
|
|
285
|
+
/**
|
|
286
|
+
* Phone OTP auth. If defined, enabled.
|
|
287
|
+
**/
|
|
288
|
+
phoneOtp?: {
|
|
289
|
+
otpLength?: number;
|
|
290
|
+
expiresIn?: number;
|
|
291
|
+
};
|
|
292
|
+
/**
|
|
293
|
+
* Email OTP auth. If defined, enabled.
|
|
294
|
+
**/
|
|
295
|
+
emailOtp?: {
|
|
296
|
+
otpLength?: number;
|
|
297
|
+
expiresIn?: number;
|
|
298
|
+
};
|
|
299
|
+
};
|
|
300
|
+
/**
|
|
301
|
+
* OAuth providers - true = enabled, undefined/false = disabled.
|
|
302
|
+
**/
|
|
303
|
+
oauth?: {
|
|
304
|
+
google?: boolean;
|
|
305
|
+
github?: boolean;
|
|
306
|
+
apple?: boolean;
|
|
307
|
+
facebook?: boolean;
|
|
308
|
+
};
|
|
309
|
+
/**
|
|
310
|
+
* Plugins - if defined, it's enabled.
|
|
311
|
+
**/
|
|
312
|
+
plugins?: {
|
|
313
|
+
/**
|
|
314
|
+
* Admin plugin. If defined, enabled. Includes RBAC for both server and client.
|
|
315
|
+
**/
|
|
316
|
+
admin?: {
|
|
317
|
+
defaultRole?: string;
|
|
318
|
+
adminRoles?: string[];
|
|
319
|
+
/**
|
|
320
|
+
* Access controller created via createAccessControl().
|
|
321
|
+
**/
|
|
322
|
+
ac: AccessController;
|
|
323
|
+
/**
|
|
324
|
+
* Role definitions created via ac.newRole().
|
|
325
|
+
**/
|
|
326
|
+
roles: AccessControlRoles;
|
|
327
|
+
};
|
|
328
|
+
/**
|
|
329
|
+
* API key plugin. If defined, enabled.
|
|
330
|
+
**/
|
|
331
|
+
apiKey?: {
|
|
332
|
+
defaultPrefix?: string;
|
|
333
|
+
defaultKeyLength?: number;
|
|
334
|
+
rateLimit?: {
|
|
335
|
+
maxRequests?: number;
|
|
336
|
+
timeWindow?: number;
|
|
337
|
+
};
|
|
338
|
+
};
|
|
339
|
+
/**
|
|
340
|
+
* Two-factor plugin. If defined, enabled. Sub-features also presence-based.
|
|
341
|
+
**/
|
|
342
|
+
twoFactor?: {
|
|
343
|
+
issuer?: string;
|
|
344
|
+
totp?: {
|
|
345
|
+
digits?: 6 | 8;
|
|
346
|
+
period?: number;
|
|
347
|
+
};
|
|
348
|
+
otp?: boolean;
|
|
349
|
+
backupCodes?: {
|
|
350
|
+
amount?: number;
|
|
351
|
+
length?: number;
|
|
352
|
+
};
|
|
353
|
+
};
|
|
354
|
+
/**
|
|
355
|
+
* Multi-session plugin. If defined, enabled.
|
|
356
|
+
**/
|
|
357
|
+
multiSession?: {
|
|
358
|
+
/**
|
|
359
|
+
* Maximum number of active sessions per user.
|
|
360
|
+
*/
|
|
361
|
+
maximumSessions?: number;
|
|
362
|
+
};
|
|
363
|
+
/**
|
|
364
|
+
* Username plugin. If defined, enabled.
|
|
365
|
+
**/
|
|
366
|
+
username?: {
|
|
367
|
+
minUsernameLength?: number;
|
|
368
|
+
maxUsernameLength?: number;
|
|
369
|
+
};
|
|
370
|
+
/**
|
|
371
|
+
* Anonymous auth plugin. If defined, enabled.
|
|
372
|
+
**/
|
|
373
|
+
anonymous?: {
|
|
374
|
+
emailDomainName?: string;
|
|
375
|
+
};
|
|
376
|
+
/**
|
|
377
|
+
* SSO plugin. If defined, enabled.
|
|
378
|
+
**/
|
|
379
|
+
sso?: {
|
|
380
|
+
providersLimit?: number;
|
|
381
|
+
trustEmailVerified?: boolean;
|
|
382
|
+
domainVerification?: boolean;
|
|
383
|
+
};
|
|
384
|
+
};
|
|
385
|
+
/**
|
|
386
|
+
* Brand configuration for auth pages.
|
|
387
|
+
* Controls the logo and app name displayed on authentication screens.
|
|
388
|
+
*/
|
|
389
|
+
brand?: {
|
|
390
|
+
/**
|
|
391
|
+
* Logo URL or path relative to the public folder.
|
|
392
|
+
*
|
|
393
|
+
* @default "/logo.png"
|
|
394
|
+
*/
|
|
395
|
+
logo?: string;
|
|
396
|
+
/**
|
|
397
|
+
* Alt text for the logo image.
|
|
398
|
+
*
|
|
399
|
+
* @default App name or "Logo"
|
|
400
|
+
*/
|
|
401
|
+
logoAlt?: string;
|
|
402
|
+
/**
|
|
403
|
+
* App or brand name displayed next to the logo.
|
|
404
|
+
*
|
|
405
|
+
* @default "AppOS"
|
|
406
|
+
*/
|
|
407
|
+
name?: string;
|
|
408
|
+
};
|
|
409
|
+
/**
|
|
410
|
+
* Rate limiting configuration for auth endpoints.
|
|
411
|
+
* Uses database storage for horizontal scaling support.
|
|
412
|
+
* Set to false to disable.
|
|
413
|
+
*
|
|
414
|
+
* @default { enabled: true, window: 60, max: 100 }
|
|
415
|
+
*
|
|
416
|
+
* @example
|
|
417
|
+
* ```typescript
|
|
418
|
+
* // Default - enabled with sensible defaults
|
|
419
|
+
* rateLimit: undefined
|
|
420
|
+
*
|
|
421
|
+
* // Custom limits
|
|
422
|
+
* rateLimit: { window: 30, max: 50 }
|
|
423
|
+
*
|
|
424
|
+
* // Override specific endpoint limits
|
|
425
|
+
* rateLimit: {
|
|
426
|
+
* customRules: {
|
|
427
|
+
* "/send-verification-email": { window: 60, max: 10 },
|
|
428
|
+
* },
|
|
429
|
+
* }
|
|
430
|
+
*
|
|
431
|
+
* // Disable completely
|
|
432
|
+
* rateLimit: false
|
|
433
|
+
* ```
|
|
434
|
+
*/
|
|
435
|
+
rateLimit?: {
|
|
436
|
+
/** Enable rate limiting. @default true */
|
|
437
|
+
enabled?: boolean;
|
|
438
|
+
/** Time window in seconds. @default 60 */
|
|
439
|
+
window?: number;
|
|
440
|
+
/** Max requests per window. @default 100 */
|
|
441
|
+
max?: number;
|
|
442
|
+
/** Custom rate limits per endpoint. Merged with defaults. */
|
|
443
|
+
customRules?: Record<string, {
|
|
444
|
+
window: number;
|
|
445
|
+
max: number;
|
|
446
|
+
}>;
|
|
447
|
+
} | false;
|
|
448
|
+
}
|
|
449
|
+
/** Base hook types for reference */
|
|
450
|
+
type EmailHook = (params: {
|
|
451
|
+
email: string;
|
|
452
|
+
url: string;
|
|
453
|
+
token: string;
|
|
454
|
+
}) => Promise<void>;
|
|
455
|
+
type OtpHook = (params: {
|
|
456
|
+
email: string;
|
|
457
|
+
otp: string;
|
|
458
|
+
}) => Promise<void>;
|
|
459
|
+
type PhoneOtpHook = (params: {
|
|
460
|
+
phoneNumber: string;
|
|
461
|
+
otp: string;
|
|
462
|
+
}) => Promise<void>;
|
|
463
|
+
/**
|
|
464
|
+
* Conditionally required hooks based on config.
|
|
465
|
+
*/
|
|
466
|
+
type RequiredHooks<T extends AuthConfig> = (T["methods"] extends {
|
|
467
|
+
emailPassword: {
|
|
468
|
+
requireEmailVerification: true;
|
|
469
|
+
};
|
|
470
|
+
} ? {
|
|
471
|
+
sendVerificationEmail: EmailHook;
|
|
472
|
+
} : {
|
|
473
|
+
sendVerificationEmail?: EmailHook;
|
|
474
|
+
}) & (T["methods"] extends {
|
|
475
|
+
emailPassword: object;
|
|
476
|
+
} ? {
|
|
477
|
+
sendResetPasswordEmail: EmailHook;
|
|
478
|
+
} : {
|
|
479
|
+
sendResetPasswordEmail?: EmailHook;
|
|
480
|
+
}) & (T["methods"] extends {
|
|
481
|
+
magicLink: object;
|
|
482
|
+
} ? {
|
|
483
|
+
sendMagicLink: EmailHook;
|
|
484
|
+
} : {
|
|
485
|
+
sendMagicLink?: EmailHook;
|
|
486
|
+
}) & (T["methods"] extends {
|
|
487
|
+
emailOtp: object;
|
|
488
|
+
} ? {
|
|
489
|
+
sendEmailOTP: OtpHook;
|
|
490
|
+
} : {
|
|
491
|
+
sendEmailOTP?: OtpHook;
|
|
492
|
+
}) & (T["methods"] extends {
|
|
493
|
+
phoneOtp: object;
|
|
494
|
+
} ? {
|
|
495
|
+
sendPhoneOTP: PhoneOtpHook;
|
|
496
|
+
} : {
|
|
497
|
+
sendPhoneOTP?: PhoneOtpHook;
|
|
498
|
+
}) & (T["plugins"] extends {
|
|
499
|
+
twoFactor: {
|
|
500
|
+
otp: true;
|
|
501
|
+
};
|
|
502
|
+
} ? {
|
|
503
|
+
send2FAOTP: OtpHook;
|
|
504
|
+
} : {
|
|
505
|
+
send2FAOTP?: OtpHook;
|
|
506
|
+
});
|
|
507
|
+
/**
|
|
508
|
+
* Conditionally required OAuth credentials based on config.
|
|
509
|
+
* If an OAuth provider is enabled in config, its credentials are REQUIRED.
|
|
510
|
+
*/
|
|
511
|
+
type RequiredOAuth<T extends AuthConfig> = (T["oauth"] extends {
|
|
512
|
+
google: true;
|
|
513
|
+
} ? {
|
|
514
|
+
google: {
|
|
515
|
+
clientId: string;
|
|
516
|
+
clientSecret: string;
|
|
517
|
+
};
|
|
518
|
+
} : {
|
|
519
|
+
google?: {
|
|
520
|
+
clientId: string;
|
|
521
|
+
clientSecret: string;
|
|
522
|
+
};
|
|
523
|
+
}) & (T["oauth"] extends {
|
|
524
|
+
github: true;
|
|
525
|
+
} ? {
|
|
526
|
+
github: {
|
|
527
|
+
clientId: string;
|
|
528
|
+
clientSecret: string;
|
|
529
|
+
};
|
|
530
|
+
} : {
|
|
531
|
+
github?: {
|
|
532
|
+
clientId: string;
|
|
533
|
+
clientSecret: string;
|
|
534
|
+
};
|
|
535
|
+
}) & (T["oauth"] extends {
|
|
536
|
+
apple: true;
|
|
537
|
+
} ? {
|
|
538
|
+
apple: {
|
|
539
|
+
clientId: string;
|
|
540
|
+
clientSecret: string;
|
|
541
|
+
};
|
|
542
|
+
} : {
|
|
543
|
+
apple?: {
|
|
544
|
+
clientId: string;
|
|
545
|
+
clientSecret: string;
|
|
546
|
+
};
|
|
547
|
+
}) & (T["oauth"] extends {
|
|
548
|
+
facebook: true;
|
|
549
|
+
} ? {
|
|
550
|
+
facebook: {
|
|
551
|
+
clientId: string;
|
|
552
|
+
clientSecret: string;
|
|
553
|
+
};
|
|
554
|
+
} : {
|
|
555
|
+
facebook?: {
|
|
556
|
+
clientId: string;
|
|
557
|
+
clientSecret: string;
|
|
558
|
+
};
|
|
559
|
+
});
|
|
560
|
+
/**
|
|
561
|
+
* Check if any OAuth provider is enabled.
|
|
562
|
+
**/
|
|
563
|
+
type HasOAuthEnabled<T extends AuthConfig> = T["oauth"] extends {
|
|
564
|
+
google: true;
|
|
565
|
+
} | {
|
|
566
|
+
github: true;
|
|
567
|
+
} | {
|
|
568
|
+
apple: true;
|
|
569
|
+
} | {
|
|
570
|
+
facebook: true;
|
|
571
|
+
} ? true : false;
|
|
572
|
+
/**
|
|
573
|
+
* Check if passkey is enabled
|
|
574
|
+
**/
|
|
575
|
+
type HasPasskeyEnabled<T extends AuthConfig> = T["methods"] extends {
|
|
576
|
+
passkey: object;
|
|
577
|
+
} ? true : false;
|
|
578
|
+
/**
|
|
579
|
+
* Server-only session configuration.
|
|
580
|
+
*/
|
|
581
|
+
interface AuthSessionConfig {
|
|
582
|
+
/**
|
|
583
|
+
* Session duration in seconds.
|
|
584
|
+
*
|
|
585
|
+
* @default 604800 (7 days)
|
|
586
|
+
*/
|
|
587
|
+
expiresIn?: number;
|
|
588
|
+
/**
|
|
589
|
+
* How often to update session in seconds.
|
|
590
|
+
*
|
|
591
|
+
* @default 86400 (1 day)
|
|
592
|
+
*/
|
|
593
|
+
updateAge?: number;
|
|
594
|
+
/**
|
|
595
|
+
* Session freshness in seconds for sensitive ops.
|
|
596
|
+
*
|
|
597
|
+
* @default 86400 (1 day)
|
|
598
|
+
*/
|
|
599
|
+
freshAge?: number;
|
|
600
|
+
}
|
|
601
|
+
/**
|
|
602
|
+
* Server-only passkey configuration (required if passkey is enabled).
|
|
603
|
+
*/
|
|
604
|
+
interface AuthPasskeyConfig {
|
|
605
|
+
/**
|
|
606
|
+
* Relying Party ID - domain for passkey (e.g., "example.com" or "localhost").
|
|
607
|
+
*/
|
|
608
|
+
rpID: string;
|
|
609
|
+
/**
|
|
610
|
+
* Origin URL for passkey verification (e.g., "http://localhost:8000").
|
|
611
|
+
*/
|
|
612
|
+
origin: string;
|
|
613
|
+
}
|
|
614
|
+
/**
|
|
615
|
+
* Fully type-safe options for defineAuth().
|
|
616
|
+
*
|
|
617
|
+
* Server-only fields:
|
|
618
|
+
* - `appName` - Application name for passkey rpName, TOTP issuer, emails
|
|
619
|
+
* - `auditLog` - Audit logging configuration
|
|
620
|
+
* - `session` - Session duration and freshness settings
|
|
621
|
+
*
|
|
622
|
+
* Conditional requirements:
|
|
623
|
+
* - If config has `oauth.google: true`, then `oauth.google` credentials are REQUIRED
|
|
624
|
+
* - If config has `methods.magicLink` defined, then `hooks.sendMagicLink` is REQUIRED
|
|
625
|
+
*
|
|
626
|
+
* @template T - Auth config type
|
|
627
|
+
* @template TDb - Database record type for type-safe excludeTables
|
|
628
|
+
*/
|
|
629
|
+
type DefineAuthOptions<T extends AuthConfig, TDb = unknown> = {
|
|
630
|
+
/**
|
|
631
|
+
* The application name.
|
|
632
|
+
*/
|
|
633
|
+
appName: string;
|
|
634
|
+
/**
|
|
635
|
+
* Audit logging configuration (server-only). Use qualified table names: "dbName.tableName".
|
|
636
|
+
*/
|
|
637
|
+
auditLog?: AuditLogOptions<TDb>;
|
|
638
|
+
/**
|
|
639
|
+
* The neutral auth configuration.
|
|
640
|
+
*/
|
|
641
|
+
config: T;
|
|
642
|
+
/**
|
|
643
|
+
* Full db object (container.db) for type inference.
|
|
644
|
+
*/
|
|
645
|
+
db: TDb;
|
|
646
|
+
/**
|
|
647
|
+
* Primary database for Better Auth storage.
|
|
648
|
+
*/
|
|
649
|
+
database: Database;
|
|
650
|
+
/**
|
|
651
|
+
* Hooks for email sending and OTP delivery.
|
|
652
|
+
*/
|
|
653
|
+
hooks: RequiredHooks<T>;
|
|
654
|
+
/**
|
|
655
|
+
* Secret key for signing tokens and cookies.
|
|
656
|
+
*/
|
|
657
|
+
secret: string;
|
|
658
|
+
/**
|
|
659
|
+
* Session configuration.
|
|
660
|
+
*/
|
|
661
|
+
session?: AuthSessionConfig;
|
|
662
|
+
/**
|
|
663
|
+
* URL to redirect users when auth errors occur (e.g., OAuth failures).
|
|
664
|
+
*
|
|
665
|
+
* Better Auth automatically appends `?error=...&error_description=...`
|
|
666
|
+
* query params to this URL when redirecting.
|
|
667
|
+
*
|
|
668
|
+
* @default "/login"
|
|
669
|
+
*/
|
|
670
|
+
errorURL?: string;
|
|
671
|
+
} & (HasOAuthEnabled<T> extends true ? {
|
|
672
|
+
oauth: RequiredOAuth<T>;
|
|
673
|
+
} : {
|
|
674
|
+
oauth?: RequiredOAuth<T>;
|
|
675
|
+
}) & (HasPasskeyEnabled<T> extends true ? {
|
|
676
|
+
passkey: AuthPasskeyConfig;
|
|
677
|
+
} : {
|
|
678
|
+
passkey?: AuthPasskeyConfig;
|
|
679
|
+
});
|
|
680
|
+
/**
|
|
681
|
+
* Rate limit rule for a single endpoint.
|
|
682
|
+
*/
|
|
683
|
+
type RateLimitRule = {
|
|
684
|
+
window: number;
|
|
685
|
+
max: number;
|
|
686
|
+
};
|
|
687
|
+
/**
|
|
688
|
+
* Default rate limits for endpoints that trigger costly 3rd party services.
|
|
689
|
+
* 3 requests per 60 seconds to prevent excessive email/SMS costs.
|
|
690
|
+
*/
|
|
691
|
+
declare const DEFAULT_COSTLY_RATE_LIMITS: {
|
|
692
|
+
readonly "/send-verification-email": {
|
|
693
|
+
readonly window: 60;
|
|
694
|
+
readonly max: 3;
|
|
695
|
+
};
|
|
696
|
+
readonly "/request-password-reset": {
|
|
697
|
+
readonly window: 60;
|
|
698
|
+
readonly max: 3;
|
|
699
|
+
};
|
|
700
|
+
readonly "/sign-in/magic-link": {
|
|
701
|
+
readonly window: 60;
|
|
702
|
+
readonly max: 3;
|
|
703
|
+
};
|
|
704
|
+
readonly "/email-otp/send-verification-otp": {
|
|
705
|
+
readonly window: 60;
|
|
706
|
+
readonly max: 3;
|
|
707
|
+
};
|
|
708
|
+
readonly "/two-factor/send-otp": {
|
|
709
|
+
readonly window: 60;
|
|
710
|
+
readonly max: 3;
|
|
711
|
+
};
|
|
712
|
+
readonly "/phone-number/send-otp": {
|
|
713
|
+
readonly window: 60;
|
|
714
|
+
readonly max: 3;
|
|
715
|
+
};
|
|
716
|
+
};
|
|
717
|
+
/**
|
|
718
|
+
* Default endpoint paths that have rate limiting applied.
|
|
719
|
+
*/
|
|
720
|
+
type DefaultRateLimitEndpoint = keyof typeof DEFAULT_COSTLY_RATE_LIMITS;
|
|
721
|
+
/**
|
|
722
|
+
* Creates endpoint-specific rate limit rules by merging user overrides with defaults.
|
|
723
|
+
* User overrides take precedence over defaults.
|
|
724
|
+
*
|
|
725
|
+
* @param overrides - Custom rate limits to override defaults (type-safe for default endpoints).
|
|
726
|
+
* @returns Merged rate limit rules.
|
|
727
|
+
*
|
|
728
|
+
* @see https://www.better-auth.com/docs/concepts/rate-limit
|
|
729
|
+
*
|
|
730
|
+
* @example
|
|
731
|
+
* ```typescript
|
|
732
|
+
* // Use defaults
|
|
733
|
+
* defineEndpointRateLimits()
|
|
734
|
+
*
|
|
735
|
+
* // Override specific endpoint (type-safe)
|
|
736
|
+
* defineEndpointRateLimits({
|
|
737
|
+
* "/send-verification-email": { window: 120, max: 5 },
|
|
738
|
+
* })
|
|
739
|
+
*
|
|
740
|
+
* // Add custom endpoint
|
|
741
|
+
* defineEndpointRateLimits({
|
|
742
|
+
* "/custom-endpoint": { window: 30, max: 10 },
|
|
743
|
+
* })
|
|
744
|
+
* ```
|
|
745
|
+
*/
|
|
746
|
+
declare function defineEndpointRateLimits(overrides?: Partial<Record<DefaultRateLimitEndpoint, RateLimitRule>> & Record<string, RateLimitRule>): Record<string, RateLimitRule>;
|
|
747
|
+
/**
|
|
748
|
+
* Defines Better Auth instance from neutral config + server dependencies.
|
|
749
|
+
*/
|
|
750
|
+
declare function defineAuth<T extends AuthConfig, TDb extends Record<"primary", Database> & Record<string, Database> = Record<"primary", Database> & Record<string, Database>>(opts: DefineAuthOptions<T, TDb>): ReturnType<typeof betterAuth> & {
|
|
751
|
+
auditLog?: AuditLogOptions<TDb>;
|
|
752
|
+
shouldAudit(tableName: QualifiedTableNames<TDb>): boolean;
|
|
753
|
+
};
|
|
754
|
+
/**
|
|
755
|
+
* The auth instance type.
|
|
756
|
+
*/
|
|
757
|
+
type Auth$1<TDb extends Record<"primary", Database> & Record<string, Database> = Record<"primary", Database> & Record<string, Database>> = ReturnType<typeof defineAuth<AuthConfig, TDb>>;
|
|
758
|
+
//#endregion
|
|
759
|
+
export { defineTestDatabase as C, defineLogger as D, Logger as E, defineMigrationOpts as S, DefineLoggerOptions as T, DefineTestDatabaseOptions as _, AuthConfig as a, dbChanges as b, DefineAuthOptions as c, createAccessControl as d, defineAuth as f, DefineDatabaseOptions as g, Database as h, Auth$1 as i, Role as l, AuthPaths as m, AccessController as n, AuthPasskeyConfig as o, defineEndpointRateLimits as p, AuditAction as r, AuthSessionConfig as s, AccessControlRoles as t, auditActionSchema as u, MigrationType as v, migrationsSchema as w, defineDatabase as x, QualifiedTableNames as y };
|