Merge pull request #3075 from yougotwill/fix/ses-1734/link_device_fails

fix: recover an account with a new display name if linking fails
pull/3076/head
Audric Ackermann 1 month ago committed by GitHub
commit 99562a5073
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -578,5 +578,6 @@
"resolution": "Resolution", "resolution": "Resolution",
"duration": "Duration", "duration": "Duration",
"notApplicable": "N/A", "notApplicable": "N/A",
"unknownError": "Unknown Error" "unknownError": "Unknown Error",
"displayNameErrorNew": "We were unable to load your display name. Please enter a new display name to continue."
} }

@ -1,12 +1,11 @@
import React, { createContext, useEffect, useState } from 'react'; import React, { createContext, useEffect, useState } from 'react';
import { SignUpMode, SignUpTab } from './SignUpTab';
import { SignInMode, SignInTab } from './SignInTab';
import { Data } from '../../data/data'; import { Data } from '../../data/data';
import { SettingsKey } from '../../data/settings-key';
import { getSwarmPollingInstance } from '../../session/apis/snode_api'; import { getSwarmPollingInstance } from '../../session/apis/snode_api';
import { getConversationController } from '../../session/conversations'; import { getConversationController } from '../../session/conversations';
import { mnDecode } from '../../session/crypto/mnemonic'; import { mnDecode } from '../../session/crypto/mnemonic';
import { PromiseUtils, StringUtils, ToastUtils } from '../../session/utils'; import { PromiseUtils, StringUtils, ToastUtils } from '../../session/utils';
import { TaskTimedOutError } from '../../session/utils/Promise'; import { fromHex } from '../../session/utils/String';
import { trigger } from '../../shims/events'; import { trigger } from '../../shims/events';
import { import {
generateMnemonic, generateMnemonic,
@ -14,9 +13,9 @@ import {
sessionGenerateKeyPair, sessionGenerateKeyPair,
signInByLinkingDevice, signInByLinkingDevice,
} from '../../util/accountManager'; } from '../../util/accountManager';
import { fromHex } from '../../session/utils/String'; import { Storage, setSignInByLinking, setSignWithRecoveryPhrase } from '../../util/storage';
import { setSignInByLinking, setSignWithRecoveryPhrase, Storage } from '../../util/storage'; import { SignInMode, SignInTab } from './SignInTab';
import { SettingsKey } from '../../data/settings-key'; import { SignUpMode, SignUpTab } from './SignUpTab';
export async function resetRegistration() { export async function resetRegistration() {
await Data.removeAll(); await Data.removeAll();
@ -104,7 +103,10 @@ export async function signInWithRecovery(signInDetails: {
* This is will try to sign in with the user recovery phrase. * This is will try to sign in with the user recovery phrase.
* If no ConfigurationMessage is received in 60seconds, the loading will be canceled. * If no ConfigurationMessage is received in 60seconds, the loading will be canceled.
*/ */
export async function signInWithLinking(signInDetails: { userRecoveryPhrase: string }) { export async function signInWithLinking(
signInDetails: { userRecoveryPhrase: string },
setSignInMode: (phase: SignInMode) => void
) {
const { userRecoveryPhrase } = signInDetails; const { userRecoveryPhrase } = signInDetails;
window?.log?.info('LINKING DEVICE'); window?.log?.info('LINKING DEVICE');
@ -136,18 +138,14 @@ export async function signInWithLinking(signInDetails: { userRecoveryPhrase: str
trigger('openInbox'); trigger('openInbox');
} catch (e) { } catch (e) {
await resetRegistration(); await resetRegistration();
if (e instanceof TaskTimedOutError) { ToastUtils.pushToastError('registrationError', window.i18n('displayNameErrorNew'));
ToastUtils.pushToastError( window?.log?.error(
'registrationError', '[signInWithLinking] Error during sign in by linking lets try and sign in by recovery phrase',
'Could not find your display name. Please Sign In by Restoring Your Account instead.' e.message || e
); );
} else { getSwarmPollingInstance().stop(e);
ToastUtils.pushToastError( await setSignWithRecoveryPhrase(false);
'registrationError', setSignInMode(SignInMode.UsingRecoveryPhrase);
`Error: ${e.message || 'Something went wrong'}`
);
}
window?.log?.warn('exception during registration:', e);
} }
} }

@ -123,7 +123,7 @@ export const SignInTab = () => {
// from the configuration message will be used. // from the configuration message will be used.
const showDisplayNameField = isRecovery; const showDisplayNameField = isRecovery;
// Display name is required only on isRecoveryMode // Display name is required only on isRecoveryMode or if linking a device fails
const displayNameOK = (isRecovery && !displayNameError && !!displayName) || isLinking; const displayNameOK = (isRecovery && !displayNameError && !!displayName) || isLinking;
// Seed is mandatory no matter which mode // Seed is mandatory no matter which mode
@ -139,9 +139,12 @@ export const SignInTab = () => {
}); });
} else if (isLinking) { } else if (isLinking) {
setIsLoading(true); setIsLoading(true);
await signInWithLinking({ await signInWithLinking(
userRecoveryPhrase: recoveryPhrase, {
}); userRecoveryPhrase: recoveryPhrase,
},
setSignInMode
);
setIsLoading(false); setIsLoading(false);
} }
}; };

@ -57,6 +57,8 @@ export function extractWebSocketContent(
} }
let instance: SwarmPolling | undefined; let instance: SwarmPolling | undefined;
const timeouts: Array<NodeJS.Timeout> = [];
export const getSwarmPollingInstance = () => { export const getSwarmPollingInstance = () => {
if (!instance) { if (!instance) {
instance = new SwarmPolling(); instance = new SwarmPolling();
@ -84,9 +86,11 @@ export class SwarmPolling {
if (waitForFirstPoll) { if (waitForFirstPoll) {
await this.pollForAllKeys(); await this.pollForAllKeys();
} else { } else {
setTimeout(() => { timeouts.push(
void this.pollForAllKeys(); setTimeout(() => {
}, 4000); void this.pollForAllKeys();
}, 4000)
);
} }
} }
@ -98,6 +102,17 @@ export class SwarmPolling {
this.hasStarted = false; this.hasStarted = false;
} }
// TODO[epic=ses-50] this is a temporary solution until onboarding is merged
public stop(e: Error) {
window.log.error(`[swarmPolling] stopped polling due to error: ${e.message || e}`);
for (let i = 0; i < timeouts.length; i++) {
clearTimeout(timeouts[i]);
window.log.debug(`[swarmPolling] cleared timeout ${timeouts[i]} `);
}
this.resetSwarmPolling();
}
public forcePolledTimestamp(pubkey: PubKey, lastPoll: number) { public forcePolledTimestamp(pubkey: PubKey, lastPoll: number) {
this.groupPolling = this.groupPolling.map(group => { this.groupPolling = this.groupPolling.map(group => {
if (PubKey.isEqual(pubkey, group.pubkey)) { if (PubKey.isEqual(pubkey, group.pubkey)) {
@ -163,7 +178,7 @@ export class SwarmPolling {
if (!window.getGlobalOnlineStatus()) { if (!window.getGlobalOnlineStatus()) {
window?.log?.error('pollForAllKeys: offline'); window?.log?.error('pollForAllKeys: offline');
// Very important to set up a new polling call so we do retry at some point // Very important to set up a new polling call so we do retry at some point
setTimeout(this.pollForAllKeys.bind(this), SWARM_POLLING_TIMEOUT.ACTIVE); timeouts.push(setTimeout(this.pollForAllKeys.bind(this), SWARM_POLLING_TIMEOUT.ACTIVE));
return; return;
} }
// we always poll as often as possible for our pubkey // we always poll as often as possible for our pubkey
@ -200,7 +215,7 @@ export class SwarmPolling {
window?.log?.warn('pollForAllKeys exception: ', e); window?.log?.warn('pollForAllKeys exception: ', e);
throw e; throw e;
} finally { } finally {
setTimeout(this.pollForAllKeys.bind(this), SWARM_POLLING_TIMEOUT.ACTIVE); timeouts.push(setTimeout(this.pollForAllKeys.bind(this), SWARM_POLLING_TIMEOUT.ACTIVE));
} }
} }

@ -162,6 +162,7 @@ export type LocalizerKeys =
| 'disappears' | 'disappears'
| 'displayName' | 'displayName'
| 'displayNameEmpty' | 'displayNameEmpty'
| 'displayNameErrorNew'
| 'displayNameTooLong' | 'displayNameTooLong'
| 'document' | 'document'
| 'documents' | 'documents'

Loading…
Cancel
Save