You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
176 lines
6.5 KiB
TypeScript
176 lines
6.5 KiB
TypeScript
import _ from 'lodash';
|
|
import { OpenGroupV2Room } from '../../../../data/opengroups';
|
|
import { getConversationController } from '../../../conversations';
|
|
import { PromiseUtils, ToastUtils } from '../../../utils';
|
|
|
|
import { forceSyncConfigurationNowIfNeeded } from '../../../utils/syncUtils';
|
|
import {
|
|
getOpenGroupV2ConversationId,
|
|
openGroupV2CompleteURLRegex,
|
|
prefixify,
|
|
publicKeyParam,
|
|
} from '../utils/OpenGroupUtils';
|
|
import { hasExistingOpenGroup } from './ApiUtil';
|
|
import { getOpenGroupManager } from './OpenGroupManagerV2';
|
|
// tslint:disable: variable-name
|
|
|
|
// Inputs that should work:
|
|
// https://sessionopengroup.co/main?public_key=658d29b91892a2389505596b135e76a53db6e11d613a51dbd3d0816adffb231c
|
|
// http://sessionopengroup.co/main?public_key=658d29b91892a2389505596b135e76a53db6e11d613a51dbd3d0816adffb231c
|
|
// sessionopengroup.co/main?public_key=658d29b91892a2389505596b135e76a53db6e11d613a51dbd3d0816adffb231c (does NOT go to HTTPS)
|
|
// https://143.198.213.225:443/main?public_key=658d29b91892a2389505596b135e76a53db6e11d613a51dbd3d0816adffb231c
|
|
// 143.198.213.255:80/main?public_key=658d29b91892a2389505596b135e76a53db6e11d613a51dbd3d0816adffb231c
|
|
|
|
export function parseOpenGroupV2(urlWithPubkey: string): OpenGroupV2Room | undefined {
|
|
const lowerCased = urlWithPubkey.trim().toLowerCase();
|
|
try {
|
|
if (!openGroupV2CompleteURLRegex.test(lowerCased)) {
|
|
throw new Error('regex fail');
|
|
}
|
|
|
|
// prefix the URL if it does not have a prefix
|
|
const prefixedUrl = prefixify(lowerCased);
|
|
// new URL fails if the protocol is not explicit
|
|
const url = new URL(prefixedUrl);
|
|
|
|
// the port (if any is set) is already in the url.host so no need to += url.port
|
|
const serverUrl = `${url.protocol}//${url.host}`;
|
|
|
|
const room: OpenGroupV2Room = {
|
|
serverUrl,
|
|
roomId: url.pathname.slice(1), // remove first '/'
|
|
serverPublicKey: url.search.slice(publicKeyParam.length + 1), // remove the '?' and the 'public_key=' header
|
|
};
|
|
return room;
|
|
} catch (e) {
|
|
window?.log?.error('Invalid Opengroup v2 join URL:', lowerCased, e);
|
|
}
|
|
return undefined;
|
|
}
|
|
|
|
/**
|
|
* Join an open group using the v2 logic.
|
|
*
|
|
* If you only have an string with all details in it, use parseOpenGroupV2() to extract and check the URL is valid
|
|
*
|
|
* @param server The server URL to join, defaults to https if protocol is not set
|
|
* @param room The room id to join
|
|
* @param publicKey The server publicKey. It comes from the joining link. (or is already here for the default open group server)
|
|
*/
|
|
async function joinOpenGroupV2(room: OpenGroupV2Room, fromConfigMessage: boolean): Promise<void> {
|
|
if (!room.serverUrl || !room.roomId || room.roomId.length < 2 || !room.serverPublicKey) {
|
|
return;
|
|
}
|
|
|
|
const serverUrl = room.serverUrl.toLowerCase();
|
|
const roomId = room.roomId.toLowerCase();
|
|
const publicKey = room.serverPublicKey.toLowerCase();
|
|
const prefixedServer = prefixify(serverUrl);
|
|
|
|
const alreadyExist = hasExistingOpenGroup(serverUrl, roomId);
|
|
const conversationId = getOpenGroupV2ConversationId(serverUrl, roomId);
|
|
const existingConvo = getConversationController().get(conversationId);
|
|
|
|
if (alreadyExist) {
|
|
window?.log?.warn('Skipping join opengroupv2: already exists');
|
|
return;
|
|
} else if (existingConvo) {
|
|
// we already have a convo associated with it. Remove everything related to it so we start fresh
|
|
window?.log?.warn('leaving before rejoining open group v2 room', conversationId);
|
|
await getConversationController().deleteContact(conversationId);
|
|
}
|
|
|
|
// Try to connect to server
|
|
try {
|
|
const conversation = await PromiseUtils.timeout(
|
|
getOpenGroupManager().attemptConnectionV2OneAtATime(prefixedServer, roomId, publicKey),
|
|
20000
|
|
);
|
|
|
|
if (!conversation) {
|
|
window?.log?.warn('Failed to join open group v2');
|
|
throw new Error(window.i18n('connectToServerFail'));
|
|
}
|
|
|
|
// here we managed to connect to the group.
|
|
// if this is not a Sync Message, we should trigger one
|
|
if (!fromConfigMessage) {
|
|
await forceSyncConfigurationNowIfNeeded();
|
|
}
|
|
} catch (e) {
|
|
window?.log?.error('Could not join open group v2', e.message);
|
|
throw e;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* This function does not throw
|
|
* This function can be used to join an opengroupv2 server, from a user initiated click or from a syncMessage.
|
|
* If the user made the request, the UI callback needs to be set.
|
|
* the callback will be called on loading events (start and stop joining). Also, this callback being set defines if we will trigger a sync message or not.
|
|
*
|
|
* Basically,
|
|
* - user invitation click => uicallback set
|
|
* - user join manually from the join open group field => uicallback set
|
|
* - joining from a sync message => no uicallback
|
|
*
|
|
*
|
|
* return true if the room did not exist before, and we join it correctly
|
|
*/
|
|
export async function joinOpenGroupV2WithUIEvents(
|
|
completeUrl: string,
|
|
showToasts: boolean,
|
|
fromConfigMessage: boolean,
|
|
uiCallback?: (loading: boolean) => void
|
|
): Promise<boolean> {
|
|
try {
|
|
const parsedRoom = parseOpenGroupV2(completeUrl);
|
|
if (!parsedRoom) {
|
|
if (showToasts) {
|
|
ToastUtils.pushToastError('connectToServer', window.i18n('invalidOpenGroupUrl'));
|
|
}
|
|
return false;
|
|
}
|
|
const alreadyExist = hasExistingOpenGroup(parsedRoom.serverUrl, parsedRoom.roomId);
|
|
const conversationID = getOpenGroupV2ConversationId(parsedRoom.serverUrl, parsedRoom.roomId);
|
|
if (alreadyExist || getConversationController().get(conversationID)) {
|
|
if (showToasts) {
|
|
ToastUtils.pushToastError('publicChatExists', window.i18n('publicChatExists'));
|
|
}
|
|
return false;
|
|
}
|
|
if (showToasts) {
|
|
ToastUtils.pushToastInfo('connectingToServer', window.i18n('connectingToServer'));
|
|
}
|
|
if (uiCallback) {
|
|
uiCallback(true);
|
|
}
|
|
await joinOpenGroupV2(parsedRoom, fromConfigMessage);
|
|
|
|
const isConvoCreated = getConversationController().get(conversationID);
|
|
if (isConvoCreated) {
|
|
if (showToasts) {
|
|
ToastUtils.pushToastSuccess(
|
|
'connectToServerSuccess',
|
|
window.i18n('connectToServerSuccess')
|
|
);
|
|
}
|
|
return true;
|
|
} else {
|
|
if (showToasts) {
|
|
ToastUtils.pushToastError('connectToServerFail', window.i18n('connectToServerFail'));
|
|
}
|
|
}
|
|
} catch (error) {
|
|
window?.log?.warn('got error while joining open group:', error.message);
|
|
if (showToasts) {
|
|
ToastUtils.pushToastError('connectToServerFail', window.i18n('connectToServerFail'));
|
|
}
|
|
} finally {
|
|
if (uiCallback) {
|
|
uiCallback(false);
|
|
}
|
|
}
|
|
return false;
|
|
}
|