import React from 'react'; import classNames from 'classnames'; import { SessionIcon, SessionIconType } from './icon'; import { SessionButton, SessionButtonColor, SessionButtonType, } from './SessionButton'; interface State { error: string; errorCount: number; clearDataView: boolean; } export class SessionPasswordPrompt extends React.PureComponent<{}, State> { constructor(props: any) { super(props); this.state = { error: '', errorCount: 0, clearDataView: false, }; this.onKeyUp = this.onKeyUp.bind(this); this.onPaste = this.onPaste.bind(this); this.initLogin = this.initLogin.bind(this); this.initClearDataView = this.initClearDataView.bind(this); } public componentDidMount() { setTimeout(() => $('#password-prompt-input').focus(), 100); } public render() { const showResetElements = this.state.errorCount >= window.CONSTANTS.MAX_LOGIN_TRIES; const wrapperClass = this.state.clearDataView ? 'clear-data-wrapper' : 'password-prompt-wrapper'; const containerClass = this.state.clearDataView ? 'clear-data-container' : 'password-prompt-container'; const infoAreaClass = this.state.clearDataView ? 'warning-info-area' : 'password-info-area'; const infoTitle = this.state.clearDataView ? window.i18n('clearDataHeader') : window.i18n('passwordViewTitle'); const buttonGroup = this.state.clearDataView ? this.renderClearDataViewButtons() : this.renderPasswordViewButtons(); const featureElement = this.state.clearDataView ? (

{window.i18n('clearDataExplanation')}

) : ( ); const infoIcon = this.state.clearDataView ? ( ) : ( ); const errorSection = !this.state.clearDataView && (
{this.state.error && ( <> {showResetElements ? (
{window.i18n('maxPasswordAttempts')}
) : (
{this.state.error}
)} )}
); return (
{infoIcon}

{infoTitle}

{featureElement} {errorSection} {buttonGroup}
); } public async onKeyUp(event: any) { switch (event.key) { case 'Enter': await this.initLogin(); break; default: } event.preventDefault(); } public onPaste(event: any) { const clipboard = event.clipboardData.getData('text'); if (clipboard.length > window.CONSTANTS.MAX_PASSWORD_LENGTH){ this.setState({ error: String(window.i18n('pasteLongPasswordToastTitle', window.CONSTANTS.MAX_PASSWORD_LENGTH)) }); } // Prevent pating into input return false; } public async onLogin(passPhrase: string) { const trimmed = passPhrase ? passPhrase.trim() : passPhrase; try { await window.onLogin(trimmed); } catch (error) { // Increment the error counter and show the button if necessary this.setState({ errorCount: this.state.errorCount + 1, }); this.setState({ error }); } } private async initLogin() { const passPhrase = String($('#password-prompt-input').val()); await this.onLogin(passPhrase); } private initClearDataView() { this.setState({ error: '', errorCount: 0, clearDataView: true, }); } private renderPasswordViewButtons(): JSX.Element { const showResetElements = this.state.errorCount >= window.CONSTANTS.MAX_LOGIN_TRIES; return (
{showResetElements && ( <> )}
); } private renderClearDataViewButtons(): JSX.Element { return (
{ this.setState({ clearDataView: false }); }} />
); } }