import React, { useEffect, useState } from 'react'; import { View, Text, InteractionManager } from 'react-native'; import isEmpty from 'lodash/isEmpty'; import PropTypes from 'prop-types'; import { sha256 } from 'js-sha256'; import Modal from 'react-native-modal'; import useDeepCompareEffect from 'use-deep-compare-effect'; import { connect } from 'react-redux'; import TextInput from '../TextInput'; import I18n from '../../i18n'; import EventEmitter from '../../utils/events'; import { withTheme } from '../../theme'; import { themes } from '../../constants/colors'; import Button from '../Button'; import sharedStyles from '../../views/Styles'; import RocketChat from '../../lib/rocketchat'; import styles from './styles'; export const TWO_FACTOR = 'TWO_FACTOR'; const methods = { totp: { text: 'Open_your_authentication_app_and_enter_the_code', keyboardType: 'numeric' }, email: { text: 'Verify_your_email_for_the_code_we_sent', keyboardType: 'numeric' }, password: { title: 'Please_enter_your_password', text: 'For_your_security_you_must_enter_your_current_password_to_continue', secureTextEntry: true, keyboardType: 'default' } }; const TwoFactor = React.memo(({ theme, isMasterDetail }) => { const [visible, setVisible] = useState(false); const [data, setData] = useState({}); const [code, setCode] = useState(''); const method = methods[data.method]; const isEmail = data.method === 'email'; const sendEmail = () => RocketChat.sendEmailCode(); useDeepCompareEffect(() => { if (!isEmpty(data)) { setCode(''); setVisible(true); } else { setVisible(false); } }, [data]); const showTwoFactor = args => setData(args); useEffect(() => { const listener = EventEmitter.addEventListener(TWO_FACTOR, showTwoFactor); return () => EventEmitter.removeListener(TWO_FACTOR, listener); }, []); const onCancel = () => { const { cancel } = data; if (cancel) { cancel(); } setData({}); }; const onSubmit = () => { const { submit } = data; if (submit) { if (data.method === 'password') { submit(sha256(code)); } else { submit(code); } } setData({}); }; const color = themes[theme].titleText; return ( {I18n.t(method?.title || 'Two_Factor_Authentication')} {method?.text ? {I18n.t(method.text)} : null} InteractionManager.runAfterInteractions(() => e?.getNativeRef()?.focus())} returnKeyType='send' autoCapitalize='none' onChangeText={setCode} onSubmitEditing={onSubmit} keyboardType={method?.keyboardType} secureTextEntry={method?.secureTextEntry} error={data.invalid && { error: 'totp-invalid', reason: I18n.t('Code_or_password_invalid') }} testID='two-factor-input' /> {isEmail && {I18n.t('Send_me_the_code_again')}}