From 063c8eeb8cb43b22a44be7241676f95bc4534bb5 Mon Sep 17 00:00:00 2001 From: Yellowcooln <12516003+yellowcooln@users.noreply.github.com> Date: Tue, 9 Jun 2026 15:50:09 -0400 Subject: [PATCH] Fix companion identity OpenAPI contract --- repeater/web/openapi.yaml | 40 ++++++++++++++++++------- tests/test_openapi_identity_contract.py | 23 ++++++++++++++ 2 files changed, 53 insertions(+), 10 deletions(-) create mode 100644 tests/test_openapi_identity_contract.py diff --git a/repeater/web/openapi.yaml b/repeater/web/openapi.yaml index 45c1577..747a571 100644 --- a/repeater/web/openapi.yaml +++ b/repeater/web/openapi.yaml @@ -1862,7 +1862,7 @@ paths: tags: [Identities] summary: Create new identity description: | - Create a new repeater or room server identity. + Create a new companion or room server identity. `name` must be non-empty after trimming leading/trailing whitespace (whitespace-only values are rejected). requestBody: required: true @@ -1883,14 +1883,14 @@ paths: example: "General Chat" identity_key: type: string - pattern: '^[0-9a-fA-F]{64}$' - description: 32-byte hex key (64 chars). Omit for auto-generation - example: "abc123def456..." + pattern: '^(?:[0-9a-fA-F]{64}|[0-9a-fA-F]{128})$' + description: 32- or 64-byte hex key (64 or 128 chars). Omit for auto-generation + example: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" type: type: string - enum: [repeater, room_server] + enum: [companion, room_server] description: | - - repeater: Repeater identity (only one allowed) + - companion: Companion identity with a TCP endpoint - room_server: Room server for group chat example: room_server settings: @@ -1914,6 +1914,22 @@ paths: default: 32 description: Maximum messages to keep (hard limit 32) example: 32 + node_name: + type: string + description: Advertised node name (companion only; defaults to identity name) + example: "My Companion" + tcp_port: + type: integer + minimum: 1 + maximum: 65535 + default: 5000 + description: TCP listener port (companion only) + example: 5000 + bind_address: + type: string + default: "0.0.0.0" + description: TCP listener bind address (companion only) + example: "0.0.0.0" examples: room_server: value: @@ -1923,11 +1939,15 @@ paths: admin_password: "admin123" guest_password: "guest123" max_posts: 32 - repeater: + companion: value: - name: "My Repeater" - type: repeater - identity_key: "abc123def456..." + name: "My Companion" + type: companion + identity_key: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + settings: + node_name: "My Companion" + tcp_port: 5000 + bind_address: "0.0.0.0" responses: '200': description: Identity created diff --git a/tests/test_openapi_identity_contract.py b/tests/test_openapi_identity_contract.py new file mode 100644 index 0000000..fdfa743 --- /dev/null +++ b/tests/test_openapi_identity_contract.py @@ -0,0 +1,23 @@ +from pathlib import Path + +import yaml + + +def test_create_identity_schema_matches_supported_identity_types(): + spec_path = Path(__file__).parents[1] / "repeater" / "web" / "openapi.yaml" + spec = yaml.safe_load(spec_path.read_text(encoding="utf-8")) + + schema = spec["paths"]["/create_identity"]["post"]["requestBody"]["content"][ + "application/json" + ]["schema"] + properties = schema["properties"] + + assert properties["type"]["enum"] == ["companion", "room_server"] + assert {"node_name", "tcp_port", "bind_address"} <= set( + properties["settings"]["properties"] + ) + assert set( + spec["paths"]["/create_identity"]["post"]["requestBody"]["content"][ + "application/json" + ]["examples"] + ) == {"companion", "room_server"}