diff --git a/public/api/Dictionary.php b/public/api/Dictionary.php index 23e9c72..b1622d0 100644 --- a/public/api/Dictionary.php +++ b/public/api/Dictionary.php @@ -33,11 +33,11 @@ class Dictionary { if ($insert_dictionary === true) { $new_dictionary_id = $this->db->lastInsertId(); - $insert_linguistics_query = "INSERT INTO dictionary_linguistics (dictionary, partsOfSpeech, phonology) + $insert_linguistics_query = "INSERT INTO dictionary_linguistics (dictionary, parts_of_speech, phonology) VALUES ($new_dictionary_id, ?, ?)"; $insert_linguistics = $this->db->execute($insert_linguistics_query, array( json_encode($this->defaults['partsOfSpeech']), - json_encode($this->defaults['phonotactics']), + json_encode($this->defaults['phonology']), )); if ($insert_linguistics === true) { diff --git a/public/api/User.php b/public/api/User.php index bc9a97d..fbcded5 100644 --- a/public/api/User.php +++ b/public/api/User.php @@ -13,8 +13,8 @@ class User { } public function logIn ($email, $password) { - $query = 'SELECT * FROM users WHERE email=?'; - $user = $this->db->query($query, array($email))->fetch(); + $query = 'SELECT * FROM users WHERE email=:email OR username=:email'; + $user = $this->db->query($query, array(':email' => $email))->fetch(); if ($user) { if ($user['old_password'] !== null) { if ($user['old_password'] === crypt($password, $email)) { @@ -23,6 +23,7 @@ class User { } } } else if (password_verify($password, $user['password'])) { + $this->db->execute('UPDATE users SET last_login=' . time() . ' WHERE id=' . $user['id']); return $this->generateUserToken($user['id'], $user['current_dictionary']); } } @@ -41,11 +42,18 @@ class User { return $user->rowCount() > 0; } - public function create ($email, $password) { - $insert_user_query = 'INSERT INTO users (email, password) VALUES (?, ?)'; + public function create ($email, $password, $user_data) { + $insert_user_query = 'INSERT INTO users (email, password, public_name, username, allow_email, created_on) +VALUES (?, ?, ?, ?, ?, '. time() .')'; $password_hash = password_hash($password, PASSWORD_DEFAULT); - $insert_user = $this->db->execute($insert_user_query, array($email, $password_hash)); + $insert_user = $this->db->execute($insert_user_query, array( + $email, + $password_hash, + $user_data['publicName'] !== '' ? $user_data['publicName'] : null, + $user_data['username'] !== '' ? $user_data['username'] : null, + $user_data['allowEmail'] ? 1 : 0, + )); if ($insert_user === true) { $new_user_id = $this->db->lastInsertId(); diff --git a/public/api/index.php b/public/api/index.php index 8247fc0..6a96fc8 100644 --- a/public/api/index.php +++ b/public/api/index.php @@ -33,7 +33,7 @@ switch ($action) { if (isset($request['email']) && isset($request['password'])) { $user = new User(); if (!$user->emailExists($request['email'])) { - $token = $user->create($request['email'], $request['password']); + $token = $user->create($request['email'], $request['password'], $request['userData']); if ($token !== false) { return Response::json(array( 'data' => $token, diff --git a/src/components/management/AccountManager/LoginForm.jsx b/src/components/management/AccountManager/LoginForm.jsx index 1efbd8d..7b6dbf0 100644 --- a/src/components/management/AccountManager/LoginForm.jsx +++ b/src/components/management/AccountManager/LoginForm.jsx @@ -24,6 +24,7 @@ export class LoginForm extends Component { loginPassword: '', loginEmailError: '', loginPasswordError: '', + loginFormIsValid: true, signupEmail: '', signupUsername: '', signupPublicName: '', @@ -38,48 +39,104 @@ export class LoginForm extends Component { signupUsernameChecking: false, signupEmailIsUnique: true, signupUsernameIsUnique: true, + signupFormIsValid: true, }; } + get loginFormIsValid () { + const { + loginEmailError, + loginPasswordError, + } = this.state; + return loginEmailError === '' && loginPasswordError === ''; + } + + get signupFormIsValid () { + const { + signupEmailError, + signupEmailChecking, + signupEmailIsUnique, + signupUsernameError, + signupUsernameChecking, + signupUsernameIsUnique, + signupPasswordError, + signupConfirmError, + } = this.state; + return !signupEmailChecking && !signupUsernameChecking + && signupEmailIsUnique && signupUsernameIsUnique + && signupEmailError === '' && signupUsernameError === '' + && signupPasswordError === '' && signupConfirmError === ''; + } + changeTab (tab) { this.setState({ visibleTab: tab }); } updateField (field, event) { - const requiredFields = ['loginEmail', 'loginPassword', 'signupEmail', 'signupPassword', 'signupConfirm']; const {value, checked} = event.target; const fieldUpdate = {}; + const fieldErrors = this.validateField(field, value); + fieldUpdate[field] = (field === 'signupAllowEmail') ? checked : value; + this.setState(Object.assign(fieldUpdate, fieldErrors)); + } + + validateField (field, value) { + const fieldErrors = {}; const errorFieldName = `${field}Error`; let isValid = true; + const requiredFields = ['loginEmail', 'loginPassword', 'signupEmail', 'signupPassword', 'signupConfirm']; if (requiredFields.includes(field)) { if (value === '') { isValid = false; - fieldUpdate[errorFieldName] = 'This field must not be blank'; - } else if (field.includes('Email') && !/.+@.+/g.test(value)) { + fieldErrors[errorFieldName] = 'This field must not be blank'; + } else if (field === 'signupEmail' && !/.+@.+/g.test(value)) { isValid = false; - fieldUpdate[errorFieldName] = 'The email address you entered looks wrong'; + fieldErrors[errorFieldName] = 'The email address you entered looks wrong'; } else if (field === 'signupPassword' && value.length < 6) { isValid = 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)) { + fieldErrors[errorFieldName] = 'Please make your password at least 6 characters long'; + } else if (field === 'signupConfirm' && value !== this.state.signupPassword) { isValid = false; - fieldUpdate[errorFieldName] = 'Your passwords must match'; + fieldErrors[errorFieldName] = 'Your passwords must match'; } } if (field === 'signupUsername') { if (value !== '' && /[^a-zA-Z0-9]+/g.test(value)) { isValid = false; - fieldUpdate[errorFieldName] = 'Please use only letters and numbers'; + fieldErrors[errorFieldName] = 'Please use only letters and numbers'; } } if (isValid) { - fieldUpdate[errorFieldName] = ''; + fieldErrors[errorFieldName] = ''; } - fieldUpdate[field] = (field === 'signupAllowEmail') ? checked : value; - this.setState(fieldUpdate); + return fieldErrors; + } + + validateSignupForm (callback) { + const fields = ['signupEmail', 'signupUsername', 'signupPassword', 'signupConfirm']; + let errors = {}; + fields.forEach(field => { + const fieldErrors = this.validateField(field, this.state[field]); + errors = Object.assign(errors, fieldErrors); + }); + errors.signupFormIsValid = !signupEmailChecking && !signupUsernameChecking + && signupEmailIsUnique && signupUsernameIsUnique + && Object.keys(errors).every(field => errors[field] === ''); + this.setState(errors, callback); + } + + validateLoginForm (callback) { + const fields = ['loginEmail','loginPassword']; + let errors = {}; + fields.forEach(field => { + errors = Object.assign(errors, this.validateField(field, this.state[field])); + }); + errors.loginFormIsValid = Object.keys(errors).every(field => { + return errors[field] === ''; + }); + this.setState(errors, callback); } checkFieldUnique (field, event) { @@ -117,6 +174,34 @@ export class LoginForm extends Component { } } + logIn () { + this.validateLoginForm(() => { + if (this.loginFormIsValid) { + const { loginEmail, loginPassword } = this.state; + this.props.logIn(loginEmail, loginPassword); + } + }); + } + + createAccount () { + this.validateSignupForm(() => { + if (this.signupFormIsValid) { + const { + signupEmail, + signupUsername, + signupPublicName, + signupPassword, + signupAllowEmail + } = this.state; + this.props.signUp(signupEmail, signupPassword, { + username: signupUsername, + publicName: signupPublicName, + allowEmail: signupAllowEmail, + }); + } + }); + } + render () { return (