diff options
| author | Christophe Besson <cbesson@gmail.com> | 2026-08-11 23:11:36 +0200 |
|---|---|---|
| committer | Christophe Besson <cbesson@gmail.com> | 2026-08-11 23:11:36 +0200 |
| commit | 35130e5528a52161630fd1c93572e1b2b7cd911b (patch) | |
| tree | 50954e2da56e186e2651ad838093eb6c09c259a8 /packages/meshbay-node/src/meshbay_node/daemon.py | |
| parent | c66ee41d8476461939c5f4e7fdc71c5d7fb4a85c (diff) | |
| download | meshbay-35130e5528a52161630fd1c93572e1b2b7cd911b.tar.gz | |
feat(node): audit logging + local admin UI rewrite
Add SQLite audit store for legal compliance (LCEN/DSA): logs user IP,
actions (handshake, file download/upload/delete, stream, chat), and
timestamps. Retention: 1 year, with cleanup method.
WebRTC transport now logs all user actions to the audit store with
remote IP extraction from the ICE transport.
Local web UI rewritten as a proper admin dashboard:
- Stats cards (groups, files, peers)
- Connected peers table with IP, username, group, state
- Group cards with file listings and shared directory info
- Audit log page with event/user filtering
- Dark theme, responsive, auto-refresh
- JSON API: /api/status, /api/groups, /api/peers, /api/audit, /api/config
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Diffstat (limited to 'packages/meshbay-node/src/meshbay_node/daemon.py')
| -rw-r--r-- | packages/meshbay-node/src/meshbay_node/daemon.py | 17 |
1 files changed, 17 insertions, 0 deletions
diff --git a/packages/meshbay-node/src/meshbay_node/daemon.py b/packages/meshbay-node/src/meshbay_node/daemon.py index 5b6e770..5851b34 100644 --- a/packages/meshbay-node/src/meshbay_node/daemon.py +++ b/packages/meshbay-node/src/meshbay_node/daemon.py @@ -33,6 +33,7 @@ import uvicorn from meshbay_common import MNP_VERSION from meshbay_common.protocol import MNP +from meshbay_node.audit import AuditStore from meshbay_node.chat.store import ChatStore from meshbay_node.config import Config, load_config, write_example_config from meshbay_node.hub_client import HubClient, HubConfig @@ -109,6 +110,7 @@ class NodeDaemon: self._webrtc = None self._denylist = Denylist() if Denylist else None self._chat_stores: dict[str, ChatStore] = {} + self._audit_store: AuditStore | None = None self._indexers: list[DirectoryIndexer] = [] self._tasks: list[asyncio.Task] = [] self._hub: HubClient | None = None @@ -192,6 +194,12 @@ class NodeDaemon: groups_ctx[gid]["chat_store"] = store log.info("Chat stores opened: %d groups", len(self._chat_stores)) + # 4b. Audit store (legal compliance — IP + action logging) + audit_db = data_dir / "audit.db" + self._audit_store = AuditStore(db_path=audit_db) + await self._audit_store.open() + log.info("Audit store opened: %s", audit_db) + # 5. Denylist denylist = self._denylist @@ -210,6 +218,7 @@ class NodeDaemon: self._webrtc._ctx["chat_store"] = first.get("chat_store") self._webrtc._ctx["hub_ws"] = _WsSender(hub) self._webrtc._ctx["node_user_id"] = session.user_id + self._webrtc._ctx["audit_store"] = self._audit_store log.info("WebRTC transport ready") else: log.warning("WebRTC not available (aiortc not installed)") @@ -315,6 +324,11 @@ class NodeDaemon: group_cfg.http_port, group_cfg.name) # 10. Local web UI + self._state["groups_ctx"] = groups_ctx + self._state["config"] = self._config + self._state["audit_store"] = self._audit_store + self._state["webrtc"] = self._webrtc + self._state["hub"] = hub from meshbay_node.ui import create_ui_app ui_app = create_ui_app(self._state) ui_cfg = uvicorn.Config( @@ -412,6 +426,9 @@ class NodeDaemon: if self._webrtc: await self._webrtc.close_all() + if self._audit_store: + await self._audit_store.close() + for store in self._chat_stores.values(): await store.close() |