@lenne.tech/nest-server 11.27.4 → 11.27.5

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.
@@ -7,6 +7,7 @@ import * as crypto from 'crypto';
7
7
  import * as fs from 'fs';
8
8
  import * as path from 'path';
9
9
 
10
+ import { resolveServerUrls } from '../../common/helpers/cookies.helper';
10
11
  import { IBetterAuth, ICorsConfig } from '../../common/interfaces/server-options.interface';
11
12
  import { detectCookiePrefixDrift, resolveBetterAuthCookiePrefix } from './better-auth-cookie-prefix.helper';
12
13
 
@@ -914,21 +915,6 @@ function readProjectNameFromPackageJson(): string {
914
915
  return fallback;
915
916
  }
916
917
 
917
- /**
918
- * Default URLs for local/test environments (local, ci, e2e)
919
- * These environments typically run on localhost and don't have a deployed domain.
920
- */
921
- const LOCALHOST_DEFAULTS = {
922
- API_URL: 'http://localhost:3000',
923
- APP_URL: 'http://localhost:3001',
924
- };
925
-
926
- /**
927
- * Environments that use localhost defaults for URLs.
928
- * These are typically development/test environments without deployed domains.
929
- */
930
- const LOCALHOST_ENVS = ['local', 'ci', 'e2e'];
931
-
932
918
  /**
933
919
  * Resolves the effective URLs for BetterAuth configuration.
934
920
  *
@@ -948,37 +934,6 @@ interface ResolvedUrls {
948
934
  warnings: string[];
949
935
  }
950
936
 
951
- /**
952
- * Derives appUrl from baseUrl by removing 'api.' prefix from subdomain.
953
- *
954
- * Examples:
955
- * - 'https://api.example.com' → 'https://example.com'
956
- * - 'https://api.dev.example.com' → 'https://dev.example.com'
957
- * - 'https://example.com' → 'https://example.com' (unchanged)
958
- * - 'http://localhost:3000' → 'http://localhost:3000' (unchanged)
959
- *
960
- * @param baseUrl - The API base URL
961
- * @returns Derived app URL or the original URL if no 'api.' prefix
962
- */
963
- function deriveAppUrlFromBaseUrl(baseUrl: string): string {
964
- try {
965
- const url = new URL(baseUrl);
966
- const hostname = url.hostname;
967
-
968
- // Check if hostname starts with 'api.'
969
- if (hostname.startsWith('api.')) {
970
- // Remove 'api.' prefix
971
- url.hostname = hostname.substring(4);
972
- return url.origin;
973
- }
974
-
975
- // Return original URL if no 'api.' prefix
976
- return url.origin;
977
- } catch {
978
- return baseUrl;
979
- }
980
- }
981
-
982
937
  /**
983
938
  * Extracts the root domain from a URL for use as Passkey rpId.
984
939
  *
@@ -1263,36 +1218,31 @@ function deriveCookieDomainFromUrls(appUrl?: string, baseUrl?: string): string |
1263
1218
  }
1264
1219
 
1265
1220
  function resolveUrls(options: CreateBetterAuthOptions): ResolvedUrls {
1266
- const { config, serverAppUrl, serverBaseUrl, serverEnv } = options;
1221
+ const { config, serverAppUrl, serverBaseUrl, serverCorsConfig, serverEnv } = options;
1267
1222
  const warnings: string[] = [];
1268
- const usesLocalhostDefaults = LOCALHOST_ENVS.includes(serverEnv || '');
1269
1223
 
1270
- // Step 1: Resolve baseUrl
1271
- // Priority: betterAuth.baseUrl > serverBaseUrl > localhost default (for local/ci/e2e)
1272
- let baseUrl = config.baseUrl || serverBaseUrl;
1273
- if (!baseUrl && usesLocalhostDefaults) {
1274
- baseUrl = LOCALHOST_DEFAULTS.API_URL;
1224
+ // Steps 1+2 (baseUrl, appUrl) are delegated to the shared resolver in cookies.helper so that
1225
+ // BetterAuth's trustedOrigins and the REST/GraphQL CORS allowlist can never disagree about
1226
+ // which app origin this server is reachable under. `cors.deriveAppUrl: false` therefore
1227
+ // suppresses the `api.`-strip derivation on this layer too.
1228
+ const corsObj = typeof serverCorsConfig === 'object' && serverCorsConfig !== null ? serverCorsConfig : undefined;
1229
+ const resolved = resolveServerUrls({
1230
+ appUrl: serverAppUrl,
1231
+ // Priority: betterAuth.baseUrl > serverBaseUrl (> localhost default, applied by the resolver)
1232
+ baseUrl: config.baseUrl || serverBaseUrl,
1233
+ deriveAppUrl: corsObj?.deriveAppUrl,
1234
+ env: serverEnv,
1235
+ });
1236
+ const { appUrl, baseUrl } = resolved;
1237
+
1238
+ if (resolved.baseUrlSource === 'localhost-default') {
1275
1239
  warnings.push(`URL: Using localhost default baseUrl="${baseUrl}" (env: '${serverEnv}')`);
1276
1240
  }
1277
-
1278
- // Step 2: Resolve appUrl
1279
- // Priority: serverAppUrl > localhost default (when baseUrl is localhost) > derived from baseUrl
1280
- let appUrl = serverAppUrl;
1281
-
1282
- // For localhost environments with localhost baseUrl, use localhost app default
1283
- // This handles the common case where API runs on :3000 and App on :3001
1284
- const isBaseUrlLocalhost = baseUrl && (baseUrl.includes('localhost') || baseUrl.includes('127.0.0.1'));
1285
- if (!appUrl && usesLocalhostDefaults && isBaseUrlLocalhost) {
1286
- appUrl = LOCALHOST_DEFAULTS.APP_URL;
1241
+ if (resolved.appUrlSource === 'localhost-default') {
1287
1242
  warnings.push(`URL: Using localhost default appUrl="${appUrl}" (env: '${serverEnv}')`);
1288
1243
  }
1289
-
1290
- // For non-localhost environments, try to derive appUrl from baseUrl
1291
- if (!appUrl && baseUrl) {
1292
- appUrl = deriveAppUrlFromBaseUrl(baseUrl);
1293
- if (appUrl !== baseUrl) {
1294
- warnings.push(`URL: Auto-derived appUrl="${appUrl}" from baseUrl="${baseUrl}"`);
1295
- }
1244
+ if (resolved.appUrlSource === 'derived' && appUrl !== baseUrl) {
1245
+ warnings.push(`URL: Auto-derived appUrl="${appUrl}" from baseUrl="${baseUrl}"`);
1296
1246
  }
1297
1247
 
1298
1248
  // Step 3: Resolve rpId from appUrl (not baseUrl!)