diff options
-rw-r--r-- | mitmproxy/cmdline.py | 13 | ||||
-rw-r--r-- | mitmproxy/contentviews.py | 19 | ||||
-rw-r--r-- | mitmproxy/web/static/app.js | 28 | ||||
-rw-r--r-- | test/mitmproxy/test_cmdline.py | 12 | ||||
-rw-r--r-- | test/mitmproxy/test_contentview.py | 54 | ||||
-rw-r--r-- | test/mitmproxy/test_custom_contentview.py | 2 | ||||
-rw-r--r-- | tox.ini | 2 | ||||
-rw-r--r-- | web/src/js/actions.js | 23 | ||||
-rw-r--r-- | web/src/js/components/Footer.jsx | 9 | ||||
-rw-r--r-- | web/src/js/components/Header.jsx | 9 | ||||
-rw-r--r-- | web/src/js/components/Header/FlowMenu.jsx | 10 | ||||
-rw-r--r-- | web/src/js/components/Header/MainMenu.jsx | 39 | ||||
-rw-r--r-- | web/src/js/components/Header/OptionMenu.jsx | 33 | ||||
-rw-r--r-- | web/src/js/components/ProxyApp.jsx | 7 | ||||
-rw-r--r-- | web/src/js/components/common/Button.jsx | 6 | ||||
-rw-r--r-- | web/src/js/ducks/settings.js | 20 |
16 files changed, 142 insertions, 144 deletions
diff --git a/mitmproxy/cmdline.py b/mitmproxy/cmdline.py index 77cdb8ca..d46051a2 100644 --- a/mitmproxy/cmdline.py +++ b/mitmproxy/cmdline.py @@ -9,6 +9,7 @@ import configargparse from mitmproxy import filt from mitmproxy.proxy import config from netlib import human +from netlib import strutils from netlib import tcp from netlib import version from netlib.http import url @@ -73,7 +74,7 @@ def parse_replace_hook(s): try: re.compile(regex) except re.error as e: - raise ParseException("Malformed replacement regex: %s" % str(e.message)) + raise ParseException("Malformed replacement regex: %s" % str(e)) return patt, regex, replacement @@ -109,7 +110,7 @@ def parse_setheader(s): def parse_server_spec(spec): try: p = url.parse(spec) - if p[0] not in ("http", "https"): + if p[0] not in (b"http", b"https"): raise ValueError() except ValueError: raise configargparse.ArgumentTypeError( @@ -127,7 +128,7 @@ def parse_upstream_auth(auth): raise configargparse.ArgumentTypeError( "Invalid upstream auth specification: %s" % auth ) - return "Basic" + " " + base64.b64encode(auth) + return b"Basic" + b" " + base64.b64encode(strutils.always_bytes(auth)) def get_common_options(options): @@ -147,13 +148,13 @@ def get_common_options(options): try: p = parse_replace_hook(i) except ParseException as e: - raise configargparse.ArgumentTypeError(e.message) + raise configargparse.ArgumentTypeError(e) reps.append(p) for i in options.replace_file: try: patt, rex, path = parse_replace_hook(i) except ParseException as e: - raise configargparse.ArgumentTypeError(e.message) + raise configargparse.ArgumentTypeError(e) try: v = open(path, "rb").read() except IOError as e: @@ -167,7 +168,7 @@ def get_common_options(options): try: p = parse_setheader(i) except ParseException as e: - raise configargparse.ArgumentTypeError(e.message) + raise configargparse.ArgumentTypeError(e) setheaders.append(p) if options.outfile and options.outfile[0] == options.rfile: diff --git a/mitmproxy/contentviews.py b/mitmproxy/contentviews.py index 90dafca0..7c9e4ba1 100644 --- a/mitmproxy/contentviews.py +++ b/mitmproxy/contentviews.py @@ -26,7 +26,7 @@ import lxml.html import six from PIL import ExifTags from PIL import Image -from six.moves import cStringIO as StringIO +from six import BytesIO from mitmproxy import exceptions from mitmproxy.contrib import jsbeautifier @@ -64,7 +64,7 @@ KEY_MAX = 30 def pretty_json(s): # type: (bytes) -> bytes try: - p = json.loads(s) + p = json.loads(s.decode('utf-8')) except ValueError: return None pretty = json.dumps(p, sort_keys=True, indent=4, ensure_ascii=False) @@ -143,11 +143,11 @@ class ViewAuto(View): ct = "%s/%s" % (ct[0], ct[1]) if ct in content_types_map: return content_types_map[ct][0](data, **metadata) - elif strutils.isXML(data): + elif strutils.isXML(data.decode()): return get("XML")(data, **metadata) if metadata.get("query"): return get("Query")(data, **metadata) - if data and strutils.isMostlyBin(data): + if data and strutils.isMostlyBin(data.decode()): return get("Hex")(data) if not data: return "No content", [] @@ -209,7 +209,7 @@ class ViewXML(View): p = p.getprevious() doctype = docinfo.doctype if prev: - doctype += "\n".join(prev).strip() + doctype += "\n".join(p.decode() for p in prev).strip() doctype = doctype.strip() s = lxml.etree.tostring( @@ -240,7 +240,7 @@ class ViewHTML(View): content_types = ["text/html"] def __call__(self, data, **metadata): - if strutils.isXML(data): + if strutils.isXML(data.decode()): parser = lxml.etree.HTMLParser( strip_cdata=True, remove_blank_text=True @@ -323,7 +323,10 @@ if pyamf: prompt = ("amf", "f") content_types = ["application/x-amf"] - def unpack(self, b, seen=set([])): + def unpack(self, b, seen=None): + if seen is None: + seen = set([]) + if hasattr(b, "body"): return self.unpack(b.body, seen) if isinstance(b, DummyObject): @@ -416,7 +419,7 @@ class ViewImage(View): def __call__(self, data, **metadata): try: - img = Image.open(StringIO(data)) + img = Image.open(BytesIO(data)) except IOError: return None parts = [ diff --git a/mitmproxy/web/static/app.js b/mitmproxy/web/static/app.js index 387062d8..15516839 100644 --- a/mitmproxy/web/static/app.js +++ b/mitmproxy/web/static/app.js @@ -1,5 +1,5 @@ (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){ -"use strict";function _interopRequireDefault(e){return e&&e.__esModule?e:{"default":e}}Object.defineProperty(exports,"__esModule",{value:!0}),exports.Query=exports.FlowActions=exports.SettingsActions=exports.ConnectionActions=exports.StoreCmds=exports.ActionTypes=void 0;var _jquery=require("jquery"),_jquery2=_interopRequireDefault(_jquery),_dispatcher=require("./dispatcher.js"),_utils=require("./utils.js"),ActionTypes=exports.ActionTypes={CONNECTION_OPEN:"connection_open",CONNECTION_CLOSE:"connection_close",CONNECTION_ERROR:"connection_error",SETTINGS_STORE:"settings",EVENT_STORE:"events",FLOW_STORE:"flows"},StoreCmds=exports.StoreCmds={ADD:"add",UPDATE:"update",REMOVE:"remove",RESET:"reset"},ConnectionActions=exports.ConnectionActions={open:function(){_dispatcher.AppDispatcher.dispatchViewAction({type:ActionTypes.CONNECTION_OPEN})},close:function(){_dispatcher.AppDispatcher.dispatchViewAction({type:ActionTypes.CONNECTION_CLOSE})},error:function(){_dispatcher.AppDispatcher.dispatchViewAction({type:ActionTypes.CONNECTION_ERROR})}},SettingsActions=exports.SettingsActions={update:function(e){_jquery2["default"].ajax({type:"PUT",url:"/settings",contentType:"application/json",data:JSON.stringify(e)})}},FlowActions=exports.FlowActions={accept:function(e){_jquery2["default"].post("/flows/"+e.id+"/accept")},accept_all:function(){_jquery2["default"].post("/flows/accept")},"delete":function(e){_jquery2["default"].ajax({type:"DELETE",url:"/flows/"+e.id})},duplicate:function(e){_jquery2["default"].post("/flows/"+e.id+"/duplicate")},replay:function(e){_jquery2["default"].post("/flows/"+e.id+"/replay")},revert:function(e){_jquery2["default"].post("/flows/"+e.id+"/revert")},update:function(e,t){_jquery2["default"].ajax({type:"PUT",url:"/flows/"+e.id,contentType:"application/json",data:JSON.stringify(t)})},clear:function(){_jquery2["default"].post("/clear")},download:function(){return window.location="/flows/dump"},upload:function(e){var t=new FormData;t.append("file",e),(0,_utils.fetchApi)("/flows/dump",{method:"post",body:t})}},Query=exports.Query={SEARCH:"s",HIGHLIGHT:"h",SHOW_EVENTLOG:"e"}; +"use strict";function _interopRequireDefault(e){return e&&e.__esModule?e:{"default":e}}Object.defineProperty(exports,"__esModule",{value:!0}),exports.Query=exports.FlowActions=exports.ConnectionActions=exports.StoreCmds=exports.ActionTypes=void 0;var _jquery=require("jquery"),_jquery2=_interopRequireDefault(_jquery),_dispatcher=require("./dispatcher.js"),_utils=require("./utils.js"),ActionTypes=exports.ActionTypes={CONNECTION_OPEN:"connection_open",CONNECTION_CLOSE:"connection_close",CONNECTION_ERROR:"connection_error",SETTINGS_STORE:"settings",EVENT_STORE:"events",FLOW_STORE:"flows"},StoreCmds=exports.StoreCmds={ADD:"add",UPDATE:"update",REMOVE:"remove",RESET:"reset"},ConnectionActions=exports.ConnectionActions={open:function(){_dispatcher.AppDispatcher.dispatchViewAction({type:ActionTypes.CONNECTION_OPEN})},close:function(){_dispatcher.AppDispatcher.dispatchViewAction({type:ActionTypes.CONNECTION_CLOSE})},error:function(){_dispatcher.AppDispatcher.dispatchViewAction({type:ActionTypes.CONNECTION_ERROR})}},FlowActions=exports.FlowActions={accept:function(e){_jquery2["default"].post("/flows/"+e.id+"/accept")},accept_all:function(){_jquery2["default"].post("/flows/accept")},"delete":function(e){_jquery2["default"].ajax({type:"DELETE",url:"/flows/"+e.id})},duplicate:function(e){_jquery2["default"].post("/flows/"+e.id+"/duplicate")},replay:function(e){_jquery2["default"].post("/flows/"+e.id+"/replay")},revert:function(e){_jquery2["default"].post("/flows/"+e.id+"/revert")},update:function(e,t){_jquery2["default"].ajax({type:"PUT",url:"/flows/"+e.id,contentType:"application/json",data:JSON.stringify(t)})},clear:function(){_jquery2["default"].post("/clear")},download:function(){return window.location="/flows/dump"},upload:function(e){var t=new FormData;t.append("file",e),(0,_utils.fetchApi)("/flows/dump",{method:"post",body:t})}},Query=exports.Query={SEARCH:"s",HIGHLIGHT:"h",SHOW_EVENTLOG:"e"}; },{"./dispatcher.js":41,"./utils.js":52,"jquery":"jquery"}],2:[function(require,module,exports){ "use strict";function _interopRequireDefault(e){return e&&e.__esModule?e:{"default":e}}var _react=require("react"),_react2=_interopRequireDefault(_react),_reactDom=require("react-dom"),_redux=require("redux"),_reactRedux=require("react-redux"),_reduxLogger=require("redux-logger"),_reduxLogger2=_interopRequireDefault(_reduxLogger),_reduxThunk=require("redux-thunk"),_reduxThunk2=_interopRequireDefault(_reduxThunk),_reactRouter=require("react-router"),_connection=require("./connection"),_connection2=_interopRequireDefault(_connection),_ProxyApp=require("./components/ProxyApp"),_ProxyApp2=_interopRequireDefault(_ProxyApp),_MainView=require("./components/MainView"),_MainView2=_interopRequireDefault(_MainView),_index=require("./ducks/index"),_index2=_interopRequireDefault(_index),_eventLog=require("./ducks/eventLog"),store=(0,_redux.createStore)(_index2["default"],(0,_redux.applyMiddleware)(_reduxThunk2["default"],(0,_reduxLogger2["default"])()));window.addEventListener("error",function(e){store.dispatch((0,_eventLog.addLogEntry)(e))}),document.addEventListener("DOMContentLoaded",function(){window.ws=new _connection2["default"]("/updates",store.dispatch),(0,_reactDom.render)(_react2["default"].createElement(_reactRedux.Provider,{store:store},_react2["default"].createElement(_reactRouter.Router,{history:_reactRouter.hashHistory},_react2["default"].createElement(_reactRouter.Redirect,{from:"/",to:"/flows"}),_react2["default"].createElement(_reactRouter.Route,{path:"/",component:_ProxyApp2["default"]},_react2["default"].createElement(_reactRouter.Route,{path:"flows",component:_MainView2["default"]}),_react2["default"].createElement(_reactRouter.Route,{path:"flows/:flowId/:detailTab",component:_MainView2["default"]})))),document.getElementById("mitmproxy"))}); @@ -53,10 +53,10 @@ "use strict";function _interopRequireDefault(e){return e&&e.__esModule?e:{"default":e}}function NavAction(e){var t=e.icon,a=e.title,c=e.onClick;return _react2["default"].createElement("a",{title:a,href:"#",className:"nav-action",onClick:function(e){e.preventDefault(),c(e)}},_react2["default"].createElement("i",{className:"fa fa-fw "+t}))}function Nav(e){var t=e.flow,a=e.active,c=e.tabs,r=e.onSelectTab;return _react2["default"].createElement("nav",{className:"nav-tabs nav-tabs-sm"},c.map(function(e){return _react2["default"].createElement("a",{key:e,href:"#",className:(0,_classnames2["default"])({active:a===e}),onClick:function(t){t.preventDefault(),r(e)}},_.capitalize(e))}),_react2["default"].createElement(NavAction,{title:"[d]elete flow",icon:"fa-trash",onClick:function(){return _actions.FlowActions["delete"](t)}}),_react2["default"].createElement(NavAction,{title:"[D]uplicate flow",icon:"fa-copy",onClick:function(){return _actions.FlowActions.duplicate(t)}}),_react2["default"].createElement(NavAction,{disabled:!0,title:"[r]eplay flow",icon:"fa-repeat",onClick:function(){return _actions.FlowActions.replay(t)}}),t.intercepted&&_react2["default"].createElement(NavAction,{title:"[a]ccept intercepted flow",icon:"fa-play",onClick:function(){return _actions.FlowActions.accept(t)}}),t.modified&&_react2["default"].createElement(NavAction,{title:"revert changes to flow [V]",icon:"fa-history",onClick:function(){return _actions.FlowActions.revert(t)}}))}Object.defineProperty(exports,"__esModule",{value:!0}),exports["default"]=Nav;var _react=require("react"),_react2=_interopRequireDefault(_react),_classnames=require("classnames"),_classnames2=_interopRequireDefault(_classnames),_actions=require("../../actions.js");NavAction.propTypes={icon:_react.PropTypes.string.isRequired,title:_react.PropTypes.string.isRequired,onClick:_react.PropTypes.func.isRequired},Nav.propTypes={flow:_react.PropTypes.object.isRequired,active:_react.PropTypes.string.isRequired,tabs:_react.PropTypes.array.isRequired,onSelectTab:_react.PropTypes.func.isRequired}; },{"../../actions.js":1,"classnames":"classnames","react":"react"}],19:[function(require,module,exports){ -"use strict";function _interopRequireDefault(e){return e&&e.__esModule?e:{"default":e}}function Footer(e){var a=e.settings;return _react2["default"].createElement("footer",null,a.mode&&"regular"!=a.mode&&_react2["default"].createElement("span",{className:"label label-success"},a.mode," mode"),a.intercept&&_react2["default"].createElement("span",{className:"label label-success"},"Intercept: ",a.intercept),a.showhost&&_react2["default"].createElement("span",{className:"label label-success"},"showhost"),a.no_upstream_cert&&_react2["default"].createElement("span",{className:"label label-success"},"no-upstream-cert"),a.rawtcp&&_react2["default"].createElement("span",{className:"label label-success"},"raw-tcp"),!a.http2&&_react2["default"].createElement("span",{className:"label label-success"},"no-http2"),a.anticache&&_react2["default"].createElement("span",{className:"label label-success"},"anticache"),a.anticomp&&_react2["default"].createElement("span",{className:"label label-success"},"anticomp"),a.stickyauth&&_react2["default"].createElement("span",{className:"label label-success"},"stickyauth: ",a.stickyauth),a.stickycookie&&_react2["default"].createElement("span",{className:"label label-success"},"stickycookie: ",a.stickycookie),a.stream&&_react2["default"].createElement("span",{className:"label label-success"},"stream: ",(0,_utils.formatSize)(a.stream)))}Object.defineProperty(exports,"__esModule",{value:!0}),exports["default"]=Footer;var _react=require("react"),_react2=_interopRequireDefault(_react),_utils=require("../utils.js");Footer.propTypes={settings:_react2["default"].PropTypes.object.isRequired}; +"use strict";function _interopRequireDefault(e){return e&&e.__esModule?e:{"default":e}}function Footer(e){var t=e.settings;return _react2["default"].createElement("footer",null,t.mode&&"regular"!=t.mode&&_react2["default"].createElement("span",{className:"label label-success"},t.mode," mode"),t.intercept&&_react2["default"].createElement("span",{className:"label label-success"},"Intercept: ",t.intercept),t.showhost&&_react2["default"].createElement("span",{className:"label label-success"},"showhost"),t.no_upstream_cert&&_react2["default"].createElement("span",{className:"label label-success"},"no-upstream-cert"),t.rawtcp&&_react2["default"].createElement("span",{className:"label label-success"},"raw-tcp"),!t.http2&&_react2["default"].createElement("span",{className:"label label-success"},"no-http2"),t.anticache&&_react2["default"].createElement("span",{className:"label label-success"},"anticache"),t.anticomp&&_react2["default"].createElement("span",{className:"label label-success"},"anticomp"),t.stickyauth&&_react2["default"].createElement("span",{className:"label label-success"},"stickyauth: ",t.stickyauth),t.stickycookie&&_react2["default"].createElement("span",{className:"label label-success"},"stickycookie: ",t.stickycookie),t.stream&&_react2["default"].createElement("span",{className:"label label-success"},"stream: ",(0,_utils.formatSize)(t.stream)))}Object.defineProperty(exports,"__esModule",{value:!0});var _react=require("react"),_react2=_interopRequireDefault(_react),_reactRedux=require("react-redux"),_utils=require("../utils.js");Footer.propTypes={settings:_react2["default"].PropTypes.object.isRequired},exports["default"]=(0,_reactRedux.connect)(function(e){return{settings:e.settings.settings}})(Footer); -},{"../utils.js":52,"react":"react"}],20:[function(require,module,exports){ -"use strict";function _interopRequireDefault(e){return e&&e.__esModule?e:{"default":e}}function _toConsumableArray(e){if(Array.isArray(e)){for(var t=0,r=Array(e.length);t<e.length;t++)r[t]=e[t];return r}return Array.from(e)}function _classCallCheck(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function _possibleConstructorReturn(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function _inherits(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}Object.defineProperty(exports,"__esModule",{value:!0});var _createClass=function(){function e(e,t){for(var r=0;r<t.length;r++){var n=t[r];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(e,n.key,n)}}return function(t,r,n){return r&&e(t.prototype,r),n&&e(t,n),t}}(),_react=require("react"),_react2=_interopRequireDefault(_react),_reactRedux=require("react-redux"),_classnames=require("classnames"),_classnames2=_interopRequireDefault(_classnames),_eventLog=require("../ducks/eventLog"),_MainMenu=require("./Header/MainMenu"),_MainMenu2=_interopRequireDefault(_MainMenu),_ViewMenu=require("./Header/ViewMenu"),_ViewMenu2=_interopRequireDefault(_ViewMenu),_OptionMenu=require("./Header/OptionMenu"),_OptionMenu2=_interopRequireDefault(_OptionMenu),_FileMenu=require("./Header/FileMenu"),_FileMenu2=_interopRequireDefault(_FileMenu),_FlowMenu=require("./Header/FlowMenu"),_FlowMenu2=_interopRequireDefault(_FlowMenu),_ui=require("../ducks/ui.js"),Header=function(e){function t(){return _classCallCheck(this,t),_possibleConstructorReturn(this,Object.getPrototypeOf(t).apply(this,arguments))}return _inherits(t,e),_createClass(t,[{key:"handleClick",value:function(e,t){t.preventDefault(),this.props.setActiveMenu(e.title)}},{key:"render",value:function(){var e=this,r=this.props,n=r.settings,u=r.updateLocation,a=r.query,i=r.selectedFlow,o=r.activeMenu,l=[].concat(_toConsumableArray(t.entries));i&&l.push(_FlowMenu2["default"]);var c=_.find(l,function(e){return e.title==o});return _react2["default"].createElement("header",null,_react2["default"].createElement("nav",{className:"nav-tabs nav-tabs-lg"},_react2["default"].createElement(_FileMenu2["default"],null),l.map(function(t){return _react2["default"].createElement("a",{key:t.title,href:"#",className:(0,_classnames2["default"])({active:t===c}),onClick:function(r){return e.handleClick(t,r)}},t.title)})),_react2["default"].createElement("div",{className:"menu"},_react2["default"].createElement(c,{settings:n,updateLocation:u,query:a})))}}]),t}(_react.Component);Header.entries=[_MainMenu2["default"],_ViewMenu2["default"],_OptionMenu2["default"]],Header.propTypes={settings:_react.PropTypes.object.isRequired},exports["default"]=(0,_reactRedux.connect)(function(e){return{selectedFlow:e.flows.selected[0],activeMenu:e.ui.activeMenu}},{setActiveMenu:_ui.setActiveMenu})(Header); +},{"../utils.js":52,"react":"react","react-redux":"react-redux"}],20:[function(require,module,exports){ +"use strict";function _interopRequireDefault(e){return e&&e.__esModule?e:{"default":e}}function _toConsumableArray(e){if(Array.isArray(e)){for(var t=0,r=Array(e.length);t<e.length;t++)r[t]=e[t];return r}return Array.from(e)}function _classCallCheck(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function _possibleConstructorReturn(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function _inherits(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}Object.defineProperty(exports,"__esModule",{value:!0});var _createClass=function(){function e(e,t){for(var r=0;r<t.length;r++){var n=t[r];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(e,n.key,n)}}return function(t,r,n){return r&&e(t.prototype,r),n&&e(t,n),t}}(),_react=require("react"),_react2=_interopRequireDefault(_react),_reactRedux=require("react-redux"),_classnames=require("classnames"),_classnames2=_interopRequireDefault(_classnames),_eventLog=require("../ducks/eventLog"),_MainMenu=require("./Header/MainMenu"),_MainMenu2=_interopRequireDefault(_MainMenu),_ViewMenu=require("./Header/ViewMenu"),_ViewMenu2=_interopRequireDefault(_ViewMenu),_OptionMenu=require("./Header/OptionMenu"),_OptionMenu2=_interopRequireDefault(_OptionMenu),_FileMenu=require("./Header/FileMenu"),_FileMenu2=_interopRequireDefault(_FileMenu),_FlowMenu=require("./Header/FlowMenu"),_FlowMenu2=_interopRequireDefault(_FlowMenu),_ui=require("../ducks/ui.js"),Header=function(e){function t(){return _classCallCheck(this,t),_possibleConstructorReturn(this,Object.getPrototypeOf(t).apply(this,arguments))}return _inherits(t,e),_createClass(t,[{key:"handleClick",value:function(e,t){t.preventDefault(),this.props.setActiveMenu(e.title)}},{key:"render",value:function(){var e=this,r=this.props,n=r.updateLocation,u=r.query,a=r.selectedFlow,i=r.activeMenu,l=[].concat(_toConsumableArray(t.entries));a&&l.push(_FlowMenu2["default"]);var o=_.find(l,function(e){return e.title==i});return _react2["default"].createElement("header",null,_react2["default"].createElement("nav",{className:"nav-tabs nav-tabs-lg"},_react2["default"].createElement(_FileMenu2["default"],null),l.map(function(t){return _react2["default"].createElement("a",{key:t.title,href:"#",className:(0,_classnames2["default"])({active:t===o}),onClick:function(r){return e.handleClick(t,r)}},t.title)})),_react2["default"].createElement("div",{className:"menu"},_react2["default"].createElement(o,{updateLocation:n,query:u})))}}]),t}(_react.Component);Header.entries=[_MainMenu2["default"],_ViewMenu2["default"],_OptionMenu2["default"]],exports["default"]=(0,_reactRedux.connect)(function(e){return{selectedFlow:e.flows.selected[0],activeMenu:e.ui.activeMenu}},{setActiveMenu:_ui.setActiveMenu})(Header); },{"../ducks/eventLog":42,"../ducks/ui.js":46,"./Header/FileMenu":21,"./Header/FlowMenu":24,"./Header/MainMenu":25,"./Header/OptionMenu":26,"./Header/ViewMenu":27,"classnames":"classnames","react":"react","react-redux":"react-redux"}],21:[function(require,module,exports){ "use strict";function _interopRequireDefault(e){return e&&e.__esModule?e:{"default":e}}function _classCallCheck(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function _possibleConstructorReturn(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function _inherits(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}Object.defineProperty(exports,"__esModule",{value:!0});var _createClass=function(){function e(e,t){for(var n=0;n<t.length;n++){var a=t[n];a.enumerable=a.enumerable||!1,a.configurable=!0,"value"in a&&(a.writable=!0),Object.defineProperty(e,a.key,a)}}return function(t,n,a){return n&&e(t.prototype,n),a&&e(t,a),t}}(),_react=require("react"),_react2=_interopRequireDefault(_react),_classnames=require("classnames"),_classnames2=_interopRequireDefault(_classnames),_actions=require("../../actions.js"),FileMenu=function(e){function t(e,n){_classCallCheck(this,t);var a=_possibleConstructorReturn(this,Object.getPrototypeOf(t).call(this,e,n));return a.state={show:!1},a.close=a.close.bind(a),a.onFileClick=a.onFileClick.bind(a),a.onNewClick=a.onNewClick.bind(a),a.onOpenClick=a.onOpenClick.bind(a),a.onOpenFile=a.onOpenFile.bind(a),a.onSaveClick=a.onSaveClick.bind(a),a}return _inherits(t,e),_createClass(t,[{key:"close",value:function(){this.setState({show:!1}),document.removeEventListener("click",this.close)}},{key:"onFileClick",value:function(e){e.preventDefault(),this.state.show||(document.addEventListener("click",this.close),this.setState({show:!0}))}},{key:"onNewClick",value:function(e){e.preventDefault(),confirm("Delete all flows?")&&_actions.FlowActions.clear()}},{key:"onOpenClick",value:function(e){e.preventDefault(),this.fileInput.click()}},{key:"onOpenFile",value:function(e){e.preventDefault(),e.target.files.length>0&&(_actions.FlowActions.upload(e.target.files[0]),this.fileInput.value="")}},{key:"onSaveClick",value:function(e){e.preventDefault(),_actions.FlowActions.download()}},{key:"render",value:function(){var e=this;return _react2["default"].createElement("div",{className:(0,_classnames2["default"])("dropdown pull-left",{open:this.state.show})},_react2["default"].createElement("a",{href:"#",className:"special",onClick:this.onFileClick},"mitmproxy"),_react2["default"].createElement("ul",{className:"dropdown-menu",role:"menu"},_react2["default"].createElement("li",null,_react2["default"].createElement("a",{href:"#",onClick:this.onNewClick},_react2["default"].createElement("i",{className:"fa fa-fw fa-file"}),"New")),_react2["default"].createElement("li",null,_react2["default"].createElement("a",{href:"#",onClick:this.onOpenClick},_react2["default"].createElement("i",{className:"fa fa-fw fa-folder-open"}),"Open..."),_react2["default"].createElement("input",{ref:function(t){return e.fileInput=t},className:"hidden",type:"file",onChange:this.onOpenFile})),_react2["default"].createElement("li",null,_react2["default"].createElement("a",{href:"#",onClick:this.onSaveClick},_react2["default"].createElement("i",{className:"fa fa-fw fa-floppy-o"}),"Save...")),_react2["default"].createElement("li",{role:"presentation",className:"divider"}),_react2["default"].createElement("li",null,_react2["default"].createElement("a",{href:"http://mitm.it/",target:"_blank"},_react2["default"].createElement("i",{className:"fa fa-fw fa-external-link"}),"Install Certificates..."))))}}]),t}(_react.Component);exports["default"]=FileMenu; @@ -71,12 +71,12 @@ "use strict";function _interopRequireDefault(e){return e&&e.__esModule?e:{"default":e}}function FlowMenu(e){var t=e.flow;return _react2["default"].createElement("div",null,_react2["default"].createElement("div",{className:"menu-row"},_react2["default"].createElement(_Button2["default"],{disabled:!0,title:"[r]eplay flow",text:"Replay",icon:"fa-repeat",onClick:_actions.FlowActions.replay.bind(null,t)}),_react2["default"].createElement(_Button2["default"],{title:"[D]uplicate flow",text:"Duplicate",icon:"fa-copy",onClick:_actions.FlowActions.duplicate.bind(null,t)}),_react2["default"].createElement(_Button2["default"],{title:"[d]elete flow",text:"Delete",icon:"fa-trash",onClick:_actions.FlowActions["delete"].bind(null,t)}),_react2["default"].createElement(_Button2["default"],{title:"download",text:"Download",icon:"fa-download",onClick:function(){return window.location=_utils.MessageUtils.getContentURL(t,t.response)}})),_react2["default"].createElement("div",{className:"clearfix"}))}Object.defineProperty(exports,"__esModule",{value:!0});var _react=require("react"),_react2=_interopRequireDefault(_react),_Button=require("../common/Button"),_Button2=_interopRequireDefault(_Button),_actions=require("../../actions.js"),_utils=require("../../flow/utils.js"),_reactRedux=require("react-redux");FlowMenu.title="Flow",FlowMenu.propTypes={flow:_react.PropTypes.object.isRequired},exports["default"]=(0,_reactRedux.connect)(function(e){return{flow:e.flows.all.byId[e.flows.selected[0]]}})(FlowMenu); },{"../../actions.js":1,"../../flow/utils.js":51,"../common/Button":34,"react":"react","react-redux":"react-redux"}],25:[function(require,module,exports){ -"use strict";function _interopRequireDefault(e){return e&&e.__esModule?e:{"default":e}}function _defineProperty(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function _classCallCheck(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function _possibleConstructorReturn(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function _inherits(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}Object.defineProperty(exports,"__esModule",{value:!0});var _createClass=function(){function e(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(t,n,r){return n&&e(t.prototype,n),r&&e(t,r),t}}(),_react=require("react"),_react2=_interopRequireDefault(_react),_actions=require("../../actions.js"),_FilterInput=require("./FilterInput"),_FilterInput2=_interopRequireDefault(_FilterInput),MainMenu=function(e){function t(e,n){_classCallCheck(this,t);var r=_possibleConstructorReturn(this,Object.getPrototypeOf(t).call(this,e,n));return r.onSearchChange=r.onSearchChange.bind(r),r.onHighlightChange=r.onHighlightChange.bind(r),r.onInterceptChange=r.onInterceptChange.bind(r),r}return _inherits(t,e),_createClass(t,[{key:"onSearchChange",value:function(e){this.props.updateLocation(void 0,_defineProperty({},_actions.Query.SEARCH,e))}},{key:"onHighlightChange",value:function(e){this.props.updateLocation(void 0,_defineProperty({},_actions.Query.HIGHLIGHT,e))}},{key:"onInterceptChange",value:function(e){_actions.SettingsActions.update({intercept:e})}},{key:"render",value:function(){var e=this.props,t=e.query,n=e.settings,r=t[_actions.Query.SEARCH]||"",a=t[_actions.Query.HIGHLIGHT]||"",o=n.intercept||"";return _react2["default"].createElement("div",null,_react2["default"].createElement("div",{className:"menu-row"},_react2["default"].createElement(_FilterInput2["default"],{ref:"search",placeholder:"Search",type:"search",color:"black",value:r,onChange:this.onSearchChange}),_react2["default"].createElement(_FilterInput2["default"],{ref:"highlight",placeholder:"Highlight",type:"tag",color:"hsl(48, 100%, 50%)",value:a,onChange:this.onHighlightChange}),_react2["default"].createElement(_FilterInput2["default"],{ref:"intercept",placeholder:"Intercept",type:"pause",color:"hsl(208, 56%, 53%)",value:o,onChange:this.onInterceptChange})),_react2["default"].createElement("div",{className:"clearfix"}))}}]),t}(_react.Component);MainMenu.title="Start",MainMenu.route="flows",MainMenu.propTypes={settings:_react2["default"].PropTypes.object.isRequired},exports["default"]=MainMenu; +"use strict";function _interopRequireDefault(e){return e&&e.__esModule?e:{"default":e}}function _defineProperty(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function _classCallCheck(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function _possibleConstructorReturn(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function _inherits(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}Object.defineProperty(exports,"__esModule",{value:!0});var _createClass=function(){function e(e,t){for(var r=0;r<t.length;r++){var n=t[r];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(e,n.key,n)}}return function(t,r,n){return r&&e(t.prototype,r),n&&e(t,n),t}}(),_react=require("react"),_react2=_interopRequireDefault(_react),_reactRedux=require("react-redux"),_FilterInput=require("./FilterInput"),_FilterInput2=_interopRequireDefault(_FilterInput),_actions=require("../../actions.js"),_settings=require("../../ducks/settings"),MainMenu=function(e){function t(e,r){_classCallCheck(this,t);var n=_possibleConstructorReturn(this,Object.getPrototypeOf(t).call(this,e,r));return n.onSearchChange=n.onSearchChange.bind(n),n.onHighlightChange=n.onHighlightChange.bind(n),n}return _inherits(t,e),_createClass(t,[{key:"onSearchChange",value:function(e){this.props.updateLocation(void 0,_defineProperty({},_actions.Query.SEARCH,e))}},{key:"onHighlightChange",value:function(e){this.props.updateLocation(void 0,_defineProperty({},_actions.Query.HIGHLIGHT,e))}},{key:"render",value:function(){var e=this.props,t=e.query,r=e.settings,n=e.onSettingsChange;return _react2["default"].createElement("div",null,_react2["default"].createElement("div",{className:"menu-row"},_react2["default"].createElement(_FilterInput2["default"],{ref:"search",placeholder:"Search",type:"search",color:"black",value:t[_actions.Query.SEARCH]||"",onChange:this.onSearchChange}),_react2["default"].createElement(_FilterInput2["default"],{ref:"highlight",placeholder:"Highlight",type:"tag",color:"hsl(48, 100%, 50%)",value:t[_actions.Query.HIGHLIGHT]||"",onChange:this.onHighlightChange}),_react2["default"].createElement(_FilterInput2["default"],{ref:"intercept",placeholder:"Intercept",type:"pause",color:"hsl(208, 56%, 53%)",value:r.intercept||"",onChange:function(e){return n({intercept:e})}})),_react2["default"].createElement("div",{className:"clearfix"}))}}]),t}(_react.Component);MainMenu.title="Start",MainMenu.route="flows",MainMenu.propTypes={query:_react.PropTypes.object.isRequired,settings:_react.PropTypes.object.isRequired,updateLocation:_react.PropTypes.func.isRequired,onSettingsChange:_react.PropTypes.func.isRequired},exports["default"]=(0,_reactRedux.connect)(function(e){return{settings:e.settings.settings}},{onSettingsChange:_settings.updateSettings})(MainMenu); -},{"../../actions.js":1,"./FilterInput":23,"react":"react"}],26:[function(require,module,exports){ -"use strict";function _interopRequireDefault(t){return t&&t.__esModule?t:{"default":t}}function OptionMenu(t){var e=t.settings;return _react2["default"].createElement("div",null,_react2["default"].createElement("div",{className:"menu-row"},_react2["default"].createElement(_ToggleButton2["default"],{text:"showhost",checked:e.showhost,onToggle:function(){return _actions.SettingsActions.update({showhost:!e.showhost})}}),_react2["default"].createElement(_ToggleButton2["default"],{text:"no_upstream_cert",checked:e.no_upstream_cert,onToggle:function(){return _actions.SettingsActions.update({no_upstream_cert:!e.no_upstream_cert})}}),_react2["default"].createElement(_ToggleButton2["default"],{text:"rawtcp",checked:e.rawtcp,onToggle:function(){return _actions.SettingsActions.update({rawtcp:!e.rawtcp})}}),_react2["default"].createElement(_ToggleButton2["default"],{text:"http2",checked:e.http2,onToggle:function(){return _actions.SettingsActions.update({http2:!e.http2})}}),_react2["default"].createElement(_ToggleButton2["default"],{text:"anticache",checked:e.anticache,onToggle:function(){return _actions.SettingsActions.update({anticache:!e.anticache})}}),_react2["default"].createElement(_ToggleButton2["default"],{text:"anticomp",checked:e.anticomp,onToggle:function(){return _actions.SettingsActions.update({anticomp:!e.anticomp})}}),_react2["default"].createElement(_ToggleInputButton2["default"],{name:"stickyauth",placeholder:"Sticky auth filter",checked:!!e.stickyauth,txt:e.stickyauth||"",onToggleChanged:function(t){return _actions.SettingsActions.update({stickyauth:e.stickyauth?null:t})}}),_react2["default"].createElement(_ToggleInputButton2["default"],{name:"stickycookie",placeholder:"Sticky cookie filter",checked:!!e.stickycookie,txt:e.stickycookie||"",onToggleChanged:function(t){return _actions.SettingsActions.update({stickycookie:e.stickycookie?null:t})}}),_react2["default"].createElement(_ToggleInputButton2["default"],{name:"stream",placeholder:"stream...",checked:!!e.stream,txt:e.stream||"",inputType:"number",onToggleChanged:function(t){return _actions.SettingsActions.update({stream:e.stream?null:t})}})),_react2["default"].createElement("div",{className:"clearfix"}))}Object.defineProperty(exports,"__esModule",{value:!0}),exports["default"]=OptionMenu;var _react=require("react"),_react2=_interopRequireDefault(_react),_ToggleButton=require("../common/ToggleButton"),_ToggleButton2=_interopRequireDefault(_ToggleButton),_ToggleInputButton=require("../common/ToggleInputButton"),_ToggleInputButton2=_interopRequireDefault(_ToggleInputButton),_actions=require("../../actions.js");OptionMenu.title="Options",OptionMenu.propTypes={settings:_react.PropTypes.object.isRequired}; +},{"../../actions.js":1,"../../ducks/settings":45,"./FilterInput":23,"react":"react","react-redux":"react-redux"}],26:[function(require,module,exports){ +"use strict";function _interopRequireDefault(e){return e&&e.__esModule?e:{"default":e}}function OptionMenu(e){var t=e.settings,n=e.onSettingsChange;return _react2["default"].createElement("div",null,_react2["default"].createElement("div",{className:"menu-row"},_react2["default"].createElement(_ToggleButton2["default"],{text:"showhost",checked:t.showhost,onToggle:function(){return n({showhost:!t.showhost})}}),_react2["default"].createElement(_ToggleButton2["default"],{text:"no_upstream_cert",checked:t.no_upstream_cert,onToggle:function(){return n({no_upstream_cert:!t.no_upstream_cert})}}),_react2["default"].createElement(_ToggleButton2["default"],{text:"rawtcp",checked:t.rawtcp,onToggle:function(){return n({rawtcp:!t.rawtcp})}}),_react2["default"].createElement(_ToggleButton2["default"],{text:"http2",checked:t.http2,onToggle:function(){return n({http2:!t.http2})}}),_react2["default"].createElement(_ToggleButton2["default"],{text:"anticache",checked:t.anticache,onToggle:function(){return n({anticache:!t.anticache})}}),_react2["default"].createElement(_ToggleButton2["default"],{text:"anticomp",checked:t.anticomp,onToggle:function(){return n({anticomp:!t.anticomp})}}),_react2["default"].createElement(_ToggleInputButton2["default"],{name:"stickyauth",placeholder:"Sticky auth filter",checked:!!t.stickyauth,txt:t.stickyauth||"",onToggleChanged:function(e){return n({stickyauth:t.stickyauth?null:e})}}),_react2["default"].createElement(_ToggleInputButton2["default"],{name:"stickycookie",placeholder:"Sticky cookie filter",checked:!!t.stickycookie,txt:t.stickycookie||"",onToggleChanged:function(e){return n({stickycookie:t.stickycookie?null:e})}}),_react2["default"].createElement(_ToggleInputButton2["default"],{name:"stream",placeholder:"stream...",checked:!!t.stream,txt:t.stream||"",inputType:"number",onToggleChanged:function(e){return n({stream:t.stream?null:e})}})),_react2["default"].createElement("div",{className:"clearfix"}))}Object.defineProperty(exports,"__esModule",{value:!0});var _react=require("react"),_react2=_interopRequireDefault(_react),_reactRedux=require("react-redux"),_ToggleButton=require("../common/ToggleButton"),_ToggleButton2=_interopRequireDefault(_ToggleButton),_ToggleInputButton=require("../common/ToggleInputButton"),_ToggleInputButton2=_interopRequireDefault(_ToggleInputButton),_settings=require("../../ducks/settings");OptionMenu.title="Options",OptionMenu.propTypes={settings:_react.PropTypes.object.isRequired,onSettingsChange:_react.PropTypes.func.isRequired},exports["default"]=(0,_reactRedux.connect)(function(e){return{settings:e.settings.settings}},{onSettingsChange:_settings.updateSettings})(OptionMenu); -},{"../../actions.js":1,"../common/ToggleButton":36,"../common/ToggleInputButton":37,"react":"react"}],27:[function(require,module,exports){ +},{"../../ducks/settings":45,"../common/ToggleButton":36,"../common/ToggleInputButton":37,"react":"react","react-redux":"react-redux"}],27:[function(require,module,exports){ "use strict";function _interopRequireDefault(e){return e&&e.__esModule?e:{"default":e}}function ViewMenu(e){var t=e.visible,r=e.onToggle;return _react2["default"].createElement("div",null,_react2["default"].createElement("div",{className:"menu-row"},_react2["default"].createElement(_ToggleButton2["default"],{text:"Show Event Log",checked:t,onToggle:r})),_react2["default"].createElement("div",{className:"clearfix"}))}Object.defineProperty(exports,"__esModule",{value:!0});var _react=require("react"),_react2=_interopRequireDefault(_react),_reactRedux=require("react-redux"),_ToggleButton=require("../common/ToggleButton"),_ToggleButton2=_interopRequireDefault(_ToggleButton),_eventLog=require("../../ducks/eventLog");ViewMenu.title="View",ViewMenu.route="flows",ViewMenu.propTypes={visible:_react.PropTypes.bool.isRequired,onToggle:_react.PropTypes.func.isRequired},exports["default"]=(0,_reactRedux.connect)(function(e){return{visible:e.eventLog.visible}},{onToggle:_eventLog.toggleEventLogVisibility})(ViewMenu); },{"../../ducks/eventLog":42,"../common/ToggleButton":36,"react":"react","react-redux":"react-redux"}],28:[function(require,module,exports){ @@ -86,9 +86,9 @@ "use strict";function _interopRequireDefault(e){return e&&e.__esModule?e:{"default":e}}function Prompt(e,t){function r(e){return _lodash2["default"].map(i,"key").includes(e)}function o(e){e.stopPropagation(),e.preventDefault();var r=i.find(function(t){return _utils.Key[t.key.toUpperCase()]===e.keyCode});(r||e.keyCode===_utils.Key.ESC||e.keyCode===_utils.Key.ENTER)&&(n(k||!1),t.returnFocus())}for(var a=e.prompt,n=e.done,u=e.options,i=[],s=0;s<u.length;s++){var l=u[s];if(_lodash2["default"].isString(l)){for(var p=l;p.length>0&&r(p[0]);)p=p.substr(1);l={text:l,key:p[0]}}if(!l.text||!l.key||r(l.key))throw"invalid options";i.push(l)}return _react2["default"].createElement("div",{tabIndex:"0",onKeyDown:o,onClick:onClick,className:"prompt-dialog"},_react2["default"].createElement("div",{className:"prompt-content"},a||_react2["default"].createElement("strong",null,"Select: "),i.map(function(e){function t(t){n(e.key),t.stopPropagation()}var r=e.text.indexOf(e.key);return _react2["default"].createElement("span",{key:e.key,className:"option",onClick:t},-1!==r?e.text.substring(0,r):e.text+"(",prefix,_react2["default"].createElement("strong",{className:"text-primary"},e.key),-1!==r?e.text.substring(r+1):")")})))}Object.defineProperty(exports,"__esModule",{value:!0}),exports["default"]=Prompt;var _react=require("react"),_react2=_interopRequireDefault(_react),_reactDom=require("react-dom"),_reactDom2=_interopRequireDefault(_reactDom),_lodash=require("lodash"),_lodash2=_interopRequireDefault(_lodash),_utils=require("../utils.js");Prompt.contextTypes={returnFocus:_react.PropTypes.func},Prompt.propTypes={options:_react.PropTypes.array.isRequired,done:_react.PropTypes.func.isRequired,prompt:_react.PropTypes.string}; },{"../utils.js":52,"lodash":"lodash","react":"react","react-dom":"react-dom"}],30:[function(require,module,exports){ -"use strict";function _interopRequireDefault(e){return e&&e.__esModule?e:{"default":e}}function _classCallCheck(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function _possibleConstructorReturn(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function _inherits(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}Object.defineProperty(exports,"__esModule",{value:!0});var _createClass=function(){function e(e,t){for(var r=0;r<t.length;r++){var n=t[r];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(e,n.key,n)}}return function(t,r,n){return r&&e(t.prototype,r),n&&e(t,n),t}}(),_react=require("react"),_react2=_interopRequireDefault(_react),_reactDom=require("react-dom"),_reactDom2=_interopRequireDefault(_reactDom),_lodash=require("lodash"),_lodash2=_interopRequireDefault(_lodash),_reactRedux=require("react-redux"),_settings=require("../ducks/settings"),_Header=require("./Header"),_Header2=_interopRequireDefault(_Header),_EventLog=require("./EventLog"),_EventLog2=_interopRequireDefault(_EventLog),_Footer=require("./Footer"),_Footer2=_interopRequireDefault(_Footer),_utils=require("../utils.js"),ProxyAppMain=function(e){function t(e,r){_classCallCheck(this,t);var n=_possibleConstructorReturn(this,Object.getPrototypeOf(t).call(this,e,r));return n.focus=n.focus.bind(n),n.onKeyDown=n.onKeyDown.bind(n),n.updateLocation=n.updateLocation.bind(n),n}return _inherits(t,e),_createClass(t,[{key:"updateLocation",value:function(e,t){void 0===e&&(e=this.props.location.pathname);var r=this.props.location.query,n=!0,o=!1,i=void 0;try{for(var a,u=Object.keys(t||{})[Symbol.iterator]();!(n=(a=u.next()).done);n=!0){var c=a.value;r[c]=t[c]||void 0}}catch(s){o=!0,i=s}finally{try{!n&&u["return"]&&u["return"]()}finally{if(o)throw i}}this.context.router.replace({pathname:e,query:r})}},{key:"getQuery",value:function(){return _lodash2["default"].clone(this.props.location.query)}},{key:"componentWillMount",value:function(){this.props.fetchSettings()}},{key:"componentDidMount",value:function(){this.focus()}},{key:"getChildContext",value:function(){return{returnFocus:this.focus}}},{key:"focus",value:function(){document.activeElement.blur(),window.getSelection().removeAllRanges(),_reactDom2["default"].findDOMNode(this).focus()}},{key:"onKeyDown",value:function(e){var t=this,r=null;switch(e.keyCode){case _utils.Key.I:r="intercept";break;case _utils.Key.L:r="search";break;case _utils.Key.H:r="highlight";break;default:var n=this.refs.view;return this.refs.view.getWrappedInstance&&(n=this.refs.view.getWrappedInstance()),void(n.onMainKeyDown&&n.onMainKeyDown(e))}r&&!function(){var e=t.refs.header;e.setState({active:_Header2["default"].entries[0]},function(){e.refs.active.refs[r].select()})}(),e.preventDefault()}},{key:"render",value:function(){var e=this.props,t=e.showEventLog,r=e.location,n=e.children,o=e.settings,i=this.getQuery();return _react2["default"].createElement("div",{id:"container",tabIndex:"0",onKeyDown:this.onKeyDown},_react2["default"].createElement(_Header2["default"],{ref:"header",settings:o,updateLocation:this.updateLocation,query:i}),_react2["default"].cloneElement(n,{ref:"view",location:r,query:i,updateLocation:this.updateLocation}),t&&_react2["default"].createElement(_EventLog2["default"],{key:"eventlog"}),_react2["default"].createElement(_Footer2["default"],{settings:o}))}}]),t}(_react.Component);ProxyAppMain.childContextTypes={returnFocus:_react.PropTypes.func.isRequired},ProxyAppMain.contextTypes={router:_react.PropTypes.object.isRequired},exports["default"]=(0,_reactRedux.connect)(function(e){return{showEventLog:e.eventLog.visible,settings:e.settings.settings}},{fetchSettings:_settings.fetch})(ProxyAppMain); +"use strict";function _interopRequireDefault(e){return e&&e.__esModule?e:{"default":e}}function _classCallCheck(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function _possibleConstructorReturn(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function _inherits(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}Object.defineProperty(exports,"__esModule",{value:!0});var _createClass=function(){function e(e,t){for(var r=0;r<t.length;r++){var o=t[r];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(e,o.key,o)}}return function(t,r,o){return r&&e(t.prototype,r),o&&e(t,o),t}}(),_react=require("react"),_react2=_interopRequireDefault(_react),_reactDom=require("react-dom"),_reactDom2=_interopRequireDefault(_reactDom),_lodash=require("lodash"),_lodash2=_interopRequireDefault(_lodash),_reactRedux=require("react-redux"),_Header=require("./Header"),_Header2=_interopRequireDefault(_Header),_EventLog=require("./EventLog"),_EventLog2=_interopRequireDefault(_EventLog),_Footer=require("./Footer"),_Footer2=_interopRequireDefault(_Footer),_utils=require("../utils.js"),ProxyAppMain=function(e){function t(e,r){_classCallCheck(this,t);var o=_possibleConstructorReturn(this,Object.getPrototypeOf(t).call(this,e,r));return o.focus=o.focus.bind(o),o.onKeyDown=o.onKeyDown.bind(o),o.updateLocation=o.updateLocation.bind(o),o}return _inherits(t,e),_createClass(t,[{key:"updateLocation",value:function(e,t){void 0===e&&(e=this.props.location.pathname);var r=this.props.location.query,o=!0,n=!1,a=void 0;try{for(var i,u=Object.keys(t||{})[Symbol.iterator]();!(o=(i=u.next()).done);o=!0){var c=i.value;r[c]=t[c]||void 0}}catch(l){n=!0,a=l}finally{try{!o&&u["return"]&&u["return"]()}finally{if(n)throw a}}this.context.router.replace({pathname:e,query:r})}},{key:"getQuery",value:function(){return _lodash2["default"].clone(this.props.location.query)}},{key:"componentDidMount",value:function(){this.focus()}},{key:"getChildContext",value:function(){return{returnFocus:this.focus}}},{key:"focus",value:function(){document.activeElement.blur(),window.getSelection().removeAllRanges(),_reactDom2["default"].findDOMNode(this).focus()}},{key:"onKeyDown",value:function(e){var t=this,r=null;switch(e.keyCode){case _utils.Key.I:r="intercept";break;case _utils.Key.L:r="search";break;case _utils.Key.H:r="highlight";break;default:var o=this.refs.view;return this.refs.view.getWrappedInstance&&(o=this.refs.view.getWrappedInstance()),void(o.onMainKeyDown&&o.onMainKeyDown(e))}r&&!function(){var e=t.refs.header;e.setState({active:_Header2["default"].entries[0]},function(){e.refs.active.refs[r].select()})}(),e.preventDefault()}},{key:"render",value:function(){var e=this.props,t=e.showEventLog,r=e.location,o=e.children,n=this.getQuery();return _react2["default"].createElement("div",{id:"container",tabIndex:"0",onKeyDown:this.onKeyDown},_react2["default"].createElement(_Header2["default"],{ref:"header",updateLocation:this.updateLocation,query:n}),_react2["default"].cloneElement(o,{ref:"view",location:r,query:n,updateLocation:this.updateLocation}),t&&_react2["default"].createElement(_EventLog2["default"],{key:"eventlog"}),_react2["default"].createElement(_Footer2["default"],null))}}]),t}(_react.Component);ProxyAppMain.childContextTypes={returnFocus:_react.PropTypes.func.isRequired},ProxyAppMain.contextTypes={router:_react.PropTypes.object.isRequired},exports["default"]=(0,_reactRedux.connect)(function(e){return{showEventLog:e.eventLog.visible}})(ProxyAppMain); -},{"../ducks/settings":45,"../utils.js":52,"./EventLog":8,"./Footer":19,"./Header":20,"lodash":"lodash","react":"react","react-dom":"react-dom","react-redux":"react-redux"}],31:[function(require,module,exports){ +},{"../utils.js":52,"./EventLog":8,"./Footer":19,"./Header":20,"lodash":"lodash","react":"react","react-dom":"react-dom","react-redux":"react-redux"}],31:[function(require,module,exports){ "use strict";function _interopRequireDefault(e){return e&&e.__esModule?e:{"default":e}}function _classCallCheck(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function _possibleConstructorReturn(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function _inherits(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}Object.defineProperty(exports,"__esModule",{value:!0});var _extends=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var r=arguments[t];for(var o in r)Object.prototype.hasOwnProperty.call(r,o)&&(e[o]=r[o])}return e},_createClass=function(){function e(e,t){for(var r=0;r<t.length;r++){var o=t[r];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(e,o.key,o)}}return function(t,r,o){return r&&e(t.prototype,r),o&&e(t,o),t}}(),_react=require("react"),_react2=_interopRequireDefault(_react),_reactDom=require("react-dom"),_reactDom2=_interopRequireDefault(_reactDom),_ValidateEditor=require("./ValueEditor/ValidateEditor"),_ValidateEditor2=_interopRequireDefault(_ValidateEditor),ValueEditor=function(e){function t(e){_classCallCheck(this,t);var r=_possibleConstructorReturn(this,Object.getPrototypeOf(t).call(this,e));return r.focus=r.focus.bind(r),r}return _inherits(t,e),_createClass(t,[{key:"render",value:function(){var e=this,t=this.props.inline?"span":"div";return _react2["default"].createElement(_ValidateEditor2["default"],_extends({},this.props,{onStop:function(){return e.context.returnFocus()},tag:t}))}},{key:"focus",value:function(){_reactDom2["default"].findDOMNode(this).focus()}}]),t}(_react.Component);ValueEditor.contextTypes={returnFocus:_react.PropTypes.func},ValueEditor.propTypes={content:_react.PropTypes.string.isRequired,onDone:_react.PropTypes.func.isRequired,inline:_react.PropTypes.bool},exports["default"]=ValueEditor; },{"./ValueEditor/ValidateEditor":33,"react":"react","react-dom":"react-dom"}],32:[function(require,module,exports){ @@ -116,7 +116,7 @@ "use strict";function calcVScroll(t){if(!t)return{start:0,end:0,paddingTop:0,paddingBottom:0};var e=t.itemCount,o=t.rowHeight,r=t.viewportTop,a=t.viewportHeight,i=t.itemHeights,l=r+a,n=0,c=0,d=0,p=0;if(i)for(var h=0,s=0;e>h;h++){var m=i[h]||o;r>=s&&h%2===0&&(d=s,n=h),l>=s?c=h+1:p+=m,s+=m}else n=-2&Math.max(0,Math.floor(r/o)-1),c=Math.min(e,n+Math.ceil(a/o)+2),d=Math.min(n,e)*o,p=Math.max(0,e-c)*o;return{start:n,end:c,paddingTop:d,paddingBottom:p}}Object.defineProperty(exports,"__esModule",{value:!0}),exports.calcVScroll=calcVScroll; },{}],40:[function(require,module,exports){ -"use strict";function _interopRequireWildcard(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&(t[n]=e[n]);return t["default"]=e,t}function Connection(e,t){"/"===e[0]&&(e=location.origin.replace("http","ws")+e);var n=new WebSocket(e);return n.onopen=function(){t(webSocketActions.connected()),t(settingsActions.fetch()),t(flowActions.fetchFlows()).then(function(){console.log("flows are loaded now"),_actions.ConnectionActions.open()}),t(eventLogActions.fetchLogEntries())},n.onmessage=function(e){var n=JSON.parse(e.data);switch(_dispatcher.AppDispatcher.dispatchServerAction(n),n.type){case eventLogActions.UPDATE_LOG:return t(eventLogActions.updateLogEntries(n));case flowActions.UPDATE_FLOWS:return t(flowActions.updateFlows(n));case settingsActions.WS_MSG_TYPE:return t(settingsActions.handleWsMsg(n));default:console.warn("unknown message",n)}},n.onerror=function(){_actions.ConnectionActions.error(),t(eventLogActions.addLogEntry("WebSocket connection error."))},n.onclose=function(){_actions.ConnectionActions.close(),t(eventLogActions.addLogEntry("WebSocket connection closed.")),t(webSocketActions.disconnected())},n}Object.defineProperty(exports,"__esModule",{value:!0}),exports["default"]=Connection;var _actions=require("./actions.js"),_dispatcher=require("./dispatcher.js"),_websocket=require("./ducks/websocket"),webSocketActions=_interopRequireWildcard(_websocket),_eventLog=require("./ducks/eventLog"),eventLogActions=_interopRequireWildcard(_eventLog),_flows=require("./ducks/flows"),flowActions=_interopRequireWildcard(_flows),_settings=require("./ducks/settings"),settingsActions=_interopRequireWildcard(_settings); +"use strict";function _interopRequireWildcard(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)Object.prototype.hasOwnProperty.call(e,n)&&(t[n]=e[n]);return t["default"]=e,t}function Connection(e,t){"/"===e[0]&&(e=location.origin.replace("http","ws")+e);var n=new WebSocket(e);return n.onopen=function(){t(webSocketActions.connected()),t(settingsActions.fetchSettings()),t(flowActions.fetchFlows()).then(function(){console.log("flows are loaded now"),_actions.ConnectionActions.open()}),t(eventLogActions.fetchLogEntries())},n.onmessage=function(e){var n=JSON.parse(e.data);switch(_dispatcher.AppDispatcher.dispatchServerAction(n),n.type){case eventLogActions.UPDATE_LOG:return t(eventLogActions.updateLogEntries(n));case flowActions.UPDATE_FLOWS:return t(flowActions.updateFlows(n));case settingsActions.UPDATE_SETTINGS:return t(settingsActions.updateSettings(n));default:console.warn("unknown message",n)}},n.onerror=function(){_actions.ConnectionActions.error(),t(eventLogActions.addLogEntry("WebSocket connection error."))},n.onclose=function(){_actions.ConnectionActions.close(),t(eventLogActions.addLogEntry("WebSocket connection closed.")),t(webSocketActions.disconnected())},n}Object.defineProperty(exports,"__esModule",{value:!0}),exports["default"]=Connection;var _actions=require("./actions.js"),_dispatcher=require("./dispatcher.js"),_websocket=require("./ducks/websocket"),webSocketActions=_interopRequireWildcard(_websocket),_eventLog=require("./ducks/eventLog"),eventLogActions=_interopRequireWildcard(_eventLog),_flows=require("./ducks/flows"),flowActions=_interopRequireWildcard(_flows),_settings=require("./ducks/settings"),settingsActions=_interopRequireWildcard(_settings); },{"./actions.js":1,"./dispatcher.js":41,"./ducks/eventLog":42,"./ducks/flows":43,"./ducks/settings":45,"./ducks/websocket":49}],41:[function(require,module,exports){ "use strict";function _interopRequireDefault(e){return e&&e.__esModule?e:{"default":e}}Object.defineProperty(exports,"__esModule",{value:!0}),exports.AppDispatcher=void 0;var _flux=require("flux"),_flux2=_interopRequireDefault(_flux),PayloadSources={VIEW:"view",SERVER:"server"},AppDispatcher=exports.AppDispatcher=new _flux2["default"].Dispatcher;AppDispatcher.dispatchViewAction=function(e){e.source=PayloadSources.VIEW,this.dispatch(e)},AppDispatcher.dispatchServerAction=function(e){e.source=PayloadSources.SERVER,this.dispatch(e)}; @@ -131,9 +131,9 @@ "use strict";function _interopRequireDefault(e){return e&&e.__esModule?e:{"default":e}}Object.defineProperty(exports,"__esModule",{value:!0});var _redux=require("redux"),_eventLog=require("./eventLog"),_eventLog2=_interopRequireDefault(_eventLog),_websocket=require("./websocket"),_websocket2=_interopRequireDefault(_websocket),_flows=require("./flows"),_flows2=_interopRequireDefault(_flows),_settings=require("./settings"),_settings2=_interopRequireDefault(_settings),_ui=require("./ui"),_ui2=_interopRequireDefault(_ui),rootReducer=(0,_redux.combineReducers)({eventLog:_eventLog2["default"],websocket:_websocket2["default"],flows:_flows2["default"],settings:_settings2["default"],ui:_ui2["default"]});exports["default"]=rootReducer; },{"./eventLog":42,"./flows":43,"./settings":45,"./ui":46,"./websocket":49,"redux":"redux"}],45:[function(require,module,exports){ -"use strict";function reduce(){var e=arguments.length<=0||void 0===arguments[0]?defaultState:arguments[0],t=arguments[1];switch(t.type){case BEGIN_FETCH:return _extends({},e,{pendings:[]});case FETCHED:var n=e.pendings||[];return _extends({},e,{pendings:null,settings:n.reduce(reduceData,t.data)});case RECV_WS_MSG:return e.pendings?_extends({},e,{pendings:e.pendings.concat(t)}):_extends({},e,{settings:reduceData(e.settings,t)});default:return e}}function reduceData(e,t){switch(t.cmd){case WS_MSG_CMD_UPDATE:return _extends({},e,t.data);default:return e}}function fetch(){return function(e){return e({type:BEGIN_FETCH}),$.getJSON("/settings").done(function(t){return e(handleFetchResponse(t.data))}).fail(function(t){return e(handleFetchError(t))})}}function handleWsMsg(e){return{type:RECV_WS_MSG,cmd:e.cmd,data:e.data}}function handleFetchResponse(e){return{type:FETCHED,data:e}}function handleFetchError(e){return(0,_eventLog.addLogEntry)(e.stack||e.message||e)}Object.defineProperty(exports,"__esModule",{value:!0}),exports.RECV_WS_MSG=exports.FETCHED=exports.BEGIN_FETCH=exports.WS_MSG_CMD_UPDATE=exports.WS_MSG_TYPE=void 0;var _extends=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e};exports["default"]=reduce,exports.fetch=fetch,exports.handleWsMsg=handleWsMsg,exports.handleFetchResponse=handleFetchResponse,exports.handleFetchError=handleFetchError;var _eventLog=require("./eventLog"),WS_MSG_TYPE=exports.WS_MSG_TYPE="settings",WS_MSG_CMD_UPDATE=exports.WS_MSG_CMD_UPDATE="update",BEGIN_FETCH=exports.BEGIN_FETCH="SETTINGS_BEGIN_FETCH",FETCHED=exports.FETCHED="SETTINGS_FETCHED",RECV_WS_MSG=exports.RECV_WS_MSG="SETTINGS_RECV_WS_MSG",defaultState={settings:{},pendings:null}; +"use strict";function _toConsumableArray(t){if(Array.isArray(t)){for(var e=0,n=Array(t.length);e<t.length;e++)n[e]=t[e];return n}return Array.from(t)}function reducer(){var t=arguments.length<=0||void 0===arguments[0]?defaultState:arguments[0],e=arguments[1];switch(e.type){case REQUEST_SETTINGS:return _extends({},t,{isFetching:!0});case RECEIVE_SETTINGS:var n={settings:e.settings,isFetching:!1,actionsDuringFetch:[]},r=!0,s=!1,i=void 0;try{for(var u,E=t.actionsDuringFetch[Symbol.iterator]();!(r=(u=E.next()).done);r=!0)e=u.value,n=reducer(n,e)}catch(S){s=!0,i=S}finally{try{!r&&E["return"]&&E["return"]()}finally{if(s)throw i}}return n;case UPDATE_SETTINGS:return t.isFetching?_extends({},t,{actionsDuringFetch:[].concat(_toConsumableArray(t.actionsDuringFetch),[e])}):_extends({},t,{settings:_extends({},t.settings,e.settings)});default:return t}}function updateSettings(t){return"update"===t.cmd?{type:UPDATE_SETTINGS,settings:t.data}:void console.error("unknown settings update",t)}function fetchSettings(){return function(t){return t({type:REQUEST_SETTINGS}),(0,_utils.fetchApi)("/settings").then(function(t){return t.json()}).then(function(e){return t({type:RECEIVE_SETTINGS,settings:e.data})})}}function updateSettings(t){return _utils.fetchApi.put("/settings",t),{type:SET_INTERCEPT}}Object.defineProperty(exports,"__esModule",{value:!0}),exports.UPDATE_SETTINGS=exports.RECEIVE_SETTINGS=exports.REQUEST_SETTINGS=void 0;var _extends=Object.assign||function(t){for(var e=1;e<arguments.length;e++){var n=arguments[e];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(t[r]=n[r])}return t};exports["default"]=reducer,exports.updateSettings=updateSettings,exports.fetchSettings=fetchSettings,exports.updateSettings=updateSettings;var _utils=require("../utils"),REQUEST_SETTINGS=exports.REQUEST_SETTINGS="REQUEST_SETTINGS",RECEIVE_SETTINGS=exports.RECEIVE_SETTINGS="RECEIVE_SETTINGS",UPDATE_SETTINGS=exports.UPDATE_SETTINGS="UPDATE_SETTINGS",defaultState={settings:{},isFetching:!1,actionsDuringFetch:[]}; -},{"./eventLog":42}],46:[function(require,module,exports){ +},{"../utils":52}],46:[function(require,module,exports){ "use strict";function reducer(){var e=arguments.length<=0||void 0===arguments[0]?defaultState:arguments[0],t=arguments[1];switch(t.type){case SET_ACTIVE_MENU:return _extends({},e,{activeMenu:t.activeMenu});case _flows.SELECT_FLOW:var r=t.flowId&&!t.currentSelection,n=!t.flowId&&t.currentSelection;return r?_extends({},e,{activeMenu:"Flow"}):n&&"Flow"===e.activeMenu?_extends({},e,{activeMenu:"Start"}):e;default:return e}}function setActiveMenu(e){return{type:SET_ACTIVE_MENU,activeMenu:e}}Object.defineProperty(exports,"__esModule",{value:!0});var _extends=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var r=arguments[t];for(var n in r)Object.prototype.hasOwnProperty.call(r,n)&&(e[n]=r[n])}return e};exports["default"]=reducer,exports.setActiveMenu=setActiveMenu;var _flows=require("./flows"),SET_ACTIVE_MENU="SET_ACTIVE_MENU",defaultState={activeMenu:"Start"}; },{"./flows":43}],47:[function(require,module,exports){ @@ -152,7 +152,7 @@ "use strict";function _interopRequireDefault(e){return e&&e.__esModule?e:{"default":e}}Object.defineProperty(exports,"__esModule",{value:!0}),exports.parseHttpVersion=exports.isValidHttpVersion=exports.parseUrl=exports.ResponseUtils=exports.RequestUtils=exports.MessageUtils=void 0;var _lodash=require("lodash"),_lodash2=_interopRequireDefault(_lodash),_jquery=require("jquery"),_jquery2=_interopRequireDefault(_jquery),defaultPorts={http:80,https:443},MessageUtils=exports.MessageUtils={getContentType:function(e){var t=this.get_first_header(e,/^Content-Type$/i);return t?t.split(";")[0].trim():void 0},get_first_header:function(e,t){if(e._headerLookups||Object.defineProperty(e,"_headerLookups",{value:{},configurable:!1,enumerable:!1,writable:!1}),!(t in e._headerLookups)){for(var r,s=0;s<e.headers.length;s++)if(e.headers[s][0].match(t)){r=e.headers[s];break}e._headerLookups[t]=r?r[1]:void 0}return e._headerLookups[t]},match_header:function(e,t){for(var r=e.headers,s=r.length;s--;)if(t.test(r[s].join(" ")))return r[s];return!1},getContentURL:function(e,t){return t===e.request?t="request":t===e.response&&(t="response"),"/flows/"+e.id+"/"+t+"/content"},getContent:function(e,t){var r=MessageUtils.getContentURL(e,t);return _jquery2["default"].get(r)}},RequestUtils=exports.RequestUtils=_lodash2["default"].extend(MessageUtils,{pretty_host:function(e){return e.host},pretty_url:function(e){var t="";return defaultPorts[e.scheme]!==e.port&&(t=":"+e.port),e.scheme+"://"+this.pretty_host(e)+t+e.path}}),ResponseUtils=exports.ResponseUtils=_lodash2["default"].extend(MessageUtils,{}),parseUrl_regex=/^(?:(https?):\/\/)?([^\/:]+)?(?::(\d+))?(\/.*)?$/i,parseUrl=exports.parseUrl=function(e){var t=parseUrl_regex.exec(e);if(!t)return!1;var r=t[1],s=t[2],o=parseInt(t[3]),n=t[4];r&&(o=o||defaultPorts[r]);var i={};return r&&(i.scheme=r),s&&(i.host=s),o&&(i.port=o),n&&(i.path=n),i},isValidHttpVersion_regex=/^HTTP\/\d+(\.\d+)*$/i,isValidHttpVersion=exports.isValidHttpVersion=function(e){return isValidHttpVersion_regex.test(e)},parseHttpVersion=exports.parseHttpVersion=function(e){return e=e.replace("HTTP/","").split("."),_lodash2["default"].map(e,function(e){return parseInt(e)})}; },{"jquery":"jquery","lodash":"lodash"}],52:[function(require,module,exports){ -"use strict";function _interopRequireDefault(e){return e&&e.__esModule?e:{"default":e}}function reverseString(e){return String.fromCharCode.apply(String,_lodash2["default"].map(e.split(""),function(e){return 65535-e.charCodeAt(0)}))+end}function getCookie(e){var r=document.cookie.match(new RegExp("\\b"+e+"=([^;]*)\\b"));return r?r[1]:void 0}function fetchApi(e,r){return e+=-1===e.indexOf("?")?"?"+xsrf:"&"+xsrf,fetch(e,_extends({},r,{credentials:"same-origin"}))}Object.defineProperty(exports,"__esModule",{value:!0}),exports.formatTimeStamp=exports.formatTimeDelta=exports.formatSize=exports.Key=void 0;var _extends=Object.assign||function(e){for(var r=1;r<arguments.length;r++){var t=arguments[r];for(var o in t)Object.prototype.hasOwnProperty.call(t,o)&&(e[o]=t[o])}return e};exports.reverseString=reverseString,exports.fetchApi=fetchApi;var _jquery=require("jquery"),_jquery2=_interopRequireDefault(_jquery),_lodash=require("lodash"),_lodash2=_interopRequireDefault(_lodash),_actions=require("./actions.js"),_actions2=_interopRequireDefault(_actions);window.$=_jquery2["default"],window._=_lodash2["default"],window.React=require("react");for(var Key=exports.Key={UP:38,DOWN:40,PAGE_UP:33,PAGE_DOWN:34,HOME:36,END:35,LEFT:37,RIGHT:39,ENTER:13,ESC:27,TAB:9,SPACE:32,BACKSPACE:8,SHIFT:16},i=65;90>=i;i++)Key[String.fromCharCode(i)]=i;var formatSize=exports.formatSize=function(e){if(0===e)return"0";for(var r=["b","kb","mb","gb","tb"],t=0;t<r.length&&!(Math.pow(1024,t+1)>e);t++);var o;return o=e%Math.pow(1024,t)===0?0:1,(e/Math.pow(1024,t)).toFixed(o)+r[t]},formatTimeDelta=exports.formatTimeDelta=function(e){for(var r=e,t=["ms","s","min","h"],o=[1e3,60,60],a=0;Math.abs(r)>=o[a]&&a<o.length;)r/=o[a],a++;return Math.round(r)+t[a]},formatTimeStamp=exports.formatTimeStamp=function(e){var r=new Date(1e3*e).toISOString();return r.replace("T"," ").replace("Z","")},end=String.fromCharCode(65535),xsrf="_xsrf="+getCookie("_xsrf");_jquery2["default"].ajaxPrefilter(function(e){["post","put","delete"].indexOf(e.type.toLowerCase())>=0&&"/"===e.url[0]&&(-1===e.url.indexOf("?")?e.url+="?"+xsrf:e.url+="&"+xsrf)}),(0,_jquery2["default"])(document).ajaxError(function(e,r,t,o){if("abort"!==o){var a=r.responseText;console.error(o,a,arguments),alert(a)}}); +"use strict";function _interopRequireDefault(e){return e&&e.__esModule?e:{"default":e}}function reverseString(e){return String.fromCharCode.apply(String,_lodash2["default"].map(e.split(""),function(e){return 65535-e.charCodeAt(0)}))+end}function getCookie(e){var r=document.cookie.match(new RegExp("\\b"+e+"=([^;]*)\\b"));return r?r[1]:void 0}function fetchApi(e,r){return e+=-1===e.indexOf("?")?"?"+xsrf:"&"+xsrf,fetch(e,_extends({credentials:"same-origin"},r))}Object.defineProperty(exports,"__esModule",{value:!0}),exports.formatTimeStamp=exports.formatTimeDelta=exports.formatSize=exports.Key=void 0;var _extends=Object.assign||function(e){for(var r=1;r<arguments.length;r++){var t=arguments[r];for(var o in t)Object.prototype.hasOwnProperty.call(t,o)&&(e[o]=t[o])}return e};exports.reverseString=reverseString,exports.fetchApi=fetchApi;var _jquery=require("jquery"),_jquery2=_interopRequireDefault(_jquery),_lodash=require("lodash"),_lodash2=_interopRequireDefault(_lodash),_actions=require("./actions.js"),_actions2=_interopRequireDefault(_actions);window.$=_jquery2["default"],window._=_lodash2["default"],window.React=require("react");for(var Key=exports.Key={UP:38,DOWN:40,PAGE_UP:33,PAGE_DOWN:34,HOME:36,END:35,LEFT:37,RIGHT:39,ENTER:13,ESC:27,TAB:9,SPACE:32,BACKSPACE:8,SHIFT:16},i=65;90>=i;i++)Key[String.fromCharCode(i)]=i;var formatSize=exports.formatSize=function(e){if(0===e)return"0";for(var r=["b","kb","mb","gb","tb"],t=0;t<r.length&&!(Math.pow(1024,t+1)>e);t++);var o;return o=e%Math.pow(1024,t)===0?0:1,(e/Math.pow(1024,t)).toFixed(o)+r[t]},formatTimeDelta=exports.formatTimeDelta=function(e){for(var r=e,t=["ms","s","min","h"],o=[1e3,60,60],n=0;Math.abs(r)>=o[n]&&n<o.length;)r/=o[n],n++;return Math.round(r)+t[n]},formatTimeStamp=exports.formatTimeStamp=function(e){var r=new Date(1e3*e).toISOString();return r.replace("T"," ").replace("Z","")},end=String.fromCharCode(65535),xsrf="_xsrf="+getCookie("_xsrf");_jquery2["default"].ajaxPrefilter(function(e){["post","put","delete"].indexOf(e.type.toLowerCase())>=0&&"/"===e.url[0]&&(-1===e.url.indexOf("?")?e.url+="?"+xsrf:e.url+="&"+xsrf)}),(0,_jquery2["default"])(document).ajaxError(function(e,r,t,o){if("abort"!==o){var n=r.responseText;console.error(o,n,arguments),alert(n)}}),fetchApi.put=function(e,r,t){return fetchApi(e,_extends({method:"PUT",headers:{"Content-Type":"application/json"},body:JSON.stringify(r)},t))}; },{"./actions.js":1,"jquery":"jquery","lodash":"lodash","react":"react"}]},{},[2]) diff --git a/test/mitmproxy/test_cmdline.py b/test/mitmproxy/test_cmdline.py index e75b7baf..4fe2cf94 100644 --- a/test/mitmproxy/test_cmdline.py +++ b/test/mitmproxy/test_cmdline.py @@ -39,11 +39,11 @@ def test_parse_replace_hook(): def test_parse_server_spec(): tutils.raises("Invalid server specification", cmdline.parse_server_spec, "") assert cmdline.parse_server_spec( - "http://foo.com:88") == ("http", ("foo.com", 88)) + "http://foo.com:88") == (b"http", (b"foo.com", 88)) assert cmdline.parse_server_spec( - "http://foo.com") == ("http", ("foo.com", 80)) + "http://foo.com") == (b"http", (b"foo.com", 80)) assert cmdline.parse_server_spec( - "https://foo.com") == ("https", ("foo.com", 443)) + "https://foo.com") == (b"https", (b"foo.com", 443)) tutils.raises( "Invalid server specification", cmdline.parse_server_spec, @@ -59,9 +59,9 @@ def test_parse_upstream_auth(): tutils.raises("Invalid upstream auth specification", cmdline.parse_upstream_auth, ":") tutils.raises("Invalid upstream auth specification", cmdline.parse_upstream_auth, ":test") assert cmdline.parse_upstream_auth( - "test:test") == "Basic" + " " + base64.b64encode("test:test") + "test:test") == b"Basic" + b" " + base64.b64encode(b"test:test") assert cmdline.parse_upstream_auth( - "test:") == "Basic" + " " + base64.b64encode("test:") + "test:") == b"Basic" + b" " + base64.b64encode(b"test:") def test_parse_setheaders(): @@ -124,7 +124,7 @@ def test_common(): opts.replace_file = [("/foo/bar/%s" % p)] v = cmdline.get_common_options(opts)["replacements"] assert len(v) == 1 - assert v[0][2].strip() == "replacecontents" + assert v[0][2].strip() == b"replacecontents" def test_mitmproxy(): diff --git a/test/mitmproxy/test_contentview.py b/test/mitmproxy/test_contentview.py index 48825bc2..52fceeac 100644 --- a/test/mitmproxy/test_contentview.py +++ b/test/mitmproxy/test_contentview.py @@ -23,37 +23,37 @@ class TestContentView: def test_view_auto(self): v = cv.ViewAuto() f = v( - "foo", + b"foo", headers=Headers() ) assert f[0] == "Raw" f = v( - "<html></html>", + b"<html></html>", headers=Headers(content_type="text/html") ) assert f[0] == "HTML" f = v( - "foo", + b"foo", headers=Headers(content_type="text/flibble") ) assert f[0] == "Raw" f = v( - "<xml></xml>", + b"<xml></xml>", headers=Headers(content_type="text/flibble") ) assert f[0].startswith("XML") f = v( - "", + b"", headers=Headers() ) assert f[0] == "No content" f = v( - "", + b"", headers=Headers(), query=multidict.MultiDict([("foo", "bar")]), ) @@ -69,29 +69,29 @@ class TestContentView: def test_view_html(self): v = cv.ViewHTML() - s = "<html><br><br></br><p>one</p></html>" + s = b"<html><br><br></br><p>one</p></html>" assert v(s) - s = "gobbledygook" + s = b"gobbledygook" assert not v(s) def test_view_html_outline(self): v = cv.ViewHTMLOutline() - s = "<html><br><br></br><p>one</p></html>" + s = b"<html><br><br></br><p>one</p></html>" assert v(s) def test_view_json(self): cv.VIEW_CUTOFF = 100 v = cv.ViewJSON() - assert v("{}") - assert not v("{") - assert v("[1, 2, 3, 4, 5]") + assert v(b"{}") + assert not v(b"{") + assert v(b"[1, 2, 3, 4, 5]") def test_view_xml(self): v = cv.ViewXML() - assert v("<foo></foo>") - assert not v("<foo>") - s = """<?xml version="1.0" encoding="UTF-8"?> + assert v(b"<foo></foo>") + assert not v(b"<foo>") + s = b"""<?xml version="1.0" encoding="UTF-8"?> <?xml-stylesheet title="XSL_formatting"?> <rss xmlns:media="http://search.yahoo.com/mrss/" @@ -103,7 +103,7 @@ class TestContentView: def test_view_raw(self): v = cv.ViewRaw() - assert v("foo") + assert v(b"foo") def test_view_javascript(self): v = cv.ViewJavaScript() @@ -133,7 +133,7 @@ class TestContentView: def test_view_hex(self): v = cv.ViewHex() - assert v("foo") + assert v(b"foo") def test_view_image(self): v = cv.ViewImage() @@ -149,11 +149,11 @@ class TestContentView: p = tutils.test_data.path("data/image.ico") assert v(open(p, "rb").read()) - assert not v("flibble") + assert not v(b"flibble") def test_view_multipart(self): view = cv.ViewMultipart() - v = """ + v = b""" --AaB03x Content-Disposition: form-data; name="submit-name" @@ -182,21 +182,21 @@ Larry def test_get_content_view(self): r = cv.get_content_view( cv.get("Raw"), - "[1, 2, 3]", + b"[1, 2, 3]", headers=Headers(content_type="application/json") ) assert "Raw" in r[0] r = cv.get_content_view( cv.get("Auto"), - "[1, 2, 3]", + b"[1, 2, 3]", headers=Headers(content_type="application/json") ) assert r[0] == "JSON" r = cv.get_content_view( cv.get("Auto"), - "[1, 2", + b"[1, 2", headers=Headers(content_type="application/json") ) assert "Raw" in r[0] @@ -205,13 +205,13 @@ Larry ContentViewException, cv.get_content_view, cv.get("AMF"), - "[1, 2", + b"[1, 2", headers=Headers() ) r = cv.get_content_view( cv.get("Auto"), - encoding.encode('gzip', "[1, 2, 3]"), + encoding.encode('gzip', b"[1, 2, 3]"), headers=Headers( content_type="application/json", content_encoding="gzip" @@ -222,7 +222,7 @@ Larry r = cv.get_content_view( cv.get("XML"), - encoding.encode('gzip', "[1, 2, 3]"), + encoding.encode('gzip', b"[1, 2, 3]"), headers=Headers( content_type="application/json", content_encoding="gzip" @@ -277,7 +277,7 @@ def test_get_by_shortcut(): def test_pretty_json(): - assert cv.pretty_json('{"foo": 1}') - assert not cv.pretty_json("moo") + assert cv.pretty_json(b'{"foo": 1}') + assert not cv.pretty_json(b"moo") assert cv.pretty_json(b'{"foo" : "\xe4\xb8\x96\xe7\x95\x8c"}') # utf8 with chinese characters assert not cv.pretty_json(b'{"foo" : "\xFF"}') diff --git a/test/mitmproxy/test_custom_contentview.py b/test/mitmproxy/test_custom_contentview.py index 479b0b43..889fb8b3 100644 --- a/test/mitmproxy/test_custom_contentview.py +++ b/test/mitmproxy/test_custom_contentview.py @@ -40,7 +40,7 @@ def test_custom_views(): cv.remove(view_obj) r = cv.get_content_view( cv.get("Auto"), - "[1, 2, 3]", + b"[1, 2, 3]", headers=Headers( content_type="text/none" ) @@ -7,7 +7,7 @@ deps = codecov>=2.0.5 passenv = CI TRAVIS_BUILD_ID TRAVIS TRAVIS_BRANCH TRAVIS_JOB_NUMBER TRAVIS_PULL_REQUEST TRAVIS_JOB_ID TRAVIS_REPO_SLUG TRAVIS_COMMIT setenv = - PY3TESTS = test/netlib test/pathod/ test/mitmproxy/script + PY3TESTS = test/netlib test/pathod/ test/mitmproxy/script test/mitmproxy/test_contentview.py test/mitmproxy/test_custom_contentview.py test/mitmproxy/test_app.py test/mitmproxy/test_controller.py test/mitmproxy/test_fuzzing.py test/mitmproxy/test_script.py test/mitmproxy/test_web_app.py test/mitmproxy/test_utils.py test/mitmproxy/test_stateobject.py test/mitmproxy/test_cmdline.py [testenv:py27] commands = diff --git a/web/src/js/actions.js b/web/src/js/actions.js index 588245ae..bb1d0dd6 100644 --- a/web/src/js/actions.js +++ b/web/src/js/actions.js @@ -39,27 +39,6 @@ export var ConnectionActions = { } }; -export var SettingsActions = { - update: function (settings) { - - $.ajax({ - type: "PUT", - url: "/settings", - contentType: 'application/json', - data: JSON.stringify(settings) - }); - - /* - //Facebook Flux: We do an optimistic update on the client already. - AppDispatcher.dispatchViewAction({ - type: ActionTypes.SETTINGS_STORE, - cmd: StoreCmds.UPDATE, - data: settings - }); - */ - } -}; - export var FlowActions = { accept: function (flow) { $.post("/flows/" + flow.id + "/accept"); @@ -119,4 +98,4 @@ export var Query = { SEARCH: "s", HIGHLIGHT: "h", SHOW_EVENTLOG: "e" -};
\ No newline at end of file +}; diff --git a/web/src/js/components/Footer.jsx b/web/src/js/components/Footer.jsx index 1f6de2d7..82d6d8a1 100644 --- a/web/src/js/components/Footer.jsx +++ b/web/src/js/components/Footer.jsx @@ -1,11 +1,12 @@ import React from 'react' +import { connect } from 'react-redux' import { formatSize } from '../utils.js' Footer.propTypes = { settings: React.PropTypes.object.isRequired, } -export default function Footer({ settings }) { +function Footer({ settings }) { return ( <footer> {settings.mode && settings.mode != "regular" && ( @@ -44,3 +45,9 @@ export default function Footer({ settings }) { </footer> ) } + +export default connect( + state => ({ + settings: state.settings.settings, + }) +)(Footer) diff --git a/web/src/js/components/Header.jsx b/web/src/js/components/Header.jsx index 93ca5154..ab25eb41 100644 --- a/web/src/js/components/Header.jsx +++ b/web/src/js/components/Header.jsx @@ -12,10 +12,6 @@ import {setActiveMenu} from '../ducks/ui.js' class Header extends Component { static entries = [MainMenu, ViewMenu, OptionMenu] - static propTypes = { - settings: PropTypes.object.isRequired, - } - handleClick(active, e) { e.preventDefault() this.props.setActiveMenu(active.title) @@ -24,7 +20,7 @@ class Header extends Component { } render() { - const { settings, updateLocation, query, selectedFlow, activeMenu} = this.props + const { updateLocation, query, selectedFlow, activeMenu} = this.props let entries = [...Header.entries] if(selectedFlow) @@ -47,10 +43,9 @@ class Header extends Component { </nav> <div className="menu"> <Active - settings={settings} updateLocation={updateLocation} query={query} - /> + /> </div> </header> ) diff --git a/web/src/js/components/Header/FlowMenu.jsx b/web/src/js/components/Header/FlowMenu.jsx index 96f42652..abecf0dc 100644 --- a/web/src/js/components/Header/FlowMenu.jsx +++ b/web/src/js/components/Header/FlowMenu.jsx @@ -15,10 +15,12 @@ function FlowMenu({ flow }) { return ( <div> <div className="menu-row"> - <Button disabled title="[r]eplay flow" text="Replay" icon="fa-repeat" onClick={FlowActions.replay.bind(null, flow)} /> - <Button title="[D]uplicate flow" text="Duplicate" icon="fa-copy" onClick={FlowActions.duplicate.bind(null, flow)} /> - <Button title="[d]elete flow" text="Delete" icon="fa-trash" onClick={FlowActions.delete.bind(null, flow)}/> - <Button title="download" text="Download" icon="fa-download" onClick={() => window.location = MessageUtils.getContentURL(flow, flow.response)}/> + <Button disabled={!flow.intercepted} title="[a]ccept intercepted flow" text="Accept" icon="fa-play" onClick={() => FlowActions.accept(flow)} /> + <Button title="[r]eplay flow" text="Replay" icon="fa-repeat" onClick={FlowActions.replay.bind(null, flow)} /> + <Button title="[D]uplicate flow" text="Duplicate" icon="fa-copy" onClick={FlowActions.duplicate.bind(null, flow)} /> + <Button title="[d]elete flow" text="Delete" icon="fa-trash" onClick={FlowActions.delete.bind(null, flow)}/> + <Button disabled={!flow.modified} title="revert changes to flow [V]" text="Revert" icon="fa-history" onClick={() => FlowActions.revert(flow)} /> + <Button title="download" text="Download" icon="fa-download" onClick={() => window.location = MessageUtils.getContentURL(flow, flow.response)}/> </div> <div className="clearfix"/> </div> diff --git a/web/src/js/components/Header/MainMenu.jsx b/web/src/js/components/Header/MainMenu.jsx index 7b0b542c..a466a980 100644 --- a/web/src/js/components/Header/MainMenu.jsx +++ b/web/src/js/components/Header/MainMenu.jsx @@ -1,8 +1,8 @@ import React, { Component, PropTypes } from 'react' +import { connect } from 'react-redux' import FilterInput from './FilterInput' import { Query } from '../../actions.js' -import {setInterceptPattern} from "../../ducks/settings" -import { connect } from 'react-redux' +import { updateSettings } from '../../ducks/settings' class MainMenu extends Component { @@ -10,14 +10,16 @@ class MainMenu extends Component { static route = 'flows' static propTypes = { - settings: React.PropTypes.object.isRequired, + query: PropTypes.object.isRequired, + settings: PropTypes.object.isRequired, + updateLocation: PropTypes.func.isRequired, + onSettingsChange: PropTypes.func.isRequired, } constructor(props, context) { super(props, context) this.onSearchChange = this.onSearchChange.bind(this) this.onHighlightChange = this.onHighlightChange.bind(this) - this.onInterceptChange = this.onInterceptChange.bind(this) } onSearchChange(val) { @@ -28,16 +30,8 @@ class MainMenu extends Component { this.props.updateLocation(undefined, { [Query.HIGHLIGHT]: val }) } - onInterceptChange(val) { - this.props.setInterceptPattern(val); - } - render() { - const { query, settings } = this.props - - const search = query[Query.SEARCH] || '' - const highlight = query[Query.HIGHLIGHT] || '' - const intercept = settings.intercept || '' + const { query, settings, onSettingsChange } = this.props return ( <div> @@ -47,7 +41,7 @@ class MainMenu extends Component { placeholder="Search" type="search" color="black" - value={search} + value={query[Query.SEARCH] || ''} onChange={this.onSearchChange} /> <FilterInput @@ -55,7 +49,7 @@ class MainMenu extends Component { placeholder="Highlight" type="tag" color="hsl(48, 100%, 50%)" - value={highlight} + value={query[Query.HIGHLIGHT] || ''} onChange={this.onHighlightChange} /> <FilterInput @@ -63,8 +57,8 @@ class MainMenu extends Component { placeholder="Intercept" type="pause" color="hsl(208, 56%, 53%)" - value={intercept} - onChange={this.onInterceptChange} + value={settings.intercept || ''} + onChange={intercept => onSettingsChange({ intercept })} /> </div> <div className="clearfix"></div> @@ -73,6 +67,11 @@ class MainMenu extends Component { } } -export default connect(undefined, { - setInterceptPattern -})(MainMenu); +export default connect( + state => ({ + settings: state.settings.settings, + }), + { + onSettingsChange: updateSettings, + } +)(MainMenu); diff --git a/web/src/js/components/Header/OptionMenu.jsx b/web/src/js/components/Header/OptionMenu.jsx index 44f309fd..f871ec92 100644 --- a/web/src/js/components/Header/OptionMenu.jsx +++ b/web/src/js/components/Header/OptionMenu.jsx @@ -1,61 +1,72 @@ import React, { PropTypes } from 'react' +import { connect } from 'react-redux' import ToggleButton from '../common/ToggleButton' import ToggleInputButton from '../common/ToggleInputButton' -import { SettingsActions } from '../../actions.js' +import { updateSettings } from '../../ducks/settings' OptionMenu.title = 'Options' OptionMenu.propTypes = { settings: PropTypes.object.isRequired, + onSettingsChange: PropTypes.func.isRequired, } -export default function OptionMenu({ settings }) { +function OptionMenu({ settings, onSettingsChange }) { // @todo use settings.map return ( <div> <div className="menu-row"> <ToggleButton text="showhost" checked={settings.showhost} - onToggle={() => SettingsActions.update({ showhost: !settings.showhost })} + onToggle={() => onSettingsChange({ showhost: !settings.showhost })} /> <ToggleButton text="no_upstream_cert" checked={settings.no_upstream_cert} - onToggle={() => SettingsActions.update({ no_upstream_cert: !settings.no_upstream_cert })} + onToggle={() => onSettingsChange({ no_upstream_cert: !settings.no_upstream_cert })} /> <ToggleButton text="rawtcp" checked={settings.rawtcp} - onToggle={() => SettingsActions.update({ rawtcp: !settings.rawtcp })} + onToggle={() => onSettingsChange({ rawtcp: !settings.rawtcp })} /> <ToggleButton text="http2" checked={settings.http2} - onToggle={() => SettingsActions.update({ http2: !settings.http2 })} + onToggle={() => onSettingsChange({ http2: !settings.http2 })} /> <ToggleButton text="anticache" checked={settings.anticache} - onToggle={() => SettingsActions.update({ anticache: !settings.anticache })} + onToggle={() => onSettingsChange({ anticache: !settings.anticache })} /> <ToggleButton text="anticomp" checked={settings.anticomp} - onToggle={() => SettingsActions.update({ anticomp: !settings.anticomp })} + onToggle={() => onSettingsChange({ anticomp: !settings.anticomp })} /> <ToggleInputButton name="stickyauth" placeholder="Sticky auth filter" checked={!!settings.stickyauth} txt={settings.stickyauth || ''} - onToggleChanged={txt => SettingsActions.update({ stickyauth: !settings.stickyauth ? txt : null })} + onToggleChanged={txt => onSettingsChange({ stickyauth: !settings.stickyauth ? txt : null })} /> <ToggleInputButton name="stickycookie" placeholder="Sticky cookie filter" checked={!!settings.stickycookie} txt={settings.stickycookie || ''} - onToggleChanged={txt => SettingsActions.update({ stickycookie: !settings.stickycookie ? txt : null })} + onToggleChanged={txt => onSettingsChange({ stickycookie: !settings.stickycookie ? txt : null })} /> <ToggleInputButton name="stream" placeholder="stream..." checked={!!settings.stream} txt={settings.stream || ''} inputType="number" - onToggleChanged={txt => SettingsActions.update({ stream: !settings.stream ? txt : null })} + onToggleChanged={txt => onSettingsChange({ stream: !settings.stream ? txt : null })} /> </div> <div className="clearfix"/> </div> ) } + +export default connect( + state => ({ + settings: state.settings.settings, + }), + { + onSettingsChange: updateSettings, + } +)(OptionMenu) diff --git a/web/src/js/components/ProxyApp.jsx b/web/src/js/components/ProxyApp.jsx index 39cadff5..5d795b57 100644 --- a/web/src/js/components/ProxyApp.jsx +++ b/web/src/js/components/ProxyApp.jsx @@ -111,11 +111,11 @@ class ProxyAppMain extends Component { } render() { - const { showEventLog, location, children, settings } = this.props + const { showEventLog, location, children } = this.props const query = this.getQuery() return ( <div id="container" tabIndex="0" onKeyDown={this.onKeyDown}> - <Header ref="header" settings={settings} updateLocation={this.updateLocation} query={query} /> + <Header ref="header" updateLocation={this.updateLocation} query={query} /> {React.cloneElement( children, { ref: 'view', location, query, updateLocation: this.updateLocation } @@ -123,7 +123,7 @@ class ProxyAppMain extends Component { {showEventLog && ( <EventLog key="eventlog"/> )} - <Footer settings={settings}/> + <Footer /> </div> ) } @@ -132,6 +132,5 @@ class ProxyAppMain extends Component { export default connect( state => ({ showEventLog: state.eventLog.visible, - settings: state.settings.settings, }) )(ProxyAppMain) diff --git a/web/src/js/components/common/Button.jsx b/web/src/js/components/common/Button.jsx index cc2fe9dd..574288df 100644 --- a/web/src/js/components/common/Button.jsx +++ b/web/src/js/components/common/Button.jsx @@ -5,9 +5,11 @@ Button.propTypes = { text: PropTypes.string.isRequired } -export default function Button({ onClick, text, icon }) { +export default function Button({ onClick, text, icon, disabled }) { return ( - <div className={"btn btn-default"} onClick={onClick}> + <div className={"btn btn-default"} + onClick={onClick} + disabled={disabled}> <i className={"fa fa-fw " + icon}/> {text} diff --git a/web/src/js/ducks/settings.js b/web/src/js/ducks/settings.js index 73c62120..3e6c8366 100644 --- a/web/src/js/ducks/settings.js +++ b/web/src/js/ducks/settings.js @@ -1,8 +1,8 @@ -import {fetchApi} from "../utils"; +import {fetchApi} from '../utils'; -export const REQUEST_SETTINGS = "REQUEST_SETTINGS" -export const RECEIVE_SETTINGS = "RECEIVE_SETTINGS" -export const UPDATE_SETTINGS = "UPDATE_SETTINGS" +export const REQUEST_SETTINGS = 'REQUEST_SETTINGS' +export const RECEIVE_SETTINGS = 'RECEIVE_SETTINGS' +export const UPDATE_SETTINGS = 'UPDATE_SETTINGS' const defaultState = { settings: {}, @@ -49,20 +49,20 @@ export default function reducer(state = defaultState, action) { export function updateSettings(event) { /* This action creator takes all WebSocket events */ - if (event.cmd === "update") { + if (event.cmd === 'update') { return { type: UPDATE_SETTINGS, settings: event.data } } - console.error("unknown settings update", event) + console.error('unknown settings update', event) } export function fetchSettings() { return dispatch => { dispatch({type: REQUEST_SETTINGS}) - return fetchApi("/settings") + return fetchApi('/settings') .then(response => response.json()) .then(json => dispatch({type: RECEIVE_SETTINGS, settings: json.data}) @@ -71,7 +71,7 @@ export function fetchSettings() { } } -export function setInterceptPattern(intercept) { - return dispatch => - fetchApi.put("/settings", {intercept}) +export function updateSettings(settings) { + fetchApi.put('/settings', settings) + return { type: SET_INTERCEPT } } |