diff --git a/ts/session/messages/outgoing/OpenGroupMessage.ts b/ts/session/messages/outgoing/OpenGroupMessage.ts index 286f9b593..c670a5e68 100644 --- a/ts/session/messages/outgoing/OpenGroupMessage.ts +++ b/ts/session/messages/outgoing/OpenGroupMessage.ts @@ -1,11 +1,6 @@ import { Message, MessageParams } from './Message'; import { AttachmentPointer, Preview, Quote } from './content'; - -interface OpenGroup { - server: string; - channel: number; - conversationId: string; -} +import { OpenGroup } from '../../types/OpenGroup'; interface OpenGroupMessageParams extends MessageParams { group: OpenGroup; @@ -20,7 +15,7 @@ export class OpenGroupMessage extends Message { public readonly body?: string; public readonly attachments: Array; public readonly quote?: Quote; - public readonly preview: Array; + public readonly preview?: Array; constructor({ timestamp, diff --git a/ts/session/messages/outgoing/content/OpenGroupChatMessage.ts b/ts/session/messages/outgoing/content/OpenGroupChatMessage.ts new file mode 100644 index 000000000..e69de29bb diff --git a/ts/session/messages/outgoing/content/sync/OpenGroupSyncMessage.ts b/ts/session/messages/outgoing/content/sync/OpenGroupSyncMessage.ts new file mode 100644 index 000000000..e69de29bb diff --git a/ts/session/types/OpenGroup.ts b/ts/session/types/OpenGroup.ts new file mode 100644 index 000000000..658f2f8d1 --- /dev/null +++ b/ts/session/types/OpenGroup.ts @@ -0,0 +1,82 @@ +// This is the Open Group equivalent to the PubKey type. + +interface OpenGroupParams { + server: string; + channel: number; + conversationId: string; +} + +export class OpenGroup { + private static readonly serverRegex = new RegExp( + '^([\\w-]{2,}.){1,2}[\\w-]{2,}$' + ); + private static readonly groupIdRegex = new RegExp( + '^publicChat:[0-9]*@([\\w-]{2,}.){1,2}[\\w-]{2,}$' + ); + public readonly server: string; + public readonly channel: number; + public readonly groupId?: string; + public readonly conversationId: string; + + constructor(params: OpenGroupParams) { + const strippedServer = params.server.replace('https://', ''); + this.server = strippedServer; + + // Validate server format + const isValid = OpenGroup.serverRegex.test(this.server); + if (!isValid) { + throw Error('an invalid server or groupId was provided'); + } + + this.channel = params.channel; + this.conversationId = params.conversationId; + this.groupId = OpenGroup.getGroupId(this.server, this.channel); + } + + public static from( + groupId: string, + conversationId: string + ): OpenGroup | undefined { + // Returns a new instance from a groupId if it's valid + // eg. groupId = 'publicChat:1@chat.getsession.org' + + const server = this.getServer(groupId); + const channel = this.getChannel(groupId); + + // Was groupId successfully utilized? + if (!server || !channel) { + return; + } + + const openGroupParams = { + server, + channel, + groupId, + conversationId, + } as OpenGroupParams; + + if (this.serverRegex.test(server)) { + return new OpenGroup(openGroupParams); + } + + return; + } + + private static getServer(groupId: string): string | undefined { + const isValid = this.groupIdRegex.test(groupId); + + return isValid ? groupId.split('@')[1] : undefined; + } + + private static getChannel(groupId: string): number | undefined { + const isValid = this.groupIdRegex.test(groupId); + const channelMatch = groupId.match(/^.*\:([0-9]*)\@.*$/); + + return channelMatch && isValid ? Number(channelMatch[1]) : undefined; + } + + private static getGroupId(server: string, channel: number): string { + // server is already validated in constructor; no need to re-check + return `publicChat:${channel}@${server}`; + } +} diff --git a/ts/test/session/messages/OpenGroupMessage_test.ts b/ts/test/session/messages/OpenGroupMessage_test.ts index 7223ca394..ad05c5b6e 100644 --- a/ts/test/session/messages/OpenGroupMessage_test.ts +++ b/ts/test/session/messages/OpenGroupMessage_test.ts @@ -5,13 +5,14 @@ import { OpenGroupMessage, } from '../../../session/messages/outgoing'; import * as MIME from '../../../../ts/types/MIME'; +import { OpenGroup } from '../../../session/types/OpenGroup' describe('OpenGroupMessage', () => { - const group = { - server: 'server', + const group = new OpenGroup({ + server: 'chat.example.server', channel: 1, conversationId: '0', - }; + }); it('can create empty message with just a timestamp and group', () => { const message = new OpenGroupMessage({