aboutsummaryrefslogtreecommitdiffstats
path: root/packages/meshbay-node/src/meshbay_node/transport/webrtc
diff options
context:
space:
mode:
Diffstat (limited to 'packages/meshbay-node/src/meshbay_node/transport/webrtc')
-rw-r--r--packages/meshbay-node/src/meshbay_node/transport/webrtc/admin.py2
-rw-r--r--packages/meshbay-node/src/meshbay_node/transport/webrtc/chat.py41
-rw-r--r--packages/meshbay-node/src/meshbay_node/transport/webrtc/dispatch.py1
3 files changed, 43 insertions, 1 deletions
diff --git a/packages/meshbay-node/src/meshbay_node/transport/webrtc/admin.py b/packages/meshbay-node/src/meshbay_node/transport/webrtc/admin.py
index 48734ab..7b3b1c9 100644
--- a/packages/meshbay-node/src/meshbay_node/transport/webrtc/admin.py
+++ b/packages/meshbay-node/src/meshbay_node/transport/webrtc/admin.py
@@ -15,6 +15,7 @@ from meshbay_common.adminop import (
OP_CHAT_DIRECTORY,
OP_CHAT_EPOCH,
OP_CHAT_LINK_PREVIEW,
+ OP_CHAT_PURGE,
OP_DIR_DELETE,
OP_FILE_DELETE,
OP_INVITE_CANCEL,
@@ -68,6 +69,7 @@ _ADMIN_EXECUTORS = {
OP_CHAT_LINK_PREVIEW: "_admin_exec_chat_link_preview",
OP_SEARCH_LISTED: "_admin_exec_search_listed",
OP_CHAT_EPOCH: "_admin_exec_chat_epoch",
+ OP_CHAT_PURGE: "_admin_exec_chat_purge",
OP_ROOT_EJECT: "_admin_exec_root_eject",
OP_ROOT_PLUG: "_admin_exec_root_plug",
}
diff --git a/packages/meshbay-node/src/meshbay_node/transport/webrtc/chat.py b/packages/meshbay-node/src/meshbay_node/transport/webrtc/chat.py
index dc43ae2..f200884 100644
--- a/packages/meshbay-node/src/meshbay_node/transport/webrtc/chat.py
+++ b/packages/meshbay-node/src/meshbay_node/transport/webrtc/chat.py
@@ -7,7 +7,12 @@ import time
import blake3
from meshbay_common import MNP_VERSION
-from meshbay_common.adminop import OP_CHAT_DIRECTORY, OP_CHAT_EPOCH, OP_CHAT_LINK_PREVIEW
+from meshbay_common.adminop import (
+ OP_CHAT_DIRECTORY,
+ OP_CHAT_EPOCH,
+ OP_CHAT_LINK_PREVIEW,
+ OP_CHAT_PURGE,
+)
from meshbay_common.chatbox import NONCE_LEN as CHAT_NONCE_LEN
from meshbay_common.chatbox import SIG_LEN as CHAT_SIG_LEN
from meshbay_common.groupbox import PURPOSE_CHAT_KEYS, seal
@@ -227,6 +232,40 @@ class ChatMixin:
self._broadcast_to_group({"type": MNP.CHAT_EPOCH_ACK,
"v": MNP_VERSION, "epoch": result["epoch"]})
+ def _do_chat_purge(self, msg: dict) -> None:
+ """
+ Delete the group's stored chat. Operator only, and signed. The subject is
+ the group id, so a signature for one group's purge purges no other.
+
+ Always this connection's group, never one named in the message: the ack
+ is broadcast to this group, and an operator purges the chat they see.
+ """
+ group_id = self._group_id
+ if not group_id:
+ self._send({"type": "error", "detail": "No group on this connection"})
+ return
+ if not self._has_admin_authority():
+ self._send({"type": "error", "detail": "No authorized key for this"})
+ return
+ self._issue_admin_challenge(OP_CHAT_PURGE, group_id, group_id=group_id)
+
+ async def _admin_exec_chat_purge(
+ self, pending: dict, transcript: bytes, sig: bytes,
+ ) -> None:
+ if not await self._verify_admin_sig(transcript, sig):
+ self._send({"type": "error", "detail": "Signature verification failed"})
+ self._audit("admin_auth_failed", f"chat_purge:{pending['subject'][:8]}")
+ return
+ try:
+ result = await self._run_op(ops.purge_chat, pending["subject"])
+ except ops.OpError as e:
+ self._send({"type": "error", "detail": e.message})
+ return
+ self._audit("chat_purge", str(result["removed"]))
+ # Every open chat panel empties, not only the operator's.
+ self._broadcast_to_group({"type": MNP.CHAT_PURGE_ACK,
+ "v": MNP_VERSION, "removed": result["removed"]})
+
async def _do_chat_keys_req(self, msg: dict) -> None:
"""
Hand this member every chat epoch key the group has, sealed.
diff --git a/packages/meshbay-node/src/meshbay_node/transport/webrtc/dispatch.py b/packages/meshbay-node/src/meshbay_node/transport/webrtc/dispatch.py
index a8b5767..5d4ed94 100644
--- a/packages/meshbay-node/src/meshbay_node/transport/webrtc/dispatch.py
+++ b/packages/meshbay-node/src/meshbay_node/transport/webrtc/dispatch.py
@@ -56,6 +56,7 @@ _HANDLERS = {
MNP.CHAT_LINK_PREVIEW: ("_do_chat_link_preview", INLINE),
MNP.SEARCH_LISTED: ("_do_search_listed", INLINE),
MNP.CHAT_EPOCH: ("_do_chat_epoch", INLINE),
+ MNP.CHAT_PURGE: ("_do_chat_purge", INLINE),
MNP.CHAT_KEYS_REQ: ("_do_chat_keys_req", SPAWNED),
MNP.GROUP_ROSTER_REQ: ("_do_group_roster_req", SPAWNED),
MNP.MEDIA_META_REQ: ("_do_media_meta_request", SPAWNED),