WAT-4: Initial code analysis config

This commit is contained in:
2024-06-27 23:56:43 -04:00
parent b9b4a31f37
commit 655bb77d3b
13 changed files with 351 additions and 42 deletions

View File

@@ -1 +1 @@
BASE_RSS_FEED=https://example.com
BASE_RSS_FEED=https://rss.plex.tv/

View File

@@ -1,29 +0,0 @@
module.exports = {
env: {
browser: true,
es2021: true,
},
extends: [
'airbnb-base',
'plugin:sonarjs/recommended',
'plugin:react-hooks/recommended',
'plugin:@tanstack/eslint-plugin-query/recommended'
],
overrides: [
{
env: {
node: true,
},
files: ['.eslintrc.{js,cjs}'],
parserOptions: {
sourceType: 'script',
},
},
],
parserOptions: {
ecmaVersion: 'latest',
sourceType: 'module',
},
rules: {},
ignorePatterns: ['**/libs/*.js', 'node_modules/**', 'env/**'],
};

2
.gitignore vendored
View File

@@ -128,3 +128,5 @@ dist
.yarn/build-state.yml
.yarn/install-state.gz
.pnp.*
.vscode

14
.pre-commit-config.yaml Normal file
View File

@@ -0,0 +1,14 @@
# .pre-commit-config.yaml
repos:
- repo: https://github.com/Yelp/detect-secrets
rev: v1.5.0
hooks:
- id: detect-secrets
args: ['--baseline', '.secrets.baseline']
exclude: package.lock.json
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.4.0 # Use the ref you want to point at
hooks:
- id: trailing-whitespace
- id: check-json
#- id: check-yaml

127
.secrets.baseline Normal file
View File

@@ -0,0 +1,127 @@
{
"version": "1.5.0",
"plugins_used": [
{
"name": "ArtifactoryDetector"
},
{
"name": "AWSKeyDetector"
},
{
"name": "AzureStorageKeyDetector"
},
{
"name": "Base64HighEntropyString",
"limit": 4.5
},
{
"name": "BasicAuthDetector"
},
{
"name": "CloudantDetector"
},
{
"name": "DiscordBotTokenDetector"
},
{
"name": "GitHubTokenDetector"
},
{
"name": "GitLabTokenDetector"
},
{
"name": "HexHighEntropyString",
"limit": 3.0
},
{
"name": "IbmCloudIamDetector"
},
{
"name": "IbmCosHmacDetector"
},
{
"name": "IPPublicDetector"
},
{
"name": "JwtTokenDetector"
},
{
"name": "KeywordDetector",
"keyword_exclude": ""
},
{
"name": "MailchimpDetector"
},
{
"name": "NpmDetector"
},
{
"name": "OpenAIDetector"
},
{
"name": "PrivateKeyDetector"
},
{
"name": "PypiTokenDetector"
},
{
"name": "SendGridDetector"
},
{
"name": "SlackDetector"
},
{
"name": "SoftlayerDetector"
},
{
"name": "SquareOAuthDetector"
},
{
"name": "StripeDetector"
},
{
"name": "TelegramBotTokenDetector"
},
{
"name": "TwilioKeyDetector"
}
],
"filters_used": [
{
"path": "detect_secrets.filters.allowlist.is_line_allowlisted"
},
{
"path": "detect_secrets.filters.common.is_ignored_due_to_verification_policies",
"min_level": 2
},
{
"path": "detect_secrets.filters.heuristic.is_indirect_reference"
},
{
"path": "detect_secrets.filters.heuristic.is_likely_id_string"
},
{
"path": "detect_secrets.filters.heuristic.is_lock_file"
},
{
"path": "detect_secrets.filters.heuristic.is_not_alphanumeric_string"
},
{
"path": "detect_secrets.filters.heuristic.is_potential_uuid"
},
{
"path": "detect_secrets.filters.heuristic.is_prefixed_with_dollar_sign"
},
{
"path": "detect_secrets.filters.heuristic.is_sequential_string"
},
{
"path": "detect_secrets.filters.heuristic.is_swagger_file"
},
{
"path": "detect_secrets.filters.heuristic.is_templated_secret"
}
],
"results": {},
"generated_at": "2024-06-28T03:54:46Z"
}

94
CodeAnalysisJenkinsfile Normal file
View File

@@ -0,0 +1,94 @@
pipeline {
agent {
label 'python311 && amd64'
}
options {
quietPeriod(120)
disableConcurrentBuilds()
}
tools {nodejs "Node 20"}
environment {
DEPCHECK_SCAN_ACCOUNT = credentials('DEPCHECK_SCAN_ACCOUNT')
DEPCHECK_CONNSTRING = credentials('DEPCHECK_CONNSTRING')
SONATYPE_OSSINDEX_API_KEY = credentials('SONATYPE_OSSINDEX_API_KEY')
SONAR_SCANNER_OPTS = '-Xmx128m'
}
stages {
stage('Install Python Virtual Enviroment') {
steps {
sh 'echo $PATH'
sh 'python3.11 -m venv env'
}
}
stage('Install Application Dependencies') {
steps {
sh '''
. env/bin/activate
pip3.11 install --upgrade pip
pip3.11 install -r requirements.txt
corepack enable
npm install
mkdir reports
deactivate
'''
}
}
stage('ESLint') {
steps {
script {
try {
sh ". env/bin/activate && npx eslint . -c eslint.config.mjs -o reports/eslint.json --format json || true"
sh ". env/bin/activate && npx eslint . -c eslint.config.mjs -o reports/eslint-checkstyle.report --format checkstyle || true"
}
finally {
recordIssues tool: esLint(pattern: '**/reports/eslint-checkstyle.report'), aggregatingResults: true
}
}
}
}
stage('OWASP Dependency-Check Vulnerabilities') {
steps {
sh 'curl -O https://jdbc.postgresql.org/download/postgresql-42.7.3.jar'
dependencyCheck odcInstallation: 'DepCheck',
additionalArguments: '--project "Plex Watchlist" -o ./reports -f XML -f HTML -f JSON -f CSV --noupdate --connectionString $DEPCHECK_CONNSTRING --dbDriverPath postgresql-42.7.3.jar --dbDriverName org.postgresql.Driver --dbUser $DEPCHECK_SCAN_ACCOUNT_USR --dbPassword $DEPCHECK_SCAN_ACCOUNT_PSW --ossIndexUsername averymd@irrsinn.net --ossIndexPassword $SONATYPE_OSSINDEX_API_KEY'
dependencyCheckPublisher pattern: 'reports/dependency-check-report.xml'
}
}
stage('SonarQube Analysis') {
environment {
scannerHome = tool 'SonarQubeDefault'
}
steps {
withSonarQubeEnv('Personal SonarQube') {
sh """
. env/bin/activate
${scannerHome}/bin/sonar-scanner \
-Dsonar.dependencyCheck.jsonReportPath=reports/dependency-check-report.json \
-Dsonar.dependencyCheck.xmlReportPath=reports/dependency-check-report.xml \
-Dsonar.dependencyCheck.htmlReportPath=reports/dependency-check-report.html \
-Dsonar.eslint.reportPaths=reports/eslint.json
deactivate
"""
}
}
}
}
post {
cleanup {
cleanWs()
dir("${env.WORKSPACE}@tmp") {
deleteDir()
}
dir("${env.WORKSPACE}@2") {
deleteDir()
}
dir("${env.WORKSPACE}@2@tmp") {
deleteDir()
}
}
}
}

45
eslint.config.mjs Normal file
View File

@@ -0,0 +1,45 @@
import { fixupConfigRules } from '@eslint/compat';
import globals from 'globals';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
import js from '@eslint/js';
import { FlatCompat } from '@eslint/eslintrc';
import sonarjs from 'eslint-plugin-sonarjs';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const compat = new FlatCompat({
baseDirectory: __dirname,
allConfig: js.configs.all,
});
export default [
{
ignores: ['**/libs/*.js', 'node_modules/**/*', '.env/**/*', 'dist/**/*'],
},
sonarjs.configs.recommended,
...fixupConfigRules(
compat.extends(
'plugin:react-hooks/recommended',
'plugin:@tanstack/eslint-plugin-query/recommended'
)
),
{
languageOptions: {
globals: {
...globals.browser,
},
parserOptions: {
ecmaFeatures: {
jsx: true,
modules: true,
},
},
ecmaVersion: 'latest',
sourceType: 'module',
},
rules: {},
},
];

65
package-lock.json generated
View File

@@ -16,16 +16,20 @@
"@mui/x-date-pickers": "^7.7.1",
"@tanstack/react-query": "^5.45.1",
"axios": "^1.7.2",
"globals": "^15.6.0",
"material-react-table": "^2.13.0",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"rss-parser": "^3.13.0"
},
"devDependencies": {
"@eslint/compat": "^1.1.0",
"@tanstack/eslint-plugin-query": "^5.43.1",
"buffer": "^6.0.3",
"eslint": "^9.5.0",
"eslint-formatter-checkstyle": "^8.40.0",
"eslint-plugin-react-hooks": "^5.1.0-rc-1434af3d22-20240618",
"eslint-plugin-sonarjs": "^1.0.3",
"events": "^3.3.0",
"https-browserify": "^1.0.0",
"parcel": "^2.12.0",
@@ -517,6 +521,16 @@
"node": "^12.0.0 || ^14.0.0 || >=16.0.0"
}
},
"node_modules/@eslint/compat": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@eslint/compat/-/compat-1.1.0.tgz",
"integrity": "sha512-s9Wi/p25+KbzxKlDm3VshQdImhWk+cbdblhwGNnyCU5lpSwtWa4v7VQCxSki0FAUrGA3s8nCWgYzAH41mwQVKQ==",
"dev": true,
"license": "Apache-2.0",
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
}
},
"node_modules/@eslint/config-array": {
"version": "0.16.0",
"resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.16.0.tgz",
@@ -1940,6 +1954,22 @@
"url": "https://opencollective.com/parcel"
}
},
"node_modules/@parcel/packager-js/node_modules/globals": {
"version": "13.24.0",
"resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz",
"integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"type-fest": "^0.20.2"
},
"engines": {
"node": ">=8"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/@parcel/packager-raw": {
"version": "2.12.0",
"resolved": "https://registry.npmjs.org/@parcel/packager-raw/-/packager-raw-2.12.0.tgz",
@@ -4324,6 +4354,16 @@
"url": "https://eslint.org/donate"
}
},
"node_modules/eslint-formatter-checkstyle": {
"version": "8.40.0",
"resolved": "https://registry.npmjs.org/eslint-formatter-checkstyle/-/eslint-formatter-checkstyle-8.40.0.tgz",
"integrity": "sha512-OpYAiI2yejMPUlB1O2pkfyNfBQrKNWrMK6X2eOn2vg/q94roDiHnOYExK0isdNglKeaYHA5JtgmuBtokFdj0AA==",
"dev": true,
"license": "MIT",
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
}
},
"node_modules/eslint-plugin-react-hooks": {
"version": "5.1.0-rc-1434af3d22-20240618",
"resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-5.1.0-rc-1434af3d22-20240618.tgz",
@@ -4337,6 +4377,19 @@
"eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0"
}
},
"node_modules/eslint-plugin-sonarjs": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/eslint-plugin-sonarjs/-/eslint-plugin-sonarjs-1.0.3.tgz",
"integrity": "sha512-6s41HLPYPyDrp+5+7Db5yFYbod6h9pC7yx+xfcNwHRcLe1EZwbbQT/tdOAkR7ekVUkNGEvN3GmYakIoQUX7dEg==",
"dev": true,
"license": "LGPL-3.0-only",
"engines": {
"node": ">=16"
},
"peerDependencies": {
"eslint": "^8.0.0 || ^9.0.0"
}
},
"node_modules/eslint-scope": {
"version": "8.0.1",
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.0.1.tgz",
@@ -4672,16 +4725,12 @@
}
},
"node_modules/globals": {
"version": "13.24.0",
"resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz",
"integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==",
"dev": true,
"version": "15.6.0",
"resolved": "https://registry.npmjs.org/globals/-/globals-15.6.0.tgz",
"integrity": "sha512-UzcJi88Hw//CurUIRa9Jxb0vgOCcuD/MNjwmXp633cyaRKkCWACkoqHCtfZv43b1kqXGg/fpOa8bwgacCeXsVg==",
"license": "MIT",
"dependencies": {
"type-fest": "^0.20.2"
},
"engines": {
"node": ">=8"
"node": ">=18"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"

View File

@@ -2,7 +2,6 @@
"name": "public-plex-watchlist",
"version": "0.0.1",
"description": "Turn your Plex Watchlist RSS feed into an interface non-Plex folks can search and filter.",
"main": "src/index.js",
"source": "src/index.html",
"scripts": {
"start": "parcel",
@@ -31,16 +30,20 @@
"@mui/x-date-pickers": "^7.7.1",
"@tanstack/react-query": "^5.45.1",
"axios": "^1.7.2",
"globals": "^15.6.0",
"material-react-table": "^2.13.0",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"rss-parser": "^3.13.0"
},
"devDependencies": {
"@eslint/compat": "^1.1.0",
"@tanstack/eslint-plugin-query": "^5.43.1",
"buffer": "^6.0.3",
"eslint": "^9.5.0",
"eslint-formatter-checkstyle": "^8.40.0",
"eslint-plugin-react-hooks": "^5.1.0-rc-1434af3d22-20240618",
"eslint-plugin-sonarjs": "^1.0.3",
"events": "^3.3.0",
"https-browserify": "^1.0.0",
"parcel": "^2.12.0",

2
requirements.txt Normal file
View File

@@ -0,0 +1,2 @@
detect-secrets==1.5.0
pre-commit==3.7.1

3
sonar-project.properties Normal file
View File

@@ -0,0 +1,3 @@
sonar.projectKey=averymd_public-plex-watchlist_3d43ef27-fec8-4c37-9758-6f95ec5635cc
sonar.exclusions=env/**,node_modules/**
sonar.python.version=3.11

View File

@@ -12,6 +12,5 @@ export async function fetchPlexWatchlistFeed({ pageParam }) {
],
},
});
let result = rssParser.parseURL(pageParam);
return result;
return rssParser.parseURL(pageParam);
}

View File

@@ -4,7 +4,7 @@
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<title>Plex Watchlist</title>
</head>
<body>