Generate PNI key on standalone registration
This commit is contained in:
parent
13de35bea2
commit
ca1aef660f
4 changed files with 101 additions and 81 deletions
|
@ -30,7 +30,6 @@ import {
|
||||||
generateSignedPreKey,
|
generateSignedPreKey,
|
||||||
generatePreKey,
|
generatePreKey,
|
||||||
} from '../Curve';
|
} from '../Curve';
|
||||||
import type { UUIDStringType } from '../types/UUID';
|
|
||||||
import { UUID, UUIDKind } from '../types/UUID';
|
import { UUID, UUIDKind } from '../types/UUID';
|
||||||
import { isMoreRecentThan, isOlderThan } from '../util/timestamp';
|
import { isMoreRecentThan, isOlderThan } from '../util/timestamp';
|
||||||
import { ourProfileKeyService } from '../services/ourProfileKey';
|
import { ourProfileKeyService } from '../services/ourProfileKey';
|
||||||
|
@ -73,6 +72,18 @@ export type GeneratedKeysType = {
|
||||||
identityKey: Uint8Array;
|
identityKey: Uint8Array;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
type CreateAccountOptionsType = Readonly<{
|
||||||
|
number: string;
|
||||||
|
verificationCode: string;
|
||||||
|
identityKeyPair: KeyPairType;
|
||||||
|
pniKeyPair?: KeyPairType;
|
||||||
|
profileKey?: Uint8Array;
|
||||||
|
deviceName?: string;
|
||||||
|
userAgent?: string;
|
||||||
|
readReceipts?: boolean;
|
||||||
|
accessKey?: Uint8Array;
|
||||||
|
}>;
|
||||||
|
|
||||||
export default class AccountManager extends EventTarget {
|
export default class AccountManager extends EventTarget {
|
||||||
pending: Promise<void>;
|
pending: Promise<void>;
|
||||||
|
|
||||||
|
@ -156,28 +167,28 @@ export default class AccountManager extends EventTarget {
|
||||||
async registerSingleDevice(number: string, verificationCode: string) {
|
async registerSingleDevice(number: string, verificationCode: string) {
|
||||||
return this.queueTask(async () => {
|
return this.queueTask(async () => {
|
||||||
const identityKeyPair = generateKeyPair();
|
const identityKeyPair = generateKeyPair();
|
||||||
|
const pniKeyPair = generateKeyPair();
|
||||||
const profileKey = getRandomBytes(PROFILE_KEY_LENGTH);
|
const profileKey = getRandomBytes(PROFILE_KEY_LENGTH);
|
||||||
const accessKey = deriveAccessKey(profileKey);
|
const accessKey = deriveAccessKey(profileKey);
|
||||||
|
|
||||||
await this.createAccount(
|
await this.createAccount({
|
||||||
number,
|
number,
|
||||||
verificationCode,
|
verificationCode,
|
||||||
identityKeyPair,
|
identityKeyPair,
|
||||||
|
pniKeyPair,
|
||||||
profileKey,
|
profileKey,
|
||||||
null,
|
accessKey,
|
||||||
null,
|
});
|
||||||
null,
|
|
||||||
{ accessKey }
|
|
||||||
);
|
|
||||||
|
|
||||||
await this.clearSessionsAndPreKeys();
|
await this.clearSessionsAndPreKeys();
|
||||||
// TODO: DESKTOP-2788
|
|
||||||
const keys = await this.generateKeys(
|
await Promise.all(
|
||||||
SIGNED_KEY_GEN_BATCH_SIZE,
|
[UUIDKind.ACI, UUIDKind.PNI].map(async kind => {
|
||||||
UUIDKind.ACI
|
const keys = await this.generateKeys(SIGNED_KEY_GEN_BATCH_SIZE, kind);
|
||||||
|
await this.server.registerKeys(keys, kind);
|
||||||
|
await this.confirmKeys(keys, kind);
|
||||||
|
})
|
||||||
);
|
);
|
||||||
await this.server.registerKeys(keys, UUIDKind.ACI);
|
|
||||||
await this.confirmKeys(keys);
|
|
||||||
await this.registrationDone();
|
await this.registrationDone();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -187,7 +198,6 @@ export default class AccountManager extends EventTarget {
|
||||||
confirmNumber: (number?: string) => Promise<string>,
|
confirmNumber: (number?: string) => Promise<string>,
|
||||||
progressCallback?: Function
|
progressCallback?: Function
|
||||||
) {
|
) {
|
||||||
const createAccount = this.createAccount.bind(this);
|
|
||||||
const clearSessionsAndPreKeys = this.clearSessionsAndPreKeys.bind(this);
|
const clearSessionsAndPreKeys = this.clearSessionsAndPreKeys.bind(this);
|
||||||
const provisioningCipher = new ProvisioningCipher();
|
const provisioningCipher = new ProvisioningCipher();
|
||||||
const pubKey = await provisioningCipher.getPublicKey();
|
const pubKey = await provisioningCipher.getPublicKey();
|
||||||
|
@ -266,20 +276,15 @@ export default class AccountManager extends EventTarget {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
await createAccount(
|
await this.createAccount({
|
||||||
provisionMessage.number,
|
number: provisionMessage.number,
|
||||||
provisionMessage.provisioningCode,
|
verificationCode: provisionMessage.provisioningCode,
|
||||||
provisionMessage.identityKeyPair,
|
identityKeyPair: provisionMessage.identityKeyPair,
|
||||||
provisionMessage.profileKey,
|
profileKey: provisionMessage.profileKey,
|
||||||
deviceName,
|
deviceName,
|
||||||
provisionMessage.userAgent,
|
userAgent: provisionMessage.userAgent,
|
||||||
provisionMessage.readReceipts,
|
readReceipts: provisionMessage.readReceipts,
|
||||||
{
|
});
|
||||||
uuid: provisionMessage.uuid
|
|
||||||
? UUID.cast(provisionMessage.uuid)
|
|
||||||
: undefined,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
await clearSessionsAndPreKeys();
|
await clearSessionsAndPreKeys();
|
||||||
// TODO: DESKTOP-2794
|
// TODO: DESKTOP-2794
|
||||||
const keys = await this.generateKeys(
|
const keys = await this.generateKeys(
|
||||||
|
@ -288,7 +293,7 @@ export default class AccountManager extends EventTarget {
|
||||||
progressCallback
|
progressCallback
|
||||||
);
|
);
|
||||||
await this.server.registerKeys(keys, UUIDKind.ACI);
|
await this.server.registerKeys(keys, UUIDKind.ACI);
|
||||||
await this.confirmKeys(keys);
|
await this.confirmKeys(keys, UUIDKind.ACI);
|
||||||
await this.registrationDone();
|
await this.registrationDone();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -454,18 +459,18 @@ export default class AccountManager extends EventTarget {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
async createAccount(
|
async createAccount({
|
||||||
number: string,
|
number,
|
||||||
verificationCode: string,
|
verificationCode,
|
||||||
identityKeyPair: KeyPairType,
|
identityKeyPair,
|
||||||
profileKey: Uint8Array | undefined,
|
pniKeyPair,
|
||||||
deviceName: string | null,
|
profileKey,
|
||||||
userAgent?: string | null,
|
deviceName,
|
||||||
readReceipts?: boolean | null,
|
userAgent,
|
||||||
options: { accessKey?: Uint8Array; uuid?: UUIDStringType } = {}
|
readReceipts,
|
||||||
): Promise<void> {
|
accessKey,
|
||||||
|
}: CreateAccountOptionsType): Promise<void> {
|
||||||
const { storage } = window.textsecure;
|
const { storage } = window.textsecure;
|
||||||
const { accessKey, uuid } = options;
|
|
||||||
let password = Bytes.toBase64(getRandomBytes(16));
|
let password = Bytes.toBase64(getRandomBytes(16));
|
||||||
password = password.substring(0, password.length - 2);
|
password = password.substring(0, password.length - 2);
|
||||||
const registrationId = generateRegistrationId();
|
const registrationId = generateRegistrationId();
|
||||||
|
@ -491,11 +496,11 @@ export default class AccountManager extends EventTarget {
|
||||||
password,
|
password,
|
||||||
registrationId,
|
registrationId,
|
||||||
encryptedDeviceName,
|
encryptedDeviceName,
|
||||||
{ accessKey, uuid }
|
{ accessKey }
|
||||||
);
|
);
|
||||||
|
|
||||||
const ourUuid = uuid || response.uuid;
|
const ourUuid = UUID.cast(response.uuid);
|
||||||
strictAssert(ourUuid !== undefined, 'Should have UUID after registration');
|
const ourPni = UUID.cast(response.pni);
|
||||||
|
|
||||||
const uuidChanged = previousUuid && ourUuid && previousUuid !== ourUuid;
|
const uuidChanged = previousUuid && ourUuid && previousUuid !== ourUuid;
|
||||||
|
|
||||||
|
@ -554,7 +559,7 @@ export default class AccountManager extends EventTarget {
|
||||||
// information.
|
// information.
|
||||||
await storage.user.setCredentials({
|
await storage.user.setCredentials({
|
||||||
uuid: ourUuid,
|
uuid: ourUuid,
|
||||||
pni: response.pni,
|
pni: ourPni,
|
||||||
number,
|
number,
|
||||||
deviceId: response.deviceId ?? 1,
|
deviceId: response.deviceId ?? 1,
|
||||||
deviceName: deviceName ?? undefined,
|
deviceName: deviceName ?? undefined,
|
||||||
|
@ -574,15 +579,27 @@ export default class AccountManager extends EventTarget {
|
||||||
throw new Error('registrationDone: no conversationId!');
|
throw new Error('registrationDone: no conversationId!');
|
||||||
}
|
}
|
||||||
|
|
||||||
// update our own identity key, which may have changed
|
const identityAttrs = {
|
||||||
// if we're relinking after a reinstall on the master device
|
|
||||||
await storage.protocol.saveIdentityWithAttributes(new UUID(ourUuid), {
|
|
||||||
publicKey: identityKeyPair.pubKey,
|
|
||||||
firstUse: true,
|
firstUse: true,
|
||||||
timestamp: Date.now(),
|
timestamp: Date.now(),
|
||||||
verified: storage.protocol.VerifiedStatus.VERIFIED,
|
verified: storage.protocol.VerifiedStatus.VERIFIED,
|
||||||
nonblockingApproval: true,
|
nonblockingApproval: true,
|
||||||
});
|
};
|
||||||
|
|
||||||
|
// update our own identity key, which may have changed
|
||||||
|
// if we're relinking after a reinstall on the master device
|
||||||
|
await Promise.all([
|
||||||
|
storage.protocol.saveIdentityWithAttributes(new UUID(ourUuid), {
|
||||||
|
...identityAttrs,
|
||||||
|
publicKey: identityKeyPair.pubKey,
|
||||||
|
}),
|
||||||
|
pniKeyPair
|
||||||
|
? storage.protocol.saveIdentityWithAttributes(new UUID(ourPni), {
|
||||||
|
...identityAttrs,
|
||||||
|
publicKey: pniKeyPair.pubKey,
|
||||||
|
})
|
||||||
|
: Promise.resolve(),
|
||||||
|
]);
|
||||||
|
|
||||||
const identityKeyMap = {
|
const identityKeyMap = {
|
||||||
...(storage.get('identityKeyMap') || {}),
|
...(storage.get('identityKeyMap') || {}),
|
||||||
|
@ -590,10 +607,20 @@ export default class AccountManager extends EventTarget {
|
||||||
pubKey: Bytes.toBase64(identityKeyPair.pubKey),
|
pubKey: Bytes.toBase64(identityKeyPair.pubKey),
|
||||||
privKey: Bytes.toBase64(identityKeyPair.privKey),
|
privKey: Bytes.toBase64(identityKeyPair.privKey),
|
||||||
},
|
},
|
||||||
|
...(pniKeyPair
|
||||||
|
? {
|
||||||
|
[ourPni]: {
|
||||||
|
pubKey: Bytes.toBase64(pniKeyPair.pubKey),
|
||||||
|
privKey: Bytes.toBase64(pniKeyPair.privKey),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
: {}),
|
||||||
};
|
};
|
||||||
const registrationIdMap = {
|
const registrationIdMap = {
|
||||||
...(storage.get('registrationIdMap') || {}),
|
...(storage.get('registrationIdMap') || {}),
|
||||||
[ourUuid]: registrationId,
|
[ourUuid]: registrationId,
|
||||||
|
// TODO: DESKTOP-2825
|
||||||
|
[ourPni]: registrationId,
|
||||||
};
|
};
|
||||||
|
|
||||||
await storage.put('identityKeyMap', identityKeyMap);
|
await storage.put('identityKeyMap', identityKeyMap);
|
||||||
|
@ -633,7 +660,7 @@ export default class AccountManager extends EventTarget {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Takes the same object returned by generateKeys
|
// Takes the same object returned by generateKeys
|
||||||
async confirmKeys(keys: GeneratedKeysType) {
|
async confirmKeys(keys: GeneratedKeysType, uuidKind: UUIDKind) {
|
||||||
const store = window.textsecure.storage.protocol;
|
const store = window.textsecure.storage.protocol;
|
||||||
const key = keys.signedPreKey;
|
const key = keys.signedPreKey;
|
||||||
const confirmed = true;
|
const confirmed = true;
|
||||||
|
@ -642,8 +669,11 @@ export default class AccountManager extends EventTarget {
|
||||||
throw new Error('confirmKeys: signedPreKey is null');
|
throw new Error('confirmKeys: signedPreKey is null');
|
||||||
}
|
}
|
||||||
|
|
||||||
log.info('confirmKeys: confirming key', key.keyId);
|
log.info(
|
||||||
const ourUuid = window.textsecure.storage.user.getCheckedUuid();
|
`AccountManager.confirmKeys(${uuidKind}): confirming key`,
|
||||||
|
key.keyId
|
||||||
|
);
|
||||||
|
const ourUuid = window.textsecure.storage.user.getCheckedUuid(uuidKind);
|
||||||
await store.storeSignedPreKey(ourUuid, key.keyId, key.keyPair, confirmed);
|
await store.storeSignedPreKey(ourUuid, key.keyId, key.keyPair, confirmed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2036,7 +2036,7 @@ export default class MessageSender {
|
||||||
// Simple pass-throughs
|
// Simple pass-throughs
|
||||||
|
|
||||||
async getProfile(
|
async getProfile(
|
||||||
number: string,
|
uuid: UUID,
|
||||||
options: Readonly<{
|
options: Readonly<{
|
||||||
accessKey?: string;
|
accessKey?: string;
|
||||||
profileKeyVersion: string;
|
profileKeyVersion: string;
|
||||||
|
@ -2051,10 +2051,10 @@ export default class MessageSender {
|
||||||
...options,
|
...options,
|
||||||
accessKey,
|
accessKey,
|
||||||
};
|
};
|
||||||
return this.server.getProfileUnauth(number, unauthOptions);
|
return this.server.getProfileUnauth(uuid.toString(), unauthOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.server.getProfile(number, options);
|
return this.server.getProfile(uuid.toString(), options);
|
||||||
}
|
}
|
||||||
|
|
||||||
async checkAccountExistence(uuid: UUID): Promise<boolean> {
|
async checkAccountExistence(uuid: UUID): Promise<boolean> {
|
||||||
|
|
|
@ -765,7 +765,7 @@ export type WebAPIType = {
|
||||||
newPassword: string,
|
newPassword: string,
|
||||||
registrationId: number,
|
registrationId: number,
|
||||||
deviceName?: string | null,
|
deviceName?: string | null,
|
||||||
options?: { accessKey?: Uint8Array; uuid?: UUIDStringType }
|
options?: { accessKey?: Uint8Array }
|
||||||
) => Promise<ConfirmCodeResultType>;
|
) => Promise<ConfirmCodeResultType>;
|
||||||
createGroup: (
|
createGroup: (
|
||||||
group: Proto.IGroup,
|
group: Proto.IGroup,
|
||||||
|
@ -1634,7 +1634,7 @@ export function initialize({
|
||||||
newPassword: string,
|
newPassword: string,
|
||||||
registrationId: number,
|
registrationId: number,
|
||||||
deviceName?: string | null,
|
deviceName?: string | null,
|
||||||
options: { accessKey?: Uint8Array; uuid?: UUIDStringType } = {}
|
options: { accessKey?: Uint8Array } = {}
|
||||||
) {
|
) {
|
||||||
const capabilities: CapabilitiesUploadType = {
|
const capabilities: CapabilitiesUploadType = {
|
||||||
announcementGroup: true,
|
announcementGroup: true,
|
||||||
|
@ -1644,7 +1644,7 @@ export function initialize({
|
||||||
changeNumber: true,
|
changeNumber: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
const { accessKey, uuid } = options;
|
const { accessKey } = options;
|
||||||
const jsonData = {
|
const jsonData = {
|
||||||
capabilities,
|
capabilities,
|
||||||
fetchesMessages: true,
|
fetchesMessages: true,
|
||||||
|
@ -1678,7 +1678,7 @@ export function initialize({
|
||||||
})) as ConfirmCodeResultType;
|
})) as ConfirmCodeResultType;
|
||||||
|
|
||||||
// Set final REST credentials to let `registerKeys` succeed.
|
// Set final REST credentials to let `registerKeys` succeed.
|
||||||
username = `${uuid || response.uuid || number}.${response.deviceId || 1}`;
|
username = `${response.uuid || number}.${response.deviceId || 1}`;
|
||||||
password = newPassword;
|
password = newPassword;
|
||||||
|
|
||||||
return response;
|
return response;
|
||||||
|
|
|
@ -5,7 +5,6 @@ import type { ProfileKeyCredentialRequestContext } from '@signalapp/signal-clien
|
||||||
import { SEALED_SENDER } from '../types/SealedSender';
|
import { SEALED_SENDER } from '../types/SealedSender';
|
||||||
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 * as Bytes from '../Bytes';
|
import * as Bytes from '../Bytes';
|
||||||
import { trimForDisplay, verifyAccessKey, decryptProfile } from '../Crypto';
|
import { trimForDisplay, verifyAccessKey, decryptProfile } from '../Crypto';
|
||||||
import {
|
import {
|
||||||
|
@ -62,13 +61,11 @@ export async function getProfile(
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const profileKey = c.get('profileKey');
|
const profileKey = c.get('profileKey');
|
||||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
const uuid = c.getCheckedUuid('getProfile');
|
||||||
const uuid = c.get('uuid')!;
|
const profileKeyVersionHex = c.get('profileKeyVersion');
|
||||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
if (!profileKeyVersionHex) {
|
||||||
const identifier = c.getSendTarget()!;
|
throw new Error('No profile key version available');
|
||||||
const targetUuid = UUID.checkedLookup(identifier);
|
}
|
||||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
||||||
const profileKeyVersionHex = c.get('profileKeyVersion')!;
|
|
||||||
const existingProfileKeyCredential = c.get('profileKeyCredential');
|
const existingProfileKeyCredential = c.get('profileKeyCredential');
|
||||||
|
|
||||||
let profileKeyCredentialRequestHex: undefined | string;
|
let profileKeyCredentialRequestHex: undefined | string;
|
||||||
|
@ -76,31 +73,24 @@ export async function getProfile(
|
||||||
| undefined
|
| undefined
|
||||||
| ProfileKeyCredentialRequestContext;
|
| ProfileKeyCredentialRequestContext;
|
||||||
|
|
||||||
if (
|
if (profileKey && profileKeyVersionHex && !existingProfileKeyCredential) {
|
||||||
profileKey &&
|
|
||||||
uuid &&
|
|
||||||
profileKeyVersionHex &&
|
|
||||||
!existingProfileKeyCredential
|
|
||||||
) {
|
|
||||||
log.info('Generating request...');
|
log.info('Generating request...');
|
||||||
({
|
({
|
||||||
requestHex: profileKeyCredentialRequestHex,
|
requestHex: profileKeyCredentialRequestHex,
|
||||||
context: profileCredentialRequestContext,
|
context: profileCredentialRequestContext,
|
||||||
} = generateProfileKeyCredentialRequest(
|
} = generateProfileKeyCredentialRequest(
|
||||||
clientZkProfileCipher,
|
clientZkProfileCipher,
|
||||||
uuid,
|
uuid.toString(),
|
||||||
profileKey
|
profileKey
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
const { sendMetadata = {} } = await getSendOptions(c.attributes);
|
const { sendMetadata = {} } = await getSendOptions(c.attributes);
|
||||||
const getInfo =
|
const getInfo = sendMetadata[uuid.toString()] || {};
|
||||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
||||||
sendMetadata[c.get('uuid')!] || sendMetadata[c.get('e164')!] || {};
|
|
||||||
|
|
||||||
if (getInfo.accessKey) {
|
if (getInfo.accessKey) {
|
||||||
try {
|
try {
|
||||||
profile = await window.textsecure.messaging.getProfile(identifier, {
|
profile = await window.textsecure.messaging.getProfile(uuid, {
|
||||||
accessKey: getInfo.accessKey,
|
accessKey: getInfo.accessKey,
|
||||||
profileKeyVersion: profileKeyVersionHex,
|
profileKeyVersion: profileKeyVersionHex,
|
||||||
profileKeyCredentialRequest: profileKeyCredentialRequestHex,
|
profileKeyCredentialRequest: profileKeyCredentialRequestHex,
|
||||||
|
@ -112,7 +102,7 @@ export async function getProfile(
|
||||||
`Setting sealedSender to DISABLED for conversation ${c.idForLogging()}`
|
`Setting sealedSender to DISABLED for conversation ${c.idForLogging()}`
|
||||||
);
|
);
|
||||||
c.set({ sealedSender: SEALED_SENDER.DISABLED });
|
c.set({ sealedSender: SEALED_SENDER.DISABLED });
|
||||||
profile = await window.textsecure.messaging.getProfile(identifier, {
|
profile = await window.textsecure.messaging.getProfile(uuid, {
|
||||||
profileKeyVersion: profileKeyVersionHex,
|
profileKeyVersion: profileKeyVersionHex,
|
||||||
profileKeyCredentialRequest: profileKeyCredentialRequestHex,
|
profileKeyCredentialRequest: profileKeyCredentialRequestHex,
|
||||||
userLanguages,
|
userLanguages,
|
||||||
|
@ -122,7 +112,7 @@ export async function getProfile(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
profile = await window.textsecure.messaging.getProfile(identifier, {
|
profile = await window.textsecure.messaging.getProfile(uuid, {
|
||||||
profileKeyVersion: profileKeyVersionHex,
|
profileKeyVersion: profileKeyVersionHex,
|
||||||
profileKeyCredentialRequest: profileKeyCredentialRequestHex,
|
profileKeyCredentialRequest: profileKeyCredentialRequestHex,
|
||||||
userLanguages,
|
userLanguages,
|
||||||
|
@ -132,7 +122,7 @@ export async function getProfile(
|
||||||
if (profile.identityKey) {
|
if (profile.identityKey) {
|
||||||
const identityKey = Bytes.fromBase64(profile.identityKey);
|
const identityKey = Bytes.fromBase64(profile.identityKey);
|
||||||
const changed = await window.textsecure.storage.protocol.saveIdentity(
|
const changed = await window.textsecure.storage.protocol.saveIdentity(
|
||||||
new Address(targetUuid, 1),
|
new Address(uuid, 1),
|
||||||
identityKey,
|
identityKey,
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
|
@ -141,7 +131,7 @@ export async function getProfile(
|
||||||
// must close that one manually.
|
// must close that one manually.
|
||||||
const ourUuid = window.textsecure.storage.user.getCheckedUuid();
|
const ourUuid = window.textsecure.storage.user.getCheckedUuid();
|
||||||
await window.textsecure.storage.protocol.archiveSession(
|
await window.textsecure.storage.protocol.archiveSession(
|
||||||
new QualifiedAddress(ourUuid, new Address(targetUuid, 1))
|
new QualifiedAddress(ourUuid, new Address(uuid, 1))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue