Add hosted proxy option with informed consent dialog - #131
Conversation
The web build needs a CORS proxy, and the "spectacled Proxy on Fly.io" entry in the settings dropdown could be picked with a single tap - even though that proxy terminates TLS and therefore sees the CalDAV credentials of everyone who uses it. Settings -> More now presents the proxy as a choice between two named options instead of a dropdown of URLs: - "My own proxy server" (recommended, default), with the URL field and the localhost/setup shortcuts underneath it, - "Spectacled proxy (hosted by us)", badged "Sees your credentials". Picking the hosted one opens ProxyTrustDialog, which states what the operator can see, what we do and don't log, that this is unverifiable from the outside, and the safer alternatives (self-hosting, an app-specific password). Its confirm button stays disabled until the acknowledgement checkbox is ticked. Consent is stored as the URL it was given for, so it never carries over silently to another instance, and while the hosted proxy is active the settings page keeps the disclosure on screen with shortcuts to review it or switch back. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NwACpV4rjwUXSZaBpZGLiX
…sclosure-settings-4v98z4
Unit tests have been failing on main since eb8f4d8, first at :kotlinStoreYarnLock and, once 1020b01 fixed the JS lock, at :kotlinWasmStoreYarnLock - both with "Lock file was changed". The failure reproduces on main's own head (8b4d034) and has nothing to do with this branch, which touches no npm dependency. kotlin-js-store/wasm/yarn.lock carries the same leftover entry that 1020b01 removed from kotlin-js-store/yarn.lock: an exact-pinned ws@8.18.0 that no dependency in the file requests at any range, left behind when the pin moved to 8.20.1. This applies that same deletion to the Wasm lock. Regenerating it properly (./gradlew kotlinWasmUpgradeYarnLock) was not possible in the environment this was written in, so CI is the check on it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NwACpV4rjwUXSZaBpZGLiX
CI: the yarn-lock failure is main's, not this PR'sThe first run here failed at
Two things were wrong with the branch state, both now addressed:
One caveat on the second commit: Worth noting from the first run: Generated by Claude Code |
…://github.com/TechbeeAT/spectacled into claude/proxy-trust-disclosure-settings-4v98z4
|
CI is green on The hand-applied Wasm lock deletion held: run 33740638015 passed on No action needed on the lock commits. The change itself is unreviewed as a design: the trust dialog's wording and the persistent disclosure card are the parts worth a human eye, along with the two previews ( Generated by Claude Code |
The "Use local development proxy" text button spent permanent vertical space on a dev-only affordance. A trailing-icon menu on the field is the usual place for presets that fill it, and it has room for more entries if another preset ever shows up. Only own-server presets live in it. The hosted proxy stays out: putting it one tap away in a menu is exactly what this branch replaced, since selecting it has to go through the consent dialog. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NwACpV4rjwUXSZaBpZGLiX
On the web build every CalDAV request goes through the proxy, so a user who reaches the add-account sheet without one configured can pick either option and only find out at the first request - which fails looking like an unreachable server rather than a missing setup step. The selection page now asks that question first on WASM: an explanatory card carrying the proxy picker, with both option cards disabled until a proxy is set. Once it is, the card collapses to a one-line confirmation with a Change affordance, so returning users and every native platform see the flow exactly as before. The picker itself moves out of SettingsMorePage into ProxyServerSetup so both entry points share one implementation. That matters beyond reuse: a second copy of this UI would be a second chance to get the hosted proxy selected without its consent dialog. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NwACpV4rjwUXSZaBpZGLiX
e1be6e6 dropped defaultProxyUrl(), so there is no platform default to fall back to any more - but the comment above proxyUrlProvider still described one. Say what the code now does, and why that is the point: an unconfigured web build fails at the browser rather than at a localhost address nobody is listening on. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NwACpV4rjwUXSZaBpZGLiX
…://github.com/TechbeeAT/spectacled into claude/proxy-trust-disclosure-settings-4v98z4
Summary
This PR introduces a hosted CORS proxy option for web users who cannot self-host, with an informed-consent flow that ensures users understand the security implications before using it.
Key Changes
https://spectacled-proxy.fly.devas an alternative to self-hosted proxies, operated by TechbeehostedProxyConsentUrltoUserAppPreferencesStoreto track which proxy URL the user has explicitly consented to useProxyTrustDialogcomponent that:ownProxyServerDraftto preserve user's custom proxy URL while hosted proxy is selected, allowing seamless switching backImplementation Details
HttpClientFactoryalongside the setup instructions URLhttps://claude.ai/code/session_01NwACpV4rjwUXSZaBpZGLiX