mirror of
https://github.com/elyby/accounts-frontend.git
synced 2024-09-29 23:07:31 +05:30
Интеграция appInfo с API
This commit is contained in:
parent
aa422cb4f2
commit
404684b8d9
42
src/components/auth/OAuthInit.jsx
Normal file
42
src/components/auth/OAuthInit.jsx
Normal file
@ -0,0 +1,42 @@
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import { oAuthValidate } from 'components/auth/actions';
|
||||
|
||||
class OAuthInit extends Component {
|
||||
static displayName = 'OAuthInit';
|
||||
|
||||
static propTypes = {
|
||||
query: PropTypes.shape({
|
||||
client_id: PropTypes.string.isRequired,
|
||||
redirect_uri: PropTypes.string.isRequired,
|
||||
response_type: PropTypes.string.isRequired,
|
||||
scope: PropTypes.string.isRequired,
|
||||
state: PropTypes.string
|
||||
}),
|
||||
validate: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
componentWillMount() {
|
||||
const {query} = this.props;
|
||||
|
||||
this.props.validate({
|
||||
clientId: query.client_id,
|
||||
redirectUrl: query.redirect_uri,
|
||||
responseType: query.response_type,
|
||||
scope: query.scope,
|
||||
state: query.state
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
return <span />;
|
||||
}
|
||||
}
|
||||
|
||||
export default connect((state) => ({
|
||||
query: state.routing.location.query
|
||||
}), {
|
||||
validate: oAuthValidate
|
||||
})(OAuthInit);
|
@ -107,3 +107,45 @@ export function logout() {
|
||||
dispatch(routeActions.push('/login'));
|
||||
};
|
||||
}
|
||||
|
||||
// TODO: move to oAuth actions?
|
||||
// test request: /oauth?client_id=ely&redirect_uri=http%3A%2F%2Fely.by&response_type=code&scope=minecraft_server_session
|
||||
export function oAuthValidate({clientId, redirectUrl, responseType, scope, state}) {
|
||||
return (dispatch) =>
|
||||
request.get(
|
||||
'/api/oauth/validate',
|
||||
{
|
||||
client_id: clientId,
|
||||
redirect_uri: redirectUrl,
|
||||
response_type: responseType,
|
||||
scope,
|
||||
state
|
||||
}
|
||||
)
|
||||
.then((resp) => {
|
||||
dispatch(setClient(resp.client));
|
||||
dispatch(routeActions.push('/oauth/permissions'));
|
||||
})
|
||||
.catch((resp = {}) => { // TODO
|
||||
if (resp.statusCode === 400 && resp.error === 'invalid_request') {
|
||||
alert(`Invalid request (${resp.parameter} required).`);
|
||||
}
|
||||
if (resp.statusCode === 401 && resp.error === 'invalid_client') {
|
||||
alert('Can not find application you are trying to authorize.');
|
||||
}
|
||||
if (resp.statusCode === 400 && resp.error === 'unsupported_response_type') {
|
||||
alert(`Invalid response type '${resp.parameter}'.`);
|
||||
}
|
||||
if (resp.statusCode === 400 && resp.error === 'invalid_scope') {
|
||||
alert(`Invalid scope '${resp.parameter}'.`);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export const SET_CLIENT = 'set_client';
|
||||
export function setClient({id, name, description}) {
|
||||
return {
|
||||
type: SET_CLIENT,
|
||||
payload: {id, name, description}
|
||||
};
|
||||
}
|
||||
|
@ -1,9 +1,10 @@
|
||||
import { combineReducers } from 'redux';
|
||||
|
||||
import { ERROR } from './actions';
|
||||
import { ERROR, SET_CLIENT } from './actions';
|
||||
|
||||
export default combineReducers({
|
||||
error
|
||||
error,
|
||||
client
|
||||
});
|
||||
|
||||
function error(
|
||||
@ -21,3 +22,20 @@ function error(
|
||||
return state;
|
||||
}
|
||||
}
|
||||
|
||||
function client(
|
||||
state = null,
|
||||
{type, payload = {}}
|
||||
) {
|
||||
switch (type) {
|
||||
case SET_CLIENT:
|
||||
return {
|
||||
id: payload.id,
|
||||
name: payload.name,
|
||||
description: payload.description
|
||||
};
|
||||
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
}
|
||||
|
@ -1,29 +1,34 @@
|
||||
import React, { Component } from 'react';
|
||||
import React, { Component, PropTypes } from 'react';
|
||||
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import AppInfo from 'components/auth/AppInfo';
|
||||
import PanelTransition from 'components/auth/PanelTransition';
|
||||
|
||||
import styles from './auth.scss';
|
||||
|
||||
export default class AuthPage extends Component {
|
||||
class AuthPage extends Component {
|
||||
static displayName = 'AuthPage';
|
||||
static propTypes = {
|
||||
client: PropTypes.shape({
|
||||
id: PropTypes.string.isRequired,
|
||||
name: PropTypes.string.isRequired,
|
||||
description: PropTypes.string.isRequired
|
||||
})
|
||||
};
|
||||
|
||||
state = {
|
||||
isSidebarHidden: false
|
||||
};
|
||||
|
||||
render() {
|
||||
var {isSidebarHidden} = this.state;
|
||||
|
||||
var appInfo = {
|
||||
name: 'TLauncher',
|
||||
description: `Лучший альтернативный лаунчер для Minecraft с большим количеством версий и их модификаций, а также возмоностью входа как с лицензионным аккаунтом, так и без него.`
|
||||
};
|
||||
const {isSidebarHidden} = this.state;
|
||||
const {client} = this.props;
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className={isSidebarHidden ? styles.hiddenSidebar : styles.sidebar}>
|
||||
<AppInfo {...appInfo} onGoToAuth={this.onGoToAuth} />
|
||||
<AppInfo {...client} onGoToAuth={this.onGoToAuth} />
|
||||
</div>
|
||||
<div className={styles.content}>
|
||||
<PanelTransition {...this.props} />
|
||||
@ -38,3 +43,8 @@ export default class AuthPage extends Component {
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
export default connect((state) => ({
|
||||
client: state.auth.client
|
||||
}))(AuthPage);
|
||||
|
@ -5,6 +5,7 @@ import RootPage from 'pages/root/RootPage';
|
||||
import IndexPage from 'pages/index/IndexPage';
|
||||
import AuthPage from 'pages/auth/AuthPage';
|
||||
|
||||
import OAuthInit from 'components/auth/OAuthInit';
|
||||
import Register from 'components/auth/Register';
|
||||
import Login from 'components/auth/Login';
|
||||
import Permissions from 'components/auth/Permissions';
|
||||
@ -47,10 +48,10 @@ export default function routesFactory(store) {
|
||||
<Route path="/register" components={new Register()} />
|
||||
<Route path="/activation" components={new Activation()} />
|
||||
<Route path="/oauth/permissions" components={new Permissions()} onEnter={checkAuth} />
|
||||
<Route path="/oauth/:id" component={Permissions} />
|
||||
<Route path="/password-change" components={new PasswordChange()} />
|
||||
</Route>
|
||||
|
||||
<Route path="oauth" component={OAuthInit} />
|
||||
<Route path="logout" component={Logout} />
|
||||
</Route>
|
||||
);
|
||||
|
@ -2,7 +2,7 @@ function serialize(data) {
|
||||
return Object.keys(data)
|
||||
.map(
|
||||
(keyName) =>
|
||||
[keyName, data[keyName]]
|
||||
[keyName, typeof data[keyName] === 'undefined' ? '' : data[keyName]]
|
||||
.map(encodeURIComponent)
|
||||
.join('=')
|
||||
)
|
||||
@ -10,6 +10,9 @@ function serialize(data) {
|
||||
;
|
||||
}
|
||||
|
||||
const toJSON = (resp) => resp.json();
|
||||
const handleResponse = (resp) => Promise[resp.success ? 'resolve' : 'reject'](resp);
|
||||
|
||||
export default {
|
||||
post(url, data) {
|
||||
return fetch(url, {
|
||||
@ -20,8 +23,23 @@ export default {
|
||||
},
|
||||
body: serialize(data)
|
||||
})
|
||||
.then((resp) => resp.json())
|
||||
.then((resp) => Promise[resp.success ? 'resolve' : 'reject'](resp))
|
||||
.then(toJSON)
|
||||
.then(handleResponse)
|
||||
;
|
||||
},
|
||||
get(url, data) {
|
||||
if (typeof data === 'object') {
|
||||
const separator = url.indexOf('?') === -1 ? '?' : '&';
|
||||
url += separator + serialize(data);
|
||||
}
|
||||
|
||||
return fetch(url, {
|
||||
headers: {
|
||||
Accept: 'application/json'
|
||||
}
|
||||
})
|
||||
.then(toJSON)
|
||||
.then(handleResponse)
|
||||
;
|
||||
}
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user