Island: refactor Main.js and SideNavComponent.js into typescript and add the ability to disable side navigation

This commit is contained in:
VakarisZ 2021-07-14 12:43:28 +03:00
parent f804d6cf5b
commit 93b90dbadf
7 changed files with 823 additions and 278 deletions

File diff suppressed because it is too large Load Diff

View File

@ -73,6 +73,7 @@
"@fortawesome/free-solid-svg-icons": "^5.15.1",
"@fortawesome/react-fontawesome": "^0.1.12",
"@kunukn/react-collapse": "^1.2.7",
"@types/react-router-dom": "^5.1.8",
"bootstrap": "^4.5.3",
"classnames": "^2.2.6",
"core-js": "^3.7.0",

View File

@ -2,19 +2,19 @@ import React from 'react';
import {BrowserRouter as Router, Redirect, Route, Switch} from 'react-router-dom';
import {Container} from 'react-bootstrap';
import GettingStartedPage from 'components/pages/GettingStartedPage';
import ConfigurePage from 'components/pages/ConfigurePage';
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';
import ReportPage from 'components/pages/ReportPage';
import LicensePage from 'components/pages/LicensePage';
import AuthComponent from 'components/AuthComponent';
import LoginPageComponent from 'components/pages/LoginPage';
import RegisterPageComponent from 'components/pages/RegisterPage';
import ConfigurePage from './pages/ConfigurePage.js';
import RunMonkeyPage from './pages/RunMonkeyPage/RunMonkeyPage';
import MapPage from './pages/MapPage';
import TelemetryPage from './pages/TelemetryPage';
import StartOverPage from './pages/StartOverPage';
import ReportPage from './pages/ReportPage';
import LicensePage from './pages/LicensePage';
import AuthComponent from './AuthComponent';
import LoginPageComponent from './pages/LoginPage';
import RegisterPageComponent from './pages/RegisterPage';
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';
@ -22,14 +22,33 @@ import 'react-data-components/css/table-twbs.css';
import 'styles/App.css';
import 'react-toggle/style.css';
import 'react-table/react-table.css';
import notificationIcon from '../images/notification-logo-512x512.png';
import {StandardLayoutComponent} from './layouts/StandardLayoutComponent';
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 islandModeRoute = '/api/island-mode'
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 = () => {
if (this.state.isLoggedIn === false) {
return
@ -51,6 +70,8 @@ class AppComponent extends AuthComponent {
})
}
this.checkMode();
if (res) {
this.authFetch('/api')
.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) => {
let render_func = () => {
switch (this.state.isLoggedIn) {
case true:
if(this.state.islandMode === undefined){
return this.getLandingPage();
}
return page_component;
case false:
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) => {
let pathQuery = new RegExp(userPath + '[/]?$', 'g');
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() {
this.updateStatus();
this.interval = setInterval(this.updateStatus, 10000);
this.updateIslandMode()
}
componentWillUnmount() {
@ -220,6 +233,4 @@ class AppComponent extends AuthComponent {
}
}
AppComponent.defaultProps = {};
export default AppComponent;

View File

@ -4,16 +4,23 @@ import {FontAwesomeIcon} from '@fortawesome/react-fontawesome';
import {faCheck} from '@fortawesome/free-solid-svg-icons/faCheck';
import {faUndo} from '@fortawesome/free-solid-svg-icons/faUndo';
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 '../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 (
<>
<NavLink to={'/'} exact={true}>
@ -25,25 +32,26 @@ class SideNavComponent extends React.Component {
<ul className='navigation'>
<li>
<NavLink to='/run-monkey'>
<NavLink to='/run-monkey' className={getNavLinkClass()}>
<span className='number'>1.</span>
Run Monkey
{this.props.completedSteps.run_monkey ?
{completedSteps.runMonkey ?
<FontAwesomeIcon icon={faCheck} className='pull-right checkmark'/>
: ''}
</NavLink>
</li>
<li>
<NavLink to='/infection/map'>
<NavLink to='/infection/map' className={getNavLinkClass()}>
<span className='number'>2.</span>
Infection Map
{this.props.completedSteps.infection_done ?
{completedSteps.infectionDone ?
<FontAwesomeIcon icon={faCheck} className='pull-right checkmark'/>
: ''}
</NavLink>
</li>
<li>
<NavLink to='/report/security'
className={getNavLinkClass()}
isActive={(_match, location) => {
return (location.pathname === '/report/attack'
|| location.pathname === '/report/zeroTrust'
@ -51,13 +59,13 @@ class SideNavComponent extends React.Component {
}}>
<span className='number'>3.</span>
Security Reports
{this.props.completedSteps.report_done ?
{completedSteps.reportDone ?
<FontAwesomeIcon icon={faCheck} className='pull-right checkmark'/>
: ''}
</NavLink>
</li>
<li>
<NavLink to='/start-over'>
<NavLink to='/start-over' className={getNavLinkClass()}>
<span className='number'><FontAwesomeIcon icon={faUndo} style={{'marginLeft': '-1px'}}/></span>
Start Over
</NavLink>
@ -66,8 +74,14 @@ class SideNavComponent extends React.Component {
<hr/>
<ul>
<li><NavLink to='/configure'>Configuration</NavLink></li>
<li><NavLink to='/infection/telemetry'>Logs</NavLink></li>
<li><NavLink to='/configure'
className={getNavLinkClass()}>
Configuration
</NavLink></li>
<li><NavLink to='/infection/telemetry'
className={getNavLinkClass()}>
Logs
</NavLink></li>
</ul>
<hr/>
@ -85,8 +99,15 @@ class SideNavComponent extends React.Component {
<NavLink to='/license'>License</NavLink>
</div>
<VersionComponent/>
</>)
}
</>);
function getNavLinkClass() {
if(disabled){
return `nav-link disabled`
} else {
return ''
}
}
}
export default SideNavComponent;

View File

@ -1,6 +1,6 @@
import React from 'react'
import {Route} from 'react-router-dom'
import SideNavComponent from '../SideNavComponent'
import SideNavComponent from '../SideNavComponent.tsx'
import {Col, Row} from 'react-bootstrap';
export const StandardLayoutComponent = ({component: Component, ...rest}) => (

View File

@ -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;
}
}

View File

@ -1,5 +1,6 @@
{
"compilerOptions": {
"allowJs": true,
"sourceMap": true,
"module": "commonjs",
"target": "es6",