Skip to content
This repository was archived by the owner on Mar 25, 2026. It is now read-only.

Native proxy settings#2827

Closed
tim2zg wants to merge 25 commits intoelement-hq:developfrom
tim2zg:feat/native-proxy-settings
Closed

Native proxy settings#2827
tim2zg wants to merge 25 commits intoelement-hq:developfrom
tim2zg:feat/native-proxy-settings

Conversation

@tim2zg
Copy link
Copy Markdown

@tim2zg tim2zg commented Feb 1, 2026

Description

This PR implements a native "Network Proxy" settings window, allowing users to configure their proxy connection directly within the application UI instead of relying on command-line arguments or environment variables.

Changes

  • Added a new Proxy Settings entry to the "View" menu.
  • Implemented a dedicated Electron window with a UI that matches the Element look and feel (including dark/light mode support).
  • Created a new module to handle applying proxy configurations to the Electron defaultSession.
  • Persisted proxy configuration using the existing Store.

Solution for Issue: element-hq/element-web#32407

Checklist

  • Ensure your code works with manual testing.
  • New or updated public/exported symbols have accurate TSDoc documentation.
  • Linter and other CI checks pass.
  • I have licensed the changes to Element by completing the Contributor License Agreement (CLA)

tim2zg and others added 9 commits September 23, 2025 21:37
Co-authored-by: tim2zg <59140326+tim2zg@users.noreply.github.com>
…-e9fc06269a7b

Fix TypeScript error TS2345 in settings.ts: Add type assertion for desktopProxyConfig
- Added proxy authentication handling in the Electron main process.
- Introduced `getLastAppliedConfig` function to retrieve the last applied proxy configuration.
- Enhanced the proxy preload script to include a resize window feature.
- Updated the proxy window HTML to improve UI with a modern design and better accessibility.
- Implemented secure password storage for proxy credentials.
- Refactored proxy configuration handling to ensure proper validation and error handling.
- Improved the settings management for proxy configurations, including reading and writing to secure storage.
@tim2zg tim2zg requested a review from a team as a code owner February 1, 2026 10:33
@CLAassistant
Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you all sign our Contributor License Agreement before we can accept your contribution.
1 out of 2 committers have signed the CLA.

✅ tim2zg
❌ Copilot
You have signed the CLA already but the status is still pending? Let us recheck it.

@dosubot
Copy link
Copy Markdown

dosubot Bot commented Feb 1, 2026

Related Documentation

No published documentation to review for changes on this repository.

Write your first living document

How did I do? Any feedback?  Join Discord

@github-actions github-actions Bot added the Z-Community-PR Issue is solved by a community member's PR label Feb 1, 2026
@dosubot dosubot Bot added the T-Enhancement label Feb 1, 2026
Comment thread src/proxy-preload.cts Outdated
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Can this be cts instead and be transpiled by typescript into the lib dir instead of avoiding typescript? I.e follow the path of the main preload script

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Fair, done

Copy link
Copy Markdown
Member

@t3chguy t3chguy left a comment

Choose a reason for hiding this comment

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

This is exciting, but a few points

Additionally, looks like the autoUpdater won't respect these proxy settings which is problematic without a warning to the user

Comment thread src/proxy-window.html Outdated
@@ -0,0 +1,378 @@
<!--
Copyright 2026 New Vector Ltd.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We are not New Vector anymore, this should be your copyright anyway

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Done

Comment thread src/proxy-window.ts Outdated
@@ -0,0 +1,96 @@
/*
Copyright 2026 New Vector Ltd.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Ditto

Comment thread src/proxy.ts Outdated
@@ -0,0 +1,154 @@
/*
Copyright 2026 New Vector Ltd.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Ditto

Comment thread src/proxy-window.html Outdated
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think this will want to use Compound components for UI, so may need more complexity and likely to be within the main UI rather than entirely standalone. Needs design

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Will need help with this

Comment thread src/proxy-window.html Outdated
Comment on lines +179 to +194
<h1>Network Proxy</h1>

<div class="section">
<span class="section-title">Connection Mode</span>
<label class="radio-option"
><input type="radio" name="mode" id="proxy-mode-system" value="system" checked /> Use system proxy
settings</label
>
<label class="radio-option"
><input type="radio" name="mode" id="proxy-mode-direct" value="direct" /> No proxy (direct
connection)</label
>
<label class="radio-option"
><input type="radio" name="mode" id="proxy-mode-custom" value="custom" /> Manual configuration</label
>
</div>
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Needs i18n

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

tried it but not sure if it's right

Comment thread src/proxy-window.html Outdated
<input id="proxy-password" type="password" autocomplete="off" />
</div>
</div>
<div class="helper-text">Passwords are stored securely in the system keychain.</div>
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I don't think this is true with safeStorage, a single random string is stored in system keychain and other secrets are encrypted symmetrically using it. Additionally the user may have no keychain where this message becauses confusing.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Changed it

@t3chguy t3chguy changed the title Feat/native proxy settings Native proxy settings Feb 2, 2026
@t3chguy
Copy link
Copy Markdown
Member

t3chguy commented Feb 2, 2026

I have licensed the changes to Element by completing the Contributor License Agreement (CLA)

You checked this box but the CLA does not appear to be signed.

Could you also include screenshots of what the UI you added looks like?

@tim2zg
Copy link
Copy Markdown
Author

tim2zg commented Feb 2, 2026

This is exciting, but a few points

Additionally, looks like the autoUpdater won't respect these proxy settings which is problematic without a warning to the user

Added a notice

@tim2zg
Copy link
Copy Markdown
Author

tim2zg commented Feb 2, 2026

I have licensed the changes to Element by completing the Contributor License Agreement (CLA)

You checked this box but the CLA does not appear to be signed.

Could you also include screenshots of what the UI you added looks like?

grafik

Also, the CLA is not okay because I tried using GitHub Copilot at the beginning and didn’t reset the history. GitHub now lists Copilot as a contributor.

@t3chguy t3chguy requested a review from a team February 2, 2026 18:27
@americanrefugee
Copy link
Copy Markdown

Hello, thanks for your contribution @tim2zg!

In order to integrate this feature into the product, the form you've proposed will need to be presented in a modal (rather than in a separate browser tab). Then there will be 2 places from which the user can access this modal: From the Welcome screen, and from Settings. Here are visuals to help illustrate:

  1. On the Sign in page, we would add a text link in the footer
1_Sign In Page
  1. Click the link to launch the modal. By default the modal would show just the 3 radio button options with the first selected. The "Save" button is disabled until a change is made.
2_Modal - Network proxy - Default
  1. If the last option is selected, then the form appears below. The "Cancel" and "Save" buttons should be sticky and the form scrolls behind until the end. Once the user has entered the minimum information, the "Save" button is enabled.
3_Modal - Network proxy - Manual configuration selected
  1. Once signed into the client, the user can go to Settings > Security & Privacy > Network proxy to manage this setting.
4_Settings_Security and Privacy_Network proxy

Ideally, please provide 1.) the modal and form contents and 2.) the settings section block.

As for UI components, use those provide by our Compound Design System at https://compound.element.io

Here's a quick cheat sheet:

@tim2zg
Copy link
Copy Markdown
Author

tim2zg commented Feb 5, 2026

Hey, thanks for the feedback. Would this then be added to the main element app repo or injected into it from the wrapper? And would I then need to open up a second pull request there?

Best regards

@t3chguy
Copy link
Copy Markdown
Member

t3chguy commented Feb 6, 2026

Yes the UI code would live in element-web & communicate over IPC, there's already a wrapper for settings to handle the IPC communication for you. In the future it may be possible to have the UI code live on the element-desktop side and be injected as a module but we aren't there yet. In the near future element-desktop will be re-merged into the element-web (mono)repo to make contributions like this easier.

@fjh1997
Copy link
Copy Markdown

fjh1997 commented Mar 5, 2026

Thanks for working on this! This feature is highly anticipated by many users, including myself, as it significantly improves the desktop experience. Looking forward to seeing this merged. Is there anything the community can help with to speed up the process? @tim2zg

@tim2zg
Copy link
Copy Markdown
Author

tim2zg commented Mar 9, 2026

Hello @fjh1997,

Thank you. I will open another PR on the web repo shortly. I could use some help testing!

Best regards,
Tim

@fjh1997
Copy link
Copy Markdown

fjh1997 commented Mar 10, 2026

@tim2zg Awesome! Let me know when it's ready for testing.

@dbkr
Copy link
Copy Markdown
Member

dbkr commented Mar 12, 2026

I'm just going to put this back into draft while it's still waiting on other parts.

@dbkr dbkr marked this pull request as draft March 12, 2026 10:14
tim2zg and others added 3 commits March 14, 2026 09:37
- Explicitly resolve and apply system proxies in 'system' mode to avoid HTTP bypass
- Fix proxyRules separator to use semicolons per Chromium standard
- Ensure consistent focus rings in NetworkProxyModal for Compound inputs
- Fix password box outline vanishing when clicked in the proxy modal
- Remove obsolete proxy proposal documentation
- Extracted resolveSystemProxy to reduce cognitive complexity
- Replaced global with globalThis for better standards compliance
- Used optional chaining and nullish coalescing where appropriate
- Removed redundant type assertions and duplicate imports
@tim2zg tim2zg marked this pull request as ready for review March 15, 2026 09:40
@tim2zg
Copy link
Copy Markdown
Author

tim2zg commented Mar 15, 2026

UI PR: element-hq/element-web#32804

@tim2zg tim2zg force-pushed the feat/native-proxy-settings branch from 4012b9a to 221271f Compare March 17, 2026 11:37
- Use optional chaining in proxyConfig check
- Remove redundant void operators
- Fix redundant type assertions in settings
- Correct TS error in certificate-error listener
@tim2zg
Copy link
Copy Markdown
Author

tim2zg commented Mar 17, 2026

@fjh1997 Please feel free to test:)

@fjh1997
Copy link
Copy Markdown

fjh1997 commented Mar 21, 2026

Hi @tim2zg,

I’m a user in mainland China, so I need a proxy to log in to Matrix at all.

I tested your desktop PR together with the corresponding element-web PR locally. The proxy UI does appear after login, but I still ran into a few usability problems:

  1. There is no proxy settings entry on the welcome/login screen.
    Without that, I cannot configure a proxy before login, but without a proxy I also cannot log in in the first place.

  2. If the saved proxy becomes invalid, and I log out, I get stuck again.
    At that point I cannot log in, and I also cannot get back to the proxy settings to fix it.

  3. If the default/configured homeserver is unreachable from the current network, the app can sit on a blank/white screen for a long time.
    In that state, it would be much better if the user could still change both proxy settings and homeserver settings to recover.

  4. A proxy connectivity test button would also be very helpful.
    That would let users quickly confirm whether the configured proxy is actually working.

  5. With the original PR combination, I also hit:
    Error
    Unable to load! Check your network connectivity and try again.
    especially around the Security & Privacy area.
    I only got past that locally after applying extra patches like these:

diff --git a/packages/shared-components/src/settings/NetworkProxyView/NetworkProxyView.tsx b/packages/shared-components/src/settings/NetworkProxyView/NetworkProxyView.tsx
--- a/packages/shared-components/src/settings/NetworkProxyView/NetworkProxyView.tsx
+++ b/packages/shared-components/src/settings/NetworkProxyView/NetworkProxyView.tsx
@@
-import { _t } from "../../utils/I18nApi";
+import { _t } from "../../utils/i18n";

diff --git a/apps/web/src/settings/Settings.tsx b/apps/web/src/settings/Settings.tsx
--- a/apps/web/src/settings/Settings.tsx
+++ b/apps/web/src/settings/Settings.tsx
@@
+    "desktopProxyConfig": {
+        supportedLevels: [SettingLevel.PLATFORM],
+        displayName: _td("settings|network_proxy|title"),
+        default: {
+            mode: "system",
+        },
+    },

diff --git a/apps/web/src/i18n/strings/en_EN.json b/apps/web/src/i18n/strings/en_EN.json
--- a/apps/web/src/i18n/strings/en_EN.json
+++ b/apps/web/src/i18n/strings/en_EN.json
@@
+        "network_proxy": {
+            "connection_mode": "Connection mode",
+            "manual_configuration": "Manual configuration",
+            "mode_custom_selected": "Manual proxy configuration is enabled.",
+            "mode_direct_selected": "Direct connection is enabled. No proxy will be used.",
+            "mode_system_selected": "Using the system proxy configuration.",
+            "no_proxy_direct": "No proxy (direct connection)",
+            "no_proxy_for_comma_separated": "No proxy for",
+            "port": "Port",
+            "proxy_config_encrypted_system_storage": "Proxy password is stored in the system credential store when available.",
+            "proxy_host": "Proxy host",
+            "proxy_settings_updates_warning": "Changes apply to new network requests after saving.",
+            "settings_button": "Configure proxy",
+            "title": "Network Proxy",
+            "use_system_proxy": "Use system proxy"
+        },
  1. I also found another proxy bug on the desktop side.
    With a custom proxy like 192.168.1.5:10808, the current code builds a rule like http=http://host:port.
    That only proxies plain HTTP, while HTTPS homeserver requests can still remain DIRECT, so the login/welcome flow can still fail even though a proxy was configured.
    I only got reliable login-page proxying locally after changing it like this:
diff --git a/src/proxy.ts b/src/proxy.ts
--- a/src/proxy.ts
+++ b/src/proxy.ts
@@
-        const scheme = cfg.scheme ?? "http";
-        parts.push(`${scheme}=${scheme}://${auth}${cfg.host}:${cfg.port}`);
+        const scheme = cfg.scheme ?? "http";
+        parts.push(`${scheme}://${auth}${cfg.host}:${cfg.port}`);
  1. Logging out currently also wipes the saved desktop proxy config.
    From what I tested, after logging out, desktopProxyConfig disappears from the desktop profile, so the user is trapped again if the login screen still needs a proxy.
    The reason seems to be that the logout flow eventually calls desktop clearStorage(), which then calls Store.instance?.clear(), wiping the whole Electron store instead of only login/session-related data.

I think the proxy config should survive logout. For example:

  • keep desktopProxyConfig out of the Store.instance?.clear() path, or
  • store proxy settings in a separate desktop-only config file/store that is not cleared on logout.

For me, the main issue is that recovery is too hard when network access is broken. I think the login/welcome flow should still provide a way to change proxy and homeserver settings, similar to Telegram.

For reference, this is roughly how I built and tested the two PRs locally:

git clone https://github.com/element-hq/element-web.git
git clone https://github.com/element-hq/element-desktop.git

cd element-web
git fetch origin pull/32804/head:pr-32804
git checkout pr-32804
pnpm install
cp ../element-desktop/element.io/release/config.json ./apps/web/config.json
sed -i 's|from "../../utils/I18nApi"|from "../../utils/i18n"|' \
    packages/shared-components/src/settings/NetworkProxyView/NetworkProxyView.tsx
npx nx build element-web

cd ../element-desktop
git fetch origin pull/2827/head:pr-2827
git checkout pr-2827
pnpm install
rm -f webapp
ln -s ../element-web/apps/web/webapp ./webapp
pnpm run asar-webapp
pnpm run build
sudo apt install -y ./dist/element-desktop_1.12.12_amd64.deb

Please let me know if this is not the correct way to combine the two PRs for testing.

@t3chguy
Copy link
Copy Markdown
Member

t3chguy commented Mar 25, 2026

Sorry but you will need to merge these changes into element-hq/element-web#32804 apps/desktop

@t3chguy t3chguy closed this Mar 25, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

T-Enhancement Z-Community-PR Issue is solved by a community member's PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants