Skip to content

Commit

Permalink
support duplicate words in mnemonic verification, fixes #87 (#92)
Browse files Browse the repository at this point in the history
* support duplicate words in mnemonic verification, fixes #87

* sort mnemonic verification words alphabetically
  • Loading branch information
decentraliser authored Mar 16, 2020
1 parent 74fe532 commit d3d4c70
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 46 deletions.
16 changes: 8 additions & 8 deletions src/components/MnemonicVerification/MnemonicVerification.vue
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
<template>
<div class="mnemonic_container" @keyup.enter="processVerification()">
<div class="mnemonicWordDiv clear scroll">
<draggable v-model="selectedWords" ghost-class="ghost" @end="drag = false">
<span v-for="(word, index) in selectedWords" :key="index">
<Tag closable @on-close="removeWord(word)">
{{ word }}
<draggable v-model="selectedWordIndexes" ghost-class="ghost" @end="drag = false">
<span v-for="index in selectedWordIndexes" :key="index">
<Tag closable @on-close="removeWord(index)">
{{ shuffledWords[index] }}
</Tag>
</span>
</draggable>
</div>
<div class="wordDiv clear">
<span
v-for="(item,index) in shuffledWords"
v-for="index in shuffledWordsIndexes"
:key="index"
:class="selectedWords.includes(item) ? 'confirmed_word' : ''"
@click="addWord(item)"
:class="selectedWordIndexes.includes(index) ? 'confirmed_word' : ''"
@click="onWordClicked(index)"
>
{{ item }}
{{ shuffledWords[index] }}
</span>
</div>
<div class="buttons clear">
Expand Down
67 changes: 29 additions & 38 deletions src/components/MnemonicVerification/MnemonicVerificationTs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,75 +19,66 @@ import draggable from 'vuedraggable'
// internal dependencies
import {NotificationType} from '@/core/utils/NotificationType'

/// region helpers
/**
* Shuffles array in place. ES6 version
* @param {Array} a items An array containing the items.
*/
const shuffle = (a) => {
for (let i = a.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[a[i], a[j]] = [a[j], a[i]];
}
return a;
}
/// end-region helpers

/**
* Emits: success, error, canceled
*/
@Component({
components:{draggable},
})
export class MnemonicVerificationTs extends Vue {
@Prop({
default: []
})
words: string[]
@Prop({ default: [] }) words: string[]

/**
* Randomized words
* @var {string[]}
* @var {Record<number, string>}
*/
public shuffledWords: string[] = []
public shuffledWords: Record<number, string> = {}

/**
* Selected words
* @var {string[]}
* Randomized words indexes
* @var {number[]}
*/
public selectedWords: string[] = []
public shuffledWordsIndexes: number[] = []

/**
* Hook called when the component is mounted
* Selected words indexes
* @var {number[]}
*/
public selectedWordIndexes: number[] = []

/**
* Hook called when the component is created
* @return {void}
*/
public mounted() {
this.shuffledWords = shuffle([...this.words])
public created() {
const shuffledWordsArray: string[] = [...this.words].sort((a, b) => a.localeCompare(b))
this.shuffledWords = shuffledWordsArray.reduce(
(acc, word, index) => ({...acc, ...{[index]: word}}), {}
)
this.shuffledWordsIndexes = [...Array(shuffledWordsArray.length).keys()]
}

/**
* Add confirmed word
* Toggle a word presence in the confirmed words
* @param {string} word
* @return {string[]}
* @return {void}
*/
public addWord(word: string): string[] {
if (this.selectedWords.includes(word)) {
this.removeWord(word)
public onWordClicked(index: number): void {
if (this.selectedWordIndexes.includes(index)) {
this.removeWord(index)
return
}

this.selectedWords.push(word)
return this.selectedWords
this.selectedWordIndexes.push(index)
}

/**
* Add confirmed word
* @param {string} word
* @return {string[]}
*/
public removeWord(word: string) {
this.selectedWords = this.selectedWords.filter(sel => sel !== word)
return this.selectedWords
public removeWord(index: number): void {
this.selectedWordIndexes = [...this.selectedWordIndexes].filter(sel => sel !== index)
}

/**
Expand All @@ -96,11 +87,11 @@ export class MnemonicVerificationTs extends Vue {
*/
public processVerification(): boolean {
const origin = this.words.join(' ')
const rebuilt = this.selectedWords.join(' ')
const rebuilt = this.selectedWordIndexes.map(i => this.shuffledWords[i]).join(' ')

// - origin words list does not match
if (origin !== rebuilt) {
const errorMsg = this.selectedWords.length < 1 ?
const errorMsg = this.selectedWordIndexes.length < 1 ?
NotificationType.PLEASE_ENTER_MNEMONIC_INFO
: NotificationType.MNEMONIC_INCONSISTENCY_ERROR
this.$store.dispatch('notification/ADD_WARNING', errorMsg)
Expand Down

0 comments on commit d3d4c70

Please sign in to comment.