diff --git a/src/channelManager.ts b/src/channelManager.ts index a6100b1..42a58b9 100644 --- a/src/channelManager.ts +++ b/src/channelManager.ts @@ -47,11 +47,20 @@ class ChannelManager { if (channel) { channel.addClient(client); - client.connectToChannel(channel); return {status: 'success'}; } else { - logger.accessLog.info(`channel with id ${channel_id} does not exist.`); - return {status: 'notice', message: `channel with id ${channel_id} does not exist.`}; + logger.accessLog.info(`channel with id ${channel_id} does not exist. could not add client to channel`); + return {status: 'notice', message: `channel with id ${channel_id} does not exist. could not add client to channel`}; + } + } + + updateChannelContent(channel: PrivateChannel|PrivateChannel|CustomChannel, channelContent: JSON) { + if (channel) { + channel.channelContent = channelContent; + return {status: 'success'}; + } else { + logger.accessLog.info(`channel with id ${channel} does not exist. could not update content`); + return {status: 'notice', message: `channel with id ${channel} does not exist. could not update content`}; } } diff --git a/src/channels/channelBase.ts b/src/channels/channelBase.ts index 1bf3a06..b86716b 100644 --- a/src/channels/channelBase.ts +++ b/src/channels/channelBase.ts @@ -7,6 +7,8 @@ const logger = require('../logger'); class ChannelBase { id: string; clients: any[] = []; + broadcastConditions: string = "true"; + channelContent: JSON = JSON.parse('{}'); constructor(id: string) { this.id = id; @@ -26,8 +28,8 @@ class ChannelBase { return {status: 'success', message: `message broadcast complete`}; } - messageTransactionPossible(_from: PublicClient|PrivateClient|CustomClient, _to: PublicClient|PrivateClient|CustomClient) { - return true; + messageTransactionPossible(from: PublicClient|PrivateClient|CustomClient, to: PublicClient|PrivateClient|CustomClient) { + return eval(this.broadcastConditions); } addClient(client: PublicClient|PrivateClient|CustomClient) { @@ -36,6 +38,7 @@ class ChannelBase { return {status: 'notice', message: 'client already exists in channel'}; } else { this.clients.push(client); + client.connectToChannel(this); logger.accessLog.info('Added client to channel', {channelId: this.id, clientId: client.id}); return {status: 'success', message: 'client added'}; } diff --git a/src/channels/types/customChannel.ts b/src/channels/types/customChannel.ts index 82b6b47..fbb24f4 100644 --- a/src/channels/types/customChannel.ts +++ b/src/channels/types/customChannel.ts @@ -3,15 +3,14 @@ import ChannelBase from '../channelBase'; class CustomChannel extends ChannelBase { clients: CustomClient[] = []; - custom: any; constructor(id: string, custom: any) { super(id); - this.custom = custom; - } - messageTransactionPossible(from: CustomClient, to: CustomClient) { - return eval(this.custom.broadcastConditions); + if (custom) { + this.broadcastConditions = custom.broadcastConditions; + this.channelContent = custom.channelContent; + } } } diff --git a/src/channels/types/privateChannel.ts b/src/channels/types/privateChannel.ts index 98e5143..c4b742e 100644 --- a/src/channels/types/privateChannel.ts +++ b/src/channels/types/privateChannel.ts @@ -4,12 +4,13 @@ import ChannelBase from '../channelBase'; class PrivateChannel extends ChannelBase { clients: PrivateClient[] = []; - messageTransactionPossible(from: PrivateClient, to: PrivateClient) { - return ( - to !== from && - to.roles.includes('receiver') && - from.roles.includes('broadcaster') - ); + constructor(id: string) { + super(id); + + this.broadcastConditions = + "to != from && \ + to.roles.includes('receiver') && \ + from.roles.includes('broadcaster')"; } } diff --git a/src/channels/types/publicChannel.ts b/src/channels/types/publicChannel.ts index 2bdc2f0..3b7009e 100644 --- a/src/channels/types/publicChannel.ts +++ b/src/channels/types/publicChannel.ts @@ -4,10 +4,10 @@ import ChannelBase from '../channelBase'; class PublicChannel extends ChannelBase { clients: PublicClient[] = []; - messageTransactionPossible(from: PublicClient, to: PublicClient) { - return ( - to !== from - ); + constructor(id: string) { + super(id); + + this.broadcastConditions = "to != from"; } } diff --git a/src/clients/clientBase.ts b/src/clients/clientBase.ts index febb488..5d26f2e 100644 --- a/src/clients/clientBase.ts +++ b/src/clients/clientBase.ts @@ -17,6 +17,7 @@ class ClientBase { channelManager: ChannelManager; roles: string[]; messageListener: (data: any) => void; + closeListener: () => void; constructor(data: any, ws: WebSocket, channelManager: ChannelManager, clientManager: ClientManager) { this.ws = ws; @@ -33,6 +34,16 @@ class ClientBase { this.messageTransaction(message); } }; + this.closeListener = () => { + logger.accessLog.info(`closing connection for client ${this.id}`); + + if (this.channel) { + this.channel.removeClient(this.id); + } + + this.clientManager.removeClient(this.id); + logger.accessLog.info(`closed connection for client ${this.id}`); + }; logger.accessLog.info('Client Created', {data}); } @@ -51,19 +62,8 @@ class ClientBase { connectToChannel(channel: PublicChannel|PrivateChannel|CustomChannel) { this.channel = channel; - this.ws.on('message', this.messageListener); - - this.ws.on('close', (reasonCode: string, description: string) => { - logger.accessLog.info(`closing connection for client ${this.id}`); - - if (this.channel) { - this.channel.removeClient(this.id); - } - - this.clientManager.removeClient(this.id); - logger.accessLog.info(`closed connection for client ${this.id}`); - }); + this.ws.on('close', this.closeListener); } messageTransaction(message: any) { diff --git a/src/server.ts b/src/server.ts index 3e2ae41..f0c4dfc 100755 --- a/src/server.ts +++ b/src/server.ts @@ -41,7 +41,24 @@ function connectionManager() { client = clientManager.addClient(data, channelManager, ws); } - if (client != null) channelManager.addClientToChannel(client, data.channel); + if (client != null) { + channelManager.addClientToChannel(client, data.channel); + + if (data.channel_type == 'custom') { + const channel = channelManager.channelExists(data.channel); + const connectionResponse = { + message_type: 'channelStatus', + content: channel.channelContent + } + + if (data.user_roles.includes('super')) { + channelManager.updateChannelContent(channel, data.custom.channelContent); + channel.broadcastMessage(connectionResponse); + } else { + client.directMessage(connectionResponse); + } + } + } logger.accessLog.info(`Purging empty channels...`); channelManager.purgeEmptyChannels();