@luckystack/login 0.1.9 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -102,12 +102,34 @@ interface PreEmailChangePayload {
102
102
  interface PostEmailChangeRequestedPayload {
103
103
  userId: string;
104
104
  newEmail: string;
105
+ sent?: boolean;
105
106
  }
106
107
  interface PostEmailChangedPayload {
107
108
  userId: string;
108
109
  oldEmail: string;
109
110
  newEmail: string;
110
111
  }
112
+ interface LoginFailedPayload {
113
+ /** Email the attempt was for, when available. */
114
+ email?: string;
115
+ /** Resolved userId, when the attempt matched a real account. */
116
+ userId?: string;
117
+ /** Auth provider (e.g. `credentials`, `google`). */
118
+ provider: string;
119
+ /** i18n reason key describing why the attempt failed. */
120
+ reason: string;
121
+ /** Which flow the failure occurred in. */
122
+ stage: 'login' | 'register' | 'oauth';
123
+ requesterIp?: string;
124
+ }
125
+ interface PreAccountDeletePayload {
126
+ userId: string;
127
+ email?: string;
128
+ }
129
+ interface PostAccountDeletePayload {
130
+ userId: string;
131
+ email?: string;
132
+ }
111
133
  declare module '@luckystack/core' {
112
134
  interface HookPayloads {
113
135
  preLogin: PreLoginPayload;
@@ -128,6 +150,9 @@ declare module '@luckystack/core' {
128
150
  preEmailChange: PreEmailChangePayload;
129
151
  postEmailChangeRequested: PostEmailChangeRequestedPayload;
130
152
  postEmailChanged: PostEmailChangedPayload;
153
+ loginFailed: LoginFailedPayload;
154
+ preAccountDelete: PreAccountDeletePayload;
155
+ postAccountDelete: PostAccountDeletePayload;
131
156
  }
132
157
  }
133
158
 
@@ -155,9 +180,15 @@ declare const saveSession: (token: string, data: BaseSessionLayout, newUser?: bo
155
180
  * Retrieve a user session through the active session adapter.
156
181
  *
157
182
  * @param token - The session token
183
+ * @param options.refresh - When false, skip the sliding-expiration TTL
184
+ * extension. Defaults to true. Pass false for read-only probes (e.g. a
185
+ * background audit, an admin lookup) where a stolen token should NOT earn
186
+ * extra lifetime just because the server touched it (LOGIN-F9).
158
187
  * @returns The session data or null if not found
159
188
  */
160
- declare const getSession: (token: string | null) => Promise<BaseSessionLayout | null>;
189
+ declare const getSession: (token: string | null, options?: {
190
+ refresh?: boolean;
191
+ }) => Promise<BaseSessionLayout | null>;
161
192
  /**
162
193
  * Delete a user session through the active adapter and notify connected
163
194
  * clients.
@@ -221,10 +252,25 @@ interface SessionAdapter {
221
252
  trackActive(userId: string, token: string, ttlSeconds: number): Promise<void>;
222
253
  untrackActive(userId: string, token: string): Promise<void>;
223
254
  listActive(userId: string): Promise<string[]>;
255
+ /**
256
+ * Refresh the TTL on the active-tokens-per-user record WITHOUT adding a
257
+ * token (sliding-window expiration parity with the session key). Called on
258
+ * an authenticated read so a session kept alive purely by reads does not
259
+ * outlive its activeUsers entry — which would otherwise let a stolen token
260
+ * survive a sign-out-everywhere / password reset. Optional: backends whose
261
+ * active-set entries do not expire independently (or that have no TTL
262
+ * concept) can omit it. Must not create a record on miss.
263
+ */
264
+ touchActive?(userId: string, ttlSeconds: number): Promise<void>;
224
265
  /**
225
266
  * Admin walk: yield every active session record. Optional because
226
267
  * non-scannable backends (signed-JWT-stateless, log-only) cannot
227
268
  * enumerate. Callers fall back to a per-user listActive when omitted.
269
+ *
270
+ * **Dev/admin-only (LOGIN-F14).** Implementations scan the full keyspace and
271
+ * load every session into memory in one call — O(all sessions) in both Redis
272
+ * round-trips and memory. Do NOT call on the hot request path or from any
273
+ * user-facing API. Use `listActive(userId)` for per-user lookups.
228
274
  */
229
275
  listAll?(): Promise<{
230
276
  token: string;
@@ -249,101 +295,74 @@ declare const registerSessionAdapter: (adapter: SessionAdapter) => void;
249
295
  /** Read the currently-active session adapter (defaults to Redis). */
250
296
  declare const getSessionAdapter: () => SessionAdapter;
251
297
 
252
- interface UserAdapterCreateInput {
253
- email: string;
254
- provider: string;
255
- name?: string | null;
256
- password?: string | null;
257
- avatar?: string | null;
258
- avatarFallback?: string | null;
259
- language?: string | null;
260
- }
261
- interface UserRecord extends BaseSessionLayout {
262
- password?: string | null;
263
- provider?: string | null;
264
- /** Most recent successful login. Mirrors the optional `lastLogin` column on User. */
265
- lastLogin?: Date | null;
266
- }
267
- interface UserAdapter {
268
- findByEmail: (params: {
269
- email: string;
270
- provider: string;
271
- }) => Promise<UserRecord | null>;
272
- findById: (id: string) => Promise<UserRecord | null>;
273
- create: (input: UserAdapterCreateInput) => Promise<UserRecord>;
274
- update: (id: string, patch: Partial<UserRecord>) => Promise<UserRecord>;
275
- }
276
- declare const registerUserAdapter: (adapter: UserAdapter) => UserAdapter;
277
- declare const isUserAdapterRegistered: () => boolean;
278
- declare const defaultPrismaUserAdapter: () => UserAdapter;
279
- declare const getUserAdapter: () => UserAdapter;
298
+ type SessionSanitizer = (session: BaseSessionLayout) => BaseSessionLayout;
299
+ /**
300
+ * Register a redactor applied to the session record before it is persisted to
301
+ * the store and broadcast to connected clients. Call once at boot. Last write
302
+ * wins. Pass a function that returns a shallow copy with sensitive fields
303
+ * stripped, e.g. `({ totpSecret, stripeCustomerId, ...safe }) => safe`.
304
+ */
305
+ declare const registerSessionSanitizer: (sanitizer: SessionSanitizer) => void;
306
+ /** Read the active sanitizer (or `null` when none is registered). */
307
+ declare const getSessionSanitizer: () => SessionSanitizer | null;
280
308
 
281
- interface paramsType {
309
+ interface LoginOrRegisterParams {
282
310
  email?: string;
283
311
  password?: string;
284
312
  name?: string;
285
313
  confirmPassword?: string;
286
314
  }
287
- declare const createOAuthState: (providerName: string) => Promise<string | null>;
315
+ interface CredentialsLoginSuccess {
316
+ status: true;
317
+ reason: string;
318
+ newToken: string;
319
+ session: BaseSessionLayout;
320
+ }
321
+ interface CredentialsLoginFailure {
322
+ status: false;
323
+ reason: string;
324
+ }
325
+ type CredentialsLoginResult = CredentialsLoginSuccess | CredentialsLoginFailure;
326
+ declare const OAUTH_STATE_COOKIE_NAME = "ls-oauth-state";
327
+ interface CreateOAuthStateResult {
328
+ /** Opaque `state` param put on the authorize URL + echoed back on callback. */
329
+ state: string;
330
+ /**
331
+ * Random nonce the server must set as the value of the {@link OAUTH_STATE_COOKIE_NAME}
332
+ * cookie (HttpOnly, SameSite=Lax, short TTL) at the authorize redirect. The
333
+ * callback requires this back to accept the flow (browser-binding, F1).
334
+ */
335
+ stateCookie: string;
336
+ /**
337
+ * PKCE `code_challenge` (S256) when the provider opted into PKCE — the server
338
+ * appends `code_challenge=<value>&code_challenge_method=S256` to the authorize
339
+ * URL. `undefined` for non-PKCE providers (default).
340
+ */
341
+ codeChallenge?: string;
342
+ }
343
+ declare const createOAuthState: (providerName: string, options?: {
344
+ usePkce?: boolean;
345
+ returnUrl?: string;
346
+ }) => Promise<CreateOAuthStateResult | null>;
288
347
  declare const registerWithCredentials: ({ email, password, name, confirmPassword, }: {
289
348
  email: string;
290
349
  password: string;
291
350
  name: string;
292
351
  confirmPassword: string;
293
- }) => Promise<{
294
- status: boolean;
295
- reason: string;
296
- session?: undefined;
297
- } | {
298
- status: boolean;
299
- reason: string;
300
- session: Omit<UserRecord, "password">;
301
- }>;
352
+ }, options?: {
353
+ supersedeToken?: string;
354
+ }) => Promise<CredentialsLoginResult>;
302
355
  declare const loginWithCredentialsCore: ({ email, password }: {
303
356
  email: string;
304
357
  password: string;
305
358
  }, options?: {
306
359
  supersedeToken?: string;
307
- }) => Promise<{
308
- status: boolean;
309
- reason: string;
310
- newToken?: undefined;
311
- session?: undefined;
312
- } | {
313
- status: boolean;
314
- reason: Error;
315
- newToken?: undefined;
316
- session?: undefined;
317
- } | {
318
- status: boolean;
319
- reason: string;
320
- newToken: string;
321
- session: BaseSessionLayout;
322
- }>;
323
- declare const loginWithCredentials: (params: paramsType, options?: {
360
+ requesterIp?: string;
361
+ }) => Promise<CredentialsLoginResult>;
362
+ declare const loginWithCredentials: (params: LoginOrRegisterParams, options?: {
324
363
  supersedeToken?: string;
325
- }) => Promise<{
326
- status: false;
327
- reason: string;
328
- } | {
329
- status: boolean;
330
- reason: string;
331
- session?: undefined;
332
- } | {
333
- status: boolean;
334
- reason: string;
335
- session: Omit<UserRecord, "password">;
336
- } | {
337
- status: boolean;
338
- reason: Error;
339
- newToken?: undefined;
340
- session?: undefined;
341
- } | {
342
- status: boolean;
343
- reason: string;
344
- newToken: string;
345
- session: BaseSessionLayout;
346
- }>;
364
+ requesterIp?: string;
365
+ }) => Promise<CredentialsLoginResult>;
347
366
  interface OAuthCallbackResult {
348
367
  token: string;
349
368
  redirectUrl: string;
@@ -364,15 +383,38 @@ declare const logout: ({ token, socket, userId, skipSessionDelete }: {
364
383
  }) => Promise<void>;
365
384
 
366
385
  /**
367
- * Create a one-time password-reset token bound to a user id. Stored in Redis
368
- * with the configured TTL. Returns the token string — caller emails it to
369
- * the user (typically embedded in a URL).
386
+ * Whether `accountKey` is currently locked out (failed-attempt counter already
387
+ * at/over the cap). Non-incrementing — safe to call on every login attempt.
388
+ * Always `false` when the feature is disabled.
389
+ * Pass `requesterIp` to check the IP+account composite bucket (DD-LOGIN-F5).
390
+ */
391
+ declare const isAccountLocked: (accountKey: string, requesterIp?: string) => Promise<boolean>;
392
+ /**
393
+ * Increment the failed-attempt counter for `accountKey`. Call on every failed
394
+ * credentials login for a known/looked-up account. No-op when disabled.
395
+ * Pass `requesterIp` to increment the IP+account composite bucket (DD-LOGIN-F5).
396
+ */
397
+ declare const recordAuthFailure: (accountKey: string, requesterIp?: string) => Promise<void>;
398
+ /**
399
+ * Reset the failed-attempt counter for `accountKey` (call after a SUCCESSFUL
400
+ * login so a user who eventually gets their password right isn't penalised by
401
+ * earlier typos). No-op when disabled.
402
+ * Pass `requesterIp` to clear the IP+account composite bucket (DD-LOGIN-F5).
403
+ */
404
+ declare const clearAuthFailures: (accountKey: string, requesterIp?: string) => Promise<void>;
405
+
406
+ /**
407
+ * Create a one-time password-reset token bound to a user id. Any previously
408
+ * issued (but not yet consumed) token for the same user is invalidated first
409
+ * (LOGIN-F16). Stored in Redis with the configured TTL — only `sha256(token)`
410
+ * is persisted (hash-at-rest). Returns the raw token string — caller emails it
411
+ * to the user (typically embedded in a URL).
370
412
  */
371
413
  declare const createPasswordResetToken: (userId: string) => Promise<string>;
372
414
  /**
373
415
  * Validate and consume a password-reset token. Returns the bound userId on
374
- * success and removes the token (one-time use). Returns null when the token
375
- * is missing, expired, or malformed.
416
+ * success and removes the token (one-time use, atomic GET+DEL). Returns null
417
+ * when the token is missing, expired, malformed, or already consumed.
376
418
  */
377
419
  declare const consumePasswordResetToken: (token: string) => Promise<string | null>;
378
420
  /**
@@ -382,6 +424,20 @@ declare const consumePasswordResetToken: (token: string) => Promise<string | nul
382
424
  * (`projectConfig.auth.passwordPolicy`) before hashing — throws a `PasswordPolicyError`
383
425
  * when the plaintext fails policy. Catch and surface the error code to the
384
426
  * client; framework-mode reset/change flows already do this.
427
+ *
428
+ * ADR — DD-LOGIN-F17: this primitive intentionally does NOT revoke sessions.
429
+ * Session revocation is the responsibility of each calling route because the
430
+ * right behaviour differs per use-case:
431
+ * - `reset-password/confirmReset_v1` revokes ALL sessions (`revokeUserSessions(userId, null)`)
432
+ * because a forgot-password reset means the old credential is compromised.
433
+ * - `settings/changePassword_v1` revokes every OTHER session but keeps the
434
+ * current one active (`revokeUserSessions(userId, user.token)`) so the
435
+ * user is not kicked from the device they changed the password on.
436
+ * - Custom consumers may want a third behaviour (e.g. re-use the existing
437
+ * token after an admin password-force) — keeping the primitive pure lets
438
+ * them compose it freely.
439
+ * If you call this function directly, YOU must call `revokeUserSessions`
440
+ * afterwards unless you have a deliberate reason not to.
385
441
  */
386
442
  declare const updatePasswordHash: (userId: string, plaintext: string) => Promise<void>;
387
443
  /**
@@ -432,15 +488,19 @@ interface EmailChangePayload {
432
488
  }
433
489
  /**
434
490
  * Create a one-time email-change token bound to a user id + the new email
435
- * address. Stored in Redis with the configured TTL. Returns the token string
436
- * — caller emails the token (embedded in a URL) to the NEW address so the
491
+ * address. Any previously issued (but not yet consumed) token for the same
492
+ * user is invalidated first (LOGIN-F16) so at most one confirmation link per
493
+ * user is redeemable. Stored in Redis with the configured TTL — only
494
+ * `sha256(token)` is persisted (hash-at-rest). Returns the raw token string —
495
+ * caller emails the token (embedded in a URL) to the NEW address so the
437
496
  * confirmation click proves ownership of the new mailbox.
438
497
  */
439
498
  declare const createEmailChangeToken: (userId: string, newEmail: string) => Promise<string>;
440
499
  /**
441
500
  * Validate and consume an email-change token. Returns the bound
442
- * `{ userId, newEmail }` on success and removes the token (one-time use).
443
- * Returns null when the token is missing, expired, or malformed.
501
+ * `{ userId, newEmail }` on success and removes the token (one-time use, atomic
502
+ * GET+DEL). Returns null when the token is missing, expired, malformed, or
503
+ * already consumed.
444
504
  */
445
505
  declare const consumeEmailChangeToken: (token: string) => Promise<EmailChangePayload | null>;
446
506
 
@@ -469,6 +529,7 @@ declare const sendEmailChangeConfirmation: ({ userId, newEmail, userName, brand
469
529
  }>;
470
530
 
471
531
  type OAuthUserData = Record<string, unknown>;
532
+ declare const asOAuthUserData: (value: unknown) => OAuthUserData;
472
533
  interface CredentialsProvider {
473
534
  name: 'credentials';
474
535
  }
@@ -495,6 +556,15 @@ interface FullOAuthProvider {
495
556
  scope: string[];
496
557
  nameKey: string;
497
558
  emailKey: string;
559
+ /**
560
+ * Optional key on the userInfo response holding a provider "email verified"
561
+ * boolean. When set AND the field is present-and-falsy, the framework rejects
562
+ * the profile rather than trusting an unverified address — defense-in-depth
563
+ * against account-linking takeover under the `'unified'` strategy (SEC-21).
564
+ * A missing field (provider doesn't report it) is treated as "trusted",
565
+ * preserving behaviour for providers that don't expose the flag.
566
+ */
567
+ emailVerifiedKey?: string;
498
568
  avatarKey?: string;
499
569
  avatarCodeKey: string;
500
570
  getEmail?: (accessToken: string) => Promise<string | false | undefined>;
@@ -525,6 +595,25 @@ interface FullOAuthProvider {
525
595
  userData: OAuthUserData;
526
596
  accessToken: string;
527
597
  }) => Promise<Record<string, unknown>> | Record<string, unknown>;
598
+ /**
599
+ * Extra query params appended to the authorization-redirect URL (CFG-21).
600
+ * Lets a provider request e.g. `access_type=offline`, `login_hint=...`, or
601
+ * override the framework's default `prompt=select_account`. The server's
602
+ * authorize route merges these over the built-in params (a key present here
603
+ * wins). Reserved OAuth params (`client_id`, `redirect_uri`, `scope`,
604
+ * `response_type`, `state`, `code_challenge`, `code_challenge_method`) should
605
+ * NOT be set here — they are framework-owned. Default unset.
606
+ */
607
+ extraAuthorizationParams?: Record<string, string>;
608
+ /**
609
+ * Opt this provider into PKCE (RFC 7636, S256) (F11). When `true`, the
610
+ * framework generates a `code_verifier` at flow start, stores it server-side
611
+ * with the OAuth state, sends `code_challenge`/`code_challenge_method=S256` on
612
+ * the authorize redirect, and replays the verifier at token exchange. Required
613
+ * by OAuth 2.1 / PKCE-mandating providers (X/Twitter, some Okta/Auth0
614
+ * policies). Default `false` (no PKCE — existing flows are byte-identical).
615
+ */
616
+ usePkce?: boolean;
528
617
  }
529
618
  type OAuthProvider = CredentialsProvider | FullOAuthProvider;
530
619
  declare const isFullOAuthProvider: (provider: OAuthProvider) => provider is FullOAuthProvider;
@@ -554,6 +643,13 @@ interface OAuthHelperInput {
554
643
  * pattern.
555
644
  */
556
645
  extraSessionFields?: FullOAuthProvider['extraSessionFields'];
646
+ /**
647
+ * Extra query params for the authorize redirect (CFG-21). See
648
+ * `FullOAuthProvider.extraAuthorizationParams`.
649
+ */
650
+ extraAuthorizationParams?: Record<string, string>;
651
+ /** Opt this provider into PKCE (S256) (F11). See `FullOAuthProvider.usePkce`. */
652
+ usePkce?: boolean;
557
653
  }
558
654
  declare const credentialsProvider: () => CredentialsProvider;
559
655
  declare const googleProvider: (input: OAuthHelperInput) => FullOAuthProvider;
@@ -571,10 +667,81 @@ interface MicrosoftProviderInput extends OAuthHelperInput {
571
667
  apiVersion?: string;
572
668
  /** Graph API version segment for /me. Default `'v1.0'`. */
573
669
  graphApiVersion?: string;
670
+ /**
671
+ * Allow falling back to `userPrincipalName` as the account email when Graph
672
+ * `/me.mail` is empty (SEC-11). A UPN is NOT guaranteed routable or verified;
673
+ * under the `'unified'` account strategy a UPN equal to a victim's email would
674
+ * link accounts, and it commonly mis-keys an account on a non-deliverable
675
+ * address (reset emails never arrive). Default `false` — only enable when the
676
+ * tenant guarantees UPN == primary SMTP. When `false` and `.mail` is empty the
677
+ * provider reports "no email" and the login is rejected rather than linked.
678
+ */
679
+ allowUpnFallback?: boolean;
574
680
  }
575
681
  declare const microsoftProvider: (input: MicrosoftProviderInput) => FullOAuthProvider;
576
682
  declare const getOAuthProviders: () => OAuthProvider[];
577
683
  declare const registerOAuthProviders: (providers: OAuthProvider[]) => OAuthProvider[];
684
+ /**
685
+ * Register a factory function that builds the provider list on first use.
686
+ * Prefer this over `registerOAuthProviders` from the package `register` side-
687
+ * effect so config/env reads are deferred to request time and survive any
688
+ * `registerProjectConfig` call that happens after package import.
689
+ * A subsequent `registerOAuthProviders` call replaces the factory.
690
+ */
691
+ declare const registerOAuthProviderFactory: (factory: () => OAuthProvider[]) => void;
692
+
693
+ interface UserAdapterCreateInput {
694
+ email: string;
695
+ provider: string;
696
+ name?: string | null;
697
+ password?: string | null;
698
+ avatar?: string | null;
699
+ avatarFallback?: string | null;
700
+ language?: string | null;
701
+ }
702
+ interface UserRecord extends BaseSessionLayout {
703
+ password?: string | null;
704
+ provider?: string | null;
705
+ /** Most recent successful login. Mirrors the optional `lastLogin` column on User. */
706
+ lastLogin?: Date | null;
707
+ }
708
+ interface UserAdapter {
709
+ findByEmail: (params: {
710
+ email: string;
711
+ provider: string;
712
+ }) => Promise<UserRecord | null>;
713
+ /**
714
+ * Look up a user by email IRRESPECTIVE of provider. Required only when
715
+ * `auth.providerAccountStrategy === 'unified'` — the framework resolves
716
+ * accounts by email alone so the same address maps to one User across
717
+ * providers. Optional so existing custom adapters keep compiling; when a
718
+ * project sets `'unified'` but its adapter omits this method, the framework
719
+ * logs a one-time warning and falls back to provider-scoped lookup.
720
+ */
721
+ findByEmailAnyProvider?: (params: {
722
+ email: string;
723
+ }) => Promise<UserRecord | null>;
724
+ findById: (id: string) => Promise<UserRecord | null>;
725
+ create: (input: UserAdapterCreateInput) => Promise<UserRecord>;
726
+ update: (id: string, patch: Partial<UserRecord>) => Promise<UserRecord>;
727
+ /**
728
+ * Hard-delete a user. Account-deletion flows (`deleteAccount_v1`) call this
729
+ * instead of reaching past the adapter to `prisma.user.delete`, so a custom
730
+ * adapter / non-Prisma store / soft-delete strategy stays in control. To
731
+ * implement a soft delete, ignore the hard delete here and instead expose it
732
+ * through `update({ deletedAt: new Date() })` from your route.
733
+ *
734
+ * Optional so existing custom adapters keep compiling; the default Prisma
735
+ * adapter implements it. Consumers calling account deletion against a custom
736
+ * adapter that omits `delete` get a clear "adapter does not support delete"
737
+ * failure rather than a silent Prisma bypass.
738
+ */
739
+ delete?: (id: string) => Promise<void>;
740
+ }
741
+ declare const registerUserAdapter: (adapter: UserAdapter) => UserAdapter;
742
+ declare const isUserAdapterRegistered: () => boolean;
743
+ declare const defaultPrismaUserAdapter: () => UserAdapter;
744
+ declare const getUserAdapter: () => UserAdapter;
578
745
 
579
746
  interface PostLoginRedirectInput {
580
747
  userId: string;
@@ -586,4 +753,4 @@ type PostLoginRedirectResolver = (input: PostLoginRedirectInput) => string | Pro
586
753
  declare const registerPostLoginRedirect: (resolver: PostLoginRedirectResolver) => PostLoginRedirectResolver;
587
754
  declare const getPostLoginRedirect: () => PostLoginRedirectResolver | null;
588
755
 
589
- export { type CredentialsProvider, type EmailChangePayload, type FullOAuthProvider, type OAuthProvider, PasswordPolicyError, type PostEmailChangeRequestedPayload, type PostEmailChangedPayload, type PostLoginPayload, type PostLoginRedirectInput, type PostLoginRedirectResolver, type PostLogoutPayload, type PostRegisterPayload, type PostSessionCreatePayload, type PostSessionDeletePayload, type PreEmailChangePayload, type PreLoginPayload, type PreLogoutPayload, type PreRegisterPayload, type PreSessionCreatePayload, type PreSessionDeletePayload, type SessionAdapter, type UserAdapter, type UserAdapterCreateInput, type UserRecord, activeUsersKeyFor, consumeEmailChangeToken, consumePasswordResetToken, createEmailChangeToken, createOAuthState, createPasswordResetToken, credentialsProvider, defaultPrismaUserAdapter, deleteSession, discordProvider, facebookProvider, getAllSessions, getOAuthProviders, getPostLoginRedirect, getSession, getSessionAdapter, getUserAdapter, githubProvider, googleProvider, isFullOAuthProvider, isUserAdapterRegistered, loginCallback, loginWithCredentials, loginWithCredentialsCore, logout, microsoftProvider, redisSessionAdapter, registerOAuthProviders, registerPostLoginRedirect, registerSessionAdapter, registerUserAdapter, registerWithCredentials, revokeUserSessions, saveSession, sendEmailChangeConfirmation, sendPasswordResetEmail, sessionKeyFor, updatePasswordHash, validatePassword, verifyPassword };
756
+ export { type CreateOAuthStateResult, type CredentialsLoginFailure, type CredentialsLoginResult, type CredentialsLoginSuccess, type CredentialsProvider, type EmailChangePayload, type FullOAuthProvider, type LoginFailedPayload, OAUTH_STATE_COOKIE_NAME, type OAuthCallbackResult, type OAuthProvider, type OAuthUserData, PasswordPolicyError, type PostAccountDeletePayload, type PostEmailChangeRequestedPayload, type PostEmailChangedPayload, type PostLoginPayload, type PostLoginRedirectInput, type PostLoginRedirectResolver, type PostLogoutPayload, type PostRegisterPayload, type PostSessionCreatePayload, type PostSessionDeletePayload, type PreAccountDeletePayload, type PreEmailChangePayload, type PreLoginPayload, type PreLogoutPayload, type PreRegisterPayload, type PreSessionCreatePayload, type PreSessionDeletePayload, type SessionAdapter, type SessionSanitizer, type UserAdapter, type UserAdapterCreateInput, type UserRecord, activeUsersKeyFor, asOAuthUserData, clearAuthFailures, consumeEmailChangeToken, consumePasswordResetToken, createEmailChangeToken, createOAuthState, createPasswordResetToken, credentialsProvider, defaultPrismaUserAdapter, deleteSession, discordProvider, facebookProvider, getAllSessions, getOAuthProviders, getPostLoginRedirect, getSession, getSessionAdapter, getSessionSanitizer, getUserAdapter, githubProvider, googleProvider, isAccountLocked, isFullOAuthProvider, isUserAdapterRegistered, loginCallback, loginWithCredentials, loginWithCredentialsCore, logout, microsoftProvider, recordAuthFailure, redisSessionAdapter, registerOAuthProviderFactory, registerOAuthProviders, registerPostLoginRedirect, registerSessionAdapter, registerSessionSanitizer, registerUserAdapter, registerWithCredentials, revokeUserSessions, saveSession, sendEmailChangeConfirmation, sendPasswordResetEmail, sessionKeyFor, updatePasswordHash, validatePassword, verifyPassword };