🚀 Socket Launch Week Day 5:Introducing Repository Access Permissions and Custom Roles.Learn more
Sign In

@angular/ssr

Package Overview
Dependencies
Maintainers
2
Versions
351
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@angular/ssr - npm Package Compare versions

Comparing version
20.3.28
to
20.3.29
+2
-2
fesm2022/node.mjs

@@ -408,4 +408,4 @@ import { renderApplication, renderModule, ɵSERVER_CONTEXT as _SERVER_CONTEXT } from '@angular/platform-server';

...options,
allowedHosts: getAllowedHostsFromEnv() ?? options?.allowedHosts,
trustProxyHeaders: getTrustProxyHeadersFromEnv() ?? options?.trustProxyHeaders,
allowedHosts: options?.allowedHosts ?? getAllowedHostsFromEnv(),
trustProxyHeaders: options?.trustProxyHeaders ?? getTrustProxyHeadersFromEnv(),
};

@@ -412,0 +412,0 @@ this.angularAppEngine = new AngularAppEngine(appEngineOptions);

@@ -1,1 +0,1 @@

{"version":3,"file":"node.mjs","sources":["../../../../../../k8-fastbuild-ST-199a4f3c4e20/bin/packages/angular/ssr/node/src/environment-options.ts","../../../../../../k8-fastbuild-ST-199a4f3c4e20/bin/packages/angular/ssr/node/src/errors.ts","../../../../../../k8-fastbuild-ST-199a4f3c4e20/bin/packages/angular/ssr/node/src/common-engine/inline-css-processor.ts","../../../../../../k8-fastbuild-ST-199a4f3c4e20/bin/packages/angular/ssr/node/src/common-engine/peformance-profiler.ts","../../../../../../k8-fastbuild-ST-199a4f3c4e20/bin/packages/angular/ssr/node/src/common-engine/common-engine.ts","../../../../../../k8-fastbuild-ST-199a4f3c4e20/bin/packages/angular/ssr/node/src/request.ts","../../../../../../k8-fastbuild-ST-199a4f3c4e20/bin/packages/angular/ssr/node/src/app-engine.ts","../../../../../../k8-fastbuild-ST-199a4f3c4e20/bin/packages/angular/ssr/node/src/handler.ts","../../../../../../k8-fastbuild-ST-199a4f3c4e20/bin/packages/angular/ssr/node/src/response.ts","../../../../../../k8-fastbuild-ST-199a4f3c4e20/bin/packages/angular/ssr/node/src/module.ts"],"sourcesContent":["/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.dev/license\n */\n\n/**\n * Retrieves the list of allowed hosts from the environment variable `NG_ALLOWED_HOSTS`.\n * @returns An array of allowed hosts.\n */\nexport function getAllowedHostsFromEnv(): ReadonlyArray<string> | undefined {\n return getArrayFromEnv('NG_ALLOWED_HOSTS');\n}\n\n/**\n * Retrieves the list of trusted proxy headers from the environment variable `NG_TRUST_PROXY_HEADERS`.\n * @returns An array of trusted proxy headers.\n */\nexport function getTrustProxyHeadersFromEnv(): ReadonlyArray<string> | undefined {\n return getArrayFromEnv('NG_TRUST_PROXY_HEADERS');\n}\n\nfunction getArrayFromEnv(envName: string): ReadonlyArray<string> | undefined {\n const envValue = process.env[envName];\n if (!envValue) {\n return undefined;\n }\n\n const values: string[] = [];\n for (const value of envValue.split(',')) {\n const trimmed = value.trim();\n if (trimmed.length > 0) {\n values.push(trimmed);\n }\n }\n\n return values;\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.dev/license\n */\n\n/**\n * Attaches listeners to the Node.js process to capture and handle unhandled rejections and uncaught exceptions.\n * Captured errors are logged to the console. This function logs errors to the console, preventing unhandled errors\n * from crashing the server. It is particularly useful for Zoneless apps, ensuring error handling without relying on Zone.js.\n *\n * @remarks\n * This function is a no-op if zone.js is available.\n * For Zone-based apps, similar functionality is provided by Zone.js itself. See the Zone.js implementation here:\n * https://github.com/angular/angular/blob/4a8d0b79001ec09bcd6f2d6b15117aa6aac1932c/packages/zone.js/lib/node/node.ts#L94%7C\n *\n * @internal\n */\nexport function attachNodeGlobalErrorHandlers(): void {\n if (typeof Zone !== 'undefined') {\n return;\n }\n\n // Ensure that the listeners are registered only once.\n // Otherwise, multiple instances may be registered during edit/refresh.\n const gThis: typeof globalThis & { ngAttachNodeGlobalErrorHandlersCalled?: boolean } = globalThis;\n if (gThis.ngAttachNodeGlobalErrorHandlersCalled) {\n return;\n }\n\n gThis.ngAttachNodeGlobalErrorHandlersCalled = true;\n\n process\n // eslint-disable-next-line no-console\n .on('unhandledRejection', (error) => console.error('unhandledRejection', error))\n // eslint-disable-next-line no-console\n .on('uncaughtException', (error) => console.error('uncaughtException', error));\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.dev/license\n */\n\nimport { ɵInlineCriticalCssProcessor as InlineCriticalCssProcessor } from '@angular/ssr';\nimport { readFile } from 'node:fs/promises';\n\nexport class CommonEngineInlineCriticalCssProcessor {\n private readonly resourceCache = new Map<string, string>();\n\n async process(html: string, outputPath: string | undefined): Promise<string> {\n const beasties = new InlineCriticalCssProcessor(async (path) => {\n let resourceContent = this.resourceCache.get(path);\n if (resourceContent === undefined) {\n resourceContent = await readFile(path, 'utf-8');\n this.resourceCache.set(path, resourceContent);\n }\n\n return resourceContent;\n }, outputPath);\n\n return beasties.process(html);\n }\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.dev/license\n */\n\nconst PERFORMANCE_MARK_PREFIX = '🅰️';\n\nexport function printPerformanceLogs(): void {\n let maxWordLength = 0;\n const benchmarks: [step: string, value: string][] = [];\n\n for (const { name, duration } of performance.getEntriesByType('measure')) {\n if (!name.startsWith(PERFORMANCE_MARK_PREFIX)) {\n continue;\n }\n\n // `🅰️:Retrieve SSG Page` -> `Retrieve SSG Page:`\n const step = name.slice(PERFORMANCE_MARK_PREFIX.length + 1) + ':';\n if (step.length > maxWordLength) {\n maxWordLength = step.length;\n }\n\n benchmarks.push([step, `${duration.toFixed(1)}ms`]);\n performance.clearMeasures(name);\n }\n\n /* eslint-disable no-console */\n console.log('********** Performance results **********');\n for (const [step, value] of benchmarks) {\n const spaces = maxWordLength - step.length + 5;\n console.log(step + ' '.repeat(spaces) + value);\n }\n console.log('*****************************************');\n /* eslint-enable no-console */\n}\n\nexport async function runMethodAndMeasurePerf<T>(\n label: string,\n asyncMethod: () => Promise<T>,\n): Promise<T> {\n const labelName = `${PERFORMANCE_MARK_PREFIX}:${label}`;\n const startLabel = `start:${labelName}`;\n const endLabel = `end:${labelName}`;\n\n try {\n performance.mark(startLabel);\n\n return await asyncMethod();\n } finally {\n performance.mark(endLabel);\n performance.measure(labelName, startLabel, endLabel);\n performance.clearMarks(startLabel);\n performance.clearMarks(endLabel);\n }\n}\n\nexport function noopRunMethodAndMeasurePerf<T>(\n label: string,\n asyncMethod: () => Promise<T>,\n): Promise<T> {\n return asyncMethod();\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.dev/license\n */\n\nimport { ApplicationRef, StaticProvider, Type } from '@angular/core';\nimport { BootstrapContext } from '@angular/platform-browser';\nimport { renderApplication, renderModule, ɵSERVER_CONTEXT } from '@angular/platform-server';\nimport * as fs from 'node:fs';\nimport { dirname, join, normalize, resolve } from 'node:path';\nimport { URL } from 'node:url';\nimport { validateUrl } from '../../../src/utils/validation';\nimport { getAllowedHostsFromEnv } from '../environment-options';\nimport { attachNodeGlobalErrorHandlers } from '../errors';\nimport { CommonEngineInlineCriticalCssProcessor } from './inline-css-processor';\nimport {\n noopRunMethodAndMeasurePerf,\n printPerformanceLogs,\n runMethodAndMeasurePerf,\n} from './peformance-profiler';\n\nconst SSG_MARKER_REGEXP = /ng-server-context=[\"']\\w*\\|?ssg\\|?\\w*[\"']/;\n\nexport interface CommonEngineOptions {\n /** A method that when invoked returns a promise that returns an `ApplicationRef` instance once resolved or an NgModule. */\n bootstrap?: Type<{}> | ((context: BootstrapContext) => Promise<ApplicationRef>);\n\n /** A set of platform level providers for all requests. */\n providers?: StaticProvider[];\n\n /** Enable request performance profiling data collection and printing the results in the server console. */\n enablePerformanceProfiler?: boolean;\n\n /** A set of hostnames that are allowed to access the server. */\n allowedHosts?: readonly string[];\n}\n\nexport interface CommonEngineRenderOptions {\n /** A method that when invoked returns a promise that returns an `ApplicationRef` instance once resolved or an NgModule. */\n bootstrap?: Type<{}> | ((context: BootstrapContext) => Promise<ApplicationRef>);\n\n /** A set of platform level providers for the current request. */\n providers?: StaticProvider[];\n url?: string;\n document?: string;\n documentFilePath?: string;\n\n /**\n * Reduce render blocking requests by inlining critical CSS.\n * Defaults to true.\n */\n inlineCriticalCss?: boolean;\n\n /**\n * Base path location of index file.\n * Defaults to the 'documentFilePath' dirname when not provided.\n */\n publicPath?: string;\n}\n\n/**\n * A common engine to use to server render an application.\n */\n\nexport class CommonEngine {\n private readonly templateCache = new Map<string, string>();\n private readonly inlineCriticalCssProcessor = new CommonEngineInlineCriticalCssProcessor();\n private readonly pageIsSSG = new Map<string, boolean>();\n private readonly allowedHosts: ReadonlySet<string>;\n\n constructor(private options?: CommonEngineOptions) {\n this.allowedHosts = new Set(getAllowedHostsFromEnv() ?? this.options?.allowedHosts ?? []);\n\n attachNodeGlobalErrorHandlers();\n }\n\n /**\n * Render an HTML document for a specific URL with specified\n * render options\n */\n async render(opts: CommonEngineRenderOptions): Promise<string> {\n const { url } = opts;\n\n if (url && URL.canParse(url)) {\n const urlObj = new URL(url);\n try {\n validateUrl(urlObj, this.allowedHosts);\n } catch (error) {\n const isAllowedHostConfigured = this.allowedHosts.size > 0;\n // eslint-disable-next-line no-console\n console.error(\n `ERROR: ${(error as Error).message}` +\n 'Please provide a list of allowed hosts in the \"allowedHosts\" option in the \"CommonEngine\" constructor.',\n isAllowedHostConfigured\n ? ''\n : '\\nFalling back to client side rendering. This will become a 400 Bad Request in a future major version.',\n );\n\n if (!isAllowedHostConfigured) {\n // Fallback to CSR to avoid a breaking change.\n // TODO(alanagius): Return a 400 and remove this fallback in the next major version (v22).\n let document = opts.document;\n if (!document && opts.documentFilePath) {\n document = opts.document ?? (await this.getDocument(opts.documentFilePath));\n }\n\n if (document) {\n return document;\n }\n }\n\n throw error;\n }\n }\n\n const enablePerformanceProfiler = this.options?.enablePerformanceProfiler;\n\n const runMethod = enablePerformanceProfiler\n ? runMethodAndMeasurePerf\n : noopRunMethodAndMeasurePerf;\n\n let html = await runMethod('Retrieve SSG Page', () => this.retrieveSSGPage(opts));\n\n if (html === undefined) {\n html = await runMethod('Render Page', () => this.renderApplication(opts));\n\n if (opts.inlineCriticalCss !== false) {\n const content = await runMethod('Inline Critical CSS', () =>\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n this.inlineCriticalCss(html!, opts),\n );\n\n html = content;\n }\n }\n\n if (enablePerformanceProfiler) {\n printPerformanceLogs();\n }\n\n return html;\n }\n\n private inlineCriticalCss(html: string, opts: CommonEngineRenderOptions): Promise<string> {\n const outputPath =\n opts.publicPath ?? (opts.documentFilePath ? dirname(opts.documentFilePath) : '');\n\n return this.inlineCriticalCssProcessor.process(html, outputPath);\n }\n\n private async retrieveSSGPage(opts: CommonEngineRenderOptions): Promise<string | undefined> {\n const { publicPath, documentFilePath, url } = opts;\n if (!publicPath || !documentFilePath || url === undefined) {\n return undefined;\n }\n\n const { pathname } = new URL(url, 'resolve://');\n // Do not use `resolve` here as otherwise it can lead to path traversal vulnerability.\n // See: https://portswigger.net/web-security/file-path-traversal\n const pagePath = join(publicPath, pathname, 'index.html');\n\n if (this.pageIsSSG.get(pagePath)) {\n // Serve pre-rendered page.\n return fs.promises.readFile(pagePath, 'utf-8');\n }\n\n if (!pagePath.startsWith(normalize(publicPath))) {\n // Potential path traversal detected.\n return undefined;\n }\n\n if (pagePath === resolve(documentFilePath) || !(await exists(pagePath))) {\n // View matches with prerender path or file does not exist.\n this.pageIsSSG.set(pagePath, false);\n\n return undefined;\n }\n\n // Static file exists.\n const content = await fs.promises.readFile(pagePath, 'utf-8');\n const isSSG = SSG_MARKER_REGEXP.test(content);\n this.pageIsSSG.set(pagePath, isSSG);\n\n return isSSG ? content : undefined;\n }\n\n private async renderApplication(opts: CommonEngineRenderOptions): Promise<string> {\n const moduleOrFactory = this.options?.bootstrap ?? opts.bootstrap;\n if (!moduleOrFactory) {\n throw new Error('A module or bootstrap option must be provided.');\n }\n\n const extraProviders: StaticProvider[] = [\n { provide: ɵSERVER_CONTEXT, useValue: 'ssr' },\n ...(opts.providers ?? []),\n ...(this.options?.providers ?? []),\n ];\n\n let document = opts.document;\n if (!document && opts.documentFilePath) {\n document = await this.getDocument(opts.documentFilePath);\n }\n\n const commonRenderingOptions = {\n url: opts.url,\n document,\n // Validation is already happened in the render method.\n allowedHosts: ['*'],\n };\n\n return isBootstrapFn(moduleOrFactory)\n ? renderApplication(moduleOrFactory, {\n platformProviders: extraProviders,\n ...commonRenderingOptions,\n })\n : renderModule(moduleOrFactory, { extraProviders, ...commonRenderingOptions });\n }\n\n /** Retrieve the document from the cache or the filesystem */\n private async getDocument(filePath: string): Promise<string> {\n let doc = this.templateCache.get(filePath);\n\n if (!doc) {\n doc = await fs.promises.readFile(filePath, 'utf-8');\n this.templateCache.set(filePath, doc);\n }\n\n return doc;\n }\n}\n\nasync function exists(path: fs.PathLike): Promise<boolean> {\n try {\n await fs.promises.access(path, fs.constants.F_OK);\n\n return true;\n } catch {\n return false;\n }\n}\n\nfunction isBootstrapFn(\n value: unknown,\n): value is (context: BootstrapContext) => Promise<ApplicationRef> {\n // We can differentiate between a module and a bootstrap function by reading compiler-generated `ɵmod` static property:\n return typeof value === 'function' && !('ɵmod' in value);\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.dev/license\n */\n\nimport type { IncomingHttpHeaders, IncomingMessage } from 'node:http';\nimport type { Http2ServerRequest } from 'node:http2';\nimport {\n getFirstHeaderValue,\n isProxyHeaderAllowed,\n normalizeTrustProxyHeaders,\n} from '../../src/utils/validation';\n\n/**\n * A set containing all the pseudo-headers defined in the HTTP/2 specification.\n *\n * This set can be used to filter out pseudo-headers from a list of headers,\n * as they are not allowed to be set directly using the `Node.js` Undici API or\n * the web `Headers` API.\n */\nconst HTTP2_PSEUDO_HEADERS: ReadonlySet<string> = new Set([\n ':method',\n ':scheme',\n ':authority',\n ':path',\n ':status',\n]);\n\n/**\n * Converts a Node.js `IncomingMessage` or `Http2ServerRequest` into a\n * Web Standard `Request` object.\n *\n * This function adapts the Node.js request objects to a format that can\n * be used by web platform APIs.\n *\n * @param nodeRequest - The Node.js request object (`IncomingMessage` or `Http2ServerRequest`) to convert.\n * @param trustProxyHeaders - A boolean or an array of proxy headers to trust when constructing the request URL.\n *\n * @remarks\n * When `trustProxyHeaders` is enabled, headers such as `X-Forwarded-Host` and\n * `X-Forwarded-Prefix` should ideally be strictly validated at a higher infrastructure\n * level (e.g., at the reverse proxy or API gateway) before reaching the application.\n *\n * @returns A Web Standard `Request` object.\n */\nexport function createWebRequestFromNodeRequest(\n nodeRequest: IncomingMessage | Http2ServerRequest,\n trustProxyHeaders?: boolean | readonly string[],\n): Request {\n const trustProxyHeadersNormalized = normalizeTrustProxyHeaders(trustProxyHeaders);\n const { headers, method = 'GET' } = nodeRequest;\n const withBody = method !== 'GET' && method !== 'HEAD';\n const referrer = headers.referer && URL.canParse(headers.referer) ? headers.referer : undefined;\n\n return new Request(createRequestUrl(nodeRequest, trustProxyHeadersNormalized), {\n method,\n headers: createRequestHeaders(headers),\n body: withBody ? nodeRequest : undefined,\n duplex: withBody ? 'half' : undefined,\n referrer,\n });\n}\n\n/**\n * Creates a `Headers` object from Node.js `IncomingHttpHeaders`.\n *\n * @param nodeHeaders - The Node.js `IncomingHttpHeaders` object to convert.\n * @returns A `Headers` object containing the converted headers.\n */\nfunction createRequestHeaders(nodeHeaders: IncomingHttpHeaders): Headers {\n const headers = new Headers();\n\n for (const [name, value] of Object.entries(nodeHeaders)) {\n if (HTTP2_PSEUDO_HEADERS.has(name)) {\n continue;\n }\n\n if (typeof value === 'string') {\n headers.append(name, value);\n } else if (Array.isArray(value)) {\n for (const item of value) {\n headers.append(name, item);\n }\n }\n }\n\n return headers;\n}\n\n/**\n * Creates a `URL` object from a Node.js `IncomingMessage`, taking into account the protocol, host, and port.\n *\n * @param nodeRequest - The Node.js `IncomingMessage` or `Http2ServerRequest` object to extract URL information from.\n * @param trustProxyHeaders - A set of allowed proxy headers.\n *\n * @remarks\n * When `trustProxyHeaders` is enabled, headers such as `X-Forwarded-Host` and\n * `X-Forwarded-Prefix` should ideally be strictly validated at a higher infrastructure\n * level (e.g., at the reverse proxy or API gateway) before reaching the application.\n *\n * @returns A `URL` object representing the request URL.\n */\nexport function createRequestUrl(\n nodeRequest: IncomingMessage | Http2ServerRequest,\n trustProxyHeaders: ReadonlySet<string>,\n): URL {\n const {\n headers,\n socket,\n url = '',\n originalUrl,\n } = nodeRequest as IncomingMessage & { originalUrl?: string };\n\n const protocol =\n getAllowedProxyHeaderValue(headers, 'x-forwarded-proto', trustProxyHeaders) ??\n ('encrypted' in socket && socket.encrypted ? 'https' : 'http');\n\n const hostname =\n getAllowedProxyHeaderValue(headers, 'x-forwarded-host', trustProxyHeaders) ??\n headers.host ??\n headers[':authority'];\n\n if (Array.isArray(hostname)) {\n throw new Error('host value cannot be an array.');\n }\n\n let hostnameWithPort = hostname;\n if (!hostname?.includes(':')) {\n const port = getAllowedProxyHeaderValue(headers, 'x-forwarded-port', trustProxyHeaders);\n if (port) {\n hostnameWithPort += `:${port}`;\n }\n }\n\n return new URL(`${protocol}://${hostnameWithPort}${originalUrl ?? url}`);\n}\n\n/**\n * Gets the first value of an allowed proxy header.\n *\n * @param headers - The Node.js incoming HTTP headers.\n * @param headerName - The name of the proxy header to retrieve.\n * @param trustProxyHeaders - A set of allowed proxy headers.\n * @returns The value of the allowed proxy header, or `undefined` if not allowed or not present.\n */\nfunction getAllowedProxyHeaderValue(\n headers: IncomingHttpHeaders,\n headerName: string,\n trustProxyHeaders: ReadonlySet<string>,\n): string | undefined {\n return isProxyHeaderAllowed(headerName, trustProxyHeaders)\n ? getFirstHeaderValue(headers[headerName])\n : undefined;\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.dev/license\n */\n\nimport { AngularAppEngine } from '@angular/ssr';\nimport type { IncomingMessage } from 'node:http';\nimport type { Http2ServerRequest } from 'node:http2';\nimport { AngularAppEngineOptions } from '../../src/app-engine';\nimport { getAllowedHostsFromEnv, getTrustProxyHeadersFromEnv } from './environment-options';\nimport { attachNodeGlobalErrorHandlers } from './errors';\nimport { createWebRequestFromNodeRequest } from './request';\n\n/**\n * Options for the Angular Node.js server application engine.\n */\nexport interface AngularNodeAppEngineOptions extends AngularAppEngineOptions {}\n\n/**\n * Angular server application engine.\n * Manages Angular server applications (including localized ones), handles rendering requests,\n * and optionally transforms index HTML before rendering.\n *\n * @remarks This class should be instantiated once and used as a singleton across the server-side\n * application to ensure consistent handling of rendering requests and resource management.\n */\nexport class AngularNodeAppEngine {\n private readonly angularAppEngine: AngularAppEngine;\n private readonly trustProxyHeaders?: boolean | readonly string[];\n\n /**\n * Creates a new instance of the Angular Node.js server application engine.\n * @param options Options for the Angular Node.js server application engine.\n */\n constructor(options?: AngularNodeAppEngineOptions) {\n const appEngineOptions: AngularAppEngineOptions = {\n ...options,\n allowedHosts: getAllowedHostsFromEnv() ?? options?.allowedHosts,\n trustProxyHeaders: getTrustProxyHeadersFromEnv() ?? options?.trustProxyHeaders,\n };\n\n this.angularAppEngine = new AngularAppEngine(appEngineOptions);\n this.trustProxyHeaders = appEngineOptions.trustProxyHeaders;\n\n attachNodeGlobalErrorHandlers();\n }\n\n /**\n * Handles an incoming HTTP request by serving prerendered content, performing server-side rendering,\n * or delivering a static file for client-side rendered routes based on the `RenderMode` setting.\n *\n * This method adapts Node.js's `IncomingMessage`, `Http2ServerRequest` or `Request`\n * to a format compatible with the `AngularAppEngine` and delegates the handling logic to it.\n *\n * @param request - The incoming HTTP request (`IncomingMessage`, `Http2ServerRequest` or `Request`).\n * @param requestContext - Optional context for rendering, such as metadata associated with the request.\n * @returns A promise that resolves to the resulting HTTP response object, or `null` if no matching Angular route is found.\n *\n * @remarks A request to `https://www.example.com/page/index.html` will serve or render the Angular route\n * corresponding to `https://www.example.com/page`.\n *\n * @remarks\n * To prevent potential Server-Side Request Forgery (SSRF), this function verifies the hostname\n * of the `request.url` against a list of authorized hosts.\n * If the hostname is not recognized and `allowedHosts` is not empty, a Client-Side Rendered (CSR) version of the\n * page is returned otherwise a 400 Bad Request is returned.\n *\n * Resolution:\n * Authorize your hostname by configuring `allowedHosts` in `angular.json` in:\n * `projects.[project-name].architect.build.options.security.allowedHosts`.\n * Alternatively, you can define the allowed hostname via the environment variable `process.env['NG_ALLOWED_HOSTS']`\n * or pass it directly through the configuration options of `AngularNodeAppEngine`.\n *\n * For more information see: https://angular.dev/best-practices/security#preventing-server-side-request-forgery-ssrf\n */\n async handle(\n request: IncomingMessage | Http2ServerRequest | Request,\n requestContext?: unknown,\n ): Promise<Response | null> {\n const webRequest =\n request instanceof Request\n ? request\n : createWebRequestFromNodeRequest(request, this.trustProxyHeaders);\n\n return this.angularAppEngine.handle(webRequest, requestContext);\n }\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.dev/license\n */\n\nimport type { IncomingMessage, ServerResponse } from 'node:http';\n\n/**\n * Represents a middleware function for handling HTTP requests in a Node.js environment.\n *\n * @param req - The incoming HTTP request object.\n * @param res - The outgoing HTTP response object.\n * @param next - A callback function that signals the completion of the middleware or forwards the error if provided.\n *\n * @returns A Promise that resolves to void or simply void. The handler can be asynchronous.\n */\nexport type NodeRequestHandlerFunction = (\n req: IncomingMessage,\n res: ServerResponse,\n next: (err?: unknown) => void,\n) => Promise<void> | void;\n\n/**\n * Attaches metadata to the handler function to mark it as a special handler for Node.js environments.\n *\n * @typeParam T - The type of the handler function.\n * @param handler - The handler function to be defined and annotated.\n * @returns The same handler function passed as an argument, with metadata attached.\n *\n * @example\n * Usage in an Express application:\n * ```ts\n * const app = express();\n * export default createNodeRequestHandler(app);\n * ```\n *\n * @example\n * Usage in a Hono application:\n * ```ts\n * const app = new Hono();\n * export default createNodeRequestHandler(async (req, res, next) => {\n * try {\n * const webRes = await app.fetch(createWebRequestFromNodeRequest(req));\n * if (webRes) {\n * await writeResponseToNodeResponse(webRes, res);\n * } else {\n * next();\n * }\n * } catch (error) {\n * next(error);\n * }\n * });\n * ```\n *\n * @example\n * Usage in a Fastify application:\n * ```ts\n * const app = Fastify();\n * export default createNodeRequestHandler(async (req, res) => {\n * await app.ready();\n * app.server.emit('request', req, res);\n * });\n * ```\n */\nexport function createNodeRequestHandler<T extends NodeRequestHandlerFunction>(handler: T): T {\n (handler as T & { __ng_node_request_handler__?: boolean })['__ng_node_request_handler__'] = true;\n\n return handler;\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.dev/license\n */\n\nimport type { ServerResponse } from 'node:http';\nimport type { Http2ServerResponse } from 'node:http2';\n\n/**\n * Streams a web-standard `Response` into a Node.js `ServerResponse`\n * or `Http2ServerResponse`.\n *\n * This function adapts the web `Response` object to write its content\n * to a Node.js response object, handling both HTTP/1.1 and HTTP/2.\n *\n * @param source - The web-standard `Response` object to stream from.\n * @param destination - The Node.js response object (`ServerResponse` or `Http2ServerResponse`) to stream into.\n * @returns A promise that resolves once the streaming operation is complete.\n */\nexport async function writeResponseToNodeResponse(\n source: Response,\n destination: ServerResponse | Http2ServerResponse,\n): Promise<void> {\n const { status, headers, body } = source;\n destination.statusCode = status;\n\n let cookieHeaderSet = false;\n for (const [name, value] of headers.entries()) {\n if (name === 'set-cookie') {\n if (cookieHeaderSet) {\n continue;\n }\n\n // Sets the 'set-cookie' header only once to ensure it is correctly applied.\n // Concatenating 'set-cookie' values can lead to incorrect behavior, so we use a single value from `headers.getSetCookie()`.\n destination.setHeader(name, headers.getSetCookie());\n cookieHeaderSet = true;\n } else {\n destination.setHeader(name, value);\n }\n }\n\n if ('flushHeaders' in destination) {\n destination.flushHeaders();\n }\n\n if (!body) {\n destination.end();\n\n return;\n }\n\n try {\n const reader = body.getReader();\n\n destination.on('close', () => {\n reader.cancel().catch((error) => {\n // eslint-disable-next-line no-console\n console.error(\n `An error occurred while writing the response body for: ${destination.req.url}.`,\n error,\n );\n });\n });\n\n // eslint-disable-next-line no-constant-condition\n while (true) {\n const { done, value } = await reader.read();\n if (done) {\n destination.end();\n break;\n }\n\n const canContinue = (destination as ServerResponse).write(value);\n if (canContinue === false) {\n // Explicitly check for `false`, as AWS may return `undefined` even though this is not valid.\n // See: https://github.com/CodeGenieApp/serverless-express/issues/683\n await new Promise<void>((resolve) => destination.once('drain', resolve));\n }\n }\n } catch {\n destination.end('Internal server error.');\n }\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.dev/license\n */\n\nimport { argv } from 'node:process';\nimport { fileURLToPath } from 'node:url';\n\n/**\n * Determines whether the provided URL represents the main entry point module.\n *\n * This function checks if the provided URL corresponds to the main ESM module being executed directly.\n * It's useful for conditionally executing code that should only run when a module is the entry point,\n * such as starting a server or initializing an application.\n *\n * It performs two key checks:\n * 1. Verifies if the URL starts with 'file:', ensuring it is a local file.\n * 2. Compares the URL's resolved file path with the first command-line argument (`process.argv[1]`),\n * which points to the file being executed.\n *\n * @param url The URL of the module to check. This should typically be `import.meta.url`.\n * @returns `true` if the provided URL represents the main entry point, otherwise `false`.\n */\nexport function isMainModule(url: string): boolean {\n return url.startsWith('file:') && argv[1] === fileURLToPath(url);\n}\n"],"names":["InlineCriticalCssProcessor","URL","ɵSERVER_CONTEXT"],"mappings":"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"}
{"version":3,"file":"node.mjs","sources":["../../../../../../darwin_arm64-fastbuild-ST-199a4f3c4e20/bin/packages/angular/ssr/node/src/environment-options.ts","../../../../../../darwin_arm64-fastbuild-ST-199a4f3c4e20/bin/packages/angular/ssr/node/src/errors.ts","../../../../../../darwin_arm64-fastbuild-ST-199a4f3c4e20/bin/packages/angular/ssr/node/src/common-engine/inline-css-processor.ts","../../../../../../darwin_arm64-fastbuild-ST-199a4f3c4e20/bin/packages/angular/ssr/node/src/common-engine/peformance-profiler.ts","../../../../../../darwin_arm64-fastbuild-ST-199a4f3c4e20/bin/packages/angular/ssr/node/src/common-engine/common-engine.ts","../../../../../../darwin_arm64-fastbuild-ST-199a4f3c4e20/bin/packages/angular/ssr/node/src/request.ts","../../../../../../darwin_arm64-fastbuild-ST-199a4f3c4e20/bin/packages/angular/ssr/node/src/app-engine.ts","../../../../../../darwin_arm64-fastbuild-ST-199a4f3c4e20/bin/packages/angular/ssr/node/src/handler.ts","../../../../../../darwin_arm64-fastbuild-ST-199a4f3c4e20/bin/packages/angular/ssr/node/src/response.ts","../../../../../../darwin_arm64-fastbuild-ST-199a4f3c4e20/bin/packages/angular/ssr/node/src/module.ts"],"sourcesContent":["/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.dev/license\n */\n\n/**\n * Retrieves the list of allowed hosts from the environment variable `NG_ALLOWED_HOSTS`.\n * @returns An array of allowed hosts.\n */\nexport function getAllowedHostsFromEnv(): ReadonlyArray<string> | undefined {\n return getArrayFromEnv('NG_ALLOWED_HOSTS');\n}\n\n/**\n * Retrieves the list of trusted proxy headers from the environment variable `NG_TRUST_PROXY_HEADERS`.\n * @returns An array of trusted proxy headers.\n */\nexport function getTrustProxyHeadersFromEnv(): ReadonlyArray<string> | undefined {\n return getArrayFromEnv('NG_TRUST_PROXY_HEADERS');\n}\n\nfunction getArrayFromEnv(envName: string): ReadonlyArray<string> | undefined {\n const envValue = process.env[envName];\n if (!envValue) {\n return undefined;\n }\n\n const values: string[] = [];\n for (const value of envValue.split(',')) {\n const trimmed = value.trim();\n if (trimmed.length > 0) {\n values.push(trimmed);\n }\n }\n\n return values;\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.dev/license\n */\n\n/**\n * Attaches listeners to the Node.js process to capture and handle unhandled rejections and uncaught exceptions.\n * Captured errors are logged to the console. This function logs errors to the console, preventing unhandled errors\n * from crashing the server. It is particularly useful for Zoneless apps, ensuring error handling without relying on Zone.js.\n *\n * @remarks\n * This function is a no-op if zone.js is available.\n * For Zone-based apps, similar functionality is provided by Zone.js itself. See the Zone.js implementation here:\n * https://github.com/angular/angular/blob/4a8d0b79001ec09bcd6f2d6b15117aa6aac1932c/packages/zone.js/lib/node/node.ts#L94%7C\n *\n * @internal\n */\nexport function attachNodeGlobalErrorHandlers(): void {\n if (typeof Zone !== 'undefined') {\n return;\n }\n\n // Ensure that the listeners are registered only once.\n // Otherwise, multiple instances may be registered during edit/refresh.\n const gThis: typeof globalThis & { ngAttachNodeGlobalErrorHandlersCalled?: boolean } = globalThis;\n if (gThis.ngAttachNodeGlobalErrorHandlersCalled) {\n return;\n }\n\n gThis.ngAttachNodeGlobalErrorHandlersCalled = true;\n\n process\n // eslint-disable-next-line no-console\n .on('unhandledRejection', (error) => console.error('unhandledRejection', error))\n // eslint-disable-next-line no-console\n .on('uncaughtException', (error) => console.error('uncaughtException', error));\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.dev/license\n */\n\nimport { ɵInlineCriticalCssProcessor as InlineCriticalCssProcessor } from '@angular/ssr';\nimport { readFile } from 'node:fs/promises';\n\nexport class CommonEngineInlineCriticalCssProcessor {\n private readonly resourceCache = new Map<string, string>();\n\n async process(html: string, outputPath: string | undefined): Promise<string> {\n const beasties = new InlineCriticalCssProcessor(async (path) => {\n let resourceContent = this.resourceCache.get(path);\n if (resourceContent === undefined) {\n resourceContent = await readFile(path, 'utf-8');\n this.resourceCache.set(path, resourceContent);\n }\n\n return resourceContent;\n }, outputPath);\n\n return beasties.process(html);\n }\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.dev/license\n */\n\nconst PERFORMANCE_MARK_PREFIX = '🅰️';\n\nexport function printPerformanceLogs(): void {\n let maxWordLength = 0;\n const benchmarks: [step: string, value: string][] = [];\n\n for (const { name, duration } of performance.getEntriesByType('measure')) {\n if (!name.startsWith(PERFORMANCE_MARK_PREFIX)) {\n continue;\n }\n\n // `🅰️:Retrieve SSG Page` -> `Retrieve SSG Page:`\n const step = name.slice(PERFORMANCE_MARK_PREFIX.length + 1) + ':';\n if (step.length > maxWordLength) {\n maxWordLength = step.length;\n }\n\n benchmarks.push([step, `${duration.toFixed(1)}ms`]);\n performance.clearMeasures(name);\n }\n\n /* eslint-disable no-console */\n console.log('********** Performance results **********');\n for (const [step, value] of benchmarks) {\n const spaces = maxWordLength - step.length + 5;\n console.log(step + ' '.repeat(spaces) + value);\n }\n console.log('*****************************************');\n /* eslint-enable no-console */\n}\n\nexport async function runMethodAndMeasurePerf<T>(\n label: string,\n asyncMethod: () => Promise<T>,\n): Promise<T> {\n const labelName = `${PERFORMANCE_MARK_PREFIX}:${label}`;\n const startLabel = `start:${labelName}`;\n const endLabel = `end:${labelName}`;\n\n try {\n performance.mark(startLabel);\n\n return await asyncMethod();\n } finally {\n performance.mark(endLabel);\n performance.measure(labelName, startLabel, endLabel);\n performance.clearMarks(startLabel);\n performance.clearMarks(endLabel);\n }\n}\n\nexport function noopRunMethodAndMeasurePerf<T>(\n label: string,\n asyncMethod: () => Promise<T>,\n): Promise<T> {\n return asyncMethod();\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.dev/license\n */\n\nimport { ApplicationRef, StaticProvider, Type } from '@angular/core';\nimport { BootstrapContext } from '@angular/platform-browser';\nimport { renderApplication, renderModule, ɵSERVER_CONTEXT } from '@angular/platform-server';\nimport * as fs from 'node:fs';\nimport { dirname, join, normalize, resolve } from 'node:path';\nimport { URL } from 'node:url';\nimport { validateUrl } from '../../../src/utils/validation';\nimport { getAllowedHostsFromEnv } from '../environment-options';\nimport { attachNodeGlobalErrorHandlers } from '../errors';\nimport { CommonEngineInlineCriticalCssProcessor } from './inline-css-processor';\nimport {\n noopRunMethodAndMeasurePerf,\n printPerformanceLogs,\n runMethodAndMeasurePerf,\n} from './peformance-profiler';\n\nconst SSG_MARKER_REGEXP = /ng-server-context=[\"']\\w*\\|?ssg\\|?\\w*[\"']/;\n\nexport interface CommonEngineOptions {\n /** A method that when invoked returns a promise that returns an `ApplicationRef` instance once resolved or an NgModule. */\n bootstrap?: Type<{}> | ((context: BootstrapContext) => Promise<ApplicationRef>);\n\n /** A set of platform level providers for all requests. */\n providers?: StaticProvider[];\n\n /** Enable request performance profiling data collection and printing the results in the server console. */\n enablePerformanceProfiler?: boolean;\n\n /** A set of hostnames that are allowed to access the server. */\n allowedHosts?: readonly string[];\n}\n\nexport interface CommonEngineRenderOptions {\n /** A method that when invoked returns a promise that returns an `ApplicationRef` instance once resolved or an NgModule. */\n bootstrap?: Type<{}> | ((context: BootstrapContext) => Promise<ApplicationRef>);\n\n /** A set of platform level providers for the current request. */\n providers?: StaticProvider[];\n url?: string;\n document?: string;\n documentFilePath?: string;\n\n /**\n * Reduce render blocking requests by inlining critical CSS.\n * Defaults to true.\n */\n inlineCriticalCss?: boolean;\n\n /**\n * Base path location of index file.\n * Defaults to the 'documentFilePath' dirname when not provided.\n */\n publicPath?: string;\n}\n\n/**\n * A common engine to use to server render an application.\n */\n\nexport class CommonEngine {\n private readonly templateCache = new Map<string, string>();\n private readonly inlineCriticalCssProcessor = new CommonEngineInlineCriticalCssProcessor();\n private readonly pageIsSSG = new Map<string, boolean>();\n private readonly allowedHosts: ReadonlySet<string>;\n\n constructor(private options?: CommonEngineOptions) {\n this.allowedHosts = new Set(getAllowedHostsFromEnv() ?? this.options?.allowedHosts ?? []);\n\n attachNodeGlobalErrorHandlers();\n }\n\n /**\n * Render an HTML document for a specific URL with specified\n * render options\n */\n async render(opts: CommonEngineRenderOptions): Promise<string> {\n const { url } = opts;\n\n if (url && URL.canParse(url)) {\n const urlObj = new URL(url);\n try {\n validateUrl(urlObj, this.allowedHosts);\n } catch (error) {\n const isAllowedHostConfigured = this.allowedHosts.size > 0;\n // eslint-disable-next-line no-console\n console.error(\n `ERROR: ${(error as Error).message}` +\n 'Please provide a list of allowed hosts in the \"allowedHosts\" option in the \"CommonEngine\" constructor.',\n isAllowedHostConfigured\n ? ''\n : '\\nFalling back to client side rendering. This will become a 400 Bad Request in a future major version.',\n );\n\n if (!isAllowedHostConfigured) {\n // Fallback to CSR to avoid a breaking change.\n // TODO(alanagius): Return a 400 and remove this fallback in the next major version (v22).\n let document = opts.document;\n if (!document && opts.documentFilePath) {\n document = opts.document ?? (await this.getDocument(opts.documentFilePath));\n }\n\n if (document) {\n return document;\n }\n }\n\n throw error;\n }\n }\n\n const enablePerformanceProfiler = this.options?.enablePerformanceProfiler;\n\n const runMethod = enablePerformanceProfiler\n ? runMethodAndMeasurePerf\n : noopRunMethodAndMeasurePerf;\n\n let html = await runMethod('Retrieve SSG Page', () => this.retrieveSSGPage(opts));\n\n if (html === undefined) {\n html = await runMethod('Render Page', () => this.renderApplication(opts));\n\n if (opts.inlineCriticalCss !== false) {\n const content = await runMethod('Inline Critical CSS', () =>\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n this.inlineCriticalCss(html!, opts),\n );\n\n html = content;\n }\n }\n\n if (enablePerformanceProfiler) {\n printPerformanceLogs();\n }\n\n return html;\n }\n\n private inlineCriticalCss(html: string, opts: CommonEngineRenderOptions): Promise<string> {\n const outputPath =\n opts.publicPath ?? (opts.documentFilePath ? dirname(opts.documentFilePath) : '');\n\n return this.inlineCriticalCssProcessor.process(html, outputPath);\n }\n\n private async retrieveSSGPage(opts: CommonEngineRenderOptions): Promise<string | undefined> {\n const { publicPath, documentFilePath, url } = opts;\n if (!publicPath || !documentFilePath || url === undefined) {\n return undefined;\n }\n\n const { pathname } = new URL(url, 'resolve://');\n // Do not use `resolve` here as otherwise it can lead to path traversal vulnerability.\n // See: https://portswigger.net/web-security/file-path-traversal\n const pagePath = join(publicPath, pathname, 'index.html');\n\n if (this.pageIsSSG.get(pagePath)) {\n // Serve pre-rendered page.\n return fs.promises.readFile(pagePath, 'utf-8');\n }\n\n if (!pagePath.startsWith(normalize(publicPath))) {\n // Potential path traversal detected.\n return undefined;\n }\n\n if (pagePath === resolve(documentFilePath) || !(await exists(pagePath))) {\n // View matches with prerender path or file does not exist.\n this.pageIsSSG.set(pagePath, false);\n\n return undefined;\n }\n\n // Static file exists.\n const content = await fs.promises.readFile(pagePath, 'utf-8');\n const isSSG = SSG_MARKER_REGEXP.test(content);\n this.pageIsSSG.set(pagePath, isSSG);\n\n return isSSG ? content : undefined;\n }\n\n private async renderApplication(opts: CommonEngineRenderOptions): Promise<string> {\n const moduleOrFactory = this.options?.bootstrap ?? opts.bootstrap;\n if (!moduleOrFactory) {\n throw new Error('A module or bootstrap option must be provided.');\n }\n\n const extraProviders: StaticProvider[] = [\n { provide: ɵSERVER_CONTEXT, useValue: 'ssr' },\n ...(opts.providers ?? []),\n ...(this.options?.providers ?? []),\n ];\n\n let document = opts.document;\n if (!document && opts.documentFilePath) {\n document = await this.getDocument(opts.documentFilePath);\n }\n\n const commonRenderingOptions = {\n url: opts.url,\n document,\n // Validation is already happened in the render method.\n allowedHosts: ['*'],\n };\n\n return isBootstrapFn(moduleOrFactory)\n ? renderApplication(moduleOrFactory, {\n platformProviders: extraProviders,\n ...commonRenderingOptions,\n })\n : renderModule(moduleOrFactory, { extraProviders, ...commonRenderingOptions });\n }\n\n /** Retrieve the document from the cache or the filesystem */\n private async getDocument(filePath: string): Promise<string> {\n let doc = this.templateCache.get(filePath);\n\n if (!doc) {\n doc = await fs.promises.readFile(filePath, 'utf-8');\n this.templateCache.set(filePath, doc);\n }\n\n return doc;\n }\n}\n\nasync function exists(path: fs.PathLike): Promise<boolean> {\n try {\n await fs.promises.access(path, fs.constants.F_OK);\n\n return true;\n } catch {\n return false;\n }\n}\n\nfunction isBootstrapFn(\n value: unknown,\n): value is (context: BootstrapContext) => Promise<ApplicationRef> {\n // We can differentiate between a module and a bootstrap function by reading compiler-generated `ɵmod` static property:\n return typeof value === 'function' && !('ɵmod' in value);\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.dev/license\n */\n\nimport type { IncomingHttpHeaders, IncomingMessage } from 'node:http';\nimport type { Http2ServerRequest } from 'node:http2';\nimport {\n getFirstHeaderValue,\n isProxyHeaderAllowed,\n normalizeTrustProxyHeaders,\n} from '../../src/utils/validation';\n\n/**\n * A set containing all the pseudo-headers defined in the HTTP/2 specification.\n *\n * This set can be used to filter out pseudo-headers from a list of headers,\n * as they are not allowed to be set directly using the `Node.js` Undici API or\n * the web `Headers` API.\n */\nconst HTTP2_PSEUDO_HEADERS: ReadonlySet<string> = new Set([\n ':method',\n ':scheme',\n ':authority',\n ':path',\n ':status',\n]);\n\n/**\n * Converts a Node.js `IncomingMessage` or `Http2ServerRequest` into a\n * Web Standard `Request` object.\n *\n * This function adapts the Node.js request objects to a format that can\n * be used by web platform APIs.\n *\n * @param nodeRequest - The Node.js request object (`IncomingMessage` or `Http2ServerRequest`) to convert.\n * @param trustProxyHeaders - A boolean or an array of proxy headers to trust when constructing the request URL.\n *\n * @remarks\n * When `trustProxyHeaders` is enabled, headers such as `X-Forwarded-Host` and\n * `X-Forwarded-Prefix` should ideally be strictly validated at a higher infrastructure\n * level (e.g., at the reverse proxy or API gateway) before reaching the application.\n *\n * @returns A Web Standard `Request` object.\n */\nexport function createWebRequestFromNodeRequest(\n nodeRequest: IncomingMessage | Http2ServerRequest,\n trustProxyHeaders?: boolean | readonly string[],\n): Request {\n const trustProxyHeadersNormalized = normalizeTrustProxyHeaders(trustProxyHeaders);\n const { headers, method = 'GET' } = nodeRequest;\n const withBody = method !== 'GET' && method !== 'HEAD';\n const referrer = headers.referer && URL.canParse(headers.referer) ? headers.referer : undefined;\n\n return new Request(createRequestUrl(nodeRequest, trustProxyHeadersNormalized), {\n method,\n headers: createRequestHeaders(headers),\n body: withBody ? nodeRequest : undefined,\n duplex: withBody ? 'half' : undefined,\n referrer,\n });\n}\n\n/**\n * Creates a `Headers` object from Node.js `IncomingHttpHeaders`.\n *\n * @param nodeHeaders - The Node.js `IncomingHttpHeaders` object to convert.\n * @returns A `Headers` object containing the converted headers.\n */\nfunction createRequestHeaders(nodeHeaders: IncomingHttpHeaders): Headers {\n const headers = new Headers();\n\n for (const [name, value] of Object.entries(nodeHeaders)) {\n if (HTTP2_PSEUDO_HEADERS.has(name)) {\n continue;\n }\n\n if (typeof value === 'string') {\n headers.append(name, value);\n } else if (Array.isArray(value)) {\n for (const item of value) {\n headers.append(name, item);\n }\n }\n }\n\n return headers;\n}\n\n/**\n * Creates a `URL` object from a Node.js `IncomingMessage`, taking into account the protocol, host, and port.\n *\n * @param nodeRequest - The Node.js `IncomingMessage` or `Http2ServerRequest` object to extract URL information from.\n * @param trustProxyHeaders - A set of allowed proxy headers.\n *\n * @remarks\n * When `trustProxyHeaders` is enabled, headers such as `X-Forwarded-Host` and\n * `X-Forwarded-Prefix` should ideally be strictly validated at a higher infrastructure\n * level (e.g., at the reverse proxy or API gateway) before reaching the application.\n *\n * @returns A `URL` object representing the request URL.\n */\nexport function createRequestUrl(\n nodeRequest: IncomingMessage | Http2ServerRequest,\n trustProxyHeaders: ReadonlySet<string>,\n): URL {\n const {\n headers,\n socket,\n url = '',\n originalUrl,\n } = nodeRequest as IncomingMessage & { originalUrl?: string };\n\n const protocol =\n getAllowedProxyHeaderValue(headers, 'x-forwarded-proto', trustProxyHeaders) ??\n ('encrypted' in socket && socket.encrypted ? 'https' : 'http');\n\n const hostname =\n getAllowedProxyHeaderValue(headers, 'x-forwarded-host', trustProxyHeaders) ??\n headers.host ??\n headers[':authority'];\n\n if (Array.isArray(hostname)) {\n throw new Error('host value cannot be an array.');\n }\n\n let hostnameWithPort = hostname;\n if (!hostname?.includes(':')) {\n const port = getAllowedProxyHeaderValue(headers, 'x-forwarded-port', trustProxyHeaders);\n if (port) {\n hostnameWithPort += `:${port}`;\n }\n }\n\n return new URL(`${protocol}://${hostnameWithPort}${originalUrl ?? url}`);\n}\n\n/**\n * Gets the first value of an allowed proxy header.\n *\n * @param headers - The Node.js incoming HTTP headers.\n * @param headerName - The name of the proxy header to retrieve.\n * @param trustProxyHeaders - A set of allowed proxy headers.\n * @returns The value of the allowed proxy header, or `undefined` if not allowed or not present.\n */\nfunction getAllowedProxyHeaderValue(\n headers: IncomingHttpHeaders,\n headerName: string,\n trustProxyHeaders: ReadonlySet<string>,\n): string | undefined {\n return isProxyHeaderAllowed(headerName, trustProxyHeaders)\n ? getFirstHeaderValue(headers[headerName])\n : undefined;\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.dev/license\n */\n\nimport { AngularAppEngine } from '@angular/ssr';\nimport type { IncomingMessage } from 'node:http';\nimport type { Http2ServerRequest } from 'node:http2';\nimport { AngularAppEngineOptions } from '../../src/app-engine';\nimport { getAllowedHostsFromEnv, getTrustProxyHeadersFromEnv } from './environment-options';\nimport { attachNodeGlobalErrorHandlers } from './errors';\nimport { createWebRequestFromNodeRequest } from './request';\n\n/**\n * Options for the Angular Node.js server application engine.\n */\nexport interface AngularNodeAppEngineOptions extends AngularAppEngineOptions {}\n\n/**\n * Angular server application engine.\n * Manages Angular server applications (including localized ones), handles rendering requests,\n * and optionally transforms index HTML before rendering.\n *\n * @remarks This class should be instantiated once and used as a singleton across the server-side\n * application to ensure consistent handling of rendering requests and resource management.\n */\nexport class AngularNodeAppEngine {\n private readonly angularAppEngine: AngularAppEngine;\n private readonly trustProxyHeaders?: boolean | readonly string[];\n\n /**\n * Creates a new instance of the Angular Node.js server application engine.\n * @param options Options for the Angular Node.js server application engine.\n */\n constructor(options?: AngularNodeAppEngineOptions) {\n const appEngineOptions: AngularAppEngineOptions = {\n ...options,\n allowedHosts: options?.allowedHosts ?? getAllowedHostsFromEnv(),\n trustProxyHeaders: options?.trustProxyHeaders ?? getTrustProxyHeadersFromEnv(),\n };\n\n this.angularAppEngine = new AngularAppEngine(appEngineOptions);\n this.trustProxyHeaders = appEngineOptions.trustProxyHeaders;\n\n attachNodeGlobalErrorHandlers();\n }\n\n /**\n * Handles an incoming HTTP request by serving prerendered content, performing server-side rendering,\n * or delivering a static file for client-side rendered routes based on the `RenderMode` setting.\n *\n * This method adapts Node.js's `IncomingMessage`, `Http2ServerRequest` or `Request`\n * to a format compatible with the `AngularAppEngine` and delegates the handling logic to it.\n *\n * @param request - The incoming HTTP request (`IncomingMessage`, `Http2ServerRequest` or `Request`).\n * @param requestContext - Optional context for rendering, such as metadata associated with the request.\n * @returns A promise that resolves to the resulting HTTP response object, or `null` if no matching Angular route is found.\n *\n * @remarks A request to `https://www.example.com/page/index.html` will serve or render the Angular route\n * corresponding to `https://www.example.com/page`.\n *\n * @remarks\n * To prevent potential Server-Side Request Forgery (SSRF), this function verifies the hostname\n * of the `request.url` against a list of authorized hosts.\n * If the hostname is not recognized and `allowedHosts` is not empty, a Client-Side Rendered (CSR) version of the\n * page is returned otherwise a 400 Bad Request is returned.\n *\n * Resolution:\n * Authorize your hostname by configuring `allowedHosts` in `angular.json` in:\n * `projects.[project-name].architect.build.options.security.allowedHosts`.\n * Alternatively, you can define the allowed hostname via the environment variable `process.env['NG_ALLOWED_HOSTS']`\n * or pass it directly through the configuration options of `AngularNodeAppEngine`.\n *\n * For more information see: https://angular.dev/best-practices/security#preventing-server-side-request-forgery-ssrf\n */\n async handle(\n request: IncomingMessage | Http2ServerRequest | Request,\n requestContext?: unknown,\n ): Promise<Response | null> {\n const webRequest =\n request instanceof Request\n ? request\n : createWebRequestFromNodeRequest(request, this.trustProxyHeaders);\n\n return this.angularAppEngine.handle(webRequest, requestContext);\n }\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.dev/license\n */\n\nimport type { IncomingMessage, ServerResponse } from 'node:http';\n\n/**\n * Represents a middleware function for handling HTTP requests in a Node.js environment.\n *\n * @param req - The incoming HTTP request object.\n * @param res - The outgoing HTTP response object.\n * @param next - A callback function that signals the completion of the middleware or forwards the error if provided.\n *\n * @returns A Promise that resolves to void or simply void. The handler can be asynchronous.\n */\nexport type NodeRequestHandlerFunction = (\n req: IncomingMessage,\n res: ServerResponse,\n next: (err?: unknown) => void,\n) => Promise<void> | void;\n\n/**\n * Attaches metadata to the handler function to mark it as a special handler for Node.js environments.\n *\n * @typeParam T - The type of the handler function.\n * @param handler - The handler function to be defined and annotated.\n * @returns The same handler function passed as an argument, with metadata attached.\n *\n * @example\n * Usage in an Express application:\n * ```ts\n * const app = express();\n * export default createNodeRequestHandler(app);\n * ```\n *\n * @example\n * Usage in a Hono application:\n * ```ts\n * const app = new Hono();\n * export default createNodeRequestHandler(async (req, res, next) => {\n * try {\n * const webRes = await app.fetch(createWebRequestFromNodeRequest(req));\n * if (webRes) {\n * await writeResponseToNodeResponse(webRes, res);\n * } else {\n * next();\n * }\n * } catch (error) {\n * next(error);\n * }\n * });\n * ```\n *\n * @example\n * Usage in a Fastify application:\n * ```ts\n * const app = Fastify();\n * export default createNodeRequestHandler(async (req, res) => {\n * await app.ready();\n * app.server.emit('request', req, res);\n * });\n * ```\n */\nexport function createNodeRequestHandler<T extends NodeRequestHandlerFunction>(handler: T): T {\n (handler as T & { __ng_node_request_handler__?: boolean })['__ng_node_request_handler__'] = true;\n\n return handler;\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.dev/license\n */\n\nimport type { ServerResponse } from 'node:http';\nimport type { Http2ServerResponse } from 'node:http2';\n\n/**\n * Streams a web-standard `Response` into a Node.js `ServerResponse`\n * or `Http2ServerResponse`.\n *\n * This function adapts the web `Response` object to write its content\n * to a Node.js response object, handling both HTTP/1.1 and HTTP/2.\n *\n * @param source - The web-standard `Response` object to stream from.\n * @param destination - The Node.js response object (`ServerResponse` or `Http2ServerResponse`) to stream into.\n * @returns A promise that resolves once the streaming operation is complete.\n */\nexport async function writeResponseToNodeResponse(\n source: Response,\n destination: ServerResponse | Http2ServerResponse,\n): Promise<void> {\n const { status, headers, body } = source;\n destination.statusCode = status;\n\n let cookieHeaderSet = false;\n for (const [name, value] of headers.entries()) {\n if (name === 'set-cookie') {\n if (cookieHeaderSet) {\n continue;\n }\n\n // Sets the 'set-cookie' header only once to ensure it is correctly applied.\n // Concatenating 'set-cookie' values can lead to incorrect behavior, so we use a single value from `headers.getSetCookie()`.\n destination.setHeader(name, headers.getSetCookie());\n cookieHeaderSet = true;\n } else {\n destination.setHeader(name, value);\n }\n }\n\n if ('flushHeaders' in destination) {\n destination.flushHeaders();\n }\n\n if (!body) {\n destination.end();\n\n return;\n }\n\n try {\n const reader = body.getReader();\n\n destination.on('close', () => {\n reader.cancel().catch((error) => {\n // eslint-disable-next-line no-console\n console.error(\n `An error occurred while writing the response body for: ${destination.req.url}.`,\n error,\n );\n });\n });\n\n // eslint-disable-next-line no-constant-condition\n while (true) {\n const { done, value } = await reader.read();\n if (done) {\n destination.end();\n break;\n }\n\n const canContinue = (destination as ServerResponse).write(value);\n if (canContinue === false) {\n // Explicitly check for `false`, as AWS may return `undefined` even though this is not valid.\n // See: https://github.com/CodeGenieApp/serverless-express/issues/683\n await new Promise<void>((resolve) => destination.once('drain', resolve));\n }\n }\n } catch {\n destination.end('Internal server error.');\n }\n}\n","/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.dev/license\n */\n\nimport { argv } from 'node:process';\nimport { fileURLToPath } from 'node:url';\n\n/**\n * Determines whether the provided URL represents the main entry point module.\n *\n * This function checks if the provided URL corresponds to the main ESM module being executed directly.\n * It's useful for conditionally executing code that should only run when a module is the entry point,\n * such as starting a server or initializing an application.\n *\n * It performs two key checks:\n * 1. Verifies if the URL starts with 'file:', ensuring it is a local file.\n * 2. Compares the URL's resolved file path with the first command-line argument (`process.argv[1]`),\n * which points to the file being executed.\n *\n * @param url The URL of the module to check. This should typically be `import.meta.url`.\n * @returns `true` if the provided URL represents the main entry point, otherwise `false`.\n */\nexport function isMainModule(url: string): boolean {\n return url.startsWith('file:') && argv[1] === fileURLToPath(url);\n}\n"],"names":["InlineCriticalCssProcessor","URL","ɵSERVER_CONTEXT"],"mappings":"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"}

@@ -1,1 +0,1 @@

{"version":3,"file":"validation.mjs","sources":["../../../../../../k8-fastbuild-ST-199a4f3c4e20/bin/packages/angular/ssr/src/utils/validation.ts"],"sourcesContent":["/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.dev/license\n */\n\n/**\n * Common X-Forwarded-* headers.\n */\nconst X_FORWARDED_HEADERS = new Set([\n 'x-forwarded-for',\n 'x-forwarded-host',\n 'x-forwarded-port',\n 'x-forwarded-proto',\n 'x-forwarded-prefix',\n]);\n\n/**\n * The set of headers that should be validated for host header injection attacks.\n */\nconst HOST_HEADERS_TO_VALIDATE: ReadonlyArray<string> = ['host', 'x-forwarded-host'];\n\n/**\n * Regular expression to validate that the port is a numeric value.\n */\nconst VALID_PORT_REGEX = /^\\d+$/;\n\n/**\n * Regular expression to validate that the protocol is either http or https (case-insensitive).\n */\nconst VALID_PROTO_REGEX = /^https?$/i;\n\n/**\n * Regular expression to validate that the prefix is valid.\n */\nconst VALID_PREFIX_REGEX = /^\\/([a-z0-9_-]+\\/)*[a-z0-9_-]*$/i;\n\n/**\n * Extracts the first value from a multi-value header string.\n *\n * @param value - A string or an array of strings representing the header values.\n * If it's a string, values are expected to be comma-separated.\n * @returns The first trimmed value from the multi-value header, or `undefined` if the input is invalid or empty.\n *\n * @example\n * ```typescript\n * getFirstHeaderValue(\"value1, value2, value3\"); // \"value1\"\n * getFirstHeaderValue([\"value1\", \"value2\"]); // \"value1\"\n * getFirstHeaderValue(undefined); // undefined\n * ```\n */\nexport function getFirstHeaderValue(\n value: string | string[] | undefined | null,\n): string | undefined {\n return value?.toString().split(',', 1)[0]?.trim();\n}\n\n/**\n * Validates a request.\n *\n * @param request - The incoming `Request` object to validate.\n * @param allowedHosts - A set of allowed hostnames.\n * @throws Error if any of the validated headers contain invalid values.\n */\nexport function validateRequest(\n request: Request,\n allowedHosts: ReadonlySet<string>,\n disableHostCheck: boolean,\n): void {\n validateHeaders(request, allowedHosts, disableHostCheck);\n\n if (!disableHostCheck) {\n validateUrl(new URL(request.url), allowedHosts);\n }\n}\n\n/**\n * Validates that the hostname of a given URL is allowed.\n *\n * @param url - The URL object to validate.\n * @param allowedHosts - A set of allowed hostnames.\n * @throws Error if the hostname is not in the allowlist.\n */\nexport function validateUrl(url: URL, allowedHosts: ReadonlySet<string>): void {\n const { hostname } = url;\n if (!isHostAllowed(hostname, allowedHosts)) {\n throw new Error(`URL with hostname \"${hostname}\" is not allowed.`);\n }\n}\n\n/**\n * Sanitizes the proxy headers of a request by removing unallowed `X-Forwarded-*` headers.\n * If no headers need to be removed, the original request is returned without cloning.\n *\n * @param request - The incoming `Request` object to sanitize.\n * @param trustProxyHeaders - A set of allowed proxy headers.\n * @returns An object containing the sanitized request, or the original request if no changes were needed.\n */\nexport function sanitizeRequestHeaders(\n request: Request,\n trustProxyHeaders: ReadonlySet<string>,\n): { request: Request; deoptToCSR: boolean } {\n const keysToDelete: string[] = [];\n let deoptToCSR = false;\n\n for (const [key] of request.headers) {\n const lowerKey = key.toLowerCase();\n if (lowerKey.startsWith('x-forwarded-') && !isProxyHeaderAllowed(lowerKey, trustProxyHeaders)) {\n // eslint-disable-next-line no-console\n console.warn(\n `Received \"${key}\" header but \"trustProxyHeaders\" was not set up to allow it.\\n` +\n `For more information, see https://angular.dev/best-practices/security#configuring-trusted-proxy-headers`,\n );\n deoptToCSR = true;\n keysToDelete.push(key);\n }\n }\n\n if (keysToDelete.length === 0) {\n return { request, deoptToCSR };\n }\n\n const clonedReq = new Request(request.clone(), {\n signal: request.signal,\n });\n\n const headers = clonedReq.headers;\n for (const key of keysToDelete) {\n headers.delete(key);\n }\n\n return { request: clonedReq, deoptToCSR };\n}\n\n/**\n * Validates a specific host header value against the allowed hosts.\n *\n * @param headerName - The name of the header to validate (e.g., 'host', 'x-forwarded-host').\n * @param headerValue - The value of the header to validate.\n * @param allowedHosts - A set of allowed hostnames.\n * @throws Error if the header value is invalid or the hostname is not in the allowlist.\n */\nfunction verifyHostAllowed(\n headerName: string,\n headerValue: string,\n allowedHosts: ReadonlySet<string>,\n): void {\n const url = `http://${headerValue}`;\n if (!URL.canParse(url)) {\n throw new Error(`Header \"${headerName}\" contains an invalid value and cannot be parsed.`);\n }\n\n const { hostname, pathname, search, hash, username, password } = new URL(url);\n if (pathname !== '/' || search || hash || username || password) {\n throw new Error(\n `Header \"${headerName}\" with value \"${headerValue}\" contains characters that are not allowed.`,\n );\n }\n\n if (!isHostAllowed(hostname, allowedHosts)) {\n throw new Error(`Header \"${headerName}\" with value \"${headerValue}\" is not allowed.`);\n }\n}\n\n/**\n * Checks if the hostname is allowed.\n * @param hostname - The hostname to check.\n * @param allowedHosts - A set of allowed hostnames.\n * @returns `true` if the hostname is allowed, `false` otherwise.\n */\nfunction isHostAllowed(hostname: string, allowedHosts: ReadonlySet<string>): boolean {\n if (allowedHosts.has(hostname)) {\n return true;\n }\n\n for (const allowedHost of allowedHosts) {\n if (!allowedHost.startsWith('*.')) {\n continue;\n }\n\n const domain = allowedHost.slice(1);\n if (hostname.endsWith(domain)) {\n return true;\n }\n }\n\n return false;\n}\n\n/**\n * Validates the headers of an incoming request.\n *\n * @param request - The incoming `Request` object containing the headers to validate.\n * @param allowedHosts - A set of allowed hostnames.\n * @param disableHostCheck - Whether to disable the host check.\n * @throws Error if any of the validated headers contain invalid values.\n */\nfunction validateHeaders(\n request: Request,\n allowedHosts: ReadonlySet<string>,\n disableHostCheck: boolean,\n): void {\n const headers = request.headers;\n for (const headerName of HOST_HEADERS_TO_VALIDATE) {\n const headerValue = getFirstHeaderValue(headers.get(headerName));\n if (headerValue && !disableHostCheck) {\n verifyHostAllowed(headerName, headerValue, allowedHosts);\n }\n }\n\n const xForwardedPort = getFirstHeaderValue(headers.get('x-forwarded-port'));\n if (xForwardedPort && !VALID_PORT_REGEX.test(xForwardedPort)) {\n throw new Error('Header \"x-forwarded-port\" must be a numeric value.');\n }\n\n const xForwardedProto = getFirstHeaderValue(headers.get('x-forwarded-proto'));\n if (xForwardedProto && !VALID_PROTO_REGEX.test(xForwardedProto)) {\n throw new Error('Header \"x-forwarded-proto\" must be either \"http\" or \"https\".');\n }\n\n const xForwardedPrefix = getFirstHeaderValue(headers.get('x-forwarded-prefix'));\n if (xForwardedPrefix && !VALID_PREFIX_REGEX.test(xForwardedPrefix)) {\n throw new Error(\n 'Header \"x-forwarded-prefix\" is invalid. It must start with a \"/\" and contain ' +\n 'only alphanumeric characters, hyphens, and underscores, separated by single slashes.',\n );\n }\n}\n\n/**\n * Checks if a specific proxy header is allowed.\n *\n * @param headerName - The name of the proxy header to check.\n * @param trustProxyHeaders - A set of allowed proxy headers.\n * @returns `true` if the header is allowed, `false` otherwise.\n */\nexport function isProxyHeaderAllowed(\n headerName: string,\n trustProxyHeaders: ReadonlySet<string>,\n): boolean {\n return trustProxyHeaders.has(headerName.toLowerCase());\n}\n\n/**\n * Normalizes the `trustProxyHeaders` option to a consistent representation.\n * @param trustProxyHeaders The input `trustProxyHeaders` value.\n * @returns A `Set<string>` of normalized header names.\n */\nexport function normalizeTrustProxyHeaders(\n trustProxyHeaders: boolean | readonly string[] | undefined,\n): ReadonlySet<string> {\n if (trustProxyHeaders === undefined) {\n return new Set(['x-forwarded-host', 'x-forwarded-proto']);\n }\n\n if (trustProxyHeaders === false) {\n return new Set();\n }\n\n if (trustProxyHeaders === true) {\n return X_FORWARDED_HEADERS;\n }\n\n return new Set(trustProxyHeaders.map((h) => h.toLowerCase()));\n}\n"],"names":[],"mappings":"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"}
{"version":3,"file":"validation.mjs","sources":["../../../../../../darwin_arm64-fastbuild-ST-199a4f3c4e20/bin/packages/angular/ssr/src/utils/validation.ts"],"sourcesContent":["/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.dev/license\n */\n\n/**\n * Common X-Forwarded-* headers.\n */\nconst X_FORWARDED_HEADERS = new Set([\n 'x-forwarded-for',\n 'x-forwarded-host',\n 'x-forwarded-port',\n 'x-forwarded-proto',\n 'x-forwarded-prefix',\n]);\n\n/**\n * The set of headers that should be validated for host header injection attacks.\n */\nconst HOST_HEADERS_TO_VALIDATE: ReadonlyArray<string> = ['host', 'x-forwarded-host'];\n\n/**\n * Regular expression to validate that the port is a numeric value.\n */\nconst VALID_PORT_REGEX = /^\\d+$/;\n\n/**\n * Regular expression to validate that the protocol is either http or https (case-insensitive).\n */\nconst VALID_PROTO_REGEX = /^https?$/i;\n\n/**\n * Regular expression to validate that the prefix is valid.\n */\nconst VALID_PREFIX_REGEX = /^\\/([a-z0-9_-]+\\/)*[a-z0-9_-]*$/i;\n\n/**\n * Extracts the first value from a multi-value header string.\n *\n * @param value - A string or an array of strings representing the header values.\n * If it's a string, values are expected to be comma-separated.\n * @returns The first trimmed value from the multi-value header, or `undefined` if the input is invalid or empty.\n *\n * @example\n * ```typescript\n * getFirstHeaderValue(\"value1, value2, value3\"); // \"value1\"\n * getFirstHeaderValue([\"value1\", \"value2\"]); // \"value1\"\n * getFirstHeaderValue(undefined); // undefined\n * ```\n */\nexport function getFirstHeaderValue(\n value: string | string[] | undefined | null,\n): string | undefined {\n return value?.toString().split(',', 1)[0]?.trim();\n}\n\n/**\n * Validates a request.\n *\n * @param request - The incoming `Request` object to validate.\n * @param allowedHosts - A set of allowed hostnames.\n * @throws Error if any of the validated headers contain invalid values.\n */\nexport function validateRequest(\n request: Request,\n allowedHosts: ReadonlySet<string>,\n disableHostCheck: boolean,\n): void {\n validateHeaders(request, allowedHosts, disableHostCheck);\n\n if (!disableHostCheck) {\n validateUrl(new URL(request.url), allowedHosts);\n }\n}\n\n/**\n * Validates that the hostname of a given URL is allowed.\n *\n * @param url - The URL object to validate.\n * @param allowedHosts - A set of allowed hostnames.\n * @throws Error if the hostname is not in the allowlist.\n */\nexport function validateUrl(url: URL, allowedHosts: ReadonlySet<string>): void {\n const { hostname } = url;\n if (!isHostAllowed(hostname, allowedHosts)) {\n throw new Error(`URL with hostname \"${hostname}\" is not allowed.`);\n }\n}\n\n/**\n * Sanitizes the proxy headers of a request by removing unallowed `X-Forwarded-*` headers.\n * If no headers need to be removed, the original request is returned without cloning.\n *\n * @param request - The incoming `Request` object to sanitize.\n * @param trustProxyHeaders - A set of allowed proxy headers.\n * @returns An object containing the sanitized request, or the original request if no changes were needed.\n */\nexport function sanitizeRequestHeaders(\n request: Request,\n trustProxyHeaders: ReadonlySet<string>,\n): { request: Request; deoptToCSR: boolean } {\n const keysToDelete: string[] = [];\n let deoptToCSR = false;\n\n for (const [key] of request.headers) {\n const lowerKey = key.toLowerCase();\n if (lowerKey.startsWith('x-forwarded-') && !isProxyHeaderAllowed(lowerKey, trustProxyHeaders)) {\n // eslint-disable-next-line no-console\n console.warn(\n `Received \"${key}\" header but \"trustProxyHeaders\" was not set up to allow it.\\n` +\n `For more information, see https://angular.dev/best-practices/security#configuring-trusted-proxy-headers`,\n );\n deoptToCSR = true;\n keysToDelete.push(key);\n }\n }\n\n if (keysToDelete.length === 0) {\n return { request, deoptToCSR };\n }\n\n const clonedReq = new Request(request.clone(), {\n signal: request.signal,\n });\n\n const headers = clonedReq.headers;\n for (const key of keysToDelete) {\n headers.delete(key);\n }\n\n return { request: clonedReq, deoptToCSR };\n}\n\n/**\n * Validates a specific host header value against the allowed hosts.\n *\n * @param headerName - The name of the header to validate (e.g., 'host', 'x-forwarded-host').\n * @param headerValue - The value of the header to validate.\n * @param allowedHosts - A set of allowed hostnames.\n * @throws Error if the header value is invalid or the hostname is not in the allowlist.\n */\nfunction verifyHostAllowed(\n headerName: string,\n headerValue: string,\n allowedHosts: ReadonlySet<string>,\n): void {\n const url = `http://${headerValue}`;\n if (!URL.canParse(url)) {\n throw new Error(`Header \"${headerName}\" contains an invalid value and cannot be parsed.`);\n }\n\n const { hostname, pathname, search, hash, username, password } = new URL(url);\n if (pathname !== '/' || search || hash || username || password) {\n throw new Error(\n `Header \"${headerName}\" with value \"${headerValue}\" contains characters that are not allowed.`,\n );\n }\n\n if (!isHostAllowed(hostname, allowedHosts)) {\n throw new Error(`Header \"${headerName}\" with value \"${headerValue}\" is not allowed.`);\n }\n}\n\n/**\n * Checks if the hostname is allowed.\n * @param hostname - The hostname to check.\n * @param allowedHosts - A set of allowed hostnames.\n * @returns `true` if the hostname is allowed, `false` otherwise.\n */\nfunction isHostAllowed(hostname: string, allowedHosts: ReadonlySet<string>): boolean {\n if (allowedHosts.has(hostname)) {\n return true;\n }\n\n for (const allowedHost of allowedHosts) {\n if (!allowedHost.startsWith('*.')) {\n continue;\n }\n\n const domain = allowedHost.slice(1);\n if (hostname.endsWith(domain)) {\n return true;\n }\n }\n\n return false;\n}\n\n/**\n * Validates the headers of an incoming request.\n *\n * @param request - The incoming `Request` object containing the headers to validate.\n * @param allowedHosts - A set of allowed hostnames.\n * @param disableHostCheck - Whether to disable the host check.\n * @throws Error if any of the validated headers contain invalid values.\n */\nfunction validateHeaders(\n request: Request,\n allowedHosts: ReadonlySet<string>,\n disableHostCheck: boolean,\n): void {\n const headers = request.headers;\n for (const headerName of HOST_HEADERS_TO_VALIDATE) {\n const headerValue = getFirstHeaderValue(headers.get(headerName));\n if (headerValue && !disableHostCheck) {\n verifyHostAllowed(headerName, headerValue, allowedHosts);\n }\n }\n\n const xForwardedPort = getFirstHeaderValue(headers.get('x-forwarded-port'));\n if (xForwardedPort && !VALID_PORT_REGEX.test(xForwardedPort)) {\n throw new Error('Header \"x-forwarded-port\" must be a numeric value.');\n }\n\n const xForwardedProto = getFirstHeaderValue(headers.get('x-forwarded-proto'));\n if (xForwardedProto && !VALID_PROTO_REGEX.test(xForwardedProto)) {\n throw new Error('Header \"x-forwarded-proto\" must be either \"http\" or \"https\".');\n }\n\n const xForwardedPrefix = getFirstHeaderValue(headers.get('x-forwarded-prefix'));\n if (xForwardedPrefix && !VALID_PREFIX_REGEX.test(xForwardedPrefix)) {\n throw new Error(\n 'Header \"x-forwarded-prefix\" is invalid. It must start with a \"/\" and contain ' +\n 'only alphanumeric characters, hyphens, and underscores, separated by single slashes.',\n );\n }\n}\n\n/**\n * Checks if a specific proxy header is allowed.\n *\n * @param headerName - The name of the proxy header to check.\n * @param trustProxyHeaders - A set of allowed proxy headers.\n * @returns `true` if the header is allowed, `false` otherwise.\n */\nexport function isProxyHeaderAllowed(\n headerName: string,\n trustProxyHeaders: ReadonlySet<string>,\n): boolean {\n return trustProxyHeaders.has(headerName.toLowerCase());\n}\n\n/**\n * Normalizes the `trustProxyHeaders` option to a consistent representation.\n * @param trustProxyHeaders The input `trustProxyHeaders` value.\n * @returns A `Set<string>` of normalized header names.\n */\nexport function normalizeTrustProxyHeaders(\n trustProxyHeaders: boolean | readonly string[] | undefined,\n): ReadonlySet<string> {\n if (trustProxyHeaders === undefined) {\n return new Set(['x-forwarded-host', 'x-forwarded-proto']);\n }\n\n if (trustProxyHeaders === false) {\n return new Set();\n }\n\n if (trustProxyHeaders === true) {\n return X_FORWARDED_HEADERS;\n }\n\n return new Set(trustProxyHeaders.map((h) => h.toLowerCase()));\n}\n"],"names":[],"mappings":"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"}
{
"name": "@angular/ssr",
"version": "20.3.28",
"version": "20.3.29",
"description": "Angular server side rendering utilities",

@@ -5,0 +5,0 @@ "type": "module",

Sorry, the diff of this file is too big to display