From 7784c80d9ff2ca09dc3f6c796db1c33d89075c09 Mon Sep 17 00:00:00 2001 From: Anastasia Poupeney Date: Mon, 11 Jun 2018 13:38:35 +0200 Subject: [PATCH 1/3] wip password refactor and password page onboarding --- src/components/Onboarding/index.js | 45 +-- .../Onboarding/steps/SetPassword.js | 262 +++++++++++------- src/components/SettingsPage/PasswordForm.js | 92 ++++++ src/components/SettingsPage/PasswordModal.js | 94 +++---- src/reducers/onboarding.js | 18 +- static/i18n/en/onboarding.yml | 8 +- static/i18n/en/password.yml | 12 +- 7 files changed, 350 insertions(+), 181 deletions(-) create mode 100644 src/components/SettingsPage/PasswordForm.js diff --git a/src/components/Onboarding/index.js b/src/components/Onboarding/index.js index 495ca599..92c6dd0e 100644 --- a/src/components/Onboarding/index.js +++ b/src/components/Onboarding/index.js @@ -8,6 +8,7 @@ import styled from 'styled-components' import type { T } from 'types/common' import type { OnboardingState } from 'reducers/onboarding' +import type { SettingsState } from 'reducers/settings' import { saveSettings } from 'actions/settings' import { @@ -20,7 +21,7 @@ import { } from 'reducers/onboarding' import { getCurrentDevice } from 'reducers/devices' -// import { unlock } from 'reducers/application' +import { unlock } from 'reducers/application' import Box from 'components/base/Box' @@ -32,7 +33,7 @@ import SelectPIN from './steps/SelectPIN/index' import WriteSeed from './steps/WriteSeed/index' import GenuineCheck from './steps/GenuineCheck' // UNTIL IS NEEDED SET PASSWORD IS COMMENTED OUT -// import SetPassword from './steps/SetPassword' +import SetPassword from './steps/SetPassword' import Analytics from './steps/Analytics' import Finish from './steps/Finish' @@ -42,7 +43,7 @@ const STEPS = { selectPIN: SelectPIN, writeSeed: WriteSeed, genuineCheck: GenuineCheck, - // setPassword: SetPassword, + setPassword: SetPassword, analytics: Analytics, finish: Finish, start: Start, @@ -51,6 +52,7 @@ const STEPS = { const mapStateToProps = state => ({ hasCompletedOnboarding: state.settings.hasCompletedOnboarding, onboarding: state.onboarding, + settings: state.settings, getCurrentDevice: getCurrentDevice(state), }) @@ -59,7 +61,7 @@ const mapDispatchToProps = { nextStep, prevStep, jumpStep, - // unlock, + unlock, } type Props = { @@ -67,6 +69,7 @@ type Props = { hasCompletedOnboarding: boolean, saveSettings: Function, onboarding: OnboardingState, + settings: SettingsState, prevStep: Function, nextStep: Function, jumpStep: Function, @@ -77,12 +80,13 @@ type Props = { export type StepProps = { t: T, onboarding: OnboardingState, + settings: SettingsState, prevStep: Function, nextStep: Function, jumpStep: Function, finish: Function, saveSettings: Function, - // savePassword: Function, + savePassword: Function, getDeviceInfo: Function, updateGenuineCheck: Function, isLedgerNano: Function, @@ -92,18 +96,26 @@ export type StepProps = { class Onboarding extends PureComponent { getDeviceInfo = () => this.props.getCurrentDevice finish = () => this.props.saveSettings({ hasCompletedOnboarding: true }) - // savePassword = hash => { - // this.props.saveSettings({ - // password: { - // isEnabled: hash !== undefined, - // value: hash, - // }, - // }) - // this.props.unlock() - // } + savePassword = hash => { + this.props.saveSettings({ + password: { + isEnabled: hash !== undefined, + value: hash, + }, + }) + this.props.unlock() + } render() { - const { hasCompletedOnboarding, onboarding, prevStep, nextStep, jumpStep, t } = this.props + const { + hasCompletedOnboarding, + onboarding, + prevStep, + nextStep, + jumpStep, + settings, + t, + } = this.props if (hasCompletedOnboarding) { return null } @@ -119,6 +131,7 @@ class Onboarding extends PureComponent { const stepProps: StepProps = { t, onboarding, + settings, updateGenuineCheck, isLedgerNano, flowType, @@ -126,7 +139,7 @@ class Onboarding extends PureComponent { nextStep, jumpStep, finish: this.finish, - // savePassword: this.savePassword, + savePassword: this.savePassword, getDeviceInfo: this.getDeviceInfo, saveSettings, } diff --git a/src/components/Onboarding/steps/SetPassword.js b/src/components/Onboarding/steps/SetPassword.js index b844a4fb..8a50a77d 100644 --- a/src/components/Onboarding/steps/SetPassword.js +++ b/src/components/Onboarding/steps/SetPassword.js @@ -1,93 +1,169 @@ -// UNTIL IS NEEDED SET PASSWORD STEP IS COMMENTED OUT - -// // @flow -// -// import React, { PureComponent } from 'react' -// import bcrypt from 'bcryptjs' -// -// import { setEncryptionKey } from 'helpers/db' -// -// import Box from 'components/base/Box' -// import Button from 'components/base/Button' -// -// import IconSetPassword from 'icons/onboarding/SetPassword' -// import PasswordModal from 'components/SettingsPage/PasswordModal' -// import OnboardingFooter from '../OnboardingFooter' -// -// import type { StepProps } from '..' -// -// import { Title, Description } from '../helperComponents' -// -// type State = { -// isPasswordModalOpened: boolean, -// isPasswordEnabled: boolean, -// } -// -// class SetPassword extends PureComponent { -// state = { -// isPasswordModalOpened: false, -// isPasswordEnabled: false, -// } -// -// handleOpenPasswordModal = () => { -// this.setState({ isPasswordModalOpened: true }) -// } -// handleClosePasswordModal = () => { -// this.setState({ isPasswordModalOpened: false }) -// } -// handleChangePassword = (password: string) => { -// window.requestIdleCallback(() => { -// setEncryptionKey('accounts', password) -// const hash = password ? bcrypt.hashSync(password, 8) : undefined -// this.props.savePassword(hash) -// }) -// } -// -// handleInputChange = (key: string) => (value: string) => { -// this.setState({ [key]: value }) -// } -// -// render() { -// const { nextStep, prevStep, t } = this.props -// const { isPasswordModalOpened, isPasswordEnabled } = this.state -// return ( -// -// -// {t('onboarding:setPassword.title')} -// {t('onboarding:setPassword.desc')} -// -// -// -// -// {/* we might not be able to re-use what we have currently without modifications -// the title and descriptions are not dynamic, we might need deffirent size as well */} -// {isPasswordModalOpened && ( -// -// )} -// nextStep()} style={{ padding: 15 }}> -// -// -// -// -// -// ) -// } -// } -// -// export default SetPassword +// @flow + +import React, { PureComponent, Fragment } from 'react' +import bcrypt from 'bcryptjs' +import { colors } from 'styles/theme' +import styled from 'styled-components' +import { radii } from 'styles/theme' + +import { setEncryptionKey } from 'helpers/db' + +import Box from 'components/base/Box' +import Button from 'components/base/Button' + +import PasswordModal from 'components/SettingsPage/PasswordModal' +import OnboardingFooter from '../OnboardingFooter' +import IconChevronRight from 'icons/ChevronRight' +import { ErrorMessageInput } from 'components/base/Input' + +import PasswordForm from '../../SettingsPage/PasswordForm' +import type { StepProps } from '..' + +import { Title, Description, DisclaimerBox, Inner } from '../helperComponents' + +type State = { + currentPassword: string, + newPassword: string, + confirmPassword: string, + incorrectPassword: boolean, + submitError: boolean, +} + +const INITIAL_STATE = { + currentPassword: '', + newPassword: '', + confirmPassword: '', + incorrectPassword: false, + submitError: false, +} + +class SetPassword extends PureComponent { + state = INITIAL_STATE + + handleSave = (e: SyntheticEvent) => { + if (e) { + e.preventDefault() + } + if (!this.isValid()) { + this.setState({ submitError: true }) + return + } + const { newPassword } = this.state + const { nextStep } = this.props + + setEncryptionKey('accounts', newPassword) + const hash = newPassword ? bcrypt.hashSync(newPassword, 8) : undefined + this.props.savePassword(hash) + nextStep() + } + + handleInputChange = (key: string) => (value: string) => { + if (this.state.incorrectPassword) { + this.setState({ incorrectPassword: false }) + } + this.setState({ [key]: value }) + } + + handleReset = () => this.setState(INITIAL_STATE) + + isValid = () => { + const { newPassword, confirmPassword } = this.state + return newPassword === confirmPassword ? true : false + } + + render() { + const { nextStep, prevStep, t, savePassword, settings } = this.props + const { + newPassword, + currentPassword, + incorrectPassword, + confirmPassword, + submitError, + } = this.state + + const isPasswordEnabled = settings.password.isEnabled === true + + const disclaimerNotes = [ + { + key: 'note1', + icon: , + desc: t('onboarding:writeSeed.disclaimer.note1'), + }, + { + key: 'note2', + icon: , + desc: t('onboarding:writeSeed.disclaimer.note2'), + }, + { + key: 'note3', + icon: , + desc: t('onboarding:writeSeed.disclaimer.note3'), + }, + ] + + return ( + + + + + {t('onboarding:setPassword.title')} + + {t('onboarding:setPassword.desc')} + + + + + {!this.isValid() && ( + + {t('password:errorMessageNotMatchingPassword')} + + )} + + + + + + + + + + + + + + ) + } +} + +export default SetPassword + +const CustomFooter = styled(Box).attrs({ + px: 5, + py: 3, + horizontal: true, + align: 'center', +})` + border-top: 1px solid ${p => p.theme.colors.lightFog}; + border-bottom-left-radius: ${radii[1]}px; + border-bottom-right-radius: ${radii[1]}px; +` diff --git a/src/components/SettingsPage/PasswordForm.js b/src/components/SettingsPage/PasswordForm.js new file mode 100644 index 00000000..c64217b9 --- /dev/null +++ b/src/components/SettingsPage/PasswordForm.js @@ -0,0 +1,92 @@ +// @flow + +import React, { PureComponent, Fragment } from 'react' +import { connect } from 'react-redux' +import bcrypt from 'bcryptjs' + +import Box from 'components/base/Box' +import Button from 'components/base/Button' +import InputPassword from 'components/base/InputPassword' +import Label from 'components/base/Label' +import { ErrorMessageInput } from 'components/base/Input' + +import type { T } from 'types/common' + +type Props = { + t: T, + isPasswordEnabled: boolean, + + currentPassword: string, + newPassword: string, + confirmPassword: string, + incorrectPassword: boolean, + onSubmit: Function, + onChange: Function, +} + +class PasswordForm extends PureComponent { + render() { + const { + t, + isPasswordEnabled, + currentPassword, + newPassword, + incorrectPassword, + confirmPassword, + onChange, + onSubmit, + } = this.props + + return ( +
+ + {isPasswordEnabled && ( + + + + {incorrectPassword && ( + {t('password:errorMessageIncorrectPassword')} + )} + + )} + + {isPasswordEnabled && ( + + )} + + + + {isPasswordEnabled && ( + + )} + + + +
+ ) + } +} + +export default PasswordForm diff --git a/src/components/SettingsPage/PasswordModal.js b/src/components/SettingsPage/PasswordModal.js index 9d58b47f..84f6f0a0 100644 --- a/src/components/SettingsPage/PasswordModal.js +++ b/src/components/SettingsPage/PasswordModal.js @@ -13,6 +13,7 @@ import Label from 'components/base/Label' import { Modal, ModalContent, ModalBody, ModalTitle, ModalFooter } from 'components/base/Modal' import { ErrorMessageInput } from 'components/base/Input' +import PasswordForm from './PasswordForm' import type { T } from 'types/common' const mapDispatchToProps = { @@ -31,12 +32,14 @@ type Props = { type State = { currentPassword: string, newPassword: string, + confirmPassword: string, incorrectPassword: boolean, } const INITIAL_STATE = { currentPassword: '', newPassword: '', + confirmPassword: '', incorrectPassword: false, } @@ -50,7 +53,7 @@ class PasswordModal extends PureComponent { if (!this.isValid()) { return } - const { currentPassword, newPassword } = this.state + const { currentPassword, newPassword, confirmPassword } = this.state const { isPasswordEnabled, currentPasswordHash, onChangePassword } = this.props if (isPasswordEnabled) { if (!bcrypt.compareSync(currentPassword, currentPasswordHash)) { @@ -79,7 +82,7 @@ class PasswordModal extends PureComponent { render() { const { t, isPasswordEnabled, onClose, ...props } = this.props - const { currentPassword, newPassword, incorrectPassword } = this.state + const { currentPassword, newPassword, incorrectPassword, confirmPassword } = this.state const isValid = this.isValid() return ( { onHide={this.handleReset} onClose={onClose} render={({ onClose }) => ( -
- - {t('settings:profile.passwordModalTitle')} - - - {t('settings:profile.passwordModalSubtitle')} - - - {t('settings:profile.passwordModalDesc')} - - {isPasswordEnabled && ( - - - - {incorrectPassword && ( - - {t('password:errorMessageIncorrectPassword')} - - )} - - )} - - {isPasswordEnabled && ( - - )} - - - - - - - - - - -
+ + {t('settings:profile.passwordModalTitle')} + + + {t('settings:profile.passwordModalSubtitle')} + + + {t('settings:profile.passwordModalDesc')} + + + + + + + + )} /> ) diff --git a/src/reducers/onboarding.js b/src/reducers/onboarding.js index 3c57ba63..b9b967a3 100644 --- a/src/reducers/onboarding.js +++ b/src/reducers/onboarding.js @@ -94,15 +94,15 @@ const state: OnboardingState = { }, }, // UNTIL IS NEEDED SET PASSWORD IS COMMENTED OUT - // { - // name: 'setPassword', - // label: 'Set Password', - // options: { - // showFooter: false, - // showBackground: true, - // showBreadcrumb: true, - // }, - // }, + { + name: 'setPassword', + label: 'Set Password', + options: { + showFooter: false, + showBackground: true, + showBreadcrumb: true, + }, + }, { name: 'analytics', label: 'Analytics & Bug report', diff --git a/static/i18n/en/onboarding.yml b/static/i18n/en/onboarding.yml index e0ed0394..e25c6e4e 100644 --- a/static/i18n/en/onboarding.yml +++ b/static/i18n/en/onboarding.yml @@ -88,8 +88,12 @@ genuineCheck: title: Something is wrong with your Ledger Blue desc: A problem occurred with your Ledger Blue. Contact Ledger Support to get assistance or go back to the security check. setPassword: - title: Choose a password to securely access Ledger Live - desc: Use uppercase, lowercase, special characters (#, @, !, ?) and numbers for a stronger password. + title: Protect your privacy (optional) + desc: Set a password to prevent unauthorized access to Ledger Live data stored on your computer, including account names, balances, transactions and public addresses. + disclaimer: + note1: Make sure to remember your password and do not share it. + note2: Losing your password requires resetting Ledger Live and re-adding accounts. + note3: Loss of password doesn’t affect your crypto-assets. analytics: title: Help Ledger to improve its products and services desc: This is a long text, please replace it with the final wording once it’s done.
Lorem ipsum dolor amet ledger lorem dolor ipsum amet diff --git a/static/i18n/en/password.yml b/static/i18n/en/password.yml index 469b5f45..a5464044 100644 --- a/static/i18n/en/password.yml +++ b/static/i18n/en/password.yml @@ -3,4 +3,14 @@ warning_1: Warning 1 warning_2: Warning 2 warning_3: Warning 3 warning_4: Warning 4 -errorMessageIncorrectPassword: The password you entered is incorrect. +errorMessageIncorrectPassword: The password you entered is incorrect. +errorMessageNotMatchingPassword: Passwords don't match. +newPassword: + label: New Password + placeholder: New Password +confirmPassword: + label: Confirm Password + placeholder: Confirm Password +currentPassword: + label: Current Password + placeholder: Current Password From 07ba5f067756e96b252b4231c10b8d49e5df8621 Mon Sep 17 00:00:00 2001 From: Anastasia Poupeney Date: Mon, 11 Jun 2018 16:54:54 +0200 Subject: [PATCH 2/3] password related changes --- src/components/IsUnlocked.js | 19 +------ src/components/Onboarding/steps/Analytics.js | 34 ++++++----- .../Onboarding/steps/SetPassword.js | 45 +++++---------- .../SettingsPage/DisablePasswordModal.js | 21 +++---- src/components/SettingsPage/PasswordForm.js | 47 ++++++++-------- src/components/SettingsPage/PasswordModal.js | 56 ++++++++++--------- src/components/base/Input/index.js | 7 --- .../modals/AccountSettingRenderBody.js | 6 +- static/i18n/en/common.yml | 1 + static/i18n/en/password.yml | 30 +++++++--- static/i18n/en/settings.yml | 13 ----- 11 files changed, 120 insertions(+), 159 deletions(-) diff --git a/src/components/IsUnlocked.js b/src/components/IsUnlocked.js index 7de2bdf3..562898b9 100644 --- a/src/components/IsUnlocked.js +++ b/src/components/IsUnlocked.js @@ -11,8 +11,6 @@ import type { SettingsState as Settings } from 'reducers/settings' import type { T } from 'types/common' import IconLockScreen from 'icons/LockScreen' -import { ErrorMessageInput } from 'components/base/Input' - import get from 'lodash/get' import { setEncryptionKey } from 'helpers/db' @@ -119,21 +117,13 @@ class IsUnlocked extends Component { } } - handleFocusInput = () => { - if (this._input && this._input !== null) { - this._input.focus() - } - } - - _input: ?HTMLInputElement - render() { const { inputValue, incorrectPassword } = this.state const { isLocked, t } = this.props if (isLocked) { return ( - +
@@ -146,17 +136,12 @@ class IsUnlocked extends Component { (this._input = n)} placeholder={t('common:lockScreen.inputPlaceholder')} type="password" onChange={this.handleChangeInput('password')} value={inputValue.password} + error={incorrectPassword && t('password:errorMessageIncorrectPassword')} /> - {incorrectPassword && ( - - {t('password:errorMessageIncorrectPassword')} - - )}
diff --git a/src/components/Onboarding/steps/Analytics.js b/src/components/Onboarding/steps/Analytics.js index 34584285..2719d2cc 100644 --- a/src/components/Onboarding/steps/Analytics.js +++ b/src/components/Onboarding/steps/Analytics.js @@ -2,8 +2,6 @@ import React, { PureComponent } from 'react' import styled from 'styled-components' -import { connect } from 'react-redux' -import { saveSettings } from 'actions/settings' import Box from 'components/base/Box' import CheckBox from 'components/base/CheckBox' @@ -12,19 +10,21 @@ import OnboardingFooter from '../OnboardingFooter' import type { StepProps } from '..' -const mapDispatchToProps = { saveSettings } - type State = { analyticsToggle: boolean, termsConditionsToggle: boolean, sentryLogsToggle: boolean, } + +const INITIAL_STATE = { + analyticsToggle: false, + termsConditionsToggle: false, + sentryLogsToggle: false, +} + class Analytics extends PureComponent { - state = { - analyticsToggle: false, - termsConditionsToggle: false, - sentryLogsToggle: false, - } + state = INITIAL_STATE + handleSentryLogsToggle = (isChecked: boolean) => { this.setState({ sentryLogsToggle: !this.state.sentryLogsToggle }) this.props.saveSettings({ @@ -40,8 +40,15 @@ class Analytics extends PureComponent { handleTermsToggle = () => { this.setState({ termsConditionsToggle: !this.state.termsConditionsToggle }) } + + handleNavBack = () => { + const { savePassword, prevStep } = this.props + savePassword(undefined) + prevStep() + } + render() { - const { nextStep, prevStep, t } = this.props + const { nextStep, t } = this.props const { analyticsToggle, termsConditionsToggle, sentryLogsToggle } = this.state return ( @@ -85,7 +92,7 @@ class Analytics extends PureComponent { flow={2} t={t} nextStep={nextStep} - prevStep={prevStep} + prevStep={this.handleNavBack} isContinueDisabled={!termsConditionsToggle} />
@@ -93,10 +100,7 @@ class Analytics extends PureComponent { } } -export default connect( - null, - mapDispatchToProps, -)(Analytics) +export default Analytics export const AnalyticsText = styled(Box).attrs({ ff: 'Open Sans|Regular', diff --git a/src/components/Onboarding/steps/SetPassword.js b/src/components/Onboarding/steps/SetPassword.js index 8a50a77d..cbaf9635 100644 --- a/src/components/Onboarding/steps/SetPassword.js +++ b/src/components/Onboarding/steps/SetPassword.js @@ -2,31 +2,26 @@ import React, { PureComponent, Fragment } from 'react' import bcrypt from 'bcryptjs' -import { colors } from 'styles/theme' +import { colors, radii } from 'styles/theme' import styled from 'styled-components' -import { radii } from 'styles/theme' import { setEncryptionKey } from 'helpers/db' import Box from 'components/base/Box' import Button from 'components/base/Button' -import PasswordModal from 'components/SettingsPage/PasswordModal' -import OnboardingFooter from '../OnboardingFooter' import IconChevronRight from 'icons/ChevronRight' -import { ErrorMessageInput } from 'components/base/Input' import PasswordForm from '../../SettingsPage/PasswordForm' import type { StepProps } from '..' -import { Title, Description, DisclaimerBox, Inner } from '../helperComponents' +import { Title, Description, DisclaimerBox } from '../helperComponents' type State = { currentPassword: string, newPassword: string, confirmPassword: string, incorrectPassword: boolean, - submitError: boolean, } const INITIAL_STATE = { @@ -34,7 +29,6 @@ const INITIAL_STATE = { newPassword: '', confirmPassword: '', incorrectPassword: false, - submitError: false, } class SetPassword extends PureComponent { @@ -45,15 +39,15 @@ class SetPassword extends PureComponent { e.preventDefault() } if (!this.isValid()) { - this.setState({ submitError: true }) return } const { newPassword } = this.state - const { nextStep } = this.props + const { nextStep, savePassword } = this.props setEncryptionKey('accounts', newPassword) const hash = newPassword ? bcrypt.hashSync(newPassword, 8) : undefined - this.props.savePassword(hash) + savePassword(hash) + this.handleReset() nextStep() } @@ -68,18 +62,12 @@ class SetPassword extends PureComponent { isValid = () => { const { newPassword, confirmPassword } = this.state - return newPassword === confirmPassword ? true : false + return newPassword === confirmPassword } render() { - const { nextStep, prevStep, t, savePassword, settings } = this.props - const { - newPassword, - currentPassword, - incorrectPassword, - confirmPassword, - submitError, - } = this.state + const { nextStep, prevStep, t, settings } = this.props + const { newPassword, currentPassword, incorrectPassword, confirmPassword } = this.state const isPasswordEnabled = settings.password.isEnabled === true @@ -87,17 +75,17 @@ class SetPassword extends PureComponent { { key: 'note1', icon: , - desc: t('onboarding:writeSeed.disclaimer.note1'), + desc: t('onboarding:setPassword.disclaimer.note1'), }, { key: 'note2', icon: , - desc: t('onboarding:writeSeed.disclaimer.note2'), + desc: t('onboarding:setPassword.disclaimer.note2'), }, { key: 'note3', icon: , - desc: t('onboarding:writeSeed.disclaimer.note3'), + desc: t('onboarding:setPassword.disclaimer.note3'), }, ] @@ -119,15 +107,12 @@ class SetPassword extends PureComponent { currentPassword={currentPassword} confirmPassword={confirmPassword} incorrectPassword={incorrectPassword} + isValid={this.isValid} onChange={this.handleInputChange} t={t} /> - {!this.isValid() && ( - - {t('password:errorMessageNotMatchingPassword')} - - )} - + +
@@ -138,7 +123,7 @@ class SetPassword extends PureComponent { diff --git a/src/components/SettingsPage/PasswordForm.js b/src/components/SettingsPage/PasswordForm.js index c64217b9..29b3e7cd 100644 --- a/src/components/SettingsPage/PasswordForm.js +++ b/src/components/SettingsPage/PasswordForm.js @@ -1,26 +1,22 @@ // @flow -import React, { PureComponent, Fragment } from 'react' -import { connect } from 'react-redux' -import bcrypt from 'bcryptjs' +import React, { PureComponent } from 'react' import Box from 'components/base/Box' -import Button from 'components/base/Button' import InputPassword from 'components/base/InputPassword' import Label from 'components/base/Label' -import { ErrorMessageInput } from 'components/base/Input' import type { T } from 'types/common' type Props = { t: T, isPasswordEnabled: boolean, - currentPassword: string, newPassword: string, confirmPassword: string, incorrectPassword: boolean, onSubmit: Function, + isValid: () => boolean, onChange: Function, } @@ -33,54 +29,55 @@ class PasswordForm extends PureComponent { newPassword, incorrectPassword, confirmPassword, + isValid, onChange, onSubmit, } = this.props - + // TODO: adjust design to separate 3 fields return ( {isPasswordEnabled && ( - - + + - {incorrectPassword && ( - {t('password:errorMessageIncorrectPassword')} - )} )} - {isPasswordEnabled && ( - - )} + - {isPasswordEnabled && ( - - )} + 0 && + t('password:errorMessageNotMatchingPassword') + } /> diff --git a/src/components/SettingsPage/PasswordModal.js b/src/components/SettingsPage/PasswordModal.js index 84f6f0a0..d3f6c3ed 100644 --- a/src/components/SettingsPage/PasswordModal.js +++ b/src/components/SettingsPage/PasswordModal.js @@ -1,32 +1,22 @@ // @flow import React, { PureComponent } from 'react' -import { connect } from 'react-redux' import bcrypt from 'bcryptjs' -import { unlock } from 'reducers/application' +import type { T } from 'types/common' import Box from 'components/base/Box' import Button from 'components/base/Button' -import InputPassword from 'components/base/InputPassword' -import Label from 'components/base/Label' import { Modal, ModalContent, ModalBody, ModalTitle, ModalFooter } from 'components/base/Modal' -import { ErrorMessageInput } from 'components/base/Input' import PasswordForm from './PasswordForm' -import type { T } from 'types/common' - -const mapDispatchToProps = { - unlock, -} type Props = { t: T, - onClose: Function, - unlock: Function, + onClose: () => void, + onChangePassword: (?string) => void, isPasswordEnabled: boolean, currentPasswordHash: string, - onChangePassword: Function, } type State = { @@ -47,13 +37,15 @@ class PasswordModal extends PureComponent { state = INITIAL_STATE handleSave = (e: SyntheticEvent) => { + const { currentPassword, newPassword } = this.state + if (e) { e.preventDefault() } if (!this.isValid()) { return } - const { currentPassword, newPassword, confirmPassword } = this.state + const { isPasswordEnabled, currentPasswordHash, onChangePassword } = this.props if (isPasswordEnabled) { if (!bcrypt.compareSync(currentPassword, currentPasswordHash)) { @@ -76,14 +68,13 @@ class PasswordModal extends PureComponent { handleReset = () => this.setState(INITIAL_STATE) isValid = () => { - const { newPassword } = this.state - return newPassword + const { newPassword, confirmPassword } = this.state + return newPassword === confirmPassword } render() { const { t, isPasswordEnabled, onClose, ...props } = this.props const { currentPassword, newPassword, incorrectPassword, confirmPassword } = this.state - const isValid = this.isValid() return ( { onClose={onClose} render={({ onClose }) => ( - {t('settings:profile.passwordModalTitle')} + {isPasswordEnabled ? ( + {t('password:changePassword.title')} + ) : ( + {t('password:setPassword.title')} + )} - {t('settings:profile.passwordModalSubtitle')} + {isPasswordEnabled + ? t('password:changePassword.subTitle') + : t('password:setPassword.subTitle')} - {t('settings:profile.passwordModalDesc')} + {isPasswordEnabled + ? t('password:changePassword.desc') + : t('password:setPassword.desc')} { currentPassword={currentPassword} confirmPassword={confirmPassword} incorrectPassword={incorrectPassword} + isValid={this.isValid} onChange={this.handleInputChange} t={t} /> - - @@ -125,7 +130,4 @@ class PasswordModal extends PureComponent { } } -export default connect( - null, - mapDispatchToProps, -)(PasswordModal) +export default PasswordModal diff --git a/src/components/base/Input/index.js b/src/components/base/Input/index.js index b7611c99..62f92a80 100644 --- a/src/components/base/Input/index.js +++ b/src/components/base/Input/index.js @@ -48,13 +48,6 @@ const Base = styled.input.attrs({ } ` -export const ErrorMessageInput = styled(Box).attrs({ - alignItems: 'flex-start', - color: 'alertRed', - ff: 'Open Sans|SemiBold', - fontSize: 3, -})`` - export const Textarea = styled.textarea.attrs({ p: 2, fontSize: 4, diff --git a/src/components/modals/AccountSettingRenderBody.js b/src/components/modals/AccountSettingRenderBody.js index 1ce382ad..4e584e99 100644 --- a/src/components/modals/AccountSettingRenderBody.js +++ b/src/components/modals/AccountSettingRenderBody.js @@ -18,7 +18,7 @@ import Spoiler from 'components/base/Spoiler' import CryptoCurrencyIcon from 'components/CryptoCurrencyIcon' import Box from 'components/base/Box' import Button from 'components/base/Button' -import Input, { ErrorMessageInput } from 'components/base/Input' +import Input from 'components/base/Input' import Select from 'components/base/LegacySelect' import { ModalBody, ModalTitle, ModalFooter, ModalContent } from 'components/base/Modal' @@ -143,10 +143,8 @@ class HelperComp extends PureComponent { onChange={this.handleChangeName} renderLeft={} onFocus={e => this.handleFocus(e, 'accountName')} + error={accountNameError && t('account:settings.accountName.error')} /> - {accountNameError && ( - {t('account:settings.accountName.error')} - )} diff --git a/static/i18n/en/common.yml b/static/i18n/en/common.yml index c5add684..bef533ac 100644 --- a/static/i18n/en/common.yml +++ b/static/i18n/en/common.yml @@ -6,6 +6,7 @@ confirm: Confirm cancel: Cancel delete: Delete continue: Continue +skipThisStep: Skip This Step chooseWalletPlaceholder: Choose a wallet... currency: Currency selectAccount: Select an account diff --git a/static/i18n/en/password.yml b/static/i18n/en/password.yml index a5464044..86148b07 100644 --- a/static/i18n/en/password.yml +++ b/static/i18n/en/password.yml @@ -5,12 +5,24 @@ warning_3: Warning 3 warning_4: Warning 4 errorMessageIncorrectPassword: The password you entered is incorrect. errorMessageNotMatchingPassword: Passwords don't match. -newPassword: - label: New Password - placeholder: New Password -confirmPassword: - label: Confirm Password - placeholder: Confirm Password -currentPassword: - label: Current Password - placeholder: Current Password +inputFields: + newPassword: + label: Password + placeholder: Password + confirmPassword: + label: Confirm Password + placeholder: Confirm Password + currentPassword: + label: Current Password + placeholder: Current Password +changePassword: + title: Edit Password + subTitle: Change your password + desc: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer non nibh diam. In eget ipsum arcu donec finibus +setPassword: + title: Set Password + subTitle: Set a password to lock your application + desc: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer non nibh diam. In eget ipsum arcu donec finibus +disablePassword: + title: Disable Password + desc: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer non nibh diam. diff --git a/static/i18n/en/settings.yml b/static/i18n/en/settings.yml index 2a48bb9d..d28f2a94 100644 --- a/static/i18n/en/settings.yml +++ b/static/i18n/en/settings.yml @@ -23,22 +23,9 @@ currencies: explorer: Blockchain explorer explorerDesc: Lorem ipsum dolor sit amet profile: - username: Username - usernameDesc: Lorem ipsum dolor sit amet password: Password passwordDesc: Lorem ipsum dolor sit amet changePassword: Change password - passwordModalTitle: Password - passwordModalSubtitle: Set a password to lock your application - passwordModalDesc: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer non nibh diam. - passwordModalPasswordInput: Current password - passwordModalNewPasswordInput: New password - passwordModalRepeatPasswordInput: Repeat password - passwordModalSave: Save - disablePasswordModalTitle: Disable Password - disablePasswordModalDesc: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer non nibh diam. - disablePasswordModalInput: Current password - disablePasswordModalSave: Save sync: Sync accounts syncDesc: Lorem ipsum dolor sit amet export: Export logs From 67de591bb189d3d0c44030958735e9afcae1d9e1 Mon Sep 17 00:00:00 2001 From: Anastasia Poupeney Date: Mon, 11 Jun 2018 17:02:29 +0200 Subject: [PATCH 3/3] removing comments --- src/components/Onboarding/index.js | 1 - src/reducers/onboarding.js | 1 - 2 files changed, 2 deletions(-) diff --git a/src/components/Onboarding/index.js b/src/components/Onboarding/index.js index 92c6dd0e..70e55334 100644 --- a/src/components/Onboarding/index.js +++ b/src/components/Onboarding/index.js @@ -32,7 +32,6 @@ import SelectDevice from './steps/SelectDevice' import SelectPIN from './steps/SelectPIN/index' import WriteSeed from './steps/WriteSeed/index' import GenuineCheck from './steps/GenuineCheck' -// UNTIL IS NEEDED SET PASSWORD IS COMMENTED OUT import SetPassword from './steps/SetPassword' import Analytics from './steps/Analytics' import Finish from './steps/Finish' diff --git a/src/reducers/onboarding.js b/src/reducers/onboarding.js index b9b967a3..7655d877 100644 --- a/src/reducers/onboarding.js +++ b/src/reducers/onboarding.js @@ -93,7 +93,6 @@ const state: OnboardingState = { showBreadcrumb: true, }, }, - // UNTIL IS NEEDED SET PASSWORD IS COMMENTED OUT { name: 'setPassword', label: 'Set Password',