11 changed files with 199 additions and 58 deletions
@ -0,0 +1,100 @@ |
|||||
|
// @flow
|
||||
|
|
||||
|
import React, { PureComponent } from 'react' |
||||
|
import { connect } from 'react-redux' |
||||
|
import bcrypt from 'bcryptjs' |
||||
|
|
||||
|
import type { MapStateToProps } from 'react-redux' |
||||
|
import type { Settings } from 'types/common' |
||||
|
|
||||
|
import get from 'lodash/get' |
||||
|
|
||||
|
import { setEncryptionKey } from 'helpers/db' |
||||
|
|
||||
|
import { fetchAccounts } from 'actions/accounts' |
||||
|
import { isLocked, unlock } from 'reducers/application' |
||||
|
|
||||
|
import Box from 'components/base/Box' |
||||
|
import Input from 'components/base/Input' |
||||
|
|
||||
|
type InputValue = { |
||||
|
password: string, |
||||
|
} |
||||
|
|
||||
|
type Props = { |
||||
|
fetchAccounts: Function, |
||||
|
isLocked: boolean, |
||||
|
render: Function, |
||||
|
settings: Settings, |
||||
|
unlock: Function, |
||||
|
} |
||||
|
type State = { |
||||
|
inputValue: InputValue, |
||||
|
} |
||||
|
|
||||
|
const mapStateToProps: MapStateToProps<*, *, *> = state => ({ |
||||
|
settings: state.settings, |
||||
|
isLocked: isLocked(state), |
||||
|
}) |
||||
|
|
||||
|
const mapDispatchToProps = { |
||||
|
fetchAccounts, |
||||
|
unlock, |
||||
|
} |
||||
|
|
||||
|
class IsUnlocked extends PureComponent<Props, State> { |
||||
|
state = { |
||||
|
inputValue: { |
||||
|
password: '', |
||||
|
}, |
||||
|
} |
||||
|
|
||||
|
handleChangeInput = (key: $Keys<InputValue>) => (value: $Values<InputValue>) => |
||||
|
this.setState(prev => ({ |
||||
|
inputValue: { |
||||
|
...prev.inputValue, |
||||
|
[key]: value, |
||||
|
}, |
||||
|
})) |
||||
|
|
||||
|
handleSubmit = (e: SyntheticEvent<HTMLFormElement>) => { |
||||
|
e.preventDefault() |
||||
|
|
||||
|
const { settings, unlock, fetchAccounts } = this.props |
||||
|
const { inputValue } = this.state |
||||
|
|
||||
|
if (bcrypt.compareSync(inputValue.password, get(settings, 'password.value'))) { |
||||
|
setEncryptionKey('accounts', inputValue.password) |
||||
|
fetchAccounts() |
||||
|
unlock() |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
render() { |
||||
|
const { inputValue } = this.state |
||||
|
const { isLocked, render } = this.props |
||||
|
|
||||
|
if (isLocked) { |
||||
|
return ( |
||||
|
<Box sticky align="center" justify="center"> |
||||
|
<form onSubmit={this.handleSubmit}> |
||||
|
<Box> |
||||
|
<Input |
||||
|
placeholder="Password" |
||||
|
type="password" |
||||
|
onChange={this.handleChangeInput('password')} |
||||
|
value={inputValue.password} |
||||
|
/> |
||||
|
</Box> |
||||
|
</form> |
||||
|
</Box> |
||||
|
) |
||||
|
} |
||||
|
|
||||
|
return render() |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
export default connect(mapStateToProps, mapDispatchToProps, null, { |
||||
|
pure: false, |
||||
|
})(IsUnlocked) |
@ -1,29 +1,24 @@ |
|||||
import Store from 'electron-store' |
import Store from 'electron-store' |
||||
|
|
||||
export default { |
const encryptionKey = {} |
||||
accounts: (accounts, options = {}) => { |
|
||||
const db = new Store({ |
|
||||
name: 'accounts', |
|
||||
defaults: {}, |
|
||||
...options, |
|
||||
}) |
|
||||
|
|
||||
if (accounts) { |
const store = type => |
||||
db.store = accounts |
new Store({ |
||||
} |
name: type, |
||||
|
defaults: {}, |
||||
|
encryptionKey: encryptionKey[type], |
||||
|
}) |
||||
|
|
||||
return db.store |
export function setEncryptionKey(type, value) { |
||||
}, |
encryptionKey[type] = value |
||||
settings: settings => { |
} |
||||
const db = new Store({ |
|
||||
name: 'settings', |
export default (type, values) => { |
||||
defaults: {}, |
const db = store(type) |
||||
}) |
|
||||
|
|
||||
if (settings) { |
if (values) { |
||||
db.store = settings |
db.store = values |
||||
} |
} |
||||
|
|
||||
return db.store |
return db.store |
||||
}, |
|
||||
} |
} |
||||
|
@ -0,0 +1,32 @@ |
|||||
|
// @flow
|
||||
|
|
||||
|
import { handleActions, createAction } from 'redux-actions' |
||||
|
|
||||
|
import get from 'lodash/get' |
||||
|
|
||||
|
export type ApplicationState = {} |
||||
|
|
||||
|
const state: ApplicationState = {} |
||||
|
|
||||
|
const handlers = { |
||||
|
APPLICATION_SET_DATA: (state, { payload }: { payload: ApplicationState }) => ({ |
||||
|
...state, |
||||
|
...payload, |
||||
|
}), |
||||
|
} |
||||
|
|
||||
|
// Actions
|
||||
|
|
||||
|
export const unlock = createAction('APPLICATION_SET_DATA', () => ({ isLocked: false })) |
||||
|
export const lock = createAction('APPLICATION_SET_DATA', () => ({ isLocked: true })) |
||||
|
|
||||
|
// Selectors
|
||||
|
|
||||
|
export const isLocked = (state: Object) => |
||||
|
state.application.isLocked === undefined |
||||
|
? get(state.settings, 'password.state', false) |
||||
|
: state.application.isLocked |
||||
|
|
||||
|
// Exporting reducer
|
||||
|
|
||||
|
export default handleActions(handlers, state) |
Loading…
Reference in new issue