mirror of
https://github.com/Grasscutters/mitmproxy.git
synced 2024-11-22 15:37:45 +00:00
Merge branch 'main' of https://github.com/gorogoroumaru/mitmproxy into hover-menu
This commit is contained in:
commit
6824666424
@ -275,6 +275,8 @@ class ClearAll(RequestHandler):
|
||||
class ResumeFlows(RequestHandler):
|
||||
def post(self):
|
||||
for f in self.view:
|
||||
if not f.intercepted:
|
||||
continue
|
||||
f.resume()
|
||||
self.view.update([f])
|
||||
|
||||
|
@ -11,6 +11,13 @@ and activate your virtualenv environment before proceeding.**
|
||||
|
||||
- Run `yarn test` to run the test suite.
|
||||
|
||||
|
||||
## Advanced Tools
|
||||
|
||||
- `yarn run gulp` supports live-reloading if you install a matching
|
||||
[browser extension](http://livereload.com/extensions/).
|
||||
- You can debug application state using the [Redux DevTools](https://github.com/reduxjs/redux-devtools).
|
||||
|
||||
## Architecture
|
||||
|
||||
There are two components:
|
||||
|
@ -2,7 +2,6 @@
|
||||
.user-select (@val) {
|
||||
-webkit-touch-callout: @val;
|
||||
-webkit-user-select: @val;
|
||||
-khtml-user-select: @val;
|
||||
-moz-user-select: @val;
|
||||
-ms-user-select: @val;
|
||||
user-select: @val;
|
||||
@ -33,6 +32,7 @@
|
||||
&.sort-asc, &.sort-desc {
|
||||
background-color: lighten(#F2F2F2, 3%);
|
||||
}
|
||||
|
||||
&.sort-asc:after, &.sort-desc:after {
|
||||
font: normal normal normal 14px/1 FontAwesome;
|
||||
position: absolute;
|
||||
@ -41,9 +41,11 @@
|
||||
padding: 2px;
|
||||
background-color: fadeout(lighten(#F2F2F2, 3%), 20%);
|
||||
}
|
||||
|
||||
&.sort-asc:after {
|
||||
content: "\f0de";
|
||||
}
|
||||
|
||||
&.sort-desc:after {
|
||||
content: "\f0dd";
|
||||
}
|
||||
@ -53,17 +55,22 @@
|
||||
tr {
|
||||
cursor: pointer;
|
||||
|
||||
background-color: white;
|
||||
|
||||
&:nth-child(even) {
|
||||
background-color: rgba(0, 0, 0, 0.05);
|
||||
background-color: #f2f2f2;
|
||||
}
|
||||
|
||||
&.selected {
|
||||
background-color: hsla(209, 52%, 84%, 0.5) !important;
|
||||
background-color: #e0ebf5 !important;
|
||||
}
|
||||
|
||||
&.highlighted {
|
||||
background-color: hsla(48, 100%, 50%, 0.4);
|
||||
background-color: #ffeb99;
|
||||
}
|
||||
|
||||
&.highlighted:nth-child(even) {
|
||||
background-color: hsla(48, 100%, 50%, 0.5);
|
||||
background-color: #ffe57f;
|
||||
}
|
||||
}
|
||||
|
||||
@ -80,6 +87,7 @@
|
||||
color: @interceptorange;
|
||||
}
|
||||
}
|
||||
|
||||
tr.intercepted.has-response {
|
||||
.col-status, .col-size, .col-time {
|
||||
color: @interceptorange;
|
||||
@ -88,6 +96,7 @@
|
||||
|
||||
.fa {
|
||||
line-height: inherit;
|
||||
|
||||
&.pull-right {
|
||||
margin-left: 0;
|
||||
}
|
||||
@ -96,39 +105,89 @@
|
||||
.col-tls {
|
||||
width: 10px;
|
||||
}
|
||||
|
||||
.col-tls-https {
|
||||
background-color: rgba(0, 185, 0, 0.5);
|
||||
}
|
||||
|
||||
.col-icon {
|
||||
width: 32px;
|
||||
}
|
||||
|
||||
.col-path {
|
||||
.fa-repeat {
|
||||
color: green;
|
||||
}
|
||||
|
||||
.fa-pause {
|
||||
color: @interceptorange;
|
||||
}
|
||||
|
||||
.fa-exclamation, .fa-times {
|
||||
color: darkred;
|
||||
}
|
||||
}
|
||||
|
||||
.col-method {
|
||||
width: 60px;
|
||||
}
|
||||
|
||||
.col-status {
|
||||
width: 50px;
|
||||
}
|
||||
|
||||
.col-size {
|
||||
width: 70px;
|
||||
}
|
||||
|
||||
.col-time {
|
||||
width: 50px;
|
||||
}
|
||||
|
||||
.col-timestamp {
|
||||
width: auto;
|
||||
}
|
||||
|
||||
td.col-time, td.col-size {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.col-quickactions {
|
||||
width: 0;
|
||||
direction: rtl;
|
||||
overflow: hidden;
|
||||
background-color: inherit;
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
tr:hover .col-quickactions {
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.col-quickactions > div {
|
||||
height: 32px;
|
||||
background-color: inherit;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
|
||||
div {
|
||||
margin-right: 2px;
|
||||
height: 32px;
|
||||
width: 32px;
|
||||
border-radius: 16px;
|
||||
|
||||
&:hover {
|
||||
background-color: rgba(0, 0, 0, 5%);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.col-quickactions .fa-ellipsis-h {
|
||||
transform: translate(-3px, 3px);
|
||||
}
|
||||
|
||||
.col-quickactions .fa-play {
|
||||
transform: translate(-1px, 2px);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -3,7 +3,7 @@
|
||||
@import (reference) "../../node_modules/bootstrap/less/mixins/labels.less";
|
||||
@import (reference) "../../node_modules/bootstrap/less/labels.less";
|
||||
|
||||
@menu-height: 85px;
|
||||
@menu-height: 95px;
|
||||
|
||||
header {
|
||||
padding-top: 6px;
|
||||
@ -20,17 +20,16 @@ header {
|
||||
}
|
||||
|
||||
@menu-legend-height: 16px;
|
||||
@menu-group-hmargin: 3px;
|
||||
@menu-group-hmargin: 5px;
|
||||
.menu-group {
|
||||
margin: 0 @menu-group-hmargin;
|
||||
margin: 0 @menu-group-hmargin 0 (@menu-group-hmargin + 1px);
|
||||
display: inline-block;
|
||||
height: @menu-height;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.menu-content {
|
||||
height: @menu-height - @menu-legend-height;
|
||||
text-align: center;
|
||||
display: flow-root;
|
||||
|
||||
> .btn {
|
||||
height: @menu-height - @menu-legend-height;
|
||||
@ -45,6 +44,16 @@ header {
|
||||
margin: 0 auto 5px;
|
||||
}
|
||||
}
|
||||
|
||||
> .btn.btn-sm {
|
||||
height: (@menu-height - @menu-legend-height)/3;
|
||||
padding: 0 5px;
|
||||
i {
|
||||
display: inline-block;
|
||||
font-size: 14px;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.menu-entry {
|
||||
@ -65,6 +74,7 @@ header {
|
||||
}
|
||||
|
||||
.menu-legend {
|
||||
color: #777;
|
||||
height: @menu-legend-height;
|
||||
text-align: center;
|
||||
font-size: 12px;
|
||||
@ -73,7 +83,7 @@ header {
|
||||
|
||||
.menu-group + .menu-group:before {
|
||||
@space: 10px;
|
||||
margin-left: -@menu-group-hmargin;
|
||||
margin-left: -(@menu-group-hmargin + 1px);
|
||||
content: " ";
|
||||
border-left: solid 1px lighten(grey, 40%);
|
||||
margin-top: @space;
|
||||
@ -82,19 +92,20 @@ header {
|
||||
}
|
||||
|
||||
@menu-main-gutter-width: 5px;
|
||||
.menu-main {
|
||||
.make-row(@menu-main-gutter-width);
|
||||
padding: 2px 5px;
|
||||
.main-menu {
|
||||
display: flex;
|
||||
.menu-group {
|
||||
width: 50%;
|
||||
}
|
||||
.btn-sm {
|
||||
margin-top: 6px;
|
||||
}
|
||||
}
|
||||
|
||||
.filter-input {
|
||||
.make-sm-column(5, @menu-main-gutter-width);
|
||||
padding: 2.5px;
|
||||
margin: 4px 0;
|
||||
|
||||
@media (max-width: @screen-xs-max) {
|
||||
|
||||
padding: 2px 2.5px;
|
||||
|
||||
> .form-control, > .input-group-addon, > .input-group-btn > .btn {
|
||||
height: 23.5px;
|
||||
padding: 1px 5px;
|
||||
|
@ -4,12 +4,12 @@ exports[`ShowFullContentButton Component should connect to state 1`] = `null`;
|
||||
|
||||
exports[`ShowFullContentButton Component should render correctly 1`] = `
|
||||
<div>
|
||||
<div
|
||||
<button
|
||||
className="view-all-content-btn btn-xs btn btn-default"
|
||||
onClick={[Function]}
|
||||
>
|
||||
Show full content
|
||||
</div>
|
||||
</button>
|
||||
<span
|
||||
className="pull-right"
|
||||
>
|
||||
|
@ -1,116 +1,135 @@
|
||||
import React from 'react'
|
||||
import renderer from 'react-test-renderer'
|
||||
import * as Columns from '../../../components/FlowTable/FlowColumns'
|
||||
import { TFlow } from '../../ducks/tutils'
|
||||
import {
|
||||
IconColumn,
|
||||
MethodColumn,
|
||||
PathColumn,
|
||||
QuickActionsColumn,
|
||||
SizeColumn,
|
||||
StatusColumn,
|
||||
TimeColumn,
|
||||
TimeStampColumn,
|
||||
TLSColumn
|
||||
} from '../../../components/FlowTable/FlowColumns'
|
||||
import {TFlow, TStore} from '../../ducks/tutils'
|
||||
import {Provider} from 'react-redux'
|
||||
|
||||
describe('FlowColumns Components', () => {
|
||||
describe('Flowcolumns Components', () => {
|
||||
|
||||
let tflow = TFlow()
|
||||
it('should render TLSColumn', () => {
|
||||
let tlsColumn = renderer.create(<Columns.TLSColumn flow={tflow}/>),
|
||||
let tlsColumn = renderer.create(<TLSColumn flow={tflow}/>),
|
||||
tree = tlsColumn.toJSON()
|
||||
expect(tree).toMatchSnapshot()
|
||||
})
|
||||
|
||||
it('should render IconColumn', () => {
|
||||
let iconColumn = renderer.create(<Columns.IconColumn flow={tflow}/>),
|
||||
let iconColumn = renderer.create(<IconColumn flow={tflow}/>),
|
||||
tree = iconColumn.toJSON()
|
||||
// plain
|
||||
expect(tree).toMatchSnapshot()
|
||||
// not modified
|
||||
tflow.response.status_code = 304
|
||||
iconColumn = renderer.create(<Columns.IconColumn flow={tflow}/>)
|
||||
iconColumn = renderer.create(<IconColumn flow={tflow}/>)
|
||||
tree = iconColumn.toJSON()
|
||||
expect(tree).toMatchSnapshot()
|
||||
// redirect
|
||||
tflow.response.status_code = 302
|
||||
iconColumn = renderer.create(<Columns.IconColumn flow={tflow}/>)
|
||||
iconColumn = renderer.create(<IconColumn flow={tflow}/>)
|
||||
tree = iconColumn.toJSON()
|
||||
expect(tree).toMatchSnapshot()
|
||||
// image
|
||||
let imageFlow = TFlow()
|
||||
imageFlow.response.headers = [['Content-Type', 'image/jpeg']]
|
||||
iconColumn = renderer.create(<Columns.IconColumn flow={imageFlow}/>)
|
||||
iconColumn = renderer.create(<IconColumn flow={imageFlow}/>)
|
||||
tree = iconColumn.toJSON()
|
||||
expect(tree).toMatchSnapshot()
|
||||
// javascript
|
||||
let jsFlow = TFlow()
|
||||
jsFlow.response.headers = [['Content-Type', 'application/x-javascript']]
|
||||
iconColumn = renderer.create(<Columns.IconColumn flow={jsFlow}/>)
|
||||
iconColumn = renderer.create(<IconColumn flow={jsFlow}/>)
|
||||
tree = iconColumn.toJSON()
|
||||
expect(tree).toMatchSnapshot()
|
||||
// css
|
||||
let cssFlow = TFlow()
|
||||
cssFlow.response.headers = [['Content-Type', 'text/css']]
|
||||
iconColumn = renderer.create(<Columns.IconColumn flow={cssFlow}/>)
|
||||
iconColumn = renderer.create(<IconColumn flow={cssFlow}/>)
|
||||
tree = iconColumn.toJSON()
|
||||
expect(tree).toMatchSnapshot()
|
||||
// html
|
||||
let htmlFlow = TFlow()
|
||||
htmlFlow.response.headers = [['Content-Type', 'text/html']]
|
||||
iconColumn = renderer.create(<Columns.IconColumn flow={htmlFlow}/>)
|
||||
iconColumn = renderer.create(<IconColumn flow={htmlFlow}/>)
|
||||
tree = iconColumn.toJSON()
|
||||
expect(tree).toMatchSnapshot()
|
||||
// default
|
||||
let fooFlow = TFlow()
|
||||
fooFlow.response.headers = [['Content-Type', 'foo']]
|
||||
iconColumn = renderer.create(<Columns.IconColumn flow={fooFlow}/>)
|
||||
iconColumn = renderer.create(<IconColumn flow={fooFlow}/>)
|
||||
tree = iconColumn.toJSON()
|
||||
expect(tree).toMatchSnapshot()
|
||||
// no response
|
||||
tflow.response = null
|
||||
iconColumn = renderer.create(<Columns.IconColumn flow={tflow}/>)
|
||||
iconColumn = renderer.create(<IconColumn flow={tflow}/>)
|
||||
tree = iconColumn.toJSON()
|
||||
expect(tree).toMatchSnapshot()
|
||||
})
|
||||
|
||||
it('should render pathColumn', () => {
|
||||
let pathColumn = renderer.create(<Columns.PathColumn flow={tflow}/>),
|
||||
let pathColumn = renderer.create(<PathColumn flow={tflow}/>),
|
||||
tree = pathColumn.toJSON()
|
||||
expect(tree).toMatchSnapshot()
|
||||
|
||||
tflow.error.msg = 'Connection killed.'
|
||||
tflow.intercepted = true
|
||||
pathColumn = renderer.create(<Columns.PathColumn flow={tflow}/>)
|
||||
pathColumn = renderer.create(<PathColumn flow={tflow}/>)
|
||||
tree = pathColumn.toJSON()
|
||||
expect(tree).toMatchSnapshot()
|
||||
})
|
||||
|
||||
it('should render MethodColumn', () => {
|
||||
let methodColumn =renderer.create(<Columns.MethodColumn flow={tflow}/>),
|
||||
let methodColumn = renderer.create(<MethodColumn flow={tflow}/>),
|
||||
tree = methodColumn.toJSON()
|
||||
expect(tree).toMatchSnapshot()
|
||||
})
|
||||
|
||||
it('should render StatusColumn', () => {
|
||||
let statusColumn = renderer.create(<Columns.StatusColumn flow={tflow}/>),
|
||||
let statusColumn = renderer.create(<StatusColumn flow={tflow}/>),
|
||||
tree = statusColumn.toJSON()
|
||||
expect(tree).toMatchSnapshot()
|
||||
})
|
||||
|
||||
it('should render SizeColumn', () => {
|
||||
tflow = TFlow()
|
||||
let sizeColumn = renderer.create(<Columns.SizeColumn flow={tflow}/>),
|
||||
let sizeColumn = renderer.create(<SizeColumn flow={tflow}/>),
|
||||
tree = sizeColumn.toJSON()
|
||||
expect(tree).toMatchSnapshot()
|
||||
})
|
||||
|
||||
it('should render TimeColumn', () => {
|
||||
let timeColumn = renderer.create(<Columns.TimeColumn flow={tflow}/>),
|
||||
let timeColumn = renderer.create(<TimeColumn flow={tflow}/>),
|
||||
tree = timeColumn.toJSON()
|
||||
expect(tree).toMatchSnapshot()
|
||||
|
||||
tflow.response = null
|
||||
timeColumn = renderer.create(<Columns.TimeColumn flow={tflow}/>),
|
||||
timeColumn = renderer.create(<TimeColumn flow={tflow}/>)
|
||||
tree = timeColumn.toJSON()
|
||||
expect(tree).toMatchSnapshot()
|
||||
})
|
||||
|
||||
it('should render TimeStampColumn', () => {
|
||||
let timeStampColumn = renderer.create(<Columns.TimeStampColumn flow={tflow}/>),
|
||||
let timeStampColumn = renderer.create(<TimeStampColumn flow={tflow}/>),
|
||||
tree = timeStampColumn.toJSON()
|
||||
tflow.request.timestamp_start =
|
||||
expect(tree).toMatchSnapshot()
|
||||
})
|
||||
|
||||
it('should render QuickActionsColumn', () => {
|
||||
let store = TStore(),
|
||||
provider = renderer.create(
|
||||
<Provider store={store}>
|
||||
<QuickActionsColumn flow={tflow}/>
|
||||
</Provider>),
|
||||
tree = provider.toJSON()
|
||||
expect(tree).toMatchSnapshot()
|
||||
})
|
||||
})
|
||||
|
@ -1,6 +1,6 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`FlowColumns Components should render IconColumn 1`] = `
|
||||
exports[`Flowcolumns Components should render IconColumn 1`] = `
|
||||
<td
|
||||
className="col-icon"
|
||||
>
|
||||
@ -10,7 +10,7 @@ exports[`FlowColumns Components should render IconColumn 1`] = `
|
||||
</td>
|
||||
`;
|
||||
|
||||
exports[`FlowColumns Components should render IconColumn 2`] = `
|
||||
exports[`Flowcolumns Components should render IconColumn 2`] = `
|
||||
<td
|
||||
className="col-icon"
|
||||
>
|
||||
@ -20,7 +20,7 @@ exports[`FlowColumns Components should render IconColumn 2`] = `
|
||||
</td>
|
||||
`;
|
||||
|
||||
exports[`FlowColumns Components should render IconColumn 3`] = `
|
||||
exports[`Flowcolumns Components should render IconColumn 3`] = `
|
||||
<td
|
||||
className="col-icon"
|
||||
>
|
||||
@ -30,7 +30,7 @@ exports[`FlowColumns Components should render IconColumn 3`] = `
|
||||
</td>
|
||||
`;
|
||||
|
||||
exports[`FlowColumns Components should render IconColumn 4`] = `
|
||||
exports[`Flowcolumns Components should render IconColumn 4`] = `
|
||||
<td
|
||||
className="col-icon"
|
||||
>
|
||||
@ -40,7 +40,7 @@ exports[`FlowColumns Components should render IconColumn 4`] = `
|
||||
</td>
|
||||
`;
|
||||
|
||||
exports[`FlowColumns Components should render IconColumn 5`] = `
|
||||
exports[`Flowcolumns Components should render IconColumn 5`] = `
|
||||
<td
|
||||
className="col-icon"
|
||||
>
|
||||
@ -50,7 +50,7 @@ exports[`FlowColumns Components should render IconColumn 5`] = `
|
||||
</td>
|
||||
`;
|
||||
|
||||
exports[`FlowColumns Components should render IconColumn 6`] = `
|
||||
exports[`Flowcolumns Components should render IconColumn 6`] = `
|
||||
<td
|
||||
className="col-icon"
|
||||
>
|
||||
@ -60,7 +60,7 @@ exports[`FlowColumns Components should render IconColumn 6`] = `
|
||||
</td>
|
||||
`;
|
||||
|
||||
exports[`FlowColumns Components should render IconColumn 7`] = `
|
||||
exports[`Flowcolumns Components should render IconColumn 7`] = `
|
||||
<td
|
||||
className="col-icon"
|
||||
>
|
||||
@ -70,7 +70,7 @@ exports[`FlowColumns Components should render IconColumn 7`] = `
|
||||
</td>
|
||||
`;
|
||||
|
||||
exports[`FlowColumns Components should render IconColumn 8`] = `
|
||||
exports[`Flowcolumns Components should render IconColumn 8`] = `
|
||||
<td
|
||||
className="col-icon"
|
||||
>
|
||||
@ -80,7 +80,7 @@ exports[`FlowColumns Components should render IconColumn 8`] = `
|
||||
</td>
|
||||
`;
|
||||
|
||||
exports[`FlowColumns Components should render IconColumn 9`] = `
|
||||
exports[`Flowcolumns Components should render IconColumn 9`] = `
|
||||
<td
|
||||
className="col-icon"
|
||||
>
|
||||
@ -90,7 +90,7 @@ exports[`FlowColumns Components should render IconColumn 9`] = `
|
||||
</td>
|
||||
`;
|
||||
|
||||
exports[`FlowColumns Components should render MethodColumn 1`] = `
|
||||
exports[`Flowcolumns Components should render MethodColumn 1`] = `
|
||||
<td
|
||||
className="col-method"
|
||||
>
|
||||
@ -98,7 +98,23 @@ exports[`FlowColumns Components should render MethodColumn 1`] = `
|
||||
</td>
|
||||
`;
|
||||
|
||||
exports[`FlowColumns Components should render SizeColumn 1`] = `
|
||||
exports[`Flowcolumns Components should render QuickActionsColumn 1`] = `
|
||||
<td
|
||||
className="col-quickactions"
|
||||
>
|
||||
<div>
|
||||
<div
|
||||
className="quickaction"
|
||||
>
|
||||
<i
|
||||
className="fa fa-fw fa-ellipsis-h"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
`;
|
||||
|
||||
exports[`Flowcolumns Components should render SizeColumn 1`] = `
|
||||
<td
|
||||
className="col-size"
|
||||
>
|
||||
@ -106,7 +122,7 @@ exports[`FlowColumns Components should render SizeColumn 1`] = `
|
||||
</td>
|
||||
`;
|
||||
|
||||
exports[`FlowColumns Components should render StatusColumn 1`] = `
|
||||
exports[`Flowcolumns Components should render StatusColumn 1`] = `
|
||||
<td
|
||||
className="col-status"
|
||||
style={
|
||||
@ -117,13 +133,13 @@ exports[`FlowColumns Components should render StatusColumn 1`] = `
|
||||
/>
|
||||
`;
|
||||
|
||||
exports[`FlowColumns Components should render TLSColumn 1`] = `
|
||||
exports[`Flowcolumns Components should render TLSColumn 1`] = `
|
||||
<td
|
||||
className="col-tls col-tls-http"
|
||||
/>
|
||||
`;
|
||||
|
||||
exports[`FlowColumns Components should render TimeColumn 1`] = `
|
||||
exports[`Flowcolumns Components should render TimeColumn 1`] = `
|
||||
<td
|
||||
className="col-time"
|
||||
>
|
||||
@ -131,7 +147,7 @@ exports[`FlowColumns Components should render TimeColumn 1`] = `
|
||||
</td>
|
||||
`;
|
||||
|
||||
exports[`FlowColumns Components should render TimeColumn 2`] = `
|
||||
exports[`Flowcolumns Components should render TimeColumn 2`] = `
|
||||
<td
|
||||
className="col-time"
|
||||
>
|
||||
@ -139,7 +155,7 @@ exports[`FlowColumns Components should render TimeColumn 2`] = `
|
||||
</td>
|
||||
`;
|
||||
|
||||
exports[`FlowColumns Components should render TimeStampColumn 1`] = `
|
||||
exports[`Flowcolumns Components should render TimeStampColumn 1`] = `
|
||||
<td
|
||||
className="col-start"
|
||||
>
|
||||
@ -147,7 +163,7 @@ exports[`FlowColumns Components should render TimeStampColumn 1`] = `
|
||||
</td>
|
||||
`;
|
||||
|
||||
exports[`FlowColumns Components should render pathColumn 1`] = `
|
||||
exports[`Flowcolumns Components should render pathColumn 1`] = `
|
||||
<td
|
||||
className="col-path"
|
||||
>
|
||||
@ -158,7 +174,7 @@ exports[`FlowColumns Components should render pathColumn 1`] = `
|
||||
</td>
|
||||
`;
|
||||
|
||||
exports[`FlowColumns Components should render pathColumn 2`] = `
|
||||
exports[`Flowcolumns Components should render pathColumn 2`] = `
|
||||
<td
|
||||
className="col-path"
|
||||
>
|
||||
|
@ -48,6 +48,19 @@ exports[`FlowRow Component should render correctly 1`] = `
|
||||
>
|
||||
3s
|
||||
</td>
|
||||
<td
|
||||
className="col-quickactions"
|
||||
>
|
||||
<div>
|
||||
<div
|
||||
className="quickaction"
|
||||
>
|
||||
<i
|
||||
className="fa fa-fw fa-ellipsis-h"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<div
|
||||
className="dropdown pull-left btn btn-default"
|
||||
>
|
||||
@ -103,20 +116,6 @@ exports[`FlowRow Component should render correctly 1`] = `
|
||||
</a>
|
||||
|
||||
</li>
|
||||
<li>
|
||||
|
||||
<a
|
||||
href="#"
|
||||
onClick={[Function]}
|
||||
>
|
||||
<i
|
||||
className="fa fa-fw fa-plus"
|
||||
/>
|
||||
Intercept all requests from
|
||||
192.168.0.1
|
||||
</a>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</tr>
|
||||
|
@ -44,6 +44,12 @@ exports[`FlowTableHead Component should connect to state 1`] = `
|
||||
>
|
||||
Time
|
||||
</th>
|
||||
<th
|
||||
className="col-quickactions"
|
||||
onClick={[Function]}
|
||||
>
|
||||
|
||||
</th>
|
||||
</tr>
|
||||
`;
|
||||
|
||||
@ -97,5 +103,11 @@ exports[`FlowTableHead Component should render correctly 1`] = `
|
||||
>
|
||||
Time
|
||||
</th>
|
||||
<th
|
||||
className="col-quickactions"
|
||||
onClick={[Function]}
|
||||
>
|
||||
|
||||
</th>
|
||||
</tr>
|
||||
`;
|
||||
|
@ -16,7 +16,7 @@ describe('FilterInput Component', () => {
|
||||
let filterInput = TestUtil.renderIntoDocument(
|
||||
<FilterInput type='foo' color='red' placeholder='bar' value='' onChange={jest.fn()}/>)
|
||||
it('should handle componentWillReceiveProps', () => {
|
||||
filterInput.componentWillReceiveProps({value: 'foo'})
|
||||
filterInput.UNSAFE_componentWillReceiveProps({value: 'foo'})
|
||||
expect(filterInput.state.value).toEqual('foo')
|
||||
})
|
||||
|
||||
|
@ -1,14 +1,16 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`FlowMenu Component should connect to state 1`] = `
|
||||
<div>
|
||||
<div
|
||||
className="flow-menu"
|
||||
>
|
||||
<div
|
||||
className="menu-group"
|
||||
>
|
||||
<div
|
||||
className="menu-content"
|
||||
>
|
||||
<div
|
||||
<button
|
||||
className="btn btn-default"
|
||||
onClick={[Function]}
|
||||
title="[r]eplay flow"
|
||||
@ -17,8 +19,8 @@ exports[`FlowMenu Component should connect to state 1`] = `
|
||||
className="fa fa-fw fa-repeat text-primary"
|
||||
/>
|
||||
Replay
|
||||
</div>
|
||||
<div
|
||||
</button>
|
||||
<button
|
||||
className="btn btn-default"
|
||||
onClick={[Function]}
|
||||
title="[D]uplicate flow"
|
||||
@ -27,8 +29,8 @@ exports[`FlowMenu Component should connect to state 1`] = `
|
||||
className="fa fa-fw fa-copy text-info"
|
||||
/>
|
||||
Duplicate
|
||||
</div>
|
||||
<div
|
||||
</button>
|
||||
<button
|
||||
className="btn btn-default"
|
||||
disabled={true}
|
||||
title="revert changes to flow [V]"
|
||||
@ -37,8 +39,8 @@ exports[`FlowMenu Component should connect to state 1`] = `
|
||||
className="fa fa-fw fa-history text-warning"
|
||||
/>
|
||||
Revert
|
||||
</div>
|
||||
<div
|
||||
</button>
|
||||
<button
|
||||
className="btn btn-default"
|
||||
onClick={[Function]}
|
||||
title="[d]elete flow"
|
||||
@ -47,7 +49,7 @@ exports[`FlowMenu Component should connect to state 1`] = `
|
||||
className="fa fa-fw fa-trash text-danger"
|
||||
/>
|
||||
Delete
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
className="menu-legend"
|
||||
@ -61,7 +63,7 @@ exports[`FlowMenu Component should connect to state 1`] = `
|
||||
<div
|
||||
className="menu-content"
|
||||
>
|
||||
<div
|
||||
<button
|
||||
className="btn btn-default"
|
||||
onClick={[Function]}
|
||||
title="download"
|
||||
@ -70,7 +72,7 @@ exports[`FlowMenu Component should connect to state 1`] = `
|
||||
className="fa fa-fw fa-download"
|
||||
/>
|
||||
Download
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
className="menu-legend"
|
||||
@ -84,7 +86,7 @@ exports[`FlowMenu Component should connect to state 1`] = `
|
||||
<div
|
||||
className="menu-content"
|
||||
>
|
||||
<div
|
||||
<button
|
||||
className="btn btn-default"
|
||||
disabled={true}
|
||||
title="[a]ccept intercepted flow"
|
||||
@ -93,8 +95,8 @@ exports[`FlowMenu Component should connect to state 1`] = `
|
||||
className="fa fa-fw fa-play text-success"
|
||||
/>
|
||||
Resume
|
||||
</div>
|
||||
<div
|
||||
</button>
|
||||
<button
|
||||
className="btn btn-default"
|
||||
disabled={true}
|
||||
title="kill intercepted flow [x]"
|
||||
@ -103,7 +105,7 @@ exports[`FlowMenu Component should connect to state 1`] = `
|
||||
className="fa fa-fw fa-times text-danger"
|
||||
/>
|
||||
Abort
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
className="menu-legend"
|
||||
@ -115,14 +117,16 @@ exports[`FlowMenu Component should connect to state 1`] = `
|
||||
`;
|
||||
|
||||
exports[`FlowMenu Component should render correctly with flow 1`] = `
|
||||
<div>
|
||||
<div
|
||||
className="flow-menu"
|
||||
>
|
||||
<div
|
||||
className="menu-group"
|
||||
>
|
||||
<div
|
||||
className="menu-content"
|
||||
>
|
||||
<div
|
||||
<button
|
||||
className="btn btn-default"
|
||||
onClick={[Function]}
|
||||
title="[r]eplay flow"
|
||||
@ -131,8 +135,8 @@ exports[`FlowMenu Component should render correctly with flow 1`] = `
|
||||
className="fa fa-fw fa-repeat text-primary"
|
||||
/>
|
||||
Replay
|
||||
</div>
|
||||
<div
|
||||
</button>
|
||||
<button
|
||||
className="btn btn-default"
|
||||
onClick={[Function]}
|
||||
title="[D]uplicate flow"
|
||||
@ -141,8 +145,8 @@ exports[`FlowMenu Component should render correctly with flow 1`] = `
|
||||
className="fa fa-fw fa-copy text-info"
|
||||
/>
|
||||
Duplicate
|
||||
</div>
|
||||
<div
|
||||
</button>
|
||||
<button
|
||||
className="btn btn-default"
|
||||
disabled={false}
|
||||
onClick={[Function]}
|
||||
@ -152,8 +156,8 @@ exports[`FlowMenu Component should render correctly with flow 1`] = `
|
||||
className="fa fa-fw fa-history text-warning"
|
||||
/>
|
||||
Revert
|
||||
</div>
|
||||
<div
|
||||
</button>
|
||||
<button
|
||||
className="btn btn-default"
|
||||
onClick={[Function]}
|
||||
title="[d]elete flow"
|
||||
@ -162,7 +166,7 @@ exports[`FlowMenu Component should render correctly with flow 1`] = `
|
||||
className="fa fa-fw fa-trash text-danger"
|
||||
/>
|
||||
Delete
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
className="menu-legend"
|
||||
@ -176,7 +180,7 @@ exports[`FlowMenu Component should render correctly with flow 1`] = `
|
||||
<div
|
||||
className="menu-content"
|
||||
>
|
||||
<div
|
||||
<button
|
||||
className="btn btn-default"
|
||||
onClick={[Function]}
|
||||
title="download"
|
||||
@ -185,7 +189,7 @@ exports[`FlowMenu Component should render correctly with flow 1`] = `
|
||||
className="fa fa-fw fa-download"
|
||||
/>
|
||||
Download
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
className="menu-legend"
|
||||
@ -199,7 +203,7 @@ exports[`FlowMenu Component should render correctly with flow 1`] = `
|
||||
<div
|
||||
className="menu-content"
|
||||
>
|
||||
<div
|
||||
<button
|
||||
className="btn btn-default"
|
||||
disabled={false}
|
||||
onClick={[Function]}
|
||||
@ -209,8 +213,8 @@ exports[`FlowMenu Component should render correctly with flow 1`] = `
|
||||
className="fa fa-fw fa-play text-success"
|
||||
/>
|
||||
Resume
|
||||
</div>
|
||||
<div
|
||||
</button>
|
||||
<button
|
||||
className="btn btn-default"
|
||||
disabled={false}
|
||||
onClick={[Function]}
|
||||
@ -220,7 +224,7 @@ exports[`FlowMenu Component should render correctly with flow 1`] = `
|
||||
className="fa fa-fw fa-times text-danger"
|
||||
/>
|
||||
Abort
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
className="menu-legend"
|
||||
|
@ -2,8 +2,14 @@
|
||||
|
||||
exports[`MainMenu Component should render and connect to state 1`] = `
|
||||
<div
|
||||
className="menu-main"
|
||||
className="main-menu"
|
||||
>
|
||||
<div
|
||||
className="menu-group"
|
||||
>
|
||||
<div
|
||||
className="menu-content"
|
||||
>
|
||||
<div
|
||||
className="filter-input input-group"
|
||||
>
|
||||
@ -56,6 +62,19 @@ exports[`MainMenu Component should render and connect to state 1`] = `
|
||||
value="~a bar"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className="menu-legend"
|
||||
>
|
||||
Find
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className="menu-group"
|
||||
>
|
||||
<div
|
||||
className="menu-content"
|
||||
>
|
||||
<div
|
||||
className="filter-input input-group"
|
||||
>
|
||||
@ -82,5 +101,22 @@ exports[`MainMenu Component should render and connect to state 1`] = `
|
||||
value=""
|
||||
/>
|
||||
</div>
|
||||
<button
|
||||
className="btn-sm btn btn-default"
|
||||
onClick={[Function]}
|
||||
title="[a]ccept all"
|
||||
>
|
||||
<i
|
||||
className="fa fa-fw fa-forward text-success"
|
||||
/>
|
||||
Resume All
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
className="menu-legend"
|
||||
>
|
||||
Intercept
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
@ -8,7 +8,7 @@ exports[`OptionMenu Component should render correctly 1`] = `
|
||||
<div
|
||||
className="menu-content"
|
||||
>
|
||||
<div
|
||||
<button
|
||||
className="btn btn-default"
|
||||
onClick={[Function]}
|
||||
title="Open Options"
|
||||
@ -20,7 +20,7 @@ exports[`OptionMenu Component should render correctly 1`] = `
|
||||
<sup>
|
||||
alpha
|
||||
</sup>
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
className="menu-legend"
|
||||
|
@ -56,6 +56,12 @@ exports[`FlowTable Component should render correctly 1`] = `
|
||||
>
|
||||
Time
|
||||
</th>
|
||||
<th
|
||||
className="col-quickactions"
|
||||
onClick={[Function]}
|
||||
>
|
||||
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
@ -24,7 +24,7 @@ describe('Dropdown Component', () => {
|
||||
it('should handle open/close action', () => {
|
||||
document.body.addEventListener('click', ()=>{})
|
||||
let tree = dropup.toJSON(),
|
||||
e = { preventDefault: jest.fn() }
|
||||
e = { preventDefault: jest.fn(), stopPropagation: jest.fn() }
|
||||
tree.children[0].props.onClick(e)
|
||||
expect(tree).toMatchSnapshot()
|
||||
|
||||
|
@ -1,18 +1,18 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`Button Component should be able to be disabled 1`] = `
|
||||
<div
|
||||
<button
|
||||
className="classname btn btn-default"
|
||||
disabled="true"
|
||||
>
|
||||
<a>
|
||||
foo
|
||||
</a>
|
||||
</div>
|
||||
</button>
|
||||
`;
|
||||
|
||||
exports[`Button Component should render correctly 1`] = `
|
||||
<div
|
||||
<button
|
||||
className="classname btn btn-default"
|
||||
onClick={[Function]}
|
||||
title="title"
|
||||
@ -23,5 +23,5 @@ exports[`Button Component should render correctly 1`] = `
|
||||
<a>
|
||||
foo
|
||||
</a>
|
||||
</div>
|
||||
</button>
|
||||
`;
|
||||
|
@ -1,28 +1,30 @@
|
||||
import React from 'react'
|
||||
import { render } from 'react-dom'
|
||||
import { applyMiddleware, createStore } from 'redux'
|
||||
import { Provider } from 'react-redux'
|
||||
import {render} from 'react-dom'
|
||||
import {applyMiddleware, compose, createStore} from 'redux'
|
||||
import {Provider} from 'react-redux'
|
||||
import thunk from 'redux-thunk'
|
||||
|
||||
import ProxyApp from './components/ProxyApp'
|
||||
import rootReducer from './ducks/index'
|
||||
import { add as addLog } from './ducks/eventLog'
|
||||
import {add as addLog} from './ducks/eventLog'
|
||||
import useUrlState from './urlState'
|
||||
import WebSocketBackend from './backends/websocket'
|
||||
import StaticBackend from './backends/static'
|
||||
import { logger } from 'redux-logger'
|
||||
import {logger} from 'redux-logger'
|
||||
|
||||
|
||||
const middlewares = [thunk];
|
||||
|
||||
// logger must be last
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
middlewares.push(logger);
|
||||
}
|
||||
|
||||
// logger must be last
|
||||
|
||||
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
|
||||
const store = createStore(
|
||||
rootReducer,
|
||||
applyMiddleware(...middlewares)
|
||||
composeEnhancers(applyMiddleware(...middlewares))
|
||||
)
|
||||
|
||||
useUrlState(store)
|
||||
@ -39,7 +41,7 @@ window.addEventListener('error', msg => {
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
render(
|
||||
<Provider store={store}>
|
||||
<ProxyApp />
|
||||
<ProxyApp/>
|
||||
</Provider>,
|
||||
document.getElementById("mitmproxy")
|
||||
)
|
||||
|
@ -12,7 +12,7 @@ ViewSelector.propTypes = {
|
||||
}
|
||||
|
||||
export function ViewSelector ({contentViews, activeView, setContentView}){
|
||||
let inner = <span> <b>View:</b> {activeView.toLowerCase()} <span className="caret"></span> </span>
|
||||
let inner = <span> <b>View:</b> {activeView.toLowerCase()} <span className="caret"/> </span>
|
||||
|
||||
return (
|
||||
<Dropdown dropup className="pull-left" btnClass="btn btn-default btn-xs" text={inner}>
|
||||
@ -28,7 +28,7 @@ export function ViewSelector ({contentViews, activeView, setContentView}){
|
||||
|
||||
export default connect (
|
||||
state => ({
|
||||
contentViews: state.settings.contentViews,
|
||||
contentViews: state.settings.contentViews || [],
|
||||
activeView: state.ui.flow.contentView,
|
||||
}), {
|
||||
setContentView,
|
||||
|
@ -1,23 +1,25 @@
|
||||
import React, { Component } from 'react'
|
||||
import React from 'react'
|
||||
import {useDispatch} from 'react-redux'
|
||||
import classnames from 'classnames'
|
||||
import { RequestUtils, ResponseUtils } from '../../flow/utils.js'
|
||||
import { formatSize, formatTimeDelta, formatTimeStamp } from '../../utils.js'
|
||||
import {RequestUtils, ResponseUtils} from '../../flow/utils.js'
|
||||
import {formatSize, formatTimeDelta, formatTimeStamp} from '../../utils.js'
|
||||
import * as flowActions from "../../ducks/flows";
|
||||
|
||||
export const defaultColumnNames = ["tls", "icon", "path", "method", "status", "size", "time"]
|
||||
|
||||
export function TLSColumn({ flow }) {
|
||||
export function TLSColumn({flow}) {
|
||||
return (
|
||||
<td className={classnames('col-tls', flow.request.scheme === 'https' ? 'col-tls-https' : 'col-tls-http')}></td>
|
||||
<td className={classnames('col-tls', flow.request.scheme === 'https' ? 'col-tls-https' : 'col-tls-http')}/>
|
||||
)
|
||||
}
|
||||
|
||||
TLSColumn.headerClass = 'col-tls'
|
||||
TLSColumn.headerName = ''
|
||||
|
||||
export function IconColumn({ flow }) {
|
||||
export function IconColumn({flow}) {
|
||||
return (
|
||||
<td className="col-icon">
|
||||
<div className={classnames('resource-icon', IconColumn.getIcon(flow))}></div>
|
||||
<div className={classnames('resource-icon', IconColumn.getIcon(flow))}/>
|
||||
</td>
|
||||
)
|
||||
}
|
||||
@ -55,23 +57,23 @@ IconColumn.getIcon = flow => {
|
||||
return 'resource-icon-plain'
|
||||
}
|
||||
|
||||
export function PathColumn({ flow }) {
|
||||
export function PathColumn({flow}) {
|
||||
|
||||
let err;
|
||||
if(flow.error){
|
||||
if (flow.error.msg === "Connection killed."){
|
||||
err = <i className="fa fa-fw fa-times pull-right"></i>
|
||||
if (flow.error) {
|
||||
if (flow.error.msg === "Connection killed.") {
|
||||
err = <i className="fa fa-fw fa-times pull-right"/>
|
||||
} else {
|
||||
err = <i className="fa fa-fw fa-exclamation pull-right"></i>
|
||||
err = <i className="fa fa-fw fa-exclamation pull-right"/>
|
||||
}
|
||||
}
|
||||
return (
|
||||
<td className="col-path">
|
||||
{flow.request.is_replay && (
|
||||
<i className="fa fa-fw fa-repeat pull-right"></i>
|
||||
<i className="fa fa-fw fa-repeat pull-right"/>
|
||||
)}
|
||||
{flow.intercepted && (
|
||||
<i className="fa fa-fw fa-pause pull-right"></i>
|
||||
<i className="fa fa-fw fa-pause pull-right"/>
|
||||
)}
|
||||
{err}
|
||||
{RequestUtils.pretty_url(flow.request)}
|
||||
@ -82,7 +84,7 @@ export function PathColumn({ flow }) {
|
||||
PathColumn.headerClass = 'col-path'
|
||||
PathColumn.headerName = 'Path'
|
||||
|
||||
export function MethodColumn({ flow }) {
|
||||
export function MethodColumn({flow}) {
|
||||
return (
|
||||
<td className="col-method">{flow.request.method}</td>
|
||||
)
|
||||
@ -91,22 +93,18 @@ export function MethodColumn({ flow }) {
|
||||
MethodColumn.headerClass = 'col-method'
|
||||
MethodColumn.headerName = 'Method'
|
||||
|
||||
export function StatusColumn({ flow }) {
|
||||
export function StatusColumn({flow}) {
|
||||
let color = 'darkred';
|
||||
|
||||
if (flow.response && 100 <= flow.response.status_code && flow.response.status_code < 200) {
|
||||
color = 'green'
|
||||
}
|
||||
else if (flow.response && 200 <= flow.response.status_code && flow.response.status_code < 300) {
|
||||
} else if (flow.response && 200 <= flow.response.status_code && flow.response.status_code < 300) {
|
||||
color = 'darkgreen'
|
||||
}
|
||||
else if (flow.response && 300 <= flow.response.status_code && flow.response.status_code < 400) {
|
||||
} else if (flow.response && 300 <= flow.response.status_code && flow.response.status_code < 400) {
|
||||
color = 'lightblue'
|
||||
}
|
||||
else if (flow.response && 400 <= flow.response.status_code && flow.response.status_code < 500) {
|
||||
} else if (flow.response && 400 <= flow.response.status_code && flow.response.status_code < 500) {
|
||||
color = 'lightred'
|
||||
}
|
||||
else if (flow.response && 500 <= flow.response.status_code && flow.response.status_code < 600) {
|
||||
} else if (flow.response && 500 <= flow.response.status_code && flow.response.status_code < 600) {
|
||||
color = 'lightred'
|
||||
}
|
||||
|
||||
@ -118,7 +116,7 @@ export function StatusColumn({ flow }) {
|
||||
StatusColumn.headerClass = 'col-status'
|
||||
StatusColumn.headerName = 'Status'
|
||||
|
||||
export function SizeColumn({ flow }) {
|
||||
export function SizeColumn({flow}) {
|
||||
return (
|
||||
<td className="col-size">{formatSize(SizeColumn.getTotalSize(flow))}</td>
|
||||
)
|
||||
@ -135,7 +133,7 @@ SizeColumn.getTotalSize = flow => {
|
||||
SizeColumn.headerClass = 'col-size'
|
||||
SizeColumn.headerName = 'Size'
|
||||
|
||||
export function TimeColumn({ flow }) {
|
||||
export function TimeColumn({flow}) {
|
||||
return (
|
||||
<td className="col-time">
|
||||
{flow.response ? (
|
||||
@ -150,7 +148,7 @@ export function TimeColumn({ flow }) {
|
||||
TimeColumn.headerClass = 'col-time'
|
||||
TimeColumn.headerName = 'Time'
|
||||
|
||||
export function TimeStampColumn({ flow }) {
|
||||
export function TimeStampColumn({flow}) {
|
||||
return (
|
||||
<td className="col-start">
|
||||
{flow.request.timestamp_start ? (
|
||||
@ -165,7 +163,33 @@ export function TimeStampColumn({ flow }) {
|
||||
TimeStampColumn.headerClass = 'col-timestamp'
|
||||
TimeStampColumn.headerName = 'TimeStamp'
|
||||
|
||||
export default [
|
||||
export function QuickActionsColumn({flow}) {
|
||||
const dispatch = useDispatch()
|
||||
|
||||
function resume(e) {
|
||||
dispatch(flowActions.resume(flow))
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
}
|
||||
|
||||
return (
|
||||
<td className="col-quickactions">
|
||||
<div>
|
||||
<div className="quickaction"><i className="fa fa-fw fa-ellipsis-h"/></div>
|
||||
{flow.intercepted
|
||||
? <div className="quickaction" onClick={resume}><i className="fa fa-fw fa-play text-success"/></div>
|
||||
: null}
|
||||
</div>
|
||||
</td>
|
||||
)
|
||||
}
|
||||
|
||||
QuickActionsColumn.headerClass = 'col-quickactions'
|
||||
QuickActionsColumn.headerName = ''
|
||||
|
||||
|
||||
export const columns = {};
|
||||
for (let col of [
|
||||
TLSColumn,
|
||||
IconColumn,
|
||||
PathColumn,
|
||||
@ -174,4 +198,7 @@ export default [
|
||||
TimeStampColumn,
|
||||
SizeColumn,
|
||||
TimeColumn,
|
||||
]
|
||||
QuickActionsColumn,
|
||||
]) {
|
||||
columns[col.name.replace(/Column$/, "").toLowerCase()] = col;
|
||||
}
|
||||
|
@ -1,10 +1,10 @@
|
||||
import React from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import { connect } from 'react-redux'
|
||||
import {connect} from 'react-redux'
|
||||
import classnames from 'classnames'
|
||||
import columns, {defaultColumnNames} from './FlowColumns'
|
||||
import {columns, defaultColumnNames} from './FlowColumns'
|
||||
|
||||
import { setSort } from '../../ducks/flows'
|
||||
import {setSort} from '../../ducks/flows'
|
||||
|
||||
FlowTableHead.propTypes = {
|
||||
setSort: PropTypes.func.isRequired,
|
||||
@ -14,19 +14,13 @@ FlowTableHead.propTypes = {
|
||||
}
|
||||
|
||||
export function getDisplayColumns(displayColumnNames) {
|
||||
let displayColumns = []
|
||||
if (typeof displayColumnNames == "undefined") {
|
||||
return columns
|
||||
return Object.values(columns)
|
||||
}
|
||||
for (const column of columns) {
|
||||
if (displayColumnNames.includes(column.name.slice(0,-6).toLowerCase())) {
|
||||
displayColumns.push(column)
|
||||
}
|
||||
}
|
||||
return displayColumns
|
||||
return displayColumnNames.map(x => columns[x]).concat([columns.quickactions]);
|
||||
}
|
||||
|
||||
export function FlowTableHead({ sortColumn, sortDesc, setSort, displayColumnNames}) {
|
||||
export function FlowTableHead({sortColumn, sortDesc, setSort, displayColumnNames}) {
|
||||
const sortType = sortDesc ? 'sort-desc' : 'sort-asc'
|
||||
|
||||
const displayColumns = getDisplayColumns(displayColumnNames)
|
||||
|
@ -13,7 +13,7 @@ function Footer({ settings }) {
|
||||
stickyauth, stickycookie, stream_large_bodies, listen_host, listen_port, version, server} = settings;
|
||||
return (
|
||||
<footer>
|
||||
{mode && mode != "regular" && (
|
||||
{mode && mode !== "regular" && (
|
||||
<span className="label label-success">{mode} mode</span>
|
||||
)}
|
||||
{intercept && (
|
||||
@ -25,8 +25,8 @@ function Footer({ settings }) {
|
||||
{no_upstream_cert && (
|
||||
<span className="label label-success">no-upstream-cert</span>
|
||||
)}
|
||||
{rawtcp && (
|
||||
<span className="label label-success">raw-tcp</span>
|
||||
{!rawtcp && (
|
||||
<span className="label label-success">no-raw-tcp</span>
|
||||
)}
|
||||
{!http2 && (
|
||||
<span className="label label-success">no-http2</span>
|
||||
|
@ -22,7 +22,7 @@ export function FlowMenu({ flow, resumeFlow, killFlow, replayFlow, duplicateFlow
|
||||
if (!flow)
|
||||
return <div/>
|
||||
return (
|
||||
<div>
|
||||
<div className="flow-menu">
|
||||
<HideInStatic>
|
||||
<div className="menu-group">
|
||||
<div className="menu-content">
|
||||
@ -72,8 +72,6 @@ export function FlowMenu({ flow, resumeFlow, killFlow, replayFlow, duplicateFlow
|
||||
<div className="menu-legend">Interception</div>
|
||||
</div>
|
||||
</HideInStatic>
|
||||
|
||||
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
@ -1,24 +1,37 @@
|
||||
import React, { Component } from "react"
|
||||
import PropTypes from 'prop-types'
|
||||
import { connect } from "react-redux"
|
||||
import React from "react"
|
||||
import {connect} from "react-redux"
|
||||
import FilterInput from "./FilterInput"
|
||||
import { update as updateSettings } from "../../ducks/settings"
|
||||
import { setFilter, setHighlight } from "../../ducks/flows"
|
||||
import {update as updateSettings} from "../../ducks/settings"
|
||||
import * as flowsActions from "../../ducks/flows"
|
||||
import {setFilter, setHighlight} from "../../ducks/flows"
|
||||
import Button from "../common/Button"
|
||||
|
||||
MainMenu.title = "Start"
|
||||
|
||||
export default function MainMenu() {
|
||||
return (
|
||||
<div className="menu-main">
|
||||
<div className="main-menu">
|
||||
<div className="menu-group">
|
||||
<div className="menu-content">
|
||||
<FlowFilterInput/>
|
||||
<HighlightInput/>
|
||||
</div>
|
||||
<div className="menu-legend">Find</div>
|
||||
</div>
|
||||
|
||||
<div className="menu-group">
|
||||
<div className="menu-content">
|
||||
<InterceptInput/>
|
||||
<ResumeAll/>
|
||||
</div>
|
||||
<div className="menu-legend">Intercept</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export function setIntercept(intercept) {
|
||||
updateSettings({ intercept })
|
||||
return updateSettings({intercept})
|
||||
}
|
||||
|
||||
const InterceptInput = connect(
|
||||
@ -28,7 +41,7 @@ const InterceptInput = connect(
|
||||
type: 'pause',
|
||||
color: 'hsl(208, 56%, 53%)'
|
||||
}),
|
||||
{ onChange: setIntercept }
|
||||
{onChange: setIntercept}
|
||||
)(FilterInput);
|
||||
|
||||
const FlowFilterInput = connect(
|
||||
@ -38,7 +51,7 @@ const FlowFilterInput = connect(
|
||||
type: 'search',
|
||||
color: 'black'
|
||||
}),
|
||||
{ onChange: setFilter }
|
||||
{onChange: setFilter}
|
||||
)(FilterInput);
|
||||
|
||||
const HighlightInput = connect(
|
||||
@ -48,5 +61,19 @@ const HighlightInput = connect(
|
||||
type: 'tag',
|
||||
color: 'hsl(48, 100%, 50%)'
|
||||
}),
|
||||
{ onChange: setHighlight }
|
||||
{onChange: setHighlight}
|
||||
)(FilterInput);
|
||||
|
||||
export function ResumeAll({resumeAll}) {
|
||||
return (
|
||||
<Button className="btn-sm" title="[a]ccept all"
|
||||
icon="fa-forward text-success" onClick={() => resumeAll()}>
|
||||
Resume All
|
||||
</Button>
|
||||
)
|
||||
}
|
||||
|
||||
ResumeAll = connect(
|
||||
null,
|
||||
{resumeAll: flowsActions.resumeAll}
|
||||
)(ResumeAll)
|
||||
|
@ -4,19 +4,19 @@ import classnames from "classnames"
|
||||
|
||||
Button.propTypes = {
|
||||
onClick: PropTypes.func.isRequired,
|
||||
children: PropTypes.node.isRequired,
|
||||
children: PropTypes.node,
|
||||
icon: PropTypes.string,
|
||||
title: PropTypes.string,
|
||||
}
|
||||
|
||||
export default function Button({ onClick, children, icon, disabled, className, title }) {
|
||||
return (
|
||||
<div className={classnames(className, 'btn btn-default')}
|
||||
<button className={classnames(className, 'btn btn-default')}
|
||||
onClick={disabled ? undefined : onClick}
|
||||
disabled={disabled}
|
||||
title={title}>
|
||||
{icon && (<i className={"fa fa-fw " + icon}/> )}
|
||||
{children}
|
||||
</div>
|
||||
</button>
|
||||
)
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { Component } from 'react'
|
||||
import React, {Component} from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import classnames from 'classnames'
|
||||
|
||||
@ -18,21 +18,22 @@ export default class Dropdown extends Component {
|
||||
|
||||
constructor(props, context) {
|
||||
super(props, context)
|
||||
this.state = { open: false }
|
||||
this.state = {open: false}
|
||||
this.close = this.close.bind(this)
|
||||
this.open = this.open.bind(this)
|
||||
}
|
||||
|
||||
close() {
|
||||
this.setState({ open: false })
|
||||
this.setState({open: false})
|
||||
document.removeEventListener('click', this.close)
|
||||
}
|
||||
|
||||
open(e){
|
||||
open(e) {
|
||||
e.preventDefault()
|
||||
if (this.state.open) {
|
||||
return
|
||||
}
|
||||
e.stopPropagation();
|
||||
this.setState({open: !this.state.open})
|
||||
document.addEventListener('click', this.close)
|
||||
}
|
||||
@ -40,13 +41,13 @@ export default class Dropdown extends Component {
|
||||
render() {
|
||||
const {dropup, className, btnClass, text, children} = this.props
|
||||
return (
|
||||
<div className={classnames( (dropup ? 'dropup' : 'dropdown'), className, { open: this.state.open })}>
|
||||
<div className={classnames((dropup ? 'dropup' : 'dropdown'), className, {open: this.state.open})}>
|
||||
<a href='#' className={btnClass}
|
||||
onClick={this.open}>
|
||||
{text}
|
||||
</a>
|
||||
<ul className="dropdown-menu" role="menu">
|
||||
{children.map ( (item, i) => <li key={i}> {item} </li> )}
|
||||
{children.map((item, i) => <li key={i}> {item} </li>)}
|
||||
</ul>
|
||||
</div>
|
||||
)
|
||||
|
@ -2544,6 +2544,7 @@ dedent@^0.7.0:
|
||||
deep-diff@^0.3.5:
|
||||
version "0.3.8"
|
||||
resolved "https://registry.yarnpkg.com/deep-diff/-/deep-diff-0.3.8.tgz#c01de63efb0eec9798801d40c7e0dae25b582c84"
|
||||
integrity sha1-wB3mPvsO7JeYgB1Ax+Da4ltYLIQ=
|
||||
|
||||
deep-extend@^0.6.0:
|
||||
version "0.6.0"
|
||||
|
Loading…
Reference in New Issue
Block a user