forked from p15670423/monkey
Island: refactor Main.js and SideNavComponent.js into typescript and add the ability to disable side navigation
This commit is contained in:
parent
f804d6cf5b
commit
93b90dbadf
File diff suppressed because it is too large
Load Diff
|
@ -73,6 +73,7 @@
|
||||||
"@fortawesome/free-solid-svg-icons": "^5.15.1",
|
"@fortawesome/free-solid-svg-icons": "^5.15.1",
|
||||||
"@fortawesome/react-fontawesome": "^0.1.12",
|
"@fortawesome/react-fontawesome": "^0.1.12",
|
||||||
"@kunukn/react-collapse": "^1.2.7",
|
"@kunukn/react-collapse": "^1.2.7",
|
||||||
|
"@types/react-router-dom": "^5.1.8",
|
||||||
"bootstrap": "^4.5.3",
|
"bootstrap": "^4.5.3",
|
||||||
"classnames": "^2.2.6",
|
"classnames": "^2.2.6",
|
||||||
"core-js": "^3.7.0",
|
"core-js": "^3.7.0",
|
||||||
|
|
|
@ -2,19 +2,19 @@ import React from 'react';
|
||||||
import {BrowserRouter as Router, Redirect, Route, Switch} from 'react-router-dom';
|
import {BrowserRouter as Router, Redirect, Route, Switch} from 'react-router-dom';
|
||||||
import {Container} from 'react-bootstrap';
|
import {Container} from 'react-bootstrap';
|
||||||
|
|
||||||
import GettingStartedPage from 'components/pages/GettingStartedPage';
|
import ConfigurePage from './pages/ConfigurePage.js';
|
||||||
import ConfigurePage from 'components/pages/ConfigurePage';
|
import RunMonkeyPage from './pages/RunMonkeyPage/RunMonkeyPage';
|
||||||
import RunMonkeyPage from 'components/pages/RunMonkeyPage/RunMonkeyPage';
|
import MapPage from './pages/MapPage';
|
||||||
import MapPage from 'components/pages/MapPage';
|
import TelemetryPage from './pages/TelemetryPage';
|
||||||
import TelemetryPage from 'components/pages/TelemetryPage';
|
import StartOverPage from './pages/StartOverPage';
|
||||||
import StartOverPage from 'components/pages/StartOverPage';
|
import ReportPage from './pages/ReportPage';
|
||||||
import ReportPage from 'components/pages/ReportPage';
|
import LicensePage from './pages/LicensePage';
|
||||||
import LicensePage from 'components/pages/LicensePage';
|
import AuthComponent from './AuthComponent';
|
||||||
import AuthComponent from 'components/AuthComponent';
|
import LoginPageComponent from './pages/LoginPage';
|
||||||
import LoginPageComponent from 'components/pages/LoginPage';
|
import RegisterPageComponent from './pages/RegisterPage';
|
||||||
import RegisterPageComponent from 'components/pages/RegisterPage';
|
|
||||||
import Notifier from 'react-desktop-notification';
|
import Notifier from 'react-desktop-notification';
|
||||||
import NotFoundPage from 'components/pages/NotFoundPage';
|
import NotFoundPage from './pages/NotFoundPage';
|
||||||
|
import GettingStartedPage from './pages/GettingStartedPage';
|
||||||
|
|
||||||
|
|
||||||
import 'normalize.css/normalize.css';
|
import 'normalize.css/normalize.css';
|
||||||
|
@ -22,14 +22,33 @@ import 'react-data-components/css/table-twbs.css';
|
||||||
import 'styles/App.css';
|
import 'styles/App.css';
|
||||||
import 'react-toggle/style.css';
|
import 'react-toggle/style.css';
|
||||||
import 'react-table/react-table.css';
|
import 'react-table/react-table.css';
|
||||||
import notificationIcon from '../images/notification-logo-512x512.png';
|
|
||||||
import {StandardLayoutComponent} from './layouts/StandardLayoutComponent';
|
import {StandardLayoutComponent} from './layouts/StandardLayoutComponent';
|
||||||
import LoadingScreen from './ui-components/LoadingScreen';
|
import LoadingScreen from './ui-components/LoadingScreen';
|
||||||
|
import LandingPageComponent from "./pages/LandingPage";
|
||||||
|
import {DisabledSidebarLayoutComponent} from "./layouts/DisabledSidebarLayoutComponent";
|
||||||
|
import {CompletedSteps} from "./side-menu/CompletedSteps";
|
||||||
|
import Timeout = NodeJS.Timeout;
|
||||||
|
|
||||||
|
|
||||||
|
let notificationIcon = require('../images/notification-logo-512x512.png');
|
||||||
|
|
||||||
const reportZeroTrustRoute = '/report/zeroTrust';
|
const reportZeroTrustRoute = '/report/zeroTrust';
|
||||||
const islandModeRoute = '/api/island-mode'
|
|
||||||
|
|
||||||
class AppComponent extends AuthComponent {
|
class AppComponent extends AuthComponent {
|
||||||
|
private interval: Timeout;
|
||||||
|
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
let completedSteps = new CompletedSteps(false);
|
||||||
|
this.state = {
|
||||||
|
completedSteps: completedSteps,
|
||||||
|
islandMode: undefined,
|
||||||
|
noAuthLoginAttempted: undefined
|
||||||
|
};
|
||||||
|
this.interval = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
updateStatus = () => {
|
updateStatus = () => {
|
||||||
if (this.state.isLoggedIn === false) {
|
if (this.state.isLoggedIn === false) {
|
||||||
return
|
return
|
||||||
|
@ -51,6 +70,8 @@ class AppComponent extends AuthComponent {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.checkMode();
|
||||||
|
|
||||||
if (res) {
|
if (res) {
|
||||||
this.authFetch('/api')
|
this.authFetch('/api')
|
||||||
.then(res => res.json())
|
.then(res => res.json())
|
||||||
|
@ -72,10 +93,22 @@ class AppComponent extends AuthComponent {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
checkMode = () => {
|
||||||
|
// TODO change to fetch the mode from UI
|
||||||
|
this.authFetch('/api')
|
||||||
|
.then(res => res.json())
|
||||||
|
.then(res => {
|
||||||
|
this.setState({IslandMode: undefined})
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
renderRoute = (route_path, page_component, is_exact_path = false) => {
|
renderRoute = (route_path, page_component, is_exact_path = false) => {
|
||||||
let render_func = () => {
|
let render_func = () => {
|
||||||
switch (this.state.isLoggedIn) {
|
switch (this.state.isLoggedIn) {
|
||||||
case true:
|
case true:
|
||||||
|
if(this.state.islandMode === undefined){
|
||||||
|
return this.getLandingPage();
|
||||||
|
}
|
||||||
return page_component;
|
return page_component;
|
||||||
case false:
|
case false:
|
||||||
switch (this.state.needsRegistration) {
|
switch (this.state.needsRegistration) {
|
||||||
|
@ -98,6 +131,12 @@ class AppComponent extends AuthComponent {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
getLandingPage() {
|
||||||
|
return <DisabledSidebarLayoutComponent component={LandingPageComponent}
|
||||||
|
completedSteps={new CompletedSteps()}
|
||||||
|
onStatusChange={this.updateStatus}/>
|
||||||
|
}
|
||||||
|
|
||||||
redirectTo = (userPath, targetPath) => {
|
redirectTo = (userPath, targetPath) => {
|
||||||
let pathQuery = new RegExp(userPath + '[/]?$', 'g');
|
let pathQuery = new RegExp(userPath + '[/]?$', 'g');
|
||||||
if (window.location.pathname.match(pathQuery)) {
|
if (window.location.pathname.match(pathQuery)) {
|
||||||
|
@ -105,35 +144,9 @@ class AppComponent extends AuthComponent {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
constructor(props) {
|
|
||||||
super(props);
|
|
||||||
this.state = {
|
|
||||||
completedSteps: {
|
|
||||||
run_server: true,
|
|
||||||
run_monkey: false,
|
|
||||||
infection_done: false,
|
|
||||||
report_done: false,
|
|
||||||
isLoggedIn: undefined,
|
|
||||||
needsRegistration: undefined,
|
|
||||||
islandMode: undefined
|
|
||||||
},
|
|
||||||
noAuthLoginAttempted: undefined
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
updateIslandMode() {
|
|
||||||
this.authFetch(islandModeRoute)
|
|
||||||
.then(res => res.json())
|
|
||||||
.then(res => {
|
|
||||||
this.setState({islandMode: res.mode})
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.updateStatus();
|
this.updateStatus();
|
||||||
this.interval = setInterval(this.updateStatus, 10000);
|
this.interval = setInterval(this.updateStatus, 10000);
|
||||||
this.updateIslandMode()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
|
@ -220,6 +233,4 @@ class AppComponent extends AuthComponent {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AppComponent.defaultProps = {};
|
|
||||||
|
|
||||||
export default AppComponent;
|
export default AppComponent;
|
|
@ -4,16 +4,23 @@ import {FontAwesomeIcon} from '@fortawesome/react-fontawesome';
|
||||||
import {faCheck} from '@fortawesome/free-solid-svg-icons/faCheck';
|
import {faCheck} from '@fortawesome/free-solid-svg-icons/faCheck';
|
||||||
import {faUndo} from '@fortawesome/free-solid-svg-icons/faUndo';
|
import {faUndo} from '@fortawesome/free-solid-svg-icons/faUndo';
|
||||||
import {faExternalLinkAlt} from '@fortawesome/free-solid-svg-icons';
|
import {faExternalLinkAlt} from '@fortawesome/free-solid-svg-icons';
|
||||||
import guardicoreLogoImage from '../images/guardicore-logo.png';
|
|
||||||
import logoImage from '../images/monkey-icon.svg';
|
|
||||||
import infectionMonkeyImage from '../images/infection-monkey.svg';
|
|
||||||
import VersionComponent from './side-menu/VersionComponent';
|
import VersionComponent from './side-menu/VersionComponent';
|
||||||
import '../styles/components/SideNav.scss';
|
import '../styles/components/SideNav.scss';
|
||||||
|
import {CompletedSteps} from "./side-menu/CompletedSteps";
|
||||||
|
|
||||||
|
|
||||||
class SideNavComponent extends React.Component {
|
const guardicoreLogoImage = require('../images/guardicore-logo.png');
|
||||||
|
const logoImage = require('../images/monkey-icon.svg');
|
||||||
|
const infectionMonkeyImage = require('../images/infection-monkey.svg');
|
||||||
|
|
||||||
render() {
|
|
||||||
|
type Props = {
|
||||||
|
disabled?: boolean,
|
||||||
|
completedSteps: CompletedSteps
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const SideNavComponent = ({disabled=false, completedSteps}: Props) => {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<NavLink to={'/'} exact={true}>
|
<NavLink to={'/'} exact={true}>
|
||||||
|
@ -25,25 +32,26 @@ class SideNavComponent extends React.Component {
|
||||||
|
|
||||||
<ul className='navigation'>
|
<ul className='navigation'>
|
||||||
<li>
|
<li>
|
||||||
<NavLink to='/run-monkey'>
|
<NavLink to='/run-monkey' className={getNavLinkClass()}>
|
||||||
<span className='number'>1.</span>
|
<span className='number'>1.</span>
|
||||||
Run Monkey
|
Run Monkey
|
||||||
{this.props.completedSteps.run_monkey ?
|
{completedSteps.runMonkey ?
|
||||||
<FontAwesomeIcon icon={faCheck} className='pull-right checkmark'/>
|
<FontAwesomeIcon icon={faCheck} className='pull-right checkmark'/>
|
||||||
: ''}
|
: ''}
|
||||||
</NavLink>
|
</NavLink>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<NavLink to='/infection/map'>
|
<NavLink to='/infection/map' className={getNavLinkClass()}>
|
||||||
<span className='number'>2.</span>
|
<span className='number'>2.</span>
|
||||||
Infection Map
|
Infection Map
|
||||||
{this.props.completedSteps.infection_done ?
|
{completedSteps.infectionDone ?
|
||||||
<FontAwesomeIcon icon={faCheck} className='pull-right checkmark'/>
|
<FontAwesomeIcon icon={faCheck} className='pull-right checkmark'/>
|
||||||
: ''}
|
: ''}
|
||||||
</NavLink>
|
</NavLink>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<NavLink to='/report/security'
|
<NavLink to='/report/security'
|
||||||
|
className={getNavLinkClass()}
|
||||||
isActive={(_match, location) => {
|
isActive={(_match, location) => {
|
||||||
return (location.pathname === '/report/attack'
|
return (location.pathname === '/report/attack'
|
||||||
|| location.pathname === '/report/zeroTrust'
|
|| location.pathname === '/report/zeroTrust'
|
||||||
|
@ -51,13 +59,13 @@ class SideNavComponent extends React.Component {
|
||||||
}}>
|
}}>
|
||||||
<span className='number'>3.</span>
|
<span className='number'>3.</span>
|
||||||
Security Reports
|
Security Reports
|
||||||
{this.props.completedSteps.report_done ?
|
{completedSteps.reportDone ?
|
||||||
<FontAwesomeIcon icon={faCheck} className='pull-right checkmark'/>
|
<FontAwesomeIcon icon={faCheck} className='pull-right checkmark'/>
|
||||||
: ''}
|
: ''}
|
||||||
</NavLink>
|
</NavLink>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<NavLink to='/start-over'>
|
<NavLink to='/start-over' className={getNavLinkClass()}>
|
||||||
<span className='number'><FontAwesomeIcon icon={faUndo} style={{'marginLeft': '-1px'}}/></span>
|
<span className='number'><FontAwesomeIcon icon={faUndo} style={{'marginLeft': '-1px'}}/></span>
|
||||||
Start Over
|
Start Over
|
||||||
</NavLink>
|
</NavLink>
|
||||||
|
@ -66,8 +74,14 @@ class SideNavComponent extends React.Component {
|
||||||
|
|
||||||
<hr/>
|
<hr/>
|
||||||
<ul>
|
<ul>
|
||||||
<li><NavLink to='/configure'>Configuration</NavLink></li>
|
<li><NavLink to='/configure'
|
||||||
<li><NavLink to='/infection/telemetry'>Logs</NavLink></li>
|
className={getNavLinkClass()}>
|
||||||
|
Configuration
|
||||||
|
</NavLink></li>
|
||||||
|
<li><NavLink to='/infection/telemetry'
|
||||||
|
className={getNavLinkClass()}>
|
||||||
|
Logs
|
||||||
|
</NavLink></li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<hr/>
|
<hr/>
|
||||||
|
@ -85,8 +99,15 @@ class SideNavComponent extends React.Component {
|
||||||
<NavLink to='/license'>License</NavLink>
|
<NavLink to='/license'>License</NavLink>
|
||||||
</div>
|
</div>
|
||||||
<VersionComponent/>
|
<VersionComponent/>
|
||||||
</>)
|
</>);
|
||||||
}
|
|
||||||
|
function getNavLinkClass() {
|
||||||
|
if(disabled){
|
||||||
|
return `nav-link disabled`
|
||||||
|
} else {
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default SideNavComponent;
|
export default SideNavComponent;
|
|
@ -1,6 +1,6 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import {Route} from 'react-router-dom'
|
import {Route} from 'react-router-dom'
|
||||||
import SideNavComponent from '../SideNavComponent'
|
import SideNavComponent from '../SideNavComponent.tsx'
|
||||||
import {Col, Row} from 'react-bootstrap';
|
import {Col, Row} from 'react-bootstrap';
|
||||||
|
|
||||||
export const StandardLayoutComponent = ({component: Component, ...rest}) => (
|
export const StandardLayoutComponent = ({component: Component, ...rest}) => (
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
export class CompletedSteps {
|
||||||
|
runServer: boolean
|
||||||
|
runMonkey: boolean
|
||||||
|
infectionDone: boolean
|
||||||
|
reportDone: boolean
|
||||||
|
isLoggedIn: boolean
|
||||||
|
needsRegistration: boolean
|
||||||
|
|
||||||
|
public constructor(runServer?: boolean,
|
||||||
|
runMonkey?: boolean,
|
||||||
|
infectinDone?: boolean,
|
||||||
|
reportDone?: boolean,
|
||||||
|
isLoggedIn?: boolean,
|
||||||
|
needsRegistration?: boolean) {
|
||||||
|
this.runServer = runServer || false;
|
||||||
|
this.runMonkey = runMonkey || false;
|
||||||
|
this.infectionDone = infectinDone || false;
|
||||||
|
this.reportDone = reportDone || false;
|
||||||
|
this.isLoggedIn = isLoggedIn || false;
|
||||||
|
this.needsRegistration = needsRegistration || false;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
{
|
{
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
|
"allowJs": true,
|
||||||
"sourceMap": true,
|
"sourceMap": true,
|
||||||
"module": "commonjs",
|
"module": "commonjs",
|
||||||
"target": "es6",
|
"target": "es6",
|
||||||
|
|
Loading…
Reference in New Issue