Browse Source

Work on set password

master
meriadec 7 years ago
parent
commit
d58273bb38
No known key found for this signature in database GPG Key ID: 1D2FC2305E2CB399
  1. 2
      src/components/IsUnlocked.js
  2. 156
      src/components/SettingsPage/PasswordModal.js
  3. 2
      src/components/SettingsPage/index.js
  4. 24
      src/components/SettingsPage/sections/Profile.js
  5. 5
      src/reducers/settings.js

2
src/components/IsUnlocked.js

@ -1,10 +1,10 @@
// @flow // @flow
import bcrypt from 'bcryptjs'
import React, { Component } from 'react' import React, { Component } from 'react'
import { connect } from 'react-redux' import { connect } from 'react-redux'
import { compose } from 'redux' import { compose } from 'redux'
import { translate } from 'react-i18next' import { translate } from 'react-i18next'
import bcrypt from 'bcryptjs'
import type { Account } from '@ledgerhq/wallet-common/lib/types' import type { Account } from '@ledgerhq/wallet-common/lib/types'
import type { Settings, T } from 'types/common' import type { Settings, T } from 'types/common'

156
src/components/SettingsPage/PasswordModal.js

@ -1,6 +1,10 @@
// @flow // @flow
import React, { PureComponent } from 'react' import React, { PureComponent } from 'react'
import { connect } from 'react-redux'
import bcrypt from 'bcryptjs'
import { unlock } from 'reducers/application'
import Box from 'components/base/Box' import Box from 'components/base/Box'
import Button from 'components/base/Button' import Button from 'components/base/Button'
@ -10,68 +14,128 @@ import { Modal, ModalContent, ModalBody, ModalTitle, ModalFooter } from 'compone
import type { T } from 'types/common' import type { T } from 'types/common'
const mapDispatchToProps = {
unlock,
}
type Props = { type Props = {
t: T, t: T,
onClose: Function, onClose: Function,
unlock: Function,
isPasswordEnabled: boolean,
currentPasswordHash: string,
onChangePassword: Function,
}
type State = {
currentPassword: string,
newPassword: string,
repeatPassword: string,
} }
class PasswordModal extends PureComponent<Props> { class PasswordModal extends PureComponent<Props, State> {
state = {
currentPassword: '',
newPassword: '',
repeatPassword: '',
}
handleSave = (e: SyntheticEvent<HTMLFormElement>) => {
if (e) {
e.preventDefault()
}
if (!this.isValid()) {
return
}
const { currentPassword, newPassword, repeatPassword } = this.state
const { isPasswordEnabled, currentPasswordHash, onChangePassword } = this.props
if (isPasswordEnabled) {
const calculatedPasswordHash = bcrypt.hashSync(currentPassword, 8)
if (calculatedPasswordHash !== currentPasswordHash) {
return
}
onChangePassword(newPassword)
} else if (newPassword === repeatPassword) {
onChangePassword(newPassword)
}
}
handleInputChange = key => value => this.setState({ [key]: value })
isValid = () => {
const { newPassword, repeatPassword } = this.state
return newPassword && newPassword === repeatPassword
}
render() { render() {
const { t, onClose, ...props } = this.props const { t, isPasswordEnabled, onClose, ...props } = this.props
const isValid = this.isValid()
return ( return (
<Modal <Modal
{...props} {...props}
onClose={onClose} onClose={onClose}
render={({ onClose }) => ( render={({ onClose }) => (
<ModalBody onClose={onClose}> <form onSubmit={this.handleSave}>
<ModalTitle>{t('settings:profile.passwordModalTitle')}</ModalTitle> <ModalBody onClose={onClose}>
<ModalContent> <ModalTitle>{t('settings:profile.passwordModalTitle')}</ModalTitle>
<Box ff="Museo Sans|Regular" color="dark" textAlign="center" mb={2} mt={3}> <ModalContent>
{t('settings:profile.passwordModalSubtitle')} <Box ff="Museo Sans|Regular" color="dark" textAlign="center" mb={2} mt={3}>
</Box> {t('settings:profile.passwordModalSubtitle')}
<Box ff="Open Sans" color="smoke" fontSize={4} textAlign="center" px={4}> </Box>
{t('settings:profile.passwordModalDesc')} <Box ff="Open Sans" color="smoke" fontSize={4} textAlign="center" px={4}>
<Box px={7} mt={4} flow={3}> {t('settings:profile.passwordModalDesc')}
<Box flow={1}> <Box px={7} mt={4} flow={3}>
<Label htmlFor="password"> {isPasswordEnabled && (
{t('settings:profile.passwordModalPasswordInput')} <Box flow={1}>
</Label> <Label htmlFor="password">
<Input {t('settings:profile.passwordModalPasswordInput')}
placeholder={t('settings:profile.passwordModalPasswordInput')} </Label>
autoFocus <Input
id="password" type="password"
/> placeholder={t('settings:profile.passwordModalPasswordInput')}
</Box> autoFocus
<Box flow={1}> id="password"
<Label htmlFor="newPassword"> onChange={this.handleInputChange('currentPassword')}
{t('settings:profile.passwordModalNewPasswordInput')} />
</Label> </Box>
<Input )}
placeholder={t('settings:profile.passwordModalNewPasswordInput')} <Box flow={1}>
id="newPassword" <Label htmlFor="newPassword">
/> {t('settings:profile.passwordModalNewPasswordInput')}
</Box> </Label>
<Box flow={1}> <Input
<Label htmlFor="repeatPassword"> type="password"
{t('settings:profile.passwordModalRepeatPasswordInput')} placeholder={t('settings:profile.passwordModalNewPasswordInput')}
</Label> id="newPassword"
<Input onChange={this.handleInputChange('newPassword')}
placeholder={t('settings:profile.passwordModalRepeatPasswordInput')} />
id="repeatPassword" </Box>
/> <Box flow={1}>
<Label htmlFor="repeatPassword">
{t('settings:profile.passwordModalRepeatPasswordInput')}
</Label>
<Input
type="password"
placeholder={t('settings:profile.passwordModalRepeatPasswordInput')}
id="repeatPassword"
onChange={this.handleInputChange('repeatPassword')}
/>
</Box>
</Box> </Box>
</Box> </Box>
</Box> </ModalContent>
</ModalContent> <ModalFooter horizontal align="center" justify="flex-end" flow={2}>
<ModalFooter horizontal align="center" justify="flex-end" flow={2}> <Button onClick={onClose}>{t('common:cancel')}</Button>
<Button onClick={onClose}>{t('common:cancel')}</Button> <Button primary onClick={this.handleSave} disabled={!isValid}>
<Button primary>{t('settings:profile.passwordModalSave')}</Button> {t('settings:profile.passwordModalSave')}
</ModalFooter> </Button>
</ModalBody> </ModalFooter>
</ModalBody>
</form>
)} )}
/> />
) )
} }
} }
export default PasswordModal export default connect(null, mapDispatchToProps)(PasswordModal)

2
src/components/SettingsPage/index.js

@ -43,7 +43,7 @@ type State = {
class SettingsPage extends PureComponent<Props, State> { class SettingsPage extends PureComponent<Props, State> {
state = { state = {
tab: 0, tab: 2,
} }
_items = [] _items = []

24
src/components/SettingsPage/sections/Profile.js

@ -3,11 +3,12 @@
import React, { PureComponent } from 'react' import React, { PureComponent } from 'react'
import { connect } from 'react-redux' import { connect } from 'react-redux'
import { remote } from 'electron' import { remote } from 'electron'
import bcrypt from 'bcryptjs'
import type { Settings, T } from 'types/common' import type { Settings, T } from 'types/common'
import { unlock } from 'reducers/application' import { unlock } from 'reducers/application'
import db from 'helpers/db' import db, { setEncryptionKey } from 'helpers/db'
import Input from 'components/base/Input' import Input from 'components/base/Input'
import CheckBox from 'components/base/CheckBox' import CheckBox from 'components/base/CheckBox'
@ -32,7 +33,6 @@ type Props = {
t: T, t: T,
settings: Settings, settings: Settings,
saveSettings: Function, saveSettings: Function,
// unlock: Function,
} }
type State = { type State = {
@ -73,6 +73,21 @@ class TabProfile extends PureComponent<Props, State> {
} }
} }
handleChangePassword = (password: ?string) => {
const { saveSettings, unlock } = this.props
const hash = bcrypt.hashSync(password, 8)
setEncryptionKey('accounts', password)
window.requestIdleCallback(() => {
saveSettings({
password: {
isEnabled: hash !== undefined,
value: hash,
},
})
unlock()
})
}
render() { render() {
const { t, settings } = this.props const { t, settings } = this.props
const { username, isHardResetModalOpened, isPasswordModalOpened } = this.state const { username, isHardResetModalOpened, isPasswordModalOpened } = this.state
@ -125,8 +140,11 @@ class TabProfile extends PureComponent<Props, State> {
<PasswordModal <PasswordModal
t={t} t={t}
isOpened={isPasswordModalOpened} isOpened={true || isPasswordModalOpened}
onClose={this.handleClosePasswordModal} onClose={this.handleClosePasswordModal}
onChangePassword={this.handleChangePassword}
isPasswordEnabled={isPasswordEnabled}
currentPasswordHash={settings.password.value}
/> />
</Section> </Section>
) )

5
src/reducers/settings.js

@ -15,7 +15,8 @@ const defaultState: SettingsState = {
language: 'en', language: 'en',
orderAccounts: 'balance|asc', orderAccounts: 'balance|asc',
password: { password: {
state: false, isEnabled: false,
value: '',
}, },
} }
@ -35,7 +36,7 @@ const handlers: Object = {
} }
export const hasPassword = (state: Object) => export const hasPassword = (state: Object) =>
get(state.settings, 'password.state', defaultState.password.state) get(state.settings, 'password.isEnabled', defaultState.password.isEnabled)
export const getCounterValueCode = (state: Object) => export const getCounterValueCode = (state: Object) =>
get(state.settings, 'counterValue', defaultState.counterValue) get(state.settings, 'counterValue', defaultState.counterValue)

Loading…
Cancel
Save