From 4d6dba548708e0408ac3982ec4ee21f4825edfc1 Mon Sep 17 00:00:00 2001 From: Padreug Date: Mon, 20 Jul 2026 01:39:39 +0200 Subject: [PATCH] fix: strip checkin_instructions from public room dicts (privacy leak) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The AUTH_NONE RPC room endpoints (chatelet_room_list/_get) stripped wallet but NOT checkin_instructions — which was added in #5 after this code, so the operator's private access details (address, gate code) were leaking to any guest. Centralize a public_room_dict(room) helper (strips wallet + checkin_instructions) and route both doors through it. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_019VUQCfdqiLSsFS2jcGnaFD --- models.py | 12 ++++++++++++ transport_rpcs.py | 9 ++++++--- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/models.py b/models.py index 8a239e3..6fd20a8 100644 --- a/models.py +++ b/models.py @@ -17,6 +17,7 @@ Design notes carried into the field definitions: arbiter of "is this range open" — Nostr events are requests, not locks. """ +import json from datetime import datetime, timezone from enum import Enum @@ -194,6 +195,17 @@ class Block(BaseModel): # --------------------------------------------------------------------------- +def public_room_dict(room: Room) -> dict: + """A Room as public JSON for guests — strips operator-private fields: the + wallet id, and the check-in instructions (address/gate code, delivered only + in the encrypted post-payment DM). Shared by the HTTP and Nostr-RPC guest + doors so neither can leak them.""" + d = json.loads(room.json()) + d.pop("wallet", None) + d.pop("checkin_instructions", None) + return d + + class AvailabilityQuery(BaseModel): room_id: str check_in: str # YYYY-MM-DD inclusive diff --git a/transport_rpcs.py b/transport_rpcs.py index f8f634b..d3e5cc3 100644 --- a/transport_rpcs.py +++ b/transport_rpcs.py @@ -196,6 +196,9 @@ def _to_dict(obj) -> dict: def _public_room(room) -> dict: - d = _to_dict(room) - d.pop("wallet", None) # wallet id is operator-internal, not for guests - return d + # Shared with the HTTP door; strips wallet id AND checkin_instructions + # (the latter was leaking to guests before — added after this file's + # original public dict). + from .models import public_room_dict + + return public_room_dict(room)