@authowl/core 0.11.0 → 0.12.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.
@@ -0,0 +1,1294 @@
1
+ import { R as ResolvedAuthConfig, H as HasParams, O as OrganizationMembership } from './organization-membership-B3m6PbmO.cjs';
2
+
3
+ type EnvironmentType = 'development' | 'production';
4
+ /**
5
+ * The public, publishable-key-safe project config the SDK renders its sign-in
6
+ * UI from (server contract CONTRACTS §2, `GET /api/projects/:id/public-config`).
7
+ * Nothing here is secret. Method slugs are canonical snake_case.
8
+ */
9
+ type PublicConfig = {
10
+ /** Stable workspace product container shared by its environments. */
11
+ applicationId: string;
12
+ /** Stable tenant id for the exact environment selected by the publishable key. */
13
+ environmentId: string;
14
+ /** Environment class that determines key prefixes and billing treatment. */
15
+ environmentType: EnvironmentType;
16
+ /** Canonical authentication endpoint for this environment. */
17
+ authBaseUrl: string;
18
+ /**
19
+ * Public acquisition mode. Optional only for rolling compatibility with
20
+ * servers released before waitlist support.
21
+ */
22
+ signUp?: {
23
+ mode: 'open' | 'restricted' | 'allowlist' | 'waitlist';
24
+ };
25
+ /**
26
+ * Identity and credential lifecycle policy. Optional only for rolling
27
+ * compatibility with AuthOwl servers released before plan 35.
28
+ */
29
+ authentication?: {
30
+ email: {
31
+ signUp: boolean;
32
+ signIn: Array<'password' | 'magic_link' | 'email_otp'>;
33
+ };
34
+ phone: {
35
+ signUp: boolean;
36
+ signIn: boolean;
37
+ };
38
+ password: {
39
+ signUp: boolean;
40
+ add: boolean;
41
+ /** Server-owned password length policy. Optional for rolling compatibility. */
42
+ minLength?: number;
43
+ maxLength?: number;
44
+ };
45
+ passkey: {
46
+ signIn: boolean;
47
+ add: boolean;
48
+ };
49
+ username: {
50
+ collectOnSignUp: boolean;
51
+ signIn: boolean;
52
+ };
53
+ };
54
+ /** Email ownership ceremony selected by the project. */
55
+ emailVerification?: {
56
+ required: boolean;
57
+ method: 'link' | 'code';
58
+ };
59
+ /** End-user profile fields and self-service permissions. */
60
+ userModel?: {
61
+ requireEmail: boolean;
62
+ firstLastName: boolean;
63
+ emailChange: boolean;
64
+ accountDeletion: boolean;
65
+ };
66
+ /**
67
+ * MFA presentation contract. Backup codes follow TOTP and are not an
68
+ * independently configurable authentication method.
69
+ */
70
+ mfa?: {
71
+ totp: boolean;
72
+ required: boolean;
73
+ backupCodes: boolean;
74
+ };
75
+ branding: {
76
+ appName?: string;
77
+ logoUrl?: string;
78
+ /** Whether the application name is visible beside the logo. */
79
+ showAppName?: boolean;
80
+ /** Alignment of the brand identity within managed component headers. */
81
+ alignment?: 'left' | 'center' | 'right';
82
+ primaryColor?: string;
83
+ theme?: 'light' | 'dark' | 'system';
84
+ };
85
+ /** Canonical method slugs, e.g. "password", "magic_link", "passkey". */
86
+ enabledMethods: string[];
87
+ /** Configured social provider ids, e.g. "google". */
88
+ socialProviders: string[];
89
+ /**
90
+ * Public OAuth client ids keyed by provider. Optional for rolling compatibility
91
+ * with servers released before Google One Tap support.
92
+ */
93
+ socialProviderClientIds?: Record<string, string>;
94
+ /**
95
+ * When true, an email/password sign-up does not create a session - the user
96
+ * must confirm their address first. <SignUp/> shows a "check your email" state
97
+ * instead of redirecting. Always false unless password sign-up is enabled.
98
+ */
99
+ requireEmailVerification: boolean;
100
+ /**
101
+ * Legal consent gate. When `required`, <SignUp/> shows an acceptance checkbox
102
+ * linking `termsUrl`/`privacyUrl` and blocks sign-up until it's checked, echoing
103
+ * `version` back so the server records and enforces it. `required` is true only
104
+ * when the project both requires consent and has a document URL to link.
105
+ */
106
+ legal: {
107
+ termsUrl?: string;
108
+ privacyUrl?: string;
109
+ version: number;
110
+ required: boolean;
111
+ };
112
+ /**
113
+ * Whether the project lets signed-in users enrol a second factor (TOTP). A
114
+ * capability flag, not a sign-in method (so it's absent from `enabledMethods`):
115
+ * gate an "enable two-factor" affordance / <MFAEnrollment/> on it. The sign-in
116
+ * 2FA challenge is handled by <SignIn/> regardless of this flag.
117
+ */
118
+ twoFactor: boolean;
119
+ /** Whether enrolled MFA is mandatory rather than optional for this project. */
120
+ mfaRequired: boolean;
121
+ /** Whether signed-in users may delete their own account. */
122
+ accountDeletion: boolean;
123
+ /** Whether organization routes and components are available for this project. */
124
+ organizations: boolean;
125
+ /**
126
+ * Whether inbound enterprise SSO is enabled for this project. SSO IS a sign-in
127
+ * method, so when true the server also pushes `'sso'` into `enabledMethods`;
128
+ * this flag mirrors the server capability (matching the `twoFactor`
129
+ * convention). <SignIn/> gates the SSO affordance on `enabledMethods`, not on
130
+ * this flag, so the two never drift.
131
+ */
132
+ sso: boolean;
133
+ /**
134
+ * JWT issuer (server contract CONTRACTS §8). Non-null only when the project's
135
+ * issuer toggle is on: exactly what a third-party verifier needs (Convex
136
+ * `auth.config.ts` = `{ type: "customJwt", issuer, jwks: jwksUrl,
137
+ * applicationID: aud, algorithm: "ES256" }`). `getToken` mints from
138
+ * `<issuer>/token`.
139
+ */
140
+ jwtIssuer: {
141
+ issuer: string;
142
+ jwksUrl: string;
143
+ aud: string;
144
+ } | null;
145
+ /** Public Cloudflare Turnstile site key for the phone OTP challenge. */
146
+ turnstileSiteKey: string | null;
147
+ /** Public Cloudflare Turnstile site key for protected sign-up/sign-in actions. */
148
+ authTurnstileSiteKey: string | null;
149
+ locale: string;
150
+ badge: boolean;
151
+ configVersion: number;
152
+ };
153
+ /**
154
+ * Fetch a project's public config. Publishable-key gated server-side; sent
155
+ * without cookies (the payload is public, so no session is needed). Throws on a
156
+ * non-2xx response so the caller can distinguish "config unavailable" from a
157
+ * project that simply has a method disabled.
158
+ */
159
+ declare function getPublicConfig(config: ResolvedAuthConfig): Promise<PublicConfig>;
160
+
161
+ /** One compatibility boundary for project-controlled authentication UI. */
162
+ type ProjectCapabilities = {
163
+ emailSignUp: boolean;
164
+ passwordSignUp: boolean;
165
+ phoneSignUp: boolean;
166
+ passwordSignIn: boolean;
167
+ passwordMinLength: number;
168
+ passwordMaxLength: number;
169
+ magicLinkSignIn: boolean;
170
+ emailOtpSignIn: boolean;
171
+ phoneSignIn: boolean;
172
+ usernameSignIn: boolean;
173
+ collectUsername: boolean;
174
+ passkeySignIn: boolean;
175
+ passkeyAdd: boolean;
176
+ firstLastName: boolean;
177
+ emailChange: boolean;
178
+ accountDeletion: boolean;
179
+ emailVerificationRequired: boolean;
180
+ emailVerificationMethod: 'link' | 'code';
181
+ totp: boolean;
182
+ mfaRequired: boolean;
183
+ backupCodes: boolean;
184
+ /** Preserve the pre-plan-35 display-name field only for an older server. */
185
+ legacyNameField: boolean;
186
+ };
187
+ /**
188
+ * Resolve current and legacy public-config shapes once, rather than spreading
189
+ * compatibility checks through each platform's components.
190
+ */
191
+ declare function resolveProjectCapabilities(config: PublicConfig | null): ProjectCapabilities;
192
+
193
+ /** Legal-consent status for the signed-in user (server contract: `GET /consent`). */
194
+ type ConsentStatus = {
195
+ /** Whether the project has an active consent gate at all. */
196
+ required: boolean;
197
+ /**
198
+ * True when the signed-in user must (re-)accept the current version — either
199
+ * never accepted, or the operator bumped the version since they did. Absent
200
+ * when `required` is false or the user isn't signed in.
201
+ */
202
+ needsConsent?: boolean;
203
+ version?: number;
204
+ termsUrl?: string;
205
+ privacyUrl?: string;
206
+ };
207
+ type ConsentAcceptResult = {
208
+ ok: boolean;
209
+ version?: number;
210
+ };
211
+ /**
212
+ * Fetch the signed-in user's consent status. Sent WITH cookies (needs the
213
+ * session). A 401 (not signed in) resolves to `{ required: false }` — new users
214
+ * are handled by the sign-up consent gate, not this one.
215
+ */
216
+ declare function getConsentStatus(config: ResolvedAuthConfig): Promise<ConsentStatus>;
217
+ /**
218
+ * Record the signed-in user's acceptance of the terms version they were shown.
219
+ * `version` is echoed from {@link getConsentStatus} so the server records only the
220
+ * exact version the UI displayed; if the operator bumped it in between, the server
221
+ * rejects with 409 (surfaced as a thrown error) and the caller should re-fetch.
222
+ */
223
+ declare function acceptConsent(config: ResolvedAuthConfig, version: number): Promise<ConsentAcceptResult>;
224
+
225
+ /**
226
+ * Short-lived JWTs for third-party backends (Convex, Supabase, Hasura - server
227
+ * contract CONTRACTS §8, `GET <issuer>/token`). The server signs a ~15-minute
228
+ * ES256 token for the signed-in user; verifiers check it statelessly against
229
+ * the project's published JWKS.
230
+ *
231
+ * Contract (recorded from the convex@1.42.1 source, evidence 17-B.9):
232
+ * - `forceRefresh: true` MUST bypass only the selected template cache and hit
233
+ * the network. A stale token served to a verifier retry is a hard failure
234
+ * loop.
235
+ * - Tokens are cached in MEMORY ONLY (never localStorage - PLAN.md security
236
+ * model), and served only while comfortably inside their `exp`. Named cache
237
+ * keys include the client environment, token subject, active organization,
238
+ * normalized template name, and server template policy version. The client
239
+ * wrapper clears all entries when the auth identity changes.
240
+ * - "Not signed in" (401) resolves to `null`; other failures throw (adapters
241
+ * map them to null per Convex's error contract).
242
+ */
243
+ type GetTokenOptions = {
244
+ /** Named JWT template configured for this environment. */
245
+ template?: string;
246
+ /** Bypass the in-memory cache and mint a fresh token from the server. */
247
+ forceRefresh?: boolean;
248
+ };
249
+ type GetToken = (options?: GetTokenOptions) => Promise<string | null>;
250
+ type TokenClient = {
251
+ getToken: GetToken;
252
+ /** Drop the cached token (call on any auth-identity change, e.g. sign-out). */
253
+ clear: () => void;
254
+ };
255
+ /**
256
+ * Build a token client bound to one config. `getToken` is cheap to call
257
+ * repeatedly: fresh cached tokens return without a request, and concurrent
258
+ * non-forced calls share one in-flight request.
259
+ */
260
+ declare function createTokenClient(config: ResolvedAuthConfig): TokenClient;
261
+
262
+ declare const AUTH_CHALLENGE_HEADER = "x-authowl-turnstile-token";
263
+ type ResponseDecoder<T> = (value: unknown) => T;
264
+ type AuthHttpRequest<T = unknown> = {
265
+ method?: 'GET' | 'POST' | 'PATCH';
266
+ body?: unknown;
267
+ query?: Record<string, string | number | boolean | undefined>;
268
+ fetchOptions?: ActionFetchOptions;
269
+ decode?: ResponseDecoder<T>;
270
+ credentials?: RequestCredentials;
271
+ };
272
+ interface AuthHttpClient {
273
+ request<T>(path: string, options?: AuthHttpRequest<T>): Promise<AuthActionResult<T>>;
274
+ }
275
+ declare function createAuthHttpClient(config: ResolvedAuthConfig, baseURL?: string): AuthHttpClient;
276
+
277
+ type JsonPrimitive = string | number | boolean | null;
278
+ type JsonValue = JsonPrimitive | JsonObject | JsonValue[];
279
+ type JsonObject = {
280
+ [key: string]: JsonValue;
281
+ };
282
+ /** Browser-safe metadata for the currently signed-in user. */
283
+ interface UserMetadata {
284
+ /** Trusted server-authored data. End users can read but cannot write it. */
285
+ publicMetadata: JsonObject;
286
+ /** End-user-owned data. Applications must treat every value as untrusted. */
287
+ unsafeMetadata: JsonObject;
288
+ /** Pass this value as expectedVersion on the next unsafe metadata write. */
289
+ metadataVersion: number;
290
+ }
291
+ interface UpdateUnsafeMetadataOptions {
292
+ expectedVersion: number;
293
+ /** JSON Merge Patch. Null members delete the matching stored key. */
294
+ unsafeMetadata: JsonObject;
295
+ }
296
+
297
+ interface UpdateProfileOptions {
298
+ name?: string;
299
+ image?: string | null;
300
+ username?: string;
301
+ firstName?: string;
302
+ lastName?: string;
303
+ }
304
+ interface ChangeEmailOptions {
305
+ newEmail: string;
306
+ callbackURL?: string;
307
+ }
308
+ interface ChangePasswordOptions {
309
+ currentPassword: string;
310
+ newPassword: string;
311
+ revokeOtherSessions?: boolean;
312
+ }
313
+ interface ChangePasswordData {
314
+ user: AuthUser;
315
+ }
316
+ /** Browser-safe metadata for one signed-in session. */
317
+ interface AccountSession {
318
+ id: string;
319
+ userId: string;
320
+ createdAt: Date;
321
+ updatedAt: Date;
322
+ expiresAt: Date;
323
+ ipAddress?: string | null;
324
+ userAgent?: string | null;
325
+ }
326
+ interface RevokeSessionOptions {
327
+ sessionId: string;
328
+ }
329
+ interface AccountStatusData {
330
+ status: boolean;
331
+ }
332
+ interface SocialAccount {
333
+ id: string;
334
+ userId: string;
335
+ providerId: string;
336
+ accountId: string;
337
+ scopes: string[];
338
+ createdAt: Date;
339
+ updatedAt: Date;
340
+ /** False when disconnecting this provider would remove the last sign-in method. */
341
+ canUnlink: boolean;
342
+ }
343
+ interface LinkSocialOptions {
344
+ provider: string;
345
+ callbackURL?: string;
346
+ errorCallbackURL?: string;
347
+ disableRedirect?: boolean;
348
+ requestSignUp?: boolean;
349
+ scopes?: string[];
350
+ idToken?: SocialIdTokenOptions & {
351
+ scopes?: string[];
352
+ };
353
+ }
354
+ interface LinkSocialData {
355
+ url: string;
356
+ redirect: boolean;
357
+ }
358
+ interface UnlinkSocialOptions {
359
+ providerId: string;
360
+ accountId?: string;
361
+ }
362
+ interface DeleteAccountOptions {
363
+ callbackURL?: string;
364
+ password?: string;
365
+ token?: string;
366
+ }
367
+ interface DeleteAccountData {
368
+ success: boolean;
369
+ message: string;
370
+ }
371
+ interface AccountClient {
372
+ /** Read public and unsafe metadata for the signed-in user. Private metadata is never returned. */
373
+ getMetadata(fetchOptions?: ActionFetchOptions): Promise<AuthActionResult<UserMetadata>>;
374
+ /** Optimistically apply a JSON Merge Patch to end-user-owned unsafe metadata. */
375
+ updateUnsafeMetadata(params: UpdateUnsafeMetadataOptions, fetchOptions?: ActionFetchOptions): Promise<AuthActionResult<UserMetadata>>;
376
+ updateProfile(params: UpdateProfileOptions, fetchOptions?: ActionFetchOptions): Promise<AuthActionResult<AccountStatusData>>;
377
+ changeEmail(params: ChangeEmailOptions, fetchOptions?: ActionFetchOptions): Promise<AuthActionResult<AccountStatusData>>;
378
+ changePassword(params: ChangePasswordOptions, fetchOptions?: ActionFetchOptions): Promise<AuthActionResult<ChangePasswordData>>;
379
+ listSessions(fetchOptions?: ActionFetchOptions): Promise<AuthActionResult<AccountSession[]>>;
380
+ revokeSession(params: RevokeSessionOptions, fetchOptions?: ActionFetchOptions): Promise<AuthActionResult<AccountStatusData>>;
381
+ revokeOtherSessions(fetchOptions?: ActionFetchOptions): Promise<AuthActionResult<AccountStatusData>>;
382
+ listSocialAccounts(fetchOptions?: ActionFetchOptions): Promise<AuthActionResult<SocialAccount[]>>;
383
+ linkSocial(params: LinkSocialOptions, fetchOptions?: ActionFetchOptions): Promise<AuthActionResult<LinkSocialData>>;
384
+ unlinkSocial(params: UnlinkSocialOptions, fetchOptions?: ActionFetchOptions): Promise<AuthActionResult<AccountStatusData>>;
385
+ /** Available only when `PublicConfig.accountDeletion` is true. */
386
+ delete(params?: DeleteAccountOptions, fetchOptions?: ActionFetchOptions): Promise<AuthActionResult<DeleteAccountData>>;
387
+ }
388
+
389
+ interface Organization {
390
+ id: string;
391
+ name: string;
392
+ slug: string;
393
+ createdAt: Date;
394
+ logo?: string | null;
395
+ metadata?: unknown;
396
+ }
397
+ interface OrganizationMemberUser {
398
+ id: string;
399
+ name: string;
400
+ email: string;
401
+ image?: string | null;
402
+ }
403
+ interface OrganizationMember {
404
+ id: string;
405
+ organizationId: string;
406
+ userId: string;
407
+ role: string;
408
+ createdAt: Date;
409
+ user?: OrganizationMemberUser;
410
+ }
411
+ interface OrganizationMemberWithUser extends OrganizationMember {
412
+ user: OrganizationMemberUser;
413
+ }
414
+ type OrganizationInvitationStatus = 'pending' | 'accepted' | 'rejected' | 'canceled';
415
+ interface OrganizationInvitation {
416
+ id: string;
417
+ organizationId: string;
418
+ email: string;
419
+ role: string;
420
+ status: OrganizationInvitationStatus;
421
+ inviterId: string;
422
+ expiresAt: Date;
423
+ createdAt: Date;
424
+ }
425
+ interface OrganizationInvitationDetails extends OrganizationInvitation {
426
+ organizationName: string;
427
+ organizationSlug: string;
428
+ inviterEmail: string;
429
+ }
430
+ interface OrganizationUserInvitation extends OrganizationInvitation {
431
+ organizationName: string;
432
+ }
433
+ interface OrganizationDetails extends Organization {
434
+ members: OrganizationMemberWithUser[];
435
+ invitations: OrganizationInvitation[];
436
+ }
437
+ interface CreateOrganizationOptions {
438
+ name: string;
439
+ slug: string;
440
+ logo?: string | null;
441
+ metadata?: Record<string, unknown>;
442
+ keepCurrentActiveOrganization?: boolean;
443
+ }
444
+ interface OrganizationSelector {
445
+ organizationId?: string;
446
+ organizationSlug?: string;
447
+ }
448
+ interface GetOrganizationOptions extends OrganizationSelector {
449
+ membersLimit?: number;
450
+ }
451
+ interface SetActiveOrganizationOptions {
452
+ organizationId?: string | null;
453
+ organizationSlug?: string;
454
+ }
455
+ /**
456
+ * A team: a named sub-group of members inside one organization.
457
+ *
458
+ * Teams are GROUPING only. Being on one grants nothing - a member's authority comes
459
+ * from their organization role. Use a team to decide what your own product shows or
460
+ * routes, never as an authority check.
461
+ */
462
+ interface OrganizationTeam {
463
+ id: string;
464
+ name: string;
465
+ organizationId: string;
466
+ createdAt: Date;
467
+ updatedAt?: Date;
468
+ }
469
+ interface ListOrganizationTeamsOptions {
470
+ /** Defaults to the caller's active organization. */
471
+ organizationId?: string;
472
+ }
473
+ interface SetActiveTeamOptions {
474
+ /** The team to make active, or null to clear it. Must be a team the caller is on. */
475
+ teamId: string | null;
476
+ }
477
+ interface UpdateOrganizationOptions {
478
+ organizationId?: string;
479
+ data: {
480
+ name?: string;
481
+ slug?: string;
482
+ logo?: string | null;
483
+ metadata?: Record<string, unknown>;
484
+ };
485
+ }
486
+ interface DeleteOrganizationOptions {
487
+ organizationId: string;
488
+ }
489
+ type OrganizationFilterOperator = 'eq' | 'ne' | 'gt' | 'gte' | 'lt' | 'lte' | 'in' | 'not_in' | 'contains' | 'starts_with' | 'ends_with';
490
+ interface ListOrganizationMembersOptions extends OrganizationSelector {
491
+ limit?: number;
492
+ offset?: number;
493
+ sortBy?: string;
494
+ sortDirection?: 'asc' | 'desc';
495
+ filterField?: string;
496
+ filterValue?: string | number | boolean;
497
+ filterOperator?: OrganizationFilterOperator;
498
+ }
499
+ interface OrganizationMembersData {
500
+ members: OrganizationMemberWithUser[];
501
+ total: number;
502
+ }
503
+ interface InviteOrganizationMemberOptions {
504
+ email: string;
505
+ role: string | string[];
506
+ organizationId?: string;
507
+ resend?: boolean;
508
+ }
509
+ interface ListOrganizationInvitationsOptions {
510
+ organizationId?: string;
511
+ }
512
+ interface GetOrganizationInvitationOptions {
513
+ id: string;
514
+ }
515
+ interface OrganizationInvitationActionOptions {
516
+ invitationId: string;
517
+ }
518
+ interface AcceptOrganizationInvitationData {
519
+ invitation: OrganizationInvitation;
520
+ member: OrganizationMember;
521
+ }
522
+ interface RejectOrganizationInvitationData {
523
+ invitation: OrganizationInvitation | null;
524
+ member: null;
525
+ }
526
+ interface RemoveOrganizationMemberOptions {
527
+ memberIdOrEmail: string;
528
+ organizationId?: string;
529
+ }
530
+ interface RemoveOrganizationMemberData {
531
+ member: OrganizationMember;
532
+ }
533
+ interface UpdateOrganizationMemberRoleOptions {
534
+ memberId: string;
535
+ role: string | string[];
536
+ organizationId?: string;
537
+ }
538
+ interface LeaveOrganizationOptions {
539
+ organizationId: string;
540
+ }
541
+ interface ListOrganizationRolesOptions {
542
+ /** Defaults to the caller's active organization. */
543
+ organizationId?: string;
544
+ }
545
+ /**
546
+ * A role assignable in an organization, as returned by the engine's
547
+ * `/organization/list-roles` (the per-org dynamic roles, which after projection
548
+ * include this project's custom roles). Built-in `owner`/`admin`/`member` are
549
+ * static and NOT returned here - the UI adds them alongside this list.
550
+ */
551
+ interface OrganizationRoleSummary {
552
+ role: string;
553
+ /** The role's ⊆14 system-statement document (engine shape); advisory here. */
554
+ permission?: unknown;
555
+ }
556
+ interface OrganizationClient {
557
+ create(params: CreateOrganizationOptions, fetchOptions?: ActionFetchOptions): Promise<AuthActionResult<Organization>>;
558
+ list(fetchOptions?: ActionFetchOptions): Promise<AuthActionResult<Organization[]>>;
559
+ get(params?: GetOrganizationOptions, fetchOptions?: ActionFetchOptions): Promise<AuthActionResult<OrganizationDetails | null>>;
560
+ setActive(params: SetActiveOrganizationOptions, fetchOptions?: ActionFetchOptions): Promise<AuthActionResult<Organization | null>>;
561
+ /**
562
+ * The teams of an organization, for resolving the team ids carried in the
563
+ * membership claim to names. Requires membership of that organization.
564
+ */
565
+ listTeams(params?: ListOrganizationTeamsOptions, fetchOptions?: ActionFetchOptions): Promise<AuthActionResult<OrganizationTeam[]>>;
566
+ /**
567
+ * Select the caller's active team, which surfaces as `activeTeamId` on the session
568
+ * and `team_id` in the project token. Only a team the caller is on can be made
569
+ * active; pass null to clear it. Clearing also happens on its own whenever the
570
+ * active organization changes.
571
+ */
572
+ setActiveTeam(params: SetActiveTeamOptions, fetchOptions?: ActionFetchOptions): Promise<AuthActionResult<OrganizationTeam | null>>;
573
+ update(params: UpdateOrganizationOptions, fetchOptions?: ActionFetchOptions): Promise<AuthActionResult<Organization | null>>;
574
+ delete(params: DeleteOrganizationOptions, fetchOptions?: ActionFetchOptions): Promise<AuthActionResult<Organization>>;
575
+ listMembers(params?: ListOrganizationMembersOptions, fetchOptions?: ActionFetchOptions): Promise<AuthActionResult<OrganizationMembersData>>;
576
+ inviteMember(params: InviteOrganizationMemberOptions, fetchOptions?: ActionFetchOptions): Promise<AuthActionResult<OrganizationInvitation>>;
577
+ listInvitations(params?: ListOrganizationInvitationsOptions, fetchOptions?: ActionFetchOptions): Promise<AuthActionResult<OrganizationInvitation[]>>;
578
+ listUserInvitations(fetchOptions?: ActionFetchOptions): Promise<AuthActionResult<OrganizationUserInvitation[]>>;
579
+ getInvitation(params: GetOrganizationInvitationOptions, fetchOptions?: ActionFetchOptions): Promise<AuthActionResult<OrganizationInvitationDetails>>;
580
+ acceptInvitation(params: OrganizationInvitationActionOptions, fetchOptions?: ActionFetchOptions): Promise<AuthActionResult<AcceptOrganizationInvitationData>>;
581
+ rejectInvitation(params: OrganizationInvitationActionOptions, fetchOptions?: ActionFetchOptions): Promise<AuthActionResult<RejectOrganizationInvitationData>>;
582
+ cancelInvitation(params: OrganizationInvitationActionOptions, fetchOptions?: ActionFetchOptions): Promise<AuthActionResult<OrganizationInvitation | null>>;
583
+ removeMember(params: RemoveOrganizationMemberOptions, fetchOptions?: ActionFetchOptions): Promise<AuthActionResult<RemoveOrganizationMemberData>>;
584
+ updateMemberRole(params: UpdateOrganizationMemberRoleOptions, fetchOptions?: ActionFetchOptions): Promise<AuthActionResult<OrganizationMember>>;
585
+ leave(params: LeaveOrganizationOptions, fetchOptions?: ActionFetchOptions): Promise<AuthActionResult<OrganizationMember>>;
586
+ /**
587
+ * List the roles assignable in an organization (the engine's dynamic roles,
588
+ * which include this project's projected custom roles). Built-in roles are
589
+ * static and not returned; surfaces populate the select alongside them.
590
+ */
591
+ listRoles(params?: ListOrganizationRolesOptions, fetchOptions?: ActionFetchOptions): Promise<AuthActionResult<OrganizationRoleSummary[]>>;
592
+ /**
593
+ * Clerk-style `has()` over the ACTIVE membership's advisory claim: true when
594
+ * the signed-in member's role matches `role` AND/OR their permissions include
595
+ * `permission`. PURE + synchronous - it reads the local session claim and
596
+ * NEVER calls `/organization/has-permission` (which only knows the 14 static
597
+ * statements and would wrongly deny custom permissions). UX affordance only;
598
+ * enforce real authorization server-side over the verified token.
599
+ */
600
+ has(params: HasParams): boolean;
601
+ /** Clerk-style `hasPermission()`: true when the active membership grants `permission`. Pure. */
602
+ hasPermission(params: {
603
+ permission: string;
604
+ }): boolean;
605
+ }
606
+
607
+ /**
608
+ * The narrow, portable surface of the underlying auth client that this SDK
609
+ * depends on and re-exports.
610
+ *
611
+ * We deliberately do NOT expose the engine's full inferred client type: it
612
+ * references internal module paths (not portable across package boundaries -
613
+ * TS2742) and is too large to serialize into a `.d.ts` (TS7056). Hand-writing
614
+ * the surface we actually use keeps the published types small, stable, and
615
+ * portable. Extend these interfaces as the SDK starts using more of the client
616
+ * (e.g. two-factor / organization / passkey flows in later plans).
617
+ */
618
+ /**
619
+ * Minimal end-user shape the SDK surfaces (mirror of the underlying session
620
+ * user). `name`/`image` are optional and nullable because the engine omits
621
+ * them entirely for users that have none - this SDK only casts the response, it
622
+ * does not normalize missing fields, so the type must not over-promise.
623
+ */
624
+ interface AuthUser {
625
+ id: string;
626
+ /** Null for phone-only users whose internal synthetic email is redacted. */
627
+ email: string | null;
628
+ /** Present for phone-authenticated users when the phone plugin is enabled. */
629
+ phoneNumber?: string | null;
630
+ /** Canonical project-scoped username, when username support is enabled. */
631
+ username?: string | null;
632
+ /** User-facing username casing retained alongside the canonical value. */
633
+ displayUsername?: string | null;
634
+ /** Structured profile names, when enabled by the project. */
635
+ firstName?: string | null;
636
+ lastName?: string | null;
637
+ emailVerified: boolean;
638
+ name?: string | null;
639
+ image?: string | null;
640
+ createdAt: Date;
641
+ updatedAt: Date;
642
+ /**
643
+ * Whether the user has a verified second factor enrolled. Optional and
644
+ * nullable because the engine only includes it once the twoFactor plugin is
645
+ * active and the user has enrolled; treat a missing value as "not enrolled".
646
+ */
647
+ twoFactorEnabled?: boolean | null;
648
+ }
649
+ interface AuthSession {
650
+ id: string;
651
+ userId: string;
652
+ expiresAt: Date;
653
+ /**
654
+ * The active organization id, present once the organization plugin is in use
655
+ * and the user has set an active org. Mirrors the JWT's `org_id` claim, so
656
+ * consumers (e.g. the Convex adapter) can re-mint tokens when it changes.
657
+ */
658
+ activeOrganizationId?: string | null;
659
+ /**
660
+ * The member's active team within the active organization, or null.
661
+ *
662
+ * AuthOwl VALIDATES this before returning it: a stored pointer at a team in
663
+ * another organization, at a deleted team, or at one the member has been removed
664
+ * from comes back null, so it never needs re-checking here. The JWT carries the
665
+ * same value as `team_id`, which is OMITTED rather than null when there is none -
666
+ * the same convention `org_id` follows.
667
+ */
668
+ activeTeamId?: string | null;
669
+ /**
670
+ * The active organization membership - the member's canonical role and its
671
+ * advisory permission claim (`org:sys_*` + custom `org:<feature>:<action>`
672
+ * ids), populated by AuthOwl's `/get-session` shaping for the active org, else
673
+ * `null`. This is the array the client `has()`/`hasPermission()` evaluate. It
674
+ * is a UX affordance, NOT a security boundary: enforce authorization on the
675
+ * server with the verified token (`@authowl/next`'s server `has()`).
676
+ */
677
+ membership?: OrganizationMembership | null;
678
+ /**
679
+ * B.5c: true while this session is held at required-MFA enrolment (the
680
+ * project requires MFA and the user has no verified factor). The SDK and
681
+ * auth() treat such a session as unauthenticated for app purposes; it is
682
+ * cleared server-side when enrolment completes (CONTRACTS §5).
683
+ */
684
+ pendingMfaEnrollment?: boolean | null;
685
+ }
686
+ interface AuthClientError {
687
+ message?: string;
688
+ status?: number;
689
+ statusText?: string;
690
+ code?: AuthOwlErrorCode | (string & {});
691
+ /** Sanitized upstream correlation id, when the service supplied one. */
692
+ requestId?: string;
693
+ /** Present on VERSION_CONFLICT so the caller can re-read before retrying. */
694
+ currentVersion?: number;
695
+ /**
696
+ * Seconds to wait before retrying, parsed from the body's `retryAfterSeconds`
697
+ * field or the `Retry-After` / `X-Retry-After` header (delta-seconds form),
698
+ * clamped to [1, 86400]. Present on rate-limit / lockout responses so callers
699
+ * can render a live countdown; the drop-in forms surface it automatically.
700
+ */
701
+ retryAfterSeconds?: number;
702
+ }
703
+ /** Secret-free lifecycle metadata exposed before an auth request is sent. */
704
+ type AuthRequestContext = Readonly<{
705
+ method: 'GET' | 'POST' | 'PATCH';
706
+ /** Endpoint path only. Query values, headers, cookies, and bodies are omitted. */
707
+ path: string;
708
+ }>;
709
+ /** Secret-free lifecycle metadata exposed after a parsed response arrives. */
710
+ type AuthResponseContext = Readonly<AuthRequestContext & {
711
+ status: number;
712
+ requestId?: string;
713
+ }>;
714
+ /** Secret-free lifecycle metadata exposed for transport or API failures. */
715
+ type AuthErrorContext = Readonly<AuthRequestContext & {
716
+ status: number;
717
+ requestId?: string;
718
+ failure: 'api' | 'aborted' | 'timeout' | 'network' | 'response_too_large' | 'invalid_response';
719
+ }>;
720
+ /** Stable AuthOwl policy codes that callers can handle without matching messages. */
721
+ type AuthOwlErrorCode = 'MAU_BUDGET_REACHED' | 'BOT_CHALLENGE_FAILED' | 'VERSION_CONFLICT' | 'SESSION_NOT_FRESH' | 'ORGANIZATION_LAST_OWNER' | 'ORGANIZATION_NOT_FOUND' | 'MEMBER_NOT_FOUND' | 'INVITATION_NOT_FOUND' | 'EMAIL_VERIFICATION_REQUIRED_FOR_INVITATION' | 'EMAIL_VERIFICATION_REQUIRED_BEFORE_ACCEPTING_OR_REJECTING_INVITATION' | 'YOU_ARE_NOT_THE_RECIPIENT_OF_THE_INVITATION';
722
+ /** Framework-neutral reactive session snapshot. */
723
+ interface SessionState {
724
+ data: {
725
+ user: AuthUser;
726
+ session: AuthSession;
727
+ } | null;
728
+ isPending: boolean;
729
+ isRefetching: boolean;
730
+ error: AuthClientError | null;
731
+ /**
732
+ * Re-fetch the current session from the server. `query.disableCookieCache`
733
+ * forces a database read AND re-sets the session cookie - the repair path
734
+ * for a stale cookie-cached `pendingMfaEnrollment` (CONTRACTS §5).
735
+ */
736
+ refetch: (options?: {
737
+ query?: {
738
+ disableCookieCache?: boolean;
739
+ };
740
+ }) => void;
741
+ }
742
+ /**
743
+ * External-store contract consumed by framework bindings such as
744
+ * `@authowl/react`. Core never imports a UI framework.
745
+ */
746
+ interface SessionStore {
747
+ subscribe(listener: () => void): () => void;
748
+ getSnapshot(): SessionState;
749
+ }
750
+ /** Standard `{ data, error }` envelope returned by the client's auth actions. */
751
+ interface AuthActionResult<T = Record<string, unknown>> {
752
+ data: T | null;
753
+ error: AuthClientError | null;
754
+ }
755
+ /** Success payload of the email sign-in action. */
756
+ interface EmailAuthData {
757
+ user: AuthUser;
758
+ /** Whether the server supplied a callback redirect. */
759
+ redirect: boolean;
760
+ url?: string;
761
+ }
762
+ /** Success payload of an in-place email one-time-code sign-in. */
763
+ interface EmailOtpAuthData {
764
+ user: AuthUser;
765
+ }
766
+ /**
767
+ * Returned by a credential sign-in when the user has two-factor enrolled: NO
768
+ * session is issued (`token`/`user` are absent) and the client must clear the 2FA
769
+ * challenge (verify a TOTP or backup code) before it is signed in. This is the
770
+ * discriminant `<SignIn/>` branches on; a headless consumer must handle it too.
771
+ */
772
+ interface TwoFactorRedirectData {
773
+ twoFactorRedirect: true;
774
+ /** Factors the server will accept, e.g. `["totp"]` / `["otp"]`. */
775
+ twoFactorMethods?: string[];
776
+ }
777
+ /**
778
+ * Success payload of the email sign-up action. `sessionCreated` is false when
779
+ * the project requires email verification or has auto-sign-in disabled, so no
780
+ * browser session was issued yet.
781
+ */
782
+ interface EmailSignUpData {
783
+ sessionCreated: boolean;
784
+ user: AuthUser;
785
+ }
786
+ /** Success payload of the social sign-in action. */
787
+ type SocialAuthData = {
788
+ redirect: true;
789
+ url: string;
790
+ } | {
791
+ redirect: false;
792
+ url: string;
793
+ } | {
794
+ redirect: false;
795
+ user: AuthUser;
796
+ };
797
+ /**
798
+ * Success payload of the enterprise SSO sign-in action. OIDC/SAML SSO is always
799
+ * a redirect flow (there is no in-place ID-token variant), so this is the
800
+ * social payload's redirect half only: the client sends the browser to the
801
+ * identity provider and the session is minted when the provider callback lands
802
+ * on a fresh page.
803
+ */
804
+ interface SsoAuthData {
805
+ /** Identity-provider authorization URL to send the browser to. */
806
+ url: string;
807
+ redirect: true;
808
+ }
809
+ /** Success payload of the sign-out action. */
810
+ interface SignOutData {
811
+ success: boolean;
812
+ }
813
+ interface EmailSignInOptions {
814
+ email: string;
815
+ password: string;
816
+ rememberMe?: boolean;
817
+ callbackURL?: string;
818
+ }
819
+ interface UsernameSignInOptions {
820
+ username: string;
821
+ password: string;
822
+ rememberMe?: boolean;
823
+ callbackURL?: string;
824
+ }
825
+ interface EmailSignUpOptions {
826
+ email: string;
827
+ password: string;
828
+ name: string;
829
+ username?: string;
830
+ firstName?: string;
831
+ lastName?: string;
832
+ image?: string;
833
+ callbackURL?: string;
834
+ /**
835
+ * The accepted legal-consent version (from `PublicConfig.legal.version`). Sent
836
+ * in the sign-up body; when the project requires consent the server rejects a
837
+ * sign-up whose value is missing or below the current version. <SignUp/> sets
838
+ * this automatically when it renders the consent checkbox.
839
+ */
840
+ consentVersion?: number;
841
+ }
842
+ interface WaitlistJoinOptions {
843
+ email: string;
844
+ }
845
+ interface WaitlistJoinData {
846
+ accepted: true;
847
+ }
848
+ /** ID-token payload for non-redirect social sign-in (e.g. native Google/Apple). */
849
+ interface SocialIdTokenOptions {
850
+ token: string;
851
+ nonce?: string;
852
+ accessToken?: string;
853
+ refreshToken?: string;
854
+ expiresAt?: number;
855
+ }
856
+ /** Options for the social sign-in action (mirror of the underlying client's). */
857
+ interface SocialSignInOptions {
858
+ provider: string;
859
+ callbackURL?: string;
860
+ errorCallbackURL?: string;
861
+ newUserCallbackURL?: string;
862
+ disableRedirect?: boolean;
863
+ scopes?: string[];
864
+ loginHint?: string;
865
+ requestSignUp?: boolean;
866
+ /** Sign in with a provider ID token instead of the redirect flow. */
867
+ idToken?: SocialIdTokenOptions;
868
+ }
869
+ /**
870
+ * Options for enterprise SSO sign-in - a SAFE SUBSET of the server's
871
+ * `signInSSOBodySchema` (the client posts the body wholesale, so no client-only
872
+ * fields leak onto the wire). It deliberately omits `scopes` and `providerType`,
873
+ * which stay server-resolved: the app injects `scopes` from the stored connection
874
+ * rather than trusting the caller, since user-supplied scopes would be a
875
+ * scope-escalation surface. Supply at least one of `email` / `providerId` /
876
+ * `domain` / `organizationSlug` so the server can resolve the connection; the
877
+ * drop-in resolves the IdP from the user's email domain. `callbackURL` is
878
+ * REQUIRED by the server - where the browser lands after the IdP round-trip.
879
+ */
880
+ interface SsoSignInOptions {
881
+ /** The user's email; its domain identifies the SSO connection to use. */
882
+ email?: string;
883
+ /** Resolve the connection by its provider id directly (instead of by email domain). */
884
+ providerId?: string;
885
+ /** Resolve the connection by verified email domain directly. */
886
+ domain?: string;
887
+ /** Resolve the connection by the organization slug it is bound to. */
888
+ organizationSlug?: string;
889
+ /** Where the browser lands after the IdP round-trip. Required by the server. */
890
+ callbackURL: string;
891
+ /** Where to send the browser if the SSO flow fails. */
892
+ errorCallbackURL?: string;
893
+ /** Where to land when SSO provisions a new account (if the connection allows it). */
894
+ newUserCallbackURL?: string;
895
+ /** `login_hint` forwarded to the identity provider when it supports one. */
896
+ loginHint?: string;
897
+ /** Explicitly request sign-up when the connection has implicit sign-up disabled. */
898
+ requestSignUp?: boolean;
899
+ }
900
+ /** Options for passwordless magic-link sign-in (a link is emailed to the user). */
901
+ interface MagicLinkSignInOptions {
902
+ email: string;
903
+ /** Where to land after the emailed link is followed. */
904
+ callbackURL?: string;
905
+ /** Where to send the browser if the link is invalid or expired. */
906
+ errorCallbackURL?: string;
907
+ /** Where to land when the link creates a new account (if the server allows it). */
908
+ newUserCallbackURL?: string;
909
+ }
910
+ /**
911
+ * Success payload of the magic-link request. No session is issued here - the
912
+ * link is emailed and the session is created when the user follows it.
913
+ */
914
+ interface MagicLinkData {
915
+ status: boolean;
916
+ }
917
+ /** Purpose of an email one-time code. Sign-in is the SDK's passwordless flow. */
918
+ type EmailOtpType = 'sign-in' | 'email-verification' | 'forget-password';
919
+ /** Options to request an email one-time code. */
920
+ interface SendVerificationOtpOptions {
921
+ email: string;
922
+ type: EmailOtpType;
923
+ }
924
+ /** Success payload of the send-OTP request (no session yet). */
925
+ interface SendOtpData {
926
+ success: boolean;
927
+ }
928
+ /** Options to complete email-OTP sign-in with the emailed code. */
929
+ interface EmailOtpSignInOptions {
930
+ email: string;
931
+ otp: string;
932
+ }
933
+ /** Options to complete required email ownership verification with a code. */
934
+ interface VerifyEmailOtpOptions {
935
+ email: string;
936
+ otp: string;
937
+ }
938
+ interface VerifyEmailOtpData {
939
+ status: boolean;
940
+ user: AuthUser;
941
+ }
942
+ /** Start an Egyptian phone OTP sign-in. Reuse idempotencyKey after an ambiguous retry. */
943
+ interface PhoneOtpStartOptions {
944
+ phoneNumber: string;
945
+ turnstileToken: string;
946
+ idempotencyKey?: string;
947
+ }
948
+ interface PhoneOtpStartData {
949
+ status: 'pending';
950
+ }
951
+ /** Verify the SMS code and create or resume the phone user's session. */
952
+ interface PhoneOtpVerifyOptions {
953
+ phoneNumber: string;
954
+ code: string;
955
+ consentVersion?: number;
956
+ }
957
+ interface PhoneAuthUser {
958
+ id: string;
959
+ name?: string | null;
960
+ phoneNumber: string;
961
+ phoneNumberVerified: boolean;
962
+ createdAt?: Date;
963
+ updatedAt?: Date;
964
+ }
965
+ interface PhoneOtpVerifyData {
966
+ status: true;
967
+ sessionCreated: true;
968
+ user: PhoneAuthUser;
969
+ }
970
+ /** Options to request a password-reset email. */
971
+ interface RequestPasswordResetOptions {
972
+ email: string;
973
+ /**
974
+ * Where the emailed reset link lands - the page hosting your reset form. The
975
+ * link validates the token server-side then redirects here with `?token=`. Its
976
+ * origin must be one of the project's allowed origins.
977
+ */
978
+ redirectTo?: string;
979
+ }
980
+ /** Options to set a new password with a reset token. */
981
+ interface ResetPasswordOptions {
982
+ newPassword: string;
983
+ /** The token from the `?token=` query param the reset link redirected to. */
984
+ token: string;
985
+ }
986
+ /** Success payload of the request-reset / reset-password actions (no session). */
987
+ interface PasswordResetData {
988
+ status: boolean;
989
+ }
990
+ /** Options to (re)send the email-verification link. */
991
+ interface SendVerificationEmailOptions {
992
+ email: string;
993
+ /**
994
+ * Where the verification link lands after it confirms the address - the page
995
+ * hosting <VerifyEmail/>. Its origin must be one of the project's allowed
996
+ * origins. Defaults to "/" server-side when omitted.
997
+ */
998
+ callbackURL?: string;
999
+ }
1000
+ /** Success payload of the send-verification-email action (no session). */
1001
+ interface VerificationEmailData {
1002
+ status: boolean;
1003
+ }
1004
+ /** Options for passkey (WebAuthn) sign-in. */
1005
+ interface PasskeySignInOptions {
1006
+ /**
1007
+ * Use conditional mediation (browser autofill) instead of a modal. The caller
1008
+ * must have an input with an `autocomplete` value containing `webauthn` on the
1009
+ * page for the browser to surface passkeys; the promise resolves when the user
1010
+ * picks one. Defaults to a modal prompt.
1011
+ */
1012
+ autoFill?: boolean;
1013
+ }
1014
+ /** Success payload of passkey sign-in. */
1015
+ interface PasskeyAuthData {
1016
+ session: AuthSession;
1017
+ user: AuthUser;
1018
+ }
1019
+ /**
1020
+ * A registered passkey credential projected from the engine's row. Only `id`,
1021
+ * `name`, `deviceType`, and `createdAt` are needed to render a management list;
1022
+ * the rest are surfaced for completeness.
1023
+ */
1024
+ interface AuthPasskey {
1025
+ id: string;
1026
+ name?: string | null;
1027
+ publicKey: string;
1028
+ userId: string;
1029
+ credentialID: string;
1030
+ counter: number;
1031
+ /** WebAuthn credential device type. */
1032
+ deviceType: 'singleDevice' | 'multiDevice';
1033
+ backedUp: boolean;
1034
+ transports?: string | null;
1035
+ createdAt: Date;
1036
+ aaguid?: string | null;
1037
+ }
1038
+ /** Options to register a new passkey for the signed-in user. */
1039
+ interface AddPasskeyOptions {
1040
+ /** Human label shown in the passkey list (defaults to a browser-chosen name). */
1041
+ name?: string;
1042
+ /** Prefer a platform (device) or cross-platform (security key) authenticator. */
1043
+ authenticatorAttachment?: 'platform' | 'cross-platform';
1044
+ }
1045
+ /** Options to rename an existing passkey. */
1046
+ interface UpdatePasskeyOptions {
1047
+ id: string;
1048
+ name: string;
1049
+ }
1050
+ /** Options to remove an existing passkey. */
1051
+ interface DeletePasskeyOptions {
1052
+ id: string;
1053
+ }
1054
+ /** Success payload of the delete-passkey action. */
1055
+ interface DeletePasskeyData {
1056
+ status: true;
1057
+ }
1058
+ /**
1059
+ * Success payload of the update-passkey action. The engine returns the updated
1060
+ * row wrapped as `{ passkey }` (not a bare passkey), so consumers read
1061
+ * `res.data.passkey`.
1062
+ */
1063
+ interface UpdatePasskeyData {
1064
+ passkey: AuthPasskey;
1065
+ }
1066
+ /** Options to begin TOTP two-factor enrolment (password-gated). */
1067
+ interface EnableTwoFactorOptions {
1068
+ password: string;
1069
+ /** Overrides the issuer label shown in the authenticator app (defaults server-side). */
1070
+ issuer?: string;
1071
+ }
1072
+ /**
1073
+ * Enrolment payload: the `otpauth://` URI to render as a QR (and its embedded
1074
+ * secret for manual entry) plus the one-time backup codes, shown ONCE. The factor
1075
+ * is not active until a live TOTP is verified.
1076
+ */
1077
+ interface TwoFactorEnableData {
1078
+ totpURI: string;
1079
+ backupCodes: string[];
1080
+ }
1081
+ /** Options to disable two-factor for the signed-in user (password-gated). */
1082
+ interface DisableTwoFactorOptions {
1083
+ password: string;
1084
+ }
1085
+ /** Options to (re)generate the backup codes (password-gated), invalidating the old set. */
1086
+ interface GenerateBackupCodesOptions {
1087
+ password: string;
1088
+ }
1089
+ /** Payload carrying a freshly-generated set of backup codes (shown once). */
1090
+ interface TwoFactorBackupCodesData {
1091
+ backupCodes: string[];
1092
+ }
1093
+ /** Verify a TOTP code - to activate a new factor, or to clear a sign-in challenge. */
1094
+ interface VerifyTotpOptions {
1095
+ code: string;
1096
+ /** Skip the challenge on this device for ~30 days (sets a trusted-device cookie). */
1097
+ trustDevice?: boolean;
1098
+ }
1099
+ /** Verify a single-use backup code to clear a sign-in challenge. */
1100
+ interface VerifyBackupCodeOptions {
1101
+ code: string;
1102
+ trustDevice?: boolean;
1103
+ }
1104
+ /** Request the emailed fallback code for a pending 2FA challenge (B.5d). */
1105
+ interface SendTwoFactorOtpOptions {
1106
+ /**
1107
+ * Inert here - the engine's send endpoint accepts this field but ignores it;
1108
+ * device trust is granted only when you verify. Pass `trustDevice` to
1109
+ * `verifyOtp` instead.
1110
+ */
1111
+ trustDevice?: boolean;
1112
+ }
1113
+ /** Success payload of the fallback-code send (the code goes to the user's email). */
1114
+ interface SendTwoFactorOtpData {
1115
+ status: boolean;
1116
+ }
1117
+ /** Verify the emailed fallback code to clear a sign-in challenge. */
1118
+ interface VerifyTwoFactorOtpOptions {
1119
+ code: string;
1120
+ trustDevice?: boolean;
1121
+ }
1122
+ /**
1123
+ * Result of clearing a 2FA challenge. The browser session is issued only via
1124
+ * Set-Cookie; its durable token is never projected into JavaScript state.
1125
+ */
1126
+ interface TwoFactorVerifyData {
1127
+ status: true;
1128
+ }
1129
+ /** Success payload of enable/disable (the engine returns a bare status flag). */
1130
+ interface TwoFactorStatusData {
1131
+ status: boolean;
1132
+ }
1133
+ /**
1134
+ * Per-call fetch options every action accepts as an optional second argument -
1135
+ * lifecycle callbacks and extra headers, matching the underlying client. The
1136
+ * callback context is intentionally `unknown`: narrow it at the call site.
1137
+ */
1138
+ interface ActionFetchOptions {
1139
+ headers?: Record<string, string>;
1140
+ /**
1141
+ * Single-use Cloudflare Turnstile token for a protected public-auth action.
1142
+ * The SDK transports it in `x-authowl-turnstile-token`; it is never serialized
1143
+ * into the action JSON body. Obtain the token with the exact action name
1144
+ * documented for the endpoint.
1145
+ */
1146
+ authChallengeToken?: string;
1147
+ signal?: AbortSignal;
1148
+ /**
1149
+ * Retry safe GET network failures and 5xx responses, capped at three retries.
1150
+ * POST and PATCH actions are never replayed by the generic client.
1151
+ */
1152
+ retry?: number;
1153
+ onRequest?: (context: AuthRequestContext) => unknown;
1154
+ onResponse?: (context: AuthResponseContext) => unknown;
1155
+ onSuccess?: (context: AuthResponseContext) => unknown;
1156
+ onError?: (context: AuthErrorContext) => unknown;
1157
+ }
1158
+ interface AuthOwlClient {
1159
+ /** Framework-neutral session state. React consumers use `@authowl/react`'s `useSession()`. */
1160
+ sessionStore: SessionStore;
1161
+ /** Signed-in account profile, credential, session, provider, and deletion actions. */
1162
+ account: AccountClient;
1163
+ /** Signed-in organization, membership, role, and invitation actions. */
1164
+ organization: OrganizationClient;
1165
+ signIn: {
1166
+ /**
1167
+ * Email + password sign-in. For a two-factor-enrolled user the result is a
1168
+ * {@link TwoFactorRedirectData} (no session) - branch on `twoFactorRedirect`
1169
+ * before treating the sign-in as complete.
1170
+ */
1171
+ email(params: EmailSignInOptions, fetchOptions?: ActionFetchOptions): Promise<AuthActionResult<EmailAuthData | TwoFactorRedirectData>>;
1172
+ /** Username + password sign-in, when enabled by project policy. */
1173
+ username(params: UsernameSignInOptions, fetchOptions?: ActionFetchOptions): Promise<AuthActionResult<EmailAuthData | TwoFactorRedirectData>>;
1174
+ social(params: SocialSignInOptions, fetchOptions?: ActionFetchOptions): Promise<AuthActionResult<SocialAuthData>>;
1175
+ /**
1176
+ * Enterprise SSO (OIDC/SAML): resolve the tenant's identity provider (by the
1177
+ * email domain, or an explicit `providerId`/`domain`/`organizationSlug`) and
1178
+ * redirect the browser to it. Always a redirect flow - no session is issued
1179
+ * here; it is minted when the provider callback lands on a fresh page.
1180
+ */
1181
+ sso(params: SsoSignInOptions, fetchOptions?: ActionFetchOptions): Promise<AuthActionResult<SsoAuthData>>;
1182
+ /** Passwordless: email a one-time sign-in link. */
1183
+ magicLink(params: MagicLinkSignInOptions, fetchOptions?: ActionFetchOptions): Promise<AuthActionResult<MagicLinkData>>;
1184
+ /** Passwordless: complete sign-in with an emailed one-time code. */
1185
+ emailOtp(params: EmailOtpSignInOptions, fetchOptions?: ActionFetchOptions): Promise<AuthActionResult<EmailOtpAuthData>>;
1186
+ /** Passwordless: sign in with a registered passkey (WebAuthn). */
1187
+ passkey(params?: PasskeySignInOptions, fetchOptions?: ActionFetchOptions): Promise<AuthActionResult<PasskeyAuthData>>;
1188
+ };
1189
+ signUp: {
1190
+ email(params: EmailSignUpOptions, fetchOptions?: ActionFetchOptions): Promise<AuthActionResult<EmailSignUpData>>;
1191
+ };
1192
+ /** Public email-only waitlist enrollment for this environment. */
1193
+ waitlist: {
1194
+ join(params: WaitlistJoinOptions, fetchOptions?: ActionFetchOptions): Promise<AuthActionResult<WaitlistJoinData>>;
1195
+ };
1196
+ /** Email one-time-code actions (request side; completion is `signIn.emailOtp`). */
1197
+ emailOtp: {
1198
+ sendVerificationOtp(params: SendVerificationOtpOptions, fetchOptions?: ActionFetchOptions): Promise<AuthActionResult<SendOtpData>>;
1199
+ /** Complete a required email verification ceremony with an emailed code. */
1200
+ verifyEmail(params: VerifyEmailOtpOptions, fetchOptions?: ActionFetchOptions): Promise<AuthActionResult<VerifyEmailOtpData>>;
1201
+ };
1202
+ /** Managed Egyptian phone OTP. Start sends the code; verify establishes the session. */
1203
+ phoneOtp: {
1204
+ start(params: PhoneOtpStartOptions, fetchOptions?: ActionFetchOptions): Promise<AuthActionResult<PhoneOtpStartData>>;
1205
+ verify(params: PhoneOtpVerifyOptions, fetchOptions?: ActionFetchOptions): Promise<AuthActionResult<PhoneOtpVerifyData>>;
1206
+ };
1207
+ /** Email a password-reset link to the user (no session issued). */
1208
+ requestPasswordReset(params: RequestPasswordResetOptions, fetchOptions?: ActionFetchOptions): Promise<AuthActionResult<PasswordResetData>>;
1209
+ /** Set a new password using the token from a reset link. */
1210
+ resetPassword(params: ResetPasswordOptions, fetchOptions?: ActionFetchOptions): Promise<AuthActionResult<PasswordResetData>>;
1211
+ /** (Re)send the email-verification link. No session required. */
1212
+ sendVerificationEmail(params: SendVerificationEmailOptions, fetchOptions?: ActionFetchOptions): Promise<AuthActionResult<VerificationEmailData>>;
1213
+ /** Passkey management for the signed-in user. */
1214
+ passkey: {
1215
+ addPasskey(params?: AddPasskeyOptions, fetchOptions?: ActionFetchOptions): Promise<AuthActionResult<AuthPasskey>>;
1216
+ /**
1217
+ * List the signed-in user's passkeys. Takes no argument: this is a GET
1218
+ * endpoint and the underlying client would send a first argument as a POST
1219
+ * body (flipping the method), so fetch options are intentionally not exposed.
1220
+ */
1221
+ listUserPasskeys(): Promise<AuthActionResult<AuthPasskey[]>>;
1222
+ updatePasskey(params: UpdatePasskeyOptions, fetchOptions?: ActionFetchOptions): Promise<AuthActionResult<UpdatePasskeyData>>;
1223
+ deletePasskey(params: DeletePasskeyOptions, fetchOptions?: ActionFetchOptions): Promise<AuthActionResult<DeletePasskeyData>>;
1224
+ };
1225
+ /**
1226
+ * TOTP two-factor for the signed-in user (enrolment) and the sign-in challenge
1227
+ * (verify). Enrolment is password-gated; a factor only becomes active once a live
1228
+ * TOTP is verified. Drives {@link useMFA}/<MFAEnrollment/>/<MFAChallenge/>.
1229
+ */
1230
+ twoFactor: {
1231
+ /** Begin enrolment: returns the TOTP URI + one-time backup codes (factor stays inactive until verified). */
1232
+ enable(params: EnableTwoFactorOptions, fetchOptions?: ActionFetchOptions): Promise<AuthActionResult<TwoFactorEnableData>>;
1233
+ /** Turn two-factor off for the user (password-gated). */
1234
+ disable(params: DisableTwoFactorOptions, fetchOptions?: ActionFetchOptions): Promise<AuthActionResult<TwoFactorStatusData>>;
1235
+ /** Verify a TOTP code: activates a pending factor, or clears a sign-in challenge. */
1236
+ verifyTotp(params: VerifyTotpOptions, fetchOptions?: ActionFetchOptions): Promise<AuthActionResult<TwoFactorVerifyData>>;
1237
+ /** Clear a sign-in challenge with a single-use backup code. */
1238
+ verifyBackupCode(params: VerifyBackupCodeOptions, fetchOptions?: ActionFetchOptions): Promise<AuthActionResult<TwoFactorVerifyData>>;
1239
+ /**
1240
+ * Email a fallback second-factor code for the pending challenge (B.5d -
1241
+ * the lost-authenticator path; only live during a challenge).
1242
+ */
1243
+ sendOtp(params?: SendTwoFactorOtpOptions, fetchOptions?: ActionFetchOptions): Promise<AuthActionResult<SendTwoFactorOtpData>>;
1244
+ /** Clear a sign-in challenge with the emailed fallback code. */
1245
+ verifyOtp(params: VerifyTwoFactorOtpOptions, fetchOptions?: ActionFetchOptions): Promise<AuthActionResult<TwoFactorVerifyData>>;
1246
+ /** Regenerate the backup codes (password-gated), invalidating the previous set. */
1247
+ generateBackupCodes(params: GenerateBackupCodesOptions, fetchOptions?: ActionFetchOptions): Promise<AuthActionResult<TwoFactorBackupCodesData>>;
1248
+ };
1249
+ signOut(fetchOptions?: ActionFetchOptions): Promise<AuthActionResult<SignOutData>>;
1250
+ /**
1251
+ * One-shot session fetch (the reactive form is `sessionStore`). `query.
1252
+ * disableCookieCache: true` forces a database read - required before acting
1253
+ * on `pendingMfaEnrollment` (its cookie-cached value can be stale-true for
1254
+ * up to 5 minutes; CONTRACTS §5).
1255
+ */
1256
+ getSession(options?: {
1257
+ query?: {
1258
+ disableCookieCache?: boolean;
1259
+ };
1260
+ }): Promise<AuthActionResult<{
1261
+ session: AuthSession;
1262
+ user: AuthUser;
1263
+ } | null>>;
1264
+ /**
1265
+ * Mint a short-lived JWT for third-party backends (Convex/Supabase/Hasura;
1266
+ * requires the project's JWT issuer to be enabled). Cached in memory and
1267
+ * refreshed ahead of expiry. `{ template: 'convex' }` selects a named
1268
+ * environment template and `{ forceRefresh: true }` bypasses only that
1269
+ * template's cache entry.
1270
+ * Resolves `null` when nobody is signed in; throws on other failures.
1271
+ */
1272
+ getToken: GetToken;
1273
+ /**
1274
+ * Legal-consent status for the signed-in user. Drives the re-consent gate: when
1275
+ * the operator bumps the terms version, `needsConsent` flips true until the user
1276
+ * accepts. `{ required: false }` when the project has no gate or nobody's signed in.
1277
+ */
1278
+ getConsentStatus(): Promise<ConsentStatus>;
1279
+ /**
1280
+ * Record the signed-in user's acceptance of the terms `version` they were shown
1281
+ * (echo `getConsentStatus().version`). A 409 (the operator bumped the version
1282
+ * meanwhile) surfaces as a thrown error; re-fetch the status and re-prompt.
1283
+ */
1284
+ acceptConsent(version: number): Promise<ConsentAcceptResult>;
1285
+ }
1286
+ /**
1287
+ * Build the underlying auth client pointed at the project's per-project endpoint.
1288
+ * Every request is sent with credentials so the HttpOnly session cookie flows
1289
+ * cross-origin (server must set SameSite=None + Secure for this to work).
1290
+ * The publishable key travels in X-Publishable-Key on every request.
1291
+ */
1292
+ declare function createAuthOwlClient(config: ResolvedAuthConfig): AuthOwlClient;
1293
+
1294
+ export { type ListOrganizationTeamsOptions as $, AUTH_CHALLENGE_HEADER as A, type EmailOtpAuthData as B, type ChangeEmailOptions as C, type DeleteAccountData as D, type EmailAuthData as E, type EmailOtpSignInOptions as F, type EmailOtpType as G, type EmailSignInOptions as H, type EmailSignUpData as I, type EmailSignUpOptions as J, type EnableTwoFactorOptions as K, type EnvironmentType as L, type GenerateBackupCodesOptions as M, type GetOrganizationInvitationOptions as N, type GetOrganizationOptions as O, type GetToken as P, type GetTokenOptions as Q, type InviteOrganizationMemberOptions as R, type JsonObject as S, type JsonPrimitive as T, type JsonValue as U, type LeaveOrganizationOptions as V, type LinkSocialData as W, type LinkSocialOptions as X, type ListOrganizationInvitationsOptions as Y, type ListOrganizationMembersOptions as Z, type ListOrganizationRolesOptions as _, type AcceptOrganizationInvitationData as a, type VerifyEmailOtpData as a$, type MagicLinkData as a0, type MagicLinkSignInOptions as a1, type Organization as a2, type OrganizationClient as a3, type OrganizationDetails as a4, type OrganizationFilterOperator as a5, type OrganizationInvitation as a6, type OrganizationInvitationActionOptions as a7, type OrganizationInvitationDetails as a8, type OrganizationInvitationStatus as a9, type SendTwoFactorOtpOptions as aA, type SendVerificationOtpOptions as aB, type SessionState as aC, type SessionStore as aD, type SetActiveOrganizationOptions as aE, type SetActiveTeamOptions as aF, type SignOutData as aG, type SocialAccount as aH, type SocialAuthData as aI, type SocialIdTokenOptions as aJ, type SocialSignInOptions as aK, type TokenClient as aL, type TwoFactorBackupCodesData as aM, type TwoFactorEnableData as aN, type TwoFactorRedirectData as aO, type TwoFactorStatusData as aP, type TwoFactorVerifyData as aQ, type UnlinkSocialOptions as aR, type UpdateOrganizationMemberRoleOptions as aS, type UpdateOrganizationOptions as aT, type UpdatePasskeyData as aU, type UpdatePasskeyOptions as aV, type UpdateProfileOptions as aW, type UpdateUnsafeMetadataOptions as aX, type UserMetadata as aY, type UsernameSignInOptions as aZ, type VerifyBackupCodeOptions as a_, type OrganizationMember as aa, type OrganizationMemberUser as ab, type OrganizationMemberWithUser as ac, type OrganizationMembersData as ad, type OrganizationRoleSummary as ae, type OrganizationSelector as af, type OrganizationTeam as ag, type OrganizationUserInvitation as ah, type PasskeyAuthData as ai, type PasskeySignInOptions as aj, type PasswordResetData as ak, type PhoneAuthUser as al, type PhoneOtpStartData as am, type PhoneOtpStartOptions as an, type PhoneOtpVerifyData as ao, type PhoneOtpVerifyOptions as ap, type ProjectCapabilities as aq, type PublicConfig as ar, type RejectOrganizationInvitationData as as, type RemoveOrganizationMemberData as at, type RemoveOrganizationMemberOptions as au, type RequestPasswordResetOptions as av, type ResetPasswordOptions as aw, type RevokeSessionOptions as ax, type SendOtpData as ay, type SendTwoFactorOtpData as az, type AccountClient as b, type VerifyEmailOtpOptions as b0, type VerifyTotpOptions as b1, type VerifyTwoFactorOtpOptions as b2, type WaitlistJoinData as b3, type WaitlistJoinOptions as b4, acceptConsent as b5, createAuthOwlClient as b6, createTokenClient as b7, getConsentStatus as b8, getPublicConfig as b9, resolveProjectCapabilities as ba, createAuthHttpClient as bb, type AuthHttpClient as bc, type AccountSession as c, type AccountStatusData as d, type ActionFetchOptions as e, type AddPasskeyOptions as f, type AuthActionResult as g, type AuthClientError as h, type AuthErrorContext as i, type AuthOwlClient as j, type AuthOwlErrorCode as k, type AuthPasskey as l, type AuthRequestContext as m, type AuthResponseContext as n, type AuthSession as o, type AuthUser as p, type ChangePasswordData as q, type ChangePasswordOptions as r, type ConsentAcceptResult as s, type ConsentStatus as t, type CreateOrganizationOptions as u, type DeleteAccountOptions as v, type DeleteOrganizationOptions as w, type DeletePasskeyData as x, type DeletePasskeyOptions as y, type DisableTwoFactorOptions as z };