diff --git a/.github/workflows/analyses.yml b/.github/workflows/analyses.yml index 0262b35..9419124 100644 --- a/.github/workflows/analyses.yml +++ b/.github/workflows/analyses.yml @@ -102,6 +102,7 @@ jobs: - name: TypeScript run: npm run ts:check + # Step 5: Run unit tests unit_tests: needs: install # Depends on the install job @@ -120,3 +121,50 @@ jobs: # Run unit tests - name: Unit tests run: npm run test:unit + + # Generate coverage report + - name: Generate Coverage Report + run: npm run coverage + + # Upload coverage report + - name: Upload coverage Report + uses: actions/upload-artifact@v3 + with: + name: coverage-report + path: coverage + + # Step 6: Run SonarQube analysis + sonarqube: + name: SonarQube Analysis + needs: [build, unit_tests] + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + #Download coverage report + - name: Download coverage Report + uses: actions/download-artifact@v3 + with: + name: coverage-report + path: coverage + + # Run SonarQube analysis + - uses: sonarsource/sonarqube-scan-action@v3 + env: + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }} + with: + args: | + -Dsonar.projectKey=Webank-Userapp + -Dsonar.source=src + -Dsonar.javascript.lcov.reportPaths=coverage/lcov.info + -Dsonar.qualitygate.wait=true + + #If you wish to fail your job when the Quality Gate is red + - uses: sonarsource/sonarqube-quality-gate-action@master + timeout-minutes: 5 + env: + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} \ No newline at end of file diff --git a/.gitignore b/.gitignore index 6d6ae5a..137a0d3 100644 --- a/.gitignore +++ b/.gitignore @@ -6,13 +6,17 @@ yarn-debug.log* yarn-error.log* pnpm-debug.log* lerna-debug.log* +coverage +!coverage/lcov.info +!coverage/lcov-report node_modules dist dist-ssr dev-dist *.local - +.sonar +*.sonar # Editor directories and files .vscode/* !.vscode/extensions.json diff --git a/package-lock.json b/package-lock.json index 61ebb1f..533c4f9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -43,6 +43,7 @@ "jsdom": "^25.0.1", "postcss": "^8.4.47", "prettier": "^3.3.3", + "sonarqube-scanner": "^4.2.5", "tailwindcss": "^3.4.14", "tslib": "^2.8.0", "typescript": "^5.6.3", @@ -4121,6 +4122,16 @@ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, + "node_modules/adm-zip": { + "version": "0.5.12", + "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.5.12.tgz", + "integrity": "sha512-6TVU49mK6KZb4qG6xWaaM4C7sA/sgUMLy/JYMOzkcp3BvVLpW0fXDFQiIzAuxFCt/2+xD7fNIiPFAoLZPhVNLQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0" + } + }, "node_modules/agent-base": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", @@ -6660,6 +6671,16 @@ "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", "license": "MIT" }, + "node_modules/hpagent": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/hpagent/-/hpagent-1.2.0.tgz", + "integrity": "sha512-A91dYTeIB6NoXG+PxTQpCCDDnfHsW9kc06Lvpu1TEe9gnd6ZFeiBoRO9JvzEv6xK7EX97/dUE8g/vBMTqTS3CA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + } + }, "node_modules/html-encoding-sniffer": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-4.0.0.tgz", @@ -7443,6 +7464,19 @@ "node": ">=8" } }, + "node_modules/jest-sonar-reporter": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/jest-sonar-reporter/-/jest-sonar-reporter-2.0.0.tgz", + "integrity": "sha512-ZervDCgEX5gdUbdtWsjdipLN3bKJwpxbvhkYNXTAYvAckCihobSLr9OT/IuyNIRT1EZMDDwR6DroWtrq+IL64w==", + "dev": true, + "license": "MIT", + "dependencies": { + "xml": "^1.0.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, "node_modules/jiti": { "version": "1.21.6", "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.6.tgz", @@ -8007,6 +8041,16 @@ "dev": true, "license": "MIT" }, + "node_modules/node-forge": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", + "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==", + "dev": true, + "license": "(BSD-3-Clause OR GPL-2.0)", + "engines": { + "node": ">= 6.13.0" + } + }, "node_modules/node-releases": { "version": "2.0.18", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", @@ -8653,6 +8697,16 @@ "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", "license": "MIT" }, + "node_modules/properties-file": { + "version": "3.5.4", + "resolved": "https://registry.npmjs.org/properties-file/-/properties-file-3.5.4.tgz", + "integrity": "sha512-OGQPWZ4j9ENDKBl+wUHqNtzayGF5sLlVcmjcqEMUUHeCbUSggDndii+kjcBDPj3GQvqYB9sUEc4siX36wx4glw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, "node_modules/proxy-from-env": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", @@ -9439,6 +9493,16 @@ "node": ">=8" } }, + "node_modules/slugify": { + "version": "1.6.6", + "resolved": "https://registry.npmjs.org/slugify/-/slugify-1.6.6.tgz", + "integrity": "sha512-h+z7HKHYXj6wJU+AnS/+IH8Uh9fdcX1Lrhg1/VMdf9PwoBQXFcXiAdsy2tSK0P6gKwJLXp02r90ahUCqHk9rrw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.0.0" + } + }, "node_modules/smob": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/smob/-/smob-1.5.0.tgz", @@ -9446,6 +9510,94 @@ "dev": true, "license": "MIT" }, + "node_modules/sonarqube-scanner": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/sonarqube-scanner/-/sonarqube-scanner-4.2.5.tgz", + "integrity": "sha512-7Hs8Or1ZmgzIh4DLavRVlmrKfoQo+x6DFr7Aw3BnMRswlflalObKKJrj10/A2J2bfYd7iqkt1DXeIoTXNJrCkg==", + "dev": true, + "license": "LGPL-3.0-only", + "dependencies": { + "adm-zip": "0.5.12", + "axios": "1.7.7", + "commander": "12.0.0", + "fs-extra": "11.2.0", + "hpagent": "1.2.0", + "jest-sonar-reporter": "2.0.0", + "node-forge": "^1.3.1", + "properties-file": "3.5.4", + "proxy-from-env": "^1.1.0", + "semver": "7.6.0", + "slugify": "1.6.6", + "tar-stream": "3.1.7" + }, + "bin": { + "sonar-scanner": "bin/sonar-scanner" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/sonarqube-scanner/node_modules/commander": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-12.0.0.tgz", + "integrity": "sha512-MwVNWlYjDTtOjX5PiD7o5pK0UrFU/OYgcJfjjK4RaHZETNtjJqrZa9Y9ds88+A+f+d5lv+561eZ+yCKoS3gbAA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/sonarqube-scanner/node_modules/fs-extra": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", + "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/sonarqube-scanner/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/sonarqube-scanner/node_modules/semver": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", + "dev": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/sonarqube-scanner/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true, + "license": "ISC" + }, "node_modules/source-map": { "version": "0.8.0-beta.0", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.8.0-beta.0.tgz", @@ -11216,6 +11368,13 @@ } } }, + "node_modules/xml": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/xml/-/xml-1.0.1.tgz", + "integrity": "sha512-huCv9IH9Tcf95zuYCsQraZtWnJvBtLVE0QHMOs8bWyZAFZNDcYjsPq1nEx8jKA9y+Beo9v+7OBPRisQTjinQMw==", + "dev": true, + "license": "MIT" + }, "node_modules/xml-name-validator": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz", diff --git a/package.json b/package.json index fc8553d..1ed55d6 100644 --- a/package.json +++ b/package.json @@ -50,6 +50,7 @@ "jsdom": "^25.0.1", "postcss": "^8.4.47", "prettier": "^3.3.3", + "sonarqube-scanner": "^4.2.5", "tailwindcss": "^3.4.14", "tslib": "^2.8.0", "typescript": "^5.6.3", diff --git a/sonar-project.properties b/sonar-project.properties new file mode 100644 index 0000000..5e2f085 --- /dev/null +++ b/sonar-project.properties @@ -0,0 +1,8 @@ +sonar.projectKey=Webank-Userapp +sonar.javascript.lcov.reportPaths=coverage/lcov.info +sonar.sources=src +sonar.tests=src +sonar.language=ts +sonar.inclusions=**/*.ts,**/*.tsx +sonar.test.inclusions=**/*.spec.js,**/*.test.js,**/*.spec.ts,**/*.test.ts +sonar.test.exclusions=**/node_modules/** diff --git a/src/services/keyManagement/storageSetup.ts b/src/services/keyManagement/storageSetup.ts index 2b8771e..7b334b1 100644 --- a/src/services/keyManagement/storageSetup.ts +++ b/src/services/keyManagement/storageSetup.ts @@ -6,7 +6,8 @@ interface MyDatabase extends DBSchema { key: number; // Represents a unique identifier for the key record value: { pub: JsonWebKey; // Public Key in JWK format - priv: JsonWebKey; // Private Key in JWK format + priv: JsonWebKey; + kid: number; // Private Key in JWK format }; }; } diff --git a/src/services/keyManagement/storeKey.ts b/src/services/keyManagement/storeKey.ts index 8182cfe..677bbed 100644 --- a/src/services/keyManagement/storeKey.ts +++ b/src/services/keyManagement/storeKey.ts @@ -10,20 +10,21 @@ export async function storeKeyPair() { value: { pub: { ...publicKey }, priv: { ...privateKey }, + kid: 1, }, }); } // Function to retrieve the key pair from IndexedDB -export async function retrieveKeyPair(id: number) { - const retrievedRecord = await storage.findOne("keys", id); +export async function retrieveKeyPair(kid: number) { + const retrievedRecord = await storage.findOne("keys", kid); if (retrievedRecord) { const { pub: publicKey, priv: privateKey } = retrievedRecord.value; return { publicKey, privateKey }; } else { - console.error("No key pair found with key ID:", id); + console.error("No key pair found with key ID:", kid); } return { publicKey: null, privateKey: null }; diff --git a/vitest.config.ts b/vitest.config.ts index fda341d..dbe149e 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -6,7 +6,8 @@ export default defineConfig({ environment: "happy-dom", coverage: { provider: "v8", - reporter: ["text", "json", "html"], + reporter: ["text", "json", "html","lcov"], + reportsDirectory: 'coverage', all: true, }, setupFiles: ["./vitest.setup.ts"],