diff options
| author | Christophe Besson <cbesson@gmail.com> | 2026-09-02 11:54:22 +0200 |
|---|---|---|
| committer | Christophe Besson <cbesson@gmail.com> | 2026-09-02 11:54:22 +0200 |
| commit | 2d8c6bc449e343a80569e45d4ceae0423616cedd (patch) | |
| tree | 09a1ee29c2a39db6189ba80315cfa0a1c463bcf3 /packages/meshbay-hub/src/meshbay_hub/config.py | |
| parent | bee5901f7a04d17c40e2c8d077437f10e59c8d81 (diff) | |
| download | meshbay-2d8c6bc449e343a80569e45d4ceae0423616cedd.tar.gz | |
fix(hub): a desktop solve reports no hostname at all, not "meshbay"
Registering from the native client failed with `captcha_failed` while the
checkbox was green — a worse symptom than the one being fixed, because the
widget now looked fine and only the hub's own log said otherwise:
captcha solved on an unexpected host ''; allowed: ['localhost', 'meshbay', 'meshbay.org']
The previous commit assumed Google would report the host component of the
origin, so `app://meshbay` would come back as `meshbay` and could sit in
`allowed_hosts`. It does not. A solve Google cannot attribute to a domain
reports an **empty** hostname, and no allowlist entry can match that. An empty
entry is not the answer either: a blank in a TOML list is a typo far more
often than an intention, and `load_config` drops blanks for that reason —
`captcha.allow_unattributed_host` is a named flag instead, so the trade is
stated where it is made.
What it admits, plainly: every non-web client, not only ours. A file:// page
or somebody else's Electron application look identical from here. That is the
same bar the client's own origin would have been — main.js already records
that `app://meshbay` is not a credential — and it is a bar: the captcha still
has to be solved, per token, in something that can render it. What is given up
is the origin restriction for non-web clients, not the captcha. Off by
default, and a hub without the desktop client should leave it off.
The refusal now names which of the two it is, since they need different
answers: an unexpected host names the host, an unattributed one says to set
the flag.
docs/captcha.md §6 said `meshbay` was the value and told operators to add it;
it now records what was measured and why the guess was wrong. The packaged
example config carries the flag with the same warning.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014UtzVrzM7e2tG9fSpkR9ML
Diffstat (limited to 'packages/meshbay-hub/src/meshbay_hub/config.py')
| -rw-r--r-- | packages/meshbay-hub/src/meshbay_hub/config.py | 11 |
1 files changed, 11 insertions, 0 deletions
diff --git a/packages/meshbay-hub/src/meshbay_hub/config.py b/packages/meshbay-hub/src/meshbay_hub/config.py index 39fdc52..e61e69e 100644 --- a/packages/meshbay-hub/src/meshbay_hub/config.py +++ b/packages/meshbay-hub/src/meshbay_hub/config.py @@ -74,6 +74,13 @@ class CaptchaConfig: # so the hostname Google sees is not the hub's and never can be. See # docs/captcha.md §6. allowed_hosts: list[str] = field(default_factory=list) + # A solve from a page Google cannot attribute to a domain reports an empty + # hostname — `app://meshbay` does, measured live, and so does any other + # non-web client. No `allowed_hosts` entry can match that, and a blank + # entry is not the answer: the parser drops blanks because in a TOML list + # a blank is a typo far more often than an intention. Hence a named flag, + # which also states the trade at the place it is made. + allow_unattributed_host: bool = False @property def enabled(self) -> bool: @@ -122,6 +129,8 @@ def load_config(path: Path | None = None) -> HubConfig: cfg.captcha.secret_key = cap.get("secret_key", cfg.captcha.secret_key) if hosts := cap.get("allowed_hosts"): cfg.captcha.allowed_hosts = [str(h).strip() for h in hosts if str(h).strip()] + if "allow_unattributed_host" in cap: + cfg.captcha.allow_unattributed_host = bool(cap["allow_unattributed_host"]) break # Env var overrides @@ -143,5 +152,7 @@ def load_config(path: Path | None = None) -> HubConfig: cfg.captcha.secret_key = captcha_secret if captcha_hosts := os.environ.get("MESHBAY_CAPTCHA_ALLOWED_HOSTS"): cfg.captcha.allowed_hosts = [h.strip() for h in captcha_hosts.split(",") if h.strip()] + if unattributed := os.environ.get("MESHBAY_CAPTCHA_ALLOW_UNATTRIBUTED_HOST"): + cfg.captcha.allow_unattributed_host = unattributed.lower() in ("1", "true", "yes") return cfg |