You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			125 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			TypeScript
		
	
			
		
		
	
	
			125 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			TypeScript
		
	
| import { useDispatch } from 'react-redux';
 | |
| import styled from 'styled-components';
 | |
| 
 | |
| import { useRef } from 'react';
 | |
| import useAsyncFn from 'react-use/lib/useAsyncFn';
 | |
| import useMount from 'react-use/lib/useMount';
 | |
| import { ToastUtils } from '../../session/utils';
 | |
| 
 | |
| import { updateEnterPasswordModal } from '../../state/ducks/modalDialog';
 | |
| import { SpacerSM } from '../basic/Text';
 | |
| 
 | |
| import { useHotkey } from '../../hooks/useHotkey';
 | |
| import { SessionWrapperModal } from '../SessionWrapperModal';
 | |
| import { SessionButton, SessionButtonColor, SessionButtonType } from '../basic/SessionButton';
 | |
| 
 | |
| const StyledModalContainer = styled.div`
 | |
|   margin: var(--margins-md) var(--margins-sm);
 | |
| `;
 | |
| 
 | |
| export type EnterPasswordModalProps = {
 | |
|   setPasswordValid: (value: boolean) => void;
 | |
|   onClickOk?: () => void;
 | |
|   onClickClose?: () => void;
 | |
| };
 | |
| 
 | |
| export const EnterPasswordModal = (props: EnterPasswordModalProps) => {
 | |
|   const { setPasswordValid, onClickOk, onClickClose } = props;
 | |
|   const title = window.i18n('sessionRecoveryPassword');
 | |
| 
 | |
|   const passwordInputRef = useRef<HTMLInputElement>(null);
 | |
|   const dispatch = useDispatch();
 | |
| 
 | |
|   const onPasswordVerified = () => {
 | |
|     onClickOk?.();
 | |
|     dispatch(updateEnterPasswordModal(null));
 | |
|   };
 | |
| 
 | |
|   const [, verifyPassword] = useAsyncFn(async () => {
 | |
|     try {
 | |
|       const passwordValue = passwordInputRef.current?.value;
 | |
|       if (!passwordValue) {
 | |
|         ToastUtils.pushToastError(
 | |
|           'enterPasswordErrorToast',
 | |
|           window.i18n.stripped('passwordIncorrect')
 | |
|         );
 | |
| 
 | |
|         return;
 | |
|       }
 | |
| 
 | |
|       // this throws if the password is invalid.
 | |
|       await window.onTryPassword(passwordValue);
 | |
| 
 | |
|       setPasswordValid(true);
 | |
|       onPasswordVerified();
 | |
|     } catch (e) {
 | |
|       window.log.error('window.onTryPassword failed with', e);
 | |
|       ToastUtils.pushToastError(
 | |
|         'enterPasswordErrorToast',
 | |
|         window.i18n.stripped('passwordIncorrect')
 | |
|       );
 | |
|     }
 | |
|   });
 | |
| 
 | |
|   const onClose = () => {
 | |
|     if (onClickClose) {
 | |
|       onClickClose();
 | |
|     }
 | |
|     dispatch(updateEnterPasswordModal(null));
 | |
|   };
 | |
| 
 | |
|   useMount(() => {
 | |
|     if (passwordInputRef.current) {
 | |
|       passwordInputRef.current.focus();
 | |
|     }
 | |
|   });
 | |
| 
 | |
|   useHotkey('Enter', (event: KeyboardEvent) => {
 | |
|     if (event.target === passwordInputRef.current) {
 | |
|       void verifyPassword();
 | |
|     }
 | |
|   });
 | |
| 
 | |
|   return (
 | |
|     <SessionWrapperModal
 | |
|       title={title || window.i18n('passwordEnter')}
 | |
|       onClose={onClose}
 | |
|       showExitIcon={true}
 | |
|     >
 | |
|       <StyledModalContainer>
 | |
|         <SpacerSM />
 | |
| 
 | |
|         <div className="session-modal__input-group">
 | |
|           <input
 | |
|             type="password"
 | |
|             ref={passwordInputRef}
 | |
|             data-testid="password-input"
 | |
|             placeholder={window.i18n('passwordEnter')}
 | |
|           />
 | |
|         </div>
 | |
| 
 | |
|         <SpacerSM />
 | |
| 
 | |
|         <div
 | |
|           className="session-modal__button-group"
 | |
|           style={{ justifyContent: 'center', width: '100%' }}
 | |
|         >
 | |
|           <SessionButton
 | |
|             text={window.i18n('done')}
 | |
|             buttonType={SessionButtonType.Simple}
 | |
|             onClick={verifyPassword}
 | |
|             dataTestId="session-confirm-ok-button"
 | |
|           />
 | |
|           <SessionButton
 | |
|             text={window.i18n('cancel')}
 | |
|             buttonType={SessionButtonType.Simple}
 | |
|             buttonColor={SessionButtonColor.Danger}
 | |
|             onClick={onClose}
 | |
|             dataTestId="session-confirm-cancel-button"
 | |
|           />
 | |
|         </div>
 | |
|       </StyledModalContainer>
 | |
|     </SessionWrapperModal>
 | |
|   );
 | |
| };
 |