move more logic to build sync message in ts for ContactSync and GroupSync

pull/1194/head
Audric Ackermann 5 years ago
parent fea75de3fe
commit cd79b5051c
No known key found for this signature in database
GPG Key ID: 999F434D76324AD4

@ -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;
})();

@ -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 <Element0.length><Element0><Element1.length><Element1>...
// 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,
});
}

@ -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 };

@ -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<string>;
blocked: boolean;
expireTimer?: number;
admins: Array<string>;
}
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<string>;
public readonly blocked: boolean;
public readonly expireTimer: number | undefined;
public readonly admins: Array<string>;
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;
}

@ -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;
}

@ -6,16 +6,16 @@ import { PubKey } from '../../../../types';
interface SentSyncMessageParams extends MessageParams {
dataMessage: SignalService.DataMessage;
expirationStartTimestamp?: number;
sentTo?: [PubKey];
unidentifiedDeliveries?: [PubKey];
sentTo?: Array<PubKey>;
unidentifiedDeliveries?: Array<PubKey>;
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<PubKey>;
public readonly unidentifiedDeliveries?: Array<PubKey>;
public readonly destination?: PubKey;
constructor(params: SentSyncMessageParams) {

@ -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 <Element0.length><Element0><Element1.length><Element1>...
// This is an implementation of the reciprocal of contacts_parser.js
export function serialiseByteBuffers(buffers: Array<Uint8Array>): 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;
}

Loading…
Cancel
Save