From d5f94b76986615b255b77b2a7b7ed336e5ad4838 Mon Sep 17 00:00:00 2001
From: Emiliano Ciavatta
Date: Wed, 7 Oct 2020 14:58:48 +0200
Subject: Implement notifications
---
frontend/src/components/panels/PcapPane.js | 33 ++++----
frontend/src/components/panels/RulePane.js | 116 ++++++++++++++------------
frontend/src/components/panels/ServicePane.js | 35 ++++----
frontend/src/components/panels/common.scss | 4 +-
4 files changed, 99 insertions(+), 89 deletions(-)
(limited to 'frontend/src/components/panels')
diff --git a/frontend/src/components/panels/PcapPane.js b/frontend/src/components/panels/PcapPane.js
index 31d8815..13f7cb3 100644
--- a/frontend/src/components/panels/PcapPane.js
+++ b/frontend/src/components/panels/PcapPane.js
@@ -9,28 +9,31 @@ import CheckField from "../fields/CheckField";
import TextField from "../fields/TextField";
import ButtonField from "../fields/ButtonField";
import LinkPopover from "../objects/LinkPopover";
+import dispatcher from "../../dispatcher";
class PcapPane extends Component {
- constructor(props) {
- super(props);
-
- this.state = {
- sessions: [],
- isUploadFileValid: true,
- isUploadFileFocused: false,
- uploadFlushAll: false,
- isFileValid: true,
- isFileFocused: false,
- fileValue: "",
- processFlushAll: false,
- deleteOriginalFile: false
- };
- }
+ state = {
+ sessions: [],
+ isUploadFileValid: true,
+ isUploadFileFocused: false,
+ uploadFlushAll: false,
+ isFileValid: true,
+ isFileFocused: false,
+ fileValue: "",
+ processFlushAll: false,
+ deleteOriginalFile: false
+ };
componentDidMount() {
this.loadSessions();
+ dispatcher.register("notifications", payload => {
+ if (payload.event === "pcap.upload" || payload.event === "pcap.file") {
+ this.loadSessions();
+ }
+ });
+
document.title = "caronte:~/pcaps$";
}
diff --git a/frontend/src/components/panels/RulePane.js b/frontend/src/components/panels/RulePane.js
index 4641378..76f3ac0 100644
--- a/frontend/src/components/panels/RulePane.js
+++ b/frontend/src/components/panels/RulePane.js
@@ -14,35 +14,13 @@ import ButtonField from "../fields/ButtonField";
import validation from "../../validation";
import LinkPopover from "../objects/LinkPopover";
import {randomClassName} from "../../utils";
+import dispatcher from "../../dispatcher";
const classNames = require('classnames');
const _ = require('lodash');
class RulePane extends Component {
- constructor(props) {
- super(props);
-
- this.state = {
- rules: [],
- newRule: this.emptyRule,
- newPattern: this.emptyPattern
- };
-
- this.directions = {
- 0: "both",
- 1: "c->s",
- 2: "s->c"
- };
- }
-
- componentDidMount() {
- this.reset();
- this.loadRules();
-
- document.title = "caronte:~/rules$";
- }
-
emptyRule = {
"name": "",
"color": "",
@@ -60,7 +38,6 @@ class RulePane extends Component {
},
"version": 0
};
-
emptyPattern = {
"regex": "",
"flags": {
@@ -74,6 +51,34 @@ class RulePane extends Component {
"max_occurrences": 0,
"direction": 0
};
+ state = {
+ rules: [],
+ newRule: this.emptyRule,
+ newPattern: this.emptyPattern
+ };
+
+ constructor(props) {
+ super(props);
+
+ this.directions = {
+ 0: "both",
+ 1: "c->s",
+ 2: "s->c"
+ };
+ }
+
+ componentDidMount() {
+ this.reset();
+ this.loadRules();
+
+ dispatcher.register("notifications", payload => {
+ if (payload.event === "rules.new" || payload.event === "rules.edit") {
+ this.loadRules();
+ }
+ });
+
+ document.title = "caronte:~/rules$";
+ }
loadRules = () => {
backend.get("/api/rules").then(res => this.setState({rules: res.json, rulesStatusCode: res.status}))
@@ -226,17 +231,17 @@ class RulePane extends Component {
{
this.reset();
this.setState({selectedRule: _.cloneDeep(r)});
- }} className={classNames("row-small", "row-clickable", {"row-selected": rule.id === r.id })}>
+ }} className={classNames("row-small", "row-clickable", {"row-selected": rule.id === r.id})}>
{r["id"].substring(0, 8)} |
{r["name"]} |
- |
+ |
{r["notes"]} |
);
let patterns = (this.state.selectedPattern == null && !isUpdate ?
- rule.patterns.concat(this.state.newPattern) :
- rule.patterns
+ rule.patterns.concat(this.state.newPattern) :
+ rule.patterns
).map(p => p === pattern ?
@@ -244,7 +249,7 @@ class RulePane extends Component {
onChange={(v) => {
this.updateParam(() => pattern.regex = v);
this.setState({patternRegexFocused: pattern.regex === ""});
- }} />
+ }}/>
|
this.updateParam(() => pattern.flags.caseless = v)}/> |
@@ -259,34 +264,35 @@ class RulePane extends Component {
this.updateParam(() => pattern.min_occurrences = v)} />
+ onChange={(v) => this.updateParam(() => pattern.min_occurrences = v)}/>
|
this.updateParam(() => pattern.max_occurrences = v)} />
+ onChange={(v) => this.updateParam(() => pattern.max_occurrences = v)}/>
|
s", "s->c"]}
value={this.directions[pattern.direction]}
- onChange={(v) => this.updateParam(() => pattern.direction = v)} /> |
+ onChange={(v) => this.updateParam(() => pattern.direction = v)}/>
{this.state.selectedPattern == null ?
this.addPattern(p)}/> :
- this.updatePattern(p)}/>}
+ this.updatePattern(p)}/>}
|
:
{p.regex} |
- {p.flags.caseless ? "yes": "no"} |
- {p.flags.dot_all ? "yes": "no"} |
- {p.flags.multi_line ? "yes": "no"} |
- {p.flags.utf_8_mode ? "yes": "no"} |
- {p.flags.unicode_property ? "yes": "no"} |
+ {p.flags.caseless ? "yes" : "no"} |
+ {p.flags.dot_all ? "yes" : "no"} |
+ {p.flags.multi_line ? "yes" : "no"} |
+ {p.flags.utf_8_mode ? "yes" : "no"} |
+ {p.flags.unicode_property ? "yes" : "no"} |
{p.min_occurrences} |
{p.max_occurrences} |
{this.directions[p.direction]} |
{!isUpdate && this.editPattern(p) }/> | }
+ onClick={() => this.editPattern(p)}/>}
);
@@ -296,9 +302,9 @@ class RulePane extends Component {
GET /api/rules
{this.state.rulesStatusCode &&
- }
+ }
@@ -327,7 +333,7 @@ class RulePane extends Component {
+ placement="left"/>
@@ -336,11 +342,11 @@ class RulePane extends Component {
this.updateParam((r) => r.name = v)}
- error={this.state.ruleNameError} />
+ error={this.state.ruleNameError}/>
this.updateParam((r) => r.color = v)} />
+ onChange={(v) => this.updateParam((r) => r.color = v)}/>
this.updateParam((r) => r.notes = v)} />
+ onChange={(v) => this.updateParam((r) => r.notes = v)}/>
@@ -348,29 +354,29 @@ class RulePane extends Component {
this.updateParam((r) => r.filter.service_port = v)}
min={0} max={65565} error={this.state.ruleServicePortError}
- readonly={isUpdate} />
+ readonly={isUpdate}/>
this.updateParam((r) => r.filter.client_port = v)}
min={0} max={65565} error={this.state.ruleClientPortError}
- readonly={isUpdate} />
+ readonly={isUpdate}/>
this.updateParam((r) => r.filter.client_address = v)} />
+ onChange={(v) => this.updateParam((r) => r.filter.client_address = v)}/>
this.updateParam((r) => r.filter.min_duration = v)} />
+ onChange={(v) => this.updateParam((r) => r.filter.min_duration = v)}/>
this.updateParam((r) => r.filter.max_duration = v)} />
+ onChange={(v) => this.updateParam((r) => r.filter.max_duration = v)}/>
this.updateParam((r) => r.filter.min_bytes = v)} />
+ onChange={(v) => this.updateParam((r) => r.filter.min_bytes = v)}/>
this.updateParam((r) => r.filter.max_bytes = v)} />
+ onChange={(v) => this.updateParam((r) => r.filter.max_bytes = v)}/>
@@ -388,7 +394,7 @@ class RulePane extends Component {
min |
max |
direction |
- {!isUpdate && actions | }
+ {!isUpdate && actions | }
@@ -403,7 +409,7 @@ class RulePane extends Component {
{}
+ bordered onClick={isUpdate ? this.updateRule : this.addRule}/>
diff --git a/frontend/src/components/panels/ServicePane.js b/frontend/src/components/panels/ServicePane.js
index 0e99652..22c6655 100644
--- a/frontend/src/components/panels/ServicePane.js
+++ b/frontend/src/components/panels/ServicePane.js
@@ -12,28 +12,13 @@ import ButtonField from "../fields/ButtonField";
import validation from "../../validation";
import LinkPopover from "../objects/LinkPopover";
import {createCurlCommand} from "../../utils";
+import dispatcher from "../../dispatcher";
const classNames = require('classnames');
const _ = require('lodash');
class ServicePane extends Component {
- constructor(props) {
- super(props);
-
- this.state = {
- services: [],
- currentService: this.emptyService,
- };
-
- document.title = "caronte:~/services$";
- }
-
- componentDidMount() {
- this.reset();
- this.loadServices();
- }
-
emptyService = {
"port": 0,
"name": "",
@@ -41,6 +26,24 @@ class ServicePane extends Component {
"notes": ""
};
+ state = {
+ services: [],
+ currentService: this.emptyService,
+ };
+
+ componentDidMount() {
+ this.reset();
+ this.loadServices();
+
+ dispatcher.register("notifications", payload => {
+ if (payload.event === "services.edit") {
+ this.loadServices();
+ }
+ });
+
+ document.title = "caronte:~/services$";
+ }
+
loadServices = () => {
backend.get("/api/services")
.then(res => this.setState({services: Object.values(res.json), servicesStatusCode: res.status}))
diff --git a/frontend/src/components/panels/common.scss b/frontend/src/components/panels/common.scss
index 121a917..1468f35 100644
--- a/frontend/src/components/panels/common.scss
+++ b/frontend/src/components/panels/common.scss
@@ -2,11 +2,9 @@
.pane-container {
height: 100%;
- padding: 10px 10px 0;
background-color: $color-primary-3;
.pane-section {
- margin-bottom: 10px;
background-color: $color-primary-0;
.section-header {
@@ -14,7 +12,7 @@
font-weight: 500;
display: flex;
padding: 5px 10px;
- background-color: $color-primary-2;
+ background-color: $color-primary-3;
.api-request {
flex: 1;
--
cgit v1.2.3-70-g09d2