aboutsummaryrefslogtreecommitdiffstats
path: root/web
diff options
context:
space:
mode:
Diffstat (limited to 'web')
-rw-r--r--web/package.json4
-rw-r--r--web/src/js/components/Header/MainMenu.jsx11
-rw-r--r--web/src/js/components/ProxyApp.jsx34
-rw-r--r--web/src/js/connection.js6
-rw-r--r--web/src/js/ducks/index.js2
-rw-r--r--web/src/js/ducks/settings.js77
-rw-r--r--web/src/js/store/store.js96
-rw-r--r--web/src/js/store/view.js0
-rw-r--r--web/src/js/utils.js18
9 files changed, 113 insertions, 135 deletions
diff --git a/web/package.json b/web/package.json
index 54555cb1..7ace808a 100644
--- a/web/package.json
+++ b/web/package.json
@@ -2,7 +2,9 @@
"name": "mitmproxy",
"private": true,
"scripts": {
- "test": "jest"
+ "test": "jest",
+ "build": "gulp prod",
+ "start": "gulp"
},
"jest": {
"testPathDirs": [
diff --git a/web/src/js/components/Header/MainMenu.jsx b/web/src/js/components/Header/MainMenu.jsx
index 86bf961a..7b0b542c 100644
--- a/web/src/js/components/Header/MainMenu.jsx
+++ b/web/src/js/components/Header/MainMenu.jsx
@@ -1,9 +1,10 @@
import React, { Component, PropTypes } from 'react'
-import { SettingsActions } from "../../actions.js"
import FilterInput from './FilterInput'
import { Query } from '../../actions.js'
+import {setInterceptPattern} from "../../ducks/settings"
+import { connect } from 'react-redux'
-export default class MainMenu extends Component {
+class MainMenu extends Component {
static title = 'Start'
static route = 'flows'
@@ -28,7 +29,7 @@ export default class MainMenu extends Component {
}
onInterceptChange(val) {
- SettingsActions.update({ intercept: val })
+ this.props.setInterceptPattern(val);
}
render() {
@@ -71,3 +72,7 @@ export default class MainMenu extends Component {
)
}
}
+
+export default connect(undefined, {
+ setInterceptPattern
+})(MainMenu);
diff --git a/web/src/js/components/ProxyApp.jsx b/web/src/js/components/ProxyApp.jsx
index c458639d..39cadff5 100644
--- a/web/src/js/components/ProxyApp.jsx
+++ b/web/src/js/components/ProxyApp.jsx
@@ -6,7 +6,6 @@ import { connect } from 'react-redux'
import Header from './Header'
import EventLog from './EventLog'
import Footer from './Footer'
-import { SettingsStore } from '../store/store.js'
import { Key } from '../utils.js'
class ProxyAppMain extends Component {
@@ -22,17 +21,9 @@ class ProxyAppMain extends Component {
constructor(props, context) {
super(props, context)
- this.settingsStore = new SettingsStore()
-
- // Default Settings before fetch
- _.extend(this.settingsStore.dict, {})
-
- this.state = { settings: this.settingsStore.dict }
-
this.focus = this.focus.bind(this)
this.onKeyDown = this.onKeyDown.bind(this)
this.updateLocation = this.updateLocation.bind(this)
- this.onSettingsChange = this.onSettingsChange.bind(this)
}
/**
@@ -59,29 +50,10 @@ class ProxyAppMain extends Component {
}
/**
- * @todo remove settings store
- * @todo connect websocket here
* @todo listen to window's key events
*/
componentDidMount() {
this.focus()
- this.settingsStore.addListener('recalculate', this.onSettingsChange)
- }
-
- /**
- * @todo remove settings store
- * @todo disconnect websocket here
- * @todo stop listening to window's key events
- */
- componentWillUnmount() {
- this.settingsStore.removeListener('recalculate', this.onSettingsChange)
- }
-
- /**
- * @todo move to actions
- */
- onSettingsChange() {
- this.setState({ settings: this.settingsStore.dict })
}
/**
@@ -139,8 +111,7 @@ class ProxyAppMain extends Component {
}
render() {
- const { showEventLog, location, children } = this.props
- const { settings } = this.state
+ const { showEventLog, location, children, settings } = this.props
const query = this.getQuery()
return (
<div id="container" tabIndex="0" onKeyDown={this.onKeyDown}>
@@ -160,6 +131,7 @@ class ProxyAppMain extends Component {
export default connect(
state => ({
- showEventLog: state.eventLog.visible
+ showEventLog: state.eventLog.visible,
+ settings: state.settings.settings,
})
)(ProxyAppMain)
diff --git a/web/src/js/connection.js b/web/src/js/connection.js
index 5961909e..786a6394 100644
--- a/web/src/js/connection.js
+++ b/web/src/js/connection.js
@@ -3,6 +3,7 @@ import {AppDispatcher} from "./dispatcher.js";
import * as webSocketActions from "./ducks/websocket"
import * as eventLogActions from "./ducks/eventLog"
import * as flowActions from "./ducks/flows"
+import * as settingsActions from './ducks/settings'
export default function Connection(url, dispatch) {
if (url[0] === "/") {
@@ -12,6 +13,7 @@ export default function Connection(url, dispatch) {
var ws = new WebSocket(url);
ws.onopen = function () {
dispatch(webSocketActions.connected())
+ dispatch(settingsActions.fetchSettings())
dispatch(flowActions.fetchFlows())
// workaround to make sure that our state is already available.
.then(() => {
@@ -28,6 +30,8 @@ export default function Connection(url, dispatch) {
return dispatch(eventLogActions.updateLogEntries(message))
case flowActions.UPDATE_FLOWS:
return dispatch(flowActions.updateFlows(message))
+ case settingsActions.UPDATE_SETTINGS:
+ return dispatch(settingsActions.updateSettings(message))
default:
console.warn("unknown message", message)
}
@@ -42,4 +46,4 @@ export default function Connection(url, dispatch) {
dispatch(webSocketActions.disconnected());
};
return ws;
-} \ No newline at end of file
+}
diff --git a/web/src/js/ducks/index.js b/web/src/js/ducks/index.js
index fee4d792..ffde1a64 100644
--- a/web/src/js/ducks/index.js
+++ b/web/src/js/ducks/index.js
@@ -2,12 +2,14 @@ import {combineReducers} from 'redux'
import eventLog from './eventLog'
import websocket from './websocket'
import flows from './flows'
+import settings from './settings'
import ui from './ui'
const rootReducer = combineReducers({
eventLog,
websocket,
flows,
+ settings,
ui
})
diff --git a/web/src/js/ducks/settings.js b/web/src/js/ducks/settings.js
new file mode 100644
index 00000000..73c62120
--- /dev/null
+++ b/web/src/js/ducks/settings.js
@@ -0,0 +1,77 @@
+import {fetchApi} from "../utils";
+
+export const REQUEST_SETTINGS = "REQUEST_SETTINGS"
+export const RECEIVE_SETTINGS = "RECEIVE_SETTINGS"
+export const UPDATE_SETTINGS = "UPDATE_SETTINGS"
+
+const defaultState = {
+ settings: {},
+ isFetching: false,
+ actionsDuringFetch: [],
+}
+
+export default function reducer(state = defaultState, action) {
+ switch (action.type) {
+
+ case REQUEST_SETTINGS:
+ return {
+ ...state,
+ isFetching: true
+ }
+
+ case RECEIVE_SETTINGS:
+ let s = {
+ settings: action.settings,
+ isFetching: false,
+ actionsDuringFetch: [],
+ }
+ for (action of state.actionsDuringFetch) {
+ s = reducer(s, action)
+ }
+ return s
+
+ case UPDATE_SETTINGS:
+ if (state.isFetching) {
+ return {
+ ...state,
+ actionsDuringFetch: [...state.actionsDuringFetch, action]
+ }
+ }
+ return {
+ ...state,
+ settings: {...state.settings, ...action.settings}
+ }
+
+ default:
+ return state
+ }
+}
+
+export function updateSettings(event) {
+ /* This action creator takes all WebSocket events */
+ if (event.cmd === "update") {
+ return {
+ type: UPDATE_SETTINGS,
+ settings: event.data
+ }
+ }
+ console.error("unknown settings update", event)
+}
+
+export function fetchSettings() {
+ return dispatch => {
+ dispatch({type: REQUEST_SETTINGS})
+
+ return fetchApi("/settings")
+ .then(response => response.json())
+ .then(json =>
+ dispatch({type: RECEIVE_SETTINGS, settings: json.data})
+ )
+ // TODO: Error handling
+ }
+}
+
+export function setInterceptPattern(intercept) {
+ return dispatch =>
+ fetchApi.put("/settings", {intercept})
+}
diff --git a/web/src/js/store/store.js b/web/src/js/store/store.js
deleted file mode 100644
index f3e2074f..00000000
--- a/web/src/js/store/store.js
+++ /dev/null
@@ -1,96 +0,0 @@
-
-import _ from "lodash";
-import $ from "jquery";
-import {EventEmitter} from 'events';
-import {ActionTypes, StoreCmds} from "../actions.js";
-import {AppDispatcher} from "../dispatcher.js";
-
-
-function DictStore() {
- EventEmitter.call(this);
- this.reset();
-}
-_.extend(DictStore.prototype, EventEmitter.prototype, {
- update: function (dict) {
- _.merge(this.dict, dict);
- this.emit("recalculate");
- },
- reset: function (dict) {
- this.dict = dict || {};
- this.emit("recalculate");
- }
-});
-
-function LiveStoreMixin(type) {
- this.type = type;
-
- this._updates_before_fetch = undefined;
- this._fetchxhr = false;
-
- this.handle = this.handle.bind(this);
- AppDispatcher.register(this.handle);
-
- // Avoid double-fetch on startup.
- if (!(window.ws && window.ws.readyState === WebSocket.CONNECTING)) {
- this.fetch();
- }
-}
-_.extend(LiveStoreMixin.prototype, {
- handle: function (event) {
- if (event.type === ActionTypes.CONNECTION_OPEN) {
- return this.fetch();
- }
- if (event.type === this.type) {
- if (event.cmd === StoreCmds.RESET) {
- this.fetch(event.data);
- } else if (this._updates_before_fetch) {
- console.log("defer update", event);
- this._updates_before_fetch.push(event);
- } else {
- this[event.cmd](event.data);
- }
- }
- },
- close: function () {
- AppDispatcher.unregister(this.handle);
- },
- fetch: function (data) {
- console.log("fetch " + this.type);
- if (this._fetchxhr) {
- this._fetchxhr.abort();
- }
- this._updates_before_fetch = []; // (JS: empty array is true)
- if (data) {
- this.handle_fetch(data);
- } else {
- this._fetchxhr = $.getJSON("/" + this.type)
- .done(function (message) {
- this.handle_fetch(message.data);
- }.bind(this))
- .fail(function () {
- console.error("Could not fetch " + this.type)
- }.bind(this));
- }
- },
- handle_fetch: function (data) {
- this._fetchxhr = false;
- console.log(this.type + " fetched.", this._updates_before_fetch);
- this.reset(data);
- var updates = this._updates_before_fetch;
- this._updates_before_fetch = false;
- for (var i = 0; i < updates.length; i++) {
- this.handle(updates[i]);
- }
- },
-});
-
-function LiveDictStore(type) {
- DictStore.call(this);
- LiveStoreMixin.call(this, type);
-}
-_.extend(LiveDictStore.prototype, DictStore.prototype, LiveStoreMixin.prototype);
-
-
-export function SettingsStore() {
- return new LiveDictStore(ActionTypes.SETTINGS_STORE);
-} \ No newline at end of file
diff --git a/web/src/js/store/view.js b/web/src/js/store/view.js
deleted file mode 100644
index e69de29b..00000000
--- a/web/src/js/store/view.js
+++ /dev/null
diff --git a/web/src/js/utils.js b/web/src/js/utils.js
index 2e5c3005..2e25016e 100644
--- a/web/src/js/utils.js
+++ b/web/src/js/utils.js
@@ -109,7 +109,19 @@ export function fetchApi(url, options) {
url += "&" + xsrf;
}
return fetch(url, {
- ...options,
- credentials: 'same-origin'
+ credentials: 'same-origin',
+ ...options
});
-} \ No newline at end of file
+}
+
+fetchApi.put = (url, json, options) => fetchApi(
+ url,
+ {
+ method: "PUT",
+ headers: {
+ 'Content-Type': 'application/json'
+ },
+ body: JSON.stringify(json),
+ ...options
+ }
+)