|
|
|
@ -3,7 +3,7 @@ import React from 'react';
|
|
|
|
|
import { missingCaseError } from '../../util';
|
|
|
|
|
import { ToastUtils } from '../../session/utils';
|
|
|
|
|
import { Data } from '../../data/data';
|
|
|
|
|
import { SpacerLG, SpacerSM } from '../basic/Text';
|
|
|
|
|
import { SpacerSM } from '../basic/Text';
|
|
|
|
|
import autoBind from 'auto-bind';
|
|
|
|
|
import { sessionPassword } from '../../state/ducks/modalDialog';
|
|
|
|
|
import { LocalizerKeys } from '../../types/LocalizerKeys';
|
|
|
|
@ -11,7 +11,7 @@ import { SessionButton, SessionButtonColor, SessionButtonType } from '../basic/S
|
|
|
|
|
import { SessionWrapperModal } from '../SessionWrapperModal';
|
|
|
|
|
import { matchesHash, validatePassword } from '../../util/passwordUtils';
|
|
|
|
|
|
|
|
|
|
export type PasswordAction = 'set' | 'change' | 'remove';
|
|
|
|
|
export type PasswordAction = 'set' | 'change' | 'remove' | 'enter';
|
|
|
|
|
|
|
|
|
|
interface Props {
|
|
|
|
|
passwordAction: PasswordAction;
|
|
|
|
@ -62,6 +62,9 @@ export class SessionPasswordDialog extends React.Component<Props, State> {
|
|
|
|
|
case 'remove':
|
|
|
|
|
placeholders = [window.i18n('enterPassword')];
|
|
|
|
|
break;
|
|
|
|
|
case 'enter':
|
|
|
|
|
placeholders = [window.i18n('enterPassword')];
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
placeholders = [window.i18n('createPassword'), window.i18n('confirmPassword')];
|
|
|
|
|
}
|
|
|
|
@ -72,6 +75,8 @@ export class SessionPasswordDialog extends React.Component<Props, State> {
|
|
|
|
|
? 'changePassword'
|
|
|
|
|
: passwordAction === 'remove'
|
|
|
|
|
? 'removePassword'
|
|
|
|
|
: passwordAction === 'enter'
|
|
|
|
|
? 'passwordViewTitle'
|
|
|
|
|
: 'setPassword';
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
@ -89,7 +94,7 @@ export class SessionPasswordDialog extends React.Component<Props, State> {
|
|
|
|
|
onKeyUp={this.onPasswordInput}
|
|
|
|
|
data-testid="password-input"
|
|
|
|
|
/>
|
|
|
|
|
{passwordAction !== 'remove' && (
|
|
|
|
|
{passwordAction !== 'enter' && passwordAction !== 'remove' && (
|
|
|
|
|
<input
|
|
|
|
|
type="password"
|
|
|
|
|
id="password-modal-input-confirm"
|
|
|
|
@ -110,7 +115,6 @@ export class SessionPasswordDialog extends React.Component<Props, State> {
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<SpacerSM />
|
|
|
|
|
{this.showError()}
|
|
|
|
|
|
|
|
|
|
<div className="session-modal__button-group">
|
|
|
|
|
<SessionButton
|
|
|
|
@ -119,12 +123,14 @@ export class SessionPasswordDialog extends React.Component<Props, State> {
|
|
|
|
|
buttonType={SessionButtonType.Simple}
|
|
|
|
|
onClick={this.setPassword}
|
|
|
|
|
/>
|
|
|
|
|
<SessionButton
|
|
|
|
|
text={window.i18n('cancel')}
|
|
|
|
|
buttonColor={passwordAction !== 'remove' ? SessionButtonColor.Danger : undefined}
|
|
|
|
|
buttonType={SessionButtonType.Simple}
|
|
|
|
|
onClick={this.closeDialog}
|
|
|
|
|
/>
|
|
|
|
|
{passwordAction !== 'enter' && (
|
|
|
|
|
<SessionButton
|
|
|
|
|
text={window.i18n('cancel')}
|
|
|
|
|
buttonColor={passwordAction !== 'remove' ? SessionButtonColor.Danger : undefined}
|
|
|
|
|
buttonType={SessionButtonType.Simple}
|
|
|
|
|
onClick={this.closeDialog}
|
|
|
|
|
/>
|
|
|
|
|
)}
|
|
|
|
|
</div>
|
|
|
|
|
</SessionWrapperModal>
|
|
|
|
|
);
|
|
|
|
@ -141,18 +147,9 @@ export class SessionPasswordDialog extends React.Component<Props, State> {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private showError() {
|
|
|
|
|
const message = this.state.error;
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<>
|
|
|
|
|
{message && (
|
|
|
|
|
<>
|
|
|
|
|
<div className="session-label danger">{message}</div>
|
|
|
|
|
<SpacerLG />
|
|
|
|
|
</>
|
|
|
|
|
)}
|
|
|
|
|
</>
|
|
|
|
|
);
|
|
|
|
|
if (this.state.error) {
|
|
|
|
|
ToastUtils.pushToastError('enterPasswordErrorToast', this.state.error);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
@ -166,6 +163,7 @@ export class SessionPasswordDialog extends React.Component<Props, State> {
|
|
|
|
|
this.setState({
|
|
|
|
|
error: errorFirstInput,
|
|
|
|
|
});
|
|
|
|
|
this.showError();
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
@ -182,6 +180,7 @@ export class SessionPasswordDialog extends React.Component<Props, State> {
|
|
|
|
|
this.setState({
|
|
|
|
|
error: window.i18n('setPasswordInvalid'),
|
|
|
|
|
});
|
|
|
|
|
this.showError();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
await window.setPassword(enteredPassword, null);
|
|
|
|
@ -211,6 +210,7 @@ export class SessionPasswordDialog extends React.Component<Props, State> {
|
|
|
|
|
this.setState({
|
|
|
|
|
error: window.i18n('passwordsDoNotMatch'),
|
|
|
|
|
});
|
|
|
|
|
this.showError();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -219,6 +219,7 @@ export class SessionPasswordDialog extends React.Component<Props, State> {
|
|
|
|
|
this.setState({
|
|
|
|
|
error: window.i18n('changePasswordInvalid'),
|
|
|
|
|
});
|
|
|
|
|
this.showError();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
await window.setPassword(newPassword, oldPassword);
|
|
|
|
@ -240,6 +241,7 @@ export class SessionPasswordDialog extends React.Component<Props, State> {
|
|
|
|
|
this.setState({
|
|
|
|
|
error: window.i18n('removePasswordInvalid'),
|
|
|
|
|
});
|
|
|
|
|
this.showError();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
await window.setPassword(null, oldPassword);
|
|
|
|
@ -254,6 +256,25 @@ export class SessionPasswordDialog extends React.Component<Props, State> {
|
|
|
|
|
this.closeDialog();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private async handleActionEnter(enteredPassword: string) {
|
|
|
|
|
// be sure the password is valid
|
|
|
|
|
if (!this.validatePassword(enteredPassword)) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const isValidWithStoredInDB = Boolean(await this.validatePasswordHash(enteredPassword));
|
|
|
|
|
if (!isValidWithStoredInDB) {
|
|
|
|
|
this.setState({
|
|
|
|
|
error: window.i18n('invalidPassword'),
|
|
|
|
|
});
|
|
|
|
|
this.showError();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this.props.onOk();
|
|
|
|
|
this.closeDialog();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// tslint:disable-next-line: cyclomatic-complexity
|
|
|
|
|
private async setPassword() {
|
|
|
|
|
const { passwordAction } = this.props;
|
|
|
|
@ -285,6 +306,10 @@ export class SessionPasswordDialog extends React.Component<Props, State> {
|
|
|
|
|
await this.handleActionRemove(firstPasswordEntered);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
case 'enter': {
|
|
|
|
|
await this.handleActionEnter(firstPasswordEntered);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
default:
|
|
|
|
|
throw missingCaseError(passwordAction);
|
|
|
|
|
}
|
|
|
|
|