Mercure enforces a subscriber's mercure.subscribe topic scope ONLY for updates
marked private. An update published without the flag is public: the hub delivers it
to any authenticated subscriber that names the topic, regardless of what their token
authorises. So the careful per-subject scoping in MercureTokenMinter bought nothing —
a subscriber holding a valid token for their own channel could read any other
subject's by asking for it.
Confirmed against a live hub before and after: a token scoped to topic A received a
publish on topic B; with private=on the same subscriber receives nothing, while the
correctly-scoped token still does.
Adds CurlHubPublisherTest, which asserts the encoded request body over a real socket
rather than through a mock — a mock would only re-assert whatever the publisher chose
to pass along, which is precisely the bug it needs to catch. The private flag, the
event name, and the payload encoding are all silent failures when wrong, so all three
are pinned.
Also drops curl_close(): a no-op since PHP 8.0 and deprecated in 8.5, where it emitted
a deprecation notice on every publish.
Split from f81d8a8236ca04605f6c698f75df89668abccd0c