add some regex to identify Opengroupv2 vs Opengroupv1 convo Ids

pull/1576/head
Audric Ackermann 4 years ago
parent 9de65c8813
commit 3b30d13719
No known key found for this signature in database
GPG Key ID: 999F434D76324AD4

@ -37,6 +37,7 @@ import {
import { GroupInvitationMessage } from '../session/messages/outgoing/visibleMessage/GroupInvitationMessage';
import { ReadReceiptMessage } from '../session/messages/outgoing/controlMessage/receipt/ReadReceiptMessage';
import { OpenGroup } from '../opengroup/opengroupV1/OpenGroup';
import { openGroupPrefixRegex } from '../opengroup/utils/OpenGroupUtils';
export enum ConversationType {
GROUP = 'group',
@ -188,7 +189,7 @@ export class ConversationModel extends Backbone.Model<ConversationAttributes> {
return UserUtils.isUsFromCache(this.id);
}
public isPublic() {
return !!(this.id && this.id.match(OpenGroup.openGroupPrefixRegex));
return !!(this.id && this.id.match(openGroupPrefixRegex));
}
public isOpenGroupV2() {
return this.get('type') === ConversationType.OPEN_GROUP;

@ -23,6 +23,8 @@ import { getSuggestedFilenameSending } from '../types/Attachment';
import { actions as conversationActions } from '../state/ducks/conversations';
import { VisibleMessage } from '../session/messages/outgoing/visibleMessage/VisibleMessage';
import { buildSyncMessage } from '../session/utils/syncUtils';
import { isOpenGroupV2 } from '../opengroup/utils/OpenGroupUtils';
import { banUser } from '../opengroup/opengroupV2/OpenGroupAPIV2';
export class MessageModel extends Backbone.Model<MessageAttributes> {
public propsForTimerNotification: any;
public propsForGroupNotification: any;
@ -715,14 +717,17 @@ export class MessageModel extends Backbone.Model<MessageAttributes> {
window.log.info('cannot ban user, the corresponding conversation was not found.');
return;
}
const channelAPI = await conversation.getPublicSendData();
if (!channelAPI) {
window.log.info('cannot ban user, the corresponding channelAPI was not found.');
return;
let success = false;
if (isOpenGroupV2(conversation.id)) {
await banUser();
} else {
const channelAPI = await conversation.getPublicSendData();
if (!channelAPI) {
window.log.info('cannot ban user, the corresponding channelAPI was not found.');
return;
}
success = await channelAPI.banUser(source);
}
const success = await channelAPI.banUser(source);
if (success) {
ToastUtils.pushUserBanSuccess();
} else {

@ -3,7 +3,7 @@ import { ConversationController } from '../../session/conversations';
import { PromiseUtils } from '../../session/utils';
import { allowOnlyOneAtATime } from '../../session/utils/Promise';
import { forceSyncConfigurationNowIfNeeded } from '../../session/utils/syncUtils';
import { prefixify } from '../utils/OpenGroupUtils';
import { openGroupPrefix, prefixify } from '../utils/OpenGroupUtils';
interface OpenGroupParams {
server: string;
@ -12,20 +12,11 @@ interface OpenGroupParams {
}
export class OpenGroup {
/**
* Just a constant to have less `publicChat:` everywhere
* Note: It does already have the ':' included
*/
public static readonly openGroupPrefix = 'publicChat:';
/**
* Just a regex to match a public chat (i.e. a string starting with publicChat:)
*/
public static readonly openGroupPrefixRegex = new RegExp(`/^${OpenGroup.openGroupPrefix}/`);
private static readonly serverRegex = new RegExp(
'^((https?:\\/\\/){0,1})([\\w-]{2,}\\.){1,2}[\\w-]{2,}$'
);
private static readonly groupIdRegex = new RegExp(
`^${OpenGroup.openGroupPrefix}:[0-9]*@([\\w-]{2,}.){1,2}[\\w-]{2,}$`
`^${openGroupPrefix}:[0-9]*@([\\w-]{2,}.){1,2}[\\w-]{2,}$`
);
public readonly server: string;
@ -39,7 +30,7 @@ export class OpenGroup {
*
* @param params.server The server URL. `https` will be prepended if `http` or `https` is not explicitly set
* @param params.channel The server channel
* @param params.groupId The string corresponding to the server. Eg. `${OpenGroup.openGroupPrefix}1@chat.getsession.org`
* @param params.groupId The string corresponding to the server. Eg. `${openGroupPrefix}1@chat.getsession.org`
* @param params.conversationId The conversation ID for the backbone model
*/
constructor(params: OpenGroupParams) {
@ -76,7 +67,7 @@ export class OpenGroup {
* Try to make a new instance of `OpenGroup`.
* This does NOT respect `ConversationController` and does not guarentee the conversation's existence.
*
* @param groupId The string corresponding to the server. Eg. `${OpenGroup.openGroupPrefix}1@chat.getsession.org`
* @param groupId The string corresponding to the server. Eg. `${openGroupPrefix}1@chat.getsession.org`
* @param conversationId The conversation ID for the backbone model
* @returns `OpenGroup` if valid otherwise returns `undefined`.
*/
@ -167,7 +158,7 @@ export class OpenGroup {
}
const rawServerURL = server.replace(/^https?:\/\//i, '').replace(/[/\\]+$/i, '');
const channelId = 1;
const conversationId = `${OpenGroup.openGroupPrefix}${channelId}@${rawServerURL}`;
const conversationId = `${openGroupPrefix}${channelId}@${rawServerURL}`;
// Quickly peak to make sure we don't already have it
return ConversationController.getInstance().get(conversationId);
@ -210,7 +201,7 @@ export class OpenGroup {
const prefixRegex = new RegExp('https?:\\/\\/');
const strippedServer = server.replace(prefixRegex, '');
return `${OpenGroup.openGroupPrefix}${channel}@${strippedServer}`;
return `${openGroupPrefix}${channel}@${strippedServer}`;
}
/**
@ -252,7 +243,7 @@ export class OpenGroup {
const rawServerURL = serverUrl.replace(/^https?:\/\//i, '').replace(/[/\\]+$/i, '');
const conversationId = `${OpenGroup.openGroupPrefix}${channelId}@${rawServerURL}`;
const conversationId = `${openGroupPrefix}${channelId}@${rawServerURL}`;
// Quickly peak to make sure we don't already have it
const conversationExists = ConversationController.getInstance().get(conversationId);

@ -6,24 +6,14 @@ import {
import { ConversationController } from '../../session/conversations';
import { PromiseUtils } from '../../session/utils';
import { forceSyncConfigurationNowIfNeeded } from '../../session/utils/syncUtils';
import { getOpenGroupV2ConversationId, prefixify } from '../utils/OpenGroupUtils';
import {
getOpenGroupV2ConversationId,
openGroupV2CompleteURLRegex,
prefixify,
publicKeyParam,
} from '../utils/OpenGroupUtils';
import { attemptConnectionV2OneAtATime } from './OpenGroupManagerV2';
const protocolRegex = '(https?://)?';
const hostnameRegex =
'(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]).)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9-]*[A-Za-z0-9])';
const portRegex = '(:[0-9]+)?';
// roomIds allows between 2 and 64 of '0-9' or 'a-z' or '_' chars
const roomIdRegex = '[0-9a-z_]{2,64}';
const publicKeyRegex = '[0-9a-z]{64}';
const publicKeyParam = 'public_key=';
const openGroupV2CompleteURLRegex = new RegExp(
`^${protocolRegex}${hostnameRegex}${portRegex}/${roomIdRegex}\\?${publicKeyParam}${publicKeyRegex}$`,
'gm'
);
// Inputs that should work:
// https://sessionopengroup.co/main?public_key=658d29b91892a2389505596b135e76a53db6e11d613a51dbd3d0816adffb231c
// http://sessionopengroup.co/main?public_key=658d29b91892a2389505596b135e76a53db6e11d613a51dbd3d0816adffb231c

@ -2,6 +2,45 @@ import { default as insecureNodeFetch } from 'node-fetch';
import { sendViaOnion } from '../../session/onions/onionSend';
import { OpenGroup } from '../opengroupV1/OpenGroup';
export const protocolRegex = '(https?://)?';
export const hostnameRegex =
'(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]).)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9-]*[A-Za-z0-9])';
export const portRegex = '(:[0-9]+)?';
// roomIds allows between 2 and 64 of '0-9' or 'a-z' or '_' chars
export const roomIdV2Regex = '[0-9a-z_]{2,64}';
export const publicKeyRegex = '[0-9a-z]{64}';
export const publicKeyParam = 'public_key=';
export const openGroupV2ServerUrlRegex = new RegExp(`${protocolRegex}${hostnameRegex}${portRegex}`);
export const openGroupV2CompleteURLRegex = new RegExp(
`^${openGroupV2ServerUrlRegex}/${roomIdV2Regex}\\?${publicKeyParam}${publicKeyRegex}$`,
'gm'
);
/**
* Just a constant to have less `publicChat:` everywhere.
* This is the prefix used to identify our open groups in the conversation database (v1 or v2)
* Note: It does already have the ':' included
*/
export const openGroupPrefix = 'publicChat:';
/**
* Just a regex to match a public chat (i.e. a string starting with publicChat:)
*/
export const openGroupPrefixRegex = new RegExp(`/^${openGroupPrefix}/`);
/**
* An open group v1 conversation id can only have the char '1' as roomId
*/
export const openGroupV1ConversationIdRegex = new RegExp(
`${openGroupPrefix}1@${protocolRegex}${hostnameRegex}`
);
export const openGroupV2ConversationIdRegex = new RegExp(
`${openGroupPrefix}${roomIdV2Regex}@${protocolRegex}${hostnameRegex}${portRegex}`
);
/**
* Tries to establish a connection with the specified open group url.
*
@ -94,14 +133,37 @@ export function prefixify(server: string, hasSSL: boolean = true): string {
}
/**
* No sql access. Just how our open groupv2 url looks like
* @returns `${OpenGroup.openGroupPrefix}${roomId}@${serverUrl}`
* No sql access. Just how our open groupv2 url looks like.
* ServerUrl can have the protocol and port included, or not
* @returns `${openGroupPrefix}${roomId}@${serverUrl}`
*/
export function getOpenGroupV2ConversationId(serverUrl: string, roomId: string) {
if (roomId.length < 2) {
throw new Error('Invalid roomId: too short');
if (!roomId.match(roomIdV2Regex)) {
throw new Error('getOpenGroupV2ConversationId: Invalid roomId');
}
if (!serverUrl.match(openGroupV2ServerUrlRegex)) {
throw new Error('getOpenGroupV2ConversationId: Invalid serverUrl');
}
return `${OpenGroup.openGroupPrefix}${roomId}@${serverUrl}`;
return `${openGroupPrefix}${roomId}@${serverUrl}`;
}
export function isOpenGroupV2(conversationId: string) {}
/**
* Check if this conversation id corresponds to an OpenGroupV2 conversation.
* No access to database are made. Only regex matches
* @param conversationId the convo id to evaluate
* @returns true if this conversation id matches the Opengroupv2 conversation id regex
*/
export function isOpenGroupV2(conversationId: string) {
if (!conversationId?.match(openGroupPrefixRegex)) {
// this is not even an open group
return false;
}
if (!conversationId?.match(openGroupV1ConversationIdRegex)) {
// this is an open group v1
console.warn('this is an open group v1:', conversationId);
return false;
}
return conversationId.match(openGroupV2ConversationIdRegex);
}

@ -23,6 +23,7 @@ import { ConversationController } from '../session/conversations';
import { removeUnprocessed } from '../data/data';
import { ConversationType } from '../models/conversation';
import { OpenGroup } from '../opengroup/opengroupV1/OpenGroup';
import { openGroupPrefixRegex } from '../opengroup/utils/OpenGroupUtils';
// TODO: check if some of these exports no longer needed
@ -273,8 +274,7 @@ export async function handlePublicMessage(messageData: any) {
await updateProfile(conversation, profile, profileKey);
}
const isPublicVisibleMessage =
group && group.id && !!group.id.match(OpenGroup.openGroupPrefixRegex);
const isPublicVisibleMessage = group && group.id && !!group.id.match(openGroupPrefixRegex);
if (!isPublicVisibleMessage) {
throw new Error('handlePublicMessage Should only be called with public message groups');

@ -21,6 +21,7 @@ import { ClosedGroupNameChangeMessage } from '../../../../session/messages/outgo
import { ClosedGroupNewMessage } from '../../../../session/messages/outgoing/controlMessage/group/ClosedGroupNewMessage';
import { ClosedGroupRemovedMembersMessage } from '../../../../session/messages/outgoing/controlMessage/group/ClosedGroupRemovedMembersMessage';
import { OpenGroup } from '../../../../opengroup/opengroupV1/OpenGroup';
import { openGroupPrefix } from '../../../../opengroup/utils/OpenGroupUtils';
const { expect } = chai;
@ -227,12 +228,12 @@ describe('Message Utils', () => {
let convos: Array<ConversationModel>;
const mockValidOpenGroup = new MockConversation({
type: ConversationType.OPEN_GROUP,
id: `${OpenGroup.openGroupPrefix}1@chat-dev.lokinet.org`,
id: `${openGroupPrefix}1@chat-dev.lokinet.org`,
});
const mockValidOpenGroup2 = new MockConversation({
type: ConversationType.OPEN_GROUP,
id: `${OpenGroup.openGroupPrefix}1@chat-dev2.lokinet.org`,
id: `${openGroupPrefix}1@chat-dev2.lokinet.org`,
});
const mockValidClosedGroup = new MockConversation({

@ -5,6 +5,7 @@ import { ConversationAttributes, ConversationType } from '../../../models/conver
import { OpenGroupMessage } from '../../../session/messages/outgoing';
import { VisibleMessage } from '../../../session/messages/outgoing/visibleMessage/VisibleMessage';
import { OpenGroup } from '../../../opengroup/opengroupV1/OpenGroup';
import { openGroupPrefixRegex } from '../../../opengroup/utils/OpenGroupUtils';
export function generateVisibleMessage(identifier?: string): VisibleMessage {
return new VisibleMessage({
@ -92,7 +93,7 @@ export class MockConversation {
}
public isPublic() {
return this.id.match(OpenGroup.openGroupPrefixRegex);
return this.id.match(openGroupPrefixRegex);
}
public isMediumGroup() {

Loading…
Cancel
Save