Skip to content

Commit

Permalink
few UI tweaks on the payloads page for better output viewing
Browse files Browse the repository at this point in the history
  • Loading branch information
its-a-feature committed Nov 27, 2024
1 parent 83f81c9 commit 96b05c9
Show file tree
Hide file tree
Showing 16 changed files with 125 additions and 226 deletions.
6 changes: 6 additions & 0 deletions MythicReactUI/CHANGELOG.MD
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [0.2.61] - 2024-11-27

### Changed

- Updated the payloads' page modal boxes to reduce blank space and provide the same text feel as task output

## [0.2.60] - 2024-11-26

### Changed
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ export function C2ProfileOutputDialog(props) {
<div style={{height: "calc(80vh)", overflowY: "auto"}}>
<ResponseDisplayPlaintext
initial_mode={"json"}
render_colors={true}
render_colors={false}
wrap_text={false}
plaintext={outputData}
expand={true}/>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,10 @@
import React, {useState, useEffect} from 'react';
import Button from '@mui/material/Button';
import DialogActions from '@mui/material/DialogActions';
import DialogContent from '@mui/material/DialogContent';
import DialogTitle from '@mui/material/DialogTitle';
import {useQuery, gql} from '@apollo/client';
import LinearProgress from '@mui/material/LinearProgress';
import AceEditor from 'react-ace';
import 'ace-builds/src-noconflict/mode-json';
import 'ace-builds/src-noconflict/theme-monokai';
import 'ace-builds/src-noconflict/theme-xcode';
import "ace-builds/src-noconflict/ext-searchbox";
import {useTheme} from '@mui/material/styles';
import {ResponseDisplayPlaintext} from "../Callbacks/ResponseDisplayPlaintext";

const getDescriptionQuery = gql`
query getDescriptionQuery ($payload_id: Int!) {
Expand All @@ -24,9 +18,8 @@ query getDescriptionQuery ($payload_id: Int!) {
`;

export function PayloadBuildMessageDialog(props) {
const [payloadData, setPayloadData] = useState({});
const [payloadData, setPayloadData] = useState({"error": "", "message": ""});
const [viewError, setViewError] = useState(false);
const theme = useTheme();
const { loading, error } = useQuery(getDescriptionQuery, {
variables: {payload_id: props.payload_id},
onCompleted: data => {
Expand All @@ -51,32 +44,23 @@ export function PayloadBuildMessageDialog(props) {
}

return (
<React.Fragment>
<DialogTitle id="form-dialog-title">Payload Build Messages</DialogTitle>
<DialogContent dividers={true}>
<AceEditor
mode="text"
theme={theme.palette.mode === "dark" ? "monokai" : "xcode"}
fontSize={14}
showGutter={true}
height={"100px"}
highlightActiveLine={true}
value={viewError ? payloadData["error"] : payloadData["message"]}
width={"100%"}
minLines={2}
maxLines={50}
setOptions={{
showLineNumbers: true,
tabSize: 4,
useWorker: false
}}/>
</DialogContent>
<DialogActions>
<Button variant="contained" onClick={props.onClose} color="primary">
Close
</Button>
</DialogActions>
</React.Fragment>
<React.Fragment>
<DialogTitle id="form-dialog-title">Payload Build Messages</DialogTitle>
<div style={{height: "calc(80vh)", overflowY: "auto"}}>
<ResponseDisplayPlaintext
initial_mode={"html"}
render_colors={false}
wrap_text={true}
plaintext={viewError ? payloadData["error"] : payloadData["message"]}
expand={true}
/>
</div>
<DialogActions>
<Button variant="contained" onClick={props.onClose} color="primary">
Close
</Button>
</DialogActions>
</React.Fragment>
);
}

Original file line number Diff line number Diff line change
@@ -1,17 +1,11 @@
import React, {useState} from 'react';
import Button from '@mui/material/Button';
import DialogActions from '@mui/material/DialogActions';
import DialogContent from '@mui/material/DialogContent';
import DialogTitle from '@mui/material/DialogTitle';
import {useQuery, gql} from '@apollo/client';
import LinearProgress from '@mui/material/LinearProgress';
import { snackActions } from '../../utilities/Snackbar';
import AceEditor from 'react-ace';
import 'ace-builds/src-noconflict/mode-json';
import 'ace-builds/src-noconflict/theme-monokai';
import 'ace-builds/src-noconflict/theme-xcode';
import "ace-builds/src-noconflict/ext-searchbox";
import {useTheme} from '@mui/material/styles';
import {ResponseDisplayPlaintext} from "../Callbacks/ResponseDisplayPlaintext";

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

export function PayloadConfigCheckDialog(props) {
const [message, setMessage] = useState("");
const theme = useTheme();
const { loading, error } = useQuery(checkPayloadConfigurationQuery, {
variables: {uuid: props.uuid},
onCompleted: data => {
Expand All @@ -48,32 +41,23 @@ export function PayloadConfigCheckDialog(props) {
}

return (
<React.Fragment>
<DialogTitle id="form-dialog-title">Payload Config Check</DialogTitle>
<DialogContent dividers={true}>
<AceEditor
mode="text"
theme={theme.palette.mode === "dark" ? "monokai" : "xcode"}
fontSize={14}
showGutter={true}
height={"100px"}
highlightActiveLine={true}
value={message}
width={"100%"}
minLines={2}
maxLines={50}
setOptions={{
showLineNumbers: true,
tabSize: 4,
useWorker: false
}}/>
</DialogContent>
<DialogActions>
<Button variant="contained" onClick={props.onClose} color="primary">
Close
</Button>
</DialogActions>
</React.Fragment>
<React.Fragment>
<DialogTitle id="form-dialog-title">Payload Config Check</DialogTitle>
<div style={{height: "calc(80vh)", overflowY: "auto"}}>
<ResponseDisplayPlaintext
initial_mode={"html"}
render_colors={false}
wrap_text={true}
plaintext={message}
expand={true}
/>
</div>
<DialogActions>
<Button variant="contained" onClick={props.onClose} color="primary">
Close
</Button>
</DialogActions>
</React.Fragment>
);
}

Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
import React, {useState} from 'react';
import Button from '@mui/material/Button';
import DialogActions from '@mui/material/DialogActions';
import DialogContent from '@mui/material/DialogContent';
import DialogTitle from '@mui/material/DialogTitle';
import MythicTextField from '../../MythicComponents/MythicTextField';
import {useQuery, gql, useMutation} from '@apollo/client';
import { snackActions } from '../../utilities/Snackbar';
import {MythicConfirmDialog} from "../../MythicComponents/MythicConfirmDialog";
import Typography from '@mui/material/Typography';
import {MythicModifyStringDialog} from "../../MythicComponents/MythicDialog";

const updateDescriptionMutation = gql`
mutation updateDescription ($payload_id: Int!, $description: String) {
Expand Down Expand Up @@ -37,14 +33,14 @@ query getDescriptionQuery ($payload_id: Int!) {
`;

export function PayloadDescriptionDialog(props) {
const [description, setDescription] = useState("");
const oldDescription = React.useRef();
const description = React.useRef("");
const [oldDescription, setOldDescription] = useState("");
const hasCallbacks = React.useRef(false);
useQuery(getDescriptionQuery, {
variables: {payload_id: props.payload_id},
onCompleted: data => {
setDescription(data.payload_by_pk.description)
oldDescription.current = data.payload_by_pk.description;
description.current = data.payload_by_pk.description;
setOldDescription(data.payload_by_pk.description);
hasCallbacks.current = data.payload_by_pk.callbacks.length > 0;
},
fetchPolicy: "network-only"
Expand Down Expand Up @@ -81,43 +77,34 @@ export function PayloadDescriptionDialog(props) {
setOpenUpdateAll(false);
updateCallbackDescriptions({variables: {
payloadID: props.payload_id,
oldDescription: oldDescription.current,
newDescription: description,
oldDescription: oldDescription,
newDescription: description.current,
}});
updatePayloadDescription();
// now update all
}
const updatePayloadDescription = () => {
setOpenUpdateAll(false);
updateDescription({variables: {payload_id: props.payload_id, description: description}});
updateDescription({variables: {payload_id: props.payload_id, description: description.current}});
props.onClose();
}
const onCommitSubmit = () => {
const onCommitSubmit = (updatedMessage) => {
description.current = updatedMessage;
if(hasCallbacks.current){
setOpenUpdateAll(true);
} else {
updatePayloadDescription();
}

}
const onChange = (name, value, error) => {
setDescription(value);
}


return (
<React.Fragment>
<DialogTitle id="form-dialog-title">Edit Payload Description</DialogTitle>
<DialogContent dividers={true}>
<MythicTextField autoFocus onChange={onChange} value={description} onEnter={onCommitSubmit}/>
</DialogContent>
<DialogActions>
<Button variant="contained" onClick={props.onClose} color="primary">
Close
</Button>
<Button variant="contained" onClick={onCommitSubmit} color="success">
Submit
</Button>
</DialogActions>
<MythicModifyStringDialog title={"Edit Payload Description"}
maxRows={5}
onClose={props.onClose}
value={description.current}
onSubmit={onCommitSubmit} />
{openUpdateAll &&
<MythicConfirmDialog title={"Update Associated Callback's Descriptions?"}
dontCloseOnSubmit={true}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
import React, {useState} from 'react';
import Button from '@mui/material/Button';
import DialogActions from '@mui/material/DialogActions';
import DialogContent from '@mui/material/DialogContent';
import DialogTitle from '@mui/material/DialogTitle';
import MythicTextField from '../../MythicComponents/MythicTextField';
import {useQuery, gql, useMutation} from '@apollo/client';
import LinearProgress from '@mui/material/LinearProgress';
import { snackActions } from '../../utilities/Snackbar';
import {b64DecodeUnicode} from '../Callbacks/ResponseDisplay';
import {MythicModifyStringDialog} from "../../MythicComponents/MythicDialog";

const updateDescriptionMutation = gql`
mutation updateDescription ($file_id: Int!, $filename: bytea!) {
Expand Down Expand Up @@ -52,28 +48,18 @@ export function PayloadFilenameDialog(props) {
console.error(error);
return <div>Error!</div>;
}
const onCommitSubmit = () => {
updateDescription({variables: {file_id: fileId, filename: description}});
const onCommitSubmit = (newDescription) => {
updateDescription({variables: {file_id: fileId, filename: newDescription}});
props.onClose();
}
const onChange = (name, value, error) => {
setDescription(value);
}


return (
<React.Fragment>
<DialogTitle id="form-dialog-title">Edit Payload Filename</DialogTitle>
<DialogContent dividers={true}>
<MythicTextField autoFocus onChange={onChange} value={description} onEnter={onCommitSubmit}/>
</DialogContent>
<DialogActions>
<Button variant="contained" onClick={props.onClose} color="primary">
Close
</Button>
<Button variant="contained" onClick={onCommitSubmit} color="success">
Submit
</Button>
</DialogActions>
<MythicModifyStringDialog title={"Edit Payload Filename"}
maxRows={2}
onClose={props.onClose}
value={description}
onSubmit={onCommitSubmit} />
</React.Fragment>
);
}
Expand Down
52 changes: 18 additions & 34 deletions MythicReactUI/src/components/pages/Payloads/PayloadGetIOCDialog.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,11 @@
import React, {useState} from 'react';
import Button from '@mui/material/Button';
import DialogActions from '@mui/material/DialogActions';
import DialogContent from '@mui/material/DialogContent';
import DialogTitle from '@mui/material/DialogTitle';
import {useQuery, gql} from '@apollo/client';
import LinearProgress from '@mui/material/LinearProgress';
import { snackActions } from '../../utilities/Snackbar';
import AceEditor from 'react-ace';
import 'ace-builds/src-noconflict/mode-json';
import 'ace-builds/src-noconflict/theme-monokai';
import 'ace-builds/src-noconflict/theme-xcode';
import "ace-builds/src-noconflict/ext-searchbox";
import {useTheme} from '@mui/material/styles';
import {ResponseDisplayPlaintext} from "../Callbacks/ResponseDisplayPlaintext";

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

export function PayloadGetIOCDialog(props) {
const [message, setMessage] = useState("");
const theme = useTheme();
const { loading, error } = useQuery(generateIOCMutation, {
variables: {uuid: props.uuid},
onCompleted: data => {
Expand All @@ -48,32 +41,23 @@ export function PayloadGetIOCDialog(props) {
}

return (
<React.Fragment>
<DialogTitle id="form-dialog-title">Payload Network IOCs</DialogTitle>
<DialogContent dividers={true}>
<AceEditor
mode="text"
theme={theme.palette.mode === "dark" ? "monokai" : "xcode"}
fontSize={14}
showGutter={true}
height={"100px"}
highlightActiveLine={true}
value={message}
width={"100%"}
minLines={2}
maxLines={50}
setOptions={{
showLineNumbers: true,
tabSize: 4,
useWorker: false
}}/>
</DialogContent>
<DialogActions>
<Button variant="contained" onClick={props.onClose} color="primary">
Close
</Button>
</DialogActions>
</React.Fragment>
<React.Fragment>
<DialogTitle id="form-dialog-title">Payload Network IOCs</DialogTitle>
<div style={{height: "calc(80vh)", overflowY: "auto"}}>
<ResponseDisplayPlaintext
initial_mode={"html"}
render_colors={false}
wrap_text={true}
plaintext={message}
expand={true}
/>
</div>
<DialogActions>
<Button variant="contained" onClick={props.onClose} color="primary">
Close
</Button>
</DialogActions>
</React.Fragment>
);
}

Loading

0 comments on commit 96b05c9

Please sign in to comment.