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