@payez/next-mvp 4.0.45 → 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 -2
  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 -2
  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
@@ -1,24 +1,37 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.resolveNextAuthSecret = resolveNextAuthSecret;
3
+ exports.resolveAuthSecret = resolveAuthSecret;
4
4
  require("server-only");
5
5
  const secret_validation_1 = require("./secret-validation");
6
6
  const crypto_1 = require("crypto");
7
7
  let cachedSecret = null;
8
8
  let lastFetchedAt = 0;
9
9
  /**
10
- * Resolve the NextAuth secret (server-only).
10
+ * Resolve the Better Auth signing secret (server-only).
11
11
  *
12
12
  * Priority:
13
- * 1) Use process.env.NEXTAUTH_SECRET if present (allows overrides/production)
14
- * 2) Fetch from IDP broker endpoint - IDP handles all Key Vault/signing
15
- * 3) Cache result in-memory and set process.env.NEXTAUTH_SECRET for subsequent calls
13
+ * 1) Use process.env.BETTER_AUTH_SECRET (preferred) or NEXTAUTH_SECRET (legacy)
14
+ * if present allows overrides/production via env.
15
+ * 2) Fetch from IDP broker endpoint IDP handles all Key Vault/signing.
16
+ * 3) Cache result in-memory and set process.env.BETTER_AUTH_SECRET for
17
+ * subsequent calls.
18
+ *
19
+ * NOTE on naming: this secret is the cryptographic key Better Auth uses to
20
+ * sign session JWTs. The IDP backend still names the broker endpoint and
21
+ * response field with the legacy "next-auth" / "nextAuthSecret" names; we
22
+ * read both new and legacy on the wire during the migration window.
16
23
  */
17
- async function resolveNextAuthSecret() {
18
- // Check if already in environment
19
- if (process.env.NEXTAUTH_SECRET && process.env.NEXTAUTH_SECRET.trim() !== '') {
24
+ async function resolveAuthSecret() {
25
+ // Check if already in environment (prefer new name, fall back to legacy)
26
+ const envSecret = (process.env.BETTER_AUTH_SECRET && process.env.BETTER_AUTH_SECRET.trim() !== ''
27
+ ? process.env.BETTER_AUTH_SECRET
28
+ : undefined) ||
29
+ (process.env.NEXTAUTH_SECRET && process.env.NEXTAUTH_SECRET.trim() !== ''
30
+ ? process.env.NEXTAUTH_SECRET
31
+ : undefined);
32
+ if (envSecret) {
20
33
  // Silent - already configured
21
- return process.env.NEXTAUTH_SECRET;
34
+ return envSecret;
22
35
  }
23
36
  // Check if cached and fresh (within 5 minutes)
24
37
  if (cachedSecret && Date.now() - lastFetchedAt < 5 * 60 * 1000) {
@@ -64,7 +77,8 @@ async function resolveNextAuthSecret() {
64
77
  if (!client_assertion || typeof client_assertion !== 'string') {
65
78
  throw new Error('IDP did not return a valid signed client assertion');
66
79
  }
67
- // Step 2: Use the signed assertion to fetch the NextAuth secret
80
+ // Step 2: Use the signed assertion to fetch the auth secret
81
+ // (Endpoint is still served at /next-auth/secret on the IDP — legacy path.)
68
82
  const proxyUrl = new URL(`${base.replace(/\/$/, '')}/api/ExternalAuth/next-auth/secret`);
69
83
  const proxyResp = await fetch(proxyUrl.toString(), {
70
84
  method: 'POST',
@@ -83,18 +97,20 @@ async function resolveNextAuthSecret() {
83
97
  }
84
98
  const proxyBody = await proxyResp.json().catch(() => ({}));
85
99
  const secret = (proxyBody?.data?.secret ?? proxyBody?.secret);
86
- const configuration = (proxyBody?.data?.configuration ?? proxyBody?.configuration);
87
100
  // Configuration is available but we don't log it verbosely
88
101
  if (!secret || typeof secret !== 'string') {
89
- throw new Error('Proxy did not return a valid NextAuth secret');
102
+ throw new Error('Proxy did not return a valid auth secret');
90
103
  }
91
- const validation = (0, secret_validation_1.validateNextAuthSecret)(secret);
104
+ const validation = (0, secret_validation_1.validateAuthSecret)(secret);
92
105
  if (!validation.valid) {
93
- throw new Error(`Fetched NextAuth secret failed validation: ${validation.reason}`);
106
+ throw new Error(`Fetched auth secret failed validation: ${validation.reason}`);
94
107
  }
95
108
  cachedSecret = secret;
96
109
  lastFetchedAt = Date.now();
110
+ process.env.BETTER_AUTH_SECRET = secret;
111
+ // Also set legacy name during transition so any consumer still reading
112
+ // process.env.NEXTAUTH_SECRET keeps working until they upgrade.
97
113
  process.env.NEXTAUTH_SECRET = secret;
98
- console.log('[NEXTAUTH-SECRET] Resolved from IDP (length:', secret.length + ')');
114
+ console.log('[AUTH-SECRET] Resolved from IDP (length:', secret.length + ')');
99
115
  return secret;
100
116
  }
@@ -12,5 +12,7 @@ function isDemoMode() {
12
12
  function isAuthConfigured() {
13
13
  if (isDemoMode())
14
14
  return false;
15
- return !!(process.env.NEXTAUTH_SECRET || (process.env.NEXT_CLIENT_ID && process.env.NEXT_CLIENT_PRIVATE_KEY_PEM));
15
+ return !!(process.env.BETTER_AUTH_SECRET ||
16
+ process.env.NEXTAUTH_SECRET ||
17
+ (process.env.NEXT_CLIENT_ID && process.env.NEXT_CLIENT_PRIVATE_KEY_PEM));
16
18
  }
@@ -5,7 +5,7 @@
5
5
  * - OAuth provider credentials (from Key Vault)
6
6
  * - 2FA/MFA settings
7
7
  * - Session configuration
8
- * - NextAuth secret
8
+ * - Better Auth signing secret
9
9
  * - Branding
10
10
  *
11
11
  * CACHING STRATEGY:
@@ -47,7 +47,11 @@ export interface BrandingConfig {
47
47
  export interface IDPClientConfig {
48
48
  clientId: string;
49
49
  clientSlug: string;
50
- nextAuthSecret: string;
50
+ /**
51
+ * Cryptographic secret used by Better Auth to sign session JWTs.
52
+ * Historically named "nextAuthSecret" — kept under the new name now.
53
+ */
54
+ authSecret: string;
51
55
  configCacheTtlSeconds: number;
52
56
  oauthProviders: OAuthProviderConfig[];
53
57
  authSettings: AuthSettings;
@@ -6,7 +6,7 @@
6
6
  * - OAuth provider credentials (from Key Vault)
7
7
  * - 2FA/MFA settings
8
8
  * - Session configuration
9
- * - NextAuth secret
9
+ * - Better Auth signing secret
10
10
  * - Branding
11
11
  *
12
12
  * CACHING STRATEGY:
@@ -115,13 +115,14 @@ async function getIDPClientConfig(forceRefresh = false) {
115
115
  // Restore to in-memory cache
116
116
  cachedConfig = redisConfig;
117
117
  cacheExpiry = Date.now() + ((redisConfig.configCacheTtlSeconds || 300) * 1000);
118
- // Set NEXTAUTH_SECRET from cached config
119
- if (redisConfig.nextAuthSecret) {
120
- process.env.NEXTAUTH_SECRET = redisConfig.nextAuthSecret;
118
+ // Set BETTER_AUTH_SECRET from cached config (also set legacy
119
+ // NEXTAUTH_SECRET during the rename transition).
120
+ if (redisConfig.authSecret) {
121
+ process.env.BETTER_AUTH_SECRET = redisConfig.authSecret;
122
+ process.env.NEXTAUTH_SECRET = redisConfig.authSecret;
121
123
  }
122
- // Set IDENTITY_CLIENT_BASE_EXTERNAL_URL from cached config
123
- // AUTH_TRUST_HOST=true tells NextAuth to derive OAuth callback URLs from headers.
124
- // Only set if not already defined (allows deployment override for beta/staging)
124
+ // Set IDENTITY_CLIENT_BASE_EXTERNAL_URL from cached config.
125
+ // Only set if not already defined (allows deployment override for beta/staging).
125
126
  if (redisConfig.baseClientUrl && !process.env.IDENTITY_CLIENT_BASE_EXTERNAL_URL) {
126
127
  process.env.IDENTITY_CLIENT_BASE_EXTERNAL_URL = redisConfig.baseClientUrl;
127
128
  }
@@ -149,16 +150,17 @@ async function getIDPClientConfig(forceRefresh = false) {
149
150
  cacheExpiry = Date.now() + ((config.configCacheTtlSeconds || 300) * 1000);
150
151
  // Store in Redis for persistence across module reloads
151
152
  await setConfigInRedis(config);
152
- // Set NEXTAUTH_SECRET from config
153
- if (config.nextAuthSecret) {
154
- process.env.NEXTAUTH_SECRET = config.nextAuthSecret;
153
+ // Set BETTER_AUTH_SECRET from config (also set legacy
154
+ // NEXTAUTH_SECRET during the rename transition).
155
+ if (config.authSecret) {
156
+ process.env.BETTER_AUTH_SECRET = config.authSecret;
157
+ process.env.NEXTAUTH_SECRET = config.authSecret;
155
158
  }
156
159
  else {
157
- throw new Error('[IDP_CONFIG] FATAL: IDP did not return nextAuthSecret');
160
+ throw new Error('[IDP_CONFIG] FATAL: IDP did not return authSecret');
158
161
  }
159
- // Set IDENTITY_CLIENT_BASE_EXTERNAL_URL from config
160
- // AUTH_TRUST_HOST=true tells NextAuth to derive OAuth callback URLs from headers.
161
- // Only set if not already defined (allows deployment override for beta/staging)
162
+ // Set IDENTITY_CLIENT_BASE_EXTERNAL_URL from config.
163
+ // Only set if not already defined (allows deployment override for beta/staging).
162
164
  if (config.baseClientUrl && !process.env.IDENTITY_CLIENT_BASE_EXTERNAL_URL) {
163
165
  process.env.IDENTITY_CLIENT_BASE_EXTERNAL_URL = config.baseClientUrl;
164
166
  console.log("[IDP_CONFIG] Set IDENTITY_CLIENT_BASE_EXTERNAL_URL:", config.baseClientUrl);
@@ -230,7 +232,13 @@ async function fetchConfigFromInternalIDP(internalIdpUrl, clientIdStr) {
230
232
  const config = {
231
233
  clientId: String(rawClientId),
232
234
  clientSlug: configData.clientSlug ?? configData.client_slug ?? configData.slug ?? '',
233
- nextAuthSecret: configData.nextAuthSecret ?? configData.next_auth_secret ?? '',
235
+ // Wire compatibility: accept new authSecret first, fall back to legacy
236
+ // nextAuthSecret/next_auth_secret while IDP rename rolls out.
237
+ authSecret: configData.authSecret ??
238
+ configData.auth_secret ??
239
+ configData.nextAuthSecret ??
240
+ configData.next_auth_secret ??
241
+ '',
234
242
  configCacheTtlSeconds: configData.configCacheTtlSeconds ?? configData.config_cache_ttl_seconds ?? 300,
235
243
  oauthProviders: (configData.oauthProviders ?? configData.oauth_providers ?? []).map((p) => ({
236
244
  provider: p.provider ?? '',
@@ -260,8 +268,8 @@ async function fetchConfigFromInternalIDP(internalIdpUrl, clientIdStr) {
260
268
  },
261
269
  baseClientUrl: configData.baseClientUrl ?? configData.base_client_url ?? configData.BaseClientUrl
262
270
  };
263
- if (!config.nextAuthSecret) {
264
- throw new Error('[IDP_CONFIG] FATAL: Internal IDP did not return nextAuthSecret');
271
+ if (!config.authSecret) {
272
+ throw new Error('[IDP_CONFIG] FATAL: Internal IDP did not return authSecret');
265
273
  }
266
274
  console.log(`[IDP_CONFIG] Internal IDP config loaded for ${clientIdStr}`);
267
275
  consecutiveFailures = 0;
@@ -366,11 +374,17 @@ async function fetchConfigFromIDP(idpUrl, clientIdStr) {
366
374
  if (rawClientId === undefined || rawClientId === null) {
367
375
  throw new Error(`[IDP_CONFIG] FATAL: IDP response missing clientId/client_id. Got: ${JSON.stringify(Object.keys(configData))}`);
368
376
  }
369
- // Map response to our interface (IDP always returns snake_case)
377
+ // Map response to our interface (IDP returns camelCase or snake_case).
378
+ // Wire compatibility: accept new authSecret first, fall back to legacy
379
+ // nextAuthSecret/next_auth_secret while IDP rename rolls out.
370
380
  const config = {
371
381
  clientId: String(rawClientId),
372
382
  clientSlug: configData.clientSlug ?? configData.client_slug ?? configData.slug ?? '',
373
- nextAuthSecret: configData.nextAuthSecret ?? configData.next_auth_secret ?? '',
383
+ authSecret: configData.authSecret ??
384
+ configData.auth_secret ??
385
+ configData.nextAuthSecret ??
386
+ configData.next_auth_secret ??
387
+ '',
374
388
  configCacheTtlSeconds: configData.configCacheTtlSeconds ?? configData.config_cache_ttl_seconds ?? 300,
375
389
  oauthProviders: (configData.oauthProviders ?? configData.oauth_providers ?? []).map((p) => ({
376
390
  provider: p.provider ?? '',
@@ -418,8 +432,8 @@ async function fetchConfigFromIDP(idpUrl, clientIdStr) {
418
432
  if (!config.clientId) {
419
433
  throw new Error('[IDP_CONFIG] FATAL: clientId is empty or missing after parsing');
420
434
  }
421
- if (!config.nextAuthSecret) {
422
- throw new Error('[IDP_CONFIG] FATAL: nextAuthSecret is empty after parsing');
435
+ if (!config.authSecret) {
436
+ throw new Error('[IDP_CONFIG] FATAL: authSecret is empty after parsing');
423
437
  }
424
438
  // Success - reset failure tracking
425
439
  consecutiveFailures = 0;
@@ -1,4 +1,4 @@
1
- export declare function validateNextAuthSecret(secret: string): {
1
+ export declare function validateAuthSecret(secret: string): {
2
2
  valid: boolean;
3
3
  reason?: string;
4
4
  };
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.validateNextAuthSecret = validateNextAuthSecret;
4
- function validateNextAuthSecret(secret) {
3
+ exports.validateAuthSecret = validateAuthSecret;
4
+ function validateAuthSecret(secret) {
5
5
  if (!secret || typeof secret !== 'string')
6
6
  return { valid: false, reason: 'missing' };
7
7
  if (secret.length < 32)
@@ -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
  */
@@ -27,7 +27,7 @@ export declare function logStartupStatus(): void;
27
27
  */
28
28
  export declare function getStartupIDPConfig(): IDPClientConfig | null;
29
29
  /**
30
- * Check if initialization failed (NEXTAUTH_SECRET couldn't be retrieved)
30
+ * Check if initialization failed (auth signing secret couldn't be retrieved)
31
31
  */
32
32
  export declare function isInitializationFailed(): boolean;
33
33
  /**
@@ -5,8 +5,8 @@
5
5
  * This module ensures that critical initialization tasks are completed
6
6
  * before the application serves requests.
7
7
  *
8
- * Now uses unified IDP client config for:
9
- * - NEXTAUTH_SECRET
8
+ * Uses unified IDP client config for:
9
+ * - BETTER_AUTH_SECRET (the Better Auth signing secret)
10
10
  * - OAuth provider configuration
11
11
  * - Auth settings (2FA, session timeouts, etc.)
12
12
  */
@@ -105,7 +105,7 @@ function logStartupStatus() {
105
105
  console.log('║ 🚀 PayEz Next MVP - Starting Up ║');
106
106
  console.log('║ ║');
107
107
  console.log('║ Async initialization in progress... ║');
108
- console.log('║ - Resolving NEXTAUTH_SECRET from IDP ║');
108
+ console.log('║ - Resolving BETTER_AUTH_SECRET from IDP ║');
109
109
  console.log('║ - Verifying environment configuration ║');
110
110
  console.log('║ ║');
111
111
  console.log('║ Check logs below for detailed initialization status: ║');
@@ -144,15 +144,20 @@ async function performInitialization() {
144
144
  console.log('[STARTUP] Client config loaded successfully');
145
145
  console.log('[STARTUP] - Client ID:', config.clientId);
146
146
  console.log('[STARTUP] - Client Slug:', config.clientSlug);
147
- console.log('[STARTUP] - Secret length:', config.nextAuthSecret?.length || 0, 'chars');
147
+ console.log('[STARTUP] - Secret length:', config.authSecret?.length || 0, 'chars');
148
148
  console.log('[STARTUP] - OAuth Providers:', config.oauthProviders?.filter(p => p.enabled).map(p => p.provider).join(', ') || 'none');
149
149
  console.log('[STARTUP] - Require 2FA:', config.authSettings?.require2FA);
150
150
  console.log('[STARTUP] - Cache TTL:', config.configCacheTtlSeconds, 'seconds');
151
151
  console.log('[STARTUP] - Base Client URL:', config.baseClientUrl || '(not set)');
152
- // Set NEXTAUTH_SECRET from IDP response if not already set
153
- if (config.nextAuthSecret && !process.env.NEXTAUTH_SECRET) {
154
- process.env.NEXTAUTH_SECRET = config.nextAuthSecret;
155
- console.log('[STARTUP] Set NEXTAUTH_SECRET from IDP config');
152
+ // Set BETTER_AUTH_SECRET from IDP response if not already set.
153
+ // Also mirror to legacy NEXTAUTH_SECRET during the rename transition
154
+ // so any consumer code still reading the old name keeps working.
155
+ if (config.authSecret && !process.env.BETTER_AUTH_SECRET) {
156
+ process.env.BETTER_AUTH_SECRET = config.authSecret;
157
+ console.log('[STARTUP] Set BETTER_AUTH_SECRET from IDP config');
158
+ }
159
+ if (config.authSecret && !process.env.NEXTAUTH_SECRET) {
160
+ process.env.NEXTAUTH_SECRET = config.authSecret;
156
161
  }
157
162
  }
158
163
  catch (error) {
@@ -161,15 +166,15 @@ async function performInitialization() {
161
166
  // No fallback available — IDP config is the only source for the auth secret
162
167
  console.error('[STARTUP] No fallback available for auth secret resolution');
163
168
  }
164
- // Step 2: Verify NEXTAUTH_SECRET is available - FAIL FAST if not
165
- console.log('[STARTUP] Step 2/2: Verifying NEXTAUTH_SECRET...');
166
- const secret = process.env.NEXTAUTH_SECRET;
169
+ // Step 2: Verify BETTER_AUTH_SECRET is available - FAIL FAST if not
170
+ console.log('[STARTUP] Step 2/2: Verifying BETTER_AUTH_SECRET...');
171
+ const secret = process.env.BETTER_AUTH_SECRET || process.env.NEXTAUTH_SECRET;
167
172
  if (!secret || secret.trim() === '') {
168
173
  console.error('');
169
174
  console.error('╔══════════════════════════════════════════════════════════════╗');
170
- console.error('║ ❌ FATAL: NEXTAUTH_SECRET NOT AVAILABLE ║');
175
+ console.error('║ ❌ FATAL: BETTER_AUTH_SECRET NOT AVAILABLE ║');
171
176
  console.error('║ ║');
172
- console.error('║ The app cannot start without a valid NEXTAUTH_SECRET. ║');
177
+ console.error('║ The app cannot start without a valid auth signing secret. ║');
173
178
  console.error('║ This should be fetched from IDP at startup. ║');
174
179
  console.error('║ ║');
175
180
  console.error('║ Possible causes: ║');
@@ -179,9 +184,9 @@ async function performInitialization() {
179
184
  console.error('║ • Network connectivity issue ║');
180
185
  console.error('╚══════════════════════════════════════════════════════════════╝');
181
186
  console.error('');
182
- throw new Error('FATAL: NEXTAUTH_SECRET not available - cannot start without valid secret from IDP');
187
+ throw new Error('FATAL: BETTER_AUTH_SECRET not available - cannot start without valid secret from IDP');
183
188
  }
184
- console.log('[STARTUP] NEXTAUTH_SECRET verified (' + secret.length + ' chars)');
189
+ console.log('[STARTUP] BETTER_AUTH_SECRET verified (' + secret.length + ' chars)');
185
190
  // Step 3: Validate cookie name consistency
186
191
  // This catches bugs where getJwtCookieName() returns a different name than
187
192
  // what auth-options.ts configures, which causes sessions to fail in production
@@ -210,9 +215,9 @@ async function performInitialization() {
210
215
  : '';
211
216
  console.error(`
212
217
  ╔══════════════════════════════════════════════════════════════╗
213
- ║ ❌ FATAL: NEXTAUTH_SECRET NOT AVAILABLE
218
+ ║ ❌ FATAL: BETTER_AUTH_SECRET NOT AVAILABLE
214
219
  ║ ║
215
- ║ The app cannot start without a valid NEXTAUTH_SECRET.
220
+ ║ The app cannot start without a valid auth signing secret.
216
221
  ║ This should be fetched from IDP at startup. ║
217
222
  ║ ║
218
223
  ${connectionLine}║ Possible causes: ║
@@ -240,7 +245,7 @@ function getStartupIDPConfig() {
240
245
  return cachedIDPConfig;
241
246
  }
242
247
  /**
243
- * Check if initialization failed (NEXTAUTH_SECRET couldn't be retrieved)
248
+ * Check if initialization failed (auth signing secret couldn't be retrieved)
244
249
  */
245
250
  function isInitializationFailed() {
246
251
  return initializationFailed;
@@ -40,11 +40,11 @@ const app_slug_1 = require("./app-slug");
40
40
  async function getTokenTestAware(req) {
41
41
  if (process.env.TEST_MODE === 'true') {
42
42
  try {
43
- let secret = process.env.NEXTAUTH_SECRET;
43
+ let secret = process.env.BETTER_AUTH_SECRET || process.env.NEXTAUTH_SECRET;
44
44
  if (!secret || secret.trim() === '') {
45
45
  const { getIDPClientConfig } = await Promise.resolve().then(() => __importStar(require('./idp-client-config')));
46
46
  const idpConfig = await getIDPClientConfig();
47
- secret = idpConfig.nextAuthSecret;
47
+ secret = idpConfig.authSecret;
48
48
  }
49
49
  // Use app-slug prefixed cookie name
50
50
  const cookieName = (0, app_slug_1.getSessionCookieName)();
@@ -24,7 +24,7 @@ export { POST } from '../../api-handlers/account/masked-info';
24
24
  * Environment variables used:
25
25
  * - IDP_URL or NEXT_PUBLIC_IDP_URL (default: http://localhost:32785)
26
26
  * - CLIENT_ID or NEXT_PUBLIC_IDP_CLIENT_ID (required)
27
- * - NEXTAUTH_SECRET (required)
27
+ * - BETTER_AUTH_SECRET (required — fetched from IDP at startup)
28
28
  *
29
29
  * Returns:
30
30
  * - Masked email addresses
@@ -30,7 +30,7 @@ Object.defineProperty(exports, "POST", { enumerable: true, get: function () { re
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
  * - Masked email addresses
@@ -28,7 +28,7 @@ export { POST } from '../../api-handlers/account/send-code';
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
  * - Success status
@@ -33,7 +33,7 @@ Object.defineProperty(exports, "POST", { enumerable: true, get: function () { re
33
33
  * Environment variables used:
34
34
  * - IDP_URL or NEXT_PUBLIC_IDP_URL (default: http://localhost:32785)
35
35
  * - CLIENT_ID or NEXT_PUBLIC_IDP_CLIENT_ID (required)
36
- * - NEXTAUTH_SECRET (required)
36
+ * - BETTER_AUTH_SECRET (required — fetched from IDP at startup)
37
37
  *
38
38
  * Returns:
39
39
  * - Success status
@@ -27,7 +27,7 @@ export { POST } from '../../api-handlers/account/verify-email';
27
27
  * Environment variables used:
28
28
  * - IDP_URL or NEXT_PUBLIC_IDP_URL (default: http://localhost:32785)
29
29
  * - CLIENT_ID or NEXT_PUBLIC_IDP_CLIENT_ID (required)
30
- * - NEXTAUTH_SECRET (required)
30
+ * - BETTER_AUTH_SECRET (required — fetched from IDP at startup)
31
31
  *
32
32
  * Returns:
33
33
  * - Upgraded access token with MFA claim
@@ -32,7 +32,7 @@ Object.defineProperty(exports, "POST", { enumerable: true, get: function () { re
32
32
  * Environment variables used:
33
33
  * - IDP_URL or NEXT_PUBLIC_IDP_URL (default: http://localhost:32785)
34
34
  * - CLIENT_ID or NEXT_PUBLIC_IDP_CLIENT_ID (required)
35
- * - NEXTAUTH_SECRET (required)
35
+ * - BETTER_AUTH_SECRET (required — fetched from IDP at startup)
36
36
  *
37
37
  * Returns:
38
38
  * - Upgraded access token with MFA claim
@@ -27,7 +27,7 @@ export { POST } from '../../api-handlers/account/verify-sms';
27
27
  * Environment variables used:
28
28
  * - IDP_URL or NEXT_PUBLIC_IDP_URL (default: http://localhost:32785)
29
29
  * - CLIENT_ID or NEXT_PUBLIC_IDP_CLIENT_ID (required)
30
- * - NEXTAUTH_SECRET (required)
30
+ * - BETTER_AUTH_SECRET (required — fetched from IDP at startup)
31
31
  *
32
32
  * Returns:
33
33
  * - Upgraded access token with MFA claim
@@ -32,7 +32,7 @@ Object.defineProperty(exports, "POST", { enumerable: true, get: function () { re
32
32
  * Environment variables used:
33
33
  * - IDP_URL or NEXT_PUBLIC_IDP_URL (default: http://localhost:32785)
34
34
  * - CLIENT_ID or NEXT_PUBLIC_IDP_CLIENT_ID (required)
35
- * - NEXTAUTH_SECRET (required)
35
+ * - BETTER_AUTH_SECRET (required — fetched from IDP at startup)
36
36
  *
37
37
  * Returns:
38
38
  * - Upgraded access token with MFA claim
@@ -17,10 +17,8 @@
17
17
  Object.defineProperty(exports, "__esModule", { value: true });
18
18
  exports.POST = POST;
19
19
  const refresh_1 = require("../../api-handlers/auth/refresh");
20
- const idp_client_config_1 = require("../../lib/idp-client-config");
21
- // Configuration is read at runtime from IDP config (cached)
22
- async function getConfig() {
23
- const idpConfig = await (0, idp_client_config_1.getIDPClientConfig)();
20
+ // Configuration is read at runtime from environment.
21
+ function getConfig() {
24
22
  const idpBaseUrl = process.env.IDP_URL;
25
23
  if (!idpBaseUrl) {
26
24
  throw new Error('[IDP_URL] FATAL: IDP_URL environment variable is REQUIRED.');
@@ -28,7 +26,6 @@ async function getConfig() {
28
26
  return {
29
27
  idpBaseUrl,
30
28
  clientId: process.env.CLIENT_ID || process.env.NEXT_PUBLIC_IDP_CLIENT_ID || '',
31
- nextAuthSecret: idpConfig.nextAuthSecret || '',
32
29
  refreshEndpoint: process.env.REFRESH_ENDPOINT || '/api/ExternalAuth/refresh',
33
30
  };
34
31
  }
@@ -38,14 +35,12 @@ 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 = null;
45
41
  async function POST(req) {
46
42
  if (!_handler) {
47
- const config = await getConfig();
48
- _handler = (0, refresh_1.createRefreshHandler)(config);
43
+ _handler = (0, refresh_1.createRefreshHandler)(getConfig());
49
44
  }
50
45
  return _handler(req);
51
46
  }
@@ -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
  import 'server-only';
11
8
  /**
@@ -36,7 +33,7 @@ export declare function getAuthInstance(): Promise<import("better-auth/types").A
36
33
  };
37
34
  };
38
35
  };
39
- plugins: [...any[], {
36
+ plugins: [{
40
37
  id: "next-cookies";
41
38
  hooks: {
42
39
  before: {
@@ -1,12 +1,9 @@
1
1
  "use strict";
2
2
  /**
3
- * Server-side auth utilities for Better Auth (v4.0)
3
+ * Server-side auth utilities for Better Auth.
4
4
  *
5
- * Replaces:
6
- * - getToken() from next-auth/jwt
7
- * - getServerSession() from next-auth
8
- *
9
- * All server-side auth flows go through the Better Auth instance.
5
+ * All server-side auth flows go through the Better Auth instance returned by
6
+ * getAuthInstance(); use getSession(req) for the request-scoped session.
10
7
  */
11
8
  var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
12
9
  if (k2 === undefined) k2 = k;
@@ -166,9 +166,9 @@ async function decodeSession(requestCookies) {
166
166
  return null;
167
167
  }
168
168
  const config = await (0, idp_client_config_1.getIDPClientConfig)();
169
- const secret = config.nextAuthSecret;
169
+ const secret = config.authSecret;
170
170
  if (!secret) {
171
- console.error('[DECODE-SESSION] No nextAuthSecret available from IDP config');
171
+ console.error('[DECODE-SESSION] No authSecret available from IDP config');
172
172
  return null;
173
173
  }
174
174
  const secretKey = new TextEncoder().encode(secret);
@@ -141,7 +141,7 @@ export declare function useVibeMutation<T extends VibeTableName, Op extends Muta
141
141
  /**
142
142
  * Convenience hook for creating records.
143
143
  */
144
- export declare function useVibeCreate<T extends VibeTableName>(table: T, options?: Omit<UseVibeMutationOptions<T, 'create'>, never>): import("@tanstack/react-query").UseMutationResult<VibeTableType<T>, VibeError, Omit<VibeTableType<T>, "id" | "created_at" | "updated_at">, unknown>;
144
+ export declare function useVibeCreate<T extends VibeTableName>(table: T, options?: Omit<UseVibeMutationOptions<T, 'create'>, never>): import("@tanstack/react-query").UseMutationResult<VibeTableType<T>, VibeError, Omit<VibeTableType<T>, "created_at" | "id" | "updated_at">, unknown>;
145
145
  /**
146
146
  * Convenience hook for updating records.
147
147
  */