YNX-1003: Implement single-identifier single-active-connection policy

- Refactor transport to track temp connections separately from authenticated
- Add assignIdentifierToTemp() for hello phase (pre-auth)
- Add promoteToAuthenticated() that closes old connection only after new one auths
- Add removeTempConnection() for cleanup on auth failure
- Update runtime to use new API: assignIdentifierToTemp() on hello, promoteToAuthenticated() on auth_success

This prevents an attacker from kicking an authenticated connection with just a hello message.
This commit is contained in:
nav
2026-04-08 23:24:33 +00:00
parent 4f20ec3fd7
commit 988170dcf6
2 changed files with 79 additions and 31 deletions

View File

@@ -254,7 +254,7 @@ export class YonexusServerRuntime {
const record = this.ensureClientRecord(helloIdentifier);
record.updatedAt = this.now();
this.options.transport.registerConnection(helloIdentifier, connection.ws);
this.options.transport.assignIdentifierToTemp(connection.ws, helloIdentifier);
this.registry.sessions.set(helloIdentifier, {
identifier: helloIdentifier,
socket: connection.ws,
@@ -361,7 +361,7 @@ export class YonexusServerRuntime {
}
if (connection.identifier !== identifier) {
this.options.transport.registerConnection(identifier, connection.ws);
this.options.transport.assignIdentifierToTemp(connection.ws, identifier);
}
const session = this.registry.sessions.get(identifier);
@@ -540,7 +540,7 @@ export class YonexusServerRuntime {
session.lastActivityAt = now;
session.publicKey = publicKey;
}
this.options.transport.markAuthenticated(identifier);
this.options.transport.promoteToAuthenticated(identifier, connection.ws);
this.options.transport.sendToConnection(
{ ...connection, identifier },
encodeBuiltin(