Skip to content

Conversation

@lohit-bruno
Copy link
Collaborator

@lohit-bruno lohit-bruno commented Dec 2, 2025

jira

Description

Contribution Checklist:

  • The pull request only addresses one issue or adds one feature.
  • The pull request does not introduce any breaking changes
  • I have added screenshots or gifs to help explain the change if applicable.
  • I have read the contribution guidelines.
  • Create an issue and link to the pull request.

Note: Keeping the PR small and focused helps make it easier to review and merge. If you have multiple changes you want to make, please consider submitting them as separate pull requests.

Publishing to New Package Managers

Please see here for more information.

Summary by CodeRabbit

  • New Features

    • Read-only System Proxy view in Preferences showing OS proxy values and guidance.
    • New public getSystemProxy API for on-demand system proxy retrieval exposed to renderers.
  • Changes

    • Default proxy mode changed to "system".
    • System proxy logic now applies HTTP vs HTTPS proxies by protocol with improved validation and clearer errors.
    • IPC now provides system proxy data on demand rather than pushed on ready.
    • Minor UI: Headers tab has a test identifier for QA.
  • Tests

    • Extensive Windows, macOS, and Linux detection and normalization tests added.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link

coderabbitai bot commented Dec 2, 2025

Walkthrough

Adds a cross-platform async system proxy resolver (with caching, timeouts, and env fallback), exposes getSystemProxy(), wires an IPC handler, adds Redux thunk and read-only SystemProxy UI, updates Electron/CLI proxy flows to use the resolver, and introduces platform detectors with tests.

Changes

Cohort / File(s) Summary
System Proxy Core & Types
packages/bruno-requests/src/network/system-proxy/index.ts, packages/bruno-requests/src/network/system-proxy/types.ts, packages/bruno-requests/src/network/system-proxy/index.spec.js
New SystemProxyResolver with in‑flight dedupe, caching, timeouts, platform delegation and environment fallback; exports top-level getSystemProxy() and related types; tests added.
Normalization Utilities & Tests
packages/bruno-requests/src/network/system-proxy/utils/common.ts, packages/bruno-requests/src/network/system-proxy/utils/common.spec.ts
Added normalizeProxyUrl and normalizeNoProxy helpers with unit tests.
Platform Detectors + Tests
packages/bruno-requests/src/network/system-proxy/utils/windows.ts, .../windows.spec.ts, packages/bruno-requests/src/network/system-proxy/utils/macos.ts, .../macos.spec.ts, packages/bruno-requests/src/network/system-proxy/utils/linux.ts, .../linux.spec.ts
New Windows, macOS, and Linux proxy resolvers implementing platform-specific detection/parsing and comprehensive test suites.
Public Exports
packages/bruno-requests/src/index.ts, packages/bruno-requests/src/network/index.ts
Re-exported getSystemProxy from network package.
Electron IPC & Preferences
packages/bruno-electron/src/ipc/preferences.js, packages/bruno-electron/src/store/preferences.js
Added ipcMain.handle('renderer:get-system-proxy-variables', ...) to return getSystemProxy() on demand; removed automatic ready-time push of system proxy env; default proxy mode set to 'system'.
Electron Proxy Agents & Certs
packages/bruno-electron/src/utils/proxy-util.js, packages/bruno-electron/src/ipc/network/cert-utils.js
Introduced timeline-enabled proxy agent wrappers and logging; cert-utils now calls getSystemProxy() when proxy mode is system/global.
Frontend Redux / UI
packages/bruno-app/src/providers/ReduxStore/slices/app.js, packages/bruno-app/src/providers/App/useIpcEvents.js, packages/bruno-app/src/components/Preferences/ProxySettings/SystemProxy/index.js, packages/bruno-app/src/components/Preferences/ProxySettings/index.js
Renamed state systemProxyEnvVariablessystemProxyVariables; added thunk getSystemProxyVariables; removed old IPC push listener; added SystemProxy React component and replaced inline rendering with it.
CLI Changes
packages/bruno-cli/src/runner/run-single-request.js, packages/bruno-cli/src/utils/proxy-util.js
Replaced sync env helper with async getSystemProxy() usage; added URL parsing to select http_proxy vs https_proxy; removed getSystemProxyEnvVariables export.
Minor Frontend
packages/bruno-app/src/components/ResponsePane/index.js
Added data-testid="response-headers-tab" to the Headers tab element.

Sequence Diagram(s)

sequenceDiagram
    participant UI as React UI
    participant Redux as Redux Store
    participant Renderer as Renderer (ipcRenderer)
    participant Main as Electron Main
    participant Detector as System Proxy Detector

    UI->>Redux: dispatch getSystemProxyVariables()
    Redux->>Renderer: ipcRenderer.invoke('renderer:get-system-proxy-variables')
    Renderer->>Main: IPC invoke
    Main->>Detector: getSystemProxy()
    Detector->>Detector: detectByPlatform() or env fallback (with timeout/cache)
    Detector-->>Main: ProxyConfiguration
    Main-->>Renderer: return ProxyConfiguration
    Renderer-->>Redux: resolve promise
    Redux->>Redux: updateSystemProxyVariables(config)
    Redux-->>UI: state updated
    UI->>UI: render SystemProxy component (read-only)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

  • Files/areas to focus on:
    • Platform detectors parsing and edge-case handling (.../windows.ts, .../macos.ts, .../linux.ts) and their tests.
    • Caching, in‑flight deduplication, and timeout semantics in packages/bruno-requests/src/network/system-proxy/index.ts.
    • IPC handler and thunk integration (packages/bruno-electron/src/ipc/preferences.js, packages/bruno-app/src/providers/ReduxStore/slices/app.js, useIpcEvents.js).
    • Proxy agent timeline wrappers and TLS lifecycle impacts (packages/bruno-electron/src/utils/proxy-util.js).
    • CLI behavior around URL parsing and conditional proxy selection (packages/bruno-cli/src/runner/run-single-request.js).

Poem

🌐 In hidden nets the settings hide
Detectors scurry, patient, wide
Cached and careful, answers find
Redux stores the system mind
UI shows the proxy tide 🌊

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed Title is concise and directly refers to the main change: system proxy resolver logic updates, matching the substantial refactoring across multiple packages.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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

Copy link

@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: 6

Caution

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

⚠️ Outside diff range comments (2)
packages/bruno-cli/src/runner/run-single-request.js (2)

306-313: Duplicate getSystemProxy() call detected.

getSystemProxy() is called here at line 306 and again at line 353. This function performs OS-level detection (spawning scutil on macOS, reading registry on Windows, etc.), which is unnecessarily expensive to run twice.

Store the result and reuse it:

+  let systemProxy = null;
+  
   if (noproxy) {
     // If noproxy flag is set, don't use any proxy
     proxyMode = 'off';
   } else if (collectionProxyEnabled === true) {
     // If collection proxy is enabled, use it
     proxyConfig = collectionProxyConfig;
     proxyMode = 'on';
   } else if (collectionProxyEnabled === 'global') {
     // If collection proxy is set to 'global', use system proxy
-    const systemProxy = await getSystemProxy();
-    const { http_proxy, https_proxy } = systemProxy;
+    systemProxy = await getSystemProxy();
+    const { http_proxy, https_proxy } = systemProxy;
     if (http_proxy?.length || https_proxy?.length) {
       proxyMode = 'system';
     }

Then at line 353, reuse systemProxy instead of calling getSystemProxy() again.


351-389: Refactor to reuse system proxy result and improve error handling.

The current implementation has two issues:

  1. Duplicate call to getSystemProxy() (see previous comment)
  2. Inner throws at lines 365 and 378 are caught by the outer catch at line 385, which silently falls back to no proxy. This hides configuration errors from the user.
   } else if (proxyMode === 'system') {
-    try {
-      const systemProxy = await getSystemProxy();
-      const { http_proxy, https_proxy, no_proxy } = systemProxy;
+      const { http_proxy, https_proxy, no_proxy } = systemProxy || {};
       const shouldUseSystemProxy = shouldUseProxy(request.url, no_proxy || '');
       const parsedUrl = parseUrl(request.url);
       const isHttpsRequest = parsedUrl.protocol === 'https:';
+      
       if (shouldUseSystemProxy) {
-        try {
-          if (http_proxy?.length && !isHttpsRequest) {
+        if (http_proxy?.length && !isHttpsRequest) {
+          try {
             new URL(http_proxy);
             request.httpAgent = new HttpProxyAgent(http_proxy);
+          } catch (error) {
+            console.log(chalk.yellow('Warning: Invalid system http_proxy URL, skipping proxy'));
           }
-        } catch (error) {
-          throw new Error('Invalid system http_proxy');
         }
-        try {
-          if (https_proxy?.length && isHttpsRequest) {
+        if (https_proxy?.length && isHttpsRequest) {
+          try {
             new URL(https_proxy);
-            request.httpsAgent = new PatchedHttpsProxyAgent(https_proxy,
+            request.httpsAgent = new PatchedHttpsProxyAgent(
+              https_proxy,
               Object.keys(httpsAgentRequestFields).length > 0 ? { ...httpsAgentRequestFields } : undefined);
-          } else {
-            request.httpsAgent = new https.Agent({
-              ...httpsAgentRequestFields
-            });
+          } catch (error) {
+            console.log(chalk.yellow('Warning: Invalid system https_proxy URL, using direct connection'));
+            request.httpsAgent = new https.Agent({ ...httpsAgentRequestFields });
           }
-        } catch (error) {
-          throw new Error('Invalid system https_proxy');
+        } else if (isHttpsRequest) {
+          request.httpsAgent = new https.Agent({ ...httpsAgentRequestFields });
         }
       } else {
-        request.httpsAgent = new https.Agent({
-          ...httpsAgentRequestFields
-        });
+        request.httpsAgent = new https.Agent({ ...httpsAgentRequestFields });
       }
-    } catch (error) {
-      request.httpsAgent = new https.Agent({
-        ...httpsAgentRequestFields
-      });
-    }
   } else if (Object.keys(httpsAgentRequestFields).length > 0) {
🧹 Nitpick comments (10)
packages/bruno-app/src/components/Preferences/ProxySettings/index.js (1)

161-165: Minor: Consider removing redundant wrapper div.

The SystemProxy component already has its own wrapper with styling. The outer div at line 162 adds mb-3 pt-1 text-muted system-proxy-settings but the inner component also uses system-proxy-settings. This may cause style conflicts or redundancy.

         {formik?.values?.mode === 'system' ? (
-          <div className="mb-3 pt-1 text-muted system-proxy-settings">
-            <SystemProxy />
-          </div>
+          <SystemProxy />
         ) : null}
packages/bruno-requests/src/network/system-proxy/utils/windows.ts (2)

118-160: Significant code duplication between getSystemProxyEnvironment and getUserEnvironmentProxy.

Both methods parse registry output identically. Consider extracting a shared helper:

+  private parseEnvironmentProxyFromRegistry(stdout: string): ProxyConfiguration | null {
+    const lines = stdout.split('\n');
+    let http_proxy: string | null = null;
+    let https_proxy: string | null = null;
+    let no_proxy: string | null = null;
+
+    for (const line of lines) {
+      const trimmedLine = line.trim();
+      if (trimmedLine.includes('HTTP_PROXY') && trimmedLine.includes('REG_SZ')) {
+        const match = trimmedLine.match(/HTTP_PROXY\s+REG_SZ\s+(.+)/);
+        if (match) http_proxy = normalizeProxyUrl(match[1].trim());
+      }
+      if (trimmedLine.includes('HTTPS_PROXY') && trimmedLine.includes('REG_SZ')) {
+        const match = trimmedLine.match(/HTTPS_PROXY\s+REG_SZ\s+(.+)/);
+        if (match) https_proxy = normalizeProxyUrl(match[1].trim(), 'https');
+      }
+      if (trimmedLine.includes('NO_PROXY') && trimmedLine.includes('REG_SZ')) {
+        const match = trimmedLine.match(/NO_PROXY\s+REG_SZ\s+(.+)/);
+        if (match) no_proxy = normalizeNoProxy(match[1].trim());
+      }
+    }
+
+    if (http_proxy || https_proxy) {
+      return { http_proxy, https_proxy, no_proxy, source: 'windows-system' };
+    }
+    return null;
+  }

Also applies to: 162-204


34-44: Silent error swallowing may hide configuration issues.

Each detection method catches errors and continues, but the outer catch (lines 47-49) will also rethrow after all methods fail. Consider logging individual method failures for debugging:

         } catch (error) {
           // Continue to next method if this one fails
+          // console.debug(`Detection method failed: ${error instanceof Error ? error.message : String(error)}`);
           continue;
         }

This is optional; just flagging for visibility during troubleshooting.

packages/bruno-app/src/components/Preferences/ProxySettings/SystemProxy/index.js (3)

36-39: Nested ternary is hard to read.

Consider using an object lookup:

+const sourceLabels = {
+  'environment': 'Environment Variables',
+  'windows-system': 'Windows System Settings',
+  'macos-system': 'macOS System Settings',
+  'linux-system': 'Linux System Settings'
+};
+
 <div>
-  {source === 'environment' ? 'Environment Variables'
-    : source === 'windows-system' ? 'Windows System Settings'
-      : source === 'macos-system' ? 'macOS System Settings'
-        : source === 'linux-system' ? 'Linux System Settings' : source}
+  {sourceLabels[source] || source}
 </div>

10-12: Consider adding loading/error feedback.

The component dispatches getSystemProxyVariables but doesn't track loading state. Users may see stale or empty values briefly. If the IPC call fails, there's no error indication.


14-69: Unnecessary fragment wrapper.

The <></> wrapper is not needed since the component returns a single <div> element.

   return (
-    <>
       <div className="mb-3 text-muted system-proxy-settings space-y-4">
         ...
       </div>
-    </>
   );
packages/bruno-requests/src/network/system-proxy/utils/linux.spec.ts (1)

161-168: Fragile mock setup depends on implicit call order.

The combination of mockReturnValue(false) followed by two mockReturnValueOnce(true) relies on knowing exact internal call order of existsSync. If the implementation changes call order, this test breaks silently.

Consider being explicit:

-      // Mock all previous methods to fail
-      mockExistsSync.mockReturnValue(false);
-
-      // Mock systemd conf directory to exist
-      mockExistsSync.mockReturnValueOnce(true);
-
-      // Mock systemd proxy file to exist
-      mockExistsSync.mockReturnValueOnce(true);
+      mockExistsSync.mockImplementation((path: string) => {
+        if (path === '/etc/environment') return false;
+        if (path === '/etc/systemd/system.conf.d') return true;
+        if (path.includes('proxy.conf')) return true;
+        return false;
+      });
packages/bruno-app/src/providers/ReduxStore/slices/app.js (1)

201-210: Minor promise chaining issue.

The .then((variables) => { dispatch(...) }).then(resolve) chain resolves with undefined since the dispatch callback returns nothing. This works but is slightly confusing.

 export const getSystemProxyVariables = () => (dispatch, getState) => {
   return new Promise((resolve, reject) => {
     const { ipcRenderer } = window;
     ipcRenderer.invoke('renderer:get-system-proxy-variables')
       .then((variables) => {
         dispatch(updateSystemProxyVariables(variables));
+        resolve(variables);
-      })
-      .then(resolve).catch(reject);
+      }).catch(reject);
   });
 };
packages/bruno-requests/src/network/system-proxy/utils/linux.ts (1)

175-243: Consider simplifying the parsing loop.

The nested loops with multiple regex patterns per variable could be simplified. However, the current implementation is correct and readable enough.

One minor improvement: you could build a single combined regex pattern upfront instead of iterating per variable, but this is optional given the small, fixed list.

packages/bruno-requests/src/network/system-proxy/index.ts (1)

65-67: detectWithTimeout is a pass-through wrapper.

This method just calls detectByPlatform — the commandTimeout is passed to individual detectors. The method name is slightly misleading since no additional timeout wrapper exists here.

Consider either:

  1. Removing this wrapper and calling detectByPlatform directly, or
  2. Adding an actual Promise.race timeout if you want a hard cap beyond individual command timeouts
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9bbcf7e and 5f22e87.

📒 Files selected for processing (24)
  • packages/bruno-app/src/components/Preferences/ProxySettings/SystemProxy/index.js (1 hunks)
  • packages/bruno-app/src/components/Preferences/ProxySettings/index.js (2 hunks)
  • packages/bruno-app/src/components/ResponsePane/index.js (1 hunks)
  • packages/bruno-app/src/providers/App/useIpcEvents.js (1 hunks)
  • packages/bruno-app/src/providers/ReduxStore/slices/app.js (4 hunks)
  • packages/bruno-cli/src/runner/run-single-request.js (4 hunks)
  • packages/bruno-cli/src/utils/proxy-util.js (1 hunks)
  • packages/bruno-electron/src/ipc/network/cert-utils.js (2 hunks)
  • packages/bruno-electron/src/ipc/preferences.js (2 hunks)
  • packages/bruno-electron/src/store/preferences.js (2 hunks)
  • packages/bruno-electron/src/utils/proxy-util.js (5 hunks)
  • packages/bruno-requests/src/index.ts (1 hunks)
  • packages/bruno-requests/src/network/index.ts (1 hunks)
  • packages/bruno-requests/src/network/system-proxy/index.spec.js (1 hunks)
  • packages/bruno-requests/src/network/system-proxy/index.ts (1 hunks)
  • packages/bruno-requests/src/network/system-proxy/types.ts (1 hunks)
  • packages/bruno-requests/src/network/system-proxy/utils/common.spec.ts (1 hunks)
  • packages/bruno-requests/src/network/system-proxy/utils/common.ts (1 hunks)
  • packages/bruno-requests/src/network/system-proxy/utils/linux.spec.ts (1 hunks)
  • packages/bruno-requests/src/network/system-proxy/utils/linux.ts (1 hunks)
  • packages/bruno-requests/src/network/system-proxy/utils/macos.spec.ts (1 hunks)
  • packages/bruno-requests/src/network/system-proxy/utils/macos.ts (1 hunks)
  • packages/bruno-requests/src/network/system-proxy/utils/windows.spec.ts (1 hunks)
  • packages/bruno-requests/src/network/system-proxy/utils/windows.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (CODING_STANDARDS.md)

**/*.{js,jsx,ts,tsx}: Use 2 spaces for indentation. No tabs, just spaces
Stick to single quotes for strings
Always add semicolons at the end of statements
No trailing commas
Always use parentheses around parameters in arrow functions, even for single parameters
For multiline constructs, put opening braces on the same line, and ensure consistency. Minimum 2 elements for multiline
No newlines inside function parentheses. Keep 'em tight
Space before and after the arrow in arrow functions. () => {} is good
No space between function name and parentheses. func() not func ()
Semicolons go at the end of the line, not on a new line
Names for functions need to be concise and descriptive
Add in JSDoc comments to add more details to the abstractions if needed
Avoid single line abstractions where all that's being done is increasing the call stack with one additional function
Add in meaningful comments instead of obvious ones where complex code flow is explained properly

Files:

  • packages/bruno-requests/src/network/system-proxy/types.ts
  • packages/bruno-app/src/components/ResponsePane/index.js
  • packages/bruno-electron/src/ipc/network/cert-utils.js
  • packages/bruno-requests/src/network/system-proxy/utils/macos.spec.ts
  • packages/bruno-requests/src/network/system-proxy/utils/common.ts
  • packages/bruno-app/src/components/Preferences/ProxySettings/SystemProxy/index.js
  • packages/bruno-cli/src/runner/run-single-request.js
  • packages/bruno-requests/src/index.ts
  • packages/bruno-requests/src/network/index.ts
  • packages/bruno-electron/src/ipc/preferences.js
  • packages/bruno-requests/src/network/system-proxy/utils/linux.ts
  • packages/bruno-requests/src/network/system-proxy/utils/windows.ts
  • packages/bruno-requests/src/network/system-proxy/index.spec.js
  • packages/bruno-requests/src/network/system-proxy/utils/macos.ts
  • packages/bruno-requests/src/network/system-proxy/utils/linux.spec.ts
  • packages/bruno-requests/src/network/system-proxy/index.ts
  • packages/bruno-requests/src/network/system-proxy/utils/windows.spec.ts
  • packages/bruno-cli/src/utils/proxy-util.js
  • packages/bruno-electron/src/utils/proxy-util.js
  • packages/bruno-app/src/components/Preferences/ProxySettings/index.js
  • packages/bruno-requests/src/network/system-proxy/utils/common.spec.ts
  • packages/bruno-app/src/providers/App/useIpcEvents.js
  • packages/bruno-electron/src/store/preferences.js
  • packages/bruno-app/src/providers/ReduxStore/slices/app.js
🧬 Code graph analysis (13)
packages/bruno-app/src/components/ResponsePane/index.js (6)
packages/bruno-app/src/components/FolderSettings/index.js (1)
  • getTabClassname (69-73)
packages/bruno-app/src/components/CollectionSettings/index.js (1)
  • getTabClassname (83-87)
packages/bruno-app/src/components/RequestPane/HttpRequestPane/index.js (2)
  • getTabClassname (83-87)
  • selectTab (27-34)
packages/bruno-app/src/components/ResponsePane/StatusCode/index.js (1)
  • getTabClassname (8-16)
packages/bruno-app/src/components/RunnerResults/ResponsePane/index.js (2)
  • getTabClassname (83-87)
  • selectTab (36-36)
packages/bruno-app/src/components/RequestPane/GraphQLRequestPane/index.js (2)
  • getTabClassname (123-127)
  • selectTab (54-61)
packages/bruno-electron/src/ipc/network/cert-utils.js (5)
packages/bruno-requests/src/index.ts (1)
  • getSystemProxy (10-10)
packages/bruno-requests/src/network/index.ts (1)
  • getSystemProxy (3-3)
packages/bruno-requests/src/network/system-proxy/index.ts (2)
  • getSystemProxy (22-44)
  • getSystemProxy (106-120)
packages/bruno-electron/src/utils/proxy-util.js (1)
  • proxyConfig (379-379)
packages/bruno-app/src/components/CollectionSettings/index.js (1)
  • proxyConfig (42-42)
packages/bruno-requests/src/network/system-proxy/utils/macos.spec.ts (1)
packages/bruno-requests/src/network/system-proxy/utils/macos.ts (1)
  • MacOSProxyDetector (8-122)
packages/bruno-app/src/components/Preferences/ProxySettings/SystemProxy/index.js (1)
packages/bruno-app/src/providers/ReduxStore/slices/app.js (2)
  • getSystemProxyVariables (201-210)
  • getSystemProxyVariables (201-210)
packages/bruno-requests/src/network/system-proxy/utils/linux.ts (2)
packages/bruno-requests/src/network/system-proxy/types.ts (2)
  • ProxyDetector (8-10)
  • ProxyConfiguration (1-6)
packages/bruno-requests/src/network/system-proxy/utils/common.ts (2)
  • normalizeProxyUrl (13-23)
  • normalizeNoProxy (30-40)
packages/bruno-requests/src/network/system-proxy/utils/windows.ts (3)
packages/bruno-requests/src/network/system-proxy/types.ts (2)
  • ProxyDetector (8-10)
  • ProxyConfiguration (1-6)
packages/bruno-requests/src/network/system-proxy/index.ts (1)
  • ProxyConfiguration (122-122)
packages/bruno-requests/src/network/system-proxy/utils/common.ts (2)
  • normalizeProxyUrl (13-23)
  • normalizeNoProxy (30-40)
packages/bruno-requests/src/network/system-proxy/index.spec.js (4)
packages/bruno-requests/src/network/system-proxy/index.ts (3)
  • SystemProxyDetector (8-102)
  • getSystemProxy (22-44)
  • getSystemProxy (106-120)
packages/bruno-requests/src/network/system-proxy/utils/windows.ts (1)
  • WindowsProxyDetector (16-235)
packages/bruno-requests/src/network/system-proxy/utils/macos.ts (1)
  • MacOSProxyDetector (8-122)
packages/bruno-requests/src/network/system-proxy/utils/linux.ts (1)
  • LinuxProxyDetector (24-244)
packages/bruno-requests/src/network/system-proxy/utils/macos.ts (2)
packages/bruno-requests/src/network/system-proxy/types.ts (2)
  • ProxyDetector (8-10)
  • ProxyConfiguration (1-6)
packages/bruno-requests/src/network/system-proxy/utils/common.ts (2)
  • normalizeProxyUrl (13-23)
  • normalizeNoProxy (30-40)
packages/bruno-requests/src/network/system-proxy/utils/linux.spec.ts (1)
packages/bruno-requests/src/network/system-proxy/utils/linux.ts (1)
  • LinuxProxyDetector (24-244)
packages/bruno-requests/src/network/system-proxy/utils/windows.spec.ts (1)
packages/bruno-requests/src/network/system-proxy/utils/windows.ts (1)
  • WindowsProxyDetector (16-235)
packages/bruno-electron/src/utils/proxy-util.js (2)
packages/bruno-cli/src/runner/run-single-request.js (4)
  • proxyUri (324-324)
  • proxyConfig (292-292)
  • parsedUrl (356-356)
  • parseUrl (3-3)
packages/bruno-cli/src/utils/proxy-util.js (3)
  • shouldUseProxy (16-63)
  • parsedUrl (26-26)
  • parseUrl (1-1)
packages/bruno-app/src/components/Preferences/ProxySettings/index.js (1)
packages/bruno-app/src/components/Preferences/ProxySettings/SystemProxy/index.js (1)
  • SystemProxy (5-70)
packages/bruno-requests/src/network/system-proxy/utils/common.spec.ts (1)
packages/bruno-requests/src/network/system-proxy/utils/common.ts (2)
  • normalizeProxyUrl (13-23)
  • normalizeNoProxy (30-40)
🪛 ast-grep (0.40.0)
packages/bruno-requests/src/network/system-proxy/utils/linux.ts

[warning] 208-208: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp(^export\\s+${varName}\\s*=\\s*(.+)$, 'i')
Note: [CWE-1333] Inefficient Regular Expression Complexity [REFERENCES]
- https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS
- https://cwe.mitre.org/data/definitions/1333.html

(regexp-from-variable)


[warning] 209-209: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp(^${varName}\\s*=\\s*(.+)$, 'i')
Note: [CWE-1333] Inefficient Regular Expression Complexity [REFERENCES]
- https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS
- https://cwe.mitre.org/data/definitions/1333.html

(regexp-from-variable)

🪛 Biome (2.1.2)
packages/bruno-electron/src/utils/proxy-util.js

[error] 88-103: This constructor has code paths that return without calling super().

If this is intentional, add an explicit throw statement in unsupported paths.

(lint/correctness/noUnreachableSuper)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: Playwright E2E Tests
  • GitHub Check: CLI Tests
  • GitHub Check: Unit Tests
  • GitHub Check: SSL Tests - Linux
  • GitHub Check: SSL Tests - macOS
  • GitHub Check: SSL Tests - Windows
🔇 Additional comments (35)
packages/bruno-requests/src/network/system-proxy/types.ts (1)

1-15: System proxy type definitions look consistent and usable.

ProxyConfiguration, ProxyDetector, and SystemProxyDetectorOptions align well with the new detection flow and env-style proxy fields.

packages/bruno-electron/src/utils/proxy-util.js (2)

337-340: System proxy handling and HTTP proxy agent options look coherent.

  • httpProxyAgentOptions with keepAlive: true and the new TimelineHttpProxyAgent wiring for both manual (proxyMode === 'on') and system proxies integrate cleanly with the existing timeline agent pattern.
  • In system mode, splitting behavior by protocol (http_proxy for non‑HTTPS, https_proxy for HTTPS) and validating via new URL(...) before constructing agents gives clear, actionable error messages when system proxy values are malformed.
  • Fallback to a non‑proxy https.Agent when system proxies are disabled by no_proxy or missing also looks reasonable.

Also applies to: 365-368, 379-407


86-105: Derived agent constructor should always call super (and fail fast if proxy is missing).

The subclass returned by createTimelineHttpAgentClass only calls super when options?.proxy is set and BaseAgentClass.name === 'HttpProxyAgent'. Other code paths fall through without calling super, which violates class constructor requirements and can lead to runtime errors if the factory is used differently in the future.

Given that a proxy URI is always required here, restructure to:

  • Unconditionally destructure proxy and options
  • Throw if proxy is missing
  • Always call super(proxyUri, httpProxyAgentOptions) before accessing this
  • Remove the fragile BaseAgentClass.name check
-function createTimelineHttpAgentClass(BaseAgentClass) {
-  return class extends BaseAgentClass {
-    constructor(options, timeline) {
-      // For proxy agents, the first argument is the proxy URI and the second is options
-      if (options?.proxy) {
-        if (BaseAgentClass.name === 'HttpProxyAgent') {
-          const { proxy: proxyUri, httpProxyAgentOptions } = options;
-          super(proxyUri, httpProxyAgentOptions);
-          this.timeline = Array.isArray(timeline) ? timeline : [];
-          // Log the proxy details
-          this.timeline.push({
-            timestamp: new Date(),
-            type: 'info',
-            message: `Using proxy: ${proxyUri}`
-          });
-        }
-      }
-    }
-  };
-}
+function createTimelineHttpAgentClass(BaseAgentClass) {
+  return class extends BaseAgentClass {
+    constructor(options, timeline) {
+      const { proxy: proxyUri, httpProxyAgentOptions } = options || {};
+
+      if (!proxyUri) {
+        throw new Error('TimelineHttpProxyAgent requires a "proxy" option');
+      }
+
+      // For proxy agents, the first argument is the proxy URI and the second is options
+      super(proxyUri, httpProxyAgentOptions);
+
+      this.timeline = Array.isArray(timeline) ? timeline : [];
+      this.timeline.push({
+        timestamp: new Date(),
+        type: 'info',
+        message: `Using proxy: ${proxyUri}`
+      });
+    }
+  };
+}

Ensure all call sites pass options.proxy and test against your Node/Electron versions.

packages/bruno-app/src/components/ResponsePane/index.js (1)

160-165: Adding data-testid on the Headers tab is a clean, non-invasive test hook.

Nice way to make the Headers tab easy to target in tests without affecting runtime behavior.

packages/bruno-requests/src/index.ts (1)

8-10: Re-exporting getSystemProxy from the package entrypoint looks correct.

This cleanly surfaces the new system proxy API alongside existing exports without breaking the current public surface.

packages/bruno-electron/src/ipc/network/cert-utils.js (1)

4-4: Good integration of shared getSystemProxy into Electron’s proxy resolution.

For collections using the global proxy config, resolving proxyMode to 'system' and then delegating to await getSystemProxy() centralizes system proxy detection in the requests layer and keeps this IPC helper focused on wiring.

Also applies to: 105-122

packages/bruno-requests/src/network/index.ts (1)

1-3: Network module export of getSystemProxy is consistent with the new API surface.

This keeps the network entrypoint aligned with the package entrypoint and downstream Electron usage.

packages/bruno-electron/src/store/preferences.js (1)

30-30: Defaulting global proxy mode to 'system' is consistent and backward-tolerant.

Changing the default mode to 'system' in both defaultPreferences and getGlobalProxyConfig aligns behavior for new installs while still allowing existing saved preferences to override it through the merge logic.

Also applies to: 195-196

packages/bruno-cli/src/utils/proxy-util.js (1)

82-85: Verify no remaining imports of getSystemProxyEnvVariables exist in the codebase.

The module now exports only shouldUseProxy and PatchedHttpsProxyAgent. Ensure that getSystemProxyEnvVariables is not imported or used anywhere else in the project before merging.

packages/bruno-app/src/components/Preferences/ProxySettings/index.js (1)

11-11: LGTM on the import.

Clean import of the new SystemProxy component. The explicit /index suffix is consistent with the codebase style.

packages/bruno-app/src/providers/App/useIpcEvents.js (1)

2-6: LGTM on the import cleanup.

Removal of updateSystemProxyEnvVariables is consistent with the architectural shift to on-demand IPC-based proxy detection. The new flow correctly fetches system proxy data via the getSystemProxyVariables thunk when the SystemProxy component mounts.

packages/bruno-requests/src/network/system-proxy/utils/common.spec.ts (2)

1-25: Good test coverage for normalizeProxyUrl.

Tests cover the key scenarios: missing protocol, existing protocols, empty strings, SOCKS variants, and URLs without ports. The assertions align correctly with the implementation in common.ts.


27-64: Comprehensive tests for normalizeNoProxy.

Excellent coverage of delimiter variations, whitespace handling, and edge cases. The complex patterns test at line 61-63 properly validates CIDR, wildcards, and <local> patterns.

packages/bruno-electron/src/ipc/preferences.js (2)

6-6: LGTM on the import.

Clean import of getSystemProxy from the @usebruno/requests package.


51-55: Consider adding error handling for robustness.

The handler works but doesn't catch errors from getSystemProxy(). If the system proxy detection fails (e.g., scutil command fails on macOS), the rejection propagates to the renderer. Ensure the Redux thunk handles this gracefully.

packages/bruno-requests/src/network/system-proxy/utils/macos.spec.ts (3)

1-22: LGTM on the test setup.

Clean mock setup for child_process.exec and util.promisify. The beforeEach correctly resets mocks between tests.


24-128: Solid coverage for proxy detection scenarios.

Tests properly validate HTTP/HTTPS combinations, default port fallbacks, and enabled/disabled states. Assertions match the expected ProxyConfiguration shape.


235-247: Good error handling coverage.

Tests correctly verify that command failures and invalid output formats throw appropriate errors.

packages/bruno-cli/src/runner/run-single-request.js (2)

3-3: LGTM on the import.

Using Node's built-in url.parse for protocol detection.


19-20: LGTM on the updated imports.

Clean imports for the new proxy utilities and getSystemProxy from @usebruno/requests.

packages/bruno-requests/src/network/system-proxy/utils/windows.ts (1)

8-14: Good use of an enum to restrict commands.

This approach mitigates command injection by whitelisting allowed shell commands. Clean pattern.

packages/bruno-requests/src/network/system-proxy/utils/common.ts (1)

1-40: Clean utility functions with good documentation.

Both helpers are well-documented, handle edge cases appropriately, and follow consistent patterns. The regex for protocol detection is correct and the no_proxy normalization handles multiple delimiter formats.

packages/bruno-requests/src/network/system-proxy/index.spec.js (1)

37-78: Good test coverage across detection scenarios.

Tests cover environment variable priority, platform routing, error fallbacks, caching behavior, and the public getSystemProxy function. Solid integration test suite.

Also applies to: 80-116, 118-154, 156-195, 197-210

packages/bruno-requests/src/network/system-proxy/utils/linux.spec.ts (2)

40-126: Good coverage for gsettings scenarios.

Tests cover manual proxy, identical HTTP/HTTPS proxies, non-manual mode handling, and empty ignore lists. Well-structured mocking of sequential gsettings calls.


186-223: Error handling tests are comprehensive.

Covers gsettings unavailable, missing schema, and no configuration found scenarios. All properly assert the expected error message.

packages/bruno-app/src/providers/ReduxStore/slices/app.js (1)

46-47: LGTM on the renamed state field.

Consistent rename from systemProxyEnvVariables to systemProxyVariables — makes sense given it now captures system-level proxy config, not just environment variables.

packages/bruno-requests/src/network/system-proxy/utils/macos.ts (1)

88-121: LGTM on proxy configuration builder.

Good handling of HTTP/HTTPS proxies with appropriate default ports and proper normalization. The <local> append for ExcludeSimpleHostnames is a nice touch.

packages/bruno-requests/src/network/system-proxy/utils/windows.spec.ts (3)

1-22: LGTM on test setup.

Clean mocking of node:child_process and node:util. The beforeEach properly resets mocks between tests.


24-84: Solid coverage for Internet Options detection.

Good test cases for single proxy, protocol-specific, and fallback scenarios. The mock chaining for fallback behavior is well structured.


231-377: Thorough edge case coverage.

Tests for existing prefixes, empty overrides, disabled proxies, decimal values, and complex bypass lists provide good confidence in parsing robustness.

packages/bruno-requests/src/network/system-proxy/utils/linux.ts (3)

10-22: Good use of enum for command allowlisting.

Prevents command injection by constraining shell commands to known-safe values.


59-92: LGTM on GNOME gsettings detection.

Properly checks for manual mode, parses host/port pairs, and handles the gsettings array format for ignore-hosts.


206-223: Static analysis warning is a false positive.

The varName comes from the hardcoded proxyVars array (line 176), not user input. No ReDoS risk here.

packages/bruno-requests/src/network/system-proxy/index.ts (2)

8-44: Well-designed caching and concurrency control.

The activeDetection promise coalescing prevents redundant concurrent detections. Cache TTL of 60s is reasonable for proxy settings that rarely change.


106-120: LGTM on the exported getSystemProxy function.

Environment variables taking precedence over system detection is a sensible default — allows users to override system proxy easily.

Copy link

@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

♻️ Duplicate comments (1)
packages/bruno-requests/src/network/system-proxy/index.ts (1)

97-101: Race condition: clearing activeDetection during in-flight detection.

Line 100 sets activeDetection = null, which can cause duplicate detections if clearCache() is called while a detection is in progress. The next getSystemProxy() call (line 29) won't find the active detection and will start a new one.

Choose one approach:

Option 1 (recommended): Preserve in-flight detection

 clearCache(): void {
   this.cachedResult = null;
   this.cacheTimestamp = 0;
-  this.activeDetection = null;
+  // Keep activeDetection to avoid duplicate in-flight requests
 }

Option 2: Implement force-refresh semantics

-clearCache(): void {
+async clearCache(): Promise<void> {
+  // Wait for any in-flight detection to complete before clearing
+  if (this.activeDetection) {
+    await this.activeDetection.catch(() => {});
+  }
   this.cachedResult = null;
   this.cacheTimestamp = 0;
   this.activeDetection = null;
 }
🧹 Nitpick comments (4)
packages/bruno-electron/src/ipc/network/cert-utils.js (1)

116-119: Use strict equality.

Line 116 uses loose equality (==) instead of strict equality (===).

Apply this diff:

-    if (proxyMode == 'system') {
+    if (proxyMode === 'system') {
packages/bruno-requests/src/network/system-proxy/utils/linux.ts (1)

206-223: Static analysis flag is a false positive, but pattern pre-compilation would improve performance.

The static analyzer warns about RegExp construction from variables (lines 208-209), but varName comes from the hardcoded proxyVars array (line 176), not user input, so there's no ReDoS risk.

For better performance, consider pre-compiling the patterns:

+  // Pre-compiled patterns for known proxy variables
+  private readonly PROXY_PATTERNS = [
+    'http_proxy', 'https_proxy', 'no_proxy', 'all_proxy',
+    'HTTP_PROXY', 'HTTPS_PROXY', 'NO_PROXY', 'ALL_PROXY'
+  ].flatMap((varName) => [
+    { regex: new RegExp(`^export\\s+${varName}\\s*=\\s*(.+)$`, 'i'), varName },
+    { regex: new RegExp(`^${varName}\\s*=\\s*(.+)$`, 'i'), varName }
+  ]);
+
   private parseProxyFromContent(content: string): ProxyConfiguration | null {
-    const proxyVars = ['http_proxy', 'https_proxy', 'no_proxy', 'all_proxy', 'HTTP_PROXY', 'HTTPS_PROXY', 'NO_PROXY', 'ALL_PROXY'];
     const proxies: Record<string, string> = {};

     const lines = content.split('\n');
     for (const line of lines) {
       const trimmedLine = line.trim();

       // Skip comments and empty lines
       if (!trimmedLine || trimmedLine.startsWith('#')) {
         continue;
       }

       // ... systemd handling ...

-      // Handle different formats: VAR=value, export VAR=value, VAR="value", etc.
-      for (const varName of proxyVars) {
-        const patterns = [
-          new RegExp(`^export\\s+${varName}\\s*=\\s*(.+)$`, 'i'),
-          new RegExp(`^${varName}\\s*=\\s*(.+)$`, 'i')
-        ];
-
-        for (const pattern of patterns) {
-          const match = trimmedLine.match(pattern);
-          if (match) {
-            let value = match[1].trim();
-            // Remove surrounding quotes
-            value = value.replace(/^["']|["']$/g, '');
-            proxies[varName.toLowerCase()] = value;
-            break;
-          }
+      for (const { regex, varName } of this.PROXY_PATTERNS) {
+        const match = trimmedLine.match(regex);
+        if (match) {
+          let value = match[1].trim();
+          value = value.replace(/^["']|["']$/g, '');
+          proxies[varName.toLowerCase()] = value;
+          break;
         }
       }
     }
packages/bruno-electron/src/utils/proxy-util.js (1)

379-407: System proxy selection & validation behaviour is clearer; watch expectations around env formats

The updated proxyMode === 'system' logic:

  • Destructures { http_proxy, https_proxy, no_proxy } from proxyConfig || {} and uses shouldUseProxy(requestConfig.url, no_proxy || '') to respect no_proxy.
  • Differentiates HTTP vs HTTPS requests via parseUrl(requestConfig.url) and parsedUrl.protocol === 'https:', using http_proxy only for non‑HTTPS and https_proxy only for HTTPS.
  • Validates each configured system proxy with new URL(...) and wraps failures in explicit error messages: Invalid system http_proxy "…" / Invalid system https_proxy "…", which is a nice debugging improvement.
  • Reuses the same timeline‑enabled agents as the manual proxy mode, so HTTP/HTTPS system proxies now benefit from the same logging.

Two things to keep in mind:

  • This behaviour assumes http_proxy / https_proxy are full URLs acceptable to new URL(...) (including a scheme). If your system‑proxy detection can emit bare host:port values, those will now be rejected; confirm that upstream always normalizes to proper URLs.
  • Because the HTTP/system proxy agents push Using proxy: ${proxyUri} into the timeline, any credentials embedded in http_proxy / https_proxy will end up in diagnostic output. If that’s a concern for your users, consider redacting the userinfo segment before logging.

Functionally this change looks sound; the main follow‑up is just to verify the expected shape of the system proxy values fed into proxyConfig.

packages/bruno-cli/src/runner/run-single-request.js (1)

3-3: Prefer new URL() over legacy url.parse for protocol detection

You import parseUrl just to read parsedUrl.protocol, while elsewhere in this file you already use the global URL constructor. For consistency and to avoid the legacy url API, you can drop the import and do:

-const parseUrl = require('url').parse;

and later:

-        const parsedUrl = parseUrl(request.url);
-        const isHttpsRequest = parsedUrl.protocol === 'https:';
+        const parsedUrl = new URL(request.url);
+        const isHttpsRequest = parsedUrl.protocol === 'https:';

This keeps everything on the WHATWG URL path and removes an extra dependency.

Also applies to: 356-357

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5f22e87 and 73ef5b7.

📒 Files selected for processing (24)
  • packages/bruno-app/src/components/Preferences/ProxySettings/SystemProxy/index.js (1 hunks)
  • packages/bruno-app/src/components/Preferences/ProxySettings/index.js (2 hunks)
  • packages/bruno-app/src/components/ResponsePane/index.js (1 hunks)
  • packages/bruno-app/src/providers/App/useIpcEvents.js (1 hunks)
  • packages/bruno-app/src/providers/ReduxStore/slices/app.js (4 hunks)
  • packages/bruno-cli/src/runner/run-single-request.js (4 hunks)
  • packages/bruno-cli/src/utils/proxy-util.js (1 hunks)
  • packages/bruno-electron/src/ipc/network/cert-utils.js (2 hunks)
  • packages/bruno-electron/src/ipc/preferences.js (2 hunks)
  • packages/bruno-electron/src/store/preferences.js (2 hunks)
  • packages/bruno-electron/src/utils/proxy-util.js (5 hunks)
  • packages/bruno-requests/src/index.ts (1 hunks)
  • packages/bruno-requests/src/network/index.ts (1 hunks)
  • packages/bruno-requests/src/network/system-proxy/index.spec.js (1 hunks)
  • packages/bruno-requests/src/network/system-proxy/index.ts (1 hunks)
  • packages/bruno-requests/src/network/system-proxy/types.ts (1 hunks)
  • packages/bruno-requests/src/network/system-proxy/utils/common.spec.ts (1 hunks)
  • packages/bruno-requests/src/network/system-proxy/utils/common.ts (1 hunks)
  • packages/bruno-requests/src/network/system-proxy/utils/linux.spec.ts (1 hunks)
  • packages/bruno-requests/src/network/system-proxy/utils/linux.ts (1 hunks)
  • packages/bruno-requests/src/network/system-proxy/utils/macos.spec.ts (1 hunks)
  • packages/bruno-requests/src/network/system-proxy/utils/macos.ts (1 hunks)
  • packages/bruno-requests/src/network/system-proxy/utils/windows.spec.ts (1 hunks)
  • packages/bruno-requests/src/network/system-proxy/utils/windows.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (14)
  • packages/bruno-app/src/components/ResponsePane/index.js
  • packages/bruno-requests/src/network/system-proxy/index.spec.js
  • packages/bruno-app/src/components/Preferences/ProxySettings/index.js
  • packages/bruno-app/src/providers/ReduxStore/slices/app.js
  • packages/bruno-requests/src/network/system-proxy/utils/macos.spec.ts
  • packages/bruno-requests/src/network/system-proxy/utils/common.ts
  • packages/bruno-requests/src/index.ts
  • packages/bruno-requests/src/network/system-proxy/types.ts
  • packages/bruno-app/src/components/Preferences/ProxySettings/SystemProxy/index.js
  • packages/bruno-requests/src/network/system-proxy/utils/macos.ts
  • packages/bruno-requests/src/network/system-proxy/utils/windows.spec.ts
  • packages/bruno-electron/src/ipc/preferences.js
  • packages/bruno-requests/src/network/index.ts
  • packages/bruno-requests/src/network/system-proxy/utils/linux.spec.ts
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (CODING_STANDARDS.md)

**/*.{js,jsx,ts,tsx}: Use 2 spaces for indentation. No tabs, just spaces
Stick to single quotes for strings
Always add semicolons at the end of statements
No trailing commas
Always use parentheses around parameters in arrow functions, even for single parameters
For multiline constructs, put opening braces on the same line, and ensure consistency. Minimum 2 elements for multiline
No newlines inside function parentheses. Keep 'em tight
Space before and after the arrow in arrow functions. () => {} is good
No space between function name and parentheses. func() not func ()
Semicolons go at the end of the line, not on a new line
Names for functions need to be concise and descriptive
Add in JSDoc comments to add more details to the abstractions if needed
Avoid single line abstractions where all that's being done is increasing the call stack with one additional function
Add in meaningful comments instead of obvious ones where complex code flow is explained properly

Files:

  • packages/bruno-requests/src/network/system-proxy/utils/common.spec.ts
  • packages/bruno-cli/src/runner/run-single-request.js
  • packages/bruno-cli/src/utils/proxy-util.js
  • packages/bruno-requests/src/network/system-proxy/utils/windows.ts
  • packages/bruno-app/src/providers/App/useIpcEvents.js
  • packages/bruno-requests/src/network/system-proxy/utils/linux.ts
  • packages/bruno-electron/src/utils/proxy-util.js
  • packages/bruno-requests/src/network/system-proxy/index.ts
  • packages/bruno-electron/src/store/preferences.js
  • packages/bruno-electron/src/ipc/network/cert-utils.js
🧬 Code graph analysis (2)
packages/bruno-requests/src/network/system-proxy/utils/common.spec.ts (1)
packages/bruno-requests/src/network/system-proxy/utils/common.ts (2)
  • normalizeProxyUrl (13-23)
  • normalizeNoProxy (30-40)
packages/bruno-requests/src/network/system-proxy/index.ts (7)
packages/bruno-requests/src/network/system-proxy/types.ts (2)
  • ProxyConfiguration (1-6)
  • SystemProxyDetectorOptions (12-15)
packages/bruno-requests/src/network/system-proxy/utils/windows.ts (1)
  • WindowsProxyDetector (16-235)
packages/bruno-requests/src/network/system-proxy/utils/macos.ts (1)
  • MacOSProxyDetector (8-118)
packages/bruno-requests/src/network/system-proxy/utils/linux.ts (1)
  • LinuxProxyDetector (24-244)
packages/bruno-requests/src/network/system-proxy/utils/common.ts (2)
  • normalizeProxyUrl (13-23)
  • normalizeNoProxy (30-40)
packages/bruno-requests/src/index.ts (1)
  • getSystemProxy (10-10)
packages/bruno-requests/src/network/index.ts (1)
  • getSystemProxy (3-3)
🪛 ast-grep (0.40.0)
packages/bruno-requests/src/network/system-proxy/utils/linux.ts

[warning] 208-208: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp(^export\\s+${varName}\\s*=\\s*(.+)$, 'i')
Note: [CWE-1333] Inefficient Regular Expression Complexity [REFERENCES]
- https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS
- https://cwe.mitre.org/data/definitions/1333.html

(regexp-from-variable)


[warning] 209-209: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp(^${varName}\\s*=\\s*(.+)$, 'i')
Note: [CWE-1333] Inefficient Regular Expression Complexity [REFERENCES]
- https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS
- https://cwe.mitre.org/data/definitions/1333.html

(regexp-from-variable)

🪛 Biome (2.1.2)
packages/bruno-electron/src/utils/proxy-util.js

[error] 88-103: This constructor has code paths that return without calling super().

If this is intentional, add an explicit throw statement in unsupported paths.

(lint/correctness/noUnreachableSuper)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: Unit Tests
  • GitHub Check: Playwright E2E Tests
  • GitHub Check: CLI Tests
  • GitHub Check: SSL Tests - Windows
  • GitHub Check: SSL Tests - macOS
  • GitHub Check: SSL Tests - Linux
🔇 Additional comments (12)
packages/bruno-cli/src/utils/proxy-util.js (1)

82-85: Export surface change looks good; confirm no remaining callers of removed helper

module.exports now only exposes shouldUseProxy and PatchedHttpsProxyAgent, which matches the PR's move toward centralized system-proxy handling elsewhere. No issues with the remaining exports.

Please confirm that any prior consumers of the removed helper (e.g., getSystemProxyEnvVariables) have been updated or removed across the repo so there are no lingering import errors.

packages/bruno-app/src/providers/App/useIpcEvents.js (1)

2-6: Import of updatePreferences is consistent and necessary

The added updatePreferences named import matches its usage in the 'main:load-preferences' handler below and aligns with existing import style; no issues from this change in this file.

packages/bruno-electron/src/store/preferences.js (1)

30-30: LGTM - Default proxy mode updated to 'system'.

The default proxy mode change from 'off' to 'system' is consistent across both defaultPreferences (line 30) and getGlobalProxyConfig (line 195). This aligns with the PR's system proxy detection feature.

Also applies to: 195-195

packages/bruno-requests/src/network/system-proxy/utils/common.spec.ts (1)

1-64: LGTM - Comprehensive test coverage.

The test suite thoroughly covers edge cases for both normalizeProxyUrl and normalizeNoProxy utilities, including empty inputs, protocol handling, delimiter normalization, and whitespace handling.

packages/bruno-requests/src/network/system-proxy/utils/windows.ts (2)

9-50: LGTM - Well-structured detection with command injection prevention.

The AllowedWindowsCommands enum effectively prevents command injection, and the cascading fallback strategy (Internet Settings → WinHTTP → System/User environment) provides robust detection across different Windows configurations.


147-154: Past review comment addressed.

The normalization for environment-based proxy URLs has been implemented as suggested in the previous review. The code now applies normalizeProxyUrl and normalizeNoProxy to registry-derived values.

packages/bruno-requests/src/network/system-proxy/utils/linux.ts (1)

11-57: LGTM - Robust Linux proxy detection.

The command injection prevention via AllowedLinuxCommands enum and the cascading detection strategy (GNOME GSettings → KDE → environment files → systemd) provide comprehensive coverage across different Linux desktop environments and configurations.

packages/bruno-requests/src/network/system-proxy/index.ts (2)

22-44: LGTM - Effective caching and concurrency control.

The implementation prevents duplicate concurrent detections by checking activeDetection (lines 29-31) and properly clears it in the finally block (line 42) after caching the result.


106-120: LGTM - Sensible environment variable precedence and error handling.

The function prioritizes environment variables (lines 107-113) over system detection, which is correct behavior. The try-catch fallback (lines 115-119) ensures a valid ProxyConfiguration is always returned, even if system detection fails.

packages/bruno-electron/src/utils/proxy-util.js (2)

337-340: Centralized httpProxyAgentOptions definition looks good

Pulling the HTTP proxy agent options (currently keepAlive: true) into a shared httpProxyAgentOptions constant keeps the setupProxyAgents branches consistent and makes it easier to tune behaviour in one place. No issues from a logic/readability standpoint.


365-368: Wiring TimelineHttpProxyAgent for explicit HTTP proxies is consistent with the new helper

The proxyMode === 'on' HTTP branch now instantiates TimelineHttpProxyAgent with { proxy: proxyUri, httpProxyAgentOptions }, which matches the expected shape of the new createTimelineHttpAgentClass helper and cleanly separates HTTP proxy handling from the TLS-aware TimelineHttpsProxyAgent.

Once the constructor of createTimelineHttpAgentClass is tightened up as suggested above, this call site should be safe and future-proof.

packages/bruno-cli/src/runner/run-single-request.js (1)

291-293: Harden system proxy handling: avoid hard failures on detection errors and surface invalid proxy config

Two coupled concerns here:

  1. Unprotected getSystemProxy() during mode selection can abort the whole request

When collectionProxyEnabled === 'global' you call getSystemProxy() outside a try/catch. If this call rejects (e.g., platform-specific detector fails), the error bubbles to the outermost runSingleRequest try/catch and the request is returned as an overall error instead of just falling back to direct connectivity. That's a behavioral regression relative to the "best-effort" nature of system proxies.

  1. Invalid system proxies are silently ignored

Inside the proxyMode === 'system' branch, thrown errors like 'Invalid system http_proxy' are immediately swallowed by the catch block at Line 385, which only sets request.httpsAgent without logging or rethrowing. Users won't see why system proxy was skipped.

  1. getSystemProxy() is called twice

You first call it while deciding proxyMode, then again inside the system branch. This duplication makes error handling unnecessarily complex.

Suggested direction

  • Fetch systemProxy once at initialization and reuse it throughout.
  • Wrap the initial detection in a local try/catch so a detector failure simply leaves proxyMode = 'off'.
  • Log invalid proxies instead of silently ignoring them.

Relevant sections: lines 305–311 (proxy mode selection), 352–385 (system proxy handling).

Copy link

@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)
packages/bruno-electron/src/utils/proxy-util.js (1)

136-141: Same credential redaction needed here.

The createTimelineAgentClass also logs proxy URIs at line 140. Apply the same credential redaction approach to avoid leaking secrets.

♻️ Duplicate comments (1)
packages/bruno-electron/src/utils/proxy-util.js (1)

99-104: Redact credentials from proxy URI before logging.

The proxy URI may contain embedded credentials (e.g., http://user:[email protected]:8080). Logging the full URI leaks secrets into the timeline. Consider parsing and redacting userinfo before logging.

+      // Redact credentials from proxy URI for logging
+      let safeProxyUri = proxyUri;
+      try {
+        const parsed = new URL(proxyUri);
+        if (parsed.username || parsed.password) {
+          parsed.username = parsed.username ? '***' : '';
+          parsed.password = parsed.password ? '***' : '';
+          safeProxyUri = parsed.toString();
+        }
+      } catch (e) {
+        // If parsing fails, use a generic message
+        safeProxyUri = '[proxy]';
+      }
       this.timeline.push({
         timestamp: new Date(),
         type: 'info',
-        message: `Using proxy: ${proxyUri}`
+        message: `Using proxy: ${safeProxyUri}`
       });

Based on past review comments, this concern was previously flagged.

🧹 Nitpick comments (7)
packages/bruno-electron/src/utils/proxy-util.js (1)

400-400: Minor formatting: add space after comma.

Per coding guidelines, maintain consistent spacing around spread operators.

-            { proxy: https_proxy,...tlsOptions },
+            { proxy: https_proxy, ...tlsOptions },
packages/bruno-app/src/components/Preferences/ProxySettings/index.js (1)

11-11: Consider simplifying the import path.

The /index suffix is unnecessary since ES modules resolve directory imports to index.js by default.

-import SystemProxy from './SystemProxy/index';
+import SystemProxy from './SystemProxy';
packages/bruno-app/src/components/Preferences/ProxySettings/SystemProxy/index.js (2)

10-12: Consider adding loading/error state handling.

The component dispatches the IPC call on mount but doesn't handle loading or error states. If the IPC call is slow or fails, users see stale or no data without feedback.

+const [isLoading, setIsLoading] = useState(true);
+
 useEffect(() => {
-  dispatch(getSystemProxyVariables());
+  dispatch(getSystemProxyVariables())
+    .finally(() => setIsLoading(false));
 }, [dispatch]);

You'd also need to import useState and conditionally render a loading indicator.


36-39: Nested ternary is hard to read.

Consider using a mapping object or switch statement for source label resolution.

+const SOURCE_LABELS = {
+  'environment': 'Environment Variables',
+  'windows-system': 'Windows System Settings',
+  'macos-system': 'macOS System Settings',
+  'linux-system': 'Linux System Settings'
+};

-{source === 'environment' ? 'Environment Variables'
-  : source === 'windows-system' ? 'Windows System Settings'
-    : source === 'macos-system' ? 'macOS System Settings'
-      : source === 'linux-system' ? 'Linux System Settings' : source}
+{SOURCE_LABELS[source] || source}
packages/bruno-requests/src/network/system-proxy/utils/windows.ts (1)

131-145: Use case-insensitive matching for registry proxy environment variable names.

Windows registry stores environment variable names case-insensitively but case-preservingly, so users may set http_proxy, Http_Proxy, or HTTP_PROXY when persisting these values. The current string matching only catches uppercase variants. Apply case-insensitive matching consistently:

-if (trimmedLine.includes('HTTP_PROXY') && trimmedLine.includes('REG_SZ')) {
-  const match = trimmedLine.match(/HTTP_PROXY\s+REG_SZ\s+(.+)/);
+if (trimmedLine.toUpperCase().includes('HTTP_PROXY') && trimmedLine.includes('REG_SZ')) {
+  const match = trimmedLine.match(/HTTP_PROXY\s+REG_SZ\s+(.+)/i);

Apply the same pattern to HTTPS_PROXY and NO_PROXY checks in both getSystemProxyEnvironment and getUserEnvironmentProxy.

packages/bruno-requests/src/network/system-proxy/utils/linux.ts (1)

206-223: Static analysis ReDoS warning is a false positive.

The proxyVars array is a hardcoded constant containing safe alphanumeric strings with underscores. No user input flows into the regex construction.

However, creating RegExp objects inside nested loops is inefficient. Consider pre-compiling the patterns:

+// Pre-compile patterns for proxy variable detection
+const PROXY_VAR_PATTERNS = ['http_proxy', 'https_proxy', 'no_proxy', 'all_proxy', 'HTTP_PROXY', 'HTTPS_PROXY', 'NO_PROXY', 'ALL_PROXY']
+  .flatMap((varName) => [
+    { varName: varName.toLowerCase(), pattern: new RegExp(`^export\\s+${varName}\\s*=\\s*(.+)$`, 'i') },
+    { varName: varName.toLowerCase(), pattern: new RegExp(`^${varName}\\s*=\\s*(.+)$`, 'i') }
+  ]);

 private parseProxyFromContent(content: string): ProxyConfiguration | null {
-  const proxyVars = ['http_proxy', 'https_proxy', 'no_proxy', 'all_proxy', 'HTTP_PROXY', 'HTTPS_PROXY', 'NO_PROXY', 'ALL_PROXY'];
   const proxies: Record<string, string> = {};
   // ...
   for (const line of lines) {
     // ... systemd handling ...
     
-    for (const varName of proxyVars) {
-      const patterns = [
-        new RegExp(`^export\\s+${varName}\\s*=\\s*(.+)$`, 'i'),
-        new RegExp(`^${varName}\\s*=\\s*(.+)$`, 'i')
-      ];
-      for (const pattern of patterns) {
-        const match = trimmedLine.match(pattern);
-        if (match) {
-          // ...
-        }
-      }
-    }
+    for (const { varName, pattern } of PROXY_VAR_PATTERNS) {
+      const match = trimmedLine.match(pattern);
+      if (match) {
+        let value = match[1].trim();
+        value = value.replace(/^["']|["']$/g, '');
+        proxies[varName] = value;
+        break;
+      }
+    }
   }
 }
packages/bruno-requests/src/network/system-proxy/utils/macos.ts (1)

101-109: Replace <local> with explicit bypass entries for cross-platform compatibility.

The <local> token is not a standard proxy bypass syntax—it's a Windows/IE-specific convention. macOS itself doesn't recognize it, and downstream consumers (curl, Docker, other platforms, or even Bruno's own proxy configuration serialization) won't interpret it correctly. Use explicit portable entries instead: localhost, 127.0.0.1, ::1, and any internal domain patterns. This ensures the bypass list works consistently across platforms.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 73ef5b7 and c23eb0b.

📒 Files selected for processing (24)
  • packages/bruno-app/src/components/Preferences/ProxySettings/SystemProxy/index.js (1 hunks)
  • packages/bruno-app/src/components/Preferences/ProxySettings/index.js (2 hunks)
  • packages/bruno-app/src/components/ResponsePane/index.js (1 hunks)
  • packages/bruno-app/src/providers/App/useIpcEvents.js (1 hunks)
  • packages/bruno-app/src/providers/ReduxStore/slices/app.js (4 hunks)
  • packages/bruno-cli/src/runner/run-single-request.js (4 hunks)
  • packages/bruno-cli/src/utils/proxy-util.js (1 hunks)
  • packages/bruno-electron/src/ipc/network/cert-utils.js (2 hunks)
  • packages/bruno-electron/src/ipc/preferences.js (2 hunks)
  • packages/bruno-electron/src/store/preferences.js (2 hunks)
  • packages/bruno-electron/src/utils/proxy-util.js (5 hunks)
  • packages/bruno-requests/src/index.ts (1 hunks)
  • packages/bruno-requests/src/network/index.ts (1 hunks)
  • packages/bruno-requests/src/network/system-proxy/index.spec.js (1 hunks)
  • packages/bruno-requests/src/network/system-proxy/index.ts (1 hunks)
  • packages/bruno-requests/src/network/system-proxy/types.ts (1 hunks)
  • packages/bruno-requests/src/network/system-proxy/utils/common.spec.ts (1 hunks)
  • packages/bruno-requests/src/network/system-proxy/utils/common.ts (1 hunks)
  • packages/bruno-requests/src/network/system-proxy/utils/linux.spec.ts (1 hunks)
  • packages/bruno-requests/src/network/system-proxy/utils/linux.ts (1 hunks)
  • packages/bruno-requests/src/network/system-proxy/utils/macos.spec.ts (1 hunks)
  • packages/bruno-requests/src/network/system-proxy/utils/macos.ts (1 hunks)
  • packages/bruno-requests/src/network/system-proxy/utils/windows.spec.ts (1 hunks)
  • packages/bruno-requests/src/network/system-proxy/utils/windows.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (12)
  • packages/bruno-electron/src/store/preferences.js
  • packages/bruno-requests/src/network/system-proxy/index.spec.js
  • packages/bruno-requests/src/network/system-proxy/utils/common.spec.ts
  • packages/bruno-requests/src/network/index.ts
  • packages/bruno-electron/src/ipc/preferences.js
  • packages/bruno-requests/src/network/system-proxy/index.ts
  • packages/bruno-requests/src/index.ts
  • packages/bruno-requests/src/network/system-proxy/utils/windows.spec.ts
  • packages/bruno-requests/src/network/system-proxy/utils/common.ts
  • packages/bruno-cli/src/runner/run-single-request.js
  • packages/bruno-app/src/providers/App/useIpcEvents.js
  • packages/bruno-requests/src/network/system-proxy/utils/linux.spec.ts
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (CODING_STANDARDS.md)

**/*.{js,jsx,ts,tsx}: Use 2 spaces for indentation. No tabs, just spaces
Stick to single quotes for strings
Always add semicolons at the end of statements
No trailing commas
Always use parentheses around parameters in arrow functions, even for single parameters
For multiline constructs, put opening braces on the same line, and ensure consistency. Minimum 2 elements for multiline
No newlines inside function parentheses. Keep 'em tight
Space before and after the arrow in arrow functions. () => {} is good
No space between function name and parentheses. func() not func ()
Semicolons go at the end of the line, not on a new line
Names for functions need to be concise and descriptive
Add in JSDoc comments to add more details to the abstractions if needed
Avoid single line abstractions where all that's being done is increasing the call stack with one additional function
Add in meaningful comments instead of obvious ones where complex code flow is explained properly

Files:

  • packages/bruno-app/src/components/ResponsePane/index.js
  • packages/bruno-cli/src/utils/proxy-util.js
  • packages/bruno-app/src/components/Preferences/ProxySettings/index.js
  • packages/bruno-requests/src/network/system-proxy/utils/macos.spec.ts
  • packages/bruno-requests/src/network/system-proxy/utils/macos.ts
  • packages/bruno-app/src/components/Preferences/ProxySettings/SystemProxy/index.js
  • packages/bruno-electron/src/utils/proxy-util.js
  • packages/bruno-app/src/providers/ReduxStore/slices/app.js
  • packages/bruno-requests/src/network/system-proxy/utils/linux.ts
  • packages/bruno-electron/src/ipc/network/cert-utils.js
  • packages/bruno-requests/src/network/system-proxy/types.ts
  • packages/bruno-requests/src/network/system-proxy/utils/windows.ts
🧬 Code graph analysis (8)
packages/bruno-app/src/components/Preferences/ProxySettings/index.js (1)
packages/bruno-app/src/components/Preferences/ProxySettings/SystemProxy/index.js (1)
  • SystemProxy (5-70)
packages/bruno-requests/src/network/system-proxy/utils/macos.spec.ts (1)
packages/bruno-requests/src/network/system-proxy/utils/macos.ts (1)
  • MacOSProxyDetector (8-118)
packages/bruno-requests/src/network/system-proxy/utils/macos.ts (2)
packages/bruno-requests/src/network/system-proxy/types.ts (2)
  • ProxyDetector (8-10)
  • ProxyConfiguration (1-6)
packages/bruno-requests/src/network/system-proxy/utils/common.ts (2)
  • normalizeProxyUrl (13-23)
  • normalizeNoProxy (30-40)
packages/bruno-app/src/components/Preferences/ProxySettings/SystemProxy/index.js (1)
packages/bruno-app/src/providers/ReduxStore/slices/app.js (2)
  • getSystemProxyVariables (201-210)
  • getSystemProxyVariables (201-210)
packages/bruno-electron/src/utils/proxy-util.js (1)
packages/bruno-cli/src/utils/proxy-util.js (3)
  • shouldUseProxy (16-63)
  • parsedUrl (26-26)
  • parseUrl (1-1)
packages/bruno-app/src/providers/ReduxStore/slices/app.js (2)
packages/bruno-app/src/utils/network/ws-event-listeners.js (1)
  • window (8-8)
packages/bruno-app/src/providers/App/ConfirmAppClose/index.js (1)
  • window (7-7)
packages/bruno-requests/src/network/system-proxy/utils/linux.ts (2)
packages/bruno-requests/src/network/system-proxy/types.ts (2)
  • ProxyDetector (8-10)
  • ProxyConfiguration (1-6)
packages/bruno-requests/src/network/system-proxy/utils/common.ts (2)
  • normalizeProxyUrl (13-23)
  • normalizeNoProxy (30-40)
packages/bruno-electron/src/ipc/network/cert-utils.js (3)
packages/bruno-requests/src/network/system-proxy/index.ts (2)
  • getSystemProxy (22-44)
  • getSystemProxy (106-120)
packages/bruno-electron/src/utils/proxy-util.js (1)
  • proxyConfig (381-381)
packages/bruno-app/src/components/CollectionSettings/index.js (1)
  • proxyConfig (42-42)
🪛 ast-grep (0.40.0)
packages/bruno-requests/src/network/system-proxy/utils/linux.ts

[warning] 208-208: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp(^export\\s+${varName}\\s*=\\s*(.+)$, 'i')
Note: [CWE-1333] Inefficient Regular Expression Complexity [REFERENCES]
- https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS
- https://cwe.mitre.org/data/definitions/1333.html

(regexp-from-variable)


[warning] 209-209: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp(^${varName}\\s*=\\s*(.+)$, 'i')
Note: [CWE-1333] Inefficient Regular Expression Complexity [REFERENCES]
- https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS
- https://cwe.mitre.org/data/definitions/1333.html

(regexp-from-variable)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: SSL Tests - Windows
  • GitHub Check: SSL Tests - macOS
  • GitHub Check: SSL Tests - Linux
  • GitHub Check: CLI Tests
  • GitHub Check: Playwright E2E Tests
  • GitHub Check: Unit Tests
🔇 Additional comments (25)
packages/bruno-electron/src/utils/proxy-util.js (3)

339-341: LGTM!

The httpProxyAgentOptions with keepAlive: true is appropriate for connection reuse.


367-369: LGTM!

The integration of TimelineHttpProxyAgent for HTTP proxy handling is consistent with the HTTPS proxy pattern.


381-413: System proxy logic looks correct.

The routing logic correctly:

  • Uses http_proxy for non-HTTPS requests
  • Uses https_proxy for HTTPS requests
  • Falls back to a standard HTTPS agent when no proxy applies

One note: ensure upstream callers provide proxyConfig with the expected shape ({ http_proxy, https_proxy, no_proxy }). The code already defends against missing proxyConfig with the proxyConfig || {} pattern, but verify callers consistently provide the required properties.

packages/bruno-electron/src/ipc/network/cert-utils.js (2)

4-4: Verification of getSystemProxy API import could not be completed.

The import addition appears structurally sound, but verification of the getSystemProxy API export and ProxyConfiguration type signature could not be performed due to repository access limitations. To ensure correctness, manually verify:

  • The getSystemProxy function is properly exported from @usebruno/requests
  • The returned ProxyConfiguration structure matches expectations in consuming code (especially proxy-util.js which destructures http_proxy, https_proxy, no_proxy)
  • Error handling from getSystemProxy() aligns with the application's proxy fallback strategy

116-119: Use strict equality for string comparison.

Line 116 should use strict equality (===) instead of loose equality (==). This follows JavaScript best practices and prevents unintended type coercion. Apply the following change:

-    if (proxyMode == 'system') {
+    if (proxyMode === 'system') {
       const systemProxyConfig = await getSystemProxy();
       proxyConfig = systemProxyConfig;
     }

Verify that getSystemProxy() returns an object with the standard Node.js proxy environment variable fields: http_proxy, https_proxy, and no_proxy.

packages/bruno-app/src/components/ResponsePane/index.js (1)

162-162: LGTM!

Good addition of data-testid for testing purposes. Clean and non-intrusive.

packages/bruno-app/src/components/Preferences/ProxySettings/index.js (1)

161-164: LGTM!

Clean integration of the SystemProxy component. The conditional rendering based on formik.values.mode === 'system' is appropriate.

packages/bruno-app/src/components/Preferences/ProxySettings/SystemProxy/index.js (1)

14-68: LGTM on the component structure.

The read-only display with fallbacks (|| '-') and clear user guidance about OS documentation is well done.

packages/bruno-requests/src/network/system-proxy/utils/macos.spec.ts (3)

1-22: LGTM on test setup.

Clean mocking of child_process and util modules. The beforeEach properly resets mocks between tests.


207-227: Test now properly validates malformed input handling.

The input at line 214 (HTTPSProxy proxy.usebruno.com) lacks the colon separator, correctly testing graceful degradation. The expectation that https_proxy is null while http_proxy is parsed confirms the parser handles partial malformation.


230-242: LGTM on error handling tests.

Good coverage of both command failure and invalid output scenarios.

packages/bruno-requests/src/network/system-proxy/utils/windows.ts (4)

9-14: Good security practice with command allowlist.

Using an enum to constrain shell commands prevents injection vulnerabilities. Clean approach.


25-44: LGTM on detection strategy waterfall.

The ordered fallback through four detection methods with graceful error handling is robust. Each method failing silently allows the next to attempt detection.


206-234: LGTM on parseProxyString implementation.

Correctly handles both protocol-specific (http=proxy1:8080;https=proxy2:8080) and single-proxy formats. Normalization is properly applied.


221-226: Verify single-proxy format for HTTPS.

When a single proxy is used for all protocols, both http_proxy and https_proxy get the same normalized URL. However, normalizeProxyUrl(proxyServer) defaults to http:// scheme. Downstream consumers expecting https:// for https_proxy may behave unexpectedly.

Is it intentional that https_proxy uses http:// scheme when a single proxy is configured? Some proxy clients require matching schemes.

packages/bruno-cli/src/utils/proxy-util.js (1)

82-85: Verify no remaining usages of removed getSystemProxyEnvVariables.

The export was removed from module.exports. Confirm no callers remain in the CLI package to avoid runtime errors.

packages/bruno-app/src/providers/ReduxStore/slices/app.js (2)

46-47: State shape update looks correct.

The rename from systemProxyEnvVariables to systemProxyVariables aligns with the broader refactor for system proxy detection.


93-95: Reducer rename is consistent.

updateSystemProxyVariables correctly updates the renamed state field.

packages/bruno-requests/src/network/system-proxy/utils/macos.ts (2)

8-22: Clean implementation of macOS proxy detection.

The detector correctly uses scutil --proxy, applies reasonable timeouts, and handles the dictionary output format. The use of normalizeProxyUrl and normalizeNoProxy from common utilities ensures consistency.


41-82: Parsing logic handles scutil output correctly.

The recursive dictionary and array parsing covers typical scutil --proxy output. One minor observation: if HTTPPort or HTTPSPort are explicitly set to 0 in the config, the fallback to default ports (80/443) would override that. This is likely acceptable since port 0 is invalid for proxies.

packages/bruno-requests/src/network/system-proxy/utils/linux.ts (4)

10-22: Good security practice with AllowedLinuxCommands enum.

Using an enum of pre-defined commands prevents command injection vulnerabilities. This is a solid pattern for system command execution.


32-56: Detection strategy chain is well-designed.

The fallback approach (GNOME → KDE → /etc/environment → systemd) covers major Linux environments. Swallowing errors per-method and continuing to the next is appropriate here.


59-91: GSettings parsing handles gsettings output quirks correctly.

The single-quote stripping on line 72 and array bracket handling on line 81 properly account for gsettings' output format.


146-173: Systemd proxy detection covers common config locations.

Reading from /etc/systemd/system.conf.d/ with fallback files is a reasonable approach. Note that this won't detect proxies set via systemctl set-environment, but that's acceptable for a file-based detection strategy.

packages/bruno-requests/src/network/system-proxy/types.ts (1)

1-15: Type definitions are well-structured.

Clear interfaces for ProxyConfiguration, ProxyDetector, and SystemProxyDetectorOptions. The source union type properly distinguishes between environment and platform-specific sources.

The question about SystemProxyDetectorOptions defining cacheTimeout and commandTimeout while ProxyDetector.detect() uses timeoutMs should be verified against the implementation to confirm these options are wired correctly and understand whether they serve different purposes (e.g., cache vs. command execution timeout) or if there's a naming inconsistency that needs alignment.

Copy link

@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

Caution

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

⚠️ Outside diff range comments (1)
packages/bruno-cli/src/runner/run-single-request.js (1)

304-313: Refactor to avoid duplicate system proxy fetch.

The system proxy is fetched twice:

  • Line 306: To determine if system proxy should be used
  • Line 353: To actually apply the system proxy configuration

This is inefficient and could lead to inconsistencies if the system proxy changes between calls. Cache the result from the first call and reuse it.

Apply this diff to cache and reuse the system proxy:

     let proxyMode = 'off';
     let proxyConfig = {};
+    let systemProxyConfig = null;
 
     const collectionProxyConfig = get(brunoConfig, 'proxy', {});
     const collectionProxyEnabled = get(collectionProxyConfig, 'enabled', false);
     
     if (noproxy) {
       // If noproxy flag is set, don't use any proxy
       proxyMode = 'off';
     } else if (collectionProxyEnabled === true) {
       // If collection proxy is enabled, use it
       proxyConfig = collectionProxyConfig;
       proxyMode = 'on';
     } else if (collectionProxyEnabled === 'global') {
       // If collection proxy is set to 'global', use system proxy
-      const systemProxy = await getSystemProxy();
-      const { http_proxy, https_proxy } = systemProxy;
+      systemProxyConfig = await getSystemProxy();
+      const { http_proxy, https_proxy } = systemProxyConfig;
       if (http_proxy?.length || https_proxy?.length) {
         proxyMode = 'system';
       }
     } else {
       proxyMode = 'off';
     }
 
     // ... existing code ...
 
     } else if (proxyMode === 'system') {
       try {
-        const systemProxy = await getSystemProxy();
-        const { http_proxy, https_proxy, no_proxy } = systemProxy;
+        const { http_proxy, https_proxy, no_proxy } = systemProxyConfig;
         const shouldUseSystemProxy = shouldUseProxy(request.url, no_proxy || '');

Also applies to: 351-389

♻️ Duplicate comments (2)
packages/bruno-requests/src/network/system-proxy/index.ts (1)

97-101: Avoid clearing activeDetection inside clearCache to preserve dedup semantics

If clearCache() is called while a detection is in progress, setting activeDetection = null allows the next getSystemProxy() call to start a second detection instead of reusing the in‑flight one. That defeats the in-flight dedup behavior and can cause duplicate work.

Since clearCache() cannot actually cancel the existing Promise, it’s safer to leave activeDetection untouched here and only reset the cached value and timestamp:

  clearCache(): void {
    this.cachedResult = null;
    this.cacheTimestamp = 0;
-    this.activeDetection = null;
  }

If you really need “force refresh even if one is in flight”, I’d make that an explicit API (e.g. refresh()) and document the semantics.

packages/bruno-electron/src/utils/proxy-util.js (1)

98-105: Avoid logging or throwing full proxy URIs that may contain credentials

Right now the timeline entries and error messages include the raw proxy URI. If the proxy URI contains user:pass@host, this will leak credentials into logs/timelines and possibly the UI.

Consider redacting userinfo before logging or including it in error text. One way to do this:

 class PatchedHttpsProxyAgent extends HttpsProxyAgent {
   constructor(proxy, opts) {
     super(proxy, opts);
     this.constructorOpts = opts;
   }
 }
 
+function redactProxyUri(uri) {
+  try {
+    const url = new URL(uri);
+    if (url.username || url.password) {
+      url.username = '***';
+      url.password = '***';
+    }
+    return url.toString();
+  } catch {
+    return uri;
+  }
+}
+
 function createTimelineHttpAgentClass(BaseAgentClass) {
@@
-      this.timeline.push({
-        timestamp: new Date(),
-        type: 'info',
-        message: `Using proxy: ${proxyUri}`
-      });
+      this.timeline.push({
+        timestamp: new Date(),
+        type: 'info',
+        message: `Using proxy: ${redactProxyUri(proxyUri)}`
+      });
-        this.timeline.push({
-          timestamp: new Date(),
-          type: 'info',
-          message: `Using proxy: ${proxyUri}`,
-        });
+        this.timeline.push({
+          timestamp: new Date(),
+          type: 'info',
+          message: `Using proxy: ${redactProxyUri(proxyUri)}`,
+        });
-        throw new Error(`Invalid system http_proxy "${http_proxy}": ${error.message}`);
+        throw new Error(`Invalid system http_proxy "${redactProxyUri(http_proxy)}": ${error.message}`);
-        throw new Error(`Invalid system https_proxy "${https_proxy}": ${error.message}`);
+        throw new Error(`Invalid system https_proxy "${redactProxyUri(https_proxy)}": ${error.message}`);

Also applies to: 137-141, 393-393, 408-408

🧹 Nitpick comments (8)
packages/bruno-cli/src/runner/run-single-request.js (1)

360-379: Consider simplifying nested try-catch blocks.

The nested try-catch blocks for http_proxy and https_proxy validation add complexity. While the logic is correct, consider extracting proxy validation to a helper function for better readability.

Example helper function:

const validateAndSetProxy = (proxyUrl, proxyType, agentType, agentOptions) => {
  try {
    if (proxyUrl?.length) {
      new URL(proxyUrl);
      if (agentType === 'http') {
        request.httpAgent = new HttpProxyAgent(proxyUrl);
      } else {
        request.httpsAgent = new PatchedHttpsProxyAgent(proxyUrl, agentOptions);
      }
      return true;
    }
    return false;
  } catch (error) {
    throw new Error(`Invalid system ${proxyType}_proxy`);
  }
};
packages/bruno-app/src/components/Preferences/ProxySettings/SystemProxy/index.js (1)

13-18: Move SOURCE_LABELS outside the component.

This constant is recreated on every render. Since it never changes, define it at module scope for better performance.

+const SOURCE_LABELS = {
+  'environment': 'Environment Variables',
+  'windows-system': 'Windows System Settings',
+  'macos-system': 'macOS System Settings',
+  'linux-system': 'Linux System Settings'
+};
+
 const SystemProxy = () => {
   const dispatch = useDispatch();
   const systemProxyVariables = useSelector((state) => state.app.systemProxyVariables);
   const { source, http_proxy, https_proxy, no_proxy } = systemProxyVariables || {};
   const [isFetching, setIsFetching] = useState(true);
   const [error, setError] = useState(null);
-
-  const SOURCE_LABELS = {
-    'environment': 'Environment Variables',
-    'windows-system': 'Windows System Settings',
-    'macos-system': 'macOS System Settings',
-    'linux-system': 'Linux System Settings'
-  };
packages/bruno-requests/src/network/system-proxy/utils/macos.ts (1)

41-82: Consider edge case: array terminator detection.

The array parsing loop at line 62 terminates on any line containing }. If an array element itself contains } (unlikely but possible in edge cases), parsing would terminate early.

This is a minor edge case since proxy exception lists typically contain hostnames/IPs, but worth noting.

packages/bruno-requests/src/network/system-proxy/types.ts (1)

1-6: Consider simplifying nullability syntax.

The fields use both ? (optional) and | null. This is redundant—? already allows undefined. If you want to explicitly allow null values (distinct from missing keys), the current approach is fine. Otherwise, simplify:

 export interface ProxyConfiguration {
-  http_proxy?: string | null;
-  https_proxy?: string | null;
-  no_proxy?: string | null;
+  http_proxy?: string;
+  https_proxy?: string;
+  no_proxy?: string;
   source: 'environment' | 'windows-system' | 'macos-system' | 'linux-system';
 }
packages/bruno-requests/src/network/system-proxy/utils/linux.ts (1)

153-180: Hardcoded systemd file paths may miss configurations.

The detector only checks proxy.conf and environment.conf in /etc/systemd/system.conf.d/. Some distributions or users may use different filenames.

Consider using readdir to scan all .conf files in the directory:

-      const systemdFiles = ['proxy.conf', 'environment.conf'];
+      const { readdir } = require('node:fs/promises');
+      const files = await readdir(systemdConfDir);
+      const systemdFiles = files.filter((f) => f.endsWith('.conf'));
packages/bruno-requests/src/network/system-proxy/index.ts (2)

16-20: Prefer ?? over || for numeric option defaults

Using || means an explicit 0 for cacheTimeout or commandTimeout is treated as “unset” and replaced with the default, which makes it impossible to intentionally disable caching/timeouts with 0.

You can make the intent clearer and allow 0 as a valid value by switching to nullish coalescing:

  constructor(options: SystemProxyDetectorOptions = {}) {
    this.platform = platform();
-    this.cacheTimeout = options.cacheTimeout || 60000; // 60 seconds default
-    this.commandTimeout = options.commandTimeout || 10000; // 10 seconds default
+    this.cacheTimeout = options.cacheTimeout ?? 60000; // 60 seconds default
+    this.commandTimeout = options.commandTimeout ?? 10000; // 10 seconds default
  }

65-67: detectWithTimeout is currently a pass‑through abstraction

Right now detectWithTimeout just forwards to detectByPlatform and adds only an extra stack frame. Given the guideline to avoid single-line abstractions, either:

  • Inline it in detectSystemProxy:
-      const result = await this.detectWithTimeout();
+      const result = await this.detectByPlatform();

and drop detectWithTimeout, or

  • Add actual timeout behavior here (e.g. Promise.race with a timer) and a short JSDoc explaining that it owns the timeout semantics.
packages/bruno-electron/src/utils/proxy-util.js (1)

86-96: Optional: simplify createTimelineHttpAgentClass options shape

The current pattern:

  • Call sites pass { proxy, httpProxyAgentOptions }.
  • The factory immediately unpacks { proxy: proxyUri, httpProxyAgentOptions } and forwards httpProxyAgentOptions to super.

Functionally this is fine, but you could make the HTTP factory mirror createTimelineAgentClass and accept { proxy, ...agentOptions }, merging in keepAlive: true internally. That would:

  • Remove the extra httpProxyAgentOptions wrapper, and
  • Keep the “options” contract consistent across the timeline agent factories.

Purely a readability/API-tidy suggestion; not a blocker.

Also applies to: 339-341, 367-370, 387-391

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c23eb0b and 5f3416b.

📒 Files selected for processing (24)
  • packages/bruno-app/src/components/Preferences/ProxySettings/SystemProxy/index.js (1 hunks)
  • packages/bruno-app/src/components/Preferences/ProxySettings/index.js (2 hunks)
  • packages/bruno-app/src/components/ResponsePane/index.js (1 hunks)
  • packages/bruno-app/src/providers/App/useIpcEvents.js (1 hunks)
  • packages/bruno-app/src/providers/ReduxStore/slices/app.js (4 hunks)
  • packages/bruno-cli/src/runner/run-single-request.js (4 hunks)
  • packages/bruno-cli/src/utils/proxy-util.js (1 hunks)
  • packages/bruno-electron/src/ipc/network/cert-utils.js (2 hunks)
  • packages/bruno-electron/src/ipc/preferences.js (2 hunks)
  • packages/bruno-electron/src/store/preferences.js (2 hunks)
  • packages/bruno-electron/src/utils/proxy-util.js (4 hunks)
  • packages/bruno-requests/src/index.ts (1 hunks)
  • packages/bruno-requests/src/network/index.ts (1 hunks)
  • packages/bruno-requests/src/network/system-proxy/index.spec.js (1 hunks)
  • packages/bruno-requests/src/network/system-proxy/index.ts (1 hunks)
  • packages/bruno-requests/src/network/system-proxy/types.ts (1 hunks)
  • packages/bruno-requests/src/network/system-proxy/utils/common.spec.ts (1 hunks)
  • packages/bruno-requests/src/network/system-proxy/utils/common.ts (1 hunks)
  • packages/bruno-requests/src/network/system-proxy/utils/linux.spec.ts (1 hunks)
  • packages/bruno-requests/src/network/system-proxy/utils/linux.ts (1 hunks)
  • packages/bruno-requests/src/network/system-proxy/utils/macos.spec.ts (1 hunks)
  • packages/bruno-requests/src/network/system-proxy/utils/macos.ts (1 hunks)
  • packages/bruno-requests/src/network/system-proxy/utils/windows.spec.ts (1 hunks)
  • packages/bruno-requests/src/network/system-proxy/utils/windows.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (8)
  • packages/bruno-requests/src/network/system-proxy/utils/macos.spec.ts
  • packages/bruno-requests/src/network/system-proxy/utils/common.spec.ts
  • packages/bruno-cli/src/utils/proxy-util.js
  • packages/bruno-app/src/providers/App/useIpcEvents.js
  • packages/bruno-app/src/providers/ReduxStore/slices/app.js
  • packages/bruno-app/src/components/ResponsePane/index.js
  • packages/bruno-requests/src/network/system-proxy/index.spec.js
  • packages/bruno-requests/src/network/system-proxy/utils/common.ts
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (CODING_STANDARDS.md)

**/*.{js,jsx,ts,tsx}: Use 2 spaces for indentation. No tabs, just spaces
Stick to single quotes for strings
Always add semicolons at the end of statements
No trailing commas
Always use parentheses around parameters in arrow functions, even for single parameters
For multiline constructs, put opening braces on the same line, and ensure consistency. Minimum 2 elements for multiline
No newlines inside function parentheses. Keep 'em tight
Space before and after the arrow in arrow functions. () => {} is good
No space between function name and parentheses. func() not func ()
Semicolons go at the end of the line, not on a new line
Names for functions need to be concise and descriptive
Add in JSDoc comments to add more details to the abstractions if needed
Avoid single line abstractions where all that's being done is increasing the call stack with one additional function
Add in meaningful comments instead of obvious ones where complex code flow is explained properly

Files:

  • packages/bruno-electron/src/store/preferences.js
  • packages/bruno-app/src/components/Preferences/ProxySettings/index.js
  • packages/bruno-requests/src/network/system-proxy/utils/windows.ts
  • packages/bruno-requests/src/network/system-proxy/index.ts
  • packages/bruno-requests/src/network/system-proxy/types.ts
  • packages/bruno-electron/src/ipc/network/cert-utils.js
  • packages/bruno-app/src/components/Preferences/ProxySettings/SystemProxy/index.js
  • packages/bruno-cli/src/runner/run-single-request.js
  • packages/bruno-requests/src/network/system-proxy/utils/windows.spec.ts
  • packages/bruno-electron/src/utils/proxy-util.js
  • packages/bruno-requests/src/network/system-proxy/utils/linux.spec.ts
  • packages/bruno-electron/src/ipc/preferences.js
  • packages/bruno-requests/src/network/index.ts
  • packages/bruno-requests/src/network/system-proxy/utils/macos.ts
  • packages/bruno-requests/src/network/system-proxy/utils/linux.ts
  • packages/bruno-requests/src/index.ts
🧠 Learnings (1)
📚 Learning: 2025-12-02T07:26:37.751Z
Learnt from: CR
Repo: usebruno/bruno PR: 0
File: CODING_STANDARDS.md:0-0
Timestamp: 2025-12-02T07:26:37.751Z
Learning: Applies to **/*.{js,jsx,ts,tsx} : Add in meaningful comments instead of obvious ones where complex code flow is explained properly

Applied to files:

  • packages/bruno-requests/src/network/system-proxy/utils/linux.spec.ts
🧬 Code graph analysis (8)
packages/bruno-electron/src/store/preferences.js (1)
packages/bruno-cli/src/runner/prepare-request.js (1)
  • get (1-1)
packages/bruno-requests/src/network/system-proxy/types.ts (1)
packages/bruno-requests/src/network/system-proxy/index.ts (1)
  • ProxyConfiguration (122-122)
packages/bruno-electron/src/ipc/network/cert-utils.js (3)
packages/bruno-requests/src/index.ts (1)
  • getSystemProxy (10-10)
packages/bruno-requests/src/network/index.ts (1)
  • getSystemProxy (3-3)
packages/bruno-requests/src/network/system-proxy/index.ts (2)
  • getSystemProxy (22-44)
  • getSystemProxy (106-120)
packages/bruno-app/src/components/Preferences/ProxySettings/SystemProxy/index.js (1)
packages/bruno-app/src/providers/ReduxStore/slices/app.js (2)
  • getSystemProxyVariables (201-211)
  • getSystemProxyVariables (201-211)
packages/bruno-electron/src/utils/proxy-util.js (1)
packages/bruno-cli/src/utils/proxy-util.js (3)
  • shouldUseProxy (16-63)
  • parsedUrl (26-26)
  • parseUrl (1-1)
packages/bruno-requests/src/network/system-proxy/utils/linux.spec.ts (2)
packages/bruno-requests/src/network/system-proxy/index.spec.js (1)
  • detector (11-11)
packages/bruno-requests/src/network/system-proxy/utils/linux.ts (1)
  • LinuxProxyDetector (31-244)
packages/bruno-electron/src/ipc/preferences.js (2)
packages/bruno-requests/src/index.ts (1)
  • getSystemProxy (10-10)
packages/bruno-requests/src/network/system-proxy/index.ts (2)
  • getSystemProxy (22-44)
  • getSystemProxy (106-120)
packages/bruno-requests/src/network/system-proxy/utils/macos.ts (2)
packages/bruno-requests/src/network/system-proxy/types.ts (2)
  • ProxyDetector (8-10)
  • ProxyConfiguration (1-6)
packages/bruno-requests/src/network/system-proxy/utils/common.ts (2)
  • normalizeProxyUrl (13-23)
  • normalizeNoProxy (30-40)
🪛 ast-grep (0.40.0)
packages/bruno-requests/src/network/system-proxy/utils/linux.ts

[warning] 26-26: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp(^export\\s+${varName}\\s*=\\s*(.+)$, 'i')
Note: [CWE-1333] Inefficient Regular Expression Complexity [REFERENCES]
- https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS
- https://cwe.mitre.org/data/definitions/1333.html

(regexp-from-variable)


[warning] 27-27: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp(^${varName}\\s*=\\s*(.+)$, 'i')
Note: [CWE-1333] Inefficient Regular Expression Complexity [REFERENCES]
- https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS
- https://cwe.mitre.org/data/definitions/1333.html

(regexp-from-variable)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: CLI Tests
  • GitHub Check: SSL Tests - Windows
  • GitHub Check: Playwright E2E Tests
  • GitHub Check: SSL Tests - macOS
  • GitHub Check: SSL Tests - Linux
  • GitHub Check: Unit Tests
🔇 Additional comments (24)
packages/bruno-electron/src/store/preferences.js (1)

30-30: LGTM!

The default proxy mode change to 'system' is consistent across both the defaultPreferences object and the getGlobalProxyConfig fallback. The validation schema already supports this value.

Also applies to: 195-195

packages/bruno-requests/src/network/index.ts (1)

1-3: LGTM!

Clean export structure for the network module's public API.

packages/bruno-app/src/components/Preferences/ProxySettings/index.js (1)

11-11: LGTM!

Clean refactoring that delegates system proxy rendering to a dedicated component, improving modularity and maintainability.

Also applies to: 163-163

packages/bruno-requests/src/index.ts (1)

8-10: LGTM!

The new getSystemProxy export expands the public API surface appropriately for the system proxy feature.

packages/bruno-electron/src/ipc/preferences.js (1)

52-55: LGTM!

Clean on-demand IPC handler for system proxy data. The async implementation is correct, and this approach is more efficient than the previous eager-loading pattern.

packages/bruno-requests/src/network/system-proxy/utils/windows.spec.ts (1)

1-400: LGTM!

Comprehensive test suite with excellent coverage of Windows proxy detection scenarios:

  • Multiple detection sources (Registry, WinHTTP, Environment variables)
  • Edge cases (protocol prefixes, empty bypass lists, disabled proxies)
  • Error handling (access denied, malformed output)

The test organization is clear and the mock setup is appropriate for testing system-level operations.

packages/bruno-app/src/components/Preferences/ProxySettings/SystemProxy/index.js (2)

20-25: LGTM on the data fetch pattern.

The useEffect properly dispatches, handles errors, and cleans up loading state via .finally(). The dispatch dependency is correctly included.


27-89: Clean UI implementation with proper error and loading states.

The component correctly handles all display states: loading spinner, error banner, and the read-only proxy values. The fallback to '-' for empty values is user-friendly.

packages/bruno-requests/src/network/system-proxy/utils/windows.ts (4)

8-14: Good use of command allowlist to prevent injection.

The enum constrains shell commands to a fixed set, mitigating command injection risks.


25-50: Detection cascade is well structured.

The ordered fallback approach ensures robust detection across different Windows proxy configurations. Error handling correctly continues to the next method on failure.


147-154: Normalization applied correctly after previous review feedback.

The environment registry methods now properly normalize URLs via normalizeProxyUrl and normalizeNoProxy, ensuring consistent output format.

Also applies to: 191-198


222-227: The suggestion is not necessary; using the same proxy address for both HTTP and HTTPS traffic is standard behavior.

When a single proxy is configured in Windows Internet Options, the same proxy address (host:port) is applied to both HTTP and HTTPS traffic. The protocol prefix (http=, https=) indicates the traffic type, not a different proxy server. Setting both http_proxy and https_proxy to the same normalized URL is correct and aligns with Windows proxy conventions.

Likely an incorrect or invalid review comment.

packages/bruno-requests/src/network/system-proxy/utils/linux.spec.ts (2)

1-38: Comprehensive mock setup for Linux detector tests.

The mocking strategy correctly isolates the detector from system dependencies. Using jest.clearAllMocks() in beforeEach ensures clean state between tests.


93-99: Stray comment removed as per previous review.

The // ? debug marker flagged in the past review is no longer present.

packages/bruno-requests/src/network/system-proxy/utils/macos.ts (2)

71-75: Dead code branches removed as per previous review.

The boolean parsing branches for '1' and '0' that were unreachable have been cleaned up. The logic now correctly parses integers and falls back to string values.


84-117: Solid proxy configuration building logic.

The method correctly:

  • Checks enable flags before using proxy values
  • Applies sensible port defaults (80/443)
  • Handles ExceptionsList arrays
  • Appends <local> for ExcludeSimpleHostnames
  • Normalizes output via helper functions
packages/bruno-requests/src/network/system-proxy/types.ts (1)

8-15: Well-defined interfaces for the detector pattern.

The ProxyDetector interface provides a clean contract for platform-specific implementations. SystemProxyDetectorOptions offers sensible configuration points.

packages/bruno-requests/src/network/system-proxy/utils/linux.ts (5)

24-29: Static analysis ReDoS warning is a false positive.

The varName values come from a hardcoded array of known proxy variable names, not user input. The patterns are safe.


10-22: Good command allowlist with stderr suppression.

The enum constrains commands and redirects stderr to /dev/null to handle missing tools gracefully.


66-99: Well-implemented gsettings detection.

Correctly checks for 'manual' mode before reading proxy values. The quote stripping and ignore-hosts parsing are handled properly.


101-139: KDE proxy detection with clear type documentation.

The ProxyType value comments are helpful. Only manual configuration (type 1) is handled, which is appropriate for deterministic proxy settings.


182-243: Robust content parsing with multiple format support.

The parseProxyFromContent method handles:

  • Shell variable formats (VAR=value, export VAR=value)
  • Quoted values (single and double)
  • Systemd directives (Environment=, DefaultEnvironment=)
  • ALL_PROXY fallback

The implementation is thorough.

packages/bruno-requests/src/network/system-proxy/index.ts (1)

104-120: Environment‑first singleton API looks solid

The exported getSystemProxy correctly:

  • Reads and normalizes env proxy variables once
  • Short‑circuits to env when http_proxy/https_proxy (or all_proxy) are present
  • Falls back to the shared SystemProxyDetector and degrades to env again on error

This is a good, resilient shape for callers in CLI/Electron contexts.

packages/bruno-electron/src/utils/proxy-util.js (1)

381-385: Confirm invariants for requestConfig.url and proxyConfig in system proxy mode

This branch assumes:

  • requestConfig.url is always a non-empty string (used directly in parseUrl(requestConfig.url)), and
  • proxyConfig carries lowercase keys http_proxy, https_proxy, no_proxy.

If those invariants ever change (e.g. url missing/undefined, or keys normalized differently), this block can either throw earlier than expected or silently skip the system proxy.

If that’s not already enforced at the call site, consider a light guard here (early-return if !requestConfig.url) or normalizing proxyConfig keys once upstream.

Also applies to: 387-391, 396-408

Copy link

@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: 4

♻️ Duplicate comments (2)
packages/bruno-requests/src/network/system-proxy/utils/linux.spec.ts (1)

154-182: Mock ordering may cause flaky behavior.

The mockReturnValue(false) at line 161 sets the default, but execution order matters: getEnvironmentFileProxy checks /etc/environment before getSystemdProxy checks the systemd directory. The mockReturnValueOnce calls at lines 164 and 167 may not align with actual call order.

Use path-based mock or explicit sequential ordering:

-      // Mock all previous methods to fail
-      mockExistsSync.mockReturnValue(false);
-
-      // Mock systemd conf directory to exist
-      mockExistsSync.mockReturnValueOnce(true);
-
-      // Mock systemd proxy file to exist
-      mockExistsSync.mockReturnValueOnce(true);
+      // Mock /etc/environment to not exist, then systemd dir and file to exist
+      mockExistsSync
+        .mockReturnValueOnce(false)  // /etc/environment
+        .mockReturnValueOnce(true)   // /etc/systemd/system.conf.d
+        .mockReturnValueOnce(true);  // proxy.conf file
packages/bruno-electron/src/utils/proxy-util.js (1)

86-107: Redact credentials from proxy URI before logging.

The super() issue from the previous review has been resolved—the constructor now either throws before super() (which is valid) or calls super() before accessing this.

However, the credential leakage issue remains: Line 103 logs the full proxyUri, which may contain credentials in the format http://user:[email protected]. Redact the userinfo portion before adding it to the timeline.

Apply this diff to redact credentials:

+      // Redact credentials from proxy URI for logging
+      const redactedProxyUri = proxyUri.replace(/\/\/([^:]+):([^@]+)@/, '//$1:***@');
+
       this.timeline = Array.isArray(timeline) ? timeline : [];
       // Log the proxy details
       this.timeline.push({
         timestamp: new Date(),
         type: 'info',
-        message: `Using proxy: ${proxyUri}`
+        message: `Using proxy: ${redactedProxyUri}`
       });
🧹 Nitpick comments (1)
packages/bruno-requests/src/network/system-proxy/index.ts (1)

58-69: Consider instantiating platform resolvers once.

New resolver instances are created on each detection call. For better efficiency, instantiate them once during construction and reuse.

 export class SystemProxyResolver {
   private platform: string;
   private commandTimeout: number;
+  private windowsResolver?: WindowsProxyResolver;
+  private macosResolver?: MacOSProxyResolver;
+  private linuxResolver?: LinuxProxyResolver;
   private activeDetection: Promise<ProxyConfiguration> | null = null;

   constructor(options: SystemProxyResolverOptions = {}) {
     this.platform = platform();
     this.commandTimeout = options.commandTimeout || 10000;
+    // Initialize platform-specific resolver
+    if (this.platform === 'win32') {
+      this.windowsResolver = new WindowsProxyResolver();
+    } else if (this.platform === 'darwin') {
+      this.macosResolver = new MacOSProxyResolver();
+    } else if (this.platform === 'linux') {
+      this.linuxResolver = new LinuxProxyResolver();
+    }
   }
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5f3416b and 2c17f1d.

📒 Files selected for processing (24)
  • packages/bruno-app/src/components/Preferences/ProxySettings/SystemProxy/index.js (1 hunks)
  • packages/bruno-app/src/components/Preferences/ProxySettings/index.js (2 hunks)
  • packages/bruno-app/src/components/ResponsePane/index.js (1 hunks)
  • packages/bruno-app/src/providers/App/useIpcEvents.js (1 hunks)
  • packages/bruno-app/src/providers/ReduxStore/slices/app.js (4 hunks)
  • packages/bruno-cli/src/runner/run-single-request.js (3 hunks)
  • packages/bruno-cli/src/utils/proxy-util.js (1 hunks)
  • packages/bruno-electron/src/ipc/network/cert-utils.js (2 hunks)
  • packages/bruno-electron/src/ipc/preferences.js (2 hunks)
  • packages/bruno-electron/src/store/preferences.js (2 hunks)
  • packages/bruno-electron/src/utils/proxy-util.js (4 hunks)
  • packages/bruno-requests/src/index.ts (1 hunks)
  • packages/bruno-requests/src/network/index.ts (1 hunks)
  • packages/bruno-requests/src/network/system-proxy/index.spec.js (1 hunks)
  • packages/bruno-requests/src/network/system-proxy/index.ts (1 hunks)
  • packages/bruno-requests/src/network/system-proxy/types.ts (1 hunks)
  • packages/bruno-requests/src/network/system-proxy/utils/common.spec.ts (1 hunks)
  • packages/bruno-requests/src/network/system-proxy/utils/common.ts (1 hunks)
  • packages/bruno-requests/src/network/system-proxy/utils/linux.spec.ts (1 hunks)
  • packages/bruno-requests/src/network/system-proxy/utils/linux.ts (1 hunks)
  • packages/bruno-requests/src/network/system-proxy/utils/macos.spec.ts (1 hunks)
  • packages/bruno-requests/src/network/system-proxy/utils/macos.ts (1 hunks)
  • packages/bruno-requests/src/network/system-proxy/utils/windows.spec.ts (1 hunks)
  • packages/bruno-requests/src/network/system-proxy/utils/windows.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (15)
  • packages/bruno-app/src/components/ResponsePane/index.js
  • packages/bruno-electron/src/ipc/network/cert-utils.js
  • packages/bruno-requests/src/network/system-proxy/utils/macos.spec.ts
  • packages/bruno-app/src/components/Preferences/ProxySettings/SystemProxy/index.js
  • packages/bruno-requests/src/index.ts
  • packages/bruno-cli/src/runner/run-single-request.js
  • packages/bruno-requests/src/network/system-proxy/types.ts
  • packages/bruno-cli/src/utils/proxy-util.js
  • packages/bruno-requests/src/network/index.ts
  • packages/bruno-requests/src/network/system-proxy/utils/common.spec.ts
  • packages/bruno-requests/src/network/system-proxy/utils/common.ts
  • packages/bruno-app/src/providers/ReduxStore/slices/app.js
  • packages/bruno-app/src/providers/App/useIpcEvents.js
  • packages/bruno-app/src/components/Preferences/ProxySettings/index.js
  • packages/bruno-electron/src/store/preferences.js
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (CODING_STANDARDS.md)

**/*.{js,jsx,ts,tsx}: Use 2 spaces for indentation, never tabs
Use single quotes for strings instead of double quotes
Always add semicolons at the end of statements
No trailing commas in code
Always use parentheses around parameters in arrow functions, even for single parameters
For multiline constructs, put opening braces on the same line with a minimum of 2 elements for multiline formatting
No newlines inside function parentheses
Space before and after the arrow in arrow functions: () => {}
No space between function name and parentheses: func() not func ()
Semicolons should go at the end of the line, not on a new line
Function names should be concise and descriptive
Add JSDoc comments to provide details to abstractions
Avoid single-line abstractions where all that is being done is increasing the call stack with one additional function
Add meaningful comments to explain complex code flow instead of obvious comments

Files:

  • packages/bruno-requests/src/network/system-proxy/utils/windows.ts
  • packages/bruno-requests/src/network/system-proxy/utils/linux.spec.ts
  • packages/bruno-electron/src/ipc/preferences.js
  • packages/bruno-requests/src/network/system-proxy/utils/macos.ts
  • packages/bruno-requests/src/network/system-proxy/utils/linux.ts
  • packages/bruno-requests/src/network/system-proxy/index.spec.js
  • packages/bruno-electron/src/utils/proxy-util.js
  • packages/bruno-requests/src/network/system-proxy/index.ts
  • packages/bruno-requests/src/network/system-proxy/utils/windows.spec.ts
**/*.{test,spec}.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (CODING_STANDARDS.md)

Add tests for any new functionality or meaningful changes; update corresponding tests when code is added, removed, or significantly modified

Files:

  • packages/bruno-requests/src/network/system-proxy/utils/linux.spec.ts
  • packages/bruno-requests/src/network/system-proxy/index.spec.js
  • packages/bruno-requests/src/network/system-proxy/utils/windows.spec.ts
🧠 Learnings (1)
📚 Learning: 2025-12-03T08:09:57.124Z
Learnt from: CR
Repo: usebruno/bruno PR: 0
File: CODING_STANDARDS.md:0-0
Timestamp: 2025-12-03T08:09:57.124Z
Learning: Applies to **/*.{test,spec}.{js,jsx,ts,tsx} : Add tests for any new functionality or meaningful changes; update corresponding tests when code is added, removed, or significantly modified

Applied to files:

  • packages/bruno-requests/src/network/system-proxy/utils/linux.spec.ts
  • packages/bruno-requests/src/network/system-proxy/index.spec.js
  • packages/bruno-requests/src/network/system-proxy/utils/windows.spec.ts
🧬 Code graph analysis (3)
packages/bruno-requests/src/network/system-proxy/utils/linux.spec.ts (1)
packages/bruno-requests/src/network/system-proxy/utils/linux.ts (1)
  • LinuxProxyResolver (31-245)
packages/bruno-electron/src/utils/proxy-util.js (1)
packages/bruno-cli/src/utils/proxy-util.js (2)
  • shouldUseProxy (16-63)
  • parseUrl (1-1)
packages/bruno-requests/src/network/system-proxy/utils/windows.spec.ts (1)
packages/bruno-requests/src/network/system-proxy/utils/windows.ts (1)
  • WindowsProxyResolver (16-236)
🪛 ast-grep (0.40.0)
packages/bruno-requests/src/network/system-proxy/utils/linux.ts

[warning] 26-26: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp(^export\\s+${varName}\\s*=\\s*(.+)$, 'i')
Note: [CWE-1333] Inefficient Regular Expression Complexity [REFERENCES]
- https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS
- https://cwe.mitre.org/data/definitions/1333.html

(regexp-from-variable)


[warning] 27-27: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp(^${varName}\\s*=\\s*(.+)$, 'i')
Note: [CWE-1333] Inefficient Regular Expression Complexity [REFERENCES]
- https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS
- https://cwe.mitre.org/data/definitions/1333.html

(regexp-from-variable)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: Playwright E2E Tests
  • GitHub Check: CLI Tests
  • GitHub Check: Unit Tests
  • GitHub Check: SSL Tests - Linux
  • GitHub Check: SSL Tests - macOS
  • GitHub Check: SSL Tests - Windows
🔇 Additional comments (39)
packages/bruno-requests/src/network/system-proxy/utils/linux.spec.ts (3)

1-38: LGTM! Test setup is well-structured.

Mocks are correctly configured for all required dependencies, and the beforeEach properly initializes the detector and clears mocks between tests.


40-126: LGTM! gsettings test coverage is thorough.

Tests properly cover manual proxy detection, identical proxies, non-manual mode fallback, and empty ignore hosts scenarios.


185-222: LGTM! Error handling tests are comprehensive.

Covers gsettings unavailable, schema not installed, and no configuration found scenarios.

packages/bruno-requests/src/network/system-proxy/utils/windows.spec.ts (5)

1-23: LGTM! Clean test setup.

Mock configuration and beforeEach initialization are correct.


24-84: LGTM! Registry detection tests are thorough.

Covers single proxy, protocol-specific proxy, and fallback to WinHTTP scenarios.


86-157: LGTM! WinHTTP detection coverage is solid.

Tests direct access handling, single/protocol-specific proxies, and "(none)" bypass list correctly.


159-229: LGTM! Environment detection tests are complete.

Covers system-wide and user-specific proxy environment variables with proper fallback chain.


231-399: LGTM! Edge cases and error handling are comprehensive.

Good coverage of prefix handling, decimal ProxyEnable values, malformed output, and complex bypass lists.

packages/bruno-electron/src/ipc/preferences.js (1)

6-7: LGTM! Import added correctly.

packages/bruno-requests/src/network/system-proxy/utils/windows.ts (7)

1-14: LGTM! Clean setup with injection prevention.

Using an enum for allowed commands is a good security practice.


16-50: LGTM! Detection flow is well-structured.

Ordered fallback chain with proper error handling at each step.


52-92: LGTM! Registry parsing handles edge cases correctly.

Supports both hex (0x1) and decimal (1) ProxyEnable values.


94-116: LGTM! WinHTTP detection is robust.

Correctly identifies "Direct access" as no-proxy scenario.


118-160: LGTM! System environment detection with proper normalization.

The past review issue regarding missing normalization has been addressed.


162-204: LGTM! User environment detection mirrors system environment logic.

Consistent implementation with proper normalization.


206-236: LGTM! Proxy string parsing handles both formats correctly.

Protocol-specific (http=...;https=...) and single proxy formats are properly handled.

packages/bruno-requests/src/network/system-proxy/index.spec.js (4)

1-35: LGTM! Test setup and teardown are correct.

Timer cleanup order is now proper: runOnlyPendingTimers() executes pending timers before clearAllTimers() removes them.


37-78: LGTM! Environment variable tests are thorough.

Covers lowercase/uppercase priority, fallback behavior, and null handling.


80-116: LGTM! Platform routing tests verify correct detector delegation.

Each platform test properly mocks os.platform() and verifies the correct resolver is invoked.


118-169: LGTM! Error handling and fallback tests are comprehensive.

Covers detection failure fallback and timeout graceful handling.

packages/bruno-requests/src/network/system-proxy/utils/macos.ts (4)

1-22: LGTM! Clean setup with proper timeout handling.

Uses scutil --proxy for macOS proxy detection with configurable timeout.


24-39: LGTM! Output parsing is robust.

Validates input, finds dictionary section, and delegates to parsing helpers.


41-82: LGTM! Configuration parsing handles all value types.

Arrays, integers, and strings are correctly parsed from scutil output.


84-118: LGTM! Proxy configuration builder is correct.

Properly handles HTTP/HTTPS enables, default ports, ExceptionsList, and ExcludeSimpleHostnames.

packages/bruno-requests/src/network/system-proxy/utils/linux.ts (6)

1-29: LGTM! Safe command enumeration and pattern precompilation.

The static analysis ReDoS warning on lines 26-27 is a false positive—varName comes from a hardcoded array of trusted proxy variable names (http_proxy, https_proxy, etc.), not user input. The patterns are compiled once at module load time.


31-64: LGTM! Detection flow with proper fallback chain.

Tries gsettings → KDE → /etc/environment → systemd in order, returning on first success.


66-99: LGTM! gsettings parsing handles GNOME proxy settings correctly.

Properly checks for manual mode and cleans quoted values.


101-139: LGTM! KDE proxy detection is well-documented.

ProxyType value meanings are documented, and only manual configuration (type 1) is handled.


141-181: LGTM! File-based proxy detection is robust.

Both /etc/environment and systemd configuration directory are checked with proper null guards.


183-245: LGTM! Content parsing handles multiple formats.

Supports shell VAR=value, export VAR=value, and systemd Environment= directives with proper quote removal. ALL_PROXY fallback is correctly implemented.

packages/bruno-requests/src/network/system-proxy/index.ts (6)

1-6: LGTM!

Imports are well-organized and follow the coding guidelines.


8-16: LGTM!

Class structure and constructor are clean. The 10-second default timeout is reasonable for system proxy detection.


18-33: LGTM!

In-flight deduplication is correctly implemented. The finally block ensures activeDetection is cleared after the promise settles, preventing duplicate concurrent detections.


71-84: LGTM!

Environment variable handling is comprehensive with proper fallback chain and normalization.


87-103: LGTM!

The singleton pattern and environment variable precedence are appropriate. Environment variables correctly take precedence over system detection, matching expected behavior for proxy configuration in most CLI tools.


105-105: LGTM!

Type re-export for convenience.

packages/bruno-electron/src/utils/proxy-util.js (3)

339-341: LGTM—keepAlive for HTTP proxy agents.

The httpProxyAgentOptions with keepAlive: true improves connection reuse for HTTP proxy agents.


380-391: System proxy protocol detection looks correct.

The logic correctly routes http_proxy to non-HTTPS requests (Line 387: !isHttpsRequest) and https_proxy to HTTPS requests (Line 396), aligning with standard proxy conventions. URL validation with new URL() is appropriate.


396-406: HTTPS proxy setup properly uses PatchedHttpsProxyAgent.

The conditional application of https_proxy only for HTTPS requests (Line 396: isHttpsRequest) and the use of PatchedHttpsProxyAgent with tlsOptions ensure TLS settings are correctly propagated. The fallback to a regular HTTPS agent (lines 403-406) is appropriate.

Comment on lines +51 to +55

ipcMain.handle('renderer:get-system-proxy-variables', async () => {
const systemProxyConfig = await getSystemProxy();
return systemProxyConfig;
});
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Add error handling to prevent unhandled rejection.

If getSystemProxy() throws (e.g., detection fails on all platforms), the renderer receives an unhandled promise rejection. Wrap in try/catch to return a graceful fallback or propagate a meaningful error.

   ipcMain.handle('renderer:get-system-proxy-variables', async () => {
-    const systemProxyConfig = await getSystemProxy();
-    return systemProxyConfig;
+    try {
+      const systemProxyConfig = await getSystemProxy();
+      return systemProxyConfig;
+    } catch (error) {
+      console.error('Failed to get system proxy:', error);
+      return {
+        http_proxy: null,
+        https_proxy: null,
+        no_proxy: null,
+        source: 'environment'
+      };
+    }
   });
🤖 Prompt for AI Agents
In packages/bruno-electron/src/ipc/preferences.js around lines 51 to 55, the
ipcMain handler calls getSystemProxy() without error handling which can produce
an unhandled rejection; wrap the await call in a try/catch, log or process the
error inside the catch, and then either return a safe fallback (e.g., null or an
empty config) or throw a meaningful Error that the renderer can handle so the
promise always resolves or rejects with a controlled value and no unhandled
rejection occurs.

Comment on lines 392 to 394
} catch (error) {
throw new Error('Invalid system http_proxy');
throw new Error(`Invalid system http_proxy "${http_proxy}": ${error.message}`);
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Redact credentials from proxy URIs in error messages.

Including the raw proxy URI values (http_proxy, https_proxy) in error messages risks leaking credentials if they are embedded in the URI format http://user:[email protected]. Error messages may appear in logs or user-facing dialogs.

Redact the userinfo before interpolating:

+      const redactedHttpProxy = http_proxy ? http_proxy.replace(/\/\/([^:]+):([^@]+)@/, '//$1:***@') : http_proxy;
       } catch (error) {
-        throw new Error(`Invalid system http_proxy "${http_proxy}": ${error.message}`);
+        throw new Error(`Invalid system http_proxy "${redactedHttpProxy}": ${error.message}`);
       }

Apply the same pattern for https_proxy at Line 408:

+      const redactedHttpsProxy = https_proxy ? https_proxy.replace(/\/\/([^:]+):([^@]+)@/, '//$1:***@') : https_proxy;
       } catch (error) {
-        throw new Error(`Invalid system https_proxy "${https_proxy}": ${error.message}`);
+        throw new Error(`Invalid system https_proxy "${redactedHttpsProxy}": ${error.message}`);
       }

Also applies to: 407-409

🤖 Prompt for AI Agents
In packages/bruno-electron/src/utils/proxy-util.js around lines 392-394 and
407-409, the code interpolates raw proxy URIs into error messages which can leak
credentials; parse each proxy string with the URL constructor (or equivalent),
detect username/password in the URL, replace the userinfo with a redaction (e.g.
remove username/password or set them to "[REDACTED]"), then interpolate the
sanitized URL into the thrown Error (and keep including error.message); if URL
parsing fails, fall back to a safe placeholder like "<invalid-proxy>" so no raw
credentials are logged.

Comment on lines +35 to +52
private async detectSystemProxy(): Promise<ProxyConfiguration> {
const startTime = Date.now();

try {
const result = await this.detectWithTimeout();

// Log slow detections
const detectionTime = Date.now() - startTime;
if (detectionTime > 5000) {
console.warn(`System proxy detection took ${detectionTime}ms`);
}

return result;
} catch (error) {
console.warn(`System proxy detection failed after ${Date.now() - startTime}ms:`, error instanceof Error ? error.message : String(error));
return this.getEnvironmentVariables();
}
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Fallback might hide detection failures.

The catch block silently falls back to environment variables, which could mask code bugs or configuration issues in platform-specific detectors. Consider logging the error type or adding telemetry to track detection failures.

That said, the fallback behavior may be intentional for resilience. If so, document the design choice.

🤖 Prompt for AI Agents
In packages/bruno-requests/src/network/system-proxy/index.ts around lines 35–52,
the catch block quietly falls back to environment variables which can hide
detector failures; update the catch to log the error type and details (e.g.,
error.name and error.message and/or stack) and emit a telemetry/event hook (or
call a provided metrics reporter) with the failure reason and duration so
failures are observable, and add a short inline comment or JSDoc above
detectSystemProxy explaining that the fallback is intentional for resilience (or
change behavior if it should instead surface errors).

Comment on lines +54 to +56
private async detectWithTimeout(): Promise<ProxyConfiguration> {
return await this.detectByPlatform();
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Misleading method name - no timeout logic implemented.

detectWithTimeout doesn't implement any timeout handling; it simply calls detectByPlatform. The timeout is actually handled by individual platform resolvers. Either implement a proper timeout wrapper here or remove this unnecessary indirection.

Consider:

-private async detectWithTimeout(): Promise<ProxyConfiguration> {
-  return await this.detectByPlatform();
-}
-
 private async detectSystemProxy(): Promise<ProxyConfiguration> {
   const startTime = Date.now();

   try {
-    const result = await this.detectWithTimeout();
+    const result = await this.detectByPlatform();

Or implement actual timeout logic:

private async detectWithTimeout(): Promise<ProxyConfiguration> {
  return Promise.race([
    this.detectByPlatform(),
    new Promise<ProxyConfiguration>((_, reject) => 
      setTimeout(() => reject(new Error('Detection timeout')), this.commandTimeout)
    )
  ]);
}
🤖 Prompt for AI Agents
In packages/bruno-requests/src/network/system-proxy/index.ts around lines 54-56,
the method detectWithTimeout is misleading because it declares a timeout
behavior but only calls detectByPlatform; replace the indirection with a real
timeout wrapper: return a Promise.race between this.detectByPlatform() and a
timeout Promise that rejects with a clear Error (e.g., "Detection timeout")
after this.commandTimeout milliseconds, making sure types match
(Promise<ProxyConfiguration>) and the timeout Promise rejects so callers receive
the failure; alternatively, if you prefer not to implement timeout here, remove
this method and call detectByPlatform() directly where used to avoid confusion.

@lohit-bruno lohit-bruno changed the title fix: system proxy detection logic updates fix: system proxy resolver logic updates Dec 3, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants