summaryrefslogtreecommitdiffstats
path: root/packages/meshbay-hub/tests/test_desktop_shell.py
diff options
context:
space:
mode:
authorChristophe Besson <cbesson@gmail.com>2026-10-14 13:34:47 +0200
committerChristophe Besson <cbesson@gmail.com>2026-10-14 13:34:47 +0200
commit51705056a578d2649a989bf14a056fbcfae58a6b (patch)
treedfd078aba518427387fca29b9d43c3723b030008 /packages/meshbay-hub/tests/test_desktop_shell.py
parentdaec4bc6a2a9f9e038e5269586b06018ff327a27 (diff)
downloadmeshbay-51705056a578d2649a989bf14a056fbcfae58a6b.tar.gz
feat(hub): replace reCAPTCHA with a self-hosted proof of work
Sign-up and passphrase reset sent every visitor's address and browser details to Google, which needed a consent the sign-up form could not ask for freely. The hub now issues its own challenge (ALTCHA's scheme, signed with a key derived from the hub's private key, single-use, 30 minutes) and the page solves it with SubtleCrypto while the form is filled in. - GET /v1/users/captcha issues a challenge; 404 captcha_disabled when off. - [captcha] enabled / max_number replace site_key / secret_key, which are now ignored with a warning; MESHBAY_CAPTCHA_ENABLED replaces the old variables. - No Google origin left in the CSP of the hub, the desktop shell or the Android shell; captcha_site_key leaves /v1/hub/info. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'packages/meshbay-hub/tests/test_desktop_shell.py')
-rw-r--r--packages/meshbay-hub/tests/test_desktop_shell.py34
1 files changed, 11 insertions, 23 deletions
diff --git a/packages/meshbay-hub/tests/test_desktop_shell.py b/packages/meshbay-hub/tests/test_desktop_shell.py
index c2ea4ca..7a26dfb 100644
--- a/packages/meshbay-hub/tests/test_desktop_shell.py
+++ b/packages/meshbay-hub/tests/test_desktop_shell.py
@@ -197,14 +197,9 @@ def _policy() -> str:
"""
import re
source = _main()
- # The array mixes plain strings and one `${RECAPTCHA_SRC}` template literal;
- # resolve the constant so every directive reads as plain text.
- rec = re.search(r"const RECAPTCHA_SRC = '([^']*)'", source)
match = re.search(r"const CSP = \[(.*?)\]\.join", source, re.S)
assert match, "no CSP constant in the main process"
body = match.group(1)
- if rec:
- body = body.replace("${RECAPTCHA_SRC}", rec.group(1))
# Skip the `//` comments inside the array. Reading one as a directive is
# the mistake this file already records against the packaged unit test,
# which matched the comment explaining why `User=` was absent: parse
@@ -226,24 +221,22 @@ def _directive(name: str) -> str:
def test_the_hub_is_reachable_but_never_executable():
"""
- The page connects to its own files and to reCAPTCHA, nothing else: every
+ The page connects to its own files, nothing else: every
hub call leaves from the main process (a page on `app://` is refused by
CORS anyway), and the node arrives over WebRTC, which connect-src does not
govern. A bare `https:` there let injected script post anything anywhere.
script-src never names the hub: nothing it returns is ever executed. The
- only script sources are 'self', the wasm eval token, and the two reCAPTCHA
- hosts (see the next test) — never a bare `https:` scheme, which would let
- the hub's own origin serve script.
+ only script sources are 'self' and the wasm eval token — never a bare
+ `https:` scheme, which would let the hub's own origin serve script.
"""
connect = _directive("connect-src").split()[1:]
- assert set(connect) == {"'self'", "https://www.google.com", "https://www.gstatic.com"}
+ assert set(connect) == {"'self'"}
script = _directive("script-src")
assert script, "no script-src directive"
sources = script.split()[1:] # drop the "script-src" keyword itself
allowed = {
"'self'", "'wasm-unsafe-eval'",
- "https://www.google.com", "https://www.gstatic.com",
}
assert set(sources) <= allowed, \
f"unexpected script-src source: {set(sources) - allowed}"
@@ -252,22 +245,17 @@ def test_the_hub_is_reachable_but_never_executable():
assert "default-src 'none'" in _policy()
-def test_recaptcha_is_the_only_third_party_and_stays_scoped_to_it():
+def test_no_third_party_origin_in_the_policy():
"""
- reCAPTCHA gates sign-up in the app the same way it does in the browser.
- www.google.com and www.gstatic.com are allowed under script-src, frame-src
- and img-src for that — and no other external origin appears anywhere in the
- policy. Remove this expectation only alongside the reCAPTCHA widget.
+ Nothing outside the application's own files is reachable from the page.
+ The one exception there was, reCAPTCHA's two Google origins under
+ script-src, frame-src and img-src, went with the captcha: sign-up is gated
+ by a proof of work the hub issues itself (meshbay_hub/captcha.py).
"""
- hosts = {"https://www.google.com", "https://www.gstatic.com"}
- for directive in ("script-src", "frame-src", "img-src"):
- srcs = set(_directive(directive).split()[1:])
- assert hosts <= srcs, f"{directive} is missing a reCAPTCHA host"
-
for part in _policy().split(";"):
for tok in part.strip().split()[1:]:
- if tok.startswith(("http://", "https://")):
- assert tok in hosts, f"unexpected external origin in CSP: {tok}"
+ assert not tok.startswith(("http://", "https://")), (
+ f"external origin in CSP: {tok}")
def test_the_pdf_preview_has_both_permissions_it_needs():