Webatrice: tech debt (#4560)

* turn autocomplete off by default on inputs

* trim input fields onSubmit

* move trim to form submit

* cleanup

* remove dead code

* protect trim against null values

* make password optional on Login for servers that allow unregisted logins

* cleanup

Co-authored-by: Jeremy Letto <jeremy.letto@datasite.com>
This commit is contained in:
Jeremy Letto 2022-02-06 10:41:02 -06:00 committed by GitHub
parent 6928a2bd98
commit bf08a04cda
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 53 additions and 112 deletions

View file

@ -38,6 +38,7 @@ const InputField = ({ input, meta: { touched, error, warning }, ...args }) => {
) } ) }
<TextField <TextField
autoComplete='off'
{ ...input } { ...input }
{ ...args } { ...args }
className="rounded" className="rounded"

View file

@ -159,6 +159,10 @@ const Login = ({ state, description }: LoginProps) => {
}); });
}; };
const handleAccountActivationDialogSubmit = ({ token }) => {
AuthenticationService.activateAccount({ token } as any);
};
const handleRequestPasswordResetDialogSubmit = (form) => { const handleRequestPasswordResetDialogSubmit = (form) => {
const { userName, email, selectedHost } = form; const { userName, email, selectedHost } = form;
const { host, port } = getHostPort(selectedHost); const { host, port } = getHostPort(selectedHost);
@ -173,11 +177,8 @@ const Login = ({ state, description }: LoginProps) => {
const handleResetPasswordDialogSubmit = ({ userName, token, newPassword, selectedHost }) => { const handleResetPasswordDialogSubmit = ({ userName, token, newPassword, selectedHost }) => {
const { host, port } = getHostPort(selectedHost); const { host, port } = getHostPort(selectedHost);
AuthenticationService.resetPassword({ userName, token, newPassword, host, port } as any);
};
const handleAccountActivationDialogSubmit = ({ token }) => { AuthenticationService.resetPassword({ userName, token, newPassword, host, port } as any);
AuthenticationService.activateAccount({ token } as any);
}; };
const skipTokenRequest = (userName) => { const skipTokenRequest = (userName) => {

View file

@ -21,9 +21,12 @@ const AccountActivationForm = ({ onSubmit }) => {
setErrorMessage(true); setErrorMessage(true);
}, ServerTypes.ACCOUNT_ACTIVATION_FAILED, []); }, ServerTypes.ACCOUNT_ACTIVATION_FAILED, []);
const handleOnSubmit = (form) => { const handleOnSubmit = ({ token, ...values }) => {
setErrorMessage(false); setErrorMessage(false);
onSubmit(form);
token = token?.trim();
onSubmit({ token, ...values });
} }
const validate = values => { const validate = values => {
@ -42,7 +45,7 @@ const AccountActivationForm = ({ onSubmit }) => {
return ( return (
<form className="AccountActivationForm" onSubmit={handleSubmit}> <form className="AccountActivationForm" onSubmit={handleSubmit}>
<div className="AccountActivationForm-item"> <div className="AccountActivationForm-item">
<Field label="Token" name="token" component={InputField} autoComplete="off" /> <Field label="Token" name="token" component={InputField} />
</div> </div>
{errorMessage && ( {errorMessage && (

View file

@ -1,18 +0,0 @@
.connectForm {
width: 100%;
padding: 20px;
}
.connectForm-item {
display: flex;
flex-direction: column;
}
.connectForm-submit.MuiButton-root {
display: block;
margin: 20px auto 0;
}
.selectKnownHosts-items {
margin-bottom: 4px;
}

View file

@ -1,71 +0,0 @@
// eslint-disable-next-line
import React, { useState } from "react";
import { connect } from 'react-redux';
import { Form, Field, reduxForm, change } from 'redux-form'
import Button from '@material-ui/core/Button';
import { InputField } from 'components';
import { FormKey, KnownHost, KnownHosts } from 'types';
import './ConnectForm.css';
import { Select, MenuItem } from '@material-ui/core';
const ConnectForm = (props) => {
const { handleSubmit, dispatch } = props;
const [knownHosts, setKnownHosts] = useState(KnownHost.ROOSTER);
const handleChange = (event) => {
setKnownHosts(event.target.value);
dispatch(change(FormKey.CONNECT, 'host', KnownHosts[event.target.value].host));
dispatch(change(FormKey.CONNECT, 'port', KnownHosts[event.target.value].port))
};
return (
<Form className="connectForm" onSubmit={handleSubmit}>
<div className="connectForm-item">
<Select
labelId="selectedKnownHosts-label"
id="selectedKnownHosts-label"
className="selectKnownHosts-items"
value={knownHosts}
fullWidth={true}
onChange={handleChange}
>
<MenuItem value={KnownHost.ROOSTER}>{KnownHost.ROOSTER}</MenuItem>
<MenuItem value={KnownHost.TETRARCH}>{KnownHost.TETRARCH}</MenuItem>
</Select>
</div>
<div className="connectForm-item">
<Field label="Host" name="host" component={InputField} />
</div>
<div className="connectForm-item">
<Field label="Port" name="port" component={InputField} />
</div>
<div className="connectForm-item">
<Field label="User" name="user" component={InputField} autoComplete="username" />
</div>
<div className="connectForm-item">
<Field label="Pass" name="pass" type="password" component={InputField} autoComplete="current-password" />
</div>
<Button className="connectForm-submit" color="primary" variant="contained" type="submit">
Connect
</Button>
</Form>
);
};
const propsMap = {
form: FormKey.CONNECT
};
const mapStateToProps = () => ({
initialValues: {
// host: "mtg.tetrarch.co/servatrice",
// port: "443"
host: 'server.cockatrice.us',
port: '4748'
}
});
export default connect(mapStateToProps)(reduxForm(propsMap)(ConnectForm));

View file

@ -33,6 +33,13 @@ const KnownHostForm = ({ host, onRemove, onSubmit }) => {
} }
}; };
const handleOnSubmit = ({ name, host, ...values }) => {
name = name?.trim();
host = host?.trim();
onSubmit({ name, host, ...values });
}
return ( return (
<Form <Form
initialValues={{ initialValues={{
@ -41,7 +48,7 @@ const KnownHostForm = ({ host, onRemove, onSubmit }) => {
host: host?.host, host: host?.host,
port: host?.port, port: host?.port,
}} }}
onSubmit={onSubmit} onSubmit={handleOnSubmit}
validate={validate} validate={validate}
> >
{({ handleSubmit }) => ( {({ handleSubmit }) => (

View file

@ -26,9 +26,6 @@ const LoginForm = ({ onSubmit, disableSubmitButton, onResetPassword }: LoginForm
if (!values.userName) { if (!values.userName) {
errors.userName = 'Required'; errors.userName = 'Required';
} }
if (!values.password && !values.selectedHost?.hashedPassword) {
errors.password = 'Required';
}
if (!values.selectedHost) { if (!values.selectedHost) {
errors.selectedHost = 'Required'; errors.selectedHost = 'Required';
} }
@ -41,8 +38,14 @@ const LoginForm = ({ onSubmit, disableSubmitButton, onResetPassword }: LoginForm
setPasswordLabel(useStoredLabel ? STORED_PASSWORD_LABEL : PASSWORD_LABEL); setPasswordLabel(useStoredLabel ? STORED_PASSWORD_LABEL : PASSWORD_LABEL);
}; };
const handleOnSubmit = ({ userName, ...values }) => {
userName = userName?.trim();
onSubmit({ userName, ...values });
}
return ( return (
<Form onSubmit={onSubmit} validate={validate}> <Form onSubmit={handleOnSubmit} validate={validate}>
{({ handleSubmit, form }) => { {({ handleSubmit, form }) => {
const { values } = form.getState(); const { values } = form.getState();
@ -109,7 +112,7 @@ const LoginForm = ({ onSubmit, disableSubmitButton, onResetPassword }: LoginForm
<form className='loginForm' onSubmit={handleSubmit}> <form className='loginForm' onSubmit={handleSubmit}>
<div className='loginForm-items'> <div className='loginForm-items'>
<div className='loginForm-item'> <div className='loginForm-item'>
<Field label='Username' name='userName' component={InputField} autoComplete='off' /> <Field label='Username' name='userName' component={InputField} autoComplete='username' />
<OnChange name="userName">{onUserNameChange}</OnChange> <OnChange name="userName">{onUserNameChange}</OnChange>
</div> </div>
<div className='loginForm-item'> <div className='loginForm-item'>

View file

@ -47,9 +47,14 @@ const RegisterForm = ({ onSubmit }: RegisterFormProps) => {
setUserNameError(error); setUserNameError(error);
}, ServerTypes.REGISTRATION_USERNAME_ERROR); }, ServerTypes.REGISTRATION_USERNAME_ERROR);
const handleOnSubmit = form => { const handleOnSubmit = ({ userName, email, realName, ...values }) => {
setError(null); setError(null);
onSubmit(form);
userName = userName?.trim();
email = email?.trim();
realName = realName?.trim();
onSubmit({ userName, email, realName, ...values });
} }
const validate = values => { const validate = values => {
@ -100,10 +105,10 @@ const RegisterForm = ({ onSubmit }: RegisterFormProps) => {
return ( return (
<> <>
<form className="RegisterForm" onSubmit={handleSubmit} autoComplete="off"> <form className="RegisterForm" onSubmit={handleSubmit}>
<div className="RegisterForm-column"> <div className="RegisterForm-column">
<div className="RegisterForm-item"> <div className="RegisterForm-item">
<Field label="Player Name" name="userName" component={InputField} /> <Field label="Player Name" name="userName" component={InputField} autoComplete="username" />
<OnChange name="userName">{onUserNameChange}</OnChange> <OnChange name="userName">{onUserNameChange}</OnChange>
</div> </div>
<div className="RegisterForm-item"> <div className="RegisterForm-item">
@ -126,7 +131,7 @@ const RegisterForm = ({ onSubmit }: RegisterFormProps) => {
</div> </div>
<div className="RegisterForm-column" > <div className="RegisterForm-column" >
<div className="RegisterForm-item"> <div className="RegisterForm-item">
<Field label="Real Name" name="realName" component={InputField} autoComplete='off' /> <Field label="Real Name" name="realName" component={InputField} />
</div> </div>
<div className="RegisterForm-item"> <div className="RegisterForm-item">
<Field label="Email" name="email" type="email" component={InputField} /> <Field label="Email" name="email" type="email" component={InputField} />

View file

@ -26,9 +26,13 @@ const RequestPasswordResetForm = ({ onSubmit, skipTokenRequest }) => {
setIsMFA(true); setIsMFA(true);
}, ServerTypes.RESET_PASSWORD_CHALLENGE, []); }, ServerTypes.RESET_PASSWORD_CHALLENGE, []);
const handleOnSubmit = (form) => { const handleOnSubmit = ({ userName, email, ...values }) => {
setErrorMessage(false); setErrorMessage(false);
onSubmit(form);
userName = userName?.trim();
email = email?.trim();
onSubmit({ userName, email, ...values });
} }
const validate = values => { const validate = values => {
@ -63,7 +67,7 @@ const RequestPasswordResetForm = ({ onSubmit, skipTokenRequest }) => {
</div> </div>
{isMFA ? ( {isMFA ? (
<div className="RequestPasswordResetForm-item"> <div className="RequestPasswordResetForm-item">
<Field label="Email" name="email" component={InputField} autoComplete="email" /> <Field label="Email" name="email" type="email" component={InputField} autoComplete="email" />
<div>Server has multi-factor authentication enabled</div> <div>Server has multi-factor authentication enabled</div>
</div> </div>
) : null} ) : null}

View file

@ -49,8 +49,15 @@ const ResetPasswordForm = ({ onSubmit, userName }) => {
return errors; return errors;
}; };
const handleOnSubmit = ({ userName, token, ...values }) => {
userName = userName?.trim();
token = token?.trim();
onSubmit({ userName, token, ...values });
}
return ( return (
<Form onSubmit={onSubmit} validate={validate} initialValues={{ userName }}> <Form onSubmit={handleOnSubmit} validate={validate} initialValues={{ userName }}>
{({ handleSubmit, form }) => ( {({ handleSubmit, form }) => (
<form className='ResetPasswordForm' onSubmit={handleSubmit}> <form className='ResetPasswordForm' onSubmit={handleSubmit}>
<div className='ResetPasswordForm-items'> <div className='ResetPasswordForm-items'>

View file

@ -1,6 +1,5 @@
export { default as AccountActivationForm } from './AccountActivationForm/AccountActivationForm'; export { default as AccountActivationForm } from './AccountActivationForm/AccountActivationForm';
export { default as CardImportForm } from './CardImportForm/CardImportForm'; export { default as CardImportForm } from './CardImportForm/CardImportForm';
export { default as ConnectForm } from './ConnectForm/ConnectForm';
export { default as LoginForm } from './LoginForm/LoginForm'; export { default as LoginForm } from './LoginForm/LoginForm';
export { default as KnownHostForm } from './KnownHostForm/KnownHostForm'; export { default as KnownHostForm } from './KnownHostForm/KnownHostForm';
export { default as RegisterForm } from './RegisterForm/RegisterForm'; export { default as RegisterForm } from './RegisterForm/RegisterForm';