diff --git a/.github/workflows/build-deploy-docs.yml b/.github/workflows/build-deploy-docs.yml new file mode 100644 index 0000000..ad76719 --- /dev/null +++ b/.github/workflows/build-deploy-docs.yml @@ -0,0 +1,35 @@ +name: "DOC - Build and deploy - Beta" +on: + push: + branches: + - main + - development + - docs + paths: + - "docs/**" + +concurrency: + group: ${{ github.ref }}-${{ github.workflow }} + cancel-in-progress: true + +jobs: + + deploy: + runs-on: ubuntu-latest + permissions: + contents: write + if: github.repository == 'oxsecurity/codetotal' + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + - uses: actions/setup-python@v4.5.0 + with: + python-version: 3.10.4 + - run: pip install --upgrade markdown==3.3.7 mkdocs-material pymdown-extensions==9.11 mkdocs-glightbox==0.3.2 mdx_truly_sane_lists + - run: | + git config --global user.name megalinter-bot + git config --global user.email nicolas.vuillamy@ox.security + - run: mkdocs gh-deploy --force + + \ No newline at end of file diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index babc733..7ede6cf 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -26,7 +26,7 @@ jobs: # Runs a single command using the runners shell - name: Install deps - run: npm i + run: npm ci - name: Lint run: npm run lint diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..3a164dc --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,9 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [Unreleased] (beta, main branch content) + +Initial version \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..41e391a --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,417 @@ +- [Development Mode](#development-mode) +- [Available Scripts](#available-scripts) +- [Config](#config) +- [Building For Production](#building-for-production) +- [Debugging in VSCode](#debugging-in-vscode) +- [Messages from MegaLinter server](#messages-from-megalinter-server) + - [Start Megalinter analysis](#start-megalinter-analysis) + - [Start Linter analysis](#start-linter-analysis) + - [Complete Linter analysis](#complete-linter-analysis) + - [Complete Megalinter analysis](#complete-megalinter-analysis) + - [MegaLinter server error](#megalinter-server-error) + +## Development Mode + +- Clone this repo +- Run `npm i` to install dependencies +- Start megalinter server `npm run start:megalinter` +- Run `npm start` +- Open [`codetotal app`](http://localhost:3000) + +## Available Scripts + +- `npm start` start all projects in development mode +- `npm run lint` lint all projects +- `npm run build:be` build the backend (used by `launch.json` file for debugging) +- `npm run start:fe` start the FE in development mode +- `npm test` run all unit tests + +## Config + +Add a `.env` file in the root of the project. +Only variables starting with the `CODETOTAL_` prefix will be injected into the frontend bundle. + +```ini +# MEGALINTER +MEGALINTER_ANALYSIS_URL=http://127.0.0.1:8000/analysis +MEGALINTER_UPLOAD_URL=http://127.0.0.1:8000/upload-file +MEGALINTER_REDIS_URL=redis://127.0.0.1:6379 +MEGALINTER_REDIS_CHANNEL=megalinter:pubsub: + +# BACKEND +CODETOTAL_HTTP_PORT=8081 +CODETOTAL_HTTP_HOST=127.0.0.1 +CODETOTAL_WS_PORT=8080 +CODETOTAL_WS_HOST=127.0.0.1 +DEBUG_MODULES=actions,megalinter,stores,transport + +# FRONTEND +CODETOTAL_UPLOAD_FILE_LIMIT_BYTES=10000000 +``` + +## Building For Production + +- Config files must be set before the build (see `Config` section) +- Run `npm run build` at the root folder +- This will create a `dist` folder with the backend code +- The frontend code will be under `dist/public` +- Run using `npm run production` (equivilant to `node dist/index.js`) + +## Debugging in VSCode + +Add a `launch.json` file under the `.vscode` folder with the following content: + +```typescript +{ + "version": "0.2.0", + "configurations": [ + { + "type": "node", + "request": "launch", + "name": "Build Project", + "program": "${workspaceFolder}/packages/backend/dist/index.js", + "preLaunchTask": "npm: build:be", + "sourceMaps": true, + "smartStep": true, + "internalConsoleOptions": "openOnSessionStart", + "outFiles": ["${workspaceFolder}/packages/backend/dist/**/*.js"] + } + ] +} +``` + +## Messages from MegaLinter server + +Event-based management of MegaLinter Server can send the following list of messages into Redis PUBSUB channel built the following way: **megalinter:pubsub:REQUEST_ID** + +Example: `megalinter:pubsub:RQ_cbdd1d82-1e7b-11ee-9258-0242ac120004` + +### Start Megalinter analysis + +This message is sent once by analysis, when a **MegaLinter instance has identified the linters to run** and is about to start them. + +Example of **megalinterStart** messageType: + +```json +{ + "messageType": "megalinterStart", + "megaLinterStatus": "created", + "linters": [ + { + "descriptorId": "BASH", + "linterId": "bash-exec", + "linterKey": "BASH_EXEC", + "linterVersion": "5.2.15", + "linterCliLintMode": "file", + "requestId": "RQ_cbdd1d82-1e7b-11ee-9258-0242ac120004", + "docUrl": "https://megalinter.io/alpha/descriptors/bash_bash_exec", + "isFormatter": false, + "isSBOM": false, + "filesNumber": 1 + }, + { + "descriptorId": "BASH", + "linterId": "shellcheck", + "linterKey": "BASH_SHELLCHECK", + "linterVersion": "0.9.0", + "linterCliLintMode": "list_of_files", + "requestId": "RQ_cbdd1d82-1e7b-11ee-9258-0242ac120004", + "docUrl": "https://megalinter.io/alpha/descriptors/bash_shellcheck", + "isFormatter": false, + "isSBOM": false, + "filesNumber": 1 + }, + { + "descriptorId": "BASH", + "linterId": "shfmt", + "linterKey": "BASH_SHFMT", + "linterVersion": "ERROR", + "linterCliLintMode": "list_of_files", + "requestId": "RQ_cbdd1d82-1e7b-11ee-9258-0242ac120004", + "docUrl": "https://megalinter.io/alpha/descriptors/bash_shfmt", + "isFormatter": true, + "isSBOM": false, + "filesNumber": 1 + }, + { + "descriptorId": "COPYPASTE", + "linterId": "jscpd", + "linterKey": "COPYPASTE_JSCPD", + "linterVersion": "ERROR", + "linterCliLintMode": "project", + "requestId": "RQ_cbdd1d82-1e7b-11ee-9258-0242ac120004", + "docUrl": "https://megalinter.io/alpha/descriptors/copypaste_jscpd", + "isFormatter": false, + "isSBOM": false + }, + { + "descriptorId": "REPOSITORY", + "linterId": "checkov", + "linterKey": "REPOSITORY_CHECKOV", + "linterVersion": "3.11", + "linterCliLintMode": "project", + "requestId": "RQ_cbdd1d82-1e7b-11ee-9258-0242ac120004", + "docUrl": "https://megalinter.io/alpha/descriptors/repository_checkov", + "isFormatter": false, + "isSBOM": false + }, + { + "descriptorId": "REPOSITORY", + "linterId": "devskim", + "linterKey": "REPOSITORY_DEVSKIM", + "linterVersion": "1.0.11", + "linterCliLintMode": "project", + "requestId": "RQ_cbdd1d82-1e7b-11ee-9258-0242ac120004", + "docUrl": "https://megalinter.io/alpha/descriptors/repository_devskim", + "isFormatter": false, + "isSBOM": false + }, + { + "descriptorId": "REPOSITORY", + "linterId": "dustilock", + "linterKey": "REPOSITORY_DUSTILOCK", + "linterVersion": "1.2.0", + "linterCliLintMode": "project", + "requestId": "RQ_cbdd1d82-1e7b-11ee-9258-0242ac120004", + "docUrl": "https://megalinter.io/alpha/descriptors/repository_dustilock", + "isFormatter": false, + "isSBOM": false + }, + { + "descriptorId": "REPOSITORY", + "linterId": "git_diff", + "linterKey": "REPOSITORY_GIT_DIFF", + "linterVersion": "2.38.5", + "linterCliLintMode": "project", + "requestId": "RQ_cbdd1d82-1e7b-11ee-9258-0242ac120004", + "docUrl": "https://megalinter.io/alpha/descriptors/repository_git_diff", + "isFormatter": false, + "isSBOM": false + }, + { + "descriptorId": "REPOSITORY", + "linterId": "gitleaks", + "linterKey": "REPOSITORY_GITLEAKS", + "linterVersion": "8.17.0", + "linterCliLintMode": "project", + "requestId": "RQ_cbdd1d82-1e7b-11ee-9258-0242ac120004", + "docUrl": "https://megalinter.io/alpha/descriptors/repository_gitleaks", + "isFormatter": false, + "isSBOM": false + }, + { + "descriptorId": "REPOSITORY", + "linterId": "kics", + "linterKey": "REPOSITORY_KICS", + "linterVersion": "1.7.3", + "linterCliLintMode": "project", + "requestId": "RQ_cbdd1d82-1e7b-11ee-9258-0242ac120004", + "docUrl": "https://megalinter.io/alpha/descriptors/repository_kics", + "isFormatter": false, + "isSBOM": false + }, + { + "descriptorId": "REPOSITORY", + "linterId": "secretlint", + "linterKey": "REPOSITORY_SECRETLINT", + "linterVersion": "7.0.3", + "linterCliLintMode": "project", + "requestId": "RQ_cbdd1d82-1e7b-11ee-9258-0242ac120004", + "docUrl": "https://megalinter.io/alpha/descriptors/repository_secretlint", + "isFormatter": false, + "isSBOM": false + }, + { + "descriptorId": "REPOSITORY", + "linterId": "semgrep", + "linterKey": "REPOSITORY_SEMGREP", + "linterVersion": "1.31.2", + "linterCliLintMode": "project", + "requestId": "RQ_cbdd1d82-1e7b-11ee-9258-0242ac120004", + "docUrl": "https://megalinter.io/alpha/descriptors/repository_semgrep", + "isFormatter": false, + "isSBOM": false + }, + { + "descriptorId": "REPOSITORY", + "linterId": "trivy", + "linterKey": "REPOSITORY_TRIVY", + "linterVersion": "0.43.1", + "linterCliLintMode": "project", + "requestId": "RQ_cbdd1d82-1e7b-11ee-9258-0242ac120004", + "docUrl": "https://megalinter.io/alpha/descriptors/repository_trivy", + "isFormatter": false, + "isSBOM": false + }, + { + "descriptorId": "SPELL", + "linterId": "cspell", + "linterKey": "SPELL_CSPELL", + "linterVersion": "ERROR", + "linterCliLintMode": "list_of_files", + "requestId": "RQ_cbdd1d82-1e7b-11ee-9258-0242ac120004", + "docUrl": "https://megalinter.io/alpha/descriptors/spell_cspell", + "isFormatter": false, + "filesNumber": 1, + "isSBOM": false + } + ], + "requestId": "RQ_cbdd1d82-1e7b-11ee-9258-0242ac120004" +} +``` + +### Start Linter analysis + +This message is sent once by linter run, it indicates that **a single linter has started running**. + +Example of **linterStart** messageType with `linterCliLintMode=project`: + +```json +{ + "messageType": "linterStart", + "linterStatus": "started", + "descriptorId": "REPOSITORY", + "linterId": "trivy", + "linterKey": "REPOSITORY_TRIVY", + "linterVersion": "0.43.1", + "linterCliLintMode": "project", + "requestId": "RQ_cbdd1d82-1e7b-11ee-9258-0242ac120004", + "docUrl": "https://megalinter.io/alpha/descriptors/repository_trivy", + "isFormatter": false, + "isSBOM": false +} +``` + +Example of **linterStart** messageType with `linterCliLintMode=list_of_files` (with **filesNumber** additional property): + +```json +{ + "messageType": "linterStart", + "linterStatus": "started", + "descriptorId": "BASH", + "linterId": "shellcheck", + "linterKey": "BASH_SHELLCHECK", + "linterVersion": "0.9.0", + "linterCliLintMode": "list_of_files", + "requestId": "RQ_cbdd1d82-1e7b-11ee-9258-0242ac120004", + "docUrl": "https://megalinter.io/alpha/descriptors/bash_shellcheck", + "isFormatter": false, + "isSBOM": false, + "filesNumber": 1 +} +``` + +### Complete Linter analysis + +This message is sent once by linter run, it indicates that **a single linter has been completed**. + +If SARIF is available, it will be located in `outputSarif` property, otherwise results can be found in `outputText` and or `outputJson`. + +Example of **linterComplete** messageType: + +```json +{ + "messageType": "linterComplete", + "linterStatus": "success", + "linterErrorNumber": 0, + "linterStatusMessage": "No errors were found in the linting process", + "linterElapsedTime": 11.16, + "linterCliCommand": [ + "trivy", + "fs", + "--scanners", + "vuln,config", + "--exit-code", + "1", + "--format", + "sarif", + "-o", + "/tmp/ct-megalinter-xmv82bvyv/megalinter-reports/sarif/REPOSITORY_TRIVY.sarif", + "." + ], + "descriptorId": "REPOSITORY", + "linterId": "trivy", + "linterKey": "REPOSITORY_TRIVY", + "linterVersion": "0.43.1", + "linterCliLintMode": "project", + "requestId": "RQ_cbdd1d82-1e7b-11ee-9258-0242ac120004", + "docUrl": "https://megalinter.io/alpha/descriptors/repository_trivy", + "isFormatter": false, + "isSBOM": false, + "outputSarif": { + "$schema": "https://json.schemastore.org/sarif-2.1.0.json", + "runs": [ + { + "columnKind": "utf16CodeUnits", + "originalUriBaseIds": { + "ROOTPATH": { + "uri": "file:///" + } + }, + "properties": { + "megalinter": { + "docUrl": "https://megalinter.io/alpha/descriptors/repository_trivy", + "linterKey": "REPOSITORY_TRIVY", + "linterVersion": "0.43.1" + } + }, + "results": [], + "tool": { + "driver": { + "fullName": "Trivy Vulnerability Scanner", + "informationUri": "https://github.com/aquasecurity/trivy", + "name": "Trivy (MegaLinter REPOSITORY_TRIVY)", + "rules": [], + "version": "0.43.1" + } + } + } + ], + "version": "2.1.0" + } +} +``` + +### Complete Megalinter analysis + +This message is sent once by analysis, when a **MegaLinter analysis is completed**. + +CodeTotal stops listening to the requestId pubsub channel once this message is received, as no new message will be sent through this channel. + +Example of **megalinterComplete** messageType: + +```json +{ + "messageType": "megalinterComplete", + "megaLinterStatus": "completed", + "requestId": "RQ_cbdd1d82-1e7b-11ee-9258-0242ac120004" +} +``` + +### MegaLinter server error + +In some cases, it is not possible for MegaLinter to start an analysis because there has been an error during initialization. + +In that case, CodeTotal stops listening to the pubsub channel, as no more messages will be sent. + +List of errors: + +- `missingAnalysisType`: Missing type (snippet, file or repository) +- `gitCloneError`: Unable to clone the repository (probably not existing or not reachable) +- `uploadedFileNotFound`: Unable to find file(s) that were supposed to be uploaded by a previous HTTP call to `/upload-file` +- `snippetGuessError`: Unable to automatically detect the language of a code snippet +- `snippetBuildError`: Unable to find a file extension for the guessed snipper language + +Example of **serverError** messageType + +```json +{ + "messageType": "serverError", + "message": "Unable to clone repository\nCmd('git') failed due to: exit code(128)\n cmdline: git clone -v -- https://github.com/nvuillam/node-sarif-builder2 /tmp/ct-megalinter-x0afpmcmb\n stderr: 'Cloning into '/tmp/ct-megalinter-x0afpmcmb'...\nfatal: could not read Username for 'https://github.com': No such device or address\n'", + "errorCode": "gitCloneError", + "errorDetails": { + "error": "Cmd('git') failed due to: exit code(128)\n cmdline: git clone -v -- https://github.com/nvuillam/node-sarif-builder2 /tmp/ct-megalinter-x0afpmcmb\n stderr: 'Cloning into '/tmp/ct-megalinter-x0afpmcmb'...\nfatal: could not read Username for 'https://github.com': No such device or address\n'" + }, + "requestId": "RQ_e630c962-1e7c-11ee-9258-0242ac120004" +} +``` diff --git a/README.md b/README.md index 631b9d3..746a29b 100644 --- a/README.md +++ b/README.md @@ -1,422 +1,9 @@ # CodeTotal -![Alt text](docs/screen.jpg "A screenshot from the app") +**CodeTotal** analyzes any **snippet**, **file**, or **repository** to detect possible **security flaws** such as **secret in code**, **open source vulnerability**, **code security**, **vulnerability**, insecure **infrastructure as code**, and potential **legal issues** with open source licenses. -- [CodeTotal](#codetotal) - - [Development Mode](#development-mode) - - [Available Scripts](#available-scripts) - - [Config](#config) - - [Building For Production](#building-for-production) - - [Debugging in VSCode](#debugging-in-vscode) - - [Messages from MegaLinter server](#messages-from-megalinter-server) - - [Start Megalinter analysis](#start-megalinter-analysis) - - [Start Linter analysis](#start-linter-analysis) - - [Complete Linter analysis](#complete-linter-analysis) - - [Complete Megalinter analysis](#complete-megalinter-analysis) - - [MegaLinter server error](#megalinter-server-error) +Brought to you by [OX Security](https://ox.security), powered by [MegaLinter](https://megalinter.io) -## Development Mode +[![CodeTotal Screenshot](docs/assets/images/screen.jpg "A screenshot from the app")](https://codetotal.io) -- Clone this repo -- Run `npm i` to install dependencies -- Start megalinter server `npm run start:megalinter` -- Run `npm start` -- Open [`codetotal app`](http://localhost:3000) - -## Available Scripts - -- `npm start` start all projects in development mode -- `npm run lint` lint all projects -- `npm run build:be` build the backend (used by `launch.json` file for debugging) -- `npm run start:fe` start the FE in development mode -- `npm test` run all unit tests - -## Config - -Add a `.env` file in the root of the project. -Only variables starting with the `CODETOTAL_` prefix will be injected into the frontend bundle. - -``` -# MEGALINTER -MEGALINTER_ANALYSIS_URL=http://127.0.0.1:8000/analysis -MEGALINTER_UPLOAD_URL=http://127.0.0.1:8000/upload-file -MEGALINTER_REDIS_URL=redis://127.0.0.1:6379 -MEGALINTER_REDIS_CHANNEL=megalinter:pubsub: - -# BACKEND -CODETOTAL_HTTP_PORT=8081 -CODETOTAL_HTTP_HOST=127.0.0.1 -CODETOTAL_WS_PORT=8080 -CODETOTAL_WS_HOST=127.0.0.1 -DEBUG_MODULES=actions,megalinter,stores,transport - -# FRONTEND -CODETOTAL_UPLOAD_FILE_LIMIT_BYTES=10000000 -``` - -## Building For Production - -- Config files must be set before the build (see `Config` section) -- Run `npm run build` at the root folder -- This will create a `dist` folder with the backend code -- The frontend code will be under `dist/public` -- Run using `npm run production` (equivilant to `node dist/index.js`) - -## Debugging in VSCode - -Add a `launch.json` file under the `.vscode` folder with the following content: - -```typescript -{ - "version": "0.2.0", - "configurations": [ - { - "type": "node", - "request": "launch", - "name": "Build Project", - "program": "${workspaceFolder}/packages/backend/dist/index.js", - "preLaunchTask": "npm: build:be", - "sourceMaps": true, - "smartStep": true, - "internalConsoleOptions": "openOnSessionStart", - "outFiles": ["${workspaceFolder}/packages/backend/dist/**/*.js"] - } - ] -} -``` - -## Messages from MegaLinter server - -Event-based management of MegaLinter Server can send the following list of messages into Redis PUBSUB channel built the following way: **megalinter:pubsub:REQUEST_ID** - -Example: `megalinter:pubsub:RQ_cbdd1d82-1e7b-11ee-9258-0242ac120004` - -### Start Megalinter analysis - -This message is sent once by analysis, when a **MegaLinter instance has identified the linters to run** and is about to start them. - -Example of **megalinterStart** messageType: - -```json -{ - "messageType": "megalinterStart", - "megaLinterStatus": "created", - "linters": [ - { - "descriptorId": "BASH", - "linterId": "bash-exec", - "linterKey": "BASH_EXEC", - "linterVersion": "5.2.15", - "linterCliLintMode": "file", - "requestId": "RQ_cbdd1d82-1e7b-11ee-9258-0242ac120004", - "docUrl": "https://megalinter.io/alpha/descriptors/bash_bash_exec", - "isFormatter": false, - "isSBOM": false, - "filesNumber": 1 - }, - { - "descriptorId": "BASH", - "linterId": "shellcheck", - "linterKey": "BASH_SHELLCHECK", - "linterVersion": "0.9.0", - "linterCliLintMode": "list_of_files", - "requestId": "RQ_cbdd1d82-1e7b-11ee-9258-0242ac120004", - "docUrl": "https://megalinter.io/alpha/descriptors/bash_shellcheck", - "isFormatter": false, - "isSBOM": false, - "filesNumber": 1 - }, - { - "descriptorId": "BASH", - "linterId": "shfmt", - "linterKey": "BASH_SHFMT", - "linterVersion": "ERROR", - "linterCliLintMode": "list_of_files", - "requestId": "RQ_cbdd1d82-1e7b-11ee-9258-0242ac120004", - "docUrl": "https://megalinter.io/alpha/descriptors/bash_shfmt", - "isFormatter": true, - "isSBOM": false, - "filesNumber": 1 - }, - { - "descriptorId": "COPYPASTE", - "linterId": "jscpd", - "linterKey": "COPYPASTE_JSCPD", - "linterVersion": "ERROR", - "linterCliLintMode": "project", - "requestId": "RQ_cbdd1d82-1e7b-11ee-9258-0242ac120004", - "docUrl": "https://megalinter.io/alpha/descriptors/copypaste_jscpd", - "isFormatter": false, - "isSBOM": false - }, - { - "descriptorId": "REPOSITORY", - "linterId": "checkov", - "linterKey": "REPOSITORY_CHECKOV", - "linterVersion": "3.11", - "linterCliLintMode": "project", - "requestId": "RQ_cbdd1d82-1e7b-11ee-9258-0242ac120004", - "docUrl": "https://megalinter.io/alpha/descriptors/repository_checkov", - "isFormatter": false, - "isSBOM": false - }, - { - "descriptorId": "REPOSITORY", - "linterId": "devskim", - "linterKey": "REPOSITORY_DEVSKIM", - "linterVersion": "1.0.11", - "linterCliLintMode": "project", - "requestId": "RQ_cbdd1d82-1e7b-11ee-9258-0242ac120004", - "docUrl": "https://megalinter.io/alpha/descriptors/repository_devskim", - "isFormatter": false, - "isSBOM": false - }, - { - "descriptorId": "REPOSITORY", - "linterId": "dustilock", - "linterKey": "REPOSITORY_DUSTILOCK", - "linterVersion": "1.2.0", - "linterCliLintMode": "project", - "requestId": "RQ_cbdd1d82-1e7b-11ee-9258-0242ac120004", - "docUrl": "https://megalinter.io/alpha/descriptors/repository_dustilock", - "isFormatter": false, - "isSBOM": false - }, - { - "descriptorId": "REPOSITORY", - "linterId": "git_diff", - "linterKey": "REPOSITORY_GIT_DIFF", - "linterVersion": "2.38.5", - "linterCliLintMode": "project", - "requestId": "RQ_cbdd1d82-1e7b-11ee-9258-0242ac120004", - "docUrl": "https://megalinter.io/alpha/descriptors/repository_git_diff", - "isFormatter": false, - "isSBOM": false - }, - { - "descriptorId": "REPOSITORY", - "linterId": "gitleaks", - "linterKey": "REPOSITORY_GITLEAKS", - "linterVersion": "8.17.0", - "linterCliLintMode": "project", - "requestId": "RQ_cbdd1d82-1e7b-11ee-9258-0242ac120004", - "docUrl": "https://megalinter.io/alpha/descriptors/repository_gitleaks", - "isFormatter": false, - "isSBOM": false - }, - { - "descriptorId": "REPOSITORY", - "linterId": "kics", - "linterKey": "REPOSITORY_KICS", - "linterVersion": "1.7.3", - "linterCliLintMode": "project", - "requestId": "RQ_cbdd1d82-1e7b-11ee-9258-0242ac120004", - "docUrl": "https://megalinter.io/alpha/descriptors/repository_kics", - "isFormatter": false, - "isSBOM": false - }, - { - "descriptorId": "REPOSITORY", - "linterId": "secretlint", - "linterKey": "REPOSITORY_SECRETLINT", - "linterVersion": "7.0.3", - "linterCliLintMode": "project", - "requestId": "RQ_cbdd1d82-1e7b-11ee-9258-0242ac120004", - "docUrl": "https://megalinter.io/alpha/descriptors/repository_secretlint", - "isFormatter": false, - "isSBOM": false - }, - { - "descriptorId": "REPOSITORY", - "linterId": "semgrep", - "linterKey": "REPOSITORY_SEMGREP", - "linterVersion": "1.31.2", - "linterCliLintMode": "project", - "requestId": "RQ_cbdd1d82-1e7b-11ee-9258-0242ac120004", - "docUrl": "https://megalinter.io/alpha/descriptors/repository_semgrep", - "isFormatter": false, - "isSBOM": false - }, - { - "descriptorId": "REPOSITORY", - "linterId": "trivy", - "linterKey": "REPOSITORY_TRIVY", - "linterVersion": "0.43.1", - "linterCliLintMode": "project", - "requestId": "RQ_cbdd1d82-1e7b-11ee-9258-0242ac120004", - "docUrl": "https://megalinter.io/alpha/descriptors/repository_trivy", - "isFormatter": false, - "isSBOM": false - }, - { - "descriptorId": "SPELL", - "linterId": "cspell", - "linterKey": "SPELL_CSPELL", - "linterVersion": "ERROR", - "linterCliLintMode": "list_of_files", - "requestId": "RQ_cbdd1d82-1e7b-11ee-9258-0242ac120004", - "docUrl": "https://megalinter.io/alpha/descriptors/spell_cspell", - "isFormatter": false, - "filesNumber": 1, - "isSBOM": false - } - ], - "requestId": "RQ_cbdd1d82-1e7b-11ee-9258-0242ac120004" -} -``` - -### Start Linter analysis - -This message is sent once by linter run, it indicates that **a single linter has started running**. - -Example of **linterStart** messageType with `linterCliLintMode=project`: - -```json -{ - "messageType": "linterStart", - "linterStatus": "started", - "descriptorId": "REPOSITORY", - "linterId": "trivy", - "linterKey": "REPOSITORY_TRIVY", - "linterVersion": "0.43.1", - "linterCliLintMode": "project", - "requestId": "RQ_cbdd1d82-1e7b-11ee-9258-0242ac120004", - "docUrl": "https://megalinter.io/alpha/descriptors/repository_trivy", - "isFormatter": false, - "isSBOM": false -} -``` - -Example of **linterStart** messageType with `linterCliLintMode=list_of_files` (with **filesNumber** additional property): - -```json -{ - "messageType": "linterStart", - "linterStatus": "started", - "descriptorId": "BASH", - "linterId": "shellcheck", - "linterKey": "BASH_SHELLCHECK", - "linterVersion": "0.9.0", - "linterCliLintMode": "list_of_files", - "requestId": "RQ_cbdd1d82-1e7b-11ee-9258-0242ac120004", - "docUrl": "https://megalinter.io/alpha/descriptors/bash_shellcheck", - "isFormatter": false, - "isSBOM": false, - "filesNumber": 1 -} -``` - -### Complete Linter analysis - -This message is sent once by linter run, it indicates that **a single linter has been completed**. - -If SARIF is available, it will be located in `outputSarif` property, otherwise results can be found in `outputText` and or `outputJson`. - -Example of **linterComplete** messageType: - -```json -{ - "messageType": "linterComplete", - "linterStatus": "success", - "linterErrorNumber": 0, - "linterStatusMessage": "No errors were found in the linting process", - "linterElapsedTime": 11.16, - "linterCliCommand": [ - "trivy", - "fs", - "--scanners", - "vuln,config", - "--exit-code", - "1", - "--format", - "sarif", - "-o", - "/tmp/ct-megalinter-xmv82bvyv/megalinter-reports/sarif/REPOSITORY_TRIVY.sarif", - "." - ], - "descriptorId": "REPOSITORY", - "linterId": "trivy", - "linterKey": "REPOSITORY_TRIVY", - "linterVersion": "0.43.1", - "linterCliLintMode": "project", - "requestId": "RQ_cbdd1d82-1e7b-11ee-9258-0242ac120004", - "docUrl": "https://megalinter.io/alpha/descriptors/repository_trivy", - "isFormatter": false, - "isSBOM": false, - "outputSarif": { - "$schema": "https://json.schemastore.org/sarif-2.1.0.json", - "runs": [ - { - "columnKind": "utf16CodeUnits", - "originalUriBaseIds": { - "ROOTPATH": { - "uri": "file:///" - } - }, - "properties": { - "megalinter": { - "docUrl": "https://megalinter.io/alpha/descriptors/repository_trivy", - "linterKey": "REPOSITORY_TRIVY", - "linterVersion": "0.43.1" - } - }, - "results": [], - "tool": { - "driver": { - "fullName": "Trivy Vulnerability Scanner", - "informationUri": "https://github.com/aquasecurity/trivy", - "name": "Trivy (MegaLinter REPOSITORY_TRIVY)", - "rules": [], - "version": "0.43.1" - } - } - } - ], - "version": "2.1.0" - } -} -``` - -### Complete Megalinter analysis - -This message is sent once by analysis, when a **MegaLinter analysis is completed**. - -CodeTotal stops listening to the requestId pubsub channel once this message is received, as no new message will be sent through this channel. - -Example of **megalinterComplete** messageType: - -```json -{ - "messageType": "megalinterComplete", - "megaLinterStatus": "completed", - "requestId": "RQ_cbdd1d82-1e7b-11ee-9258-0242ac120004" -} -``` - -### MegaLinter server error - -In some cases, it is not possible for MegaLinter to start an analysis because there has been an error during initialization. - -In that case, CodeTotal stops listening to the pubsub channel, as no more messages will be sent. - -List of errors: - -- `missingAnalysisType`: Missing type (snippet, file or repository) -- `gitCloneError`: Unable to clone the repository (probably not existing or not reachable) -- `uploadedFileNotFound`: Unable to find file(s) that were supposed to be uploaded by a previous HTTP call to `/upload-file` -- `snippetGuessError`: Unable to automatically detect the language of a code snippet -- `snippetBuildError`: Unable to find a file extension for the guessed snipper language - -Example of **serverError** messageType - -```json -{ - "messageType": "serverError", - "message": "Unable to clone repository\nCmd('git') failed due to: exit code(128)\n cmdline: git clone -v -- https://github.com/nvuillam/node-sarif-builder2 /tmp/ct-megalinter-x0afpmcmb\n stderr: 'Cloning into '/tmp/ct-megalinter-x0afpmcmb'...\nfatal: could not read Username for 'https://github.com': No such device or address\n'", - "errorCode": "gitCloneError", - "errorDetails": { - "error": "Cmd('git') failed due to: exit code(128)\n cmdline: git clone -v -- https://github.com/nvuillam/node-sarif-builder2 /tmp/ct-megalinter-x0afpmcmb\n stderr: 'Cloning into '/tmp/ct-megalinter-x0afpmcmb'...\nfatal: could not read Username for 'https://github.com': No such device or address\n'" - }, - "requestId": "RQ_e630c962-1e7c-11ee-9258-0242ac120004" -} -``` +To see how to use CodeTotal, please read [online documentation](https://codetotal.io) :) diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md new file mode 100644 index 0000000..11fa8a5 --- /dev/null +++ b/docs/CHANGELOG.md @@ -0,0 +1 @@ +--8<-- "../CHANGELOG.md" diff --git a/docs/assets/images/ox-icon.jpg b/docs/assets/images/ox-icon.jpg new file mode 100644 index 0000000..bb2207a Binary files /dev/null and b/docs/assets/images/ox-icon.jpg differ diff --git a/docs/screen.jpg b/docs/assets/images/screen.jpg similarity index 100% rename from docs/screen.jpg rename to docs/assets/images/screen.jpg diff --git a/docs/contributing.md b/docs/contributing.md new file mode 100644 index 0000000..3f2d90d --- /dev/null +++ b/docs/contributing.md @@ -0,0 +1 @@ +--8<-- "../CONTRIBUTING.md" diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 0000000..28bae1c --- /dev/null +++ b/docs/index.md @@ -0,0 +1,9 @@ +# CodeTotal + +**CodeTotal** analyzes any **snippet**, **file**, or **repository** to detect possible **security flaws** such as **secret in code**, **open source vulnerability**, **code security**, **vulnerability**, insecure **infrastructure as code**, and potential **legal issues** with open source licenses. + +Brought to you by [OX Security](https://ox.security), powered by [MegaLinter](https://megalinter.io) + +![CodeTotal Screenshot](assets/images/screen.jpg "A screenshot from the app") + +[Start now !](quick-start.md) \ No newline at end of file diff --git a/docs/javascripts/gtag.js b/docs/javascripts/gtag.js new file mode 100644 index 0000000..2aa2817 --- /dev/null +++ b/docs/javascripts/gtag.js @@ -0,0 +1,20 @@ +var gtag_id = ""; //"G-9B8BSP0VV7"; replace by GTAG if you want stats + +if (gtag_id === "") { + return; +} + +var script = document.createElement("script"); +script.src = "https://www.googletagmanager.com/gtag/js?id=" + gtag_id; +document.head.appendChild(script); + +location$.subscribe(function (url) { + window.dataLayer = window.dataLayer || []; + + function gtag() { + dataLayer.push(arguments); + } + + gtag("js", new Date()); + gtag("config", gtag_id); +}); \ No newline at end of file diff --git a/docs/javascripts/quickfixes.js b/docs/javascripts/quickfixes.js new file mode 100644 index 0000000..ed49b1d --- /dev/null +++ b/docs/javascripts/quickfixes.js @@ -0,0 +1,17 @@ +function hideHomeTitle() { + // Hide h1 containing Home (to have a nicer home page) + var h1s = document.querySelectorAll("h1"); + for (var i = 0; i < h1s.length; i++) { + if (h1s[i].innerText === 'Home') { + h1s[i].style.display = 'none'; + } + } +} + +(window.onload = function () { + hideHomeTitle(); + // So ugly setInterval: TODO: make that clean + setInterval(function () { + hideHomeTitle() + }, 1000); +}) diff --git a/docs/javascripts/tables.js b/docs/javascripts/tables.js new file mode 100644 index 0000000..513f93e --- /dev/null +++ b/docs/javascripts/tables.js @@ -0,0 +1,6 @@ +document$.subscribe(function () { + var tables = document.querySelectorAll("article table") + tables.forEach(function (table) { + new Tablesort(table) + }) +}) diff --git a/docs/license-explanations.md b/docs/license-explanations.md new file mode 100644 index 0000000..86bd144 --- /dev/null +++ b/docs/license-explanations.md @@ -0,0 +1,29 @@ +--- +title: License explanation +description: What you can do and can not do with CodeTotal +--- + + +# Why AGPL V3 License ? + +CodeTotal is an open-source and free tool graciously provided to the developer community. + +We don't earn money with CodeTotal, but it takes a lot of time to maintain it, so we want to avoid companies to make money with it by selling software or services without sharing their sources, like it happened in the past with [ElasticSearch](https://www.elastic.co/blog/why-license-change-aws) or [MongoDB](https://techcrunch.com/2018/10/16/mongodb-switches-up-its-open-source-license/). + +## What you can do + +- Use CodeTotal with public repositories +- Use CodeTotal with private repositories, even commercial ones +- Use CodeTotal to build commercial closed-source applications +- Use CodeTotal with on-premise Git services, like Github Enterprise or Gitlab Community Edition + +## What you can not do + +- Sell CodeTotal +- Expose a closed-source online service that calls CodeTotal in the background + +## What you could do + +If you have a professional use of CodeTotal, you can be nice and support us by [sponsoring us](https://megalinter.io/latest/sponsor/), and ask your clients to sponsor us too :) + +Any questions ? [Contact us](https://www.ox.security/contact/) ! \ No newline at end of file diff --git a/docs/license.md b/docs/license.md new file mode 100644 index 0000000..ec5e9f6 --- /dev/null +++ b/docs/license.md @@ -0,0 +1,5 @@ +# License + +## GNU Affero General Public License + + --8<-- "../LICENSE" diff --git a/docs/overrides/main.html b/docs/overrides/main.html new file mode 100644 index 0000000..1fc76a5 --- /dev/null +++ b/docs/overrides/main.html @@ -0,0 +1,32 @@ +{% extends "base.html" %} + +{% block extrahead %} + +{% if page and page.meta and page.meta.title and page.meta.description %} + + + + + + + + + + +{% else %} + + + + + + + + + + + + + +{% endif %} + +{% endblock %} diff --git a/docs/quick-start.md b/docs/quick-start.md new file mode 100644 index 0000000..478fa48 --- /dev/null +++ b/docs/quick-start.md @@ -0,0 +1,23 @@ +--- +title: Quick Start +description: Learn how to easily start CodeTotal on your computer or your server ! +--- + + +## Pre-requisites + +CodeTotal is based on docker images, so all you need to have is: + +- [docker](https://docs.docker.com/engine/install/) installed and started on your computer, so our [docker-compose.yml](https://github.com/oxsecurity/codetotal/blob/main/docker-compose.yml) file can be interpreted. +- [nodejs](https://nodejs.org/en), to call npm startup script + +## Clone the repository + +- Run `git clone https://github.com/oxsecurity/codetotal.git` + +## Start CodeTotal + +- Run `npm run codetotal` + +- Open in your Web browser + diff --git a/docs/security-linters.md b/docs/security-linters.md new file mode 100644 index 0000000..c5f7c35 --- /dev/null +++ b/docs/security-linters.md @@ -0,0 +1,48 @@ +--- +title: MegaLinter Security flavor +description: List of security linters embedded in CodeTotal +--- + +## Embedded linters + +CodeTotal is based on [MegaLinter security flavor](https://megalinter.io/latest/flavors/security/). + +### Languages + +| | Language | Linter | Additional | +|:----------------------------------------------------------------------------------------------------------------------------------------------------------------:|--------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------:| +| | [**BASH**](https://megalinter.io/beta/descriptors/bash/) | [**bash-exec**](https://megalinter.io/beta/descriptors/bash_bash_exec/)
[_BASH_EXEC_](https://megalinter.io/beta/descriptors/bash_bash_exec/) | | +| | [**BASH**](https://megalinter.io/beta/descriptors/bash/) | [**shellcheck**](https://megalinter.io/beta/descriptors/bash_shellcheck/)
[_BASH_SHELLCHECK_](https://megalinter.io/beta/descriptors/bash_shellcheck/) | [![GitHub stars](https://img.shields.io/github/stars/koalaman/shellcheck?cacheSeconds=3600)](https://github.com/koalaman/shellcheck) ![sarif](https://shields.io/badge/-SARIF-orange) | +| | [**PYTHON**](https://megalinter.io/beta/descriptors/python/) | [**bandit**](https://megalinter.io/beta/descriptors/python_bandit/)
[_PYTHON_BANDIT_](https://megalinter.io/beta/descriptors/python_bandit/) | [![GitHub stars](https://img.shields.io/github/stars/PyCQA/bandit?cacheSeconds=3600)](https://github.com/PyCQA/bandit) ![sarif](https://shields.io/badge/-SARIF-orange) | + +### Tooling + +| | Tooling format | Linter | Additional | +|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------:|------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------:| +| | [**ANSIBLE**](https://megalinter.io/beta/descriptors/ansible/) | [**ansible-lint**](https://megalinter.io/beta/descriptors/ansible_ansible_lint/)
[_ANSIBLE_ANSIBLE_LINT_](https://megalinter.io/beta/descriptors/ansible_ansible_lint/) | [![GitHub stars](https://img.shields.io/github/stars/ansible/ansible-lint?cacheSeconds=3600)](https://github.com/ansible/ansible-lint) ![sarif](https://shields.io/badge/-SARIF-orange) | +| | [**CLOUDFORMATION**](https://megalinter.io/beta/descriptors/cloudformation/) | [**cfn-lint**](https://megalinter.io/beta/descriptors/cloudformation_cfn_lint/)
[_CLOUDFORMATION_CFN_LINT_](https://megalinter.io/beta/descriptors/cloudformation_cfn_lint/) | [![GitHub stars](https://img.shields.io/github/stars/aws-cloudformation/cfn-lint?cacheSeconds=3600)](https://github.com/aws-cloudformation/cfn-lint) ![sarif](https://shields.io/badge/-SARIF-orange) | +| | [**DOCKERFILE**](https://megalinter.io/beta/descriptors/dockerfile/) | [**hadolint**](https://megalinter.io/beta/descriptors/dockerfile_hadolint/)
[_DOCKERFILE_HADOLINT_](https://megalinter.io/beta/descriptors/dockerfile_hadolint/) | [![GitHub stars](https://img.shields.io/github/stars/hadolint/hadolint?cacheSeconds=3600)](https://github.com/hadolint/hadolint) ![sarif](https://shields.io/badge/-SARIF-orange) | +| | [**KUBERNETES**](https://megalinter.io/beta/descriptors/kubernetes/) | [**kubeconform**](https://megalinter.io/beta/descriptors/kubernetes_kubeconform/)
[_KUBERNETES_KUBECONFORM_](https://megalinter.io/beta/descriptors/kubernetes_kubeconform/) | [![GitHub stars](https://img.shields.io/github/stars/yannh/kubeconform?cacheSeconds=3600)](https://github.com/yannh/kubeconform) | +| | [**KUBERNETES**](https://megalinter.io/beta/descriptors/kubernetes/) | [**helm**](https://megalinter.io/beta/descriptors/kubernetes_helm/)
[_KUBERNETES_HELM_](https://megalinter.io/beta/descriptors/kubernetes_helm/) | [![GitHub stars](https://img.shields.io/github/stars/helm/helm?cacheSeconds=3600)](https://github.com/helm/helm) | +| | [**KUBERNETES**](https://megalinter.io/beta/descriptors/kubernetes/) | [**kubescape**](https://megalinter.io/beta/descriptors/kubernetes_kubescape/)
[_KUBERNETES_KUBESCAPE_](https://megalinter.io/beta/descriptors/kubernetes_kubescape/) | [![GitHub stars](https://img.shields.io/github/stars/kubescape/kubescape?cacheSeconds=3600)](https://github.com/kubescape/kubescape) ![sarif](https://shields.io/badge/-SARIF-orange) | +| | [**TERRAFORM**](https://megalinter.io/beta/descriptors/terraform/) | [**tflint**](https://megalinter.io/beta/descriptors/terraform_tflint/)
[_TERRAFORM_TFLINT_](https://megalinter.io/beta/descriptors/terraform_tflint/) | [![GitHub stars](https://img.shields.io/github/stars/terraform-linters/tflint?cacheSeconds=3600)](https://github.com/terraform-linters/tflint) ![sarif](https://shields.io/badge/-SARIF-orange) | +| | [**TERRAFORM**](https://megalinter.io/beta/descriptors/terraform/) | [**terrascan**](https://megalinter.io/beta/descriptors/terraform_terrascan/)
[_TERRAFORM_TERRASCAN_](https://megalinter.io/beta/descriptors/terraform_terrascan/) | [![GitHub stars](https://img.shields.io/github/stars/tenable/terrascan?cacheSeconds=3600)](https://github.com/tenable/terrascan) ![sarif](https://shields.io/badge/-SARIF-orange) | +| | [**TERRAFORM**](https://megalinter.io/beta/descriptors/terraform/) | [**terragrunt**](https://megalinter.io/beta/descriptors/terraform_terragrunt/)
[_TERRAFORM_TERRAGRUNT_](https://megalinter.io/beta/descriptors/terraform_terragrunt/) | [![GitHub stars](https://img.shields.io/github/stars/gruntwork-io/terragrunt?cacheSeconds=3600)](https://github.com/gruntwork-io/terragrunt) ![autofix](https://shields.io/badge/-autofix-green) | + +### Other + +| | Code quality checker | Linter | Additional | +|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------:|----------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------:| +| | [**REPOSITORY**](https://megalinter.io/beta/descriptors/repository/) | [**checkov**](https://megalinter.io/beta/descriptors/repository_checkov/)
[_REPOSITORY_CHECKOV_](https://megalinter.io/beta/descriptors/repository_checkov/) | [![GitHub stars](https://img.shields.io/github/stars/bridgecrewio/checkov?cacheSeconds=3600)](https://github.com/bridgecrewio/checkov) ![sarif](https://shields.io/badge/-SARIF-orange) | +| | [**REPOSITORY**](https://megalinter.io/beta/descriptors/repository/) | [**devskim**](https://megalinter.io/beta/descriptors/repository_devskim/)
[_REPOSITORY_DEVSKIM_](https://megalinter.io/beta/descriptors/repository_devskim/) | [![GitHub stars](https://img.shields.io/github/stars/microsoft/DevSkim?cacheSeconds=3600)](https://github.com/microsoft/DevSkim) ![sarif](https://shields.io/badge/-SARIF-orange) | +| | [**REPOSITORY**](https://megalinter.io/beta/descriptors/repository/) | [**dustilock**](https://megalinter.io/beta/descriptors/repository_dustilock/)
[_REPOSITORY_DUSTILOCK_](https://megalinter.io/beta/descriptors/repository_dustilock/) | [![GitHub stars](https://img.shields.io/github/stars/Checkmarx/dustilock?cacheSeconds=3600)](https://github.com/Checkmarx/dustilock) ![sarif](https://shields.io/badge/-SARIF-orange) | +| | [**REPOSITORY**](https://megalinter.io/beta/descriptors/repository/) | [**gitleaks**](https://megalinter.io/beta/descriptors/repository_gitleaks/)
[_REPOSITORY_GITLEAKS_](https://megalinter.io/beta/descriptors/repository_gitleaks/) | [![GitHub stars](https://img.shields.io/github/stars/gitleaks/gitleaks?cacheSeconds=3600)](https://github.com/gitleaks/gitleaks) ![sarif](https://shields.io/badge/-SARIF-orange) | +| | [**REPOSITORY**](https://megalinter.io/beta/descriptors/repository/) | [**grype**](https://megalinter.io/beta/descriptors/repository_grype/)
[_REPOSITORY_GRYPE_](https://megalinter.io/beta/descriptors/repository_grype/) | [![GitHub stars](https://img.shields.io/github/stars/anchore/grype?cacheSeconds=3600)](https://github.com/anchore/grype) ![sarif](https://shields.io/badge/-SARIF-orange) | +| | [**REPOSITORY**](https://megalinter.io/beta/descriptors/repository/) | [**kics**](https://megalinter.io/beta/descriptors/repository_kics/)
[_REPOSITORY_KICS_](https://megalinter.io/beta/descriptors/repository_kics/) | [![GitHub stars](https://img.shields.io/github/stars/checkmarx/kics?cacheSeconds=3600)](https://github.com/checkmarx/kics) ![sarif](https://shields.io/badge/-SARIF-orange) | +| | [**REPOSITORY**](https://megalinter.io/beta/descriptors/repository/) | [**secretlint**](https://megalinter.io/beta/descriptors/repository_secretlint/)
[_REPOSITORY_SECRETLINT_](https://megalinter.io/beta/descriptors/repository_secretlint/) | [![GitHub stars](https://img.shields.io/github/stars/secretlint/secretlint?cacheSeconds=3600)](https://github.com/secretlint/secretlint) ![sarif](https://shields.io/badge/-SARIF-orange) | +| | [**REPOSITORY**](https://megalinter.io/beta/descriptors/repository/) | [**semgrep**](https://megalinter.io/beta/descriptors/repository_semgrep/)
[_REPOSITORY_SEMGREP_](https://megalinter.io/beta/descriptors/repository_semgrep/) | [![GitHub stars](https://img.shields.io/github/stars/returntocorp/semgrep?cacheSeconds=3600)](https://github.com/returntocorp/semgrep) ![sarif](https://shields.io/badge/-SARIF-orange) | +| | [**REPOSITORY**](https://megalinter.io/beta/descriptors/repository/) | [**syft**](https://megalinter.io/beta/descriptors/repository_syft/)
[_REPOSITORY_SYFT_](https://megalinter.io/beta/descriptors/repository_syft/) | [![GitHub stars](https://img.shields.io/github/stars/anchore/syft?cacheSeconds=3600)](https://github.com/anchore/syft) ![sarif](https://shields.io/badge/-SARIF-orange) | +| | [**REPOSITORY**](https://megalinter.io/beta/descriptors/repository/) | [**trivy**](https://megalinter.io/beta/descriptors/repository_trivy/)
[_REPOSITORY_TRIVY_](https://megalinter.io/beta/descriptors/repository_trivy/) | [![GitHub stars](https://img.shields.io/github/stars/aquasecurity/trivy?cacheSeconds=3600)](https://github.com/aquasecurity/trivy) ![sarif](https://shields.io/badge/-SARIF-orange) | +| | [**REPOSITORY**](https://megalinter.io/beta/descriptors/repository/) | [**trivy-sbom**](https://megalinter.io/beta/descriptors/repository_trivy_sbom/)
[_REPOSITORY_TRIVY_SBOM_](https://megalinter.io/beta/descriptors/repository_trivy_sbom/) | [![GitHub stars](https://img.shields.io/github/stars/aquasecurity/trivy?cacheSeconds=3600)](https://github.com/aquasecurity/trivy) ![sarif](https://shields.io/badge/-SARIF-orange) | +| | [**REPOSITORY**](https://megalinter.io/beta/descriptors/repository/) | [**trufflehog**](https://megalinter.io/beta/descriptors/repository_trufflehog/)
[_REPOSITORY_TRUFFLEHOG_](https://megalinter.io/beta/descriptors/repository_trufflehog/) | [![GitHub stars](https://img.shields.io/github/stars/trufflesecurity/trufflehog?cacheSeconds=3600)](https://github.com/trufflesecurity/trufflehog) | + diff --git a/docs/stylesheets/extra.css b/docs/stylesheets/extra.css new file mode 100644 index 0000000..ff8be96 --- /dev/null +++ b/docs/stylesheets/extra.css @@ -0,0 +1,81 @@ +/* stylelint-disable SelectorFormat, selector-class-pattern */ +.codetotal-banner { + height: 50px; + max-height: 150px; +} + +.codetotal-logo { + height: 70px; + max-height: 70px; +} + +.codetotal-icon { + max-height: 32px; + max-width: 32px; +} + +.megalinter-icon { + max-height: 32px; + max-width: 32px; +} + +.md-typeset__table { + min-width: 100%; +} + +.md-typeset table:not([class]) { + display: table; +} + +/* light mode table header bgcolor */ +.md-typeset__table th { + background-color: #f2edfe; +} + +/* dark mode table header bgcolor */ +[data-md-color-scheme="slate"] .md-typeset__table th { + background-color: hsla(var(--md-hue),25%,25%,1) +} + +/* light mode alternating table bg colors */ +.md-typeset__table tr:nth-child(2n) { + background-color: #f8f8f8; +} + +/* dark mode alternating table bg colors */ +[data-md-color-scheme="slate"] .md-typeset__table tr:nth-child(2n) { + background-color: hsla(var(--md-hue),25%,25%,1) +} + +h1[content~=Home] { + display: none; +} + +:root>* { + --md-default-fg-color: #1E144D; + --md-default-fg-color--light: #6A2BFF; + --md-default-fg-color--lighter: #FD80CD ; + --md-default-fg-color--lightest: #dcc4d3; + --md-default-bg-color: #fff; + --md-default-bg-color--light: #fff; + --md-default-bg-color--lighter: #fff; + --md-default-bg-color--lightest: #fff; + + --md-primary-fg-color: #1E144D; + --md-primary-fg-color--light: #FD80CD; + --md-primary-fg-color--dark: #6A2BFF; + --md-primary-bg-color: #fff; + --md-primary-bg-color--light: #fff; + + + --md-accent-fg-color: #6A2BFF; + --md-accent-fg-color--transparent: #6A2BFF; + --md-accent-bg-color: #B95CE4; + --md-accent-bg-color--light: #FD80CD; + + --md-footer-bg-color: #B95CE4; + + --md-typeset-table-color--light: #fff5fb; + +} + diff --git a/mkdocs.yml b/mkdocs.yml new file mode 100644 index 0000000..721ed90 --- /dev/null +++ b/mkdocs.yml @@ -0,0 +1,65 @@ +--- +site_name: CodeTotal by OX Security +site_url: https://codetotal.io +repo_url: https://github.com/oxsecurity/codetotal +edit_uri: tree/main/docs +site_author: Nicolas Vuillamy +# site_description-start +site_description: +# site_description-end +copyright: Copyright © 2022 OX Security +theme: + name: material + font: + text: Satoshi, sans-serif + custom_dir: docs/overrides + features: + - navigation.instant + - navigation.footer + logo: assets/images/ox-icon.jpg + favicon: assets/images/ox-icon.jpg + palette: + primary: white +plugins: + - glightbox + - search +markdown_extensions: + - pymdownx.emoji: + emoji_index: !!python/name:materialx.emoji.twemoji + emoji_generator: !!python/name:materialx.emoji.to_svg + - pymdownx.snippets: + base_path: docs + check_paths: true + - mdx_truly_sane_lists + - attr_list +extra_javascript: + - https://cdnjs.cloudflare.com/ajax/libs/tablesort/5.2.1/tablesort.min.js + - javascripts/tables.js +# - javascripts/gtag.js +# - javascripts/version-mike.js + - javascripts/quickfixes.js +extra_css: + - stylesheets/extra.css +extra: + social: + - icon: fontawesome/brands/linkedin + link: https://www.linkedin.com/company/ox-security/ + - icon: fontawesome/regular/circle-question + link: https://github.com/oxsecurity/codetotal/issues + title: Need help ? Post an issue :) + - icon: fontawesome/brands/github + link: https://github.com/oxsecurity/codetotal + - icon: fontawesome/brands/docker + link: https://hub.docker.com/r/oxsecurity/codetotal + generator: false +nav: + - "Home": "index.md" + - "Quick Start": "quick-start.md" + - "Security linters": "security-linters.md" + - "Contribute": "contributing.md" + - "License": + - "AGPL V3 License": "license.md" + - "License explanations": "license-explanations.md" + - "Changelog": "CHANGELOG.md" + - "MegaLinter WebSite": "https://megalinter.io" + - "OX Security WebSite": "https://ox.security?ref=codetotal" diff --git a/package.json b/package.json index 8e234b2..a53c87b 100644 --- a/package.json +++ b/package.json @@ -21,6 +21,8 @@ "codetotal:dev": "cross-env DOCKER_DEFAULT_PLATFORM=linux/amd64 docker-compose -f docker-compose-local.yml up", "precodetotal": "cross-env DOCKER_DEFAULT_PLATFORM=linux/amd64 docker-compose -f docker-compose.yml pull", "codetotal": "cross-env DOCKER_DEFAULT_PLATFORM=linux/amd64 docker-compose -f docker-compose.yml up", + "doc:install": "pip install --upgrade markdown==3.3.7 mkdocs-material pymdown-extensions==9.11 mkdocs-glightbox==0.3.2 mdx_truly_sane_lists", + "doc:test": "mkdocs serve", "e2e": "npx cypress open" }, "pre-commit": [