@payez/next-mvp 4.0.46 → 4.0.49

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 (63) hide show
  1. package/dist/api/auth-handler.d.ts +0 -2
  2. package/dist/api/auth-handler.js +1 -1
  3. package/dist/api-handlers/admin/stats.js +24 -14
  4. package/dist/api-handlers/auth/refresh.d.ts +4 -6
  5. package/dist/api-handlers/auth/refresh.js +5 -7
  6. package/dist/api-handlers/auth/signout.d.ts +6 -15
  7. package/dist/api-handlers/auth/signout.js +9 -16
  8. package/dist/api-handlers/auth/update-session.d.ts +6 -15
  9. package/dist/api-handlers/auth/update-session.js +7 -15
  10. package/dist/api-handlers/auth/verify-code.d.ts +6 -15
  11. package/dist/api-handlers/auth/verify-code.js +7 -15
  12. package/dist/api-handlers/session/viability.js +2 -2
  13. package/dist/auth/better-auth.d.ts +3 -19
  14. package/dist/auth/better-auth.js +7 -13
  15. package/dist/client/better-auth-client.d.ts +7 -8
  16. package/dist/client/better-auth-client.js +3 -4
  17. package/dist/lib/auth-secret.d.ts +17 -0
  18. package/dist/lib/{nextauth-secret.js → auth-secret.js} +31 -15
  19. package/dist/lib/demo-mode.js +3 -1
  20. package/dist/lib/idp-client-config.d.ts +6 -2
  21. package/dist/lib/idp-client-config.js +35 -21
  22. package/dist/lib/secret-validation.d.ts +1 -1
  23. package/dist/lib/secret-validation.js +2 -2
  24. package/dist/lib/startup-init.d.ts +3 -3
  25. package/dist/lib/startup-init.js +23 -18
  26. package/dist/lib/test-aware-get-token.js +2 -51
  27. package/dist/routes/account/masked-info.d.ts +1 -1
  28. package/dist/routes/account/masked-info.js +1 -1
  29. package/dist/routes/account/send-code.d.ts +1 -1
  30. package/dist/routes/account/send-code.js +1 -1
  31. package/dist/routes/account/verify-email.d.ts +1 -1
  32. package/dist/routes/account/verify-email.js +1 -1
  33. package/dist/routes/account/verify-sms.d.ts +1 -1
  34. package/dist/routes/account/verify-sms.js +1 -1
  35. package/dist/routes/auth/refresh.js +3 -8
  36. package/dist/server/auth.d.ts +28 -7
  37. package/dist/server/auth.js +106 -55
  38. package/dist/server/decode-session.js +2 -2
  39. package/dist/vibe/hooks/index.d.ts +1 -1
  40. package/package.json +888 -893
  41. package/src/api/auth-handler.ts +0 -4
  42. package/src/api-handlers/admin/stats.ts +249 -238
  43. package/src/api-handlers/auth/refresh.ts +5 -8
  44. package/src/api-handlers/auth/signout.ts +9 -21
  45. package/src/api-handlers/auth/update-session.ts +7 -20
  46. package/src/api-handlers/auth/verify-code.ts +7 -20
  47. package/src/api-handlers/session/viability.ts +2 -2
  48. package/src/auth/better-auth.ts +7 -32
  49. package/src/client/better-auth-client.ts +3 -4
  50. package/src/lib/{nextauth-secret.ts → auth-secret.ts} +32 -16
  51. package/src/lib/demo-mode.ts +5 -1
  52. package/src/lib/idp-client-config.ts +42 -22
  53. package/src/lib/secret-validation.ts +1 -1
  54. package/src/lib/startup-init.ts +23 -18
  55. package/src/lib/test-aware-get-token.ts +2 -51
  56. package/src/routes/account/masked-info.ts +1 -1
  57. package/src/routes/account/send-code.ts +1 -1
  58. package/src/routes/account/verify-email.ts +1 -1
  59. package/src/routes/account/verify-sms.ts +1 -1
  60. package/src/routes/auth/refresh.ts +3 -8
  61. package/src/server/auth.ts +129 -22
  62. package/src/server/decode-session.ts +2 -2
  63. package/dist/lib/nextauth-secret.d.ts +0 -10
@@ -31,8 +31,6 @@ export interface AuthHandlerOptions {
31
31
  retryOn401?: boolean;
32
32
  /** Maximum number of retry attempts on 401 (default: 1) */
33
33
  maxRetries?: number;
34
- /** NextAuth secret for JWT decoding */
35
- nextAuthSecret?: string;
36
34
  /** IDP base URL for refresh requests */
37
35
  idpBaseUrl?: string;
38
36
  /** OAuth client ID */
@@ -39,7 +39,7 @@ const session_store_1 = require("../lib/session-store");
39
39
  */
40
40
  function createAuthHandler(options = {}) {
41
41
  const { requireAuth = true, autoRefresh = true, refreshBuffer = 60, // 60 seconds - matches website-membership proven threshold
42
- retryOn401 = true, maxRetries = 1, nextAuthSecret = process.env.NEXTAUTH_SECRET, idpBaseUrl = process.env.IDP_URL, clientId = process.env.CLIENT_ID || process.env.NEXT_PUBLIC_IDP_CLIENT_ID } = options;
42
+ retryOn401 = true, maxRetries = 1, idpBaseUrl = process.env.IDP_URL, clientId = process.env.CLIENT_ID || process.env.NEXT_PUBLIC_IDP_CLIENT_ID } = options;
43
43
  /**
44
44
  * Performs coordinated token refresh with Redis locking
45
45
  * This prevents multiple concurrent requests from all trying to refresh simultaneously
@@ -128,14 +128,16 @@ function createStatsHandler(config) {
128
128
  if (adminCheck.error)
129
129
  return adminCheck.error;
130
130
  try {
131
- // Fetch from 3 sources in parallel
132
- const [usersResult, sessionCount, auditResult] = await Promise.allSettled([
133
- // 1. Users + tier breakdown via HMAC proxy (Vibe collection query)
131
+ // Fetch from 4 sources in parallel
132
+ const [usersResult, tierDistributionResult, sessionCount, auditResult] = await Promise.allSettled([
133
+ // 1. Users count via HMAC proxy (Vibe collection query)
134
134
  vibeServiceRequest('/v1/collections/vibe_app/tables/users/query', {
135
135
  method: 'POST',
136
136
  body: { page: 1, pageSize: 500, orderBy: 'created_at', orderDirection: 'desc' },
137
137
  }),
138
- // 2. Active sessions from Redis
138
+ // 2. Tier distribution from analytics endpoint (uses purchases table)
139
+ vibeServiceRequest('/v1/analytics/tier-distribution?includeTrend=false', { method: 'GET' }),
140
+ // 3. Active sessions from Redis
139
141
  (async () => {
140
142
  const redis = (0, redis_1.getRedis)();
141
143
  const sessionPrefix = getSessionPrefix();
@@ -148,12 +150,11 @@ function createStatsHandler(config) {
148
150
  } while (cursor !== '0');
149
151
  return sessionKeys.length;
150
152
  })(),
151
- // 3. Recent audit activity via HMAC proxy
153
+ // 4. Recent audit activity via HMAC proxy
152
154
  vibeServiceRequest('/v1/audit?pageSize=10&sortDir=desc', { method: 'GET' }),
153
155
  ]);
154
156
  // Parse users — deduplicate by user_id
155
157
  let totalUsers = 0;
156
- let tierBreakdown = {};
157
158
  if (usersResult.status === 'fulfilled' && usersResult.value.ok && usersResult.value.data) {
158
159
  const data = usersResult.value.data;
159
160
  const rawUsers = data.data || data.documents || data.users || [];
@@ -166,17 +167,26 @@ function createStatsHandler(config) {
166
167
  userMap.set(uid, u);
167
168
  }
168
169
  }
169
- const uniqueUsers = Array.from(userMap.values());
170
- totalUsers = uniqueUsers.length;
171
- // Build tier breakdown from deduplicated users (unless API provides one)
172
- tierBreakdown = data.tierBreakdown || data.tiers || {};
173
- if (Object.keys(tierBreakdown).length === 0) {
174
- for (const user of uniqueUsers) {
175
- const tier = user.tier || 'free';
176
- tierBreakdown[tier] = (tierBreakdown[tier] || 0) + 1;
170
+ totalUsers = userMap.size;
171
+ }
172
+ // Parse tier distribution from analytics endpoint (uses purchases table)
173
+ let tierBreakdown = {};
174
+ if (tierDistributionResult.status === 'fulfilled' && tierDistributionResult.value.ok && tierDistributionResult.value.data) {
175
+ const data = tierDistributionResult.value.data;
176
+ // Handle response shape: { distribution: [{ tierKey, userCount }, ...] }
177
+ const distribution = data.distribution || data.data || data.tiers || [];
178
+ if (Array.isArray(distribution)) {
179
+ for (const item of distribution) {
180
+ const tierKey = item.tierKey || item.tier || item.name || 'free';
181
+ const count = item.userCount || item.count || item.users || 0;
182
+ tierBreakdown[tierKey] = (tierBreakdown[tierKey] || 0) + count;
177
183
  }
178
184
  }
179
185
  }
186
+ // Fallback: if no tier data from analytics, show all as free
187
+ if (Object.keys(tierBreakdown).length === 0) {
188
+ tierBreakdown = { free: totalUsers };
189
+ }
180
190
  // Parse active sessions count
181
191
  let activeSessions = 0;
182
192
  if (sessionCount.status === 'fulfilled') {
@@ -4,7 +4,7 @@
4
4
  * ASK BEFORE EDITING - TESTED AND WORKING SYSTEM
5
5
  *
6
6
  * This handler manages the server-side refresh token cycle with:
7
- * - NextAuth JWT token extraction
7
+ * - Better Auth session extraction
8
8
  * - Session token fallback for internal calls
9
9
  * - PayEz IDP refresh token exchange
10
10
  * - Session state updates with new tokens
@@ -17,13 +17,12 @@ import { NextRequest, NextResponse } from 'next/server';
17
17
  interface RefreshConfig {
18
18
  idpBaseUrl: string;
19
19
  clientId: string;
20
- nextAuthSecret: string;
21
20
  refreshEndpoint?: string;
22
21
  }
23
22
  /**
24
23
  * Creates a refresh token handler for Next.js API routes
25
24
  *
26
- * @param config Configuration for IDP connection and NextAuth
25
+ * @param config IDP connection settings (Better Auth handles session crypto)
27
26
  * @returns Next.js POST handler function
28
27
  *
29
28
  * @example
@@ -34,7 +33,6 @@ interface RefreshConfig {
34
33
  * export const POST = createRefreshHandler({
35
34
  * idpBaseUrl: process.env.IDP_URL!,
36
35
  * clientId: process.env.CLIENT_ID!,
37
- * nextAuthSecret: process.env.NEXTAUTH_SECRET!,
38
36
  * refreshEndpoint: '/api/ExternalAuth/refresh'
39
37
  * });
40
38
  * ```
@@ -54,8 +52,8 @@ export declare function createRefreshHandler(config: RefreshConfig): (req: NextR
54
52
  hasRefreshToken: boolean;
55
53
  }>>;
56
54
  /**
57
- * Default export for backward compatibility
58
- * Requires environment variables: IDP_URL, CLIENT_ID, NEXTAUTH_SECRET
55
+ * Default POST export — drop-in for `app/api/auth/refresh/route.ts`.
56
+ * Requires environment variables: IDP_URL, CLIENT_ID
59
57
  */
60
58
  export declare const POST: (req: NextRequest) => Promise<NextResponse<{
61
59
  error: string;
@@ -5,7 +5,7 @@
5
5
  * ASK BEFORE EDITING - TESTED AND WORKING SYSTEM
6
6
  *
7
7
  * This handler manages the server-side refresh token cycle with:
8
- * - NextAuth JWT token extraction
8
+ * - Better Auth session extraction
9
9
  * - Session token fallback for internal calls
10
10
  * - PayEz IDP refresh token exchange
11
11
  * - Session state updates with new tokens
@@ -25,7 +25,7 @@ const token_utils_1 = require("../../auth/utils/token-utils");
25
25
  /**
26
26
  * Creates a refresh token handler for Next.js API routes
27
27
  *
28
- * @param config Configuration for IDP connection and NextAuth
28
+ * @param config IDP connection settings (Better Auth handles session crypto)
29
29
  * @returns Next.js POST handler function
30
30
  *
31
31
  * @example
@@ -36,13 +36,12 @@ const token_utils_1 = require("../../auth/utils/token-utils");
36
36
  * export const POST = createRefreshHandler({
37
37
  * idpBaseUrl: process.env.IDP_URL!,
38
38
  * clientId: process.env.CLIENT_ID!,
39
- * nextAuthSecret: process.env.NEXTAUTH_SECRET!,
40
39
  * refreshEndpoint: '/api/ExternalAuth/refresh'
41
40
  * });
42
41
  * ```
43
42
  */
44
43
  function createRefreshHandler(config) {
45
- const { idpBaseUrl, clientId, nextAuthSecret, refreshEndpoint = '/api/ExternalAuth/refresh' } = config;
44
+ const { idpBaseUrl, clientId, refreshEndpoint = '/api/ExternalAuth/refresh' } = config;
46
45
  return async function POST(req) {
47
46
  try {
48
47
  // Extract session from Better Auth
@@ -622,12 +621,11 @@ function createRefreshHandler(config) {
622
621
  };
623
622
  }
624
623
  /**
625
- * Default export for backward compatibility
626
- * Requires environment variables: IDP_URL, CLIENT_ID, NEXTAUTH_SECRET
624
+ * Default POST export — drop-in for `app/api/auth/refresh/route.ts`.
625
+ * Requires environment variables: IDP_URL, CLIENT_ID
627
626
  */
628
627
  exports.POST = createRefreshHandler({
629
628
  idpBaseUrl: process.env.IDP_URL,
630
629
  clientId: process.env.CLIENT_ID || 'payez_default_client',
631
- nextAuthSecret: process.env.NEXTAUTH_SECRET || '',
632
630
  refreshEndpoint: '/api/ExternalAuth/refresh'
633
631
  });
@@ -9,29 +9,20 @@
9
9
  * @requires No authentication (public endpoint)
10
10
  */
11
11
  import { NextRequest, NextResponse } from 'next/server';
12
- interface SignoutConfig {
13
- nextAuthSecret: string;
14
- }
15
12
  /**
16
- * Creates a signout handler for Next.js API routes
13
+ * Creates a signout handler for Next.js API routes.
17
14
  *
18
- * @param config Configuration for NextAuth
19
- * @returns Next.js POST handler function
15
+ * Better Auth resolves its session from cookies, so this handler takes no
16
+ * configuration. Use the default `POST` export below for typical usage.
20
17
  *
21
18
  * @example
22
19
  * ```typescript
23
20
  * // In your app's /app/api/auth/signout/route.ts
24
- * import { createSignoutHandler } from '@payez/next-mvp/api-handlers/auth/signout';
25
- *
26
- * export const POST = createSignoutHandler({
27
- * nextAuthSecret: process.env.NEXTAUTH_SECRET!
28
- * });
21
+ * export { POST } from '@payez/next-mvp/api-handlers/auth/signout';
29
22
  * ```
30
23
  */
31
- export declare function createSignoutHandler(config: SignoutConfig): (req: NextRequest) => Promise<NextResponse<unknown>>;
24
+ export declare function createSignoutHandler(): (req: NextRequest) => Promise<NextResponse<unknown>>;
32
25
  /**
33
- * Default export for backward compatibility
34
- * Requires environment variable: NEXTAUTH_SECRET
26
+ * Default POST export — drop-in for `app/api/auth/signout/route.ts`.
35
27
  */
36
28
  export declare const POST: (req: NextRequest) => Promise<NextResponse<unknown>>;
37
- export {};
@@ -46,23 +46,18 @@ function addSecurityHeaders(response) {
46
46
  return response;
47
47
  }
48
48
  /**
49
- * Creates a signout handler for Next.js API routes
49
+ * Creates a signout handler for Next.js API routes.
50
50
  *
51
- * @param config Configuration for NextAuth
52
- * @returns Next.js POST handler function
51
+ * Better Auth resolves its session from cookies, so this handler takes no
52
+ * configuration. Use the default `POST` export below for typical usage.
53
53
  *
54
54
  * @example
55
55
  * ```typescript
56
56
  * // In your app's /app/api/auth/signout/route.ts
57
- * import { createSignoutHandler } from '@payez/next-mvp/api-handlers/auth/signout';
58
- *
59
- * export const POST = createSignoutHandler({
60
- * nextAuthSecret: process.env.NEXTAUTH_SECRET!
61
- * });
57
+ * export { POST } from '@payez/next-mvp/api-handlers/auth/signout';
62
58
  * ```
63
59
  */
64
- function createSignoutHandler(config) {
65
- const { nextAuthSecret } = config;
60
+ function createSignoutHandler() {
66
61
  return async function POST(req) {
67
62
  const cookieStore = await (0, headers_1.cookies)();
68
63
  // Get app-slug prefixed cookie names
@@ -91,7 +86,8 @@ function createSignoutHandler(config) {
91
86
  // Get chunk cookies for cleanup count
92
87
  const chunkCookies = cookieStore.getAll()
93
88
  .filter(cookie => cookie.name.startsWith(`${sessionCookieName}.`));
94
- // Decode NextAuth JWT to extract the Redis session UUID before deletion
89
+ // Decode the Better Auth session JWT to extract the Redis session UUID
90
+ // before deletion.
95
91
  let redisSessionToken = null;
96
92
  // First attempt: Better Auth getSession
97
93
  try {
@@ -178,9 +174,6 @@ function createSignoutHandler(config) {
178
174
  };
179
175
  }
180
176
  /**
181
- * Default export for backward compatibility
182
- * Requires environment variable: NEXTAUTH_SECRET
177
+ * Default POST export — drop-in for `app/api/auth/signout/route.ts`.
183
178
  */
184
- exports.POST = createSignoutHandler({
185
- nextAuthSecret: process.env.NEXTAUTH_SECRET || ''
186
- });
179
+ exports.POST = createSignoutHandler();
@@ -9,29 +9,20 @@
9
9
  * @requires Authentication (authenticated endpoint)
10
10
  */
11
11
  import { NextRequest, NextResponse } from 'next/server';
12
- interface UpdateSessionConfig {
13
- nextAuthSecret?: string;
14
- }
15
12
  /**
16
- * Creates an update-session handler for Next.js API routes
13
+ * Creates an update-session handler for Next.js API routes.
17
14
  *
18
- * @param config Configuration for NextAuth
19
- * @returns Next.js POST handler function
15
+ * Better Auth resolves its session from cookies, so this handler takes no
16
+ * configuration. Use the default `POST` export below for typical usage.
20
17
  *
21
18
  * @example
22
19
  * ```typescript
23
20
  * // In your app's /app/api/auth/update-session/route.ts
24
- * import { createUpdateSessionHandler } from '@payez/next-mvp/api-handlers/auth/update-session';
25
- *
26
- * export const POST = createUpdateSessionHandler({
27
- * nextAuthSecret: process.env.NEXTAUTH_SECRET!
28
- * });
21
+ * export { POST } from '@payez/next-mvp/api-handlers/auth/update-session';
29
22
  * ```
30
23
  */
31
- export declare function createUpdateSessionHandler(config: UpdateSessionConfig): (req: NextRequest) => Promise<NextResponse<unknown>>;
24
+ export declare function createUpdateSessionHandler(): (req: NextRequest) => Promise<NextResponse<unknown>>;
32
25
  /**
33
- * Default export for backward compatibility
34
- * Requires environment variable: NEXTAUTH_SECRET
26
+ * Default POST export — drop-in for `app/api/auth/update-session/route.ts`.
35
27
  */
36
28
  export declare const POST: (req: NextRequest) => Promise<NextResponse<unknown>>;
37
- export {};
@@ -29,23 +29,18 @@ function addSecurityHeaders(response) {
29
29
  return response;
30
30
  }
31
31
  /**
32
- * Creates an update-session handler for Next.js API routes
32
+ * Creates an update-session handler for Next.js API routes.
33
33
  *
34
- * @param config Configuration for NextAuth
35
- * @returns Next.js POST handler function
34
+ * Better Auth resolves its session from cookies, so this handler takes no
35
+ * configuration. Use the default `POST` export below for typical usage.
36
36
  *
37
37
  * @example
38
38
  * ```typescript
39
39
  * // In your app's /app/api/auth/update-session/route.ts
40
- * import { createUpdateSessionHandler } from '@payez/next-mvp/api-handlers/auth/update-session';
41
- *
42
- * export const POST = createUpdateSessionHandler({
43
- * nextAuthSecret: process.env.NEXTAUTH_SECRET!
44
- * });
40
+ * export { POST } from '@payez/next-mvp/api-handlers/auth/update-session';
45
41
  * ```
46
42
  */
47
- function createUpdateSessionHandler(config) {
48
- const { nextAuthSecret } = config;
43
+ function createUpdateSessionHandler() {
49
44
  return async function POST(req) {
50
45
  try {
51
46
  let body;
@@ -85,9 +80,6 @@ function createUpdateSessionHandler(config) {
85
80
  };
86
81
  }
87
82
  /**
88
- * Default export for backward compatibility
89
- * Requires environment variable: NEXTAUTH_SECRET
83
+ * Default POST export — drop-in for `app/api/auth/update-session/route.ts`.
90
84
  */
91
- exports.POST = createUpdateSessionHandler({
92
- nextAuthSecret: process.env.NEXTAUTH_SECRET || ''
93
- });
85
+ exports.POST = createUpdateSessionHandler();
@@ -9,35 +9,26 @@
9
9
  * @requires Authentication (authenticated endpoint)
10
10
  */
11
11
  import { NextRequest, NextResponse } from 'next/server';
12
- interface VerifyCodeConfig {
13
- nextAuthSecret?: string;
14
- }
15
12
  /**
16
- * Creates a verify-code/complete-2FA handler for Next.js API routes
13
+ * Creates a verify-code/complete-2FA handler for Next.js API routes.
17
14
  *
18
- * @param config Configuration for NextAuth
19
- * @returns Next.js POST handler function
15
+ * Better Auth resolves its session from cookies, so this handler takes no
16
+ * configuration. Use the default `POST` export below for typical usage.
20
17
  *
21
18
  * @example
22
19
  * ```typescript
23
20
  * // In your app's /app/api/auth/verify-code/route.ts
24
- * import { createVerifyCodeHandler } from '@payez/next-mvp/api-handlers/auth/verify-code';
25
- *
26
- * export const POST = createVerifyCodeHandler({
27
- * nextAuthSecret: process.env.NEXTAUTH_SECRET!
28
- * });
21
+ * export { POST } from '@payez/next-mvp/api-handlers/auth/verify-code';
29
22
  * ```
30
23
  */
31
- export declare function createVerifyCodeHandler(config: VerifyCodeConfig): (req: NextRequest) => Promise<NextResponse<{
24
+ export declare function createVerifyCodeHandler(): (req: NextRequest) => Promise<NextResponse<{
32
25
  success: boolean;
33
26
  message: string;
34
27
  }>>;
35
28
  /**
36
- * Default export for backward compatibility
37
- * Requires environment variable: NEXTAUTH_SECRET
29
+ * Default POST export — drop-in for `app/api/auth/verify-code/route.ts`.
38
30
  */
39
31
  export declare const POST: (req: NextRequest) => Promise<NextResponse<{
40
32
  success: boolean;
41
33
  message: string;
42
34
  }>>;
43
- export {};
@@ -16,23 +16,18 @@ const server_1 = require("next/server");
16
16
  const auth_1 = require("../../server/auth");
17
17
  const session_store_1 = require("../../lib/session-store");
18
18
  /**
19
- * Creates a verify-code/complete-2FA handler for Next.js API routes
19
+ * Creates a verify-code/complete-2FA handler for Next.js API routes.
20
20
  *
21
- * @param config Configuration for NextAuth
22
- * @returns Next.js POST handler function
21
+ * Better Auth resolves its session from cookies, so this handler takes no
22
+ * configuration. Use the default `POST` export below for typical usage.
23
23
  *
24
24
  * @example
25
25
  * ```typescript
26
26
  * // In your app's /app/api/auth/verify-code/route.ts
27
- * import { createVerifyCodeHandler } from '@payez/next-mvp/api-handlers/auth/verify-code';
28
- *
29
- * export const POST = createVerifyCodeHandler({
30
- * nextAuthSecret: process.env.NEXTAUTH_SECRET!
31
- * });
27
+ * export { POST } from '@payez/next-mvp/api-handlers/auth/verify-code';
32
28
  * ```
33
29
  */
34
- function createVerifyCodeHandler(config) {
35
- const { nextAuthSecret } = config;
30
+ function createVerifyCodeHandler() {
36
31
  return async function POST(req) {
37
32
  try {
38
33
  let body;
@@ -82,9 +77,6 @@ function createVerifyCodeHandler(config) {
82
77
  };
83
78
  }
84
79
  /**
85
- * Default export for backward compatibility
86
- * Requires environment variable: NEXTAUTH_SECRET
80
+ * Default POST export — drop-in for `app/api/auth/verify-code/route.ts`.
87
81
  */
88
- exports.POST = createVerifyCodeHandler({
89
- nextAuthSecret: process.env.NEXTAUTH_SECRET || ''
90
- });
82
+ exports.POST = createVerifyCodeHandler();
@@ -13,8 +13,8 @@ const startup_init_1 = require("../../lib/startup-init");
13
13
  const idp_client_config_1 = require("../../lib/idp-client-config");
14
14
  async function GET(req) {
15
15
  try {
16
- // Ensure initialization is complete
17
- if (!process.env.NEXTAUTH_SECRET) {
16
+ // Ensure initialization is complete (auth signing secret resolved from IDP)
17
+ if (!process.env.BETTER_AUTH_SECRET && !process.env.NEXTAUTH_SECRET) {
18
18
  try {
19
19
  await (0, startup_init_1.ensureInitialized)();
20
20
  }
@@ -22,29 +22,13 @@ export interface BetterAuthSocialProvider {
22
22
  * Build Better Auth social providers from IDP config.
23
23
  */
24
24
  export declare function buildBetterAuthProviders(config: IDPClientConfig): Record<string, BetterAuthSocialProvider>;
25
- /**
26
- * Optional extra plugins for createBetterAuthInstance.
27
- * Use to add credentials/custom signin endpoints from the host app.
28
- */
29
- export type BetterAuthExtraPlugins = any[];
30
- /**
31
- * Optional overrides for createBetterAuthInstance.
32
- */
33
- export interface BetterAuthInstanceOptions {
34
- /** Path suffix for the BA mount (default: '/api/auth'). Use '/api/ba-auth' for migration scenarios. */
35
- basePath?: string;
36
- }
37
25
  /**
38
26
  * Create Better Auth instance from IDP config.
39
27
  *
40
28
  * No database — runs in stateless mode with JWE cookie cache.
41
29
  * Call after getIDPClientConfig() resolves.
42
- *
43
- * @param idpConfig IDP client config (from getIDPClientConfig)
44
- * @param extraPlugins Optional plugins to add (e.g., credentials plugin from host app)
45
- * @param options Optional overrides (e.g., basePath for migration scenarios)
46
30
  */
47
- export declare function createBetterAuthInstance(idpConfig: IDPClientConfig, extraPlugins?: BetterAuthExtraPlugins, options?: BetterAuthInstanceOptions): import("better-auth").Auth<{
31
+ export declare function createBetterAuthInstance(idpConfig: IDPClientConfig): import("better-auth").Auth<{
48
32
  baseURL: string;
49
33
  secret: string;
50
34
  socialProviders: Record<string, BetterAuthSocialProvider>;
@@ -69,7 +53,7 @@ export declare function createBetterAuthInstance(idpConfig: IDPClientConfig, ext
69
53
  };
70
54
  };
71
55
  };
72
- plugins: [...any[], {
56
+ plugins: [{
73
57
  id: "next-cookies";
74
58
  hooks: {
75
59
  before: {
@@ -93,7 +77,7 @@ export declare function isBetterAuthEnabled(): boolean;
93
77
  */
94
78
  declare let cachedInstance: any;
95
79
  export { cachedInstance as __betterAuthInstance };
96
- export declare function getBetterAuthInstance(extraPlugins?: BetterAuthExtraPlugins): Promise<any>;
80
+ export declare function getBetterAuthInstance(): Promise<any>;
97
81
  /**
98
82
  * Get flag-gated auth handler for Next.js route.
99
83
  *
@@ -80,23 +80,18 @@ function buildBetterAuthProviders(config) {
80
80
  *
81
81
  * No database — runs in stateless mode with JWE cookie cache.
82
82
  * Call after getIDPClientConfig() resolves.
83
- *
84
- * @param idpConfig IDP client config (from getIDPClientConfig)
85
- * @param extraPlugins Optional plugins to add (e.g., credentials plugin from host app)
86
- * @param options Optional overrides (e.g., basePath for migration scenarios)
87
83
  */
88
- function createBetterAuthInstance(idpConfig, extraPlugins = [], options = {}) {
84
+ function createBetterAuthInstance(idpConfig) {
89
85
  const appSlug = idpConfig.clientSlug || (0, app_slug_1.getAppSlug)();
90
- const basePath = options.basePath || '/api/auth';
91
86
  // Resolve base URL: BETTER_AUTH_URL env > IDP config > localhost fallback
92
- // basePath defaults to /api/auth but can be overridden via options for migration scenarios
87
+ // Must include /api/auth since that's where the catch-all route is mounted
93
88
  const rawBaseURL = process.env.BETTER_AUTH_URL
94
89
  || idpConfig.baseClientUrl
95
90
  || `http://localhost:${process.env.PORT || '3000'}`;
96
- const baseURL = rawBaseURL.replace(/\/+$/, '') + basePath;
91
+ const baseURL = rawBaseURL.replace(/\/+$/, '') + '/api/auth';
97
92
  return (0, better_auth_1.betterAuth)({
98
93
  baseURL,
99
- secret: idpConfig.nextAuthSecret,
94
+ secret: idpConfig.authSecret,
100
95
  socialProviders: buildBetterAuthProviders(idpConfig),
101
96
  // Trust the app's own origin + any configured base URL
102
97
  trustedOrigins: [
@@ -153,7 +148,6 @@ function createBetterAuthInstance(idpConfig, extraPlugins = [], options = {}) {
153
148
  },
154
149
  },
155
150
  plugins: [
156
- ...extraPlugins,
157
151
  (0, next_js_1.nextCookies)(),
158
152
  ],
159
153
  });
@@ -173,12 +167,12 @@ let cachedInstance = null;
173
167
  exports.__betterAuthInstance = cachedInstance;
174
168
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
175
169
  let initPromise = null;
176
- async function getBetterAuthInstance(extraPlugins = []) {
170
+ async function getBetterAuthInstance() {
177
171
  if (cachedInstance)
178
172
  return cachedInstance;
179
173
  if (!initPromise) {
180
174
  initPromise = (0, idp_client_config_1.getIDPClientConfig)(true).then(config => {
181
- const instance = createBetterAuthInstance(config, extraPlugins);
175
+ const instance = createBetterAuthInstance(config);
182
176
  exports.__betterAuthInstance = cachedInstance = instance;
183
177
  console.log('[BETTER_AUTH] Instance created for', config.clientSlug || config.clientId);
184
178
  return instance;
@@ -275,7 +269,7 @@ async function exchangeOAuthForIdpTokens(sessionToken, provider = 'google') {
275
269
  return false;
276
270
  }
277
271
  // Build IDP token data
278
- const requiresTwoFactor = result.requires_two_factor ?? result.user?.requiresTwoFactor ?? result.requiresTwoFactor ?? false;
272
+ const requiresTwoFactor = result.user?.requiresTwoFactor ?? result.requiresTwoFactor ?? false;
279
273
  const idpTokenData = {
280
274
  idpAccessToken: result.access_token,
281
275
  idpRefreshToken: result.refresh_token,
@@ -1,16 +1,15 @@
1
1
  /**
2
- * Better Auth Client (Phase 3)
2
+ * Better Auth Client.
3
3
  *
4
- * Drop-in replacement for next-auth/react hooks and functions.
5
4
  * Import from '@payez/next-mvp/client/better-auth-client'.
6
5
  *
7
- * Includes useSessionCompat() — returns NextAuth-shaped { data, status }
8
- * so existing components don't need destructure pattern changes.
6
+ * Includes useSessionCompat() — returns a { data, status } shape so existing
7
+ * components written against the legacy hook don't need destructure changes.
9
8
  */
10
9
  export declare const authClient: {
11
10
  signIn: {
12
11
  social: <FetchOptions extends import("@better-auth/core").ClientFetchOption<Partial<{
13
- provider: (string & {}) | "linear" | "huggingface" | "github" | "apple" | "atlassian" | "cognito" | "discord" | "facebook" | "figma" | "microsoft" | "google" | "slack" | "spotify" | "twitch" | "twitter" | "dropbox" | "kick" | "linkedin" | "gitlab" | "tiktok" | "reddit" | "roblox" | "salesforce" | "vk" | "zoom" | "notion" | "kakao" | "naver" | "line" | "paybin" | "paypal" | "polar" | "railway" | "vercel" | "wechat";
12
+ provider: "github" | "apple" | "atlassian" | "cognito" | "discord" | "facebook" | "figma" | "microsoft" | "google" | "huggingface" | "slack" | "spotify" | "twitch" | "twitter" | "dropbox" | "kick" | "linear" | "linkedin" | "gitlab" | "tiktok" | "reddit" | "roblox" | "salesforce" | "vk" | "zoom" | "notion" | "kakao" | "naver" | "line" | "paybin" | "paypal" | "polar" | "railway" | "vercel" | "wechat" | (string & {});
14
13
  callbackURL?: string | undefined;
15
14
  newUserCallbackURL?: string | undefined;
16
15
  errorCallbackURL?: string | undefined;
@@ -34,7 +33,7 @@ export declare const authClient: {
34
33
  loginHint?: string | undefined;
35
34
  additionalData?: Record<string, any> | undefined;
36
35
  }> & Record<string, any>, Partial<Record<string, any>> & Record<string, any>, Record<string, any> | undefined>>(data_0: import("better-auth/react").Prettify<{
37
- provider: (string & {}) | "linear" | "huggingface" | "github" | "apple" | "atlassian" | "cognito" | "discord" | "facebook" | "figma" | "microsoft" | "google" | "slack" | "spotify" | "twitch" | "twitter" | "dropbox" | "kick" | "linkedin" | "gitlab" | "tiktok" | "reddit" | "roblox" | "salesforce" | "vk" | "zoom" | "notion" | "kakao" | "naver" | "line" | "paybin" | "paypal" | "polar" | "railway" | "vercel" | "wechat";
36
+ provider: "github" | "apple" | "atlassian" | "cognito" | "discord" | "facebook" | "figma" | "microsoft" | "google" | "huggingface" | "slack" | "spotify" | "twitch" | "twitter" | "dropbox" | "kick" | "linear" | "linkedin" | "gitlab" | "tiktok" | "reddit" | "roblox" | "salesforce" | "vk" | "zoom" | "notion" | "kakao" | "naver" | "line" | "paybin" | "paypal" | "polar" | "railway" | "vercel" | "wechat" | (string & {});
38
37
  callbackURL?: string | undefined;
39
38
  newUserCallbackURL?: string | undefined;
40
39
  errorCallbackURL?: string | undefined;
@@ -828,7 +827,7 @@ export declare const useSession: () => {
828
827
  } | undefined) => Promise<void>;
829
828
  }, signIn: {
830
829
  social: <FetchOptions extends import("@better-auth/core").ClientFetchOption<Partial<{
831
- provider: (string & {}) | "linear" | "huggingface" | "github" | "apple" | "atlassian" | "cognito" | "discord" | "facebook" | "figma" | "microsoft" | "google" | "slack" | "spotify" | "twitch" | "twitter" | "dropbox" | "kick" | "linkedin" | "gitlab" | "tiktok" | "reddit" | "roblox" | "salesforce" | "vk" | "zoom" | "notion" | "kakao" | "naver" | "line" | "paybin" | "paypal" | "polar" | "railway" | "vercel" | "wechat";
830
+ provider: "github" | "apple" | "atlassian" | "cognito" | "discord" | "facebook" | "figma" | "microsoft" | "google" | "huggingface" | "slack" | "spotify" | "twitch" | "twitter" | "dropbox" | "kick" | "linear" | "linkedin" | "gitlab" | "tiktok" | "reddit" | "roblox" | "salesforce" | "vk" | "zoom" | "notion" | "kakao" | "naver" | "line" | "paybin" | "paypal" | "polar" | "railway" | "vercel" | "wechat" | (string & {});
832
831
  callbackURL?: string | undefined;
833
832
  newUserCallbackURL?: string | undefined;
834
833
  errorCallbackURL?: string | undefined;
@@ -852,7 +851,7 @@ export declare const useSession: () => {
852
851
  loginHint?: string | undefined;
853
852
  additionalData?: Record<string, any> | undefined;
854
853
  }> & Record<string, any>, Partial<Record<string, any>> & Record<string, any>, Record<string, any> | undefined>>(data_0: import("better-auth/react").Prettify<{
855
- provider: (string & {}) | "linear" | "huggingface" | "github" | "apple" | "atlassian" | "cognito" | "discord" | "facebook" | "figma" | "microsoft" | "google" | "slack" | "spotify" | "twitch" | "twitter" | "dropbox" | "kick" | "linkedin" | "gitlab" | "tiktok" | "reddit" | "roblox" | "salesforce" | "vk" | "zoom" | "notion" | "kakao" | "naver" | "line" | "paybin" | "paypal" | "polar" | "railway" | "vercel" | "wechat";
854
+ provider: "github" | "apple" | "atlassian" | "cognito" | "discord" | "facebook" | "figma" | "microsoft" | "google" | "huggingface" | "slack" | "spotify" | "twitch" | "twitter" | "dropbox" | "kick" | "linear" | "linkedin" | "gitlab" | "tiktok" | "reddit" | "roblox" | "salesforce" | "vk" | "zoom" | "notion" | "kakao" | "naver" | "line" | "paybin" | "paypal" | "polar" | "railway" | "vercel" | "wechat" | (string & {});
856
855
  callbackURL?: string | undefined;
857
856
  newUserCallbackURL?: string | undefined;
858
857
  errorCallbackURL?: string | undefined;
@@ -1,12 +1,11 @@
1
1
  "use strict";
2
2
  /**
3
- * Better Auth Client (Phase 3)
3
+ * Better Auth Client.
4
4
  *
5
- * Drop-in replacement for next-auth/react hooks and functions.
6
5
  * Import from '@payez/next-mvp/client/better-auth-client'.
7
6
  *
8
- * Includes useSessionCompat() — returns NextAuth-shaped { data, status }
9
- * so existing components don't need destructure pattern changes.
7
+ * Includes useSessionCompat() — returns a { data, status } shape so existing
8
+ * components written against the legacy hook don't need destructure changes.
10
9
  */
11
10
  Object.defineProperty(exports, "__esModule", { value: true });
12
11
  exports.signOut = exports.signIn = exports.useSession = exports.authClient = void 0;