Migrate textsecure to eslint
Co-authored-by: Chris Svenningsen <chris@carbonfive.com>
This commit is contained in:
parent
b5df9b4067
commit
7b6d8f55d6
24 changed files with 706 additions and 299 deletions
|
@ -1,19 +1,25 @@
|
|||
// tslint:disable no-bitwise no-default-export
|
||||
/* eslint-disable @typescript-eslint/ban-types */
|
||||
/* eslint-disable no-bitwise */
|
||||
/* eslint-disable class-methods-use-this */
|
||||
/* eslint-disable more/no-then */
|
||||
/* eslint-disable camelcase */
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
/* eslint-disable max-classes-per-file */
|
||||
|
||||
import { isNumber, map, omit } from 'lodash';
|
||||
import { w3cwebsocket as WebSocket } from 'websocket';
|
||||
import PQueue from 'p-queue';
|
||||
import { v4 as getGuid } from 'uuid';
|
||||
|
||||
import { SessionCipherClass, SignalProtocolAddressClass } from '../libsignal.d';
|
||||
import { BatcherType, createBatcher } from '../util/batcher';
|
||||
|
||||
import EventTarget from './EventTarget';
|
||||
import { WebAPIType } from './WebAPI';
|
||||
import { BatcherType, createBatcher } from '../util/batcher';
|
||||
import utils from './Helpers';
|
||||
import WebSocketResource, {
|
||||
IncomingWebSocketRequest,
|
||||
} from './WebsocketResources';
|
||||
import Crypto from './Crypto';
|
||||
import { SessionCipherClass, SignalProtocolAddressClass } from '../libsignal.d';
|
||||
import { ContactBuffer, GroupBuffer } from './ContactsParser';
|
||||
import { IncomingIdentityKeyError } from './Errors';
|
||||
|
||||
|
@ -30,6 +36,8 @@ import {
|
|||
VerifiedClass,
|
||||
} from '../textsecure.d';
|
||||
|
||||
import { WebSocket } from './WebSocket';
|
||||
|
||||
import { deriveGroupFields, MASTER_KEY_LENGTH } from '../groups';
|
||||
|
||||
const RETRY_TIMEOUT = 2 * 60 * 1000;
|
||||
|
@ -84,30 +92,51 @@ type CacheUpdateItemType = {
|
|||
|
||||
class MessageReceiverInner extends EventTarget {
|
||||
_onClose?: (ev: any) => Promise<void>;
|
||||
|
||||
appQueue: PQueue;
|
||||
|
||||
cacheAddBatcher: BatcherType<CacheAddItemType>;
|
||||
|
||||
cacheRemoveBatcher: BatcherType<string>;
|
||||
|
||||
cacheUpdateBatcher: BatcherType<CacheUpdateItemType>;
|
||||
|
||||
calledClose?: boolean;
|
||||
|
||||
count: number;
|
||||
|
||||
deviceId: number;
|
||||
|
||||
hasConnected?: boolean;
|
||||
|
||||
incomingQueue: PQueue;
|
||||
|
||||
isEmptied?: boolean;
|
||||
// tslint:disable-next-line variable-name
|
||||
|
||||
number_id: string | null;
|
||||
|
||||
password: string;
|
||||
|
||||
pendingQueue: PQueue;
|
||||
|
||||
retryCachedTimeout: any;
|
||||
|
||||
server: WebAPIType;
|
||||
|
||||
serverTrustRoot: ArrayBuffer;
|
||||
|
||||
signalingKey: ArrayBuffer;
|
||||
|
||||
socket?: WebSocket;
|
||||
|
||||
stoppingProcessing?: boolean;
|
||||
|
||||
username: string;
|
||||
|
||||
uuid: string;
|
||||
// tslint:disable-next-line variable-name
|
||||
|
||||
uuid_id: string | null;
|
||||
|
||||
wsr?: WebSocketResource;
|
||||
|
||||
constructor(
|
||||
|
@ -175,10 +204,13 @@ class MessageReceiverInner extends EventTarget {
|
|||
|
||||
static stringToArrayBuffer = (string: string): ArrayBuffer =>
|
||||
window.dcodeIO.ByteBuffer.wrap(string, 'binary').toArrayBuffer();
|
||||
|
||||
static arrayBufferToString = (arrayBuffer: ArrayBuffer): string =>
|
||||
window.dcodeIO.ByteBuffer.wrap(arrayBuffer).toString('binary');
|
||||
|
||||
static stringToArrayBufferBase64 = (string: string): ArrayBuffer =>
|
||||
window.dcodeIO.ByteBuffer.wrap(string, 'base64').toArrayBuffer();
|
||||
|
||||
static arrayBufferToStringBase64 = (arrayBuffer: ArrayBuffer): string =>
|
||||
window.dcodeIO.ByteBuffer.wrap(arrayBuffer).toString('base64');
|
||||
|
||||
|
@ -237,12 +269,9 @@ class MessageReceiverInner extends EventTarget {
|
|||
|
||||
shutdown() {
|
||||
if (this.socket) {
|
||||
// @ts-ignore
|
||||
this.socket.onclose = null;
|
||||
// @ts-ignore
|
||||
this.socket.onerror = null;
|
||||
// @ts-ignore
|
||||
this.socket.onopen = null;
|
||||
delete this.socket.onclose;
|
||||
delete this.socket.onerror;
|
||||
delete this.socket.onopen;
|
||||
this.socket = undefined;
|
||||
}
|
||||
|
||||
|
@ -253,6 +282,7 @@ class MessageReceiverInner extends EventTarget {
|
|||
this.wsr = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
async close() {
|
||||
window.log.info('MessageReceiver.close()');
|
||||
this.calledClose = true;
|
||||
|
@ -267,18 +297,22 @@ class MessageReceiverInner extends EventTarget {
|
|||
|
||||
return this.drain();
|
||||
}
|
||||
|
||||
onopen() {
|
||||
window.log.info('websocket open');
|
||||
}
|
||||
|
||||
onerror() {
|
||||
window.log.error('websocket error');
|
||||
}
|
||||
|
||||
async dispatchAndWait(event: Event) {
|
||||
// tslint:disable-next-line no-floating-promises
|
||||
this.appQueue.add(async () => Promise.all(this.dispatchEvent(event)));
|
||||
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
async onclose(ev: any) {
|
||||
window.log.info(
|
||||
'websocket closed',
|
||||
|
@ -309,6 +343,7 @@ class MessageReceiverInner extends EventTarget {
|
|||
return this.dispatchAndWait(event);
|
||||
});
|
||||
}
|
||||
|
||||
handleRequest(request: IncomingWebSocketRequest) {
|
||||
// We do the message decryption here, instead of in the ordered pending queue,
|
||||
// to avoid exposing the time it took us to process messages through the time-to-ack.
|
||||
|
@ -395,6 +430,7 @@ class MessageReceiverInner extends EventTarget {
|
|||
// tslint:disable-next-line no-floating-promises
|
||||
this.incomingQueue.add(job);
|
||||
}
|
||||
|
||||
calculateMessageAge(
|
||||
headers: Array<string>,
|
||||
serverTimestamp?: number
|
||||
|
@ -404,6 +440,7 @@ class MessageReceiverInner extends EventTarget {
|
|||
if (serverTimestamp) {
|
||||
// The 'X-Signal-Timestamp' is usually the last item, so start there.
|
||||
let it = headers.length;
|
||||
// eslint-disable-next-line no-plusplus
|
||||
while (--it >= 0) {
|
||||
const match = headers[it].match(/^X-Signal-Timestamp:\s*(\d+)\s*$/);
|
||||
if (match && match.length === 2) {
|
||||
|
@ -422,6 +459,7 @@ class MessageReceiverInner extends EventTarget {
|
|||
|
||||
return messageAgeSec;
|
||||
}
|
||||
|
||||
async addToQueue(task: () => Promise<void>) {
|
||||
this.count += 1;
|
||||
|
||||
|
@ -437,9 +475,11 @@ class MessageReceiverInner extends EventTarget {
|
|||
|
||||
return promise;
|
||||
}
|
||||
|
||||
hasEmptied(): boolean {
|
||||
return Boolean(this.isEmptied);
|
||||
}
|
||||
|
||||
onEmpty() {
|
||||
const emitEmpty = () => {
|
||||
window.log.info("MessageReceiver: emitting 'empty' event");
|
||||
|
@ -478,6 +518,7 @@ class MessageReceiverInner extends EventTarget {
|
|||
// tslint:disable-next-line no-floating-promises
|
||||
waitForCacheAddBatcher();
|
||||
}
|
||||
|
||||
async drain() {
|
||||
const waitForIncomingQueue = async () =>
|
||||
this.addToQueue(async () => {
|
||||
|
@ -486,6 +527,7 @@ class MessageReceiverInner extends EventTarget {
|
|||
|
||||
return this.incomingQueue.add(waitForIncomingQueue);
|
||||
}
|
||||
|
||||
updateProgress(count: number) {
|
||||
// count by 10s
|
||||
if (count % 10 !== 0) {
|
||||
|
@ -495,6 +537,7 @@ class MessageReceiverInner extends EventTarget {
|
|||
ev.count = count;
|
||||
this.dispatchEvent(ev);
|
||||
}
|
||||
|
||||
async queueAllCached() {
|
||||
const items = await this.getAllFromCache();
|
||||
const max = items.length;
|
||||
|
@ -503,6 +546,7 @@ class MessageReceiverInner extends EventTarget {
|
|||
await this.queueCached(items[i]);
|
||||
}
|
||||
}
|
||||
|
||||
async queueCached(item: UnprocessedType) {
|
||||
try {
|
||||
let envelopePlaintext: ArrayBuffer;
|
||||
|
@ -573,6 +617,7 @@ class MessageReceiverInner extends EventTarget {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
getEnvelopeId(envelope: EnvelopeClass) {
|
||||
if (envelope.sourceUuid || envelope.source) {
|
||||
return `${envelope.sourceUuid || envelope.source}.${
|
||||
|
@ -582,12 +627,14 @@ class MessageReceiverInner extends EventTarget {
|
|||
|
||||
return envelope.id;
|
||||
}
|
||||
|
||||
clearRetryTimeout() {
|
||||
if (this.retryCachedTimeout) {
|
||||
clearInterval(this.retryCachedTimeout);
|
||||
this.retryCachedTimeout = null;
|
||||
}
|
||||
}
|
||||
|
||||
maybeScheduleRetryTimeout() {
|
||||
if (this.isEmptied) {
|
||||
this.clearRetryTimeout();
|
||||
|
@ -597,6 +644,7 @@ class MessageReceiverInner extends EventTarget {
|
|||
}, RETRY_TIMEOUT);
|
||||
}
|
||||
}
|
||||
|
||||
async getAllFromCache() {
|
||||
window.log.info('getAllFromCache');
|
||||
const count = await window.textsecure.storage.unprocessed.getCount();
|
||||
|
@ -640,6 +688,7 @@ class MessageReceiverInner extends EventTarget {
|
|||
})
|
||||
);
|
||||
}
|
||||
|
||||
async cacheAndQueueBatch(items: Array<CacheAddItemType>) {
|
||||
const dataArray = items.map(item => item.data);
|
||||
try {
|
||||
|
@ -661,6 +710,7 @@ class MessageReceiverInner extends EventTarget {
|
|||
);
|
||||
}
|
||||
}
|
||||
|
||||
cacheAndQueue(
|
||||
envelope: EnvelopeClass,
|
||||
plaintext: ArrayBuffer,
|
||||
|
@ -680,9 +730,11 @@ class MessageReceiverInner extends EventTarget {
|
|||
data,
|
||||
});
|
||||
}
|
||||
|
||||
async cacheUpdateBatch(items: Array<Partial<UnprocessedType>>) {
|
||||
await window.textsecure.storage.unprocessed.addDecryptedDataToList(items);
|
||||
}
|
||||
|
||||
updateCache(envelope: EnvelopeClass, plaintext: ArrayBuffer) {
|
||||
const { id } = envelope;
|
||||
const data = {
|
||||
|
@ -694,13 +746,16 @@ class MessageReceiverInner extends EventTarget {
|
|||
};
|
||||
this.cacheUpdateBatcher.add({ id, data });
|
||||
}
|
||||
|
||||
async cacheRemoveBatch(items: Array<string>) {
|
||||
await window.textsecure.storage.unprocessed.remove(items);
|
||||
}
|
||||
|
||||
removeFromCache(envelope: EnvelopeClass) {
|
||||
const { id } = envelope;
|
||||
this.cacheRemoveBatcher.add(id);
|
||||
}
|
||||
|
||||
async queueDecryptedEnvelope(
|
||||
envelope: EnvelopeClass,
|
||||
plaintext: ArrayBuffer
|
||||
|
@ -722,6 +777,7 @@ class MessageReceiverInner extends EventTarget {
|
|||
);
|
||||
});
|
||||
}
|
||||
|
||||
async queueEnvelope(envelope: EnvelopeClass) {
|
||||
const id = this.getEnvelopeId(envelope);
|
||||
window.log.info('queueing envelope', id);
|
||||
|
@ -747,6 +803,7 @@ class MessageReceiverInner extends EventTarget {
|
|||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Same as handleEnvelope, just without the decryption step. Necessary for handling
|
||||
// messages which were successfully decrypted, but application logic didn't finish
|
||||
// processing.
|
||||
|
@ -764,7 +821,8 @@ class MessageReceiverInner extends EventTarget {
|
|||
await this.innerHandleContentMessage(envelope, plaintext);
|
||||
|
||||
return;
|
||||
} else if (envelope.legacyMessage) {
|
||||
}
|
||||
if (envelope.legacyMessage) {
|
||||
await this.innerHandleLegacyMessage(envelope, plaintext);
|
||||
|
||||
return;
|
||||
|
@ -773,6 +831,7 @@ class MessageReceiverInner extends EventTarget {
|
|||
this.removeFromCache(envelope);
|
||||
throw new Error('Received message with no content and no legacyMessage');
|
||||
}
|
||||
|
||||
async handleEnvelope(envelope: EnvelopeClass) {
|
||||
if (this.stoppingProcessing) {
|
||||
return Promise.resolve();
|
||||
|
@ -784,20 +843,24 @@ class MessageReceiverInner extends EventTarget {
|
|||
|
||||
if (envelope.content) {
|
||||
return this.handleContentMessage(envelope);
|
||||
} else if (envelope.legacyMessage) {
|
||||
}
|
||||
if (envelope.legacyMessage) {
|
||||
return this.handleLegacyMessage(envelope);
|
||||
}
|
||||
this.removeFromCache(envelope);
|
||||
throw new Error('Received message with no content and no legacyMessage');
|
||||
}
|
||||
|
||||
getStatus() {
|
||||
if (this.socket) {
|
||||
return this.socket.readyState;
|
||||
} else if (this.hasConnected) {
|
||||
}
|
||||
if (this.hasConnected) {
|
||||
return WebSocket.CLOSED;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
async onDeliveryReceipt(envelope: EnvelopeClass) {
|
||||
// tslint:disable-next-line promise-must-complete
|
||||
return new Promise((resolve, reject) => {
|
||||
|
@ -812,6 +875,7 @@ class MessageReceiverInner extends EventTarget {
|
|||
this.dispatchAndWait(ev).then(resolve as any, reject as any);
|
||||
});
|
||||
}
|
||||
|
||||
unpad(paddedData: ArrayBuffer) {
|
||||
const paddedPlaintext = new Uint8Array(paddedData);
|
||||
let plaintext;
|
||||
|
@ -837,11 +901,10 @@ class MessageReceiverInner extends EventTarget {
|
|||
): Promise<ArrayBuffer> {
|
||||
const { serverTrustRoot } = this;
|
||||
|
||||
let address: SignalProtocolAddressClass;
|
||||
let promise;
|
||||
const identifier = envelope.sourceUuid || envelope.source;
|
||||
|
||||
address = new window.libsignal.SignalProtocolAddress(
|
||||
const address = new window.libsignal.SignalProtocolAddress(
|
||||
// Using source as opposed to sourceUuid allows us to get the existing
|
||||
// session if we haven't yet harvested the incoming uuid
|
||||
identifier as any,
|
||||
|
@ -1034,6 +1097,7 @@ class MessageReceiverInner extends EventTarget {
|
|||
return this.dispatchAndWait(ev).then(returnError, returnError);
|
||||
});
|
||||
}
|
||||
|
||||
async decryptPreKeyWhisperMessage(
|
||||
ciphertext: ArrayBuffer,
|
||||
sessionCipher: SessionCipherClass,
|
||||
|
@ -1057,6 +1121,7 @@ class MessageReceiverInner extends EventTarget {
|
|||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
async handleSentMessage(
|
||||
envelope: EnvelopeClass,
|
||||
sentContainer: SyncMessageClass.Sent
|
||||
|
@ -1114,7 +1179,7 @@ class MessageReceiverInner extends EventTarget {
|
|||
)} ignored; destined for blocked group`
|
||||
);
|
||||
this.removeFromCache(envelope);
|
||||
return;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const ev = new Event('sent');
|
||||
|
@ -1136,6 +1201,7 @@ class MessageReceiverInner extends EventTarget {
|
|||
})
|
||||
);
|
||||
}
|
||||
|
||||
async handleDataMessage(envelope: EnvelopeClass, msg: DataMessageClass) {
|
||||
window.log.info('data message from', this.getEnvelopeId(envelope));
|
||||
let p: Promise<any> = Promise.resolve();
|
||||
|
@ -1152,7 +1218,7 @@ class MessageReceiverInner extends EventTarget {
|
|||
window.log.info(
|
||||
'MessageReceiver.handleDataMessage: dropping GroupV2 message'
|
||||
);
|
||||
return;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
this.deriveGroupsV2Data(msg);
|
||||
|
@ -1204,7 +1270,7 @@ class MessageReceiverInner extends EventTarget {
|
|||
)} ignored; destined for blocked group`
|
||||
);
|
||||
this.removeFromCache(envelope);
|
||||
return;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const ev = new Event('message');
|
||||
|
@ -1222,6 +1288,7 @@ class MessageReceiverInner extends EventTarget {
|
|||
})
|
||||
);
|
||||
}
|
||||
|
||||
async handleLegacyMessage(envelope: EnvelopeClass) {
|
||||
return this.decrypt(envelope, envelope.legacyMessage).then(plaintext => {
|
||||
if (!plaintext) {
|
||||
|
@ -1231,6 +1298,7 @@ class MessageReceiverInner extends EventTarget {
|
|||
return this.innerHandleLegacyMessage(envelope, plaintext);
|
||||
});
|
||||
}
|
||||
|
||||
async innerHandleLegacyMessage(
|
||||
envelope: EnvelopeClass,
|
||||
plaintext: ArrayBuffer
|
||||
|
@ -1238,6 +1306,7 @@ class MessageReceiverInner extends EventTarget {
|
|||
const message = window.textsecure.protobuf.DataMessage.decode(plaintext);
|
||||
return this.handleDataMessage(envelope, message);
|
||||
}
|
||||
|
||||
async handleContentMessage(envelope: EnvelopeClass) {
|
||||
return this.decrypt(envelope, envelope.content).then(plaintext => {
|
||||
if (!plaintext) {
|
||||
|
@ -1247,6 +1316,7 @@ class MessageReceiverInner extends EventTarget {
|
|||
return this.innerHandleContentMessage(envelope, plaintext);
|
||||
});
|
||||
}
|
||||
|
||||
async innerHandleContentMessage(
|
||||
envelope: EnvelopeClass,
|
||||
plaintext: ArrayBuffer
|
||||
|
@ -1254,21 +1324,27 @@ class MessageReceiverInner extends EventTarget {
|
|||
const content = window.textsecure.protobuf.Content.decode(plaintext);
|
||||
if (content.syncMessage) {
|
||||
return this.handleSyncMessage(envelope, content.syncMessage);
|
||||
} else if (content.dataMessage) {
|
||||
}
|
||||
if (content.dataMessage) {
|
||||
return this.handleDataMessage(envelope, content.dataMessage);
|
||||
} else if (content.nullMessage) {
|
||||
}
|
||||
if (content.nullMessage) {
|
||||
this.handleNullMessage(envelope);
|
||||
return;
|
||||
} else if (content.callingMessage) {
|
||||
return undefined;
|
||||
}
|
||||
if (content.callingMessage) {
|
||||
return this.handleCallingMessage(envelope, content.callingMessage);
|
||||
} else if (content.receiptMessage) {
|
||||
}
|
||||
if (content.receiptMessage) {
|
||||
return this.handleReceiptMessage(envelope, content.receiptMessage);
|
||||
} else if (content.typingMessage) {
|
||||
}
|
||||
if (content.typingMessage) {
|
||||
return this.handleTypingMessage(envelope, content.typingMessage);
|
||||
}
|
||||
this.removeFromCache(envelope);
|
||||
throw new Error('Unsupported content message');
|
||||
}
|
||||
|
||||
async handleCallingMessage(
|
||||
envelope: EnvelopeClass,
|
||||
callingMessage: CallingMessageClass
|
||||
|
@ -1279,6 +1355,7 @@ class MessageReceiverInner extends EventTarget {
|
|||
callingMessage
|
||||
);
|
||||
}
|
||||
|
||||
async handleReceiptMessage(
|
||||
envelope: EnvelopeClass,
|
||||
receiptMessage: ReceiptMessageClass
|
||||
|
@ -1319,6 +1396,7 @@ class MessageReceiverInner extends EventTarget {
|
|||
}
|
||||
return Promise.all(results);
|
||||
}
|
||||
|
||||
handleTypingMessage(
|
||||
envelope: EnvelopeClass,
|
||||
typingMessage: TypingMessageClass
|
||||
|
@ -1366,6 +1444,7 @@ class MessageReceiverInner extends EventTarget {
|
|||
|
||||
return this.dispatchEvent(ev);
|
||||
}
|
||||
|
||||
handleNullMessage(envelope: EnvelopeClass) {
|
||||
window.log.info('null message from', this.getEnvelopeId(envelope));
|
||||
this.removeFromCache(envelope);
|
||||
|
@ -1404,6 +1483,7 @@ class MessageReceiverInner extends EventTarget {
|
|||
groupV2.groupChange = groupV2.groupChange.toString('base64');
|
||||
}
|
||||
}
|
||||
|
||||
getGroupId(message: DataMessageClass) {
|
||||
if (message.groupV2) {
|
||||
return message.groupV2.id;
|
||||
|
@ -1418,11 +1498,11 @@ class MessageReceiverInner extends EventTarget {
|
|||
getDestination(sentMessage: SyncMessageClass.Sent) {
|
||||
if (sentMessage.message && sentMessage.message.groupV2) {
|
||||
return `groupv2(${sentMessage.message.groupV2.id})`;
|
||||
} else if (sentMessage.message && sentMessage.message.group) {
|
||||
return `group(${sentMessage.message.group.id.toBinary()})`;
|
||||
} else {
|
||||
return sentMessage.destination || sentMessage.destinationUuid;
|
||||
}
|
||||
if (sentMessage.message && sentMessage.message.group) {
|
||||
return `group(${sentMessage.message.group.id.toBinary()})`;
|
||||
}
|
||||
return sentMessage.destination || sentMessage.destinationUuid;
|
||||
}
|
||||
|
||||
// tslint:disable-next-line cyclomatic-complexity
|
||||
|
@ -1450,7 +1530,7 @@ class MessageReceiverInner extends EventTarget {
|
|||
if (!fromSelfSource && !fromSelfSourceUuid) {
|
||||
throw new Error('Received sync message from another number');
|
||||
}
|
||||
// tslint:disable-next-line triple-equals
|
||||
// eslint-disable-next-line eqeqeq
|
||||
if (envelope.sourceDevice == this.deviceId) {
|
||||
throw new Error('Received sync message from our own device');
|
||||
}
|
||||
|
@ -1468,7 +1548,7 @@ class MessageReceiverInner extends EventTarget {
|
|||
window.log.info(
|
||||
'MessageReceiver.handleSyncMessage: dropping GroupV2 message'
|
||||
);
|
||||
return;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
this.deriveGroupsV2Data(sentMessage.message);
|
||||
|
@ -1481,26 +1561,34 @@ class MessageReceiverInner extends EventTarget {
|
|||
this.getEnvelopeId(envelope)
|
||||
);
|
||||
return this.handleSentMessage(envelope, sentMessage);
|
||||
} else if (syncMessage.contacts) {
|
||||
}
|
||||
if (syncMessage.contacts) {
|
||||
this.handleContacts(envelope, syncMessage.contacts);
|
||||
return;
|
||||
} else if (syncMessage.groups) {
|
||||
return undefined;
|
||||
}
|
||||
if (syncMessage.groups) {
|
||||
this.handleGroups(envelope, syncMessage.groups);
|
||||
return;
|
||||
} else if (syncMessage.blocked) {
|
||||
return undefined;
|
||||
}
|
||||
if (syncMessage.blocked) {
|
||||
return this.handleBlocked(envelope, syncMessage.blocked);
|
||||
} else if (syncMessage.request) {
|
||||
}
|
||||
if (syncMessage.request) {
|
||||
window.log.info('Got SyncMessage Request');
|
||||
this.removeFromCache(envelope);
|
||||
return;
|
||||
} else if (syncMessage.read && syncMessage.read.length) {
|
||||
return undefined;
|
||||
}
|
||||
if (syncMessage.read && syncMessage.read.length) {
|
||||
window.log.info('read messages from', this.getEnvelopeId(envelope));
|
||||
return this.handleRead(envelope, syncMessage.read);
|
||||
} else if (syncMessage.verified) {
|
||||
}
|
||||
if (syncMessage.verified) {
|
||||
return this.handleVerified(envelope, syncMessage.verified);
|
||||
} else if (syncMessage.configuration) {
|
||||
}
|
||||
if (syncMessage.configuration) {
|
||||
return this.handleConfiguration(envelope, syncMessage.configuration);
|
||||
} else if (
|
||||
}
|
||||
if (
|
||||
syncMessage.stickerPackOperation &&
|
||||
syncMessage.stickerPackOperation.length > 0
|
||||
) {
|
||||
|
@ -1508,22 +1596,27 @@ class MessageReceiverInner extends EventTarget {
|
|||
envelope,
|
||||
syncMessage.stickerPackOperation
|
||||
);
|
||||
} else if (syncMessage.viewOnceOpen) {
|
||||
}
|
||||
if (syncMessage.viewOnceOpen) {
|
||||
return this.handleViewOnceOpen(envelope, syncMessage.viewOnceOpen);
|
||||
} else if (syncMessage.messageRequestResponse) {
|
||||
}
|
||||
if (syncMessage.messageRequestResponse) {
|
||||
return this.handleMessageRequestResponse(
|
||||
envelope,
|
||||
syncMessage.messageRequestResponse
|
||||
);
|
||||
} else if (syncMessage.fetchLatest) {
|
||||
}
|
||||
if (syncMessage.fetchLatest) {
|
||||
return this.handleFetchLatest(envelope, syncMessage.fetchLatest);
|
||||
} else if (syncMessage.keys) {
|
||||
}
|
||||
if (syncMessage.keys) {
|
||||
return this.handleKeys(envelope, syncMessage.keys);
|
||||
}
|
||||
|
||||
this.removeFromCache(envelope);
|
||||
throw new Error('Got empty SyncMessage');
|
||||
}
|
||||
|
||||
async handleConfiguration(
|
||||
envelope: EnvelopeClass,
|
||||
configuration: SyncMessageClass.Configuration
|
||||
|
@ -1534,6 +1627,7 @@ class MessageReceiverInner extends EventTarget {
|
|||
ev.configuration = configuration;
|
||||
return this.dispatchAndWait(ev);
|
||||
}
|
||||
|
||||
async handleViewOnceOpen(
|
||||
envelope: EnvelopeClass,
|
||||
sync: SyncMessageClass.ViewOnceOpen
|
||||
|
@ -1554,6 +1648,7 @@ class MessageReceiverInner extends EventTarget {
|
|||
|
||||
return this.dispatchAndWait(ev);
|
||||
}
|
||||
|
||||
async handleMessageRequestResponse(
|
||||
envelope: EnvelopeClass,
|
||||
sync: SyncMessageClass.MessageRequestResponse
|
||||
|
@ -1573,6 +1668,7 @@ class MessageReceiverInner extends EventTarget {
|
|||
'MessageReceiver::handleMessageRequestResponse'
|
||||
);
|
||||
}
|
||||
|
||||
async handleFetchLatest(
|
||||
envelope: EnvelopeClass,
|
||||
sync: SyncMessageClass.FetchLatest
|
||||
|
@ -1585,11 +1681,12 @@ class MessageReceiverInner extends EventTarget {
|
|||
|
||||
return this.dispatchAndWait(ev);
|
||||
}
|
||||
|
||||
async handleKeys(envelope: EnvelopeClass, sync: SyncMessageClass.Keys) {
|
||||
window.log.info('got keys sync message');
|
||||
|
||||
if (!sync.storageService) {
|
||||
return;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const ev = new Event('keys');
|
||||
|
@ -1598,6 +1695,7 @@ class MessageReceiverInner extends EventTarget {
|
|||
|
||||
return this.dispatchAndWait(ev);
|
||||
}
|
||||
|
||||
async handleStickerPackOperation(
|
||||
envelope: EnvelopeClass,
|
||||
operations: Array<SyncMessageClass.StickerPackOperation>
|
||||
|
@ -1615,6 +1713,7 @@ class MessageReceiverInner extends EventTarget {
|
|||
}));
|
||||
return this.dispatchAndWait(ev);
|
||||
}
|
||||
|
||||
async handleVerified(envelope: EnvelopeClass, verified: VerifiedClass) {
|
||||
const ev = new Event('verified');
|
||||
ev.confirm = this.removeFromCache.bind(this, envelope);
|
||||
|
@ -1631,6 +1730,7 @@ class MessageReceiverInner extends EventTarget {
|
|||
);
|
||||
return this.dispatchAndWait(ev);
|
||||
}
|
||||
|
||||
async handleRead(
|
||||
envelope: EnvelopeClass,
|
||||
read: Array<SyncMessageClass.Read>
|
||||
|
@ -1655,6 +1755,7 @@ class MessageReceiverInner extends EventTarget {
|
|||
}
|
||||
return Promise.all(results);
|
||||
}
|
||||
|
||||
handleContacts(envelope: EnvelopeClass, contacts: SyncMessageClass.Contacts) {
|
||||
window.log.info('contact sync');
|
||||
const { blob } = contacts;
|
||||
|
@ -1692,6 +1793,7 @@ class MessageReceiverInner extends EventTarget {
|
|||
});
|
||||
});
|
||||
}
|
||||
|
||||
handleGroups(envelope: EnvelopeClass, groups: SyncMessageClass.Groups) {
|
||||
window.log.info('group sync');
|
||||
const { blob } = groups;
|
||||
|
@ -1726,6 +1828,7 @@ class MessageReceiverInner extends EventTarget {
|
|||
});
|
||||
});
|
||||
}
|
||||
|
||||
async handleBlocked(
|
||||
envelope: EnvelopeClass,
|
||||
blocked: SyncMessageClass.Blocked
|
||||
|
@ -1750,19 +1853,22 @@ class MessageReceiverInner extends EventTarget {
|
|||
await window.textsecure.storage.put('blocked-groups', groupIds);
|
||||
|
||||
this.removeFromCache(envelope);
|
||||
return;
|
||||
}
|
||||
|
||||
isBlocked(number: string) {
|
||||
return window.textsecure.storage.get('blocked', []).includes(number);
|
||||
}
|
||||
|
||||
isUuidBlocked(uuid: string) {
|
||||
return window.textsecure.storage.get('blocked-uuids', []).includes(uuid);
|
||||
}
|
||||
|
||||
isGroupBlocked(groupId: string) {
|
||||
return window.textsecure.storage
|
||||
.get('blocked-groups', [])
|
||||
.includes(groupId);
|
||||
}
|
||||
|
||||
cleanAttachment(attachment: AttachmentPointerClass) {
|
||||
return {
|
||||
...omit(attachment, 'thumbnail'),
|
||||
|
@ -1771,6 +1877,7 @@ class MessageReceiverInner extends EventTarget {
|
|||
digest: attachment.digest ? attachment.digest.toString('base64') : null,
|
||||
};
|
||||
}
|
||||
|
||||
private isLinkPreviewDateValid(value: unknown): value is number {
|
||||
return (
|
||||
typeof value === 'number' &&
|
||||
|
@ -1779,6 +1886,7 @@ class MessageReceiverInner extends EventTarget {
|
|||
value > 0
|
||||
);
|
||||
}
|
||||
|
||||
private cleanLinkPreviewDate(value: unknown): number | null {
|
||||
if (this.isLinkPreviewDateValid(value)) {
|
||||
return value;
|
||||
|
@ -1794,6 +1902,7 @@ class MessageReceiverInner extends EventTarget {
|
|||
}
|
||||
return this.isLinkPreviewDateValid(result) ? result : null;
|
||||
}
|
||||
|
||||
async downloadAttachment(
|
||||
attachment: AttachmentPointerClass
|
||||
): Promise<DownloadAttachmentType> {
|
||||
|
@ -1826,12 +1935,14 @@ class MessageReceiverInner extends EventTarget {
|
|||
data,
|
||||
};
|
||||
}
|
||||
|
||||
async handleAttachment(
|
||||
attachment: AttachmentPointerClass
|
||||
): Promise<DownloadAttachmentType> {
|
||||
const cleaned = this.cleanAttachment(attachment);
|
||||
return this.downloadAttachment(cleaned);
|
||||
}
|
||||
|
||||
async handleEndSession(identifier: string) {
|
||||
window.log.info('got end session');
|
||||
const deviceIds = await window.textsecure.storage.protocol.getDeviceIds(
|
||||
|
@ -1890,7 +2001,8 @@ class MessageReceiverInner extends EventTarget {
|
|||
decrypted.attachments = [];
|
||||
decrypted.group = null;
|
||||
return Promise.resolve(decrypted);
|
||||
} else if (decrypted.flags & FLAGS.EXPIRATION_TIMER_UPDATE) {
|
||||
}
|
||||
if (decrypted.flags & FLAGS.EXPIRATION_TIMER_UPDATE) {
|
||||
decrypted.body = null;
|
||||
decrypted.attachments = [];
|
||||
} else if (decrypted.flags & FLAGS.PROFILE_KEY_UPDATE) {
|
||||
|
@ -2053,20 +2165,30 @@ export default class MessageReceiver {
|
|||
}
|
||||
|
||||
addEventListener: (name: string, handler: Function) => void;
|
||||
|
||||
close: () => Promise<void>;
|
||||
|
||||
downloadAttachment: (
|
||||
attachment: AttachmentPointerClass
|
||||
) => Promise<DownloadAttachmentType>;
|
||||
|
||||
getStatus: () => number;
|
||||
|
||||
hasEmptied: () => boolean;
|
||||
|
||||
removeEventListener: (name: string, handler: Function) => void;
|
||||
|
||||
stopProcessing: () => Promise<void>;
|
||||
|
||||
unregisterBatchers: () => void;
|
||||
|
||||
static stringToArrayBuffer = MessageReceiverInner.stringToArrayBuffer;
|
||||
|
||||
static arrayBufferToString = MessageReceiverInner.arrayBufferToString;
|
||||
|
||||
static stringToArrayBufferBase64 =
|
||||
MessageReceiverInner.stringToArrayBufferBase64;
|
||||
|
||||
static arrayBufferToStringBase64 =
|
||||
MessageReceiverInner.arrayBufferToStringBase64;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue