Commit 5a8c7d12 authored by roadscape's avatar roadscape
Browse files

remove waiting_list and pick_account

parent 5740f817
import models from '../db/models';
import sendEmail from '../server/sendEmail';
import secureRandom from 'secure-random'
function inviteUser(u, email, number) {
const confirmation_code = secureRandom.randomBuffer(13).toString('hex');
console.log(`\n***** invite #${number} ***** `, u.id, email, confirmation_code);
const i_attrs = {
provider: 'email',
user_id: u.id,
email,
verified: false,
confirmation_code
};
models.Identity.create(i_attrs).then(() => {
sendEmail('waiting_list_invite', 'to@example.com', {confirmation_code}, 'from@example.com');
});
}
models.User.findAll({
attributes: ['id', 'email'],
where: {waiting_list: true, email: {$ne: null}, id: {$gt: 0}},
order: 'id',
limit: 1000
}).then(users => {
let counter = 1;
for(let u of users) {
const email = u.email.toLowerCase();
if (email.match(/\@qq\.com$/)) continue;
const m = email.match(/\.(\w+)$/);
if (!m || m[1] === 'ru') continue;
const number = counter;
setTimeout(() => inviteUser(u, email, number), counter * 1000);
counter += 1;
}
});
......@@ -55,9 +55,6 @@ export default function resolveRoute(path) {
if (path === '/recover_account_step_2') {
return { page: 'RecoverAccountStep2' };
}
if (path === '/waiting_list.html') {
return { page: 'WaitingList' };
}
if (path === '/market') {
return { page: 'Market' };
}
......
......@@ -34,10 +34,8 @@ describe('resolveRoute', () => {
['/change_password', { page: 'ChangePassword' }],
['/create_account', { page: 'CreateAccount' }],
['/approval', { page: 'Approval' }],
['/pick_account', { page: 'NotFound' }],
['/recover_account_step_1', { page: 'RecoverAccountStep1' }],
['/recover_account_step_2', { page: 'RecoverAccountStep2' }],
['/waiting_list.html', { page: 'WaitingList' }],
['/market', { page: 'Market' }],
['/~witnesses', { page: 'Witnesses' }],
['/@gdpr/nice345', { page: 'NotFound' }],
......
......@@ -34,8 +34,6 @@ export default {
cb(null, [require('app/components/pages/Tos')]);
} else if (route.page === 'ChangePassword') {
cb(null, [require('app/components/pages/ChangePasswordPage')]);
} else if (route.page === 'PickAccount') {
cb(null, [require('app/components/pages/PickAccount')]);
} else if (route.page === 'CreateAccount') {
cb(null, [require('app/components/pages/CreateAccount')]);
} else if (route.page === 'Approval') {
......@@ -44,8 +42,6 @@ export default {
cb(null, [require('app/components/pages/RecoverAccountStep1')]);
} else if (route.page === 'RecoverAccountStep2') {
cb(null, [require('app/components/pages/RecoverAccountStep2')]);
} else if (route.page === 'WaitingList') {
cb(null, [require('app/components/pages/WaitingList')]);
} else if (route.page === 'Witnesses') {
cb(null, [require('app/components/pages/Witnesses')]);
} else if (route.page === 'UserProfile') {
......
......@@ -129,9 +129,7 @@ class App extends React.Component {
order,
} = this.props;
const miniHeader =
pathname === '/create_account' || pathname === '/pick_account';
const miniHeader = false;
const whistleView = viewMode === VIEW_MODE_WHISTLE;
const headerHidden = whistleView;
const params_keys = Object.keys(params);
......
import React from 'react';
import tt from 'counterpart';
import { APP_NAME } from 'app/client_config';
const email_regex = /^([^\x00-\x20\x22\x28\x29\x2c\x2e\x3a-\x3c\x3e\x40\x5b-\x5d\x7f-\xff]+|\x22([^\x0d\x22\x5c\x80-\xff]|\x5c[\x00-\x7f])*\x22)(\x2e([^\x00-\x20\x22\x28\x29\x2c\x2e\x3a-\x3c\x3e\x40\x5b-\x5d\x7f-\xff]+|\x22([^\x0d\x22\x5c\x80-\xff]|\x5c[\x00-\x7f])*\x22))*\x40([^\x00-\x20\x22\x28\x29\x2c\x2e\x3a-\x3c\x3e\x40\x5b-\x5d\x7f-\xff]+|\x5b([^\x0d\x5b-\x5d\x80-\xff]|\x5c[\x00-\x7f])*\x5d)(\x2e([^\x00-\x20\x22\x28\x29\x2c\x2e\x3a-\x3c\x3e\x40\x5b-\x5d\x7f-\xff]+|\x5b([^\x0d\x5b-\x5d\x80-\xff]|\x5c[\x00-\x7f])*\x5d))*$/;
export default class AddToWaitingList extends React.Component {
constructor() {
super();
this.state = { email: '', submitted: false, email_error: '' };
this.onEmailChange = this.onEmailChange.bind(this);
}
onSubmit = e => {
e.preventDefault();
const email = this.state.email;
if (!email) return;
fetch('/api/v1/update_email', {
method: 'post',
mode: 'no-cors',
credentials: 'same-origin',
headers: {
Accept: 'application/json',
'Content-type': 'application/json',
},
body: JSON.stringify({ csrf: $STM_csrf, email }),
})
.then(r => r.json())
.then(res => {
if (res.error || res.status !== 'ok') {
console.error('CreateAccount server error', res.error);
} else {
// TODO: process errors
}
this.setState({ submitted: true });
})
.catch(error => {
console.error('Caught CreateAccount server error', error);
this.setState({ submitted: true });
});
};
onEmailChange(e) {
const email = e.target.value.trim().toLowerCase();
let email_error = '';
if (!email_regex.test(email.toLowerCase()))
email_error = tt('g.not_valid_email');
this.setState({ email, email_error });
}
render() {
const { email, email_error, submitted } = this.state;
if (submitted) {
return (
<div className="callout success">
{tt('g.thank_you_for_being_an_early_visitor_to_APP_NAME', {
APP_NAME,
})}
</div>
);
}
return (
<form onSubmit={this.onSubmit}>
<div>
<label>
{tt('g.email')}
<input
ref="email"
type="text"
name="name"
autoComplete="off"
value={email}
onChange={this.onEmailChange}
/>
</label>
<p className="error">{email_error}</p>
</div>
<br />
<input
type="submit"
className="button secondary"
value={tt('g.submit')}
/>
</form>
);
}
}
......@@ -65,8 +65,6 @@ class Header extends React.Component {
page_title = tt('header_jsx.change_account_password');
} else if (route.page == 'CreateAccount') {
page_title = tt('header_jsx.create_account');
} else if (route.page == 'PickAccount') {
page_title = `Pick Your New Steemit Account`;
} else if (route.page == 'Approval') {
page_title = `Account Confirmation`;
} else if (
......
import React from 'react';
import { connect } from 'react-redux';
import SvgImage from 'app/components/elements/SvgImage';
import AddToWaitingList from 'app/components/modules/AddToWaitingList';
class SignUp extends React.Component {
constructor() {
super();
this.state = { waiting_list: false };
}
render() {
if ($STM_Config.read_only_mode) {
......@@ -36,7 +34,6 @@ class SignUp extends React.Component {
only because of unexpectedly high sign up rate.
Submit your email to get on the waiting list.
</p>
<AddToWaitingList />
</div>
</div>
);
......@@ -90,28 +87,6 @@ class SignUp extends React.Component {
</span>
</div>
</div>
<div className="row">
<div className="column">
<br />
Don't have a Facebook or Reddit account? <br />
{this.state.waiting_list ? (
<AddToWaitingList />
) : (
<a
href="#"
onClick={() =>
this.setState({ waiting_list: true })
}
>
<strong>
{' '}
Subscribe to get a notification when SMS
confirmation is available.
</strong>
</a>
)}
</div>
</div>
<div className="row">
<div className="column">
<br />
......
/* eslint react/prop-types: 0 */
/*global $STM_csrf, $STM_Config */
import React from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { Link } from 'react-router';
import classNames from 'classnames';
import { api } from '@steemit/steem-js';
import * as userActions from 'app/redux/UserReducer';
import { validate_account_name } from 'app/utils/ChainValidation';
import runTests from 'app/utils/BrowserTests';
import { PARAM_VIEW_MODE } from 'shared/constants';
import { makeParams } from 'app/utils/Links';
class PickAccount extends React.Component {
static propTypes = {
loginUser: PropTypes.func.isRequired,
serverBusy: PropTypes.bool,
};
constructor(props) {
super(props);
this.state = {
name: '',
password: '',
password_valid: '',
name_error: '',
server_error: '',
loading: false,
cryptographyFailure: false,
showRules: false,
subheader_hidden: true,
};
this.onSubmit = this.onSubmit.bind(this);
this.onNameChange = this.onNameChange.bind(this);
this.onPasswordChange = this.onPasswordChange.bind(this);
}
componentDidMount() {
const cryptoTestResult = runTests();
if (cryptoTestResult !== undefined) {
console.error(
'CreateAccount - cryptoTestResult: ',
cryptoTestResult
);
this.setState({ cryptographyFailure: true }); // TODO: do not use setState in componentDidMount
}
}
onSubmit(e) {
e.preventDefault();
this.setState({ server_error: '', loading: true });
const { name } = this.state;
if (!name) return;
const params = { account: name };
if (this.props.viewMode) {
params[PARAM_VIEW_MODE] = this.props.viewMode;
}
window.location = '/enter_email' + makeParams(params);
}
onPasswordChange(password, password_valid) {
this.setState({ password, password_valid });
}
onNameChange(e) {
const name = e.target.value.trim().toLowerCase();
this.validateAccountName(name);
this.setState({ name });
}
validateAccountName(name) {
let name_error = '';
let promise;
if (name.length > 0) {
name_error = validate_account_name(name);
if (!name_error) {
this.setState({ name_error: '' });
promise = api.getAccountsAsync([name]).then(res => {
return res && res.length > 0
? 'Account name is not available'
: '';
});
}
}
if (promise) {
promise
.then(name_error => this.setState({ name_error }))
.catch(() =>
this.setState({
name_error:
"Account name can't be verified right now due to server failure. Please try again later.",
})
);
} else {
this.setState({ name_error });
}
}
render() {
if (!process.env.BROWSER) {
// don't render this page on the server
return (
<div className="row">
<div className="column">
<p className="text-center">LOADING..</p>
</div>
</div>
);
}
const {
name,
name_error,
server_error,
loading,
cryptographyFailure,
} = this.state;
const { loggedIn, logout, offchainUser, serverBusy } = this.props;
const submit_btn_disabled = loading || !name || name_error;
const submit_btn_class = classNames('button action', {
disabled: submit_btn_disabled,
});
const account_status = offchainUser
? offchainUser.get('account_status')
: null;
if (serverBusy || $STM_Config.disable_signups) {
return (
<div className="row">
<div className="column">
<div className="callout alert">
<p>
The creation of new accounts is temporarily
disabled.
</p>
</div>
</div>
</div>
);
}
if (cryptographyFailure) {
return (
<div className="row">
<div className="column">
<div className="callout alert">
<h4>Browser Out of Date</h4>
<p>
We will be unable to create your Steem account
with this browser.
</p>
<p>
The latest versions of{' '}
<a href="https://www.google.com/chrome/">
Chrome
</a>{' '}
and{' '}
<a href="https://www.mozilla.org/en-US/firefox/new/">
Firefox
</a>
are well-tested and known to work well with
steemit.com.
</p>
</div>
</div>
</div>
);
}
if (loggedIn) {
return (
<div className="row">
<div className="column">
<div className="callout alert">
<p>
You need to{' '}
<a href="#" onClick={logout}>
Logout
</a>{' '}
before you can create an additional account.
</p>
<p>
Please note that Steemit can only register one
account per verified user.
</p>
</div>
</div>
</div>
);
}
if (account_status === 'waiting') {
return (
<div className="row">
<div className="column">
<br />
<div className="callout alert">
<p>
Your sign up request is being processed and you
will receive an email from us when it is ready.
</p>
<p>
Signup requests can take up to 7 days to be
processed, but usually complete in a day or two.
</p>
</div>
</div>
</div>
);
}
if (account_status === 'approved') {
return (
<div className="row">
<div className="column">
<br />
<div className="callout success">
<p>
Congratulations! Your sign up request has been
approved.
</p>
<p>
<Link to="/create_account">
Let's get your account created!
</Link>
</p>
</div>
</div>
</div>
);
}
// const existingUserAccount = offchainUser.get('account');
// if (existingUserAccount) {
// return <div className="row">
// <div className="column">
// <div className="callout alert">
// <p>Our records indicate that you already have steem account: <strong>{existingUserAccount}</strong></p>
// <p>In order to prevent abuse Steemit can only register one account per verified user.</p>
// <p>You can either <a href="/login.html">login</a> to your existing account
// or <a href="mailto:support@steemit.com">send us email</a> if you need a new account.</p>
// </div>
// </div>
// </div>;
// }
let next_step = null;
if (server_error) {
if (server_error === 'Email address is not confirmed') {
next_step = (
<div className="callout alert">
<a href="/enter_email">
Please verify your email address
</a>
</div>
);
} else if (server_error === 'Phone number is not confirmed') {
next_step = (
<div className="callout alert">
<a href="/enter_mobile">
Please verify your phone number
</a>
</div>
);
} else {
next_step = (
<div className="callout alert">
<h5>
Couldn't create account. The server returned the
following error:
</h5>
<p>{server_error}</p>
</div>
);
}
}
return (
<div>
<div className="CreateAccount row">
<div
className="column"
style={{ maxWidth: '36rem', margin: '0 auto' }}
>
<br />
<div className="progress">
<div style={{ width: '10%' }} />
</div>
<br />
<h4 className="CreateAccount__title">
Welcome to Steemit
</h4>
<div>
<p>
Your account name is how you will be known on
steemit.com.<br />
{/*Your account name <strong>can never be changed</strong>, so please choose carefully.*/}
</p>
</div>
<form
onSubmit={this.onSubmit}
autoComplete="off"
noValidate
method="post"
>
<div className={name_error ? 'error' : ''}>
<label>ACCOUNT NAME</label>
<input
type="text"
name="name"
autoComplete="off"
onChange={this.onNameChange}
value={name}
placeholder={'Name...'}
/>
<p>{name_error}</p>
</div>
<input
disabled={submit_btn_disabled}
type="submit"
className={submit_btn_class}
value="Continue"
/>
</form>
<br />
<p className="secondary whistle-hidden">
Got an account? <Link to="/login.html">Login</Link>
</p>
</div>
</div>
</div>
);
}
}
module.exports = {
path: 'pick_account',
component: connect(
state => {
return {
viewMode: state.app.get('viewMode'),
loggedIn: !!state.user.get('current'),
offchainUser: state.offchain.get('user'),
serverBusy: state.offchain.get('serverBusy'),
};
},
dispatch => ({
loginUser: (username, password) =>
dispatch(
userActions.usernamePasswordLogin({
username,
password,
saveLogin: true,