mirror of
https://github.com/elyby/accounts-frontend.git
synced 2024-12-16 02:08:59 +05:30
oauth/complete
This commit is contained in:
parent
31d94ae770
commit
e44360a20b
@ -2,7 +2,7 @@ import React, { Component, PropTypes } from 'react';
|
|||||||
|
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
|
|
||||||
import { oAuthValidate } from 'components/auth/actions';
|
import { oAuthValidate, oAuthComplete } from 'components/auth/actions';
|
||||||
|
|
||||||
class OAuthInit extends Component {
|
class OAuthInit extends Component {
|
||||||
static displayName = 'OAuthInit';
|
static displayName = 'OAuthInit';
|
||||||
@ -27,7 +27,7 @@ class OAuthInit extends Component {
|
|||||||
responseType: query.response_type,
|
responseType: query.response_type,
|
||||||
scope: query.scope,
|
scope: query.scope,
|
||||||
state: query.state
|
state: query.state
|
||||||
});
|
}).then(this.props.complete);
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
@ -38,5 +38,6 @@ class OAuthInit extends Component {
|
|||||||
export default connect((state) => ({
|
export default connect((state) => ({
|
||||||
query: state.routing.location.query
|
query: state.routing.location.query
|
||||||
}), {
|
}), {
|
||||||
validate: oAuthValidate
|
validate: oAuthValidate,
|
||||||
|
complete: oAuthComplete
|
||||||
})(OAuthInit);
|
})(OAuthInit);
|
||||||
|
@ -345,5 +345,6 @@ export default connect((state) => ({
|
|||||||
register: actions.register,
|
register: actions.register,
|
||||||
activate: actions.activate,
|
activate: actions.activate,
|
||||||
clearErrors: actions.clearErrors,
|
clearErrors: actions.clearErrors,
|
||||||
|
oAuthComplete: actions.oAuthComplete,
|
||||||
setError: actions.setError
|
setError: actions.setError
|
||||||
})(PanelTransition);
|
})(PanelTransition);
|
||||||
|
@ -15,6 +15,7 @@ class Body extends BaseAuthBody {
|
|||||||
static propTypes = {
|
static propTypes = {
|
||||||
...BaseAuthBody.propTypes,
|
...BaseAuthBody.propTypes,
|
||||||
login: PropTypes.func.isRequired,
|
login: PropTypes.func.isRequired,
|
||||||
|
oAuthComplete: PropTypes.func.isRequired,
|
||||||
auth: PropTypes.shape({
|
auth: PropTypes.shape({
|
||||||
error: PropTypes.string,
|
error: PropTypes.string,
|
||||||
login: PropTypes.shape({
|
login: PropTypes.shape({
|
||||||
@ -24,6 +25,8 @@ class Body extends BaseAuthBody {
|
|||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
const {user} = this.props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
{this.renderErrors()}
|
{this.renderErrors()}
|
||||||
@ -31,14 +34,16 @@ class Body extends BaseAuthBody {
|
|||||||
<PanelBodyHeader>
|
<PanelBodyHeader>
|
||||||
<div className={styles.authInfo}>
|
<div className={styles.authInfo}>
|
||||||
<div className={styles.authInfoAvatar}>
|
<div className={styles.authInfoAvatar}>
|
||||||
{/*<img src="//lorempixel.com/g/90/90" />*/}
|
{user.avatar
|
||||||
<span className={icons.user} />
|
? <img src={user.avatar} />
|
||||||
|
: <span className={icons.user} />
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
<div className={styles.authInfoTitle}>
|
<div className={styles.authInfoTitle}>
|
||||||
<Message {...messages.youAuthorizedAs} />
|
<Message {...messages.youAuthorizedAs} />
|
||||||
</div>
|
</div>
|
||||||
<div className={styles.authInfoEmail}>
|
<div className={styles.authInfoEmail}>
|
||||||
{'erickskrauch@yandex.ru'}
|
{user.email}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</PanelBodyHeader>
|
</PanelBodyHeader>
|
||||||
@ -59,7 +64,9 @@ class Body extends BaseAuthBody {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onFormSubmit() {
|
onFormSubmit() {
|
||||||
// TODO
|
this.props.oAuthComplete({
|
||||||
|
accept: true
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,38 +138,78 @@ export function logout() {
|
|||||||
|
|
||||||
// TODO: move to oAuth actions?
|
// 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
|
// 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}) {
|
export function oAuthValidate(oauth) {
|
||||||
return (dispatch) =>
|
return (dispatch) =>
|
||||||
request.get(
|
request.get(
|
||||||
'/api/oauth/validate',
|
'/api/oauth/validate',
|
||||||
{
|
getOAuthRequest(oauth)
|
||||||
client_id: clientId,
|
|
||||||
redirect_uri: redirectUrl,
|
|
||||||
response_type: responseType,
|
|
||||||
scope,
|
|
||||||
state
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
.then((resp) => {
|
.then((resp) => {
|
||||||
dispatch(setClient(resp.client));
|
dispatch(setClient(resp.client));
|
||||||
dispatch(routeActions.push('/oauth/permissions'));
|
dispatch(setOAuthRequest(resp.oAuth));
|
||||||
})
|
})
|
||||||
.catch((resp = {}) => { // TODO
|
.catch((resp = {}) => { // TODO
|
||||||
if (resp.statusCode === 400 && resp.error === 'invalid_request') {
|
handleOauthParamsValidation(resp);
|
||||||
alert(`Invalid request (${resp.parameter} required).`);
|
if (resp.statusCode === 401 && resp.error === 'accept_required') {
|
||||||
}
|
alert('Accept 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 function oAuthComplete(params = {}) {
|
||||||
|
return (dispatch, getState) => {
|
||||||
|
const oauth = getState().auth.oauth;
|
||||||
|
const query = request.buildQuery(getOAuthRequest(oauth));
|
||||||
|
|
||||||
|
return request.post(
|
||||||
|
`/api/oauth/complete?${query}`,
|
||||||
|
typeof params.accept === 'undefined' ? {} : {accept: params.accept}
|
||||||
|
)
|
||||||
|
.then((resp) => {
|
||||||
|
if (resp.redirectUri) {
|
||||||
|
location.href = resp.redirectUri;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((resp = {}) => { // TODO
|
||||||
|
handleOauthParamsValidation(resp);
|
||||||
|
|
||||||
|
if (resp.statusCode === 401 && resp.error === 'accept_required') {
|
||||||
|
dispatch(routeActions.push('/oauth/permissions'));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (resp.statusCode === 401 && resp.error === 'access_denied') {
|
||||||
|
// user declined permissions
|
||||||
|
location.href = resp.redirectUri;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function getOAuthRequest(oauth) {
|
||||||
|
return {
|
||||||
|
client_id: oauth.clientId,
|
||||||
|
redirect_uri: oauth.redirectUrl,
|
||||||
|
response_type: oauth.responseType,
|
||||||
|
scope: oauth.scope,
|
||||||
|
state: oauth.state
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleOauthParamsValidation(resp = {}) {
|
||||||
|
if (resp.statusCode === 400 && resp.error === 'invalid_request') {
|
||||||
|
alert(`Invalid request (${resp.parameter} required).`);
|
||||||
|
}
|
||||||
|
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}'.`);
|
||||||
|
}
|
||||||
|
if (resp.statusCode === 401 && resp.error === 'invalid_client') {
|
||||||
|
alert('Can not find application you are trying to authorize.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export const SET_CLIENT = 'set_client';
|
export const SET_CLIENT = 'set_client';
|
||||||
export function setClient({id, name, description}) {
|
export function setClient({id, name, description}) {
|
||||||
return {
|
return {
|
||||||
@ -177,3 +217,17 @@ export function setClient({id, name, description}) {
|
|||||||
payload: {id, name, description}
|
payload: {id, name, description}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const SET_OAUTH = 'set_oauth';
|
||||||
|
export function setOAuthRequest(oauth) {
|
||||||
|
return {
|
||||||
|
type: SET_OAUTH,
|
||||||
|
payload: {
|
||||||
|
clientId: oauth.client_id,
|
||||||
|
redirectUrl: oauth.redirect_uri,
|
||||||
|
responseType: oauth.response_type,
|
||||||
|
scope: oauth.scope,
|
||||||
|
state: oauth.state
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
import { combineReducers } from 'redux';
|
import { combineReducers } from 'redux';
|
||||||
|
|
||||||
import { ERROR, SET_CLIENT } from './actions';
|
import { ERROR, SET_CLIENT, SET_OAUTH } from './actions';
|
||||||
|
|
||||||
export default combineReducers({
|
export default combineReducers({
|
||||||
error,
|
error,
|
||||||
client
|
client,
|
||||||
|
oauth
|
||||||
});
|
});
|
||||||
|
|
||||||
function error(
|
function error(
|
||||||
@ -39,3 +40,22 @@ function client(
|
|||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function oauth(
|
||||||
|
state = null,
|
||||||
|
{type, payload = {}}
|
||||||
|
) {
|
||||||
|
switch (type) {
|
||||||
|
case SET_OAUTH:
|
||||||
|
return {
|
||||||
|
clientId: payload.clientId,
|
||||||
|
redirectUrl: payload.redirectUrl,
|
||||||
|
responseType: payload.responseType,
|
||||||
|
scope: payload.scope,
|
||||||
|
state: payload.state
|
||||||
|
};
|
||||||
|
|
||||||
|
default:
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -37,6 +37,8 @@ export default function routesFactory(store) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: validate that we have all required data on premissions page
|
||||||
|
|
||||||
if (forcePath && pathname !== forcePath) {
|
if (forcePath && pathname !== forcePath) {
|
||||||
switch (pathname) {
|
switch (pathname) {
|
||||||
case '/':
|
case '/':
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
function serialize(data) {
|
function buildQuery(data) {
|
||||||
return Object.keys(data)
|
return Object.keys(data)
|
||||||
.map(
|
.map(
|
||||||
(keyName) =>
|
(keyName) =>
|
||||||
@ -33,7 +33,7 @@ export default {
|
|||||||
...getDefaultHeaders(),
|
...getDefaultHeaders(),
|
||||||
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
|
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
|
||||||
},
|
},
|
||||||
body: serialize(data)
|
body: buildQuery(data)
|
||||||
})
|
})
|
||||||
.then(toJSON)
|
.then(toJSON)
|
||||||
.then(handleResponse)
|
.then(handleResponse)
|
||||||
@ -43,7 +43,7 @@ export default {
|
|||||||
get(url, data) {
|
get(url, data) {
|
||||||
if (typeof data === 'object') {
|
if (typeof data === 'object') {
|
||||||
const separator = url.indexOf('?') === -1 ? '?' : '&';
|
const separator = url.indexOf('?') === -1 ? '?' : '&';
|
||||||
url += separator + serialize(data);
|
url += separator + buildQuery(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
return fetch(url, {
|
return fetch(url, {
|
||||||
@ -54,6 +54,8 @@ export default {
|
|||||||
;
|
;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
buildQuery,
|
||||||
|
|
||||||
setAuthToken(tkn) {
|
setAuthToken(tkn) {
|
||||||
authToken = tkn;
|
authToken = tkn;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user