This repository has been archived by the owner on Apr 15, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 60
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #737 from LiskHQ/559-remeber-account
Add option to remember account for read-only access - Closes #559
- Loading branch information
Showing
43 changed files
with
917 additions
and
350 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
Feature: Account management | ||
Scenario: should allow to save account locally, after page reload it should require passphrase to do the first transaction, and remember the passphrase for next transactions | ||
Given I'm logged in as "genesis" | ||
When I click "save account" in main menu | ||
And I click "save account button" | ||
And I wait 1 seconds | ||
And I should see text "Account saved" in "toast" element | ||
And I Refresh the page | ||
And I wait 2 seconds | ||
Then I should be logged in | ||
And I click "send button" | ||
And I should see empty "passphrase" field | ||
And I fill in "1" to "amount" field | ||
And I fill in "537318935439898807L" to "recipient" field | ||
And I fill in passphrase of "genesis" to "passphrase" field | ||
And I click "submit button" | ||
And I click "ok button" | ||
And I wait 1 seconds | ||
And I click "send button" | ||
And I fill in "2" to "amount" field | ||
And I fill in "537318935439898807L" to "recipient" field | ||
And I click "submit button" | ||
And I should see alert dialog with title "Success" and text "Your transaction of 2 LSK to 537318935439898807L was accepted and will be processed in a few seconds." | ||
|
||
Scenario: should allow to forget locally saved account | ||
Given I'm logged in as "any account" | ||
When I click "save account" in main menu | ||
And I click "save account button" | ||
And I Refresh the page | ||
And I wait 2 seconds | ||
And I click "forget account" in main menu | ||
And I wait 1 seconds | ||
Then I should see text "Account was successfully forgotten." in "toast" element | ||
And I Refresh the page | ||
And I should be on login page | ||
|
||
Scenario: should allow to exit save account dialog with "cancel button" | ||
Given I'm logged in as "any account" | ||
When I click "save account" in main menu | ||
And I click "cancel button" | ||
Then I should see no "modal dialog" | ||
|
||
Scenario: should allow to exit save account dialog with "x button" | ||
Given I'm logged in as "any account" | ||
When I click "save account" in main menu | ||
And I click "x button" | ||
Then I should see no "modal dialog" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -71,6 +71,7 @@ | |
position: absolute; | ||
top: 5px; | ||
right: 5px; | ||
z-index: 1; | ||
} | ||
} | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
import React from 'react'; | ||
import PassphraseInput from '../passphraseInput'; | ||
import { extractPublicKey } from '../../utils/api/account'; | ||
|
||
class AuthInputs extends React.Component { | ||
componentDidMount() { | ||
if (this.props.account.secondSignature) { | ||
this.props.onChange('secondPassphrase', ''); | ||
} | ||
} | ||
|
||
onChange(name, value, error) { | ||
if (!error) { | ||
const publicKeyMap = { | ||
passphrase: 'publicKey', | ||
secondPassphrase: 'secondPublicKey', | ||
}; | ||
const expectedPublicKey = this.props.account[publicKeyMap[name]]; | ||
|
||
if (expectedPublicKey && expectedPublicKey !== extractPublicKey(value)) { | ||
error = 'Entered passphrase does not belong to the active account'; | ||
} | ||
} | ||
this.props.onChange(name, value, error); | ||
} | ||
|
||
render() { | ||
return <span> | ||
{(!this.props.account.passphrase && | ||
<PassphraseInput label='Passphrase' | ||
className='passphrase' | ||
error={this.props.passphrase.error} | ||
value={this.props.passphrase.value} | ||
onChange={this.onChange.bind(this, 'passphrase')} />)} | ||
{(this.props.account.secondSignature && | ||
<PassphraseInput label='Second Passphrase' | ||
className='second-passphrase' | ||
error={this.props.secondPassphrase.error} | ||
value={this.props.secondPassphrase.value} | ||
onChange={this.onChange.bind(this, 'secondPassphrase')} />)} | ||
</span>; | ||
} | ||
} | ||
|
||
export default AuthInputs; | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
import React from 'react'; | ||
import { expect } from 'chai'; | ||
import { mount } from 'enzyme'; | ||
import sinon from 'sinon'; | ||
import AuthInputs from './authInputs'; | ||
|
||
|
||
describe('AuthInputs', () => { | ||
let wrapper; | ||
let props; | ||
const passphrase = 'recipe bomb asset salon coil symbol tiger engine assist pact pumpkin visit'; | ||
|
||
beforeEach(() => { | ||
props = { | ||
onChange: sinon.spy(), | ||
secondPassphrase: { }, | ||
account: { | ||
passphrase, | ||
}, | ||
passphrase: { | ||
value: passphrase, | ||
}, | ||
}; | ||
}); | ||
|
||
it('should render Input if props.account.secondSignature', () => { | ||
props.account.secondSignature = true; | ||
wrapper = mount(<AuthInputs {...props} />); | ||
expect(wrapper.find('Input')).to.have.lengthOf(1); | ||
}); | ||
|
||
it('should render null if !props.account.secondSignature', () => { | ||
props.account.secondSignature = false; | ||
wrapper = mount(<AuthInputs {...props} />); | ||
expect(wrapper.html()).to.equal('<span></span>'); | ||
}); | ||
|
||
it('should render null if !props.account.secondSignature', () => { | ||
props.account.secondSignature = false; | ||
wrapper = mount(<AuthInputs {...props} />); | ||
expect(wrapper.html()).to.equal('<span></span>'); | ||
}); | ||
|
||
it('should call props.onChange when input value changes', () => { | ||
props.account.secondSignature = true; | ||
wrapper = mount(<AuthInputs {...props} />); | ||
wrapper.find('.second-passphrase input').simulate('change', { target: { value: passphrase } }); | ||
expect(props.onChange).to.have.been.calledWith('secondPassphrase', passphrase); | ||
}); | ||
|
||
it('should call props.onChange with an error if entered secondPassphrase does not belong to secondPublicKey', () => { | ||
const error = 'Entered passphrase does not belong to the active account'; | ||
props.account.secondSignature = true; | ||
props.account.secondPublicKey = 'fab9d261ea050b9e326d7e11587eccc343a20e64e29d8781b50fd06683cacc88'; | ||
wrapper = mount(<AuthInputs {...props} />); | ||
wrapper.find('.second-passphrase input').simulate('change', { target: { value: passphrase } }); | ||
expect(props.onChange).to.have.been.calledWith('secondPassphrase', passphrase, error); | ||
}); | ||
|
||
it('should call props.onChange(\'secondPassphrase\', \'Required\') when input value changes to \'\'', () => { | ||
props.account.secondSignature = true; | ||
wrapper = mount(<AuthInputs {...props} />); | ||
wrapper.find('.second-passphrase input').simulate('change', { target: { value: '' } }); | ||
expect(props.onChange).to.have.been.calledWith('secondPassphrase', '', 'Required'); | ||
}); | ||
|
||
it('should call props.onChange(\'secondPassphrase\', \'Invalid passphrase\') when input value changes to \'test\'', () => { | ||
props.account.secondSignature = true; | ||
wrapper = mount(<AuthInputs {...props} />); | ||
wrapper.find('.second-passphrase input').simulate('change', { target: { value: 'test' } }); | ||
expect(props.onChange).to.have.been.calledWith('secondPassphrase', 'test', 'Passphrase should have 12 words, entered passphrase has 1'); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import { connect } from 'react-redux'; | ||
import AuthInputs from './authInputs'; | ||
|
||
const mapStateToProps = state => ({ | ||
account: state.account, | ||
}); | ||
|
||
export default connect(mapStateToProps)(AuthInputs); | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import React from 'react'; | ||
import { expect } from 'chai'; | ||
import { mount } from 'enzyme'; | ||
import { Provider } from 'react-redux'; | ||
import configureMockStore from 'redux-mock-store'; | ||
import AuthInputsHOC from './index'; | ||
|
||
describe('AuthInputsHOC', () => { | ||
let wrapper; | ||
const passphrase = 'recipe bomb asset salon coil symbol tiger engine assist pact pumpkin visit'; | ||
const props = { | ||
onChange: () => {}, | ||
secondPassphrase: {}, | ||
}; | ||
const account = { | ||
secondSignature: 1, | ||
passphrase, | ||
}; | ||
|
||
it('should render AuthInputs with props.account equal to state.account ', () => { | ||
const store = configureMockStore([])({ account }); | ||
wrapper = mount(<Provider store={store}> | ||
<AuthInputsHOC {...props}/> | ||
</Provider>); | ||
expect(wrapper.find('AuthInputs').props().account).to.deep.equal(account); | ||
}); | ||
}); |
Oops, something went wrong.