Browse Source

Merge pull request #503 from NastiaS/passwordBranch

Password branch
master
Meriadec Pillet 7 years ago
committed by GitHub
parent
commit
da80beae76
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 19
      src/components/IsUnlocked.js
  2. 46
      src/components/Onboarding/index.js
  3. 34
      src/components/Onboarding/steps/Analytics.js
  4. 247
      src/components/Onboarding/steps/SetPassword.js
  5. 21
      src/components/SettingsPage/DisablePasswordModal.js
  6. 89
      src/components/SettingsPage/PasswordForm.js
  7. 136
      src/components/SettingsPage/PasswordModal.js
  8. 7
      src/components/base/Input/index.js
  9. 6
      src/components/modals/AccountSettingRenderBody.js
  10. 19
      src/reducers/onboarding.js
  11. 1
      static/i18n/en/common.yml
  12. 8
      static/i18n/en/onboarding.yml
  13. 22
      static/i18n/en/password.yml
  14. 13
      static/i18n/en/settings.yml

19
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<Props, State> {
}
}
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 (
<Box sticky alignItems="center" justifyContent="center" onClick={this.handleFocusInput}>
<Box sticky alignItems="center" justifyContent="center">
<form onSubmit={this.handleSubmit}>
<Box align="center">
<IconLockScreen size={136} />
@ -146,17 +136,12 @@ class IsUnlocked extends Component<Props, State> {
<Box style={{ minWidth: 230 }}>
<InputPassword
autoFocus
innerRef={(n: any) => (this._input = n)}
placeholder={t('common:lockScreen.inputPlaceholder')}
type="password"
onChange={this.handleChangeInput('password')}
value={inputValue.password}
error={incorrectPassword && t('password:errorMessageIncorrectPassword')}
/>
{incorrectPassword && (
<ErrorMessageInput>
{t('password:errorMessageIncorrectPassword')}
</ErrorMessageInput>
)}
</Box>
</Box>
</form>

46
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'
@ -31,8 +32,7 @@ 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 SetPassword from './steps/SetPassword'
import Analytics from './steps/Analytics'
import Finish from './steps/Finish'
@ -42,7 +42,7 @@ const STEPS = {
selectPIN: SelectPIN,
writeSeed: WriteSeed,
genuineCheck: GenuineCheck,
// setPassword: SetPassword,
setPassword: SetPassword,
analytics: Analytics,
finish: Finish,
start: Start,
@ -51,6 +51,7 @@ const STEPS = {
const mapStateToProps = state => ({
hasCompletedOnboarding: state.settings.hasCompletedOnboarding,
onboarding: state.onboarding,
settings: state.settings,
getCurrentDevice: getCurrentDevice(state),
})
@ -59,7 +60,7 @@ const mapDispatchToProps = {
nextStep,
prevStep,
jumpStep,
// unlock,
unlock,
}
type Props = {
@ -67,6 +68,7 @@ type Props = {
hasCompletedOnboarding: boolean,
saveSettings: Function,
onboarding: OnboardingState,
settings: SettingsState,
prevStep: Function,
nextStep: Function,
jumpStep: Function,
@ -77,12 +79,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 +95,26 @@ export type StepProps = {
class Onboarding extends PureComponent<Props> {
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 +130,7 @@ class Onboarding extends PureComponent<Props> {
const stepProps: StepProps = {
t,
onboarding,
settings,
updateGenuineCheck,
isLedgerNano,
flowType,
@ -126,7 +138,7 @@ class Onboarding extends PureComponent<Props> {
nextStep,
jumpStep,
finish: this.finish,
// savePassword: this.savePassword,
savePassword: this.savePassword,
getDeviceInfo: this.getDeviceInfo,
saveSettings,
}

34
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<StepProps, State> {
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<StepProps, State> {
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<StepProps, State> {
flow={2}
t={t}
nextStep={nextStep}
prevStep={prevStep}
prevStep={this.handleNavBack}
isContinueDisabled={!termsConditionsToggle}
/>
</Box>
@ -93,10 +100,7 @@ class Analytics extends PureComponent<StepProps, State> {
}
}
export default connect(
null,
mapDispatchToProps,
)(Analytics)
export default Analytics
export const AnalyticsText = styled(Box).attrs({
ff: 'Open Sans|Regular',

247
src/components/Onboarding/steps/SetPassword.js

@ -1,93 +1,154 @@
// 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<StepProps, State> {
// 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 (
// <Box sticky pt={150}>
// <Box grow alignItems="center">
// <Title>{t('onboarding:setPassword.title')}</Title>
// <Description>{t('onboarding:setPassword.desc')}</Description>
// <IconSetPassword />
// <Box style={{ paddingTop: 35 }}>
// <Button small primary onClick={() => this.handleOpenPasswordModal()}>
// Set Password
// </Button>
// </Box>
// {/* 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 && (
// <PasswordModal
// t={t}
// isOpened={isPasswordModalOpened}
// onClose={this.handleClosePasswordModal}
// onChangePassword={this.handleChangePassword}
// isPasswordEnabled={isPasswordEnabled}
// currentPasswordHash=""
// />
// )}
// <Box onClick={() => nextStep()} style={{ padding: 15 }}>
// <Button>Skip this step</Button>
// </Box>
// </Box>
// <OnboardingFooter
// horizontal
// align="center"
// flow={2}
// t={t}
// nextStep={nextStep}
// prevStep={prevStep}
// />
// </Box>
// )
// }
// }
//
// export default SetPassword
// @flow
import React, { PureComponent, Fragment } from 'react'
import bcrypt from 'bcryptjs'
import { colors, radii } from 'styles/theme'
import styled from 'styled-components'
import { setEncryptionKey } from 'helpers/db'
import Box from 'components/base/Box'
import Button from 'components/base/Button'
import IconChevronRight from 'icons/ChevronRight'
import PasswordForm from '../../SettingsPage/PasswordForm'
import type { StepProps } from '..'
import { Title, Description, DisclaimerBox } from '../helperComponents'
type State = {
currentPassword: string,
newPassword: string,
confirmPassword: string,
incorrectPassword: boolean,
}
const INITIAL_STATE = {
currentPassword: '',
newPassword: '',
confirmPassword: '',
incorrectPassword: false,
}
class SetPassword extends PureComponent<StepProps, State> {
state = INITIAL_STATE
handleSave = (e: SyntheticEvent<HTMLFormElement>) => {
if (e) {
e.preventDefault()
}
if (!this.isValid()) {
return
}
const { newPassword } = this.state
const { nextStep, savePassword } = this.props
setEncryptionKey('accounts', newPassword)
const hash = newPassword ? bcrypt.hashSync(newPassword, 8) : undefined
savePassword(hash)
this.handleReset()
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
}
render() {
const { nextStep, prevStep, t, settings } = this.props
const { newPassword, currentPassword, incorrectPassword, confirmPassword } = this.state
const isPasswordEnabled = settings.password.isEnabled === true
const disclaimerNotes = [
{
key: 'note1',
icon: <IconChevronRight size={12} style={{ color: colors.smoke }} />,
desc: t('onboarding:setPassword.disclaimer.note1'),
},
{
key: 'note2',
icon: <IconChevronRight size={12} style={{ color: colors.smoke }} />,
desc: t('onboarding:setPassword.disclaimer.note2'),
},
{
key: 'note3',
icon: <IconChevronRight size={12} style={{ color: colors.smoke }} />,
desc: t('onboarding:setPassword.disclaimer.note3'),
},
]
return (
<Box sticky pt={50}>
<Box grow alignItems="center" justify="center">
<Fragment>
<Box mb={3} alignItems="center">
<Title>{t('onboarding:setPassword.title')}</Title>
<Description style={{ maxWidth: 620 }}>
{t('onboarding:setPassword.desc')}
</Description>
</Box>
<Box align="center" mt={2}>
<PasswordForm
onSubmit={this.handleSave}
isPasswordEnabled={isPasswordEnabled}
newPassword={newPassword}
currentPassword={currentPassword}
confirmPassword={confirmPassword}
incorrectPassword={incorrectPassword}
isValid={this.isValid}
onChange={this.handleInputChange}
t={t}
/>
<DisclaimerBox mt={7} disclaimerNotes={disclaimerNotes} />
</Box>
</Fragment>
</Box>
<CustomFooter>
<Button padded outlineGrey onClick={() => prevStep()}>
{t('common:back')}
</Button>
<Box horizontal ml="auto">
<Button padded disabled={false} onClick={() => nextStep()} mx={2}>
{t('common:skipThisStep')}
</Button>
<Button
padded
onClick={this.handleSave}
disabled={!this.isValid() || !newPassword.length || !confirmPassword.length}
primary
>
{t('common:continue')}
</Button>
</Box>
</CustomFooter>
</Box>
)
}
}
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;
`

21
src/components/SettingsPage/DisablePasswordModal.js

@ -7,7 +7,6 @@ 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 { Modal, ModalContent, ModalBody, ModalTitle, ModalFooter } from 'components/base/Modal'
import type { T } from 'types/common'
@ -30,6 +29,7 @@ const INITIAL_STATE = {
incorrectPassword: false,
}
// TODO: combine with the refactored password form
class DisablePasswordModal extends PureComponent<Props, State> {
state = INITIAL_STATE
@ -71,44 +71,41 @@ class DisablePasswordModal extends PureComponent<Props, State> {
render={({ onClose }) => (
<form onSubmit={this.disablePassword}>
<ModalBody onClose={onClose}>
<ModalTitle>{t('settings:profile.disablePasswordModalTitle')}</ModalTitle>
<ModalTitle>{t('password:disablePassword.title')}</ModalTitle>
<ModalContent>
<Box ff="Open Sans" color="smoke" fontSize={4} textAlign="center" px={4}>
{t('settings:profile.disablePasswordModalDesc')}
{t('password:disablePassword.desc')}
<Box px={7} mt={4} flow={3}>
{isPasswordEnabled && (
<Box flow={1}>
<Label htmlFor="password">
{t('settings:profile.disablePasswordModalInput')}
{t('password:inputFields.currentPassword.label')}
</Label>
<InputPassword
autoFocus
type="password"
placeholder={t('settings:profile.disablePasswordModalInput')}
placeholder={t('password:inputFields.currentPassword.placeholder')}
id="password"
onChange={this.handleInputChange('currentPassword')}
value={currentPassword}
error={incorrectPassword && t('password:errorMessageIncorrectPassword')}
/>
{incorrectPassword && (
<ErrorMessageInput>
{t('password:errorMessageIncorrectPassword')}
</ErrorMessageInput>
)}
</Box>
)}
</Box>
</Box>
</ModalContent>
<ModalFooter horizontal align="center" justify="flex-end" flow={2}>
<Button type="button" onClick={onClose}>
<Button type="button" padded onClick={onClose}>
{t('common:cancel')}
</Button>
<Button
primary
padded
onClick={this.disablePassword}
disabled={!currentPassword && !incorrectPassword}
>
{t('settings:profile.disablePasswordModalSave')}
{t('common:save')}
</Button>
</ModalFooter>
</ModalBody>

89
src/components/SettingsPage/PasswordForm.js

@ -0,0 +1,89 @@
// @flow
import React, { PureComponent } from 'react'
import Box from 'components/base/Box'
import InputPassword from 'components/base/InputPassword'
import Label from 'components/base/Label'
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,
}
class PasswordForm extends PureComponent<Props> {
render() {
const {
t,
isPasswordEnabled,
currentPassword,
newPassword,
incorrectPassword,
confirmPassword,
isValid,
onChange,
onSubmit,
} = this.props
// TODO: adjust design to separate 3 fields
return (
<form onSubmit={onSubmit}>
<Box px={7} mt={4} flow={3}>
{isPasswordEnabled && (
<Box flow={1} mb={5}>
<Label htmlFor="currentPassword">
{t('password:inputFields.currentPassword.label')}
</Label>
<InputPassword
autoFocus
placeholder={t('password:inputFields.currentPassword.placeholder')}
id="currentPassword"
onChange={onChange('currentPassword')}
value={currentPassword}
error={incorrectPassword && t('password:errorMessageIncorrectPassword')}
/>
</Box>
)}
<Box flow={1}>
<Label htmlFor="newPassword">{t('password:inputFields.newPassword.label')}</Label>
<InputPassword
style={{ mt: 4, width: 240 }}
autoFocus={!isPasswordEnabled}
placeholder={t('password:inputFields.newPassword.placeholder')}
id="newPassword"
onChange={onChange('newPassword')}
value={newPassword}
/>
</Box>
<Box flow={1}>
<Label htmlFor="confirmPassword">
{t('password:inputFields.confirmPassword.label')}
</Label>
<InputPassword
style={{ width: 240 }}
placeholder={t('password:inputFields.confirmPassword.placeholder')}
id="confirmPassword"
onChange={onChange('confirmPassword')}
value={confirmPassword}
error={
!isValid() &&
confirmPassword.length > 0 &&
t('password:errorMessageNotMatchingPassword')
}
/>
</Box>
</Box>
</form>
)
}
}
export default PasswordForm

136
src/components/SettingsPage/PasswordModal.js

@ -1,42 +1,35 @@
// @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 type { T } from 'types/common'
const mapDispatchToProps = {
unlock,
}
import PasswordForm from './PasswordForm'
type Props = {
t: T,
onClose: Function,
unlock: Function,
onClose: () => void,
onChangePassword: (?string) => void,
isPasswordEnabled: boolean,
currentPasswordHash: string,
onChangePassword: Function,
}
type State = {
currentPassword: string,
newPassword: string,
confirmPassword: string,
incorrectPassword: boolean,
}
const INITIAL_STATE = {
currentPassword: '',
newPassword: '',
confirmPassword: '',
incorrectPassword: false,
}
@ -44,13 +37,15 @@ class PasswordModal extends PureComponent<Props, State> {
state = INITIAL_STATE
handleSave = (e: SyntheticEvent<HTMLFormElement>) => {
const { currentPassword, newPassword } = this.state
if (e) {
e.preventDefault()
}
if (!this.isValid()) {
return
}
const { currentPassword, newPassword } = this.state
const { isPasswordEnabled, currentPasswordHash, onChangePassword } = this.props
if (isPasswordEnabled) {
if (!bcrypt.compareSync(currentPassword, currentPasswordHash)) {
@ -73,85 +68,66 @@ class PasswordModal extends PureComponent<Props, State> {
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 } = this.state
const isValid = this.isValid()
const { currentPassword, newPassword, incorrectPassword, confirmPassword } = this.state
return (
<Modal
{...props}
onHide={this.handleReset}
onClose={onClose}
render={({ onClose }) => (
<form onSubmit={this.handleSave}>
<ModalBody onClose={onClose}>
<ModalTitle>{t('settings:profile.passwordModalTitle')}</ModalTitle>
<ModalContent>
<Box ff="Museo Sans|Regular" color="dark" textAlign="center" mb={2} mt={3}>
{t('settings:profile.passwordModalSubtitle')}
</Box>
<Box ff="Open Sans" color="smoke" fontSize={4} textAlign="center" px={4}>
{t('settings:profile.passwordModalDesc')}
<Box px={7} mt={4} flow={3}>
{isPasswordEnabled && (
<Box flow={1}>
<Label htmlFor="password">
{t('settings:profile.passwordModalPasswordInput')}
</Label>
<InputPassword
autoFocus
type="password"
placeholder={t('settings:profile.passwordModalPasswordInput')}
id="password"
onChange={this.handleInputChange('currentPassword')}
value={currentPassword}
/>
{incorrectPassword && (
<ErrorMessageInput>
{t('password:errorMessageIncorrectPassword')}
</ErrorMessageInput>
)}
</Box>
)}
<Box flow={1}>
{isPasswordEnabled && (
<Label htmlFor="newPassword">
{t('settings:profile.passwordModalNewPasswordInput')}
</Label>
)}
<InputPassword
autoFocus={!isPasswordEnabled}
placeholder={t('settings:profile.passwordModalNewPasswordInput')}
id="newPassword"
onChange={this.handleInputChange('newPassword')}
value={newPassword}
withStrength
/>
</Box>
</Box>
</Box>
</ModalContent>
<ModalFooter horizontal align="center" justify="flex-end" flow={2}>
<Button type="button" onClick={onClose}>
{t('common:cancel')}
</Button>
<Button primary onClick={this.handleSave} disabled={!isValid}>
{t('settings:profile.passwordModalSave')}
</Button>
</ModalFooter>
</ModalBody>
</form>
<ModalBody onClose={onClose}>
{isPasswordEnabled ? (
<ModalTitle>{t('password:changePassword.title')}</ModalTitle>
) : (
<ModalTitle>{t('password:setPassword.title')}</ModalTitle>
)}
<ModalContent>
<Box ff="Museo Sans|Regular" color="dark" textAlign="center" mb={2} mt={3}>
{isPasswordEnabled
? t('password:changePassword.subTitle')
: t('password:setPassword.subTitle')}
</Box>
<Box ff="Open Sans" color="smoke" fontSize={4} textAlign="center" px={4}>
{isPasswordEnabled
? t('password:changePassword.desc')
: t('password:setPassword.desc')}
</Box>
<PasswordForm
onSubmit={this.handleSave}
isPasswordEnabled={isPasswordEnabled}
newPassword={newPassword}
currentPassword={currentPassword}
confirmPassword={confirmPassword}
incorrectPassword={incorrectPassword}
isValid={this.isValid}
onChange={this.handleInputChange}
t={t}
/>
</ModalContent>
<ModalFooter horizontal align="center" justify="flex-end" flow={2}>
<Button type="button" padded onClick={onClose}>
{t('common:cancel')}
</Button>
<Button
padded
primary
onClick={this.handleSave}
disabled={!this.isValid() || !newPassword.length || !confirmPassword.length}
>
{t('common:save')}
</Button>
</ModalFooter>
</ModalBody>
)}
/>
)
}
}
export default connect(
null,
mapDispatchToProps,
)(PasswordModal)
export default PasswordModal

7
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,

6
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<Props, State> {
onChange={this.handleChangeName}
renderLeft={<InputLeft currency={account.currency} />}
onFocus={e => this.handleFocus(e, 'accountName')}
error={accountNameError && t('account:settings.accountName.error')}
/>
{accountNameError && (
<ErrorMessageInput>{t('account:settings.accountName.error')}</ErrorMessageInput>
)}
</Box>
</Container>
<Container>

19
src/reducers/onboarding.js

@ -93,16 +93,15 @@ const state: OnboardingState = {
showBreadcrumb: true,
},
},
// 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',

1
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

8
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

22
static/i18n/en/password.yml

@ -4,3 +4,25 @@ warning_2: Warning 2
warning_3: Warning 3
warning_4: Warning 4
errorMessageIncorrectPassword: The password you entered is incorrect.
errorMessageNotMatchingPassword: Passwords don't match.
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.

13
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

Loading…
Cancel
Save