diff --git a/embark-ui/src/constants.js b/embark-ui/src/constants.js index b2e1799d..432f55eb 100644 --- a/embark-ui/src/constants.js +++ b/embark-ui/src/constants.js @@ -5,5 +5,5 @@ export const LIGHT_THEME = 'light'; export const DEPLOYMENT_PIPELINES = { injectedWeb3: 'injectedWeb3', embark: 'embark' -} -export const DEFAULT_HOST = 'localhost:8000'; +}; +export const DEFAULT_HOST = process.env.NODE_ENV === 'development' ? 'localhost:8000' : window.location.host; diff --git a/embark-ui/src/containers/AppContainer.js b/embark-ui/src/containers/AppContainer.js index 593699c4..56323517 100644 --- a/embark-ui/src/containers/AppContainer.js +++ b/embark-ui/src/containers/AppContainer.js @@ -5,7 +5,8 @@ import {withRouter} from "react-router-dom"; import routes from '../routes'; import Login from '../components/Login'; import Layout from "../components/Layout"; -import { DEFAULT_HOST } from '../constants'; +import {DEFAULT_HOST} from '../constants'; +import {getQueryToken, stripQueryToken} from '../utils/utils'; import { authenticate, fetchCredentials, logout, @@ -18,42 +19,57 @@ import { import {LIGHT_THEME, DARK_THEME} from '../constants'; -import { getCredentials, getAuthenticationError, getProcesses, getTheme } from '../reducers/selectors'; - -const qs = require('qs'); +import { + getCredentials, getAuthenticationError, getProcesses, getTheme +} from '../reducers/selectors'; class AppContainer extends Component { - constructor (props) { - super(props); - - this.queryStringAuthenticate(); - } - - queryStringAuthenticate() { - const token = qs.parse(this.props.location.search, {ignoreQueryPrefix: true}).token; - - if (!token) { - return; - } - const host = process.env.NODE_ENV === 'development' ? DEFAULT_HOST : window.location.host; - if (token === this.props.credentials.token && this.props.credentials.host === host) { - return; - } - this.props.authenticate(host, token); - } - componentDidMount() { this.props.fetchCredentials(); this.props.fetchTheme(); } + doAuthenticate() { + let {host, token} = this.props.credentials; + const queryToken = getQueryToken(this.props.location); + + if (queryToken) { + host = DEFAULT_HOST; + token = queryToken; + } + + this.props.authenticate(host, token); + } + requireAuthentication() { - return this.props.credentials.token && this.props.credentials.host && !this.props.credentials.authenticated; + if (this.props.credentials.authenticating) { + return false; + } + + const queryToken = getQueryToken(this.props.location); + if (queryToken && !(queryToken === this.props.credentials.token && + this.props.credentials.host === DEFAULT_HOST)) { + return true; + } + + if (!this.props.credentials.authenticated && + this.props.credentials.host && + this.props.credentials.token) { + return true; + } + + return false; } componentDidUpdate(){ if (this.requireAuthentication()) { - this.props.authenticate(this.props.credentials.host, this.props.credentials.token); + this.doAuthenticate(); + } + + if (getQueryToken(this.props.location) && + (!this.props.credentials.authenticating || + this.props.credentials.authenticated)) { + this.props.history.replace(stripQueryToken(this.props.location)); } if (this.props.credentials.authenticated && !this.props.initialized) { @@ -64,7 +80,8 @@ class AppContainer extends Component { } shouldRenderLogin() { - return this.props.authenticationError || !this.props.credentials.authenticated; + return this.props.authenticationError || + !(this.props.credentials.authenticated || this.props.credentials.authenticating); } toggleTheme() { @@ -77,12 +94,18 @@ class AppContainer extends Component { renderBody() { if (this.shouldRenderLogin()) { - return ; + return ( + + ); + } else if (this.props.credentials.authenticating) { + return ; } return ( - this.toggleTheme()} + toggleTheme={() => this.toggleTheme()} currentTheme={this.props.theme}> {routes} @@ -90,7 +113,11 @@ class AppContainer extends Component { } render() { - return
{this.renderBody()}
; + return ( +
+ {this.renderBody()} +
+ ); } } diff --git a/embark-ui/src/reducers/index.js b/embark-ui/src/reducers/index.js index a2f1da97..9de87adb 100644 --- a/embark-ui/src/reducers/index.js +++ b/embark-ui/src/reducers/index.js @@ -200,7 +200,13 @@ function compilingContract(state = false, action) { return state; } -const DEFAULT_CREDENTIALS_STATE = {host: DEFAULT_HOST, token: '', authenticated: false}; +const DEFAULT_CREDENTIALS_STATE = { + host: DEFAULT_HOST, + token: '', + authenticated: false, + authenticating: false, + error: null +}; function credentials(state = DEFAULT_CREDENTIALS_STATE, action) { if (action.type === LOGOUT[SUCCESS]) { @@ -208,17 +214,21 @@ function credentials(state = DEFAULT_CREDENTIALS_STATE, action) { } if (action.type === AUTHENTICATE[FAILURE]) { - return {error: action.error, authenticated: false}; + return {error: action.error, ...DEFAULT_CREDENTIALS_STATE}; } if (action.type === AUTHENTICATE[SUCCESS]) { - return {...state, ...{authenticated: true, token: action.token, host: action.host, error: null}}; + return {...state, ...{authenticated: true, authenticating: false, token: action.token, host: action.host, error: null}}; } if (action.type === FETCH_CREDENTIALS[SUCCESS]) { return {...state, ...{token: action.token, host: action.host}}; } + if (action.type === AUTHENTICATE[REQUEST]) { + return {...state, ...{authenticating: true, error: null}}; + } + return state; } diff --git a/embark-ui/src/sagas/index.js b/embark-ui/src/sagas/index.js index 26cb905b..99b64238 100644 --- a/embark-ui/src/sagas/index.js +++ b/embark-ui/src/sagas/index.js @@ -273,6 +273,10 @@ export function *watchAuthenticateSuccess() { yield takeEvery(actions.AUTHENTICATE[actions.SUCCESS], saveCredentials); } +export function *watchAuthenticateFailure() { + yield takeEvery(actions.AUTHENTICATE[actions.FAILURE], logout); +} + export function *watchFetchCredentials() { yield takeEvery(actions.FETCH_CREDENTIALS[actions.REQUEST], fetchCredentials); } @@ -518,6 +522,7 @@ export default function *root() { fork(watchToggleBreakpoint), fork(watchAuthenticate), fork(watchAuthenticateSuccess), + fork(watchAuthenticateFailure), fork(watchLogout), fork(watchExplorerSearch), fork(watchFetchTheme), diff --git a/embark-ui/src/utils/utils.js b/embark-ui/src/utils/utils.js index e70aeb56..978b1e2c 100644 --- a/embark-ui/src/utils/utils.js +++ b/embark-ui/src/utils/utils.js @@ -1,4 +1,5 @@ -const Convert = require('ansi-to-html'); +import Convert from 'ansi-to-html'; +import qs from 'qs'; export function last(array) { return array && array.length ? array[array.length - 1] : undefined; @@ -17,5 +18,18 @@ export function hashCode(str) { export function ansiToHtml(text) { const convert = new Convert(); - return convert.toHtml(text.replace(/\n/g,'
')) + return convert.toHtml(text.replace(/\n/g,'
')); +} + +export function getQueryToken(location) { + return qs.parse(location.search, {ignoreQueryPrefix: true}).token; +} + +export function stripQueryToken(location) { + const _location = Object.assign({}, location); + _location.search = _location.search.replace( + /(\?|&?)(token=[\w-]*)(&?)/, + (_, p1, p2, p3) => (p2 ? (p3 === '&' ? p1 : '') : '') + ); + return _location; }