├── .erb
├── mocks
│ └── fileMock.js
├── img
│ └── erb-logo.png
├── configs
│ ├── .eslintrc
│ ├── webpack.config.eslint.ts
│ ├── webpack.paths.ts
│ ├── webpack.config.base.ts
│ ├── webpack.config.renderer.dev.dll.ts
│ ├── webpack.config.preload.dev.ts
│ ├── webpack.config.main.prod.ts
│ ├── webpack.config.renderer.prod.ts
│ └── webpack.config.renderer.dev.ts
└── scripts
│ ├── .eslintrc
│ ├── delete-source-maps.js
│ ├── link-modules.ts
│ ├── check-node-env.js
│ ├── clean.js
│ ├── check-port-in-use.js
│ ├── electron-rebuild.js
│ ├── check-build-exists.ts
│ ├── notarize.js
│ └── check-native-dep.js
├── src
├── renderer
│ ├── components
│ │ ├── Charts.css
│ │ ├── host
│ │ │ ├── actions
│ │ │ │ └── handleVulnList.js
│ │ │ ├── HostSoftware.js
│ │ │ ├── HostServices.js
│ │ │ ├── HostOverview.js
│ │ │ ├── HostManager.js
│ │ │ ├── VulnList.tsx
│ │ │ └── NewHost.tsx
│ │ ├── VulnPieGraph.js
│ │ ├── agent
│ │ │ ├── Agent.css
│ │ │ ├── TerminalCanvas.js
│ │ │ ├── AgentFinder.js
│ │ │ └── TerminalPrompt.js
│ │ ├── TopRemediations.js
│ │ ├── VulnOverTime.js
│ │ ├── TopVulns.js
│ │ ├── MenuBar.tsx
│ │ ├── WindowControls.js
│ │ ├── VulnFilter.js
│ │ ├── DashCards.js
│ │ ├── ToolBar.js
│ │ ├── VulnsBySeverity.js
│ │ ├── Home.css
│ │ └── MenuBar2.js
│ ├── preload.d.ts
│ ├── index.ejs
│ ├── index.tsx
│ ├── containers
│ │ ├── Main.css
│ │ ├── Dashboard.js
│ │ ├── Agents.js
│ │ └── Hosts.js
│ ├── App.css
│ ├── Nav.tsx
│ ├── actions
│ │ └── api
│ │ │ └── db.js
│ └── App.tsx
├── __tests__
│ └── App.test.tsx
└── main
│ ├── util.ts
│ ├── preload.ts
│ ├── main.ts
│ └── menu.ts
├── assets
├── icon.icns
├── icon.ico
├── icon.png
├── logo.png
├── icons
│ ├── 128x128.png
│ ├── 16x16.png
│ ├── 24x24.png
│ ├── 256x256.png
│ ├── 32x32.png
│ ├── 48x48.png
│ ├── 512x512.png
│ ├── 64x64.png
│ ├── 96x96.png
│ └── 1024x1024.png
├── entitlements.mac.plist
├── assets.d.ts
└── icon.svg
├── .husky
└── pre-commit
├── .vscode
├── extensions.json
├── settings.json
├── tasks.json
└── launch.json
├── .github
├── config.yml
├── FUNDING.yml
├── ISSUE_TEMPLATE
│ ├── 3-Feature_request.md
│ ├── 2-Question.md
│ └── 1-Bug_report.md
├── stale.yml
└── workflows
│ ├── test.yml
│ └── publish.yml
├── .editorconfig
├── .gitattributes
├── release
└── app
│ ├── package-lock.json
│ └── package.json
├── .gitignore
├── .eslintignore
├── tsconfig.json
├── .eslintrc.js
├── README.md
├── LICENSE
├── CODE_OF_CONDUCT.md
├── package.json
└── CHANGELOG.md
/.erb/mocks/fileMock.js:
--------------------------------------------------------------------------------
1 | export default 'test-file-stub';
2 |
--------------------------------------------------------------------------------
/src/renderer/components/Charts.css:
--------------------------------------------------------------------------------
1 | .titletext {
2 | color: white;
3 | }
4 |
--------------------------------------------------------------------------------
/assets/icon.icns:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/0sm0s1z/Sirius/HEAD/assets/icon.icns
--------------------------------------------------------------------------------
/assets/icon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/0sm0s1z/Sirius/HEAD/assets/icon.ico
--------------------------------------------------------------------------------
/assets/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/0sm0s1z/Sirius/HEAD/assets/icon.png
--------------------------------------------------------------------------------
/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/0sm0s1z/Sirius/HEAD/assets/logo.png
--------------------------------------------------------------------------------
/.erb/img/erb-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/0sm0s1z/Sirius/HEAD/.erb/img/erb-logo.png
--------------------------------------------------------------------------------
/.husky/pre-commit:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | . "$(dirname "$0")/_/husky.sh"
3 |
4 | npx lint-staged
5 |
--------------------------------------------------------------------------------
/assets/icons/128x128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/0sm0s1z/Sirius/HEAD/assets/icons/128x128.png
--------------------------------------------------------------------------------
/assets/icons/16x16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/0sm0s1z/Sirius/HEAD/assets/icons/16x16.png
--------------------------------------------------------------------------------
/assets/icons/24x24.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/0sm0s1z/Sirius/HEAD/assets/icons/24x24.png
--------------------------------------------------------------------------------
/assets/icons/256x256.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/0sm0s1z/Sirius/HEAD/assets/icons/256x256.png
--------------------------------------------------------------------------------
/assets/icons/32x32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/0sm0s1z/Sirius/HEAD/assets/icons/32x32.png
--------------------------------------------------------------------------------
/assets/icons/48x48.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/0sm0s1z/Sirius/HEAD/assets/icons/48x48.png
--------------------------------------------------------------------------------
/assets/icons/512x512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/0sm0s1z/Sirius/HEAD/assets/icons/512x512.png
--------------------------------------------------------------------------------
/assets/icons/64x64.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/0sm0s1z/Sirius/HEAD/assets/icons/64x64.png
--------------------------------------------------------------------------------
/assets/icons/96x96.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/0sm0s1z/Sirius/HEAD/assets/icons/96x96.png
--------------------------------------------------------------------------------
/assets/icons/1024x1024.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/0sm0s1z/Sirius/HEAD/assets/icons/1024x1024.png
--------------------------------------------------------------------------------
/.vscode/extensions.json:
--------------------------------------------------------------------------------
1 | {
2 | "recommendations": ["dbaeumer.vscode-eslint", "EditorConfig.EditorConfig"]
3 | }
4 |
--------------------------------------------------------------------------------
/.github/config.yml:
--------------------------------------------------------------------------------
1 | requiredHeaders:
2 | - Prerequisites
3 | - Expected Behavior
4 | - Current Behavior
5 | - Possible Solution
6 | - Your Environment
7 |
--------------------------------------------------------------------------------
/.erb/configs/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "rules": {
3 | "no-console": "off",
4 | "global-require": "off",
5 | "import/no-dynamic-require": "off"
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/src/renderer/components/host/actions/handleVulnList.js:
--------------------------------------------------------------------------------
1 | export async function handleVulnList (vulnList) {
2 |
3 | console.log(vulnList.CVEDataFormat)
4 |
5 | }
6 |
--------------------------------------------------------------------------------
/.erb/configs/webpack.config.eslint.ts:
--------------------------------------------------------------------------------
1 | /* eslint import/no-unresolved: off, import/no-self-import: off */
2 |
3 | module.exports = require('./webpack.config.renderer.dev').default;
4 |
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | github: [electron-react-boilerplate, amilajack]
4 | patreon: amilajack
5 | open_collective: electron-react-boilerplate-594
6 |
--------------------------------------------------------------------------------
/.erb/scripts/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "rules": {
3 | "no-console": "off",
4 | "global-require": "off",
5 | "import/no-dynamic-require": "off",
6 | "import/no-extraneous-dependencies": "off"
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | indent_style = space
5 | indent_size = 2
6 | end_of_line = lf
7 | charset = utf-8
8 | trim_trailing_whitespace = true
9 | insert_final_newline = true
10 |
11 | [*.md]
12 | trim_trailing_whitespace = false
13 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | * text eol=lf
2 | *.exe binary
3 | *.png binary
4 | *.jpg binary
5 | *.jpeg binary
6 | *.ico binary
7 | *.icns binary
8 | *.eot binary
9 | *.otf binary
10 | *.ttf binary
11 | *.woff binary
12 | *.woff2 binary
13 |
--------------------------------------------------------------------------------
/src/__tests__/App.test.tsx:
--------------------------------------------------------------------------------
1 | import '@testing-library/jest-dom';
2 | import { render } from '@testing-library/react';
3 | import App from '../renderer/App';
4 |
5 | describe('App', () => {
6 | it('should render', () => {
7 | expect(render()).toBeTruthy();
8 | });
9 | });
10 |
--------------------------------------------------------------------------------
/.erb/scripts/delete-source-maps.js:
--------------------------------------------------------------------------------
1 | import path from 'path';
2 | import rimraf from 'rimraf';
3 | import webpackPaths from '../configs/webpack.paths';
4 |
5 | export default function deleteSourceMaps() {
6 | rimraf.sync(path.join(webpackPaths.distMainPath, '*.js.map'));
7 | rimraf.sync(path.join(webpackPaths.distRendererPath, '*.js.map'));
8 | }
9 |
--------------------------------------------------------------------------------
/release/app/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "electron-react-boilerplate",
3 | "version": "4.5.0",
4 | "lockfileVersion": 2,
5 | "requires": true,
6 | "packages": {
7 | "": {
8 | "name": "electron-react-boilerplate",
9 | "version": "4.5.0",
10 | "hasInstallScript": true,
11 | "license": "MIT"
12 | }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/.erb/scripts/link-modules.ts:
--------------------------------------------------------------------------------
1 | import fs from 'fs';
2 | import webpackPaths from '../configs/webpack.paths';
3 |
4 | const { srcNodeModulesPath } = webpackPaths;
5 | const { appNodeModulesPath } = webpackPaths;
6 |
7 | if (!fs.existsSync(srcNodeModulesPath) && fs.existsSync(appNodeModulesPath)) {
8 | fs.symlinkSync(appNodeModulesPath, srcNodeModulesPath, 'junction');
9 | }
10 |
--------------------------------------------------------------------------------
/assets/entitlements.mac.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | com.apple.security.cs.allow-unsigned-executable-memory
6 |
7 | com.apple.security.cs.allow-jit
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/src/renderer/preload.d.ts:
--------------------------------------------------------------------------------
1 | declare global {
2 | interface Window {
3 | electron: {
4 | ipcRenderer: {
5 | myPing(): void;
6 | on(
7 | channel: string,
8 | func: (...args: unknown[]) => void
9 | ): (() => void) | undefined;
10 | once(channel: string, func: (...args: unknown[]) => void): void;
11 | };
12 | };
13 | }
14 | }
15 |
16 | export {};
17 |
--------------------------------------------------------------------------------
/src/renderer/index.ejs:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
8 |
12 | Sirius Scan
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/src/renderer/index.tsx:
--------------------------------------------------------------------------------
1 | import { createRoot } from 'react-dom/client';
2 | import App from './App';
3 |
4 | const container = document.getElementById('root')!;
5 | const root = createRoot(container);
6 | root.render();
7 |
8 | // calling IPC exposed from preload script
9 | window.electron.ipcRenderer.once('ipc-example', (arg) => {
10 | // eslint-disable-next-line no-console
11 | console.log(arg);
12 | });
13 | window.electron.ipcRenderer.myPing();
14 |
--------------------------------------------------------------------------------
/.erb/scripts/check-node-env.js:
--------------------------------------------------------------------------------
1 | import chalk from 'chalk';
2 |
3 | export default function checkNodeEnv(expectedEnv) {
4 | if (!expectedEnv) {
5 | throw new Error('"expectedEnv" not set');
6 | }
7 |
8 | if (process.env.NODE_ENV !== expectedEnv) {
9 | console.log(
10 | chalk.whiteBright.bgRed.bold(
11 | `"process.env.NODE_ENV" must be "${expectedEnv}" to use this webpack config`
12 | )
13 | );
14 | process.exit(2);
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/3-Feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: You want something added to the boilerplate. 🎉
4 | labels: 'enhancement'
5 | ---
6 |
7 |
16 |
--------------------------------------------------------------------------------
/.erb/scripts/clean.js:
--------------------------------------------------------------------------------
1 | import rimraf from 'rimraf';
2 | import process from 'process';
3 | import webpackPaths from '../configs/webpack.paths';
4 |
5 | const args = process.argv.slice(2);
6 | const commandMap = {
7 | dist: webpackPaths.distPath,
8 | release: webpackPaths.releasePath,
9 | dll: webpackPaths.dllPath,
10 | };
11 |
12 | args.forEach((x) => {
13 | const pathToRemove = commandMap[x];
14 | if (pathToRemove !== undefined) {
15 | rimraf.sync(pathToRemove);
16 | }
17 | });
18 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/2-Question.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Question
3 | about: Ask a question.❓
4 | labels: 'question'
5 | ---
6 |
7 | ## Summary
8 |
9 |
10 |
11 |
20 |
--------------------------------------------------------------------------------
/.erb/scripts/check-port-in-use.js:
--------------------------------------------------------------------------------
1 | import chalk from 'chalk';
2 | import detectPort from 'detect-port';
3 |
4 | const port = process.env.PORT || '1212';
5 |
6 | detectPort(port, (err, availablePort) => {
7 | if (port !== String(availablePort)) {
8 | throw new Error(
9 | chalk.whiteBright.bgRed.bold(
10 | `Port "${port}" on "localhost" is already in use. Please use another port. ex: PORT=4343 npm start`
11 | )
12 | );
13 | } else {
14 | process.exit(0);
15 | }
16 | });
17 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 |
5 | # Runtime data
6 | pids
7 | *.pid
8 | *.seed
9 |
10 | # Coverage directory used by tools like istanbul
11 | coverage
12 | .eslintcache
13 |
14 | # Dependency directory
15 | # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git
16 | node_modules
17 |
18 | # OSX
19 | .DS_Store
20 |
21 | release/app/dist
22 | release/build
23 | .erb/dll
24 |
25 | .idea
26 | npm-debug.log.*
27 | *.css.d.ts
28 | *.sass.d.ts
29 | *.scss.d.ts
30 |
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 |
5 | # Runtime data
6 | pids
7 | *.pid
8 | *.seed
9 |
10 | # Coverage directory used by tools like istanbul
11 | coverage
12 | .eslintcache
13 |
14 | # Dependency directory
15 | # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git
16 | node_modules
17 |
18 | # OSX
19 | .DS_Store
20 |
21 | release/app/dist
22 | release/build
23 | .erb/dll
24 |
25 | .idea
26 | npm-debug.log.*
27 | *.css.d.ts
28 | *.sass.d.ts
29 | *.scss.d.ts
30 |
31 | # eslint ignores hidden directories by default:
32 | # https://github.com/eslint/eslint/issues/8429
33 | !.erb
34 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "files.associations": {
3 | ".eslintrc": "jsonc",
4 | ".prettierrc": "jsonc",
5 | ".eslintignore": "ignore"
6 | },
7 |
8 | "javascript.validate.enable": false,
9 | "javascript.format.enable": false,
10 | "typescript.format.enable": false,
11 |
12 | "search.exclude": {
13 | ".git": true,
14 | ".eslintcache": true,
15 | ".erb/dll": true,
16 | "release/{build,app/dist}": true,
17 | "node_modules": true,
18 | "npm-debug.log.*": true,
19 | "test/**/__snapshots__": true,
20 | "package-lock.json": true,
21 | "*.{css,sass,scss}.d.ts": true
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/assets/assets.d.ts:
--------------------------------------------------------------------------------
1 | type Styles = Record;
2 |
3 | declare module '*.svg' {
4 | const content: string;
5 | export default content;
6 | }
7 |
8 | declare module '*.png' {
9 | const content: string;
10 | export default content;
11 | }
12 |
13 | declare module '*.jpg' {
14 | const content: string;
15 | export default content;
16 | }
17 |
18 | declare module '*.scss' {
19 | const content: Styles;
20 | export default content;
21 | }
22 |
23 | declare module '*.sass' {
24 | const content: Styles;
25 | export default content;
26 | }
27 |
28 | declare module '*.css' {
29 | const content: Styles;
30 | export default content;
31 | }
32 |
--------------------------------------------------------------------------------
/src/main/util.ts:
--------------------------------------------------------------------------------
1 | /* eslint import/prefer-default-export: off, import/no-mutable-exports: off */
2 | import { URL } from 'url';
3 | import path from 'path';
4 |
5 | export let resolveHtmlPath: (htmlFileName: string) => string;
6 |
7 | if (process.env.NODE_ENV === 'development') {
8 | const port = process.env.PORT || 1212;
9 | resolveHtmlPath = (htmlFileName: string) => {
10 | const url = new URL(`http://localhost:${port}`);
11 | url.pathname = htmlFileName;
12 | return url.href;
13 | };
14 | } else {
15 | resolveHtmlPath = (htmlFileName: string) => {
16 | return `file://${path.resolve(__dirname, '../renderer/', htmlFileName)}`;
17 | };
18 | }
19 |
--------------------------------------------------------------------------------
/.vscode/tasks.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "2.0.0",
3 | "tasks": [
4 | {
5 | "type": "npm",
6 | "label": "Start Webpack Dev",
7 | "script": "start:renderer",
8 | "options": {
9 | "cwd": "${workspaceFolder}"
10 | },
11 | "isBackground": true,
12 | "problemMatcher": {
13 | "owner": "custom",
14 | "pattern": {
15 | "regexp": "____________"
16 | },
17 | "background": {
18 | "activeOnStart": true,
19 | "beginsPattern": "Compiling\\.\\.\\.$",
20 | "endsPattern": "(Compiled successfully|Failed to compile)\\.$"
21 | }
22 | }
23 | }
24 | ]
25 | }
26 |
--------------------------------------------------------------------------------
/src/renderer/containers/Main.css:
--------------------------------------------------------------------------------
1 | .maincontainer {
2 | position: relative;
3 | top: 67px;
4 | height: 100vh;
5 | background-color: #333;
6 | width: 100vw;
7 | padding-top: 30px;
8 | }
9 | .maincontent {
10 | padding-left: 65px;
11 | }
12 | .dashbanner {
13 | padding-left: 20px;
14 | padding-right: 20px;
15 | padding-bottom: 50px;
16 | }
17 | .MuiPaper-root.info {
18 | background-color: #7373ba;
19 | color: white;
20 | }
21 | .MuiPaper-root.critical {
22 | background-color: #931717;
23 | color: white;
24 | }
25 | .MuiPaper-root.moderate {
26 | background-color: #87876e;
27 | color: white;
28 | }
29 | .MuiPaper-root.secure {
30 | background-color: #247424;
31 | color: white;
32 | }
33 |
--------------------------------------------------------------------------------
/.erb/scripts/electron-rebuild.js:
--------------------------------------------------------------------------------
1 | import { execSync } from 'child_process';
2 | import fs from 'fs';
3 | import { dependencies } from '../../release/app/package.json';
4 | import webpackPaths from '../configs/webpack.paths';
5 |
6 | if (
7 | Object.keys(dependencies || {}).length > 0 &&
8 | fs.existsSync(webpackPaths.appNodeModulesPath)
9 | ) {
10 | const electronRebuildCmd =
11 | '../../node_modules/.bin/electron-rebuild --force --types prod,dev,optional --module-dir .';
12 | const cmd =
13 | process.platform === 'win32'
14 | ? electronRebuildCmd.replace(/\//g, '\\')
15 | : electronRebuildCmd;
16 | execSync(cmd, {
17 | cwd: webpackPaths.appPath,
18 | stdio: 'inherit',
19 | });
20 | }
21 |
--------------------------------------------------------------------------------
/release/app/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "electron-react-boilerplate",
3 | "version": "4.5.0",
4 | "description": "A foundation for scalable desktop apps",
5 | "main": "./dist/main/main.js",
6 | "author": {
7 | "name": "Electron React Boilerplate Maintainers",
8 | "email": "electronreactboilerplate@gmail.com",
9 | "url": "https://github.com/electron-react-boilerplate"
10 | },
11 | "scripts": {
12 | "electron-rebuild": "node -r ts-node/register ../../.erb/scripts/electron-rebuild.js",
13 | "link-modules": "node -r ts-node/register ../../.erb/scripts/link-modules.ts",
14 | "postinstall": "npm run electron-rebuild && npm run link-modules"
15 | },
16 | "dependencies": {},
17 | "license": "MIT"
18 | }
19 |
--------------------------------------------------------------------------------
/.github/stale.yml:
--------------------------------------------------------------------------------
1 | # Number of days of inactivity before an issue becomes stale
2 | daysUntilStale: 60
3 | # Number of days of inactivity before a stale issue is closed
4 | daysUntilClose: 7
5 | # Issues with these labels will never be considered stale
6 | exemptLabels:
7 | - discussion
8 | - security
9 | # Label to use when marking an issue as stale
10 | staleLabel: wontfix
11 | # Comment to post when marking an issue as stale. Set to `false` to disable
12 | markComment: >
13 | This issue has been automatically marked as stale because it has not had
14 | recent activity. It will be closed if no further activity occurs. Thank you
15 | for your contributions.
16 | # Comment to post when closing a stale issue. Set to `false` to disable
17 | closeComment: false
18 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es2021",
4 | "module": "commonjs",
5 | "lib": ["dom", "es2021"],
6 | "declaration": true,
7 | "declarationMap": true,
8 | "jsx": "react-jsx",
9 | "strict": true,
10 | "pretty": true,
11 | "sourceMap": true,
12 | "baseUrl": "./src",
13 | "noUnusedLocals": true,
14 | "noUnusedParameters": true,
15 | "noImplicitReturns": true,
16 | "noFallthroughCasesInSwitch": true,
17 | "moduleResolution": "node",
18 | "esModuleInterop": true,
19 | "allowSyntheticDefaultImports": true,
20 | "resolveJsonModule": true,
21 | "allowJs": true,
22 | "outDir": "release/app/dist"
23 | },
24 | "exclude": ["test", "release/build", "release/app/dist", ".erb/dll"]
25 | }
26 |
--------------------------------------------------------------------------------
/.vscode/launch.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "0.2.0",
3 | "configurations": [
4 | {
5 | "name": "Electron: Main",
6 | "type": "node",
7 | "request": "launch",
8 | "protocol": "inspector",
9 | "runtimeExecutable": "npm",
10 | "runtimeArgs": [
11 | "run start:main --inspect=5858 --remote-debugging-port=9223"
12 | ],
13 | "preLaunchTask": "Start Webpack Dev"
14 | },
15 | {
16 | "name": "Electron: Renderer",
17 | "type": "chrome",
18 | "request": "attach",
19 | "port": 9223,
20 | "webRoot": "${workspaceFolder}",
21 | "timeout": 15000
22 | }
23 | ],
24 | "compounds": [
25 | {
26 | "name": "Electron: All",
27 | "configurations": ["Electron: Main", "Electron: Renderer"]
28 | }
29 | ]
30 | }
31 |
--------------------------------------------------------------------------------
/.github/workflows/test.yml:
--------------------------------------------------------------------------------
1 | name: Test
2 |
3 | on: [push, pull_request]
4 |
5 | jobs:
6 | release:
7 | runs-on: ${{ matrix.os }}
8 |
9 | strategy:
10 | matrix:
11 | os: [macos-latest, windows-latest, ubuntu-latest]
12 |
13 | steps:
14 | - name: Check out Git repository
15 | uses: actions/checkout@v1
16 |
17 | - name: Install Node.js and NPM
18 | uses: actions/setup-node@v2
19 | with:
20 | node-version: 16
21 | cache: npm
22 |
23 | - name: npm install
24 | run: |
25 | npm install
26 |
27 | - name: npm test
28 | env:
29 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
30 | run: |
31 | npm run package
32 | npm run lint
33 | npm exec tsc
34 | npm test
35 |
--------------------------------------------------------------------------------
/.erb/scripts/check-build-exists.ts:
--------------------------------------------------------------------------------
1 | // Check if the renderer and main bundles are built
2 | import path from 'path';
3 | import chalk from 'chalk';
4 | import fs from 'fs';
5 | import webpackPaths from '../configs/webpack.paths';
6 |
7 | const mainPath = path.join(webpackPaths.distMainPath, 'main.js');
8 | const rendererPath = path.join(webpackPaths.distRendererPath, 'renderer.js');
9 |
10 | if (!fs.existsSync(mainPath)) {
11 | throw new Error(
12 | chalk.whiteBright.bgRed.bold(
13 | 'The main process is not built yet. Build it by running "npm run build:main"'
14 | )
15 | );
16 | }
17 |
18 | if (!fs.existsSync(rendererPath)) {
19 | throw new Error(
20 | chalk.whiteBright.bgRed.bold(
21 | 'The renderer process is not built yet. Build it by running "npm run build:renderer"'
22 | )
23 | );
24 | }
25 |
--------------------------------------------------------------------------------
/.erb/scripts/notarize.js:
--------------------------------------------------------------------------------
1 | const { notarize } = require('electron-notarize');
2 | const { build } = require('../../package.json');
3 |
4 | exports.default = async function notarizeMacos(context) {
5 | const { electronPlatformName, appOutDir } = context;
6 | if (electronPlatformName !== 'darwin') {
7 | return;
8 | }
9 |
10 | if (process.env.CI !== 'true') {
11 | console.warn('Skipping notarizing step. Packaging is not running in CI');
12 | return;
13 | }
14 |
15 | if (!('APPLE_ID' in process.env && 'APPLE_ID_PASS' in process.env)) {
16 | console.warn(
17 | 'Skipping notarizing step. APPLE_ID and APPLE_ID_PASS env variables must be set'
18 | );
19 | return;
20 | }
21 |
22 | const appName = context.packager.appInfo.productFilename;
23 |
24 | await notarize({
25 | appBundleId: build.appId,
26 | appPath: `${appOutDir}/${appName}.app`,
27 | appleId: process.env.APPLE_ID,
28 | appleIdPassword: process.env.APPLE_ID_PASS,
29 | });
30 | };
31 |
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | extends: 'erb',
3 | rules: {
4 | // A temporary hack related to IDE not resolving correct package.json
5 | 'import/no-extraneous-dependencies': 'off',
6 | 'import/no-unresolved': 'error',
7 | // Since React 17 and typescript 4.1 you can safely disable the rule
8 | 'react/react-in-jsx-scope': 'off',
9 | },
10 | parserOptions: {
11 | ecmaVersion: 2020,
12 | sourceType: 'module',
13 | project: './tsconfig.json',
14 | tsconfigRootDir: __dirname,
15 | createDefaultProgram: true,
16 | },
17 | settings: {
18 | 'import/resolver': {
19 | // See https://github.com/benmosher/eslint-plugin-import/issues/1396#issuecomment-575727774 for line below
20 | node: {},
21 | webpack: {
22 | config: require.resolve('./.erb/configs/webpack.config.eslint.ts'),
23 | },
24 | typescript: {},
25 | },
26 | 'import/parsers': {
27 | '@typescript-eslint/parser': ['.ts', '.tsx'],
28 | },
29 | },
30 | };
31 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Sirius Scan
2 |
3 | Sirius is the first truly open-source general purpose vulnerability scanner. Today, the information security community remains the best and most expedient source for cybersecurity intelligence. The community itself regularly outperforms commercial vendors. This is the primary advantage Sirius Scan intends to leverage.
4 |
5 | The framework is built around four general vulnerability identification concepts: The vulnerability database, network vulnerability scanning, agent-based discovery, and custom assessor analysis. With these powers combined around an easy to use interface Sirius hopes to enable industry evolution.
6 |
7 | ## Getting Started
8 |
9 | Sirius is now in Alpha! Wooo! Currently, there is no automatic installation utility (that will be coming with the Beta release). For now, the following guide should help you get started.
10 |
11 | ### Dependencies
12 |
13 | - MongoDB
14 | - NodeJS
15 | - npm
16 | - Go
17 |
18 | ### Sirius UI
19 |
20 | To install the UI clone this repository and instantiate it with npm.
21 |
22 | ```
23 | npm start
24 | ```
25 |
--------------------------------------------------------------------------------
/src/main/preload.ts:
--------------------------------------------------------------------------------
1 | import { contextBridge, ipcRenderer, IpcRendererEvent } from 'electron';
2 |
3 | contextBridge.exposeInMainWorld('electron', {
4 | ipcRenderer: {
5 | myPing() {
6 | ipcRenderer.send('ipc-example', 'ping');
7 | },
8 | on(channel: string, func: (...args: unknown[]) => void) {
9 | const validChannels = ['ipc-example'];
10 | if (validChannels.includes(channel)) {
11 | const subscription = (_event: IpcRendererEvent, ...args: unknown[]) =>
12 | func(...args);
13 | // Deliberately strip event as it includes `sender`
14 | ipcRenderer.on(channel, subscription);
15 |
16 | return () => ipcRenderer.removeListener(channel, subscription);
17 | }
18 |
19 | return undefined;
20 | },
21 | once(channel: string, func: (...args: unknown[]) => void) {
22 | const validChannels = ['ipc-example'];
23 | if (validChannels.includes(channel)) {
24 | // Deliberately strip event as it includes `sender`
25 | ipcRenderer.once(channel, (_event, ...args) => func(...args));
26 | }
27 | },
28 | },
29 | });
30 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015-present Electron React Boilerplate
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/.erb/configs/webpack.paths.ts:
--------------------------------------------------------------------------------
1 | const path = require('path');
2 |
3 | const rootPath = path.join(__dirname, '../..');
4 |
5 | const dllPath = path.join(__dirname, '../dll');
6 |
7 | const srcPath = path.join(rootPath, 'src');
8 | const srcMainPath = path.join(srcPath, 'main');
9 | const srcRendererPath = path.join(srcPath, 'renderer');
10 |
11 | const releasePath = path.join(rootPath, 'release');
12 | const appPath = path.join(releasePath, 'app');
13 | const appPackagePath = path.join(appPath, 'package.json');
14 | const appNodeModulesPath = path.join(appPath, 'node_modules');
15 | const srcNodeModulesPath = path.join(srcPath, 'node_modules');
16 |
17 | const distPath = path.join(appPath, 'dist');
18 | const distMainPath = path.join(distPath, 'main');
19 | const distRendererPath = path.join(distPath, 'renderer');
20 |
21 | const buildPath = path.join(releasePath, 'build');
22 |
23 | export default {
24 | rootPath,
25 | dllPath,
26 | srcPath,
27 | srcMainPath,
28 | srcRendererPath,
29 | releasePath,
30 | appPath,
31 | appPackagePath,
32 | appNodeModulesPath,
33 | srcNodeModulesPath,
34 | distPath,
35 | distMainPath,
36 | distRendererPath,
37 | buildPath,
38 | };
39 |
--------------------------------------------------------------------------------
/src/renderer/App.css:
--------------------------------------------------------------------------------
1 | /*
2 | * @NOTE: Prepend a `~` to css file paths that are in your node_modules
3 | * See https://github.com/webpack-contrib/sass-loader#imports
4 | */
5 | body {
6 | position: relative;
7 | color: white;
8 | height: 100vh;
9 | font-family: sans-serif;
10 | overflow-y: hidden;
11 | display: flex;
12 | justify-content: center;
13 | align-items: center;
14 | }
15 |
16 | button {
17 | background-color: white;
18 | padding: 10px 20px;
19 | border-radius: 10px;
20 | border: none;
21 | appearance: none;
22 | font-size: 1.3rem;
23 | box-shadow: 0px 8px 28px -6px rgba(24, 39, 75, 0.12),
24 | 0px 18px 88px -4px rgba(24, 39, 75, 0.14);
25 | transition: all ease-in 0.1s;
26 | cursor: pointer;
27 | opacity: 0.9;
28 | }
29 |
30 | button:hover {
31 | transform: scale(1.05);
32 | opacity: 1;
33 | }
34 |
35 | li {
36 | list-style: none;
37 | }
38 |
39 | a {
40 | text-decoration: none;
41 | height: fit-content;
42 | width: fit-content;
43 | margin: 10px;
44 | }
45 |
46 | a:hover {
47 | opacity: 1;
48 | text-decoration: none;
49 | }
50 |
51 | .Hello {
52 | display: flex;
53 | justify-content: center;
54 | align-items: center;
55 | margin: 20px 0;
56 | }
57 |
--------------------------------------------------------------------------------
/src/renderer/Nav.tsx:
--------------------------------------------------------------------------------
1 | import { MemoryRouter as Router, Routes, Route } from 'react-router-dom';
2 | import icon from '../../assets/icon.svg';
3 | import './App.css';
4 |
5 | const Hello = () => {
6 | return (
7 |
8 |
9 |

10 |
11 |
sutff
12 |
38 |
39 | );
40 | };
41 |
42 | export default function App() {
43 | return (
44 |
45 |
46 | } />
47 |
48 |
49 | );
50 | }
51 |
--------------------------------------------------------------------------------
/.erb/configs/webpack.config.base.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Base webpack config used across other specific configs
3 | */
4 |
5 | import webpack from 'webpack';
6 | import webpackPaths from './webpack.paths';
7 | import { dependencies as externals } from '../../release/app/package.json';
8 |
9 | const configuration: webpack.Configuration = {
10 | externals: [...Object.keys(externals || {})],
11 |
12 | stats: 'errors-only',
13 |
14 | module: {
15 | rules: [
16 | {
17 | test: /\.[jt]sx?$/,
18 | exclude: /node_modules/,
19 | use: {
20 | loader: 'ts-loader',
21 | options: {
22 | // Remove this line to enable type checking in webpack builds
23 | transpileOnly: true,
24 | },
25 | },
26 | },
27 | ],
28 | },
29 |
30 | output: {
31 | path: webpackPaths.srcPath,
32 | // https://github.com/webpack/webpack/issues/1114
33 | library: {
34 | type: 'commonjs2',
35 | },
36 | },
37 |
38 | /**
39 | * Determine the array of extensions that should be used to resolve modules.
40 | */
41 | resolve: {
42 | extensions: ['.js', '.jsx', '.json', '.ts', '.tsx'],
43 | modules: [webpackPaths.srcPath, 'node_modules'],
44 | },
45 |
46 | plugins: [
47 | new webpack.EnvironmentPlugin({
48 | NODE_ENV: 'production',
49 | }),
50 | ],
51 | };
52 |
53 | export default configuration;
54 |
--------------------------------------------------------------------------------
/src/renderer/components/VulnPieGraph.js:
--------------------------------------------------------------------------------
1 | // @flow
2 | import React, { Component } from 'react';
3 | import { Link } from 'react-router-dom';
4 | import { PieChart, Pie, Sector, Cell, Label } from 'recharts';
5 |
6 | class VulnPieGraph extends React.Component {
7 | //props: Props;
8 |
9 | constructor(props) {
10 | super(props);
11 |
12 | this.state = {
13 | open: false
14 | };
15 | }
16 |
17 |
18 | render() {
19 | const data = [
20 | { name: 'Group A', value: 400 },
21 | { name: 'Group B', value: 100 },
22 | { name: 'Group C', value: 300 },
23 | { name: 'Group D', value: 500 },
24 | ];
25 | const COLORS = ['#0088FE', 'red', '#FFBB28', '#FF8042'];
26 |
27 | return (
28 |
29 |
39 |
40 | {data.map((entry, index) => (
41 | |
42 | ))}
43 |
44 |
45 | );
46 | }
47 | }
48 |
49 | export default VulnPieGraph;
50 |
--------------------------------------------------------------------------------
/.github/workflows/publish.yml:
--------------------------------------------------------------------------------
1 | name: Publish
2 |
3 | on:
4 | push:
5 | branches:
6 | - main
7 |
8 | jobs:
9 | publish:
10 | # To enable auto publishing to github, update your electron publisher
11 | # config in package.json > "build" and remove the conditional below
12 | if: ${{ github.repository_owner == 'electron-react-boilerplate' }}
13 |
14 | runs-on: ${{ matrix.os }}
15 |
16 | strategy:
17 | matrix:
18 | os: [macos-latest]
19 |
20 | steps:
21 | - name: Checkout git repo
22 | uses: actions/checkout@v1
23 |
24 | - name: Install Node and NPM
25 | uses: actions/setup-node@v1
26 | with:
27 | node-version: 16
28 | cache: npm
29 |
30 | - name: Install dependencies
31 | run: |
32 | npm install
33 |
34 | - name: Publish releases
35 | env:
36 | # These values are used for auto updates signing
37 | APPLE_ID: ${{ secrets.APPLE_ID }}
38 | APPLE_ID_PASS: ${{ secrets.APPLE_ID_PASS }}
39 | CSC_LINK: ${{ secrets.CSC_LINK }}
40 | CSC_KEY_PASSWORD: ${{ secrets.CSC_KEY_PASSWORD }}
41 | # This is used for uploading release assets to github
42 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
43 | run: |
44 | npm run postinstall
45 | npm run build
46 | npm exec electron-builder -- --publish always --win --mac --linux
47 |
--------------------------------------------------------------------------------
/src/renderer/components/agent/Agent.css:
--------------------------------------------------------------------------------
1 | .terminalprompt {
2 | position: fixed;
3 | bottom: -10px;
4 | left: 65px;
5 | background-color: black;
6 | padding: 15px;
7 | min-height: 15px;
8 | color: yellow;
9 | width: 100vw;
10 | font-family: monospace;
11 | font-size: 22px;
12 | }
13 | .terminaldressing {
14 | position: fixed;
15 | bottom: 59px;
16 | left: 65px;
17 | padding-bottom: 2px;
18 | margin-bottom: 3px;
19 | background-color: #0080ff;
20 | border-top: 1px solid white;
21 | color: #fff;
22 | width: 100vw;
23 | font-family: monospace;
24 | }
25 | .terminalprompt input {
26 | color: white;
27 | font-family: monospace;
28 | font-size: 22px;
29 | }
30 | .terminalcanvas {
31 | position: fixed;
32 | color: white;
33 | height: 800px;
34 | bottom: 80px;
35 | left: 85px;
36 | font-family: monospace;
37 | font-size: 22px;
38 | overflow: scroll;
39 | }
40 | .terminalbg {
41 | position: relative;
42 | left: 50px;
43 | bottom: 160px;
44 | background-color: rgb(35 33 33);
45 | opacity: .4;
46 | z-index: -1;
47 | }
48 | .commandoutput {
49 | font-size: 16px;
50 | }
51 | .terminalcontainer {
52 | position: relative;
53 | min-width: 100vw;
54 | height: 100vh;
55 | background-color: rgb(21 21 21);
56 | }
57 | .terminalbody {
58 | position: absolute;
59 | left: 65px;
60 | min-height: 100vh;
61 | }
62 | .terminalblock{
63 | position: relative;
64 | min-width: 80vw;
65 | z-index: 10;
66 | }
67 | .terminalheader {
68 | position: absolute;
69 | top: 90px;
70 | z-index: 100;
71 | }
72 |
--------------------------------------------------------------------------------
/src/renderer/components/host/HostSoftware.js:
--------------------------------------------------------------------------------
1 | // @flow
2 | import React, { Component } from 'react';
3 | import { Link } from 'react-router-dom';
4 |
5 | import Paper from '@mui/material/Paper';
6 | import Card from '@mui/material/Card';
7 | import CardActions from '@mui/material/CardActions';
8 | import CardContent from '@mui/material/CardContent';
9 | import Typography from '@mui/material/Typography';
10 |
11 | import Chip from '@mui/material/Chip';
12 | import Autocomplete from '@mui/material/Autocomplete';
13 | import TextField from '@mui/material/TextField';
14 | import Stack from '@mui/material/Stack';
15 |
16 | import Security from '@mui/icons-material/Security';
17 | import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
18 | import { faWindows } from '@fortawesome/free-brands-svg-icons';
19 |
20 | import '../Home.css';
21 |
22 | class HostOverview extends React.Component {
23 | //props: Props;
24 |
25 | constructor(props) {
26 | super(props);
27 |
28 | this.state = {
29 | open: false
30 | };
31 | }
32 |
33 |
34 | render() {
35 | return (
36 |
37 |
38 |
39 |
40 | Software
41 |
42 |
43 |
44 |
45 | Struts 2.3
46 |
47 |
48 |
49 |
50 | );
51 | }
52 | }
53 |
54 | export default HostOverview;
55 |
--------------------------------------------------------------------------------
/src/renderer/components/host/HostServices.js:
--------------------------------------------------------------------------------
1 | // @flow
2 | import React, { Component } from 'react';
3 | import { Link } from 'react-router-dom';
4 |
5 | import Paper from '@mui/material/Paper';
6 | import Card from '@mui/material/Card';
7 | import CardActions from '@mui/material/CardActions';
8 | import CardContent from '@mui/material/CardContent';
9 | import Typography from '@mui/material/Typography';
10 |
11 | import Chip from '@mui/material/Chip';
12 | import Autocomplete from '@mui/material/Autocomplete';
13 | import TextField from '@mui/material/TextField';
14 | import Stack from '@mui/material/Stack';
15 |
16 | import Security from '@mui/icons-material/Security';
17 | import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
18 | import { faWindows } from '@fortawesome/free-brands-svg-icons';
19 |
20 | import '../Home.css';
21 |
22 | class HostOverview extends React.Component {
23 | //props: Props;
24 |
25 | constructor(props) {
26 | super(props);
27 |
28 | this.state = {
29 | open: false
30 | };
31 | }
32 |
33 |
34 | render() {
35 | return (
36 |
37 |
38 |
39 |
40 | Services
41 |
42 |
43 |
44 |
45 | Apache 2.4.1
46 |
47 |
48 |
49 |
50 | );
51 | }
52 | }
53 |
54 | export default HostOverview;
55 |
--------------------------------------------------------------------------------
/src/renderer/components/TopRemediations.js:
--------------------------------------------------------------------------------
1 | // @flow
2 | import React, { Component } from 'react';
3 | import { Link } from 'react-router-dom';
4 |
5 | import Paper from '@mui/material/Paper';
6 | import Card from '@mui/material/Card';
7 | import CardActions from '@mui/material/CardActions';
8 | import CardContent from '@mui/material/CardContent';
9 | import Typography from '@mui/material/Typography';
10 |
11 | import './Home.css';
12 |
13 | class TopRemediations extends React.Component {
14 | //props: Props;
15 |
16 | constructor(props) {
17 | super(props);
18 |
19 | this.state = {
20 | open: false
21 | };
22 | }
23 |
24 |
25 | render() {
26 | return (
27 |
28 |
29 |
30 |
31 | Top Remediations
32 |
33 |
34 |
35 | 1 - Microsoft Windows Cumultive Updates
36 |
37 |
38 |
39 | 2 - Wordpress Updates
40 |
41 |
42 |
43 | 3 - Apache Webserver Update
44 |
45 |
46 |
47 |
48 |
49 | );
50 | }
51 | }
52 |
53 | export default TopRemediations;
54 |
--------------------------------------------------------------------------------
/src/renderer/components/VulnOverTime.js:
--------------------------------------------------------------------------------
1 | // @flow
2 | import React, { Component } from 'react';
3 | import { Link } from 'react-router-dom';
4 | import { AreaChart, Area, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer } from 'recharts';
5 |
6 | class VulnOverTime extends React.Component {
7 | //props: Props;
8 |
9 | constructor(props) {
10 | super(props);
11 |
12 | this.state = {
13 | open: false
14 | };
15 | }
16 |
17 |
18 | render() {
19 | const data = [
20 | {
21 | name: '',
22 | uv: 4000,
23 | pv: 2400,
24 | amt: 2400,
25 | },
26 | {
27 | name: '',
28 | uv: 3000,
29 | pv: 1398,
30 | amt: 2210,
31 | },
32 | {
33 | name: '',
34 | uv: 2000,
35 | pv: 9800,
36 | amt: 2290,
37 | },
38 | {
39 | name: '',
40 | uv: 2780,
41 | pv: 3908,
42 | amt: 2000,
43 | },
44 | {
45 | name: '',
46 | uv: 1890,
47 | pv: 4800,
48 | amt: 2181,
49 | },
50 | {
51 | name: '',
52 | uv: 2390,
53 | pv: 3800,
54 | amt: 2500,
55 | },
56 | {
57 | name: '',
58 | uv: 3490,
59 | pv: 4300,
60 | amt: 2100,
61 | },
62 | {
63 | name: '',
64 | uv: 1490,
65 | pv: 2300,
66 | amt: 1100,
67 | },
68 | ];
69 |
70 | return (
71 |
82 |
83 |
84 |
85 |
86 |
87 |
88 | );
89 | }
90 | }
91 |
92 | export default VulnOverTime;
93 |
--------------------------------------------------------------------------------
/src/renderer/components/TopVulns.js:
--------------------------------------------------------------------------------
1 | // @flow
2 | import React, { Component } from 'react';
3 | import { Link } from 'react-router-dom';
4 |
5 | import Paper from '@mui/material/Paper';
6 | import Card from '@mui/material/Card';
7 | import CardActions from '@mui/material/CardActions';
8 | import CardContent from '@mui/material/CardContent';
9 | import Typography from '@mui/material/Typography';
10 |
11 | import './Home.css';
12 |
13 | class TopVulns extends React.Component {
14 | //props: Props;
15 |
16 | constructor(props) {
17 | super(props);
18 |
19 | this.state = {
20 | open: false
21 | };
22 | }
23 |
24 |
25 | render() {
26 | return (
27 |
28 |
29 |
30 |
31 | Top Vulnerabilities
32 |
33 |
34 |
35 | 5 - CVE-2017-0145 - Remote Code Execution
36 |
37 |
38 |
39 | 2 - CVE-2020-8196 - Application Delivery Controller (ADC), Gateway, and SDWAN WANOP
40 |
41 |
42 |
43 | 78 - CVE-2021-38647 - Microsoft Azure Open Management Infrastructure (OMI) Remote Code Execution Vulnerability
44 |
45 |
46 |
47 | 13 - CVE-2021-34473 - Microsoft Exchange Server Remote Code Execution Vulnerability
48 |
49 |
50 |
51 |
52 |
53 | );
54 | }
55 | }
56 |
57 | export default TopVulns;
58 |
--------------------------------------------------------------------------------
/.erb/configs/webpack.config.renderer.dev.dll.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Builds the DLL for development electron renderer process
3 | */
4 |
5 | import webpack from 'webpack';
6 | import path from 'path';
7 | import { merge } from 'webpack-merge';
8 | import baseConfig from './webpack.config.base';
9 | import webpackPaths from './webpack.paths';
10 | import { dependencies } from '../../package.json';
11 | import checkNodeEnv from '../scripts/check-node-env';
12 |
13 | checkNodeEnv('development');
14 |
15 | const dist = webpackPaths.dllPath;
16 |
17 | const configuration: webpack.Configuration = {
18 | context: webpackPaths.rootPath,
19 |
20 | devtool: 'eval',
21 |
22 | mode: 'development',
23 |
24 | target: 'electron-renderer',
25 |
26 | externals: ['fsevents', 'crypto-browserify'],
27 |
28 | /**
29 | * Use `module` from `webpack.config.renderer.dev.js`
30 | */
31 | module: require('./webpack.config.renderer.dev').default.module,
32 |
33 | entry: {
34 | renderer: Object.keys(dependencies || {}),
35 | },
36 |
37 | output: {
38 | path: dist,
39 | filename: '[name].dev.dll.js',
40 | library: {
41 | name: 'renderer',
42 | type: 'var',
43 | },
44 | },
45 |
46 | plugins: [
47 | new webpack.DllPlugin({
48 | path: path.join(dist, '[name].json'),
49 | name: '[name]',
50 | }),
51 |
52 | /**
53 | * Create global constants which can be configured at compile time.
54 | *
55 | * Useful for allowing different behaviour between development builds and
56 | * release builds
57 | *
58 | * NODE_ENV should be production so that modules do not perform certain
59 | * development checks
60 | */
61 | new webpack.EnvironmentPlugin({
62 | NODE_ENV: 'development',
63 | }),
64 |
65 | new webpack.LoaderOptionsPlugin({
66 | debug: true,
67 | options: {
68 | context: webpackPaths.srcPath,
69 | output: {
70 | path: webpackPaths.dllPath,
71 | },
72 | },
73 | }),
74 | ],
75 | };
76 |
77 | export default merge(baseConfig, configuration);
78 |
--------------------------------------------------------------------------------
/src/renderer/actions/api/db.js:
--------------------------------------------------------------------------------
1 | export async function getHosts() {
2 | try {
3 | const response = await fetch('http://localhost:8080/api/get/hosts');
4 | return await response.json();
5 | } catch (error) {
6 | return [];
7 | }
8 | }
9 |
10 | export async function getVendors() {
11 | try {
12 | const response = await fetch('http://localhost:8080/api/data/cpe_vendors');
13 | return await response.json();
14 | } catch (error) {
15 | return [];
16 | }
17 | }
18 |
19 | export async function addHost(data) {
20 | try {
21 | const response = await fetch(`http://localhost:8080/api/add/host`, {
22 | method: 'POST',
23 | mode: 'same-origin',
24 | headers: { 'Content-Type': 'application/json' },
25 | body: JSON.stringify(data),
26 | });
27 | return await response.json();
28 | } catch (error) {
29 | return [];
30 | }
31 | }
32 |
33 | export async function taskAgent(data) {
34 | try {
35 | const response = await fetch(`http://localhost:8080/api/agent/task`, {
36 | method: 'POST',
37 | mode: 'same-origin',
38 | headers: { 'Content-Type': 'application/json' },
39 | body: JSON.stringify(data),
40 | });
41 | return await response.json();
42 | } catch (error) {
43 | return [];
44 | }
45 | }
46 |
47 | export async function getTerminalHistory(data) {
48 | try {
49 | const response = await fetch(
50 | `http://localhost:8080/api/data/terminalhistory`,
51 | {
52 | method: 'POST',
53 | mode: 'same-origin',
54 | headers: { 'Content-Type': 'application/json' },
55 | body: JSON.stringify(data),
56 | }
57 | );
58 | return await response.json();
59 | } catch (error) {
60 | return [];
61 | }
62 | }
63 |
64 | export async function getVulnerabilityList(data) {
65 | try {
66 | const response = await fetch(`http://localhost:8080/api/svdb/report/host`, {
67 | method: 'POST',
68 | mode: 'same-origin',
69 | headers: { 'Content-Type': 'application/json' },
70 | body: JSON.stringify(data),
71 | });
72 | return await response.json();
73 | } catch (error) {
74 | return [];
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/src/renderer/components/MenuBar.tsx:
--------------------------------------------------------------------------------
1 | // @flow
2 | import React, { Component } from 'react';
3 | import { Link } from 'react-router-dom';
4 |
5 | import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
6 | import { faWallet, faIndustry, faTerminal, faScroll, faBars, faBug, faKey, faServer, faRadiation, faHeadphones, faTable, faDragon } from '@fortawesome/free-solid-svg-icons';
7 | import ReactTooltip from 'react-tooltip';
8 |
9 | import Button from '@mui/material/Button';
10 | import Avatar from '@mui/material/Avatar';
11 | import Tabs from '@mui/material/Tabs';
12 |
13 |
14 | import './Home.css';
15 | import logo from '/assets/logo.png';
16 |
17 |
18 |
19 | class MenuBar extends React.Component {
20 | props: Props;
21 |
22 | constructor(props) {
23 | super(props);
24 |
25 | this.state = {
26 | open: false
27 | };
28 | }
29 |
30 |
31 | render() {
32 | return (
33 |
34 |
35 |
36 |
37 |
38 |
39 |

40 |
41 |
42 | Dashboard
43 |
44 |
45 | Hosts
46 |
47 |
48 | Vulnerabilities
49 |
50 |
51 | Agents
52 |
53 |
54 | Scans
55 |
56 |
57 |
58 |
59 |
62 |
63 |
64 |
65 |
66 |
67 | );
68 | }
69 | }
70 |
71 | export default MenuBar;
72 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/1-Bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: You're having technical issues. 🐞
4 | labels: 'bug'
5 | ---
6 |
7 |
8 |
9 | ## Prerequisites
10 |
11 |
12 |
13 | - [ ] Using npm
14 | - [ ] Using an up-to-date [`main` branch](https://github.com/electron-react-boilerplate/electron-react-boilerplate/tree/main)
15 | - [ ] Using latest version of devtools. [Check the docs for how to update](https://electron-react-boilerplate.js.org/docs/dev-tools/)
16 | - [ ] Tried solutions mentioned in [#400](https://github.com/electron-react-boilerplate/electron-react-boilerplate/issues/400)
17 | - [ ] For issue in production release, add devtools output of `DEBUG_PROD=true npm run build && npm start`
18 |
19 | ## Expected Behavior
20 |
21 |
22 |
23 | ## Current Behavior
24 |
25 |
26 |
27 | ## Steps to Reproduce
28 |
29 |
30 |
31 |
32 | 1.
33 |
34 | 2.
35 |
36 | 3.
37 |
38 | 4.
39 |
40 | ## Possible Solution (Not obligatory)
41 |
42 |
43 |
44 | ## Context
45 |
46 |
47 |
48 |
49 |
50 | ## Your Environment
51 |
52 |
53 |
54 | - Node version :
55 | - electron-react-boilerplate version or branch :
56 | - Operating System and version :
57 | - Link to your project :
58 |
59 |
68 |
--------------------------------------------------------------------------------
/.erb/configs/webpack.config.preload.dev.ts:
--------------------------------------------------------------------------------
1 | import path from 'path';
2 | import webpack from 'webpack';
3 | import { merge } from 'webpack-merge';
4 | import { BundleAnalyzerPlugin } from 'webpack-bundle-analyzer';
5 | import baseConfig from './webpack.config.base';
6 | import webpackPaths from './webpack.paths';
7 | import checkNodeEnv from '../scripts/check-node-env';
8 |
9 | // When an ESLint server is running, we can't set the NODE_ENV so we'll check if it's
10 | // at the dev webpack config is not accidentally run in a production environment
11 | if (process.env.NODE_ENV === 'production') {
12 | checkNodeEnv('development');
13 | }
14 |
15 | const configuration: webpack.Configuration = {
16 | devtool: 'inline-source-map',
17 |
18 | mode: 'development',
19 |
20 | target: 'electron-preload',
21 |
22 | entry: path.join(webpackPaths.srcMainPath, 'preload.ts'),
23 |
24 | output: {
25 | path: webpackPaths.dllPath,
26 | filename: 'preload.js',
27 | },
28 |
29 | plugins: [
30 | new BundleAnalyzerPlugin({
31 | analyzerMode: process.env.ANALYZE === 'true' ? 'server' : 'disabled',
32 | }),
33 |
34 | /**
35 | * Create global constants which can be configured at compile time.
36 | *
37 | * Useful for allowing different behaviour between development builds and
38 | * release builds
39 | *
40 | * NODE_ENV should be production so that modules do not perform certain
41 | * development checks
42 | *
43 | * By default, use 'development' as NODE_ENV. This can be overriden with
44 | * 'staging', for example, by changing the ENV variables in the npm scripts
45 | */
46 | new webpack.EnvironmentPlugin({
47 | NODE_ENV: 'development',
48 | }),
49 |
50 | new webpack.LoaderOptionsPlugin({
51 | debug: true,
52 | }),
53 | ],
54 |
55 | /**
56 | * Disables webpack processing of __dirname and __filename.
57 | * If you run the bundle in node.js it falls back to these values of node.js.
58 | * https://github.com/webpack/webpack/issues/2010
59 | */
60 | node: {
61 | __dirname: false,
62 | __filename: false,
63 | },
64 |
65 | watch: true,
66 | };
67 |
68 | export default merge(baseConfig, configuration);
69 |
--------------------------------------------------------------------------------
/.erb/scripts/check-native-dep.js:
--------------------------------------------------------------------------------
1 | import fs from 'fs';
2 | import chalk from 'chalk';
3 | import { execSync } from 'child_process';
4 | import { dependencies } from '../../package.json';
5 |
6 | if (dependencies) {
7 | const dependenciesKeys = Object.keys(dependencies);
8 | const nativeDeps = fs
9 | .readdirSync('node_modules')
10 | .filter((folder) => fs.existsSync(`node_modules/${folder}/binding.gyp`));
11 | if (nativeDeps.length === 0) {
12 | process.exit(0);
13 | }
14 | try {
15 | // Find the reason for why the dependency is installed. If it is installed
16 | // because of a devDependency then that is okay. Warn when it is installed
17 | // because of a dependency
18 | const { dependencies: dependenciesObject } = JSON.parse(
19 | execSync(`npm ls ${nativeDeps.join(' ')} --json`).toString()
20 | );
21 | const rootDependencies = Object.keys(dependenciesObject);
22 | const filteredRootDependencies = rootDependencies.filter((rootDependency) =>
23 | dependenciesKeys.includes(rootDependency)
24 | );
25 | if (filteredRootDependencies.length > 0) {
26 | const plural = filteredRootDependencies.length > 1;
27 | console.log(`
28 | ${chalk.whiteBright.bgYellow.bold(
29 | 'Webpack does not work with native dependencies.'
30 | )}
31 | ${chalk.bold(filteredRootDependencies.join(', '))} ${
32 | plural ? 'are native dependencies' : 'is a native dependency'
33 | } and should be installed inside of the "./release/app" folder.
34 | First, uninstall the packages from "./package.json":
35 | ${chalk.whiteBright.bgGreen.bold('npm uninstall your-package')}
36 | ${chalk.bold(
37 | 'Then, instead of installing the package to the root "./package.json":'
38 | )}
39 | ${chalk.whiteBright.bgRed.bold('npm install your-package')}
40 | ${chalk.bold('Install the package to "./release/app/package.json"')}
41 | ${chalk.whiteBright.bgGreen.bold(
42 | 'cd ./release/app && npm install your-package'
43 | )}
44 | Read more about native dependencies at:
45 | ${chalk.bold(
46 | 'https://electron-react-boilerplate.js.org/docs/adding-dependencies/#module-structure'
47 | )}
48 | `);
49 | process.exit(1);
50 | }
51 | } catch (e) {
52 | console.log('Native dependencies could not be checked');
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/src/renderer/components/agent/TerminalCanvas.js:
--------------------------------------------------------------------------------
1 | // @flow
2 | import React, { useRef, useEffect, Component } from 'react';
3 | import { Link } from 'react-router-dom';
4 |
5 | import Grid from '@mui/material/Grid';
6 | import Input from '@mui/material/Input';
7 | import FormControl from '@mui/material/FormControl';
8 |
9 | import './Agent.css';
10 |
11 |
12 |
13 | class TerminalCanvas extends React.Component {
14 | //props: Props;
15 |
16 | constructor(props) {
17 | super(props);
18 |
19 | this.state = {
20 | open: false,
21 |
22 | };
23 |
24 | }
25 | decodeB64(str) {
26 | let base64ToString = ""
27 | try {
28 | base64ToString = atob(str)
29 | } catch(e) {
30 | console.log(e)
31 | }
32 |
33 | if (base64ToString != "") {
34 | return (
35 |
36 | {base64ToString}
37 |
38 | )
39 | }
40 | }
41 | encodeB64(str) {
42 | let base64ToString = ""
43 | try {
44 | base64ToString = atob(str)
45 | } catch(e) {
46 | console.log(e)
47 | }
48 |
49 | if (base64ToString != "") {
50 | return (
51 |
52 | {base64ToString}
53 |
54 | )
55 | }
56 | }
57 |
58 | render() {
59 | const results = [];
60 | var i = 0
61 | this.props.terminalHistory?.forEach(command => {
62 | if (i > 0) {
63 | results.push (
64 |
65 |
66 | ({command.IP}){'>'} {this.encodeB64(command.Command)}
67 |
68 | {this.decodeB64(command.Result)}
69 |
70 | );
71 | }
72 | i++
73 | })
74 | return (
75 |
76 | {results}
77 |
78 |
79 |
80 |
81 | );
82 | }
83 | }
84 | const AlwaysScrollToBottom = (term) => {
85 | const bottomRef = useRef(null);
86 | useEffect(() => {
87 | // 👇️ scroll to bottom every time messages change
88 | bottomRef.current?.scrollIntoView({behavior: 'smooth', block: 'end', inline: 'end'});
89 | }, [term]);
90 | return ;
91 | };
92 |
93 | export default TerminalCanvas;
94 |
--------------------------------------------------------------------------------
/.erb/configs/webpack.config.main.prod.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Webpack config for production electron main process
3 | */
4 |
5 | import path from 'path';
6 | import webpack from 'webpack';
7 | import { merge } from 'webpack-merge';
8 | import TerserPlugin from 'terser-webpack-plugin';
9 | import { BundleAnalyzerPlugin } from 'webpack-bundle-analyzer';
10 | import baseConfig from './webpack.config.base';
11 | import webpackPaths from './webpack.paths';
12 | import checkNodeEnv from '../scripts/check-node-env';
13 | import deleteSourceMaps from '../scripts/delete-source-maps';
14 |
15 | checkNodeEnv('production');
16 | deleteSourceMaps();
17 |
18 | const devtoolsConfig =
19 | process.env.DEBUG_PROD === 'true'
20 | ? {
21 | devtool: 'source-map',
22 | }
23 | : {};
24 |
25 | const configuration: webpack.Configuration = {
26 | ...devtoolsConfig,
27 |
28 | mode: 'production',
29 |
30 | target: 'electron-main',
31 |
32 | entry: {
33 | main: path.join(webpackPaths.srcMainPath, 'main.ts'),
34 | preload: path.join(webpackPaths.srcMainPath, 'preload.ts'),
35 | },
36 |
37 | output: {
38 | path: webpackPaths.distMainPath,
39 | filename: '[name].js',
40 | },
41 |
42 | optimization: {
43 | minimizer: [
44 | new TerserPlugin({
45 | parallel: true,
46 | }),
47 | ],
48 | },
49 |
50 | plugins: [
51 | new BundleAnalyzerPlugin({
52 | analyzerMode: process.env.ANALYZE === 'true' ? 'server' : 'disabled',
53 | }),
54 |
55 | /**
56 | * Create global constants which can be configured at compile time.
57 | *
58 | * Useful for allowing different behaviour between development builds and
59 | * release builds
60 | *
61 | * NODE_ENV should be production so that modules do not perform certain
62 | * development checks
63 | */
64 | new webpack.EnvironmentPlugin({
65 | NODE_ENV: 'production',
66 | DEBUG_PROD: false,
67 | START_MINIMIZED: false,
68 | }),
69 | ],
70 |
71 | /**
72 | * Disables webpack processing of __dirname and __filename.
73 | * If you run the bundle in node.js it falls back to these values of node.js.
74 | * https://github.com/webpack/webpack/issues/2010
75 | */
76 | node: {
77 | __dirname: false,
78 | __filename: false,
79 | },
80 | };
81 |
82 | export default merge(baseConfig, configuration);
83 |
--------------------------------------------------------------------------------
/src/renderer/App.tsx:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import { MemoryRouter as Router, Routes, Route } from 'react-router-dom';
3 | import icon from '../../assets/icon.svg';
4 |
5 | import { styled, createTheme, ThemeProvider } from '@mui/material/styles';
6 | import { green, purple } from '@mui/material/colors';
7 |
8 | import './App.css';
9 |
10 | import Dashboard from './containers/Dashboard';
11 | import Hosts from './containers/Hosts';
12 | import Agents from './containers/Agents';
13 |
14 | import MenuBar from './components/MenuBar';
15 | import ToolBar from './components/ToolBar';
16 |
17 |
18 | class Main extends React.Component {
19 | //props: Props;
20 |
21 | constructor(props) {
22 | super(props);
23 |
24 | this.state = {
25 | dashboard: true,
26 | hosts: false,
27 | agents: false,
28 | };
29 | this.disableViews = this.disableViews.bind(this)
30 | this.toggleDashView = this.toggleDashView.bind(this)
31 | this.toggleHostsView = this.toggleHostsView.bind(this)
32 | this.toggleAgentsView = this.toggleAgentsView.bind(this)
33 |
34 | }
35 |
36 | disableViews() {
37 | this.setState({
38 | dashboard: false,
39 | hosts: false,
40 | agents: false
41 | });
42 | }
43 |
44 | toggleDashView() {
45 | this.disableViews()
46 | this.setState({
47 | dashboard: true
48 | });
49 | }
50 | toggleHostsView() {
51 | this.disableViews()
52 | this.setState({
53 | hosts: true
54 | });
55 | }
56 | toggleAgentsView() {
57 | this.disableViews()
58 | this.setState({
59 | agents: true
60 | });
61 | }
62 |
63 |
64 | render() {
65 | return (
66 |
67 |
68 |
73 | { this.state.dashboard ?
: null }
74 | { this.state.hosts ?
: null }
75 | { this.state.agents ?
: null }
76 |
77 | );
78 | }
79 | }
80 |
81 | export default function App() {
82 |
83 | return (
84 |
85 |
86 | } />
87 |
88 |
89 | );
90 | }
91 |
--------------------------------------------------------------------------------
/src/renderer/components/WindowControls.js:
--------------------------------------------------------------------------------
1 | // @flow
2 | import React, { Component } from 'react';
3 | import { Link } from 'react-router-dom';
4 |
5 | import styles from './Home.css';
6 |
7 | const remote = require('electron').remote;
8 | const {BrowserWindow} = require('electron').remote
9 |
10 | //const ElectronTitlebarWindows = require('electron-titlebar-windows');
11 |
12 | type Props = {
13 | increment: () => void,
14 | incrementIfOdd: () => void,
15 | incrementAsync: () => void,
16 | decrement: () => void,
17 | counter: number
18 | };
19 |
20 | export default class WindowControls extends Component {
21 | props: Props;
22 |
23 | windowMaximize() {
24 | var window = BrowserWindow.getFocusedWindow();
25 | if(window.isMaximized()) {
26 | window.unmaximize();
27 | } else{
28 | window.maximize();
29 | }
30 | }
31 | windowMinimize() {
32 | var window = BrowserWindow.getFocusedWindow();
33 | window.minimize();
34 | }
35 | windowClose() {
36 | var window = BrowserWindow.getFocusedWindow();
37 | window.close();
38 | }
39 |
40 | render() {
41 | const {
42 | increment,
43 | incrementIfOdd,
44 | incrementAsync,
45 | decrement,
46 | counter
47 | } = this.props;
48 | return (
49 |
50 |
Prismatica | Diagon UI
51 |
52 |
57 |
62 |
63 |
66 |
67 |
68 |
69 | );
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/src/renderer/components/host/HostOverview.js:
--------------------------------------------------------------------------------
1 | // @flow
2 | import React, { Component } from 'react';
3 | import { Link } from 'react-router-dom';
4 |
5 | import Paper from '@mui/material/Paper';
6 | import Card from '@mui/material/Card';
7 | import CardActions from '@mui/material/CardActions';
8 | import CardContent from '@mui/material/CardContent';
9 | import Typography from '@mui/material/Typography';
10 | import Grid from '@mui/material/Grid';
11 |
12 | import Chip from '@mui/material/Chip';
13 | import Autocomplete from '@mui/material/Autocomplete';
14 | import TextField from '@mui/material/TextField';
15 | import Stack from '@mui/material/Stack';
16 |
17 | import Security from '@mui/icons-material/Security';
18 | import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
19 | import { faWindows } from '@fortawesome/free-brands-svg-icons';
20 |
21 | import '../Home.css';
22 |
23 | class HostOverview extends React.Component {
24 | //props: Props;
25 |
26 | constructor(props) {
27 | super(props);
28 |
29 | this.state = {
30 | open: false
31 | };
32 | }
33 |
34 |
35 | render() {
36 | return (
37 |
38 |
39 |
40 |
41 | Host Overview
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 | IP: {this.props.hostDetails}
54 |
55 |
56 |
57 | HOST: SANS-SEC460
58 |
59 |
60 |
61 | OS: Windows 10
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 | );
70 | }
71 | }
72 |
73 | export default HostOverview;
74 |
--------------------------------------------------------------------------------
/src/renderer/containers/Dashboard.js:
--------------------------------------------------------------------------------
1 | // @flow
2 | import React, { Component } from 'react';
3 | import { Link } from 'react-router-dom';
4 |
5 | import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
6 | import { faWallet, faIndustry, faTerminal, faScroll, faBars, faBug, faKey, faServer, faRadiation, faHeadphones, faTable, faDragon } from '@fortawesome/free-solid-svg-icons';
7 | import ReactTooltip from 'react-tooltip';
8 | import { PieChart, Pie, Sector, Cell, ResponsiveContainer } from 'recharts';
9 |
10 | import Grid from '@mui/material/Grid';
11 | import Paper from '@mui/material/Paper';
12 | import Box from '@mui/material/Box';
13 | import Button from '@mui/material/Button';
14 | import Avatar from '@mui/material/Avatar';
15 | import Card from '@mui/material/Card';
16 | import CardActions from '@mui/material/CardActions';
17 | import CardContent from '@mui/material/CardContent';
18 | import Typography from '@mui/material/Typography';
19 |
20 | import { createTheme, ThemeProvider, styled } from '@mui/material/styles';
21 |
22 | import './Main.css';
23 | import logo from '/assets/logo.png';
24 |
25 | import DashCards from '../components/DashCards.js';
26 | import VulnPieGraph from '../components/VulnPieGraph.js';
27 | import TopVulns from '../components/TopVulns.js';
28 | import TopRemediations from '../components/TopRemediations.js';
29 | import VulnsBySeverity from '../components/VulnsBySeverity.js';
30 | import VulnOverTime from '../components/VulnOverTime.js';
31 |
32 |
33 | const Item = styled(Paper)(({ theme }) => ({
34 | ...theme.typography.body2,
35 | textAlign: 'center',
36 | color: theme.palette.text.secondary,
37 | height: 60,
38 | backgroundColor: null,
39 | lineHeight: '60px',
40 | }));
41 |
42 |
43 | class Dashboard extends React.Component {
44 | //props: Props;
45 |
46 | constructor(props) {
47 | super(props);
48 |
49 | this.state = {
50 | open: false
51 | };
52 | }
53 |
54 |
55 | render() {
56 | return (
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 | );
83 | }
84 | }
85 |
86 | export default Dashboard;
87 |
--------------------------------------------------------------------------------
/src/renderer/components/VulnFilter.js:
--------------------------------------------------------------------------------
1 | // @flow
2 | import React, { Component } from 'react';
3 | import { Link } from 'react-router-dom';
4 |
5 | import Paper from '@mui/material/Paper';
6 | import Card from '@mui/material/Card';
7 | import CardActions from '@mui/material/CardActions';
8 | import CardContent from '@mui/material/CardContent';
9 | import Typography from '@mui/material/Typography';
10 |
11 | import Chip from '@mui/material/Chip';
12 | import Autocomplete from '@mui/material/Autocomplete';
13 | import TextField from '@mui/material/TextField';
14 | import Stack from '@mui/material/Stack';
15 |
16 | import AddBox from '@mui/icons-material/AddBox';
17 | import IndeterminateCheckBoxIcon from '@mui/icons-material/IndeterminateCheckBox';
18 | import UploadFileRoundedIcon from '@mui/icons-material/UploadFileRounded';
19 |
20 | import './Home.css';
21 |
22 | class VulnFilter extends React.Component {
23 | //props: Props;
24 |
25 | constructor(props) {
26 | super(props);
27 |
28 | this.state = {
29 | open: false
30 | };
31 | }
32 |
33 |
34 | render() {
35 | return (
36 |
37 |
38 |
39 |
40 | Vulnerablity Manager
41 |
42 |
43 |
44 |
45 | option.title}
49 | defaultValue={[top100Films[13]]}
50 | renderInput={(params) => (
51 |
57 | )}
58 | />
59 |
60 |
61 |
62 |
63 | );
64 | }
65 | }
66 |
67 | // Top 100 films as rated by IMDb users. http://www.imdb.com/chart/top
68 | const top100Films = [
69 | { title: 'The Shawshank Redemption', year: 1994 },
70 | { title: 'The Godfather', year: 1972 },
71 | { title: 'The Godfather: Part II', year: 1974 },
72 | { title: 'The Dark Knight', year: 2008 },
73 | { title: '12 Angry Men', year: 1957 },
74 | { title: "Schindler's List", year: 1993 },
75 | { title: 'Pulp Fiction', year: 1994 },
76 | ];
77 |
78 | export default VulnFilter;
79 |
--------------------------------------------------------------------------------
/src/renderer/components/agent/AgentFinder.js:
--------------------------------------------------------------------------------
1 | // @flow
2 | import React, { Component } from 'react';
3 | import { Link } from 'react-router-dom';
4 |
5 | import Paper from '@mui/material/Paper';
6 | import Card from '@mui/material/Card';
7 | import CardActions from '@mui/material/CardActions';
8 | import CardContent from '@mui/material/CardContent';
9 | import Typography from '@mui/material/Typography';
10 |
11 | import Chip from '@mui/material/Chip';
12 | import Autocomplete from '@mui/material/Autocomplete';
13 | import TextField from '@mui/material/TextField';
14 | import Stack from '@mui/material/Stack';
15 |
16 | import AddBox from '@mui/icons-material/AddBox';
17 | import IndeterminateCheckBoxIcon from '@mui/icons-material/IndeterminateCheckBox';
18 | import UploadFileRoundedIcon from '@mui/icons-material/UploadFileRounded';
19 |
20 | import '../Home.css';
21 |
22 |
23 |
24 |
25 |
26 | class AgentFinder extends React.Component {
27 | //props: Props;
28 |
29 | constructor(props) {
30 | super(props);
31 |
32 | this.state = {
33 | open: false,
34 | hostList: [{
35 | "ip": ""
36 | }],
37 | };
38 | //this.fetchHosts = this.fetchHosts.bind(this);
39 | this.selectHost = this.selectHost.bind(this);
40 | }
41 |
42 | selectHost(event) {
43 | const target = event.target;
44 | const value = target.type === 'checkbox' ? target.checked : target.value;
45 | const name = target.name;
46 |
47 | this.props.setSelectedHost(target.innerHTML);
48 | }
49 |
50 | render() {
51 | return (
52 |
53 |
54 |
55 |
56 | Host Manager
57 |
58 |
59 |
60 |
61 | option.ip}
65 | defaultValue="IP Address"
66 | name="selectedHost"
67 | onChange={this.selectHost}
68 | renderInput={(params) => (
69 |
75 | )}
76 | />
77 |
78 |
79 |
80 |
81 | );
82 | }
83 | }
84 |
85 | export default AgentFinder;
86 |
--------------------------------------------------------------------------------
/src/renderer/components/agent/TerminalPrompt.js:
--------------------------------------------------------------------------------
1 | // @flow
2 | import React, { Component } from 'react';
3 | import { Link } from 'react-router-dom';
4 |
5 | import Grid from '@mui/material/Grid';
6 | import Input from '@mui/material/Input';
7 | import FormControl from '@mui/material/FormControl';
8 | import Button from '@mui/material/Button';
9 |
10 | import './Agent.css';
11 |
12 |
13 |
14 | class TerminalPrompt extends React.Component {
15 | //props: Props;
16 |
17 | constructor(props) {
18 | super(props);
19 |
20 | this.state = {
21 | open: false,
22 | hostList: [{
23 | "ip": ""
24 | }],
25 | selectedAgents: [{
26 | "ip": "192.168.1.15"
27 | }],
28 | terminal: "",
29 | selectedHost: ["192.168.1.15"],
30 | prepCommand: {
31 | hosts : ["192.168.1.15", "10.0.10.5"],
32 | command : "",
33 | },
34 | };
35 | this.handleChange = this.handleChange.bind(this);
36 | this.handleSubmit = this.handleSubmit.bind(this);
37 | this.resetPrompt = this.resetPrompt.bind(this);
38 | }
39 | handleChange(event) {
40 | const target = event.target;
41 | const value = target.type === 'checkbox' ? target.checked : target.value;
42 | const name = target.name;
43 |
44 | this.setState({
45 | [name]: value
46 | });
47 | }
48 | handleSubmit() {
49 | event.preventDefault();
50 | this.setState({
51 | prepCommand: {
52 | "hosts": this.state.selectedHost,
53 | "command": this.state.terminal,
54 | }
55 | });
56 | if (this.state.prepCommand) {
57 | this.props.handleCommand(this.state.selectedHost, this.state.terminal)
58 | }
59 |
60 | this.resetPrompt()
61 | }
62 | resetPrompt() {
63 | this.setState({
64 | terminal: ""
65 | });
66 | }
67 |
68 | render() {
69 | return (
70 |
71 |
72 | {this.state.selectedHost.map((ip) => {
73 | return (
74 |
75 | ({ip}) /
76 |
77 | );
78 | })}
79 |
80 |
81 |
97 |
98 |
99 | );
100 | }
101 | }
102 |
103 | export default TerminalPrompt;
104 |
--------------------------------------------------------------------------------
/src/renderer/components/host/HostManager.js:
--------------------------------------------------------------------------------
1 | // @flow
2 | import React, { Component } from 'react';
3 | import { Link } from 'react-router-dom';
4 |
5 | import Paper from '@mui/material/Paper';
6 | import Card from '@mui/material/Card';
7 | import CardActions from '@mui/material/CardActions';
8 | import CardContent from '@mui/material/CardContent';
9 | import Typography from '@mui/material/Typography';
10 |
11 | import Chip from '@mui/material/Chip';
12 | import Autocomplete from '@mui/material/Autocomplete';
13 | import TextField from '@mui/material/TextField';
14 | import Stack from '@mui/material/Stack';
15 |
16 | import AddBox from '@mui/icons-material/AddBox';
17 | import IndeterminateCheckBoxIcon from '@mui/icons-material/IndeterminateCheckBox';
18 | import UploadFileRoundedIcon from '@mui/icons-material/UploadFileRounded';
19 |
20 |
21 |
22 | import '../Home.css';
23 |
24 | class HostSearch extends React.Component {
25 | //props: Props;
26 |
27 | constructor(props) {
28 | super(props);
29 |
30 | this.state = {
31 | open: false,
32 | hostList: [{
33 | "ip": "1"
34 | }],
35 | };
36 | //this.fetchHosts = this.fetchHosts.bind(this);
37 | this.selectHost = this.selectHost.bind(this);
38 | }
39 |
40 | selectHost(event) {
41 | const target = event.target;
42 | const value = target.type === 'checkbox' ? target.checked : target.value;
43 | const name = target.name;
44 |
45 | this.props.setSelectedHost(target.innerHTML);
46 | }
47 |
48 | render() {
49 | return (
50 |
51 |
52 |
53 |
54 | Host Manager
55 |
56 |
57 |
58 |
59 | option.ip}
63 | defaultValue="IP Address"
64 | name="selectedHost"
65 | onChange={this.selectHost}
66 | renderInput={(params) => (
67 |
73 | )}
74 | />
75 |
76 |
77 |
78 |
79 | );
80 | }
81 | }
82 |
83 | export default HostSearch;
84 |
--------------------------------------------------------------------------------
/src/renderer/components/DashCards.js:
--------------------------------------------------------------------------------
1 | // @flow
2 | import React, { Component } from 'react';
3 | import { Link } from 'react-router-dom';
4 |
5 | import { createTheme, ThemeProvider, styled } from '@mui/material/styles';
6 |
7 | import Paper from '@mui/material/Paper';
8 | import Grid from '@mui/material/Grid';
9 | import Card from '@mui/material/Card';
10 | import CardActions from '@mui/material/CardActions';
11 | import CardContent from '@mui/material/CardContent';
12 | import Typography from '@mui/material/Typography';
13 |
14 | import '../containers/Main.css';
15 |
16 | const Item = styled(Paper)(({ theme }) => ({
17 | ...theme.typography.body2,
18 | textAlign: 'center',
19 | color: theme.palette.text.secondary,
20 | height: 60,
21 | backgroundColor: null,
22 | lineHeight: '60px',
23 | }));
24 |
25 | class VulnOverTime extends React.Component {
26 | //props: Props;
27 |
28 | constructor(props) {
29 | super(props);
30 |
31 |
32 | this.state = {
33 | open: false
34 | };
35 | }
36 |
37 | render() {
38 |
39 | return (
40 |
41 |
42 |
43 |
44 |
45 | CRITICAL VULNERABILITIES
46 |
47 |
48 | 5
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 | HOSTS
58 |
59 |
60 | 21
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 | TOTAL VULNERABILITIES
70 |
71 |
72 | 328
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 | SCANS
82 |
83 |
84 | 8
85 |
86 |
87 |
88 |
89 |
90 | );
91 | }
92 | }
93 |
94 | export default VulnOverTime;
95 |
--------------------------------------------------------------------------------
/assets/icon.svg:
--------------------------------------------------------------------------------
1 |
24 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Contributor Covenant Code of Conduct
2 |
3 | ## Our Pledge
4 |
5 | In the interest of fostering an open and welcoming environment, we as
6 | contributors and maintainers pledge to making participation in our project and
7 | our community a harassment-free experience for everyone, regardless of age, body
8 | size, disability, ethnicity, sex characteristics, gender identity and expression,
9 | level of experience, education, socio-economic status, nationality, personal
10 | appearance, race, religion, or sexual identity and orientation.
11 |
12 | ## Our Standards
13 |
14 | Examples of behavior that contributes to creating a positive environment
15 | include:
16 |
17 | * Using welcoming and inclusive language
18 | * Being respectful of differing viewpoints and experiences
19 | * Gracefully accepting constructive criticism
20 | * Focusing on what is best for the community
21 | * Showing empathy towards other community members
22 |
23 | Examples of unacceptable behavior by participants include:
24 |
25 | * The use of sexualized language or imagery and unwelcome sexual attention or
26 | advances
27 | * Trolling, insulting/derogatory comments, and personal or political attacks
28 | * Public or private harassment
29 | * Publishing others' private information, such as a physical or electronic
30 | address, without explicit permission
31 | * Other conduct which could reasonably be considered inappropriate in a
32 | professional setting
33 |
34 | ## Our Responsibilities
35 |
36 | Project maintainers are responsible for clarifying the standards of acceptable
37 | behavior and are expected to take appropriate and fair corrective action in
38 | response to any instances of unacceptable behavior.
39 |
40 | Project maintainers have the right and responsibility to remove, edit, or
41 | reject comments, commits, code, wiki edits, issues, and other contributions
42 | that are not aligned to this Code of Conduct, or to ban temporarily or
43 | permanently any contributor for other behaviors that they deem inappropriate,
44 | threatening, offensive, or harmful.
45 |
46 | ## Scope
47 |
48 | This Code of Conduct applies both within project spaces and in public spaces
49 | when an individual is representing the project or its community. Examples of
50 | representing a project or community include using an official project e-mail
51 | address, posting via an official social media account, or acting as an appointed
52 | representative at an online or offline event. Representation of a project may be
53 | further defined and clarified by project maintainers.
54 |
55 | ## Enforcement
56 |
57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be
58 | reported by contacting the project team at electronreactboilerplate@gmail.com. All
59 | complaints will be reviewed and investigated and will result in a response that
60 | is deemed necessary and appropriate to the circumstances. The project team is
61 | obligated to maintain confidentiality with regard to the reporter of an incident.
62 | Further details of specific enforcement policies may be posted separately.
63 |
64 | Project maintainers who do not follow or enforce the Code of Conduct in good
65 | faith may face temporary or permanent repercussions as determined by other
66 | members of the project's leadership.
67 |
68 | ## Attribution
69 |
70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
72 |
73 | [homepage]: https://www.contributor-covenant.org
74 |
75 | For answers to common questions about this code of conduct, see
76 | https://www.contributor-covenant.org/faq
77 |
--------------------------------------------------------------------------------
/.erb/configs/webpack.config.renderer.prod.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Build config for electron renderer process
3 | */
4 |
5 | import path from 'path';
6 | import webpack from 'webpack';
7 | import HtmlWebpackPlugin from 'html-webpack-plugin';
8 | import MiniCssExtractPlugin from 'mini-css-extract-plugin';
9 | import { BundleAnalyzerPlugin } from 'webpack-bundle-analyzer';
10 | import CssMinimizerPlugin from 'css-minimizer-webpack-plugin';
11 | import { merge } from 'webpack-merge';
12 | import TerserPlugin from 'terser-webpack-plugin';
13 | import baseConfig from './webpack.config.base';
14 | import webpackPaths from './webpack.paths';
15 | import checkNodeEnv from '../scripts/check-node-env';
16 | import deleteSourceMaps from '../scripts/delete-source-maps';
17 |
18 | checkNodeEnv('production');
19 | deleteSourceMaps();
20 |
21 | const devtoolsConfig =
22 | process.env.DEBUG_PROD === 'true'
23 | ? {
24 | devtool: 'source-map',
25 | }
26 | : {};
27 |
28 | const configuration: webpack.Configuration = {
29 | ...devtoolsConfig,
30 |
31 | mode: 'production',
32 |
33 | target: ['web', 'electron-renderer'],
34 |
35 | entry: [path.join(webpackPaths.srcRendererPath, 'index.tsx')],
36 |
37 | output: {
38 | path: webpackPaths.distRendererPath,
39 | publicPath: './',
40 | filename: 'renderer.js',
41 | library: {
42 | type: 'umd',
43 | },
44 | },
45 |
46 | module: {
47 | rules: [
48 | {
49 | test: /\.s?(a|c)ss$/,
50 | use: [
51 | MiniCssExtractPlugin.loader,
52 | {
53 | loader: 'css-loader',
54 | options: {
55 | modules: true,
56 | sourceMap: true,
57 | importLoaders: 1,
58 | },
59 | },
60 | 'sass-loader',
61 | ],
62 | include: /\.module\.s?(c|a)ss$/,
63 | },
64 | {
65 | test: /\.s?(a|c)ss$/,
66 | use: [MiniCssExtractPlugin.loader, 'css-loader', 'sass-loader'],
67 | exclude: /\.module\.s?(c|a)ss$/,
68 | },
69 | // Fonts
70 | {
71 | test: /\.(woff|woff2|eot|ttf|otf)$/i,
72 | type: 'asset/resource',
73 | },
74 | // Images
75 | {
76 | test: /\.(png|svg|jpg|jpeg|gif)$/i,
77 | type: 'asset/resource',
78 | },
79 | ],
80 | },
81 |
82 | optimization: {
83 | minimize: true,
84 | minimizer: [
85 | new TerserPlugin({
86 | parallel: true,
87 | }),
88 | new CssMinimizerPlugin(),
89 | ],
90 | },
91 |
92 | plugins: [
93 | /**
94 | * Create global constants which can be configured at compile time.
95 | *
96 | * Useful for allowing different behaviour between development builds and
97 | * release builds
98 | *
99 | * NODE_ENV should be production so that modules do not perform certain
100 | * development checks
101 | */
102 | new webpack.EnvironmentPlugin({
103 | NODE_ENV: 'production',
104 | DEBUG_PROD: false,
105 | }),
106 |
107 | new MiniCssExtractPlugin({
108 | filename: 'style.css',
109 | }),
110 |
111 | new BundleAnalyzerPlugin({
112 | analyzerMode: process.env.ANALYZE === 'true' ? 'server' : 'disabled',
113 | }),
114 |
115 | new HtmlWebpackPlugin({
116 | filename: 'index.html',
117 | template: path.join(webpackPaths.srcRendererPath, 'index.ejs'),
118 | minify: {
119 | collapseWhitespace: true,
120 | removeAttributeQuotes: true,
121 | removeComments: true,
122 | },
123 | isBrowser: false,
124 | isDevelopment: process.env.NODE_ENV !== 'production',
125 | }),
126 | ],
127 | };
128 |
129 | export default merge(baseConfig, configuration);
130 |
--------------------------------------------------------------------------------
/src/main/main.ts:
--------------------------------------------------------------------------------
1 | /* eslint global-require: off, no-console: off, promise/always-return: off */
2 |
3 | /**
4 | * This module executes inside of electron's main process. You can start
5 | * electron renderer process from here and communicate with the other processes
6 | * through IPC.
7 | *
8 | * When running `npm run build` or `npm run build:main`, this file is compiled to
9 | * `./src/main.js` using webpack. This gives us some performance wins.
10 | */
11 | import path from 'path';
12 | import { app, BrowserWindow, shell, ipcMain } from 'electron';
13 | import { autoUpdater } from 'electron-updater';
14 | import log from 'electron-log';
15 | import MenuBuilder from './menu';
16 | import { resolveHtmlPath } from './util';
17 |
18 | export default class AppUpdater {
19 | constructor() {
20 | log.transports.file.level = 'info';
21 | autoUpdater.logger = log;
22 | autoUpdater.checkForUpdatesAndNotify();
23 | }
24 | }
25 |
26 | let mainWindow: BrowserWindow | null = null;
27 |
28 | ipcMain.on('ipc-example', async (event, arg) => {
29 | const msgTemplate = (pingPong: string) => `IPC test: ${pingPong}`;
30 | console.log(msgTemplate(arg));
31 | event.reply('ipc-example', msgTemplate('pong'));
32 | });
33 |
34 | if (process.env.NODE_ENV === 'production') {
35 | const sourceMapSupport = require('source-map-support');
36 | sourceMapSupport.install();
37 | }
38 |
39 | const isDevelopment =
40 | process.env.NODE_ENV === 'development' || process.env.DEBUG_PROD === 'true';
41 |
42 | if (isDevelopment) {
43 | require('electron-debug')();
44 | }
45 |
46 | const installExtensions = async () => {
47 | const installer = require('electron-devtools-installer');
48 | const forceDownload = !!process.env.UPGRADE_EXTENSIONS;
49 | const extensions = ['REACT_DEVELOPER_TOOLS'];
50 |
51 | return installer
52 | .default(
53 | extensions.map((name) => installer[name]),
54 | forceDownload
55 | )
56 | .catch(console.log);
57 | };
58 |
59 | const createWindow = async () => {
60 | if (isDevelopment) {
61 | await installExtensions();
62 | }
63 |
64 | const RESOURCES_PATH = app.isPackaged
65 | ? path.join(process.resourcesPath, 'assets')
66 | : path.join(__dirname, '../../assets');
67 |
68 | const getAssetPath = (...paths: string[]): string => {
69 | return path.join(RESOURCES_PATH, ...paths);
70 | };
71 |
72 | mainWindow = new BrowserWindow({
73 | show: false,
74 | width: 1024,
75 | height: 728,
76 | icon: getAssetPath('icon.png'),
77 | webPreferences: {
78 | webSecurity: false,
79 | preload: app.isPackaged
80 | ? path.join(__dirname, 'preload.js')
81 | : path.join(__dirname, '../../.erb/dll/preload.js'),
82 | },
83 | });
84 |
85 | mainWindow.loadURL(resolveHtmlPath('index.html'));
86 |
87 | mainWindow.on('ready-to-show', () => {
88 | if (!mainWindow) {
89 | throw new Error('"mainWindow" is not defined');
90 | }
91 | if (process.env.START_MINIMIZED) {
92 | mainWindow.minimize();
93 | } else {
94 | mainWindow.show();
95 | }
96 | });
97 |
98 | mainWindow.on('closed', () => {
99 | mainWindow = null;
100 | });
101 |
102 | const menuBuilder = new MenuBuilder(mainWindow);
103 | menuBuilder.buildMenu();
104 |
105 | // Open urls in the user's browser
106 | mainWindow.webContents.setWindowOpenHandler((edata) => {
107 | shell.openExternal(edata.url);
108 | return { action: 'deny' };
109 | });
110 |
111 | // Remove this if your app does not use auto updates
112 | // eslint-disable-next-line
113 | new AppUpdater();
114 | };
115 |
116 | /**
117 | * Add event listeners...
118 | */
119 |
120 | app.on('window-all-closed', () => {
121 | // Respect the OSX convention of having the application in memory even
122 | // after all windows have been closed
123 | if (process.platform !== 'darwin') {
124 | app.quit();
125 | }
126 | });
127 |
128 | app
129 | .whenReady()
130 | .then(() => {
131 | createWindow();
132 | app.on('activate', () => {
133 | // On macOS it's common to re-create a window in the app when the
134 | // dock icon is clicked and there are no other windows open.
135 | if (mainWindow === null) createWindow();
136 | });
137 | })
138 | .catch(console.log);
139 |
--------------------------------------------------------------------------------
/src/renderer/components/ToolBar.js:
--------------------------------------------------------------------------------
1 | // @flow
2 | import React, { Component } from 'react';
3 | import { Link } from 'react-router-dom';
4 |
5 | import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
6 | import { faWallet, faIndustry, faTerminal, faScroll, faBars, faBug, faKey, faServer, faRadiation, faHeadphones, faTable, faDragon } from '@fortawesome/free-solid-svg-icons';
7 | import ReactTooltip from 'react-tooltip';
8 |
9 | import Button from '@mui/material/Button';
10 | import Avatar from '@mui/material/Avatar';
11 |
12 | import Box from '@mui/material/Box';
13 | import Drawer from '@mui/material/Drawer';
14 | import CssBaseline from '@mui/material/CssBaseline';
15 | import AppBar from '@mui/material/AppBar';
16 | import Toolbar from '@mui/material/Toolbar';
17 | import List from '@mui/material/List';
18 | import Typography from '@mui/material/Typography';
19 | import Divider from '@mui/material/Divider';
20 | import ListItem from '@mui/material/ListItem';
21 |
22 | import ListItemIcon from '@mui/material/ListItemIcon';
23 | import InboxIcon from '@mui/icons-material/MoveToInbox';
24 | import BugReport from '@mui/icons-material/BugReport';
25 | import Policy from '@mui/icons-material/Policy';
26 | import Token from '@mui/icons-material/Token';
27 | import Security from '@mui/icons-material/Security';
28 | import Settings from '@mui/icons-material/Settings';
29 | import Logout from '@mui/icons-material/Logout';
30 | import PrivacyTip from '@mui/icons-material/PrivacyTip';
31 | import ViewList from '@mui/icons-material/ViewList';
32 |
33 |
34 | import './Home.css';
35 | import logo from '/assets/logo.png';
36 |
37 |
38 | class ToolBar extends React.Component {
39 | //props: Props;
40 |
41 | constructor(props) {
42 | super(props);
43 |
44 | this.state = {
45 | open: false
46 | };
47 | }
48 |
49 |
50 | render() {
51 | return (
52 |
53 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 | );
118 | }
119 | }
120 |
121 | export default ToolBar;
122 |
--------------------------------------------------------------------------------
/src/renderer/components/VulnsBySeverity.js:
--------------------------------------------------------------------------------
1 | // @flow
2 | import React, { Component } from 'react';
3 | import { Link } from 'react-router-dom';
4 |
5 | import Paper from '@mui/material/Paper';
6 | import Card from '@mui/material/Card';
7 | import Badge from '@mui/material/Badge';
8 | import CardActions from '@mui/material/CardActions';
9 | import CardContent from '@mui/material/CardContent';
10 | import Typography from '@mui/material/Typography';
11 |
12 | import { createMuiTheme } from 'material-ui/styles';
13 |
14 |
15 | import './Home.css';
16 |
17 | class VulnsBySeverity extends React.Component {
18 | //props: Props;
19 |
20 | constructor(props) {
21 | super(props);
22 |
23 | this.state = {
24 | open: false
25 | };
26 | }
27 |
28 |
29 | render() {
30 | return (
31 |
32 |
33 |
34 |
35 | Vulnerabilities by Severity
36 |
37 |
38 |
39 | Critical
40 |
41 |
51 |
52 |
53 |
54 |
55 |
56 | High
57 |
58 |
68 |
69 |
70 |
71 |
72 |
73 | Medium
74 |
75 |
85 |
86 |
87 |
88 |
89 |
90 | Low
91 |
92 |
102 |
103 |
104 |
105 |
106 |
107 | Informational
108 |
109 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 | );
127 | }
128 | }
129 |
130 | export default VulnsBySeverity;
131 |
--------------------------------------------------------------------------------
/src/renderer/components/Home.css:
--------------------------------------------------------------------------------
1 | .logo {
2 | max-width: 50px;
3 | }
4 | .toolbar {
5 | background-color: #333;
6 | color: white;
7 | }
8 | .container {
9 | position: absolute;
10 | text-align: center;
11 | }
12 |
13 | .container h2 {
14 | font-size: 5rem;
15 | }
16 |
17 | .container a {
18 | font-size: 1.4rem;
19 | }
20 | .terminal-base {
21 | width: 100%;
22 | max-width: 100%;
23 | height: 100%;
24 | min-height: 630px;
25 | max-height: 100vh;
26 | text-align: initial;
27 | }
28 | .menucontainer {
29 | position: fixed;
30 | top: 0px;
31 | left: 0px;
32 | height: 65px;
33 | background-color: #222;
34 | width: 100vw;
35 | padding-bottom: 10px;
36 | z-index: 2999;
37 | }
38 | .logoitem {
39 | position: relative;
40 | float: left;
41 | color: #fff;
42 | cursor: pointer;
43 | margin-left: 20px;
44 | margin-top: 12px;
45 | font-size: 20px;
46 | padding-right: 20px;
47 | }
48 | .menuitem {
49 | position: relative;
50 | float: left;
51 | color: #fff;
52 | cursor: pointer;
53 | margin-left: 20px;
54 | margin-top: 23px;
55 | font-size: 25px;
56 | }
57 | .menuitemr {
58 | position: relative;
59 | float: right;
60 | color: #fff;
61 | cursor: pointer;
62 | margin-right: 20px;
63 | margin-top: 18px;
64 | font-size: 25px;
65 | }
66 | .menusettings {
67 | position: relative;
68 | float: right;
69 | color: #fff;
70 | cursor: pointer;
71 | margin-right: 20px;
72 | margin-top: 12px;
73 | font-size: 20px;
74 | }
75 | .menuitem:hover {
76 | color: green;
77 | }
78 | .menugroup {
79 | margin-left: 0px;
80 | }
81 | .termcontainer {
82 | top: -45px;
83 | background-color: #002b36;
84 | }
85 | .basecontainer {
86 | position: absolute;
87 | left: -10px;
88 | }
89 | .customModal {
90 | color: black;
91 | }
92 | .customModalContainer {
93 | width: 650px;
94 | color: black;
95 | }
96 | .menuSpacing {
97 | width: 500px;
98 | }
99 | .modalTextField {
100 | margin-top: 20px;
101 | }
102 | .loader {
103 | position: absolute;
104 | top: 300px;
105 | left: 50%;
106 | }
107 | .terminalText {
108 | color: green;
109 | font-family: monospace;
110 | }
111 | .windowcontrols {
112 | -webkit-app-region: no-drag;
113 | position: fixed;
114 | right: 0px;
115 | margin-right: 2px;
116 | text-align: left;
117 | top: 0;
118 | z-index: 3001;
119 | }
120 | .windowMax,
121 | .windowMin,
122 | .windowClose {
123 | text-align: left;
124 | float: right;
125 | width: 45px;
126 | height: 31px;
127 | margin: 1px 1px 0 0;
128 | text-align: center;
129 | line-height: 29px;
130 |
131 | -webkit-transition: background-color 0.2s;
132 | -moz-transition: background-color 0.2s;
133 | -ms-transition: background-color 0.2s;
134 | -o-transition: background-color 0.2s;
135 | transition: background-color 0.2s;
136 | }
137 |
138 | .windowClose svg,
139 | .windowMax svg,
140 | .windowMin svg {
141 | width: 10px;
142 | height: 10px;
143 | shape-rendering: crispEdges;
144 | fill: rgba(255, 255, 255, 1);
145 | }
146 | .windowClose svg polygon,
147 | .windowMax svg polygon,
148 | .windowMin svg polygon {
149 | fill: rgba(255, 255, 255, 1);
150 | -webkit-transition: fill 0.2s;
151 | -moz-transition: fill 0.2s;
152 | -ms-transition: fill 0.2s;
153 | -o-transition: fill 0.2s;
154 | transition: fill 0.2s;
155 | }
156 | .windowClose svg polygon {
157 | -webkit-transition: fill 0.2s;
158 | -moz-transition: fill 0.2s;
159 | -ms-transition: fill 0.2s;
160 | -o-transition: fill 0.2s;
161 | transition: fill 0.2s;
162 | }
163 | .windowClose:hover,
164 | .windowMax:hover,
165 | .windowMin:hover {
166 | background-color: rgba(255, 255, 255, 0.1);
167 | }
168 |
169 | .windowClose:hover svg polygon,
170 | .windowMax:hover svg path,
171 | .windowMin:hover svg rect {
172 | fill: #222;
173 | }
174 | .settingsmodal {
175 | min-width: 600px;
176 | border-radius: 10px;
177 | z-index: 2015;
178 | }
179 | .boxpadding {
180 | margin-right: 10px;
181 | }
182 | .pagecontent {
183 | position: relative;
184 | top: 50px;
185 | padding: 0px;
186 | margin: 0px;
187 | height: 100vh;
188 | background-color: #333;
189 | width: 100vw;
190 | }
191 | .centeredUserInput {
192 | width: 35em;
193 | height: 25em;
194 | margin: 0 auto;
195 | background-color: #fff;
196 | }
197 |
198 | .centeredUserInput h1 {
199 | text-align: center;
200 | padding-top: 1em;
201 | }
202 |
203 | .centeredUserInput p {
204 | text-align: center;
205 | }
206 |
207 | .centeredUserInput input {
208 | display: block;
209 | width: 50%;
210 | padding: 1em;
211 | margin: 1em auto;
212 | }
213 | .successicon {
214 | color: green;
215 | }
216 | .authmodal {
217 | position: absolute;
218 | top: 20vh;
219 | left: 35vw;
220 | z-index: 2015;
221 | }
222 | .dashbox {
223 | padding-left: 20px;
224 | padding-right: 20px;
225 | padding-bottom: 50px;
226 | }
227 | .right {
228 | float: right;
229 | padding-right: 20px;
230 | }
231 | .MuiBadge-standard {
232 | background-color: red;
233 | color: red;
234 | }
235 | .bottom {
236 | position: absolute;
237 | bottom: 0;
238 | color: 'red';
239 | }
240 | .navtoolbar {
241 | vh: 100;
242 | }
243 | .leftcard {
244 | padding-left: 10px;
245 | padding-right: 0px;
246 | padding-bottom: 10px;
247 | z-index: 100;
248 | }
249 | .rightcard {
250 | padding-left: 0px;
251 | padding-right: 10px;
252 | padding-bottom: 10px;
253 | }
254 |
--------------------------------------------------------------------------------
/.erb/configs/webpack.config.renderer.dev.ts:
--------------------------------------------------------------------------------
1 | import 'webpack-dev-server';
2 | import path from 'path';
3 | import fs from 'fs';
4 | import webpack from 'webpack';
5 | import HtmlWebpackPlugin from 'html-webpack-plugin';
6 | import chalk from 'chalk';
7 | import { merge } from 'webpack-merge';
8 | import { execSync, spawn } from 'child_process';
9 | import ReactRefreshWebpackPlugin from '@pmmmwh/react-refresh-webpack-plugin';
10 | import baseConfig from './webpack.config.base';
11 | import webpackPaths from './webpack.paths';
12 | import checkNodeEnv from '../scripts/check-node-env';
13 |
14 | // When an ESLint server is running, we can't set the NODE_ENV so we'll check if it's
15 | // at the dev webpack config is not accidentally run in a production environment
16 | if (process.env.NODE_ENV === 'production') {
17 | checkNodeEnv('development');
18 | }
19 |
20 | const port = process.env.PORT || 1212;
21 | const manifest = path.resolve(webpackPaths.dllPath, 'renderer.json');
22 | // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
23 | const requiredByDLLConfig = module.parent!.filename.includes(
24 | 'webpack.config.renderer.dev.dll'
25 | );
26 |
27 | /**
28 | * Warn if the DLL is not built
29 | */
30 | if (
31 | !requiredByDLLConfig &&
32 | !(fs.existsSync(webpackPaths.dllPath) && fs.existsSync(manifest))
33 | ) {
34 | console.log(
35 | chalk.black.bgYellow.bold(
36 | 'The DLL files are missing. Sit back while we build them for you with "npm run build-dll"'
37 | )
38 | );
39 | execSync('npm run postinstall');
40 | }
41 |
42 | const configuration: webpack.Configuration = {
43 | devtool: 'inline-source-map',
44 |
45 | mode: 'development',
46 |
47 | target: ['web', 'electron-renderer'],
48 |
49 | entry: [
50 | `webpack-dev-server/client?http://localhost:${port}/dist`,
51 | 'webpack/hot/only-dev-server',
52 | path.join(webpackPaths.srcRendererPath, 'index.tsx'),
53 | ],
54 |
55 | output: {
56 | path: webpackPaths.distRendererPath,
57 | publicPath: '/',
58 | filename: 'renderer.dev.js',
59 | library: {
60 | type: 'umd',
61 | },
62 | },
63 |
64 | module: {
65 | rules: [
66 | {
67 | test: /\.s?css$/,
68 | use: [
69 | 'style-loader',
70 | {
71 | loader: 'css-loader',
72 | options: {
73 | modules: true,
74 | sourceMap: true,
75 | importLoaders: 1,
76 | },
77 | },
78 | 'sass-loader',
79 | ],
80 | include: /\.module\.s?(c|a)ss$/,
81 | },
82 | {
83 | test: /\.s?css$/,
84 | use: ['style-loader', 'css-loader', 'sass-loader'],
85 | exclude: /\.module\.s?(c|a)ss$/,
86 | },
87 | // Fonts
88 | {
89 | test: /\.(woff|woff2|eot|ttf|otf)$/i,
90 | type: 'asset/resource',
91 | },
92 | // Images
93 | {
94 | test: /\.(png|svg|jpg|jpeg|gif)$/i,
95 | type: 'asset/resource',
96 | },
97 | ],
98 | },
99 | plugins: [
100 | ...(requiredByDLLConfig
101 | ? []
102 | : [
103 | new webpack.DllReferencePlugin({
104 | context: webpackPaths.dllPath,
105 | manifest: require(manifest),
106 | sourceType: 'var',
107 | }),
108 | ]),
109 |
110 | new webpack.NoEmitOnErrorsPlugin(),
111 |
112 | /**
113 | * Create global constants which can be configured at compile time.
114 | *
115 | * Useful for allowing different behaviour between development builds and
116 | * release builds
117 | *
118 | * NODE_ENV should be production so that modules do not perform certain
119 | * development checks
120 | *
121 | * By default, use 'development' as NODE_ENV. This can be overriden with
122 | * 'staging', for example, by changing the ENV variables in the npm scripts
123 | */
124 | new webpack.EnvironmentPlugin({
125 | NODE_ENV: 'development',
126 | }),
127 |
128 | new webpack.LoaderOptionsPlugin({
129 | debug: true,
130 | }),
131 |
132 | new ReactRefreshWebpackPlugin(),
133 |
134 | new HtmlWebpackPlugin({
135 | filename: path.join('index.html'),
136 | template: path.join(webpackPaths.srcRendererPath, 'index.ejs'),
137 | minify: {
138 | collapseWhitespace: true,
139 | removeAttributeQuotes: true,
140 | removeComments: true,
141 | },
142 | isBrowser: false,
143 | env: process.env.NODE_ENV,
144 | isDevelopment: process.env.NODE_ENV !== 'production',
145 | nodeModules: webpackPaths.appNodeModulesPath,
146 | }),
147 | ],
148 |
149 | node: {
150 | __dirname: false,
151 | __filename: false,
152 | },
153 |
154 | devServer: {
155 | port,
156 | compress: true,
157 | hot: true,
158 | headers: { 'Access-Control-Allow-Origin': '*' },
159 | static: {
160 | publicPath: '/',
161 | },
162 | historyApiFallback: {
163 | verbose: true,
164 | },
165 | setupMiddlewares(middlewares) {
166 | console.log('Starting preload.js builder...');
167 | const preloadProcess = spawn('npm', ['run', 'start:preload'], {
168 | shell: true,
169 | stdio: 'inherit',
170 | })
171 | .on('close', (code: number) => process.exit(code!))
172 | .on('error', (spawnError) => console.error(spawnError));
173 |
174 | console.log('Starting Main Process...');
175 | spawn('npm', ['run', 'start:main'], {
176 | shell: true,
177 | stdio: 'inherit',
178 | })
179 | .on('close', (code: number) => {
180 | preloadProcess.kill();
181 | process.exit(code!);
182 | })
183 | .on('error', (spawnError) => console.error(spawnError));
184 | return middlewares;
185 | },
186 | },
187 | };
188 |
189 | export default merge(baseConfig, configuration);
190 |
--------------------------------------------------------------------------------
/src/renderer/components/host/VulnList.tsx:
--------------------------------------------------------------------------------
1 | // @flow
2 | import React, { Component } from 'react';
3 | import { Link } from 'react-router-dom';
4 |
5 | import Paper from '@mui/material/Paper';
6 | import Card from '@mui/material/Card';
7 | import Badge from '@mui/material/Badge';
8 | import CardActions from '@mui/material/CardActions';
9 | import CardContent from '@mui/material/CardContent';
10 | import Typography from '@mui/material/Typography';
11 | import Table from '@mui/material/Table';
12 | import TableBody from '@mui/material/TableBody';
13 | import TableCell from '@mui/material/TableCell';
14 | import TableContainer from '@mui/material/TableContainer';
15 | import TableHead from '@mui/material/TableHead';
16 | import TableRow from '@mui/material/TableRow';
17 | import Collapse from '@mui/material/Collapse';
18 | import IconButton from '@mui/material/IconButton';
19 | import Box from '@mui/material/Box';
20 |
21 | import KeyboardArrowDownIcon from '@mui/icons-material/KeyboardArrowDown';
22 | import KeyboardArrowUpIcon from '@mui/icons-material/KeyboardArrowUp';
23 | import AddBox from '@mui/icons-material/AddBox';
24 | import IndeterminateCheckBoxIcon from '@mui/icons-material/IndeterminateCheckBox';
25 | import UploadFileRoundedIcon from '@mui/icons-material/UploadFileRounded';
26 |
27 | import { createMuiTheme } from 'material-ui/styles';
28 |
29 | import '../Home.css';
30 |
31 | function createData(
32 | cve: string,
33 | catagory: string,
34 | tags: string,
35 | cvss: int,
36 | srs: int,
37 | description: string
38 | ) {
39 | return {
40 | cve,
41 | catagory,
42 | tags,
43 | cvss,
44 | srs,
45 | description,
46 | };
47 | }
48 |
49 | const imp17 = '3,3,3';
50 |
51 | const rows = [
52 | createData(
53 | 'CVE-2017-0145 - Remote Code Execution',
54 | 'RCE',
55 | 'CISA Worm RCE Wild',
56 | 9.8,
57 | 10,
58 | 'this.props.vulnerabilityList[0].description',
59 | imp17
60 | ),
61 | createData(
62 | 'CVE-2021-38647 - Microsoft Azure Open Management Infrastructure (OMI) Remote Code Execution Vulnerability',
63 | 237,
64 | 9.0,
65 | 37,
66 | 4.3,
67 | 4.99
68 | ),
69 | createData(
70 | 'CVE-2020-8196 - Application Delivery Controller (ADC), Gateway, and SDWAN WANOP',
71 | 262,
72 | 16.0,
73 | 24,
74 | 6.0,
75 | 3.79
76 | ),
77 | createData(
78 | 'CVE-2021-34473 - Microsoft Exchange Server Remote Code Execution Vulnerability',
79 | 305,
80 | 3.7,
81 | 67,
82 | 4.3,
83 | 2.5
84 | ),
85 | ];
86 |
87 | function Row(props: { row: ReturnType }) {
88 | const { row } = props;
89 | const [open, setOpen] = React.useState(false);
90 |
91 | return (
92 | <>
93 | *': { borderBottom: 'unset' } }}>
94 |
95 | setOpen(!open)}
99 | >
100 | {open ? : }
101 |
102 |
103 |
104 | {row.CVEDataMeta.ID}
105 |
106 | {row.CVSSV3.baseSeverity}
107 | {row.Tags}
108 | {row.CVSSV3.baseScore}
109 |
110 |
111 |
112 |
113 |
114 |
115 | Vulnerablity Summary
116 |
117 |
118 | {row.Description.description_data[0].value}
119 |
120 |
121 | Impact
122 |
123 |
124 |
125 |
126 |
127 | Confidentiality Impact
128 | Integrity Impact
129 | Availability Impact
130 |
131 |
132 |
133 |
134 | High
135 | High
136 | High
137 |
138 |
139 |
140 |
141 |
142 | References
143 |
144 |
145 | {row.References[0]}
146 |
147 |
148 |
149 |
150 |
151 | >
152 | );
153 | }
154 |
155 | class VulnList extends React.Component {
156 | //props: Props;
157 |
158 | constructor(props) {
159 | super(props);
160 | this.props.vulnerabilityList.map((row) => console.log(row.CVEDataMeta.ID));
161 |
162 | this.state = {
163 | open: false,
164 | setOpen: false,
165 | };
166 | }
167 |
168 | render() {
169 | return (
170 |
171 |
172 |
173 |
174 |
175 |
176 | Vulnerability
177 | Severity
178 | Tags
179 | CVSS
180 |
181 |
182 |
183 | {this.props.vulnerabilityList.map((row) => (
184 |
185 | ))}
186 |
187 |
188 |
189 |
190 | );
191 | }
192 | }
193 |
194 | export default VulnList;
195 |
--------------------------------------------------------------------------------
/src/renderer/containers/Agents.js:
--------------------------------------------------------------------------------
1 | // @flow
2 | import React, { Component } from 'react';
3 | import { Link } from 'react-router-dom';
4 |
5 | import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
6 | import { faWallet, faIndustry, faTerminal, faScroll, faBars, faBug, faKey, faServer, faRadiation, faHeadphones, faTable, faDragon } from '@fortawesome/free-solid-svg-icons';
7 | import ReactTooltip from 'react-tooltip';
8 | import { PieChart, Pie, Sector, Cell, ResponsiveContainer } from 'recharts';
9 |
10 | import Grid from '@mui/material/Grid';
11 | import Paper from '@mui/material/Paper';
12 | import Box from '@mui/material/Box';
13 | import Button from '@mui/material/Button';
14 | import Avatar from '@mui/material/Avatar';
15 | import Card from '@mui/material/Card';
16 | import CardActions from '@mui/material/CardActions';
17 | import CardContent from '@mui/material/CardContent';
18 | import Typography from '@mui/material/Typography';
19 |
20 | import { createTheme, ThemeProvider, styled } from '@mui/material/styles';
21 |
22 | import './Main.css';
23 | import '../components/agent/Agent.css';
24 | import logo from '/assets/logo.png';
25 |
26 | import DashCards from '../components/DashCards.js';
27 | import VulnPieGraph from '../components/VulnPieGraph.js';
28 | import VulnFilter from '../components/VulnFilter.js';
29 |
30 | //Host Compoments
31 | import AgentFinder from '../components/agent/AgentFinder.js';
32 | import TerminalPrompt from '../components/agent/TerminalPrompt.js';
33 | import TerminalCanvas from '../components/agent/TerminalCanvas.js';
34 |
35 | import VulnList from '../components/VulnList.tsx';
36 |
37 |
38 | import { taskAgent, getHosts, getTerminalHistory } from '../actions/api/db.js'
39 |
40 |
41 | const Item = styled(Paper)(({ theme }) => ({
42 | ...theme.typography.body2,
43 | textAlign: 'center',
44 | color: theme.palette.text.secondary,
45 | height: 60,
46 | backgroundColor: null,
47 | lineHeight: '60px',
48 | }));
49 |
50 | const test = [
51 | {"data": "test"}
52 | ];
53 |
54 | class Agents extends React.Component {
55 | //props: Props;
56 |
57 | constructor(props) {
58 | super(props);
59 |
60 | this.state = {
61 | open: false,
62 | newhost: false,
63 | vulnerabilityview: false,
64 | selectedHost: "",
65 | hostList: [{
66 | "ip": ""
67 | }],
68 | terminalHistory: [{}],
69 | };
70 | this.toggleNewHost = this.toggleNewHost.bind(this)
71 | this.setSelectedHost = this.setSelectedHost.bind(this)
72 | this.disableViews = this.disableViews.bind(this)
73 | this.handleCommand = this.handleCommand.bind(this)
74 | this.createTaskID = this.createTaskID.bind(this)
75 | }
76 |
77 | componentDidMount() {
78 | getHosts()
79 | .then(hosts => {
80 | console.log(hosts)
81 | this.setState({ hostList: hosts })
82 | });
83 | //.then(data => this.setState({ data }));
84 | setInterval(() => {
85 | getTerminalHistory()
86 | .then(history => {
87 | console.log(history)
88 | this.setState({ terminalHistory: history })
89 | });
90 | }, 1000);
91 | }
92 | disableViews() {
93 | this.setState({
94 | vulnerabilityview: false,
95 | newhost: false
96 | });
97 | }
98 |
99 | toggleNewHost() {
100 | this.disableViews()
101 | this.setState({ newhost: true });
102 | }
103 | handleCommand(hosts, command) {
104 | console.log(hosts)
105 | console.log(command)
106 | let encodedCommand = btoa(command)
107 | let newHistory = this.state.terminalHistory
108 |
109 | //Filter for special commands
110 | if (command == "reset") {
111 | this.setState({terminalHistory : [{}]});
112 | } else {
113 | //Deliver command to agent and push to history
114 | for (let i = 0; i < hosts.length; i++) {
115 | let cmdid = 1
116 | if (this.state.terminalHistory) {
117 | cmdid = this.state.terminalHistory.length
118 | }
119 | console.log(cmdid)
120 | let newCommand = {
121 | id : cmdid,
122 | IP : hosts[i],
123 | Command : encodedCommand,
124 | Result : "PENvbW1hbmQgU2VudD4K"
125 | }
126 | newHistory.push(newCommand)
127 | //Send to DB
128 | /*
129 | Docs:
130 | type SiriusAgent
131 | AgentId string
132 | HostKey string
133 | IP string
134 | OS string
135 | Tasks []Task
136 | type Task
137 | ID string
138 | Type string
139 | Date time.Time
140 | Command string
141 | Result string
142 | Status string
143 | */
144 | const utcTimestamp = new Date().getTime();
145 | var taskID = this.createTaskID(hosts[i])
146 | const task = {
147 | agentid: "13859332",
148 | ip: hosts[i],
149 | hostkey: "",
150 | os: "",
151 | tasks: [{
152 | id: taskID,
153 | type: "c",
154 | command: encodedCommand,
155 | result: "",
156 | status: "",
157 | date: utcTimestamp,
158 | }]
159 | }
160 | console.log(task)
161 | taskAgent(task)
162 | .then(res => {
163 | console.log(res)
164 | });
165 | }
166 | this.setState({terminalHistory : newHistory});
167 | }
168 | }
169 | createTaskID(host) {
170 | var taskID = Math.floor(Math.random() * 900000000 )
171 | var taskID = "AGENT-" + host + "-" + taskID
172 | return taskID
173 | }
174 |
175 | //Trigger fetchHosts... or such
176 | setSelectedHost = (ip) => {
177 | this.disableViews()
178 | this.setState({
179 | vulnerabilityview: true,
180 | selectedHost: ip
181 | });
182 | }
183 |
184 | render() {
185 | return (
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 | );
204 | }
205 | }
206 |
207 | export default Agents;
208 |
--------------------------------------------------------------------------------
/src/renderer/containers/Hosts.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable react/jsx-filename-extension */
2 | // @flow
3 | import React, { Component } from 'react';
4 | import { Link } from 'react-router-dom';
5 |
6 | import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
7 | import {
8 | faWallet,
9 | faIndustry,
10 | faTerminal,
11 | faScroll,
12 | faBars,
13 | faBug,
14 | faKey,
15 | faServer,
16 | faRadiation,
17 | faHeadphones,
18 | faTable,
19 | faDragon,
20 | } from '@fortawesome/free-solid-svg-icons';
21 | import ReactTooltip from 'react-tooltip';
22 | import { PieChart, Pie, Sector, Cell, ResponsiveContainer } from 'recharts';
23 |
24 | import Grid from '@mui/material/Grid';
25 | import Paper from '@mui/material/Paper';
26 | import Box from '@mui/material/Box';
27 | import Button from '@mui/material/Button';
28 | import Avatar from '@mui/material/Avatar';
29 | import Card from '@mui/material/Card';
30 | import CardActions from '@mui/material/CardActions';
31 | import CardContent from '@mui/material/CardContent';
32 | import Typography from '@mui/material/Typography';
33 |
34 | import { createTheme, ThemeProvider, styled } from '@mui/material/styles';
35 |
36 | import './Main.css';
37 | import logo from '/assets/logo.png';
38 |
39 | import DashCards from '../components/DashCards.js';
40 | import VulnPieGraph from '../components/VulnPieGraph.js';
41 | import VulnFilter from '../components/VulnFilter.js';
42 |
43 | // Host Compoments
44 | import HostOverview from '../components/host/HostOverview.js';
45 | import HostManager from '../components/host/HostManager.js';
46 | import HostServices from '../components/host/HostServices.js';
47 | import HostSoftware from '../components/host/HostSoftware.js';
48 | import NewHost from '../components/host/NewHost.tsx';
49 | import VulnList from '../components/host/VulnList.tsx';
50 |
51 | // Host Actions
52 | import { handleVulnList } from '../components/host/actions/handleVulnList.js';
53 |
54 | import { getHosts, getVulnerabilityList } from '../actions/api/db.js';
55 |
56 | const Item = styled(Paper)(({ theme }) => ({
57 | ...theme.typography.body2,
58 | textAlign: 'center',
59 | color: theme.palette.text.secondary,
60 | height: 60,
61 | backgroundColor: null,
62 | lineHeight: '60px',
63 | }));
64 |
65 | const test = [{ data: 'test' }];
66 |
67 | class Hosts extends React.Component {
68 | // props: Props;
69 |
70 | constructor(props) {
71 | super(props);
72 |
73 | this.state = {
74 | open: false,
75 | newhost: false,
76 | vulnerabilityview: false,
77 | selectedHost: '',
78 | hostList: [
79 | {
80 | ip: '127.0.0.1',
81 | },
82 | ],
83 | vulnerabilityList: [
84 | {
85 | CVEDataMeta: {
86 | ID: 'Loading Vulnerability List...',
87 | ASSIGNER: 'cve@mitre.org',
88 | },
89 | CVSSV3: {
90 | baseScore: 0,
91 | baseSeverity: '',
92 | },
93 | Description: {
94 | description_data: [
95 | {
96 | value: 'Loading...',
97 | },
98 | ],
99 | },
100 | References: ['Loading...'],
101 | cve: 'CVE-2017-0145 - Remote Code Execution',
102 | catagory: '',
103 | tags: 'CISA Worm RCE Wild',
104 | cvss: 9.8,
105 | srs: 10,
106 | description:
107 | 'The SMBv1 server in Microsoft Windows Vista SP2; Windows Server 2008 SP2 and R2 SP1; Windows 7 SP1; Windows 8.1; Windows Server 2012 Gold and R2; Windows RT 8.1; and Windows 10 Gold, 1511, and 1607; and Windows Server 2016 allows remote attackers to execute arbitrary code via crafted packets, aka "Windows SMB Remote Code Execution Vulnerability." This vulnerability is different from those described in CVE-2017-0143, CVE-2017-0144, CVE-2017-0146, and CVE-2017-0148.',
108 | cia: '3,3,3',
109 | },
110 | ],
111 | baseVulnerabilityList: [
112 | {
113 | CVEDataMeta: {
114 | ID: 'Loading Vulnerability List...',
115 | ASSIGNER: 'cve@mitre.org',
116 | },
117 | CVSSV3: {
118 | baseScore: 0,
119 | baseSeverity: '',
120 | },
121 | Description: {
122 | description_data: [
123 | {
124 | value: 'Loading...',
125 | },
126 | ],
127 | },
128 | References: ['Loading...'],
129 | cve: 'CVE-2017-0145 - Remote Code Execution',
130 | catagory: '',
131 | tags: 'CISA Worm RCE Wild',
132 | cvss: 9.8,
133 | srs: 10,
134 | description:
135 | 'The SMBv1 server in Microsoft Windows Vista SP2; Windows Server 2008 SP2 and R2 SP1; Windows 7 SP1; Windows 8.1; Windows Server 2012 Gold and R2; Windows RT 8.1; and Windows 10 Gold, 1511, and 1607; and Windows Server 2016 allows remote attackers to execute arbitrary code via crafted packets, aka "Windows SMB Remote Code Execution Vulnerability." This vulnerability is different from those described in CVE-2017-0143, CVE-2017-0144, CVE-2017-0146, and CVE-2017-0148.',
136 | cia: '3,3,3',
137 | },
138 | ],
139 | };
140 | this.toggleNewHost = this.toggleNewHost.bind(this);
141 | this.setSelectedHost = this.setSelectedHost.bind(this);
142 | this.disableViews = this.disableViews.bind(this);
143 | }
144 |
145 | componentDidMount() {
146 | getHosts().then((hosts) => {
147 | console.log(hosts);
148 | if (hosts) {
149 | this.setState({ hostList: hosts });
150 | }
151 | });
152 | setInterval(() => {
153 | const svdbhost = {
154 | ip: this.state.selectedHost,
155 | };
156 | getVulnerabilityList(svdbhost).then((data) => {
157 | console.log(data);
158 | if (data) {
159 | this.setState({ vulnerabilityList: data });
160 | } else {
161 | const emptyList = this.state.baseVulnerabilityList;
162 | emptyList[0].CVEDataMeta.ID = 'No Vulnerabilities Found'
163 | this.setState({ vulnerabilityList: emptyList });
164 | }
165 | });
166 | }, 5000);
167 | // .then(data => this.setState({ data }));
168 | }
169 | disableViews() {
170 | this.setState({
171 | vulnerabilityview: false,
172 | newhost: false,
173 | });
174 | }
175 |
176 | toggleNewHost() {
177 | this.disableViews();
178 | this.setState({ newhost: true });
179 | }
180 |
181 | // Trigger fetchHosts... or such
182 | setSelectedHost = (ip) => {
183 | this.disableViews();
184 | this.setState({
185 | vulnerabilityview: true,
186 | selectedHost: ip,
187 | });
188 | };
189 |
190 | render() {
191 | return (
192 |
193 |
194 |
195 |
196 |
201 | {this.state.vulnerabilityview ? (
202 |
203 |
204 |
205 |
206 |
207 | ) : null}
208 |
209 |
210 | {this.state.vulnerabilityview ? (
211 |
212 |
213 |
214 |
215 | ) : null}
216 |
217 | {this.state.newhost ? (
218 |
219 | ) : null}
220 |
221 |
222 |
223 |
224 | );
225 | }
226 | }
227 |
228 | export default Hosts;
229 |
--------------------------------------------------------------------------------
/src/main/menu.ts:
--------------------------------------------------------------------------------
1 | import {
2 | app,
3 | Menu,
4 | shell,
5 | BrowserWindow,
6 | MenuItemConstructorOptions,
7 | } from 'electron';
8 |
9 | interface DarwinMenuItemConstructorOptions extends MenuItemConstructorOptions {
10 | selector?: string;
11 | submenu?: DarwinMenuItemConstructorOptions[] | Menu;
12 | }
13 |
14 | export default class MenuBuilder {
15 | mainWindow: BrowserWindow;
16 |
17 | constructor(mainWindow: BrowserWindow) {
18 | this.mainWindow = mainWindow;
19 | }
20 |
21 | buildMenu(): Menu {
22 | if (
23 | process.env.NODE_ENV === 'development' ||
24 | process.env.DEBUG_PROD === 'true'
25 | ) {
26 | this.setupDevelopmentEnvironment();
27 | }
28 |
29 | const template =
30 | process.platform === 'darwin'
31 | ? this.buildDarwinTemplate()
32 | : this.buildDefaultTemplate();
33 |
34 | const menu = Menu.buildFromTemplate(template);
35 | Menu.setApplicationMenu(menu);
36 |
37 | return menu;
38 | }
39 |
40 | setupDevelopmentEnvironment(): void {
41 | this.mainWindow.webContents.on('context-menu', (_, props) => {
42 | const { x, y } = props;
43 |
44 | Menu.buildFromTemplate([
45 | {
46 | label: 'Inspect element',
47 | click: () => {
48 | this.mainWindow.webContents.inspectElement(x, y);
49 | },
50 | },
51 | ]).popup({ window: this.mainWindow });
52 | });
53 | }
54 |
55 | buildDarwinTemplate(): MenuItemConstructorOptions[] {
56 | const subMenuAbout: DarwinMenuItemConstructorOptions = {
57 | label: 'Electron',
58 | submenu: [
59 | {
60 | label: 'About ElectronReact',
61 | selector: 'orderFrontStandardAboutPanel:',
62 | },
63 | { type: 'separator' },
64 | { label: 'Services', submenu: [] },
65 | { type: 'separator' },
66 | {
67 | label: 'Hide ElectronReact',
68 | accelerator: 'Command+H',
69 | selector: 'hide:',
70 | },
71 | {
72 | label: 'Hide Others',
73 | accelerator: 'Command+Shift+H',
74 | selector: 'hideOtherApplications:',
75 | },
76 | { label: 'Show All', selector: 'unhideAllApplications:' },
77 | { type: 'separator' },
78 | {
79 | label: 'Quit',
80 | accelerator: 'Command+Q',
81 | click: () => {
82 | app.quit();
83 | },
84 | },
85 | ],
86 | };
87 | const subMenuEdit: DarwinMenuItemConstructorOptions = {
88 | label: 'Edit',
89 | submenu: [
90 | { label: 'Undo', accelerator: 'Command+Z', selector: 'undo:' },
91 | { label: 'Redo', accelerator: 'Shift+Command+Z', selector: 'redo:' },
92 | { type: 'separator' },
93 | { label: 'Cut', accelerator: 'Command+X', selector: 'cut:' },
94 | { label: 'Copy', accelerator: 'Command+C', selector: 'copy:' },
95 | { label: 'Paste', accelerator: 'Command+V', selector: 'paste:' },
96 | {
97 | label: 'Select All',
98 | accelerator: 'Command+A',
99 | selector: 'selectAll:',
100 | },
101 | ],
102 | };
103 | const subMenuViewDev: MenuItemConstructorOptions = {
104 | label: 'View',
105 | submenu: [
106 | {
107 | label: 'Reload',
108 | accelerator: 'Command+R',
109 | click: () => {
110 | this.mainWindow.webContents.reload();
111 | },
112 | },
113 | {
114 | label: 'Toggle Full Screen',
115 | accelerator: 'Ctrl+Command+F',
116 | click: () => {
117 | this.mainWindow.setFullScreen(!this.mainWindow.isFullScreen());
118 | },
119 | },
120 | {
121 | label: 'Toggle Developer Tools',
122 | accelerator: 'Alt+Command+I',
123 | click: () => {
124 | this.mainWindow.webContents.toggleDevTools();
125 | },
126 | },
127 | ],
128 | };
129 | const subMenuViewProd: MenuItemConstructorOptions = {
130 | label: 'View',
131 | submenu: [
132 | {
133 | label: 'Toggle Full Screen',
134 | accelerator: 'Ctrl+Command+F',
135 | click: () => {
136 | this.mainWindow.setFullScreen(!this.mainWindow.isFullScreen());
137 | },
138 | },
139 | ],
140 | };
141 | const subMenuWindow: DarwinMenuItemConstructorOptions = {
142 | label: 'Window',
143 | submenu: [
144 | {
145 | label: 'Minimize',
146 | accelerator: 'Command+M',
147 | selector: 'performMiniaturize:',
148 | },
149 | { label: 'Close', accelerator: 'Command+W', selector: 'performClose:' },
150 | { type: 'separator' },
151 | { label: 'Bring All to Front', selector: 'arrangeInFront:' },
152 | ],
153 | };
154 | const subMenuHelp: MenuItemConstructorOptions = {
155 | label: 'Help',
156 | submenu: [
157 | {
158 | label: 'Learn More',
159 | click() {
160 | shell.openExternal('https://electronjs.org');
161 | },
162 | },
163 | {
164 | label: 'Documentation',
165 | click() {
166 | shell.openExternal(
167 | 'https://github.com/electron/electron/tree/main/docs#readme'
168 | );
169 | },
170 | },
171 | {
172 | label: 'Community Discussions',
173 | click() {
174 | shell.openExternal('https://www.electronjs.org/community');
175 | },
176 | },
177 | {
178 | label: 'Search Issues',
179 | click() {
180 | shell.openExternal('https://github.com/electron/electron/issues');
181 | },
182 | },
183 | ],
184 | };
185 |
186 | const subMenuView =
187 | process.env.NODE_ENV === 'development' ||
188 | process.env.DEBUG_PROD === 'true'
189 | ? subMenuViewDev
190 | : subMenuViewProd;
191 |
192 | return [subMenuAbout, subMenuEdit, subMenuView, subMenuWindow, subMenuHelp];
193 | }
194 |
195 | buildDefaultTemplate() {
196 | const templateDefault = [
197 | {
198 | label: '&File',
199 | submenu: [
200 | {
201 | label: '&Open',
202 | accelerator: 'Ctrl+O',
203 | },
204 | {
205 | label: '&Close',
206 | accelerator: 'Ctrl+W',
207 | click: () => {
208 | this.mainWindow.close();
209 | },
210 | },
211 | ],
212 | },
213 | {
214 | label: '&View',
215 | submenu:
216 | process.env.NODE_ENV === 'development' ||
217 | process.env.DEBUG_PROD === 'true'
218 | ? [
219 | {
220 | label: '&Reload',
221 | accelerator: 'Ctrl+R',
222 | click: () => {
223 | this.mainWindow.webContents.reload();
224 | },
225 | },
226 | {
227 | label: 'Toggle &Full Screen',
228 | accelerator: 'F11',
229 | click: () => {
230 | this.mainWindow.setFullScreen(
231 | !this.mainWindow.isFullScreen()
232 | );
233 | },
234 | },
235 | {
236 | label: 'Toggle &Developer Tools',
237 | accelerator: 'Alt+Ctrl+I',
238 | click: () => {
239 | this.mainWindow.webContents.toggleDevTools();
240 | },
241 | },
242 | ]
243 | : [
244 | {
245 | label: 'Toggle &Full Screen',
246 | accelerator: 'F11',
247 | click: () => {
248 | this.mainWindow.setFullScreen(
249 | !this.mainWindow.isFullScreen()
250 | );
251 | },
252 | },
253 | ],
254 | },
255 | {
256 | label: 'Help',
257 | submenu: [
258 | {
259 | label: 'Learn More',
260 | click() {
261 | shell.openExternal('https://electronjs.org');
262 | },
263 | },
264 | {
265 | label: 'Documentation',
266 | click() {
267 | shell.openExternal(
268 | 'https://github.com/electron/electron/tree/main/docs#readme'
269 | );
270 | },
271 | },
272 | {
273 | label: 'Community Discussions',
274 | click() {
275 | shell.openExternal('https://www.electronjs.org/community');
276 | },
277 | },
278 | {
279 | label: 'Search Issues',
280 | click() {
281 | shell.openExternal('https://github.com/electron/electron/issues');
282 | },
283 | },
284 | ],
285 | },
286 | ];
287 |
288 | return templateDefault;
289 | }
290 | }
291 |
--------------------------------------------------------------------------------
/src/renderer/components/MenuBar2.js:
--------------------------------------------------------------------------------
1 | // @flow
2 | import React, { Component } from 'react';
3 | import { Link } from 'react-router-dom';
4 |
5 | import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
6 | import { faWallet, faIndustry, faTerminal, faScroll, faBars, faBug, faKey, faServer, faRadiation, faHeadphones, faTable } from '@fortawesome/free-solid-svg-icons';
7 | import ReactTooltip from 'react-tooltip';
8 | import Modal from 'react-responsive-modal';
9 |
10 | import FormControl from '@material-ui/core/FormControl';
11 | import FormHelperText from '@material-ui/core/FormHelperText';
12 | import InputLabel from '@material-ui/core/InputLabel';
13 | import TextField from '@material-ui/core/TextField';
14 | import Input from '@material-ui/core/Input';
15 | import Button from '@material-ui/core/Button';
16 | import Grid from '@material-ui/core/Grid';
17 |
18 |
19 | import styles from './Home.css';
20 |
21 | const remote = require('electron').remote;
22 |
23 | import Settings from './menus/Settings';
24 | import Listeners from './menus/Listeners';
25 |
26 | import payloadGenerator from '../renderers/backdoor-factory';
27 |
28 |
29 | export default class MenuBar extends Component {
30 | props: Props;
31 |
32 | constructor(props) {
33 | super(props);
34 |
35 | this.state = {
36 | open: false,
37 | showSettings: false,
38 | showListeners: false,
39 | payload: "Gryffindor",
40 | listener: "",
41 | c2profile: "default.profile",
42 | loader: false,
43 | };
44 | this.toggleSettings = this.toggleSettings.bind(this)
45 | this.toggleListeners = this.toggleListeners.bind(this)
46 | }
47 |
48 | toggleSettings() {
49 | if (this.state.showSettings == true) {
50 | this.setState({ showSettings: false });
51 | } else {
52 | this.setState({ showSettings: true });
53 | }
54 | }
55 | toggleListeners() {
56 | if (this.state.showListeners == true) {
57 | this.setState({ showListeners: false });
58 | } else {
59 | this.setState({ showListeners: true });
60 | }
61 | }
62 | openBackdoorFactory() {
63 | this.setState({ open: true });
64 | }
65 | closeBackdoorFactory() {
66 | this.setState({ open: false });
67 | }
68 | generatePayload() {
69 | this.closeBackdoorFactory();
70 | this.showLoader();
71 |
72 | var settings = {
73 | "name": "Gryffindor",
74 | "listener": this.state.listener,
75 | "profile": this.state.c2profile
76 | }
77 |
78 | payloadGenerator(settings);
79 | }
80 | showLoader() {
81 | this.setState({ loader: true });
82 | setTimeout(function() { //Start the timer
83 | this.setState({loader: false}) //After 1 second, set render to true
84 | }.bind(this), 3000)
85 | }
86 |
87 | handleChange = name => event => {
88 | this.setState({ [name]: event.target.value });
89 | };
90 |
91 | render() {
92 | const {
93 | increment,
94 | incrementIfOdd,
95 | incrementAsync,
96 | decrement,
97 | counter
98 | } = this.props;
99 | const { open } = this.state;
100 | const payloads = [
101 | {
102 | name: "Gryffindor"
103 | }
104 | ]
105 | const Loading = () => {
106 | return (
107 |
108 |
109 |
Saving payload to engagement directory...
110 |
111 | )
112 | }
113 | return (
114 |
115 |
116 | {this.state.loader ? : null }
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
162 |
235 |
236 | {this.state.showSettings ?
: null }
237 | {this.state.showListeners ?
: null }
238 |
239 | );
240 | }
241 | }
242 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "sirius-scan",
3 | "description": "A foundation for scalable desktop apps",
4 | "scripts": {
5 | "build": "concurrently \"npm run build:main\" \"npm run build:renderer\"",
6 | "build:main": "cross-env NODE_ENV=production TS_NODE_TRANSPILE_ONLY=true webpack --config ./.erb/configs/webpack.config.main.prod.ts",
7 | "build:renderer": "cross-env NODE_ENV=production TS_NODE_TRANSPILE_ONLY=true webpack --config ./.erb/configs/webpack.config.renderer.prod.ts",
8 | "rebuild": "electron-rebuild --parallel --types prod,dev,optional --module-dir release/app",
9 | "lint": "cross-env NODE_ENV=development eslint . --ext .js,.jsx,.ts,.tsx",
10 | "package": "ts-node ./.erb/scripts/clean.js dist && npm run build && electron-builder build --win --ia32 --publish never",
11 | "postinstall": "ts-node .erb/scripts/check-native-dep.js && electron-builder install-app-deps && cross-env NODE_ENV=development TS_NODE_TRANSPILE_ONLY=true webpack --config ./.erb/configs/webpack.config.renderer.dev.dll.ts && opencollective-postinstall",
12 | "start": "ts-node ./.erb/scripts/check-port-in-use.js && npm run start:renderer",
13 | "start:main": "cross-env NODE_ENV=development electron -r ts-node/register/transpile-only ./src/main/main.ts",
14 | "start:preload": "cross-env NODE_ENV=development TS_NODE_TRANSPILE_ONLY=true webpack --config ./.erb/configs/webpack.config.preload.dev.ts",
15 | "start:renderer": "cross-env NODE_ENV=development TS_NODE_TRANSPILE_ONLY=true webpack serve --config ./.erb/configs/webpack.config.renderer.dev.ts",
16 | "test": "jest",
17 | "prepare": "husky install"
18 | },
19 | "lint-staged": {
20 | "*.{js,jsx,ts,tsx}": [
21 | "cross-env NODE_ENV=development eslint --cache"
22 | ],
23 | "*.json,.{eslintrc,prettierrc}": [
24 | "prettier --ignore-path .eslintignore --parser json --write"
25 | ],
26 | "*.{css,scss}": [
27 | "prettier --ignore-path .eslintignore --single-quote --write"
28 | ],
29 | "*.{html,md,yml}": [
30 | "prettier --ignore-path .eslintignore --single-quote --write"
31 | ]
32 | },
33 | "build": {
34 | "productName": "SiriusScan",
35 | "appId": "org.erb.SiriusScan",
36 | "asar": true,
37 | "asarUnpack": "**\\*.{node,dll}",
38 | "files": [
39 | "dist",
40 | "node_modules",
41 | "package.json"
42 | ],
43 | "afterSign": ".erb/scripts/notarize.js",
44 | "mac": {
45 | "target": {
46 | "target": "default",
47 | "arch": [
48 | "arm64",
49 | "x64"
50 | ]
51 | },
52 | "type": "distribution",
53 | "hardenedRuntime": true,
54 | "entitlements": "assets/entitlements.mac.plist",
55 | "entitlementsInherit": "assets/entitlements.mac.plist",
56 | "gatekeeperAssess": false
57 | },
58 | "dmg": {
59 | "contents": [
60 | {
61 | "x": 130,
62 | "y": 220
63 | },
64 | {
65 | "x": 410,
66 | "y": 220,
67 | "type": "link",
68 | "path": "/Applications"
69 | }
70 | ]
71 | },
72 | "win": {
73 | "target": [
74 | "nsis"
75 | ]
76 | },
77 | "linux": {
78 | "target": [
79 | "AppImage"
80 | ],
81 | "category": "Development"
82 | },
83 | "directories": {
84 | "app": "release/app",
85 | "buildResources": "assets",
86 | "output": "release/build"
87 | },
88 | "extraResources": [
89 | "./assets/**"
90 | ],
91 | "publish": {
92 | "provider": "github",
93 | "owner": "electron-react-boilerplate",
94 | "repo": "electron-react-boilerplate"
95 | }
96 | },
97 | "repository": {
98 | "type": "git",
99 | "url": "git+https://github.com/electron-react-boilerplate/electron-react-boilerplate.git"
100 | },
101 | "author": {
102 | "name": "Electron React Boilerplate Maintainers",
103 | "email": "electronreactboilerplate@gmail.com",
104 | "url": "https://electron-react-boilerplate.js.org"
105 | },
106 | "contributors": [
107 | {
108 | "name": "Amila Welihinda",
109 | "email": "amilajack@gmail.com",
110 | "url": "https://github.com/amilajack"
111 | },
112 | {
113 | "name": "John Tran",
114 | "email": "jptran318@gmail.com",
115 | "url": "https://github.com/jooohhn"
116 | }
117 | ],
118 | "license": "MIT",
119 | "bugs": {
120 | "url": "https://github.com/electron-react-boilerplate/electron-react-boilerplate/issues"
121 | },
122 | "keywords": [
123 | "electron",
124 | "boilerplate",
125 | "react",
126 | "typescript",
127 | "ts",
128 | "sass",
129 | "webpack",
130 | "hot",
131 | "reload"
132 | ],
133 | "homepage": "https://github.com/electron-react-boilerplate/electron-react-boilerplate#readme",
134 | "jest": {
135 | "testURL": "http://localhost/",
136 | "testEnvironment": "jsdom",
137 | "transform": {
138 | "\\.(ts|tsx|js|jsx)$": "ts-jest"
139 | },
140 | "moduleNameMapper": {
141 | "\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "/.erb/mocks/fileMock.js",
142 | "\\.(css|less|sass|scss)$": "identity-obj-proxy"
143 | },
144 | "moduleFileExtensions": [
145 | "js",
146 | "jsx",
147 | "ts",
148 | "tsx",
149 | "json"
150 | ],
151 | "moduleDirectories": [
152 | "node_modules",
153 | "release/app/node_modules"
154 | ],
155 | "testPathIgnorePatterns": [
156 | "release/app/dist"
157 | ],
158 | "setupFiles": [
159 | "./.erb/scripts/check-build-exists.ts"
160 | ]
161 | },
162 | "devDependencies": {
163 | "@pmmmwh/react-refresh-webpack-plugin": "0.5.5",
164 | "@teamsupercell/typings-for-css-modules-loader": "^2.5.1",
165 | "@testing-library/jest-dom": "^5.16.4",
166 | "@testing-library/react": "^13.0.0",
167 | "@types/jest": "^27.4.1",
168 | "@types/node": "17.0.23",
169 | "@types/react": "^17.0.43",
170 | "@types/react-dom": "^17.0.14",
171 | "@types/react-test-renderer": "^17.0.1",
172 | "@types/terser-webpack-plugin": "^5.0.4",
173 | "@types/webpack-bundle-analyzer": "^4.4.1",
174 | "@types/webpack-env": "^1.16.3",
175 | "@typescript-eslint/eslint-plugin": "^5.18.0",
176 | "@typescript-eslint/parser": "^5.18.0",
177 | "browserslist-config-erb": "^0.0.3",
178 | "chalk": "^4.1.2",
179 | "concurrently": "^7.1.0",
180 | "core-js": "^3.21.1",
181 | "cross-env": "^7.0.3",
182 | "css-loader": "^6.7.1",
183 | "css-minimizer-webpack-plugin": "^3.4.1",
184 | "detect-port": "^1.3.0",
185 | "electron": "^18.0.1",
186 | "electron-builder": "22.14.13",
187 | "electron-devtools-installer": "^3.2.0",
188 | "electron-notarize": "^1.2.1",
189 | "electron-rebuild": "^3.2.7",
190 | "eslint": "^8.12.0",
191 | "eslint-config-airbnb-base": "^15.0.0",
192 | "eslint-config-erb": "^4.0.3",
193 | "eslint-import-resolver-typescript": "^2.7.1",
194 | "eslint-import-resolver-webpack": "^0.13.2",
195 | "eslint-plugin-compat": "^4.0.2",
196 | "eslint-plugin-import": "^2.25.4",
197 | "eslint-plugin-jest": "^26.1.3",
198 | "eslint-plugin-jsx-a11y": "^6.5.1",
199 | "eslint-plugin-promise": "^6.0.0",
200 | "eslint-plugin-react": "^7.29.4",
201 | "eslint-plugin-react-hooks": "^4.4.0",
202 | "file-loader": "^6.2.0",
203 | "html-webpack-plugin": "^5.5.0",
204 | "husky": "^7.0.4",
205 | "identity-obj-proxy": "^3.0.0",
206 | "jest": "^27.5.1",
207 | "lint-staged": "^12.3.7",
208 | "mini-css-extract-plugin": "^2.6.0",
209 | "opencollective-postinstall": "^2.0.3",
210 | "prettier": "^2.6.2",
211 | "react-refresh": "^0.12.0",
212 | "react-refresh-typescript": "^2.0.4",
213 | "react-test-renderer": "^18.0.0",
214 | "rimraf": "^3.0.2",
215 | "sass": "^1.49.11",
216 | "sass-loader": "^12.6.0",
217 | "style-loader": "^3.3.1",
218 | "terser-webpack-plugin": "^5.3.1",
219 | "ts-jest": "^27.1.4",
220 | "ts-loader": "^9.2.8",
221 | "ts-node": "^10.7.0",
222 | "typescript": "^4.6.3",
223 | "url-loader": "^4.1.1",
224 | "webpack": "^5.71.0",
225 | "webpack-bundle-analyzer": "^4.5.0",
226 | "webpack-cli": "^4.9.2",
227 | "webpack-dev-server": "^4.8.0",
228 | "webpack-merge": "^5.8.0"
229 | },
230 | "dependencies": {
231 | "@emotion/react": "^11.9.0",
232 | "@emotion/styled": "^11.8.1",
233 | "@fortawesome/fontawesome-svg-core": "^6.1.1",
234 | "@fortawesome/free-brands-svg-icons": "^6.1.1",
235 | "@fortawesome/free-regular-svg-icons": "^6.1.1",
236 | "@fortawesome/free-solid-svg-icons": "^6.1.1",
237 | "@fortawesome/react-fontawesome": "^0.1.18",
238 | "@mui/icons-material": "^5.6.0",
239 | "@mui/material": "^5.6.0",
240 | "chart.js": "^3.7.1",
241 | "electron-debug": "^3.2.0",
242 | "electron-log": "^4.4.6",
243 | "electron-updater": "^4.6.5",
244 | "fs": "^0.0.1-security",
245 | "history": "^5.3.0",
246 | "react": "^18.0.0",
247 | "react-dom": "^18.0.0",
248 | "react-router-dom": "^6.3.0",
249 | "react-tooltip": "^4.2.21",
250 | "react-vis": "^1.11.7",
251 | "recharts": "^2.1.9"
252 | },
253 | "devEngines": {
254 | "node": ">=14.x",
255 | "npm": ">=7.x"
256 | },
257 | "collective": {
258 | "url": "https://opencollective.com/electron-react-boilerplate-594"
259 | },
260 | "browserslist": [],
261 | "prettier": {
262 | "overrides": [
263 | {
264 | "files": [
265 | ".prettierrc",
266 | ".eslintrc"
267 | ],
268 | "options": {
269 | "parser": "json"
270 | }
271 | }
272 | ],
273 | "singleQuote": true
274 | }
275 | }
276 |
--------------------------------------------------------------------------------
/src/renderer/components/host/NewHost.tsx:
--------------------------------------------------------------------------------
1 | // @flow
2 | import React, { Component } from 'react';
3 | import { Link } from 'react-router-dom';
4 |
5 | import Paper from '@mui/material/Paper';
6 | import Card from '@mui/material/Card';
7 | import Grid from '@mui/material/Grid';
8 | import CardActions from '@mui/material/CardActions';
9 | import CardContent from '@mui/material/CardContent';
10 | import Typography from '@mui/material/Typography';
11 | import Box from '@mui/material/Box';
12 |
13 | import Divider from '@mui/material/Divider';
14 | import Chip from '@mui/material/Chip';
15 | import Autocomplete from '@mui/material/Autocomplete';
16 | import TextField from '@mui/material/TextField';
17 | import Stack from '@mui/material/Stack';
18 |
19 | import Table from '@mui/material/Table';
20 | import TableBody from '@mui/material/TableBody';
21 | import TableCell from '@mui/material/TableCell';
22 | import TableContainer from '@mui/material/TableContainer';
23 | import TableHead from '@mui/material/TableHead';
24 | import TableRow from '@mui/material/TableRow';
25 |
26 | import Close from '@mui/icons-material/Close';
27 | import Add from '@mui/icons-material/Add';
28 | import IndeterminateCheckBoxIcon from '@mui/icons-material/IndeterminateCheckBox';
29 | import UploadFileRoundedIcon from '@mui/icons-material/UploadFileRounded';
30 | import Button from '@mui/material/Button';
31 |
32 | import { getHosts, addHost, getVendors } from '../../actions/api/db.js';
33 |
34 | import '../Home.css';
35 |
36 | const vendors = [
37 | {
38 | "vendor_name": "\\$0.99_kindle_books_project",
39 | "product": null
40 | },
41 | {
42 | "vendor_name": "-",
43 | "product": null
44 | },
45 | {
46 | "vendor_name": ".bbsoftware",
47 | "product": [
48 | {
49 | "product_name": "wireless_ip_camera_360"
50 | }
51 | ]
52 | },
53 | {
54 | "vendor_name": ".joomclan",
55 | "product": [
56 | {
57 | "product_name": "wireless_ip_camera_360"
58 | }
59 | ]
60 | },
61 | {
62 | "vendor_name": ".matteoiammarrone",
63 | "product": [
64 | {
65 | "product_name": "wireless_ip_camera_360"
66 | }
67 | ]
68 | },
69 | {
70 | "vendor_name": "\\@mail",
71 | "product": [
72 | {
73 | "product_name": "wireless_ip_camera_360"
74 | },
75 | {
76 | "product_name": "iamma_simple_gallery"
77 | }
78 | ]
79 | },
80 | {
81 | "vendor_name": "\\@thi.ng\\/egf_project",
82 | "product": [
83 | {
84 | "product_name": "wireless_ip_camera_360"
85 | },
86 | {
87 | "product_name": "iamma_simple_gallery"
88 | }
89 | ]
90 | },
91 | {
92 | "vendor_name": "\\[gwa\\]_autoresponder_project",
93 | "product": [
94 | {
95 | "product_name": "wireless_ip_camera_360"
96 | },
97 | {
98 | "product_name": "iamma_simple_gallery"
99 | }
100 | ]
101 | },
102 | {
103 | "vendor_name": "_akindo_sushiro_co_ltd",
104 | "product": [
105 | {
106 | "product_name": "wireless_ip_camera_360"
107 | },
108 | {
109 | "product_name": "iamma_simple_gallery"
110 | }
111 | ]
112 | },
113 | {
114 | "vendor_name": "_wp_favorite_posts_project",
115 | "product": [
116 | {
117 | "product_name": "wireless_ip_camera_360"
118 | },
119 | {
120 | "product_name": "iamma_simple_gallery"
121 | },
122 | {
123 | "product_name": "sushiro"
124 | }
125 | ]
126 | },
127 | {
128 | "vendor_name": "0verkill",
129 | "product": [
130 | {
131 | "product_name": "wireless_ip_camera_360"
132 | },
133 | {
134 | "product_name": "iamma_simple_gallery"
135 | },
136 | {
137 | "product_name": "sushiro"
138 | }
139 | ]
140 | },
141 | {
142 | "vendor_name": "1-script",
143 | "product": [
144 | {
145 | "product_name": "wireless_ip_camera_360"
146 | },
147 | {
148 | "product_name": "iamma_simple_gallery"
149 | },
150 | {
151 | "product_name": "sushiro"
152 | }
153 | ]
154 | },
155 | {
156 | "vendor_name": "10web",
157 | "product": [
158 | {
159 | "product_name": "wireless_ip_camera_360"
160 | },
161 | {
162 | "product_name": "iamma_simple_gallery"
163 | },
164 | {
165 | "product_name": "sushiro"
166 | }
167 | ]
168 | }
169 | ];
170 |
171 | class NewHost extends React.Component {
172 | constructor(props) {
173 | super(props);
174 |
175 | this.state = {
176 | open: false,
177 | os: '',
178 | osversion: '',
179 | ip: '',
180 | hostname: '',
181 | port: null,
182 | product: '',
183 | vendor: '',
184 | pversion: '',
185 | cpe: [],
186 | vendors: [],
187 | products: [
188 | { name: 'Apache' },
189 | ],
190 | tags: [],
191 | };
192 | this.handleChange = this.handleChange.bind(this);
193 | this.handleSubmit = this.handleSubmit.bind(this);
194 | this.handleVendorChange = this.handleVendorChange.bind(this);
195 | this.handleProductChange = this.handleProductChange.bind(this);
196 | this.addCPE = this.addCPE.bind(this);
197 | this.fetchHosts = this.fetchHosts.bind(this);
198 | this.submitHost = this.submitHost.bind(this);
199 | }
200 |
201 | fetchHosts() {
202 | getHosts().then((hosts) => {
203 | console.log(hosts);
204 | });
205 | }
206 |
207 | componentDidMount() {
208 | getVendors().then((vendors) => {
209 | console.log(vendors);
210 | if (vendors) {
211 | this.setState({ vendors: vendors });
212 | }
213 | });
214 | }
215 |
216 | submitHost() {
217 | // HOST CREATION FROM STATE DATA
218 | this.props.disableViews();
219 | const host = {
220 | os: this.state.os,
221 | osversion: this.state.osversion,
222 | ip: this.state.ip,
223 | hostname: this.state.hostname,
224 | cpe: this.state.cpe,
225 | };
226 | addHost(host).then((res) => {
227 | console.log(res);
228 | });
229 | }
230 |
231 | handleVendorChange(event, values) {
232 | //Get products from vendor
233 | const productList = [];
234 | console.log(values)
235 | for (let i = 0; i < this.state.vendors.length; i++) {
236 | if (this.state.vendors[i].vendor_name === values) {
237 | if (this.state.vendors[i].product) {
238 | for (let j = 0; j < this.state.vendors[i].product.length; j++) {
239 | var product = this.state.vendors[i].product[j].product_name//.replace(/\\/g, '');
240 | productList.push({
241 | name: product,
242 | });
243 | }
244 | }
245 | }
246 | }
247 | //Remove escape characters from vendor name
248 | values = values.replace(/\\/g, '');
249 |
250 |
251 | this.setState({
252 | products: productList,
253 | vendor: values,
254 | });
255 | console.log(this.state.products);
256 | }
257 | handleProductChange(event, values) {
258 | console.log(values)
259 |
260 | this.setState({
261 | product: values,
262 | });
263 | console.log(this.state.product);
264 | }
265 |
266 | handleChange(event) {
267 | const target = event.target;
268 | const value = target.type === 'checkbox' ? target.checked : target.value;
269 | const name = target.name;
270 |
271 | this.setState({
272 | [name]: value,
273 | });
274 | }
275 | addCPE() {
276 | const newcpe ="cpe:2.3:a:" + this.state.vendor + ':' + this.state.product + ':' + this.state.pversion + ':*:*:*:*:*:*:*'
277 |
278 | this.setState({
279 | cpe: [...this.state.cpe, newcpe],
280 | });
281 | console.log(newcpe);
282 | }
283 |
284 | handleSubmit(event) {
285 | alert('A name was submitted: ' + this.state.value);
286 | event.preventDefault();
287 | }
288 |
289 | render() {
290 | const { error, isLoaded, items } = this.state;
291 | return (
292 |
293 |
294 |
295 |
296 | New Host Details{' '}
297 |
301 |
302 |
303 |
304 | option.title)}
308 | defaultValue={[hostTags[2].title]}
309 | freeSolo
310 | renderTags={(value: readonly string[], getTagProps) =>
311 | value.map((option: string, index: number) => (
312 |
317 | ))
318 | }
319 | renderInput={(params) => (
320 |
326 | )}
327 | />
328 |
329 |
330 |
331 |
332 |
333 | :not(style)': { m: 1, width: '25ch' },
337 | marginTop: '15px',
338 | }}
339 | noValidate
340 | autoComplete="off"
341 | >
342 |
349 |
356 |
363 |
364 |
365 |
366 |
367 | :not(style)': { m: 1, width: '25ch' },
371 | marginTop: '15px',
372 | }}
373 | noValidate
374 | autoComplete="off"
375 | >
376 |
383 |
384 |
385 |
386 |
387 |
388 |
389 |
390 |
391 |
392 |
397 |
398 |
399 | CPE
400 |
401 |
402 |
403 | {this.state.cpe.map((row, i) => (
404 |
410 | {row}
411 |
412 | ))}
413 |
414 |
415 |
416 |
417 | :not(style)': { m: 1 },
421 | marginTop: '15px',
422 | }}
423 | noValidate
424 | autoComplete="off"
425 | >
426 | option.vendor_name)}
431 | sx={{ width: 300 }}
432 | onChange={this.handleVendorChange}
433 | renderInput={(params) => }
440 | />
441 | option.name)}
447 | sx={{ width: 300 }}
448 | onChange={this.handleProductChange}
449 | renderInput={(params) => }
456 | />
457 |
464 |
471 |
472 |
473 |
474 |
475 |
476 |
477 |
478 |
479 |
482 |
483 |
484 |
485 |
486 |
487 |
488 | );
489 | }
490 | }
491 |
492 | // Host Tags Get From Host DB Component Mount // Hardcoding for now
493 | const hostTags = [
494 | { title: 'Compliance Required', year: 1994 },
495 | { title: 'Critical Asset', year: 1972 },
496 | { title: 'Windows', year: 1974 },
497 | { title: 'Linux', year: 2008 },
498 | { title: 'NERC-SIP', year: 1957 },
499 | { title: 'PCI', year: 1993 },
500 | ];
501 |
502 |
503 |
504 |
505 | export default NewHost;
506 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # 2.1.0
2 |
3 | - Migrate to `css-minifier-webpack-plugin`
4 |
5 | # 2.0.1
6 |
7 | ## Fixes
8 |
9 | - Fix broken css linking in production build
10 |
11 | # 2.0.0
12 |
13 | ## Breaking Changes
14 |
15 | - drop redux
16 | - remove counter example app
17 | - simplify directory structure
18 | - move `dll` dir to `.erb` dir
19 | - fix icon/font import paths
20 | - migrate to `react-refresh` from `react-hot-loader`
21 | - migrate to webpack@5
22 | - migrate to electron@11
23 | - remove e2e tests and testcafe integration
24 | - rename `app` dir to more conventional `src` dir
25 | - rename `resources` dir to `assets`
26 | - simplify npm scripts
27 | - drop stylelint
28 | - simplify styling of boilerplate app
29 | - remove `START_HOT` env variable
30 | - notarize support
31 | - landing page boilerplate
32 | - docs updates
33 | - restore removed debugging support
34 |
35 | # 1.4.0
36 |
37 | - Migrate to `eslint-config-erb@2`
38 | - Rename `dev` npm script to `start`
39 | - GitHub Actions: only publish GitHub releases when on master branch
40 |
41 | # 1.3.1
42 |
43 | - Fix sass building bug ([#2540](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/2540))
44 | - Fix CI bug related to E2E tests and network timeouts
45 | - Move automated dependency PRs to `next` ([#2554](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/2554))
46 | - Bump dependencies to patch semver
47 |
48 | # 1.3.0
49 |
50 | - Fixes E2E tests ([#2516](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/2516))
51 | - Fixes preload entrypoint ([#2503](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/2503))
52 | - Downgrade to `electron@8`
53 | - Bump dependencies to latest semver
54 |
55 | # 1.2.0
56 |
57 | - Migrate to redux toolkit
58 | - Lazy load routes with react suspense
59 | - Drop support for azure-pipelines and use only github actions
60 | - Bump all deps to latest semver
61 | - Remove `test-e2e` script from tests (blocked on release of https://github.com/DevExpress/testcafe-browser-provider-electron/pull/65)
62 | - Swap `typed-css-modules-webpack-plugin` for `typings-for-css-modules-loader`
63 | - Use latest version of `eslint-config-erb`
64 | - Remove unnecessary file extensions from ts exclude
65 | - Add experimental support for vscode debugging
66 | - Revert https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/2365 as default for users, provide as opt in option
67 |
68 | # 1.1.0
69 |
70 | - Fix #2402
71 | - Simplify configs (https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/2406)
72 |
73 | # 1.0.0
74 |
75 | - Migrate to TypeScript from Flow ([#2363](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/2363))
76 | - Use browserslist for `@babel/preset-env` targets ([#2368](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/2368))
77 | - Use preload script, disable `nodeIntegration` in renderer process for [improved security](https://www.electronjs.org/docs/tutorial/security#2-do-not-enable-nodejs-integration-for-remote-content) ([#2365](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/2365))
78 | - Add support for azure pipelines ([#2369](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/2369))
79 | - Disable sourcemaps in production
80 |
81 | # 0.18.1 (2019.12.12)
82 |
83 | - Fix HMR env bug ([#2343](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/2343))
84 | - Bump all deps to latest semver
85 | - Bump to `electron@7`
86 |
87 | # 0.18.0 (2019.11.19)
88 |
89 | - Bump electron to `electron@6` (`electron@7` introduces breaking changes to testcafe end to end tests)
90 | - Revert back to [two `package.json` structure](https://www.electron.build/tutorials/two-package-structure)
91 | - Bump all deps to latest semver
92 |
93 | # 0.17.1 (2018.11.20)
94 |
95 | - Fix `yarn test-e2e` and testcafe for single package.json structure
96 | - Fixes incorrect path in `yarn start` script
97 | - Bumped deps
98 | - Bump g++ in travis
99 | - Change clone arguments to clone only master
100 | - Change babel config to target current electron version
101 |
102 | For full change list, see https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/2021
103 |
104 | # 0.17.0 (2018.10.30)
105 |
106 | - upgraded to `babel@7` (thanks to @vikr01 🎉🎉🎉)
107 | - migrated from [two `package.json` structure](https://www.electron.build/tutorials/two-package-structure) (thanks to @HyperSprite!)
108 | - initial auto update support (experimental)
109 | - migrate from greenkeeper to [renovate](https://renovatebot.com)
110 | - added issue template
111 | - use `babel-preset-env` to target current electron version
112 | - add [opencollective](https://opencollective.com/electron-react-boilerplate-594) banner message display in postinstall script (help support ERB 🙏)
113 | - fix failing ci issues
114 |
115 | # 0.16.0 (2018.10.3)
116 |
117 | - removed unused dependencies
118 | - migrate from `react-redux-router` to `connect-react-router`
119 | - move webpack configs to `./webpack` dir
120 | - use `g++` on travis when testing linux
121 | - migrate from `spectron` to `testcafe` for e2e tests
122 | - add linting support for config styles
123 | - changed stylelint config
124 | - temporarily disabled flow in appveyor to make ci pass
125 | - added necessary infra to publish releases from ci
126 |
127 | # 0.15.0 (2018.8.25)
128 |
129 | - Performance: cache webpack uglify results
130 | - Feature: add start minimized feature
131 | - Feature: lint and fix styles with prettier and stylelint
132 | - Feature: add greenkeeper support
133 |
134 | # 0.14.0 (2018.5.24)
135 |
136 | - Improved CI timings
137 | - Migrated README commands to yarn from npm
138 | - Improved vscode config
139 | - Updated all dependencies to latest semver
140 | - Fix `electron-rebuild` script bug
141 | - Migrated to `mini-css-extract-plugin` from `extract-text-plugin`
142 | - Added `optimize-css-assets-webpack-plugin`
143 | - Run `prettier` on json, css, scss, and more filetypes
144 |
145 | # 0.13.3 (2018.5.24)
146 |
147 | - Add git precommit hook, when git commit will use `prettier` to format git add code
148 | - Add format code function in `lint-fix` npm script which can use `prettier` to format project js code
149 |
150 | # 0.13.2 (2018.1.31)
151 |
152 | - Hot Module Reload (HMR) fixes
153 | - Bumped all dependencies to latest semver
154 | - Prevent error propagation of `CheckNativeDeps` script
155 |
156 | # 0.13.1 (2018.1.13)
157 |
158 | - Hot Module Reload (HMR) fixes
159 | - Bumped all dependencies to latest semver
160 | - Fixed electron-rebuild script
161 | - Fixed tests scripts to run on all platforms
162 | - Skip redux logs in console in test ENV
163 |
164 | # 0.13.0 (2018.1.6)
165 |
166 | #### Additions
167 |
168 | - Add native dependencies check on postinstall
169 | - Updated all dependencies to latest semver
170 |
171 | # 0.12.0 (2017.7.8)
172 |
173 | #### Misc
174 |
175 | - Removed `babel-polyfill`
176 | - Renamed and alphabetized npm scripts
177 |
178 | #### Breaking
179 |
180 | - Changed node dev `__dirname` and `__filename` to node built in fn's (https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/1035)
181 | - Renamed `src/bundle.js` to `src/renderer.prod.js` for consistency
182 | - Renamed `dll/vendor.js` to `dll/renderer.dev.dll.js` for consistency
183 |
184 | #### Additions
185 |
186 | - Enable node_modules cache on CI
187 |
188 | # 0.11.2 (2017.5.1)
189 |
190 | Yay! Another patch release. This release mostly includes refactorings and router bug fixes. Huge thanks to @anthonyraymond!
191 |
192 | ⚠️ Windows electron builds are failing because of [this issue](https://github.com/electron/electron/issues/9321). This is not an issue with the boilerplate ⚠️
193 |
194 | #### Breaking
195 |
196 | - **Renamed `./src/main.development.js` => `./src/main.{dev,prod}.js`:** [#963](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/963)
197 |
198 | #### Fixes
199 |
200 | - **Fixed reloading when not on `/` path:** [#958](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/958) [#949](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/949)
201 |
202 | #### Additions
203 |
204 | - **Added support for stylefmt:** [#960](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/960)
205 |
206 | # 0.11.1 (2017.4.23)
207 |
208 | You can now debug the production build with devtools like so:
209 |
210 | ```
211 | DEBUG_PROD=true npm run package
212 | ```
213 |
214 | 🎉🎉🎉
215 |
216 | #### Additions
217 |
218 | - **Added support for debugging production build:** [#fab245a](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/941/commits/fab245a077d02a09630f74270806c0c534a4ff95)
219 |
220 | #### Bug Fixes
221 |
222 | - **Fixed bug related to importing native dependencies:** [#933](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/933)
223 |
224 | #### Improvements
225 |
226 | - **Updated all deps to latest semver**
227 |
228 | # 0.11.0 (2017.4.19)
229 |
230 | Here's the most notable changes since `v0.10.0`. Its been about a year since a release has been pushed. Expect a new release to be published every 3-4 weeks.
231 |
232 | #### Breaking Changes
233 |
234 | - **Dropped support for node < 6**
235 | - **Refactored webpack config files**
236 | - **Migrate to two-package.json project structure**
237 | - **Updated all devDeps to latest semver**
238 | - **Migrated to Jest:** [#768](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/768)
239 | - **Migrated to `react-router@4`**
240 | - **Migrated to `electron-builder@4`**
241 | - **Migrated to `webpack@2`**
242 | - **Migrated to `react-hot-loader@3`**
243 | - **Changed default live reload server PORT to `1212` from `3000`**
244 |
245 | #### Additions
246 |
247 | - **Added support for Yarn:** [#451](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/451)
248 | - **Added support for Flow:** [#425](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/425)
249 | - **Added support for stylelint:** [#911](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/911)
250 | - **Added support for electron-builder:** [#876](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/876)
251 | - **Added optional support for SASS:** [#880](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/880)
252 | - **Added support for eslint-plugin-flowtype:** [#911](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/911)
253 | - **Added support for appveyor:** [#280](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/280)
254 | - **Added support for webpack dlls:** [#860](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/860)
255 | - **Route based code splitting:** [#884](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/884)
256 | - **Added support for Webpack Bundle Analyzer:** [#922](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/922)
257 |
258 | #### Improvements
259 |
260 | - **Parallelize renderer and main build processes when running `npm run build`**
261 | - **Dynamically generate electron app menu**
262 | - **Improved vscode integration:** [#856](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/856)
263 |
264 | #### Bug Fixes
265 |
266 | - **Fixed hot module replacement race condition bug:** [#917](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/917) [#920](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/920)
267 |
268 | # 0.10.0 (2016.4.18)
269 |
270 | #### Improvements
271 |
272 | - **Use Babel in main process with Webpack build:** [#201](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/201)
273 | - **Change targets to built-in support by webpack:** [#197](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/197)
274 | - **use es2015 syntax for webpack configs:** [#195](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/195)
275 | - **Open application when webcontent is loaded:** [#192](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/192)
276 | - **Upgraded dependencies**
277 |
278 | #### Bug fixed
279 |
280 | - **Fix `npm list electron-prebuilt` in package.js:** [#188](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/188)
281 |
282 | # 0.9.0 (2016.3.23)
283 |
284 | #### Improvements
285 |
286 | - **Added [redux-logger](https://github.com/fcomb/redux-logger)**
287 | - **Upgraded [react-router-redux](https://github.com/reactjs/react-router-redux) to v4**
288 | - **Upgraded dependencies**
289 | - **Added `npm run dev` command:** [#162](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/162)
290 | - **electron to v0.37.2**
291 |
292 | #### Breaking Changes
293 |
294 | - **css module as default:** [#154](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/154).
295 | - **set default NODE_ENV to production:** [#140](https://github.com/electron-react-boilerplate/electron-react-boilerplate/issues/140)
296 |
297 | # 0.8.0 (2016.2.17)
298 |
299 | #### Bug fixed
300 |
301 | - **Fix lint errors**
302 | - **Fix Webpack publicPath for production builds**: [#119](https://github.com/electron-react-boilerplate/electron-react-boilerplate/issues/119).
303 | - **package script now chooses correct OS icon extension**
304 |
305 | #### Improvements
306 |
307 | - **babel 6**
308 | - **Upgrade Dependencies**
309 | - **Enable CSS source maps**
310 | - **Add json-loader**: [#128](https://github.com/electron-react-boilerplate/electron-react-boilerplate/issues/128).
311 | - **react-router 2.0 and react-router-redux 3.0**
312 |
313 | # 0.7.1 (2015.12.27)
314 |
315 | #### Bug fixed
316 |
317 | - **Fixed npm script on windows 10:** [#103](https://github.com/electron-react-boilerplate/electron-react-boilerplate/issues/103).
318 | - **history and react-router version bump**: [#109](https://github.com/electron-react-boilerplate/electron-react-boilerplate/issues/109), [#110](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/110).
319 |
320 | #### Improvements
321 |
322 | - **electron 0.36**
323 |
324 | # 0.7.0 (2015.12.16)
325 |
326 | #### Bug fixed
327 |
328 | - **Fixed process.env.NODE_ENV variable in webpack:** [#74](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/74).
329 | - **add missing object-assign**: [#76](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/76).
330 | - **packaging in npm@3:** [#77](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/77).
331 | - **compatibility in windows:** [#100](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/100).
332 | - **disable chrome debugger in production env:** [#102](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/102).
333 |
334 | #### Improvements
335 |
336 | - **redux**
337 | - **css-modules**
338 | - **upgrade to react-router 1.x**
339 | - **unit tests**
340 | - **e2e tests**
341 | - **travis-ci**
342 | - **upgrade to electron 0.35.x**
343 | - **use es2015**
344 | - **check dev engine for node and npm**
345 |
346 | # 0.6.5 (2015.11.7)
347 |
348 | #### Improvements
349 |
350 | - **Bump style-loader to 0.13**
351 | - **Bump css-loader to 0.22**
352 |
353 | # 0.6.4 (2015.10.27)
354 |
355 | #### Improvements
356 |
357 | - **Bump electron-debug to 0.3**
358 |
359 | # 0.6.3 (2015.10.26)
360 |
361 | #### Improvements
362 |
363 | - **Initialize ExtractTextPlugin once:** [#64](https://github.com/electron-react-boilerplate/electron-react-boilerplate/issues/64).
364 |
365 | # 0.6.2 (2015.10.18)
366 |
367 | #### Bug fixed
368 |
369 | - **Babel plugins production env not be set properly:** [#57](https://github.com/electron-react-boilerplate/electron-react-boilerplate/issues/57).
370 |
371 | # 0.6.1 (2015.10.17)
372 |
373 | #### Improvements
374 |
375 | - **Bump electron to v0.34.0**
376 |
377 | # 0.6.0 (2015.10.16)
378 |
379 | #### Breaking Changes
380 |
381 | - **From react-hot-loader to react-transform**
382 |
383 | # 0.5.2 (2015.10.15)
384 |
385 | #### Improvements
386 |
387 | - **Run tests with babel-register:** [#29](https://github.com/electron-react-boilerplate/electron-react-boilerplate/issues/29).
388 |
389 | # 0.5.1 (2015.10.12)
390 |
391 | #### Bug fixed
392 |
393 | - **Fix #51:** use `path.join(__dirname` instead of `./`.
394 |
395 | # 0.5.0 (2015.10.11)
396 |
397 | #### Improvements
398 |
399 | - **Simplify webpack config** see [#50](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/50).
400 |
401 | #### Breaking Changes
402 |
403 | - **webpack configs**
404 | - **port changed:** changed default port from 2992 to 3000.
405 | - **npm scripts:** remove `start-dev` and `dev-server`. rename `hot-dev-server` to `hot-server`.
406 |
407 | # 0.4.3 (2015.9.22)
408 |
409 | #### Bug fixed
410 |
411 | - **Fix #45 zeromq crash:** bump version of `electron-prebuilt`.
412 |
413 | # 0.4.2 (2015.9.15)
414 |
415 | #### Bug fixed
416 |
417 | - **run start-hot breaks chrome refresh(CTRL+R) (#42)**: bump `electron-debug` to `0.2.1`
418 |
419 | # 0.4.1 (2015.9.11)
420 |
421 | #### Improvements
422 |
423 | - **use electron-prebuilt version for packaging (#33)**
424 |
425 | # 0.4.0 (2015.9.5)
426 |
427 | #### Improvements
428 |
429 | - **update dependencies**
430 |
431 | # 0.3.0 (2015.8.31)
432 |
433 | #### Improvements
434 |
435 | - **eslint-config-airbnb**
436 |
437 | # 0.2.10 (2015.8.27)
438 |
439 | #### Features
440 |
441 | - **custom placeholder icon**
442 |
443 | #### Improvements
444 |
445 | - **electron-renderer as target:** via [webpack-target-electron-renderer](https://github.com/chentsulin/webpack-target-electron-renderer)
446 |
447 | # 0.2.9 (2015.8.18)
448 |
449 | #### Bug fixed
450 |
451 | - **Fix hot-reload**
452 |
453 | # 0.2.8 (2015.8.13)
454 |
455 | #### Improvements
456 |
457 | - **bump electron-debug**
458 | - **babelrc**
459 | - **organize webpack scripts**
460 |
461 | # 0.2.7 (2015.7.9)
462 |
463 | #### Bug fixed
464 |
465 | - **defaultProps:** fix typos.
466 |
467 | # 0.2.6 (2015.7.3)
468 |
469 | #### Features
470 |
471 | - **menu**
472 |
473 | #### Bug fixed
474 |
475 | - **package.js:** include webpack build.
476 |
477 | # 0.2.5 (2015.7.1)
478 |
479 | #### Features
480 |
481 | - **NPM Script:** support multi-platform
482 | - **package:** `--all` option
483 |
484 | # 0.2.4 (2015.6.9)
485 |
486 | #### Bug fixed
487 |
488 | - **Eslint:** typo, [#17](https://github.com/electron-react-boilerplate/electron-react-boilerplate/issues/17) and improve `.eslintrc`
489 |
490 | # 0.2.3 (2015.6.3)
491 |
492 | #### Features
493 |
494 | - **Package Version:** use latest release electron version as default
495 | - **Ignore Large peerDependencies**
496 |
497 | #### Bug fixed
498 |
499 | - **Npm Script:** typo, [#6](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/6)
500 | - **Missing css:** [#7](https://github.com/electron-react-boilerplate/electron-react-boilerplate/pull/7)
501 |
502 | # 0.2.2 (2015.6.2)
503 |
504 | #### Features
505 |
506 | - **electron-debug**
507 |
508 | #### Bug fixed
509 |
510 | - **Webpack:** add `.json` and `.node` to extensions for imitating node require.
511 | - **Webpack:** set `node_modules` to externals for native module support.
512 |
513 | # 0.2.1 (2015.5.30)
514 |
515 | #### Bug fixed
516 |
517 | - **Webpack:** #1, change build target to `atom`.
518 |
519 | # 0.2.0 (2015.5.30)
520 |
521 | #### Features
522 |
523 | - **Ignore:** `test`, `tools`, `release` folder and devDependencies in `package.json`.
524 | - **Support asar**
525 | - **Support icon**
526 |
527 | # 0.1.0 (2015.5.27)
528 |
529 | #### Features
530 |
531 | - **Webpack:** babel, react-hot, ...
532 | - **Flux:** actions, api, components, containers, stores..
533 | - **Package:** darwin (osx), linux and win32 (windows) platform.
534 |
--------------------------------------------------------------------------------