|
|
|
@ -1,15 +1,17 @@
|
|
|
|
|
// This is the Open Group equivalent to the PubKey type.
|
|
|
|
|
|
|
|
|
|
interface OpenGroupParams {
|
|
|
|
|
server?: string;
|
|
|
|
|
channel?: number;
|
|
|
|
|
server: string;
|
|
|
|
|
channel: number;
|
|
|
|
|
conversationId: string;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export class OpenGroup {
|
|
|
|
|
private static readonly conversationIdRegex: RegExp = new RegExp('^publicChat:[0-9]*@([\\w-]{2,}.){1,2}[\\w-]{2,}$');
|
|
|
|
|
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;
|
|
|
|
|
private readonly isValid: boolean;
|
|
|
|
|
|
|
|
|
@ -17,51 +19,66 @@ export class OpenGroup {
|
|
|
|
|
this.isValid = OpenGroup.validate(params);
|
|
|
|
|
|
|
|
|
|
if (!this.isValid) {
|
|
|
|
|
throw Error('an invalid conversationId was provided');
|
|
|
|
|
throw Error('an invalid server or groupId was provided');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const strippedServer = params.server.replace('https://', '');
|
|
|
|
|
|
|
|
|
|
this.server = strippedServer;
|
|
|
|
|
this.channel = params.channel;
|
|
|
|
|
this.conversationId = params.conversationId;
|
|
|
|
|
this.server = params.server ?? this.getServer(params.conversationId);
|
|
|
|
|
this.channel = params.channel ?? this.getChannel(params.conversationId);
|
|
|
|
|
this.groupId = OpenGroup.getGroupId(this.server, this.channel);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static from(conversationId: string): OpenGroup | undefined {
|
|
|
|
|
// Returns a new instance if conversationId is valid
|
|
|
|
|
if (OpenGroup.validate({conversationId})) {
|
|
|
|
|
return new OpenGroup({conversationId});
|
|
|
|
|
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'
|
|
|
|
|
|
|
|
|
|
// Valid groupId?
|
|
|
|
|
if (!this.groupIdRegex.test(groupId)) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const openGroupParams = {
|
|
|
|
|
server: this.getServer(groupId),
|
|
|
|
|
channel: this.getChannel(groupId),
|
|
|
|
|
groupId,
|
|
|
|
|
conversationId,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
if (this.validate(openGroupParams)) {
|
|
|
|
|
return new OpenGroup(openGroupParams);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return undefined;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static validate(openGroup: OpenGroupParams): boolean {
|
|
|
|
|
// Validate conversationId
|
|
|
|
|
const { server, channel, conversationId } = openGroup;
|
|
|
|
|
// Validate that all the values match by rebuilding groupId.
|
|
|
|
|
const { server } = openGroup;
|
|
|
|
|
|
|
|
|
|
if (!this.conversationIdRegex.test(conversationId)) {
|
|
|
|
|
// Valid server?
|
|
|
|
|
if (!this.serverRegex.test(server)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Validate channel and server if provided
|
|
|
|
|
if (server && channel) {
|
|
|
|
|
const contrivedId = `publicChat:${String(channel)}@${server}`;
|
|
|
|
|
if (contrivedId !== conversationId) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private getServer(conversationId: string): string {
|
|
|
|
|
// conversationId is already validated in constructor; no need to re-check
|
|
|
|
|
return conversationId.split('@')[1];
|
|
|
|
|
private static getServer(groupId: string): string {
|
|
|
|
|
// groupId is already validated in constructor; no need to re-check
|
|
|
|
|
return groupId.split('@')[1];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private getChannel(conversationId: string): number {
|
|
|
|
|
// conversationId is already validated in constructor; no need to re-check
|
|
|
|
|
const channelMatch = conversationId.match(/^.*\:([0-9]*)\@.*$/);
|
|
|
|
|
private static getChannel(groupId: string): number {
|
|
|
|
|
// groupId is already validated in constructor; no need to re-check
|
|
|
|
|
const channelMatch = groupId.match(/^.*\:([0-9]*)\@.*$/);
|
|
|
|
|
|
|
|
|
|
return channelMatch ? Number(channelMatch[1]) : 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static getGroupId(server: string, channel: number): string {
|
|
|
|
|
// server is already validated in constructor; no need to re-check
|
|
|
|
|
return `publicChat:${channel}@${server}`;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|