mirror of
https://github.com/status-im/embark-area-51.git
synced 2025-01-23 05:38:52 +00:00
Merge pull request #49 from status-im/features/token-auth
Add token authorization to backend tab
This commit is contained in:
commit
cf6108e798
@ -11,6 +11,7 @@
|
|||||||
"connected-react-router": "^4.3.0",
|
"connected-react-router": "^4.3.0",
|
||||||
"history": "^4.7.2",
|
"history": "^4.7.2",
|
||||||
"prop-types": "^15.6.2",
|
"prop-types": "^15.6.2",
|
||||||
|
"query-string": "^6.1.0",
|
||||||
"react": "^16.4.2",
|
"react": "^16.4.2",
|
||||||
"react-ace": "^6.1.4",
|
"react-ace": "^6.1.4",
|
||||||
"react-copy-to-clipboard": "^5.0.1",
|
"react-copy-to-clipboard": "^5.0.1",
|
||||||
|
@ -13,6 +13,13 @@ function action(type, payload = {}) {
|
|||||||
return {type, ...payload};
|
return {type, ...payload};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const AUTHORIZE = createRequestTypes('AUTHORIZE');
|
||||||
|
export const authorize = {
|
||||||
|
request: (token, callback) => action(AUTHORIZE[REQUEST], {token, callback}),
|
||||||
|
success: () => action(AUTHORIZE[SUCCESS]),
|
||||||
|
failure: (error) => action(AUTHORIZE[FAILURE], {error})
|
||||||
|
};
|
||||||
|
|
||||||
export const ACCOUNTS = createRequestTypes('ACCOUNTS');
|
export const ACCOUNTS = createRequestTypes('ACCOUNTS');
|
||||||
export const accounts = {
|
export const accounts = {
|
||||||
request: () => action(ACCOUNTS[REQUEST]),
|
request: () => action(ACCOUNTS[REQUEST]),
|
||||||
@ -219,6 +226,20 @@ export const saveCurrentFile = {
|
|||||||
failure: () => action(SAVE_CURRENT_FILE[FAILURE])
|
failure: () => action(SAVE_CURRENT_FILE[FAILURE])
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const GET_TOKEN = createRequestTypes('TOKEN');
|
||||||
|
export const getToken = {
|
||||||
|
request: (callback) => action(GET_TOKEN[REQUEST], {callback}),
|
||||||
|
success: (token) => action(GET_TOKEN[SUCCESS], {token}),
|
||||||
|
failure: () => action(GET_TOKEN[FAILURE])
|
||||||
|
};
|
||||||
|
|
||||||
|
export const POST_TOKEN = createRequestTypes('POST_TOKEN');
|
||||||
|
export const postToken = {
|
||||||
|
request: (token) => action(POST_TOKEN[REQUEST], {token}),
|
||||||
|
success: (token) => action(POST_TOKEN[SUCCESS], {token}),
|
||||||
|
failure: () => action(POST_TOKEN[FAILURE])
|
||||||
|
};
|
||||||
|
|
||||||
export const GAS_ORACLE = createRequestTypes('GAS_ORACLE');
|
export const GAS_ORACLE = createRequestTypes('GAS_ORACLE');
|
||||||
export const gasOracle = {
|
export const gasOracle = {
|
||||||
request: () => action(GAS_ORACLE[REQUEST]),
|
request: () => action(GAS_ORACLE[REQUEST]),
|
||||||
|
24
embark-ui/src/components/AuthError.js
Normal file
24
embark-ui/src/components/AuthError.js
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
import PropTypes from "prop-types";
|
||||||
|
import React from 'react';
|
||||||
|
import {Page, Alert, Form, Button} from "tabler-react";
|
||||||
|
|
||||||
|
const AuthError = ({error}) => {
|
||||||
|
return <Page.Content>
|
||||||
|
<Alert type="danger">
|
||||||
|
{error}
|
||||||
|
</Alert>
|
||||||
|
<Form>
|
||||||
|
<Form.Input name="token" label="Token" placeholder="Enter Token"/>
|
||||||
|
<Button type="submit" color="primary">
|
||||||
|
Authorize
|
||||||
|
</Button>
|
||||||
|
</Form>
|
||||||
|
</Page.Content>;
|
||||||
|
};
|
||||||
|
|
||||||
|
AuthError.propTypes = {
|
||||||
|
error: PropTypes.string.isRequired
|
||||||
|
};
|
||||||
|
|
||||||
|
export default AuthError;
|
||||||
|
|
@ -1,20 +1,48 @@
|
|||||||
import {ConnectedRouter} from "connected-react-router";
|
|
||||||
import PropTypes from "prop-types";
|
import PropTypes from "prop-types";
|
||||||
import {connect} from 'react-redux';
|
import {connect} from 'react-redux';
|
||||||
import React, {Component} from 'react';
|
import React, {Component} from 'react';
|
||||||
|
import {withRouter} from "react-router-dom";
|
||||||
|
|
||||||
import history from '../history';
|
|
||||||
import Layout from '../components/Layout';
|
|
||||||
import routes from '../routes';
|
import routes from '../routes';
|
||||||
|
import AuthError from '../components/AuthError';
|
||||||
|
import queryString from 'query-string';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
initBlockHeader,
|
initBlockHeader,
|
||||||
|
authorize, getToken, postToken,
|
||||||
processes as processesAction,
|
processes as processesAction,
|
||||||
versions as versionsAction,
|
versions as versionsAction,
|
||||||
plugins as pluginsAction
|
plugins as pluginsAction
|
||||||
} from '../actions';
|
} from '../actions';
|
||||||
|
|
||||||
class AppContainer extends Component {
|
class AppContainer extends Component {
|
||||||
|
constructor (props) {
|
||||||
|
super(props);
|
||||||
|
this.state = {
|
||||||
|
authenticateError: null
|
||||||
|
};
|
||||||
|
|
||||||
|
this.checkToken();
|
||||||
|
}
|
||||||
|
|
||||||
|
checkToken() {
|
||||||
|
if (this.props.location.search) {
|
||||||
|
const token = queryString.parse(this.props.location.search).token;
|
||||||
|
this.props.postToken(token);
|
||||||
|
return this.props.authorize(token, this.authCallback.bind(this));
|
||||||
|
}
|
||||||
|
this.props.getToken((err, token) => {
|
||||||
|
this.props.authorize(token, this.authCallback.bind(this));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
authCallback(err) {
|
||||||
|
if (err) {
|
||||||
|
return this.setState({authenticateError: err});
|
||||||
|
}
|
||||||
|
this.setState({authenticateError: null});
|
||||||
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.props.initBlockHeader();
|
this.props.initBlockHeader();
|
||||||
this.props.fetchProcesses();
|
this.props.fetchProcesses();
|
||||||
@ -23,30 +51,33 @@ class AppContainer extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
if (this.state.authenticateError) {
|
||||||
<ConnectedRouter history={history}>
|
return <AuthError error={this.state.authenticateError}/>;
|
||||||
<Layout>
|
}
|
||||||
{routes}
|
return (<React.Fragment>{routes}</React.Fragment>);
|
||||||
</Layout>
|
|
||||||
</ConnectedRouter>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AppContainer.propTypes = {
|
AppContainer.propTypes = {
|
||||||
|
authorize: PropTypes.func,
|
||||||
|
getToken: PropTypes.func,
|
||||||
|
postToken: PropTypes.func,
|
||||||
initBlockHeader: PropTypes.func,
|
initBlockHeader: PropTypes.func,
|
||||||
fetchProcesses: PropTypes.func,
|
fetchProcesses: PropTypes.func,
|
||||||
fetchPlugins: PropTypes.func,
|
fetchPlugins: PropTypes.func,
|
||||||
fetchVersions: PropTypes.func
|
fetchVersions: PropTypes.func,
|
||||||
|
location: PropTypes.object
|
||||||
};
|
};
|
||||||
|
|
||||||
export default connect(
|
export default withRouter(connect(
|
||||||
null,
|
null,
|
||||||
{
|
{
|
||||||
initBlockHeader,
|
initBlockHeader,
|
||||||
|
authorize: authorize.request,
|
||||||
|
getToken: getToken.request,
|
||||||
|
postToken: postToken.request,
|
||||||
fetchProcesses: processesAction.request,
|
fetchProcesses: processesAction.request,
|
||||||
|
|
||||||
fetchVersions: versionsAction.request,
|
fetchVersions: versionsAction.request,
|
||||||
fetchPlugins: pluginsAction.request
|
fetchPlugins: pluginsAction.request
|
||||||
},
|
},
|
||||||
)(AppContainer);
|
)(AppContainer));
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import {ConnectedRouter} from "connected-react-router";
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import ReactDOM from 'react-dom';
|
import ReactDOM from 'react-dom';
|
||||||
import {Provider} from 'react-redux';
|
import {Provider} from 'react-redux';
|
||||||
@ -5,8 +6,10 @@ import {Provider} from 'react-redux';
|
|||||||
import "tabler-react/dist/Tabler.css";
|
import "tabler-react/dist/Tabler.css";
|
||||||
import "./general.css";
|
import "./general.css";
|
||||||
import "./slider.css";
|
import "./slider.css";
|
||||||
|
import Layout from "./components/Layout";
|
||||||
|
|
||||||
import AppContainer from './containers/AppContainer';
|
import AppContainer from './containers/AppContainer';
|
||||||
|
import history from "./history";
|
||||||
import registerServiceWorker from './registerServiceWorker';
|
import registerServiceWorker from './registerServiceWorker';
|
||||||
import configureStore from './store/configureStore';
|
import configureStore from './store/configureStore';
|
||||||
|
|
||||||
@ -14,7 +17,11 @@ const store = configureStore();
|
|||||||
|
|
||||||
ReactDOM.render(
|
ReactDOM.render(
|
||||||
<Provider store={store}>
|
<Provider store={store}>
|
||||||
|
<ConnectedRouter history={history}>
|
||||||
|
<Layout>
|
||||||
<AppContainer/>
|
<AppContainer/>
|
||||||
|
</Layout>
|
||||||
|
</ConnectedRouter>
|
||||||
</Provider>,
|
</Provider>,
|
||||||
document.getElementById('root')
|
document.getElementById('root')
|
||||||
);
|
);
|
||||||
|
@ -146,12 +146,17 @@ function compilingContract(state = false, action) {
|
|||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function token(state = null, action) {
|
||||||
|
return (action.token) ? action.token : state;
|
||||||
|
}
|
||||||
|
|
||||||
const rootReducer = combineReducers({
|
const rootReducer = combineReducers({
|
||||||
entities,
|
entities,
|
||||||
loading,
|
loading,
|
||||||
compilingContract,
|
compilingContract,
|
||||||
errorMessage,
|
errorMessage,
|
||||||
errorEntities
|
errorEntities,
|
||||||
|
token
|
||||||
});
|
});
|
||||||
|
|
||||||
export default rootReducer;
|
export default rootReducer;
|
||||||
|
@ -2,9 +2,12 @@ import * as actions from '../actions';
|
|||||||
import * as api from '../services/api';
|
import * as api from '../services/api';
|
||||||
import * as storage from '../services/storage';
|
import * as storage from '../services/storage';
|
||||||
import {eventChannel} from 'redux-saga';
|
import {eventChannel} from 'redux-saga';
|
||||||
import {all, call, fork, put, takeEvery, take} from 'redux-saga/effects';
|
import {all, call, fork, put, takeEvery, take, select} from 'redux-saga/effects';
|
||||||
|
|
||||||
function *doRequest(entity, serviceFn, payload) {
|
function *doRequest(entity, serviceFn, payload) {
|
||||||
|
payload.token = yield select(function (state) {
|
||||||
|
return state.token;
|
||||||
|
});
|
||||||
const {response, error} = yield call(serviceFn, payload);
|
const {response, error} = yield call(serviceFn, payload);
|
||||||
if(response) {
|
if(response) {
|
||||||
yield put(entity.success(response.data, payload));
|
yield put(entity.success(response.data, payload));
|
||||||
@ -39,10 +42,13 @@ export const fetchFile = doRequest.bind(null, actions.file, api.fetchFile);
|
|||||||
export const postFile = doRequest.bind(null, actions.saveFile, api.postFile);
|
export const postFile = doRequest.bind(null, actions.saveFile, api.postFile);
|
||||||
export const deleteFile = doRequest.bind(null, actions.removeFile, api.deleteFile);
|
export const deleteFile = doRequest.bind(null, actions.removeFile, api.deleteFile);
|
||||||
export const fetchEthGas = doRequest.bind(null, actions.gasOracle, api.getEthGasAPI);
|
export const fetchEthGas = doRequest.bind(null, actions.gasOracle, api.getEthGasAPI);
|
||||||
|
export const authorize = doRequest.bind(null, actions.authorize, api.authorize);
|
||||||
|
|
||||||
export const fetchCurrentFile = doRequest.bind(null, actions.currentFile, storage.fetchCurrentFile);
|
export const fetchCurrentFile = doRequest.bind(null, actions.currentFile, storage.fetchCurrentFile);
|
||||||
export const postCurrentFile = doRequest.bind(null, actions.saveCurrentFile, storage.postCurrentFile);
|
export const postCurrentFile = doRequest.bind(null, actions.saveCurrentFile, storage.postCurrentFile);
|
||||||
export const deleteCurrentFile = doRequest.bind(null, null, storage.deleteCurrentFile);
|
export const deleteCurrentFile = doRequest.bind(null, null, storage.deleteCurrentFile);
|
||||||
|
export const fetchToken = doRequest.bind(null, actions.getToken, storage.fetchToken);
|
||||||
|
export const postToken = doRequest.bind(null, actions.postToken, storage.postToken);
|
||||||
|
|
||||||
|
|
||||||
export function *watchFetchTransaction() {
|
export function *watchFetchTransaction() {
|
||||||
@ -166,10 +172,22 @@ export function *watchPostCurrentFile() {
|
|||||||
yield takeEvery(actions.SAVE_CURRENT_FILE[actions.REQUEST], postCurrentFile);
|
yield takeEvery(actions.SAVE_CURRENT_FILE[actions.REQUEST], postCurrentFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function *watchFetchToken() {
|
||||||
|
yield takeEvery(actions.GET_TOKEN[actions.REQUEST], fetchToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function *watchPostToken() {
|
||||||
|
yield takeEvery(actions.POST_TOKEN[actions.REQUEST], postToken);
|
||||||
|
}
|
||||||
|
|
||||||
export function *watchFetchEthGas() {
|
export function *watchFetchEthGas() {
|
||||||
yield takeEvery(actions.GAS_ORACLE[actions.REQUEST], fetchEthGas);
|
yield takeEvery(actions.GAS_ORACLE[actions.REQUEST], fetchEthGas);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function *watchAuthenticate() {
|
||||||
|
yield takeEvery(actions.AUTHORIZE[actions.REQUEST], authorize);
|
||||||
|
}
|
||||||
|
|
||||||
function createChannel(socket) {
|
function createChannel(socket) {
|
||||||
return eventChannel(emit => {
|
return eventChannel(emit => {
|
||||||
socket.onmessage = ((message) => {
|
socket.onmessage = ((message) => {
|
||||||
@ -278,7 +296,10 @@ export default function *root() {
|
|||||||
fork(watchFetchFileSuccess),
|
fork(watchFetchFileSuccess),
|
||||||
fork(watchFetchCurrentFile),
|
fork(watchFetchCurrentFile),
|
||||||
fork(watchPostCurrentFile),
|
fork(watchPostCurrentFile),
|
||||||
|
fork(watchFetchToken),
|
||||||
|
fork(watchPostToken),
|
||||||
fork(watchFetchEthGas),
|
fork(watchFetchEthGas),
|
||||||
|
fork(watchAuthenticate),
|
||||||
fork(watchListenGasOracle)
|
fork(watchListenGasOracle)
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
@ -1,143 +1,147 @@
|
|||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import constants from '../constants';
|
import constants from '../constants';
|
||||||
|
|
||||||
function get(path, params, endpoint) {
|
function request(type, path, params = {}, endpoint) {
|
||||||
return axios.get((endpoint || constants.httpEndpoint) + path, params)
|
axios.defaults.headers.common['Authorization'] = params.token;
|
||||||
|
const callback = params.callback || function() {};
|
||||||
|
return axios[type]((endpoint || constants.httpEndpoint) + path, params)
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
return {response, error: null};
|
const data = (response.data && response.data.error) ? {error: response.data.error} : {response, error: null};
|
||||||
|
callback(data.error, data.response);
|
||||||
|
return data;
|
||||||
}).catch((error) => {
|
}).catch((error) => {
|
||||||
return {response: null, error: error.message || 'Something bad happened'};
|
const data = {response: null, error: error.message || 'Something bad happened'};
|
||||||
|
callback(data.error, data.response);
|
||||||
|
return data;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function post(path, params) {
|
function get() {
|
||||||
return axios.post(constants.httpEndpoint + path, params)
|
return request('get', ...arguments);
|
||||||
.then((response) => {
|
|
||||||
return {response, error: null};
|
|
||||||
})
|
|
||||||
.catch((error) => {
|
|
||||||
return {response: null, error: error.message || 'Something bad happened'};
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function destroy(path, params) {
|
function post() {
|
||||||
return axios.delete(constants.httpEndpoint + path, params)
|
return request('post', ...arguments);
|
||||||
.then((response) => {
|
|
||||||
return {response, error: null};
|
|
||||||
})
|
|
||||||
.catch((error) => {
|
|
||||||
return {response: null, error: error.message || 'Something bad happened'};
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function postCommand(payload) {
|
function destroy() {
|
||||||
return post('/command', payload);
|
return request('delete', ...arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function postCommand() {
|
||||||
|
return post('/command', ...arguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function fetchAccounts() {
|
export function fetchAccounts() {
|
||||||
return get('/blockchain/accounts');
|
return get('/blockchain/accounts', ...arguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function fetchAccount(payload) {
|
export function fetchAccount(payload) {
|
||||||
return get(`/blockchain/accounts/${payload.address}`);
|
return get(`/blockchain/accounts/${payload.address}`, ...arguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function fetchBlocks(payload) {
|
export function fetchBlocks(payload) {
|
||||||
return get('/blockchain/blocks', {params: payload});
|
return get('/blockchain/blocks', {params: payload, token: payload.token});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function fetchBlock(payload) {
|
export function fetchBlock(payload) {
|
||||||
return get(`/blockchain/blocks/${payload.blockNumber}`);
|
return get(`/blockchain/blocks/${payload.blockNumber}`, ...arguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function fetchTransactions(payload) {
|
export function fetchTransactions(payload) {
|
||||||
return get('/blockchain/transactions', {params: payload});
|
return get('/blockchain/transactions', {params: payload, token: payload.token});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function fetchTransaction(payload) {
|
export function fetchTransaction(payload) {
|
||||||
return get(`/blockchain/transactions/${payload.hash}`);
|
return get(`/blockchain/transactions/${payload.hash}`, ...arguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function fetchProcesses() {
|
export function fetchProcesses() {
|
||||||
return get('/processes');
|
return get('/processes', ...arguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function fetchProcessLogs(payload) {
|
export function fetchProcessLogs(payload) {
|
||||||
return get(`/process-logs/${payload.processName}`);
|
return get(`/process-logs/${payload.processName}`, ...arguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function fetchContractLogs() {
|
export function fetchContractLogs() {
|
||||||
return get(`/contracts/logs`);
|
return get(`/contracts/logs`, ...arguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function fetchContracts() {
|
export function fetchContracts() {
|
||||||
return get('/contracts');
|
return get('/contracts', ...arguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function fetchContract(payload) {
|
export function fetchContract(payload) {
|
||||||
return get(`/contract/${payload.contractName}`);
|
return get(`/contract/${payload.contractName}`, ...arguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function postContractFunction(payload) {
|
export function postContractFunction(payload) {
|
||||||
return post(`/contract/${payload.contractName}/function`, payload);
|
return post(`/contract/${payload.contractName}/function`, ...arguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function postContractDeploy(payload) {
|
export function postContractDeploy(payload) {
|
||||||
return post(`/contract/${payload.contractName}/deploy`, payload);
|
return post(`/contract/${payload.contractName}/deploy`, ...arguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function postContractCompile(payload) {
|
export function postContractCompile() {
|
||||||
return post('/contract/compile', payload);
|
return post('/contract/compile', ...arguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function fetchVersions() {
|
export function fetchVersions() {
|
||||||
return get('/versions');
|
return get('/versions', ...arguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function fetchPlugins() {
|
export function fetchPlugins() {
|
||||||
return get('/plugins');
|
return get('/plugins', ...arguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function sendMessage(payload) {
|
export function sendMessage(payload) {
|
||||||
return post(`/communication/sendMessage`, payload.body);
|
return post(`/communication/sendMessage`, Object.assign({}, payload.body, {token: payload.token}));
|
||||||
}
|
}
|
||||||
|
|
||||||
export function fetchContractProfile(payload) {
|
export function fetchContractProfile(payload) {
|
||||||
return get(`/profiler/${payload.contractName}`);
|
return get(`/profiler/${payload.contractName}`, ...arguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function fetchEnsRecord(payload) {
|
export function fetchEnsRecord(payload) {
|
||||||
|
const _payload = {params: payload, token: payload.token};
|
||||||
if (payload.name) {
|
if (payload.name) {
|
||||||
return get('/ens/resolve', {params: payload});
|
return get('/ens/resolve', _payload);
|
||||||
} else {
|
} else {
|
||||||
return get('/ens/lookup', {params: payload});
|
return get('/ens/lookup', _payload);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function postEnsRecord(payload) {
|
export function postEnsRecord() {
|
||||||
return post('/ens/register', payload);
|
return post('/ens/register', ...arguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getEthGasAPI() {
|
export function getEthGasAPI() {
|
||||||
return get('/blockchain/gas/oracle', {});
|
return get('/blockchain/gas/oracle', ...arguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function fetchFiles() {
|
export function fetchFiles() {
|
||||||
return get('/files');
|
return get('/files', ...arguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function fetchFile(payload) {
|
export function fetchFile(payload) {
|
||||||
return get('/file', {params: payload});
|
return get('/file', {params: payload, token: payload.token});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function postFile(payload) {
|
export function postFile() {
|
||||||
return post('/files', payload);
|
return post('/files', ...arguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function deleteFile(payload) {
|
export function deleteFile(payload) {
|
||||||
return destroy('/file', {params: payload});
|
return destroy('/file', {params: payload, token: payload.token});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function authorize() {
|
||||||
|
return post('/authorize', ...arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO token for WS?
|
||||||
export function listenToChannel(channel) {
|
export function listenToChannel(channel) {
|
||||||
return new WebSocket(`${constants.wsEndpoint}/communication/listenTo/${channel}`);
|
return new WebSocket(`${constants.wsEndpoint}/communication/listenTo/${channel}`);
|
||||||
}
|
}
|
||||||
|
@ -17,3 +17,19 @@ export function deleteCurrentFile() {
|
|||||||
resolve({});
|
resolve({});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function postToken(data) {
|
||||||
|
return new Promise(function(resolve) {
|
||||||
|
localStorage.setItem('token', data.token);
|
||||||
|
resolve({response: {data: data.token}});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function fetchToken({callback}) {
|
||||||
|
callback = callback || function(){};
|
||||||
|
return new Promise(function(resolve) {
|
||||||
|
const token = localStorage.getItem('token');
|
||||||
|
callback(null, token);
|
||||||
|
resolve({response: {data: token}});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
@ -202,6 +202,7 @@ class Engine {
|
|||||||
|
|
||||||
webServerService(_options) {
|
webServerService(_options) {
|
||||||
this.registerModule('webserver', {plugins: this.plugins});
|
this.registerModule('webserver', {plugins: this.plugins});
|
||||||
|
this.registerModule('authenticator');
|
||||||
}
|
}
|
||||||
|
|
||||||
storageService(_options) {
|
storageService(_options) {
|
||||||
|
57
lib/modules/authenticator/index.js
Normal file
57
lib/modules/authenticator/index.js
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
const uuid = require('uuid/v1');
|
||||||
|
|
||||||
|
const ERROR_OBJ = {error: __('Wrong authentication token. Get your token from the Embark console by typing `token`')};
|
||||||
|
|
||||||
|
class Authenticator {
|
||||||
|
constructor(embark, _options) {
|
||||||
|
this.authToken = uuid();
|
||||||
|
this.embark = embark;
|
||||||
|
this.logger = embark.logger;
|
||||||
|
this.events = embark.events;
|
||||||
|
|
||||||
|
this.registerCalls();
|
||||||
|
this.registerEvents();
|
||||||
|
}
|
||||||
|
|
||||||
|
registerCalls() {
|
||||||
|
this.embark.registerAPICall(
|
||||||
|
'post',
|
||||||
|
'/embark-api/authorize',
|
||||||
|
(req, res) => {
|
||||||
|
if (req.body.token !== this.authToken) {
|
||||||
|
this.logger.warn(__('Someone tried and failed to authorize to the backend'));
|
||||||
|
this.logger.warn(__('- User-Agent: %s', req.headers['user-agent']));
|
||||||
|
this.logger.warn(__('- Referer: %s', req.headers.referer));
|
||||||
|
return res.send(ERROR_OBJ);
|
||||||
|
}
|
||||||
|
res.send();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
this.embark.registerConsoleCommand((cmd, _options) => {
|
||||||
|
return {
|
||||||
|
match: () => cmd === "token",
|
||||||
|
process: (callback) => {
|
||||||
|
callback(null, __('Your authorisation token: %s', this.authToken));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
registerEvents() {
|
||||||
|
this.events.once('outputDone', () => {
|
||||||
|
const {port, host} = this.embark.config.webServerConfig;
|
||||||
|
this.logger.info(__('Access the web backend with the following url: %s',
|
||||||
|
(`http://${host}:${port}/embark?token=${this.authToken}`.underline)));
|
||||||
|
});
|
||||||
|
|
||||||
|
this.events.setCommandHandler('authenticator:authorize', (token, cb) => {
|
||||||
|
if (token !== this.authToken) {
|
||||||
|
return cb(ERROR_OBJ);
|
||||||
|
}
|
||||||
|
cb();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = Authenticator;
|
@ -49,13 +49,13 @@ class Server {
|
|||||||
|
|
||||||
for (let apiCall of apiCalls) {
|
for (let apiCall of apiCalls) {
|
||||||
console.dir("adding " + apiCall.method + " " + apiCall.endpoint);
|
console.dir("adding " + apiCall.method + " " + apiCall.endpoint);
|
||||||
app[apiCall.method].apply(app, [apiCall.endpoint, apiCall.cb]);
|
app[apiCall.method].apply(app, [apiCall.endpoint, this.applyAPIFunction.bind(this, apiCall.cb)]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.events.on('plugins:register:api', (apiCall) => {
|
this.events.on('plugins:register:api', (apiCall) => {
|
||||||
console.dir("adding " + apiCall.method + " " + apiCall.endpoint);
|
console.dir("adding " + apiCall.method + " " + apiCall.endpoint);
|
||||||
app[apiCall.method].apply(app, [apiCall.endpoint, apiCall.cb]);
|
app[apiCall.method].apply(app, [apiCall.endpoint, this.applyAPIFunction.bind(this, apiCall.cb)]);
|
||||||
});
|
});
|
||||||
|
|
||||||
app.get('/embark/*', function(req, res) {
|
app.get('/embark/*', function(req, res) {
|
||||||
@ -78,6 +78,16 @@ class Server {
|
|||||||
":" + this.port).bold.underline.green);
|
":" + this.port).bold.underline.green);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
applyAPIFunction (cb, req, res) {
|
||||||
|
this.events.request('authenticator:authorize', req.headers.authorization, (err) => {
|
||||||
|
if (err) {
|
||||||
|
const send = res.send ? res.send.bind(res) : req.send.bind(req); // WS only has the first params
|
||||||
|
return send(err);
|
||||||
|
}
|
||||||
|
cb(req, res);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
stop(callback) {
|
stop(callback) {
|
||||||
callback = callback || function () {};
|
callback = callback || function () {};
|
||||||
if (!this.server || !this.server.listening) {
|
if (!this.server || !this.server.listening) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user