diff --git a/monkey/monkey_island/cc/ui/src/components/AuthComponent.js b/monkey/monkey_island/cc/ui/src/components/AuthComponent.js
index 9eb02a397..eb8427670 100644
--- a/monkey/monkey_island/cc/ui/src/components/AuthComponent.js
+++ b/monkey/monkey_island/cc/ui/src/components/AuthComponent.js
@@ -10,4 +10,10 @@ class AuthComponent extends React.Component {
}
}
+export function authFetch(){
+ const auth = new AuthService();
+ const authFetch = auth.authFetch;
+ const jwtHeader = auth.jwtHeader();
+}
+
export default AuthComponent;
diff --git a/monkey/monkey_island/cc/ui/src/components/Main.js b/monkey/monkey_island/cc/ui/src/components/Main.js
index 7ef373f05..47116c5da 100644
--- a/monkey/monkey_island/cc/ui/src/components/Main.js
+++ b/monkey/monkey_island/cc/ui/src/components/Main.js
@@ -4,7 +4,7 @@ import {Container} from 'react-bootstrap';
import RunServerPage from 'components/pages/RunServerPage';
import ConfigurePage from 'components/pages/ConfigurePage';
-import RunMonkeyPage from 'components/pages/RunMonkeyPage';
+import RunMonkeyPage from 'components/pages/RunMonkeyPage/RunMonkeyPage';
import MapPage from 'components/pages/MapPage';
import TelemetryPage from 'components/pages/TelemetryPage';
import StartOverPage from 'components/pages/StartOverPage';
diff --git a/monkey/monkey_island/cc/ui/src/components/pages/RunMonkeyPage/CommandTypes.js b/monkey/monkey_island/cc/ui/src/components/pages/RunMonkeyPage/CommandTypes.js
new file mode 100644
index 000000000..e69de29bb
diff --git a/monkey/monkey_island/cc/ui/src/components/pages/RunMonkeyPage/InterfaceSelection.js b/monkey/monkey_island/cc/ui/src/components/pages/RunMonkeyPage/InterfaceSelection.js
new file mode 100644
index 000000000..542edb568
--- /dev/null
+++ b/monkey/monkey_island/cc/ui/src/components/pages/RunMonkeyPage/InterfaceSelection.js
@@ -0,0 +1,29 @@
+import React, {useEffect, useState} from 'react';
+import NextSelectionButton from '../../ui-components/inline-selection/NextSelectionButton';
+import InlineSelection from '../../ui-components/inline-selection/InlineSelection';
+import CommandSection from '../../ui-components/inline-selection/CommandSection';
+import LocalManualRunOptions from './LocalManualRunOptions';
+
+function InterfaceSelection(props) {
+ return InlineSelection(getContents, props, LocalManualRunOptions)
+}
+
+const getContents = (props) => {
+ const ips = props.ips.map((ip) =>
+
{ip}
+ );
+ return ({ips}
);
+}
+
+const setCommandAsContent = (props) => {
+ let commandComponent = () => InlineSelection(CommandSection,
+ {
+ commands: win64commands,
+ setComponent: props.setComponent
+ },
+ LocalManualRunOptions
+ );
+ props.setComponent(commandComponent, props);
+}
+
+export default InterfaceSelection;
diff --git a/monkey/monkey_island/cc/ui/src/components/pages/RunMonkeyPage/LocalManualRunOptions.js b/monkey/monkey_island/cc/ui/src/components/pages/RunMonkeyPage/LocalManualRunOptions.js
new file mode 100644
index 000000000..89275067a
--- /dev/null
+++ b/monkey/monkey_island/cc/ui/src/components/pages/RunMonkeyPage/LocalManualRunOptions.js
@@ -0,0 +1,42 @@
+import React, {useEffect} from 'react';
+import NextSelectionButton from '../../ui-components/inline-selection/NextSelectionButton';
+import InlineSelection from '../../ui-components/inline-selection/InlineSelection';
+import CommandSection from '../../ui-components/inline-selection/CommandSection';
+import ManualRunOptions from './ManualRunOptions';
+import InterfaceSelection from './InterfaceSelection';
+
+const LocalManualRunOptions = (props) => {
+ return InlineSelection(getContents, props, ManualRunOptions)
+}
+
+const win64commands = [{name: "CMD", command: "monkey.exe m0nk3y -s 192.168.56.1"}]
+
+const getContents = (props) => {
+ return (
+ <>
+ {
+ props.setComponent(InterfaceSelection('Windows64'))
+ }}/>
+ {
+ }}/>
+ {
+ }}/>
+ {
+ }}/>
+ >
+ )
+}
+
+const setCommandAsContent = (props) => {
+ let commandComponent = () => InlineSelection(CommandSection,
+ {
+ commands: win64commands,
+ setComponent: props.setComponent
+ },
+ LocalManualRunOptions
+ );
+ props.setComponent(commandComponent, props);
+}
+
+export default LocalManualRunOptions;
diff --git a/monkey/monkey_island/cc/ui/src/components/pages/RunMonkeyPage/ManualRunOptions.js b/monkey/monkey_island/cc/ui/src/components/pages/RunMonkeyPage/ManualRunOptions.js
new file mode 100644
index 000000000..0b84084ab
--- /dev/null
+++ b/monkey/monkey_island/cc/ui/src/components/pages/RunMonkeyPage/ManualRunOptions.js
@@ -0,0 +1,58 @@
+import React, {useEffect, useState} from 'react';
+import NextSelectionButton from '../../ui-components/inline-selection/NextSelectionButton';
+import LocalManualRunOptions from './LocalManualRunOptions';
+import AuthComponent from '../../AuthComponent';
+
+function ManualRunOptions(props) {
+
+ const [currentContent, setCurrentContent] = useState(loadingContents());
+ const [ips, setIps] = useState([]);
+ const [initialized, setInitialized] = useState(false);
+
+ const authComponent = new AuthComponent({})
+
+ useEffect(() => {
+ if (initialized === false) {
+ authComponent.authFetch('/api')
+ .then(res => res.json())
+ .then(res => {
+ setIps([res['ip_addresses']]);
+ setInitialized(true);
+ });
+ }
+ })
+
+ useEffect(() => {
+ setCurrentContent(getDefaultContents());
+ }, [initialized])
+
+ function setComponent(component, props) {
+ if (component === undefined) {
+ setCurrentContent(getDefaultContents())
+ } else {
+ setCurrentContent(component({...props}))
+ }
+ }
+
+ function loadingContents() {
+ return (Loading
)
+ }
+
+ function getDefaultContents() {
+ return (
+
+ {
+ setComponent(LocalManualRunOptions, {ips: ips, setComponent: setComponent})
+ }}/>
+ {
+ }}/>
+ {
+ }}/>
+
+ );
+ }
+
+ return currentContent;
+}
+
+export default ManualRunOptions;
diff --git a/monkey/monkey_island/cc/ui/src/components/pages/RunMonkeyPage.js b/monkey/monkey_island/cc/ui/src/components/pages/RunMonkeyPage/RunMonkeyPage.js
similarity index 96%
rename from monkey/monkey_island/cc/ui/src/components/pages/RunMonkeyPage.js
rename to monkey/monkey_island/cc/ui/src/components/pages/RunMonkeyPage/RunMonkeyPage.js
index 48a11f008..19650fc19 100644
--- a/monkey/monkey_island/cc/ui/src/components/pages/RunMonkeyPage.js
+++ b/monkey/monkey_island/cc/ui/src/components/pages/RunMonkeyPage/RunMonkeyPage.js
@@ -12,10 +12,11 @@ import {faInfoCircle} from '@fortawesome/free-solid-svg-icons/faInfoCircle';
import {faExclamationTriangle} from '@fortawesome/free-solid-svg-icons/faExclamationTriangle';
import {Link} from 'react-router-dom';
-import AuthComponent from '../AuthComponent';
-import AwsRunTable from '../run-monkey/AwsRunTable';
+import AuthComponent from '../../AuthComponent';
+import AwsRunTable from '../../run-monkey/AwsRunTable';
-import MissingBinariesModal from '../ui-components/MissingBinariesModal';
+import MissingBinariesModal from '../../ui-components/MissingBinariesModal';
+import ManualRunOptions from './ManualRunOptions';
const loading_css_override = css`
display: block;
@@ -329,22 +330,11 @@ class RunMonkeyPageComponent extends AuthComponent {
showModal={this.state.showModal}
onClose={this.closeModal}
errorDetails={this.state.errorDetails}/>
- {
- // TODO: implement button functionality
- /*
-
- */
- }
OR
+
+ )
+}
+
+backButton.propTypes = {
+ onClick: PropTypes.func
+}
diff --git a/monkey/monkey_island/cc/ui/src/components/ui-components/inline-selection/CommandSection.js b/monkey/monkey_island/cc/ui/src/components/ui-components/inline-selection/CommandSection.js
new file mode 100644
index 000000000..ec4a53f0e
--- /dev/null
+++ b/monkey/monkey_island/cc/ui/src/components/ui-components/inline-selection/CommandSection.js
@@ -0,0 +1,19 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+
+
+export default function CommandSection(props){
+ return (
+
+ {props.commands[0].name}
+ {props.commands[0].command}
+
+ )
+}
+
+CommandSection.propTypes = {
+ commands: PropTypes.arrayOf(PropTypes.exact({
+ name: PropTypes.string,
+ command: PropTypes.string
+ }))
+}
diff --git a/monkey/monkey_island/cc/ui/src/components/ui-components/inline-selection/InlineSelection.js b/monkey/monkey_island/cc/ui/src/components/ui-components/inline-selection/InlineSelection.js
new file mode 100644
index 000000000..97bb82d99
--- /dev/null
+++ b/monkey/monkey_island/cc/ui/src/components/ui-components/inline-selection/InlineSelection.js
@@ -0,0 +1,28 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import BackButton from './BackButton';
+import ManualRunOptions from '../../pages/RunMonkeyPage/ManualRunOptions';
+
+
+export default function InlineSelection(WrappedComponent, props, previousComponent){
+ return (
+
+ {previousComponent === undefined ? '' :
+ {setPreviousComponent(props, previousComponent)}}/>}
+
+
+ )
+}
+
+function setPreviousComponent(props, previousComponent) {
+ if(previousComponent === ManualRunOptions){
+ return props.setComponent()
+ } else {
+ return props.setComponent(previousComponent)
+ }
+}
+
+InlineSelection.propTypes = {
+ setComponent: PropTypes.func,
+ ips: PropTypes.arrayOf(PropTypes.string)
+}
diff --git a/monkey/monkey_island/cc/ui/src/components/ui-components/inline-selection/NextSelectionButton.js b/monkey/monkey_island/cc/ui/src/components/ui-components/inline-selection/NextSelectionButton.js
new file mode 100644
index 000000000..6f6ac4cb7
--- /dev/null
+++ b/monkey/monkey_island/cc/ui/src/components/ui-components/inline-selection/NextSelectionButton.js
@@ -0,0 +1,17 @@
+import {Button} from 'react-bootstrap';
+import React from 'react';
+import PropTypes from 'prop-types';
+
+export default function nextSelectionButton(props) {
+ return (
+
+ )
+}
+
+nextSelectionButton.propTypes = {
+ text: PropTypes.string,
+ onButtonClick: PropTypes.func
+}
diff --git a/monkey/monkey_island/cc/ui/src/styles/Main.scss b/monkey/monkey_island/cc/ui/src/styles/Main.scss
index 6b6096a3f..2fb672693 100644
--- a/monkey/monkey_island/cc/ui/src/styles/Main.scss
+++ b/monkey/monkey_island/cc/ui/src/styles/Main.scss
@@ -11,6 +11,7 @@
@import 'components/InfoPane';
@import 'components/PreviewPane';
@import 'components/AdvancedMultiSelect';
+@import 'components/InlineSelection';
// Define custom elements after bootstrap import
diff --git a/monkey/monkey_island/cc/ui/src/styles/components/InlineSelection.scss b/monkey/monkey_island/cc/ui/src/styles/components/InlineSelection.scss
new file mode 100644
index 000000000..c264344de
--- /dev/null
+++ b/monkey/monkey_island/cc/ui/src/styles/components/InlineSelection.scss
@@ -0,0 +1,8 @@
+.inline-selection-component.container {
+ display: flex;
+ justify-content: center;
+}
+
+.inline-selection-component.container .selection-button{
+ margin: 0 5px 0 5px;
+}