UNPKG

open-collaboration-server

Version:

Open Collaboration Server implementation, part of the Open Collaboration Tools project

96 lines 4.22 kB
// ****************************************************************************** // Copyright 2024 TypeFox GmbH // This program and the accompanying materials are made available under the // terms of the MIT License, which is available in the project root. // ****************************************************************************** var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; import { inject, injectable } from 'inversify'; import { Deferred, BroadcastMessage, Message } from 'open-collaboration-protocol'; import { nanoid } from 'nanoid'; import { Logger } from './utils/logging.js'; let MessageRelay = class MessageRelay { logger; requestMap = new Map(); pushResponse(receiver, message) { const relayedRequest = this.requestMap.get(message.id.toString()); if (relayedRequest) { relayedRequest.response.resolve(message); relayedRequest.dispose(); } } sendRequest(target, message, timeoutMs) { const deferred = new Deferred(); const messageId = message.id; const key = nanoid(24); const dispose = () => { this.requestMap.delete(key); clearTimeout(timeout); deferred.reject(new Error('Request timed out')); }; const timeout = setTimeout(dispose, timeoutMs ?? 30_000); this.requestMap.set(key, { id: messageId, response: deferred, dispose }); const targetMessage = { ...message, id: key }; target.channel.sendMessage(targetMessage); return deferred.promise; } sendNotification(target, message) { target.channel.sendMessage(message); } sendBroadcast(origin, message) { try { const room = origin.room; message.origin = origin.id; for (const peer of room.peers) { if (peer !== origin) { // Find the key for the target peer const peerKey = message.metadata.encryption.keys.find(e => e.target === peer.id); if (peerKey && BroadcastMessage.isEncrypted(message)) { // Adjust the message to only contain the key for the target peer // All other keys are not of use for the target peer const messageWithSingleKey = { ...message, metadata: { ...message.metadata, encryption: { keys: [peerKey] } } }; peer.channel.sendMessage(messageWithSingleKey); } else if (!Message.isEncrypted(message)) { peer.channel.sendMessage(message); } else { // If the sender did not include a key for one of the peers, they cannot decrypt the message // This is unexpected behavior as every broadcast should be sent to every peer in the room this.logger.warn(`No key found for peer ${peer.id} in room ${room.id}`); } } } } catch (error) { this.logger.error('Error occurred during broadcast', error); } } }; __decorate([ inject(Logger) ], MessageRelay.prototype, "logger", void 0); MessageRelay = __decorate([ injectable() ], MessageRelay); export { MessageRelay }; //# sourceMappingURL=message-relay.js.map