Use --force-long with pbjs
This commit is contained in:
parent
bb066d4a84
commit
2eaacac151
|
@ -23,7 +23,7 @@
|
|||
"get-expire-time": "node ts/scripts/get-expire-time.js",
|
||||
"copy-and-concat": "node ts/scripts/copy-and-concat.js",
|
||||
"sass": "sass stylesheets/manifest.scss:stylesheets/manifest.css stylesheets/manifest_bridge.scss:stylesheets/manifest_bridge.css",
|
||||
"build-module-protobuf": "pbjs --target static-module --no-verify --no-create --wrap commonjs --out ts/protobuf/compiled.js protos/*.proto && pbts --out ts/protobuf/compiled.d.ts ts/protobuf/compiled.js",
|
||||
"build-module-protobuf": "pbjs --target static-module --force-long --no-verify --no-create --wrap commonjs --out ts/protobuf/compiled.js protos/*.proto && pbts --out ts/protobuf/compiled.d.ts ts/protobuf/compiled.js",
|
||||
"clean-module-protobuf": "rm -f ts/protobuf/compiled.d.ts ts/protobuf/compiled.js",
|
||||
"build-protobuf": "yarn build-module-protobuf",
|
||||
"clean-protobuf": "yarn clean-module-protobuf",
|
||||
|
|
|
@ -142,7 +142,7 @@ export function decryptDeviceName(
|
|||
|
||||
export function deriveStorageManifestKey(
|
||||
storageServiceKey: Uint8Array,
|
||||
version: number
|
||||
version: Long = Long.fromNumber(0)
|
||||
): Uint8Array {
|
||||
return hmacSha256(storageServiceKey, Bytes.fromString(`Manifest_${version}`));
|
||||
}
|
||||
|
|
13
ts/groups.ts
13
ts/groups.ts
|
@ -10,6 +10,7 @@ import {
|
|||
last,
|
||||
values,
|
||||
} from 'lodash';
|
||||
import Long from 'long';
|
||||
import type { ClientZkGroupCipher } from '@signalapp/signal-client/zkgroup';
|
||||
import { v4 as getGuid } from 'uuid';
|
||||
import LRU from 'lru-cache';
|
||||
|
@ -614,7 +615,7 @@ function buildGroupProto(
|
|||
member.role = item.role || MEMBER_ROLE_ENUM.DEFAULT;
|
||||
|
||||
pendingMember.member = member;
|
||||
pendingMember.timestamp = item.timestamp;
|
||||
pendingMember.timestamp = Long.fromNumber(item.timestamp);
|
||||
pendingMember.addedByUserId = ourUuidCipherTextBuffer;
|
||||
|
||||
return pendingMember;
|
||||
|
@ -717,7 +718,7 @@ export async function buildAddMembersChange(
|
|||
const memberPendingProfileKey = new Proto.MemberPendingProfileKey();
|
||||
memberPendingProfileKey.member = member;
|
||||
memberPendingProfileKey.addedByUserId = ourUuidCipherTextBuffer;
|
||||
memberPendingProfileKey.timestamp = now;
|
||||
memberPendingProfileKey.timestamp = Long.fromNumber(now);
|
||||
|
||||
const addPendingMemberAction =
|
||||
new Proto.GroupChange.Actions.AddMemberPendingProfileKeyAction();
|
||||
|
@ -5112,17 +5113,11 @@ function isValidProfileKey(buffer?: Uint8Array): boolean {
|
|||
return Boolean(buffer && buffer.length === 32);
|
||||
}
|
||||
|
||||
function normalizeTimestamp(
|
||||
timestamp: number | Long | null | undefined
|
||||
): number {
|
||||
function normalizeTimestamp(timestamp: Long | null | undefined): number {
|
||||
if (!timestamp) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (typeof timestamp === 'number') {
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
const asNumber = timestamp.toNumber();
|
||||
|
||||
const now = Date.now();
|
||||
|
|
|
@ -9,7 +9,6 @@ import {
|
|||
import * as Bytes from '../Bytes';
|
||||
import { assert } from '../util/assert';
|
||||
import { missingCaseError } from '../util/missingCaseError';
|
||||
import { normalizeNumber } from '../util/normalizeNumber';
|
||||
import { waitForOnline } from '../util/waitForOnline';
|
||||
import * as log from '../logging/log';
|
||||
import type { StorageInterface } from '../types/Storage.d';
|
||||
|
@ -181,7 +180,7 @@ export class SenderCertificateService {
|
|||
const decodedCert = decodedContainer.certificate
|
||||
? SenderCertificate.Certificate.decode(decodedContainer.certificate)
|
||||
: undefined;
|
||||
const expires = normalizeNumber(decodedCert?.expires);
|
||||
const expires = decodedCert?.expires?.toNumber();
|
||||
|
||||
if (!isExpirationValid(expires)) {
|
||||
log.warn(
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
import { debounce, isNumber } from 'lodash';
|
||||
import pMap from 'p-map';
|
||||
import Long from 'long';
|
||||
|
||||
import dataInterface from '../sql/Client';
|
||||
import * as Bytes from '../Bytes';
|
||||
|
@ -27,12 +28,12 @@ import {
|
|||
import type { MergeResultType } from './storageRecordOps';
|
||||
import type { ConversationModel } from '../models/conversations';
|
||||
import { strictAssert } from '../util/assert';
|
||||
import { dropNull } from '../util/dropNull';
|
||||
import * as durations from '../util/durations';
|
||||
import { BackOff } from '../util/BackOff';
|
||||
import { storageJobQueue } from '../util/JobQueue';
|
||||
import { sleep } from '../util/sleep';
|
||||
import { isMoreRecentThan } from '../util/timestamp';
|
||||
import { normalizeNumber } from '../util/normalizeNumber';
|
||||
import { ourProfileKeyService } from './ourProfileKey';
|
||||
import {
|
||||
ConversationTypes,
|
||||
|
@ -495,7 +496,7 @@ async function generateManifest(
|
|||
}
|
||||
|
||||
const manifestRecord = new Proto.ManifestRecord();
|
||||
manifestRecord.version = version;
|
||||
manifestRecord.version = Long.fromNumber(version);
|
||||
manifestRecord.keys = Array.from(manifestRecordKeys);
|
||||
|
||||
const storageKeyBase64 = window.storage.get('storageKey');
|
||||
|
@ -503,14 +504,17 @@ async function generateManifest(
|
|||
throw new Error('No storage key');
|
||||
}
|
||||
const storageKey = Bytes.fromBase64(storageKeyBase64);
|
||||
const storageManifestKey = deriveStorageManifestKey(storageKey, version);
|
||||
const storageManifestKey = deriveStorageManifestKey(
|
||||
storageKey,
|
||||
Long.fromNumber(version)
|
||||
);
|
||||
const encryptedManifest = encryptProfile(
|
||||
Proto.ManifestRecord.encode(manifestRecord).finish(),
|
||||
storageManifestKey
|
||||
);
|
||||
|
||||
const storageManifest = new Proto.StorageManifest();
|
||||
storageManifest.version = version;
|
||||
storageManifest.version = manifestRecord.version;
|
||||
storageManifest.value = encryptedManifest;
|
||||
|
||||
return {
|
||||
|
@ -676,7 +680,7 @@ async function decryptManifest(
|
|||
const storageKey = Bytes.fromBase64(storageKeyBase64);
|
||||
const storageManifestKey = deriveStorageManifestKey(
|
||||
storageKey,
|
||||
normalizeNumber(version ?? 0)
|
||||
dropNull(version)
|
||||
);
|
||||
|
||||
strictAssert(value, 'StorageManifest has no value field');
|
||||
|
@ -1317,7 +1321,7 @@ async function sync(
|
|||
manifest.version !== undefined && manifest.version !== null,
|
||||
'Manifest without version'
|
||||
);
|
||||
const version = normalizeNumber(manifest.version);
|
||||
const version = manifest.version?.toNumber() ?? 0;
|
||||
|
||||
log.info(
|
||||
`storageService.sync: updating to remoteVersion=${version} from ` +
|
||||
|
|
|
@ -16,7 +16,7 @@ const FLAGS = Proto.DataMessage.Flags;
|
|||
const TIMESTAMP = Date.now();
|
||||
|
||||
const UNPROCESSED_ATTACHMENT: Proto.IAttachmentPointer = {
|
||||
cdnId: 123,
|
||||
cdnId: Long.fromNumber(123),
|
||||
key: new Uint8Array([1, 2, 3]),
|
||||
digest: new Uint8Array([4, 5, 6]),
|
||||
};
|
||||
|
@ -35,7 +35,7 @@ describe('processDataMessage', () => {
|
|||
const check = (message: Proto.IDataMessage) =>
|
||||
processDataMessage(
|
||||
{
|
||||
timestamp: TIMESTAMP,
|
||||
timestamp: Long.fromNumber(TIMESTAMP),
|
||||
...message,
|
||||
},
|
||||
TIMESTAMP
|
||||
|
@ -175,7 +175,7 @@ describe('processDataMessage', () => {
|
|||
it('should process quote', async () => {
|
||||
const out = await check({
|
||||
quote: {
|
||||
id: 1,
|
||||
id: Long.fromNumber(1),
|
||||
authorUuid: 'author',
|
||||
text: 'text',
|
||||
attachments: [
|
||||
|
@ -236,7 +236,7 @@ describe('processDataMessage', () => {
|
|||
await check({
|
||||
reaction: {
|
||||
emoji: '😎',
|
||||
targetTimestamp: TIMESTAMP,
|
||||
targetTimestamp: Long.fromNumber(TIMESTAMP),
|
||||
},
|
||||
})
|
||||
).reaction,
|
||||
|
@ -254,7 +254,7 @@ describe('processDataMessage', () => {
|
|||
reaction: {
|
||||
emoji: '😎',
|
||||
remove: true,
|
||||
targetTimestamp: TIMESTAMP,
|
||||
targetTimestamp: Long.fromNumber(TIMESTAMP),
|
||||
},
|
||||
})
|
||||
).reaction,
|
||||
|
@ -271,7 +271,7 @@ describe('processDataMessage', () => {
|
|||
const out = await check({
|
||||
preview: [
|
||||
{
|
||||
date: TIMESTAMP,
|
||||
date: Long.fromNumber(TIMESTAMP),
|
||||
image: UNPROCESSED_ATTACHMENT,
|
||||
},
|
||||
],
|
||||
|
|
|
@ -1,21 +0,0 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import { assert } from 'chai';
|
||||
import Long from 'long';
|
||||
|
||||
import { normalizeNumber } from '../../util/normalizeNumber';
|
||||
|
||||
describe('normalizeNumber', () => {
|
||||
it('returns undefined when input is undefined', () => {
|
||||
assert.isUndefined(normalizeNumber(undefined));
|
||||
});
|
||||
|
||||
it('returns number when input is number', () => {
|
||||
assert.strictEqual(normalizeNumber(123), 123);
|
||||
});
|
||||
|
||||
it('returns number when input is Long', () => {
|
||||
assert.strictEqual(normalizeNumber(new Long(123)), 123);
|
||||
});
|
||||
});
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
import { assert } from 'chai';
|
||||
import { v4 as getGuid } from 'uuid';
|
||||
import Long from 'long';
|
||||
|
||||
import MessageReceiver from '../textsecure/MessageReceiver';
|
||||
import { IncomingWebSocketRequest } from '../textsecure/WebsocketResources';
|
||||
|
@ -48,14 +49,14 @@ describe('MessageReceiver', () => {
|
|||
source: number,
|
||||
sourceUuid: uuid,
|
||||
sourceDevice: deviceId,
|
||||
timestamp: Date.now(),
|
||||
timestamp: Long.fromNumber(Date.now()),
|
||||
content: Crypto.getRandomBytes(200),
|
||||
}).finish();
|
||||
|
||||
messageReceiver.handleRequest(
|
||||
new IncomingWebSocketRequest(
|
||||
{
|
||||
id: 1,
|
||||
id: Long.fromNumber(1),
|
||||
verb: 'PUT',
|
||||
path: '/api/v1/message',
|
||||
body,
|
||||
|
|
|
@ -93,7 +93,7 @@ describe('WebSocket-Resource', () => {
|
|||
|
||||
it('sends requests and receives responses', async () => {
|
||||
// mock socket and request handler
|
||||
let requestId: number | Long | undefined;
|
||||
let requestId: Long | undefined;
|
||||
const socket = new FakeSocket();
|
||||
|
||||
sinon.stub(socket, 'sendBytes').callsFake((data: Uint8Array) => {
|
||||
|
|
|
@ -43,7 +43,6 @@ import type { BatcherType } from '../util/batcher';
|
|||
import { createBatcher } from '../util/batcher';
|
||||
import { dropNull } from '../util/dropNull';
|
||||
import { normalizeUuid } from '../util/normalizeUuid';
|
||||
import { normalizeNumber } from '../util/normalizeNumber';
|
||||
import { parseIntOrThrow } from '../util/parseIntOrThrow';
|
||||
import { clearTimeoutIfNecessary } from '../util/clearTimeoutIfNecessary';
|
||||
import { Zone } from '../util/Zone';
|
||||
|
@ -279,7 +278,7 @@ export default class MessageReceiver
|
|||
|
||||
try {
|
||||
const decoded = Proto.Envelope.decode(plaintext);
|
||||
const serverTimestamp = normalizeNumber(decoded.serverTimestamp);
|
||||
const serverTimestamp = decoded.serverTimestamp?.toNumber();
|
||||
|
||||
const ourUuid = this.storage.user.getCheckedUuid();
|
||||
|
||||
|
@ -310,7 +309,7 @@ export default class MessageReceiver
|
|||
)
|
||||
)
|
||||
: ourUuid,
|
||||
timestamp: normalizeNumber(decoded.timestamp),
|
||||
timestamp: decoded.timestamp?.toNumber(),
|
||||
legacyMessage: dropNull(decoded.legacyMessage),
|
||||
content: dropNull(decoded.content),
|
||||
serverGuid: decoded.serverGuid,
|
||||
|
@ -690,13 +689,12 @@ export default class MessageReceiver
|
|||
destinationUuid: new UUID(
|
||||
decoded.destinationUuid || item.destinationUuid || ourUuid.toString()
|
||||
),
|
||||
timestamp: normalizeNumber(decoded.timestamp),
|
||||
timestamp: decoded.timestamp?.toNumber(),
|
||||
legacyMessage: dropNull(decoded.legacyMessage),
|
||||
content: dropNull(decoded.content),
|
||||
serverGuid: decoded.serverGuid,
|
||||
serverTimestamp: normalizeNumber(
|
||||
item.serverTimestamp || decoded.serverTimestamp
|
||||
),
|
||||
serverTimestamp:
|
||||
item.serverTimestamp || decoded.serverTimestamp?.toNumber(),
|
||||
};
|
||||
|
||||
const { decrypted } = item;
|
||||
|
@ -1773,7 +1771,7 @@ export default class MessageReceiver
|
|||
{
|
||||
destination: dropNull(destination),
|
||||
destinationUuid: dropNull(destinationUuid),
|
||||
timestamp: timestamp ? normalizeNumber(timestamp) : undefined,
|
||||
timestamp: timestamp?.toNumber(),
|
||||
serverTimestamp: envelope.serverTimestamp,
|
||||
device: envelope.sourceDevice,
|
||||
unidentifiedStatus,
|
||||
|
@ -1781,9 +1779,7 @@ export default class MessageReceiver
|
|||
isRecipientUpdate: Boolean(isRecipientUpdate),
|
||||
receivedAtCounter: envelope.receivedAtCounter,
|
||||
receivedAtDate: envelope.receivedAtDate,
|
||||
expirationStartTimestamp: expirationStartTimestamp
|
||||
? normalizeNumber(expirationStartTimestamp)
|
||||
: undefined,
|
||||
expirationStartTimestamp: expirationStartTimestamp?.toNumber(),
|
||||
},
|
||||
this.removeFromCache.bind(this, envelope)
|
||||
);
|
||||
|
@ -2200,7 +2196,7 @@ export default class MessageReceiver
|
|||
receiptMessage.timestamp.map(async rawTimestamp => {
|
||||
const ev = new EventClass(
|
||||
{
|
||||
timestamp: normalizeNumber(rawTimestamp),
|
||||
timestamp: rawTimestamp?.toNumber(),
|
||||
envelopeTimestamp: envelope.timestamp,
|
||||
source: envelope.source,
|
||||
sourceUuid: envelope.sourceUuid,
|
||||
|
@ -2221,7 +2217,7 @@ export default class MessageReceiver
|
|||
|
||||
if (envelope.timestamp && typingMessage.timestamp) {
|
||||
const envelopeTimestamp = envelope.timestamp;
|
||||
const typingTimestamp = normalizeNumber(typingMessage.timestamp);
|
||||
const typingTimestamp = typingMessage.timestamp?.toNumber();
|
||||
|
||||
if (typingTimestamp !== envelopeTimestamp) {
|
||||
log.warn(
|
||||
|
@ -2258,7 +2254,7 @@ export default class MessageReceiver
|
|||
senderDevice: envelope.sourceDevice,
|
||||
typing: {
|
||||
typingMessage,
|
||||
timestamp: timestamp ? normalizeNumber(timestamp) : Date.now(),
|
||||
timestamp: timestamp?.toNumber() ?? Date.now(),
|
||||
started: action === Proto.TypingMessage.Action.STARTED,
|
||||
stopped: action === Proto.TypingMessage.Action.STOPPED,
|
||||
|
||||
|
@ -2421,7 +2417,7 @@ export default class MessageReceiver
|
|||
log.info(
|
||||
'sent message to',
|
||||
this.getDestination(sentMessage),
|
||||
normalizeNumber(sentMessage.timestamp),
|
||||
sentMessage.timestamp?.toNumber(),
|
||||
'from',
|
||||
this.getEnvelopeId(envelope)
|
||||
);
|
||||
|
@ -2511,7 +2507,7 @@ export default class MessageReceiver
|
|||
sourceUuid: sync.senderUuid
|
||||
? normalizeUuid(sync.senderUuid, 'handleViewOnceOpen.senderUuid')
|
||||
: undefined,
|
||||
timestamp: sync.timestamp ? normalizeNumber(sync.timestamp) : undefined,
|
||||
timestamp: sync.timestamp?.toNumber(),
|
||||
},
|
||||
this.removeFromCache.bind(this, envelope)
|
||||
);
|
||||
|
@ -2646,7 +2642,7 @@ export default class MessageReceiver
|
|||
const ev = new ReadSyncEvent(
|
||||
{
|
||||
envelopeTimestamp: envelope.timestamp,
|
||||
timestamp: normalizeNumber(dropNull(timestamp)),
|
||||
timestamp: timestamp?.toNumber(),
|
||||
sender: dropNull(sender),
|
||||
senderUuid: senderUuid
|
||||
? normalizeUuid(senderUuid, 'handleRead.senderUuid')
|
||||
|
@ -2669,7 +2665,7 @@ export default class MessageReceiver
|
|||
const ev = new ViewSyncEvent(
|
||||
{
|
||||
envelopeTimestamp: envelope.timestamp,
|
||||
timestamp: normalizeNumber(dropNull(timestamp)),
|
||||
timestamp: timestamp?.toNumber(),
|
||||
senderE164: dropNull(senderE164),
|
||||
senderUuid: senderUuid
|
||||
? normalizeUuid(senderUuid, 'handleViewed.senderUuid')
|
||||
|
|
|
@ -342,7 +342,7 @@ class Message {
|
|||
}
|
||||
const proto = new Proto.DataMessage();
|
||||
|
||||
proto.timestamp = this.timestamp;
|
||||
proto.timestamp = Long.fromNumber(this.timestamp);
|
||||
proto.attachments = this.attachmentPointers;
|
||||
|
||||
if (this.body) {
|
||||
|
@ -384,7 +384,10 @@ class Message {
|
|||
proto.reaction.emoji = this.reaction.emoji || null;
|
||||
proto.reaction.remove = this.reaction.remove || false;
|
||||
proto.reaction.targetAuthorUuid = this.reaction.targetAuthorUuid || null;
|
||||
proto.reaction.targetTimestamp = this.reaction.targetTimestamp || null;
|
||||
proto.reaction.targetTimestamp =
|
||||
this.reaction.targetTimestamp === undefined
|
||||
? null
|
||||
: Long.fromNumber(this.reaction.targetTimestamp);
|
||||
}
|
||||
|
||||
if (Array.isArray(this.preview)) {
|
||||
|
@ -407,7 +410,8 @@ class Message {
|
|||
proto.quote = new Quote();
|
||||
const { quote } = proto;
|
||||
|
||||
quote.id = this.quote.id || null;
|
||||
quote.id =
|
||||
this.quote.id === undefined ? null : Long.fromNumber(this.quote.id);
|
||||
quote.authorUuid = this.quote.authorUuid || null;
|
||||
quote.text = this.quote.text || null;
|
||||
quote.attachments = (this.quote.attachments || []).map(
|
||||
|
@ -453,7 +457,7 @@ class Message {
|
|||
}
|
||||
if (this.deletedForEveryoneTimestamp) {
|
||||
proto.delete = {
|
||||
targetSentTimestamp: this.deletedForEveryoneTimestamp,
|
||||
targetSentTimestamp: Long.fromNumber(this.deletedForEveryoneTimestamp),
|
||||
};
|
||||
}
|
||||
if (this.mentions) {
|
||||
|
@ -484,7 +488,7 @@ class Message {
|
|||
if (this.storyContext.authorUuid) {
|
||||
storyContext.authorUuid = this.storyContext.authorUuid;
|
||||
}
|
||||
storyContext.sentTimestamp = this.storyContext.timestamp;
|
||||
storyContext.sentTimestamp = Long.fromNumber(this.storyContext.timestamp);
|
||||
|
||||
proto.storyContext = storyContext;
|
||||
}
|
||||
|
@ -772,7 +776,7 @@ export default class MessageSender {
|
|||
typingMessage.groupId = groupId;
|
||||
}
|
||||
typingMessage.action = action;
|
||||
typingMessage.timestamp = finalTimestamp;
|
||||
typingMessage.timestamp = Long.fromNumber(finalTimestamp);
|
||||
|
||||
const contentMessage = new Proto.Content();
|
||||
contentMessage.typingMessage = typingMessage;
|
||||
|
@ -1111,7 +1115,7 @@ export default class MessageSender {
|
|||
|
||||
const dataMessage = Proto.DataMessage.decode(encodedDataMessage);
|
||||
const sentMessage = new Proto.SyncMessage.Sent();
|
||||
sentMessage.timestamp = timestamp;
|
||||
sentMessage.timestamp = Long.fromNumber(timestamp);
|
||||
sentMessage.message = dataMessage;
|
||||
if (destination) {
|
||||
sentMessage.destination = destination;
|
||||
|
@ -1120,7 +1124,9 @@ export default class MessageSender {
|
|||
sentMessage.destinationUuid = destinationUuid;
|
||||
}
|
||||
if (expirationStartTimestamp) {
|
||||
sentMessage.expirationStartTimestamp = expirationStartTimestamp;
|
||||
sentMessage.expirationStartTimestamp = Long.fromNumber(
|
||||
expirationStartTimestamp
|
||||
);
|
||||
}
|
||||
|
||||
if (isUpdate) {
|
||||
|
@ -1345,7 +1351,10 @@ export default class MessageSender {
|
|||
const syncMessage = this.createSyncMessage();
|
||||
syncMessage.read = [];
|
||||
for (let i = 0; i < reads.length; i += 1) {
|
||||
const proto = new Proto.SyncMessage.Read(reads[i]);
|
||||
const proto = new Proto.SyncMessage.Read({
|
||||
...reads[i],
|
||||
timestamp: Long.fromNumber(reads[i].timestamp),
|
||||
});
|
||||
|
||||
syncMessage.read.push(proto);
|
||||
}
|
||||
|
@ -1374,7 +1383,13 @@ export default class MessageSender {
|
|||
const myUuid = window.textsecure.storage.user.getCheckedUuid();
|
||||
|
||||
const syncMessage = this.createSyncMessage();
|
||||
syncMessage.viewed = views.map(view => new Proto.SyncMessage.Viewed(view));
|
||||
syncMessage.viewed = views.map(
|
||||
view =>
|
||||
new Proto.SyncMessage.Viewed({
|
||||
...view,
|
||||
timestamp: Long.fromNumber(view.timestamp),
|
||||
})
|
||||
);
|
||||
const contentMessage = new Proto.Content();
|
||||
contentMessage.syncMessage = syncMessage;
|
||||
|
||||
|
@ -1417,7 +1432,7 @@ export default class MessageSender {
|
|||
viewOnceOpen.sender = senderE164;
|
||||
}
|
||||
viewOnceOpen.senderUuid = senderUuid;
|
||||
viewOnceOpen.timestamp = timestamp;
|
||||
viewOnceOpen.timestamp = Long.fromNumber(timestamp);
|
||||
syncMessage.viewOnceOpen = viewOnceOpen;
|
||||
|
||||
const contentMessage = new Proto.Content();
|
||||
|
@ -1647,7 +1662,9 @@ export default class MessageSender {
|
|||
|
||||
const receiptMessage = new Proto.ReceiptMessage();
|
||||
receiptMessage.type = type;
|
||||
receiptMessage.timestamp = timestamps;
|
||||
receiptMessage.timestamp = timestamps.map(timestamp =>
|
||||
Long.fromNumber(timestamp)
|
||||
);
|
||||
|
||||
const contentMessage = new Proto.Content();
|
||||
contentMessage.receiptMessage = receiptMessage;
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
*/
|
||||
|
||||
import type { connection as WebSocket, IMessage } from 'websocket';
|
||||
import Long from 'long';
|
||||
|
||||
import type { EventHandler } from './EventTarget';
|
||||
import EventTarget from './EventTarget';
|
||||
|
@ -32,7 +33,6 @@ import * as durations from '../util/durations';
|
|||
import { dropNull } from '../util/dropNull';
|
||||
import { isOlderThan } from '../util/timestamp';
|
||||
import { strictAssert } from '../util/assert';
|
||||
import { normalizeNumber } from '../util/normalizeNumber';
|
||||
import * as Errors from '../types/errors';
|
||||
import { SignalService as Proto } from '../protobuf';
|
||||
import * as log from '../logging/log';
|
||||
|
@ -43,7 +43,7 @@ const THIRTY_SECONDS = 30 * durations.SECOND;
|
|||
const MAX_MESSAGE_SIZE = 256 * 1024;
|
||||
|
||||
export class IncomingWebSocketRequest {
|
||||
private readonly id: Long | number;
|
||||
private readonly id: Long;
|
||||
|
||||
public readonly verb: string;
|
||||
|
||||
|
@ -105,18 +105,18 @@ export class CloseEvent extends Event {
|
|||
}
|
||||
|
||||
export default class WebSocketResource extends EventTarget {
|
||||
private outgoingId = 1;
|
||||
private outgoingId = Long.fromNumber(1, true);
|
||||
|
||||
private closed = false;
|
||||
|
||||
private readonly outgoingMap = new Map<
|
||||
number,
|
||||
string,
|
||||
(result: SendRequestResult) => void
|
||||
>();
|
||||
|
||||
private readonly boundOnMessage: (message: IMessage) => void;
|
||||
|
||||
private activeRequests = new Set<IncomingWebSocketRequest | number>();
|
||||
private activeRequests = new Set<IncomingWebSocketRequest | string>();
|
||||
|
||||
private shuttingDown = false;
|
||||
|
||||
|
@ -176,10 +176,11 @@ export default class WebSocketResource extends EventTarget {
|
|||
options: SendRequestOptions
|
||||
): Promise<SendRequestResult> {
|
||||
const id = this.outgoingId;
|
||||
strictAssert(!this.outgoingMap.has(id), 'Duplicate outgoing request');
|
||||
const idString = id.toString();
|
||||
strictAssert(!this.outgoingMap.has(idString), 'Duplicate outgoing request');
|
||||
|
||||
// eslint-disable-next-line no-bitwise
|
||||
this.outgoingId = Math.max(1, (this.outgoingId + 1) & 0x7fffffff);
|
||||
// Note that this automatically wraps
|
||||
this.outgoingId = this.outgoingId.add(1);
|
||||
|
||||
const bytes = Proto.WebSocketMessage.encode({
|
||||
type: Proto.WebSocketMessage.Type.REQUEST,
|
||||
|
@ -197,22 +198,22 @@ export default class WebSocketResource extends EventTarget {
|
|||
);
|
||||
|
||||
strictAssert(!this.shuttingDown, 'Cannot send request, shutting down');
|
||||
this.addActive(id);
|
||||
this.addActive(idString);
|
||||
const promise = new Promise<SendRequestResult>((resolve, reject) => {
|
||||
let timer = options.timeout
|
||||
? Timers.setTimeout(() => {
|
||||
this.removeActive(id);
|
||||
this.removeActive(idString);
|
||||
reject(new Error('Request timed out'));
|
||||
}, options.timeout)
|
||||
: undefined;
|
||||
|
||||
this.outgoingMap.set(id, result => {
|
||||
this.outgoingMap.set(idString, result => {
|
||||
if (timer !== undefined) {
|
||||
Timers.clearTimeout(timer);
|
||||
timer = undefined;
|
||||
}
|
||||
|
||||
this.removeActive(id);
|
||||
this.removeActive(idString);
|
||||
resolve(result);
|
||||
});
|
||||
});
|
||||
|
@ -321,12 +322,12 @@ export default class WebSocketResource extends EventTarget {
|
|||
const { response } = message;
|
||||
strictAssert(response.id, 'response without id');
|
||||
|
||||
const responseId = normalizeNumber(response.id);
|
||||
const resolve = this.outgoingMap.get(responseId);
|
||||
this.outgoingMap.delete(responseId);
|
||||
const responseIdString = response.id.toString();
|
||||
const resolve = this.outgoingMap.get(responseIdString);
|
||||
this.outgoingMap.delete(responseIdString);
|
||||
|
||||
if (!resolve) {
|
||||
throw new Error(`Received response for unknown request ${responseId}`);
|
||||
throw new Error(`Received response for unknown request ${response.id}`);
|
||||
}
|
||||
|
||||
resolve({
|
||||
|
@ -352,11 +353,11 @@ export default class WebSocketResource extends EventTarget {
|
|||
}
|
||||
}
|
||||
|
||||
private addActive(request: IncomingWebSocketRequest | number): void {
|
||||
private addActive(request: IncomingWebSocketRequest | string): void {
|
||||
this.activeRequests.add(request);
|
||||
}
|
||||
|
||||
private removeActive(request: IncomingWebSocketRequest | number): void {
|
||||
private removeActive(request: IncomingWebSocketRequest | string): void {
|
||||
if (!this.activeRequests.has(request)) {
|
||||
log.warn('WebSocketResource: removing unknown request');
|
||||
return;
|
||||
|
|
|
@ -5,7 +5,6 @@ import Long from 'long';
|
|||
|
||||
import { assert, strictAssert } from '../util/assert';
|
||||
import { dropNull, shallowDropNull } from '../util/dropNull';
|
||||
import { normalizeNumber } from '../util/normalizeNumber';
|
||||
import { SignalService as Proto } from '../protobuf';
|
||||
import { deriveGroupFields } from '../groups';
|
||||
import * as Bytes from '../Bytes';
|
||||
|
@ -120,7 +119,7 @@ export function processQuote(
|
|||
}
|
||||
|
||||
return {
|
||||
id: normalizeNumber(dropNull(quote.id)),
|
||||
id: quote.id?.toNumber(),
|
||||
authorUuid: dropNull(quote.authorUuid),
|
||||
text: dropNull(quote.text),
|
||||
attachments: (quote.attachments ?? []).map(attachment => {
|
||||
|
@ -163,10 +162,8 @@ function isLinkPreviewDateValid(value: unknown): value is number {
|
|||
);
|
||||
}
|
||||
|
||||
function cleanLinkPreviewDate(
|
||||
value?: Long | number | null
|
||||
): number | undefined {
|
||||
const result = normalizeNumber(value ?? undefined);
|
||||
function cleanLinkPreviewDate(value?: Long | null): number | undefined {
|
||||
const result = value?.toNumber();
|
||||
return isLinkPreviewDateValid(result) ? result : undefined;
|
||||
}
|
||||
|
||||
|
@ -198,7 +195,7 @@ export function processSticker(
|
|||
return {
|
||||
packId: sticker.packId ? Bytes.toHex(sticker.packId) : undefined,
|
||||
packKey: sticker.packKey ? Bytes.toBase64(sticker.packKey) : undefined,
|
||||
stickerId: normalizeNumber(dropNull(sticker.stickerId)),
|
||||
stickerId: dropNull(sticker.stickerId),
|
||||
data: processAttachment(sticker.data),
|
||||
};
|
||||
}
|
||||
|
@ -214,7 +211,7 @@ export function processReaction(
|
|||
emoji: dropNull(reaction.emoji),
|
||||
remove: Boolean(reaction.remove),
|
||||
targetAuthorUuid: dropNull(reaction.targetAuthorUuid),
|
||||
targetTimestamp: normalizeNumber(dropNull(reaction.targetTimestamp)),
|
||||
targetTimestamp: reaction.targetTimestamp?.toNumber(),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -226,7 +223,7 @@ export function processDelete(
|
|||
}
|
||||
|
||||
return {
|
||||
targetSentTimestamp: normalizeNumber(dropNull(del.targetSentTimestamp)),
|
||||
targetSentTimestamp: del.targetSentTimestamp?.toNumber(),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -245,7 +242,7 @@ export async function processDataMessage(
|
|||
throw new Error('Missing timestamp on dataMessage');
|
||||
}
|
||||
|
||||
const timestamp = normalizeNumber(message.timestamp);
|
||||
const timestamp = message.timestamp?.toNumber();
|
||||
|
||||
if (envelopeTimestamp !== timestamp) {
|
||||
throw new Error(
|
||||
|
@ -272,9 +269,7 @@ export async function processDataMessage(
|
|||
contact: processContact(message.contact),
|
||||
preview: processPreview(message.preview),
|
||||
sticker: processSticker(message.sticker),
|
||||
requiredProtocolVersion: normalizeNumber(
|
||||
dropNull(message.requiredProtocolVersion)
|
||||
),
|
||||
requiredProtocolVersion: dropNull(message.requiredProtocolVersion),
|
||||
isViewOnce: Boolean(message.isViewOnce),
|
||||
reaction: processReaction(message.reaction),
|
||||
delete: processDelete(message.delete),
|
||||
|
|
|
@ -1,17 +0,0 @@
|
|||
// Copyright 2021 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
export function normalizeNumber(value: number | Long): number;
|
||||
export function normalizeNumber(value?: number | Long): number | undefined;
|
||||
|
||||
export function normalizeNumber(value?: number | Long): number | undefined {
|
||||
if (value === undefined) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (typeof value === 'number') {
|
||||
return value;
|
||||
}
|
||||
|
||||
return value.toNumber();
|
||||
}
|
|
@ -3,8 +3,6 @@
|
|||
|
||||
import Long from 'long';
|
||||
|
||||
import { normalizeNumber } from './normalizeNumber';
|
||||
|
||||
export function getSafeLongFromTimestamp(timestamp = 0): Long {
|
||||
if (timestamp >= Number.MAX_SAFE_INTEGER) {
|
||||
return Long.MAX_VALUE;
|
||||
|
@ -13,12 +11,12 @@ export function getSafeLongFromTimestamp(timestamp = 0): Long {
|
|||
return Long.fromNumber(timestamp);
|
||||
}
|
||||
|
||||
export function getTimestampFromLong(value?: Long | number | null): number {
|
||||
export function getTimestampFromLong(value?: Long | null): number {
|
||||
if (!value) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const num = normalizeNumber(value);
|
||||
const num = value.toNumber();
|
||||
|
||||
if (num >= Number.MAX_SAFE_INTEGER) {
|
||||
return Number.MAX_SAFE_INTEGER;
|
||||
|
|
Loading…
Reference in New Issue