use redux instead of directly localStorage

This commit is contained in:
Jonathan Rainville 2018-09-07 10:40:28 -04:00
parent 0a6196d48d
commit 2f5e4136a1
7 changed files with 113 additions and 67 deletions

View File

@ -226,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]),

View File

@ -6,11 +6,10 @@ import {Alert, Page, Form, Button} from "tabler-react";
import routes from '../routes'; import routes from '../routes';
import queryString from 'query-string'; import queryString from 'query-string';
import {put as cachePut, get as cacheGet} from '../services/cache';
import { import {
initBlockHeader, initBlockHeader,
authorize, authorize, getToken, postToken,
processes as processesAction, processes as processesAction,
versions as versionsAction, versions as versionsAction,
plugins as pluginsAction plugins as pluginsAction
@ -23,20 +22,27 @@ class AppContainer extends Component {
authenticateError: null authenticateError: null
}; };
let token; this.checkToken();
}
checkToken() {
if (this.props.location.search) { if (this.props.location.search) {
token = queryString.parse(this.props.location.search).token; const token = queryString.parse(this.props.location.search).token;
cachePut('token', token); this.props.postToken(token);
} else { return this.props.authorize(token, this.authCallback.bind(this));
token = cacheGet('token');
} }
this.props.authorize(token, (err) => { this.props.getToken((err, token) => {
if (err) { this.props.authorize(token, this.authCallback.bind(this));
return this.setState({authenticateError: err});
}
this.setState({authenticateError: null});
}); });
} }
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();
@ -64,6 +70,8 @@ class AppContainer extends Component {
AppContainer.propTypes = { AppContainer.propTypes = {
authorize: PropTypes.func, 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,
@ -76,6 +84,8 @@ export default withRouter(connect(
{ {
initBlockHeader, initBlockHeader,
authorize: authorize.request, 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

View File

@ -73,7 +73,7 @@ const filtrer = {
}, },
ensRecords: function(record, index, self) { ensRecords: function(record, index, self) {
return record.name && record.address && record.address !== voidAddress && index === self.findIndex((r) => ( return record.name && record.address && record.address !== voidAddress && index === self.findIndex((r) => (
r.address=== record.address && r.name === record.name r.address === record.address && r.name === record.name
)); ));
}, },
files: function(file, index, self) { files: function(file, index, self) {
@ -137,7 +137,7 @@ function loading(_state = false, action) {
} }
function compilingContract(state = false, action) { function compilingContract(state = false, action) {
if(action.type === CONTRACT_COMPILE[REQUEST]) { if (action.type === CONTRACT_COMPILE[REQUEST]) {
return true; return true;
} else if (action.type === CONTRACT_COMPILE[FAILURE] || action.type === CONTRACT_COMPILE[SUCCESS]) { } else if (action.type === CONTRACT_COMPILE[FAILURE] || action.type === CONTRACT_COMPILE[SUCCESS]) {
return false; return false;
@ -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;

View File

@ -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));
@ -44,6 +47,8 @@ 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() {
@ -167,6 +172,14 @@ 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);
} }
@ -283,6 +296,8 @@ 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(watchAuthenticate),
fork(watchListenGasOracle) fork(watchListenGasOracle)

View File

@ -1,10 +1,9 @@
import axios from "axios"; import axios from "axios";
import constants from '../constants'; import constants from '../constants';
import {get as cacheGet} from '../services/cache';
function request(type, path, params = {}, endpoint) { function request(type, path, params = {}, endpoint) {
axios.defaults.headers.common['Authorization'] = cacheGet('token'); axios.defaults.headers.common['Authorization'] = params.token;
const callback = params.callback || function(){}; const callback = params.callback || function() {};
return axios[type]((endpoint || constants.httpEndpoint) + path, params) return axios[type]((endpoint || constants.httpEndpoint) + path, params)
.then((response) => { .then((response) => {
const data = (response.data && response.data.error) ? {error: response.data.error} : {response, error: null}; const data = (response.data && response.data.error) ? {error: response.data.error} : {response, error: null};
@ -29,118 +28,120 @@ function destroy() {
return request('delete', ...arguments); return request('delete', ...arguments);
} }
export function postCommand(payload) { export function postCommand() {
return post('/command', payload); 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(payload) { export function authorize() {
return post('/authorize', payload); 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}`);
} }

View File

@ -1,15 +0,0 @@
export function put(key, value) {
window.localStorage.setItem(key, value);
}
export function get(key) {
return window.localStorage.getItem(key);
}
export function remove(key) {
return window.localStorage.removeItem(key);
}
export function clear() {
window.localStorage.clear();
}

View File

@ -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}});
});
}