import * as _ from 'lodash'; import { UserUtil } from '../../util'; import { getAllConversations } from '../../../js/modules/data'; import { MultiDeviceProtocol } from '../protocols'; import ByteBuffer from 'bytebuffer'; import { ContentMessage, DataMessage, SentSyncMessage, } from '../messages/outgoing'; import { PubKey } from '../types'; export function getSentSyncMessage(params: { message: ContentMessage; expirationStartTimestamp?: number; sentTo?: Array; destination: PubKey | string; }): SentSyncMessage | undefined { if (!(params.message instanceof DataMessage)) { return undefined; } const pubKey = PubKey.cast(params.destination); return new SentSyncMessage({ timestamp: Date.now(), identifier: params.message.identifier, destination: pubKey, dataMessage: params.message.dataProto(), expirationStartTimestamp: params.expirationStartTimestamp, sentTo: params.sentTo, }); } export async function getSyncContacts(): Promise | undefined> { const thisDevice = await UserUtil.getCurrentDevicePubKey(); if (!thisDevice) { return []; } const primaryDevice = await MultiDeviceProtocol.getPrimaryDevice(thisDevice); const conversations = await getAllConversations({ ConversationCollection: window.Whisper.ConversationCollection, }); // We are building a set of all contacts const primaryContacts = conversations.filter( c => c.isPrivate() && !c.isOurLocalDevice() && !c.isBlocked() && !c.attributes.secondaryStatus && !!c.get('active_at') ) || []; const secondaryContactsPartial = conversations.filter( c => c.isPrivate() && !c.isOurLocalDevice() && !c.isBlocked() && c.attributes.secondaryStatus && !!c.get('active_at') ); const secondaryContactsPromise = secondaryContactsPartial.map(async c => window.ConversationController.getOrCreateAndWait( c.getPrimaryDevicePubKey(), 'private' ) ); const secondaryContacts = (await Promise.all(secondaryContactsPromise)) // Filter out our primary key if it was added here .filter(c => c.id !== primaryDevice.key); // Return unique contacts return _.uniqBy([...primaryContacts, ...secondaryContacts], 'id'); } export async function filterOpenGroupsConvos( conversations: Array ): Promise | undefined> { // If we haven't got a primaryDeviceKey then we are in the middle of pairing // primaryDevicePubKey is set to our own number if we are the master device const thisDevice = await UserUtil.getCurrentDevicePubKey(); if (!thisDevice) { return []; } // We only want to sync across open groups that we haven't left return conversations.filter( c => c.isPublic() && !c.isRss() && !c.get('left') ); } // Serialise as ... // This is an implementation of the reciprocal of contacts_parser.js export function serialiseByteBuffers(buffers: Array): ByteBuffer { const result = new ByteBuffer(); buffers.forEach(buffer => { // bytebuffer container expands and increments // offset automatically result.writeInt32(buffer.length); result.append(buffer); }); result.limit = result.offset; result.reset(); return result; }