Skip to content

fix: generate default allowedHosts with available variables instead of skipping all due to a single missing one#441

Merged
hrishikesh-k merged 45 commits into
mainfrom
hk/angular-22
May 26, 2026
Merged

fix: generate default allowedHosts with available variables instead of skipping all due to a single missing one#441
hrishikesh-k merged 45 commits into
mainfrom
hk/angular-22

Conversation

@hrishikesh-k
Copy link
Copy Markdown
Contributor

@hrishikesh-k hrishikesh-k commented May 25, 2026

From Angular 22 (specifically 22.0.0-next.0, an incorrect host will skip falling back to CSR. It will return HTTP 400. Someone could be using a proxy or might need to specify non-Netlify-specific hosts, or even maybe a specific hostname that we cannot add by default. This PR changes the following:

  • allows specifying a custom allowedHosts list
  • allows skipping the default allowedHosts config (automatically skipped when custom allowedHosts includes *)
  • fixed redundant condition for env[environmentVariable] === 'undefined' (it was getting swallowed by !env[environmentVariable])
  • instead of skipping all default allowedHosts for even a single missing variable, we now skip only the ones that are missing - the rest get added
  • check if a variable is a valid URL to prevent build-time/runtime errors
  • remove duplicates using Set
  • add JSDoc comments
  • allow configuring trustProxyHeaders as well, users can now either specify an additional trust proxy headers list or trust all proxy headers

@hrishikesh-k hrishikesh-k requested a review from a team as a code owner May 25, 2026 18:02
@netlify
Copy link
Copy Markdown

netlify Bot commented May 25, 2026

Deploy Preview for angular-runtime-demo ready!

Name Link
🔨 Latest commit 13bb97a
🔍 Latest deploy log https://app.netlify.com/projects/angular-runtime-demo/deploys/6a1576ad1e6d050008397346
😎 Deploy Preview https://deploy-preview-441--angular-runtime-demo.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 25, 2026

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

The PR refactors getAllowedHosts to conditionally generate Netlify-derived default hostnames without requiring all environment variables to be present upfront. It introduces two helper functions that validate environment values (warning and skipping when missing, empty, or the literal string "undefined") and safely extract hostnames from URL-shaped values. The main function now iterates over relevant Netlify environment variable names, conditionally adds *.netlify.app patterns, ADS-style hostname variants with --, and <deploy-id>--<site-id>.netlify.app combinations only when their required components exist, then deduplicates the final list before returning.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • netlify/angular-runtime#427: Adds getAllowedHosts() in src/app-engine-config.js to auto-generate default allowed hosts values alongside this refactor to the core function in src/app-engine.js.

Suggested reviewers

  • pieh
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description check ✅ Passed The PR description is directly related to the changeset, detailing specific modifications to how allowedHosts are handled and validated in the app-engine.js file.
Title check ✅ Passed The title accurately summarizes the main change: fixing the allowedHosts generation logic to use available variables instead of failing entirely when one is missing.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch hk/angular-22

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
src/app-engine.js (1)

93-98: ⚡ Quick win

Reduce repeated warning noise for expected missing env vars.

This can emit multiple warnings per call in non-Netlify/local contexts where missing vars are expected. Consider aggregating missing variables and logging once per invocation (or once per process) to keep logs actionable.

Proposed change
 function getEnvironmentVariable(environmentVariable) {
   const value = env[environmentVariable]

   // we inject the literal string "undefined" for variables that don't have a value
   if (value == null || value === '' || value === 'undefined') {
-    console.warn(
-      `Missing Netlify-specific environment variable ${environmentVariable}. ` +
-        '`allowedHosts` config might be incomplete.',
-    )
+    missingNetlifyEnvVars.add(environmentVariable)
     return
   }

   return value
 }
+
+const missingNetlifyEnvVars = new Set()
+let hasWarnedForMissingEnvVars = false
+
+function warnMissingNetlifyEnvVarsOnce() {
+  if (hasWarnedForMissingEnvVars || missingNetlifyEnvVars.size === 0) return
+  hasWarnedForMissingEnvVars = true
+  console.warn(
+    `Missing Netlify-specific environment variables: ${[...missingNetlifyEnvVars].join(', ')}. ` +
+      '`allowedHosts` config might be incomplete.',
+  )
+}
 export function getAllowedHosts({ allowedHosts = [], injectDefaults = true } = {}) {
   if (!injectDefaults) {
     return [...new Set(allowedHosts)]
   }

   const defaultAllowedHosts = []
@@
   if (deployId && siteId) {
@@
   }
+
+  warnMissingNetlifyEnvVarsOnce()

   return [...new Set([...defaultAllowedHosts, ...allowedHosts])]
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/app-engine.js` around lines 93 - 98, The current per-variable
console.warn (checking value, environmentVariable and `'undefined'`) causes
noisy repeated warnings; change this to aggregate missing environmentVariable
names into a single list and emit one consolidated warning instead (either once
per invocation or persist a module-level Set like missingEnvLogged to ensure
each missing var is logged only once per process). Locate the block referencing
value and environmentVariable in src/app-engine.js, collect the variables that
meet the existing condition (value == null || value === '' || value ===
'undefined') into an array/Set, and replace the per-item console.warn with a
single console.warn that lists the aggregated names and the same message text.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@src/app-engine.js`:
- Around line 93-98: The current per-variable console.warn (checking value,
environmentVariable and `'undefined'`) causes noisy repeated warnings; change
this to aggregate missing environmentVariable names into a single list and emit
one consolidated warning instead (either once per invocation or persist a
module-level Set like missingEnvLogged to ensure each missing var is logged only
once per process). Locate the block referencing value and environmentVariable in
src/app-engine.js, collect the variables that meet the existing condition (value
== null || value === '' || value === 'undefined') into an array/Set, and replace
the per-item console.warn with a single console.warn that lists the aggregated
names and the same message text.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: bb75ffc8-e17a-4cfb-9e14-67c41722a02c

📥 Commits

Reviewing files that changed from the base of the PR and between 234bc30 and e66d9ea.

📒 Files selected for processing (2)
  • src/app-engine.d.ts
  • src/app-engine.js

@hrishikesh-k hrishikesh-k changed the title allow passing custom allowedHosts feat: allow passing custom allowedHosts May 25, 2026
@github-actions github-actions Bot added the type: feature code contributing to the implementation of a feature and/or user facing functionality label May 25, 2026
@hrishikesh-k hrishikesh-k changed the title feat: allow passing custom allowedHosts feat: allow passing custom allowedHosts and trustProxyHeaders May 25, 2026
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/app-engine.d.ts`:
- Around line 8-16: Update the TypeScript declaration for getTrustProxyHeaders
to match runtime behavior: change its return type from string[] to boolean |
string[] so it can return true when trustAll is enabled; locate the
getTrustProxyHeaders declaration in the d.ts and adjust the signature to return
boolean | string[] while keeping the existing optional config overloads intact.

In `@src/app-engine.js`:
- Line 162: The Set construction in getTrustProxyHeaders is wrong: new
Set('x-forwarded-for', ...additionalTrustProxyHeaders) treats the string as
iterable and ignores additional args; replace it by creating the Set from a
single iterable array containing 'x-forwarded-for' and the spread
additionalTrustProxyHeaders (i.e., use new Set([...]) ), then return the array
form ([...theSet]) so duplicates are removed correctly; update the expression
that references additionalTrustProxyHeaders and getTrustProxyHeaders
accordingly.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 71cf33e7-6f75-41de-bd99-44fc65f8eb05

📥 Commits

Reviewing files that changed from the base of the PR and between 3e6508d and 27aa870.

📒 Files selected for processing (2)
  • src/app-engine.d.ts
  • src/app-engine.js

Comment thread src/app-engine.d.ts Outdated
Comment thread src/app-engine.js Outdated
Comment thread src/app-engine.d.ts Outdated
@hrishikesh-k hrishikesh-k changed the title feat: allow passing custom allowedHosts and trustProxyHeaders fix: generate default allowedHosts with available variables instead of skipping due to a single missing one May 26, 2026
@hrishikesh-k hrishikesh-k changed the title fix: generate default allowedHosts with available variables instead of skipping due to a single missing one fix: generate default allowedHosts with available variables instead of skipping all due to a single missing one May 26, 2026
@github-actions github-actions Bot added the type: bug code to address defects in shipped code label May 26, 2026
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/app-engine.js (1)

7-82: ⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

Expose caller-supplied allowedHosts here.

This helper now only returns Netlify-derived defaults, so there is still no way to pass a custom allowlist or honor the '*' skip-defaults behavior described in the PR. Because src/helpers/serverModuleHelpers.js:52-58 wires allowedHosts: getAllowedHosts() directly into AngularAppEngine, the new feature is unreachable from the generated server entrypoint.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/app-engine.js` around lines 7 - 82, getAllowedHosts currently only
returns Netlify-derived defaults, so caller-supplied allowedHosts or the '*'
skip-defaults flag never make it into AngularAppEngine; change getAllowedHosts
to accept a parameter (e.g. allowedHosts or options.allowedHosts) and handle
three cases: if the caller value === '*' return ['*']; if the caller provides an
array, merge it with the computed defaultAllowedHosts (preserving uniqueness) so
both custom and Netlify-derived hosts are included; otherwise behave as now.
Update the caller in serverModuleHelpers.js (where allowedHosts:
getAllowedHosts() is used) to pass through the provided allowedHosts so
AngularAppEngine receives the combined/overridden list.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/app-engine.js`:
- Around line 138-141: getTrustProxyHeaders() is currently hard-coded to return
['x-forwarded-for'], preventing callers from appending/overriding proxy headers
when constructing AngularAppEngine; change it to accept an optional input/config
(e.g., a parameter or read from process/env) and merge defaults with
caller-provided headers so serverModuleHelpers.js can pass through or extend the
list. Update the function signature getTrustProxyHeaders and the call site in
serverModuleHelpers.js where new AngularAppEngine({ trustProxyHeaders: ... }) is
used to supply the merged array (default plus any extra headers from
config/options/API), and ensure AngularAppEngine receives the final combined
list.

---

Outside diff comments:
In `@src/app-engine.js`:
- Around line 7-82: getAllowedHosts currently only returns Netlify-derived
defaults, so caller-supplied allowedHosts or the '*' skip-defaults flag never
make it into AngularAppEngine; change getAllowedHosts to accept a parameter
(e.g. allowedHosts or options.allowedHosts) and handle three cases: if the
caller value === '*' return ['*']; if the caller provides an array, merge it
with the computed defaultAllowedHosts (preserving uniqueness) so both custom and
Netlify-derived hosts are included; otherwise behave as now. Update the caller
in serverModuleHelpers.js (where allowedHosts: getAllowedHosts() is used) to
pass through the provided allowedHosts so AngularAppEngine receives the
combined/overridden list.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: da1b5e5a-ffcd-48c2-937e-1e310f05d0e9

📥 Commits

Reviewing files that changed from the base of the PR and between 0d7a751 and 13bb97a.

📒 Files selected for processing (1)
  • src/app-engine.js

Comment thread src/app-engine.js
@hrishikesh-k hrishikesh-k merged commit 2fccaf1 into main May 26, 2026
31 of 32 checks passed
@hrishikesh-k hrishikesh-k deleted the hk/angular-22 branch May 26, 2026 11:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

type: bug code to address defects in shipped code type: feature code contributing to the implementation of a feature and/or user facing functionality

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants