diff --git a/public/api/User.php b/public/api/User.php index 0c1208f..34ebb39 100644 --- a/public/api/User.php +++ b/public/api/User.php @@ -13,7 +13,7 @@ class User { } public function logIn ($email, $password) { - $query = 'SELECT * FROM users WHERE email=:email OR username=:email'; + $query = 'SELECT * FROM users WHERE email=:email'; $user = $this->db->query($query, array(':email' => $email))->fetch(); if ($user) { if ($user['old_password'] !== null) { @@ -39,22 +39,15 @@ class User { 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, $user_data) { - $insert_user_query = 'INSERT INTO users (email, password, public_name, username, allow_email, created_on) -VALUES (?, ?, ?, ?, ?, ?)'; + $insert_user_query = 'INSERT INTO users (email, password, public_name, allow_email, created_on) +VALUES (?, ?, ?, ?, ?)'; $password_hash = password_hash($password, PASSWORD_DEFAULT); $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, time(), )); @@ -108,7 +101,6 @@ VALUES (?, ?, ?, ?, ?, ?)'; if ($stmt && $user) { return array( 'email' => $user['email'], - 'username' => $user['username'], 'publicName' => $user['public_name'], 'allowEmails' => $user['allow_email'] == 1 ? true : false, ); diff --git a/src/components/management/AccountManager/LoginForm.jsx b/src/components/management/AccountManager/LoginForm.jsx index 0263a32..87a8f63 100644 --- a/src/components/management/AccountManager/LoginForm.jsx +++ b/src/components/management/AccountManager/LoginForm.jsx @@ -1,11 +1,6 @@ import Inferno from 'inferno'; import { Component } from 'inferno'; import PropTypes from 'prop-types'; -import marked from 'marked'; -import store from 'store'; - -import { Modal } from '../../structure/Modal'; -import { SearchBox } from '../../management/SearchBox'; import { request } from '../../../Helpers'; @@ -26,19 +21,15 @@ export class LoginForm extends Component { loginPasswordError: '', loginFormIsValid: true, signupEmail: '', - // signupUsername: '', signupPublicName: '', signupPassword: '', signupConfirm: '', signupAllowEmail: true, signupEmailError: '', - // signupUsernameError: '', signupPasswordError: '', signupConfirmError: '', signupEmailChecking: false, - // signupUsernameChecking: false, signupEmailIsUnique: true, - // signupUsernameIsUnique: true, signupFormIsValid: true, }; } @@ -56,15 +47,11 @@ export class LoginForm extends Component { signupEmailError, signupEmailChecking, signupEmailIsUnique, - // signupUsernameError, - // signupUsernameChecking, - // signupUsernameIsUnique, signupPasswordError, signupConfirmError, } = this.state; - return !signupEmailChecking && !signupUsernameChecking + return !signupEmailChecking && signupEmailIsUnique && signupEmailError === '' - // && signupUsernameIsUnique && signupUsernameError === '' && signupPasswordError === '' && signupConfirmError === ''; } @@ -101,13 +88,6 @@ export class LoginForm extends Component { } } - // if (field === 'signupUsername') { - // if (value !== '' && /[^a-zA-Z0-9]+/g.test(value)) { - // isValid = false; - // fieldErrors[errorFieldName] = 'Please use only letters and numbers'; - // } - // } - if (isValid) { fieldErrors[errorFieldName] = ''; } @@ -118,12 +98,9 @@ export class LoginForm extends Component { const { signupEmailChecking, signupEmailIsUnique, - // signupUsernameChecking, - // signupUsernameIsUnique, } = this.state; const fields = [ 'signupEmail', - // 'signupUsername', 'signupPassword', 'signupConfirm' ]; @@ -133,7 +110,6 @@ export class LoginForm extends Component { errors = Object.assign(errors, fieldErrors); }); errors.signupFormIsValid = !signupEmailChecking && signupEmailIsUnique - // && !signupUsernameChecking && signupUsernameIsUnique && Object.keys(errors).every(field => errors[field] === ''); this.setState(errors, callback); } @@ -169,21 +145,6 @@ export class LoginForm extends Component { }); }); } - // 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); - // }); - // }); - // } } logIn () { @@ -200,13 +161,11 @@ export class LoginForm extends Component { if (this.signupFormIsValid) { const { signupEmail, - // signupUsername, signupPublicName, signupPassword, signupAllowEmail } = this.state; this.props.signUp(signupEmail, signupPassword, { - // username: signupUsername, publicName: signupPublicName, allowEmail: signupAllowEmail, }); @@ -216,7 +175,7 @@ export class LoginForm extends Component { render () { return ( -
+
    @@ -274,10 +233,10 @@ export class LoginForm extends Component {
- Log In - +
) : ( @@ -326,29 +285,7 @@ export class LoginForm extends Component { }
- {/*
- -
- This is your unique identifier that appears in the URL if you ever decide to share your dictionaries publicly. -
-
- this.updateField('signupUsername', event)} - onBlur={(event) => this.checkFieldUnique('signupUsername', event)} /> - { - (this.state.signupUsernameError !== '' || !this.state.signupUsernameIsUnique) - ? ( -
- {!this.state.signupUsernameIsUnique &&

This username address is already in use

} - {this.state.signupUsernameError} -
- ) : null - } -
-
*/} +
+
+
+
+
- Create Account - +
diff --git a/src/components/management/AccountManager/MyAccount.jsx b/src/components/management/AccountManager/MyAccount.jsx index 4fca010..6397176 100644 --- a/src/components/management/AccountManager/MyAccount.jsx +++ b/src/components/management/AccountManager/MyAccount.jsx @@ -2,8 +2,6 @@ import Inferno from 'inferno'; import { Component } from 'inferno'; import PropTypes from 'prop-types'; -import { request } from '../../../Helpers'; - export class MyAccount extends Component { constructor(props) { super(props); @@ -69,134 +67,132 @@ export class MyAccount extends Component { render() { return ( -
-
- -
-

Account Details

-
- -
- this.setState({ email: event.target.value }) } - onChange={ () => this.checkFields() } /> -
- Note: If you change your email address, you will need to use your new email address to log in. -
-
-
-
- -
- this.setState({ publicName: event.target.value }) } - onChange={ () => this.checkFields() } /> -
- This is the name we greet you with. It's also the name displayed if you ever decide to share - any of your dictionaries. -
-
- Note: This is not a username, and is therefore not guaranteed to be unique. - Use something people will recognize you as to differentiate from other people who might use the same name! -
-
-
-
-
- { - this.setState({ allowEmails: !this.state.allowEmails }, () => this.checkFields()); - }} /> - -
- We'll make sure that you're the first to hear about any new features that get added or if any of our policies - change for any reason. We'll never spam you or sell your information, but you may need to mark emails from - lexicon.ga as not spam to receive them. -
-
- Note: Password reset emails will be sent regardless of your choice here. -
-
-
- -
-
- +
+ +
+

Account Details

+
+ +
+ this.setState({ email: event.target.value }) } + onChange={ () => this.checkFields() } /> +
+ Note: If you change your email address, you will need to use your new email address to log in.
- -
-

Account Actions

- -
- -
-
- -
+
+ +
+ this.setState({ publicName: event.target.value }) } + onChange={ () => this.checkFields() } /> +
+ This is the name we greet you with. It's also the name displayed if you ever decide to share + any of your dictionaries. +
+
+ Note: This is not a username, and is therefore not guaranteed to be unique. + Use something people will recognize you as to differentiate from other people who might use the same name!
- -
-
+
+
+ { + this.setState({ allowEmails: !this.state.allowEmails }, () => this.checkFields()); + }} /> +
- Click the button below to reload the page and show the Reset Password form. Filling out this - form will instantly change your password, and you will need to log in using the new password - from that point forward. + We'll make sure that you're the first to hear about any new features that get added or if any of our policies + change for any reason. We'll never spam you or sell your information, but you may need to mark emails from + lexicon.ga as not spam to receive them.
-
- Reset Password +
+ Note: Password reset emails will be sent regardless of your choice here.
- -
-

Request Your Data

-

- Per your GDPR rights in Articles 13–15 and 20, - we allow you to request any and all data we have stored about you. The only data we have about - you personally is your email address and your Public Name, if you decided to set one. All other - data (your Dictionary data) is visible and accessible via the Export button under your Dictionary's - Settings. Send an email to help@lexicon.ga to request your information. -

-
- -
-

Delete Your Account

-

- Per your GDPR rights in Article 17, if you wish - for your account to be deleted, please contact us at help@lexicon.ga, and we will delete your account - and all associated dictionaries and words as quickly as possible. Note that you can delete dictionaries - yourself via your Dictionary's Settings. -

-

- Anything that is deleted from our system is permanently and irretrievably removed from our system and - cannot be restored, though search engines or internet archives may retain a cached version of your content - (there is nothing we can do about this, and you will need to seek out removal of that information by directly - contacting the services that are caching your data). -

-
- + +
+
+ +
+
+ +
+

Account Actions

+ +
+ +
+
+ +
+
+
+ +
+ +
+ Click the button below to reload the page and show the Reset Password form. Filling out this + form will instantly change your password, and you will need to log in using the new password + from that point forward. +
+ +
+ +
+

Request Your Data

+

+ Per your GDPR rights in Articles 13–15 and 20, + we allow you to request any and all data we have stored about you. The only data we have about + you personally is your email address and your Public Name, if you decided to set one. All other + data (your Dictionary data) is visible and accessible via the Export button under your Dictionary's + Settings. Send an email to help@lexicon.ga to request your information. +

+
+ +
+

Delete Your Account

+

+ Per your GDPR rights in Article 17, if you wish + for your account to be deleted, please contact us at help@lexicon.ga, and we will delete your account + and all associated dictionaries and words as quickly as possible. Note that you can delete dictionaries + yourself via your Dictionary's Settings. +

+

+ Anything that is deleted from our system is permanently and irretrievably removed from our system and + cannot be restored, though search engines or internet archives may retain a cached version of your content + (there is nothing we can do about this, and you will need to seek out removal of that information by directly + contacting the services that are caching your data). +

+
+
+
); } diff --git a/src/components/management/AccountManager/index.jsx b/src/components/management/AccountManager/index.jsx index bf3e122..79e15cd 100644 --- a/src/components/management/AccountManager/index.jsx +++ b/src/components/management/AccountManager/index.jsx @@ -1,7 +1,6 @@ import Inferno from 'inferno'; import { Component } from 'inferno'; import PropTypes from 'prop-types'; -import marked from 'marked'; import store from 'store'; import swal from 'sweetalert2'; @@ -36,7 +35,16 @@ export class AccountManager extends Component { } logIn (email, password) { - return request('login', { email, password }, this.handleResponse.bind(this)); + return request('login', { email, password }, response => this.handleResponse(response, userData => { + const nameGreeting = userData.hasOwnProperty('publicName') && userData.publicName !== '' ? ', ' + userData.publicName : ''; + swal({ + title: `Welcome back${nameGreeting}!`, + text: 'You have been logged in successfully.', + type: 'success', + confirmButtonClass: 'button', + buttonsStyling: false, + }); + })); } logOut () { @@ -62,7 +70,16 @@ export class AccountManager extends Component { email, password, userData, - }, this.handleResponse.bind(this)); + }, response => this.handleResponse(response, () => { + const nameGreeting = userData.hasOwnProperty('publicName') && userData.publicName !== '' ? ', ' + userData.publicName : ''; + swal({ + title: `Welcome${nameGreeting}!`, + text: 'Your account was created successfully! We hope you enjoy what a Lexiconga account can provide for you!', + type: 'success', + confirmButtonClass: 'button', + buttonsStyling: false, + }); + })); } updateUserData (token, userData, callback = () => {}) { @@ -76,12 +93,13 @@ export class AccountManager extends Component { }); } - handleResponse (response) { + handleResponse (response, successCallback = () => {}) { const { data, error } = response; if (error) { console.error(data); } else { this.updateUserData(data.token, data.user, () => { + successCallback(data.user); this.getDictionaryNames(); this.props.updater.sync(); });