From 6b0dcf8d9f791d6a120541087ac75d3788fcaa05 Mon Sep 17 00:00:00 2001 From: Andreas Date: Thu, 7 Sep 2017 18:13:58 +0200 Subject: [PATCH] Add token viewer and http fetcher. add logout and make callback work. --- src/actions/index.js | 3 + src/components/HTTPFetchView.jsx | 94 ++++++++++++++++++++++++ src/components/HostnameInput.jsx | 1 - src/components/MainContent.jsx | 6 +- src/components/ServerConfigInput.jsx | 12 ++- src/components/TokenView.jsx | 48 ++++++++++++ src/containers/HTTPFetchContainer.js | 21 ++++++ src/containers/ServerConfigController.js | 1 + src/containers/TokenViewContainer.js | 19 +++++ src/index.js | 4 +- src/reducers/index.js | 10 ++- src/utils/API.js | 68 ++++++++++++++++- 12 files changed, 277 insertions(+), 10 deletions(-) create mode 100644 src/components/HTTPFetchView.jsx create mode 100644 src/components/TokenView.jsx create mode 100644 src/containers/HTTPFetchContainer.js create mode 100644 src/containers/TokenViewContainer.js diff --git a/src/actions/index.js b/src/actions/index.js index 04fefbd..d6a1749 100644 --- a/src/actions/index.js +++ b/src/actions/index.js @@ -7,6 +7,9 @@ const actionCreators = createActions({ }, serverConfig: { save: config => (config) + }, + tokens: { + save: x => (x) } }); diff --git a/src/components/HTTPFetchView.jsx b/src/components/HTTPFetchView.jsx new file mode 100644 index 0000000..7726ede --- /dev/null +++ b/src/components/HTTPFetchView.jsx @@ -0,0 +1,94 @@ +import React, { PureComponent } from 'react' +import {Navbar, Nav, NavItem, NavDropdown, MenuItem, Glyphicon, Jumbotron, Button} from 'react-bootstrap' +import {Row, Col, Collapse, FormControl, FormGroup, ControlLabel, HelpBlock, PanelGroup, Panel} from 'react-bootstrap' +import FontAwesome from 'react-fontawesome' + +import HostnameController from '../containers/HostnameController' +import ServerConfigController from '../containers/ServerConfigController' +import WhiteBox from './WhiteBox' + + +import moment from 'moment' +import 'moment/locale/nb'; +// import 'moment/locale/en'; + +moment.locale("en"); + + +export function expiresText(expires) { + var expiresM = moment.unix(expires) + return expiresM.fromNow() +} + +class Component extends PureComponent { + + updateAPIendpoint() { + + + } + + fetchUserinfo() { + let endpoint = ""; + + } + + fetchCustom() { + + } + + render() { + console.error("Component", this.props) + + if (!this.props.token) { + return ( +

Not ready. No token found.

+ ) + } + + + + let userinfo = null + if (this.props.serverConfig.userinfo_endpoint) { + userinfo = ( +
+

Fetch userinfo from {this.props.serverConfig.userinfo_endpoint}

+ +
+ ) + } + + return ( + + + {userinfo} + +
+

Fetch userinfo from

+ + + Fill out the hostname of your OAuth server. Will only work if your OAuth server support OpenID Connect Discovery. If not, please enter configuration manually. + + + +
+ +
+ ) + } + + +} + +export default Component diff --git a/src/components/HostnameInput.jsx b/src/components/HostnameInput.jsx index ffd555e..ec25d9c 100644 --- a/src/components/HostnameInput.jsx +++ b/src/components/HostnameInput.jsx @@ -50,7 +50,6 @@ class Component extends PureComponent { } render() { - console.log("This state", this.props) let errorMessage = null if (this.props.serverError) { errorMessage = ( diff --git a/src/components/MainContent.jsx b/src/components/MainContent.jsx index 7c12f00..832e7dd 100644 --- a/src/components/MainContent.jsx +++ b/src/components/MainContent.jsx @@ -4,6 +4,8 @@ import {Row, Col, Collapse, FormControl, FormGroup, ControlLabel, HelpBlock, Pan import HostnameController from '../containers/HostnameController' import ServerConfigController from '../containers/ServerConfigController' +import TokenViewContainer from '../containers/TokenViewContainer' +import HTTPFetchContainer from '../containers/HTTPFetchContainer' import WhiteBox from './WhiteBox' @@ -24,9 +26,9 @@ const MainContent = () => ( - - + + diff --git a/src/components/ServerConfigInput.jsx b/src/components/ServerConfigInput.jsx index bae1087..53cf143 100644 --- a/src/components/ServerConfigInput.jsx +++ b/src/components/ServerConfigInput.jsx @@ -20,10 +20,14 @@ class Component extends PureComponent { authenticateStart() { let config = Object.assign({}, this.props.serverConfig, this.state) - console.error("Authenticate", config) + console.error("Authenticate", config, this.props.serverConfig, this.state) this.props.authenticateStart(config) } + logoutStart() { + this.props.logoutStart() + } + updateFieldHandler(field) { return (e) => { this.setState({ @@ -34,7 +38,7 @@ class Component extends PureComponent { render() { - console.log("X This state", this.props) + console.log("X This props", this.props) console.log("X This state", this.state) let authorizationEndpoint = '' @@ -84,6 +88,10 @@ class Component extends PureComponent { +   + diff --git a/src/components/TokenView.jsx b/src/components/TokenView.jsx new file mode 100644 index 0000000..f3f7fbe --- /dev/null +++ b/src/components/TokenView.jsx @@ -0,0 +1,48 @@ +import React, { PureComponent } from 'react' +import {Navbar, Nav, NavItem, NavDropdown, MenuItem, Glyphicon, Jumbotron, Button} from 'react-bootstrap' +import {Row, Col, Collapse, FormControl, FormGroup, ControlLabel, HelpBlock, PanelGroup, Panel} from 'react-bootstrap' + +import HostnameController from '../containers/HostnameController' +import ServerConfigController from '../containers/ServerConfigController' +import WhiteBox from './WhiteBox' + + +import moment from 'moment' +import 'moment/locale/nb'; +// import 'moment/locale/en'; + +moment.locale("en"); + + +export function expiresText(expires) { + var expiresM = moment.unix(expires) + return expiresM.fromNow() +} + +class Component extends PureComponent { + + render() { + console.error("Component", this.props) + + if (!this.props.token) { + return ( +

No token

+ ) + } + + let extxt = expiresText(this.props.token.expires) + + return ( + + +

This access token expires {extxt}

+
{this.props.tokenstring}
+ +
+ ) + } + + +} + +export default Component diff --git a/src/containers/HTTPFetchContainer.js b/src/containers/HTTPFetchContainer.js new file mode 100644 index 0000000..71f6ecd --- /dev/null +++ b/src/containers/HTTPFetchContainer.js @@ -0,0 +1,21 @@ +import { connect } from 'react-redux' +import Component from '../components/HTTPFetchView' +// import { discoveryStart } from '../actions/' +// import API from '../utils/API' +import API from '../utils/API' + +const mapStateToProps = (state) => ({ + serverConfig: state.serverConfig, + token: state.token +}) + +const mapDispatchToProps = { + httpRequest: API.httpRequest, +} + +const Controller = connect( + mapStateToProps, + mapDispatchToProps +)(Component) + +export default Controller diff --git a/src/containers/ServerConfigController.js b/src/containers/ServerConfigController.js index fa98b97..791b708 100644 --- a/src/containers/ServerConfigController.js +++ b/src/containers/ServerConfigController.js @@ -9,6 +9,7 @@ const mapStateToProps = (state) => ({ const mapDispatchToProps = { authenticateStart: API.authenticate, + logoutStart: API.logout } const Controller = connect( diff --git a/src/containers/TokenViewContainer.js b/src/containers/TokenViewContainer.js new file mode 100644 index 0000000..c88c1f0 --- /dev/null +++ b/src/containers/TokenViewContainer.js @@ -0,0 +1,19 @@ +import { connect } from 'react-redux' +import TokenView from '../components/TokenView' +// import { discoveryStart } from '../actions/' +// import API from '../utils/API' + +const mapStateToProps = (state) => ({ + token: state.token, + tokenstring: JSON.stringify(state.token, undefined, 2) +}) + +const mapDispatchToProps = { +} + +const Controller = connect( + mapStateToProps, + mapDispatchToProps +)(TokenView) + +export default Controller diff --git a/src/index.js b/src/index.js index 5ab343a..a9673ac 100644 --- a/src/index.js +++ b/src/index.js @@ -37,7 +37,7 @@ let store = createStore( ) ) -store.dispatch(API.callback()) + // const state = store.getState() // if (!state.auth.user.token) { @@ -71,3 +71,5 @@ ReactDOM.render(( ), document.getElementById('app') ) + +store.dispatch(API.callback()) diff --git a/src/reducers/index.js b/src/reducers/index.js index 66fbca8..2400b98 100644 --- a/src/reducers/index.js +++ b/src/reducers/index.js @@ -19,10 +19,16 @@ const reducer = handleActions({ } }, serverConfig: { - save: (config) => ({ - serverConfig: config.serverConfig, + save: (state, action) => ({ + serverConfig: action.payload, serverError: null }) + }, + tokens: { + save: (state, action) => ({ + token: action.payload, + ...state + }) } }, { diff --git a/src/utils/API.js b/src/utils/API.js index 7587044..f0309db 100644 --- a/src/utils/API.js +++ b/src/utils/API.js @@ -35,6 +35,35 @@ const API = { } }, + "httpRequest": function() { + return dispatch => { + dispatch(actions.discovery.start(null)) + + let url = '/.well-known/openid-configuration' + let config = {"headers": {}} + // config.headers.Authorization = 'Bearer ' + token.access_token + // config.headers["original-token"] = token.access_token + config.method = "GET" + config.mode = "cors" + console.log("About to fetch", config) + + return fetch(url, config).then((response) => { + if (response.ok) { + return response.json() + } + throw Error(response.statusText) + }) + .then((data) => { + console.log("DATA", data) + dispatch(actions.discovery.completed(data)) + }) + .catch((err) => { + console.error("ERROR Fetching API Discovery", err) + dispatch(actions.discovery.completed(err)) + }) + } + }, + "authenticate": function(config) { return dispatch => { console.error("About to save config", JSON.stringify(config, undefined, 3)) @@ -53,17 +82,52 @@ const API = { appJSO = new jso(jsoconfig) appJSO.getToken((token) => { console.error("Got token, ayay", token) + dispatch(actions.tokens.save(token)) }) }, 1000) } }, + "logout": function() { + return (dispatch, getState) => { + var state = getState() + const jsoconfig = { + providerID: "oauthPlay", + client_id: state.serverConfig.clientId, + redirect_uri: state.serverConfig.redirectURL, + authorization: state.serverConfig.authorization_endpoint + // scopes: { request: ["userinfo"]} + } + console.error("About to logout with ", jsoconfig) + appJSO = new jso(jsoconfig) + appJSO.wipeTokens() + dispatch(actions.tokens.save(null)) + } + }, + "callback": function() { return (dispatch, getState) => { var state = getState() - console.error("Callback", state) - // appJSO.callback() + + if (!state || !state.serverConfig || !state.serverConfig.clientId) { + console.error("CANNOT DO CALLBACK BECAUSE CLIENDIT is missing...", state) + return + } + console.error(". STATE STATE STATE ", state) + const jsoconfig = { + providerID: "oauthPlay", + client_id: state.serverConfig.clientId, + redirect_uri: state.serverConfig.redirectURL, + authorization: state.serverConfig.authorization_endpoint + // scopes: { request: ["userinfo"]} + } + console.error(". Initialising oauth callback", jsoconfig) + appJSO = new jso(jsoconfig) + appJSO.callback(undefined, (token) => { + console.error(" ====) (===== Got token, ayay", token) + dispatch(actions.tokens.save(token)) + }) } } -- GitLab