summaryrefslogtreecommitdiffstats
path: root/packages/meshbay-hub/src/meshbay_hub/api/admin.py
diff options
context:
space:
mode:
authorChristophe Besson <cbesson@gmail.com>2026-08-13 03:56:30 +0200
committerChristophe Besson <cbesson@gmail.com>2026-08-13 03:56:30 +0200
commitf0248975908ad670fa8a820f865bf22ea8d0172d (patch)
treef4af64d36cacaccb4f6d13436e001aeb57e861e3 /packages/meshbay-hub/src/meshbay_hub/api/admin.py
parent35130e5528a52161630fd1c93572e1b2b7cd911b (diff)
downloadmeshbay-f0248975908ad670fa8a820f865bf22ea8d0172d.tar.gz
feat: Phase 12 — P2P crypto material, password split, node Ed25519 auth
Baseline commit capturing in-progress Phase 12 work that was already present in the working tree (uncommitted) before the Phase 11.5 security remediation begins. Committed as-is, without review or modification, so that remediation changes arrive as a separable diff. Contents: BundleStore (P2P GEK + keypair bundles), password split (auth_key / bundle_key), node Ed25519 auth (POST /v1/nodes/auth, node-scoped JWT), GEK-HMAC handshake proof with DTLS channel binding, Ed25519 admin challenge-response, node local admin UI rewrite, browser key persistence. Not authored in this session — captured to establish a baseline. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Diffstat (limited to 'packages/meshbay-hub/src/meshbay_hub/api/admin.py')
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/api/admin.py12
1 files changed, 9 insertions, 3 deletions
diff --git a/packages/meshbay-hub/src/meshbay_hub/api/admin.py b/packages/meshbay-hub/src/meshbay_hub/api/admin.py
index 88e231a..164885d 100644
--- a/packages/meshbay-hub/src/meshbay_hub/api/admin.py
+++ b/packages/meshbay-hub/src/meshbay_hub/api/admin.py
@@ -211,6 +211,7 @@ async def admin_list_groups(
"name": g.name,
"admin_id": g.admin_id,
"visibility": g.visibility,
+ "description": g.description or "",
"status": g.status,
"created_at": g.created_at.isoformat(),
"member_count": mc,
@@ -265,25 +266,30 @@ async def admin_list_logs(
offset: int = 0,
limit: int = Query(default=50, le=200),
):
- query = select(IPLog).order_by(IPLog.timestamp.desc())
+ query = (
+ select(IPLog, User.username)
+ .outerjoin(User, IPLog.user_id == User.id)
+ .order_by(IPLog.timestamp.desc())
+ )
if user_id:
query = query.where(IPLog.user_id == user_id)
if event:
query = query.where(IPLog.event == event)
query = query.offset(offset).limit(limit)
result = await db.execute(query)
- logs = result.scalars().all()
+ rows = result.all()
return {
"logs": [
{
"id": lg.id,
"user_id": lg.user_id,
+ "username": uname or "",
"event": lg.event,
"ip_address": lg.ip_address,
"detail": lg.detail,
"timestamp": lg.timestamp.isoformat(),
}
- for lg in logs
+ for lg, uname in rows
],
}