From 51705056a578d2649a989bf14a056fbcfae58a6b Mon Sep 17 00:00:00 2001 From: Christophe Besson Date: Wed, 14 Oct 2026 13:34:47 +0200 Subject: 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 --- packages/meshbay-hub/src/meshbay_hub/api/hub.py | 10 ---------- 1 file changed, 10 deletions(-) (limited to 'packages/meshbay-hub/src/meshbay_hub/api/hub.py') diff --git a/packages/meshbay-hub/src/meshbay_hub/api/hub.py b/packages/meshbay-hub/src/meshbay_hub/api/hub.py index 0d2d39c..b47f076 100644 --- a/packages/meshbay-hub/src/meshbay_hub/api/hub.py +++ b/packages/meshbay-hub/src/meshbay_hub/api/hub.py @@ -7,19 +7,10 @@ from sqlalchemy.ext.asyncio import AsyncSession from meshbay_hub import __version__, hub_settings from meshbay_hub.api import federation from meshbay_hub.auth import hub_public_key_pem -from meshbay_hub.config import HubConfig from meshbay_hub.db.engine import get_db, get_engine router = APIRouter(prefix="/v1/hub", tags=["hub"]) -_cfg: HubConfig | None = None - - -def set_config(cfg: HubConfig) -> None: - global _cfg - _cfg = cfg - - @router.get("/info") async def hub_info(db: AsyncSession = Depends(get_db)): """Versions and the instance policy a client needs before signing in.""" @@ -40,7 +31,6 @@ async def hub_info(db: AsyncSession = Depends(get_db)): # which answers 503 — this is the same answer somewhere an operator can # read it without opening the source. "federation": federation.FEDERATION_ENABLED, - "captcha_site_key": _cfg.captcha.site_key if _cfg and _cfg.captcha.enabled else "", # How long a browser tab stays signed in with nobody at it. The page # measures it (static/idle.js); the hub only says how long. "browser_idle_hours": -- cgit v1.2.3