import _ from 'lodash'; import { FileServerV2Request } from '../../fileserver/FileServerApiV2'; import { PubKey } from '../../session/types'; import { allowOnlyOneAtATime } from '../../session/utils/Promise'; import { updateDefaultRooms, updateDefaultRoomsInProgress } from '../../state/ducks/defaultRooms'; import { BlockedNumberController } from '../../util'; import { getCompleteUrlFromRoom } from '../utils/OpenGroupUtils'; import { parseOpenGroupV2 } from './JoinOpenGroupV2'; import { getAllRoomInfos } from './OpenGroupAPIV2'; import { OpenGroupMessageV2 } from './OpenGroupMessageV2'; export type OpenGroupRequestCommonType = { serverUrl: string; roomId: string; }; export type OpenGroupV2Request = FileServerV2Request & { room: string; server: string; isAuthRequired: boolean; serverPublicKey?: string; // if not provided, a db called will be made to try to get it. forcedTokenToUse?: string; }; export type OpenGroupV2CompactPollRequest = { server: string; endpoint: string; body: string; serverPubKey: string; }; export type OpenGroupV2Info = { id: string; name: string; imageId?: string; }; export type OpenGroupV2InfoJoinable = OpenGroupV2Info & { completeUrl: string; base64Data?: string; }; export const TextToBase64 = async (text: string) => { const arrayBuffer = await window.callWorker('bytesFromString', text); const base64 = await window.callWorker('arrayBufferToStringBase64', arrayBuffer); return base64; }; export const textToArrayBuffer = async (text: string) => { return window.callWorker('bytesFromString', text); }; export const verifyED25519Signature = async ( pubkey: string, base64EncodedData: string, base64EncondedSignature: string ): Promise => { return window.callWorker('verifySignature', pubkey, base64EncodedData, base64EncondedSignature); }; export const parseMessages = async ( rawMessages: Array> ): Promise> => { if (!rawMessages || rawMessages.length === 0) { window?.log?.info('no new messages'); return []; } const parsedMessages = []; // tslint:disable-next-line: prefer-for-of for (let i = 0; i < rawMessages.length; i++) { try { const opengroupv2Message = OpenGroupMessageV2.fromJson(rawMessages[i]); if ( !opengroupv2Message?.serverId || !opengroupv2Message.sentTimestamp || // this is our serverTimestamp !opengroupv2Message.base64EncodedData || !opengroupv2Message.base64EncodedSignature ) { window?.log?.warn('invalid open group message received'); continue; } // Validate the message signature const senderPubKey = PubKey.cast(opengroupv2Message.sender).withoutPrefix(); const signatureValid = (await window.callWorker( 'verifySignature', senderPubKey, opengroupv2Message.base64EncodedData, opengroupv2Message.base64EncodedSignature )) as boolean; if (!signatureValid) { throw new Error('opengroup message signature invalisd'); } parsedMessages.push(opengroupv2Message); } catch (e) { window?.log?.error('An error happened while fetching getMessages output:', e); } } return _.compact( parsedMessages.map(m => m && m.sender && !BlockedNumberController.isBlocked(m.sender) ? m : null ) ).sort((a, b) => (a.serverId || 0) - (b.serverId || 0)); }; // tslint:disable: no-http-string const defaultServerUrl = 'http://116.203.70.33'; const defaultServerPublicKey = 'a03c383cf63c3c4efe67acc52112a6dd734b3a946b9545f488aaa93da7991238'; const defaultRoom = `${defaultServerUrl}/main?public_key=${defaultServerPublicKey}`; const loadDefaultRoomsSingle = () => allowOnlyOneAtATime( 'loadDefaultRoomsSingle', async (): Promise> => { const roomInfos = parseOpenGroupV2(defaultRoom); if (roomInfos) { try { const roomsGot = await getAllRoomInfos(roomInfos); if (!roomsGot) { return []; } return roomsGot.map(room => { return { ...room, completeUrl: getCompleteUrlFromRoom({ serverUrl: roomInfos.serverUrl, serverPublicKey: roomInfos.serverPublicKey, roomId: room.id, }), }; }); } catch (e) { window?.log?.warn('loadDefaultRoomloadDefaultRoomssIfNeeded failed', e); } return []; } return []; } ); /** * Load to the cache all the details of the room of the default opengroupv2 server * This call will only run once at a time. */ export const loadDefaultRooms = async () => { window.inboxStore?.dispatch(updateDefaultRoomsInProgress(true)); const allRooms: Array = await loadDefaultRoomsSingle(); window.inboxStore?.dispatch(updateDefaultRoomsInProgress(false)); if (allRooms !== undefined) { window.inboxStore?.dispatch(updateDefaultRooms(allRooms)); } };