feat: add ephemeral friend presence and invites

Add short-lived capability channels for online friend status and public-room invitations without storing accounts, fingerprints, social graphs, or offline messages.
This commit is contained in:
Alexander Sellite 2026-08-23 20:52:57 -04:00
parent 029e247649
commit 21d17c4211
7 changed files with 626 additions and 3 deletions

View file

@ -1,5 +1,6 @@
from __future__ import annotations
import hashlib
from http.client import HTTPConnection
import json
import socketserver
@ -203,6 +204,95 @@ class DiscoveryHTTPTests(unittest.TestCase):
self.assertEqual(body["version"], "0.16.2-alpha")
self.assertEqual(body["build_revision"], "test-build")
def test_live_friend_presence_and_invitation_endpoints(self) -> None:
status, created = self.request("POST", "/v1/rooms", VALID_ROOM)
self.assertEqual(status, 201)
assert created is not None
room = created["room"]
traversal = created["traversal"]
assert isinstance(room, dict)
assert isinstance(traversal, dict)
room_id = str(room["room_id"])
self.server.registry.verify_endpoint(
room_id,
str(traversal["verification_token"]),
"127.0.0.1",
7777,
)
inbox_token = "b" * 64
social_version = {
"game_version": VALID_ROOM["game_version"],
"protocol_version": VALID_ROOM["protocol_version"],
}
status, polled = self.request(
"POST",
"/v1/invitations/poll",
dict(social_version, inbox_tokens=[inbox_token]),
)
self.assertEqual(status, 200)
assert polled is not None
self.assertEqual(polled["invitations"], [])
status, _sent = self.request(
"POST",
"/v1/invitations",
dict(social_version, inbox_token=inbox_token, room_id=room_id),
)
self.assertEqual(status, 201)
status, polled = self.request(
"POST",
"/v1/invitations/poll",
dict(social_version, inbox_tokens=[inbox_token]),
)
self.assertEqual(status, 200)
assert polled is not None
self.assertEqual(polled["invitations"][0]["room"]["room_id"], room_id)
status, offline = self.request(
"POST",
"/v1/invitations",
dict(social_version, inbox_token="c" * 64, room_id=room_id),
)
self.assertEqual(status, 409)
assert offline is not None
self.assertEqual(offline["error"]["code"], "friend_offline")
self.assertEqual(
offline["error"]["message"],
"This person needs to be online to do this.",
)
write_token = "d" * 64
channel = hashlib.sha256(
f"NETFISHING_PRESENCE_V1:{write_token}".encode()
).hexdigest()
status, _published = self.request(
"POST",
"/v1/presence",
dict(
social_version,
write_tokens=[write_token],
online=True,
display_name="Voyager",
room_id=room_id,
),
)
self.assertEqual(status, 200)
status, presence = self.request(
"POST",
"/v1/presence/query",
dict(social_version, channels=[channel]),
)
self.assertEqual(status, 200)
assert presence is not None
self.assertEqual(presence["presence"][0]["room"]["room_id"], room_id)
self.request(
"DELETE",
f"/v1/rooms/{room_id}",
token=str(created["lease_token"]),
)
def test_udp_rendezvous_does_not_spawn_per_packet_threads(self) -> None:
self.assertFalse(issubclass(TraversalUDPServer, socketserver.ThreadingMixIn))