Commit 1a7177ed authored by 2breakegg's avatar 2breakegg

Merge remote-tracking branch 'origin/master'

parents 8e8fb944 0373d4e2
...@@ -2,15 +2,19 @@ ...@@ -2,15 +2,19 @@
root = true root = true
[*] [*]
charset = utf-8
indent_style = space indent_style = space
indent_size = 2 indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true insert_final_newline = true
trim_trailing_whitespace = true
end_of_line = lf
[*.md] [*.md]
max_line_length = 0
trim_trailing_whitespace = false trim_trailing_whitespace = false
[Makefile] # Indentation override
indent_style = tab #[lib/**.js]
#[{package.json,.travis.yml}]
#[**/**.js]
...@@ -23,11 +23,16 @@ ...@@ -23,11 +23,16 @@
"no-bitwise": [0], "no-bitwise": [0],
"no-cond-assign": [0], "no-cond-assign": [0],
"import/no-unresolved": [0], "import/no-unresolved": [0],
"require-yield": [1] "require-yield": [1],
"react/react-in-jsx-scope": [0],
"no-extra-semi": [0]
}, },
"parserOptions": { "parserOptions": {
"ecmaFeatures": { "ecmaFeatures": {
"experimentalObjectRestSpread": true "experimentalObjectRestSpread": true
} }
},
"env": {
"browser": true
} }
} }
This diff is collapsed.
let publicPath = 'https://cdn01.moecube.com/accounts/' let publicPath = 'https://cdn01.moecube.com/accounts/'
let defineConf = { let defineConf = {
apiRoot: process.env["BUILD"] == 'development' ? 'http://114.215.243.95:8082' : 'https://api.moeube.com/accounts' apiRoot: process.env["API_ROOT"]
} }
export default { export default {
......
language: node_js
node_js: node
env:
global:
secure: NObcZ6fY1VQuoDfxRxKVOZ+p7g3LTDkonG4Ow4HIbx2g8wJ24mMqs9gN0J3Asbdbz68isDMpkKy7IW1mK9+N9fM0pBauqD1YMbglnEv+HhYjhiEsQdRdDM2nzDIjS4PCwavI1Da5TLhaUjSAM4lrHx7bVOK4YsvF3s8JEApS54QgSlbeJgvSbPcCiapl0VwwaL36cGndChc3tawq4xseuk4bP2NrTEd7ifYZMt+iojId+UuhRQk4w0HUlBhEDKiT/fLxeQDwMRv2WIdIPW7D7+Wo01iX+T0Ti629QhQBe/S76affkG6G085HIPin3VvXDQaiYbK4ALbc79O+9jqSxEFd9nwG8xbp2jezzvclUSXPhIyZe7VSRS6z1MdevlyQa56AUEP7My7IMqj8j7NPoUgrnVlKtR8WPHQacfAVkrcOIX+Tzwl2IMOCqonamDtJjUNX5xpYB+IEj+INvQmRqT2NicExGWj9LZp3L3kscwq1u+0hPzgoQ9yovE+OvLFNE/R5AE90GIaSlwXw4MqOeB+8l+ou2JzNZFJhHBvAsOFwQTloFz/pu7ichJ+P0KsMPteLFA4Btuo6bBu31K7R310CmlIdYJIeeybMuM6e6bG8IkbVcMq5skg9LNa64KuDG46oopwGLiWkdRwDzG3VmXGwVm+OF2EWZi/B0wIcTwY=
NODE_ENV: development
script: npm run build
before_deploy:
- curl --location --retry 5 --output ossutil 'https://github.com/mycard/ossutil/releases/download/1.0.0.Beta2/ossutil'
- chmod +x ossutil
- ./ossutil config --endpoint oss-cn-hangzhou.aliyuncs.com --access-key-id $ALIYUN_ID
--access-key-secret $ALIYUN_SECRET
deploy:
provider: script
script: ./ossutil cp -rf dist oss://mycard/accounts
skip_cleanup: true
on:
branch: master
...@@ -159,7 +159,6 @@ ...@@ -159,7 +159,6 @@
"i_not_found":"用户不存在", "i_not_found":"用户不存在",
"i_key_time_out":"此链接已过期", "i_key_time_out":"此链接已过期",
"i_key_invalid":"此链接已失效", "i_key_invalid":"此链接已失效",
"没毛用":"防逗号报错,上线删" "没毛用":"防逗号报错,上线删"
} }
......
{ {
"private": true, "private": true,
"scripts": { "scripts": {
"start": "cross-env BUILD=development roadhog server", "start": "cross-env API_ROOT=http://192.168.1.9:3000 roadhog server",
"build:dev": "cross-env BUILD=development roadhog build", "build:dev": "cross-env API_ROOT=http://114.215.243.95:8082 roadhog build",
"build": "roadhog build", "build": "cross-env API_ROOT=https://api.moeube.com/accounts roadhog build",
"lint": "eslint --ext .js src test", "lint": "eslint --ext .js src test",
"precommit": "npm run lint" "precommit": "npm run lint"
}, },
......
...@@ -3,7 +3,8 @@ ...@@ -3,7 +3,8 @@
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="index.css" /> <link rel="stylesheet" href="index.css"/>
<link rel="icon" href="https://moecube.com/favicon.ico">
</head> </head>
<body> <body>
......
...@@ -18,7 +18,9 @@ class EmailForm extends React.Component { ...@@ -18,7 +18,9 @@ class EmailForm extends React.Component {
onSubmit = (e) => { onSubmit = (e) => {
const { form, dispatch, user: { id } } = this.props; const { form, dispatch, user: { id } } = this.props;
e && e.preventDefault(); if (e) {
e.preventDefault();
}
form.validateFieldsAndScroll((err, values) => { form.validateFieldsAndScroll((err, values) => {
if (!err) { if (!err) {
console.log('Received values of form: ', values); console.log('Received values of form: ', values);
......
...@@ -18,6 +18,24 @@ class EmailForm extends React.Component { ...@@ -18,6 +18,24 @@ class EmailForm extends React.Component {
static contextTypes = { static contextTypes = {
intl: PropTypes.object.isRequired, intl: PropTypes.object.isRequired,
}; };
onSubmit = (e) => {
const { form, dispatch, user: { id } } = this.props;
if (e) {
e.preventDefault();
}
form.validateFieldsAndScroll((err, values) => {
if (!err) {
console.log('Received values of form: ', values);
const { new_password, password } = values;
dispatch({ type: 'user/updateAccount', payload: { new_password, password, user_id: id } });
}
});
};
checkPassword = (rule, value, callback) => { checkPassword = (rule, value, callback) => {
const form = this.props.form; const form = this.props.form;
const { intl: { messages } } = this.context; const { intl: { messages } } = this.context;
...@@ -36,20 +54,6 @@ class EmailForm extends React.Component { ...@@ -36,20 +54,6 @@ class EmailForm extends React.Component {
callback(); callback();
}; };
onSubmit = (e) => {
const { form, dispatch, user: { id } } = this.props;
e && e.preventDefault();
form.validateFieldsAndScroll((err, values) => {
if (!err) {
console.log('Received values of form: ', values);
const { new_password, password } = values;
dispatch({ type: 'user/updateAccount', payload: { new_password, password, user_id: id } });
}
});
};
render() { render() {
const { form } = this.props; const { form } = this.props;
...@@ -131,7 +135,7 @@ class EmailForm extends React.Component { ...@@ -131,7 +135,7 @@ class EmailForm extends React.Component {
} }
function mapStateToProps(state, props) { function mapStateToProps(state) {
const { const {
user: { user }, user: { user },
} = state; } = state;
......
...@@ -18,7 +18,9 @@ class EmailForm extends React.Component { ...@@ -18,7 +18,9 @@ class EmailForm extends React.Component {
onSubmit = (e) => { onSubmit = (e) => {
const { form, dispatch, user: { id } } = this.props; const { form, dispatch, user: { id } } = this.props;
e && e.preventDefault(); if (e) {
e.preventDefault();
}
form.validateFieldsAndScroll((err, values) => { form.validateFieldsAndScroll((err, values) => {
if (!err) { if (!err) {
console.log('Received values of form: ', values); console.log('Received values of form: ', values);
...@@ -59,7 +61,8 @@ class EmailForm extends React.Component { ...@@ -59,7 +61,8 @@ class EmailForm extends React.Component {
{getFieldDecorator('email', { ...emailProps.decorator })( {getFieldDecorator('email', { ...emailProps.decorator })(
<Input <Input
{...emailProps.input} {...emailProps.input}
onBlur={() => dispatch({ type: 'auth/checkEmail', payload: { ...form.getFieldsValue(), id } })}/>, onBlur={() => dispatch({ type: 'auth/checkEmail', payload: { ...form.getFieldsValue(), id } })}
/>,
)} )}
</FormItem> </FormItem>
......
...@@ -18,7 +18,9 @@ class EmailForm extends React.Component { ...@@ -18,7 +18,9 @@ class EmailForm extends React.Component {
onSubmit = (e) => { onSubmit = (e) => {
const { form, dispatch, user: { id } } = this.props; const { form, dispatch, user: { id } } = this.props;
e && e.preventDefault(); if (e) {
e.preventDefault();
}
form.validateFieldsAndScroll((err, values) => { form.validateFieldsAndScroll((err, values) => {
if (!err) { if (!err) {
console.log('Received values of form: ', values); console.log('Received values of form: ', values);
......
/* global apiRoot */
export default { export default {
apiRoot: apiRoot apiRoot,
}; };
...@@ -11,7 +11,7 @@ import './index.less'; ...@@ -11,7 +11,7 @@ import './index.less';
// 1. Initialize // 1. Initialize
const app = dva({ const app = dva({
onError: (error, dispatch) => { onError: (error) => {
message.destroy(); message.destroy();
message.error(error.message); message.error(error.message);
}, },
......
html, body, :global(#root) { html, body, :global(#root) {
height: 100%; height: 100%;
min-height: 100%;
} }
:global { :global {
...@@ -21,4 +21,4 @@ html, body, :global(#root) { ...@@ -21,4 +21,4 @@ html, body, :global(#root) {
opacity: 0.01; opacity: 0.01;
transition: opacity 300ms ease-in; transition: opacity 300ms ease-in;
} }
} }
\ No newline at end of file
...@@ -22,8 +22,9 @@ export default { ...@@ -22,8 +22,9 @@ export default {
}, },
reducers: { reducers: {
signOut(state) { signOut(state) {
console.log('sign out');
localStorage.removeItem('token'); localStorage.removeItem('token');
location='/'; location.href = '/';
return state; return state;
}, },
change(state, action) { change(state, action) {
......
...@@ -144,7 +144,7 @@ export default { ...@@ -144,7 +144,7 @@ export default {
if (data.active) { if (data.active) {
yield put(routerRedux.replace('/profiles')); yield put(routerRedux.replace('/profiles'));
} else { } else {
yield put(routerRedux.replace('/verify')); yield put(routerRedux.replace('/signin'));
} }
} }
} catch (error) { } catch (error) {
...@@ -204,11 +204,19 @@ export default { ...@@ -204,11 +204,19 @@ export default {
const token = localStorage.getItem('token'); const token = localStorage.getItem('token');
if (token) { if (token) {
dispatch({ type: 'getAuthUser', payload: { token } }); dispatch({ type: 'getAuthUser', payload: { token } });
} else if (location.pathname === '/profiles') {
dispatch(routerRedux.replace('/signin'));
} }
history.listen(({ pathname }) => {
history.listen(({ pathname, query }) => {
if (pathname === '/') { if (pathname === '/') {
dispatch({ type: 'preLogin', payload: { token } }); dispatch({ type: 'preLogin', payload: { token } });
} }
if (pathname === '/reset' || pathname === '/activate') {
if (!query.key) {
message.error('缺少参数');
}
}
}); });
}, },
}, },
......
import { Redirect, Route, Router } from 'dva/router'; import { Route, Router } from 'dva/router';
import React from 'react'; import React from 'react';
import Active from './routes/Activate.js'; import Active from './routes/Activate.js';
......
...@@ -14,7 +14,7 @@ class Active extends React.Component { ...@@ -14,7 +14,7 @@ class Active extends React.Component {
render() { render() {
const { loading } = this.props; const { loading } = this.props;
return ( return (
<div style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', flex: 1 }}> <div style={{ display: 'flex', flex: 1, justifyContent: 'center', alignItems: 'center', height: '100%' }}>
<Button type="primary" icon="poweroff" loading={loading} onClick={this.handleClick}> <Button type="primary" icon="poweroff" loading={loading} onClick={this.handleClick}>
<Format id={'verify-email'}/> <Format id={'verify-email'}/>
</Button> </Button>
......
...@@ -14,9 +14,11 @@ class Login extends React.Component { ...@@ -14,9 +14,11 @@ class Login extends React.Component {
}; };
onSubmitLogin = (e) => { onSubmitLogin = (e) => {
const { form, dispatch, params: { id } } = this.props; const { form, dispatch } = this.props;
e && e.preventDefault(); if (e) {
e.preventDefault();
}
form.validateFieldsAndScroll((err, values) => { form.validateFieldsAndScroll((err, values) => {
if (!err) { if (!err) {
console.log('Received values of form: ', values); console.log('Received values of form: ', values);
...@@ -33,7 +35,7 @@ class Login extends React.Component { ...@@ -33,7 +35,7 @@ class Login extends React.Component {
const { loading } = this.props; const { loading } = this.props;
const { intl: { messages } } = this.context; const { intl: { messages } } = this.context;
return ( return (
<div style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', height: '100%'}}> <div style={{ display: 'flex', flex: 1, justifyContent: 'center', alignItems: 'center', height: '100%' }}>
<Spin spinning={loading} delay={100}> <Spin spinning={loading} delay={100}>
<Form onSubmit={this.onSubmitLogin} className="login-form"> <Form onSubmit={this.onSubmitLogin} className="login-form">
...@@ -46,7 +48,10 @@ class Login extends React.Component { ...@@ -46,7 +48,10 @@ class Login extends React.Component {
{getFieldDecorator('email', { {getFieldDecorator('email', {
rules: [{ required: true, message: 'Please input your username or email!' }], rules: [{ required: true, message: 'Please input your username or email!' }],
})( })(
<Input prefix={<Icon type="user" style={{ fontSize: 13 }}/>} placeholder={messages['email-address-or-username']}/>, <Input
prefix={<Icon type="user" style={{ fontSize: 13 }}/>}
placeholder={messages['email-address-or-username']}
/>,
)} )}
</FormItem> </FormItem>
......
...@@ -139,12 +139,12 @@ function Index({ children, messages, dispatch }) { ...@@ -139,12 +139,12 @@ function Index({ children, messages, dispatch }) {
</Menu> </Menu>
); );
return ( return (
<div style={{ height: '100%'}}> <div style={{ display: 'flex', flexDirection: 'column', flex: 1, minHeight: '100%' }}>
<DocumentTitle title={messages.title || 'Moe Cube'} /> <DocumentTitle title={messages.title || 'Moe Cube'}/>
<Header style={{ display: 'flex', alignItems: 'center' }}> <Header style={{ display: 'flex', alignItems: 'center' }}>
<Link to="/" style={{ marginTop: '20px' }}> <Link to="/" style={{ marginTop: '20px' }}>
<img src={logo} style={{ width: '140px', height: '44px' }}/> <img alt="logo" src={logo} style={{ width: '140px', height: '44px' }}/>
</Link> </Link>
<Menu <Menu
...@@ -167,7 +167,11 @@ function Index({ children, messages, dispatch }) { ...@@ -167,7 +167,11 @@ function Index({ children, messages, dispatch }) {
style={{ lineHeight: '64px', position: 'absolute', right: '50px' }} style={{ lineHeight: '64px', position: 'absolute', right: '50px' }}
> >
{localStorage.getItem('token') ? (<Menu.Item key="1"> {localStorage.getItem('token') ? (<Menu.Item key="1">
<div onClick={() => { dispatch({ type : 'auth/signOut' }) }}> <div
onClick={() => {
dispatch({ type: 'auth/signOut' });
}}
>
<Format id="sign-out"/> <Format id="sign-out"/>
</div> </div>
</Menu.Item>) : ('') </Menu.Item>) : ('')
...@@ -196,7 +200,7 @@ function Index({ children, messages, dispatch }) { ...@@ -196,7 +200,7 @@ function Index({ children, messages, dispatch }) {
/> />
{children} {children}
<Footer style={{ position: 'absolute', width: '100%'}}> <Footer style={{ width: '100%' }}>
<div>© MoeCube 2017 all right reserved.</div> <div>© MoeCube 2017 all right reserved.</div>
</Footer> </Footer>
</div> </div>
......
.particles { .particles {
position: fixed; position: fixed;
top: 0; top: 0;
left: 0; left: 0;
z-index: 1; z-index: 1;
width: 100%; width: 100%;
height: 100%; height: 100%;
} }
\ No newline at end of file
...@@ -35,7 +35,7 @@ class Login extends React.Component { ...@@ -35,7 +35,7 @@ class Login extends React.Component {
const { intl: { messages } } = this.context; const { intl: { messages } } = this.context;
return ( return (
<div style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', height: '100%' }}> <div style={{ display: 'flex', flex: 1, justifyContent: 'center', alignItems: 'center', height: '100%' }}>
<Spin spinning={loading} delay={100}> <Spin spinning={loading} delay={100}>
<Form onSubmit={this.onSubmitLogin} className="login-form"> <Form onSubmit={this.onSubmitLogin} className="login-form">
...@@ -43,14 +43,20 @@ class Login extends React.Component { ...@@ -43,14 +43,20 @@ class Login extends React.Component {
{getFieldDecorator('account', { {getFieldDecorator('account', {
rules: [{ required: true, message: messages['Please input your account!'] }], rules: [{ required: true, message: messages['Please input your account!'] }],
})( })(
<Input prefix={<Icon type="user" style={{ fontSize: 13 }}/>} placeholder={messages['email-address-or-username']}/>, <Input
prefix={<Icon type="user" style={{ fontSize: 13 }}/>}
placeholder={messages['email-address-or-username']}
/>,
)} )}
</FormItem> </FormItem>
<FormItem> <FormItem>
{getFieldDecorator('password', { {getFieldDecorator('password', {
rules: [{ required: true, message: messages['Please-input-your-Password!'] }], rules: [{ required: true, message: messages['Please-input-your-Password!'] }],
})( })(
<Input prefix={<Icon type="lock" style={{ fontSize: 13 }}/>} type="password" placeholder={messages.password}/>, <Input
prefix={<Icon type="lock" style={{ fontSize: 13 }}/>} type="password"
placeholder={messages.password}
/>,
)} )}
</FormItem> </FormItem>
<FormItem> <FormItem>
......
...@@ -19,11 +19,11 @@ const formItemLayout = { ...@@ -19,11 +19,11 @@ const formItemLayout = {
wrapperCol: { span: 15 }, wrapperCol: { span: 15 },
}; };
function getBase64(img, callback) { // function getBase64(img, callback) {
const reader = new FileReader(); // const reader = new FileReader();
reader.addEventListener('load', () => callback(reader.result)); // reader.addEventListener('load', () => callback(reader.result));
reader.readAsDataURL(img); // reader.readAsDataURL(img);
} // }
class Profiles extends React.Component { class Profiles extends React.Component {
...@@ -31,15 +31,20 @@ class Profiles extends React.Component { ...@@ -31,15 +31,20 @@ class Profiles extends React.Component {
intl: PropTypes.object.isRequired, intl: PropTypes.object.isRequired,
}; };
handleUpload = () => { onUpdateSubmit = (e) => {
if (typeof this.cropper.getCroppedCanvas() === 'undefined') { const { form, dispatch, user: { id } } = this.props;
return;
if (e) {
e.preventDefault();
} }
const { user: { id } } = this.props; form.validateFieldsAndScroll((err, values) => {
if (!err) {
console.log('Received values of form: ', values);
this.cropper.getCroppedCanvas().toBlob(blob => { const { username, name, password } = values;
console.log(blob);
this.props.dispatch({ type: 'upload/upload', payload: { image: blob, user_id: id } }); dispatch({ type: 'user/updateProfile', payload: { username, name, password, user_id: id } });
}
}); });
}; };
...@@ -57,18 +62,15 @@ class Profiles extends React.Component { ...@@ -57,18 +62,15 @@ class Profiles extends React.Component {
reader.readAsDataURL(files[0]); reader.readAsDataURL(files[0]);
}; };
onUpdateSubmit = (e) => { handleUpload = () => {
const { form, dispatch, user: { id }, } = this.props; if (typeof this.cropper.getCroppedCanvas() === 'undefined') {
return;
e && e.preventDefault(); }
form.validateFieldsAndScroll((err, values) => { const { user: { id } } = this.props;
if (!err) {
console.log('Received values of form: ', values);
const { username, name, password } = values;
dispatch({ type: 'user/updateProfile', payload: { username, name, password, user_id: id } }); this.cropper.getCroppedCanvas().toBlob((blob) => {
} console.log(blob);
this.props.dispatch({ type: 'upload/upload', payload: { image: blob, user_id: id } });
}); });
}; };
...@@ -91,7 +93,7 @@ class Profiles extends React.Component { ...@@ -91,7 +93,7 @@ class Profiles extends React.Component {
}, },
}; };
/* eslint-disable jsx-a11y/label-has-for */
return ( return (
<Spin spinning={loading} delay={100}> <Spin spinning={loading} delay={100}>
<Tabs defaultActiveKey="1" className="app-detail-nav"> <Tabs defaultActiveKey="1" className="app-detail-nav">
...@@ -99,37 +101,34 @@ class Profiles extends React.Component { ...@@ -99,37 +101,34 @@ class Profiles extends React.Component {
<Form onSubmit={this.onUpdateSubmit}> <Form onSubmit={this.onUpdateSubmit}>
<FormItem style={{ display: 'flex', justifyContent: 'center' }}> <FormItem style={{ display: 'flex', justifyContent: 'center' }}>
{ <div style={{ display: isUpload ? 'flex' : 'none', flexDirection: 'column' }}>
isUpload ? <Cropper
<div> ref={(cropper) => {
<Cropper this.cropper = cropper;
ref={cropper => { }}
this.cropper = cropper; src={imageUrl || defaultAvatar}
}} style={{ height: '20vw', width: '20vw' }}
src={ imageUrl || defaultAvatar} aspectRatio={1 / 1}
style={{ height: '20vw', width: '20vw' }} guides
aspectRatio={1 / 1} />
guides={true} <Button type="primary" onClick={this.handleUpload}>
/> <Icon type="upload"/> upload
<Button> </Button>
<label > </div>
<Icon type="plus"/> add file
<input type="file" onChange={this.onGetFile} ref={file => {
this.file = file;
}} style={{ display: 'none' }}/>
</label>
</Button>
<Button type="primary" onClick={this.handleUpload}>
<Icon type="upload"/> upload
</Button>
</div>
:
<img src={avatar || imageUrl || defaultAvatar}
style={{ height: '256px', width: '256px' }}
onClick={() => dispatch({ type: 'upload/start' })}
/>
}
<div style={{ display: !isUpload ? 'flex' : 'none', flexDirection: 'column' }}>
<img alt="avatar" src={avatar || imageUrl || defaultAvatar}/>
<Button onClick={() => { dispatch({ type: 'upload/start' }); }}>
<label>
<Icon type="plus"/> Change Avatar
<input
type="file" onChange={this.onGetFile} ref={(file) => {
this.file = file;
}} style={{ display: 'none' }}
/>
</label>
</Button>
</div>
</FormItem> </FormItem>
<FormItem {...nameProps.fromItem}> <FormItem {...nameProps.fromItem}>
......
import { Button, Form, Icon, Input, Select, Spin, Steps } from 'antd'; import { Button, Form, Icon, Input, Spin, Steps } from 'antd';
import { connect } from 'dva'; import { connect } from 'dva';
import { Link } from 'dva/router'; import { Link } from 'dva/router';
import React, { PropTypes } from 'react'; import React, { PropTypes } from 'react';
import { FormattedMessage as Format } from 'react-intl'; import { FormattedMessage as Format } from 'react-intl';
const FormItem = Form.Item; const FormItem = Form.Item;
const Option = Select.Option;
const Step = Steps.Step; const Step = Steps.Step;
...@@ -16,14 +15,16 @@ class Register extends React.Component { ...@@ -16,14 +15,16 @@ class Register extends React.Component {
}; };
onSubmitLogin = (e) => { onSubmitLogin = (e) => {
const { form, dispatch, params: { id } } = this.props; const { form, dispatch } = this.props;
e && e.preventDefault(); if (e) {
e.preventDefault();
}
form.validateFieldsAndScroll((err, values) => { form.validateFieldsAndScroll((err, values) => {
if (!err) { if (!err) {
console.log('Received values of form: ', values); console.log('Received values of form: ', values);
const { email, username, password, } = values; const { email, username, password } = values;
dispatch({ type: 'auth/register', payload: { email, username, password } }); dispatch({ type: 'auth/register', payload: { email, username, password } });
} }
...@@ -49,35 +50,38 @@ class Register extends React.Component { ...@@ -49,35 +50,38 @@ class Register extends React.Component {
}; };
render() { render() {
const { dispatch, register, form, checkEmail, checkUsername, isEmailExists, isUserNameExists, isRegisterSubmit, loading } = this.props; const {
const { getFieldDecorator, } = form; dispatch, form, checkEmail, checkUsername,
const { email, username, password } = register; isEmailExists, isUserNameExists, loading,
} = this.props;
const { getFieldDecorator } = form;
const { intl: { messages } } = this.context; const { intl: { messages } } = this.context;
const emailProps = { const emailProps = {
hasFeedback: true, hasFeedback: true,
validateStatus: checkEmail, validateStatus: checkEmail,
help: isEmailExists ? messages['i_email_exists'] : '', extra: isEmailExists ? messages.i_email_exists : '',
}; };
const emailInputProps = { const emailInputProps = {
onBlur: () => dispatch({ type: 'auth/checkEmail', payload: { ...form.getFieldsValue() } }), onBlur: () => !form.getFieldError('email') && dispatch({ type: 'auth/checkEmail', payload: { ...form.getFieldsValue() } }),
placeholder: messages.email, placeholder: messages.email,
}; };
const usernameProps = { const usernameProps = {
hasFeedback: true, hasFeedback: true,
validateStatus: checkUsername, validateStatus: checkUsername,
help: isUserNameExists ? 'username exists' : '', extra: isUserNameExists ? 'username exists' : '',
}; };
const usernameInputProps = { const usernameInputProps = {
onBlur: () => dispatch({ type: 'auth/checkUsername', payload: { ...form.getFieldsValue() } }), onBlur: () => !form.getFieldError('username') && dispatch({ type: 'auth/checkUsername', payload: { ...form.getFieldsValue() } }),
placeholder: messages.username, placeholder: messages.username,
}; };
return ( return (
<div style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', height: '100%'}}> <div style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', height: '100%' }}>
<Spin spinning={loading} delay={100}> <Spin spinning={loading} delay={100}>
<Steps size="large" current={0}> <Steps size="large" current={0}>
...@@ -86,7 +90,7 @@ class Register extends React.Component { ...@@ -86,7 +90,7 @@ class Register extends React.Component {
</Steps> </Steps>
<Form onSubmit={this.onSubmitLogin} className="login-form" style={{ marginTop: '24px' }}> <Form onSubmit={this.onSubmitLogin} className="login-form" style={{ marginTop: '24px' }}>
<FormItem {...emailProps} > <FormItem {...emailProps} >
{getFieldDecorator('email', { {getFieldDecorator('email', {
rules: [{ rules: [{
required: true, required: true,
...@@ -123,7 +127,8 @@ class Register extends React.Component { ...@@ -123,7 +127,8 @@ class Register extends React.Component {
<Input <Input
prefix={<Icon type="lock" style={{ fontSize: 13 }}/>} prefix={<Icon type="lock" style={{ fontSize: 13 }}/>}
type="password" type="password"
placeholder={messages.password}/>, placeholder={messages.password}
/>,
)} )}
</FormItem> </FormItem>
...@@ -141,7 +146,8 @@ class Register extends React.Component { ...@@ -141,7 +146,8 @@ class Register extends React.Component {
prefix={<Icon type="lock" style={{ fontSize: 13 }}/>} prefix={<Icon type="lock" style={{ fontSize: 13 }}/>}
type="password" type="password"
onBlur={this.handleConfirmBlur} onBlur={this.handleConfirmBlur}
placeholder={messages['password-again']}/>, placeholder={messages['password-again']}
/>,
)} )}
</FormItem> </FormItem>
...@@ -163,7 +169,10 @@ class Register extends React.Component { ...@@ -163,7 +169,10 @@ class Register extends React.Component {
function mapStateToProps(state) { function mapStateToProps(state) {
const { const {
auth: { register, checkEmail, checkUsername, isEmailExists, isUserNameExists, isRegisterSubmit }, auth: {
register, checkEmail, checkUsername, isEmailExists,
isUserNameExists, isRegisterSubmit,
},
} = state; } = state;
const loading = state.loading.global || false; const loading = state.loading.global || false;
......
...@@ -20,7 +20,6 @@ ...@@ -20,7 +20,6 @@
} }
} }
.action { .action {
margin-top: 24px; margin-top: 24px;
} }
\ No newline at end of file
import { Button, Form, Icon, Input, Select, Spin } from 'antd'; import { Button, Form, Icon, Input, Spin } from 'antd';
import { connect } from 'dva'; import { connect } from 'dva';
import React, { PropTypes } from 'react'; import React, { PropTypes } from 'react';
import { FormattedMessage as Format } from 'react-intl'; import { FormattedMessage as Format } from 'react-intl';
const FormItem = Form.Item; const FormItem = Form.Item;
const Option = Select.Option;
class Reset extends React.Component { class Reset extends React.Component {
...@@ -16,7 +14,9 @@ class Reset extends React.Component { ...@@ -16,7 +14,9 @@ class Reset extends React.Component {
onSubmitReset = (e) => { onSubmitReset = (e) => {
const { form, dispatch, location: { query: { key, user_id } } } = this.props; const { form, dispatch, location: { query: { key, user_id } } } = this.props;
e && e.preventDefault(); if (e) {
e.preventDefault();
}
form.validateFieldsAndScroll((err, values) => { form.validateFieldsAndScroll((err, values) => {
if (!err) { if (!err) {
console.log('Received values of form: ', values); console.log('Received values of form: ', values);
...@@ -51,11 +51,11 @@ class Reset extends React.Component { ...@@ -51,11 +51,11 @@ class Reset extends React.Component {
const { intl: { messages } } = this.context; const { intl: { messages } } = this.context;
return ( return (
<div style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', height: '100%' }}> <div style={{ display: 'flex', flex: 1, justifyContent: 'center', alignItems: 'center', height: '100%' }}>
<Spin spinning={isResetSubmit} delay={100}> <Spin spinning={isResetSubmit} delay={100}>
<Form onSubmit={this.onSubmitReset} className="login-form"> <Form onSubmit={this.onSubmitReset} className="login-form">
<FormItem> <FormItem>
<h1><Format id='reset-password2'/></h1> <h1><Format id="reset-password2"/></h1>
</FormItem> </FormItem>
<FormItem> <FormItem>
{getFieldDecorator('password', { {getFieldDecorator('password', {
...@@ -63,8 +63,10 @@ class Reset extends React.Component { ...@@ -63,8 +63,10 @@ class Reset extends React.Component {
}, { }, {
validator: this.checkConfirm, validator: this.checkConfirm,
})( })(
<Input prefix={<Icon type="lock" style={{ fontSize: 13 }}/>} type="password" <Input
placeholder={messages.password}/>, prefix={<Icon type="lock" style={{ fontSize: 13 }}/>} type="password"
placeholder={messages.password}
/>,
)} )}
</FormItem> </FormItem>
...@@ -81,7 +83,7 @@ class Reset extends React.Component { ...@@ -81,7 +83,7 @@ class Reset extends React.Component {
</FormItem> </FormItem>
<Button type="primary" htmlType="submit" className="login-form-button"> <Button type="primary" htmlType="submit" className="login-form-button">
<Format id='reset-password2'/> <Format id="reset-password2"/>
</Button> </Button>
</Form> </Form>
</Spin> </Spin>
...@@ -90,7 +92,7 @@ class Reset extends React.Component { ...@@ -90,7 +92,7 @@ class Reset extends React.Component {
} }
} }
function mapStateToProps(state, props) { function mapStateToProps(state) {
const { const {
auth: { isResetSubmit }, auth: { isResetSubmit },
} = state; } = state;
......
...@@ -4,6 +4,7 @@ import { routerRedux } from 'dva/router'; ...@@ -4,6 +4,7 @@ import { routerRedux } from 'dva/router';
import React, { PropTypes } from 'react'; import React, { PropTypes } from 'react';
import { FormattedMessage as Format } from 'react-intl'; import { FormattedMessage as Format } from 'react-intl';
import SubmitButton from '../components/SubmitButton'; import SubmitButton from '../components/SubmitButton';
const FormItem = Form.Item; const FormItem = Form.Item;
const Step = Steps.Step; const Step = Steps.Step;
...@@ -20,7 +21,9 @@ class Verify extends React.Component { ...@@ -20,7 +21,9 @@ class Verify extends React.Component {
onSubmit = (e) => { onSubmit = (e) => {
const { form, dispatch, input: { password }, user: { id } } = this.props; const { form, dispatch, input: { password }, user: { id } } = this.props;
e && e.preventDefault(); if (e) {
e.preventDefault();
}
form.validateFieldsAndScroll((err, values) => { form.validateFieldsAndScroll((err, values) => {
if (!err) { if (!err) {
console.log('Received values of form: ', values); console.log('Received values of form: ', values);
...@@ -35,12 +38,14 @@ class Verify extends React.Component { ...@@ -35,12 +38,14 @@ class Verify extends React.Component {
onReSend = (e) => { onReSend = (e) => {
const { dispatch, input: { password }, user: { id, email } } = this.props; const { dispatch, input: { password }, user: { id, email } } = this.props;
e && e.preventDefault(); if (e) {
e.preventDefault();
}
dispatch({ type: 'user/updateEmail', payload: { email, password, user_id: id } }); dispatch({ type: 'user/updateEmail', payload: { email, password, user_id: id } });
}; };
render(select) { render() {
const { form, dispatch, user, checkEmail, isEmailExists, loading, input } = this.props; const { form, dispatch, user, checkEmail, isEmailExists, loading, input } = this.props;
const { getFieldDecorator } = form; const { getFieldDecorator } = form;
const { id, email } = user; const { id, email } = user;
...@@ -64,7 +69,8 @@ class Verify extends React.Component { ...@@ -64,7 +69,8 @@ class Verify extends React.Component {
return ( return (
<div <div
style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', flex: 1 }}> style={{ display: 'flex', flex: 1, justifyContent: 'center', alignItems: 'center', height: '100%' }}
>
<Spin spinning={loading} delay={100}> <Spin spinning={loading} delay={100}>
<Steps size="large" current={1}> <Steps size="large" current={1}>
...@@ -72,7 +78,7 @@ class Verify extends React.Component { ...@@ -72,7 +78,7 @@ class Verify extends React.Component {
<Step title={messages['verify-email']} icon={<Icon type="mail"/>}/> <Step title={messages['verify-email']} icon={<Icon type="mail"/>}/>
</Steps> </Steps>
{id && input['password'] ? {id && input.password ?
<Alert <Alert
style={{ marginTop: '24px' }} style={{ marginTop: '24px' }}
message={ message={
...@@ -93,8 +99,9 @@ class Verify extends React.Component { ...@@ -93,8 +99,9 @@ class Verify extends React.Component {
message={ message={
<div> <div>
<span style={{ marginRight: '10px' }}><Format id={'Please-sign-in'}/></span> <span style={{ marginRight: '10px' }}><Format id={'Please-sign-in'}/></span>
<Tag color="blue" onClick={ () => dispatch(routerRedux.replace('/signin'))}><Format <Tag color="blue" onClick={() => dispatch(routerRedux.replace('/signin'))}><Format
id={'sign-in'}/></Tag> id={'sign-in'}
/></Tag>
</div> </div>
} }
type="warning" type="warning"
...@@ -109,7 +116,8 @@ class Verify extends React.Component { ...@@ -109,7 +116,8 @@ class Verify extends React.Component {
{getFieldDecorator('email', { ...emailProps.decorator })( {getFieldDecorator('email', { ...emailProps.decorator })(
<Input <Input
{...emailProps.input} {...emailProps.input}
onBlur={() => dispatch({ type: 'auth/checkEmail', payload: { ...form.getFieldsValue(), id } })}/>, onBlur={() => dispatch({ type: 'auth/checkEmail', payload: { ...form.getFieldsValue(), id } })}
/>,
)} )}
</FormItem> </FormItem>
...@@ -125,7 +133,7 @@ class Verify extends React.Component { ...@@ -125,7 +133,7 @@ class Verify extends React.Component {
} }
} }
function mapStateToProps(state, props) { function mapStateToProps(state) {
const { const {
user: { user }, user: { user },
auth: { input, isEmailExists, checkEmail }, auth: { input, isEmailExists, checkEmail },
......
import request from '../utils/request'; import request from '../utils/request';
export async function login(params) { export async function login(params) {
return request(`/signin`, { return request('/signin', {
method: 'POST', method: 'POST',
body: JSON.stringify(params), body: JSON.stringify(params),
}); });
} }
export async function forgot(params) { export async function forgot(params) {
return request(`/forgot`, { return request('/forgot', {
method: 'POST', method: 'POST',
body: JSON.stringify(params), body: JSON.stringify(params),
}); });
} }
export async function register(params) { export async function register(params) {
return request(`/signup`, { return request('/signup', {
method: 'POST', method: 'POST',
body: JSON.stringify(params), body: JSON.stringify(params),
}); });
} }
export async function reset(params) { export async function reset(params) {
return request(`/reset`, { return request('/reset', {
method: 'PATCH', method: 'PATCH',
body: JSON.stringify(params), body: JSON.stringify(params),
}); });
} }
export async function activate(params) { export async function activate(params) {
return request(`/activate`, { return request('/activate', {
method: 'POST', method: 'POST',
body: JSON.stringify(params), body: JSON.stringify(params),
}); });
...@@ -50,7 +50,7 @@ export async function getUserByUsername(params) { ...@@ -50,7 +50,7 @@ export async function getUserByUsername(params) {
} }
export async function checkUserExists(params) { export async function checkUserExists(params) {
return request(`/user/exists`, { return request('/user/exists', {
method: 'POST', method: 'POST',
body: JSON.stringify(params), body: JSON.stringify(params),
}); });
...@@ -58,7 +58,7 @@ export async function checkUserExists(params) { ...@@ -58,7 +58,7 @@ export async function checkUserExists(params) {
export async function getAuthUser(params) { export async function getAuthUser(params) {
return request(`/authUser`, { return request('/authUser', {
method: 'GET', method: 'GET',
headers: { headers: {
Authorization: `Bearer ${params.token}`, Authorization: `Bearer ${params.token}`,
......
import request from '../utils/request'; import request from '../utils/request';
export async function uploadImage(params) { export async function uploadImage(params) {
console.log(params); console.log(params);
let data = new FormData(); const data = new FormData();
data.append('file', params['image']); data.append('file', params.image);
return request('/upload/image', { return request('/upload/image', {
method: 'POST', method: 'POST',
......
...@@ -10,11 +10,11 @@ async function checkStatus(response) { ...@@ -10,11 +10,11 @@ async function checkStatus(response) {
return response; return response;
} }
let message let message;
try { try {
message = (await response.json())["message"] message = (await response.json()).message;
} catch (error) { } catch (error) {
message = response.statusText message = response.statusText;
} }
const error = new Error(message); const error = new Error(message);
...@@ -29,17 +29,19 @@ async function checkStatus(response) { ...@@ -29,17 +29,19 @@ async function checkStatus(response) {
* @param {object} [options] The options we want to pass to "fetch" * @param {object} [options] The options we want to pass to "fetch"
* @return {object} An object containing either "data" or "err" * @return {object} An object containing either "data" or "err"
*/ */
export default function request(url, options) { export default function request(relativeUrl, options) {
url = `${config.apiRoot}${url}` const url = `${config.apiRoot}${relativeUrl}`;
if(options && !options.headers) { if (options && !options.headers) {
options.headers = { Object.assign(options, {
"content-type": "application/json" headers: {
} 'content-type': 'application/json',
},
});
} }
console.log(options) console.log(options);
return fetch(url, options) return fetch(url, options)
.then(checkStatus) .then(checkStatus)
.then(parseJSON) .then(parseJSON)
.then(data => ({ data })) .then(data => ({ data }));
// .catch(err => ({ err })); // .catch(err => ({ err }));
} };
import crypto from 'crypto' import crypto from 'crypto';
import "url-api-polyfill"; import 'url-api-polyfill';
const url = new URL(window.location) let sso;
const ssoString = new URL(window.location).searchParams.get('sso');
let sso
let ssoString = url.searchParams.get('sso')
if (ssoString) { if (ssoString) {
sso = new URLSearchParams(Buffer.from(ssoString, 'base64').toString()) sso = new URLSearchParams(Buffer.from(ssoString, 'base64').toString());
} }
export const handleSSO = (user) => { export const handleSSO = (user) => {
if(sso) { if (sso) {
let params = new URLSearchParams() const params = new URLSearchParams();
let url = new URL(sso.get("return_sso_url")); const url = new URL(sso.get('return_sso_url'));
for (let [key, value] of Object.entries(user)) { for (const [key, value] of Object.entries(user)) {
params.set(key, value) params.set(key, value);
} }
params.set("return_sso_url", sso.get("return_sso_url")) params.set('return_sso_url', sso.get('return_sso_url'));
params.set("nonce", sso.get("nonce")) params.set('nonce', sso.get('nonce'));
params.set("external_id", user.id) params.set('external_id', user.id);
let payload = Buffer.from(params.toString()).toString('base64') const payload = Buffer.from(params.toString()).toString('base64');
url.searchParams.set("sso", payload) url.searchParams.set('sso', payload);
url.searchParams.set('sig', crypto.createHmac('sha256', 'zsZv6LXHDwwtUAGa').update(payload).digest('hex')) url.searchParams.set('sig', crypto.createHmac('sha256', 'zsZv6LXHDwwtUAGa').update(payload).digest('hex'));
window.location.href = url window.location.href = url;
return true return true;
}else { } else {
return false return false;
} }
} };
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment