update our profile on incoming configMessage sent after our last update
This commit is contained in:
parent
e6cf28cb2a
commit
305ece1c7c
|
@ -24,16 +24,16 @@
|
|||
return textsecure.utils.unencodeNumber(numberId)[0];
|
||||
},
|
||||
|
||||
isRestoringFromSeed() {
|
||||
const isRestoring = textsecure.storage.get('is_restoring_from_seed');
|
||||
if (isRestoring === undefined) {
|
||||
isSignInByLinking() {
|
||||
const isSignInByLinking = textsecure.storage.get('is_sign_in_by_linking');
|
||||
if (isSignInByLinking === undefined) {
|
||||
return false;
|
||||
}
|
||||
return isRestoring;
|
||||
return isSignInByLinking;
|
||||
},
|
||||
|
||||
setRestoringFromSeed(isRestoringFromSeed) {
|
||||
textsecure.storage.put('is_restoring_from_seed', isRestoringFromSeed);
|
||||
setSignInByLinking(isLinking) {
|
||||
textsecure.storage.put('is_sign_in_by_linking', isLinking);
|
||||
},
|
||||
|
||||
getLastProfileUpdateTimestamp() {
|
||||
|
|
|
@ -63,6 +63,47 @@ export async function resetRegistration() {
|
|||
await ConversationController.getInstance().load();
|
||||
}
|
||||
|
||||
const passwordsAreValid = (password: string, verifyPassword: string) => {
|
||||
const passwordErrors = validatePassword(password, verifyPassword);
|
||||
if (passwordErrors.passwordErrorString) {
|
||||
window.log.warn('invalid password for registration');
|
||||
ToastUtils.pushToastError(
|
||||
'invalidPassword',
|
||||
window.i18n('invalidPassword')
|
||||
);
|
||||
return false;
|
||||
}
|
||||
if (!!password && !passwordErrors.passwordFieldsMatch) {
|
||||
window.log.warn('passwords does not match for registration');
|
||||
ToastUtils.pushToastError(
|
||||
'invalidPassword',
|
||||
window.i18n('passwordsDoNotMatch')
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns undefined if an error happened, or the trim userName.
|
||||
*
|
||||
* Be sure to use the trimmed userName for creating the account.
|
||||
*/
|
||||
const displayNameIsValid = (displayName: string): undefined | string => {
|
||||
const trimName = displayName.trim();
|
||||
|
||||
if (!trimName) {
|
||||
window.log.warn('invalid trimmed name for registration');
|
||||
ToastUtils.pushToastError(
|
||||
'invalidDisplayName',
|
||||
window.i18n('displayNameEmpty')
|
||||
);
|
||||
return undefined;
|
||||
}
|
||||
return trimName;
|
||||
};
|
||||
|
||||
export async function signUp(signUpDetails: {
|
||||
displayName: string;
|
||||
generatedRecoveryPhrase: string;
|
||||
|
@ -76,38 +117,21 @@ export async function signUp(signUpDetails: {
|
|||
generatedRecoveryPhrase,
|
||||
} = signUpDetails;
|
||||
window.log.info('SIGNING UP');
|
||||
const trimName = displayName.trim();
|
||||
|
||||
const trimName = displayNameIsValid(displayName);
|
||||
// shows toast to user about the error
|
||||
if (!trimName) {
|
||||
window.log.warn('invalid trimmed name for registration');
|
||||
ToastUtils.pushToastError(
|
||||
'invalidDisplayName',
|
||||
window.i18n('displayNameEmpty')
|
||||
);
|
||||
return;
|
||||
}
|
||||
const passwordErrors = validatePassword(password, verifyPassword);
|
||||
if (passwordErrors.passwordErrorString) {
|
||||
window.log.warn('invalid password for registration');
|
||||
ToastUtils.pushToastError(
|
||||
'invalidPassword',
|
||||
window.i18n('invalidPassword')
|
||||
);
|
||||
return;
|
||||
}
|
||||
if (!!password && !passwordErrors.passwordFieldsMatch) {
|
||||
window.log.warn('passwords does not match for registration');
|
||||
ToastUtils.pushToastError(
|
||||
'invalidPassword',
|
||||
window.i18n('passwordsDoNotMatch')
|
||||
);
|
||||
|
||||
// This will show a toast with the error
|
||||
if (!passwordsAreValid(password, verifyPassword)) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
await resetRegistration();
|
||||
await window.setPassword(password);
|
||||
UserUtils.setRestoringFromSeed(false);
|
||||
await AccountManager.registerSingleDevice(
|
||||
generatedRecoveryPhrase,
|
||||
'english',
|
||||
|
@ -142,44 +166,26 @@ export async function signInWithRecovery(signInDetails: {
|
|||
userRecoveryPhrase,
|
||||
} = signInDetails;
|
||||
window.log.info('RESTORING FROM SEED');
|
||||
const trimName = displayName.trim();
|
||||
|
||||
const trimName = displayNameIsValid(displayName);
|
||||
// shows toast to user about the error
|
||||
if (!trimName) {
|
||||
window.log.warn('invalid trimmed name for registration');
|
||||
ToastUtils.pushToastError(
|
||||
'invalidDisplayName',
|
||||
window.i18n('displayNameEmpty')
|
||||
);
|
||||
return;
|
||||
}
|
||||
const passwordErrors = validatePassword(password, verifyPassword);
|
||||
if (passwordErrors.passwordErrorString) {
|
||||
window.log.warn('invalid password for registration');
|
||||
ToastUtils.pushToastError(
|
||||
'invalidPassword',
|
||||
window.i18n('invalidPassword')
|
||||
);
|
||||
return;
|
||||
}
|
||||
if (!!password && !passwordErrors.passwordFieldsMatch) {
|
||||
window.log.warn('passwords does not match for registration');
|
||||
ToastUtils.pushToastError(
|
||||
'invalidPassword',
|
||||
window.i18n('passwordsDoNotMatch')
|
||||
);
|
||||
// This will show a toast with the error
|
||||
if (!passwordsAreValid(password, verifyPassword)) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
await resetRegistration();
|
||||
await window.setPassword(password);
|
||||
UserUtils.setRestoringFromSeed(false);
|
||||
await UserUtils.setLastProfileUpdateTimestamp(Date.now());
|
||||
|
||||
await AccountManager.registerSingleDevice(
|
||||
userRecoveryPhrase,
|
||||
'english',
|
||||
trimName
|
||||
);
|
||||
await UserUtils.setLastProfileUpdateTimestamp(Date.now());
|
||||
trigger('openInbox');
|
||||
} catch (e) {
|
||||
ToastUtils.pushToastError(
|
||||
|
@ -190,6 +196,32 @@ export async function signInWithRecovery(signInDetails: {
|
|||
}
|
||||
}
|
||||
|
||||
export async function signInWithLinking(signInDetails: {
|
||||
userRecoveryPhrase: string;
|
||||
password: string;
|
||||
verifyPassword: string;
|
||||
}) {
|
||||
const { password, verifyPassword, userRecoveryPhrase } = signInDetails;
|
||||
window.log.info('LINKING DEVICE');
|
||||
// This will show a toast with the error
|
||||
if (!passwordsAreValid(password, verifyPassword)) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
await resetRegistration();
|
||||
await window.setPassword(password);
|
||||
await AccountManager.signInByLinkingDevice(userRecoveryPhrase, 'english');
|
||||
// Do not set the lastProfileUpdateTimestamp.
|
||||
// We expect to get a display name from a configuration message while we are loading messages of this user
|
||||
trigger('openInbox');
|
||||
} catch (e) {
|
||||
ToastUtils.pushToastError(
|
||||
'registrationError',
|
||||
`Error: ${e.message || 'Something went wrong'}`
|
||||
);
|
||||
window.log.warn('exception during registration:', e);
|
||||
}
|
||||
}
|
||||
export class RegistrationTabs extends React.Component<any, State> {
|
||||
constructor() {
|
||||
super({});
|
||||
|
|
|
@ -195,8 +195,12 @@ export const SignInTab = (props: Props) => {
|
|||
password,
|
||||
verifyPassword: passwordVerify,
|
||||
});
|
||||
} else {
|
||||
throw new Error('TODO');
|
||||
} else if (isLinking) {
|
||||
await signInWithLinking({
|
||||
userRecoveryPhrase: recoveryPhrase,
|
||||
password,
|
||||
verifyPassword: passwordVerify,
|
||||
});
|
||||
}
|
||||
}}
|
||||
disabled={!activateContinueButton}
|
||||
|
|
|
@ -1131,7 +1131,10 @@ export class ConversationModel extends Backbone.Model<ConversationAttributes> {
|
|||
|
||||
await this.updateProfileName();
|
||||
}
|
||||
public async setLokiProfile(newProfile: any) {
|
||||
public async setLokiProfile(newProfile: {
|
||||
displayName?: string | null;
|
||||
avatar?: string;
|
||||
}) {
|
||||
if (!_.isEqual(this.get('profile'), newProfile)) {
|
||||
this.set({ profile: newProfile });
|
||||
await this.commit();
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { EnvelopePlus } from './types';
|
||||
import { handleDataMessage } from './dataMessage';
|
||||
import { handleDataMessage, updateProfile } from './dataMessage';
|
||||
|
||||
import { removeFromCache, updateCache } from './cache';
|
||||
import { SignalService } from '../protobuf';
|
||||
|
@ -20,6 +20,7 @@ import { ECKeyPair } from './keypairs';
|
|||
import { handleNewClosedGroup } from './closedGroups';
|
||||
import { KeyPairRequestManager } from './keyPairRequestManager';
|
||||
import { requestEncryptionKeyPair } from '../session/group';
|
||||
import { ConfigurationMessage } from '../session/messages/outgoing/content/ConfigurationMessage';
|
||||
|
||||
export async function handleContentMessage(envelope: EnvelopePlus) {
|
||||
try {
|
||||
|
@ -390,7 +391,7 @@ export async function innerHandleContentMessage(
|
|||
'private'
|
||||
);
|
||||
|
||||
if (content.dataMessage && !UserUtils.isRestoringFromSeed()) {
|
||||
if (content.dataMessage && !UserUtils.isSignInByLinking()) {
|
||||
if (
|
||||
content.dataMessage.profileKey &&
|
||||
content.dataMessage.profileKey.length === 0
|
||||
|
@ -401,16 +402,16 @@ export async function innerHandleContentMessage(
|
|||
return;
|
||||
}
|
||||
|
||||
if (content.receiptMessage && !UserUtils.isRestoringFromSeed()) {
|
||||
if (content.receiptMessage && !UserUtils.isSignInByLinking()) {
|
||||
await handleReceiptMessage(envelope, content.receiptMessage);
|
||||
return;
|
||||
}
|
||||
if (content.typingMessage && !UserUtils.isRestoringFromSeed()) {
|
||||
if (content.typingMessage && !UserUtils.isSignInByLinking()) {
|
||||
await handleTypingMessage(envelope, content.typingMessage);
|
||||
return;
|
||||
}
|
||||
|
||||
// Be sure to check for the UserUtils.isRestoringFromSeed() if you add another if here
|
||||
// Be sure to check for the UserUtils.isSignInByLinking() if you add another if here
|
||||
if (content.configurationMessage) {
|
||||
await handleConfigurationMessage(
|
||||
envelope,
|
||||
|
@ -418,7 +419,7 @@ export async function innerHandleContentMessage(
|
|||
);
|
||||
return;
|
||||
}
|
||||
// Be sure to check for the UserUtils.isRestoringFromSeed() if you add another if here
|
||||
// Be sure to check for the UserUtils.isSignInByLinking() if you add another if here
|
||||
} catch (e) {
|
||||
window.log.warn(e);
|
||||
}
|
||||
|
@ -529,22 +530,41 @@ async function handleTypingMessage(
|
|||
}
|
||||
}
|
||||
|
||||
export async function handleConfigurationMessage(
|
||||
envelope: EnvelopePlus,
|
||||
configurationMessage: SignalService.ConfigurationMessage
|
||||
): Promise<void> {
|
||||
const ourPubkey = UserUtils.getOurPubKeyStrFromCache();
|
||||
if (!ourPubkey) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (envelope.source !== ourPubkey) {
|
||||
async function handleOurProfileUpdate(
|
||||
sentAt: number | Long,
|
||||
configMessage: SignalService.ConfigurationMessage,
|
||||
ourPubkey: string
|
||||
) {
|
||||
const latestProfileUpdateTimestamp = UserUtils.getLastProfileUpdateTimestamp();
|
||||
if (latestProfileUpdateTimestamp && sentAt > latestProfileUpdateTimestamp) {
|
||||
window?.log?.info(
|
||||
'Dropping configuration change from someone else than us.'
|
||||
`Handling our profileUdpate ourLastUpdate:${latestProfileUpdateTimestamp}, envelope sent at: ${sentAt}`
|
||||
);
|
||||
return removeFromCache(envelope);
|
||||
}
|
||||
const { profileKey, profilePicture, displayName } = configMessage;
|
||||
|
||||
const ourConversation = ConversationController.getInstance().get(ourPubkey);
|
||||
if (!ourConversation) {
|
||||
window.log.error('We need a convo with ourself at all times');
|
||||
return;
|
||||
}
|
||||
|
||||
if (profileKey?.length) {
|
||||
window.log.info('Saving our profileKey from configuration message');
|
||||
// TODO not sure why we keep our profileKey in storage AND in our conversaio
|
||||
window.textsecure.storage.put('profileKey', profileKey);
|
||||
}
|
||||
const lokiProfile = {
|
||||
displayName,
|
||||
profilePicture,
|
||||
};
|
||||
await updateProfile(ourConversation, lokiProfile, profileKey);
|
||||
}
|
||||
}
|
||||
|
||||
async function handleGroupsAndContactsFromConfigMessage(
|
||||
envelope: EnvelopePlus,
|
||||
configMessage: SignalService.ConfigurationMessage
|
||||
) {
|
||||
const ITEM_ID_PROCESSED_CONFIGURATION_MESSAGE =
|
||||
'ITEM_ID_PROCESSED_CONFIGURATION_MESSAGE';
|
||||
const didWeHandleAConfigurationMessageAlready =
|
||||
|
@ -554,22 +574,23 @@ export async function handleConfigurationMessage(
|
|||
window?.log?.warn(
|
||||
'Dropping configuration change as we already handled one... '
|
||||
);
|
||||
await removeFromCache(envelope);
|
||||
return;
|
||||
}
|
||||
await createOrUpdateItem({
|
||||
id: ITEM_ID_PROCESSED_CONFIGURATION_MESSAGE,
|
||||
value: true,
|
||||
});
|
||||
if (didWeHandleAConfigurationMessageAlready) {
|
||||
window?.log?.warn(
|
||||
'Dropping configuration change as we already handled one... '
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
const numberClosedGroup = configurationMessage.closedGroups?.length || 0;
|
||||
const numberClosedGroup = configMessage.closedGroups?.length || 0;
|
||||
|
||||
window?.log?.warn(
|
||||
`Received ${numberClosedGroup} closed group on configuration. Creating them... `
|
||||
);
|
||||
|
||||
await Promise.all(
|
||||
configurationMessage.closedGroups.map(async c => {
|
||||
configMessage.closedGroups.map(async c => {
|
||||
const groupUpdate = new SignalService.DataMessage.ClosedGroupControlMessage(
|
||||
{
|
||||
type: SignalService.DataMessage.ClosedGroupControlMessage.Type.NEW,
|
||||
|
@ -591,12 +612,12 @@ export async function handleConfigurationMessage(
|
|||
);
|
||||
|
||||
const allOpenGroups = OpenGroup.getAllAlreadyJoinedOpenGroupsUrl();
|
||||
const numberOpenGroup = configurationMessage.openGroups?.length || 0;
|
||||
const numberOpenGroup = configMessage.openGroups?.length || 0;
|
||||
|
||||
// Trigger a join for all open groups we are not already in.
|
||||
// Currently, if you left an open group but kept the conversation, you won't rejoin it here.
|
||||
for (let i = 0; i < numberOpenGroup; i++) {
|
||||
const current = configurationMessage.openGroups[i];
|
||||
const current = configMessage.openGroups[i];
|
||||
if (!allOpenGroups.includes(current)) {
|
||||
window?.log?.info(
|
||||
`triggering join of public chat '${current}' from ConfigurationMessage`
|
||||
|
@ -604,6 +625,33 @@ export async function handleConfigurationMessage(
|
|||
void OpenGroup.join(current);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export async function handleConfigurationMessage(
|
||||
envelope: EnvelopePlus,
|
||||
configurationMessage: SignalService.ConfigurationMessage
|
||||
): Promise<void> {
|
||||
const ourPubkey = UserUtils.getOurPubKeyStrFromCache();
|
||||
if (!ourPubkey) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (envelope.source !== ourPubkey) {
|
||||
window?.log?.info(
|
||||
'Dropping configuration change from someone else than us.'
|
||||
);
|
||||
return removeFromCache(envelope);
|
||||
}
|
||||
|
||||
await handleOurProfileUpdate(
|
||||
envelope.timestamp,
|
||||
configurationMessage,
|
||||
ourPubkey
|
||||
);
|
||||
await handleGroupsAndContactsFromConfigMessage(
|
||||
envelope,
|
||||
configurationMessage
|
||||
);
|
||||
|
||||
await removeFromCache(envelope);
|
||||
}
|
||||
|
|
|
@ -15,9 +15,10 @@ import { handleClosedGroupControlMessage } from './closedGroups';
|
|||
import { MessageModel } from '../models/message';
|
||||
import { MessageModelType } from '../models/messageType';
|
||||
import { getMessageBySender } from '../../ts/data/data';
|
||||
import { ConversationModel } from '../models/conversation';
|
||||
|
||||
export async function updateProfile(
|
||||
conversation: any,
|
||||
conversation: ConversationModel,
|
||||
profile: SignalService.DataMessage.ILokiProfile,
|
||||
profileKey: any
|
||||
) {
|
||||
|
|
|
@ -71,12 +71,12 @@ export async function getUserED25519KeyPair(): Promise<HexKeyPair | undefined> {
|
|||
return undefined;
|
||||
}
|
||||
|
||||
export function isRestoringFromSeed(): boolean {
|
||||
return window.textsecure.storage.user.isRestoringFromSeed();
|
||||
export function isSignInByLinking(): boolean {
|
||||
return window.textsecure.storage.user.isSignInByLinking();
|
||||
}
|
||||
|
||||
export function setRestoringFromSeed(isRestoring: boolean) {
|
||||
window.textsecure.storage.user.setRestoringFromSeed(isRestoring);
|
||||
export function setSignInByLinking(isLinking: boolean) {
|
||||
window.textsecure.storage.user.setSignInByLinking(isLinking);
|
||||
}
|
||||
|
||||
export interface OurLokiProfile {
|
||||
|
|
|
@ -8,6 +8,13 @@ import {
|
|||
} from '../session/utils/String';
|
||||
import { getOurPubKeyStrFromCache } from '../session/utils/User';
|
||||
import { trigger } from '../shims/events';
|
||||
import {
|
||||
removeAllContactPreKeys,
|
||||
removeAllContactSignedPreKeys,
|
||||
removeAllPreKeys,
|
||||
removeAllSessions,
|
||||
removeAllSignedPreKeys,
|
||||
} from '../data/data';
|
||||
|
||||
/**
|
||||
* Might throw
|
||||
|
@ -56,19 +63,68 @@ const generateKeypair = async (mnemonic: string, mnemonicLanguage: string) => {
|
|||
// TODO not sure why AccountManager was a singleton before. Can we get rid of it as a singleton?
|
||||
// tslint:disable-next-line: no-unnecessary-class
|
||||
export class AccountManager {
|
||||
public static async registerSingleDevice(
|
||||
/**
|
||||
* Sign in with a recovery phrase. We won't try to recover an existing profile name
|
||||
* @param mnemonic the mnemonic the user duly saved in a safe place. We will restore his sessionID based on this.
|
||||
* @param mnemonicLanguage 'english' only is supported
|
||||
* @param profileName the displayName to use for this user
|
||||
*/
|
||||
public static async signInWithRecovery(
|
||||
mnemonic: string,
|
||||
mnemonicLanguage: string,
|
||||
profileName: string
|
||||
) {
|
||||
const createAccount = this.createAccount.bind(this);
|
||||
const clearSessionsAndPreKeys = this.clearSessionsAndPreKeys.bind(this);
|
||||
const registrationDone = this.registrationDone.bind(this);
|
||||
return AccountManager.registerSingleDevice(
|
||||
mnemonic,
|
||||
mnemonicLanguage,
|
||||
profileName
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sign in with a recovery phrase but trying to recover display name and avatar from the first encountered configuration message.
|
||||
* @param mnemonic the mnemonic the user duly saved in a safe place. We will restore his sessionID based on this.
|
||||
* @param mnemonicLanguage 'english' only is supported
|
||||
*/
|
||||
public static async signInByLinkingDevice(
|
||||
mnemonic: string,
|
||||
mnemonicLanguage: string
|
||||
) {
|
||||
if (!mnemonic) {
|
||||
throw new Error(
|
||||
'Session always needs a mnemonic. Either generated or given by the user'
|
||||
);
|
||||
}
|
||||
if (!mnemonicLanguage) {
|
||||
throw new Error('We always needs a mnemonicLanguage');
|
||||
}
|
||||
|
||||
const identityKeyPair = await generateKeypair(mnemonic, mnemonicLanguage);
|
||||
UserUtils.setSignInByLinking(true);
|
||||
await AccountManager.createAccount(identityKeyPair);
|
||||
UserUtils.saveRecoveryPhrase(mnemonic);
|
||||
await AccountManager.clearSessionsAndPreKeys();
|
||||
const pubKeyString = toHex(identityKeyPair.pubKey);
|
||||
|
||||
// await for the first configuration message to come in.
|
||||
await AccountManager.registrationDone(pubKeyString, profileName);
|
||||
}
|
||||
/**
|
||||
* This is a signup. User has no recovery and does not try to link a device
|
||||
* @param mnemonic The mnemonic generated on first app loading and to use for this brand new user
|
||||
* @param mnemonicLanguage only 'english' is supported
|
||||
* @param profileName the display name to register toi
|
||||
*/
|
||||
public static async registerSingleDevice(
|
||||
generatedMnemonic: string,
|
||||
mnemonicLanguage: string,
|
||||
profileName: string
|
||||
) {
|
||||
if (!generatedMnemonic) {
|
||||
throw new Error(
|
||||
'Session always needs a mnemonic. Either generated or given by the user'
|
||||
);
|
||||
}
|
||||
if (!profileName) {
|
||||
throw new Error('We always needs a profileName');
|
||||
}
|
||||
|
@ -76,19 +132,22 @@ export class AccountManager {
|
|||
throw new Error('We always needs a mnemonicLanguage');
|
||||
}
|
||||
|
||||
const identityKeyPair = await generateKeypair(mnemonic, mnemonicLanguage);
|
||||
await createAccount(identityKeyPair);
|
||||
UserUtils.saveRecoveryPhrase(mnemonic);
|
||||
await clearSessionsAndPreKeys();
|
||||
const identityKeyPair = await generateKeypair(
|
||||
generatedMnemonic,
|
||||
mnemonicLanguage
|
||||
);
|
||||
await AccountManager.createAccount(identityKeyPair);
|
||||
UserUtils.saveRecoveryPhrase(generatedMnemonic);
|
||||
await AccountManager.clearSessionsAndPreKeys();
|
||||
const pubKeyString = toHex(identityKeyPair.pubKey);
|
||||
await registrationDone(pubKeyString, profileName);
|
||||
await AccountManager.registrationDone(pubKeyString, profileName);
|
||||
}
|
||||
|
||||
public static async generateMnemonic(language = 'english') {
|
||||
// Note: 4 bytes are converted into 3 seed words, so length 12 seed words
|
||||
// (13 - 1 checksum) are generated using 12 * 4 / 3 = 16 bytes.
|
||||
const seedSize = 16;
|
||||
const seed = window.Signal.Crypto.getRandomBytes(seedSize);
|
||||
const seed = (await getSodium()).randombytes_buf(seedSize);
|
||||
const hex = toHex(seed);
|
||||
return window.mnemonic.mn_encode(hex, language);
|
||||
}
|
||||
|
@ -98,11 +157,11 @@ export class AccountManager {
|
|||
// During secondary device registration we need to keep our prekeys sent
|
||||
// to other pubkeys
|
||||
await Promise.all([
|
||||
window.Signal.Data.removeAllPreKeys(),
|
||||
window.Signal.Data.removeAllSignedPreKeys(),
|
||||
window.Signal.Data.removeAllContactPreKeys(),
|
||||
window.Signal.Data.removeAllContactSignedPreKeys(),
|
||||
window.Signal.Data.removeAllSessions(),
|
||||
removeAllPreKeys(),
|
||||
removeAllSignedPreKeys(),
|
||||
removeAllContactPreKeys(),
|
||||
removeAllContactSignedPreKeys(),
|
||||
removeAllSessions(),
|
||||
]);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue