Skip to content

Commit 6e3c4c1

Browse files
authored
Trim passwords input (fedibtc#589)
* feat: trim whitespace in verification codes * feat: trim leading/trailing whitespace in verification codes/rebase * feat: trim whitespace from password confirmation input
1 parent 886a376 commit 6e3c4c1

File tree

4 files changed

+44
-29
lines changed

4 files changed

+44
-29
lines changed

apps/router/src/guardian-ui/components/setup/screens/setConfiguration/ConfirmPasswordModal.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { useState } from 'react';
1+
import React from 'react';
22
import {
33
Alert,
44
AlertDescription,
@@ -21,6 +21,7 @@ import {
2121
} from '@chakra-ui/react';
2222
import { useTranslation } from '@fedimint/utils';
2323
import { ReactComponent as WarningIcon } from '../../../../assets/svgs/warning.svg';
24+
import { useTrimmedInput } from '../../../../../hooks';
2425

2526
interface ConfirmPasswordModalProps {
2627
password: string;
@@ -38,8 +39,8 @@ export const ConfirmPasswordModal: React.FC<ConfirmPasswordModalProps> = ({
3839
guardianName,
3940
}) => {
4041
const { t } = useTranslation();
41-
const [confirmPassword, setConfirmPassword] = useState('');
42-
const [confirmGuardianName, setConfirmGuardianName] = useState('');
42+
const [confirmPassword, setConfirmPassword] = useTrimmedInput('');
43+
const [confirmGuardianName, setConfirmGuardianName] = useTrimmedInput('');
4344

4445
const confirmed =
4546
confirmPassword === password && confirmGuardianName === guardianName;

apps/router/src/guardian-ui/components/setup/screens/verifyGuardians/VerifyGuardians.tsx

Lines changed: 12 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ import {
4040
useConsensusPolling,
4141
useGuardianSetupApi,
4242
useGuardianSetupContext,
43+
useTrimmedInputArray,
4344
} from '../../../../../hooks';
4445

4546
interface PeerWithHash {
@@ -63,7 +64,9 @@ export const VerifyGuardians: React.FC<Props> = ({ next }) => {
6364
const isHost = role === GuardianRole.Host;
6465
const [myHash, setMyHash] = useState('');
6566
const [peersWithHash, setPeersWithHash] = useState<PeerWithHash[]>();
66-
const [enteredHashes, setEnteredHashes] = useState<string[]>([]);
67+
const [enteredHashes, handleHashChange] = useTrimmedInputArray(
68+
peersWithHash ? peersWithHash.map(() => '') : []
69+
);
6770
const [verifiedConfigs, setVerifiedConfigs] = useState<boolean>(false);
6871
const [isStarting, setIsStarting] = useState(false);
6972
const [error, setError] = useState<string>();
@@ -74,14 +77,6 @@ export const VerifyGuardians: React.FC<Props> = ({ next }) => {
7477
useConsensusPolling();
7578

7679
useEffect(() => {
77-
if (
78-
peers.every(
79-
(peer) => peer.status === GuardianServerStatus.VerifiedConfigs
80-
)
81-
) {
82-
setVerifiedConfigs(true);
83-
}
84-
8580
async function assembleHashInfo() {
8681
if (peers.length === 0) {
8782
return setError(t('verify-guardians.error'));
@@ -97,7 +92,6 @@ export const VerifyGuardians: React.FC<Props> = ({ next }) => {
9792

9893
try {
9994
const hashes = await api.getVerifyConfigHash();
100-
10195
setMyHash(hashes[ourCurrentId]);
10296
setPeersWithHash(
10397
Object.entries(peers)
@@ -109,23 +103,23 @@ export const VerifyGuardians: React.FC<Props> = ({ next }) => {
109103
.filter((peer) => peer.id !== ourCurrentId.toString())
110104
);
111105

112-
// If we're already at the VerifiedConfigs state, prefill all the other hashes with the correct values
106+
// Prefill hashes if already verified
113107
if (
114108
peers[ourCurrentId].status === GuardianServerStatus.VerifiedConfigs
115109
) {
116110
const otherPeers = Object.entries(peers).filter(
117111
([id]) => id !== ourCurrentId.toString()
118112
);
119-
setEnteredHashes(
120-
otherPeers.map(([id]) => hashes[id as unknown as number])
121-
);
113+
otherPeers.forEach(([id], idx) => {
114+
handleHashChange(idx, hashes[id as unknown as number]);
115+
});
122116
}
123117
} catch (err) {
124118
setError(formatApiErrorMessage(err));
125119
}
126120
}
127121
assembleHashInfo();
128-
}, [api, peers, ourCurrentId, t]);
122+
}, [api, peers, ourCurrentId, t, handleHashChange]);
129123

130124
useEffect(() => {
131125
// If we're the only guardian, skip this verify other guardians step.
@@ -207,14 +201,6 @@ export const VerifyGuardians: React.FC<Props> = ({ next }) => {
207201
sm: 'row',
208202
}) as StackDirection | undefined;
209203

210-
const handleChangeHash = useCallback((value: string, index: number) => {
211-
setEnteredHashes((hashes) => {
212-
const newHashes = [...hashes];
213-
newHashes[index] = value;
214-
return newHashes;
215-
});
216-
}, []);
217-
218204
const tableRows = useMemo(() => {
219205
if (!peersWithHash) return [];
220206
return peersWithHash.map(({ peer, hash }, idx) => {
@@ -239,14 +225,14 @@ export const VerifyGuardians: React.FC<Props> = ({ next }) => {
239225
variant='filled'
240226
value={value}
241227
placeholder={`${t('verify-guardians.verified-placeholder')}`}
242-
onChange={(ev) => handleChangeHash(ev.currentTarget.value, idx)}
228+
onChange={(ev) => handleHashChange(idx, ev.currentTarget.value)}
243229
readOnly={isValid}
244230
/>
245231
</FormControl>
246232
),
247233
};
248234
});
249-
}, [peersWithHash, enteredHashes, handleChangeHash, t]);
235+
}, [peersWithHash, enteredHashes, handleHashChange, t]);
250236

251237
if (error) {
252238
return (
@@ -344,7 +330,7 @@ export const VerifyGuardians: React.FC<Props> = ({ next }) => {
344330
'verify-guardians.verified-placeholder'
345331
)}`}
346332
onChange={(ev) =>
347-
handleChangeHash(ev.currentTarget.value, idx)
333+
handleHashChange(idx, ev.currentTarget.value)
348334
}
349335
readOnly={isValid}
350336
/>
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { useState } from 'react';
2+
3+
const cleanInput = (value: string) => value.trim();
4+
5+
export const useTrimmedInput = (initialValue = '') => {
6+
const [value, setValue] = useState(initialValue);
7+
8+
const handleChange = (newValue: string) => {
9+
setValue(cleanInput(newValue));
10+
};
11+
12+
return [value, handleChange] as const;
13+
};
14+
15+
export const useTrimmedInputArray = (initialValues: string[]) => {
16+
const [values, setValues] = useState<string[]>(initialValues);
17+
18+
const handleChange = (index: number, newValue: string) => {
19+
setValues((prev) => {
20+
const newValues = [...prev];
21+
newValues[index] = cleanInput(newValue);
22+
return newValues;
23+
});
24+
};
25+
26+
return [values, handleChange] as const;
27+
};

apps/router/src/hooks/index.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { useLocation } from 'react-router-dom';
33
export * from './guardian/useGuardian';
44
export * from './guardian/useGuardianSetup';
55
export * from './gateway/useGateway';
6+
export * from './custom/useTrimmedInput';
67

78
import { useContext } from 'react';
89
import { AppContext, AppContextValue } from '../context/AppContext';

0 commit comments

Comments
 (0)