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

Merge remote-tracking branch 'origin/master'

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