From decc5922de380c9f656f8edd344be210e3b24514 Mon Sep 17 00:00:00 2001 From: Jaco Greeff Date: Wed, 26 Jul 2017 11:57:14 +0200 Subject: [PATCH] Fix previous merge --- js/src/index.js | 8 + js/src/shell/DappRequests/store.js | 278 ----------------------------- js/src/shell/index.js | 110 ------------ 3 files changed, 8 insertions(+), 388 deletions(-) delete mode 100644 js/src/shell/DappRequests/store.js delete mode 100644 js/src/shell/index.js diff --git a/js/src/index.js b/js/src/index.js index f76620e8c..58baf678f 100644 --- a/js/src/index.js +++ b/js/src/index.js @@ -27,6 +27,7 @@ import { IndexRoute, Redirect, Route, Router, hashHistory } from 'react-router'; import qs from 'querystring'; import Api from '@parity/api'; +import Abi from '@parity/abi'; import builtinDapps from '@parity/shared/config/dappsBuiltin.json'; import viewsDapps from '@parity/shared/config/dappsViews.json'; import ContractInstances from '@parity/shared/contracts'; @@ -79,6 +80,13 @@ const dappsHistory = HistoryStore.get('dapps'); function onEnterDapp ({ params: { id } }) { const token = DappRequestsStore.get().createToken(id); + // on app switch unsubscribe all subscriptions + if (window.ethereum) { + window.ethereum.unsubscribeAll(); + } + + // old API uses window.parity + window.parity = { Api, Abi }; window.ethereum = new Api.Provider.PostMessage(token, window); if (!dapps[id] || !dapps[id].skipHistory) { diff --git a/js/src/shell/DappRequests/store.js b/js/src/shell/DappRequests/store.js deleted file mode 100644 index e6082dd52..000000000 --- a/js/src/shell/DappRequests/store.js +++ /dev/null @@ -1,278 +0,0 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. -// This file is part of Parity. - -// Parity is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Parity is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Parity. If not, see . - -import { flatten } from 'lodash'; -import { action, computed, observable } from 'mobx'; -import store from 'store'; - -import { sha3 } from '@parity/api/util/sha3'; - -import VisibleStore from '../Dapps/dappsStore'; -import filteredRequests from './filteredRequests'; - -const LS_PERMISSIONS = '_parity::dapps::methods'; - -let nextQueueId = 0; - -export default class Store { - @observable permissions = {}; - @observable requests = []; - @observable tokens = {}; - - constructor (provider) { - this.provider = provider; - this.permissions = store.get(LS_PERMISSIONS) || {}; - - window.addEventListener('message', this.receiveMessage, false); - } - - @computed get hasRequests () { - return this.requests.length !== 0; - } - - @computed get squashedRequests () { - const duplicates = {}; - - return this.requests.filter(({ request: { data: { method, token } } }) => { - const section = this.getFilteredSectionName(method); - const id = `${token}:${section}`; - - if (!duplicates[id]) { - duplicates[id] = true; - return true; - } - - return false; - }); - } - - @action createToken = (appId) => { - const token = sha3(`${appId}:${Date.now()}`); - - this.tokens = Object.assign({}, this.tokens, { - [token]: appId - }); - - return token; - } - - @action removeRequest = (_queueId) => { - this.requests = this.requests.filter(({ queueId }) => queueId !== _queueId); - } - - @action queueRequest = (request) => { - const appId = this.tokens[request.data.from]; - let queueId = ++nextQueueId; - - this.requests = this.requests.concat([{ appId, queueId, request }]); - } - - @action addTokenPermission = (method, token) => { - const id = `${method}:${this.tokens[token]}`; - - this.permissions = Object.assign({}, this.permissions, { - [id]: true - }); - this.savePermissions(); - } - - @action approveSingleRequest = ({ queueId, request: { data, source } }) => { - this.removeRequest(queueId); - if (data.api) { - this.executePubsubCall(data, source); - } else { - this.executeMethodCall(data, source); - } - } - - @action approveRequest = (queueId, approveAll) => { - const queued = this.findRequest(queueId); - - if (approveAll) { - const { request: { data: { method, token, params } } } = queued; - - this.getFilteredSection(method || params[0]).methods.forEach((m) => { - this.addTokenPermission(m, token); - this.findMatchingRequests(m, token).forEach(this.approveSingleRequest); - }); - } else { - this.approveSingleRequest(queued); - } - } - - @action rejectRequest = (queueId) => { - const { request: { data: { id, method, token }, source } } = this.findRequest(queueId); - - this.removeRequest(queueId); - source.postMessage({ - error: `Method ${method} not allowed`, - id, - from: 'shell', - result: null, - token - }, '*'); - } - - @action setPermissions = (_permissions) => { - const permissions = {}; - - Object.keys(_permissions).forEach((id) => { - permissions[id] = !!_permissions[id]; - }); - - this.permissions = Object.assign({}, this.permissions, permissions); - this.savePermissions(); - - return true; - } - - hasTokenPermission = (method, token) => { - return this.hasAppPermission(method, this.tokens[token]); - } - - hasAppPermission = (method, appId) => { - return this.permissions[`${method}:${appId}`] || false; - } - - savePermissions = () => { - store.set(LS_PERMISSIONS, this.permissions); - } - - findRequest (_queueId) { - return this.requests.find(({ queueId }) => queueId === _queueId); - } - - findMatchingRequests (_method, _token) { - return this.requests.filter(({ request: { data: { method, token, params } } }) => (method === _method || (params && params[0] === _method)) && token === _token); - } - - _methodCallbackPost = (id, source, token) => { - return (error, result) => { - source.postMessage({ - error: error - ? error.message - : null, - id, - from: 'shell', - result, - token - }, '*'); - }; - } - - executePubsubCall = ({ api, id, token, params }, source) => { - const callback = this._methodCallbackPost(id, source, token); - - // TODO: enable security pubsub - this.provider.subscribe(api, callback, params).then((v, e) => { - console.log('Error and result', v, e); - this._methodCallbackPost(id, source, token)(null, v); - }); - } - - executeMethodCall = ({ id, from, method, params, token }, source) => { - const visibleStore = VisibleStore.get(); - const callback = this._methodCallbackPost(id, source, token); - - switch (method) { - case 'shell_getApps': - const [displayAll] = params; - - return callback(null, displayAll - ? visibleStore.allApps.slice() - : visibleStore.visibleApps.slice() - ); - - case 'shell_getFilteredMethods': - return callback(null, flatten( - Object - .keys(filteredRequests) - .map((key) => filteredRequests[key].methods) - )); - - case 'shell_getMethodPermissions': - return callback(null, this.permissions); - - case 'shell_setAppVisibility': - const [appId, visibility] = params; - - return callback(null, visibility - ? visibleStore.showApp(appId) - : visibleStore.hideApp(appId) - ); - - case 'shell_setMethodPermissions': - const [permissions] = params; - - return callback(null, this.setPermissions(permissions)); - - default: - return this.provider.send(method, params, callback); - } - } - - getFilteredSectionName = (method) => { - return Object.keys(filteredRequests).find((key) => { - return filteredRequests[key].methods.includes(method); - }); - } - - getFilteredSection = (method) => { - return filteredRequests[this.getFilteredSectionName(method)]; - } - - receiveMessage = ({ data, origin, source }) => { - if (!data) { - return; - } - - const { from, method, token, params, api, subId, id } = data; - - if (!from || from === 'shell' || from !== token) { - return; - } - - if ((method && this.getFilteredSection(method) && !this.hasTokenPermission(method, token)) || - (api && this.getFilteredSection(params[0]) && !this.hasTokenPermission(method, token))) { - this.queueRequest({ data, origin, source }); - return; - } - if (api) { - console.log('apiCall', data); - this.executePubsubCall(data, source); - } else if (subId) { - subId === '*' - ? this.provider.unsubscribeAll().then(v => this._methodCallbackPost(id, source, token)(null, v)) - : this.provider.unsubscribe(subId).then(v => this._methodCallbackPost(id, source, token)(null, v)); - } else { - this.executeMethodCall(data, source); - } - } - - static instance = null; - - static create (provider) { - if (!Store.instance) { - Store.instance = new Store(provider, {}); - } - - return Store.instance; - } - - static get () { - return Store.instance; - } -} diff --git a/js/src/shell/index.js b/js/src/shell/index.js deleted file mode 100644 index 54fba1507..000000000 --- a/js/src/shell/index.js +++ /dev/null @@ -1,110 +0,0 @@ -// Copyright 2015-2017 Parity Technologies (UK) Ltd. -// This file is part of Parity. - -// Parity is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Parity is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Parity. If not, see . - -import 'whatwg-fetch'; - -import es6Promise from 'es6-promise'; -es6Promise.polyfill(); - -import React from 'react'; -import ReactDOM from 'react-dom'; - -import injectTapEventPlugin from 'react-tap-event-plugin'; -import { IndexRoute, Redirect, Route, Router, hashHistory } from 'react-router'; -import qs from 'querystring'; - -import Api from '@parity/api'; -import Abi from '@parity/abi'; -import builtinDapps from '@parity/shared/config/dappsBuiltin.json'; -import viewsDapps from '@parity/shared/config/dappsViews.json'; -import ContractInstances from '@parity/shared/contracts'; -import HistoryStore from '@parity/shared/mobx/historyStore'; -import { initStore } from '@parity/shared/redux'; -import { patchApi } from '@parity/shared/util/tx'; -import ContextProvider from '@parity/ui/ContextProvider'; - -import '@parity/shared/environment'; - -import SecureApi from '~/secureApi'; - -import Application from './Application'; -import Dapp from './Dapp'; -import { setupProviderFilters, Store as DappRequestsStore } from './DappRequests'; -import Dapps from './Dapps'; - -injectTapEventPlugin(); - -console.log('UI version', process.env.UI_VERSION); - -if (process.env.NODE_ENV === 'development') { - // Expose the React Performance Tools on the`window` object - const Perf = require('react-addons-perf'); - - window.Perf = Perf; -} - -const AUTH_HASH = '#/auth?'; - -let token = null; - -if (window.location.hash && window.location.hash.indexOf(AUTH_HASH) === 0) { - token = qs.parse(window.location.hash.substr(AUTH_HASH.length)).token; -} - -const uiUrl = window.location.host; -const api = new SecureApi(uiUrl, token); - -patchApi(api); -ContractInstances.get(api); - -setupProviderFilters(api.provider); - -const store = initStore(api, hashHistory); - -const dapps = [].concat(viewsDapps, builtinDapps); - -const dappsHistory = HistoryStore.get('dapps'); - -function onEnterDapp ({ params: { id } }) { - const token = DappRequestsStore.get().createToken(id); - - // on app switch unsubscribe all subscriptions - if (window.ethereum) { - window.ethereum.unsubscribeAll(); - } - // old API uses window.parity - window.parity = { Api, Abi }; - - window.ethereum = new Api.Provider.PostMessage(token, window); - - if (!dapps[id] || !dapps[id].skipHistory) { - dappsHistory.add(id); - } -} - -ReactDOM.render( - - - - - - - - - - , - document.querySelector('#container') -);