@payez/next-mvp 4.0.46 → 4.0.47

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 (61) 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/auth/refresh.d.ts +4 -6
  4. package/dist/api-handlers/auth/refresh.js +5 -7
  5. package/dist/api-handlers/auth/signout.d.ts +6 -15
  6. package/dist/api-handlers/auth/signout.js +9 -16
  7. package/dist/api-handlers/auth/update-session.d.ts +6 -15
  8. package/dist/api-handlers/auth/update-session.js +7 -15
  9. package/dist/api-handlers/auth/verify-code.d.ts +6 -15
  10. package/dist/api-handlers/auth/verify-code.js +7 -15
  11. package/dist/api-handlers/session/viability.js +2 -2
  12. package/dist/auth/better-auth.d.ts +3 -19
  13. package/dist/auth/better-auth.js +7 -13
  14. package/dist/client/better-auth-client.d.ts +7 -8
  15. package/dist/client/better-auth-client.js +3 -4
  16. package/dist/lib/auth-secret.d.ts +17 -0
  17. package/dist/lib/{nextauth-secret.js → auth-secret.js} +31 -15
  18. package/dist/lib/demo-mode.js +3 -1
  19. package/dist/lib/idp-client-config.d.ts +6 -2
  20. package/dist/lib/idp-client-config.js +35 -21
  21. package/dist/lib/secret-validation.d.ts +1 -1
  22. package/dist/lib/secret-validation.js +2 -2
  23. package/dist/lib/startup-init.d.ts +3 -3
  24. package/dist/lib/startup-init.js +23 -18
  25. package/dist/lib/test-aware-get-token.js +2 -51
  26. package/dist/routes/account/masked-info.d.ts +1 -1
  27. package/dist/routes/account/masked-info.js +1 -1
  28. package/dist/routes/account/send-code.d.ts +1 -1
  29. package/dist/routes/account/send-code.js +1 -1
  30. package/dist/routes/account/verify-email.d.ts +1 -1
  31. package/dist/routes/account/verify-email.js +1 -1
  32. package/dist/routes/account/verify-sms.d.ts +1 -1
  33. package/dist/routes/account/verify-sms.js +1 -1
  34. package/dist/routes/auth/refresh.js +3 -8
  35. package/dist/server/auth.d.ts +4 -7
  36. package/dist/server/auth.js +3 -6
  37. package/dist/server/decode-session.js +2 -2
  38. package/dist/vibe/hooks/index.d.ts +1 -1
  39. package/package.json +888 -893
  40. package/src/api/auth-handler.ts +0 -4
  41. package/src/api-handlers/auth/refresh.ts +5 -8
  42. package/src/api-handlers/auth/signout.ts +9 -21
  43. package/src/api-handlers/auth/update-session.ts +7 -20
  44. package/src/api-handlers/auth/verify-code.ts +7 -20
  45. package/src/api-handlers/session/viability.ts +2 -2
  46. package/src/auth/better-auth.ts +7 -32
  47. package/src/client/better-auth-client.ts +3 -4
  48. package/src/lib/{nextauth-secret.ts → auth-secret.ts} +32 -16
  49. package/src/lib/demo-mode.ts +5 -1
  50. package/src/lib/idp-client-config.ts +42 -22
  51. package/src/lib/secret-validation.ts +1 -1
  52. package/src/lib/startup-init.ts +23 -18
  53. package/src/lib/test-aware-get-token.ts +2 -51
  54. package/src/routes/account/masked-info.ts +1 -1
  55. package/src/routes/account/send-code.ts +1 -1
  56. package/src/routes/account/verify-email.ts +1 -1
  57. package/src/routes/account/verify-sms.ts +1 -1
  58. package/src/routes/auth/refresh.ts +3 -8
  59. package/src/server/auth.ts +3 -6
  60. package/src/server/decode-session.ts +2 -2
  61. package/dist/lib/nextauth-secret.d.ts +0 -10
@@ -4,8 +4,8 @@
4
4
  * This module ensures that critical initialization tasks are completed
5
5
  * before the application serves requests.
6
6
  *
7
- * Now uses unified IDP client config for:
8
- * - NEXTAUTH_SECRET
7
+ * Uses unified IDP client config for:
8
+ * - BETTER_AUTH_SECRET (the Better Auth signing secret)
9
9
  * - OAuth provider configuration
10
10
  * - Auth settings (2FA, session timeouts, etc.)
11
11
  */
@@ -75,7 +75,7 @@ export function logStartupStatus(): void {
75
75
  console.log('║ 🚀 PayEz Next MVP - Starting Up ║');
76
76
  console.log('║ ║');
77
77
  console.log('║ Async initialization in progress... ║');
78
- console.log('║ - Resolving NEXTAUTH_SECRET from IDP ║');
78
+ console.log('║ - Resolving BETTER_AUTH_SECRET from IDP ║');
79
79
  console.log('║ - Verifying environment configuration ║');
80
80
  console.log('║ ║');
81
81
  console.log('║ Check logs below for detailed initialization status: ║');
@@ -117,16 +117,21 @@ async function performInitialization(): Promise<void> {
117
117
  console.log('[STARTUP] Client config loaded successfully');
118
118
  console.log('[STARTUP] - Client ID:', config.clientId);
119
119
  console.log('[STARTUP] - Client Slug:', config.clientSlug);
120
- console.log('[STARTUP] - Secret length:', config.nextAuthSecret?.length || 0, 'chars');
120
+ console.log('[STARTUP] - Secret length:', config.authSecret?.length || 0, 'chars');
121
121
  console.log('[STARTUP] - OAuth Providers:', config.oauthProviders?.filter(p => p.enabled).map(p => p.provider).join(', ') || 'none');
122
122
  console.log('[STARTUP] - Require 2FA:', config.authSettings?.require2FA);
123
123
  console.log('[STARTUP] - Cache TTL:', config.configCacheTtlSeconds, 'seconds');
124
124
  console.log('[STARTUP] - Base Client URL:', config.baseClientUrl || '(not set)');
125
125
 
126
- // Set NEXTAUTH_SECRET from IDP response if not already set
127
- if (config.nextAuthSecret && !process.env.NEXTAUTH_SECRET) {
128
- process.env.NEXTAUTH_SECRET = config.nextAuthSecret;
129
- console.log('[STARTUP] Set NEXTAUTH_SECRET from IDP config');
126
+ // Set BETTER_AUTH_SECRET from IDP response if not already set.
127
+ // Also mirror to legacy NEXTAUTH_SECRET during the rename transition
128
+ // so any consumer code still reading the old name keeps working.
129
+ if (config.authSecret && !process.env.BETTER_AUTH_SECRET) {
130
+ process.env.BETTER_AUTH_SECRET = config.authSecret;
131
+ console.log('[STARTUP] Set BETTER_AUTH_SECRET from IDP config');
132
+ }
133
+ if (config.authSecret && !process.env.NEXTAUTH_SECRET) {
134
+ process.env.NEXTAUTH_SECRET = config.authSecret;
130
135
  }
131
136
  } catch (error) {
132
137
  const errorMsg = error instanceof Error ? error.message : String(error);
@@ -136,16 +141,16 @@ async function performInitialization(): Promise<void> {
136
141
  console.error('[STARTUP] No fallback available for auth secret resolution');
137
142
  }
138
143
 
139
- // Step 2: Verify NEXTAUTH_SECRET is available - FAIL FAST if not
140
- console.log('[STARTUP] Step 2/2: Verifying NEXTAUTH_SECRET...');
144
+ // Step 2: Verify BETTER_AUTH_SECRET is available - FAIL FAST if not
145
+ console.log('[STARTUP] Step 2/2: Verifying BETTER_AUTH_SECRET...');
141
146
 
142
- const secret = process.env.NEXTAUTH_SECRET;
147
+ const secret = process.env.BETTER_AUTH_SECRET || process.env.NEXTAUTH_SECRET;
143
148
  if (!secret || secret.trim() === '') {
144
149
  console.error('');
145
150
  console.error('╔══════════════════════════════════════════════════════════════╗');
146
- console.error('║ ❌ FATAL: NEXTAUTH_SECRET NOT AVAILABLE ║');
151
+ console.error('║ ❌ FATAL: BETTER_AUTH_SECRET NOT AVAILABLE ║');
147
152
  console.error('║ ║');
148
- console.error('║ The app cannot start without a valid NEXTAUTH_SECRET. ║');
153
+ console.error('║ The app cannot start without a valid auth signing secret. ║');
149
154
  console.error('║ This should be fetched from IDP at startup. ║');
150
155
  console.error('║ ║');
151
156
  console.error('║ Possible causes: ║');
@@ -155,10 +160,10 @@ async function performInitialization(): Promise<void> {
155
160
  console.error('║ • Network connectivity issue ║');
156
161
  console.error('╚══════════════════════════════════════════════════════════════╝');
157
162
  console.error('');
158
- throw new Error('FATAL: NEXTAUTH_SECRET not available - cannot start without valid secret from IDP');
163
+ throw new Error('FATAL: BETTER_AUTH_SECRET not available - cannot start without valid secret from IDP');
159
164
  }
160
165
 
161
- console.log('[STARTUP] NEXTAUTH_SECRET verified (' + secret.length + ' chars)');
166
+ console.log('[STARTUP] BETTER_AUTH_SECRET verified (' + secret.length + ' chars)');
162
167
 
163
168
  // Step 3: Validate cookie name consistency
164
169
  // This catches bugs where getJwtCookieName() returns a different name than
@@ -192,9 +197,9 @@ async function performInitialization(): Promise<void> {
192
197
 
193
198
  console.error(`
194
199
  ╔══════════════════════════════════════════════════════════════╗
195
- ║ ❌ FATAL: NEXTAUTH_SECRET NOT AVAILABLE
200
+ ║ ❌ FATAL: BETTER_AUTH_SECRET NOT AVAILABLE
196
201
  ║ ║
197
- ║ The app cannot start without a valid NEXTAUTH_SECRET.
202
+ ║ The app cannot start without a valid auth signing secret.
198
203
  ║ This should be fetched from IDP at startup. ║
199
204
  ║ ║
200
205
  ${connectionLine}║ Possible causes: ║
@@ -225,7 +230,7 @@ export function getStartupIDPConfig(): IDPClientConfig | null {
225
230
  }
226
231
 
227
232
  /**
228
- * Check if initialization failed (NEXTAUTH_SECRET couldn't be retrieved)
233
+ * Check if initialization failed (auth signing secret couldn't be retrieved)
229
234
  */
230
235
  export function isInitializationFailed(): boolean {
231
236
  return initializationFailed;
@@ -6,11 +6,11 @@ import { getSessionCookieName } from './app-slug';
6
6
  export async function getTokenTestAware(req: NextRequest): Promise<any> {
7
7
  if (process.env.TEST_MODE === 'true') {
8
8
  try {
9
- let secret = process.env.NEXTAUTH_SECRET;
9
+ let secret = process.env.BETTER_AUTH_SECRET || process.env.NEXTAUTH_SECRET;
10
10
  if (!secret || secret.trim() === '') {
11
11
  const { getIDPClientConfig } = await import('./idp-client-config');
12
12
  const idpConfig = await getIDPClientConfig();
13
- secret = idpConfig.nextAuthSecret as string;
13
+ secret = idpConfig.authSecret;
14
14
  }
15
15
  // Use app-slug prefixed cookie name
16
16
  const cookieName = getSessionCookieName();
@@ -37,54 +37,5 @@ export async function getTokenTestAware(req: NextRequest): Promise<any> {
37
37
  };
38
38
  }
39
39
 
40
- // Fallback for legacy NextAuth-based sites: try next-auth/jwt with the
41
- // app-slug-prefixed cookie name. Uses runtime require so consumers without
42
- // next-auth installed are unaffected.
43
- try {
44
- // eslint-disable-next-line @typescript-eslint/no-implied-eval, no-eval
45
- const dynamicRequire = eval('require') as NodeRequire;
46
- let nextAuthJwt: any = null;
47
- try {
48
- nextAuthJwt = dynamicRequire('next-auth/jwt');
49
- } catch {
50
- return null; // next-auth not installed → BA-only consumer
51
- }
52
- if (!nextAuthJwt?.getToken) return null;
53
-
54
- const { resolveNextAuthSecret } = await import('./nextauth-secret');
55
- const secret = await resolveNextAuthSecret();
56
- if (!secret) return null;
57
-
58
- const cookieName = getSessionCookieName();
59
- let nextAuthToken = await nextAuthJwt.getToken({
60
- req,
61
- secret,
62
- cookieName,
63
- secureCookie: false,
64
- });
65
- if (nextAuthToken) {
66
- logger.debug('[GET_TOKEN] Resolved via NextAuth JWT (cookieName=' + cookieName + ')');
67
- return nextAuthToken;
68
- }
69
-
70
- // Try secure cookie variant for production
71
- const { getSecureSessionCookieName } = await import('./app-slug');
72
- const secureCookieName = getSecureSessionCookieName();
73
- nextAuthToken = await nextAuthJwt.getToken({
74
- req,
75
- secret,
76
- cookieName: secureCookieName,
77
- secureCookie: true,
78
- });
79
- if (nextAuthToken) {
80
- logger.debug('[GET_TOKEN] Resolved via NextAuth JWT (secure cookie)');
81
- return nextAuthToken;
82
- }
83
- } catch (error) {
84
- logger.debug('[GET_TOKEN] NextAuth fallback error', {
85
- error: error instanceof Error ? error.message : String(error),
86
- });
87
- }
88
-
89
40
  return null;
90
41
  }
@@ -28,7 +28,7 @@ export { POST } from '../../api-handlers/account/masked-info';
28
28
  * Environment variables used:
29
29
  * - IDP_URL or NEXT_PUBLIC_IDP_URL (default: http://localhost:32785)
30
30
  * - CLIENT_ID or NEXT_PUBLIC_IDP_CLIENT_ID (required)
31
- * - NEXTAUTH_SECRET (required)
31
+ * - BETTER_AUTH_SECRET (required — fetched from IDP at startup)
32
32
  *
33
33
  * Returns:
34
34
  * - Masked email addresses
@@ -31,7 +31,7 @@ export { POST } from '../../api-handlers/account/send-code';
31
31
  * Environment variables used:
32
32
  * - IDP_URL or NEXT_PUBLIC_IDP_URL (default: http://localhost:32785)
33
33
  * - CLIENT_ID or NEXT_PUBLIC_IDP_CLIENT_ID (required)
34
- * - NEXTAUTH_SECRET (required)
34
+ * - BETTER_AUTH_SECRET (required — fetched from IDP at startup)
35
35
  *
36
36
  * Returns:
37
37
  * - Success status
@@ -30,7 +30,7 @@ export { POST } from '../../api-handlers/account/verify-email';
30
30
  * Environment variables used:
31
31
  * - IDP_URL or NEXT_PUBLIC_IDP_URL (default: http://localhost:32785)
32
32
  * - CLIENT_ID or NEXT_PUBLIC_IDP_CLIENT_ID (required)
33
- * - NEXTAUTH_SECRET (required)
33
+ * - BETTER_AUTH_SECRET (required — fetched from IDP at startup)
34
34
  *
35
35
  * Returns:
36
36
  * - Upgraded access token with MFA claim
@@ -30,7 +30,7 @@ export { POST } from '../../api-handlers/account/verify-sms';
30
30
  * Environment variables used:
31
31
  * - IDP_URL or NEXT_PUBLIC_IDP_URL (default: http://localhost:32785)
32
32
  * - CLIENT_ID or NEXT_PUBLIC_IDP_CLIENT_ID (required)
33
- * - NEXTAUTH_SECRET (required)
33
+ * - BETTER_AUTH_SECRET (required — fetched from IDP at startup)
34
34
  *
35
35
  * Returns:
36
36
  * - Upgraded access token with MFA claim
@@ -15,11 +15,9 @@
15
15
  */
16
16
 
17
17
  import { createRefreshHandler } from '../../api-handlers/auth/refresh';
18
- import { getIDPClientConfig } from '../../lib/idp-client-config';
19
18
 
20
- // Configuration is read at runtime from IDP config (cached)
21
- async function getConfig() {
22
- const idpConfig = await getIDPClientConfig();
19
+ // Configuration is read at runtime from environment.
20
+ function getConfig() {
23
21
  const idpBaseUrl = process.env.IDP_URL;
24
22
  if (!idpBaseUrl) {
25
23
  throw new Error('[IDP_URL] FATAL: IDP_URL environment variable is REQUIRED.');
@@ -27,7 +25,6 @@ async function getConfig() {
27
25
  return {
28
26
  idpBaseUrl,
29
27
  clientId: process.env.CLIENT_ID || process.env.NEXT_PUBLIC_IDP_CLIENT_ID || '',
30
- nextAuthSecret: idpConfig.nextAuthSecret || '',
31
28
  refreshEndpoint: process.env.REFRESH_ENDPOINT || '/api/ExternalAuth/refresh',
32
29
  };
33
30
  }
@@ -38,7 +35,6 @@ async function getConfig() {
38
35
  * Environment variables used:
39
36
  * - IDP_URL (REQUIRED)
40
37
  * - CLIENT_ID or NEXT_PUBLIC_IDP_CLIENT_ID (required)
41
- * - NEXTAUTH_SECRET (required)
42
38
  * - REFRESH_ENDPOINT (default: /api/ExternalAuth/refresh)
43
39
  */
44
40
  let _handler: ReturnType<typeof createRefreshHandler> | null = null;
@@ -47,8 +43,7 @@ import { NextRequest } from 'next/server';
47
43
 
48
44
  export async function POST(req: NextRequest) {
49
45
  if (!_handler) {
50
- const config = await getConfig();
51
- _handler = createRefreshHandler(config);
46
+ _handler = createRefreshHandler(getConfig());
52
47
  }
53
48
  return _handler(req);
54
49
  }
@@ -1,11 +1,8 @@
1
1
  /**
2
- * Server-side auth utilities for Better Auth (v4.0)
2
+ * Server-side auth utilities for Better Auth.
3
3
  *
4
- * Replaces:
5
- * - getToken() from next-auth/jwt
6
- * - getServerSession() from next-auth
7
- *
8
- * All server-side auth flows go through the Better Auth instance.
4
+ * All server-side auth flows go through the Better Auth instance returned by
5
+ * getAuthInstance(); use getSession(req) for the request-scoped session.
9
6
  */
10
7
 
11
8
  import 'server-only';
@@ -152,9 +152,9 @@ export async function decodeSession(
152
152
  }
153
153
 
154
154
  const config = await getIDPClientConfig();
155
- const secret = config.nextAuthSecret;
155
+ const secret = config.authSecret;
156
156
  if (!secret) {
157
- console.error('[DECODE-SESSION] No nextAuthSecret available from IDP config');
157
+ console.error('[DECODE-SESSION] No authSecret available from IDP config');
158
158
  return null;
159
159
  }
160
160
 
@@ -1,10 +0,0 @@
1
- import 'server-only';
2
- /**
3
- * Resolve the NextAuth secret (server-only).
4
- *
5
- * Priority:
6
- * 1) Use process.env.NEXTAUTH_SECRET if present (allows overrides/production)
7
- * 2) Fetch from IDP broker endpoint - IDP handles all Key Vault/signing
8
- * 3) Cache result in-memory and set process.env.NEXTAUTH_SECRET for subsequent calls
9
- */
10
- export declare function resolveNextAuthSecret(): Promise<string>;