1
0
Fork 0
mirror of https://github.com/Alamantus/Lexiconga.git synced 2025-06-08 10:16:37 +02:00

Validate sign up form and check for email and username uniqueness.

This commit is contained in:
Robbie Antenesse 2018-01-13 12:44:12 -07:00
parent ae5ffe0cd1
commit bc7dc27443
3 changed files with 124 additions and 42 deletions

View file

@ -35,6 +35,12 @@ class User {
return $user->rowCount() > 0; return $user->rowCount() > 0;
} }
public function usernameExists ($username) {
$query = 'SELECT * FROM users WHERE username=?';
$user = $this->db->query($query, array($username));
return $user->rowCount() > 0;
}
public function create ($email, $password) { public function create ($email, $password) {
$insert_user_query = 'INSERT INTO users (email, password) VALUES (?, ?)'; $insert_user_query = 'INSERT INTO users (email, password) VALUES (?, ?)';
$password_hash = password_hash($password, PASSWORD_DEFAULT); $password_hash = password_hash($password, PASSWORD_DEFAULT);

View file

@ -55,6 +55,34 @@ switch ($action) {
'error' => true, 'error' => true,
), 400); ), 400);
} }
case 'check-email': {
if (isset($request['email'])) {
$user = new User();
$email_exists = $user->emailExists($request['email']);
return Response::json(array(
'data' => $email_exists,
'error' => false,
), 200);
}
return Response::json(array(
'data' => 'Could not check: required information missing',
'error' => true,
), 400);
}
case 'check-username': {
if (isset($request['username'])) {
$user = new User();
$username_exists = $user->usernameExists($request['username']);
return Response::json(array(
'data' => $username_exists,
'error' => false,
), 200);
}
return Response::json(array(
'data' => 'Could not check: required information missing',
'error' => true,
), 400);
}
case 'get-all-dictionary-names': { case 'get-all-dictionary-names': {
if ($token !== false) { if ($token !== false) {
$user = new User(); $user = new User();

View file

@ -36,7 +36,8 @@ export class LoginForm extends Component {
signupConfirmError: '', signupConfirmError: '',
signupEmailChecking: false, signupEmailChecking: false,
signupUsernameChecking: false, signupUsernameChecking: false,
takenUsernames: [], signupEmailIsUnique: true,
signupUsernameIsUnique: true,
}; };
} }
@ -48,9 +49,9 @@ export class LoginForm extends Component {
const requiredFields = ['loginEmail', 'loginPassword', 'signupEmail', 'signupPassword', 'signupConfirm']; const requiredFields = ['loginEmail', 'loginPassword', 'signupEmail', 'signupPassword', 'signupConfirm'];
const {value, checked} = event.target; const {value, checked} = event.target;
const fieldUpdate = {}; const fieldUpdate = {};
const errorFieldName = `${field}Error`;
let isValid = true; let isValid = true;
if (requiredFields.includes(field)) { if (requiredFields.includes(field)) {
const errorFieldName = `${field}Error`;
if (value === '') { if (value === '') {
isValid = false; isValid = false;
fieldUpdate[errorFieldName] = 'This field must not be blank'; fieldUpdate[errorFieldName] = 'This field must not be blank';
@ -67,47 +68,53 @@ export class LoginForm extends Component {
} }
} }
if (field === 'signupUsername') {
if (value !== '' && /[^a-zA-Z0-9]+/g.test(value)) {
isValid = false;
fieldUpdate[errorFieldName] = 'Please use only letters and numbers';
}
}
if (isValid) { if (isValid) {
fieldUpdate[field] = (field === 'signupAllowEmail') ? checked : value; fieldUpdate[errorFieldName] = '';
} }
fieldUpdate[field] = (field === 'signupAllowEmail') ? checked : value;
this.setState(fieldUpdate); this.setState(fieldUpdate);
} }
checkFieldUnique (field, event) { checkFieldUnique (field, event) {
const uniqueFields = ['signupEmail', 'signupUsername'];
const {value} = event.target; const {value} = event.target;
const fieldUpdate = {}; const fieldUpdate = {};
let isUnique = true; const errorFieldName = `${field}Error`;
if (uniqueFields.includes(field)) { if (field === 'signupEmail') {
const errorFieldName = `${field}Error`; this.setState({ signupEmailChecking: true }, () => {
request('check-email', { email: value }, (response) => {
request('check-email', value, (response) => { const { data, error } = response;
fieldUpdate['signupEmailChecking'] = false;
if (error) {
console.error(data);
} else {
fieldUpdate['signupEmailIsUnique'] = !data;
}
}).then(() => {
this.setState(fieldUpdate);
});
});
} else if (field === 'signupUsername') {
this.setState({ signupUsernameChecking: true }, () => {
request('check-username', { username: value }, (response) => {
const { data, error } = response;
fieldUpdate['signupUsernameChecking'] = false;
if (error) {
console.error(data);
} else {
fieldUpdate['signupUsernameIsUnique'] = !data;
}
}).then(() => {
this.setState(fieldUpdate);
});
}); });
if (value === '') {
isUnique = false;
fieldUpdate[errorFieldName] = 'This field must not be blank';
} else if (field.includes('Email') && !/.+@.+/g.test(value)) {
isUnique = false;
fieldUpdate[errorFieldName] = 'The email address you entered looks wrong';
} else if (field === 'signupPassword' && value.length < 6) {
isUnique = false;
fieldUpdate[errorFieldName] = 'Please make your password at least 6 characters long';
} else if ((field === 'signupPassword' && value !== this.state.signupConfirm)
|| (field === 'signupConfirm' && value !== this.state.signupPassword)) {
isUnique = false;
fieldUpdate[errorFieldName] = 'Your passwords must match';
}
} }
if (field === 'signupUsername' && value !== '') {
if (this.state.takenUsernames.length < 1) {
fetch()
}
}
this.setState(fieldUpdate);
} }
render () { render () {
@ -181,9 +188,20 @@ export class LoginForm extends Component {
<label className='label'> <label className='label'>
Email Address<sup>*</sup> Email Address<sup>*</sup>
</label> </label>
<div className='control'> <div className={`control ${this.state.signupEmailChecking && 'is-loading'}`}>
<input className='input' type='email' value={this.state.signupEmail} <input className={`input ${(this.state.signupEmailError !== '' || !this.state.signupEmailIsUnique) && 'is-danger'}`}
onInput={(event) => this.updateField('signupEmail', event)} /> type='email' value={this.state.signupEmail}
onInput={(event) => this.updateField('signupEmail', event)}
onBlur={(event) => this.checkFieldUnique('signupEmail', event)} />
{
(this.state.signupEmailError !== '' || !this.state.signupEmailIsUnique)
? (
<div className='help is-danger'>
{!this.state.signupEmailIsUnique && <p>This email address is already in use</p>}
{this.state.signupEmailError}
</div>
) : null
}
</div> </div>
</div> </div>
<div className='field'> <div className='field'>
@ -193,9 +211,20 @@ export class LoginForm extends Component {
<div className='help'> <div className='help'>
This is your unique identifier that appears in the URL if you ever decide to share your dictionaries publicly. This is your unique identifier that appears in the URL if you ever decide to share your dictionaries publicly.
</div> </div>
<div className='control'> <div className={`control ${this.state.signupUsernameChecking && 'is-loading'}`}>
<input className='input' type='text' value={this.state.signupUsername} <input className={`input ${!this.state.signupUsernameIsUnique && 'is-danger'}`}
onInput={(event) => this.updateField('signupUsername', event)} /> type='text' value={this.state.signupUsername}
onInput={(event) => this.updateField('signupUsername', event)}
onBlur={(event) => this.checkFieldUnique('signupUsername', event)} />
{
(this.state.signupUsernameError !== '' || !this.state.signupUsernameIsUnique)
? (
<div className='help is-danger'>
{!this.state.signupUsernameIsUnique && <p>This username address is already in use</p>}
{this.state.signupUsernameError}
</div>
) : null
}
</div> </div>
</div> </div>
<div className='field'> <div className='field'>
@ -206,7 +235,8 @@ export class LoginForm extends Component {
This is the name we greet you with and what we display if you ever decide to share your dictionaries publicly. This is the name we greet you with and what we display if you ever decide to share your dictionaries publicly.
</div> </div>
<div className='control'> <div className='control'>
<input className='input' type='text' value={this.state.signupPublicName} <input className='input'
type='text' value={this.state.signupPublicName}
onInput={(event) => this.updateField('signupPublicName', event)} /> onInput={(event) => this.updateField('signupPublicName', event)} />
</div> </div>
</div> </div>
@ -215,8 +245,17 @@ export class LoginForm extends Component {
Password<sup>*</sup> Password<sup>*</sup>
</label> </label>
<div className='control'> <div className='control'>
<input className='input' type='password' value={this.state.signupPassword} <input className={`input ${this.state.signupPasswordError !== '' && 'is-danger'}`}
type='password' value={this.state.signupPassword}
onInput={(event) => this.updateField('signupPassword', event)} /> onInput={(event) => this.updateField('signupPassword', event)} />
{
this.state.signupPasswordError !== ''
? (
<div className='help is-danger'>
{this.state.signupPasswordError}
</div>
) : null
}
</div> </div>
</div> </div>
<div className='field'> <div className='field'>
@ -224,8 +263,17 @@ export class LoginForm extends Component {
Confirm Password<sup>*</sup> Confirm Password<sup>*</sup>
</label> </label>
<div className='control'> <div className='control'>
<input className='input' type='password' value={this.state.signupConfirm} <input className={`input ${this.state.signupConfirmError !== '' && 'is-danger'}`}
type='password' value={this.state.signupConfirm}
onInput={(event) => this.updateField('signupConfirm', event)} /> onInput={(event) => this.updateField('signupConfirm', event)} />
{
this.state.signupConfirmError !== ''
? (
<div className='help is-danger'>
{this.state.signupConfirmError}
</div>
) : null
}
</div> </div>
</div> </div>
<div className='field'> <div className='field'>