@lunora/auth 1.0.0-alpha.4 → 1.0.0-alpha.41
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/LICENSE.md +6 -0
- package/README.md +55 -0
- package/dist/adapter.d.mts +35 -35
- package/dist/adapter.d.ts +35 -35
- package/dist/adapter.mjs +1 -47
- package/dist/audit.d.mts +114 -0
- package/dist/audit.d.ts +114 -0
- package/dist/audit.mjs +11 -0
- package/dist/email-guard.d.mts +122 -0
- package/dist/email-guard.d.ts +122 -0
- package/dist/email-guard.mjs +1 -0
- package/dist/index.d.mts +460 -146
- package/dist/index.d.ts +460 -146
- package/dist/index.mjs +1 -12
- package/dist/middleware.d.mts +156 -155
- package/dist/middleware.d.ts +156 -155
- package/dist/middleware.mjs +1 -53
- package/dist/packem_shared/DEFAULT_AUTH_BASE_PATH-kIwlEt8i.mjs +1 -0
- package/dist/packem_shared/LunoraAuthAdminError-BiNYZM9j.mjs +1 -0
- package/dist/packem_shared/authAuditHook-Dx3sqf3G.mjs +1 -0
- package/dist/packem_shared/compileMigrationsSql-ChiudSmt.mjs +1 -0
- package/dist/packem_shared/create-auth.d-De6IOirt.d.mts +128 -0
- package/dist/packem_shared/create-auth.d-De6IOirt.d.ts +128 -0
- package/dist/packem_shared/createAuth-DS6PL8Mb.mjs +1 -0
- package/dist/packem_shared/emailGateDatabaseHooks-DzBD1Qoq.mjs +1 -0
- package/dist/packem_shared/sessionPresets-DpEFjXKV.mjs +1 -0
- package/dist/plugins-client.mjs +1 -2
- package/dist/plugins.mjs +1 -22
- package/dist/schema.d.mts +39 -39
- package/dist/schema.d.ts +39 -39
- package/dist/schema.mjs +1 -62
- package/dist/sql-store.d.mts +28 -28
- package/dist/sql-store.d.ts +28 -28
- package/dist/sql-store.mjs +1 -162
- package/dist/store.d.mts +49 -31
- package/dist/store.d.ts +49 -31
- package/dist/store.mjs +1 -170
- package/dist/turnstile-middleware.d.mts +55 -55
- package/dist/turnstile-middleware.d.ts +55 -55
- package/dist/turnstile-middleware.mjs +1 -45
- package/dist/turnstile.d.mts +42 -59
- package/dist/turnstile.d.ts +42 -59
- package/dist/turnstile.mjs +1 -61
- package/package.json +19 -6
- package/dist/packem_shared/DEFAULT_AUTH_BASE_PATH-DjcUWEQl.mjs +0 -11
- package/dist/packem_shared/LunoraAuthAdminError-BxrfEeA_.mjs +0 -249
- package/dist/packem_shared/compileMigrationsSql-wZH3oXDu.mjs +0 -28
- package/dist/packem_shared/create-auth.d-M36jwG_Y.d.mts +0 -58
- package/dist/packem_shared/create-auth.d-M36jwG_Y.d.ts +0 -58
- package/dist/packem_shared/createAuth-B-tvsvQU.mjs +0 -56
- package/dist/packem_shared/sessionPresets-B95rXrd8.mjs +0 -35
package/dist/index.d.ts
CHANGED
|
@@ -1,27 +1,34 @@
|
|
|
1
1
|
export { lunoraAuthAdapter, lunoraD1Adapter } from "./adapter.js";
|
|
2
|
-
import {
|
|
3
|
-
|
|
2
|
+
import { LunoraError } from '@lunora/errors';
|
|
3
|
+
import { L as LunoraAuth, a as LunoraAuthOptions } from "./packem_shared/create-auth.d-De6IOirt.js";
|
|
4
|
+
export { c as createAuth, r as resolveAuthOptions } from "./packem_shared/create-auth.d-De6IOirt.js";
|
|
5
|
+
import { AppendAuthAuditEntry, AppendAuthAuditOptions, AuthAuditEvent } from "./audit.js";
|
|
6
|
+
export { AUTH_AUDIT_TABLE, type AuthAuditEntry, type AuthAuditOutcome, type AuthAuditReader, type ReadAuthAuditOptions, appendAuthAuditEntry, createAuthAuditReader, ensureAuthAuditTable, readAuthAuditLog } from "./audit.js";
|
|
7
|
+
import { createAuthMiddleware } from 'better-auth/api';
|
|
8
|
+
import { SqlExecutor } from "./sql-store.js";
|
|
9
|
+
export { createSqlAuthStore, d1Executor } from "./sql-store.js";
|
|
10
|
+
import { BetterAuthOptions } from 'better-auth';
|
|
11
|
+
import { EmailClassification, EmailGateConfig } from "./email-guard.js";
|
|
12
|
+
export { type EmailClass, type EmailGateMiddlewareOptions, assertEmailAllowed, classifyEmail, emailGateMiddleware, loadEmailDomainLists } from "./email-guard.js";
|
|
4
13
|
export { type LunoraAuthApiContext, LunoraAuthHeadersError, type WithAuthPluginsMiddleware, type WithAuthPluginsOptions, withAuthPlugins } from "./middleware.js";
|
|
5
14
|
export { default as authTables } from "./schema.js";
|
|
6
|
-
import { BetterAuthOptions } from 'better-auth';
|
|
7
|
-
export { type SqlExecutor, createSqlAuthStore, d1Executor } from "./sql-store.js";
|
|
8
15
|
export { type AuthQuery, type AuthRow, type AuthStore, type AuthWhereClause, createMemoryAuthStore, matchesWhere } from "./store.js";
|
|
9
16
|
export { type FetchLike, TURNSTILE_VERIFY_ENDPOINT, type TurnstileVerifyResult, type VerifyTurnstileOptions, verifyTurnstile } from "./turnstile.js";
|
|
10
17
|
export { type VerifyTurnstileMiddlewareOptions, verifyTurnstileMiddleware } from "./turnstile-middleware.js";
|
|
11
18
|
import 'better-auth/adapters';
|
|
12
19
|
import '@lunora/server';
|
|
13
20
|
/**
|
|
14
|
-
* A timestamp as it leaves the admin API: epoch-ms (better-auth stores `Date`s,
|
|
15
|
-
* which we normalize on output) or `null` when the column is unset.
|
|
16
|
-
*/
|
|
21
|
+
* A timestamp as it leaves the admin API: epoch-ms (better-auth stores `Date`s,
|
|
22
|
+
* which we normalize on output) or `null` when the column is unset.
|
|
23
|
+
*/
|
|
17
24
|
type AuthTimestamp = null | number;
|
|
18
25
|
/**
|
|
19
|
-
* One user row as the admin API surfaces it. The fixed keys mirror better-auth's
|
|
20
|
-
* core `user` table plus the `admin()` plugin columns (`role`/`banned`/…); the
|
|
21
|
-
* index signature carries any app-defined `user.additionalFields` so callers
|
|
22
|
-
* (the studio) can render them generically. Password material never lives on
|
|
23
|
-
* this row (it's in the `account` table) and is never returned.
|
|
24
|
-
*/
|
|
26
|
+
* One user row as the admin API surfaces it. The fixed keys mirror better-auth's
|
|
27
|
+
* core `user` table plus the `admin()` plugin columns (`role`/`banned`/…); the
|
|
28
|
+
* index signature carries any app-defined `user.additionalFields` so callers
|
|
29
|
+
* (the studio) can render them generically. Password material never lives on
|
|
30
|
+
* this row (it's in the `account` table) and is never returned.
|
|
31
|
+
*/
|
|
25
32
|
interface AuthAdminUser {
|
|
26
33
|
[key: string]: unknown;
|
|
27
34
|
banExpires?: AuthTimestamp;
|
|
@@ -37,12 +44,12 @@ interface AuthAdminUser {
|
|
|
37
44
|
updatedAt?: AuthTimestamp;
|
|
38
45
|
}
|
|
39
46
|
/**
|
|
40
|
-
* One session row as the admin API surfaces it. Mirrors better-auth's `session`
|
|
41
|
-
* table; `impersonatedBy` is set when the session was minted by
|
|
42
|
-
* {@link AuthAdmin.impersonateUser}. The signing `token` is stripped — it's a
|
|
43
|
-
* bearer credential, and the only place we hand one back is the explicit
|
|
44
|
-
* impersonation flow.
|
|
45
|
-
*/
|
|
47
|
+
* One session row as the admin API surfaces it. Mirrors better-auth's `session`
|
|
48
|
+
* table; `impersonatedBy` is set when the session was minted by
|
|
49
|
+
* {@link AuthAdmin.impersonateUser}. The signing `token` is stripped — it's a
|
|
50
|
+
* bearer credential, and the only place we hand one back is the explicit
|
|
51
|
+
* impersonation flow.
|
|
52
|
+
*/
|
|
46
53
|
interface AuthAdminSession {
|
|
47
54
|
[key: string]: unknown;
|
|
48
55
|
createdAt?: AuthTimestamp;
|
|
@@ -90,6 +97,35 @@ interface AuthInvitation {
|
|
|
90
97
|
role?: null | string;
|
|
91
98
|
status?: null | string;
|
|
92
99
|
}
|
|
100
|
+
/** One team row (from the `organization` plugin with `teams.enabled`). */
|
|
101
|
+
interface AuthTeam {
|
|
102
|
+
[key: string]: unknown;
|
|
103
|
+
createdAt?: AuthTimestamp;
|
|
104
|
+
id: string;
|
|
105
|
+
name?: null | string;
|
|
106
|
+
organizationId: string;
|
|
107
|
+
}
|
|
108
|
+
/** One team-membership row (teams). */
|
|
109
|
+
interface AuthTeamMember {
|
|
110
|
+
[key: string]: unknown;
|
|
111
|
+
createdAt?: AuthTimestamp;
|
|
112
|
+
id: string;
|
|
113
|
+
teamId: string;
|
|
114
|
+
userId: string;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* One custom organization role (from the organization plugin's dynamic
|
|
118
|
+
* access-control). `permission` is a JSON string of a `resource → actions[]` map
|
|
119
|
+
* as stored; the studio parses it for display/editing.
|
|
120
|
+
*/
|
|
121
|
+
interface AuthOrgRole {
|
|
122
|
+
[key: string]: unknown;
|
|
123
|
+
createdAt?: AuthTimestamp;
|
|
124
|
+
id: string;
|
|
125
|
+
organizationId: string;
|
|
126
|
+
permission?: null | string;
|
|
127
|
+
role?: null | string;
|
|
128
|
+
}
|
|
93
129
|
/** One registered passkey. Credential secrets (`publicKey`) are stripped. */
|
|
94
130
|
interface AuthPasskey {
|
|
95
131
|
[key: string]: unknown;
|
|
@@ -105,12 +141,12 @@ interface AuthPage<T> {
|
|
|
105
141
|
total: number;
|
|
106
142
|
}
|
|
107
143
|
/**
|
|
108
|
-
* Which admin surfaces a given auth instance supports, derived from the enabled
|
|
109
|
-
* better-auth plugins (and any {@link CreateAuthAdminOptions.features} overrides).
|
|
110
|
-
* The studio calls {@link AuthAdmin.capabilities} once and renders only the
|
|
111
|
-
* panels whose capability is `true` — so a deployment that doesn't enable, say,
|
|
112
|
-
* the `organization` plugin never shows an Organizations section.
|
|
113
|
-
*/
|
|
144
|
+
* Which admin surfaces a given auth instance supports, derived from the enabled
|
|
145
|
+
* better-auth plugins (and any {@link CreateAuthAdminOptions.features} overrides).
|
|
146
|
+
* The studio calls {@link AuthAdmin.capabilities} once and renders only the
|
|
147
|
+
* panels whose capability is `true` — so a deployment that doesn't enable, say,
|
|
148
|
+
* the `organization` plugin never shows an Organizations section.
|
|
149
|
+
*/
|
|
114
150
|
interface AuthCapabilities {
|
|
115
151
|
/** Linked-account browsing/unlinking — core (the `account` table always exists). */
|
|
116
152
|
accounts: boolean;
|
|
@@ -123,6 +159,64 @@ interface AuthCapabilities {
|
|
|
123
159
|
/** The `two-factor` plugin: per-user 2FA status / disable. */
|
|
124
160
|
twoFactor: boolean;
|
|
125
161
|
}
|
|
162
|
+
/**
|
|
163
|
+
* One app/plugin-defined field the create-user form should render, derived from
|
|
164
|
+
* the merged better-auth `user` table (core + plugin + `additionalFields`). Only
|
|
165
|
+
* user-settable columns are surfaced — server-managed flags (`input: false`),
|
|
166
|
+
* foreign keys (`references`), and the core columns the form already handles
|
|
167
|
+
* (`email`/`name`/`role`/ban state/…) are filtered out upstream.
|
|
168
|
+
*/
|
|
169
|
+
interface AuthUserFieldSpec {
|
|
170
|
+
/** Logical field name (the key passed back in `createUser`'s `data`). */
|
|
171
|
+
name: string;
|
|
172
|
+
/** Best-effort plugin id the field originates from (`username`, `phone-number`, …); `undefined` for app `additionalFields`. */
|
|
173
|
+
plugin?: string;
|
|
174
|
+
required: boolean;
|
|
175
|
+
/** Coarse input kind the studio maps to a control (checkbox / number / date / text). */
|
|
176
|
+
type: "boolean" | "date" | "number" | "string";
|
|
177
|
+
unique: boolean;
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* A rich, read-only description of the deployment's auth configuration for the
|
|
181
|
+
* studio's config panel and dynamic create-user form. Unlike
|
|
182
|
+
* {@link AuthCapabilities} (five booleans that gate panels), this exposes *what*
|
|
183
|
+
* is configured — enabled plugins, email/password + social sign-in, the
|
|
184
|
+
* user-settable fields, organization sub-features (teams / custom roles), and
|
|
185
|
+
* the session + rate-limit policy — without ever leaking a secret.
|
|
186
|
+
*/
|
|
187
|
+
interface AuthConfigInfo {
|
|
188
|
+
/** The same capability booleans {@link AuthAdmin.capabilities} returns, embedded so a single call drives the whole panel. */
|
|
189
|
+
capabilities: AuthCapabilities;
|
|
190
|
+
/** Whether email + password sign-in is enabled. */
|
|
191
|
+
emailAndPassword: boolean;
|
|
192
|
+
/** Organization plugin sub-features. */
|
|
193
|
+
organization: {
|
|
194
|
+
enabled: boolean;
|
|
195
|
+
/** Custom roles / dynamic access control (`organizationRole` table present). */
|
|
196
|
+
roles: boolean;
|
|
197
|
+
/** Teams (`team` table present). */
|
|
198
|
+
teams: boolean;
|
|
199
|
+
};
|
|
200
|
+
/** Enabled better-auth plugin ids, sorted. */
|
|
201
|
+
plugins: string[];
|
|
202
|
+
/** Rate-limit policy (window is in seconds). */
|
|
203
|
+
rateLimit: {
|
|
204
|
+
enabled: boolean;
|
|
205
|
+
max?: number;
|
|
206
|
+
window?: number;
|
|
207
|
+
};
|
|
208
|
+
/** Session policy (all durations in seconds). */
|
|
209
|
+
session: {
|
|
210
|
+
cookieCache?: boolean;
|
|
211
|
+
expiresIn?: number;
|
|
212
|
+
freshAge?: number;
|
|
213
|
+
updateAge?: number;
|
|
214
|
+
};
|
|
215
|
+
/** Configured social/OAuth provider ids, sorted. */
|
|
216
|
+
socialProviders: string[];
|
|
217
|
+
/** User-settable extra fields for the create-user form (plugin + app `additionalFields`). */
|
|
218
|
+
userFields: AuthUserFieldSpec[];
|
|
219
|
+
}
|
|
126
220
|
/** A scalar value usable in an adapter `where` clause / filter. */
|
|
127
221
|
type WhereValue = boolean | number | string;
|
|
128
222
|
/** Filtering / paging options for {@link AuthAdmin.listUsers}. */
|
|
@@ -149,15 +243,26 @@ interface ImpersonationResult {
|
|
|
149
243
|
user: AuthAdminUser;
|
|
150
244
|
}
|
|
151
245
|
/**
|
|
152
|
-
* The full read + write surface the studio's auth dashboard drives, backed by
|
|
153
|
-
* better-auth's tables. Returned by {@link createAuthAdmin}. The runtime accepts
|
|
154
|
-
* a structurally-compatible object as its `authAdmin` option and exposes each
|
|
155
|
-
* method behind an admin-token-gated endpoint. Methods whose backing plugin is
|
|
156
|
-
* absent still exist (they're not conditionally omitted) but the studio gates
|
|
157
|
-
* them on {@link AuthAdmin.capabilities}; calling one for an unconfigured plugin
|
|
158
|
-
* surfaces the underlying adapter error.
|
|
159
|
-
*/
|
|
246
|
+
* The full read + write surface the studio's auth dashboard drives, backed by
|
|
247
|
+
* better-auth's tables. Returned by {@link createAuthAdmin}. The runtime accepts
|
|
248
|
+
* a structurally-compatible object as its `authAdmin` option and exposes each
|
|
249
|
+
* method behind an admin-token-gated endpoint. Methods whose backing plugin is
|
|
250
|
+
* absent still exist (they're not conditionally omitted) but the studio gates
|
|
251
|
+
* them on {@link AuthAdmin.capabilities}; calling one for an unconfigured plugin
|
|
252
|
+
* surfaces the underlying adapter error.
|
|
253
|
+
*/
|
|
160
254
|
interface AuthAdmin {
|
|
255
|
+
/** Directly add an existing user as an org member (server-side, no invitation/acceptance). */
|
|
256
|
+
addMember: (input: {
|
|
257
|
+
organizationId: string;
|
|
258
|
+
role?: string;
|
|
259
|
+
userId: string;
|
|
260
|
+
}) => Promise<AuthMember>;
|
|
261
|
+
/** Add a user to a team. */
|
|
262
|
+
addTeamMember: (input: {
|
|
263
|
+
teamId: string;
|
|
264
|
+
userId: string;
|
|
265
|
+
}) => Promise<AuthTeamMember>;
|
|
161
266
|
banUser: (input: {
|
|
162
267
|
expiresInSeconds?: number;
|
|
163
268
|
reason?: string;
|
|
@@ -167,6 +272,27 @@ interface AuthAdmin {
|
|
|
167
272
|
invitationId: string;
|
|
168
273
|
}) => Promise<void>;
|
|
169
274
|
capabilities: () => Promise<AuthCapabilities>;
|
|
275
|
+
/** Rich, read-only description of the auth configuration (plugins, fields, session policy, …). */
|
|
276
|
+
config: () => Promise<AuthConfigInfo>;
|
|
277
|
+
/** Create an organization; optionally seed an `owner` member for `ownerId`. */
|
|
278
|
+
createOrganization: (input: {
|
|
279
|
+
logo?: string;
|
|
280
|
+
metadata?: Record<string, unknown>;
|
|
281
|
+
name: string;
|
|
282
|
+
ownerId?: string;
|
|
283
|
+
slug?: string;
|
|
284
|
+
}) => Promise<AuthOrganization>;
|
|
285
|
+
/** Create a custom org role with a permission grant (a `resource → actions[]` map). */
|
|
286
|
+
createOrgRole: (input: {
|
|
287
|
+
organizationId: string;
|
|
288
|
+
permission: Record<string, string[]>;
|
|
289
|
+
role: string;
|
|
290
|
+
}) => Promise<AuthOrgRole>;
|
|
291
|
+
/** Create a team under an organization. */
|
|
292
|
+
createTeam: (input: {
|
|
293
|
+
name: string;
|
|
294
|
+
organizationId: string;
|
|
295
|
+
}) => Promise<AuthTeam>;
|
|
170
296
|
createUser: (input: {
|
|
171
297
|
data?: Record<string, unknown>;
|
|
172
298
|
email: string;
|
|
@@ -174,6 +300,14 @@ interface AuthAdmin {
|
|
|
174
300
|
password?: string;
|
|
175
301
|
role?: string | string[];
|
|
176
302
|
}) => Promise<AuthAdminUser>;
|
|
303
|
+
/** Delete an organization and cascade-delete its members, invitations, teams, and custom roles. */
|
|
304
|
+
deleteOrganization: (input: {
|
|
305
|
+
organizationId: string;
|
|
306
|
+
}) => Promise<void>;
|
|
307
|
+
/** Delete a custom org role. */
|
|
308
|
+
deleteOrgRole: (input: {
|
|
309
|
+
roleId: string;
|
|
310
|
+
}) => Promise<void>;
|
|
177
311
|
deletePasskey: (input: {
|
|
178
312
|
passkeyId: string;
|
|
179
313
|
}) => Promise<void>;
|
|
@@ -183,6 +317,13 @@ interface AuthAdmin {
|
|
|
183
317
|
impersonateUser: (input: {
|
|
184
318
|
userId: string;
|
|
185
319
|
}) => Promise<ImpersonationResult>;
|
|
320
|
+
/** Create a pending email invitation to an org (no acceptance side effects). */
|
|
321
|
+
inviteMember: (input: {
|
|
322
|
+
email: string;
|
|
323
|
+
inviterId?: string;
|
|
324
|
+
organizationId: string;
|
|
325
|
+
role?: string;
|
|
326
|
+
}) => Promise<AuthInvitation>;
|
|
186
327
|
listAccounts: (input: {
|
|
187
328
|
userId: string;
|
|
188
329
|
}) => Promise<AuthAccount[]>;
|
|
@@ -200,6 +341,12 @@ interface AuthAdmin {
|
|
|
200
341
|
limit?: number;
|
|
201
342
|
offset?: number;
|
|
202
343
|
}) => Promise<AuthPage<AuthOrganization>>;
|
|
344
|
+
/** List an org's custom roles. */
|
|
345
|
+
listOrgRoles: (options: {
|
|
346
|
+
limit?: number;
|
|
347
|
+
offset?: number;
|
|
348
|
+
organizationId: string;
|
|
349
|
+
}) => Promise<AuthPage<AuthOrgRole>>;
|
|
203
350
|
listPasskeys: (input: {
|
|
204
351
|
userId: string;
|
|
205
352
|
}) => Promise<AuthPasskey[]>;
|
|
@@ -208,10 +355,30 @@ interface AuthAdmin {
|
|
|
208
355
|
offset?: number;
|
|
209
356
|
userId?: string;
|
|
210
357
|
}) => Promise<AuthPage<AuthAdminSession>>;
|
|
358
|
+
/** List a team's members. */
|
|
359
|
+
listTeamMembers: (options: {
|
|
360
|
+
limit?: number;
|
|
361
|
+
offset?: number;
|
|
362
|
+
teamId: string;
|
|
363
|
+
}) => Promise<AuthPage<AuthTeamMember>>;
|
|
364
|
+
/** List an org's teams. */
|
|
365
|
+
listTeams: (options: {
|
|
366
|
+
limit?: number;
|
|
367
|
+
offset?: number;
|
|
368
|
+
organizationId: string;
|
|
369
|
+
}) => Promise<AuthPage<AuthTeam>>;
|
|
211
370
|
listUsers: (options: ListUsersOptions) => Promise<AuthPage<AuthAdminUser>>;
|
|
212
371
|
removeMember: (input: {
|
|
213
372
|
memberId: string;
|
|
214
373
|
}) => Promise<void>;
|
|
374
|
+
/** Delete a team and its memberships. */
|
|
375
|
+
removeTeam: (input: {
|
|
376
|
+
teamId: string;
|
|
377
|
+
}) => Promise<void>;
|
|
378
|
+
/** Remove a member from a team. */
|
|
379
|
+
removeTeamMember: (input: {
|
|
380
|
+
teamMemberId: string;
|
|
381
|
+
}) => Promise<void>;
|
|
215
382
|
removeUser: (input: {
|
|
216
383
|
userId: string;
|
|
217
384
|
}) => Promise<void>;
|
|
@@ -236,6 +403,29 @@ interface AuthAdmin {
|
|
|
236
403
|
accountId: string;
|
|
237
404
|
userId: string;
|
|
238
405
|
}) => Promise<void>;
|
|
406
|
+
/** Change a member's role. */
|
|
407
|
+
updateMemberRole: (input: {
|
|
408
|
+
memberId: string;
|
|
409
|
+
role: string | string[];
|
|
410
|
+
}) => Promise<AuthMember>;
|
|
411
|
+
/** Update an organization's name/slug/logo/metadata. */
|
|
412
|
+
updateOrganization: (input: {
|
|
413
|
+
logo?: string;
|
|
414
|
+
metadata?: Record<string, unknown>;
|
|
415
|
+
name?: string;
|
|
416
|
+
organizationId: string;
|
|
417
|
+
slug?: string;
|
|
418
|
+
}) => Promise<AuthOrganization>;
|
|
419
|
+
/** Replace a custom org role's permission grant. */
|
|
420
|
+
updateOrgRole: (input: {
|
|
421
|
+
permission: Record<string, string[]>;
|
|
422
|
+
roleId: string;
|
|
423
|
+
}) => Promise<AuthOrgRole>;
|
|
424
|
+
/** Rename a team. */
|
|
425
|
+
updateTeam: (input: {
|
|
426
|
+
name: string;
|
|
427
|
+
teamId: string;
|
|
428
|
+
}) => Promise<AuthTeam>;
|
|
239
429
|
updateUser: (input: {
|
|
240
430
|
data: Record<string, unknown>;
|
|
241
431
|
userId: string;
|
|
@@ -244,143 +434,267 @@ interface AuthAdmin {
|
|
|
244
434
|
/** Options for {@link createAuthAdmin}. */
|
|
245
435
|
interface CreateAuthAdminOptions {
|
|
246
436
|
/**
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
437
|
+
* Force individual {@link AuthCapabilities} on or off regardless of which
|
|
438
|
+
* plugins are detected — e.g. `{ impersonate: false }`-style opt-outs by
|
|
439
|
+
* setting `admin: false`, or hiding linked accounts with `accounts: false`.
|
|
440
|
+
* A capability is reported only when both its plugin is enabled *and* its
|
|
441
|
+
* override isn't `false`.
|
|
442
|
+
*/
|
|
253
443
|
features?: Partial<AuthCapabilities>;
|
|
254
444
|
/**
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
445
|
+
* User id recorded as the impersonator on sessions minted by
|
|
446
|
+
* {@link AuthAdmin.impersonateUser}. Defaults to the impersonated user's own
|
|
447
|
+
* id (a self-reference) since the trusted admin plane has no acting user.
|
|
448
|
+
*/
|
|
259
449
|
impersonatedBy?: string;
|
|
260
450
|
/**
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
451
|
+
* How long (in seconds) an impersonation session lives. Must be a positive
|
|
452
|
+
* finite integer. Capped at 24 × {@link DEFAULT_IMPERSONATION_SECONDS}
|
|
453
|
+
* (86 400 s / 24 h). Defaults to {@link DEFAULT_IMPERSONATION_SECONDS}
|
|
454
|
+
* (3 600 s / 1 h).
|
|
455
|
+
*/
|
|
266
456
|
impersonationSeconds?: number;
|
|
267
457
|
}
|
|
268
458
|
/**
|
|
269
|
-
* A normalized failure from an admin operation. better-auth throws `APIError`s
|
|
270
|
-
* carrying a `body.code` (e.g. `USER_ALREADY_EXISTS_USE_ANOTHER_EMAIL`); we
|
|
271
|
-
* surface that `code` so the runtime can map it onto an HTTP status and the
|
|
272
|
-
* studio can show a meaningful message instead of a generic 500.
|
|
273
|
-
*/
|
|
274
|
-
declare class LunoraAuthAdminError extends
|
|
275
|
-
readonly code: string;
|
|
459
|
+
* A normalized failure from an admin operation. better-auth throws `APIError`s
|
|
460
|
+
* carrying a `body.code` (e.g. `USER_ALREADY_EXISTS_USE_ANOTHER_EMAIL`); we
|
|
461
|
+
* surface that `code` so the runtime can map it onto an HTTP status and the
|
|
462
|
+
* studio can show a meaningful message instead of a generic 500.
|
|
463
|
+
*/
|
|
464
|
+
declare class LunoraAuthAdminError extends LunoraError {
|
|
276
465
|
constructor(message: string, code: string);
|
|
277
466
|
}
|
|
278
467
|
/**
|
|
279
|
-
* Build the studio's auth user-management plane on top of better-auth.
|
|
280
|
-
*
|
|
281
|
-
* Pass the result as the runtime's `authAdmin` option; the runtime exposes each
|
|
282
|
-
* method behind an admin-token-gated `/_lunora/admin/auth/*` endpoint. The set
|
|
283
|
-
* of usable surfaces is reported by {@link AuthAdmin.capabilities} — derived
|
|
284
|
-
* from the enabled better-auth plugins, so enabling `admin()`, `organization()`,
|
|
285
|
-
* `twoFactor()`, or the passkey plugin in the auth config is what lights up the
|
|
286
|
-
* matching dashboard panels.
|
|
287
|
-
*
|
|
288
|
-
* **Trust model — important.** These operations talk to better-auth's
|
|
289
|
-
* `internalAdapter` (and `adapter`/password hasher) **directly**, deliberately
|
|
290
|
-
* bypassing the plugins' own endpoints, which require the caller to hold an
|
|
291
|
-
* admin-role session. That session check is the wrong gate here: the runtime
|
|
292
|
-
* already authorizes every call with `LUNORA_ADMIN_TOKEN`, so this helper acts
|
|
293
|
-
* as a trusted server-side operator. It is therefore not an end-user-callable
|
|
294
|
-
* API — never expose it on a path that isn't admin-token gated.
|
|
295
|
-
*
|
|
296
|
-
* `auth.$context` is a promise (better-auth resolves the adapter, password
|
|
297
|
-
* config, etc. lazily); we memoize it so the first call pays the cost once.
|
|
298
|
-
*/
|
|
468
|
+
* Build the studio's auth user-management plane on top of better-auth.
|
|
469
|
+
*
|
|
470
|
+
* Pass the result as the runtime's `authAdmin` option; the runtime exposes each
|
|
471
|
+
* method behind an admin-token-gated `/_lunora/admin/auth/*` endpoint. The set
|
|
472
|
+
* of usable surfaces is reported by {@link AuthAdmin.capabilities} — derived
|
|
473
|
+
* from the enabled better-auth plugins, so enabling `admin()`, `organization()`,
|
|
474
|
+
* `twoFactor()`, or the passkey plugin in the auth config is what lights up the
|
|
475
|
+
* matching dashboard panels.
|
|
476
|
+
*
|
|
477
|
+
* **Trust model — important.** These operations talk to better-auth's
|
|
478
|
+
* `internalAdapter` (and `adapter`/password hasher) **directly**, deliberately
|
|
479
|
+
* bypassing the plugins' own endpoints, which require the caller to hold an
|
|
480
|
+
* admin-role session. That session check is the wrong gate here: the runtime
|
|
481
|
+
* already authorizes every call with `LUNORA_ADMIN_TOKEN`, so this helper acts
|
|
482
|
+
* as a trusted server-side operator. It is therefore not an end-user-callable
|
|
483
|
+
* API — never expose it on a path that isn't admin-token gated.
|
|
484
|
+
*
|
|
485
|
+
* `auth.$context` is a promise (better-auth resolves the adapter, password
|
|
486
|
+
* config, etc. lazily); we memoize it so the first call pays the cost once.
|
|
487
|
+
*/
|
|
299
488
|
declare const createAuthAdmin: (auth: LunoraAuth, options?: CreateAuthAdminOptions) => AuthAdmin;
|
|
489
|
+
/** Configuration for {@link authAuditHook}. */
|
|
490
|
+
interface AuthAuditHookConfig extends AppendAuthAuditOptions {
|
|
491
|
+
/**
|
|
492
|
+
* Where to persist the trail — the same {@link SqlExecutor} seam better-auth's
|
|
493
|
+
* store rides (`d1Executor(env.DB)`), so events land in the auth D1 database.
|
|
494
|
+
*/
|
|
495
|
+
executor: SqlExecutor;
|
|
496
|
+
/**
|
|
497
|
+
* Optional export tap (pairs with SIEM forwarding): called with each redacted
|
|
498
|
+
* entry right after it is persisted, so a deployment can fan events out to an
|
|
499
|
+
* external sink. Rejections/throws are swallowed so forwarding can't break an
|
|
500
|
+
* auth request.
|
|
501
|
+
*/
|
|
502
|
+
onRecord?: (entry: AppendAuthAuditEntry) => Promise<void> | void;
|
|
503
|
+
}
|
|
504
|
+
/** Structural view of the fields we read off better-auth's after-hook context — kept loose to avoid coupling to internal types. */
|
|
505
|
+
interface AuditHookContext {
|
|
506
|
+
context?: {
|
|
507
|
+
newSession?: {
|
|
508
|
+
session?: {
|
|
509
|
+
userId?: string;
|
|
510
|
+
};
|
|
511
|
+
user?: {
|
|
512
|
+
email?: string;
|
|
513
|
+
id?: string;
|
|
514
|
+
};
|
|
515
|
+
} | null;
|
|
516
|
+
returned?: unknown;
|
|
517
|
+
session?: {
|
|
518
|
+
session?: {
|
|
519
|
+
userId?: string;
|
|
520
|
+
};
|
|
521
|
+
user?: {
|
|
522
|
+
email?: string;
|
|
523
|
+
id?: string;
|
|
524
|
+
};
|
|
525
|
+
} | null;
|
|
526
|
+
};
|
|
527
|
+
headers?: Headers;
|
|
528
|
+
path?: string;
|
|
529
|
+
request?: Request;
|
|
530
|
+
}
|
|
531
|
+
/**
|
|
532
|
+
* Map a better-auth endpoint path to the security event it represents, or
|
|
533
|
+
* `undefined` for endpoints not worth auditing (session reads, config, …). Match
|
|
534
|
+
* is by suffix so a caller `basePath` prefix (`/api/auth`) never affects it.
|
|
535
|
+
*/
|
|
536
|
+
declare const eventForPath: (path: string) => AuthAuditEvent | undefined;
|
|
537
|
+
/**
|
|
538
|
+
* Build the entry a given after-hook context should record, or `undefined` when
|
|
539
|
+
* the path is not an audited security event. Exported for direct unit testing of
|
|
540
|
+
* the classification/extraction without spinning up better-auth.
|
|
541
|
+
*/
|
|
542
|
+
declare const buildAuditEntry: (context: AuditHookContext, now?: number) => AppendAuthAuditEntry | undefined;
|
|
543
|
+
/**
|
|
544
|
+
* Create the better-auth `hooks.after` middleware that records the auth/security
|
|
545
|
+
* audit trail. Assign it to `hooks.after` (or compose via {@link withAuthAudit}).
|
|
546
|
+
*
|
|
547
|
+
* ```ts
|
|
548
|
+
* const auth = createAuth({
|
|
549
|
+
* secret: env.AUTH_SECRET,
|
|
550
|
+
* database: lunoraD1Adapter(env.DB),
|
|
551
|
+
* hooks: { after: authAuditHook({ executor: d1Executor(env.DB), retention: 100_000 }) },
|
|
552
|
+
* });
|
|
553
|
+
* ```
|
|
554
|
+
*/
|
|
555
|
+
declare const authAuditHook: (config: AuthAuditHookConfig) => ReturnType<typeof createAuthMiddleware>;
|
|
556
|
+
/**
|
|
557
|
+
* Merge the audit `hooks.after` middleware into a better-auth options object,
|
|
558
|
+
* composing with any `hooks.after` the caller already set (theirs runs first,
|
|
559
|
+
* then the audit record). Returns a new options object.
|
|
560
|
+
*/
|
|
561
|
+
declare const withAuthAudit: <Options extends {
|
|
562
|
+
hooks?: {
|
|
563
|
+
after?: unknown;
|
|
564
|
+
};
|
|
565
|
+
}>(options: Options, config: AuthAuditHookConfig) => Options;
|
|
566
|
+
/** better-auth's `databaseHooks` shape, derived so a rename upstream fails to compile rather than silently mis-hooking. */
|
|
567
|
+
type DatabaseHooks = NonNullable<BetterAuthOptions["databaseHooks"]>;
|
|
568
|
+
/** Config for the signup gate hooks: the base {@link EmailGateConfig} plus an optional classification tap. */
|
|
569
|
+
interface EmailGateHookConfig extends EmailGateConfig {
|
|
570
|
+
/**
|
|
571
|
+
* Called with the resolved classification once the gate passes, so app policy
|
|
572
|
+
* can react to `free` vs `business` at signup (e.g. tag the account). Never
|
|
573
|
+
* fires when the gate rejects. `context` is better-auth's endpoint context
|
|
574
|
+
* (`null` outside a request, e.g. an internal create).
|
|
575
|
+
*/
|
|
576
|
+
onClassify?: (classification: EmailClassification, user: Record<string, unknown>, context: unknown) => void;
|
|
577
|
+
}
|
|
578
|
+
/**
|
|
579
|
+
* Produce a `databaseHooks` fragment that gates better-auth's native signup on
|
|
580
|
+
* the email-domain policy. Spread it into `createAuth({ databaseHooks: … })`, or
|
|
581
|
+
* use {@link withEmailGate} to merge it (composing with any existing
|
|
582
|
+
* `user.create.before`).
|
|
583
|
+
*
|
|
584
|
+
* ```ts
|
|
585
|
+
* const auth = createAuth({
|
|
586
|
+
* secret: env.AUTH_SECRET,
|
|
587
|
+
* database: lunoraD1Adapter(env.DB),
|
|
588
|
+
* databaseHooks: emailGateDatabaseHooks({ blockDisposable: true }),
|
|
589
|
+
* });
|
|
590
|
+
* ```
|
|
591
|
+
*/
|
|
592
|
+
declare const emailGateDatabaseHooks: (config?: EmailGateHookConfig) => DatabaseHooks;
|
|
593
|
+
/**
|
|
594
|
+
* Merge the email-domain signup gate into an existing better-auth options object,
|
|
595
|
+
* preserving any `databaseHooks` the caller already set. If they already declared
|
|
596
|
+
* a `user.create.before`, the gate runs first (rejecting disposable signups
|
|
597
|
+
* before their hook sees them), then theirs runs on the (possibly rewritten) user.
|
|
598
|
+
*
|
|
599
|
+
* ```ts
|
|
600
|
+
* const auth = createAuth(withEmailGate({ secret, database }, { blockDisposable: true }));
|
|
601
|
+
* ```
|
|
602
|
+
*/
|
|
603
|
+
declare const withEmailGate: (options: BetterAuthOptions, config?: EmailGateHookConfig) => BetterAuthOptions;
|
|
300
604
|
/**
|
|
301
|
-
* Default basePath used by better-auth's client + handler. Override via the
|
|
302
|
-
* second argument if you mount the auth routes somewhere else.
|
|
303
|
-
*/
|
|
605
|
+
* Default basePath used by better-auth's client + handler. Override via the
|
|
606
|
+
* second argument if you mount the auth routes somewhere else.
|
|
607
|
+
*/
|
|
304
608
|
declare const DEFAULT_AUTH_BASE_PATH: string;
|
|
305
609
|
/**
|
|
306
|
-
* Route an inbound `Request` to better-auth if the path falls under
|
|
307
|
-
* `basePath`; otherwise return `null` so the caller can continue dispatching.
|
|
308
|
-
*
|
|
309
|
-
* Better-auth handles arbitrarily nested paths (`/api/auth/sign-in/email`,
|
|
310
|
-
* `/api/auth/callback/github`, …), so we use prefix matching instead of the
|
|
311
|
-
* exact-path map `createWorker` consumes for top-level routes.
|
|
312
|
-
*/
|
|
610
|
+
* Route an inbound `Request` to better-auth if the path falls under
|
|
611
|
+
* `basePath`; otherwise return `null` so the caller can continue dispatching.
|
|
612
|
+
*
|
|
613
|
+
* Better-auth handles arbitrarily nested paths (`/api/auth/sign-in/email`,
|
|
614
|
+
* `/api/auth/callback/github`, …), so we use prefix matching instead of the
|
|
615
|
+
* exact-path map `createWorker` consumes for top-level routes.
|
|
616
|
+
*/
|
|
313
617
|
declare const handleAuthRequest: (auth: LunoraAuth, request: Request, basePath?: string) => Promise<Response | undefined>;
|
|
314
618
|
/**
|
|
315
|
-
* Apply better-auth's required schema (`user`, `session`, `account`,
|
|
316
|
-
* `verification`) to the configured database. Idempotent — better-auth
|
|
317
|
-
* diffs the existing schema and only runs the missing DDL.
|
|
318
|
-
*
|
|
319
|
-
* Cached per `options` reference so the diff cost (one PRAGMA-style sweep
|
|
320
|
-
* per table) doesn't fire on every request. In Cloudflare Workers the same
|
|
321
|
-
* `env.DB` binding is reused across invocations within a single isolate, so
|
|
322
|
-
* caching against the options object — which captures the binding — is
|
|
323
|
-
* sufficient.
|
|
324
|
-
*
|
|
325
|
-
* For production you should prefer pre-applying the schema at deploy time
|
|
326
|
-
* via `compileMigrationsSql` + `wrangler d1 execute`; this helper exists for
|
|
327
|
-
* dev/playground and small deployments.
|
|
328
|
-
*/
|
|
619
|
+
* Apply better-auth's required schema (`user`, `session`, `account`,
|
|
620
|
+
* `verification`) to the configured database. Idempotent — better-auth
|
|
621
|
+
* diffs the existing schema and only runs the missing DDL.
|
|
622
|
+
*
|
|
623
|
+
* Cached per `options` reference so the diff cost (one PRAGMA-style sweep
|
|
624
|
+
* per table) doesn't fire on every request. In Cloudflare Workers the same
|
|
625
|
+
* `env.DB` binding is reused across invocations within a single isolate, so
|
|
626
|
+
* caching against the options object — which captures the binding — is
|
|
627
|
+
* sufficient.
|
|
628
|
+
*
|
|
629
|
+
* For production you should prefer pre-applying the schema at deploy time
|
|
630
|
+
* via `compileMigrationsSql` + `wrangler d1 execute`; this helper exists for
|
|
631
|
+
* dev/playground and small deployments.
|
|
632
|
+
*/
|
|
329
633
|
declare const ensureMigrated: (auth: LunoraAuth | {
|
|
330
634
|
options: LunoraAuthOptions;
|
|
331
635
|
}) => Promise<void>;
|
|
332
636
|
/**
|
|
333
|
-
* Compile better-auth's migrations to a single SQL string. Useful for
|
|
334
|
-
* `wrangler d1 execute --file -` in CI so the deploy step applies the schema
|
|
335
|
-
* before the first user request.
|
|
336
|
-
|
|
637
|
+
* Compile better-auth's migrations to a single SQL string. Useful for
|
|
638
|
+
* `wrangler d1 execute --file -` in CI so the deploy step applies the schema
|
|
639
|
+
* before the first user request.
|
|
640
|
+
*
|
|
641
|
+
* Compiles from the SAME resolved options `createAuth` runs with (via
|
|
642
|
+
* `resolveAuthOptions`), not the raw caller options — so the schema includes the
|
|
643
|
+
* `rateLimit` table the worker's default-on durable limiter writes to. Compiling
|
|
644
|
+
* from the raw options would omit it, and the running worker would then write to
|
|
645
|
+
* a table the migration never created.
|
|
646
|
+
*/
|
|
337
647
|
declare const compileMigrationsSql: (options: LunoraAuthOptions) => Promise<string>;
|
|
338
648
|
/**
|
|
339
|
-
* Lunora-friendly view over better-auth's `session` option.
|
|
340
|
-
*
|
|
341
|
-
* This is a typed alias for better-auth's own `session` shape — Lunora stays a
|
|
342
|
-
* thin wrapper, so we don't reimplement the fields, we just give them a named,
|
|
343
|
-
* documented home so callers get autocomplete without reaching into
|
|
344
|
-
* `BetterAuthOptions`. The most relevant fields for session rotation / richer
|
|
345
|
-
* policies are `expiresIn` (absolute session lifetime, in seconds),
|
|
346
|
-
* `updateAge` (rolling-rotation interval, in seconds — how often an active
|
|
347
|
-
* session's expiry is pushed forward; `0` rotates on every use),
|
|
348
|
-
* `disableSessionRefresh` (turn rolling rotation off entirely so sessions
|
|
349
|
-
* expire at the absolute `expiresIn` regardless of activity), `freshAge`
|
|
350
|
-
* (freshness window, in seconds, for sensitive operations like account
|
|
351
|
-
* deletion; `0` treats every session as fresh — not recommended), and
|
|
352
|
-
* `cookieCache` (opt-in signed-cookie session cache to skip DB reads).
|
|
353
|
-
*
|
|
354
|
-
* See better-auth's `session` option for the full field list.
|
|
355
|
-
*/
|
|
649
|
+
* Lunora-friendly view over better-auth's `session` option.
|
|
650
|
+
*
|
|
651
|
+
* This is a typed alias for better-auth's own `session` shape — Lunora stays a
|
|
652
|
+
* thin wrapper, so we don't reimplement the fields, we just give them a named,
|
|
653
|
+
* documented home so callers get autocomplete without reaching into
|
|
654
|
+
* `BetterAuthOptions`. The most relevant fields for session rotation / richer
|
|
655
|
+
* policies are `expiresIn` (absolute session lifetime, in seconds),
|
|
656
|
+
* `updateAge` (rolling-rotation interval, in seconds — how often an active
|
|
657
|
+
* session's expiry is pushed forward; `0` rotates on every use),
|
|
658
|
+
* `disableSessionRefresh` (turn rolling rotation off entirely so sessions
|
|
659
|
+
* expire at the absolute `expiresIn` regardless of activity), `freshAge`
|
|
660
|
+
* (freshness window, in seconds, for sensitive operations like account
|
|
661
|
+
* deletion; `0` treats every session as fresh — not recommended), and
|
|
662
|
+
* `cookieCache` (opt-in signed-cookie session cache to skip DB reads).
|
|
663
|
+
*
|
|
664
|
+
* See better-auth's `session` option for the full field list.
|
|
665
|
+
*/
|
|
356
666
|
type SessionPolicy = NonNullable<BetterAuthOptions["session"]>;
|
|
357
667
|
/**
|
|
358
|
-
* Validate a {@link SessionPolicy} and return it unchanged (pass-through).
|
|
359
|
-
*
|
|
360
|
-
* better-auth happily accepts the `session` block verbatim, so the only job
|
|
361
|
-
* here is to catch obviously-broken numeric inputs at construction time —
|
|
362
|
-
* negative or non-finite durations — rather than letting them produce
|
|
363
|
-
* surprising cookie expiries at runtime. Field names mirror better-auth's
|
|
364
|
-
* `session` option exactly so the validated object forwards 1:1.
|
|
365
|
-
*/
|
|
668
|
+
* Validate a {@link SessionPolicy} and return it unchanged (pass-through).
|
|
669
|
+
*
|
|
670
|
+
* better-auth happily accepts the `session` block verbatim, so the only job
|
|
671
|
+
* here is to catch obviously-broken numeric inputs at construction time —
|
|
672
|
+
* negative or non-finite durations — rather than letting them produce
|
|
673
|
+
* surprising cookie expiries at runtime. Field names mirror better-auth's
|
|
674
|
+
* `session` option exactly so the validated object forwards 1:1.
|
|
675
|
+
*/
|
|
366
676
|
declare const validateSessionPolicy: (policy: SessionPolicy) => SessionPolicy;
|
|
367
677
|
/**
|
|
368
|
-
* Ready-made {@link SessionPolicy} presets covering the common rotation /
|
|
369
|
-
* expiry trade-offs. Spread or override fields as needed:
|
|
370
|
-
*
|
|
371
|
-
* ```ts
|
|
372
|
-
* import { createAuth, sessionPresets } from "@lunora/auth";
|
|
373
|
-
*
|
|
374
|
-
* export const auth = createAuth({
|
|
375
|
-
* secret: env.AUTH_SECRET,
|
|
376
|
-
* database: env.DB,
|
|
377
|
-
* session: { ...sessionPresets.rolling, freshAge: 60 * 5 },
|
|
378
|
-
* });
|
|
379
|
-
* ```
|
|
380
|
-
*
|
|
381
|
-
* - `rolling` — balanced default: 7-day absolute expiry, rotated once per day
|
|
382
|
-
* -
|
|
383
|
-
*
|
|
384
|
-
|
|
678
|
+
* Ready-made {@link SessionPolicy} presets covering the common rotation /
|
|
679
|
+
* expiry trade-offs. Spread or override fields as needed:
|
|
680
|
+
*
|
|
681
|
+
* ```ts
|
|
682
|
+
* import { createAuth, sessionPresets } from "@lunora/auth";
|
|
683
|
+
*
|
|
684
|
+
* export const auth = createAuth({
|
|
685
|
+
* secret: env.AUTH_SECRET,
|
|
686
|
+
* database: env.DB,
|
|
687
|
+
* session: { ...sessionPresets.rolling, freshAge: 60 * 5 },
|
|
688
|
+
* });
|
|
689
|
+
* ```
|
|
690
|
+
*
|
|
691
|
+
* - `rolling` — balanced default: 7-day absolute expiry, rotated once per day,
|
|
692
|
+
* with a 60s signed-cookie session cache so bursts of authenticated calls
|
|
693
|
+
* skip the per-request DB session read.
|
|
694
|
+
* - `strict` — short, security-sensitive: 1-hour expiry, 15-minute rotation,
|
|
695
|
+
* cookie cache **off** (fast revocation / short freshness is the whole point).
|
|
696
|
+
* - `longLived` — low-friction consumer apps: 30-day expiry, daily rotation,
|
|
697
|
+
* with the same 60s cookie cache as `rolling`.
|
|
698
|
+
*/
|
|
385
699
|
declare const sessionPresets: Record<"longLived" | "rolling" | "strict", SessionPolicy>;
|
|
386
|
-
export { type AuthAccount, type AuthAdmin, type AuthAdminSession, type AuthAdminUser, type AuthCapabilities, type AuthInvitation, type AuthMember, type AuthOrganization, type AuthPage, type AuthPasskey, type AuthTimestamp, type CreateAuthAdminOptions, DEFAULT_AUTH_BASE_PATH, type ImpersonationResult, type ListUsersOptions, type LunoraAuth, LunoraAuthAdminError, type LunoraAuthOptions, type SessionPolicy, compileMigrationsSql, createAuthAdmin, ensureMigrated, handleAuthRequest, sessionPresets, validateSessionPolicy };
|
|
700
|
+
export { type AppendAuthAuditEntry, type AppendAuthAuditOptions, type AuthAccount, type AuthAdmin, type AuthAdminSession, type AuthAdminUser, type AuthAuditEvent, type AuthAuditHookConfig, type AuthCapabilities, type AuthConfigInfo, type AuthInvitation, type AuthMember, type AuthOrgRole, type AuthOrganization, type AuthPage, type AuthPasskey, type AuthTeam, type AuthTeamMember, type AuthTimestamp, type AuthUserFieldSpec, type CreateAuthAdminOptions, DEFAULT_AUTH_BASE_PATH, type EmailClassification, type EmailGateConfig, type EmailGateHookConfig, type ImpersonationResult, type ListUsersOptions, type LunoraAuth, LunoraAuthAdminError, type LunoraAuthOptions, type SessionPolicy, type SqlExecutor, authAuditHook, buildAuditEntry, compileMigrationsSql, createAuthAdmin, emailGateDatabaseHooks, ensureMigrated, eventForPath, handleAuthRequest, sessionPresets, validateSessionPolicy, withAuthAudit, withEmailGate };
|