feat: validate display names correctly when creating an account

if you use an empty name or just a space it will flag it with the correct error message
pull/3281/head
yougotwill 2 months ago
parent da16817569
commit 5a20f53906

@ -1,6 +1,7 @@
import { isEmpty } from 'lodash'; import { isEmpty } from 'lodash';
import { useDispatch } from 'react-redux'; import { useDispatch } from 'react-redux';
import useMount from 'react-use/lib/useMount'; import useMount from 'react-use/lib/useMount';
import { useState } from 'react';
import { SettingsKey } from '../../../data/settings-key'; import { SettingsKey } from '../../../data/settings-key';
import { mnDecode } from '../../../session/crypto/mnemonic'; import { mnDecode } from '../../../session/crypto/mnemonic';
import { ProfileManager } from '../../../session/profile_manager/ProfileManager'; import { ProfileManager } from '../../../session/profile_manager/ProfileManager';
@ -32,22 +33,21 @@ import { SessionInput } from '../../inputs';
import { resetRegistration } from '../RegistrationStages'; import { resetRegistration } from '../RegistrationStages';
import { ContinueButton, OnboardDescription, OnboardHeading } from '../components'; import { ContinueButton, OnboardDescription, OnboardHeading } from '../components';
import { BackButtonWithinContainer } from '../components/BackButton'; import { BackButtonWithinContainer } from '../components/BackButton';
import { displayNameIsValid, sanitizeDisplayNameOrToast } from '../utils'; import { sanitizeDisplayNameOrToast } from '../utils';
import { RetrieveDisplayNameError } from '../../../session/utils/errors'; import { EmptyDisplayNameError, RetrieveDisplayNameError } from '../../../session/utils/errors';
import { localize } from '../../../localization/localeTools'; import { localize } from '../../../localization/localeTools';
export type AccountDetails = { type AccountCreateDetails = {
recoveryPassword: string; recoveryPassword: string;
displayName?: string; displayName: string;
}; };
async function signUp(signUpDetails: AccountDetails) { async function signUp(signUpDetails: AccountCreateDetails) {
const { displayName, recoveryPassword } = signUpDetails; const { displayName, recoveryPassword } = signUpDetails;
try { try {
const validDisplayName = displayNameIsValid(displayName);
await resetRegistration(); await resetRegistration();
await registerSingleDevice(recoveryPassword, 'english', validDisplayName); await registerSingleDevice(recoveryPassword, 'english', displayName);
await Storage.put(SettingsKey.hasSyncedInitialConfigurationItem, Date.now()); await Storage.put(SettingsKey.hasSyncedInitialConfigurationItem, Date.now());
await setSignWithRecoveryPhrase(false); await setSignWithRecoveryPhrase(false);
trigger('openInbox'); trigger('openInbox');
@ -64,6 +64,8 @@ export const CreateAccount = () => {
const dispatch = useDispatch(); const dispatch = useDispatch();
const [cannotContinue, setCannotContinue] = useState(true);
const generateMnemonicAndKeyPair = async () => { const generateMnemonicAndKeyPair = async () => {
if (recoveryPassword === '') { if (recoveryPassword === '') {
const mnemonic = await generateMnemonic(); const mnemonic = await generateMnemonic();
@ -89,13 +91,16 @@ export const CreateAccount = () => {
}); });
const signUpWithDetails = async () => { const signUpWithDetails = async () => {
if (isEmpty(displayName) || !isEmpty(displayNameError)) {
return;
}
try { try {
const sanitizedName = sanitizeDisplayNameOrToast(displayName);
// this should never happen, but just in case
if (isEmpty(sanitizedName)) {
return;
}
// this throws if the display name is too long // this throws if the display name is too long
const validName = await ProfileManager.updateOurProfileDisplayNameOnboarding(displayName); const validName = await ProfileManager.updateOurProfileDisplayNameOnboarding(sanitizedName);
await signUp({ await signUp({
displayName: validName, displayName: validName,
@ -107,16 +112,17 @@ export const CreateAccount = () => {
window.log.error( window.log.error(
`[onboarding] create account: signUpWithDetails failed! Error: ${err.message || String(err)}` `[onboarding] create account: signUpWithDetails failed! Error: ${err.message || String(err)}`
); );
setCannotContinue(true);
dispatch(setAccountCreationStep(AccountCreation.DisplayName)); dispatch(setAccountCreationStep(AccountCreation.DisplayName));
if (err instanceof RetrieveDisplayNameError) { if (err instanceof EmptyDisplayNameError || err instanceof RetrieveDisplayNameError) {
dispatch(setDisplayNameError(localize('displayNameErrorDescription').toString())); dispatch(setDisplayNameError(localize('displayNameErrorDescription').toString()));
return; } else {
// Note: we have to assume here that libsession threw an error because the name was too long since we covered the other cases.
// The error reported by libsession is not localized
dispatch(setDisplayNameError(localize('displayNameErrorDescriptionShorter').toString()));
} }
// Note: we have to assume here that libsession threw an error because the name was too long since we covered the other cases.
// The error reported by libsession is not localized
dispatch(setDisplayNameError(localize('displayNameErrorDescriptionShorter').toString()));
} }
}; };
@ -150,18 +156,15 @@ export const CreateAccount = () => {
placeholder={window.i18n('displayNameEnter')} placeholder={window.i18n('displayNameEnter')}
value={displayName} value={displayName}
onValueChanged={(name: string) => { onValueChanged={(name: string) => {
const sanitizedName = sanitizeDisplayNameOrToast(name, setDisplayNameError, dispatch); dispatch(setDisplayName(name));
dispatch(setDisplayName(sanitizedName)); setCannotContinue(false);
}} }}
onEnterPressed={signUpWithDetails} onEnterPressed={signUpWithDetails}
error={displayNameError} error={displayNameError}
inputDataTestId="display-name-input" inputDataTestId="display-name-input"
/> />
<SpacerLG /> <SpacerLG />
<ContinueButton <ContinueButton onClick={signUpWithDetails} disabled={cannotContinue} />
onClick={signUpWithDetails}
disabled={isEmpty(displayName) || !isEmpty(displayNameError)}
/>
</Flex> </Flex>
</BackButtonWithinContainer> </BackButtonWithinContainer>
); );

Loading…
Cancel
Save