Skip to content

Commit

Permalink
Merge pull request #208 from cosmos/fabo/144-fix-sign-in-flow
Browse files Browse the repository at this point in the history
Fix sign in flow
  • Loading branch information
mappum authored Dec 8, 2017
2 parents 718be8f + 0ab8577 commit 3a56aae
Show file tree
Hide file tree
Showing 22 changed files with 88 additions and 154 deletions.
8 changes: 7 additions & 1 deletion app/src/renderer/components/common/NiFieldSeed.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
<template lang="pug">
field.ni-field-seed(
type="textarea"
v-model="value")
@input="update($event)"
:value="value")
</template>

<script>
Expand All @@ -11,6 +12,11 @@ export default {
components: {
Field
},
methods: {
update (value) {
this.$emit('input', value)
}
},
props: ['value']
}
</script>
Expand Down
2 changes: 1 addition & 1 deletion app/src/renderer/components/common/NiSession.vue
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ export default {
&:not(.ni-form)
&.ni-form .ni-form-main
width 32rem
height 32rem
height 36rem
.ni-session-header
background app-fg
Expand Down
6 changes: 3 additions & 3 deletions app/src/renderer/components/common/NiSessionAccountDelete.vue
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<template lang="pug">
.ni-session: form-struct(:submit='onSubmit').ni-session-container
.ni-session-header
a(@click="setState('welcome')"): i.material-icons arrow_back
.ni-session-title Enter Password
a(@click="setState('sign-in')"): i.material-icons arrow_back
.ni-session-title Remove Account
a(@click="help"): i.material-icons help_outline
.ni-session-main
form-group(:error='$v.fields.deletionPassword.$error'
Expand All @@ -23,7 +23,7 @@
| I understand that Cosmos cannot recover deleted accounts without the passphrase.
form-msg(name='Deletion confirmation' type='required' v-if='!$v.fields.deletionWarning.required')
.ni-session-footer
btn(icon="exit_to_app" value="Sign In" size="lg")
btn(icon="exit_to_app" value="Sign Out and Remove Account" size="lg")
</template>

<script>
Expand Down
2 changes: 1 addition & 1 deletion app/src/renderer/components/common/NiSessionHardware.vue
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export default {
onSubmit () {
this.$store.commit('setModalSession', false)
this.$store.commit('notify', { title: 'Welcome back!', body: 'You are now signed in to your Cosmos account.' })
this.$store.commit('signIn', {password: this.fields.signInPassword})
this.$store.dispatch('signIn', {password: this.fields.signInPassword})
}
}
}
Expand Down
5 changes: 3 additions & 2 deletions app/src/renderer/components/common/NiSessionRestore.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
form-group(:error='$v.fields.restoreSeed.$error'
field-id='restore-seed' field-label='Seed')
field-seed#restore-seed(
v-model="fields.restoreSeed"
:value="fields.restoreSeed"
@input="val => fields.restoreSeed = val"
placeholder="must be exactly 12 words")
form-msg(name='Seed' type='required' v-if='!$v.fields.restoreSeed.required')

Expand Down Expand Up @@ -61,7 +62,7 @@ export default {
if (key) {
this.$store.commit('setModalSession', false)
this.$store.commit('notify', { title: 'Welcome back!', body: 'Your account has been successfully restored.' })
this.$store.commit('signIn', {password: this.fields.signInPassword})
this.$store.dispatch('signIn', {password: this.fields.signInPassword})
}
}
},
Expand Down
10 changes: 8 additions & 2 deletions app/src/renderer/components/common/NiSessionSignIn.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
<template lang="pug">
.ni-session: form-struct(:submit='onSubmit').ni-session-container
.ni-session-header
a(@click="setState('welcome')"): i.material-icons arrow_back
.ni-session-title Sign In
a(@click="help"): i.material-icons help_outline
.ni-session-main
Expand All @@ -12,6 +11,8 @@
v-model="fields.signInPassword")
form-msg(name='Password' type='required' v-if='!$v.fields.signInPassword.required')
form-msg(name='Password' type='minLength' min="10" v-if='!$v.fields.signInPassword.minLength')
form-group
a(@click="setState('delete')") Sign Out and Remove Account
.ni-session-footer
btn(icon="arrow_forward" icon-pos="right" value="Next" size="lg")
</template>
Expand Down Expand Up @@ -47,7 +48,7 @@ export default {
if (this.$v.$error) return
try {
await this.$store.dispatch('testLogin', {password: this.fields.signInPassword})
this.$store.commit('signIn', {password: this.fields.signInPassword})
this.$store.dispatch('signIn', {password: this.fields.signInPassword})
this.$store.commit('setModalSession', false)
this.$store.commit('notify', { title: 'Signed In', body: `You are now signed in to your Cosmos account.` })
} catch (err) {
Expand All @@ -65,3 +66,8 @@ export default {
})
}
</script>
<style lang="stylus">
.ni-form-group
a
cursor pointer
</style>
3 changes: 2 additions & 1 deletion app/src/renderer/components/common/NiSessionSignUp.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
.ni-session-main
form-group(field-id='sign-up-seed' field-label='Seed (write it down)')
field-seed#sign-up-seed(v-model="fields.signUpSeed" disabled)
form-msg(body='Please back up the seed phrase for this account. These words cannot be recovered!')

form-group(:error='$v.fields.signInPassword.$error'
field-id='sign-in-password' field-label='Password')
Expand Down Expand Up @@ -78,7 +79,7 @@ export default {
if (key) {
this.$store.commit('setModalSession', false)
this.$store.commit('notify', { title: 'Signed Up', body: 'Your account has been created.' })
this.$store.commit('signIn', {password: this.fields.signInPassword})
this.$store.dispatch('signIn', {password: this.fields.signInPassword})
}
}
},
Expand Down
14 changes: 2 additions & 12 deletions app/src/renderer/components/common/NiSessionWelcome.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,6 @@
.ni-session-title Welcome to Cosmos!
a(@click="help"): i.material-icons help_outline
.ni-session-main
li-session(
v-if="accountExists"
@click.native="setState('sign-in')"
icon="lock"
title="Sign in with password"
subtitle="If you have an account, choose this option")
li-session(
@click.native="setState('sign-up')"
icon="create"
Expand Down Expand Up @@ -41,15 +35,11 @@ export default {
LiSession
},
computed: {
...mapGetters(['config']),
sessionState () {
return this.config.modals.sessions.state
}
...mapGetters(['config'])
},
methods: {
help () { this.$store.commit('setModalHelp', true) },
setState (value) { this.$store.commit('setModalSessionState', value) },
accountExists () { return !!this.$store.dispatch('accountExists') }
setState (value) { this.$store.commit('setModalSessionState', value) }
}
}
</script>
2 changes: 1 addition & 1 deletion app/src/renderer/styles/variables.styl
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ bc-dim = app-fg

// anchor
link = hsl(app-hue, 88%, 70%)
hover = hsl(app-hue, 96%, 72%)
hover = hsl(app-hue, 96%, 90%)
hover-bg = hsl(app-hue, 30%, 19%)

// input
Expand Down
40 changes: 25 additions & 15 deletions app/src/renderer/vuex/modules/user.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,6 @@ export default ({ commit, node }) => {
const state = JSON.parse(JSON.stringify(emptyUser))

const mutations = {
signIn (state, {password, account = KEY_NAME}) {
state.password = password
state.account = account
state.signedIn = true
},
activateDelegation (state) {
state.delegationActive = true
}
Expand All @@ -51,9 +46,11 @@ export default ({ commit, node }) => {
commit('notifyError', { title: `Couldn't read keys'`, body: err.message })
}
},
// testing if the provided password works so we can show the user early if he uses the wrong password
// testing this by trying to change the password... to the same password...
async testLogin (state, {password, account = KEY_NAME}) {
try {
await node.updateKey(account, {
return await node.updateKey(account, {
name: account,
password: password,
new_passphrase: password
Expand All @@ -62,18 +59,21 @@ export default ({ commit, node }) => {
commit('notifyError', { title: `Couldn't login to '${account}'`, body: err.message })
}
},
// to create a temporary seed phrase, we create a junk account with name 'trunk' for now
async createSeed ({ commit }) {
let JUNK_ACCOUNT_NAME = 'trunk'
try {
// cleanup
try {
await node.deleteKey('trunk', {
// cleanup an existing junk account
let keys = await node.listKeys()
if (keys.find(key => key.name === JUNK_ACCOUNT_NAME)) {
await node.deleteKey(JUNK_ACCOUNT_NAME, {
password: KEY_PASSWORD,
name: 'trunk'
name: JUNK_ACCOUNT_NAME
})
} catch (err) {
// ignore if this fails as we get an error anyway while creating if this fails and this fails if there is no key with that name
}
let temporaryKey = await node.generateKey({ name: 'trunk', password: KEY_PASSWORD })

// generate seedPhrase with junk account
let temporaryKey = await node.generateKey({ name: JUNK_ACCOUNT_NAME, password: KEY_PASSWORD })
return temporaryKey.seed_phrase
} catch (err) {
commit('notifyError', { title: 'Couln\'t create a seed', body: err.message })
Expand All @@ -82,7 +82,7 @@ export default ({ commit, node }) => {
async createKey ({ commit, dispatch }, { seedPhrase, password, name = KEY_NAME }) {
try {
let {key} = await node.recoverKey({ name, password, seed_phrase: seedPhrase })
dispatch('initializeWallet')
dispatch('initializeWallet', key)
return key
} catch (err) {
commit('notifyError', { title: 'Couln\'t create a key', body: err.message })
Expand All @@ -96,11 +96,21 @@ export default ({ commit, node }) => {
commit('notifyError', { title: `Couln't delete account ${name}`, body: err.message })
}
},
signOut ({ state, commit }) {
async signIn ({ state, dispatch }, {password, account = KEY_NAME}) {
state.password = password
state.account = account
state.signedIn = true

let key = await node.getKey(account)
dispatch('initializeWallet', key)
},
signOut ({ state, commit, dispatch }) {
state.password = null
state.account = null
state.signedIn = false

commit('setModalSession', true)
dispatch('showInitialScreen')
},
async submitDelegation (state, value) {
state.delegation = value
Expand Down
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "Cosmos",
"productName": "Cosmos",
"version": "1.0.0",
"version": "0.1.0",
"description": "The electron wrapper for Cosmos UI.",
"author": "All In Bits, Inc <[email protected]>",
"license": "Apache-2.0",
Expand Down Expand Up @@ -103,7 +103,7 @@
"@nylira/vue-field": "1.1.12",
"@nylira/vue-form-msg": "^1.0.3",
"@nylira/vue-input": "^3.2.0",
"@nylira/vue-notifications": "^1.4.4",
"@nylira/vue-notifications": "^1.4.0",
"axios": "^0.17.0",
"babel-jest": "^21.2.0",
"chart.js": "^2.6.0",
Expand Down Expand Up @@ -171,7 +171,7 @@
"/build/",
"/dist/",
"/test/",
"/config/"
"/config.js"
],
"testURL": "http://localhost",
"setupFiles": [
Expand Down
4 changes: 2 additions & 2 deletions test/unit/specs/NISessionAccountDelete.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ describe('NiSessionAccountDelete', () => {
expect(htmlBeautify(wrapper.html())).toMatchSnapshot()
})

it('should go back to the welcome screen on click', () => {
it('should go back to the login screen on click', () => {
wrapper.findAll('.ni-session-header a').at(0).trigger('click')
expect(store.commit.mock.calls[0]).toEqual(['setModalSessionState', 'welcome'])
expect(store.commit.mock.calls[0]).toEqual(['setModalSessionState', 'sign-in'])
})

it('should open the help model on click', () => {
Expand Down
17 changes: 8 additions & 9 deletions test/unit/specs/NISessionSignIn.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,14 @@ describe('NiSessionSignIn', () => {
expect(htmlBeautify(wrapper.html())).toMatchSnapshot()
})

it('should go back to the welcome screen on click', () => {
it('should open the help model on click', () => {
wrapper.findAll('.ni-session-header a').at(0).trigger('click')
expect(store.commit.mock.calls[0][0]).toBe('setModalSessionState')
expect(store.commit.mock.calls[0][1]).toBe('welcome')
expect(store.commit).toHaveBeenCalledWith('setModalHelp', true)
})

it('should open the help model on click', () => {
wrapper.findAll('.ni-session-header a').at(1).trigger('click')
expect(store.commit.mock.calls[0]).toEqual(['setModalHelp', true])
it('should go to account removal screen', () => {
wrapper.find('.ni-session-main a').trigger('click')
expect(store.commit).toHaveBeenCalledWith('setModalSessionState', 'delete')
})

it('should close the modal on successful login', async () => {
Expand All @@ -56,9 +55,9 @@ describe('NiSessionSignIn', () => {
signInPassword: '1234567890'
}})
await wrapper.vm.onSubmit()
let calls = store.commit.mock.calls.map(args => args[0])
expect(calls).toContain('notify')
expect(calls).toContain('signIn')
let commitCalls = store.commit.mock.calls.map(args => args[0])
expect(commitCalls).toContain('notify')
expect(store.dispatch).toHaveBeenCalledWith('signIn', {password: '1234567890'})
})

it('should show error if password not 10 long', () => {
Expand Down
2 changes: 1 addition & 1 deletion test/unit/specs/NISessionSignUp.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ describe('NISessionSignUp', () => {
await wrapper.vm.onSubmit()
expect(store.commit.mock.calls[1][0]).toEqual('notify')
expect(store.commit.mock.calls[1][1].title.toLowerCase()).toContain('signed up')
expect(store.commit).toHaveBeenCalledWith('signIn', {password: '1234567890'})
expect(store.dispatch).toHaveBeenCalledWith('signIn', {password: '1234567890'})
})

it('should show error if warnings not acknowledged', () => {
Expand Down
21 changes: 0 additions & 21 deletions test/unit/specs/NISessionWelcome.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,6 @@ describe('NISessionWelcome', () => {
})

it('has the expected html structure', () => {
wrapper.setData({
accountExists: false
})
expect(htmlBeautify(wrapper.html())).toMatchSnapshot()
})

it('has the expected html structure if accoutn exists', () => {
wrapper.setData({
accountExists: true
})
expect(htmlBeautify(wrapper.html())).toMatchSnapshot()
})

Expand All @@ -43,19 +33,8 @@ describe('NISessionWelcome', () => {
})

it('sets desired login method', () => {
wrapper.setData({
accountExists: false
})
wrapper.findAll(LiSession).trigger('click')
expect(store.commit.mock.calls[0][0]).toBe('setModalSessionState')
expect(store.commit.mock.calls.map(args => args[1])).toEqual(['sign-up', 'restore', 'hardware'])
})

it('sets desired login method if account exists', () => {
wrapper.setData({
accountExists: true
})
wrapper.findAll(LiSession).trigger('click')
expect(store.commit.mock.calls.map(args => args[1])).toEqual(['sign-in', 'sign-up', 'restore', 'hardware'])
})
})
2 changes: 1 addition & 1 deletion test/unit/specs/NiSessionRestore.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ describe('NiSessionRestore', () => {
await wrapper.vm.onSubmit()
expect(store.commit.mock.calls[1][0]).toEqual('notify')
expect(store.commit.mock.calls[1][1].title.toLowerCase()).toContain('welcome back!')
expect(store.commit).toHaveBeenCalledWith('signIn', {password: '1234567890'})
expect(store.dispatch).toHaveBeenCalledWith('signIn', {password: '1234567890'})
})

it('should show error if seed is not filled in', async () => {
Expand Down
6 changes: 5 additions & 1 deletion test/unit/specs/PageBalances.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@ import { mount, createLocalVue } from 'vue-test-utils'
import PageBalances from 'renderer/components/wallet/PageBalances'

const filters = require('renderer/vuex/modules/filters').default({})
const wallet = require('renderer/vuex/modules/wallet').default({})
const wallet = require('renderer/vuex/modules/wallet').default({
node: {
queryAccount () {}
}
})

const localVue = createLocalVue()
localVue.use(Vuex)
Expand Down
Loading

0 comments on commit 3a56aae

Please sign in to comment.