Preliminary support for destinationUuid field
This commit is contained in:
parent
bb15cfc622
commit
066a23a6a9
8 changed files with 154 additions and 36 deletions
|
@ -32,6 +32,7 @@ message Envelope {
|
||||||
optional bytes content = 8; // Contains an encrypted Content
|
optional bytes content = 8; // Contains an encrypted Content
|
||||||
optional string serverGuid = 9;
|
optional string serverGuid = 9;
|
||||||
optional uint64 serverTimestamp = 10;
|
optional uint64 serverTimestamp = 10;
|
||||||
|
optional string destinationUuid = 13;
|
||||||
}
|
}
|
||||||
|
|
||||||
message Content {
|
message Content {
|
||||||
|
|
|
@ -206,6 +206,7 @@ export type UnprocessedType = {
|
||||||
source?: string;
|
source?: string;
|
||||||
sourceUuid?: string;
|
sourceUuid?: string;
|
||||||
sourceDevice?: number;
|
sourceDevice?: number;
|
||||||
|
destinationUuid?: string;
|
||||||
serverGuid?: string;
|
serverGuid?: string;
|
||||||
serverTimestamp?: number;
|
serverTimestamp?: number;
|
||||||
decrypted?: string;
|
decrypted?: string;
|
||||||
|
|
1
ts/textsecure.d.ts
vendored
1
ts/textsecure.d.ts
vendored
|
@ -29,6 +29,7 @@ export type UnprocessedType = {
|
||||||
source?: string;
|
source?: string;
|
||||||
sourceDevice?: number;
|
sourceDevice?: number;
|
||||||
sourceUuid?: string;
|
sourceUuid?: string;
|
||||||
|
destinationUuid?: string;
|
||||||
messageAgeSec?: number;
|
messageAgeSec?: number;
|
||||||
version: number;
|
version: number;
|
||||||
};
|
};
|
||||||
|
|
|
@ -49,7 +49,8 @@ import { deriveMasterKeyFromGroupV1 } from '../Crypto';
|
||||||
import type { DownloadedAttachmentType } from '../types/Attachment';
|
import type { DownloadedAttachmentType } from '../types/Attachment';
|
||||||
import { Address } from '../types/Address';
|
import { Address } from '../types/Address';
|
||||||
import { QualifiedAddress } from '../types/QualifiedAddress';
|
import { QualifiedAddress } from '../types/QualifiedAddress';
|
||||||
import { UUID } from '../types/UUID';
|
import type { UUIDStringType } from '../types/UUID';
|
||||||
|
import { UUID, UUIDKind } from '../types/UUID';
|
||||||
import * as Errors from '../types/errors';
|
import * as Errors from '../types/errors';
|
||||||
|
|
||||||
import { SignalService as Proto } from '../protobuf';
|
import { SignalService as Proto } from '../protobuf';
|
||||||
|
@ -264,6 +265,8 @@ export default class MessageReceiver
|
||||||
const decoded = Proto.Envelope.decode(plaintext);
|
const decoded = Proto.Envelope.decode(plaintext);
|
||||||
const serverTimestamp = normalizeNumber(decoded.serverTimestamp);
|
const serverTimestamp = normalizeNumber(decoded.serverTimestamp);
|
||||||
|
|
||||||
|
const ourUuid = this.storage.user.getCheckedUuid();
|
||||||
|
|
||||||
const envelope: ProcessedEnvelope = {
|
const envelope: ProcessedEnvelope = {
|
||||||
// Make non-private envelope IDs dashless so they don't get redacted
|
// Make non-private envelope IDs dashless so they don't get redacted
|
||||||
// from logs
|
// from logs
|
||||||
|
@ -283,6 +286,14 @@ export default class MessageReceiver
|
||||||
)
|
)
|
||||||
: undefined,
|
: undefined,
|
||||||
sourceDevice: decoded.sourceDevice,
|
sourceDevice: decoded.sourceDevice,
|
||||||
|
destinationUuid: decoded.destinationUuid
|
||||||
|
? new UUID(
|
||||||
|
normalizeUuid(
|
||||||
|
decoded.destinationUuid,
|
||||||
|
'MessageReceiver.handleRequest.destinationUuid'
|
||||||
|
)
|
||||||
|
)
|
||||||
|
: ourUuid,
|
||||||
timestamp: normalizeNumber(decoded.timestamp),
|
timestamp: normalizeNumber(decoded.timestamp),
|
||||||
legacyMessage: dropNull(decoded.legacyMessage),
|
legacyMessage: dropNull(decoded.legacyMessage),
|
||||||
content: dropNull(decoded.content),
|
content: dropNull(decoded.content),
|
||||||
|
@ -604,6 +615,8 @@ export default class MessageReceiver
|
||||||
|
|
||||||
const decoded = Proto.Envelope.decode(envelopePlaintext);
|
const decoded = Proto.Envelope.decode(envelopePlaintext);
|
||||||
|
|
||||||
|
const ourUuid = this.storage.user.getCheckedUuid();
|
||||||
|
|
||||||
const envelope: ProcessedEnvelope = {
|
const envelope: ProcessedEnvelope = {
|
||||||
id: item.id,
|
id: item.id,
|
||||||
receivedAtCounter: item.timestamp,
|
receivedAtCounter: item.timestamp,
|
||||||
|
@ -615,6 +628,9 @@ export default class MessageReceiver
|
||||||
source: decoded.source || item.source,
|
source: decoded.source || item.source,
|
||||||
sourceUuid: decoded.sourceUuid || item.sourceUuid,
|
sourceUuid: decoded.sourceUuid || item.sourceUuid,
|
||||||
sourceDevice: decoded.sourceDevice || item.sourceDevice,
|
sourceDevice: decoded.sourceDevice || item.sourceDevice,
|
||||||
|
destinationUuid: new UUID(
|
||||||
|
decoded.destinationUuid || item.destinationUuid || ourUuid.toString()
|
||||||
|
),
|
||||||
timestamp: normalizeNumber(decoded.timestamp),
|
timestamp: normalizeNumber(decoded.timestamp),
|
||||||
legacyMessage: dropNull(decoded.legacyMessage),
|
legacyMessage: dropNull(decoded.legacyMessage),
|
||||||
content: dropNull(decoded.content),
|
content: dropNull(decoded.content),
|
||||||
|
@ -668,12 +684,16 @@ export default class MessageReceiver
|
||||||
private getEnvelopeId(envelope: ProcessedEnvelope): string {
|
private getEnvelopeId(envelope: ProcessedEnvelope): string {
|
||||||
const { timestamp } = envelope;
|
const { timestamp } = envelope;
|
||||||
|
|
||||||
|
let prefix = '';
|
||||||
|
|
||||||
if (envelope.sourceUuid || envelope.source) {
|
if (envelope.sourceUuid || envelope.source) {
|
||||||
const sender = envelope.sourceUuid || envelope.source;
|
const sender = envelope.sourceUuid || envelope.source;
|
||||||
return `${sender}.${envelope.sourceDevice} ${timestamp} (${envelope.id})`;
|
prefix += `${sender}.${envelope.sourceDevice} `;
|
||||||
}
|
}
|
||||||
|
|
||||||
return `${timestamp} (${envelope.id})`;
|
prefix += `> ${envelope.destinationUuid.toString()}`;
|
||||||
|
|
||||||
|
return `${prefix}${timestamp} (${envelope.id})`;
|
||||||
}
|
}
|
||||||
|
|
||||||
private clearRetryTimeout(): void {
|
private clearRetryTimeout(): void {
|
||||||
|
@ -737,9 +757,8 @@ export default class MessageReceiver
|
||||||
pendingSessions: true,
|
pendingSessions: true,
|
||||||
pendingUnprocessed: true,
|
pendingUnprocessed: true,
|
||||||
});
|
});
|
||||||
const ourUuid = this.storage.user.getCheckedUuid();
|
|
||||||
const sessionStore = new Sessions({ zone, ourUuid });
|
const storesMap = new Map<UUIDStringType, LockedStores>();
|
||||||
const identityKeyStore = new IdentityKeys({ zone, ourUuid });
|
|
||||||
const failed: Array<UnprocessedType> = [];
|
const failed: Array<UnprocessedType> = [];
|
||||||
|
|
||||||
// Below we:
|
// Below we:
|
||||||
|
@ -755,9 +774,38 @@ export default class MessageReceiver
|
||||||
await Promise.all<void>(
|
await Promise.all<void>(
|
||||||
items.map(async ({ data, envelope }) => {
|
items.map(async ({ data, envelope }) => {
|
||||||
try {
|
try {
|
||||||
|
const { destinationUuid } = envelope;
|
||||||
|
const uuidKind =
|
||||||
|
this.storage.user.getOurUuidKind(destinationUuid);
|
||||||
|
if (uuidKind === UUIDKind.Unknown) {
|
||||||
|
log.warn(
|
||||||
|
'MessageReceiver.decryptAndCacheBatch: ' +
|
||||||
|
`Rejecting envelope ${this.getEnvelopeId(envelope)}, ` +
|
||||||
|
`unknown uuid: ${destinationUuid}`
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let stores = storesMap.get(destinationUuid.toString());
|
||||||
|
if (!stores) {
|
||||||
|
stores = {
|
||||||
|
sessionStore: new Sessions({
|
||||||
|
zone,
|
||||||
|
ourUuid: destinationUuid,
|
||||||
|
}),
|
||||||
|
identityKeyStore: new IdentityKeys({
|
||||||
|
zone,
|
||||||
|
ourUuid: destinationUuid,
|
||||||
|
}),
|
||||||
|
zone,
|
||||||
|
};
|
||||||
|
storesMap.set(destinationUuid.toString(), stores);
|
||||||
|
}
|
||||||
|
|
||||||
const result = await this.queueEncryptedEnvelope(
|
const result = await this.queueEncryptedEnvelope(
|
||||||
{ sessionStore, identityKeyStore, zone },
|
stores,
|
||||||
envelope
|
envelope,
|
||||||
|
uuidKind
|
||||||
);
|
);
|
||||||
if (result.plaintext) {
|
if (result.plaintext) {
|
||||||
decrypted.push({
|
decrypted.push({
|
||||||
|
@ -769,7 +817,8 @@ export default class MessageReceiver
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
failed.push(data);
|
failed.push(data);
|
||||||
log.error(
|
log.error(
|
||||||
'decryptAndCache error when processing the envelope',
|
'MessageReceiver.decryptAndCacheBatch error when ' +
|
||||||
|
'processing the envelope',
|
||||||
Errors.toLogFormat(error)
|
Errors.toLogFormat(error)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -791,6 +840,7 @@ export default class MessageReceiver
|
||||||
source: envelope.source,
|
source: envelope.source,
|
||||||
sourceUuid: envelope.sourceUuid,
|
sourceUuid: envelope.sourceUuid,
|
||||||
sourceDevice: envelope.sourceDevice,
|
sourceDevice: envelope.sourceDevice,
|
||||||
|
destinationUuid: envelope.destinationUuid.toString(),
|
||||||
serverGuid: envelope.serverGuid,
|
serverGuid: envelope.serverGuid,
|
||||||
serverTimestamp: envelope.serverTimestamp,
|
serverTimestamp: envelope.serverTimestamp,
|
||||||
decrypted: Bytes.toBase64(plaintext),
|
decrypted: Bytes.toBase64(plaintext),
|
||||||
|
@ -901,17 +951,27 @@ export default class MessageReceiver
|
||||||
|
|
||||||
private async queueEncryptedEnvelope(
|
private async queueEncryptedEnvelope(
|
||||||
stores: LockedStores,
|
stores: LockedStores,
|
||||||
envelope: ProcessedEnvelope
|
envelope: ProcessedEnvelope,
|
||||||
|
uuidKind: UUIDKind
|
||||||
): Promise<DecryptResult> {
|
): Promise<DecryptResult> {
|
||||||
let logId = this.getEnvelopeId(envelope);
|
let logId = this.getEnvelopeId(envelope);
|
||||||
log.info('queueing envelope', logId);
|
log.info(`queueing ${uuidKind} envelope`, logId);
|
||||||
|
|
||||||
const task = createTaskWithTimeout(async (): Promise<DecryptResult> => {
|
const task = createTaskWithTimeout(async (): Promise<DecryptResult> => {
|
||||||
const unsealedEnvelope = await this.unsealEnvelope(stores, envelope);
|
const unsealedEnvelope = await this.unsealEnvelope(
|
||||||
|
stores,
|
||||||
|
envelope,
|
||||||
|
uuidKind
|
||||||
|
);
|
||||||
|
|
||||||
|
// Dropped early
|
||||||
|
if (!unsealedEnvelope) {
|
||||||
|
return { plaintext: undefined, envelope };
|
||||||
|
}
|
||||||
|
|
||||||
logId = this.getEnvelopeId(unsealedEnvelope);
|
logId = this.getEnvelopeId(unsealedEnvelope);
|
||||||
|
|
||||||
return this.decryptEnvelope(stores, unsealedEnvelope);
|
return this.decryptEnvelope(stores, unsealedEnvelope, uuidKind);
|
||||||
}, `MessageReceiver: unseal and decrypt ${logId}`);
|
}, `MessageReceiver: unseal and decrypt ${logId}`);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -976,8 +1036,9 @@ export default class MessageReceiver
|
||||||
|
|
||||||
private async unsealEnvelope(
|
private async unsealEnvelope(
|
||||||
stores: LockedStores,
|
stores: LockedStores,
|
||||||
envelope: ProcessedEnvelope
|
envelope: ProcessedEnvelope,
|
||||||
): Promise<UnsealedEnvelope> {
|
uuidKind: UUIDKind
|
||||||
|
): Promise<UnsealedEnvelope | undefined> {
|
||||||
const logId = this.getEnvelopeId(envelope);
|
const logId = this.getEnvelopeId(envelope);
|
||||||
|
|
||||||
if (this.stoppingProcessing) {
|
if (this.stoppingProcessing) {
|
||||||
|
@ -989,6 +1050,11 @@ export default class MessageReceiver
|
||||||
return envelope;
|
return envelope;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (uuidKind === UUIDKind.PNI) {
|
||||||
|
log.warn(`MessageReceiver.unsealEnvelope(${logId}): dropping for PNI`);
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
const ciphertext = envelope.content || envelope.legacyMessage;
|
const ciphertext = envelope.content || envelope.legacyMessage;
|
||||||
if (!ciphertext) {
|
if (!ciphertext) {
|
||||||
this.removeFromCache(envelope);
|
this.removeFromCache(envelope);
|
||||||
|
@ -1036,7 +1102,8 @@ export default class MessageReceiver
|
||||||
|
|
||||||
private async decryptEnvelope(
|
private async decryptEnvelope(
|
||||||
stores: LockedStores,
|
stores: LockedStores,
|
||||||
envelope: UnsealedEnvelope
|
envelope: UnsealedEnvelope,
|
||||||
|
uuidKind: UUIDKind
|
||||||
): Promise<DecryptResult> {
|
): Promise<DecryptResult> {
|
||||||
const logId = this.getEnvelopeId(envelope);
|
const logId = this.getEnvelopeId(envelope);
|
||||||
|
|
||||||
|
@ -1068,7 +1135,12 @@ export default class MessageReceiver
|
||||||
log.info(
|
log.info(
|
||||||
`MessageReceiver.decryptEnvelope(${logId})${isLegacy ? ' (legacy)' : ''}`
|
`MessageReceiver.decryptEnvelope(${logId})${isLegacy ? ' (legacy)' : ''}`
|
||||||
);
|
);
|
||||||
const plaintext = await this.decrypt(stores, envelope, ciphertext);
|
const plaintext = await this.decrypt(
|
||||||
|
stores,
|
||||||
|
envelope,
|
||||||
|
ciphertext,
|
||||||
|
uuidKind
|
||||||
|
);
|
||||||
|
|
||||||
if (!plaintext) {
|
if (!plaintext) {
|
||||||
log.warn('MessageReceiver.decryptEnvelope: plaintext was falsey');
|
log.warn('MessageReceiver.decryptEnvelope: plaintext was falsey');
|
||||||
|
@ -1206,7 +1278,7 @@ export default class MessageReceiver
|
||||||
ciphertext: Uint8Array
|
ciphertext: Uint8Array
|
||||||
): Promise<DecryptSealedSenderResult> {
|
): Promise<DecryptSealedSenderResult> {
|
||||||
const localE164 = this.storage.user.getNumber();
|
const localE164 = this.storage.user.getNumber();
|
||||||
const ourUuid = this.storage.user.getCheckedUuid();
|
const { destinationUuid } = envelope;
|
||||||
const localDeviceId = parseIntOrThrow(
|
const localDeviceId = parseIntOrThrow(
|
||||||
this.storage.user.getDeviceId(),
|
this.storage.user.getDeviceId(),
|
||||||
'MessageReceiver.decryptSealedSender: localDeviceId'
|
'MessageReceiver.decryptSealedSender: localDeviceId'
|
||||||
|
@ -1252,10 +1324,10 @@ export default class MessageReceiver
|
||||||
);
|
);
|
||||||
const sealedSenderIdentifier = certificate.senderUuid();
|
const sealedSenderIdentifier = certificate.senderUuid();
|
||||||
const sealedSenderSourceDevice = certificate.senderDeviceId();
|
const sealedSenderSourceDevice = certificate.senderDeviceId();
|
||||||
const senderKeyStore = new SenderKeys({ ourUuid });
|
const senderKeyStore = new SenderKeys({ ourUuid: destinationUuid });
|
||||||
|
|
||||||
const address = new QualifiedAddress(
|
const address = new QualifiedAddress(
|
||||||
ourUuid,
|
destinationUuid,
|
||||||
Address.create(sealedSenderIdentifier, sealedSenderSourceDevice)
|
Address.create(sealedSenderIdentifier, sealedSenderSourceDevice)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -1280,8 +1352,8 @@ export default class MessageReceiver
|
||||||
'unidentified message/passing to sealedSenderDecryptMessage'
|
'unidentified message/passing to sealedSenderDecryptMessage'
|
||||||
);
|
);
|
||||||
|
|
||||||
const preKeyStore = new PreKeys({ ourUuid });
|
const preKeyStore = new PreKeys({ ourUuid: destinationUuid });
|
||||||
const signedPreKeyStore = new SignedPreKeys({ ourUuid });
|
const signedPreKeyStore = new SignedPreKeys({ ourUuid: destinationUuid });
|
||||||
|
|
||||||
const sealedSenderIdentifier = envelope.sourceUuid;
|
const sealedSenderIdentifier = envelope.sourceUuid;
|
||||||
strictAssert(
|
strictAssert(
|
||||||
|
@ -1293,7 +1365,7 @@ export default class MessageReceiver
|
||||||
'Empty sealed sender device'
|
'Empty sealed sender device'
|
||||||
);
|
);
|
||||||
const address = new QualifiedAddress(
|
const address = new QualifiedAddress(
|
||||||
ourUuid,
|
destinationUuid,
|
||||||
Address.create(sealedSenderIdentifier, envelope.sourceDevice)
|
Address.create(sealedSenderIdentifier, envelope.sourceDevice)
|
||||||
);
|
);
|
||||||
const unsealedPlaintext = await this.storage.protocol.enqueueSessionJob(
|
const unsealedPlaintext = await this.storage.protocol.enqueueSessionJob(
|
||||||
|
@ -1304,7 +1376,7 @@ export default class MessageReceiver
|
||||||
PublicKey.deserialize(Buffer.from(this.serverTrustRoot)),
|
PublicKey.deserialize(Buffer.from(this.serverTrustRoot)),
|
||||||
envelope.serverTimestamp,
|
envelope.serverTimestamp,
|
||||||
localE164 || null,
|
localE164 || null,
|
||||||
ourUuid.toString(),
|
destinationUuid.toString(),
|
||||||
localDeviceId,
|
localDeviceId,
|
||||||
sessionStore,
|
sessionStore,
|
||||||
identityKeyStore,
|
identityKeyStore,
|
||||||
|
@ -1320,8 +1392,9 @@ export default class MessageReceiver
|
||||||
private async innerDecrypt(
|
private async innerDecrypt(
|
||||||
stores: LockedStores,
|
stores: LockedStores,
|
||||||
envelope: ProcessedEnvelope,
|
envelope: ProcessedEnvelope,
|
||||||
ciphertext: Uint8Array
|
ciphertext: Uint8Array,
|
||||||
): Promise<Uint8Array> {
|
uuidKind: UUIDKind
|
||||||
|
): Promise<Uint8Array | undefined> {
|
||||||
const { sessionStore, identityKeyStore, zone } = stores;
|
const { sessionStore, identityKeyStore, zone } = stores;
|
||||||
|
|
||||||
const logId = this.getEnvelopeId(envelope);
|
const logId = this.getEnvelopeId(envelope);
|
||||||
|
@ -1330,18 +1403,29 @@ export default class MessageReceiver
|
||||||
const identifier = envelope.sourceUuid;
|
const identifier = envelope.sourceUuid;
|
||||||
const { sourceDevice } = envelope;
|
const { sourceDevice } = envelope;
|
||||||
|
|
||||||
const ourUuid = this.storage.user.getCheckedUuid();
|
const { destinationUuid } = envelope;
|
||||||
const preKeyStore = new PreKeys({ ourUuid });
|
const preKeyStore = new PreKeys({ ourUuid: destinationUuid });
|
||||||
const signedPreKeyStore = new SignedPreKeys({ ourUuid });
|
const signedPreKeyStore = new SignedPreKeys({ ourUuid: destinationUuid });
|
||||||
|
|
||||||
strictAssert(identifier !== undefined, 'Empty identifier');
|
strictAssert(identifier !== undefined, 'Empty identifier');
|
||||||
strictAssert(sourceDevice !== undefined, 'Empty source device');
|
strictAssert(sourceDevice !== undefined, 'Empty source device');
|
||||||
|
|
||||||
const address = new QualifiedAddress(
|
const address = new QualifiedAddress(
|
||||||
ourUuid,
|
destinationUuid,
|
||||||
Address.create(identifier, sourceDevice)
|
Address.create(identifier, sourceDevice)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (
|
||||||
|
uuidKind === UUIDKind.PNI &&
|
||||||
|
envelope.type !== envelopeTypeEnum.PREKEY_BUNDLE
|
||||||
|
) {
|
||||||
|
log.warn(
|
||||||
|
`MessageReceiver.innerDecrypt(${logId}): ` +
|
||||||
|
'non-PreKey envelope on PNI'
|
||||||
|
);
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
if (envelope.type === envelopeTypeEnum.PLAINTEXT_CONTENT) {
|
if (envelope.type === envelopeTypeEnum.PLAINTEXT_CONTENT) {
|
||||||
log.info(`decrypt/${logId}: plaintext message`);
|
log.info(`decrypt/${logId}: plaintext message`);
|
||||||
const buffer = Buffer.from(ciphertext);
|
const buffer = Buffer.from(ciphertext);
|
||||||
|
@ -1445,10 +1529,11 @@ export default class MessageReceiver
|
||||||
private async decrypt(
|
private async decrypt(
|
||||||
stores: LockedStores,
|
stores: LockedStores,
|
||||||
envelope: UnsealedEnvelope,
|
envelope: UnsealedEnvelope,
|
||||||
ciphertext: Uint8Array
|
ciphertext: Uint8Array,
|
||||||
|
uuidKind: UUIDKind
|
||||||
): Promise<Uint8Array | undefined> {
|
): Promise<Uint8Array | undefined> {
|
||||||
try {
|
try {
|
||||||
return await this.innerDecrypt(stores, envelope, ciphertext);
|
return await this.innerDecrypt(stores, envelope, ciphertext, uuidKind);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
const uuid = envelope.sourceUuid;
|
const uuid = envelope.sourceUuid;
|
||||||
const deviceId = envelope.sourceDevice;
|
const deviceId = envelope.sourceDevice;
|
||||||
|
@ -1860,10 +1945,10 @@ export default class MessageReceiver
|
||||||
SenderKeyDistributionMessage.deserialize(
|
SenderKeyDistributionMessage.deserialize(
|
||||||
Buffer.from(distributionMessage)
|
Buffer.from(distributionMessage)
|
||||||
);
|
);
|
||||||
const ourUuid = this.storage.user.getCheckedUuid();
|
const { destinationUuid } = envelope;
|
||||||
const senderKeyStore = new SenderKeys({ ourUuid });
|
const senderKeyStore = new SenderKeys({ ourUuid: destinationUuid });
|
||||||
const address = new QualifiedAddress(
|
const address = new QualifiedAddress(
|
||||||
ourUuid,
|
destinationUuid,
|
||||||
Address.create(identifier, sourceDevice)
|
Address.create(identifier, sourceDevice)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
2
ts/textsecure/Types.d.ts
vendored
2
ts/textsecure/Types.d.ts
vendored
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
import type { SignalService as Proto } from '../protobuf';
|
import type { SignalService as Proto } from '../protobuf';
|
||||||
import type { IncomingWebSocketRequest } from './WebsocketResources';
|
import type { IncomingWebSocketRequest } from './WebsocketResources';
|
||||||
|
import type { UUID } from '../types/UUID';
|
||||||
|
|
||||||
export {
|
export {
|
||||||
IdentityKeyType,
|
IdentityKeyType,
|
||||||
|
@ -82,6 +83,7 @@ export type ProcessedEnvelope = Readonly<{
|
||||||
source?: string;
|
source?: string;
|
||||||
sourceUuid?: string;
|
sourceUuid?: string;
|
||||||
sourceDevice?: number;
|
sourceDevice?: number;
|
||||||
|
destinationUuid: UUID;
|
||||||
timestamp: number;
|
timestamp: number;
|
||||||
legacyMessage?: Uint8Array;
|
legacyMessage?: Uint8Array;
|
||||||
content?: Uint8Array;
|
content?: Uint8Array;
|
||||||
|
|
|
@ -5,7 +5,7 @@ import type { WebAPICredentials } from '../Types.d';
|
||||||
|
|
||||||
import { strictAssert } from '../../util/assert';
|
import { strictAssert } from '../../util/assert';
|
||||||
import type { StorageInterface } from '../../types/Storage.d';
|
import type { StorageInterface } from '../../types/Storage.d';
|
||||||
import { UUID } from '../../types/UUID';
|
import { UUID, UUIDKind } from '../../types/UUID';
|
||||||
import * as log from '../../logging/log';
|
import * as log from '../../logging/log';
|
||||||
|
|
||||||
import Helpers from '../Helpers';
|
import Helpers from '../Helpers';
|
||||||
|
@ -70,6 +70,27 @@ export class User {
|
||||||
return uuid;
|
return uuid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getPni(): UUID | undefined {
|
||||||
|
const pni = this.storage.get('pni');
|
||||||
|
if (pni === undefined) return undefined;
|
||||||
|
return new UUID(pni);
|
||||||
|
}
|
||||||
|
|
||||||
|
public getOurUuidKind(uuid: UUID): UUIDKind {
|
||||||
|
const ourUuid = this.getUuid();
|
||||||
|
|
||||||
|
if (ourUuid?.toString() === uuid.toString()) {
|
||||||
|
return UUIDKind.ACI;
|
||||||
|
}
|
||||||
|
|
||||||
|
const pni = this.getPni();
|
||||||
|
if (pni?.toString() === uuid.toString()) {
|
||||||
|
return UUIDKind.PNI;
|
||||||
|
}
|
||||||
|
|
||||||
|
return UUIDKind.Unknown;
|
||||||
|
}
|
||||||
|
|
||||||
public getDeviceId(): number | undefined {
|
public getDeviceId(): number | undefined {
|
||||||
const value = this._getDeviceIdFromUuid() || this._getDeviceIdFromNumber();
|
const value = this._getDeviceIdFromUuid() || this._getDeviceIdFromNumber();
|
||||||
if (value === undefined) {
|
if (value === undefined) {
|
||||||
|
|
1
ts/types/Storage.d.ts
vendored
1
ts/types/Storage.d.ts
vendored
|
@ -84,6 +84,7 @@ export type StorageAccessType = {
|
||||||
synced_at: number;
|
synced_at: number;
|
||||||
userAgent: string;
|
userAgent: string;
|
||||||
uuid_id: string;
|
uuid_id: string;
|
||||||
|
pni: string;
|
||||||
version: string;
|
version: string;
|
||||||
linkPreviews: boolean;
|
linkPreviews: boolean;
|
||||||
universalExpireTimer: number;
|
universalExpireTimer: number;
|
||||||
|
|
|
@ -8,6 +8,12 @@ import { strictAssert } from '../util/assert';
|
||||||
export type UUIDStringType =
|
export type UUIDStringType =
|
||||||
`${string}-${string}-${string}-${string}-${string}`;
|
`${string}-${string}-${string}-${string}-${string}`;
|
||||||
|
|
||||||
|
export enum UUIDKind {
|
||||||
|
ACI = 'ACI',
|
||||||
|
PNI = 'PNI',
|
||||||
|
Unknown = 'Unknown',
|
||||||
|
}
|
||||||
|
|
||||||
export const isValidUuid = (value: unknown): value is UUIDStringType =>
|
export const isValidUuid = (value: unknown): value is UUIDStringType =>
|
||||||
typeof value === 'string' &&
|
typeof value === 'string' &&
|
||||||
/^[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i.test(
|
/^[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i.test(
|
||||||
|
|
Loading…
Reference in a new issue