(opus assessment) Fix auth wall flash, broken multi-user write API, and single-user redirect loop

Auth wall (Base.astro): set data-auth-pending on <body> at SSG time and hide
  it with inline CSS before any JS runs; remove the attribute after /api/me
  resolves. Eliminates the flash of protected content on private instances.

  Multi-user write API (serve/server.py): the previous _apply_sidecar_edit and
  strava_sync imports from bincio.edit.server were broken (those names don't
  exist as module-level exports) and the Strava sync mutated a global data_dir,
  making concurrent requests from different users racy. Fix: extract both
  operations into bincio/edit/ops.py as pure functions that take data_dir
  explicitly. Both edit/server.py and serve/server.py now import from there.

  Security: add rate limiting to POST /api/register (5 attempts / 15 min / IP,
  separate bucket from login). Add _check_id() activity ID validation to both
  GET and POST /api/activity/{id} in serve/server.py.

  Single-user mode: _write_root_manifest now forces instance.private=false when
  no instance.db exists, even if a previous run wrote true. Prevents the auth
  wall from firing and redirecting to /login/ when bincio serve isn't running.

  ActivityFeed: skip filterHandle when profileIndexUrl is set (per-user profile
  pages load the right shard directly; activities have no handle tag at that
  point, so the filter was producing an empty feed). Fix handle links to point
  to /u/{handle}/ instead of /{handle}/. Fix <a>-inside-<a> Svelte warning by
  converting the inner handle link to a <button>.
This commit is contained in:
Davide Scaini
2026-04-09 09:19:48 +02:00
parent 98c42dc443
commit cf7c71b8a3
6 changed files with 87 additions and 117 deletions
+9 -1
View File
@@ -107,9 +107,17 @@ def _write_root_manifest(data: Path) -> None:
except Exception:
pass
has_auth = (data / "instance.db").exists()
existing_instance = existing.get("instance", {"name": "BincioActivity"})
if not has_auth:
# Single-user: no auth server, force private off regardless of what was written before.
existing_instance = {**existing_instance, "private": False}
elif "private" not in existing_instance:
# Multi-user first run: default to private.
existing_instance = {**existing_instance, "private": True}
manifest = {
"bas_version": "1.0",
"instance": existing.get("instance", {"name": "BincioActivity", "private": True}),
"instance": existing_instance,
"generated_at": datetime.now(timezone.utc).isoformat(),
"shards": [
{