on master help sign in
login: improve shard form input handling

Consider empty shard fields as valid. If too many shard fields are empty, present an error to the user, asking them to provide at least two shards. Coerce shards to be either full strings, or undefined. Keygen currently doesn't handle the empty string case well. Fixes #516.

commite1fb7c6f34a664306fdd8c2fe528fd8ccc5fedf1 authorFang <git@fang.io> dateThu 13 Aug 2020, 19:38 (6 years ago) parente9add57
3 files changed+30−4
src/form/validators.js+3 src/lib/validators.js+10 src/views/Login/Ticket.js+17−4
src/form/validators.js+3
@@ -3,6 +3,7 @@ import { some } from 'lodash';
33import {
44 validateNotEmpty,
55 validatePatq,
6+ validateShard,
67 validateMnemonic,
78 validateHdPath,
89 validatePoint,
@@ -62,6 +63,8 @@ export const hasErrors = iter =>
6263
6364export const buildPatqValidator = (validators = []) =>
6465 buildValidator([validateNotEmpty, validatePatq, ...validators]);
66+export const buildShardValidator = (validators = []) =>
67+ buildValidator([validateShard, ...validators]);
6568export const buildAnyMnemonicValidator = () =>
6669 buildValidator([validateNotEmpty]);
6770export const buildMnemonicValidator = () =>
src/lib/validators.js+10
@@ -65,6 +65,16 @@ export const validatePatq = v => {
6565 }
6666};
6767
68+export const validateShard = v => {
69+ try {
70+ if (v !== undefined && v !== '' && !ob.isValidPatq(v)) {
71+ throw new Error();
72+ }
73+ } catch {
74+ return 'This is not a valid shard.';
75+ }
76+};
77+
6878export const validateOneOf = (options = []) => v =>
6979 !includes(options, v) && 'Is not a valid option.';
7080
src/views/Login/Ticket.js+17−4
@@ -30,6 +30,7 @@ import {
3030 composeValidator,
3131 buildCheckboxValidator,
3232 buildPatqValidator,
33+ buildShardValidator,
3334 buildPassphraseValidator,
3435 buildPointValidator,
3536} from 'form/validators';
@@ -107,6 +108,14 @@ export default function Ticket({ className, goHome }) {
107108 if (errors.shard1 || errors.shard2 || errors.shard3) {
108109 return errors;
109110 }
111+ const empty = ['shard1', 'shard2', 'shard3'].filter(s => !values[s]);
112+ if (empty.length > 1) {
113+ let errors = {};
114+ empty.map(s => {
115+ errors[s] = 'Please provide at least two out of three shards.';
116+ });
117+ return errors;
118+ }
110119 } else {
111120 if (errors.ticket) {
112121 return errors;
@@ -117,7 +126,11 @@ export default function Ticket({ className, goHome }) {
117126 const onSubmit = useCallback(
118127 async values => {
119128 const ticket = values.useShards
120− ? kg.combine([values.shard1, values.shard2, values.shard3])
129+ ? kg.combine(
130+ [values.shard1, values.shard2, values.shard3].map(v =>
131+ v === '' ? undefined : v
132+ )
133+ )
121134 : values.ticket;
122135
123136 try {
@@ -177,9 +190,9 @@ export default function Ticket({ className, goHome }) {
177190 useShards: buildCheckboxValidator(),
178191 point: buildPointValidator(4),
179192 ticket: buildPatqValidator(),
180− shard1: buildPatqValidator(),
181− shard2: buildPatqValidator(),
182− shard3: buildPatqValidator(),
193+ shard1: buildShardValidator(),
194+ shard2: buildShardValidator(),
195+ shard3: buildShardValidator(),
183196 ticketHidden: buildCheckboxValidator(),
184197 passphrase: buildPassphraseValidator(),
185198 },