|
|
|
@ -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,
|
|
|
|
|