Require targetUserId for item transfers
This commit is contained in:
@@ -387,7 +387,7 @@ export type OutgoingMessage =
|
||||
| { type: 'item_drop'; itemId: string; x: number; y: number }
|
||||
| { type: 'item_delete'; itemId: string }
|
||||
| { type: 'item_transfer_targets'; itemId: string }
|
||||
| { type: 'item_transfer'; itemId: string; targetId?: string; targetUserId?: string }
|
||||
| { type: 'item_transfer'; itemId: string; targetUserId: string }
|
||||
| { type: 'item_use'; itemId: string }
|
||||
| { type: 'item_secondary_use'; itemId: string }
|
||||
| { type: 'item_piano_note'; itemId: string; keyId: string; midi: number; on: boolean }
|
||||
|
||||
@@ -29,7 +29,7 @@ This is a behavior guide for packet semantics beyond raw schemas.
|
||||
- `ping`: latency measurement.
|
||||
- `item_add`, `item_pickup`, `item_drop`, `item_delete`, `item_use`, `item_update`: item actions.
|
||||
- `item_transfer_targets`: request transfer target accounts for one item (includes online + offline active users, excluding current owner).
|
||||
- `item_transfer`: transfer item ownership to another account (supports `targetUserId`; `targetId` remains accepted for compatibility).
|
||||
- `item_transfer`: transfer item ownership to another account (`targetUserId` required).
|
||||
- `item_secondary_use`: trigger type-specific secondary action when implemented.
|
||||
- `item_piano_note`: realtime piano note on/off for active piano use mode.
|
||||
- `item_piano_recording`: piano record/playback control (`toggle_record`, `playback`, `stop_playback`).
|
||||
|
||||
@@ -140,8 +140,7 @@ class ItemDeletePacket(BasePacket):
|
||||
class ItemTransferPacket(BasePacket):
|
||||
type: Literal["item_transfer"]
|
||||
itemId: str
|
||||
targetId: str | None = None
|
||||
targetUserId: str | None = None
|
||||
targetUserId: str
|
||||
|
||||
|
||||
class ItemTransferTargetsPacket(BasePacket):
|
||||
|
||||
@@ -2545,11 +2545,7 @@ class SignalingServer:
|
||||
if not can_transfer_any and not can_transfer_own:
|
||||
await self._send_item_result(client, False, "transfer", "Not authorized to transfer this item.", item.id)
|
||||
return
|
||||
target_user_id = str(packet.targetUserId or "").strip()
|
||||
if not target_user_id and packet.targetId:
|
||||
target = self._get_client_by_id(packet.targetId)
|
||||
if target and target.authenticated and target.user_id:
|
||||
target_user_id = target.user_id
|
||||
target_user_id = str(packet.targetUserId).strip()
|
||||
if not target_user_id:
|
||||
await self._send_item_result(client, False, "transfer", "Target user is not available.", item.id)
|
||||
return
|
||||
|
||||
@@ -377,7 +377,10 @@ async def test_item_transfer_updates_item_owner(monkeypatch: pytest.MonkeyPatch)
|
||||
monkeypatch.setattr(server, "_broadcast_item", fake_broadcast_item)
|
||||
monkeypatch.setattr(server, "_broadcast", fake_broadcast)
|
||||
|
||||
await server._handle_message(owner, json.dumps({"type": "item_transfer", "itemId": item.id, "targetId": target.id}))
|
||||
await server._handle_message(
|
||||
owner,
|
||||
json.dumps({"type": "item_transfer", "itemId": item.id, "targetUserId": target.user_id}),
|
||||
)
|
||||
|
||||
assert item.createdBy == target.user_id
|
||||
assert item.createdByName == target.username
|
||||
@@ -439,7 +442,10 @@ async def test_item_transfer_allows_self_target_for_transfer_any(monkeypatch: py
|
||||
monkeypatch.setattr(server, "_send", fake_send)
|
||||
monkeypatch.setattr(server, "_broadcast_item", fake_broadcast_item)
|
||||
|
||||
await server._handle_message(actor, json.dumps({"type": "item_transfer", "itemId": item.id, "targetId": actor.id}))
|
||||
await server._handle_message(
|
||||
actor,
|
||||
json.dumps({"type": "item_transfer", "itemId": item.id, "targetUserId": actor.user_id}),
|
||||
)
|
||||
|
||||
assert item.createdBy == actor.user_id
|
||||
assert item.createdByName == actor.username
|
||||
@@ -677,7 +683,10 @@ async def test_item_transfer_rejects_when_not_authorized(monkeypatch: pytest.Mon
|
||||
|
||||
monkeypatch.setattr(server, "_send", fake_send)
|
||||
|
||||
await server._handle_message(owner, json.dumps({"type": "item_transfer", "itemId": item.id, "targetId": target.id}))
|
||||
await server._handle_message(
|
||||
owner,
|
||||
json.dumps({"type": "item_transfer", "itemId": item.id, "targetUserId": target.user_id}),
|
||||
)
|
||||
|
||||
assert item.createdBy == owner.user_id
|
||||
assert send_payloads
|
||||
|
||||
Reference in New Issue
Block a user