Merge branch 'develop' into comment-placeholder

This commit is contained in:
Daniel Ternyak 2019-02-10 13:34:36 -06:00 committed by GitHub
commit c4b7e281a5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 81 additions and 10 deletions

View File

@ -19,6 +19,7 @@ from grant.utils.misc import is_email, make_url, from_zat
from grant.utils.enums import ProposalStatus, ContributionStatus
from grant.utils import pagination
from sqlalchemy import or_
from datetime import datetime
from .models import (
Proposal,
@ -216,7 +217,7 @@ def update_proposal(milestones, proposal_id, **kwargs):
m = Milestone(
title=mdata["title"],
content=mdata["content"],
date_estimated=parse(mdata["dateEstimated"]),
date_estimated=datetime.fromtimestamp(mdata["dateEstimated"]),
payout_percent=str(mdata["payoutPercent"]),
immediate_payout=mdata["immediatePayout"],
proposal_id=g.current_proposal.id

View File

@ -156,10 +156,7 @@ class User(db.Model, UserMixin):
db.session.commit()
if _send_email:
send_email(user.email_address, 'signup', {
'display_name': user.display_name,
'confirm_url': make_url(f'/email/verify?code={ev.code}')
})
user.send_verification_email()
return user
@ -212,6 +209,12 @@ class User(db.Model, UserMixin):
def login(self):
login_user(self)
def send_verification_email(self):
send_email(self.email_address, 'signup', {
'display_name': self.display_name,
'confirm_url': make_url(f'/email/verify?code={self.email_verification.code}')
})
def send_recovery_email(self):
existing = self.email_recovery
if existing:

View File

@ -170,11 +170,18 @@ def update_user_password(current_password, password):
def update_user_email(email, password):
if not g.current_user.check_password(password):
return {"message": "Password is incorrect"}, 403
print('set_email')
g.current_user.set_email(email)
return None, 200
@blueprint.route("/me/resend-verification", methods=["PUT"])
@requires_auth
@endpoint.api()
def resend_email_verification():
g.current_user.send_verification_email()
return None, 200
@blueprint.route("/logout", methods=["POST"])
@requires_auth
@endpoint.api()

View File

@ -31,7 +31,7 @@ milestones = [
{
"title": "All the money straightaway",
"content": "cool stuff with it",
"dateEstimated": "Fri, 30 Nov 2018 01:42:23 GMT",
"dateEstimated": 1549505307,
"payoutPercent": "100",
"immediatePayout": False
}

View File

@ -294,3 +294,7 @@ export function getRFP(rfpId: number | string): Promise<{ data: RFP }> {
return res;
});
}
export function resendEmailVerification(): Promise<{ data: void }> {
return axios.put(`/api/v1/users/me/resend-verification`);
}

View File

@ -1,5 +1,10 @@
.AccountSettings {
&-form {
&-resend {
position: relative;
margin-bottom: 1rem;
}
& > .ant-form-item {
margin-bottom: 0.75rem;
}

View File

@ -1,13 +1,15 @@
import React from 'react';
import { connect } from 'react-redux';
import { Form, Input, Button, Alert } from 'antd';
import { Form, Input, Button, Alert, message } from 'antd';
import { FormComponentProps } from 'antd/lib/form';
import { updateUserEmail } from 'api/api';
import Loader from 'components/Loader';
import { updateUserEmail, resendEmailVerification } from 'api/api';
import { AppState } from 'store/reducers';
import './Account.less';
interface StateProps {
email: string;
emailVerified: boolean;
}
type Props = FormComponentProps & StateProps;
@ -17,6 +19,8 @@ const STATE = {
emailChangePending: false,
emailChangeSuccess: false,
emailChangeError: '',
isResendingVerification: false,
hasResentVerification: false,
};
type State = typeof STATE;
@ -25,12 +29,14 @@ class AccountSettings extends React.Component<Props, State> {
state: State = { ...STATE };
render() {
const { email, form } = this.props;
const { email, emailVerified, form } = this.props;
const {
emailChangeError,
emailChangePending,
emailChangeSuccess,
newEmail,
isResendingVerification,
hasResentVerification,
} = this.state;
return (
@ -40,6 +46,36 @@ class AccountSettings extends React.Component<Props, State> {
onSubmit={this.handleSubmit}
layout="vertical"
>
{!emailVerified &&
!hasResentVerification && (
<Alert
showIcon
className="AccountSettings-form-resend"
type="warning"
message="Your email has not been verified"
description={
<>
You should have a verification in your inbox. If you can't find it,
check your spam folder. Still don't see it?{' '}
<a onClick={this.resendEmailVerification}>Click here to resend</a>.
{isResendingVerification && <Loader overlay />}
</>
}
/>
)}
{!emailVerified &&
hasResentVerification && (
<Alert
showIcon
className="AccountSettings-form-resend"
type="success"
message="Verification has been sent"
description={`
It should be in your inbox shortly. If you dont see it soon,
check your spam folder or contact support for help.
`}
/>
)}
<Form.Item label="Email">
{form.getFieldDecorator('email', {
initialValue: newEmail || email,
@ -139,10 +175,25 @@ class AccountSettings extends React.Component<Props, State> {
}
});
};
private resendEmailVerification = async () => {
if (this.state.isResendingVerification) {
return;
}
this.setState({ isResendingVerification: true });
try {
await resendEmailVerification();
this.setState({ hasResentVerification: true });
} catch (err) {
message.error(err.message || err.toString());
}
this.setState({ isResendingVerification: false });
};
}
const FormWrappedAccountSettings = Form.create()(AccountSettings);
export default connect<StateProps, {}, {}, AppState>(state => ({
email: state.auth.user ? state.auth.user.emailAddress || '' : '',
emailVerified: !!state.auth.user && !!state.auth.user.emailVerified,
}))(FormWrappedAccountSettings);