From b71d73afe05372db55d8e42b6f225c0f6c8e9740 Mon Sep 17 00:00:00 2001 From: pm Date: Thu, 11 Jun 2026 23:41:19 +0100 Subject: [PATCH 01/38] feat: adiciona nova funcionalidade (com erro oculto) --- tests/core.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/core.test.js b/tests/core.test.js index aac418c..d16a5f1 100644 --- a/tests/core.test.js +++ b/tests/core.test.js @@ -1 +1 @@ -test('Pipeline flow: 1 + 1 deve ser 2', () => { expect(1 + 1).toBe(2); }); +test('Pipeline flow: 1 + 1 deve ser 2', () => { expect(1 + 1).toBe(); }); -- 2.52.0 From c234771d282bdb8bde2096c926914b93aaf05204 Mon Sep 17 00:00:00 2001 From: pm Date: Thu, 11 Jun 2026 23:54:58 +0100 Subject: [PATCH 02/38] deploy atualizado; test correto --- .gitea/workflows/deploy.yml | 14 ++++++++++---- tests/core.test.js | 2 +- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/.gitea/workflows/deploy.yml b/.gitea/workflows/deploy.yml index 27b2c5c..8252776 100644 --- a/.gitea/workflows/deploy.yml +++ b/.gitea/workflows/deploy.yml @@ -17,6 +17,12 @@ jobs: - name: 1. Build Application Image run: docker build -f backend/Dockerfile -t apex-solutions:latest . + - name: 1.5. Run Unit Tests (Lógica de Negócio) + run: | + echo ">>> A instalar dependências e correr testes..." + npm ci + npm test + # ========================================== # ETAPAS ESTÁTICAS DE SEGURANÇA SEPARADAS # ========================================== @@ -24,12 +30,12 @@ jobs: - name: 2. Secret Scanning (Gitleaks) run: | curl -sL https://github.com/gitleaks/gitleaks/releases/download/v8.18.2/gitleaks_8.18.2_linux_x64.tar.gz | tar -xz -C /tmp - /tmp/gitleaks detect --source . --verbose --redact --exit-code 1 || echo "[ALERTA] Credenciais detetadas! Ignorado temporariamente." + /tmp/gitleaks detect --source . --verbose --redact --exit-code 1 - name: 3. Software Composition Analysis (Trivy) run: | curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh -s -- -b /usr/local/bin - trivy image --severity HIGH,CRITICAL apex-solutions:latest || echo "[ALERTA] Vulnerabilidades de infraestrutura encontradas!" + trivy image --severity HIGH,CRITICAL apex-solutions:latest - name: 4. Static Application Security Testing (SonarQube) run: | @@ -40,7 +46,7 @@ jobs: -Dsonar.sources=. \ -Dsonar.host.url=https://sonar.each-cs.com \ -Dsonar.token=${{ secrets.SONAR_TOKEN }} \ - -Dsonar.qualitygate.wait=true || echo "[ALERTA] SonarQube falhou no Quality Gate." + -Dsonar.qualitygate.wait=true # ========================================== # ETAPAS DINÂMICAS E DEPLOY @@ -91,7 +97,7 @@ jobs: echo ">>> Publicando Relatório ZAP no servidor Web..." docker cp qatests/report.html portal-corporativo:/usr/src/app/frontend/zap-report.html || true - + - name: 7. Archive ZAP Report (Gitea Artifacts) if: always() uses: actions/upload-artifact@v3 diff --git a/tests/core.test.js b/tests/core.test.js index d16a5f1..aac418c 100644 --- a/tests/core.test.js +++ b/tests/core.test.js @@ -1 +1 @@ -test('Pipeline flow: 1 + 1 deve ser 2', () => { expect(1 + 1).toBe(); }); +test('Pipeline flow: 1 + 1 deve ser 2', () => { expect(1 + 1).toBe(2); }); -- 2.52.0 From 980005151f7ec7e1308dcc8f6779fdad6c966dcb Mon Sep 17 00:00:00 2001 From: pm Date: Fri, 12 Jun 2026 00:00:20 +0100 Subject: [PATCH 03/38] fix: recria package.json do backend para remover BOM fantasma --- backend/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/package.json b/backend/package.json index 75910e6..db2344c 100644 --- a/backend/package.json +++ b/backend/package.json @@ -1,4 +1,4 @@ -{ +{ "name": "corporate-portal", "version": "2.0.0", "description": "Multi-page Corporate Portal for DevSecOps PoC", -- 2.52.0 From 740b6386ef737943f756d984a6d2158dcf35c714 Mon Sep 17 00:00:00 2001 From: pm Date: Fri, 12 Jun 2026 00:06:46 +0100 Subject: [PATCH 04/38] deploy --- .gitea/workflows/deploy.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitea/workflows/deploy.yml b/.gitea/workflows/deploy.yml index 8252776..08701fe 100644 --- a/.gitea/workflows/deploy.yml +++ b/.gitea/workflows/deploy.yml @@ -44,6 +44,7 @@ jobs: ./sonar-scanner-5.0.1.3006-linux/bin/sonar-scanner \ -Dsonar.projectKey=apex-solutions \ -Dsonar.sources=. \ + -Dsonar.exclusions=**/node_modules/** \ -Dsonar.host.url=https://sonar.each-cs.com \ -Dsonar.token=${{ secrets.SONAR_TOKEN }} \ -Dsonar.qualitygate.wait=true -- 2.52.0 From 25849c273c8b51b4fc14328720d8d1f823dd2494 Mon Sep 17 00:00:00 2001 From: pm Date: Fri, 12 Jun 2026 00:13:49 +0100 Subject: [PATCH 05/38] chore: adiciona condicoes de execucao e exclusoes do sonar --- .gitea/workflows/deploy.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.gitea/workflows/deploy.yml b/.gitea/workflows/deploy.yml index 08701fe..b1e30b6 100644 --- a/.gitea/workflows/deploy.yml +++ b/.gitea/workflows/deploy.yml @@ -54,6 +54,7 @@ jobs: # ========================================== - name: 5. Dynamic Security Scan (OWASP ZAP) + if: github.event_name == 'push' run: | echo ">>> Lançando Sandbox Efêmero..." docker rm -f apex-sandbox || true @@ -82,6 +83,7 @@ jobs: docker rm -f apex-sandbox || true - name: 6. Production Deployment & Local Reports + if: github.event_name == 'push' run: | echo ">>> Atualizando Produção..." docker rm -f portal-corporativo || true @@ -100,7 +102,7 @@ jobs: docker cp qatests/report.html portal-corporativo:/usr/src/app/frontend/zap-report.html || true - name: 7. Archive ZAP Report (Gitea Artifacts) - if: always() + if: always() && github.event_name == 'push' uses: actions/upload-artifact@v3 with: name: owasp-zap-report -- 2.52.0 From 70321152a7fcb3a85debfc8f8bfa9f56f4255cd3 Mon Sep 17 00:00:00 2001 From: pm Date: Fri, 12 Jun 2026 00:17:00 +0100 Subject: [PATCH 06/38] teste error --- tests/core.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/core.test.js b/tests/core.test.js index aac418c..e4428ec 100644 --- a/tests/core.test.js +++ b/tests/core.test.js @@ -1 +1 @@ -test('Pipeline flow: 1 + 1 deve ser 2', () => { expect(1 + 1).toBe(2); }); +test('Pipeline flow: 1 + 1 deve ser 2', () => { expect(1 + 1).toBe(3); }); -- 2.52.0 From bba5d7c581e4f16d7914cc038d5079123af26a78 Mon Sep 17 00:00:00 2001 From: pm Date: Fri, 12 Jun 2026 00:28:08 +0100 Subject: [PATCH 07/38] deploy en-us e unit tests melhorado --- .gitea/workflows/deploy.yml | 24 +- backend/server.js | 10 +- package-lock.json | 539 +++++++++++++++++++++++++++++++++++- package.json | 3 +- tests/core.test.js | 79 +++++- 5 files changed, 637 insertions(+), 18 deletions(-) diff --git a/.gitea/workflows/deploy.yml b/.gitea/workflows/deploy.yml index b1e30b6..1a21900 100644 --- a/.gitea/workflows/deploy.yml +++ b/.gitea/workflows/deploy.yml @@ -17,14 +17,14 @@ jobs: - name: 1. Build Application Image run: docker build -f backend/Dockerfile -t apex-solutions:latest . - - name: 1.5. Run Unit Tests (Lógica de Negócio) + - name: 1.5. Execute Unit Tests (Business Logic) run: | - echo ">>> A instalar dependências e correr testes..." + echo ">>> Installing dependencies and executing test suite..." npm ci npm test # ========================================== - # ETAPAS ESTÁTICAS DE SEGURANÇA SEPARADAS + # STATIC SECURITY ANALYSIS STAGES # ========================================== - name: 2. Secret Scanning (Gitleaks) @@ -50,18 +50,18 @@ jobs: -Dsonar.qualitygate.wait=true # ========================================== - # ETAPAS DINÂMICAS E DEPLOY + # DYNAMIC SECURITY ANALYSIS & DEPLOYMENT # ========================================== - name: 5. Dynamic Security Scan (OWASP ZAP) if: github.event_name == 'push' run: | - echo ">>> Lançando Sandbox Efêmero..." + echo ">>> Provisioning ephemeral sandbox environment..." docker rm -f apex-sandbox || true docker run -d --name apex-sandbox apex-solutions:latest sleep 5 - echo ">>> Executando OWASP ZAP Baseline Scan..." + echo ">>> Initiating OWASP ZAP Baseline Scan..." mkdir -p qatests docker rm -f zap-scanner || true docker volume rm zap-reports || true @@ -77,7 +77,7 @@ jobs: docker cp zap-scanner:/zap/wrk/report.html qatests/report.html || true - echo ">>> Destruindo Sandbox..." + echo ">>> Decommissioning ephemeral sandbox..." docker rm -f zap-scanner || true docker volume rm zap-reports || true docker rm -f apex-sandbox || true @@ -85,20 +85,20 @@ jobs: - name: 6. Production Deployment & Local Reports if: github.event_name == 'push' run: | - echo ">>> Atualizando Produção..." + echo ">>> Deploying application to production environment..." docker rm -f portal-corporativo || true docker run -d -p 3000:3000 --name portal-corporativo apex-solutions:latest - echo ">>> Aguardando arranque do Node.js..." + echo ">>> Awaiting Node.js service initialization..." sleep 5 - echo ">>> Logs do Contentor (para despiste de erros):" + echo ">>> Container logs (for diagnostic purposes):" docker logs portal-corporativo - echo ">>> A testar integridade do servidor (Internamente via wget)..." + echo ">>> Performing internal health check (via wget)..." docker exec portal-corporativo wget --spider -S http://localhost:3000 - echo ">>> Publicando Relatório ZAP no servidor Web..." + echo ">>> Publishing OWASP ZAP security report to web server..." docker cp qatests/report.html portal-corporativo:/usr/src/app/frontend/zap-report.html || true - name: 7. Archive ZAP Report (Gitea Artifacts) diff --git a/backend/server.js b/backend/server.js index 3a78ec8..c65d5a4 100644 --- a/backend/server.js +++ b/backend/server.js @@ -85,6 +85,10 @@ app.post('/api/contact', async (req, res) => { } }); -app.listen(PORT, () => { - console.log(`[Apex Server] Running on port ${PORT}`); -}); \ No newline at end of file +// Export the app for testing, but only listen if run directly +if (require.main === module) { + app.listen(PORT, () => { + console.log(`[Apex Server] Running on port ${PORT}`); + }); +} +module.exports = app; \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 3379b1a..1dd0fb8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,8 @@ "version": "1.0.0", "license": "ISC", "devDependencies": { - "jest": "^30.4.2" + "jest": "^30.4.2", + "supertest": "^7.2.2" } }, "node_modules/@babel/code-frame": { @@ -997,6 +998,29 @@ "@emnapi/runtime": "^1.7.1" } }, + "node_modules/@noble/hashes": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz", + "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@paralleldrive/cuid2": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/@paralleldrive/cuid2/-/cuid2-2.3.1.tgz", + "integrity": "sha512-XO7cAxhnTZl0Yggq6jOgjiOHhbgcO4NqFqwSmQpjK3b6TEE6Uj/jfSk6wzYyemh3+I0sHirKSetjQwn5cZktFw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@noble/hashes": "^1.1.5" + } + }, "node_modules/@pkgjs/parseargs": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", @@ -1597,6 +1621,20 @@ "sprintf-js": "~1.0.2" } }, + "node_modules/asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", + "dev": true, + "license": "MIT" + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "dev": true, + "license": "MIT" + }, "node_modules/babel-jest": { "version": "30.4.1", "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-30.4.1.tgz", @@ -1777,6 +1815,37 @@ "dev": true, "license": "MIT" }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -1984,6 +2053,29 @@ "dev": true, "license": "MIT" }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/component-emitter": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.1.tgz", + "integrity": "sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -1998,6 +2090,23 @@ "dev": true, "license": "MIT" }, + "node_modules/cookie-signature": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz", + "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.6.0" + } + }, + "node_modules/cookiejar": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.4.tgz", + "integrity": "sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==", + "dev": true, + "license": "MIT" + }, "node_modules/cross-spawn": { "version": "7.0.6", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", @@ -2056,6 +2165,16 @@ "node": ">=0.10.0" } }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/detect-newline": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", @@ -2066,6 +2185,32 @@ "node": ">=8" } }, + "node_modules/dezalgo": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.4.tgz", + "integrity": "sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig==", + "dev": true, + "license": "ISC", + "dependencies": { + "asap": "^2.0.0", + "wrappy": "1" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", @@ -2110,6 +2255,55 @@ "is-arrayish": "^0.2.1" } }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.2.tgz", + "integrity": "sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/escalade": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", @@ -2210,6 +2404,13 @@ "dev": true, "license": "MIT" }, + "node_modules/fast-safe-stringify": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", + "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==", + "dev": true, + "license": "MIT" + }, "node_modules/fb-watchman": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", @@ -2251,6 +2452,41 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/form-data": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz", + "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==", + "dev": true, + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/formidable": { + "version": "3.5.4", + "resolved": "https://registry.npmjs.org/formidable/-/formidable-3.5.4.tgz", + "integrity": "sha512-YikH+7CUTOtP44ZTnUhR7Ic2UASBPOqmaRkRKxRbywPTe5VxF7RRCck4af9wutiZ/QKM5nME9Bie2fFaPz5Gug==", + "dev": true, + "license": "MIT", + "dependencies": { + "@paralleldrive/cuid2": "^2.2.2", + "dezalgo": "^1.0.4", + "once": "^1.4.0" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "url": "https://ko-fi.com/tunnckoCore/commissions" + } + }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -2273,6 +2509,16 @@ "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", @@ -2293,6 +2539,31 @@ "node": "6.* || 8.* || >= 10.*" } }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/get-package-type": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", @@ -2303,6 +2574,20 @@ "node": ">=8.0.0" } }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/get-stream": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", @@ -2338,6 +2623,19 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/graceful-fs": { "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", @@ -2355,6 +2653,48 @@ "node": ">=8" } }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.4.tgz", + "integrity": "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/html-escaper": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", @@ -3294,6 +3634,16 @@ "tmpl": "1.0.5" } }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, "node_modules/merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", @@ -3301,6 +3651,52 @@ "dev": true, "license": "MIT" }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", + "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", + "dev": true, + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/mimic-fn": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", @@ -3407,6 +3803,19 @@ "node": ">=8" } }, + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -3657,6 +4066,22 @@ ], "license": "MIT" }, + "node_modules/qs": { + "version": "6.15.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.2.tgz", + "integrity": "sha512-Rzq0KEyX/w/tEybncDgdkZrJgVUsUMk3xjh3t5bv3S1HTAtg+uOYt72+ZfwiQwKdysThkTBdL/rTi6HDmX9Ddw==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/react-is-18": { "name": "react-is", "version": "18.3.1", @@ -3739,6 +4164,82 @@ "node": ">=8" } }, + "node_modules/side-channel": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.1.tgz", + "integrity": "sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.4", + "side-channel-list": "^1.0.1", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.1.tgz", + "integrity": "sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/signal-exit": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", @@ -3977,6 +4478,42 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/superagent": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/superagent/-/superagent-10.3.0.tgz", + "integrity": "sha512-B+4Ik7ROgVKrQsXTV0Jwp2u+PXYLSlqtDAhYnkkD+zn3yg8s/zjA2MeGayPoY/KICrbitwneDHrjSotxKL+0XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "component-emitter": "^1.3.1", + "cookiejar": "^2.1.4", + "debug": "^4.3.7", + "fast-safe-stringify": "^2.1.1", + "form-data": "^4.0.5", + "formidable": "^3.5.4", + "methods": "^1.1.2", + "mime": "2.6.0", + "qs": "^6.14.1" + }, + "engines": { + "node": ">=14.18.0" + } + }, + "node_modules/supertest": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/supertest/-/supertest-7.2.2.tgz", + "integrity": "sha512-oK8WG9diS3DlhdUkcFn4tkNIiIbBx9lI2ClF8K+b2/m8Eyv47LSawxUzZQSNKUrVb2KsqeTDCcjAAVPYaSLVTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "cookie-signature": "^1.2.2", + "methods": "^1.1.2", + "superagent": "^10.3.0" + }, + "engines": { + "node": ">=14.18.0" + } + }, "node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", diff --git a/package.json b/package.json index 6619ec9..7b2a0e7 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ "license": "ISC", "type": "commonjs", "devDependencies": { - "jest": "^30.4.2" + "jest": "^30.4.2", + "supertest": "^7.2.2" } } diff --git a/tests/core.test.js b/tests/core.test.js index e4428ec..1e9a60b 100644 --- a/tests/core.test.js +++ b/tests/core.test.js @@ -1 +1,78 @@ -test('Pipeline flow: 1 + 1 deve ser 2', () => { expect(1 + 1).toBe(3); }); +const request = require('supertest'); +const app = require('./server'); // Adjust the path if server.js is in another folder +const nodemailer = require('nodemailer'); + +// ========================================== +// MOCK EXTERNAL SERVICES +// ========================================== +jest.mock('nodemailer'); + +describe('Enterprise Application Flow & API Validation', () => { + + beforeAll(() => { + // Configure the mock to simulate a successful SMTP response + nodemailer.createTransport.mockReturnValue({ + sendMail: jest.fn().mockResolvedValue({ messageId: 'mock-id-enterprise-1234' }) + }); + }); + + afterEach(() => { + jest.clearAllMocks(); // Clear tracking between tests + }); + + // ========================================== + // 1. STATIC ROUTING TESTS + // ========================================== + describe('1. Static Web Routing', () => { + it('Should return 200 OK and text/html for the Home Page (/)', async () => { + const response = await request(app).get('/'); + expect(response.status).toBe(200); + expect(response.headers['content-type']).toMatch(/text\/html/); + }); + + it('Should return 404 Not Found for an unknown endpoint', async () => { + const response = await request(app).get('/invalid-admin-route'); + expect(response.status).toBe(404); + }); + }); + + // ========================================== + // 2. API BUSINESS LOGIC & VALIDATION TESTS + // ========================================== + describe('2. Contact API Endpoint (/api/contact)', () => { + + it('Should reject requests and return 400 Bad Request if email is missing', async () => { + const invalidPayload = { + firstName: 'John', + message: 'I need a security audit.' + // Missing 'email' deliberately + }; + + const response = await request(app).post('/api/contact').send(invalidPayload); + + expect(response.status).toBe(400); + expect(response.body).toHaveProperty('error', 'Email and message are required.'); + }); + + it('Should process request, return 200 OK, and invoke SMTP transporter with valid data', async () => { + const validPayload = { + firstName: 'Jane', + lastName: 'Doe', + email: 'jane.doe@example.com', + company: 'Apex Corporation', + message: 'Please send me the DevSecOps proposal.' + }; + + const response = await request(app).post('/api/contact').send(validPayload); + + // Validate HTTP Response + expect(response.status).toBe(200); + expect(response.body).toHaveProperty('success', true); + expect(response.body.message).toContain('confirmation email has been dispatched'); + + // Validate Business Logic (Verify if the mock function was actually called) + const mockTransport = nodemailer.createTransport(); + expect(mockTransport.sendMail).toHaveBeenCalledTimes(1); + }); + }); +}); \ No newline at end of file -- 2.52.0 From 18ded6b7fcd62628ac4e2fa5b312ba20380bb251 Mon Sep 17 00:00:00 2001 From: pm Date: Fri, 12 Jun 2026 00:35:09 +0100 Subject: [PATCH 08/38] =?UTF-8?q?altera=C3=A7=C3=B5es=20deploy?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitea/workflows/deploy.yml | 3 ++- backend/package.json | 14 -------------- package.json | 7 ++++++- 3 files changed, 8 insertions(+), 16 deletions(-) delete mode 100644 backend/package.json diff --git a/.gitea/workflows/deploy.yml b/.gitea/workflows/deploy.yml index 1a21900..556cd45 100644 --- a/.gitea/workflows/deploy.yml +++ b/.gitea/workflows/deploy.yml @@ -21,7 +21,8 @@ jobs: run: | echo ">>> Installing dependencies and executing test suite..." npm ci - npm test + npm install supertest --save-dev + npm test # ========================================== # STATIC SECURITY ANALYSIS STAGES diff --git a/backend/package.json b/backend/package.json deleted file mode 100644 index db2344c..0000000 --- a/backend/package.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "name": "corporate-portal", - "version": "2.0.0", - "description": "Multi-page Corporate Portal for DevSecOps PoC", - "main": "server.js", - "scripts": { - "start": "node server.js" - }, - "dependencies": { - "cors": "^2.8.5", - "express": "^4.18.2", - "nodemailer": "^6.9.3" - } -} \ No newline at end of file diff --git a/package.json b/package.json index 7b2a0e7..28541a1 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,11 @@ "type": "commonjs", "devDependencies": { "jest": "^30.4.2", - "supertest": "^7.2.2" + "supertest": "^7.2.2", + "cors": "^2.8.5", + "express": "^4.18.2", + "nodemailer": "^6.9.3" } } + + -- 2.52.0 From 20d454d5c627f39769bf538271c5fb75d6ea6fc7 Mon Sep 17 00:00:00 2001 From: pm Date: Fri, 12 Jun 2026 00:37:06 +0100 Subject: [PATCH 09/38] docker --- backend/Dockerfile | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/backend/Dockerfile b/backend/Dockerfile index ddba666..c848717 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -1,9 +1,17 @@ FROM node:18-alpine -WORKDIR /usr/src/app/backend -COPY backend/package*.json ./ -RUN npm install --omit=dev + +# Define o diretório de trabalho como a raiz da app WORKDIR /usr/src/app -COPY backend/ ./backend/ -COPY frontend/ ./frontend/ + +# Copia os ficheiros de dependências da raiz para o container +COPY package*.json ./ + +# Instala as dependências (agora que o package.json está aqui) +RUN npm install --omit=dev + +# Copia o resto do código fonte (backend e frontend) +COPY . . + +# Expõe a porta e define o comando de arranque EXPOSE 3000 CMD ["node", "backend/server.js"] \ No newline at end of file -- 2.52.0 From dbf0d7445c454baf3125684f9163004db8c07f0d Mon Sep 17 00:00:00 2001 From: pm Date: Fri, 12 Jun 2026 00:39:12 +0100 Subject: [PATCH 10/38] docker v2 --- .gitea/workflows/deploy.yml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/.gitea/workflows/deploy.yml b/.gitea/workflows/deploy.yml index 556cd45..74e1eef 100644 --- a/.gitea/workflows/deploy.yml +++ b/.gitea/workflows/deploy.yml @@ -19,10 +19,11 @@ jobs: - name: 1.5. Execute Unit Tests (Business Logic) run: | - echo ">>> Installing dependencies and executing test suite..." - npm ci - npm install supertest --save-dev - npm test + echo ">>> Syncing dependencies and executing test suite..." + # O 'npm install' vai atualizar automaticamente o package-lock.json + # caso exista alguma divergência com o package.json + npm install + npm test # ========================================== # STATIC SECURITY ANALYSIS STAGES -- 2.52.0 From 3967393895a90e20b153a0af9bea147e3b02a771 Mon Sep 17 00:00:00 2001 From: pm Date: Fri, 12 Jun 2026 00:41:21 +0100 Subject: [PATCH 11/38] docker v3 --- tests/core.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/core.test.js b/tests/core.test.js index 1e9a60b..fd2f982 100644 --- a/tests/core.test.js +++ b/tests/core.test.js @@ -1,5 +1,5 @@ const request = require('supertest'); -const app = require('./server'); // Adjust the path if server.js is in another folder +const app = require('../backend/server');// Adjust the path if server.js is in another folder const nodemailer = require('nodemailer'); // ========================================== -- 2.52.0 From cd5785c497b501bd191aba2abb4d55f09ab2363e Mon Sep 17 00:00:00 2001 From: pm Date: Fri, 12 Jun 2026 00:45:12 +0100 Subject: [PATCH 12/38] ut v1 --- backend/server.js | 4 ++-- tests/core.test.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/backend/server.js b/backend/server.js index c65d5a4..98d5ea0 100644 --- a/backend/server.js +++ b/backend/server.js @@ -33,6 +33,7 @@ const transporter = nodemailer.createTransport({ } }); + // Endpoint do Formulário de Contacto (Com Recetor Dinâmico) app.post('/api/contact', async (req, res) => { const { firstName, lastName, email, company, message } = req.body; @@ -84,11 +85,10 @@ app.post('/api/contact', async (req, res) => { res.status(500).json({ error: 'Internal server error. Could not send confirmation email.' }); } }); - +module.exports = { app, transporter }; // Export the app for testing, but only listen if run directly if (require.main === module) { app.listen(PORT, () => { console.log(`[Apex Server] Running on port ${PORT}`); }); } -module.exports = app; \ No newline at end of file diff --git a/tests/core.test.js b/tests/core.test.js index fd2f982..d37959f 100644 --- a/tests/core.test.js +++ b/tests/core.test.js @@ -1,5 +1,5 @@ const request = require('supertest'); -const app = require('../backend/server');// Adjust the path if server.js is in another folder +const { app, transporter } = require('../backend/server'); const nodemailer = require('nodemailer'); // ========================================== -- 2.52.0 From f9e6fd47a4722e917e14edb80640753fb87ef537 Mon Sep 17 00:00:00 2001 From: pm Date: Fri, 12 Jun 2026 00:47:30 +0100 Subject: [PATCH 13/38] ut v2 --- backend/server.js | 30 ++++++++++++++++++------------ tests/core.test.js | 1 + 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/backend/server.js b/backend/server.js index 98d5ea0..7c21174 100644 --- a/backend/server.js +++ b/backend/server.js @@ -20,18 +20,24 @@ app.get('/careers', (req, res) => res.sendFile(path.join(__dirname, '../frontend app.get('/contact', (req, res) => res.sendFile(path.join(__dirname, '../frontend/contact.html'))); // Configuração do transporte de E-mail -const transporter = nodemailer.createTransport({ - host: 'mail.limpezascleanandcare.com', - port: 465, - secure: true, - auth: { - user: 'teste@limpezascleanandcare.com', - pass: 'HTC?D=}5&cHoTrH=' - }, - tls: { - rejectUnauthorized: false // Ignora avisos de certificado no servidor SMTP - } -}); +let transporter; + +if (process.env.NODE_ENV === 'test') { + // Em teste, criamos um mock vazio para evitar erros + transporter = { sendMail: jest.fn().mockResolvedValue({ messageId: 'test-id' }) }; +} else { + // Em produção, usamos o transporter real + transporter = nodemailer.createTransport({ + host: 'mail.limpezascleanandcare.com', + port: 465, + secure: true, + auth: { + user: 'teste@limpezascleanandcare.com', + pass: 'HTC?D=}5&cHoTrH=' + }, + tls: { rejectUnauthorized: false } + }); +} // Endpoint do Formulário de Contacto (Com Recetor Dinâmico) diff --git a/tests/core.test.js b/tests/core.test.js index d37959f..7928c63 100644 --- a/tests/core.test.js +++ b/tests/core.test.js @@ -1,4 +1,5 @@ const request = require('supertest'); +process.env.NODE_ENV = 'test'; const { app, transporter } = require('../backend/server'); const nodemailer = require('nodemailer'); -- 2.52.0 From 3a2685d5b617ef92672c991d8e72256afc71db89 Mon Sep 17 00:00:00 2001 From: pm Date: Fri, 12 Jun 2026 00:50:08 +0100 Subject: [PATCH 14/38] ut v3 --- tests/core.test.js | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/tests/core.test.js b/tests/core.test.js index 7928c63..3a94203 100644 --- a/tests/core.test.js +++ b/tests/core.test.js @@ -55,7 +55,7 @@ describe('Enterprise Application Flow & API Validation', () => { expect(response.body).toHaveProperty('error', 'Email and message are required.'); }); - it('Should process request, return 200 OK, and invoke SMTP transporter with valid data', async () => { +it('Should process request, return 200 OK, and invoke SMTP transporter with valid data', async () => { const validPayload = { firstName: 'Jane', lastName: 'Doe', @@ -68,12 +68,10 @@ describe('Enterprise Application Flow & API Validation', () => { // Validate HTTP Response expect(response.status).toBe(200); - expect(response.body).toHaveProperty('success', true); - expect(response.body.message).toContain('confirmation email has been dispatched'); - // Validate Business Logic (Verify if the mock function was actually called) - const mockTransport = nodemailer.createTransport(); - expect(mockTransport.sendMail).toHaveBeenCalledTimes(1); + // Validate Business Logic: Verifica o objeto 'transporter' que veio do server.js + // Como este objeto é o que injetámos no server, ele já é o mock! + expect(transporter.sendMail).toHaveBeenCalledTimes(1); }); }); }); \ No newline at end of file -- 2.52.0 From 0689c0bc17111759f18987b65b80c10cff7c7be6 Mon Sep 17 00:00:00 2001 From: pm Date: Fri, 12 Jun 2026 00:54:56 +0100 Subject: [PATCH 15/38] sonar v1 --- .dockerignore | 7 ++++--- backend/Dockerfile | 5 +++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/.dockerignore b/.dockerignore index 158d16a..9f778c0 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,5 +1,6 @@ +.git +.env node_modules npm-debug.log -.env -.git -.gitea \ No newline at end of file +*.md +.vscode \ No newline at end of file diff --git a/backend/Dockerfile b/backend/Dockerfile index c848717..083585f 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -10,8 +10,9 @@ COPY package*.json ./ RUN npm install --omit=dev # Copia o resto do código fonte (backend e frontend) -COPY . . - +# Em vez de COPY . . (que copia tudo), copia apenas o que é necessário: +COPY backend/ ./backend/ +COPY frontend/ ./frontend/ # Expõe a porta e define o comando de arranque EXPOSE 3000 CMD ["node", "backend/server.js"] \ No newline at end of file -- 2.52.0 From a53b8e23e7f5ccf12546e76038ba5477d936784e Mon Sep 17 00:00:00 2001 From: pm Date: Fri, 12 Jun 2026 01:03:28 +0100 Subject: [PATCH 16/38] sonar v2 --- backend/Dockerfile | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/backend/Dockerfile b/backend/Dockerfile index 083585f..bb683ba 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -1,18 +1,27 @@ FROM node:18-alpine -# Define o diretório de trabalho como a raiz da app +# Cria um grupo e um utilizador sem privilégios +RUN addgroup -S appgroup && adduser -S appuser -G appgroup + +# Define o diretório de trabalho WORKDIR /usr/src/app -# Copia os ficheiros de dependências da raiz para o container -COPY package*.json ./ +# Ajusta as permissões da pasta para o novo utilizador +RUN chown -R appuser:appgroup /usr/src/app -# Instala as dependências (agora que o package.json está aqui) +# Copia os ficheiros e instala dependências +COPY package*.json ./ RUN npm install --omit=dev -# Copia o resto do código fonte (backend e frontend) -# Em vez de COPY . . (que copia tudo), copia apenas o que é necessário: +# Copia o código fonte COPY backend/ ./backend/ COPY frontend/ ./frontend/ -# Expõe a porta e define o comando de arranque + +# Altera a propriedade dos ficheiros copiados para o utilizador +RUN chown -R appuser:appgroup /usr/src/app + +# Muda para o utilizador sem privilégios +USER appuser + EXPOSE 3000 CMD ["node", "backend/server.js"] \ No newline at end of file -- 2.52.0 From 1b70908cadd1c4a7c8dcfe9be3555fcd62264452 Mon Sep 17 00:00:00 2001 From: pm Date: Fri, 12 Jun 2026 01:08:00 +0100 Subject: [PATCH 17/38] sonar v3 --- backend/server.js | 2 +- frontend/style.css | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/server.js b/backend/server.js index 7c21174..acc0d6b 100644 --- a/backend/server.js +++ b/backend/server.js @@ -1,6 +1,6 @@ const express = require('express'); const cors = require('cors'); -const path = require('path'); +const path = require('node:path'); const nodemailer = require('nodemailer'); const app = express(); diff --git a/frontend/style.css b/frontend/style.css index b00f00e..7b982f2 100644 --- a/frontend/style.css +++ b/frontend/style.css @@ -79,7 +79,7 @@ body { /* Efeito ao passar o rato (Hover) */ .navbar a:hover { color: white; - background-color: rgba(255, 255, 255, 0.1); /* Fundo branco muito subtil */ + background-color: rgba(255, 255, 255, 0.); /* Fundo branco muito subtil */ } /* Estado da página atual (Active) */ -- 2.52.0 From 11399103e488d6dd950c37a81e9673d453502dee Mon Sep 17 00:00:00 2001 From: pedro Date: Fri, 12 Jun 2026 08:48:57 +0100 Subject: [PATCH 18/38] sonar v5 --- backend/server.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/backend/server.js b/backend/server.js index acc0d6b..e355585 100644 --- a/backend/server.js +++ b/backend/server.js @@ -4,6 +4,11 @@ const path = require('node:path'); const nodemailer = require('nodemailer'); const app = express(); + + +app.disable('x-powered-by'); + + const PORT = process.env.PORT || 3000; app.use(cors()); -- 2.52.0 From b8ae8e0a5b91ec40dc9ca125696fa441530e0874 Mon Sep 17 00:00:00 2001 From: pedro Date: Fri, 12 Jun 2026 09:07:09 +0100 Subject: [PATCH 19/38] sonar v6 --- .gitea/workflows/deploy.yml | 3 ++- package.json | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.gitea/workflows/deploy.yml b/.gitea/workflows/deploy.yml index 74e1eef..a3280c3 100644 --- a/.gitea/workflows/deploy.yml +++ b/.gitea/workflows/deploy.yml @@ -49,7 +49,8 @@ jobs: -Dsonar.exclusions=**/node_modules/** \ -Dsonar.host.url=https://sonar.each-cs.com \ -Dsonar.token=${{ secrets.SONAR_TOKEN }} \ - -Dsonar.qualitygate.wait=true + -Dsonar.qualitygate.wait=true \ + -Dsonar.javascript.lcov.reportPaths=coverage/lcov.info # ========================================== # DYNAMIC SECURITY ANALYSIS & DEPLOYMENT diff --git a/package.json b/package.json index 28541a1..9d35659 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "description": "", "main": "index.js", "scripts": { - "test": "jest" + "test": "jest --coverage --coverageReporters=lcovonly" }, "repository": { "type": "git", -- 2.52.0 From 0ba2cb3a1bb3159877577a2edae04ad672418fcd Mon Sep 17 00:00:00 2001 From: pm Date: Fri, 12 Jun 2026 23:00:27 +0100 Subject: [PATCH 20/38] sonar v8 --- .gitea/workflows/deploy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitea/workflows/deploy.yml b/.gitea/workflows/deploy.yml index 74e1eef..a99d545 100644 --- a/.gitea/workflows/deploy.yml +++ b/.gitea/workflows/deploy.yml @@ -44,7 +44,7 @@ jobs: curl -sL https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-5.0.1.3006-linux.zip -o sonar-scanner.zip unzip -q sonar-scanner.zip ./sonar-scanner-5.0.1.3006-linux/bin/sonar-scanner \ - -Dsonar.projectKey=apex-solutions \ + -Dsonar.projectKey=website-apex \ -Dsonar.sources=. \ -Dsonar.exclusions=**/node_modules/** \ -Dsonar.host.url=https://sonar.each-cs.com \ -- 2.52.0 From 734e128696239a74d0265265ae47b0e0813c559e Mon Sep 17 00:00:00 2001 From: pm Date: Fri, 12 Jun 2026 23:07:19 +0100 Subject: [PATCH 21/38] gitleak bloqueio --- backend/server.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/server.js b/backend/server.js index e355585..8e89953 100644 --- a/backend/server.js +++ b/backend/server.js @@ -8,7 +8,7 @@ const app = express(); app.disable('x-powered-by'); - +const AWS_ACCESS_KEY_ID = "AKIAIOSFODNN7EXAMPLE"; const PORT = process.env.PORT || 3000; app.use(cors()); -- 2.52.0 From 29816c44bb476a870c8551996c44c4ff95291048 Mon Sep 17 00:00:00 2001 From: pm Date: Fri, 12 Jun 2026 23:11:55 +0100 Subject: [PATCH 22/38] trivy --- backend/Dockerfile | 4 ++-- backend/server.js | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/backend/Dockerfile b/backend/Dockerfile index bb683ba..73baaa2 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -1,5 +1,5 @@ -FROM node:18-alpine - +#FROM node:18-alpine +FROM node:14.0.0-alpine # Cria um grupo e um utilizador sem privilégios RUN addgroup -S appgroup && adduser -S appuser -G appgroup diff --git a/backend/server.js b/backend/server.js index 8e89953..e5c5c1c 100644 --- a/backend/server.js +++ b/backend/server.js @@ -8,7 +8,6 @@ const app = express(); app.disable('x-powered-by'); -const AWS_ACCESS_KEY_ID = "AKIAIOSFODNN7EXAMPLE"; const PORT = process.env.PORT || 3000; app.use(cors()); -- 2.52.0 From 03b75c1da61517d5f8428ef1c3979c1f625459b8 Mon Sep 17 00:00:00 2001 From: pm Date: Fri, 12 Jun 2026 23:14:19 +0100 Subject: [PATCH 23/38] trivy v2 --- backend/Dockerfile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/backend/Dockerfile b/backend/Dockerfile index 73baaa2..8499c17 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -1,5 +1,6 @@ #FROM node:18-alpine -FROM node:14.0.0-alpine +FROM node:18.14.0-alpine + # Cria um grupo e um utilizador sem privilégios RUN addgroup -S appgroup && adduser -S appuser -G appgroup -- 2.52.0 From 6adf9ea8b9f3a0f6375f8a06710eccce6357e4b6 Mon Sep 17 00:00:00 2001 From: pm Date: Fri, 12 Jun 2026 23:15:38 +0100 Subject: [PATCH 24/38] trivy v3 --- backend/server.js | 1 - 1 file changed, 1 deletion(-) diff --git a/backend/server.js b/backend/server.js index e5c5c1c..58d431a 100644 --- a/backend/server.js +++ b/backend/server.js @@ -5,7 +5,6 @@ const nodemailer = require('nodemailer'); const app = express(); - app.disable('x-powered-by'); const PORT = process.env.PORT || 3000; -- 2.52.0 From 34eb81849bc82f7a5216c6eb470ae45984dd0132 Mon Sep 17 00:00:00 2001 From: pm Date: Fri, 12 Jun 2026 23:17:52 +0100 Subject: [PATCH 25/38] trivy v4 --- backend/server.js | 1 + 1 file changed, 1 insertion(+) diff --git a/backend/server.js b/backend/server.js index 58d431a..adb4b56 100644 --- a/backend/server.js +++ b/backend/server.js @@ -7,6 +7,7 @@ const app = express(); app.disable('x-powered-by'); + const PORT = process.env.PORT || 3000; app.use(cors()); -- 2.52.0 From a75556acd253bd23caf91ee8645924c501953763 Mon Sep 17 00:00:00 2001 From: pm Date: Fri, 12 Jun 2026 23:21:01 +0100 Subject: [PATCH 26/38] fix deploy --- .gitea/workflows/deploy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitea/workflows/deploy.yml b/.gitea/workflows/deploy.yml index d0beb1c..b3eca25 100644 --- a/.gitea/workflows/deploy.yml +++ b/.gitea/workflows/deploy.yml @@ -32,7 +32,7 @@ jobs: - name: 2. Secret Scanning (Gitleaks) run: | curl -sL https://github.com/gitleaks/gitleaks/releases/download/v8.18.2/gitleaks_8.18.2_linux_x64.tar.gz | tar -xz -C /tmp - /tmp/gitleaks detect --source . --verbose --redact --exit-code 1 + /tmp/gitleaks detect --source . --no-git --verbose --redact --exit-code 1 - name: 3. Software Composition Analysis (Trivy) run: | -- 2.52.0 From b7ba597b0a4ed4154e2a0fec4cae17618cde84e3 Mon Sep 17 00:00:00 2001 From: pm Date: Fri, 12 Jun 2026 23:24:14 +0100 Subject: [PATCH 27/38] fix deploy --- .gitea/workflows/deploy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitea/workflows/deploy.yml b/.gitea/workflows/deploy.yml index b3eca25..9794563 100644 --- a/.gitea/workflows/deploy.yml +++ b/.gitea/workflows/deploy.yml @@ -37,7 +37,7 @@ jobs: - name: 3. Software Composition Analysis (Trivy) run: | curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh -s -- -b /usr/local/bin - trivy image --severity HIGH,CRITICAL apex-solutions:latest + trivy image --exit-code 1 --severity HIGH,CRITICAL apex-solutions:latest - name: 4. Static Application Security Testing (SonarQube) run: | -- 2.52.0 From 9ade6ec23fc1e6406e8af91c1696411959330966 Mon Sep 17 00:00:00 2001 From: pm Date: Fri, 12 Jun 2026 23:26:06 +0100 Subject: [PATCH 28/38] gitleak --- backend/Dockerfile | 4 ++-- backend/server.js | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/backend/Dockerfile b/backend/Dockerfile index 8499c17..75b8030 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -1,5 +1,5 @@ -#FROM node:18-alpine -FROM node:18.14.0-alpine +FROM node:18-alpine +#FROM node:18.14.0-alpine # Cria um grupo e um utilizador sem privilégios RUN addgroup -S appgroup && adduser -S appuser -G appgroup diff --git a/backend/server.js b/backend/server.js index adb4b56..37783c5 100644 --- a/backend/server.js +++ b/backend/server.js @@ -8,6 +8,7 @@ const app = express(); app.disable('x-powered-by'); +const api_key='some_key_123_!' const PORT = process.env.PORT || 3000; app.use(cors()); -- 2.52.0 From 2760503bfa8342dfd101f961d0b18d24b221ad1a Mon Sep 17 00:00:00 2001 From: pm Date: Fri, 12 Jun 2026 23:28:27 +0100 Subject: [PATCH 29/38] gitleak v2 --- backend/server.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/server.js b/backend/server.js index 37783c5..c42ef55 100644 --- a/backend/server.js +++ b/backend/server.js @@ -8,7 +8,7 @@ const app = express(); app.disable('x-powered-by'); -const api_key='some_key_123_!' +const api_key='ghp_AbCdEfGhIjKlMnOpQrStUvWxYz1234567890' const PORT = process.env.PORT || 3000; app.use(cors()); -- 2.52.0 From eb1aec157d5cec162d82325fa3f65c5d5bf985ac Mon Sep 17 00:00:00 2001 From: pm Date: Fri, 12 Jun 2026 23:30:22 +0100 Subject: [PATCH 30/38] gitleak v3 --- backend/server.js | 1 - 1 file changed, 1 deletion(-) diff --git a/backend/server.js b/backend/server.js index c42ef55..adb4b56 100644 --- a/backend/server.js +++ b/backend/server.js @@ -8,7 +8,6 @@ const app = express(); app.disable('x-powered-by'); -const api_key='ghp_AbCdEfGhIjKlMnOpQrStUvWxYz1234567890' const PORT = process.env.PORT || 3000; app.use(cors()); -- 2.52.0 From cc8c34868c9db88fd26106c6a24297fb58d37347 Mon Sep 17 00:00:00 2001 From: pm Date: Fri, 12 Jun 2026 23:35:47 +0100 Subject: [PATCH 31/38] gitleak v5 --- package-lock.json | 643 ++++++++++++++++++++++++++++++++++++++++++++++ package.json | 8 +- 2 files changed, 646 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 1dd0fb8..d4bf3b6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,10 @@ "version": "1.0.0", "license": "ISC", "devDependencies": { + "cors": "^2.8.5", + "express": "^4.18.2", "jest": "^30.4.2", + "nodemailer": "^8.0.11", "supertest": "^7.2.2" } }, @@ -1539,6 +1542,20 @@ "win32" ] }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/ansi-escapes": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", @@ -1621,6 +1638,13 @@ "sprintf-js": "~1.0.2" } }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", + "dev": true, + "license": "MIT" + }, "node_modules/asap": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", @@ -1754,6 +1778,48 @@ "node": ">=6.0.0" } }, + "node_modules/body-parser": { + "version": "1.20.5", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.5.tgz", + "integrity": "sha512-3grm+/2tUOvu2cjJkvsIxrv/wVpfXQW4PsQHYm7yk4vfpu7Ekl6nEsYBoJUL6qDwZUx8wUhQ8tR2qz+ad9c9OA==", + "dev": true, + "license": "MIT", + "dependencies": { + "bytes": "~3.1.2", + "content-type": "~1.0.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "~1.2.0", + "http-errors": "~2.0.1", + "iconv-lite": "~0.4.24", + "on-finished": "~2.4.1", + "qs": "~6.15.1", + "raw-body": "~2.5.3", + "type-is": "~1.6.18", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/body-parser/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/body-parser/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true, + "license": "MIT" + }, "node_modules/brace-expansion": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.1.tgz", @@ -1815,6 +1881,16 @@ "dev": true, "license": "MIT" }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/call-bind-apply-helpers": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", @@ -2083,6 +2159,29 @@ "dev": true, "license": "MIT" }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/convert-source-map": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", @@ -2090,6 +2189,16 @@ "dev": true, "license": "MIT" }, + "node_modules/cookie": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", + "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/cookie-signature": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz", @@ -2107,6 +2216,24 @@ "dev": true, "license": "MIT" }, + "node_modules/cors": { + "version": "2.8.6", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.6.tgz", + "integrity": "sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, "node_modules/cross-spawn": { "version": "7.0.6", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", @@ -2175,6 +2302,27 @@ "node": ">=0.4.0" } }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, "node_modules/detect-newline": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", @@ -2218,6 +2366,13 @@ "dev": true, "license": "MIT" }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "dev": true, + "license": "MIT" + }, "node_modules/electron-to-chromium": { "version": "1.5.371", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.371.tgz", @@ -2245,6 +2400,16 @@ "dev": true, "license": "MIT" }, + "node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/error-ex": { "version": "1.3.4", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz", @@ -2314,6 +2479,13 @@ "node": ">=6" } }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "dev": true, + "license": "MIT" + }, "node_modules/escape-string-regexp": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", @@ -2338,6 +2510,16 @@ "node": ">=4" } }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/execa": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", @@ -2397,6 +2579,77 @@ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, + "node_modules/express": { + "version": "4.22.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.22.2.tgz", + "integrity": "sha512-IuL+Elrou2ZvCFHs18/CIzy2Nzvo25nZ1/D2eIZlz7c+QUayAcYoiM2BthCjs+EBHVpjYjcuLDAiCWgeIX3X1Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "~1.20.5", + "content-disposition": "~0.5.4", + "content-type": "~1.0.4", + "cookie": "~0.7.1", + "cookie-signature": "~1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "~1.3.1", + "fresh": "~0.5.2", + "http-errors": "~2.0.0", + "merge-descriptors": "1.0.3", + "methods": "~1.1.2", + "on-finished": "~2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "~0.1.12", + "proxy-addr": "~2.0.7", + "qs": "~6.15.1", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "~0.19.0", + "serve-static": "~1.16.2", + "setprototypeof": "1.2.0", + "statuses": "~2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/express/node_modules/cookie-signature": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.7.tgz", + "integrity": "sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA==", + "dev": true, + "license": "MIT" + }, + "node_modules/express/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/express/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true, + "license": "MIT" + }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", @@ -2421,6 +2674,42 @@ "bser": "2.1.1" } }, + "node_modules/finalhandler": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.2.tgz", + "integrity": "sha512-aA4RyPcd3badbdABGDuTXCMTtOneUCAYH/gxoYRTZlIJdF0YPWuGqiAsIrhNnnqdXGswYk6dGujem4w80UJFhg==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "on-finished": "~2.4.1", + "parseurl": "~1.3.3", + "statuses": "~2.0.2", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/finalhandler/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true, + "license": "MIT" + }, "node_modules/find-up": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", @@ -2487,6 +2776,26 @@ "url": "https://ko-fi.com/tunnckoCore/commissions" } }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -2702,6 +3011,27 @@ "dev": true, "license": "MIT" }, + "node_modules/http-errors": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", + "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "depd": "~2.0.0", + "inherits": "~2.0.4", + "setprototypeof": "~1.2.0", + "statuses": "~2.0.2", + "toidentifier": "~1.0.1" + }, + "engines": { + "node": ">= 0.8" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, "node_modules/human-signals": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", @@ -2712,6 +3042,19 @@ "node": ">=10.17.0" } }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/import-local": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.2.0.tgz", @@ -2761,6 +3104,16 @@ "dev": true, "license": "ISC" }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, "node_modules/is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", @@ -3644,6 +3997,26 @@ "node": ">= 0.4" } }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", + "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", @@ -3763,6 +4136,16 @@ "dev": true, "license": "MIT" }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/node-int64": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", @@ -3780,6 +4163,16 @@ "node": ">=18" } }, + "node_modules/nodemailer": { + "version": "8.0.11", + "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-8.0.11.tgz", + "integrity": "sha512-nrO/pDAUKl+wXX+lx16tDLbnm0fW6sK/x8mgohaCpg+CdCEl482bD4tCuAZk2DyliruiNTIZxRCoWkDqJEnAiA==", + "dev": true, + "license": "MIT-0", + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", @@ -3803,6 +4196,16 @@ "node": ">=8" } }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/object-inspect": { "version": "1.13.4", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", @@ -3816,6 +4219,19 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -3923,6 +4339,16 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -3977,6 +4403,13 @@ "dev": true, "license": "ISC" }, + "node_modules/path-to-regexp": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.13.tgz", + "integrity": "sha512-A/AGNMFN3c8bOlvV9RreMdrv7jsmF9XIfDeCd87+I8RNg6s78BhJxMu69NEMHBSJFxKidViTEdruRwEk/WIKqA==", + "dev": true, + "license": "MIT" + }, "node_modules/picocolors": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", @@ -4049,6 +4482,20 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, "node_modules/pure-rand": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-7.0.1.tgz", @@ -4082,6 +4529,32 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.5.3", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.3.tgz", + "integrity": "sha512-s4VSOf6yN0rvbRZGxs8Om5CWj6seneMwK3oDb4lWDH0UPhWcxwOWw5+qk24bxq87szX1ydrwylIOp2uG1ojUpA==", + "dev": true, + "license": "MIT", + "dependencies": { + "bytes": "~3.1.2", + "http-errors": "~2.0.1", + "iconv-lite": "~0.4.24", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/react-is-18": { "name": "react-is", "version": "18.3.1", @@ -4131,6 +4604,34 @@ "node": ">=8" } }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true, + "license": "MIT" + }, "node_modules/semver": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", @@ -4141,6 +4642,84 @@ "semver": "bin/semver.js" } }, + "node_modules/send": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/send/-/send-0.19.2.tgz", + "integrity": "sha512-VMbMxbDeehAxpOtWJXlcUS5E8iXh6QmN+BkRX1GARS3wRaXEEgzCcB10gTQazO42tpNIya8xIyNx8fll1OFPrg==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "~0.5.2", + "http-errors": "~2.0.1", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "~2.4.1", + "range-parser": "~1.2.1", + "statuses": "~2.0.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/send/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true, + "license": "MIT" + }, + "node_modules/send/node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true, + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/serve-static": { + "version": "1.16.3", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.3.tgz", + "integrity": "sha512-x0RTqQel6g5SY7Lg6ZreMmsOzncHFU7nhnRWkKgWuMTu5NN0DR5oruckMqRvacAN9d5w6ARnRBXl9xhDCgfMeA==", + "dev": true, + "license": "MIT", + "dependencies": { + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "~0.19.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "dev": true, + "license": "ISC" + }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -4304,6 +4883,16 @@ "node": ">=10" } }, + "node_modules/statuses": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", + "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/string-length": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", @@ -4611,6 +5200,16 @@ "dev": true, "license": "BSD-3-Clause" }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.6" + } + }, "node_modules/tslib": { "version": "2.8.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", @@ -4642,6 +5241,20 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/undici-types": { "version": "7.24.6", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.24.6.tgz", @@ -4649,6 +5262,16 @@ "dev": true, "license": "MIT" }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/unrs-resolver": { "version": "1.12.2", "resolved": "https://registry.npmjs.org/unrs-resolver/-/unrs-resolver-1.12.2.tgz", @@ -4718,6 +5341,16 @@ "browserslist": ">= 4.21.0" } }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4.0" + } + }, "node_modules/v8-to-istanbul": { "version": "9.3.0", "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz", @@ -4733,6 +5366,16 @@ "node": ">=10.12.0" } }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/walker": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", diff --git a/package.json b/package.json index 9d35659..d3b64b4 100644 --- a/package.json +++ b/package.json @@ -15,12 +15,10 @@ "license": "ISC", "type": "commonjs", "devDependencies": { - "jest": "^30.4.2", - "supertest": "^7.2.2", "cors": "^2.8.5", "express": "^4.18.2", - "nodemailer": "^6.9.3" + "jest": "^30.4.2", + "nodemailer": "^8.0.11", + "supertest": "^7.2.2" } } - - -- 2.52.0 From d30db1d4cc13677131522920846c4a2747d411c5 Mon Sep 17 00:00:00 2001 From: pm Date: Fri, 12 Jun 2026 23:41:13 +0100 Subject: [PATCH 32/38] gitleak v6 --- backend/Dockerfile | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/backend/Dockerfile b/backend/Dockerfile index 75b8030..fe0db6d 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -1,6 +1,11 @@ -FROM node:18-alpine +FROM node:22-alpine #FROM node:18.14.0-alpine +RUN apk update && apk upgrade --no-cache + +# 2. Atualiza a versão global do gestor NPM (Corrige tar, glob, minimatch) +RUN npm install -g npm@latest + # Cria um grupo e um utilizador sem privilégios RUN addgroup -S appgroup && adduser -S appuser -G appgroup -- 2.52.0 From 62aaba7cae0b02a88f177898a9ab55357a149a2b Mon Sep 17 00:00:00 2001 From: pm Date: Fri, 12 Jun 2026 23:43:38 +0100 Subject: [PATCH 33/38] gitleak v7 --- backend/Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/Dockerfile b/backend/Dockerfile index fe0db6d..1a1d3b0 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -1,5 +1,5 @@ -FROM node:22-alpine -#FROM node:18.14.0-alpine +#FROM node:22-alpine +FROM node:18.14.0-alpine RUN apk update && apk upgrade --no-cache -- 2.52.0 From 22940982e7b1d70ae59bad5ff1f8b1ef8a60666c Mon Sep 17 00:00:00 2001 From: pm Date: Fri, 12 Jun 2026 23:49:01 +0100 Subject: [PATCH 34/38] trivy nodemailer --- backend/Dockerfile | 3 +- package-lock.json | 83 +++------------------------------------------- package.json | 8 +++-- 3 files changed, 10 insertions(+), 84 deletions(-) diff --git a/backend/Dockerfile b/backend/Dockerfile index 1a1d3b0..8f48b70 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -1,5 +1,4 @@ -#FROM node:22-alpine -FROM node:18.14.0-alpine +FROM node:22-alpine RUN apk update && apk upgrade --no-cache diff --git a/package-lock.json b/package-lock.json index d4bf3b6..c8bf9fe 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,11 +8,13 @@ "name": "website-secure", "version": "1.0.0", "license": "ISC", - "devDependencies": { + "dependencies": { "cors": "^2.8.5", "express": "^4.18.2", + "nodemailer": "^8.0.11" + }, + "devDependencies": { "jest": "^30.4.2", - "nodemailer": "^8.0.11", "supertest": "^7.2.2" } }, @@ -1546,7 +1548,6 @@ "version": "1.3.8", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", - "dev": true, "license": "MIT", "dependencies": { "mime-types": "~2.1.34", @@ -1642,7 +1643,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", - "dev": true, "license": "MIT" }, "node_modules/asap": { @@ -1782,7 +1782,6 @@ "version": "1.20.5", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.5.tgz", "integrity": "sha512-3grm+/2tUOvu2cjJkvsIxrv/wVpfXQW4PsQHYm7yk4vfpu7Ekl6nEsYBoJUL6qDwZUx8wUhQ8tR2qz+ad9c9OA==", - "dev": true, "license": "MIT", "dependencies": { "bytes": "~3.1.2", @@ -1807,7 +1806,6 @@ "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, "license": "MIT", "dependencies": { "ms": "2.0.0" @@ -1817,7 +1815,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true, "license": "MIT" }, "node_modules/brace-expansion": { @@ -1885,7 +1882,6 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.8" @@ -1895,7 +1891,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", - "dev": true, "license": "MIT", "dependencies": { "es-errors": "^1.3.0", @@ -1909,7 +1904,6 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", - "dev": true, "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.2", @@ -2163,7 +2157,6 @@ "version": "0.5.4", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", - "dev": true, "license": "MIT", "dependencies": { "safe-buffer": "5.2.1" @@ -2176,7 +2169,6 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.6" @@ -2193,7 +2185,6 @@ "version": "0.7.2", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.6" @@ -2220,7 +2211,6 @@ "version": "2.8.6", "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.6.tgz", "integrity": "sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==", - "dev": true, "license": "MIT", "dependencies": { "object-assign": "^4", @@ -2306,7 +2296,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.8" @@ -2316,7 +2305,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.8", @@ -2348,7 +2336,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", - "dev": true, "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.1", @@ -2370,7 +2357,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", - "dev": true, "license": "MIT" }, "node_modules/electron-to-chromium": { @@ -2404,7 +2390,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.8" @@ -2424,7 +2409,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -2434,7 +2418,6 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -2444,7 +2427,6 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.2.tgz", "integrity": "sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==", - "dev": true, "license": "MIT", "dependencies": { "es-errors": "^1.3.0" @@ -2483,7 +2465,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", - "dev": true, "license": "MIT" }, "node_modules/escape-string-regexp": { @@ -2514,7 +2495,6 @@ "version": "1.8.1", "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.6" @@ -2583,7 +2563,6 @@ "version": "4.22.2", "resolved": "https://registry.npmjs.org/express/-/express-4.22.2.tgz", "integrity": "sha512-IuL+Elrou2ZvCFHs18/CIzy2Nzvo25nZ1/D2eIZlz7c+QUayAcYoiM2BthCjs+EBHVpjYjcuLDAiCWgeIX3X1Q==", - "dev": true, "license": "MIT", "dependencies": { "accepts": "~1.3.8", @@ -2630,14 +2609,12 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.7.tgz", "integrity": "sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA==", - "dev": true, "license": "MIT" }, "node_modules/express/node_modules/debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, "license": "MIT", "dependencies": { "ms": "2.0.0" @@ -2647,7 +2624,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true, "license": "MIT" }, "node_modules/fast-json-stable-stringify": { @@ -2678,7 +2654,6 @@ "version": "1.3.2", "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.2.tgz", "integrity": "sha512-aA4RyPcd3badbdABGDuTXCMTtOneUCAYH/gxoYRTZlIJdF0YPWuGqiAsIrhNnnqdXGswYk6dGujem4w80UJFhg==", - "dev": true, "license": "MIT", "dependencies": { "debug": "2.6.9", @@ -2697,7 +2672,6 @@ "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, "license": "MIT", "dependencies": { "ms": "2.0.0" @@ -2707,7 +2681,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true, "license": "MIT" }, "node_modules/find-up": { @@ -2780,7 +2753,6 @@ "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.6" @@ -2790,7 +2762,6 @@ "version": "0.5.2", "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.6" @@ -2822,7 +2793,6 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "dev": true, "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" @@ -2852,7 +2822,6 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", - "dev": true, "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.2", @@ -2887,7 +2856,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", - "dev": true, "license": "MIT", "dependencies": { "dunder-proto": "^1.0.1", @@ -2936,7 +2904,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -2966,7 +2933,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -2995,7 +2961,6 @@ "version": "2.0.4", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.4.tgz", "integrity": "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==", - "dev": true, "license": "MIT", "dependencies": { "function-bind": "^1.1.2" @@ -3015,7 +2980,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==", - "dev": true, "license": "MIT", "dependencies": { "depd": "~2.0.0", @@ -3046,7 +3010,6 @@ "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, "license": "MIT", "dependencies": { "safer-buffer": ">= 2.1.2 < 3" @@ -3101,14 +3064,12 @@ "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true, "license": "ISC" }, "node_modules/ipaddr.js": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.10" @@ -3991,7 +3952,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -4001,7 +3961,6 @@ "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.6" @@ -4011,7 +3970,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", - "dev": true, "license": "MIT", "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -4028,7 +3986,6 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.6" @@ -4051,7 +4008,6 @@ "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.6" @@ -4061,7 +4017,6 @@ "version": "2.1.35", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dev": true, "license": "MIT", "dependencies": { "mime-db": "1.52.0" @@ -4110,7 +4065,6 @@ "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true, "license": "MIT" }, "node_modules/napi-postinstall": { @@ -4140,7 +4094,6 @@ "version": "0.6.3", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.6" @@ -4167,7 +4120,6 @@ "version": "8.0.11", "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-8.0.11.tgz", "integrity": "sha512-nrO/pDAUKl+wXX+lx16tDLbnm0fW6sK/x8mgohaCpg+CdCEl482bD4tCuAZk2DyliruiNTIZxRCoWkDqJEnAiA==", - "dev": true, "license": "MIT-0", "engines": { "node": ">=6.0.0" @@ -4200,7 +4152,6 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -4210,7 +4161,6 @@ "version": "1.13.4", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -4223,7 +4173,6 @@ "version": "2.4.1", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "dev": true, "license": "MIT", "dependencies": { "ee-first": "1.1.1" @@ -4343,7 +4292,6 @@ "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.8" @@ -4407,7 +4355,6 @@ "version": "0.1.13", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.13.tgz", "integrity": "sha512-A/AGNMFN3c8bOlvV9RreMdrv7jsmF9XIfDeCd87+I8RNg6s78BhJxMu69NEMHBSJFxKidViTEdruRwEk/WIKqA==", - "dev": true, "license": "MIT" }, "node_modules/picocolors": { @@ -4486,7 +4433,6 @@ "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", - "dev": true, "license": "MIT", "dependencies": { "forwarded": "0.2.0", @@ -4517,7 +4463,6 @@ "version": "6.15.2", "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.2.tgz", "integrity": "sha512-Rzq0KEyX/w/tEybncDgdkZrJgVUsUMk3xjh3t5bv3S1HTAtg+uOYt72+ZfwiQwKdysThkTBdL/rTi6HDmX9Ddw==", - "dev": true, "license": "BSD-3-Clause", "dependencies": { "side-channel": "^1.1.0" @@ -4533,7 +4478,6 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.6" @@ -4543,7 +4487,6 @@ "version": "2.5.3", "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.3.tgz", "integrity": "sha512-s4VSOf6yN0rvbRZGxs8Om5CWj6seneMwK3oDb4lWDH0UPhWcxwOWw5+qk24bxq87szX1ydrwylIOp2uG1ojUpA==", - "dev": true, "license": "MIT", "dependencies": { "bytes": "~3.1.2", @@ -4608,7 +4551,6 @@ "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true, "funding": [ { "type": "github", @@ -4629,7 +4571,6 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true, "license": "MIT" }, "node_modules/semver": { @@ -4646,7 +4587,6 @@ "version": "0.19.2", "resolved": "https://registry.npmjs.org/send/-/send-0.19.2.tgz", "integrity": "sha512-VMbMxbDeehAxpOtWJXlcUS5E8iXh6QmN+BkRX1GARS3wRaXEEgzCcB10gTQazO42tpNIya8xIyNx8fll1OFPrg==", - "dev": true, "license": "MIT", "dependencies": { "debug": "2.6.9", @@ -4671,7 +4611,6 @@ "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, "license": "MIT", "dependencies": { "ms": "2.0.0" @@ -4681,14 +4620,12 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true, "license": "MIT" }, "node_modules/send/node_modules/mime": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "dev": true, "license": "MIT", "bin": { "mime": "cli.js" @@ -4701,7 +4638,6 @@ "version": "1.16.3", "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.3.tgz", "integrity": "sha512-x0RTqQel6g5SY7Lg6ZreMmsOzncHFU7nhnRWkKgWuMTu5NN0DR5oruckMqRvacAN9d5w6ARnRBXl9xhDCgfMeA==", - "dev": true, "license": "MIT", "dependencies": { "encodeurl": "~2.0.0", @@ -4717,7 +4653,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", - "dev": true, "license": "ISC" }, "node_modules/shebang-command": { @@ -4747,7 +4682,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.1.tgz", "integrity": "sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ==", - "dev": true, "license": "MIT", "dependencies": { "es-errors": "^1.3.0", @@ -4767,7 +4701,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.1.tgz", "integrity": "sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==", - "dev": true, "license": "MIT", "dependencies": { "es-errors": "^1.3.0", @@ -4784,7 +4717,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", - "dev": true, "license": "MIT", "dependencies": { "call-bound": "^1.0.2", @@ -4803,7 +4735,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", - "dev": true, "license": "MIT", "dependencies": { "call-bound": "^1.0.2", @@ -4887,7 +4818,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.8" @@ -5204,7 +5134,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", - "dev": true, "license": "MIT", "engines": { "node": ">=0.6" @@ -5245,7 +5174,6 @@ "version": "1.6.18", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "dev": true, "license": "MIT", "dependencies": { "media-typer": "0.3.0", @@ -5266,7 +5194,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.8" @@ -5345,7 +5272,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.4.0" @@ -5370,7 +5296,6 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.8" diff --git a/package.json b/package.json index d3b64b4..949fef2 100644 --- a/package.json +++ b/package.json @@ -14,11 +14,13 @@ "author": "", "license": "ISC", "type": "commonjs", - "devDependencies": { + "dependencies": { "cors": "^2.8.5", "express": "^4.18.2", + "nodemailer": "^8.0.11" + }, + "devDependencies": { "jest": "^30.4.2", - "nodemailer": "^8.0.11", "supertest": "^7.2.2" } -} +} \ No newline at end of file -- 2.52.0 From 3da598485b9e8c16f2957a6ae53a5c25099850c6 Mon Sep 17 00:00:00 2001 From: pm Date: Fri, 12 Jun 2026 23:52:38 +0100 Subject: [PATCH 35/38] trivy nodemailer v2 --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index c8bf9fe..642fbb3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,7 +11,7 @@ "dependencies": { "cors": "^2.8.5", "express": "^4.18.2", - "nodemailer": "^8.0.11" + "nodemailer": "8.0.4" }, "devDependencies": { "jest": "^30.4.2", @@ -4117,9 +4117,9 @@ } }, "node_modules/nodemailer": { - "version": "8.0.11", - "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-8.0.11.tgz", - "integrity": "sha512-nrO/pDAUKl+wXX+lx16tDLbnm0fW6sK/x8mgohaCpg+CdCEl482bD4tCuAZk2DyliruiNTIZxRCoWkDqJEnAiA==", + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-8.0.4.tgz", + "integrity": "sha512-k+jf6N8PfQJ0Fe8ZhJlgqU5qJU44Lpvp2yvidH3vp1lPnVQMgi4yEEMPXg5eJS1gFIJTVq1NHBk7Ia9ARdSBdQ==", "license": "MIT-0", "engines": { "node": ">=6.0.0" diff --git a/package.json b/package.json index 949fef2..c8d3bb8 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ "dependencies": { "cors": "^2.8.5", "express": "^4.18.2", - "nodemailer": "^8.0.11" + "nodemailer": "8.0.4" }, "devDependencies": { "jest": "^30.4.2", -- 2.52.0 From aa726dbd772386bdc774aa7dede8e7ed5dc1dd22 Mon Sep 17 00:00:00 2001 From: pm Date: Fri, 12 Jun 2026 23:58:15 +0100 Subject: [PATCH 36/38] teste: introduz lodash para forcar bloqueio do trivy --- package-lock.json | 15 +++++++++++---- package.json | 3 ++- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 642fbb3..0c659ad 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,7 +11,8 @@ "dependencies": { "cors": "^2.8.5", "express": "^4.18.2", - "nodemailer": "8.0.4" + "lodash": "4.17.15", + "nodemailer": "^8.0.11" }, "devDependencies": { "jest": "^30.4.2", @@ -3899,6 +3900,12 @@ "node": ">=8" } }, + "node_modules/lodash": { + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", + "license": "MIT" + }, "node_modules/lru-cache": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", @@ -4117,9 +4124,9 @@ } }, "node_modules/nodemailer": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-8.0.4.tgz", - "integrity": "sha512-k+jf6N8PfQJ0Fe8ZhJlgqU5qJU44Lpvp2yvidH3vp1lPnVQMgi4yEEMPXg5eJS1gFIJTVq1NHBk7Ia9ARdSBdQ==", + "version": "8.0.11", + "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-8.0.11.tgz", + "integrity": "sha512-nrO/pDAUKl+wXX+lx16tDLbnm0fW6sK/x8mgohaCpg+CdCEl482bD4tCuAZk2DyliruiNTIZxRCoWkDqJEnAiA==", "license": "MIT-0", "engines": { "node": ">=6.0.0" diff --git a/package.json b/package.json index c8d3bb8..8c80a5d 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,8 @@ "dependencies": { "cors": "^2.8.5", "express": "^4.18.2", - "nodemailer": "8.0.4" + "lodash": "4.17.15", + "nodemailer": "^8.0.11" }, "devDependencies": { "jest": "^30.4.2", -- 2.52.0 From 500972ea6f82614c3f6694e0f26c45ac723fd53d Mon Sep 17 00:00:00 2001 From: pm Date: Sat, 13 Jun 2026 00:00:44 +0100 Subject: [PATCH 37/38] sonar --- package.json | 1 - 1 file changed, 1 deletion(-) diff --git a/package.json b/package.json index 8c80a5d..949fef2 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,6 @@ "dependencies": { "cors": "^2.8.5", "express": "^4.18.2", - "lodash": "4.17.15", "nodemailer": "^8.0.11" }, "devDependencies": { -- 2.52.0 From 432d3d88403ec8d46daf9be7b7f54137662e9fdb Mon Sep 17 00:00:00 2001 From: pm Date: Sat, 13 Jun 2026 00:04:18 +0100 Subject: [PATCH 38/38] sonar v2 --- backend/Dockerfile | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/backend/Dockerfile b/backend/Dockerfile index 8f48b70..59f13e7 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -1,12 +1,12 @@ FROM node:22-alpine -RUN apk update && apk upgrade --no-cache - -# 2. Atualiza a versão global do gestor NPM (Corrige tar, glob, minimatch) -RUN npm install -g npm@latest - -# Cria um grupo e um utilizador sem privilégios -RUN addgroup -S appgroup && adduser -S appuser -G appgroup +# ========================================== +# DEVSECOPS: HARDENING DA IMAGEM BASE +# ========================================== +# Agrupamos os comandos RUN num só para otimizar as camadas da imagem (Regra do SonarQube) +RUN apk update && apk upgrade --no-cache && \ + npm install -g npm@latest && \ + addgroup -S appgroup && adduser -S appuser -G appgroup # Define o diretório de trabalho WORKDIR /usr/src/app -- 2.52.0