Skip to content

feat: allow loading configs from other sources - #2517

Open
minottic wants to merge 1 commit into
masterfrom
be_conf
Open

minottic wants to merge 1 commit into
masterfrom
be_conf

Conversation

@minottic

@minottic minottic commented Aug 31, 2026 •

Copy link
Copy Markdown
Member

Description

Short description of the pull request

Motivation

This provides a simpler implementation of #2290 (credits to @sbliven), cherry-picking the minimal changes required to enable loading confs from other sources. The additionalConfigs is an array resolved until length 3, all others are discarded. If a single value is preferred, this can also become a type string. An adopting facility can decide to discard the allowConfigOverrides option and manage everything in the additionalConfigs. Check the docs to have a more complete description

Tests included

  • Included for each change/fix?
  • Passing? (Merge will not be approved unless this is checked)

Documentation

  • swagger documentation updated [required]
  • official documentation updated [nice-to-have]

official documentation info

If you have updated the official documentation, please provide PR # and URL of the pages where the updates are included

Backend version

  • Does it require a specific version of the backend
  • which version of the backend is required:

@minottic
minottic requested a review from a team as a code owner August 31, 2026 13:39

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Hey - I've reviewed your changes and they look great!


Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@nitrosx

nitrosx commented Sep 10, 2026

Copy link
Copy Markdown
Member

Code Review Report: be_conf Branch Changes

Commit: 5d61034c0 feat: allow loading configs from other sources
Date: Mon Aug 31 12:16:57 2026 +0000
Files Changed: 4 files, 185 insertions


Overview

1. Logic Correctness

The logic is sound. The loadAdditionalConfigs method in app-config.service.ts (lines 295-324):

  • Properly checks for the existence of additionalConfigs array
  • Enforces a maximum of 3 entries to prevent request explosion
  • Iterates through URLs, fetches each with a 2-second timeout
  • Handles errors gracefully by logging and returning empty objects
  • Uses mergeWith with array-replacement semantics consistent with existing config merging
  • Returns the merged config

2. Edge Cases Handled

  • Empty or missing additionalConfigs array: Returns config unchanged
  • More than 3 entries: Processes only first 3, logs error
  • Failed URL fetches (network error, timeout, non-2xx): Treated as empty config, logged, continues processing
  • Array merging: Uses existing array-replace pattern (incoming replaces existing)

3. What the Code Does

The feature adds an additionalConfigs array to the frontend configuration interface. When present, the frontend fetches each URL in the array (up to 3) and merges the returned configuration into the existing config. This enables:

  • Loading configuration from cross-origin backends
  • Composing configuration from multiple sources (local + remote)
  • Deployment-time configuration without code changes

4. Changes Assessment

The changes make sense. They solve a real problem: when frontend and backend are on different domains, the default relative /api/v3/admin/config request fails. The additionalConfigs feature allows specifying absolute URLs to fetch configuration from any origin. The 3-entry limit prevents abuse, and the merge strategy is consistent with existing patterns.

5. Unreachable Code

No unreachable code identified. All code paths are reachable and tested.


Code Changes

Summary of Changes

File Change Type Lines Description
docs/additional-configs.md New file +87 Complete documentation with usage patterns and troubleshooting
src/app/admin/schema/frontend.config.jsonforms.json Modified +7 Added schema definition and UI control for additionalConfigs
src/app/app-config.service.ts Modified +42 Added additionalConfigs interface field, MAX_ADDITIONAL_CONFIGS constant, loadAdditionalConfigs method, and integration in loadAppConfig
src/app/app-config.service.spec.ts Modified +49 Added 3 unit tests for loadAdditionalConfigs

Assessment

Are the changes necessary?
Yes. The feature addresses a legitimate deployment constraint where frontend and backend cannot share an origin. Without this, cross-origin deployments would require code modifications.

Improvement Needed

  • Minor: The error message in line 303 of app-config.service.ts could be more specific about which URLs are being ignored
  • Consideration: The 2-second timeout (line 312) is hardcoded; could be made configurable, though the current value is reasonable
  • Documentation: The docs mention CORS but don't emphasize that absolute URLs require proper CORS headers on the target backend

Verdict
The changes are well-designed, necessary, and follow existing patterns. The implementation is robust with proper error handling.


Security Review

1. Potential Injection Vulnerabilities

No injection vulnerabilities identified. The additionalConfigs URLs are:

  • Specified by administrators in configuration files
  • Used as-is in http.get() calls
  • Angular's HttpClient properly sanitizes URLs
  • No user input is directly interpolated into URLs

2. Sensitive User Data Exposure

No sensitive data exposure. The feature:

  • Only fetches configuration data
  • Does not expose user data
  • Configuration is public-facing deployment information (backend URLs, feature flags, etc.)

3. Insecure API Usage

Potential concern identified:

  • http.get() is used without authentication headers for remote configs (line 311)
  • If additionalConfigs points to a protected endpoint, it will fail silently (caught by catchError)
  • This is acceptable behavior: configs should be publicly accessible, and failures are logged

Mitigation: The current behavior is appropriate. Configuration endpoints should not require authentication.

4. Authentication Bypass

No authentication bypass risk. The feature:

  • Does not interact with authentication mechanisms
  • Only reads configuration
  • Cannot modify authentication state or bypass existing controls

Test Coverage

Current Coverage

The new tests in app-config.service.spec.ts (lines 527-574) cover:

  1. ✅ Config unchanged when additionalConfigs is not set
  2. ✅ Config merged from single additionalConfigs entry
  3. ✅ Only first 3 entries processed when more exist

Assessment

Coverage is adequate but could be improved:

Missing test cases:

  • Error handling when a URL fails to load (network error)
  • Error handling when a URL times out (2s timeout)
  • Error handling when a URL returns non-2xx status
  • Array replacement behavior verification
  • Nested object merging behavior
  • Empty array handling
  • URLs with special characters or query parameters

Suggestions for improvement:

// Test for error handling
it("should handle failed URL fetches gracefully", async () => {
  spyOn(service["http"], "get").and.returnValue(
    throwError(() => new Error("Network error"))
  );
  const config = {
    accessTokenPrefix: "",
    additionalConfigs: ["https://unreachable.example.com/config"],
  } as AppConfigInterface;

  const result = await service["loadAdditionalConfigs"](config);

  expect(result.accessTokenPrefix).toBe("");
  expect(console.error).toHaveBeenCalled();
});

// Test for array replacement
it("should replace arrays instead of merging them", async () => {
  spyOn(service["http"], "get").and.returnValue(
    of({ datasetPageSizeOptions: [10, 20, 30] }),
  );
  const config = {
    datasetPageSizeOptions: [5, 10, 25, 100],
    additionalConfigs: ["/assets/extra.json"],
  } as AppConfigInterface;

  const result = await service["loadAdditionalConfigs"](config);

  expect(result.datasetPageSizeOptions).toEqual([10, 20, 30]);
});

Security Examples

None applicable. No security vulnerabilities were identified in the changes. The feature is designed with appropriate security considerations:

  • URLs are administrator-controlled, not user-controlled
  • Failures are handled gracefully without exposing sensitive information
  • No authentication bypass is possible through this mechanism

Testing for Security Use Cases

How to Test for Potential Issues

1. Verify URL sanitization:

// Test that malicious URLs are handled safely
it("should not execute arbitrary code from URLs", async () => {
  const maliciousUrl = "javascript:alert('xss')";
  // This should fail safely or be rejected
  const config = { additionalConfigs: [maliciousUrl] } as AppConfigInterface;
  await expectAsync(service["loadAdditionalConfigs"](config))
    .toBeRejected(); // or to resolve with unchanged config
});

2. Verify CORS behavior:

  • Manual testing required: Deploy frontend and backend on different origins
  • Configure backend with and without CORS headers
  • Verify that without proper CORS, the request fails gracefully

3. Verify no credential leakage:

  • Set additionalConfigs to a protected endpoint
  • Verify request fails without exposing credentials in error messages

Affected code: src/app/app-config.service.ts:310-318 (the http.get() call with error handling)


Summary

Consolidated Findings:

  1. Logic: The implementation is correct, handles edge cases well, and follows existing patterns.

  2. Changes: The additionalConfigs feature is necessary and well-implemented. Minor improvements possible in error messaging and timeout configurability.

  3. Security: No vulnerabilities identified. The feature is secure by design:

    • Administrator-controlled URLs only
    • Proper error handling
    • No user data exposure
    • No authentication bypass possible
  4. Testing: Current tests cover basic functionality. Should be expanded to cover:

    • Error scenarios (network errors, timeouts, non-2xx responses)
    • Array replacement behavior
    • Malicious URL handling
    • CORS-related failures
  5. Documentation: Comprehensive and well-written. Could emphasize CORS requirements more strongly.

Final Verdict: The changes in commit 5d61034c0 are well-designed, secure, and necessary. The feature solves a real deployment problem without introducing technical debt or security risks. Recommended for merge after addressing minor test coverage gaps.


Generated by Mistral Vibe.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants