Skip to content

Commit 96b05c9

Browse files
committed
few UI tweaks on the payloads page for better output viewing
1 parent 83f81c9 commit 96b05c9

16 files changed

+125
-226
lines changed

MythicReactUI/CHANGELOG.MD

+6
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file.
44
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
55
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
66

7+
## [0.2.61] - 2024-11-27
8+
9+
### Changed
10+
11+
- Updated the payloads' page modal boxes to reduce blank space and provide the same text feel as task output
12+
713
## [0.2.60] - 2024-11-26
814

915
### Changed

MythicReactUI/src/components/pages/PayloadTypesC2Profiles/C2ProfileOutputDialog.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ export function C2ProfileOutputDialog(props) {
5151
<div style={{height: "calc(80vh)", overflowY: "auto"}}>
5252
<ResponseDisplayPlaintext
5353
initial_mode={"json"}
54-
render_colors={true}
54+
render_colors={false}
5555
wrap_text={false}
5656
plaintext={outputData}
5757
expand={true}/>
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,10 @@
11
import React, {useState, useEffect} from 'react';
22
import Button from '@mui/material/Button';
33
import DialogActions from '@mui/material/DialogActions';
4-
import DialogContent from '@mui/material/DialogContent';
54
import DialogTitle from '@mui/material/DialogTitle';
65
import {useQuery, gql} from '@apollo/client';
76
import LinearProgress from '@mui/material/LinearProgress';
8-
import AceEditor from 'react-ace';
9-
import 'ace-builds/src-noconflict/mode-json';
10-
import 'ace-builds/src-noconflict/theme-monokai';
11-
import 'ace-builds/src-noconflict/theme-xcode';
12-
import "ace-builds/src-noconflict/ext-searchbox";
13-
import {useTheme} from '@mui/material/styles';
7+
import {ResponseDisplayPlaintext} from "../Callbacks/ResponseDisplayPlaintext";
148

159
const getDescriptionQuery = gql`
1610
query getDescriptionQuery ($payload_id: Int!) {
@@ -24,9 +18,8 @@ query getDescriptionQuery ($payload_id: Int!) {
2418
`;
2519

2620
export function PayloadBuildMessageDialog(props) {
27-
const [payloadData, setPayloadData] = useState({});
21+
const [payloadData, setPayloadData] = useState({"error": "", "message": ""});
2822
const [viewError, setViewError] = useState(false);
29-
const theme = useTheme();
3023
const { loading, error } = useQuery(getDescriptionQuery, {
3124
variables: {payload_id: props.payload_id},
3225
onCompleted: data => {
@@ -51,32 +44,23 @@ export function PayloadBuildMessageDialog(props) {
5144
}
5245

5346
return (
54-
<React.Fragment>
55-
<DialogTitle id="form-dialog-title">Payload Build Messages</DialogTitle>
56-
<DialogContent dividers={true}>
57-
<AceEditor
58-
mode="text"
59-
theme={theme.palette.mode === "dark" ? "monokai" : "xcode"}
60-
fontSize={14}
61-
showGutter={true}
62-
height={"100px"}
63-
highlightActiveLine={true}
64-
value={viewError ? payloadData["error"] : payloadData["message"]}
65-
width={"100%"}
66-
minLines={2}
67-
maxLines={50}
68-
setOptions={{
69-
showLineNumbers: true,
70-
tabSize: 4,
71-
useWorker: false
72-
}}/>
73-
</DialogContent>
74-
<DialogActions>
75-
<Button variant="contained" onClick={props.onClose} color="primary">
76-
Close
77-
</Button>
78-
</DialogActions>
79-
</React.Fragment>
47+
<React.Fragment>
48+
<DialogTitle id="form-dialog-title">Payload Build Messages</DialogTitle>
49+
<div style={{height: "calc(80vh)", overflowY: "auto"}}>
50+
<ResponseDisplayPlaintext
51+
initial_mode={"html"}
52+
render_colors={false}
53+
wrap_text={true}
54+
plaintext={viewError ? payloadData["error"] : payloadData["message"]}
55+
expand={true}
56+
/>
57+
</div>
58+
<DialogActions>
59+
<Button variant="contained" onClick={props.onClose} color="primary">
60+
Close
61+
</Button>
62+
</DialogActions>
63+
</React.Fragment>
8064
);
8165
}
8266

Original file line numberDiff line numberDiff line change
@@ -1,17 +1,11 @@
11
import React, {useState} from 'react';
22
import Button from '@mui/material/Button';
33
import DialogActions from '@mui/material/DialogActions';
4-
import DialogContent from '@mui/material/DialogContent';
54
import DialogTitle from '@mui/material/DialogTitle';
65
import {useQuery, gql} from '@apollo/client';
76
import LinearProgress from '@mui/material/LinearProgress';
87
import { snackActions } from '../../utilities/Snackbar';
9-
import AceEditor from 'react-ace';
10-
import 'ace-builds/src-noconflict/mode-json';
11-
import 'ace-builds/src-noconflict/theme-monokai';
12-
import 'ace-builds/src-noconflict/theme-xcode';
13-
import "ace-builds/src-noconflict/ext-searchbox";
14-
import {useTheme} from '@mui/material/styles';
8+
import {ResponseDisplayPlaintext} from "../Callbacks/ResponseDisplayPlaintext";
159

1610
const checkPayloadConfigurationQuery = gql`
1711
query checkPayloadConfigurationQuery($uuid: String!) {
@@ -25,7 +19,6 @@ query checkPayloadConfigurationQuery($uuid: String!) {
2519

2620
export function PayloadConfigCheckDialog(props) {
2721
const [message, setMessage] = useState("");
28-
const theme = useTheme();
2922
const { loading, error } = useQuery(checkPayloadConfigurationQuery, {
3023
variables: {uuid: props.uuid},
3124
onCompleted: data => {
@@ -48,32 +41,23 @@ export function PayloadConfigCheckDialog(props) {
4841
}
4942

5043
return (
51-
<React.Fragment>
52-
<DialogTitle id="form-dialog-title">Payload Config Check</DialogTitle>
53-
<DialogContent dividers={true}>
54-
<AceEditor
55-
mode="text"
56-
theme={theme.palette.mode === "dark" ? "monokai" : "xcode"}
57-
fontSize={14}
58-
showGutter={true}
59-
height={"100px"}
60-
highlightActiveLine={true}
61-
value={message}
62-
width={"100%"}
63-
minLines={2}
64-
maxLines={50}
65-
setOptions={{
66-
showLineNumbers: true,
67-
tabSize: 4,
68-
useWorker: false
69-
}}/>
70-
</DialogContent>
71-
<DialogActions>
72-
<Button variant="contained" onClick={props.onClose} color="primary">
73-
Close
74-
</Button>
75-
</DialogActions>
76-
</React.Fragment>
44+
<React.Fragment>
45+
<DialogTitle id="form-dialog-title">Payload Config Check</DialogTitle>
46+
<div style={{height: "calc(80vh)", overflowY: "auto"}}>
47+
<ResponseDisplayPlaintext
48+
initial_mode={"html"}
49+
render_colors={false}
50+
wrap_text={true}
51+
plaintext={message}
52+
expand={true}
53+
/>
54+
</div>
55+
<DialogActions>
56+
<Button variant="contained" onClick={props.onClose} color="primary">
57+
Close
58+
</Button>
59+
</DialogActions>
60+
</React.Fragment>
7761
);
7862
}
7963

MythicReactUI/src/components/pages/Payloads/PayloadDescriptionDialog.js

+16-29
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,9 @@
11
import React, {useState} from 'react';
2-
import Button from '@mui/material/Button';
3-
import DialogActions from '@mui/material/DialogActions';
4-
import DialogContent from '@mui/material/DialogContent';
5-
import DialogTitle from '@mui/material/DialogTitle';
6-
import MythicTextField from '../../MythicComponents/MythicTextField';
72
import {useQuery, gql, useMutation} from '@apollo/client';
83
import { snackActions } from '../../utilities/Snackbar';
94
import {MythicConfirmDialog} from "../../MythicComponents/MythicConfirmDialog";
105
import Typography from '@mui/material/Typography';
6+
import {MythicModifyStringDialog} from "../../MythicComponents/MythicDialog";
117

128
const updateDescriptionMutation = gql`
139
mutation updateDescription ($payload_id: Int!, $description: String) {
@@ -37,14 +33,14 @@ query getDescriptionQuery ($payload_id: Int!) {
3733
`;
3834

3935
export function PayloadDescriptionDialog(props) {
40-
const [description, setDescription] = useState("");
41-
const oldDescription = React.useRef();
36+
const description = React.useRef("");
37+
const [oldDescription, setOldDescription] = useState("");
4238
const hasCallbacks = React.useRef(false);
4339
useQuery(getDescriptionQuery, {
4440
variables: {payload_id: props.payload_id},
4541
onCompleted: data => {
46-
setDescription(data.payload_by_pk.description)
47-
oldDescription.current = data.payload_by_pk.description;
42+
description.current = data.payload_by_pk.description;
43+
setOldDescription(data.payload_by_pk.description);
4844
hasCallbacks.current = data.payload_by_pk.callbacks.length > 0;
4945
},
5046
fetchPolicy: "network-only"
@@ -81,43 +77,34 @@ export function PayloadDescriptionDialog(props) {
8177
setOpenUpdateAll(false);
8278
updateCallbackDescriptions({variables: {
8379
payloadID: props.payload_id,
84-
oldDescription: oldDescription.current,
85-
newDescription: description,
80+
oldDescription: oldDescription,
81+
newDescription: description.current,
8682
}});
8783
updatePayloadDescription();
8884
// now update all
8985
}
9086
const updatePayloadDescription = () => {
9187
setOpenUpdateAll(false);
92-
updateDescription({variables: {payload_id: props.payload_id, description: description}});
88+
updateDescription({variables: {payload_id: props.payload_id, description: description.current}});
9389
props.onClose();
9490
}
95-
const onCommitSubmit = () => {
91+
const onCommitSubmit = (updatedMessage) => {
92+
description.current = updatedMessage;
9693
if(hasCallbacks.current){
9794
setOpenUpdateAll(true);
9895
} else {
9996
updatePayloadDescription();
10097
}
10198

10299
}
103-
const onChange = (name, value, error) => {
104-
setDescription(value);
105-
}
106-
100+
107101
return (
108102
<React.Fragment>
109-
<DialogTitle id="form-dialog-title">Edit Payload Description</DialogTitle>
110-
<DialogContent dividers={true}>
111-
<MythicTextField autoFocus onChange={onChange} value={description} onEnter={onCommitSubmit}/>
112-
</DialogContent>
113-
<DialogActions>
114-
<Button variant="contained" onClick={props.onClose} color="primary">
115-
Close
116-
</Button>
117-
<Button variant="contained" onClick={onCommitSubmit} color="success">
118-
Submit
119-
</Button>
120-
</DialogActions>
103+
<MythicModifyStringDialog title={"Edit Payload Description"}
104+
maxRows={5}
105+
onClose={props.onClose}
106+
value={description.current}
107+
onSubmit={onCommitSubmit} />
121108
{openUpdateAll &&
122109
<MythicConfirmDialog title={"Update Associated Callback's Descriptions?"}
123110
dontCloseOnSubmit={true}

MythicReactUI/src/components/pages/Payloads/PayloadFilenameDialog.js

+9-23
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,9 @@
11
import React, {useState} from 'react';
2-
import Button from '@mui/material/Button';
3-
import DialogActions from '@mui/material/DialogActions';
4-
import DialogContent from '@mui/material/DialogContent';
5-
import DialogTitle from '@mui/material/DialogTitle';
6-
import MythicTextField from '../../MythicComponents/MythicTextField';
72
import {useQuery, gql, useMutation} from '@apollo/client';
83
import LinearProgress from '@mui/material/LinearProgress';
94
import { snackActions } from '../../utilities/Snackbar';
105
import {b64DecodeUnicode} from '../Callbacks/ResponseDisplay';
6+
import {MythicModifyStringDialog} from "../../MythicComponents/MythicDialog";
117

128
const updateDescriptionMutation = gql`
139
mutation updateDescription ($file_id: Int!, $filename: bytea!) {
@@ -52,28 +48,18 @@ export function PayloadFilenameDialog(props) {
5248
console.error(error);
5349
return <div>Error!</div>;
5450
}
55-
const onCommitSubmit = () => {
56-
updateDescription({variables: {file_id: fileId, filename: description}});
51+
const onCommitSubmit = (newDescription) => {
52+
updateDescription({variables: {file_id: fileId, filename: newDescription}});
5753
props.onClose();
5854
}
59-
const onChange = (name, value, error) => {
60-
setDescription(value);
61-
}
62-
55+
6356
return (
6457
<React.Fragment>
65-
<DialogTitle id="form-dialog-title">Edit Payload Filename</DialogTitle>
66-
<DialogContent dividers={true}>
67-
<MythicTextField autoFocus onChange={onChange} value={description} onEnter={onCommitSubmit}/>
68-
</DialogContent>
69-
<DialogActions>
70-
<Button variant="contained" onClick={props.onClose} color="primary">
71-
Close
72-
</Button>
73-
<Button variant="contained" onClick={onCommitSubmit} color="success">
74-
Submit
75-
</Button>
76-
</DialogActions>
58+
<MythicModifyStringDialog title={"Edit Payload Filename"}
59+
maxRows={2}
60+
onClose={props.onClose}
61+
value={description}
62+
onSubmit={onCommitSubmit} />
7763
</React.Fragment>
7864
);
7965
}
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,11 @@
11
import React, {useState} from 'react';
22
import Button from '@mui/material/Button';
33
import DialogActions from '@mui/material/DialogActions';
4-
import DialogContent from '@mui/material/DialogContent';
54
import DialogTitle from '@mui/material/DialogTitle';
65
import {useQuery, gql} from '@apollo/client';
76
import LinearProgress from '@mui/material/LinearProgress';
87
import { snackActions } from '../../utilities/Snackbar';
9-
import AceEditor from 'react-ace';
10-
import 'ace-builds/src-noconflict/mode-json';
11-
import 'ace-builds/src-noconflict/theme-monokai';
12-
import 'ace-builds/src-noconflict/theme-xcode';
13-
import "ace-builds/src-noconflict/ext-searchbox";
14-
import {useTheme} from '@mui/material/styles';
8+
import {ResponseDisplayPlaintext} from "../Callbacks/ResponseDisplayPlaintext";
159

1610
const generateIOCMutation = gql`
1711
query generateIOCQuery($uuid: String!) {
@@ -25,7 +19,6 @@ query generateIOCQuery($uuid: String!) {
2519

2620
export function PayloadGetIOCDialog(props) {
2721
const [message, setMessage] = useState("");
28-
const theme = useTheme();
2922
const { loading, error } = useQuery(generateIOCMutation, {
3023
variables: {uuid: props.uuid},
3124
onCompleted: data => {
@@ -48,32 +41,23 @@ export function PayloadGetIOCDialog(props) {
4841
}
4942

5043
return (
51-
<React.Fragment>
52-
<DialogTitle id="form-dialog-title">Payload Network IOCs</DialogTitle>
53-
<DialogContent dividers={true}>
54-
<AceEditor
55-
mode="text"
56-
theme={theme.palette.mode === "dark" ? "monokai" : "xcode"}
57-
fontSize={14}
58-
showGutter={true}
59-
height={"100px"}
60-
highlightActiveLine={true}
61-
value={message}
62-
width={"100%"}
63-
minLines={2}
64-
maxLines={50}
65-
setOptions={{
66-
showLineNumbers: true,
67-
tabSize: 4,
68-
useWorker: false
69-
}}/>
70-
</DialogContent>
71-
<DialogActions>
72-
<Button variant="contained" onClick={props.onClose} color="primary">
73-
Close
74-
</Button>
75-
</DialogActions>
76-
</React.Fragment>
44+
<React.Fragment>
45+
<DialogTitle id="form-dialog-title">Payload Network IOCs</DialogTitle>
46+
<div style={{height: "calc(80vh)", overflowY: "auto"}}>
47+
<ResponseDisplayPlaintext
48+
initial_mode={"html"}
49+
render_colors={false}
50+
wrap_text={true}
51+
plaintext={message}
52+
expand={true}
53+
/>
54+
</div>
55+
<DialogActions>
56+
<Button variant="contained" onClick={props.onClose} color="primary">
57+
Close
58+
</Button>
59+
</DialogActions>
60+
</React.Fragment>
7761
);
7862
}
7963

0 commit comments

Comments
 (0)