aboutsummaryrefslogtreecommitdiff
path: root/frontend/src
diff options
context:
space:
mode:
Diffstat (limited to 'frontend/src')
-rw-r--r--frontend/src/backend.js36
-rw-r--r--frontend/src/colors.scss32
-rw-r--r--frontend/src/components/Connection.js27
-rw-r--r--frontend/src/components/ConnectionContent.js6
-rw-r--r--frontend/src/components/fields/StringField.js31
-rw-r--r--frontend/src/components/fields/StringField.scss66
-rw-r--r--frontend/src/components/filters/FiltersDefinitions.js33
-rw-r--r--frontend/src/components/filters/RulesConnectionsFilter.js6
-rw-r--r--frontend/src/components/panels/PcapPane.js121
-rw-r--r--frontend/src/components/panels/PcapPane.scss55
-rw-r--r--frontend/src/index.scss58
-rw-r--r--frontend/src/utils.js18
-rw-r--r--frontend/src/views/Config.js8
-rw-r--r--frontend/src/views/Connections.js23
-rw-r--r--frontend/src/views/Footer.js4
-rw-r--r--frontend/src/views/Header.js12
-rw-r--r--frontend/src/views/Header.scss4
-rw-r--r--frontend/src/views/MainPane.js8
-rw-r--r--frontend/src/views/Rules.js4
-rw-r--r--frontend/src/views/Services.js33
20 files changed, 489 insertions, 96 deletions
diff --git a/frontend/src/backend.js b/frontend/src/backend.js
new file mode 100644
index 0000000..35ae6e3
--- /dev/null
+++ b/frontend/src/backend.js
@@ -0,0 +1,36 @@
+
+async function request(method, url, data) {
+ const options = {
+ method: method,
+ mode: "cors",
+ cache: "no-cache",
+ credentials: "same-origin",
+ headers: {
+ "Content-Type": "application/json"
+ },
+ redirect: "follow",
+ referrerPolicy: "no-referrer",
+ };
+ if (data != null) {
+ options.body = JSON.stringify(data);
+ }
+ const result = await fetch(url, options);
+ return result.json();
+}
+
+const backend = {
+ get: (url = "") => {
+ return request("GET", url, null);
+ },
+ post: (url = "", data = null) => {
+ return request("POST", url, data);
+ },
+ put: (url = "", data = null) => {
+ return request("PUT", url, data);
+ },
+ delete: (url = "", data = null) => {
+ return request("DELETE", url, data);
+ }
+};
+
+export default backend;
diff --git a/frontend/src/colors.scss b/frontend/src/colors.scss
index 064f9f5..d982f03 100644
--- a/frontend/src/colors.scss
+++ b/frontend/src/colors.scss
@@ -10,10 +10,30 @@ $color-secondary-2: #df3030;
$color-secondary-3: #ff9d9d;
$color-secondary-4: #ffdfdf;
-$color-blue: #247085;
-$color-blue-light: #a5b8be;
-$color-blue-dark: #013b4c;
+$color-red: #E53935;
+$color-red-light: #FFEBEE;
+$color-red-dark: #B71C1C;
-$color-green: #25965d;
-$color-green-light: #cde4d8;
-$color-green-dark: #004321;
+$color-pink: #D81B60;
+$color-pink-light: #FCE4EC;
+$color-pink-dark: #880E4F;
+
+$color-purple: #8E24AA;
+$color-purple-light: #F3E5F5;
+$color-purple-dark: #4A148C;
+
+$color-deep-purple: #5E35B1;
+$color-deep-purple-light: #EDE7F6;
+$color-deep-purple-dark: #311B92;
+
+$color-indigo: #3949AB;
+$color-indigo-light: #E8EAF6;
+$color-indigo-dark: #1A237E;
+
+$color-green: #43A047;
+$color-green-light: #E8F5E9;
+$color-green-dark: #1B5E20;
+
+$color-blue: #1E88E5;
+$color-blue-light: #E3F2FD;
+$color-blue-dark: #0D47A1;
diff --git a/frontend/src/components/Connection.js b/frontend/src/components/Connection.js
index 93c6438..1149584 100644
--- a/frontend/src/components/Connection.js
+++ b/frontend/src/components/Connection.js
@@ -1,7 +1,8 @@
import React, {Component} from 'react';
import './Connection.scss';
-import axios from 'axios'
import {Button, Form, OverlayTrigger, Popover} from "react-bootstrap";
+import backend from "../backend";
+import {formatSize} from "../utils";
class Connection extends Component {
@@ -19,22 +20,18 @@ class Connection extends Component {
handleAction(name) {
if (name === "hide") {
const enabled = !this.props.data.hidden;
- axios.post(`/api/connections/${this.props.data.id}/${enabled ? "hide" : "show"}`)
- .then(res => {
- if (res.status === 202) {
- this.props.onEnabled(!enabled);
- this.setState({update: true});
- }
+ backend.post(`/api/connections/${this.props.data.id}/${enabled ? "hide" : "show"}`)
+ .then(_ => {
+ this.props.onEnabled(!enabled);
+ this.setState({update: true});
});
}
if (name === "mark") {
const marked = this.props.data.marked;
- axios.post(`/api/connections/${this.props.data.id}/${marked ? "unmark" : "mark"}`)
- .then(res => {
- if (res.status === 202) {
- this.props.onMarked(!marked);
- this.setState({update: true});
- }
+ backend.post(`/api/connections/${this.props.data.id}/${marked ? "unmark" : "mark"}`)
+ .then(_ => {
+ this.props.onMarked(!marked);
+ this.setState({update: true});
});
}
if (name === "copy") {
@@ -114,8 +111,8 @@ class Connection extends Component {
<span className="test-tooltip">{duration}</span>
</OverlayTrigger>
</td>
- <td className="clickable" onClick={this.props.onSelected}>{conn.client_bytes}</td>
- <td className="clickable" onClick={this.props.onSelected}>{conn.server_bytes}</td>
+ <td className="clickable" onClick={this.props.onSelected}>{formatSize(conn.client_bytes)}</td>
+ <td className="clickable" onClick={this.props.onSelected}>{formatSize(conn.server_bytes)}</td>
<td className="contains-flag">
{/*<OverlayTrigger trigger={["focus", "hover"]} placement="right"*/}
{/* overlay={popoverFor("hide", <span>Hide this connection from the list</span>)}>*/}
diff --git a/frontend/src/components/ConnectionContent.js b/frontend/src/components/ConnectionContent.js
index 20ec92b..0c00e8e 100644
--- a/frontend/src/components/ConnectionContent.js
+++ b/frontend/src/components/ConnectionContent.js
@@ -1,8 +1,8 @@
import React, {Component} from 'react';
import './ConnectionContent.scss';
import {Button, Dropdown, Row} from 'react-bootstrap';
-import axios from 'axios';
import MessageAction from "./MessageAction";
+import backend from "../backend";
const classNames = require('classnames');
@@ -27,9 +27,9 @@ class ConnectionContent extends Component {
this.props.connection !== prevProps.connection || this.state.format !== prevState.format)) {
this.setState({loading: true});
// TODO: limit workaround.
- axios.get(`/api/streams/${this.props.connection.id}?format=${this.state.format}&limit=999999`).then(res => {
+ backend.get(`/api/streams/${this.props.connection.id}?format=${this.state.format}&limit=999999`).then(res => {
this.setState({
- connectionContent: res.data,
+ connectionContent: res,
loading: false
});
});
diff --git a/frontend/src/components/fields/StringField.js b/frontend/src/components/fields/StringField.js
new file mode 100644
index 0000000..09fe24d
--- /dev/null
+++ b/frontend/src/components/fields/StringField.js
@@ -0,0 +1,31 @@
+import React, {Component} from 'react';
+import './StringField.scss';
+
+const classNames = require('classnames');
+
+class StringField extends Component {
+
+ render() {
+ return (
+ <div className={classNames("field", "d-inline-block", {"field-active" : this.props.isActive},
+ {"field-invalid": this.props.isInvalid})}>
+ <div className="input-group">
+ <div className="field-name-wrapper">
+ <span className="field-name" id={`field-${this.props.name}`}>{this.props.name}:</span>
+ </div>
+ <input placeholder={this.props.defaultValue} aria-label={this.props.name}
+ aria-describedby={`filter-${this.props.name}`} className="field-value"
+ onChange={this.props.onValueChanged} value={this.props.value} />
+ </div>
+
+ { this.props.active &&
+ <div className="field-clear">
+ <span className="filter-delete-icon" onClick={() => this.props.onValueChanged("")}>del</span>
+ </div>
+ }
+ </div>
+ );
+ }
+}
+
+export default StringField;
diff --git a/frontend/src/components/fields/StringField.scss b/frontend/src/components/fields/StringField.scss
new file mode 100644
index 0000000..7efac56
--- /dev/null
+++ b/frontend/src/components/fields/StringField.scss
@@ -0,0 +1,66 @@
+@import '../../colors.scss';
+
+.field {
+ margin: 0 10px;
+ position: relative;
+
+ .field-name-wrapper {
+ background-color: $color-primary-2;
+ padding: 3px 7px;
+ border-top-left-radius: 5px;
+ border-bottom-left-radius: 5px;
+ }
+
+ .field-name {
+ font-size: 13px;
+ }
+
+ .field-value {
+ font-size: 13px;
+ padding-left: 0;
+ border-radius: 5px;
+
+ &:focus {
+ background-color: $color-primary-2;
+ }
+ }
+
+ &.field-active {
+ .field-name-wrapper {
+ background-color: $color-primary-4;
+ color: $color-primary-3;
+ }
+
+ .field-value {
+ background-color: $color-primary-4;
+ color: $color-primary-3;
+ }
+ }
+
+ &.field-invalid {
+ .field-name-wrapper {
+ background-color: $color-secondary-2;
+ color: $color-primary-4;
+ }
+
+ .field-value {
+ background-color: $color-secondary-2;
+ color: $color-primary-4;
+ }
+ }
+
+ .field-delete {
+ position: absolute;
+ right: 10px;
+ top: 10px;
+ z-index: 10;
+ font-size: 11px;
+ letter-spacing: -0.5px;
+ color: $color-primary-2;
+ cursor: pointer;
+
+ .field-delete-icon {
+ font-weight: 800;
+ }
+ }
+}
diff --git a/frontend/src/components/filters/FiltersDefinitions.js b/frontend/src/components/filters/FiltersDefinitions.js
index a582d02..d36792e 100644
--- a/frontend/src/components/filters/FiltersDefinitions.js
+++ b/frontend/src/components/filters/FiltersDefinitions.js
@@ -21,49 +21,60 @@ export const filtersDefinitions = {
service_port: <StringConnectionsFilter filterName="service_port"
defaultFilterValue="all_ports"
replaceFunc={cleanNumber}
- validateFunc={validatePort}/>,
+ validateFunc={validatePort}
+ key="service_port_filter" />,
matched_rules: <RulesConnectionsFilter />,
client_address: <StringConnectionsFilter filterName="client_address"
defaultFilterValue="all_addresses"
- validateFunc={validateIpAddress} />,
+ validateFunc={validateIpAddress}
+ key="client_address_filter" />,
client_port: <StringConnectionsFilter filterName="client_port"
defaultFilterValue="all_ports"
replaceFunc={cleanNumber}
- validateFunc={validatePort}/>,
+ validateFunc={validatePort}
+ key="client_port_filter" />,
min_duration: <StringConnectionsFilter filterName="min_duration"
defaultFilterValue="0"
replaceFunc={cleanNumber}
- validateFunc={validateMin(0)}/>,
+ validateFunc={validateMin(0)}
+ key="min_duration_filter" />,
max_duration: <StringConnectionsFilter filterName="max_duration"
defaultFilterValue="∞"
- replaceFunc={cleanNumber} />,
+ replaceFunc={cleanNumber}
+ key="max_duration_filter" />,
min_bytes: <StringConnectionsFilter filterName="min_bytes"
defaultFilterValue="0"
replaceFunc={cleanNumber}
- validateFunc={validateMin(0)} />,
+ validateFunc={validateMin(0)}
+ key="min_bytes_filter" />,
max_bytes: <StringConnectionsFilter filterName="max_bytes"
defaultFilterValue="∞"
- replaceFunc={cleanNumber} />,
+ replaceFunc={cleanNumber}
+ key="max_bytes_filter" />,
started_after: <StringConnectionsFilter filterName="started_after"
defaultFilterValue="00:00:00"
validateFunc={validate24HourTime}
encodeFunc={timeToTimestamp}
- decodeFunc={timestampToTime} />,
+ decodeFunc={timestampToTime}
+ key="started_after_filter" />,
started_before: <StringConnectionsFilter filterName="started_before"
defaultFilterValue="00:00:00"
validateFunc={validate24HourTime}
encodeFunc={timeToTimestamp}
- decodeFunc={timestampToTime} />,
+ decodeFunc={timestampToTime}
+ key="started_before_filter" />,
closed_after: <StringConnectionsFilter filterName="closed_after"
defaultFilterValue="00:00:00"
validateFunc={validate24HourTime}
encodeFunc={timeToTimestamp}
- decodeFunc={timestampToTime} />,
+ decodeFunc={timestampToTime}
+ key="closed_after_filter" />,
closed_before: <StringConnectionsFilter filterName="closed_before"
defaultFilterValue="00:00:00"
validateFunc={validate24HourTime}
encodeFunc={timeToTimestamp}
- decodeFunc={timestampToTime} />,
+ decodeFunc={timestampToTime}
+ key="closed_before_filter" />,
marked: <BooleanConnectionsFilter filterName={"marked"} />,
hidden: <BooleanConnectionsFilter filterName={"hidden"} />
};
diff --git a/frontend/src/components/filters/RulesConnectionsFilter.js b/frontend/src/components/filters/RulesConnectionsFilter.js
index 358085f..621b6d6 100644
--- a/frontend/src/components/filters/RulesConnectionsFilter.js
+++ b/frontend/src/components/filters/RulesConnectionsFilter.js
@@ -3,7 +3,7 @@ import {withRouter} from "react-router-dom";
import {Redirect} from "react-router";
import './RulesConnectionsFilter.scss';
import ReactTags from 'react-tag-autocomplete';
-import axios from 'axios';
+import backend from "../../backend";
const classNames = require('classnames');
@@ -24,8 +24,8 @@ class RulesConnectionsFilter extends Component {
let params = new URLSearchParams(this.props.location.search);
let activeRules = params.getAll("matched_rules") || [];
- axios.get("/api/rules").then(res => {
- let rules = res.data.flatMap(rule => rule.enabled ? [{id: rule.id, name: rule.name}] : []);
+ backend.get("/api/rules").then(res => {
+ let rules = res.flatMap(rule => rule.enabled ? [{id: rule.id, name: rule.name}] : []);
activeRules = rules.filter(rule => activeRules.some(id => rule.id === id));
this.setState({rules, activeRules, mounted: true});
});
diff --git a/frontend/src/components/panels/PcapPane.js b/frontend/src/components/panels/PcapPane.js
new file mode 100644
index 0000000..817c7b5
--- /dev/null
+++ b/frontend/src/components/panels/PcapPane.js
@@ -0,0 +1,121 @@
+import React, {Component} from 'react';
+import './PcapPane.scss';
+import Table from "react-bootstrap/Table";
+import backend from "../../backend";
+import {formatSize, timestampToTime2} from "../../utils";
+import {Container, Row, Col, Form} from "react-bootstrap";
+import StringField from "../fields/StringField";
+
+class PcapPane extends Component {
+
+ constructor(props) {
+ super(props);
+
+ this.state = {
+ sessions: [],
+ };
+
+ this.loadSessions = this.loadSessions.bind(this);
+ }
+
+ componentDidMount() {
+ this.loadSessions();
+ }
+
+ loadSessions() {
+ backend.get("/api/pcap/sessions").then(res => this.setState({sessions: res}));
+ }
+
+ render() {
+ let sessions = this.state.sessions.map(s =>
+ <tr className="table-row">
+ <td>{s["id"].substring(0, 8)}</td>
+ <td>{timestampToTime2(s["started_at"])}</td>
+ <td>{((new Date(s["completed_at"]) - new Date(s["started_at"])) / 1000).toFixed(3)}s</td>
+ <td>{formatSize(s["size"])}</td>
+ <td>{s["processed_packets"]}</td>
+ <td>{s["invalid_packets"]}</td>
+ <td>undefined</td>
+ <td className="table-cell-action"><a target="_blank" href={"/api/pcap/sessions/" + s["id"] + "/download"}>download</a></td>
+ </tr>
+ );
+
+ return (
+ <div className="pane-container">
+ <div className="pane-section">
+ <div className="section-header">
+ <span className="api-request">GET /api/pcap/sessions</span>
+ <span className="api-response">200 OK</span>
+ </div>
+
+ <div className="section-table">
+ <Table borderless size="sm">
+ <thead>
+ <tr>
+ <th>id</th>
+ <th>started_at</th>
+ <th>duration</th>
+ <th>size</th>
+ <th>processed_packets</th>
+ <th>invalid_packets</th>
+ <th>packets_per_service</th>
+ <th>actions</th>
+ </tr>
+ </thead>
+ <tbody>
+ {sessions}
+ </tbody>
+ </Table>
+ </div>
+ </div>
+
+ <div className="pane-section">
+ <Container className="p-0">
+ <Row>
+ <Col>
+ <div className="section-header">
+ <span className="api-request">POST /api/pcap/upload</span>
+ <span className="api-response"></span>
+ </div>
+
+ <div className="section-content">
+ <Form.File className="custom-file" onChange={this.onFileChange}
+ label=".pcap/.pcapng" id="custom-file"
+ custom={true}
+ />
+
+
+ <br/><br/><br/><br/>
+ <StringField />
+
+ </div>
+ </Col>
+
+ <Col>
+ <div className="section-header">
+ <span className="api-request">POST /api/pcap/file</span>
+ <span className="api-response"></span>
+ </div>
+
+ <div className="section-content">
+ <Form.Control type="text" id="pcap-upload" className="custom-file"
+ onChange={this.onLocalFileChange} placeholder="local .pcap/.pcapng"
+ custom
+ />
+ </div>
+ </Col>
+ </Row>
+ </Container>
+
+
+
+
+ </div>
+
+ </div>
+
+ );
+ }
+}
+
+export default PcapPane;
diff --git a/frontend/src/components/panels/PcapPane.scss b/frontend/src/components/panels/PcapPane.scss
new file mode 100644
index 0000000..3df87f5
--- /dev/null
+++ b/frontend/src/components/panels/PcapPane.scss
@@ -0,0 +1,55 @@
+@import '../../colors.scss';
+
+.pane-container {
+ background-color: $color-primary-3;
+ padding: 10px 10px 0;
+ height: 100%;
+
+ .section-header {
+ background-color: $color-primary-2;
+ padding: 5px 10px;
+ height: 31px;
+
+ font-weight: 500;
+ font-size: 14px;
+
+ .api-response {
+ float: right;
+ }
+ }
+
+ .section-table {
+ margin-top: 10px;
+
+ .table-row {
+ background-color: $color-primary-0;
+ border-top: 3px solid $color-primary-3;
+ border-bottom: 3px solid $color-primary-3;
+ }
+
+ .table-cell-action {
+ font-size: 13px;
+ font-weight: 600;
+ }
+ }
+
+ .section-content {
+ background-color: $color-primary-0;
+ padding: 10px;
+ }
+
+
+
+ th {
+ background-color: $color-primary-2;
+ border-top: 3px solid $color-primary-3;
+ border-bottom: 3px solid $color-primary-3;
+ font-size: 13.5px;
+ position: sticky;
+ top: 10px;
+ padding: 5px;
+ }
+
+
+
+} \ No newline at end of file
diff --git a/frontend/src/index.scss b/frontend/src/index.scss
index 53ce4dd..358fd70 100644
--- a/frontend/src/index.scss
+++ b/frontend/src/index.scss
@@ -49,14 +49,62 @@ pre {
}
.btn-red {
- color: $color-secondary-4;
- background-color: $color-secondary-2;
- border-bottom: 5px solid $color-secondary-1;
+ color: $color-red-light;
+ background-color: $color-red;
+ border-bottom: 5px solid $color-red-dark;
&:hover,
&:active {
- color: $color-secondary-4;
- background-color: $color-secondary-1;
+ color: $color-red-light;
+ background-color: $color-red-dark;
+ }
+}
+
+.btn-pink {
+ color: $color-pink-light;
+ background-color: $color-pink;
+ border-bottom: 5px solid $color-pink-dark;
+
+ &:hover,
+ &:active {
+ color: $color-pink-light;
+ background-color: $color-pink-dark;
+ }
+}
+
+.btn-purple {
+ color: $color-purple-light;
+ background-color: $color-purple;
+ border-bottom: 5px solid $color-purple-dark;
+
+ &:hover,
+ &:active {
+ color: $color-purple-light;
+ background-color: $color-purple-dark;
+ }
+}
+
+.btn-deep-purple {
+ color: $color-deep-purple-light;
+ background-color: $color-deep-purple;
+ border-bottom: 5px solid $color-deep-purple-dark;
+
+ &:hover,
+ &:active {
+ color: $color-deep-purple-light;
+ background-color: $color-deep-purple-dark;
+ }
+}
+
+.btn-indigo {
+ color: $color-indigo-light;
+ background-color: $color-indigo;
+ border-bottom: 5px solid $color-indigo-dark;
+
+ &:hover,
+ &:active {
+ color: $color-indigo-light;
+ background-color: $color-indigo-dark;
}
}
diff --git a/frontend/src/utils.js b/frontend/src/utils.js
index 7381f69..4991755 100644
--- a/frontend/src/utils.js
+++ b/frontend/src/utils.js
@@ -64,3 +64,21 @@ export function timestampToDateTime(timestamp) {
let d = new Date(timestamp);
return d.toLocaleDateString() + " " + d.toLocaleTimeString();
}
+
+export function timestampToTime2(timestamp) {
+ let d = new Date(timestamp);
+ let hours = d.getHours();
+ let minutes = "0" + d.getMinutes();
+ let seconds = "0" + d.getSeconds();
+ return hours + ':' + minutes.substr(-2) + ':' + seconds.substr(-2);
+}
+
+export function formatSize(size) {
+ if (size < 1000) {
+ return `${size}`;
+ } else if (size < 1000000) {
+ return `${(size / 1000).toFixed(1)}K`;
+ } else {
+ return `${(size / 1000000).toFixed(1)}M`;
+ }
+}
diff --git a/frontend/src/views/Config.js b/frontend/src/views/Config.js
index f5766eb..a770378 100644
--- a/frontend/src/views/Config.js
+++ b/frontend/src/views/Config.js
@@ -1,10 +1,6 @@
-import {
- validateIpAddress,
-} from "../utils";
-import React, {Component, useState} from 'react';
+import React, {Component} from 'react';
import './Config.scss';
-import {Button, ButtonGroup, ToggleButton, Col, Container, Form, FormControl, InputGroup, Modal, Row, Table} from "react-bootstrap";
-import {createCurlCommand} from '../utils';
+import {Button, ButtonGroup, Col, Container, Form, Modal, Row, Table, ToggleButton} from "react-bootstrap";
class Config extends Component {
diff --git a/frontend/src/views/Connections.js b/frontend/src/views/Connections.js
index 62733d7..da8958b 100644
--- a/frontend/src/views/Connections.js
+++ b/frontend/src/views/Connections.js
@@ -1,10 +1,10 @@
import React, {Component} from 'react';
import './Connections.scss';
-import axios from 'axios';
import Connection from "../components/Connection";
import Table from 'react-bootstrap/Table';
import {Redirect} from 'react-router';
import {withRouter} from "react-router-dom";
+import backend from "../backend";
class Connections extends Component {
@@ -75,15 +75,15 @@ class Connections extends Component {
}
this.setState({loading: true, prevParams: params});
- let res = await axios.get(`${url}?${urlParams}`);
+ let res = await backend.get(`${url}?${urlParams}`);
let connections = this.state.connections;
let firstConnection = this.state.firstConnection;
let lastConnection = this.state.lastConnection;
if (params !== undefined && params.from !== undefined) {
- if (res.data.length > 0) {
- connections = this.state.connections.concat(res.data);
+ if (res.length > 0) {
+ connections = this.state.connections.concat(res);
lastConnection = connections[connections.length - 1];
if (connections.length > this.maxConnections) {
connections = connections.slice(connections.length - this.maxConnections,
@@ -92,8 +92,8 @@ class Connections extends Component {
}
}
} else if (params !== undefined && params.to !== undefined) {
- if (res.data.length > 0) {
- connections = res.data.concat(this.state.connections);
+ if (res.length > 0) {
+ connections = res.concat(this.state.connections);
firstConnection = connections[0];
if (connections.length > this.maxConnections) {
connections = connections.slice(0, this.maxConnections);
@@ -101,8 +101,8 @@ class Connections extends Component {
}
}
} else {
- if (res.data.length > 0) {
- connections = res.data;
+ if (res.length > 0) {
+ connections = res;
firstConnection = connections[0];
lastConnection = connections[connections.length - 1];
} else {
@@ -115,8 +115,7 @@ class Connections extends Component {
let flagRule = this.state.flagRule;
let rules = this.state.rules;
if (flagRule === null) {
- let res = await axios.get("/api/rules");
- rules = res.data;
+ rules = await backend.get("/api/rules");
flagRule = rules.filter(rule => {
return rule.name === "flag";
})[0];
@@ -125,7 +124,7 @@ class Connections extends Component {
this.setState({
loading: false,
connections: connections,
- rules: res.data,
+ rules: res,
flagRule: flagRule,
firstConnection: firstConnection,
lastConnection: lastConnection
@@ -134,7 +133,7 @@ class Connections extends Component {
render() {
let redirect;
- let queryString = this.state.queryString !== null ? this.state.queryString : ""
+ let queryString = this.state.queryString !== null ? this.state.queryString : "";
if (this.state.selected) {
let format = this.props.match.params.format;
format = format !== undefined ? "/" + format : "";
diff --git a/frontend/src/views/Footer.js b/frontend/src/views/Footer.js
index b6ffd9d..0a3c5a3 100644
--- a/frontend/src/views/Footer.js
+++ b/frontend/src/views/Footer.js
@@ -8,11 +8,11 @@ class Footer extends Component {
<footer className="footer container-fluid">
<div className="row">
<div className="col-12">
- <div className="footer-timeline">timeline</div>
+ <div className="footer-timeline">timeline - <a href="https://github.com/eciavatta/caronte/issues/12">to be implemented</a></div>
</div>
</div>
</footer>
- )
+ );
}
}
diff --git a/frontend/src/views/Header.js b/frontend/src/views/Header.js
index 0af7abf..5860d80 100644
--- a/frontend/src/views/Header.js
+++ b/frontend/src/views/Header.js
@@ -69,12 +69,12 @@ class Header extends Component {
<div className="col">
<div className="header-buttons">
- <Button onClick={this.props.onOpenFilters}>filters</Button>
- <Button variant="warning" onClick={this.props.onOpenUpload}>pcaps</Button>
- <Button variant="blue" onClick={this.props.onOpenRules}>rules</Button>
- <Button variant="red" onClick={this.props.onOpenServices}>services</Button>
- <Button variant="green" onClick={this.props.onOpenConfig}
- disabled={this.props.onConfigDone}>config</Button>
+ <Button variant="pink" onClick={this.props.onOpenFilters}>filters</Button>
+ <Button variant="purple" onClick={this.props.onOpenUpload}>pcaps</Button>
+ <Button variant="deep-purple" onClick={this.props.onOpenRules}>rules</Button>
+ <Button variant="indigo" onClick={this.props.onOpenServices}>services</Button>
+ <Button variant="blue" onClick={this.props.onOpenConfig}
+ disabled={false}>config</Button>
</div>
</div>
</div>
diff --git a/frontend/src/views/Header.scss b/frontend/src/views/Header.scss
index e84e758..e36b2d6 100644
--- a/frontend/src/views/Header.scss
+++ b/frontend/src/views/Header.scss
@@ -16,6 +16,10 @@
.header-buttons {
margin: 5px 0;
text-align: right;
+
+ button {
+ margin-left: 10px;
+ }
}
.filters-bar-wrapper {
diff --git a/frontend/src/views/MainPane.js b/frontend/src/views/MainPane.js
index 69de725..3c0d795 100644
--- a/frontend/src/views/MainPane.js
+++ b/frontend/src/views/MainPane.js
@@ -3,7 +3,8 @@ import './MainPane.scss';
import Connections from "./Connections";
import ConnectionContent from "../components/ConnectionContent";
import {withRouter} from "react-router-dom";
-import axios from 'axios';
+import PcapPane from "../components/panels/PcapPane";
+import backend from "../backend";
class MainPane extends Component {
@@ -17,9 +18,9 @@ class MainPane extends Component {
componentDidMount() {
if ('id' in this.props.match.params) {
const id = this.props.match.params.id;
- axios.get(`/api/connections/${id}`).then(res => {
+ backend.get(`/api/connections/${id}`).then(res => {
if (res.status === 200) {
- this.setState({selectedConnection: res.data});
+ this.setState({selectedConnection: res});
}
});
}
@@ -34,6 +35,7 @@ class MainPane extends Component {
<Connections onSelected={(c) => this.setState({selectedConnection: c})} />
</div>
<div className="col-md-6 pl-0 pane">
+ {/*<PcapPane />*/}
<ConnectionContent connection={this.state.selectedConnection}/>
</div>
</div>
diff --git a/frontend/src/views/Rules.js b/frontend/src/views/Rules.js
index 3424410..bbc3bb6 100644
--- a/frontend/src/views/Rules.js
+++ b/frontend/src/views/Rules.js
@@ -1,7 +1,7 @@
import React, {Component} from 'react';
import './Services.scss';
import {Button, ButtonGroup, Col, Container, Form, FormControl, InputGroup, Modal, Row, Table} from "react-bootstrap";
-import axios from "axios";
+import backend from "../backend";
class Rules extends Component {
@@ -18,7 +18,7 @@ class Rules extends Component {
}
loadRules() {
- axios.get("/api/rules").then(res => this.setState({rules: res.data}));
+ backend.get("/api/rules").then(res => this.setState({rules: res.data}));
}
render() {
diff --git a/frontend/src/views/Services.js b/frontend/src/views/Services.js
index 0de021f..22d61b3 100644
--- a/frontend/src/views/Services.js
+++ b/frontend/src/views/Services.js
@@ -1,8 +1,8 @@
import React, {Component} from 'react';
import './Services.scss';
import {Button, ButtonGroup, Col, Container, Form, FormControl, InputGroup, Modal, Row, Table} from "react-bootstrap";
-import axios from 'axios'
import {createCurlCommand} from '../utils';
+import backend from "../backend";
class Services extends Component {
@@ -64,31 +64,20 @@ class Services extends Component {
saveService() {
if (this.state.portValid && this.state.nameValid) {
- const requestOptions = {
- method: 'PUT',
- headers: { 'Content-Type': 'application/json' },
- body: JSON.stringify({
- color: this.state.color,
- name: this.state.name,
- notes: this.state.notes,
- port: this.state.port,
- })
- };
-
-
- fetch('/api/services', requestOptions)
- .then(function(response){
- console.log(response);
- }
- );
-
- this.newService();
- this.loadServices();
+ backend.put("/api/services", {
+ color: this.state.color,
+ name: this.state.name,
+ notes: this.state.notes,
+ port: this.state.port,
+ }).then(_ => {
+ this.newService();
+ this.loadServices();
+ });
}
}
loadServices() {
- axios.get("/api/services").then(res => this.setState({services: res.data}));
+ backend.get("/api/services").then(res => this.setState({services: res}));
}
componentDidUpdate(prevProps, prevState, snapshot) {