/opt/canhelp/node_modules/better-auth/dist/utils
NameSizeModeActions
boolean.mjs1770644editdlrm
boolean.mjs.map2710644editdlrm
constants.mjs1780644editdlrm
constants.mjs.map2190644editdlrm
date.mjs2080644editdlrm
date.mjs.map3630644editdlrm
get-request-ip.d.mts2630644editdlrm
get-request-ip.mjs8790644editdlrm
get-request-ip.mjs.map18110644editdlrm
hashing.mjs7630644editdlrm
hashing.mjs.map12960644editdlrm
hide-metadata.d.mts1840644editdlrm
hide-metadata.mjs1620644editdlrm
hide-metadata.mjs.map2340644editdlrm
index.d.mts4000644editdlrm
index.mjs4030644editdlrm
is-api-error.d.mts2340644editdlrm
is-api-error.mjs3480644editdlrm
is-api-error.mjs.map5360644editdlrm
is-atom.mjs2820644editdlrm
is-atom.mjs.map5730644editdlrm
is-promise.mjs2440644editdlrm
is-promise.mjs.map4540644editdlrm
middleware-response.mjs2730644editdlrm
middleware-response.mjs.map5440644editdlrm
password.mjs11720644editdlrm
password.mjs.map22240644editdlrm
plugin-helper.mjs4740644editdlrm
plugin-helper.mjs.map8290644editdlrm
shim.mjs5630644editdlrm
shim.mjs.map10760644editdlrm
time.d.mts18230644editdlrm
time.mjs23580644editdlrm
time.mjs.map49780644editdlrm
url.d.mts34760644editdlrm
url.mjs82950644editdlrm
url.mjs.map152640644editdlrm
wildcard.mjs43370644editdlrm
wildcard.mjs.map90440644editdlrm
Edit: /opt/canhelp/node_modules/better-auth/dist/utils/url.mjs (8295B)
import { wildcardMatch } from "./wildcard.mjs"; import { env } from "@better-auth/core/env"; import { BetterAuthError } from "@better-auth/core/error"; //#region src/utils/url.ts function checkHasPath(url) { try { return (new URL(url).pathname.replace(/\/+$/, "") || "/") !== "/"; } catch { throw new BetterAuthError(`Invalid base URL: ${url}. Please provide a valid base URL.`); } } function assertHasProtocol(url) { try { const parsedUrl = new URL(url); if (parsedUrl.protocol !== "http:" && parsedUrl.protocol !== "https:") throw new BetterAuthError(`Invalid base URL: ${url}. URL must include 'http://' or 'https://'`); } catch (error) { if (error instanceof BetterAuthError) throw error; throw new BetterAuthError(`Invalid base URL: ${url}. Please provide a valid base URL.`, { cause: error }); } } function withPath(url, path = "/api/auth") { assertHasProtocol(url); if (checkHasPath(url)) return url; const trimmedUrl = url.replace(/\/+$/, ""); if (!path || path === "/") return trimmedUrl; path = path.startsWith("/") ? path : `/${path}`; return `${trimmedUrl}${path}`; } function validateProxyHeader(header, type) { if (!header || header.trim() === "") return false; if (type === "proto") return header === "http" || header === "https"; if (type === "host") { if ([ /\.\./, /\0/, /[\s]/, /^[.]/, /[<>'"]/, /javascript:/i, /file:/i, /data:/i ].some((pattern) => pattern.test(header))) return false; return /^[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(\.[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*(:[0-9]{1,5})?$/.test(header) || /^(\d{1,3}\.){3}\d{1,3}(:[0-9]{1,5})?$/.test(header) || /^\[[0-9a-fA-F:]+\](:[0-9]{1,5})?$/.test(header) || /^localhost(:[0-9]{1,5})?$/i.test(header); } return false; } function getBaseURL(url, path, request, loadEnv, trustedProxyHeaders) { if (url) return withPath(url, path); if (loadEnv !== false) { const fromEnv = env.BETTER_AUTH_URL || env.NEXT_PUBLIC_BETTER_AUTH_URL || env.PUBLIC_BETTER_AUTH_URL || env.NUXT_PUBLIC_BETTER_AUTH_URL || env.NUXT_PUBLIC_AUTH_URL || (env.BASE_URL !== "/" ? env.BASE_URL : void 0); if (fromEnv) return withPath(fromEnv, path); } const fromRequest = request?.headers.get("x-forwarded-host"); const fromRequestProto = request?.headers.get("x-forwarded-proto"); if (fromRequest && fromRequestProto && trustedProxyHeaders) { if (validateProxyHeader(fromRequestProto, "proto") && validateProxyHeader(fromRequest, "host")) try { return withPath(`${fromRequestProto}://${fromRequest}`, path); } catch (_error) {} } if (request) { const url = getOrigin(request.url); if (!url) throw new BetterAuthError("Could not get origin from request. Please provide a valid base URL."); return withPath(url, path); } if (typeof window !== "undefined" && window.location) return withPath(window.location.origin, path); } function getOrigin(url) { try { const parsedUrl = new URL(url); return parsedUrl.origin === "null" ? null : parsedUrl.origin; } catch { return null; } } function getProtocol(url) { try { return new URL(url).protocol; } catch { return null; } } function getHost(url) { try { return new URL(url).host; } catch { return null; } } /** * Checks if the baseURL config is a dynamic config object */ function isDynamicBaseURLConfig(config) { return typeof config === "object" && config !== null && "allowedHosts" in config && Array.isArray(config.allowedHosts); } /** * Extracts the host from the request headers. * Tries x-forwarded-host first (for proxy setups), then falls back to host header. * * @param request The incoming request * @returns The host string or null if not found */ function getHostFromRequest(request) { const forwardedHost = request.headers.get("x-forwarded-host"); if (forwardedHost && validateProxyHeader(forwardedHost, "host")) return forwardedHost; const host = request.headers.get("host"); if (host && validateProxyHeader(host, "host")) return host; try { return new URL(request.url).host; } catch { return null; } } /** * Extracts the protocol from the request headers. * Tries x-forwarded-proto first (for proxy setups), then infers from request URL. * * @param request The incoming request * @param configProtocol Protocol override from config * @returns The protocol ("http" or "https") */ function getProtocolFromRequest(request, configProtocol) { if (configProtocol === "http" || configProtocol === "https") return configProtocol; const forwardedProto = request.headers.get("x-forwarded-proto"); if (forwardedProto && validateProxyHeader(forwardedProto, "proto")) return forwardedProto; try { const url = new URL(request.url); if (url.protocol === "http:" || url.protocol === "https:") return url.protocol.slice(0, -1); } catch {} return "https"; } /** * Matches a hostname against a host pattern. * Supports wildcard patterns like `*.vercel.app` or `preview-*.myapp.com`. * * @param host The hostname to test (e.g., "myapp.com", "preview-123.vercel.app") * @param pattern The host pattern (e.g., "myapp.com", "*.vercel.app") * @returns {boolean} true if the host matches the pattern, false otherwise. * * @example * ```ts * matchesHostPattern("myapp.com", "myapp.com") // true * matchesHostPattern("preview-123.vercel.app", "*.vercel.app") // true * matchesHostPattern("preview-123.myapp.com", "preview-*.myapp.com") // true * matchesHostPattern("evil.com", "myapp.com") // false * ``` */ const matchesHostPattern = (host, pattern) => { if (!host || !pattern) return false; const normalizedHost = host.replace(/^https?:\/\//, "").split("/")[0].toLowerCase(); const normalizedPattern = pattern.replace(/^https?:\/\//, "").split("/")[0].toLowerCase(); if (normalizedPattern.includes("*") || normalizedPattern.includes("?")) return wildcardMatch(normalizedPattern)(normalizedHost); return normalizedHost.toLowerCase() === normalizedPattern.toLowerCase(); }; /** * Resolves the base URL from a dynamic config based on the incoming request. * Validates the derived host against the allowedHosts allowlist. * * @param config The dynamic base URL config * @param request The incoming request * @param basePath The base path to append * @returns The resolved base URL with path * @throws BetterAuthError if host is not in allowedHosts and no fallback is set */ function resolveDynamicBaseURL(config, request, basePath) { const host = getHostFromRequest(request); if (!host) { if (config.fallback) return withPath(config.fallback, basePath); throw new BetterAuthError("Could not determine host from request headers. Please provide a fallback URL in your baseURL config."); } if (config.allowedHosts.some((pattern) => matchesHostPattern(host, pattern))) return withPath(`${getProtocolFromRequest(request, config.protocol)}://${host}`, basePath); if (config.fallback) return withPath(config.fallback, basePath); throw new BetterAuthError(`Host "${host}" is not in the allowed hosts list. Allowed hosts: ${config.allowedHosts.join(", ")}. Add this host to your allowedHosts config or provide a fallback URL.`); } /** * Resolves the base URL from any config type (static string or dynamic object). * This is the main entry point for base URL resolution. * * @param config The base URL config (string or object) * @param basePath The base path to append * @param request Optional request for dynamic resolution * @param loadEnv Whether to load from environment variables * @param trustedProxyHeaders Whether to trust proxy headers (for legacy behavior) * @returns The resolved base URL with path */ function resolveBaseURL(config, basePath, request, loadEnv, trustedProxyHeaders) { if (isDynamicBaseURLConfig(config)) { if (request) return resolveDynamicBaseURL(config, request, basePath); if (config.fallback) return withPath(config.fallback, basePath); return getBaseURL(void 0, basePath, request, loadEnv, trustedProxyHeaders); } if (typeof config === "string") return getBaseURL(config, basePath, request, loadEnv, trustedProxyHeaders); return getBaseURL(void 0, basePath, request, loadEnv, trustedProxyHeaders); } //#endregion export { getBaseURL, getHost, getHostFromRequest, getOrigin, getProtocol, getProtocolFromRequest, isDynamicBaseURLConfig, matchesHostPattern, resolveBaseURL, resolveDynamicBaseURL }; //# sourceMappingURL=url.mjs.map