feat(#292): implement protocol version checking
Add protocol version validation during connection handshake. - Define FEDERATION_PROTOCOL_VERSION constant (1.0) - Validate version on both outgoing and incoming connections - Require exact version match for compatibility - Log and audit version mismatches Fixes #292 Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -21,6 +21,7 @@ import { FederationAuditService } from "./audit.service";
|
||||
import { firstValueFrom } from "rxjs";
|
||||
import type { ConnectionRequest, ConnectionDetails } from "./types/connection.types";
|
||||
import type { PublicInstanceIdentity } from "./types/instance.types";
|
||||
import { FEDERATION_PROTOCOL_VERSION } from "./constants";
|
||||
|
||||
@Injectable()
|
||||
export class ConnectionService {
|
||||
@@ -55,6 +56,9 @@ export class ConnectionService {
|
||||
// Fetch remote instance identity
|
||||
const remoteIdentity = await this.fetchRemoteIdentity(remoteUrl);
|
||||
|
||||
// Validate protocol version compatibility
|
||||
this.validateProtocolVersion(remoteIdentity.capabilities.protocolVersion);
|
||||
|
||||
// Get our instance identity
|
||||
const localIdentity = await this.federationService.getInstanceIdentity();
|
||||
|
||||
@@ -316,6 +320,25 @@ export class ConnectionService {
|
||||
throw new UnauthorizedException("Invalid connection request signature");
|
||||
}
|
||||
|
||||
// Validate protocol version compatibility
|
||||
try {
|
||||
this.validateProtocolVersion(request.capabilities.protocolVersion);
|
||||
} catch (error) {
|
||||
const errorMsg = error instanceof Error ? error.message : "Unknown error";
|
||||
this.logger.warn(`Incompatible protocol version from ${request.instanceId}: ${errorMsg}`);
|
||||
|
||||
// Audit log: Connection rejected
|
||||
this.auditService.logIncomingConnectionRejected({
|
||||
workspaceId,
|
||||
remoteInstanceId: request.instanceId,
|
||||
remoteUrl: request.instanceUrl,
|
||||
reason: "Incompatible protocol version",
|
||||
error: errorMsg,
|
||||
});
|
||||
|
||||
throw error;
|
||||
}
|
||||
|
||||
// Create pending connection
|
||||
const connection = await this.prisma.federationConnection.create({
|
||||
data: {
|
||||
@@ -403,4 +426,22 @@ export class ConnectionService {
|
||||
disconnectedAt: connection.disconnectedAt,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate protocol version compatibility
|
||||
* Currently requires exact version match
|
||||
*/
|
||||
private validateProtocolVersion(remoteVersion: string | undefined): void {
|
||||
if (!remoteVersion) {
|
||||
throw new BadRequestException(
|
||||
`Protocol version not specified. Expected ${FEDERATION_PROTOCOL_VERSION}`
|
||||
);
|
||||
}
|
||||
|
||||
if (remoteVersion !== FEDERATION_PROTOCOL_VERSION) {
|
||||
throw new BadRequestException(
|
||||
`Incompatible protocol version. Expected ${FEDERATION_PROTOCOL_VERSION}, received ${remoteVersion}`
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user