diff --git a/js/signal_protocol_store.js b/js/signal_protocol_store.js index a50a9f86f..3aa5a9aad 100644 --- a/js/signal_protocol_store.js +++ b/js/signal_protocol_store.js @@ -39,21 +39,6 @@ return false; } - function convertVerifiedStatusToProtoState(status) { - switch (status) { - case VerifiedStatus.VERIFIED: - return textsecure.protobuf.Verified.State.VERIFIED; - - case VerifiedStatus.UNVERIFIED: - return textsecure.protobuf.Verified.State.VERIFIED; - - case VerifiedStatus.DEFAULT: - // intentional fallthrough - default: - return textsecure.protobuf.Verified.State.DEFAULT; - } - } - const StaticByteBufferProto = new dcodeIO.ByteBuffer().__proto__; const StaticArrayBufferProto = new ArrayBuffer().__proto__; const StaticUint8ArrayProto = new Uint8Array().__proto__; @@ -928,5 +913,4 @@ window.SignalProtocolStore = SignalProtocolStore; window.SignalProtocolStore.prototype.Direction = Direction; window.SignalProtocolStore.prototype.VerifiedStatus = VerifiedStatus; - window.SignalProtocolStore.prototype.convertVerifiedStatusToProtoState = convertVerifiedStatusToProtoState; })(); diff --git a/libloki/api.js b/libloki/api.js index 84dcb5b40..679055724 100644 --- a/libloki/api.js +++ b/libloki/api.js @@ -1,4 +1,4 @@ -/* global window, textsecure, dcodeIO, StringView, libsession */ +/* global window, textsecure, libsession */ /* eslint-disable no-bitwise */ // eslint-disable-next-line func-names @@ -54,20 +54,6 @@ } } - // Serialise as ... - // This is an implementation of the reciprocal of contacts_parser.js - function serialiseByteBuffers(buffers) { - const result = new dcodeIO.ByteBuffer(); - buffers.forEach(buffer => { - // bytebuffer container expands and increments - // offset automatically - result.writeInt32(buffer.limit); - result.append(buffer); - }); - result.limit = result.offset; - result.reset(); - return result; - } async function createContactSyncMessage(sessionContacts) { if (sessionContacts.length === 0) { return null; @@ -76,40 +62,25 @@ const rawContacts = await Promise.all( sessionContacts.map(async conversation => { const profile = conversation.getLokiProfile(); - const number = conversation.getNumber(); const name = profile ? profile.displayName : conversation.getProfileName(); const status = await conversation.safeGetVerified(); - const protoState = textsecure.storage.protocol.convertVerifiedStatusToProtoState( - status - ); - const verified = new textsecure.protobuf.Verified({ - state: protoState, - destination: number, - identityKey: StringView.hexToArrayBuffer(number), - }); + return { name, - verified, - number, + number: conversation.getNumber(), nickname: conversation.getNickname(), blocked: conversation.isBlocked(), expireTimer: conversation.get('expireTimer'), + verifiedStatus: status, }; }) ); - // Convert raw contacts to an array of buffers - const contactDetails = rawContacts - .filter(x => x.number !== textsecure.storage.user.getNumber()) - .map(x => new textsecure.protobuf.ContactDetails(x)) - .map(x => x.encode()); - // Serialise array of byteBuffers into 1 byteBuffer - const byteBuffer = serialiseByteBuffers(contactDetails); - const data = new Uint8Array(byteBuffer.toArrayBuffer()); + return new libsession.Messages.Outgoing.ContactSyncMessage({ timestamp: Date.now(), - data, + rawContacts, }); } @@ -117,7 +88,7 @@ // We are getting a single open group here const rawGroup = { - id: window.Signal.Crypto.bytesFromString(sessionGroup.id), + id: sessionGroup.id, name: sessionGroup.get('name'), members: sessionGroup.get('members') || [], blocked: sessionGroup.isBlocked(), @@ -125,14 +96,9 @@ admins: sessionGroup.get('groupAdmins') || [], }; - // Convert raw group to a buffer - const groupDetail = new textsecure.protobuf.GroupDetails(rawGroup).encode(); - // Serialise array of byteBuffers into 1 byteBuffer - const byteBuffer = serialiseByteBuffers([groupDetail]); - const data = new Uint8Array(byteBuffer.toArrayBuffer()); return new libsession.Messages.Outgoing.ClosedGroupSyncMessage({ timestamp: Date.now(), - data, + rawGroup, }); } diff --git a/ts/session/index.ts b/ts/session/index.ts index 11cc66a57..f53c4d63d 100644 --- a/ts/session/index.ts +++ b/ts/session/index.ts @@ -3,6 +3,6 @@ import * as Protocols from './protocols'; import * as Types from './types'; import * as Utils from './utils'; -import { getMessageQueue } from './instance'; +export * from './instance'; -export { Messages, Utils, Protocols, Types, getMessageQueue }; +export { Messages, Utils, Protocols, Types }; diff --git a/ts/session/messages/outgoing/content/sync/ClosedGroupSyncMessage.ts b/ts/session/messages/outgoing/content/sync/ClosedGroupSyncMessage.ts index bdb50ed05..0b19c103a 100644 --- a/ts/session/messages/outgoing/content/sync/ClosedGroupSyncMessage.ts +++ b/ts/session/messages/outgoing/content/sync/ClosedGroupSyncMessage.ts @@ -1,24 +1,59 @@ import { SyncMessage } from './SyncMessage'; import { SignalService } from '../../../../../protobuf'; import { MessageParams } from '../../Message'; -import { PubKey } from '../../../../types'; +import { StringUtils, SyncMessageUtils } from '../../../../utils'; + +interface RawGroup { + id: string; + name: string; + members: Array; + blocked: boolean; + expireTimer?: number; + admins: Array; +} interface ClosedGroupSyncMessageParams extends MessageParams { - data: Uint8Array; + rawGroup: RawGroup; } export abstract class ClosedGroupSyncMessage extends SyncMessage { - public readonly data: Uint8Array; + public readonly id: Uint8Array; + public readonly name: string; + public readonly members: Array; + public readonly blocked: boolean; + public readonly expireTimer: number | undefined; + public readonly admins: Array; constructor(params: ClosedGroupSyncMessageParams) { super({ timestamp: params.timestamp, identifier: params.identifier }); - this.data = params.data; + this.id = new Uint8Array(StringUtils.encode(params.rawGroup.id, 'utf8')); + this.name = params.rawGroup.name; + this.members = params.rawGroup.members; + this.blocked = params.rawGroup.blocked; + this.expireTimer = params.rawGroup.expireTimer; + this.admins = params.rawGroup.admins; } protected syncProto(): SignalService.SyncMessage { const syncMessage = super.syncProto(); + const groupDetails = new SignalService.GroupDetails({ + id: this.id, + name: this.name, + members: this.members, + blocked: this.blocked, + expireTimer: this.expireTimer, + admins: this.admins, + }); + + const encodedGroupDetails = SignalService.GroupDetails.encode( + groupDetails + ).finish(); + const byteBuffer = SyncMessageUtils.serialiseByteBuffers([ + encodedGroupDetails, + ]); + const data = new Uint8Array(byteBuffer.toArrayBuffer()); syncMessage.groups = new SignalService.SyncMessage.Groups({ - data: this.data, + data, }); return syncMessage; } diff --git a/ts/session/messages/outgoing/content/sync/ContactSyncMessage.ts b/ts/session/messages/outgoing/content/sync/ContactSyncMessage.ts index e10502699..48f4ccf59 100644 --- a/ts/session/messages/outgoing/content/sync/ContactSyncMessage.ts +++ b/ts/session/messages/outgoing/content/sync/ContactSyncMessage.ts @@ -1,23 +1,63 @@ import { SyncMessage } from './SyncMessage'; import { SignalService } from '../../../../../protobuf'; import { MessageParams } from '../../Message'; +import { StringUtils, SyncMessageUtils } from '../../../../utils'; +interface RawContact { + name: string; + number: string; + nickname?: string; + blocked: boolean; + expireTimer?: number; + verifiedStatus: number; +} interface ContactSyncMessageParams extends MessageParams { - data: Uint8Array; + rawContacts: [RawContact]; } export abstract class ContactSyncMessage extends SyncMessage { - public readonly data: Uint8Array; + public readonly rawContacts: [RawContact]; constructor(params: ContactSyncMessageParams) { super({ timestamp: params.timestamp, identifier: params.identifier }); - this.data = params.data; + this.rawContacts = params.rawContacts; } protected syncProto(): SignalService.SyncMessage { const syncMessage = super.syncProto(); + const contactsWithVerified = this.rawContacts.map(c => { + let protoState = SignalService.Verified.State.DEFAULT; + + if (c.verifiedStatus === 1 || c.verifiedStatus === 2) { + protoState = SignalService.Verified.State.VERIFIED; + } + const verified = new SignalService.Verified({ + state: protoState, + destination: c.number, + identityKey: new Uint8Array(StringUtils.encode(c.number, 'hex')), + }); + + return { + name: c.name, + verified, + number: c.number, + nickname: c.nickname, + blocked: c.blocked, + expireTimer: c.expireTimer, + }; + }); + + // Convert raw contacts to an array of buffers + const contactDetails = contactsWithVerified + .map(x => new SignalService.ContactDetails(x)) + .map(x => SignalService.ContactDetails.encode(x).finish()); + + // Serialise array of byteBuffers into 1 byteBuffer + const byteBuffer = SyncMessageUtils.serialiseByteBuffers(contactDetails); + const data = new Uint8Array(byteBuffer.toArrayBuffer()); + syncMessage.contacts = new SignalService.SyncMessage.Contacts({ - data: this.data, + data, }); return syncMessage; } diff --git a/ts/session/messages/outgoing/content/sync/SentSyncMessage.ts b/ts/session/messages/outgoing/content/sync/SentSyncMessage.ts index efc1646e7..3c7ad0685 100644 --- a/ts/session/messages/outgoing/content/sync/SentSyncMessage.ts +++ b/ts/session/messages/outgoing/content/sync/SentSyncMessage.ts @@ -6,16 +6,16 @@ import { PubKey } from '../../../../types'; interface SentSyncMessageParams extends MessageParams { dataMessage: SignalService.DataMessage; expirationStartTimestamp?: number; - sentTo?: [PubKey]; - unidentifiedDeliveries?: [PubKey]; + sentTo?: Array; + unidentifiedDeliveries?: Array; destination?: PubKey; } export abstract class SentSyncMessage extends SyncMessage { public readonly dataMessage: SignalService.DataMessage; public readonly expirationStartTimestamp?: number; - public readonly sentTo?: [PubKey]; - public readonly unidentifiedDeliveries?: [PubKey]; + public readonly sentTo?: Array; + public readonly unidentifiedDeliveries?: Array; public readonly destination?: PubKey; constructor(params: SentSyncMessageParams) { diff --git a/ts/session/utils/SyncMessageUtils.ts b/ts/session/utils/SyncMessageUtils.ts index 847bbd4e3..1aa0a2c28 100644 --- a/ts/session/utils/SyncMessageUtils.ts +++ b/ts/session/utils/SyncMessageUtils.ts @@ -3,6 +3,7 @@ import { UserUtil } from '../../util/'; import { getAllConversations } from '../../../js/modules/data'; import { ContentMessage, SyncMessage } from '../messages/outgoing'; import { MultiDeviceProtocol } from '../protocols'; +import ByteBuffer from 'bytebuffer'; export function from(message: ContentMessage): SyncMessage | undefined { if (message instanceof SyncMessage) { @@ -85,3 +86,18 @@ export async function filterOpenGroupsConvos( 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; +}