diff --git a/monkey/monkey_island/cc/ui/src/components/Main.js b/monkey/monkey_island/cc/ui/src/components/Main.js index c068b9caf..7a7851af8 100644 --- a/monkey/monkey_island/cc/ui/src/components/Main.js +++ b/monkey/monkey_island/cc/ui/src/components/Main.js @@ -155,6 +155,7 @@ class AppComponent extends AuthComponent { true)} {this.renderRoute('/configure', )} {this.renderRoute('/run-monkey', diff --git a/monkey/monkey_island/cc/ui/src/components/configuration-components/ConfigurationTabs.js b/monkey/monkey_island/cc/ui/src/components/configuration-components/ConfigurationTabs.js new file mode 100644 index 000000000..7701959cf --- /dev/null +++ b/monkey/monkey_island/cc/ui/src/components/configuration-components/ConfigurationTabs.js @@ -0,0 +1,30 @@ +const CONFIGURATION_TABS = { + ATTACK: 'attack', + BASIC: 'basic', + BASIC_NETWORK: 'basic_network', + RANSOMWARE: 'ransomware', + MONKEY: 'monkey', + INTERNAL: 'internal' +}; + +const advancedModeConfigTabs = [ + CONFIGURATION_TABS.ATTACK, + CONFIGURATION_TABS.BASIC, + CONFIGURATION_TABS.BASIC_NETWORK, + CONFIGURATION_TABS.RANSOMWARE, + CONFIGURATION_TABS.MONKEY, + CONFIGURATION_TABS.INTERNAL +]; + +const ransomwareModeConfigTabs = [ + CONFIGURATION_TABS.BASIC, + CONFIGURATION_TABS.BASIC_NETWORK, + CONFIGURATION_TABS.RANSOMWARE +]; + +const CONFIGURATION_TABS_PER_MODE = { + 'advanced': advancedModeConfigTabs, + 'ransomware': ransomwareModeConfigTabs +}; + +export default CONFIGURATION_TABS_PER_MODE; diff --git a/monkey/monkey_island/cc/ui/src/components/pages/ConfigurePage.js b/monkey/monkey_island/cc/ui/src/components/pages/ConfigurePage.js index a5ea68107..c7c84e327 100644 --- a/monkey/monkey_island/cc/ui/src/components/pages/ConfigurePage.js +++ b/monkey/monkey_island/cc/ui/src/components/pages/ConfigurePage.js @@ -18,6 +18,7 @@ import ConfigExportModal from '../configuration-components/ExportConfigModal'; import ConfigImportModal from '../configuration-components/ImportConfigModal'; import applyUiSchemaManipulators from '../configuration-components/UISchemaManipulators.tsx'; import HtmlFieldDescription from '../configuration-components/HtmlFieldDescription.js'; +import CONFIGURATION_TABS_PER_MODE from '../configuration-components/ConfigurationTabs.js'; const ATTACK_URL = '/api/attack'; const CONFIG_URL = '/api/configuration/island'; @@ -28,10 +29,9 @@ class ConfigurePageComponent extends AuthComponent { constructor(props) { super(props); - this.currentSection = 'attack'; this.initialConfig = {}; this.initialAttackConfig = {}; - this.sectionsOrder = ['attack', 'basic', 'basic_network', 'ransomware', 'monkey', 'internal']; + this.currentSection = this.getSectionsOrder()[0]; this.state = { attackConfig: {}, @@ -41,7 +41,7 @@ class ConfigurePageComponent extends AuthComponent { lastAction: 'none', schema: {}, sections: [], - selectedSection: 'attack', + selectedSection: this.currentSection, showAttackAlert: false, showUnsafeOptionsConfirmation: false, showUnsafeAttackOptionsWarning: false, @@ -50,6 +50,18 @@ class ConfigurePageComponent extends AuthComponent { }; } + componentDidUpdate() { + if (!this.getSectionsOrder().includes(this.currentSection)) { + this.currentSection = this.getSectionsOrder()[0] + this.setState({selectedSection: this.currentSection}) + } + } + + getSectionsOrder() { + let islandMode = this.props.islandMode ? this.props.islandMode : 'advanced' + return CONFIGURATION_TABS_PER_MODE[islandMode]; + } + setInitialConfig(config) { // Sets a reference to know if config was changed this.initialConfig = JSON.parse(JSON.stringify(config)); @@ -62,6 +74,7 @@ class ConfigurePageComponent extends AuthComponent { componentDidMount = () => { let urls = [CONFIG_URL, ATTACK_URL]; + // ??? Why fetch config here and not in `render()`? Promise.all(urls.map(url => this.authFetch(url).then(res => res.json()))) .then(data => { let sections = []; @@ -69,7 +82,7 @@ class ConfigurePageComponent extends AuthComponent { let monkeyConfig = data[0]; this.setInitialConfig(monkeyConfig.configuration); this.setInitialAttackConfig(attackConfig.configuration); - for (let sectionKey of this.sectionsOrder) { + for (let sectionKey of this.getSectionsOrder()) { if (sectionKey === 'attack') { sections.push({key: sectionKey, title: 'ATT&CK'}) } else { @@ -83,8 +96,7 @@ class ConfigurePageComponent extends AuthComponent { schema: monkeyConfig.schema, configuration: monkeyConfig.configuration, attackConfig: attackConfig.configuration, - sections: sections, - selectedSection: 'attack' + sections: sections }) }); }; @@ -479,7 +491,7 @@ class ConfigurePageComponent extends AuthComponent { let content = ''; if (this.state.selectedSection === 'attack' && Object.entries(this.state.attackConfig).length !== 0) { content = this.renderMatrix() - } else if (this.state.selectedSection !== 'attack') { + } else if (this.state.selectedSection !== 'attack' && Object.entries(this.state.configuration).length !== 0) { content = this.renderConfigContent(displayedSchema) } return (