|  |  |  | @ -15,7 +15,7 @@ import { StringUtils, ToastUtils } from '../../session/utils'; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | enum SignInMode { | 
		
	
		
			
				|  |  |  |  |   Default, | 
		
	
		
			
				|  |  |  |  |   UsingSeed, | 
		
	
		
			
				|  |  |  |  |   UsingRecoveryPhrase, | 
		
	
		
			
				|  |  |  |  |   LinkingDevice, | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
	
		
			
				
					|  |  |  | @ -40,8 +40,8 @@ interface State { | 
		
	
		
			
				|  |  |  |  |   validatePassword: string; | 
		
	
		
			
				|  |  |  |  |   passwordErrorString: string; | 
		
	
		
			
				|  |  |  |  |   passwordFieldsMatch: boolean; | 
		
	
		
			
				|  |  |  |  |   mnemonicSeed: string; | 
		
	
		
			
				|  |  |  |  |   generatedMnemonicSeed: string; | 
		
	
		
			
				|  |  |  |  |   recoveryPhrase: string; | 
		
	
		
			
				|  |  |  |  |   generatedRecoveryPhrase: string; | 
		
	
		
			
				|  |  |  |  |   hexGeneratedPubKey: string; | 
		
	
		
			
				|  |  |  |  |   primaryDevicePubKey: string; | 
		
	
		
			
				|  |  |  |  |   mnemonicError: string | undefined; | 
		
	
	
		
			
				
					|  |  |  | @ -116,8 +116,8 @@ export class RegistrationTabs extends React.Component<{}, State> { | 
		
	
		
			
				|  |  |  |  |       validatePassword: '', | 
		
	
		
			
				|  |  |  |  |       passwordErrorString: '', | 
		
	
		
			
				|  |  |  |  |       passwordFieldsMatch: false, | 
		
	
		
			
				|  |  |  |  |       mnemonicSeed: '', | 
		
	
		
			
				|  |  |  |  |       generatedMnemonicSeed: '', | 
		
	
		
			
				|  |  |  |  |       recoveryPhrase: '', | 
		
	
		
			
				|  |  |  |  |       generatedRecoveryPhrase: '', | 
		
	
		
			
				|  |  |  |  |       hexGeneratedPubKey: '', | 
		
	
		
			
				|  |  |  |  |       primaryDevicePubKey: '', | 
		
	
		
			
				|  |  |  |  |       mnemonicError: undefined, | 
		
	
	
		
			
				
					|  |  |  | @ -165,7 +165,7 @@ export class RegistrationTabs extends React.Component<{}, State> { | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   private async generateMnemonicAndKeyPair() { | 
		
	
		
			
				|  |  |  |  |     if (this.state.generatedMnemonicSeed === '') { | 
		
	
		
			
				|  |  |  |  |     if (this.state.generatedRecoveryPhrase === '') { | 
		
	
		
			
				|  |  |  |  |       const language = 'english'; | 
		
	
		
			
				|  |  |  |  |       const mnemonic = await this.accountManager.generateMnemonic(language); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
	
		
			
				
					|  |  |  | @ -184,7 +184,7 @@ export class RegistrationTabs extends React.Component<{}, State> { | 
		
	
		
			
				|  |  |  |  |       const hexGeneratedPubKey = StringUtils.decode(keyPair.pubKey, 'hex'); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |       this.setState({ | 
		
	
		
			
				|  |  |  |  |         generatedMnemonicSeed: mnemonic, | 
		
	
		
			
				|  |  |  |  |         generatedRecoveryPhrase: mnemonic, | 
		
	
		
			
				|  |  |  |  |         hexGeneratedPubKey, // our 'frontend' sessionID
 | 
		
	
		
			
				|  |  |  |  |       }); | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
	
		
			
				
					|  |  |  | @ -203,7 +203,7 @@ export class RegistrationTabs extends React.Component<{}, State> { | 
		
	
		
			
				|  |  |  |  |       validatePassword: '', | 
		
	
		
			
				|  |  |  |  |       passwordErrorString: '', | 
		
	
		
			
				|  |  |  |  |       passwordFieldsMatch: false, | 
		
	
		
			
				|  |  |  |  |       mnemonicSeed: '', | 
		
	
		
			
				|  |  |  |  |       recoveryPhrase: '', | 
		
	
		
			
				|  |  |  |  |       primaryDevicePubKey: '', | 
		
	
		
			
				|  |  |  |  |       mnemonicError: undefined, | 
		
	
		
			
				|  |  |  |  |       displayNameError: undefined, | 
		
	
	
		
			
				
					|  |  |  | @ -212,8 +212,8 @@ export class RegistrationTabs extends React.Component<{}, State> { | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   private onSeedChanged(val: string) { | 
		
	
		
			
				|  |  |  |  |     this.setState({ | 
		
	
		
			
				|  |  |  |  |       mnemonicSeed: val, | 
		
	
		
			
				|  |  |  |  |       mnemonicError: !val ? window.i18n('mnemonicEmpty') : undefined, | 
		
	
		
			
				|  |  |  |  |       recoveryPhrase: val, | 
		
	
		
			
				|  |  |  |  |       mnemonicError: !val ? window.i18n('recoveryPhraseEmpty') : undefined, | 
		
	
		
			
				|  |  |  |  |     }); | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
	
		
			
				
					|  |  |  | @ -397,13 +397,13 @@ export class RegistrationTabs extends React.Component<{}, State> { | 
		
	
		
			
				|  |  |  |  |   private renderRegistrationContent() { | 
		
	
		
			
				|  |  |  |  |     const { signInMode, signUpMode } = this.state; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     if (signInMode === SignInMode.UsingSeed) { | 
		
	
		
			
				|  |  |  |  |     if (signInMode === SignInMode.UsingRecoveryPhrase) { | 
		
	
		
			
				|  |  |  |  |       return ( | 
		
	
		
			
				|  |  |  |  |         <div className={classNames('session-registration__entry-fields')}> | 
		
	
		
			
				|  |  |  |  |           <SessionInput | 
		
	
		
			
				|  |  |  |  |             label={window.i18n('mnemonicSeed')} | 
		
	
		
			
				|  |  |  |  |             label={window.i18n('recoveryPhrase')} | 
		
	
		
			
				|  |  |  |  |             type="password" | 
		
	
		
			
				|  |  |  |  |             placeholder={window.i18n('enterSeed')} | 
		
	
		
			
				|  |  |  |  |             placeholder={window.i18n('enterRecoveryPhrase')} | 
		
	
		
			
				|  |  |  |  |             enableShowHide={true} | 
		
	
		
			
				|  |  |  |  |             onValueChanged={(val: string) => { | 
		
	
		
			
				|  |  |  |  |               this.onSeedChanged(val); | 
		
	
	
		
			
				
					|  |  |  | @ -553,7 +553,7 @@ export class RegistrationTabs extends React.Component<{}, State> { | 
		
	
		
			
				|  |  |  |  |     if (signInMode === SignInMode.Default) { | 
		
	
		
			
				|  |  |  |  |       return ( | 
		
	
		
			
				|  |  |  |  |         <div> | 
		
	
		
			
				|  |  |  |  |           {this.renderRestoreUsingSeedButton( | 
		
	
		
			
				|  |  |  |  |           {this.renderRestoreUsingRecoveryPhraseButton( | 
		
	
		
			
				|  |  |  |  |             SessionButtonType.BrandOutline, | 
		
	
		
			
				|  |  |  |  |             SessionButtonColor.Green | 
		
	
		
			
				|  |  |  |  |           )} | 
		
	
	
		
			
				
					|  |  |  | @ -574,7 +574,7 @@ export class RegistrationTabs extends React.Component<{}, State> { | 
		
	
		
			
				|  |  |  |  |           {!this.state.secretWords && ( | 
		
	
		
			
				|  |  |  |  |             <> | 
		
	
		
			
				|  |  |  |  |               <h4>{or}</h4> | 
		
	
		
			
				|  |  |  |  |               {this.renderRestoreUsingSeedButton( | 
		
	
		
			
				|  |  |  |  |               {this.renderRestoreUsingRecoveryPhraseButton( | 
		
	
		
			
				|  |  |  |  |                 SessionButtonType.BrandOutline, | 
		
	
		
			
				|  |  |  |  |                 SessionButtonColor.White | 
		
	
		
			
				|  |  |  |  |               )} | 
		
	
	
		
			
				
					|  |  |  | @ -606,7 +606,7 @@ export class RegistrationTabs extends React.Component<{}, State> { | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   private handleContinueYourSessionClick() { | 
		
	
		
			
				|  |  |  |  |     if (this.state.signInMode === SignInMode.UsingSeed) { | 
		
	
		
			
				|  |  |  |  |     if (this.state.signInMode === SignInMode.UsingRecoveryPhrase) { | 
		
	
		
			
				|  |  |  |  |       this.register('english').ignore(); | 
		
	
		
			
				|  |  |  |  |     } else { | 
		
	
		
			
				|  |  |  |  |       this.registerSecondaryDevice().ignore(); | 
		
	
	
		
			
				
					|  |  |  | @ -623,17 +623,17 @@ export class RegistrationTabs extends React.Component<{}, State> { | 
		
	
		
			
				|  |  |  |  |       mnemonicError, | 
		
	
		
			
				|  |  |  |  |       primaryDevicePubKey, | 
		
	
		
			
				|  |  |  |  |       displayName, | 
		
	
		
			
				|  |  |  |  |       mnemonicSeed, | 
		
	
		
			
				|  |  |  |  |       recoveryPhrase, | 
		
	
		
			
				|  |  |  |  |       password, | 
		
	
		
			
				|  |  |  |  |     } = this.state; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     let enableContinue = true; | 
		
	
		
			
				|  |  |  |  |     let text = window.i18n('continueYourSession'); | 
		
	
		
			
				|  |  |  |  |     const displayNameOK = !displayNameError && !!displayName; // Display name required
 | 
		
	
		
			
				|  |  |  |  |     const mnemonicOK = !mnemonicError && !!mnemonicSeed; // Mnemonic required
 | 
		
	
		
			
				|  |  |  |  |     const mnemonicOK = !mnemonicError && !!recoveryPhrase; // Mnemonic required
 | 
		
	
		
			
				|  |  |  |  |     const passwordsOK = | 
		
	
		
			
				|  |  |  |  |       !password || (!passwordErrorString && passwordFieldsMatch); // password is valid if empty, or if no error and fields are matching
 | 
		
	
		
			
				|  |  |  |  |     if (signInMode === SignInMode.UsingSeed) { | 
		
	
		
			
				|  |  |  |  |     if (signInMode === SignInMode.UsingRecoveryPhrase) { | 
		
	
		
			
				|  |  |  |  |       enableContinue = displayNameOK && mnemonicOK && passwordsOK; | 
		
	
		
			
				|  |  |  |  |     } else if (signInMode === SignInMode.LinkingDevice) { | 
		
	
		
			
				|  |  |  |  |       enableContinue = !!primaryDevicePubKey; | 
		
	
	
		
			
				
					|  |  |  | @ -670,7 +670,7 @@ export class RegistrationTabs extends React.Component<{}, State> { | 
		
	
		
			
				|  |  |  |  |     ); | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |   private renderRestoreUsingSeedButton( | 
		
	
		
			
				|  |  |  |  |   private renderRestoreUsingRecoveryPhraseButton( | 
		
	
		
			
				|  |  |  |  |     buttonType: SessionButtonType, | 
		
	
		
			
				|  |  |  |  |     buttonColor: SessionButtonColor | 
		
	
		
			
				|  |  |  |  |   ) { | 
		
	
	
		
			
				
					|  |  |  | @ -679,16 +679,16 @@ export class RegistrationTabs extends React.Component<{}, State> { | 
		
	
		
			
				|  |  |  |  |         onClick={() => { | 
		
	
		
			
				|  |  |  |  |           this.cancelSecondaryDevice().ignore(); | 
		
	
		
			
				|  |  |  |  |           this.setState({ | 
		
	
		
			
				|  |  |  |  |             signInMode: SignInMode.UsingSeed, | 
		
	
		
			
				|  |  |  |  |             signInMode: SignInMode.UsingRecoveryPhrase, | 
		
	
		
			
				|  |  |  |  |             primaryDevicePubKey: '', | 
		
	
		
			
				|  |  |  |  |             mnemonicSeed: '', | 
		
	
		
			
				|  |  |  |  |             recoveryPhrase: '', | 
		
	
		
			
				|  |  |  |  |             displayName: '', | 
		
	
		
			
				|  |  |  |  |             signUpMode: SignUpMode.Default, | 
		
	
		
			
				|  |  |  |  |           }); | 
		
	
		
			
				|  |  |  |  |         }} | 
		
	
		
			
				|  |  |  |  |         buttonType={buttonType} | 
		
	
		
			
				|  |  |  |  |         buttonColor={buttonColor} | 
		
	
		
			
				|  |  |  |  |         text={window.i18n('restoreUsingSeed')} | 
		
	
		
			
				|  |  |  |  |         text={window.i18n('restoreUsingRecoveryPhrase')} | 
		
	
		
			
				|  |  |  |  |       /> | 
		
	
		
			
				|  |  |  |  |     ); | 
		
	
		
			
				|  |  |  |  |   } | 
		
	
	
		
			
				
					|  |  |  | @ -699,7 +699,7 @@ export class RegistrationTabs extends React.Component<{}, State> { | 
		
	
		
			
				|  |  |  |  |         onClick={() => { | 
		
	
		
			
				|  |  |  |  |           this.setState({ | 
		
	
		
			
				|  |  |  |  |             signInMode: SignInMode.LinkingDevice, | 
		
	
		
			
				|  |  |  |  |             mnemonicSeed: '', | 
		
	
		
			
				|  |  |  |  |             recoveryPhrase: '', | 
		
	
		
			
				|  |  |  |  |             displayName: '', | 
		
	
		
			
				|  |  |  |  |             signUpMode: SignUpMode.Default, | 
		
	
		
			
				|  |  |  |  |           }); | 
		
	
	
		
			
				
					|  |  |  | @ -719,7 +719,7 @@ export class RegistrationTabs extends React.Component<{}, State> { | 
		
	
		
			
				|  |  |  |  |       return; | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     if (signInMode === SignInMode.UsingSeed) { | 
		
	
		
			
				|  |  |  |  |     if (signInMode === SignInMode.UsingRecoveryPhrase) { | 
		
	
		
			
				|  |  |  |  |       this.handleContinueYourSessionClick(); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |       return; | 
		
	
	
		
			
				
					|  |  |  | @ -789,8 +789,8 @@ export class RegistrationTabs extends React.Component<{}, State> { | 
		
	
		
			
				|  |  |  |  |   private async register(language: string) { | 
		
	
		
			
				|  |  |  |  |     const { | 
		
	
		
			
				|  |  |  |  |       password, | 
		
	
		
			
				|  |  |  |  |       mnemonicSeed, | 
		
	
		
			
				|  |  |  |  |       generatedMnemonicSeed, | 
		
	
		
			
				|  |  |  |  |       recoveryPhrase, | 
		
	
		
			
				|  |  |  |  |       generatedRecoveryPhrase, | 
		
	
		
			
				|  |  |  |  |       signInMode, | 
		
	
		
			
				|  |  |  |  |       displayName, | 
		
	
		
			
				|  |  |  |  |       passwordErrorString, | 
		
	
	
		
			
				
					|  |  |  | @ -835,11 +835,11 @@ export class RegistrationTabs extends React.Component<{}, State> { | 
		
	
		
			
				|  |  |  |  |       return; | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     if (signInMode === SignInMode.UsingSeed && !mnemonicSeed) { | 
		
	
		
			
				|  |  |  |  |     if (signInMode === SignInMode.UsingRecoveryPhrase && !recoveryPhrase) { | 
		
	
		
			
				|  |  |  |  |       window.log.warn('empty mnemonic seed passed in seed restoration mode'); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |       return; | 
		
	
		
			
				|  |  |  |  |     } else if (!generatedMnemonicSeed) { | 
		
	
		
			
				|  |  |  |  |     } else if (!generatedRecoveryPhrase) { | 
		
	
		
			
				|  |  |  |  |       window.log.warn('empty generated seed'); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |       return; | 
		
	
	
		
			
				
					|  |  |  | @ -849,9 +849,9 @@ export class RegistrationTabs extends React.Component<{}, State> { | 
		
	
		
			
				|  |  |  |  |     window.textsecure.storage.remove('secondaryDeviceStatus'); | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     const seedToUse = | 
		
	
		
			
				|  |  |  |  |       signInMode === SignInMode.UsingSeed | 
		
	
		
			
				|  |  |  |  |         ? mnemonicSeed | 
		
	
		
			
				|  |  |  |  |         : generatedMnemonicSeed; | 
		
	
		
			
				|  |  |  |  |       signInMode === SignInMode.UsingRecoveryPhrase | 
		
	
		
			
				|  |  |  |  |         ? recoveryPhrase | 
		
	
		
			
				|  |  |  |  |         : generatedRecoveryPhrase; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |     try { | 
		
	
		
			
				|  |  |  |  |       await this.resetRegistration(); | 
		
	
	
		
			
				
					|  |  |  | @ -947,7 +947,7 @@ export class RegistrationTabs extends React.Component<{}, State> { | 
		
	
		
			
				|  |  |  |  |       return; | 
		
	
		
			
				|  |  |  |  |     } | 
		
	
		
			
				|  |  |  |  |     try { | 
		
	
		
			
				|  |  |  |  |       const fakeMnemonic = this.state.mnemonicSeed; | 
		
	
		
			
				|  |  |  |  |       const fakeMnemonic = this.state.recoveryPhrase; | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  |       await this.accountManager.registerSingleDevice( | 
		
	
		
			
				|  |  |  |  |         fakeMnemonic, | 
		
	
	
		
			
				
					|  |  |  | 
 |