diff --git a/ts/session/messages/outgoing/content/sync/ContactSyncMessage.ts b/ts/session/messages/outgoing/content/sync/ContactSyncMessage.ts index 7bc978132..0b90f4b86 100644 --- a/ts/session/messages/outgoing/content/sync/ContactSyncMessage.ts +++ b/ts/session/messages/outgoing/content/sync/ContactSyncMessage.ts @@ -8,13 +8,13 @@ import { ChatMessage, DataMessage } from '../data'; interface ContactSyncMessageParams extends MessageParams { - sendTo: Array; - blocked: Array; + // Send to our devices + linkedDevices: Array; dataMessage?: DataMessage; } export class ContactSyncMessage extends SyncMessage { - constructor(params: MessageParams) { + constructor(params: ContactSyncMessageParams) { super(params); } diff --git a/ts/session/messages/outgoing/content/sync/GroupSyncMessage.ts b/ts/session/messages/outgoing/content/sync/GroupSyncMessage.ts index e69de29bb..0b90f4b86 100644 --- a/ts/session/messages/outgoing/content/sync/GroupSyncMessage.ts +++ b/ts/session/messages/outgoing/content/sync/GroupSyncMessage.ts @@ -0,0 +1,58 @@ +import { SignalService } from '../../../../../protobuf'; +import { MessageParams } from '../../Message'; +import { ContentMessage, SyncMessage } from '../'; +import { ConversationController, textsecure, libloki, Whisper } from '../../../../../window'; +import { PubKey } from '../../../../types'; +import * as Data from '../../../../../../js/modules/data'; +import { ChatMessage, DataMessage } from '../data'; + + +interface ContactSyncMessageParams extends MessageParams { + // Send to our devices + linkedDevices: Array; + dataMessage?: DataMessage; +} + +export class ContactSyncMessage extends SyncMessage { + constructor(params: ContactSyncMessageParams) { + super(params); + } + + protected syncProto() { + + // const contacts = new SignalService.SyncMessage.Contacts(); + // contacts. + + // SignalService.SyncMessage.Configuration + // SignalService.SyncMessage.Contacts.create( + + // ); + // SignalService.SyncMessage.Groups + // SignalService.SyncMessage.OpenGroupDetails + // SignalService.SyncMessage.Read + + const conversations = await Data.getAllConversations({ ConversationCollection: Whisper.ConversationCollection }); + const contacts = conversations.filter((conversation: any) => { + return ( + !conversation.isMe() && + conversation.isPrivate() && + !conversation.isSecondaryDevice() && + conversation.isFriend() + ); + }); + + const syncMessage = await libloki.api.createContactSyncProtoMessage(contacts) as SignalService.SyncMessage; + + // TODO: Is this a request sync message or a basic sync message? + // Set request type + const request = new SignalService.SyncMessage.Request(); + request.type = SignalService.SyncMessage.Request.Type.CONTACTS; + syncMessage.request = request; + + return syncMessage; + } + + // protected dataProto() { + // if dataMess + // } +} diff --git a/ts/session/sending/MessageQueue.ts b/ts/session/sending/MessageQueue.ts index 3cd4cf3b9..e48a530da 100644 --- a/ts/session/sending/MessageQueue.ts +++ b/ts/session/sending/MessageQueue.ts @@ -106,19 +106,19 @@ export class MessageQueue implements MessageQueueInterface { public async sendSyncMessage( message: ContentMessage - ): Promise | undefined> { + ): Promise { // Sync with our devices - const syncMessage = SyncMessageUtils.from(message); - if (!SyncMessageUtils.canSync(syncMessage)) { - return; - } + + - const ourDevices = await this.getOurDevices(); + const ourDevices = await SyncMessageUtils.getSyncContacts(); ourDevices.forEach(async device => { - await this.queue(device, message); - }); + const syncMessage = await SyncMessageUtils.from(message, device); - return ourDevices; + if (syncMessage) { + await this.queue(device, syncMessage); + } + }); } public async processPending(device: PubKey) { @@ -177,10 +177,4 @@ export class MessageQueue implements MessageQueueInterface { return queue; } - private async getOurDevices(): Promise> { - const ourKey = await textsecure.storage.user.getNumber(); - const ourLinked = await Data.getPairedDevicesFor(ourKey); - - return ourLinked.map(d => new PubKey(d)); - } } diff --git a/ts/session/utils/SyncMessageUtils.ts b/ts/session/utils/SyncMessageUtils.ts index bb50709a1..b1c83515e 100644 --- a/ts/session/utils/SyncMessageUtils.ts +++ b/ts/session/utils/SyncMessageUtils.ts @@ -10,29 +10,83 @@ import { EncryptionType, PubKey } from '../types'; import { SignalService } from '../../protobuf'; import { SyncMessageType } from '../messages/outgoing/content/sync/SyncMessage'; +import * as Data from '../../../js/modules/data'; +import { textsecure, libloki, ConversationController, Whisper } from '../../window'; + // export function from(message: ContentMessage): SyncMessage | undefined { // testtttingggg -export function from( +export async function from( message: ContentMessage, - syncType: SyncMessageEnum = SyncMessageEnum.CONTACTS -): SyncMessageType { + sendTo: any, + syncType: SyncMessageEnum.CONTACTS | SyncMessageEnum.GROUPS = SyncMessageEnum.CONTACTS +): Promise { + const { timestamp, identifier } = message; + // Detect Sync Message Type const plainText = message.plainTextBuffer(); const decoded = SignalService.Content.decode(plainText); - console.log('[vince] decoded:', decoded); - let syncMessage: SyncMessage; - switch (syncType) { case SyncMessageEnum.CONTACTS: - syncMessage = new ContactSyncMessage({}); + + // Send to one device at a time + + const builtSyncMessage = await libloki.api.createContactSyncProtoMessage(); + + + break; + case SyncMessageEnum.GROUPS: + + syncMessage = new GroupSyncMessage({ + + }); + break; + default: } return syncMessage; } -export function canSync(message: ContentMessage): boolean { - return Boolean(from(message)); +export async function canSync(message: ContentMessage, device: any): boolean { + return Boolean(from(message, device)); +} + + +export async function getSyncContacts(): Promise> { + const thisDevice = textsecure.storage.user.getNumber(); + const primaryDevice = await Data.getPrimaryDeviceFor(thisDevice); + const conversations = await Data.getAllConversations({ ConversationCollection: Whisper.ConversationCollection }); + + // We are building a set of all contacts + const primaryContacts = conversations.filter(c => + c.isPrivate() && + !c.isOurLocalDevice() && + c.isFriend() && + !c.attributes.secondaryStatus + ) || []; + + const secondaryContactsPartial = conversations.filter(c => + c.isPrivate() && + !c.isOurLocalDevice() && + c.isFriend() && + c.attributes.secondaryStatus + ); + + const seondaryContactsPromise = secondaryContactsPartial.map(async c => + ConversationController.getOrCreateAndWait( + c.getPrimaryDevicePubKey(), + 'private' + ) + ); + + const secondaryContacts = (await Promise.all(seondaryContactsPromise)) + // Filter out our primary key if it was added here + .filter(c => c.id !== primaryDevice); + + return new Set([ + ...primaryContacts, + ...secondaryContacts, + ]); } diff --git a/ts/test/session/sending/MessageQueue_test.ts b/ts/test/session/sending/MessageQueue_test.ts index d31213996..68dfdb37e 100644 --- a/ts/test/session/sending/MessageQueue_test.ts +++ b/ts/test/session/sending/MessageQueue_test.ts @@ -14,7 +14,7 @@ interface StorageItem { value: any; } -describe('PendingMessageCache', () => { +describe('MessageQueue', () => { // Initialize new stubbed cache let data: StorageItem; let pendingMessageCacheStub: PendingMessageCache; @@ -32,12 +32,14 @@ describe('PendingMessageCache', () => { const message = TestUtils.generateChatMessage(); const rawMessage = MessageUtils.toRawMessage(device, message); - SyncMessageUtils.from(message); + // SyncMessageUtils.from(message); const myOpenGroup = new OpenGroup({conversationId: 'publicChat:1@feedback.getsession.org'}); - console.log('[vince] myOpenGroup.server:', myOpenGroup.server); console.log('[vince] myOpenGroup.channel:', myOpenGroup.channel); console.log('[vince] myOpenGroup.conversationId:', myOpenGroup.conversationId); + + + }); }); diff --git a/ts/window/index.ts b/ts/window/index.ts index 27fca768f..a75b33a08 100644 --- a/ts/window/index.ts +++ b/ts/window/index.ts @@ -138,6 +138,7 @@ export const dcodeIO = window.dcodeIO; export const libloki = window.libloki; export const libsignal = window.libsignal; export const textsecure = window.textsecure; +export const storage = window.storage; export const lokiMessageAPI = window.lokiMessageAPI; export const lokiPublicChatAPI = window.lokiPublicChatAPI;