mirror of
https://github.com/Alamantus/Lexiconga.git
synced 2025-07-06 23:54:17 +02:00
Fix sign up; Add confirmations to sign up and log in
This commit is contained in:
parent
0f6b5deb1a
commit
095b8051be
4 changed files with 150 additions and 203 deletions
|
@ -13,7 +13,7 @@ class User {
|
||||||
}
|
}
|
||||||
|
|
||||||
public function logIn ($email, $password) {
|
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();
|
$user = $this->db->query($query, array(':email' => $email))->fetch();
|
||||||
if ($user) {
|
if ($user) {
|
||||||
if ($user['old_password'] !== null) {
|
if ($user['old_password'] !== null) {
|
||||||
|
@ -39,22 +39,15 @@ 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, $user_data) {
|
public function create ($email, $password, $user_data) {
|
||||||
$insert_user_query = 'INSERT INTO users (email, password, public_name, username, allow_email, created_on)
|
$insert_user_query = 'INSERT INTO users (email, password, public_name, allow_email, created_on)
|
||||||
VALUES (?, ?, ?, ?, ?, ?)';
|
VALUES (?, ?, ?, ?, ?)';
|
||||||
$password_hash = password_hash($password, PASSWORD_DEFAULT);
|
$password_hash = password_hash($password, PASSWORD_DEFAULT);
|
||||||
|
|
||||||
$insert_user = $this->db->execute($insert_user_query, array(
|
$insert_user = $this->db->execute($insert_user_query, array(
|
||||||
$email,
|
$email,
|
||||||
$password_hash,
|
$password_hash,
|
||||||
$user_data['publicName'] !== '' ? $user_data['publicName'] : null,
|
$user_data['publicName'] !== '' ? $user_data['publicName'] : null,
|
||||||
$user_data['username'] !== '' ? $user_data['username'] : null,
|
|
||||||
$user_data['allowEmail'] ? 1 : 0,
|
$user_data['allowEmail'] ? 1 : 0,
|
||||||
time(),
|
time(),
|
||||||
));
|
));
|
||||||
|
@ -108,7 +101,6 @@ VALUES (?, ?, ?, ?, ?, ?)';
|
||||||
if ($stmt && $user) {
|
if ($stmt && $user) {
|
||||||
return array(
|
return array(
|
||||||
'email' => $user['email'],
|
'email' => $user['email'],
|
||||||
'username' => $user['username'],
|
|
||||||
'publicName' => $user['public_name'],
|
'publicName' => $user['public_name'],
|
||||||
'allowEmails' => $user['allow_email'] == 1 ? true : false,
|
'allowEmails' => $user['allow_email'] == 1 ? true : false,
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,11 +1,6 @@
|
||||||
import Inferno from 'inferno';
|
import Inferno from 'inferno';
|
||||||
import { Component } from 'inferno';
|
import { Component } from 'inferno';
|
||||||
import PropTypes from 'prop-types';
|
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';
|
import { request } from '../../../Helpers';
|
||||||
|
|
||||||
|
@ -26,19 +21,15 @@ export class LoginForm extends Component {
|
||||||
loginPasswordError: '',
|
loginPasswordError: '',
|
||||||
loginFormIsValid: true,
|
loginFormIsValid: true,
|
||||||
signupEmail: '',
|
signupEmail: '',
|
||||||
// signupUsername: '',
|
|
||||||
signupPublicName: '',
|
signupPublicName: '',
|
||||||
signupPassword: '',
|
signupPassword: '',
|
||||||
signupConfirm: '',
|
signupConfirm: '',
|
||||||
signupAllowEmail: true,
|
signupAllowEmail: true,
|
||||||
signupEmailError: '',
|
signupEmailError: '',
|
||||||
// signupUsernameError: '',
|
|
||||||
signupPasswordError: '',
|
signupPasswordError: '',
|
||||||
signupConfirmError: '',
|
signupConfirmError: '',
|
||||||
signupEmailChecking: false,
|
signupEmailChecking: false,
|
||||||
// signupUsernameChecking: false,
|
|
||||||
signupEmailIsUnique: true,
|
signupEmailIsUnique: true,
|
||||||
// signupUsernameIsUnique: true,
|
|
||||||
signupFormIsValid: true,
|
signupFormIsValid: true,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -56,15 +47,11 @@ export class LoginForm extends Component {
|
||||||
signupEmailError,
|
signupEmailError,
|
||||||
signupEmailChecking,
|
signupEmailChecking,
|
||||||
signupEmailIsUnique,
|
signupEmailIsUnique,
|
||||||
// signupUsernameError,
|
|
||||||
// signupUsernameChecking,
|
|
||||||
// signupUsernameIsUnique,
|
|
||||||
signupPasswordError,
|
signupPasswordError,
|
||||||
signupConfirmError,
|
signupConfirmError,
|
||||||
} = this.state;
|
} = this.state;
|
||||||
return !signupEmailChecking && !signupUsernameChecking
|
return !signupEmailChecking
|
||||||
&& signupEmailIsUnique && signupEmailError === ''
|
&& signupEmailIsUnique && signupEmailError === ''
|
||||||
// && signupUsernameIsUnique && signupUsernameError === ''
|
|
||||||
&& signupPasswordError === '' && signupConfirmError === '';
|
&& 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) {
|
if (isValid) {
|
||||||
fieldErrors[errorFieldName] = '';
|
fieldErrors[errorFieldName] = '';
|
||||||
}
|
}
|
||||||
|
@ -118,12 +98,9 @@ export class LoginForm extends Component {
|
||||||
const {
|
const {
|
||||||
signupEmailChecking,
|
signupEmailChecking,
|
||||||
signupEmailIsUnique,
|
signupEmailIsUnique,
|
||||||
// signupUsernameChecking,
|
|
||||||
// signupUsernameIsUnique,
|
|
||||||
} = this.state;
|
} = this.state;
|
||||||
const fields = [
|
const fields = [
|
||||||
'signupEmail',
|
'signupEmail',
|
||||||
// 'signupUsername',
|
|
||||||
'signupPassword',
|
'signupPassword',
|
||||||
'signupConfirm'
|
'signupConfirm'
|
||||||
];
|
];
|
||||||
|
@ -133,7 +110,6 @@ export class LoginForm extends Component {
|
||||||
errors = Object.assign(errors, fieldErrors);
|
errors = Object.assign(errors, fieldErrors);
|
||||||
});
|
});
|
||||||
errors.signupFormIsValid = !signupEmailChecking && signupEmailIsUnique
|
errors.signupFormIsValid = !signupEmailChecking && signupEmailIsUnique
|
||||||
// && !signupUsernameChecking && signupUsernameIsUnique
|
|
||||||
&& Object.keys(errors).every(field => errors[field] === '');
|
&& Object.keys(errors).every(field => errors[field] === '');
|
||||||
this.setState(errors, callback);
|
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 () {
|
logIn () {
|
||||||
|
@ -200,13 +161,11 @@ export class LoginForm extends Component {
|
||||||
if (this.signupFormIsValid) {
|
if (this.signupFormIsValid) {
|
||||||
const {
|
const {
|
||||||
signupEmail,
|
signupEmail,
|
||||||
// signupUsername,
|
|
||||||
signupPublicName,
|
signupPublicName,
|
||||||
signupPassword,
|
signupPassword,
|
||||||
signupAllowEmail
|
signupAllowEmail
|
||||||
} = this.state;
|
} = this.state;
|
||||||
this.props.signUp(signupEmail, signupPassword, {
|
this.props.signUp(signupEmail, signupPassword, {
|
||||||
// username: signupUsername,
|
|
||||||
publicName: signupPublicName,
|
publicName: signupPublicName,
|
||||||
allowEmail: signupAllowEmail,
|
allowEmail: signupAllowEmail,
|
||||||
});
|
});
|
||||||
|
@ -216,7 +175,7 @@ export class LoginForm extends Component {
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
return (
|
return (
|
||||||
<div className='columns'>
|
<div className='columns has-text-left'>
|
||||||
<div className='column'>
|
<div className='column'>
|
||||||
<div className='tabs is-boxed'>
|
<div className='tabs is-boxed'>
|
||||||
<ul>
|
<ul>
|
||||||
|
@ -274,10 +233,10 @@ export class LoginForm extends Component {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className='field'>
|
<div className='field'>
|
||||||
<a className='button is-success'
|
<button className='button is-success'
|
||||||
onClick={this.logIn.bind(this)}>
|
onClick={this.logIn.bind(this)}>
|
||||||
Log In
|
Log In
|
||||||
</a>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
|
@ -326,29 +285,7 @@ export class LoginForm extends Component {
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{/* <div className='field'>
|
|
||||||
<label className='label'>
|
|
||||||
Username
|
|
||||||
</label>
|
|
||||||
<div className='help'>
|
|
||||||
This is your unique identifier that appears in the URL if you ever decide to share your dictionaries publicly.
|
|
||||||
</div>
|
|
||||||
<div className={`control ${this.state.signupUsernameChecking && 'is-loading'}`}>
|
|
||||||
<input className={`input ${!this.state.signupUsernameIsUnique && 'is-danger'}`}
|
|
||||||
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 className='field'>
|
<div className='field'>
|
||||||
<label className='label'>
|
<label className='label'>
|
||||||
Public Name
|
Public Name
|
||||||
|
@ -362,6 +299,7 @@ export class LoginForm extends Component {
|
||||||
onInput={(event) => this.updateField('signupPublicName', event)} />
|
onInput={(event) => this.updateField('signupPublicName', event)} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className='field'>
|
<div className='field'>
|
||||||
<label className='label'>
|
<label className='label'>
|
||||||
Password<sup>*</sup>
|
Password<sup>*</sup>
|
||||||
|
@ -380,6 +318,7 @@ export class LoginForm extends Component {
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className='field'>
|
<div className='field'>
|
||||||
<label className='label'>
|
<label className='label'>
|
||||||
Confirm Password<sup>*</sup>
|
Confirm Password<sup>*</sup>
|
||||||
|
@ -398,6 +337,7 @@ export class LoginForm extends Component {
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className='field'>
|
<div className='field'>
|
||||||
<div className='control'>
|
<div className='control'>
|
||||||
<input className='is-checkradio' id='signupAllowEmail' type='checkbox'
|
<input className='is-checkradio' id='signupAllowEmail' type='checkbox'
|
||||||
|
@ -411,12 +351,13 @@ export class LoginForm extends Component {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className='field'>
|
<div className='field'>
|
||||||
<div className='control'>
|
<div className='control'>
|
||||||
<a className='button is-success'
|
<button className='button is-success'
|
||||||
onClick={this.createAccount.bind(this)}>
|
onClick={this.createAccount.bind(this)}>
|
||||||
Create Account
|
Create Account
|
||||||
</a>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -2,8 +2,6 @@ import Inferno from 'inferno';
|
||||||
import { Component } from 'inferno';
|
import { Component } from 'inferno';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
|
||||||
import { request } from '../../../Helpers';
|
|
||||||
|
|
||||||
export class MyAccount extends Component {
|
export class MyAccount extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
@ -69,134 +67,132 @@ export class MyAccount extends Component {
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div className='columns has-text-left'>
|
||||||
<div className='columns'>
|
|
||||||
|
|
||||||
<div className='column'>
|
<div className='column'>
|
||||||
<h2 className='title'>Account Details</h2>
|
<h2 className='title'>Account Details</h2>
|
||||||
<div className='field'>
|
<div className='field'>
|
||||||
<label className='label'>
|
<label className='label'>
|
||||||
<span>Email:</span>
|
<span>Email:</span>
|
||||||
</label>
|
</label>
|
||||||
<div className='control'>
|
<div className='control'>
|
||||||
<input className='input' type='text' value={this.state.email}
|
<input className='input' type='text' value={this.state.email}
|
||||||
onInput={ event => this.setState({ email: event.target.value }) }
|
onInput={ event => this.setState({ email: event.target.value }) }
|
||||||
onChange={ () => this.checkFields() } />
|
onChange={ () => this.checkFields() } />
|
||||||
<div className='help'>
|
<div className='help'>
|
||||||
<strong>Note:</strong> If you change your email address, you will need to use your new email address to log in.
|
<strong>Note:</strong> If you change your email address, you will need to use your new email address to log in.
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className='field'>
|
|
||||||
<label className='label'>
|
|
||||||
<span>Public Name:</span>
|
|
||||||
</label>
|
|
||||||
<div className='control'>
|
|
||||||
<input className='input' type='text' value={this.state.publicName}
|
|
||||||
onInput={ event => this.setState({ publicName: event.target.value }) }
|
|
||||||
onChange={ () => this.checkFields() } />
|
|
||||||
<div className='help'>
|
|
||||||
This is the name we greet you with. It's also the name displayed if you ever decide to share
|
|
||||||
any of your dictionaries.
|
|
||||||
</div>
|
|
||||||
<div className='help'>
|
|
||||||
<strong>Note:</strong> This is <em>not a username</em>, 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!
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className='field'>
|
|
||||||
<div className='control'>
|
|
||||||
<input className='is-checkradio is-rtl' type='checkbox' id='allowEmails'
|
|
||||||
checked={this.state.allowEmails ? 'checked' : false}
|
|
||||||
onChange={(event) => {
|
|
||||||
this.setState({ allowEmails: !this.state.allowEmails }, () => this.checkFields());
|
|
||||||
}} />
|
|
||||||
<label className='label is-unselectable' htmlFor='allowEmails'>
|
|
||||||
Allow Emails
|
|
||||||
</label>
|
|
||||||
<div className='help'>
|
|
||||||
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.
|
|
||||||
</div>
|
|
||||||
<div className='help'>
|
|
||||||
<strong>Note:</strong> Password reset emails will be sent regardless of your choice here.
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className='field'>
|
|
||||||
<div className='control'>
|
|
||||||
<button className='button' Disabled={ !this.state.canSend ? 'disabled' : null }
|
|
||||||
onClick={ () => this.saveChanges() }>
|
|
||||||
Save Changes
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div className='field'>
|
||||||
<div className='column'>
|
<label className='label'>
|
||||||
<h2 className='title'>Account Actions</h2>
|
<span>Public Name:</span>
|
||||||
|
</label>
|
||||||
<div className='field'>
|
<div className='control'>
|
||||||
<label className='label is-unselectable'>
|
<input className='input' type='text' value={this.state.publicName}
|
||||||
<span>Change Dictionary</span>
|
onInput={ event => this.setState({ publicName: event.target.value }) }
|
||||||
</label>
|
onChange={ () => this.checkFields() } />
|
||||||
<div className='control'>
|
<div className='help'>
|
||||||
<div className='select'>
|
This is the name we greet you with. It's also the name displayed if you ever decide to share
|
||||||
<select>
|
any of your dictionaries.
|
||||||
{this.props.userDictionaries.map(item => {
|
</div>
|
||||||
return <option value={item.id}>{item.name}</option>;
|
<div className='help'>
|
||||||
})}
|
<strong>Note:</strong> This is <em>not a username</em>, and is therefore not guaranteed to be unique.
|
||||||
</select>
|
Use something people will recognize you as to differentiate from other people who might use the same name!
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
<div className='field'>
|
<div className='field'>
|
||||||
<label className='label is-unselectable'>
|
<div className='control'>
|
||||||
<span>Reset Your Password</span>
|
<input className='is-checkradio is-rtl' type='checkbox' id='allowEmails'
|
||||||
|
checked={this.state.allowEmails ? 'checked' : false}
|
||||||
|
onChange={(event) => {
|
||||||
|
this.setState({ allowEmails: !this.state.allowEmails }, () => this.checkFields());
|
||||||
|
}} />
|
||||||
|
<label className='label is-unselectable' htmlFor='allowEmails'>
|
||||||
|
Allow Emails
|
||||||
</label>
|
</label>
|
||||||
<div className='help'>
|
<div className='help'>
|
||||||
Click the button below to reload the page and show the Reset Password form. Filling out this
|
We'll make sure that you're the first to hear about any new features that get added or if any of our policies
|
||||||
form will instantly change your password, and you will need to log in using the new password
|
change for any reason. We'll never spam you or sell your information, but you may need to mark emails from
|
||||||
from that point forward.
|
lexicon.ga as not spam to receive them.
|
||||||
</div>
|
</div>
|
||||||
<div className='control'>
|
<div className='help'>
|
||||||
<a className='button'>Reset Password</a>
|
<strong>Note:</strong> Password reset emails will be sent regardless of your choice here.
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className='content is-small'>
|
|
||||||
<h4><strong>Request Your Data</strong></h4>
|
|
||||||
<p>
|
|
||||||
Per your <a href='https://www.eugdpr.org/' target='_blank'>GDPR</a> 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.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className='content is-small'>
|
|
||||||
<h4><strong>Delete Your Account</strong></h4>
|
|
||||||
<p>
|
|
||||||
Per your <a href='https://www.eugdpr.org/' target='_blank'>GDPR</a> 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.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
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).
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div className='field'>
|
||||||
|
<div className='control'>
|
||||||
|
<button className='button' Disabled={ !this.state.canSend ? 'disabled' : null }
|
||||||
|
onClick={ () => this.saveChanges() }>
|
||||||
|
Save Changes
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div className='column'>
|
||||||
|
<h2 className='title'>Account Actions</h2>
|
||||||
|
|
||||||
|
<div className='field'>
|
||||||
|
<label className='label is-unselectable'>
|
||||||
|
<span>Change Dictionary</span>
|
||||||
|
</label>
|
||||||
|
<div className='control'>
|
||||||
|
<div className='select'>
|
||||||
|
<select>
|
||||||
|
{this.props.userDictionaries.map(item => {
|
||||||
|
return <option value={item.id}>{item.name}</option>;
|
||||||
|
})}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className='field'>
|
||||||
|
<label className='label is-unselectable'>
|
||||||
|
<span>Reset Your Password</span>
|
||||||
|
</label>
|
||||||
|
<div className='help'>
|
||||||
|
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.
|
||||||
|
</div>
|
||||||
|
<div className='control'>
|
||||||
|
<a className='button'>Reset Password</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className='content is-small'>
|
||||||
|
<h4><strong>Request Your Data</strong></h4>
|
||||||
|
<p>
|
||||||
|
Per your <a href='https://www.eugdpr.org/' target='_blank'>GDPR</a> 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.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className='content is-small'>
|
||||||
|
<h4><strong>Delete Your Account</strong></h4>
|
||||||
|
<p>
|
||||||
|
Per your <a href='https://www.eugdpr.org/' target='_blank'>GDPR</a> 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.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
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).
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import Inferno from 'inferno';
|
import Inferno from 'inferno';
|
||||||
import { Component } from 'inferno';
|
import { Component } from 'inferno';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import marked from 'marked';
|
|
||||||
import store from 'store';
|
import store from 'store';
|
||||||
import swal from 'sweetalert2';
|
import swal from 'sweetalert2';
|
||||||
|
|
||||||
|
@ -36,7 +35,16 @@ export class AccountManager extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
logIn (email, password) {
|
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 () {
|
logOut () {
|
||||||
|
@ -62,7 +70,16 @@ export class AccountManager extends Component {
|
||||||
email,
|
email,
|
||||||
password,
|
password,
|
||||||
userData,
|
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 = () => {}) {
|
updateUserData (token, userData, callback = () => {}) {
|
||||||
|
@ -76,12 +93,13 @@ export class AccountManager extends Component {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
handleResponse (response) {
|
handleResponse (response, successCallback = () => {}) {
|
||||||
const { data, error } = response;
|
const { data, error } = response;
|
||||||
if (error) {
|
if (error) {
|
||||||
console.error(data);
|
console.error(data);
|
||||||
} else {
|
} else {
|
||||||
this.updateUserData(data.token, data.user, () => {
|
this.updateUserData(data.token, data.user, () => {
|
||||||
|
successCallback(data.user);
|
||||||
this.getDictionaryNames();
|
this.getDictionaryNames();
|
||||||
this.props.updater.sync();
|
this.props.updater.sync();
|
||||||
});
|
});
|
||||||
|
|
Loading…
Add table
Reference in a new issue