@payez/next-mvp 4.1.14 → 4.1.21

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.
Files changed (116) hide show
  1. package/dist/api-handlers/account/profile.d.ts +38 -0
  2. package/dist/api-handlers/account/profile.js +73 -45
  3. package/dist/api-handlers/account/recovery/send-code.d.ts +33 -0
  4. package/dist/api-handlers/account/recovery/send-code.js +52 -18
  5. package/dist/api-handlers/account/recovery/verify-code.d.ts +33 -0
  6. package/dist/api-handlers/account/recovery/verify-code.js +52 -18
  7. package/dist/api-handlers/account/verify-email.js +15 -1
  8. package/dist/api-handlers/account/verify-sms.js +15 -1
  9. package/dist/api-handlers/auth/passkey-signin.d.ts +29 -0
  10. package/dist/api-handlers/auth/passkey-signin.js +97 -0
  11. package/dist/api-handlers/auth/refresh.js +38 -15
  12. package/dist/api-handlers/mfa/backup-code-verify.d.ts +73 -0
  13. package/dist/api-handlers/mfa/backup-code-verify.js +153 -0
  14. package/dist/api-handlers/mfa/backup-codes.d.ts +7 -0
  15. package/dist/api-handlers/mfa/backup-codes.js +40 -0
  16. package/dist/api-handlers/mfa/methods.d.ts +3 -0
  17. package/dist/api-handlers/mfa/methods.js +41 -0
  18. package/dist/api-handlers/mfa/totp-confirm.d.ts +8 -0
  19. package/dist/api-handlers/mfa/totp-confirm.js +41 -0
  20. package/dist/api-handlers/mfa/totp-enroll.d.ts +8 -0
  21. package/dist/api-handlers/mfa/totp-enroll.js +41 -0
  22. package/dist/api-handlers/mfa/totp-verify.d.ts +47 -0
  23. package/dist/api-handlers/mfa/totp-verify.js +134 -0
  24. package/dist/api-handlers/passkeys/list.d.ts +7 -0
  25. package/dist/api-handlers/passkeys/list.js +29 -0
  26. package/dist/api-handlers/passkeys/manage.d.ts +3 -0
  27. package/dist/api-handlers/passkeys/manage.js +54 -0
  28. package/dist/api-handlers/passkeys/register-options.d.ts +8 -0
  29. package/dist/api-handlers/passkeys/register-options.js +41 -0
  30. package/dist/api-handlers/passkeys/register-verify.d.ts +7 -0
  31. package/dist/api-handlers/passkeys/register-verify.js +40 -0
  32. package/dist/api-handlers/session/viability.js +19 -0
  33. package/dist/auth/better-auth.d.ts +68 -2
  34. package/dist/auth/better-auth.js +137 -18
  35. package/dist/auth/utils/idp-client.d.ts +13 -22
  36. package/dist/auth/utils/idp-client.js +12 -82
  37. package/dist/client/better-auth-client.d.ts +62 -62
  38. package/dist/lib/ensure-fresh-access-token.js +49 -8
  39. package/dist/lib/session-store.d.ts +1 -0
  40. package/dist/lib/session-store.js +19 -8
  41. package/dist/lib/token-lifecycle.d.ts +2 -0
  42. package/dist/lib/token-lifecycle.js +61 -7
  43. package/dist/models/SessionModel.d.ts +17 -0
  44. package/dist/pages/login/page.d.ts +10 -1
  45. package/dist/pages/login/page.js +69 -80
  46. package/dist/pages/verify-code/page.d.ts +10 -1
  47. package/dist/pages/verify-code/page.js +72 -4
  48. package/dist/routes/auth/passkey-signin.d.ts +13 -0
  49. package/dist/routes/auth/passkey-signin.js +18 -0
  50. package/dist/routes/auth/viability.d.ts +2 -0
  51. package/dist/routes/auth/viability.js +88 -0
  52. package/dist/routes/mfa/backup-code-verify.d.ts +1 -0
  53. package/dist/routes/mfa/backup-code-verify.js +5 -0
  54. package/dist/routes/mfa/backup-codes.d.ts +10 -0
  55. package/dist/routes/mfa/backup-codes.js +14 -0
  56. package/dist/routes/mfa/methods.d.ts +21 -0
  57. package/dist/routes/mfa/methods.js +10 -0
  58. package/dist/routes/mfa/totp-confirm.d.ts +10 -0
  59. package/dist/routes/mfa/totp-confirm.js +14 -0
  60. package/dist/routes/mfa/totp-enroll.d.ts +10 -0
  61. package/dist/routes/mfa/totp-enroll.js +14 -0
  62. package/dist/routes/mfa/totp-verify.d.ts +14 -0
  63. package/dist/routes/mfa/totp-verify.js +18 -0
  64. package/dist/routes/passkeys/list.d.ts +10 -0
  65. package/dist/routes/passkeys/list.js +14 -0
  66. package/dist/routes/passkeys/manage.d.ts +18 -0
  67. package/dist/routes/passkeys/manage.js +13 -0
  68. package/dist/routes/passkeys/register-options.d.ts +10 -0
  69. package/dist/routes/passkeys/register-options.js +14 -0
  70. package/dist/routes/passkeys/register-verify.d.ts +10 -0
  71. package/dist/routes/passkeys/register-verify.js +14 -0
  72. package/dist/server/auth.d.ts +29 -20
  73. package/dist/server/auth.js +8 -0
  74. package/dist/server/decode-session.js +37 -3
  75. package/package.json +958 -894
  76. package/scripts/check-internal-url-usage.sh +73 -73
  77. package/src/api-handlers/account/profile.ts +76 -57
  78. package/src/api-handlers/account/recovery/send-code.ts +65 -17
  79. package/src/api-handlers/account/recovery/verify-code.ts +65 -17
  80. package/src/api-handlers/account/verify-email.ts +15 -1
  81. package/src/api-handlers/account/verify-sms.ts +15 -1
  82. package/src/api-handlers/auth/passkey-signin.ts +98 -0
  83. package/src/api-handlers/auth/refresh.ts +38 -15
  84. package/src/api-handlers/mfa/backup-code-verify.ts +175 -0
  85. package/src/api-handlers/mfa/backup-codes.ts +41 -0
  86. package/src/api-handlers/mfa/methods.ts +46 -0
  87. package/src/api-handlers/mfa/totp-confirm.ts +42 -0
  88. package/src/api-handlers/mfa/totp-enroll.ts +42 -0
  89. package/src/api-handlers/mfa/totp-verify.ts +156 -0
  90. package/src/api-handlers/passkeys/list.ts +31 -0
  91. package/src/api-handlers/passkeys/manage.ts +54 -0
  92. package/src/api-handlers/passkeys/register-options.ts +42 -0
  93. package/src/api-handlers/passkeys/register-verify.ts +41 -0
  94. package/src/api-handlers/session/viability.ts +19 -0
  95. package/src/auth/better-auth.ts +158 -18
  96. package/src/auth/utils/idp-client.ts +13 -95
  97. package/src/lib/ensure-fresh-access-token.ts +49 -8
  98. package/src/lib/session-store.ts +11 -1
  99. package/src/lib/token-lifecycle.ts +70 -7
  100. package/src/models/SessionModel.ts +18 -0
  101. package/src/pages/login/page.tsx +123 -228
  102. package/src/pages/verify-code/page.tsx +71 -5
  103. package/src/routes/auth/passkey-signin.ts +13 -0
  104. package/src/routes/auth/viability.ts +89 -0
  105. package/src/routes/mfa/backup-code-verify.ts +1 -0
  106. package/src/routes/mfa/backup-codes.ts +10 -0
  107. package/src/routes/mfa/methods.ts +22 -0
  108. package/src/routes/mfa/totp-confirm.ts +10 -0
  109. package/src/routes/mfa/totp-enroll.ts +10 -0
  110. package/src/routes/mfa/totp-verify.ts +14 -0
  111. package/src/routes/passkeys/list.ts +10 -0
  112. package/src/routes/passkeys/manage.ts +23 -0
  113. package/src/routes/passkeys/register-options.ts +10 -0
  114. package/src/routes/passkeys/register-verify.ts +10 -0
  115. package/src/server/auth.ts +17 -1
  116. package/src/server/decode-session.ts +36 -3
@@ -24,7 +24,7 @@ export declare const authClient: {
24
24
  metadata?: Record<string, any> | undefined;
25
25
  } & {
26
26
  fetchOptions?: FetchOptions | undefined;
27
- }>, data_1?: FetchOptions | undefined) => Promise<import("@better-fetch/fetch").BetterFetchResponse<{
27
+ }>, data_1?: FetchOptions | undefined) => Promise<import("better-auth/react").BetterFetchResponse<{
28
28
  status: boolean;
29
29
  }, {
30
30
  code?: string | undefined;
@@ -46,7 +46,7 @@ export declare const authClient: {
46
46
  newUserCallbackURL?: string | undefined;
47
47
  };
48
48
  fetchOptions?: FetchOptions | undefined;
49
- }>, data_1?: FetchOptions | undefined) => Promise<import("@better-fetch/fetch").BetterFetchResponse<Omit<{
49
+ }>, data_1?: FetchOptions | undefined) => Promise<import("better-auth/react").BetterFetchResponse<Omit<{
50
50
  token: string;
51
51
  user: {
52
52
  id: string;
@@ -124,7 +124,7 @@ export declare const authClient: {
124
124
  additionalData?: Record<string, any> | undefined;
125
125
  } & {
126
126
  fetchOptions?: FetchOptions | undefined;
127
- }>, data_1?: FetchOptions | undefined) => Promise<import("@better-fetch/fetch").BetterFetchResponse<{
127
+ }>, data_1?: FetchOptions | undefined) => Promise<import("better-auth/react").BetterFetchResponse<{
128
128
  redirect: boolean;
129
129
  url: string;
130
130
  } | (Omit<{
@@ -159,7 +159,7 @@ export declare const authClient: {
159
159
  signOut: <FetchOptions extends import("@better-auth/core").ClientFetchOption<never, Partial<Record<string, any>> & Record<string, any>, Record<string, any> | undefined>>(data_0?: import("better-auth/react").Prettify<{
160
160
  query?: Record<string, any> | undefined;
161
161
  fetchOptions?: FetchOptions | undefined;
162
- }> | undefined, data_1?: FetchOptions | undefined) => Promise<import("@better-fetch/fetch").BetterFetchResponse<{
162
+ }> | undefined, data_1?: FetchOptions | undefined) => Promise<import("better-auth/react").BetterFetchResponse<{
163
163
  success: boolean;
164
164
  }, {
165
165
  code?: string | undefined;
@@ -181,7 +181,7 @@ export declare const authClient: {
181
181
  image?: string | undefined;
182
182
  callbackURL?: string | undefined;
183
183
  fetchOptions?: FetchOptions | undefined;
184
- }>, data_1?: FetchOptions | undefined) => Promise<import("@better-fetch/fetch").BetterFetchResponse<(Omit<{
184
+ }>, data_1?: FetchOptions | undefined) => Promise<import("better-auth/react").BetterFetchResponse<(Omit<{
185
185
  token: null;
186
186
  user: {
187
187
  id: string;
@@ -242,7 +242,7 @@ export declare const authClient: {
242
242
  rememberMe?: boolean | undefined;
243
243
  } & {
244
244
  fetchOptions?: FetchOptions | undefined;
245
- }>, data_1?: FetchOptions | undefined) => Promise<import("@better-fetch/fetch").BetterFetchResponse<Omit<{
245
+ }>, data_1?: FetchOptions | undefined) => Promise<import("better-auth/react").BetterFetchResponse<Omit<{
246
246
  redirect: boolean;
247
247
  token: string;
248
248
  url?: string | undefined;
@@ -281,7 +281,7 @@ export declare const authClient: {
281
281
  token?: string | undefined;
282
282
  } & {
283
283
  fetchOptions?: FetchOptions | undefined;
284
- }>, data_1?: FetchOptions | undefined) => Promise<import("@better-fetch/fetch").BetterFetchResponse<{
284
+ }>, data_1?: FetchOptions | undefined) => Promise<import("better-auth/react").BetterFetchResponse<{
285
285
  status: boolean;
286
286
  }, {
287
287
  code?: string | undefined;
@@ -297,7 +297,7 @@ export declare const authClient: {
297
297
  callbackURL?: string | undefined;
298
298
  };
299
299
  fetchOptions?: FetchOptions | undefined;
300
- }>, data_1?: FetchOptions | undefined) => Promise<import("@better-fetch/fetch").BetterFetchResponse<NonNullable<void | {
300
+ }>, data_1?: FetchOptions | undefined) => Promise<import("better-auth/react").BetterFetchResponse<NonNullable<void | {
301
301
  status: boolean;
302
302
  }>, {
303
303
  code?: string | undefined;
@@ -312,7 +312,7 @@ export declare const authClient: {
312
312
  callbackURL?: string | undefined;
313
313
  } & {
314
314
  fetchOptions?: FetchOptions | undefined;
315
- }>, data_1?: FetchOptions | undefined) => Promise<import("@better-fetch/fetch").BetterFetchResponse<{
315
+ }>, data_1?: FetchOptions | undefined) => Promise<import("better-auth/react").BetterFetchResponse<{
316
316
  status: boolean;
317
317
  }, {
318
318
  code?: string | undefined;
@@ -327,7 +327,7 @@ export declare const authClient: {
327
327
  callbackURL?: string | undefined;
328
328
  } & {
329
329
  fetchOptions?: FetchOptions | undefined;
330
- }>, data_1?: FetchOptions | undefined) => Promise<import("@better-fetch/fetch").BetterFetchResponse<{
330
+ }>, data_1?: FetchOptions | undefined) => Promise<import("better-auth/react").BetterFetchResponse<{
331
331
  status: boolean;
332
332
  }, {
333
333
  code?: string | undefined;
@@ -344,7 +344,7 @@ export declare const authClient: {
344
344
  revokeOtherSessions?: boolean | undefined;
345
345
  } & {
346
346
  fetchOptions?: FetchOptions | undefined;
347
- }>, data_1?: FetchOptions | undefined) => Promise<import("@better-fetch/fetch").BetterFetchResponse<Omit<{
347
+ }>, data_1?: FetchOptions | undefined) => Promise<import("better-auth/react").BetterFetchResponse<Omit<{
348
348
  token: string | null;
349
349
  user: {
350
350
  id: string;
@@ -380,7 +380,7 @@ export declare const authClient: {
380
380
  } & {
381
381
  updateSession: <FetchOptions extends import("@better-auth/core").ClientFetchOption<Partial<Partial<{}>> & Record<string, any>, Partial<Record<string, any>> & Record<string, any>, Record<string, any> | undefined>>(data_0?: import("better-auth/react").Prettify<Partial<{}> & {
382
382
  fetchOptions?: FetchOptions | undefined;
383
- }> | undefined, data_1?: FetchOptions | undefined) => Promise<import("@better-fetch/fetch").BetterFetchResponse<{
383
+ }> | undefined, data_1?: FetchOptions | undefined) => Promise<import("better-auth/react").BetterFetchResponse<{
384
384
  session: {
385
385
  id: string;
386
386
  createdAt: Date;
@@ -405,16 +405,16 @@ export declare const authClient: {
405
405
  $InferServerPlugin: ReturnType<(options: import("better-auth/plugins/magic-link").MagicLinkOptions) => {
406
406
  id: "magic-link";
407
407
  endpoints: {
408
- signInMagicLink: import("better-call").StrictEndpoint<"/sign-in/magic-link", {
408
+ signInMagicLink: import("better-auth/*").StrictEndpoint<"/sign-in/magic-link", {
409
409
  method: "POST";
410
410
  requireHeaders: true;
411
- body: import("zod").ZodObject<{
412
- email: import("zod").ZodEmail;
413
- name: import("zod").ZodOptional<import("zod").ZodString>;
414
- callbackURL: import("zod").ZodOptional<import("zod").ZodString>;
415
- newUserCallbackURL: import("zod").ZodOptional<import("zod").ZodString>;
416
- errorCallbackURL: import("zod").ZodOptional<import("zod").ZodString>;
417
- metadata: import("zod").ZodOptional<import("zod").ZodRecord<import("zod").ZodString, import("zod").ZodAny>>;
411
+ body: import("better-auth/*").ZodObject<{
412
+ email: import("better-auth/*").ZodEmail;
413
+ name: import("better-auth/*").ZodOptional<import("better-auth/*").ZodString>;
414
+ callbackURL: import("better-auth/*").ZodOptional<import("better-auth/*").ZodString>;
415
+ newUserCallbackURL: import("better-auth/*").ZodOptional<import("better-auth/*").ZodString>;
416
+ errorCallbackURL: import("better-auth/*").ZodOptional<import("better-auth/*").ZodString>;
417
+ metadata: import("better-auth/*").ZodOptional<import("better-auth/*").ZodRecord<import("better-auth/*").ZodString, import("better-auth/*").ZodAny>>;
418
418
  }, import("better-auth/*").$strip>;
419
419
  metadata: {
420
420
  openapi: {
@@ -442,15 +442,15 @@ export declare const authClient: {
442
442
  }, {
443
443
  status: boolean;
444
444
  }>;
445
- magicLinkVerify: import("better-call").StrictEndpoint<"/magic-link/verify", {
445
+ magicLinkVerify: import("better-auth/*").StrictEndpoint<"/magic-link/verify", {
446
446
  method: "GET";
447
- query: import("zod").ZodObject<{
448
- token: import("zod").ZodString;
449
- callbackURL: import("zod").ZodOptional<import("zod").ZodString>;
450
- errorCallbackURL: import("zod").ZodOptional<import("zod").ZodString>;
451
- newUserCallbackURL: import("zod").ZodOptional<import("zod").ZodString>;
447
+ query: import("better-auth/*").ZodObject<{
448
+ token: import("better-auth/*").ZodString;
449
+ callbackURL: import("better-auth/*").ZodOptional<import("better-auth/*").ZodString>;
450
+ errorCallbackURL: import("better-auth/*").ZodOptional<import("better-auth/*").ZodString>;
451
+ newUserCallbackURL: import("better-auth/*").ZodOptional<import("better-auth/*").ZodString>;
452
452
  }, import("better-auth/*").$strip>;
453
- use: ((inputContext: import("better-call").MiddlewareInputContext<import("better-call").MiddlewareOptions>) => Promise<void>)[];
453
+ use: ((inputContext: import("better-auth/*").MiddlewareInputContext<import("better-auth/*").MiddlewareOptions>) => Promise<void>)[];
454
454
  requireHeaders: true;
455
455
  metadata: {
456
456
  openapi: {
@@ -499,7 +499,7 @@ export declare const authClient: {
499
499
  options: import("better-auth/plugins/magic-link").MagicLinkOptions;
500
500
  }>;
501
501
  }[];
502
- }, FetchOptions>> | undefined, data_1?: FetchOptions | undefined) => Promise<import("@better-fetch/fetch").BetterFetchResponse<{
502
+ }, FetchOptions>> | undefined, data_1?: FetchOptions | undefined) => Promise<import("better-auth/react").BetterFetchResponse<{
503
503
  status: boolean;
504
504
  }, {
505
505
  code?: string | undefined;
@@ -516,7 +516,7 @@ export declare const authClient: {
516
516
  token?: string | undefined;
517
517
  } & {
518
518
  fetchOptions?: FetchOptions | undefined;
519
- }> | undefined, data_1?: FetchOptions | undefined) => Promise<import("@better-fetch/fetch").BetterFetchResponse<{
519
+ }> | undefined, data_1?: FetchOptions | undefined) => Promise<import("better-auth/react").BetterFetchResponse<{
520
520
  success: boolean;
521
521
  message: string;
522
522
  }, {
@@ -532,7 +532,7 @@ export declare const authClient: {
532
532
  redirectTo?: string | undefined;
533
533
  } & {
534
534
  fetchOptions?: FetchOptions | undefined;
535
- }>, data_1?: FetchOptions | undefined) => Promise<import("@better-fetch/fetch").BetterFetchResponse<{
535
+ }>, data_1?: FetchOptions | undefined) => Promise<import("better-auth/react").BetterFetchResponse<{
536
536
  status: boolean;
537
537
  message: string;
538
538
  }, {
@@ -550,7 +550,7 @@ export declare const authClient: {
550
550
  callbackURL: string;
551
551
  };
552
552
  fetchOptions?: FetchOptions | undefined;
553
- }>, data_1?: FetchOptions | undefined) => Promise<import("@better-fetch/fetch").BetterFetchResponse<never, {
553
+ }>, data_1?: FetchOptions | undefined) => Promise<import("better-auth/react").BetterFetchResponse<never, {
554
554
  code?: string | undefined;
555
555
  message?: string | undefined;
556
556
  }, FetchOptions["throw"] extends true ? true : false>>;
@@ -559,7 +559,7 @@ export declare const authClient: {
559
559
  listSessions: <FetchOptions extends import("@better-auth/core").ClientFetchOption<never, Partial<Record<string, any>> & Record<string, any>, Record<string, any> | undefined>>(data_0?: import("better-auth/react").Prettify<{
560
560
  query?: Record<string, any> | undefined;
561
561
  fetchOptions?: FetchOptions | undefined;
562
- }> | undefined, data_1?: FetchOptions | undefined) => Promise<import("@better-fetch/fetch").BetterFetchResponse<import("better-auth/react").Prettify<{
562
+ }> | undefined, data_1?: FetchOptions | undefined) => Promise<import("better-auth/react").BetterFetchResponse<import("better-auth/react").Prettify<{
563
563
  id: string;
564
564
  createdAt: Date;
565
565
  updatedAt: Date;
@@ -579,7 +579,7 @@ export declare const authClient: {
579
579
  token: string;
580
580
  } & {
581
581
  fetchOptions?: FetchOptions | undefined;
582
- }>, data_1?: FetchOptions | undefined) => Promise<import("@better-fetch/fetch").BetterFetchResponse<{
582
+ }>, data_1?: FetchOptions | undefined) => Promise<import("better-auth/react").BetterFetchResponse<{
583
583
  status: boolean;
584
584
  }, {
585
585
  code?: string | undefined;
@@ -589,7 +589,7 @@ export declare const authClient: {
589
589
  revokeSessions: <FetchOptions extends import("@better-auth/core").ClientFetchOption<never, Partial<Record<string, any>> & Record<string, any>, Record<string, any> | undefined>>(data_0?: import("better-auth/react").Prettify<{
590
590
  query?: Record<string, any> | undefined;
591
591
  fetchOptions?: FetchOptions | undefined;
592
- }> | undefined, data_1?: FetchOptions | undefined) => Promise<import("@better-fetch/fetch").BetterFetchResponse<{
592
+ }> | undefined, data_1?: FetchOptions | undefined) => Promise<import("better-auth/react").BetterFetchResponse<{
593
593
  status: boolean;
594
594
  }, {
595
595
  code?: string | undefined;
@@ -599,7 +599,7 @@ export declare const authClient: {
599
599
  revokeOtherSessions: <FetchOptions extends import("@better-auth/core").ClientFetchOption<never, Partial<Record<string, any>> & Record<string, any>, Record<string, any> | undefined>>(data_0?: import("better-auth/react").Prettify<{
600
600
  query?: Record<string, any> | undefined;
601
601
  fetchOptions?: FetchOptions | undefined;
602
- }> | undefined, data_1?: FetchOptions | undefined) => Promise<import("@better-fetch/fetch").BetterFetchResponse<{
602
+ }> | undefined, data_1?: FetchOptions | undefined) => Promise<import("better-auth/react").BetterFetchResponse<{
603
603
  status: boolean;
604
604
  }, {
605
605
  code?: string | undefined;
@@ -638,7 +638,7 @@ export declare const authClient: {
638
638
  additionalData?: Record<string, any> | undefined;
639
639
  } & {
640
640
  fetchOptions?: FetchOptions | undefined;
641
- }>, data_1?: FetchOptions | undefined) => Promise<import("@better-fetch/fetch").BetterFetchResponse<{
641
+ }>, data_1?: FetchOptions | undefined) => Promise<import("better-auth/react").BetterFetchResponse<{
642
642
  url: string;
643
643
  redirect: boolean;
644
644
  }, {
@@ -649,7 +649,7 @@ export declare const authClient: {
649
649
  listAccounts: <FetchOptions extends import("@better-auth/core").ClientFetchOption<never, Partial<Record<string, any>> & Record<string, any>, Record<string, any> | undefined>>(data_0?: import("better-auth/react").Prettify<{
650
650
  query?: Record<string, any> | undefined;
651
651
  fetchOptions?: FetchOptions | undefined;
652
- }> | undefined, data_1?: FetchOptions | undefined) => Promise<import("@better-fetch/fetch").BetterFetchResponse<{
652
+ }> | undefined, data_1?: FetchOptions | undefined) => Promise<import("better-auth/react").BetterFetchResponse<{
653
653
  scopes: string[];
654
654
  id: string;
655
655
  createdAt: Date;
@@ -672,7 +672,7 @@ export declare const authClient: {
672
672
  callbackURL?: string | undefined;
673
673
  };
674
674
  fetchOptions?: FetchOptions | undefined;
675
- }>, data_1?: FetchOptions | undefined) => Promise<import("@better-fetch/fetch").BetterFetchResponse<{
675
+ }>, data_1?: FetchOptions | undefined) => Promise<import("better-auth/react").BetterFetchResponse<{
676
676
  success: boolean;
677
677
  message: string;
678
678
  }, {
@@ -689,7 +689,7 @@ export declare const authClient: {
689
689
  accountId?: string | undefined;
690
690
  } & {
691
691
  fetchOptions?: FetchOptions | undefined;
692
- }>, data_1?: FetchOptions | undefined) => Promise<import("@better-fetch/fetch").BetterFetchResponse<{
692
+ }>, data_1?: FetchOptions | undefined) => Promise<import("better-auth/react").BetterFetchResponse<{
693
693
  status: boolean;
694
694
  }, {
695
695
  code?: string | undefined;
@@ -706,7 +706,7 @@ export declare const authClient: {
706
706
  userId?: string | undefined;
707
707
  } & {
708
708
  fetchOptions?: FetchOptions | undefined;
709
- }>, data_1?: FetchOptions | undefined) => Promise<import("@better-fetch/fetch").BetterFetchResponse<{
709
+ }>, data_1?: FetchOptions | undefined) => Promise<import("better-auth/react").BetterFetchResponse<{
710
710
  accessToken: string | undefined;
711
711
  refreshToken: string;
712
712
  accessTokenExpiresAt: Date | undefined;
@@ -730,7 +730,7 @@ export declare const authClient: {
730
730
  userId?: string | undefined;
731
731
  } & {
732
732
  fetchOptions?: FetchOptions | undefined;
733
- }>, data_1?: FetchOptions | undefined) => Promise<import("@better-fetch/fetch").BetterFetchResponse<{
733
+ }>, data_1?: FetchOptions | undefined) => Promise<import("better-auth/react").BetterFetchResponse<{
734
734
  accessToken: string;
735
735
  accessTokenExpiresAt: Date | undefined;
736
736
  scopes: string[];
@@ -747,7 +747,7 @@ export declare const authClient: {
747
747
  accountId?: string | undefined;
748
748
  } | undefined;
749
749
  fetchOptions?: FetchOptions | undefined;
750
- }> | undefined, data_1?: FetchOptions | undefined) => Promise<import("@better-fetch/fetch").BetterFetchResponse<{
750
+ }> | undefined, data_1?: FetchOptions | undefined) => Promise<import("better-auth/react").BetterFetchResponse<{
751
751
  user: import("better-auth/*").OAuth2UserInfo;
752
752
  data: Record<string, any>;
753
753
  }, {
@@ -764,7 +764,7 @@ export declare const authClient: {
764
764
  disableRefresh?: unknown;
765
765
  } | undefined;
766
766
  fetchOptions?: FetchOptions | undefined;
767
- }> | undefined, data_1?: FetchOptions | undefined) => Promise<import("@better-fetch/fetch").BetterFetchResponse<{
767
+ }> | undefined, data_1?: FetchOptions | undefined) => Promise<import("better-auth/react").BetterFetchResponse<{
768
768
  user: import("better-auth/react").StripEmptyObjects<{
769
769
  id: string;
770
770
  createdAt: Date;
@@ -813,7 +813,7 @@ export declare const authClient: {
813
813
  } | null;
814
814
  isPending: boolean;
815
815
  isRefetching: boolean;
816
- error: import("@better-fetch/fetch").BetterFetchError | null;
816
+ error: import("better-auth/react").BetterFetchError | null;
817
817
  refetch: (queryParams
818
818
  /**
819
819
  * NextAuth-compatible signOut wrapper.
@@ -847,21 +847,21 @@ export declare const authClient: {
847
847
  }>;
848
848
  };
849
849
  };
850
- $fetch: import("@better-fetch/fetch").BetterFetch<{
851
- plugins: (import("@better-fetch/fetch").BetterFetchPlugin<Record<string, any>> | {
850
+ $fetch: import("better-auth/react").BetterFetch<{
851
+ plugins: (import("better-auth/react").BetterFetchPlugin<Record<string, any>> | {
852
852
  id: string;
853
853
  name: string;
854
854
  hooks: {
855
- onSuccess(context: import("@better-fetch/fetch").SuccessContext<any>): void;
855
+ onSuccess(context: import("better-auth/react").SuccessContext<any>): void;
856
856
  };
857
857
  } | {
858
858
  id: string;
859
859
  name: string;
860
860
  hooks: {
861
- onSuccess: ((context: import("@better-fetch/fetch").SuccessContext<any>) => Promise<void> | void) | undefined;
862
- onError: ((context: import("@better-fetch/fetch").ErrorContext) => Promise<void> | void) | undefined;
863
- onRequest: (<T extends Record<string, any>>(context: import("@better-fetch/fetch").RequestContext<T>) => Promise<import("@better-fetch/fetch").RequestContext | void> | import("@better-fetch/fetch").RequestContext | void) | undefined;
864
- onResponse: ((context: import("@better-fetch/fetch").ResponseContext) => Promise<Response | void | import("@better-fetch/fetch").ResponseContext> | Response | import("@better-fetch/fetch").ResponseContext | void) | undefined;
861
+ onSuccess: ((context: import("better-auth/react").SuccessContext<any>) => Promise<void> | void) | undefined;
862
+ onError: ((context: import("better-auth/react").ErrorContext) => Promise<void> | void) | undefined;
863
+ onRequest: (<T extends Record<string, any>>(context: import("better-auth/react").RequestContext<T>) => Promise<import("better-auth/react").RequestContext | void> | import("better-auth/react").RequestContext | void) | undefined;
864
+ onResponse: ((context: import("better-auth/react").ResponseContext) => Promise<Response | void | import("better-auth/react").ResponseContext> | Response | import("better-auth/react").ResponseContext | void) | undefined;
865
865
  };
866
866
  })[];
867
867
  cache?: RequestCache | undefined;
@@ -881,12 +881,12 @@ export declare const authClient: {
881
881
  referrerPolicy?: ReferrerPolicy | undefined;
882
882
  signal?: (AbortSignal | null) | undefined;
883
883
  window?: null | undefined;
884
- onRetry?: ((response: import("@better-fetch/fetch").ResponseContext) => Promise<void> | void) | undefined;
884
+ onRetry?: ((response: import("better-auth/react").ResponseContext) => Promise<void> | void) | undefined;
885
885
  hookOptions?: {
886
886
  cloneResponse?: boolean;
887
887
  } | undefined;
888
888
  timeout?: number | undefined;
889
- customFetchImpl: import("@better-fetch/fetch").FetchEsque;
889
+ customFetchImpl: import("better-auth/react").FetchEsque;
890
890
  baseURL: string;
891
891
  throw?: boolean | undefined;
892
892
  auth?: ({
@@ -906,17 +906,17 @@ export declare const authClient: {
906
906
  params?: any;
907
907
  duplex?: "full" | "half" | undefined;
908
908
  jsonParser: (text: string) => Promise<any> | any;
909
- retry?: import("@better-fetch/fetch").RetryOptions | undefined;
909
+ retry?: import("better-auth/react").RetryOptions | undefined;
910
910
  retryAttempt?: number | undefined;
911
- output?: (import("@better-fetch/fetch").StandardSchemaV1 | typeof Blob | typeof File) | undefined;
912
- errorSchema?: import("@better-fetch/fetch").StandardSchemaV1 | undefined;
911
+ output?: (import("better-auth/react").StandardSchemaV1 | typeof Blob | typeof File) | undefined;
912
+ errorSchema?: import("better-auth/react").StandardSchemaV1 | undefined;
913
913
  disableValidation?: boolean | undefined;
914
914
  disableSignal?: boolean | undefined;
915
915
  }, unknown, unknown, {}>;
916
916
  $store: {
917
917
  notify: (signal?: (Omit<string, "$sessionSignal"> | "$sessionSignal") | undefined) => void;
918
918
  listen: (signal: Omit<string, "$sessionSignal"> | "$sessionSignal", listener: (value: boolean, oldValue?: boolean | undefined) => void) => void;
919
- atoms: Record<string, import("nanostores/atom").WritableAtom<any>>;
919
+ atoms: Record<string, import("better-auth/react").WritableAtom<any>>;
920
920
  };
921
921
  $ERROR_CODES: {
922
922
  USER_NOT_FOUND: import("better-auth/*").RawError<"USER_NOT_FOUND">;
@@ -993,7 +993,7 @@ export declare const useSession: () => {
993
993
  } | null;
994
994
  isPending: boolean;
995
995
  isRefetching: boolean;
996
- error: import("@better-fetch/fetch").BetterFetchError | null;
996
+ error: import("better-auth/react").BetterFetchError | null;
997
997
  refetch: (queryParams
998
998
  /**
999
999
  * NextAuth-compatible signOut wrapper.
@@ -1020,7 +1020,7 @@ export declare const useSession: () => {
1020
1020
  metadata?: Record<string, any> | undefined;
1021
1021
  } & {
1022
1022
  fetchOptions?: FetchOptions | undefined;
1023
- }>, data_1?: FetchOptions | undefined) => Promise<import("@better-fetch/fetch").BetterFetchResponse<{
1023
+ }>, data_1?: FetchOptions | undefined) => Promise<import("better-auth/react").BetterFetchResponse<{
1024
1024
  status: boolean;
1025
1025
  }, {
1026
1026
  code?: string | undefined;
@@ -1077,7 +1077,7 @@ export declare const useSession: () => {
1077
1077
  additionalData?: Record<string, any> | undefined;
1078
1078
  } & {
1079
1079
  fetchOptions?: FetchOptions | undefined;
1080
- }>, data_1?: FetchOptions | undefined) => Promise<import("@better-fetch/fetch").BetterFetchResponse<{
1080
+ }>, data_1?: FetchOptions | undefined) => Promise<import("better-auth/react").BetterFetchResponse<{
1081
1081
  redirect: boolean;
1082
1082
  url: string;
1083
1083
  } | (Omit<{
@@ -1120,7 +1120,7 @@ export declare const useSession: () => {
1120
1120
  rememberMe?: boolean | undefined;
1121
1121
  } & {
1122
1122
  fetchOptions?: FetchOptions | undefined;
1123
- }>, data_1?: FetchOptions | undefined) => Promise<import("@better-fetch/fetch").BetterFetchResponse<Omit<{
1123
+ }>, data_1?: FetchOptions | undefined) => Promise<import("better-auth/react").BetterFetchResponse<Omit<{
1124
1124
  redirect: boolean;
1125
1125
  token: string;
1126
1126
  url?: string | undefined;
@@ -1150,7 +1150,7 @@ export declare const useSession: () => {
1150
1150
  }, signOut: <FetchOptions extends import("@better-auth/core").ClientFetchOption<never, Partial<Record<string, any>> & Record<string, any>, Record<string, any> | undefined>>(data_0?: import("better-auth/react").Prettify<{
1151
1151
  query?: Record<string, any> | undefined;
1152
1152
  fetchOptions?: FetchOptions | undefined;
1153
- }> | undefined, data_1?: FetchOptions | undefined) => Promise<import("@better-fetch/fetch").BetterFetchResponse<{
1153
+ }> | undefined, data_1?: FetchOptions | undefined) => Promise<import("better-auth/react").BetterFetchResponse<{
1154
1154
  success: boolean;
1155
1155
  }, {
1156
1156
  code?: string | undefined;
@@ -50,6 +50,13 @@ async function ensureFreshAccessToken(sessionToken, config, options = {}) {
50
50
  }
51
51
  const storedToken = session.idpAccessToken;
52
52
  if (!storedToken) {
53
+ // Card 187871: same conflation as getIdpToken (server/auth.ts) - a live
54
+ // session with no access token and mfaVerified !== true is a user
55
+ // mid-2FA, not dead. Only terminal once the session itself claims 2FA
56
+ // is already done.
57
+ if (session.mfaVerified !== true) {
58
+ return { ok: false, code: 'NO_TOKEN_PENDING_2FA', message: 'Two-factor authentication required', status: 401, terminal: false };
59
+ }
53
60
  return { ok: false, code: 'NO_TOKEN', message: 'No IDP access token in session', status: 401, terminal: true };
54
61
  }
55
62
  const now = Date.now();
@@ -158,8 +165,16 @@ async function ensureFreshAccessToken(sessionToken, config, options = {}) {
158
165
  if (isOAuthSession && session.mfaVerified && acrValue === '1') {
159
166
  acrValue = '2';
160
167
  }
168
+ // WO-2: send the POST-lock current refresh token, not the pre-lock snapshot.
169
+ // `session` was read before we acquired the lock; a concurrent refresh that
170
+ // completed while we waited rotates the token, so the pre-lock value is stale
171
+ // and would draw an avoidable 401 (the CAS now catches the resulting wipe, but
172
+ // the round-trip is wasted). `latest` is the authoritative post-lock session.
173
+ // Auth-context (amr/acr/2FA) intentionally still derives from `session` — it is
174
+ // the identity context of THIS request, unchanged by a token rotation.
175
+ const sentRefreshToken = latest?.idpRefreshToken ?? session.idpRefreshToken;
161
176
  const body = {
162
- refresh_token: session.idpRefreshToken,
177
+ refresh_token: sentRefreshToken,
163
178
  amr: authMethods,
164
179
  acr: acrValue,
165
180
  };
@@ -200,15 +215,41 @@ async function ensureFreshAccessToken(sessionToken, config, options = {}) {
200
215
  if (!idpResponse.ok) {
201
216
  const idpError = responseData?.error || {};
202
217
  const code = idpError.code || 'UNKNOWN_ERROR';
203
- const discardToken = idpResponse.status === 401 || idpError.discard_token === true;
218
+ let discardToken = idpResponse.status === 401 || idpError.discard_token === true;
204
219
  const retryable = idpResponse.status !== 401 && idpError.retryable === true;
205
220
  if (discardToken) {
206
- await (0, session_store_1.updateSession)(sessionToken, {
207
- idpRefreshToken: '',
208
- idpRefreshTokenExpires: undefined,
209
- refreshTokenClearedAt: Date.now(),
210
- refreshTokenClearedReason: `IDP_DISCARD_TOKEN:${code}`,
211
- });
221
+ // Race-safe discard (CAS): only clear if the refresh token we used is STILL
222
+ // current. A concurrent refresh may have already rotated it — our 401 is then
223
+ // stale/expected, and wiping here would silently log out a healthy session
224
+ // (the rotation-race wipe, QA 6873 site 1/2). Compare-and-skip if it changed;
225
+ // a concurrent rotation is NOT a terminal condition.
226
+ const postRefresh = await (0, session_store_1.getSession)(sessionToken);
227
+ // CAS compares against the token we ACTUALLY SENT (WO-2: sentRefreshToken,
228
+ // the post-lock value), not the pre-lock snapshot — otherwise a token rotated
229
+ // between pre-lock read and our send would be misjudged.
230
+ const tokenUnchanged = !!sentRefreshToken && postRefresh?.idpRefreshToken === sentRefreshToken;
231
+ if (tokenUnchanged) {
232
+ await (0, session_store_1.updateSession)(sessionToken, {
233
+ idpRefreshToken: '',
234
+ idpRefreshTokenExpires: undefined,
235
+ refreshTokenClearedAt: Date.now(),
236
+ refreshTokenClearedReason: `IDP_DISCARD_TOKEN:${code}`,
237
+ });
238
+ }
239
+ else {
240
+ // Concurrent refresh already rotated the token — our 401 is stale. Return the
241
+ // freshly-rotated token directly so the loser succeeds without a retry round-trip
242
+ // (race-fix follow-up #1).
243
+ discardToken = false;
244
+ if (postRefresh?.idpAccessToken && postRefresh.idpAccessTokenExpires) {
245
+ return {
246
+ ok: true,
247
+ accessToken: postRefresh.idpAccessToken,
248
+ accessTokenExpires: postRefresh.idpAccessTokenExpires,
249
+ refreshed: true,
250
+ };
251
+ }
252
+ }
212
253
  }
213
254
  return {
214
255
  ok: false,
@@ -9,6 +9,7 @@
9
9
  */
10
10
  import { SessionData } from '../models/SessionModel';
11
11
  export type { SessionData } from '../models/SessionModel';
12
+ export declare const SESSION_TTL: number;
12
13
  export interface RefreshLockInfo {
13
14
  sessionToken: string;
14
15
  acquiredAt: number;
@@ -12,6 +12,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
12
12
  return (mod && mod.__esModule) ? mod : { "default": mod };
13
13
  };
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.SESSION_TTL = void 0;
15
16
  exports.generateSessionToken = generateSessionToken;
16
17
  exports.createSession = createSession;
17
18
  exports.getSession = getSession;
@@ -46,7 +47,10 @@ const getSessionVersionKey = (token) => `${(0, app_slug_1.getSessionPrefix)()}ve
46
47
  // Better Auth uses a different key format: ba:{appSlug}:{token}
47
48
  const getBetterAuthSessionKey = (token, appSlug) => `ba:${appSlug || 'app'}:${token}`;
48
49
  const REFRESH_LOCK_TTL = 60; // 60 seconds
49
- const SESSION_TTL = 3 * 24 * 60 * 60; // 3 days in seconds (matches refresh token lifetime)
50
+ // 3 days in seconds (matches refresh token lifetime). EXPORTED as the single source
51
+ // of session TTL — better-auth.ts derives its BA-session Redis TTL from this so the
52
+ // two can never drift apart again (the 7d-vs-3d drift = the zombie-session window, QA 6952).
53
+ exports.SESSION_TTL = 3 * 24 * 60 * 60;
50
54
  /**
51
55
  * Generates a new session token.
52
56
  * @returns A new session token string.
@@ -66,8 +70,8 @@ async function createSession(data) {
66
70
  const versionKey = getSessionVersionKey(sessionToken);
67
71
  try {
68
72
  await redis_1.default.multi()
69
- .setex(key, SESSION_TTL, JSON.stringify(data))
70
- .setex(versionKey, SESSION_TTL, '1')
73
+ .setex(key, exports.SESSION_TTL, JSON.stringify(data))
74
+ .setex(versionKey, exports.SESSION_TTL, '1')
71
75
  .exec();
72
76
  }
73
77
  catch (error) {
@@ -131,6 +135,13 @@ async function getBetterAuthSession(sessionToken, appSlug) {
131
135
  idpRefreshToken: data.idpTokens?.idpRefreshToken,
132
136
  idpAccessTokenExpires: data.idpTokens?.idpAccessTokenExpires,
133
137
  mfaVerified: data.idpTokens?.mfaVerified ?? false,
138
+ // Cards 141688/141741 — the IDP's routing decision, carried not derived.
139
+ // `null` is a real value here (IDP said nothing is outstanding), so it
140
+ // must stay distinguishable from `undefined` (we never captured it —
141
+ // true of every session minted before this change). No `?? null`:
142
+ // defaulting would turn "unknown" into "fully authenticated" and
143
+ // fail open on the existing session population.
144
+ nextStep: data.idpTokens?.nextStep,
134
145
  roles: data.idpTokens?.roles || [],
135
146
  idpClientId: data.idpTokens?.idpClientId ?? data.idpTokens?.clientId ?? data.idpClientId,
136
147
  merchantId: data.idpTokens?.merchantId ?? data.merchantId,
@@ -148,7 +159,7 @@ async function getBetterAuthSession(sessionToken, appSlug) {
148
159
  */
149
160
  async function touchSession(token) {
150
161
  const key = getSessionKey(token);
151
- await redis_1.default.expire(key, SESSION_TTL);
162
+ await redis_1.default.expire(key, exports.SESSION_TTL);
152
163
  }
153
164
  /**
154
165
  * Retrieves a session along with a version identifier for optimistic locking.
@@ -214,9 +225,9 @@ async function setSession(sessionToken, data) {
214
225
  const key = getSessionKey(sessionToken);
215
226
  const versionKey = getSessionVersionKey(sessionToken);
216
227
  await redis_1.default.multi()
217
- .setex(key, SESSION_TTL, JSON.stringify(data))
228
+ .setex(key, exports.SESSION_TTL, JSON.stringify(data))
218
229
  .incr(versionKey)
219
- .expire(versionKey, SESSION_TTL)
230
+ .expire(versionKey, exports.SESSION_TTL)
220
231
  .exec();
221
232
  }
222
233
  /**
@@ -254,9 +265,9 @@ async function updateSession(sessionToken, updates) {
254
265
  const updatedSession = { ...currentSession, ...updates };
255
266
  // Write the entire updated session back to Redis with version increment
256
267
  await redis_1.default.multi()
257
- .setex(key, SESSION_TTL, JSON.stringify(updatedSession))
268
+ .setex(key, exports.SESSION_TTL, JSON.stringify(updatedSession))
258
269
  .incr(versionKey)
259
- .expire(versionKey, SESSION_TTL)
270
+ .expire(versionKey, exports.SESSION_TTL)
260
271
  .exec();
261
272
  return updatedSession;
262
273
  }
@@ -31,6 +31,8 @@ export interface TokenError {
31
31
  error: 'NO_SESSION' | 'NO_TOKEN' | 'EXPIRED' | 'REFRESH_FAILED' | 'SESSION_EXPIRED_NO_REFRESH';
32
32
  message: string;
33
33
  terminal?: boolean;
34
+ code?: string;
35
+ resolution?: string;
34
36
  }
35
37
  export type EnsureFreshTokenResult = TokenResult | TokenError;
36
38
  /**