mirror of
https://github.com/norandom/OpenUltraSAST.git
synced 2026-10-18 20:49:28 +00:00
feat(pair-corpus-honesty): add vibe-py, vfc-js and agent-vfc slices with mechanism vocabulary
Tasks 1.1, 5.1, 5.2, 5.4 and the data half of 5.3. - mechanisms.toml: closed vocabulary v1 (20 ids) every expected row cites. - vibe-py: 35 Real-Vuln-Benchmark pairs (Apache-2.0), human provenance only because the LLM-generated repositories carry no license (escalated). - vfc-js: 17 Node fix-commit pairs harvested upstream (MIT/Apache-2.0), SecBench.js itself is not vendored (no license); sinks derived on 13/17. - agent-vfc: 29 agent-trailer fixes as catalog-candidates.toml plus REVIEW.md; the loaded catalog stays empty until a human reviews them. - datasets.toml and README document every slice and its review status. Co-Authored-By: Claude Fable 5.1 <[email protected]> Claude-Session: https://claude.ai/code/session_01T7XD7x5KonMdmGRkp63EQG
This commit is contained in:
co-authored by
Claude Fable 5.1
parent
c3e841003c
commit
8ab4207618
@@ -0,0 +1,18 @@
|
||||
# agent-vfc slice
|
||||
|
||||
Security-fix commits carrying an AI coding agent co-author trailer or generation marker
|
||||
(Claude Code, Codex, Cursor, Copilot, Devin), in JavaScript, TypeScript, or Python.
|
||||
`provenance = "agent"`. Only repositories with a stated license are vendored.
|
||||
|
||||
## Review checklist (Req 5.3)
|
||||
|
||||
A recipe with `reviewer = "pending"` is a candidate, not a label. Before setting `reviewer`:
|
||||
|
||||
1. The parent excerpt really contains the vulnerability the title claims (not a refactor).
|
||||
2. One mechanism from `benchmarks/pairs/mechanisms.toml` explains it; adjust `mechanism` and `cwe`.
|
||||
3. The fixed excerpt removes it and the change is inside the vendored function.
|
||||
4. No secret, token, or personal data is in either excerpt (run the redaction check).
|
||||
5. The license header is present and matches the repository license.
|
||||
|
||||
Rebuild: `python benchmarks/pairs/agent-vfc/build_recipes.py --search /tmp/agents.jsonl` then
|
||||
`--from /tmp/agents.jsonl`, `harvest.py --slice agent-vfc --all --fetch`, `catalog_gen.py --slice agent-vfc`.
|
||||
@@ -0,0 +1,45 @@
|
||||
# agent-vfc candidate review sheet
|
||||
|
||||
Set `reviewer = "<name>"` in `recipes.toml` for each row you confirm (and fix `mechanism`/`cwe` if the title-based guess is wrong), then run `python benchmarks/pairs/catalog_gen.py --slice agent-vfc`. Rows without a reviewer stay in `catalog-candidates.toml` and are never scored.
|
||||
|
||||
| # | name | mechanism (guess) | cwe | language | commit | title |
|
||||
|---|------|-------------------|-----|----------|--------|-------|
|
||||
| 1 | `academic-based-qoder-app-a79ddb` | permissive_default | CWE-16 | python | [a79ddb90](https://github.com/1173591564/academic-based-qoder/commit/a79ddb90def54e91f7507cbf6b1548b224d642aa) | fix(hub): allow DSH token validation CORS |
|
||||
| 2 | `anastasios-pw-session-14ec1a` | source_reaches_sink | CWE-918 | typescript | [14ec1ac5](https://github.com/Anas329796/Anastasios/commit/14ec1ac50f9e4e255d875236d30129c6207401d4) | fix(browser): harden SSRF redirect guard against non-navigation document hops [A |
|
||||
| 3 | `arsnova-eu-httpcors-9bcba4` | permissive_default | CWE-16 | typescript | [9bcba4f4](https://github.com/kqc-real/arsnova.eu/commit/9bcba4f442aecc6a5e16ef2dc6115177cfc2b6df) | fix(security): Produktions-CORS auf Same-Origin begrenzen (#143) |
|
||||
| 4 | `astroclaw-pw-session-1553a8` | source_reaches_sink | CWE-918 | typescript | [1553a8ad](https://github.com/P1R4N351/astroclaw/commit/1553a8adf123913cf7f1f1c75be4c4e5cd6c796b) | fix(browser): harden SSRF redirect guard against non-navigation document hops [A |
|
||||
| 5 | `capgo-app-apptabs-7d73fd` | permissive_default | CWE-16 | typescript | [7d73fd21](https://github.com/Cap-go/capgo.app/commit/7d73fd21a59eaa3a4e20c6dc0d280e73e47435b7) | fix(notifications): harden API CORS and mark console tab as beta (#2623) |
|
||||
| 6 | `capgo-app-hono-4dadd2` | permissive_default | CWE-16 | typescript | [4dadd258](https://github.com/Cap-go/capgo.app/commit/4dadd2580d02213d227a331eee0232aa59859b59) | fix(api): CORS for Capacitor localhost WebView (#3105) |
|
||||
| 7 | `dailyforge-server-ed1470` | permissive_default | CWE-16 | javascript | [ed147081](https://github.com/Annamdevula-Nissi-Grace/Dailyforge/commit/ed1470814a108bd725c8b27bd9d86cf95a979a96) | Fix: add localhost fallback for CORS origin (#172) |
|
||||
| 8 | `dnf-plugin-anyrepo-config-26d19a` | path_join_user_input | CWE-22 | python | [26d19aeb](https://github.com/jfut/dnf-plugin-anyrepo/commit/26d19aeb8884f244e34ccfdc4f49f07055adc4d0) | fix(config): prevent path traversal in repository names |
|
||||
| 9 | `edutrace-page-ee7ba2` | prototype_pollution | CWE-1321 | typescript | [ee7ba25f](https://github.com/jardimdesoftware/edutrace/commit/ee7ba25fb23ea89cc1b67549cb5e32c8ead92739) | fix(front): impedir prototype pollution nos handlers de formulário aninhado |
|
||||
| 10 | `etoj-index-605274` | permissive_default | CWE-16 | typescript | [6052743d](https://github.com/Eternity-Sky/_ETOJ/commit/6052743d477eeff62e32553c2790785d3f52c641) | Fix CORS: Add PATCH method to allowed methods |
|
||||
| 11 | `etude-lexical-markdown-editorconfig-c61a8b` | prototype_pollution | CWE-1321 | typescript | [c61a8bf7](https://github.com/dayflower/etude-lexical-markdown/commit/c61a8bf78fe20d6ae0eab2e4b8b02004508525ed) | fix: guard deepMergeInto against prototype pollution |
|
||||
| 12 | `etude-lexical-markdown-editorconfig-db4f54` | prototype_pollution | CWE-1321 | typescript | [db4f54b1](https://github.com/dayflower/etude-lexical-markdown/commit/db4f54b1ab80ad596de6425e84f90aa781c49999) | fix: make prototype pollution guard recognizable by CodeQL |
|
||||
| 13 | `gitim-git-cors-proxy-e4c3a4` | permissive_default | CWE-16 | typescript | [e4c3a479](https://github.com/CiferaTeam/GitIM/commit/e4c3a4794dbe9fbcce679f7df1ecd2b09b40f9d6) | fix(frontend): use gitim cors proxy by default |
|
||||
| 14 | `lensops-kubernetesmanagement-fe4910` | missing_auth_guard | CWE-862 | typescript | [fe49109a](https://github.com/amitknigam84/lensops/commit/fe49109aedfe21dea4d24d4d9f2fa3f1ecfb6c84) | Fix missing auth header on namespaces API call |
|
||||
| 15 | `market-cap-route-4f8ae9` | source_reaches_sink | CWE-601 | typescript | [4f8ae9be](https://github.com/navaneethbv/market-cap/commit/4f8ae9be5519ced5a975f1190e3e4bc43f84e4d6) | Fix open redirects on the auth next param |
|
||||
| 16 | `melodix-playerprovider-089931` | permissive_default | CWE-16 | typescript | [089931ef](https://github.com/alexshao3/melodix/commit/089931ef71ea1e5b7586520baf1a5498e2f05b13) | Merge pull request #17 from alexshao3/devin/1777216143-fix-audio-cors |
|
||||
| 17 | `mercado-do-vale-news-catalogmetadataservice-9b5fcf` | permissive_default | CWE-16 | typescript | [9b5fcf2d](https://github.com/handielson/Mercado-do-vale-news/commit/9b5fcf2dae41e56f5f97952266f2d6ba59598598) | fix(catalog): avoid metadata cors preflight |
|
||||
| 18 | `money-track-category-icons-4d4a5b` | prototype_pollution | CWE-1321 | typescript | [4d4a5b06](https://github.com/andrebubniak/money-track/commit/4d4a5b063278c8b6697c3faae133d7c39fcd01c0) | fix(category-icons): use Object.hasOwn to prevent prototype pollution in type gu |
|
||||
| 19 | `nestjs-filter-normalizer-aa0e60` | prototype_pollution | CWE-1321 | typescript | [aa0e600d](https://github.com/DavideCarvalho/nestjs-filter/commit/aa0e600d05997ea3d77538ea1c2db427c439f2e8) | fix(core): add prototype pollution guard to normalizeInput |
|
||||
| 20 | `new-erp-final-app-6e9644` | permissive_default | CWE-16 | typescript | [6e9644c8](https://github.com/Sachin-Salgar/NEW_ERP_FINAL/commit/6e9644c81ce3fb356669157182a5ef09a70c4b59) | fix: allow patch requests through cors |
|
||||
| 21 | `nimestream-route-d17f53` | source_reaches_sink | CWE-918 | javascript | [d17f535b](https://github.com/Irnhakim/nimestream/commit/d17f535bf3012041b056ff3aa991ff6cfa198e43) | fix: resolve command injection and SSRF/Open Redirect security issues in multiSc |
|
||||
| 22 | `onlook-helper-57ce1c` | missing_auth_guard | CWE-862 | typescript | [57ce1ccf](https://github.com/zhcndoc/onlook/commit/57ce1ccfacc7e8484cae59013a2b1e34518560e5) | Fix CVE-2025-63783: Add authorization checks to project mutation APIs (#3062) |
|
||||
| 23 | `openniw-jobs-0fc947` | identity_from_request_body | CWE-639 | python | [0fc94733](https://github.com/HHHHHejia/openniw/commit/0fc94733f6ca3c6b129a0a8e6d7b3acce19d5a10) | Fix IDOR on job endpoint: case-bound jobs require case ownership |
|
||||
| 24 | `openniw-jobs-b74de3` | identity_from_request_body | CWE-639 | python | [b74de31b](https://github.com/ziyuzuo/openniw/commit/b74de31b0a5f37e4e929ba6aa74dbe0f5e6d9a68) | Fix IDOR on job endpoint: case-bound jobs require case ownership |
|
||||
| 25 | `overleaf-with-claude-exportscontroller-3980b9` | identity_from_request_body | CWE-639 | javascript | [3980b9e5](https://github.com/ZUENS2020/overleaf-with-claude/commit/3980b9e5806defb63e45ae2696e6c1899f3a8431) | Fix IDOR in exports by adding token verification (Issue #31637) (#32883) |
|
||||
| 26 | `popmark-editorconfig-e5ac40` | prototype_pollution | CWE-1321 | typescript | [e5ac407c](https://github.com/dayflower/popmark/commit/e5ac407cef37c37178d440541ede301c838640fb) | fix: guard deepMergeInto against prototype pollution |
|
||||
| 27 | `rag-pipeline-utils-config-handler-76e5f0` | prototype_pollution | CWE-1321 | javascript | [76e5f0a9](https://github.com/DevilsDev/rag-pipeline-utils/commit/76e5f0a94d6803d0e463d26a61cedb7da90857a7) | fix(security): prevent prototype pollution in config-handler |
|
||||
| 28 | `registry-proxy-worker-426847` | permissive_default | CWE-16 | javascript | [42684789](https://github.com/agents-repo/registry-proxy/commit/426847899eb2ee94ae4e5a3aacc50423e36d2dc8) | fix: handle CORS OPTIONS preflight for catalog fetches (#10) |
|
||||
| 29 | `rls-alembic-rls-d2b6af` | permissive_default | CWE-16 | python | [d2b6af47](https://github.com/DelfinaCare/rls/commit/d2b6af47347fb285b7a3820a7f2d5dded20907ec) | Guard against ENABLE ROW LEVEL SECURITY on tables with no policies (#143) |
|
||||
| 30 | `supplieradvisor-mvp-route-387bcf` | identity_from_request_body | CWE-639 | typescript | [387bcf40](https://github.com/bigfivefoods/supplieradvisor-mvp/commit/387bcf40e984a2ee1832ab7beabf0284c5b627d8) | Brief 62: Fix IDOR on customer_claims PATCH/DELETE (#156) |
|
||||
| 31 | `supplieradvisor-mvp-route-a69e8f` | identity_from_request_body | CWE-639 | typescript | [a69e8f27](https://github.com/bigfivefoods/supplieradvisor-mvp/commit/a69e8f27c0f4d402573d16f0612b51155bbc46e1) | Brief 60: Fix IDOR on opportunities GET/PATCH/DELETE (missing company membership |
|
||||
| 32 | `tools-cli-tools-a96bc0` | source_reaches_sink | CWE-78 | python | [a96bc050](https://github.com/D-sorganization/Tools/commit/a96bc0502a3dcdac303e4f0152508886e5c35c0a) | 🛡️ Sentinel: [CRITICAL] Fix command injection in ShellTool (#3307) |
|
||||
| 33 | `tools-wsgi-e18686` | path_join_user_input | CWE-22 | python | [e18686aa](https://github.com/D-sorganization/Tools/commit/e18686aaa174a8a4843c07b4727771c92e0f179e) | fix(security): validate mesh filenames against path traversal in _download_meshe |
|
||||
| 34 | `trackly-cli-path-diagnostics-1c1aed` | path_join_user_input | CWE-22 | javascript | [1c1aed89](https://github.com/trackly-app/trackly-cli/commit/1c1aed89b07edb04051830c8f086e02b65e961c6) | fix(apply): report blocked path traversal |
|
||||
| 35 | `upstreamdrift-local-server-c3a078` | path_join_user_input | CWE-22 | python | [c3a07870](https://github.com/D-sorganization/UpstreamDrift/commit/c3a0787080489b30e2ed0abfac03b51e45da184b) | fix(api): harden local server path traversal (#2805) (#2839) |
|
||||
| 36 | `vantalk-firebase-16c3b0` | secret_in_client | CWE-798 | typescript | [16c3b028](https://github.com/NiSeullent/VanTalk/commit/16c3b02875b1f51c3cac1dc185e199978a35985c) | fix(security): load Firebase API key from env, remove hardcoded secret |
|
||||
| 37 | `waggledance-swarm-ssrf-host-guard-9a4548` | source_reaches_sink | CWE-918 | python | [9a454843](https://github.com/Ahkeratmehilaiset/waggledance-swarm/commit/9a454843aa35332ff2eb3106023eee0c4b5e444b) | fix(ssrf): reject bare-string allowed hosts (#1460) |
|
||||
| 38 | `workers-research-utils-209444` | source_reaches_sink | CWE-89 | typescript | [209444eb](https://github.com/G4brym/workers-research/commit/209444eb61cc564c2d6b43267256f85fe3e5e30e) | Fix SQL injection in search by using parameterized queries (#41) |
|
||||
| 39 | `zoonk-origin-bfbf67` | permissive_default | CWE-16 | typescript | [bfbf670c](https://github.com/zoonk/zoonk/commit/bfbf670ccb41d63c407d32c51bd26e626a174f31) | fix(api): allow staging cors from previews (#1559) |
|
||||
@@ -0,0 +1,38 @@
|
||||
// Provenance: Anas329796/Anastasios (fixed).
|
||||
// repo: Anas329796/Anastasios
|
||||
// commit: 14ec1ac50f9e4e255d875236d30129c6207401d4
|
||||
// parent: adb7b0d5d6b81c46d56451c709e7eac9d0dc93fb
|
||||
// commit_url: https://github.com/Anas329796/Anastasios/commit/14ec1ac50f9e4e255d875236d30129c6207401d4
|
||||
// cve:
|
||||
// license: MIT
|
||||
// function: isTopLevelNavigationRequest
|
||||
// relpath: extensions/browser/src/browser/pw-session.ts
|
||||
// provenance: agent
|
||||
// mechanism: source_reaches_sink
|
||||
|
||||
function isTopLevelNavigationRequest(page: Page, request: Request): boolean {
|
||||
let sameMainFrame = false;
|
||||
try {
|
||||
sameMainFrame = request.frame() === page.mainFrame();
|
||||
} catch {
|
||||
// Frame resolution can fail during redirect/renderer churn; fail closed.
|
||||
sameMainFrame = true;
|
||||
}
|
||||
if (!sameMainFrame) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
if (request.isNavigationRequest()) {
|
||||
return true;
|
||||
}
|
||||
} catch {
|
||||
// Ignore and fall back to resource-type check below.
|
||||
}
|
||||
|
||||
try {
|
||||
return request.resourceType() === "document";
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
// Provenance: Anas329796/Anastasios (vuln).
|
||||
// repo: Anas329796/Anastasios
|
||||
// commit: adb7b0d5d6b81c46d56451c709e7eac9d0dc93fb
|
||||
// parent: adb7b0d5d6b81c46d56451c709e7eac9d0dc93fb
|
||||
// commit_url: https://github.com/Anas329796/Anastasios/commit/14ec1ac50f9e4e255d875236d30129c6207401d4
|
||||
// cve:
|
||||
// license: MIT
|
||||
// function: isTopLevelNavigationRequest
|
||||
// relpath: extensions/browser/src/browser/pw-session.ts
|
||||
// provenance: agent
|
||||
// mechanism: source_reaches_sink
|
||||
|
||||
function isTopLevelNavigationRequest(page: Page, request: Request): boolean {
|
||||
if (!request.isNavigationRequest()) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
return request.frame() === page.mainFrame();
|
||||
} catch {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
// Provenance: P1R4N351/astroclaw (fixed).
|
||||
// repo: P1R4N351/astroclaw
|
||||
// commit: 1553a8adf123913cf7f1f1c75be4c4e5cd6c796b
|
||||
// parent: d3eed2dc01328f21dd404477bb28e2740fa371a4
|
||||
// commit_url: https://github.com/P1R4N351/astroclaw/commit/1553a8adf123913cf7f1f1c75be4c4e5cd6c796b
|
||||
// cve:
|
||||
// license: MIT
|
||||
// function: isTopLevelNavigationRequest
|
||||
// relpath: extensions/browser/src/browser/pw-session.ts
|
||||
// provenance: agent
|
||||
// mechanism: source_reaches_sink
|
||||
|
||||
function isTopLevelNavigationRequest(page: Page, request: Request): boolean {
|
||||
let sameMainFrame = false;
|
||||
try {
|
||||
sameMainFrame = request.frame() === page.mainFrame();
|
||||
} catch {
|
||||
// Frame resolution can fail during redirect/renderer churn; fail closed.
|
||||
sameMainFrame = true;
|
||||
}
|
||||
if (!sameMainFrame) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
if (request.isNavigationRequest()) {
|
||||
return true;
|
||||
}
|
||||
} catch {
|
||||
// Ignore and fall back to resource-type check below.
|
||||
}
|
||||
|
||||
try {
|
||||
return request.resourceType() === "document";
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
// Provenance: P1R4N351/astroclaw (vuln).
|
||||
// repo: P1R4N351/astroclaw
|
||||
// commit: d3eed2dc01328f21dd404477bb28e2740fa371a4
|
||||
// parent: d3eed2dc01328f21dd404477bb28e2740fa371a4
|
||||
// commit_url: https://github.com/P1R4N351/astroclaw/commit/1553a8adf123913cf7f1f1c75be4c4e5cd6c796b
|
||||
// cve:
|
||||
// license: MIT
|
||||
// function: isTopLevelNavigationRequest
|
||||
// relpath: extensions/browser/src/browser/pw-session.ts
|
||||
// provenance: agent
|
||||
// mechanism: source_reaches_sink
|
||||
|
||||
function isTopLevelNavigationRequest(page: Page, request: Request): boolean {
|
||||
if (!request.isNavigationRequest()) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
return request.frame() === page.mainFrame();
|
||||
} catch {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,253 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Build agent-vfc candidate recipes from agent-authored security-fix commits (maintainer, network via gh).
|
||||
|
||||
Candidates come from GitHub commit search on agent co-author trailers or generation
|
||||
markers plus security-fix wording (see --search). Each candidate is kept only when the
|
||||
repository states a license, the fix touches one to three JavaScript, TypeScript, or
|
||||
Python files, and the largest changed file has at most --max-lines changed lines.
|
||||
Every recipe starts with ``reviewer = "pending"``; a human must set the reviewer and
|
||||
confirm the mechanism before the pair is trusted (Req 5.3).
|
||||
|
||||
python benchmarks/pairs/agent-vfc/build_recipes.py --search /tmp/agent_candidates.jsonl
|
||||
python benchmarks/pairs/agent-vfc/build_recipes.py --from /tmp/agent_candidates.jsonl
|
||||
python benchmarks/pairs/harvest.py --slice agent-vfc --all --fetch
|
||||
python benchmarks/pairs/catalog_gen.py --slice agent-vfc
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import re
|
||||
import subprocess
|
||||
import time
|
||||
from pathlib import Path
|
||||
|
||||
ROOT = Path(__file__).resolve().parent
|
||||
TRAILERS = (
|
||||
'"Co-Authored-By: Claude"',
|
||||
'"Generated with Claude Code"',
|
||||
'"Co-authored-by: Cursor"',
|
||||
'"Co-authored-by: Codex"',
|
||||
'"Co-authored-by: Copilot"',
|
||||
'"Co-authored-by: devin"',
|
||||
)
|
||||
KEYWORDS = (
|
||||
'"fix IDOR"',
|
||||
'"SQL injection"',
|
||||
'"path traversal"',
|
||||
"SSRF",
|
||||
'"hardcoded secret"',
|
||||
'"CORS"',
|
||||
'"row level security"',
|
||||
'"authorization check"',
|
||||
'"command injection"',
|
||||
'"prototype pollution"',
|
||||
'"open redirect"',
|
||||
'"missing authentication"',
|
||||
)
|
||||
MECHANISM_BY_TITLE = (
|
||||
(
|
||||
re.compile(r"\bidor\b|ownership|owner.?scope|user_id from|tenant", re.I),
|
||||
"identity_from_request_body",
|
||||
"CWE-639",
|
||||
"insecure direct object reference",
|
||||
),
|
||||
(
|
||||
re.compile(r"missing auth|unauthenticated|auth(?:orization|entication)? (?:check|guard|middleware)|require.?auth", re.I),
|
||||
"missing_auth_guard",
|
||||
"CWE-862",
|
||||
"missing authorization",
|
||||
),
|
||||
(re.compile(r"sql injection|sqli", re.I), "source_reaches_sink", "CWE-89", "sql injection"),
|
||||
(re.compile(r"path traversal|zip slip|directory traversal", re.I), "path_join_user_input", "CWE-22", "path traversal"),
|
||||
(re.compile(r"\bssrf\b", re.I), "source_reaches_sink", "CWE-918", "server-side request forgery"),
|
||||
(re.compile(r"command injection|shell injection", re.I), "source_reaches_sink", "CWE-78", "command injection"),
|
||||
(re.compile(r"prototype pollution", re.I), "prototype_pollution", "CWE-1321", "prototype pollution"),
|
||||
(re.compile(r"open redirect", re.I), "source_reaches_sink", "CWE-601", "open redirect"),
|
||||
(
|
||||
re.compile(r"hardcoded|hard-coded|leaked (?:key|secret|token)|service.?role", re.I),
|
||||
"secret_in_client",
|
||||
"CWE-798",
|
||||
"hardcoded credentials",
|
||||
),
|
||||
(re.compile(r"\bcors\b|row level security|\brls\b|debug", re.I), "permissive_default", "CWE-16", "permissive default"),
|
||||
)
|
||||
ACCEPTED_LICENSES = {
|
||||
"MIT",
|
||||
"Apache-2.0",
|
||||
"BSD-3-Clause",
|
||||
"BSD-2-Clause",
|
||||
"ISC",
|
||||
"MPL-2.0",
|
||||
"GPL-3.0",
|
||||
"GPL-2.0",
|
||||
"AGPL-3.0",
|
||||
"Unlicense",
|
||||
"0BSD",
|
||||
}
|
||||
_CODE = re.compile(r"\.(py|js|mjs|cjs|ts|tsx)$")
|
||||
_SKIP = re.compile(r"(test|spec|\.d\.ts|migration|dist/|build/|min\.js|\.config\.|stories)", re.I)
|
||||
_NOISE = re.compile(r"\b(css|icon|i18n|layout|docs?|tracker|sess[aã]o|chore|bump|migration|workflow)\b", re.I)
|
||||
|
||||
|
||||
def _gh(args: list[str]) -> object:
|
||||
return json.loads(subprocess.check_output(["gh", "api", *args], stderr=subprocess.DEVNULL))
|
||||
|
||||
|
||||
def search(out: Path) -> int:
|
||||
seen: set[tuple[str, str]] = set()
|
||||
with out.open("w") as handle:
|
||||
for trailer in TRAILERS:
|
||||
for keyword in KEYWORDS:
|
||||
time.sleep(6) # commit search has a strict secondary rate limit
|
||||
try:
|
||||
result = _gh(["-X", "GET", "search/commits", "-f", f"q={trailer} {keyword} fix", "-f", "per_page=30"])
|
||||
except Exception: # noqa: BLE001 — rate limited; keep going
|
||||
continue
|
||||
for item in result.get("items", []) if isinstance(result, dict) else []:
|
||||
key = (item["repository"]["full_name"], item["sha"])
|
||||
if key in seen:
|
||||
continue
|
||||
seen.add(key)
|
||||
handle.write(
|
||||
json.dumps(
|
||||
{
|
||||
"repo": key[0],
|
||||
"sha": key[1],
|
||||
"title": item["commit"]["message"].split("\n")[0][:160],
|
||||
"date": item["commit"]["author"]["date"],
|
||||
}
|
||||
)
|
||||
+ "\n"
|
||||
)
|
||||
return len(seen)
|
||||
|
||||
|
||||
def classify(title: str) -> tuple[str, str, str] | None:
|
||||
for pattern, mechanism, cwe, cls in MECHANISM_BY_TITLE:
|
||||
if pattern.search(title):
|
||||
return mechanism, cwe, cls
|
||||
return None
|
||||
|
||||
|
||||
def build(source: Path, *, limit: int, max_lines: int) -> tuple[list[dict[str, object]], dict[str, int]]:
|
||||
recipes: list[dict[str, object]] = []
|
||||
skipped = {"noise_title": 0, "unclassified": 0, "unlicensed": 0, "no_code_file": 0, "too_big": 0, "api": 0, "duplicate_repo": 0}
|
||||
per_repo: dict[str, int] = {}
|
||||
seen_commits: set[str] = set() # the same fix commit shows up in every fork
|
||||
rows = [json.loads(line) for line in source.read_text().splitlines() if line.strip()]
|
||||
for row in sorted(rows, key=lambda r: (r["repo"], r["date"])):
|
||||
if len(recipes) >= limit:
|
||||
break
|
||||
title = str(row["title"])
|
||||
if _NOISE.search(title):
|
||||
skipped["noise_title"] += 1
|
||||
continue
|
||||
classified = classify(title)
|
||||
if classified is None:
|
||||
skipped["unclassified"] += 1
|
||||
continue
|
||||
if per_repo.get(row["repo"], 0) >= 2 or row["sha"] in seen_commits:
|
||||
skipped["duplicate_repo"] += 1
|
||||
continue
|
||||
seen_commits.add(row["sha"])
|
||||
time.sleep(0.8)
|
||||
try:
|
||||
info = _gh([f"repos/{row['repo']}"])
|
||||
commit = _gh([f"repos/{row['repo']}/commits/{row['sha']}"])
|
||||
except Exception: # noqa: BLE001
|
||||
skipped["api"] += 1
|
||||
continue
|
||||
assert isinstance(info, dict) and isinstance(commit, dict)
|
||||
license_id = (info.get("license") or {}).get("spdx_id") or ""
|
||||
if license_id not in ACCEPTED_LICENSES:
|
||||
skipped["unlicensed"] += 1
|
||||
continue
|
||||
files = [f for f in commit.get("files", []) if _CODE.search(f["filename"]) and not _SKIP.search(f["filename"]) and f.get("patch")]
|
||||
if not files or len(files) > 3:
|
||||
skipped["no_code_file"] += 1
|
||||
continue
|
||||
target = sorted(files, key=lambda f: -(f.get("additions", 0) + f.get("deletions", 0)))[0]
|
||||
if target.get("additions", 0) + target.get("deletions", 0) > max_lines:
|
||||
skipped["too_big"] += 1
|
||||
continue
|
||||
parents = commit.get("parents") or []
|
||||
if not parents:
|
||||
skipped["api"] += 1
|
||||
continue
|
||||
mechanism, cwe, cls = classified
|
||||
message = commit["commit"]["message"]
|
||||
trailer = next((line.strip() for line in message.splitlines() if re.match(r"(?i)co-authored-by:|generated with", line.strip())), "")
|
||||
suffix = Path(target["filename"]).suffix
|
||||
language = {".py": "python", ".ts": "typescript", ".tsx": "typescript"}.get(suffix, "javascript")
|
||||
base = re.sub(r"[^a-z0-9]+", "-", f"{row['repo'].split('/')[-1]}-{Path(target['filename']).stem}".lower()).strip("-")[:56]
|
||||
name = f"{base}-{row['sha'][:6]}"
|
||||
per_repo[row["repo"]] = per_repo.get(row["repo"], 0) + 1
|
||||
recipes.append(
|
||||
{
|
||||
"name": name,
|
||||
"host": "github",
|
||||
"repo": row["repo"],
|
||||
"parent": parents[0]["sha"],
|
||||
"commit": commit["sha"],
|
||||
"path": target["filename"],
|
||||
"mode": "hunk",
|
||||
"language": language,
|
||||
"relpath": target["filename"],
|
||||
"license": license_id,
|
||||
"cve": "",
|
||||
"year": int(str(commit["commit"]["author"]["date"])[:4]),
|
||||
"cwe": cwe,
|
||||
"class": cls,
|
||||
"mechanism": mechanism,
|
||||
"provenance": "agent",
|
||||
"origin": "github-agent-trailer",
|
||||
"project": row["repo"].split("/")[-1],
|
||||
"trailer": trailer[:120],
|
||||
"reviewer": "pending",
|
||||
"evidence": title[:200],
|
||||
"commit_url": f"https://github.com/{row['repo']}/commit/{commit['sha']}",
|
||||
}
|
||||
)
|
||||
for index, recipe in enumerate(sorted(recipes, key=lambda r: str(r["name"]))):
|
||||
recipe["split"] = "holdout" if index % 2 else "train"
|
||||
return recipes, skipped
|
||||
|
||||
|
||||
def to_toml(recipes: list[dict[str, object]]) -> str:
|
||||
lines = [
|
||||
"# agent-vfc candidate recipes from agent-trailer security-fix commits (build_recipes.py).",
|
||||
'# reviewer = "pending" means a human has not yet confirmed the vulnerability and mechanism.',
|
||||
"",
|
||||
]
|
||||
for recipe in sorted(recipes, key=lambda r: str(r["name"])):
|
||||
lines.append("[[recipe]]")
|
||||
for key, value in recipe.items():
|
||||
if isinstance(value, int) and not isinstance(value, bool):
|
||||
lines.append(f"{key} = {value}")
|
||||
else:
|
||||
lines.append(f'{key} = "{str(value).replace(chr(92), chr(92) * 2).replace(chr(34), chr(92) + chr(34))}"')
|
||||
lines.append("")
|
||||
return "\n".join(lines)
|
||||
|
||||
|
||||
def main(argv: list[str] | None = None) -> int:
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument("--search", type=Path, help="run the GitHub commit search and write candidates to this jsonl")
|
||||
parser.add_argument("--from", dest="source", type=Path, help="candidate jsonl to resolve into recipes")
|
||||
parser.add_argument("--limit", type=int, default=40)
|
||||
parser.add_argument("--max-lines", type=int, default=80)
|
||||
parser.add_argument("--out", type=Path, default=ROOT / "recipes.toml")
|
||||
args = parser.parse_args(argv)
|
||||
if args.search:
|
||||
print(f"searched {search(args.search)} candidates -> {args.search}")
|
||||
if args.source:
|
||||
recipes, skipped = build(args.source, limit=args.limit, max_lines=args.max_lines)
|
||||
args.out.write_text(to_toml(recipes), encoding="utf-8")
|
||||
print(f"wrote {args.out} ({len(recipes)} recipes); skipped {skipped}")
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
@@ -0,0 +1,91 @@
|
||||
// Provenance: Cap-go/capgo.app (fixed).
|
||||
// repo: Cap-go/capgo.app
|
||||
// commit: 4dadd2580d02213d227a331eee0232aa59859b59
|
||||
// parent: 8c0ac7e233946abd8dc26581b871e9fcd0928899
|
||||
// commit_url: https://github.com/Cap-go/capgo.app/commit/4dadd2580d02213d227a331eee0232aa59859b59
|
||||
// cve:
|
||||
// license: AGPL-3.0
|
||||
// function: next
|
||||
// relpath: supabase/functions/_backend/utils/hono.ts
|
||||
// provenance: agent
|
||||
// mechanism: permissive_default
|
||||
|
||||
export function createHono(functionName: string, _version: string) {
|
||||
let appGlobal
|
||||
if (getRuntimeKey() === 'deno') {
|
||||
appGlobal = new Hono<MiddlewareKeyVariables>().basePath(`/${functionName}`)
|
||||
}
|
||||
else {
|
||||
appGlobal = new Hono<MiddlewareKeyVariables>()
|
||||
}
|
||||
|
||||
// Plugin hot paths (/updates|/stats|/channel_self and the CF plugin worker).
|
||||
// HAR/CPU inspect showed middleware + logging dominating non-DB request cost.
|
||||
const pluginHotPath = functionName === 'plugin'
|
||||
|| functionName === 'updates'
|
||||
|| functionName === 'stats'
|
||||
|| functionName === 'channel_self'
|
||||
|
||||
appGlobal.use('*', (c, next): Promise<any> => {
|
||||
// ADD HEADER TO IDENTIFY WORKER SOURCE
|
||||
const name = `${getEnv(c, 'ENV_NAME') || functionName}-${CapgoVersion}`
|
||||
c.header('X-Worker-Source', name)
|
||||
const hostname = new URL(c.req.url).hostname
|
||||
if (!isPreviewHost(hostname))
|
||||
c.header('Content-Security-Policy', API_CONTENT_SECURITY_POLICY)
|
||||
return next()
|
||||
})
|
||||
|
||||
// Echo ACAO after the handler so Capacitor WebView origins work on routes
|
||||
// that forgot useCors (GET /ok). Do not mount hono cors globally: it
|
||||
// short-circuits OPTIONS and strips TUS discovery headers.
|
||||
if (!pluginHotPath) {
|
||||
appGlobal.use('*', async (c, next) => {
|
||||
await next()
|
||||
const origin = c.req.header('origin')
|
||||
if (!origin)
|
||||
return
|
||||
const allowed = getAllowedCorsOrigin(origin, c)
|
||||
if (allowed) {
|
||||
c.header('Access-Control-Allow-Origin', allowed)
|
||||
c.header('Vary', 'Origin', { append: true })
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// Skip hono's access logger on plugin hot paths — it serializes every request
|
||||
// on millions of device calls/day.
|
||||
if (!pluginHotPath)
|
||||
appGlobal.use('*', logger())
|
||||
// Use platform-specific request IDs, fallback to generated UUID.
|
||||
// Do not cloudlog inside the generator: it runs on every request (incl. cf-ray).
|
||||
appGlobal.use('*', requestId({
|
||||
generator: (c) => {
|
||||
// Cloudflare provides the Ray ID in the cf-ray header
|
||||
// Check this first as it's our primary deployment target
|
||||
const cfRay = c.req.header('cf-ray')
|
||||
if (cfRay)
|
||||
return cfRay
|
||||
// Supabase Edge Functions provide SB_EXECUTION_ID
|
||||
const sbExecutionId = getEnv(c, 'SB_EXECUTION_ID')
|
||||
if (sbExecutionId)
|
||||
return sbExecutionId
|
||||
// Fallback to crypto.randomUUID() if not on any known platform
|
||||
return crypto.randomUUID()
|
||||
},
|
||||
}))
|
||||
|
||||
appGlobal.post('/ok', (c) => {
|
||||
return c.json(BRES)
|
||||
})
|
||||
appGlobal.post('/ko', (c) => {
|
||||
const defaultResponse: SimpleErrorResponse = {
|
||||
error: 'unknown_error',
|
||||
message: 'KO',
|
||||
moreInfo: {},
|
||||
}
|
||||
return c.json(defaultResponse, 500)
|
||||
})
|
||||
|
||||
return appGlobal
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
// Provenance: Cap-go/capgo.app (vuln).
|
||||
// repo: Cap-go/capgo.app
|
||||
// commit: 8c0ac7e233946abd8dc26581b871e9fcd0928899
|
||||
// parent: 8c0ac7e233946abd8dc26581b871e9fcd0928899
|
||||
// commit_url: https://github.com/Cap-go/capgo.app/commit/4dadd2580d02213d227a331eee0232aa59859b59
|
||||
// cve:
|
||||
// license: AGPL-3.0
|
||||
// function: next
|
||||
// relpath: supabase/functions/_backend/utils/hono.ts
|
||||
// provenance: agent
|
||||
// mechanism: permissive_default
|
||||
|
||||
export function createHono(functionName: string, _version: string) {
|
||||
let appGlobal
|
||||
if (getRuntimeKey() === 'deno') {
|
||||
appGlobal = new Hono<MiddlewareKeyVariables>().basePath(`/${functionName}`)
|
||||
}
|
||||
else {
|
||||
appGlobal = new Hono<MiddlewareKeyVariables>()
|
||||
}
|
||||
|
||||
// Plugin hot paths (/updates|/stats|/channel_self and the CF plugin worker).
|
||||
// HAR/CPU inspect showed middleware + logging dominating non-DB request cost.
|
||||
const pluginHotPath = functionName === 'plugin'
|
||||
|| functionName === 'updates'
|
||||
|| functionName === 'stats'
|
||||
|| functionName === 'channel_self'
|
||||
|
||||
appGlobal.use('*', (c, next): Promise<any> => {
|
||||
// ADD HEADER TO IDENTIFY WORKER SOURCE
|
||||
const name = `${getEnv(c, 'ENV_NAME') || functionName}-${CapgoVersion}`
|
||||
c.header('X-Worker-Source', name)
|
||||
const hostname = new URL(c.req.url).hostname
|
||||
if (!isPreviewHost(hostname))
|
||||
c.header('Content-Security-Policy', API_CONTENT_SECURITY_POLICY)
|
||||
return next()
|
||||
})
|
||||
|
||||
// Skip hono's access logger on plugin hot paths — it serializes every request
|
||||
// on millions of device calls/day.
|
||||
if (!pluginHotPath)
|
||||
appGlobal.use('*', logger())
|
||||
// Use platform-specific request IDs, fallback to generated UUID.
|
||||
// Do not cloudlog inside the generator: it runs on every request (incl. cf-ray).
|
||||
appGlobal.use('*', requestId({
|
||||
generator: (c) => {
|
||||
// Cloudflare provides the Ray ID in the cf-ray header
|
||||
// Check this first as it's our primary deployment target
|
||||
const cfRay = c.req.header('cf-ray')
|
||||
if (cfRay)
|
||||
return cfRay
|
||||
// Supabase Edge Functions provide SB_EXECUTION_ID
|
||||
const sbExecutionId = getEnv(c, 'SB_EXECUTION_ID')
|
||||
if (sbExecutionId)
|
||||
return sbExecutionId
|
||||
// Fallback to crypto.randomUUID() if not on any known platform
|
||||
return crypto.randomUUID()
|
||||
},
|
||||
}))
|
||||
|
||||
appGlobal.post('/ok', (c) => {
|
||||
return c.json(BRES)
|
||||
})
|
||||
appGlobal.post('/ko', (c) => {
|
||||
const defaultResponse: SimpleErrorResponse = {
|
||||
error: 'unknown_error',
|
||||
message: 'KO',
|
||||
moreInfo: {},
|
||||
}
|
||||
return c.json(defaultResponse, 500)
|
||||
})
|
||||
|
||||
return appGlobal
|
||||
}
|
||||
@@ -0,0 +1,819 @@
|
||||
# CANDIDATES awaiting human review (reviewer = "pending"). Not loaded by load_pair_catalog.
|
||||
# Set `reviewer` in recipes.toml after confirming vulnerability, mechanism, and license; then regenerate.
|
||||
|
||||
# agent-vfc pair slice. Reviewed isolated functions with provenance.
|
||||
# Honesty dashboard — not the local 100% CI gate.
|
||||
# Do not add these names to LANGUAGE_MANIFESTS.
|
||||
# Regenerated by benchmarks/pairs/catalog_gen.py from recipes.toml.
|
||||
|
||||
[[pair]]
|
||||
name = "anastasios-pw-session-14ec1a"
|
||||
slice = "agent-vfc"
|
||||
language = "typescript"
|
||||
origin = "github-agent-trailer"
|
||||
license = "MIT"
|
||||
repo = "Anas329796/Anastasios"
|
||||
cve = ""
|
||||
cwe = "CWE-918"
|
||||
commit = "14ec1ac50f9e4e255d875236d30129c6207401d4"
|
||||
parent = "adb7b0d5d6b81c46d56451c709e7eac9d0dc93fb"
|
||||
commit_url = "https://github.com/Anas329796/Anastasios/commit/14ec1ac50f9e4e255d875236d30129c6207401d4"
|
||||
vuln = "anastasios-pw-session-14ec1a/vuln.ts"
|
||||
fixed = "anastasios-pw-session-14ec1a/fixed.ts"
|
||||
relpath = "extensions/browser/src/browser/pw-session.ts"
|
||||
min_recall = 1.0
|
||||
fix_policy = "silent"
|
||||
provenance = "agent"
|
||||
split = "holdout"
|
||||
|
||||
[[pair.expected]]
|
||||
cwe = "CWE-918"
|
||||
class = "server-side request forgery"
|
||||
path = "extensions/browser/src/browser/pw-session.ts"
|
||||
function = "isTopLevelNavigationRequest"
|
||||
mechanism = "source_reaches_sink"
|
||||
evidence = "fix(browser): harden SSRF redirect guard against non-navigation document hops [AI] (#62355)"
|
||||
|
||||
[[pair]]
|
||||
name = "astroclaw-pw-session-1553a8"
|
||||
slice = "agent-vfc"
|
||||
language = "typescript"
|
||||
origin = "github-agent-trailer"
|
||||
license = "MIT"
|
||||
repo = "P1R4N351/astroclaw"
|
||||
cve = ""
|
||||
cwe = "CWE-918"
|
||||
commit = "1553a8adf123913cf7f1f1c75be4c4e5cd6c796b"
|
||||
parent = "d3eed2dc01328f21dd404477bb28e2740fa371a4"
|
||||
commit_url = "https://github.com/P1R4N351/astroclaw/commit/1553a8adf123913cf7f1f1c75be4c4e5cd6c796b"
|
||||
vuln = "astroclaw-pw-session-1553a8/vuln.ts"
|
||||
fixed = "astroclaw-pw-session-1553a8/fixed.ts"
|
||||
relpath = "extensions/browser/src/browser/pw-session.ts"
|
||||
min_recall = 1.0
|
||||
fix_policy = "silent"
|
||||
provenance = "agent"
|
||||
split = "holdout"
|
||||
|
||||
[[pair.expected]]
|
||||
cwe = "CWE-918"
|
||||
class = "server-side request forgery"
|
||||
path = "extensions/browser/src/browser/pw-session.ts"
|
||||
function = "isTopLevelNavigationRequest"
|
||||
mechanism = "source_reaches_sink"
|
||||
evidence = "fix(browser): harden SSRF redirect guard against non-navigation document hops [AI] (#62355)"
|
||||
|
||||
[[pair]]
|
||||
name = "capgo-app-hono-4dadd2"
|
||||
slice = "agent-vfc"
|
||||
language = "typescript"
|
||||
origin = "github-agent-trailer"
|
||||
license = "AGPL-3.0"
|
||||
repo = "Cap-go/capgo.app"
|
||||
cve = ""
|
||||
cwe = "CWE-16"
|
||||
commit = "4dadd2580d02213d227a331eee0232aa59859b59"
|
||||
parent = "8c0ac7e233946abd8dc26581b871e9fcd0928899"
|
||||
commit_url = "https://github.com/Cap-go/capgo.app/commit/4dadd2580d02213d227a331eee0232aa59859b59"
|
||||
vuln = "capgo-app-hono-4dadd2/vuln.ts"
|
||||
fixed = "capgo-app-hono-4dadd2/fixed.ts"
|
||||
relpath = "supabase/functions/_backend/utils/hono.ts"
|
||||
min_recall = 1.0
|
||||
fix_policy = "silent"
|
||||
provenance = "agent"
|
||||
split = "holdout"
|
||||
|
||||
[[pair.expected]]
|
||||
cwe = "CWE-16"
|
||||
class = "permissive default"
|
||||
path = "supabase/functions/_backend/utils/hono.ts"
|
||||
function = "next"
|
||||
mechanism = "permissive_default"
|
||||
evidence = "fix(api): CORS for Capacitor localhost WebView (#3105)"
|
||||
|
||||
[[pair]]
|
||||
name = "dnf-plugin-anyrepo-config-26d19a"
|
||||
slice = "agent-vfc"
|
||||
language = "python"
|
||||
origin = "github-agent-trailer"
|
||||
license = "Apache-2.0"
|
||||
repo = "jfut/dnf-plugin-anyrepo"
|
||||
cve = ""
|
||||
cwe = "CWE-22"
|
||||
commit = "26d19aeb8884f244e34ccfdc4f49f07055adc4d0"
|
||||
parent = "33cde479d0db8f45dd89fbdcfb2bc0f1be66bd7a"
|
||||
commit_url = "https://github.com/jfut/dnf-plugin-anyrepo/commit/26d19aeb8884f244e34ccfdc4f49f07055adc4d0"
|
||||
vuln = "dnf-plugin-anyrepo-config-26d19a/vuln.py"
|
||||
fixed = "dnf-plugin-anyrepo-config-26d19a/fixed.py"
|
||||
relpath = "dnf_plugin_anyrepo/config.py"
|
||||
min_recall = 1.0
|
||||
fix_policy = "silent"
|
||||
provenance = "agent"
|
||||
split = "holdout"
|
||||
|
||||
[[pair.expected]]
|
||||
cwe = "CWE-22"
|
||||
class = "path traversal"
|
||||
path = "dnf_plugin_anyrepo/config.py"
|
||||
function = "validate_repo_name"
|
||||
mechanism = "path_join_user_input"
|
||||
evidence = "fix(config): prevent path traversal in repository names"
|
||||
|
||||
[[pair]]
|
||||
name = "edutrace-page-ee7ba2"
|
||||
slice = "agent-vfc"
|
||||
language = "typescript"
|
||||
origin = "github-agent-trailer"
|
||||
license = "Apache-2.0"
|
||||
repo = "jardimdesoftware/edutrace"
|
||||
cve = ""
|
||||
cwe = "CWE-1321"
|
||||
commit = "ee7ba25fb23ea89cc1b67549cb5e32c8ead92739"
|
||||
parent = "c4dc6ddcc5492c77c8a5ad7369c87dea29c001fd"
|
||||
commit_url = "https://github.com/jardimdesoftware/edutrace/commit/ee7ba25fb23ea89cc1b67549cb5e32c8ead92739"
|
||||
vuln = "edutrace-page-ee7ba2/vuln.tsx"
|
||||
fixed = "edutrace-page-ee7ba2/fixed.tsx"
|
||||
relpath = "front/src/app/editar-anamnese/page.tsx"
|
||||
min_recall = 1.0
|
||||
fix_policy = "silent"
|
||||
provenance = "agent"
|
||||
split = "train"
|
||||
|
||||
[[pair.expected]]
|
||||
cwe = "CWE-1321"
|
||||
class = "prototype pollution"
|
||||
path = "front/src/app/editar-anamnese/page.tsx"
|
||||
function = "handleInputChange"
|
||||
mechanism = "prototype_pollution"
|
||||
evidence = "fix(front): impedir prototype pollution nos handlers de formulário aninhado"
|
||||
|
||||
[[pair]]
|
||||
name = "etude-lexical-markdown-editorconfig-c61a8b"
|
||||
slice = "agent-vfc"
|
||||
language = "typescript"
|
||||
origin = "github-agent-trailer"
|
||||
license = "MIT"
|
||||
repo = "dayflower/etude-lexical-markdown"
|
||||
cve = ""
|
||||
cwe = "CWE-1321"
|
||||
commit = "c61a8bf78fe20d6ae0eab2e4b8b02004508525ed"
|
||||
parent = "0a2184f59e79a04b1365cd49200026e8f2ffdbd5"
|
||||
commit_url = "https://github.com/dayflower/etude-lexical-markdown/commit/c61a8bf78fe20d6ae0eab2e4b8b02004508525ed"
|
||||
vuln = "etude-lexical-markdown-editorconfig-c61a8b/vuln.ts"
|
||||
fixed = "etude-lexical-markdown-editorconfig-c61a8b/fixed.ts"
|
||||
relpath = "src/config/editorConfig.ts"
|
||||
min_recall = 1.0
|
||||
fix_policy = "silent"
|
||||
provenance = "agent"
|
||||
split = "train"
|
||||
|
||||
[[pair.expected]]
|
||||
cwe = "CWE-1321"
|
||||
class = "prototype pollution"
|
||||
path = "src/config/editorConfig.ts"
|
||||
function = "deepMergeInto"
|
||||
mechanism = "prototype_pollution"
|
||||
evidence = "fix: guard deepMergeInto against prototype pollution"
|
||||
|
||||
[[pair]]
|
||||
name = "etude-lexical-markdown-editorconfig-db4f54"
|
||||
slice = "agent-vfc"
|
||||
language = "typescript"
|
||||
origin = "github-agent-trailer"
|
||||
license = "MIT"
|
||||
repo = "dayflower/etude-lexical-markdown"
|
||||
cve = ""
|
||||
cwe = "CWE-1321"
|
||||
commit = "db4f54b1ab80ad596de6425e84f90aa781c49999"
|
||||
parent = "1c865815d05b072f4973388c3ac66b6696d9efde"
|
||||
commit_url = "https://github.com/dayflower/etude-lexical-markdown/commit/db4f54b1ab80ad596de6425e84f90aa781c49999"
|
||||
vuln = "etude-lexical-markdown-editorconfig-db4f54/vuln.ts"
|
||||
fixed = "etude-lexical-markdown-editorconfig-db4f54/fixed.ts"
|
||||
relpath = "src/config/editorConfig.ts"
|
||||
min_recall = 1.0
|
||||
fix_policy = "silent"
|
||||
provenance = "agent"
|
||||
split = "holdout"
|
||||
|
||||
[[pair.expected]]
|
||||
cwe = "CWE-1321"
|
||||
class = "prototype pollution"
|
||||
path = "src/config/editorConfig.ts"
|
||||
function = "deepMergeInto"
|
||||
mechanism = "prototype_pollution"
|
||||
evidence = "fix: make prototype pollution guard recognizable by CodeQL"
|
||||
|
||||
[[pair]]
|
||||
name = "lensops-kubernetesmanagement-fe4910"
|
||||
slice = "agent-vfc"
|
||||
language = "typescript"
|
||||
origin = "github-agent-trailer"
|
||||
license = "MIT"
|
||||
repo = "amitknigam84/lensops"
|
||||
cve = ""
|
||||
cwe = "CWE-862"
|
||||
commit = "fe49109aedfe21dea4d24d4d9f2fa3f1ecfb6c84"
|
||||
parent = "9b87ecc3a44a7fe2a5185cca1fe52441647d5748"
|
||||
commit_url = "https://github.com/amitknigam84/lensops/commit/fe49109aedfe21dea4d24d4d9f2fa3f1ecfb6c84"
|
||||
vuln = "lensops-kubernetesmanagement-fe4910/vuln.tsx"
|
||||
fixed = "lensops-kubernetesmanagement-fe4910/fixed.tsx"
|
||||
relpath = "components/KubernetesManagement.tsx"
|
||||
min_recall = 1.0
|
||||
fix_policy = "silent"
|
||||
provenance = "agent"
|
||||
split = "holdout"
|
||||
|
||||
[[pair.expected]]
|
||||
cwe = "CWE-862"
|
||||
class = "missing authorization"
|
||||
path = "components/KubernetesManagement.tsx"
|
||||
function = "setErrorMessage"
|
||||
mechanism = "missing_auth_guard"
|
||||
evidence = "Fix missing auth header on namespaces API call"
|
||||
|
||||
[[pair]]
|
||||
name = "market-cap-route-4f8ae9"
|
||||
slice = "agent-vfc"
|
||||
language = "typescript"
|
||||
origin = "github-agent-trailer"
|
||||
license = "MIT"
|
||||
repo = "navaneethbv/market-cap"
|
||||
cve = ""
|
||||
cwe = "CWE-601"
|
||||
commit = "4f8ae9be5519ced5a975f1190e3e4bc43f84e4d6"
|
||||
parent = "fec6f024ce72c9c47b61cbac6ce7a35cb2280602"
|
||||
commit_url = "https://github.com/navaneethbv/market-cap/commit/4f8ae9be5519ced5a975f1190e3e4bc43f84e4d6"
|
||||
vuln = "market-cap-route-4f8ae9/vuln.ts"
|
||||
fixed = "market-cap-route-4f8ae9/fixed.ts"
|
||||
relpath = "app/auth/confirm/route.ts"
|
||||
min_recall = 1.0
|
||||
fix_policy = "silent"
|
||||
provenance = "agent"
|
||||
split = "train"
|
||||
|
||||
[[pair.expected]]
|
||||
cwe = "CWE-601"
|
||||
class = "open redirect"
|
||||
path = "app/auth/confirm/route.ts"
|
||||
function = "GET"
|
||||
mechanism = "source_reaches_sink"
|
||||
evidence = "Fix open redirects on the auth next param"
|
||||
|
||||
[[pair]]
|
||||
name = "melodix-playerprovider-089931"
|
||||
slice = "agent-vfc"
|
||||
language = "typescript"
|
||||
origin = "github-agent-trailer"
|
||||
license = "MIT"
|
||||
repo = "alexshao3/melodix"
|
||||
cve = ""
|
||||
cwe = "CWE-16"
|
||||
commit = "089931ef71ea1e5b7586520baf1a5498e2f05b13"
|
||||
parent = "c074fc7413338aefcbea3170ef4d3ba486a8a4b7"
|
||||
commit_url = "https://github.com/alexshao3/melodix/commit/089931ef71ea1e5b7586520baf1a5498e2f05b13"
|
||||
vuln = "melodix-playerprovider-089931/vuln.tsx"
|
||||
fixed = "melodix-playerprovider-089931/fixed.tsx"
|
||||
relpath = "apps/miniapp/src/components/PlayerProvider.tsx"
|
||||
min_recall = 1.0
|
||||
fix_policy = "silent"
|
||||
provenance = "agent"
|
||||
split = "holdout"
|
||||
|
||||
[[pair.expected]]
|
||||
cwe = "CWE-16"
|
||||
class = "permissive default"
|
||||
path = "apps/miniapp/src/components/PlayerProvider.tsx"
|
||||
function = "PlayerProvider"
|
||||
mechanism = "permissive_default"
|
||||
evidence = "Merge pull request #17 from alexshao3/devin/1777216143-fix-audio-cors"
|
||||
|
||||
[[pair]]
|
||||
name = "mercado-do-vale-news-catalogmetadataservice-9b5fcf"
|
||||
slice = "agent-vfc"
|
||||
language = "typescript"
|
||||
origin = "github-agent-trailer"
|
||||
license = "MIT"
|
||||
repo = "handielson/Mercado-do-vale-news"
|
||||
cve = ""
|
||||
cwe = "CWE-16"
|
||||
commit = "9b5fcf2dae41e56f5f97952266f2d6ba59598598"
|
||||
parent = "70ca282b819ac1d60f4b5e665d224b1043ff1ccc"
|
||||
commit_url = "https://github.com/handielson/Mercado-do-vale-news/commit/9b5fcf2dae41e56f5f97952266f2d6ba59598598"
|
||||
vuln = "mercado-do-vale-news-catalogmetadataservice-9b5fcf/vuln.ts"
|
||||
fixed = "mercado-do-vale-news-catalogmetadataservice-9b5fcf/fixed.ts"
|
||||
relpath = "services/catalogMetadataService.ts"
|
||||
min_recall = 1.0
|
||||
fix_policy = "silent"
|
||||
provenance = "agent"
|
||||
split = "train"
|
||||
|
||||
[[pair.expected]]
|
||||
cwe = "CWE-16"
|
||||
class = "permissive default"
|
||||
path = "services/catalogMetadataService.ts"
|
||||
function = "fetchMetadata"
|
||||
mechanism = "permissive_default"
|
||||
evidence = "fix(catalog): avoid metadata cors preflight"
|
||||
|
||||
[[pair]]
|
||||
name = "money-track-category-icons-4d4a5b"
|
||||
slice = "agent-vfc"
|
||||
language = "typescript"
|
||||
origin = "github-agent-trailer"
|
||||
license = "MIT"
|
||||
repo = "andrebubniak/money-track"
|
||||
cve = ""
|
||||
cwe = "CWE-1321"
|
||||
commit = "4d4a5b063278c8b6697c3faae133d7c39fcd01c0"
|
||||
parent = "add96df6d6a6b61506635c23dbacf6c6cfe24dc2"
|
||||
commit_url = "https://github.com/andrebubniak/money-track/commit/4d4a5b063278c8b6697c3faae133d7c39fcd01c0"
|
||||
vuln = "money-track-category-icons-4d4a5b/vuln.ts"
|
||||
fixed = "money-track-category-icons-4d4a5b/fixed.ts"
|
||||
relpath = "src/lib/category-icons.ts"
|
||||
min_recall = 1.0
|
||||
fix_policy = "silent"
|
||||
provenance = "agent"
|
||||
split = "holdout"
|
||||
|
||||
[[pair.expected]]
|
||||
cwe = "CWE-1321"
|
||||
class = "prototype pollution"
|
||||
path = "src/lib/category-icons.ts"
|
||||
function = "isCategoryIcon"
|
||||
mechanism = "prototype_pollution"
|
||||
evidence = "fix(category-icons): use Object.hasOwn to prevent prototype pollution in type guard"
|
||||
|
||||
[[pair]]
|
||||
name = "nestjs-filter-normalizer-aa0e60"
|
||||
slice = "agent-vfc"
|
||||
language = "typescript"
|
||||
origin = "github-agent-trailer"
|
||||
license = "MIT"
|
||||
repo = "DavideCarvalho/nestjs-filter"
|
||||
cve = ""
|
||||
cwe = "CWE-1321"
|
||||
commit = "aa0e600d05997ea3d77538ea1c2db427c439f2e8"
|
||||
parent = "d899b40d3466f2ffbe9f01c4d49267412401f078"
|
||||
commit_url = "https://github.com/DavideCarvalho/nestjs-filter/commit/aa0e600d05997ea3d77538ea1c2db427c439f2e8"
|
||||
vuln = "nestjs-filter-normalizer-aa0e60/vuln.ts"
|
||||
fixed = "nestjs-filter-normalizer-aa0e60/fixed.ts"
|
||||
relpath = "packages/core/src/input/normalizer.ts"
|
||||
min_recall = 1.0
|
||||
fix_policy = "silent"
|
||||
provenance = "agent"
|
||||
split = "train"
|
||||
|
||||
[[pair.expected]]
|
||||
cwe = "CWE-1321"
|
||||
class = "prototype pollution"
|
||||
path = "packages/core/src/input/normalizer.ts"
|
||||
function = "normalizeInput"
|
||||
mechanism = "prototype_pollution"
|
||||
evidence = "fix(core): add prototype pollution guard to normalizeInput"
|
||||
|
||||
[[pair]]
|
||||
name = "new-erp-final-app-6e9644"
|
||||
slice = "agent-vfc"
|
||||
language = "typescript"
|
||||
origin = "github-agent-trailer"
|
||||
license = "Apache-2.0"
|
||||
repo = "Sachin-Salgar/NEW_ERP_FINAL"
|
||||
cve = ""
|
||||
cwe = "CWE-16"
|
||||
commit = "6e9644c81ce3fb356669157182a5ef09a70c4b59"
|
||||
parent = "08976c5d7a07b0663669b875b4507446199f85d7"
|
||||
commit_url = "https://github.com/Sachin-Salgar/NEW_ERP_FINAL/commit/6e9644c81ce3fb356669157182a5ef09a70c4b59"
|
||||
vuln = "new-erp-final-app-6e9644/vuln.ts"
|
||||
fixed = "new-erp-final-app-6e9644/fixed.ts"
|
||||
relpath = "src/presentation/http/app.ts"
|
||||
min_recall = 1.0
|
||||
fix_policy = "silent"
|
||||
provenance = "agent"
|
||||
split = "holdout"
|
||||
|
||||
[[pair.expected]]
|
||||
cwe = "CWE-16"
|
||||
class = "permissive default"
|
||||
path = "src/presentation/http/app.ts"
|
||||
function = "origin"
|
||||
mechanism = "permissive_default"
|
||||
evidence = "fix: allow patch requests through cors"
|
||||
|
||||
[[pair]]
|
||||
name = "nimestream-route-d17f53"
|
||||
slice = "agent-vfc"
|
||||
language = "javascript"
|
||||
origin = "github-agent-trailer"
|
||||
license = "MIT"
|
||||
repo = "Irnhakim/nimestream"
|
||||
cve = ""
|
||||
cwe = "CWE-918"
|
||||
commit = "d17f535bf3012041b056ff3aa991ff6cfa198e43"
|
||||
parent = "0c37bfd9e5292b15b1d7af51f52793d9bdf1cef0"
|
||||
commit_url = "https://github.com/Irnhakim/nimestream/commit/d17f535bf3012041b056ff3aa991ff6cfa198e43"
|
||||
vuln = "nimestream-route-d17f53/vuln.js"
|
||||
fixed = "nimestream-route-d17f53/fixed.js"
|
||||
relpath = "app/api/img/route.js"
|
||||
min_recall = 1.0
|
||||
fix_policy = "silent"
|
||||
provenance = "agent"
|
||||
split = "train"
|
||||
|
||||
[[pair.expected]]
|
||||
cwe = "CWE-918"
|
||||
class = "server-side request forgery"
|
||||
path = "app/api/img/route.js"
|
||||
function = "GET"
|
||||
mechanism = "source_reaches_sink"
|
||||
evidence = "fix: resolve command injection and SSRF/Open Redirect security issues in multiScraper and image proxy API"
|
||||
|
||||
[[pair]]
|
||||
name = "openniw-jobs-0fc947"
|
||||
slice = "agent-vfc"
|
||||
language = "python"
|
||||
origin = "github-agent-trailer"
|
||||
license = "MIT"
|
||||
repo = "HHHHHejia/openniw"
|
||||
cve = ""
|
||||
cwe = "CWE-639"
|
||||
commit = "0fc94733f6ca3c6b129a0a8e6d7b3acce19d5a10"
|
||||
parent = "4d91ed82fa9a5ec6bf5ef96da1d221fc187700dc"
|
||||
commit_url = "https://github.com/HHHHHejia/openniw/commit/0fc94733f6ca3c6b129a0a8e6d7b3acce19d5a10"
|
||||
vuln = "openniw-jobs-0fc947/vuln.py"
|
||||
fixed = "openniw-jobs-0fc947/fixed.py"
|
||||
relpath = "backend/app/routers/jobs.py"
|
||||
min_recall = 1.0
|
||||
fix_policy = "silent"
|
||||
provenance = "agent"
|
||||
split = "train"
|
||||
|
||||
[[pair.expected]]
|
||||
cwe = "CWE-639"
|
||||
class = "insecure direct object reference"
|
||||
path = "backend/app/routers/jobs.py"
|
||||
function = "get_job"
|
||||
mechanism = "identity_from_request_body"
|
||||
evidence = "Fix IDOR on job endpoint: case-bound jobs require case ownership"
|
||||
|
||||
[[pair]]
|
||||
name = "openniw-jobs-b74de3"
|
||||
slice = "agent-vfc"
|
||||
language = "python"
|
||||
origin = "github-agent-trailer"
|
||||
license = "MIT"
|
||||
repo = "ziyuzuo/openniw"
|
||||
cve = ""
|
||||
cwe = "CWE-639"
|
||||
commit = "b74de31b0a5f37e4e929ba6aa74dbe0f5e6d9a68"
|
||||
parent = "98a0c392ba96cd2c4aa746dd6fc2b183f385225e"
|
||||
commit_url = "https://github.com/ziyuzuo/openniw/commit/b74de31b0a5f37e4e929ba6aa74dbe0f5e6d9a68"
|
||||
vuln = "openniw-jobs-b74de3/vuln.py"
|
||||
fixed = "openniw-jobs-b74de3/fixed.py"
|
||||
relpath = "backend/app/routers/jobs.py"
|
||||
min_recall = 1.0
|
||||
fix_policy = "silent"
|
||||
provenance = "agent"
|
||||
split = "holdout"
|
||||
|
||||
[[pair.expected]]
|
||||
cwe = "CWE-639"
|
||||
class = "insecure direct object reference"
|
||||
path = "backend/app/routers/jobs.py"
|
||||
function = "get_job"
|
||||
mechanism = "identity_from_request_body"
|
||||
evidence = "Fix IDOR on job endpoint: case-bound jobs require case ownership"
|
||||
|
||||
[[pair]]
|
||||
name = "overleaf-with-claude-exportscontroller-3980b9"
|
||||
slice = "agent-vfc"
|
||||
language = "javascript"
|
||||
origin = "github-agent-trailer"
|
||||
license = "AGPL-3.0"
|
||||
repo = "ZUENS2020/overleaf-with-claude"
|
||||
cve = ""
|
||||
cwe = "CWE-639"
|
||||
commit = "3980b9e5806defb63e45ae2696e6c1899f3a8431"
|
||||
parent = "5a886aa9fb9fe4e2203f3cb1d62c91f4be0525ed"
|
||||
commit_url = "https://github.com/ZUENS2020/overleaf-with-claude/commit/3980b9e5806defb63e45ae2696e6c1899f3a8431"
|
||||
vuln = "overleaf-with-claude-exportscontroller-3980b9/vuln.mjs"
|
||||
fixed = "overleaf-with-claude-exportscontroller-3980b9/fixed.mjs"
|
||||
relpath = "services/web/app/src/Features/Exports/ExportsController.mjs"
|
||||
min_recall = 1.0
|
||||
fix_policy = "silent"
|
||||
provenance = "agent"
|
||||
split = "train"
|
||||
|
||||
[[pair.expected]]
|
||||
cwe = "CWE-639"
|
||||
class = "insecure direct object reference"
|
||||
path = "services/web/app/src/Features/Exports/ExportsController.mjs"
|
||||
function = "exportProject"
|
||||
mechanism = "identity_from_request_body"
|
||||
evidence = "Fix IDOR in exports by adding token verification (Issue #31637) (#32883)"
|
||||
|
||||
[[pair]]
|
||||
name = "popmark-editorconfig-e5ac40"
|
||||
slice = "agent-vfc"
|
||||
language = "typescript"
|
||||
origin = "github-agent-trailer"
|
||||
license = "MIT"
|
||||
repo = "dayflower/popmark"
|
||||
cve = ""
|
||||
cwe = "CWE-1321"
|
||||
commit = "e5ac407cef37c37178d440541ede301c838640fb"
|
||||
parent = "31d1ac79b4cfa3118597348e79800a6561115149"
|
||||
commit_url = "https://github.com/dayflower/popmark/commit/e5ac407cef37c37178d440541ede301c838640fb"
|
||||
vuln = "popmark-editorconfig-e5ac40/vuln.ts"
|
||||
fixed = "popmark-editorconfig-e5ac40/fixed.ts"
|
||||
relpath = "src/lexical-markdown/config/editorConfig.ts"
|
||||
min_recall = 1.0
|
||||
fix_policy = "silent"
|
||||
provenance = "agent"
|
||||
split = "holdout"
|
||||
|
||||
[[pair.expected]]
|
||||
cwe = "CWE-1321"
|
||||
class = "prototype pollution"
|
||||
path = "src/lexical-markdown/config/editorConfig.ts"
|
||||
function = "deepMergeInto"
|
||||
mechanism = "prototype_pollution"
|
||||
evidence = "fix: guard deepMergeInto against prototype pollution"
|
||||
|
||||
[[pair]]
|
||||
name = "rag-pipeline-utils-config-handler-76e5f0"
|
||||
slice = "agent-vfc"
|
||||
language = "javascript"
|
||||
origin = "github-agent-trailer"
|
||||
license = "MIT"
|
||||
repo = "DevilsDev/rag-pipeline-utils"
|
||||
cve = ""
|
||||
cwe = "CWE-1321"
|
||||
commit = "76e5f0a94d6803d0e463d26a61cedb7da90857a7"
|
||||
parent = "ba587867118f703632ff2dc63c4feb8ad6793420"
|
||||
commit_url = "https://github.com/DevilsDev/rag-pipeline-utils/commit/76e5f0a94d6803d0e463d26a61cedb7da90857a7"
|
||||
vuln = "rag-pipeline-utils-config-handler-76e5f0/vuln.js"
|
||||
fixed = "rag-pipeline-utils-config-handler-76e5f0/fixed.js"
|
||||
relpath = "src/cli/handlers/config-handler.js"
|
||||
min_recall = 1.0
|
||||
fix_policy = "silent"
|
||||
provenance = "agent"
|
||||
split = "train"
|
||||
|
||||
[[pair.expected]]
|
||||
cwe = "CWE-1321"
|
||||
class = "prototype pollution"
|
||||
path = "src/cli/handlers/config-handler.js"
|
||||
function = "handleConfigSet"
|
||||
mechanism = "prototype_pollution"
|
||||
evidence = "fix(security): prevent prototype pollution in config-handler"
|
||||
|
||||
[[pair]]
|
||||
name = "registry-proxy-worker-426847"
|
||||
slice = "agent-vfc"
|
||||
language = "javascript"
|
||||
origin = "github-agent-trailer"
|
||||
license = "MIT"
|
||||
repo = "agents-repo/registry-proxy"
|
||||
cve = ""
|
||||
cwe = "CWE-16"
|
||||
commit = "426847899eb2ee94ae4e5a3aacc50423e36d2dc8"
|
||||
parent = "6d5937972510cdb5ebca30607b538fdc2e280094"
|
||||
commit_url = "https://github.com/agents-repo/registry-proxy/commit/426847899eb2ee94ae4e5a3aacc50423e36d2dc8"
|
||||
vuln = "registry-proxy-worker-426847/vuln.js"
|
||||
fixed = "registry-proxy-worker-426847/fixed.js"
|
||||
relpath = "src/worker.js"
|
||||
min_recall = 1.0
|
||||
fix_policy = "silent"
|
||||
provenance = "agent"
|
||||
split = "holdout"
|
||||
|
||||
[[pair.expected]]
|
||||
cwe = "CWE-16"
|
||||
class = "permissive default"
|
||||
path = "src/worker.js"
|
||||
function = "buildUpstreamRequest"
|
||||
mechanism = "permissive_default"
|
||||
evidence = "fix: handle CORS OPTIONS preflight for catalog fetches (#10)"
|
||||
|
||||
[[pair]]
|
||||
name = "supplieradvisor-mvp-route-387bcf"
|
||||
slice = "agent-vfc"
|
||||
language = "typescript"
|
||||
origin = "github-agent-trailer"
|
||||
license = "MIT"
|
||||
repo = "bigfivefoods/supplieradvisor-mvp"
|
||||
cve = ""
|
||||
cwe = "CWE-639"
|
||||
commit = "387bcf40e984a2ee1832ab7beabf0284c5b627d8"
|
||||
parent = "a7a9bc260d649ea2e582c07435bfd7d93100647b"
|
||||
commit_url = "https://github.com/bigfivefoods/supplieradvisor-mvp/commit/387bcf40e984a2ee1832ab7beabf0284c5b627d8"
|
||||
vuln = "supplieradvisor-mvp-route-387bcf/vuln.ts"
|
||||
fixed = "supplieradvisor-mvp-route-387bcf/fixed.ts"
|
||||
relpath = "app/api/customers/claims/route.ts"
|
||||
min_recall = 1.0
|
||||
fix_policy = "silent"
|
||||
provenance = "agent"
|
||||
split = "holdout"
|
||||
|
||||
[[pair.expected]]
|
||||
cwe = "CWE-639"
|
||||
class = "insecure direct object reference"
|
||||
path = "app/api/customers/claims/route.ts"
|
||||
function = "PATCH"
|
||||
mechanism = "identity_from_request_body"
|
||||
evidence = "Brief 62: Fix IDOR on customer_claims PATCH/DELETE (#156)"
|
||||
|
||||
[[pair]]
|
||||
name = "supplieradvisor-mvp-route-a69e8f"
|
||||
slice = "agent-vfc"
|
||||
language = "typescript"
|
||||
origin = "github-agent-trailer"
|
||||
license = "MIT"
|
||||
repo = "bigfivefoods/supplieradvisor-mvp"
|
||||
cve = ""
|
||||
cwe = "CWE-639"
|
||||
commit = "a69e8f27c0f4d402573d16f0612b51155bbc46e1"
|
||||
parent = "8558538471e4fb10856f8d9a17d2be5ab5c4fb9c"
|
||||
commit_url = "https://github.com/bigfivefoods/supplieradvisor-mvp/commit/a69e8f27c0f4d402573d16f0612b51155bbc46e1"
|
||||
vuln = "supplieradvisor-mvp-route-a69e8f/vuln.ts"
|
||||
fixed = "supplieradvisor-mvp-route-a69e8f/fixed.ts"
|
||||
relpath = "app/api/customers/opportunities/route.ts"
|
||||
min_recall = 1.0
|
||||
fix_policy = "silent"
|
||||
provenance = "agent"
|
||||
split = "train"
|
||||
|
||||
[[pair.expected]]
|
||||
cwe = "CWE-639"
|
||||
class = "insecure direct object reference"
|
||||
path = "app/api/customers/opportunities/route.ts"
|
||||
function = "GET"
|
||||
mechanism = "identity_from_request_body"
|
||||
evidence = "Brief 60: Fix IDOR on opportunities GET/PATCH/DELETE (missing company membership checks) (#148)"
|
||||
|
||||
[[pair]]
|
||||
name = "tools-cli-tools-a96bc0"
|
||||
slice = "agent-vfc"
|
||||
language = "python"
|
||||
origin = "github-agent-trailer"
|
||||
license = "MIT"
|
||||
repo = "D-sorganization/Tools"
|
||||
cve = ""
|
||||
cwe = "CWE-78"
|
||||
commit = "a96bc0502a3dcdac303e4f0152508886e5c35c0a"
|
||||
parent = "e735d28b82dd1fbc42c0ae01157b38d1b4c7c864"
|
||||
commit_url = "https://github.com/D-sorganization/Tools/commit/a96bc0502a3dcdac303e4f0152508886e5c35c0a"
|
||||
vuln = "tools-cli-tools-a96bc0/vuln.py"
|
||||
fixed = "tools-cli-tools-a96bc0/fixed.py"
|
||||
relpath = "src/shared/python/ai/tools/cli_tools.py"
|
||||
min_recall = 1.0
|
||||
fix_policy = "silent"
|
||||
provenance = "agent"
|
||||
split = "holdout"
|
||||
|
||||
[[pair.expected]]
|
||||
cwe = "CWE-78"
|
||||
class = "command injection"
|
||||
path = "src/shared/python/ai/tools/cli_tools.py"
|
||||
function = "_is_command_allowed"
|
||||
mechanism = "source_reaches_sink"
|
||||
evidence = "🛡️ Sentinel: [CRITICAL] Fix command injection in ShellTool (#3307)"
|
||||
|
||||
[[pair]]
|
||||
name = "trackly-cli-path-diagnostics-1c1aed"
|
||||
slice = "agent-vfc"
|
||||
language = "javascript"
|
||||
origin = "github-agent-trailer"
|
||||
license = "MIT"
|
||||
repo = "trackly-app/trackly-cli"
|
||||
cve = ""
|
||||
cwe = "CWE-22"
|
||||
commit = "1c1aed89b07edb04051830c8f086e02b65e961c6"
|
||||
parent = "8d240ad8d7fc114c8f941ad956a2fdf32391ff60"
|
||||
commit_url = "https://github.com/trackly-app/trackly-cli/commit/1c1aed89b07edb04051830c8f086e02b65e961c6"
|
||||
vuln = "trackly-cli-path-diagnostics-1c1aed/vuln.js"
|
||||
fixed = "trackly-cli-path-diagnostics-1c1aed/fixed.js"
|
||||
relpath = "lib/path-diagnostics.js"
|
||||
min_recall = 1.0
|
||||
fix_policy = "silent"
|
||||
provenance = "agent"
|
||||
split = "holdout"
|
||||
|
||||
[[pair.expected]]
|
||||
cwe = "CWE-22"
|
||||
class = "path traversal"
|
||||
path = "lib/path-diagnostics.js"
|
||||
function = "inspectExistingAncestor"
|
||||
mechanism = "path_join_user_input"
|
||||
evidence = "fix(apply): report blocked path traversal"
|
||||
|
||||
[[pair]]
|
||||
name = "upstreamdrift-local-server-c3a078"
|
||||
slice = "agent-vfc"
|
||||
language = "python"
|
||||
origin = "github-agent-trailer"
|
||||
license = "MIT"
|
||||
repo = "D-sorganization/UpstreamDrift"
|
||||
cve = ""
|
||||
cwe = "CWE-22"
|
||||
commit = "c3a0787080489b30e2ed0abfac03b51e45da184b"
|
||||
parent = "e28d1da5e103d93951ef11b78a6e9b89ac1fa2bc"
|
||||
commit_url = "https://github.com/D-sorganization/UpstreamDrift/commit/c3a0787080489b30e2ed0abfac03b51e45da184b"
|
||||
vuln = "upstreamdrift-local-server-c3a078/vuln.py"
|
||||
fixed = "upstreamdrift-local-server-c3a078/fixed.py"
|
||||
relpath = "src/api/local_server.py"
|
||||
min_recall = 1.0
|
||||
fix_policy = "silent"
|
||||
provenance = "agent"
|
||||
split = "train"
|
||||
|
||||
[[pair.expected]]
|
||||
cwe = "CWE-22"
|
||||
class = "path traversal"
|
||||
path = "src/api/local_server.py"
|
||||
function = "_find_logo_file"
|
||||
mechanism = "path_join_user_input"
|
||||
evidence = "fix(api): harden local server path traversal (#2805) (#2839)"
|
||||
|
||||
[[pair]]
|
||||
name = "waggledance-swarm-ssrf-host-guard-9a4548"
|
||||
slice = "agent-vfc"
|
||||
language = "python"
|
||||
origin = "github-agent-trailer"
|
||||
license = "Apache-2.0"
|
||||
repo = "Ahkeratmehilaiset/waggledance-swarm"
|
||||
cve = ""
|
||||
cwe = "CWE-918"
|
||||
commit = "9a454843aa35332ff2eb3106023eee0c4b5e444b"
|
||||
parent = "934b939f1cca5259eaf807db3319eb97b90d8d80"
|
||||
commit_url = "https://github.com/Ahkeratmehilaiset/waggledance-swarm/commit/9a454843aa35332ff2eb3106023eee0c4b5e444b"
|
||||
vuln = "waggledance-swarm-ssrf-host-guard-9a4548/vuln.py"
|
||||
fixed = "waggledance-swarm-ssrf-host-guard-9a4548/fixed.py"
|
||||
relpath = "waggledance/core/v3_13_0/ssrf_host_guard.py"
|
||||
min_recall = 1.0
|
||||
fix_policy = "silent"
|
||||
provenance = "agent"
|
||||
split = "train"
|
||||
|
||||
[[pair.expected]]
|
||||
cwe = "CWE-918"
|
||||
class = "server-side request forgery"
|
||||
path = "waggledance/core/v3_13_0/ssrf_host_guard.py"
|
||||
function = "normalize_allowed_hosts"
|
||||
mechanism = "source_reaches_sink"
|
||||
evidence = "fix(ssrf): reject bare-string allowed hosts (#1460)"
|
||||
|
||||
[[pair]]
|
||||
name = "workers-research-utils-209444"
|
||||
slice = "agent-vfc"
|
||||
language = "typescript"
|
||||
origin = "github-agent-trailer"
|
||||
license = "MIT"
|
||||
repo = "G4brym/workers-research"
|
||||
cve = ""
|
||||
cwe = "CWE-89"
|
||||
commit = "209444eb61cc564c2d6b43267256f85fe3e5e30e"
|
||||
parent = "eab923ad3099c01b002fbd6be7cf994614bbdee4"
|
||||
commit_url = "https://github.com/G4brym/workers-research/commit/209444eb61cc564c2d6b43267256f85fe3e5e30e"
|
||||
vuln = "workers-research-utils-209444/vuln.ts"
|
||||
fixed = "workers-research-utils-209444/fixed.ts"
|
||||
relpath = "src/utils.ts"
|
||||
min_recall = 1.0
|
||||
fix_policy = "silent"
|
||||
provenance = "agent"
|
||||
split = "holdout"
|
||||
|
||||
[[pair.expected]]
|
||||
cwe = "CWE-89"
|
||||
class = "sql injection"
|
||||
path = "src/utils.ts"
|
||||
function = "formatDuration"
|
||||
mechanism = "source_reaches_sink"
|
||||
evidence = "Fix SQL injection in search by using parameterized queries (#41)"
|
||||
|
||||
[[pair]]
|
||||
name = "zoonk-origin-bfbf67"
|
||||
slice = "agent-vfc"
|
||||
language = "typescript"
|
||||
origin = "github-agent-trailer"
|
||||
license = "MIT"
|
||||
repo = "zoonk/zoonk"
|
||||
cve = ""
|
||||
cwe = "CWE-16"
|
||||
commit = "bfbf670ccb41d63c407d32c51bd26e626a174f31"
|
||||
parent = "2604269350bff51f58572c133b45010cb0976a5a"
|
||||
commit_url = "https://github.com/zoonk/zoonk/commit/bfbf670ccb41d63c407d32c51bd26e626a174f31"
|
||||
vuln = "zoonk-origin-bfbf67/vuln.ts"
|
||||
fixed = "zoonk-origin-bfbf67/fixed.ts"
|
||||
relpath = "packages/utils/src/origin.ts"
|
||||
min_recall = 1.0
|
||||
fix_policy = "silent"
|
||||
provenance = "agent"
|
||||
split = "train"
|
||||
|
||||
[[pair.expected]]
|
||||
cwe = "CWE-16"
|
||||
class = "permissive default"
|
||||
path = "packages/utils/src/origin.ts"
|
||||
function = "getAllowedHosts"
|
||||
mechanism = "permissive_default"
|
||||
evidence = "fix(api): allow staging cors from previews (#1559)"
|
||||
@@ -0,0 +1,4 @@
|
||||
# agent-vfc pair slice. Reviewed isolated functions with provenance.
|
||||
# Honesty dashboard — not the local 100% CI gate.
|
||||
# Do not add these names to LANGUAGE_MANIFESTS.
|
||||
# Regenerated by benchmarks/pairs/catalog_gen.py from recipes.toml.
|
||||
@@ -0,0 +1,26 @@
|
||||
# Provenance: jfut/dnf-plugin-anyrepo (fixed).
|
||||
# repo: jfut/dnf-plugin-anyrepo
|
||||
# commit: 26d19aeb8884f244e34ccfdc4f49f07055adc4d0
|
||||
# parent: 33cde479d0db8f45dd89fbdcfb2bc0f1be66bd7a
|
||||
# commit_url: https://github.com/jfut/dnf-plugin-anyrepo/commit/26d19aeb8884f244e34ccfdc4f49f07055adc4d0
|
||||
# cve:
|
||||
# license: Apache-2.0
|
||||
# function: validate_repo_name
|
||||
# relpath: dnf_plugin_anyrepo/config.py
|
||||
# provenance: agent
|
||||
# mechanism: path_join_user_input
|
||||
|
||||
def validate_repo_name(name: str) -> str:
|
||||
"""Validate the INI section name used as the repository alias."""
|
||||
|
||||
normalized = str(name).strip()
|
||||
if not normalized:
|
||||
raise ConfigError("repository name must not be empty")
|
||||
if normalized == "main":
|
||||
raise ConfigError("repository name must not be main")
|
||||
# Keep the alias from resolving to the cache directory itself or its parent.
|
||||
if normalized in {".", ".."}:
|
||||
raise ConfigError(f"invalid repository name: {name}")
|
||||
if any(char in normalized for char in "\x00\r\n[]/\\"):
|
||||
raise ConfigError(f"invalid repository name: {name}")
|
||||
return normalized
|
||||
@@ -0,0 +1,23 @@
|
||||
# Provenance: jfut/dnf-plugin-anyrepo (vuln).
|
||||
# repo: jfut/dnf-plugin-anyrepo
|
||||
# commit: 33cde479d0db8f45dd89fbdcfb2bc0f1be66bd7a
|
||||
# parent: 33cde479d0db8f45dd89fbdcfb2bc0f1be66bd7a
|
||||
# commit_url: https://github.com/jfut/dnf-plugin-anyrepo/commit/26d19aeb8884f244e34ccfdc4f49f07055adc4d0
|
||||
# cve:
|
||||
# license: Apache-2.0
|
||||
# function: validate_repo_name
|
||||
# relpath: dnf_plugin_anyrepo/config.py
|
||||
# provenance: agent
|
||||
# mechanism: path_join_user_input
|
||||
|
||||
def validate_repo_name(name: str) -> str:
|
||||
"""Validate the INI section name used as the repository alias."""
|
||||
|
||||
normalized = str(name).strip()
|
||||
if not normalized:
|
||||
raise ConfigError("repository name must not be empty")
|
||||
if normalized == "main":
|
||||
raise ConfigError("repository name must not be main")
|
||||
if any(char in normalized for char in "\r\n[]"):
|
||||
raise ConfigError(f"invalid repository name: {name}")
|
||||
return normalized
|
||||
@@ -0,0 +1,442 @@
|
||||
// Provenance: jardimdesoftware/edutrace (fixed).
|
||||
// repo: jardimdesoftware/edutrace
|
||||
// commit: ee7ba25fb23ea89cc1b67549cb5e32c8ead92739
|
||||
// parent: c4dc6ddcc5492c77c8a5ad7369c87dea29c001fd
|
||||
// commit_url: https://github.com/jardimdesoftware/edutrace/commit/ee7ba25fb23ea89cc1b67549cb5e32c8ead92739
|
||||
// cve:
|
||||
// license: Apache-2.0
|
||||
// function: handleInputChange
|
||||
// relpath: front/src/app/editar-anamnese/page.tsx
|
||||
// provenance: agent
|
||||
// mechanism: prototype_pollution
|
||||
|
||||
function AnamnesePage() {
|
||||
const searchParams = useSearchParams();
|
||||
const email = searchParams.get("email");
|
||||
const nome = searchParams.get("nome");
|
||||
|
||||
const { loading } = useAuth();
|
||||
const router = useRouter();
|
||||
|
||||
const [anamnesis, setAnamnesis] = useState<AnamnesisData | null>(null);
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
|
||||
const [formData, setFormData] = useState<AnamnesisData>(initialAnamnesisState);
|
||||
|
||||
useEffect(() => {
|
||||
async function fetchData() {
|
||||
setIsLoading(true);
|
||||
try {
|
||||
const token = decodeToken();
|
||||
if (!token) {
|
||||
router.push('/login');
|
||||
return;
|
||||
}
|
||||
|
||||
const isStudent = token.id_level === ESTUDANTE;
|
||||
|
||||
if (token.id_level === PROFISSIONAL_EDUCACAO || isStudent) {
|
||||
router.push(`/anamnese${email ? `?email=${email}&nome=${nome}` : ''}`);
|
||||
return;
|
||||
}
|
||||
|
||||
const target = isStudent ? token.email : email;
|
||||
|
||||
if (target) {
|
||||
const data = await getAnamneseByEmail(target);
|
||||
setAnamnesis(data);
|
||||
setFormData(data);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Anamnese não encontrada, iniciando modo de criação.", error);
|
||||
setAnamnesis(null);
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
}
|
||||
|
||||
fetchData();
|
||||
}, [email, nome, router]);
|
||||
|
||||
|
||||
const handleInputChange = (name: string, value: string) => {
|
||||
const keys = name.split('.');
|
||||
if (keys.some((key) => key === '__proto__' || key === 'constructor' || key === 'prototype')) return;
|
||||
|
||||
setFormData(prevData => {
|
||||
const newData = JSON.parse(JSON.stringify(prevData));
|
||||
let current = newData;
|
||||
for (let i = 0; i < keys.length - 1; i++) {
|
||||
current = current[keys[i]];
|
||||
}
|
||||
current[keys[keys.length - 1]] = value;
|
||||
return newData;
|
||||
});
|
||||
};
|
||||
|
||||
const handleCheckboxClick = (name: string) => {
|
||||
const keys = name.split('.');
|
||||
if (keys.some((key) => key === '__proto__' || key === 'constructor' || key === 'prototype')) return;
|
||||
|
||||
setFormData(prevData => {
|
||||
// Criar uma cópia profunda para segurança
|
||||
const newData = JSON.parse(JSON.stringify(prevData));
|
||||
|
||||
let currentSection = newData;
|
||||
// Navega até o penúltimo nível do objeto
|
||||
for (let i = 0; i < keys.length - 1; i++) {
|
||||
currentSection = currentSection[keys[i]];
|
||||
}
|
||||
|
||||
const finalKey = keys[keys.length - 1];
|
||||
const currentValue = currentSection[finalKey];
|
||||
|
||||
// Inverte o valor booleano atual
|
||||
currentSection[finalKey] = !currentValue;
|
||||
|
||||
return newData;
|
||||
});
|
||||
};
|
||||
|
||||
const handleEdit = async () => {
|
||||
if (!email) {
|
||||
alert("Email do estudante não encontrado para editar anamnese.");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const dadosAtualizados = { ...formData };
|
||||
await patchAnamnesis(dadosAtualizados, email);
|
||||
alert("Anamnese atualizada com sucesso!");
|
||||
router.push(`/estudantes/visualizar?email=${email}&nome=${nome}`);
|
||||
} catch (error) {
|
||||
console.error("Erro ao atualizar Anamnese: ", error);
|
||||
alert("Falha ao atualizar Anamnese. Verifique o console para mais detalhes.");
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
if (isLoading || loading) {
|
||||
return <h1>Carregando...</h1>; //ADICIONAR COMPONENTE DE LOADING
|
||||
}
|
||||
|
||||
if (anamnesis === null) {
|
||||
return (
|
||||
<AppLayout
|
||||
>
|
||||
<div className="p-6 text-center">
|
||||
<h2 className="text-xl font-bold text-green-700">O estudante ainda não possui uma Anamnese cadastrada</h2>
|
||||
<button className="mt-6 bg-green-600 hover:bg-green-700 text-white font-medium py-2 px-4 rounded-full" onClick={() => router.push(`/estudantes/visualizar?email=${email}&nome=${nome}`)}>
|
||||
Voltar
|
||||
</button>
|
||||
</div>
|
||||
</AppLayout>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
return (
|
||||
<AppLayout
|
||||
>
|
||||
<div className="p-6 space-y-8 w-full">
|
||||
<h1 className="text-3xl font-bold text-gray-800">Editar Anamnese</h1>
|
||||
|
||||
{/* Identificação */}
|
||||
<section>
|
||||
<h2 className="text-xl font-semibold mb-4">Identificação</h2>
|
||||
<div className="grid md:grid-cols-4 gap-4">
|
||||
<BrInput label="Nome da unidade plena" value={formData.identification.nome_unidade_plena} onInput={(e: any) => handleInputChange('identification.nome_unidade_plena', e.target.value)} />
|
||||
<BrInput label="Nome completo" value={formData.identification.nome_completo} onInput={(e: any) => handleInputChange('identification.nome_completo', e.target.value)} />
|
||||
<BrInput label="Data de Nascimento" value={formData.identification.data_de_nascimento} onInput={(e: any) => handleInputChange('identification.data_de_nascimento', e.target.value)} />
|
||||
<BrInput label="Endereço" value={formData.identification.endereco} onInput={(e: any) => handleInputChange('identification.endereco', e.target.value)} />
|
||||
<BrInput label="Bairro" value={formData.identification.bairo} onInput={(e: any) => handleInputChange('identification.bairo', e.target.value)} />
|
||||
<BrInput label="CEP" value={formData.identification.cep} onInput={(e: any) => handleInputChange('identification.cep', e.target.value)} />
|
||||
<BrInput label="Município" value={formData.identification.municipio} onInput={(e: any) => handleInputChange('identification.municipio', e.target.value)} />
|
||||
<BrInput label="Curso" value={formData.identification.curso} onInput={(e: any) => handleInputChange('identification.curso', e.target.value)} />
|
||||
<BrInput label="Série de escolaridade atual" value={formData.identification.serie_de_escolaridade_atual} onInput={(e: any) => handleInputChange('identification.serie_de_escolaridade_atual', e.target.value)} />
|
||||
<BrInput label="Turma" value={formData.identification.turma} onInput={(e: any) => handleInputChange('identification.turma', e.target.value)} />
|
||||
<BrInput label="Idade que iniciou os estudos" value={formData.identification.idade_iniciou_estudos} onInput={(e: any) => handleInputChange('identification.idade_iniciou_estudos', e.target.value)} />
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Dados Familiares */}
|
||||
<section className="border-t pt-6 mt-6">
|
||||
<h2 className="text-xl font-semibold mb-4">Dados familiares</h2>
|
||||
<div className="grid md:grid-cols-4 gap-4">
|
||||
<BrInput label="Nome do pai" value={formData.family_data.nome_pai} onInput={(e: any) => handleInputChange('family_data.nome_pai', e.target.value)} />
|
||||
<BrInput label="Profissão do pai" value={formData.family_data.profissao_pai} onInput={(e: any) => handleInputChange('family_data.profissao_pai', e.target.value)} />
|
||||
<BrInput label="Escolaridade do pai" value={formData.family_data.escolaridade_pai} onInput={(e: any) => handleInputChange('family_data.escolaridade_pai', e.target.value)} />
|
||||
<BrInput label="Idade do pai" value={formData.family_data.idade_pai} onInput={(e: any) => handleInputChange('family_data.idade_pai', e.target.value)} />
|
||||
<BrInput label="Nome da mãe" value={formData.family_data.nome_mae} onInput={(e: any) => handleInputChange('family_data.nome_mae', e.target.value)} />
|
||||
<BrInput label="Profissão da mãe" value={formData.family_data.profissao_mae} onInput={(e: any) => handleInputChange('family_data.profissao_mae', e.target.value)} />
|
||||
<BrInput label="Escolaridade da mãe" value={formData.family_data.escolaridade_mae} onInput={(e: any) => handleInputChange('family_data.escolaridade_mae', e.target.value)} />
|
||||
<BrInput label="Idade da mãe" value={formData.family_data.idade_mae} onInput={(e: any) => handleInputChange('family_data.idade_mae', e.target.value)} />
|
||||
<BrInput label="Outros filhos" value={formData.family_data.outros_filhos} onInput={(e: any) => handleInputChange('family_data.outros_filhos', e.target.value)} />
|
||||
</div>
|
||||
<div className="mt-4 space-y-2">
|
||||
<label className="text-sm font-medium text-black">União dos Pais</label>
|
||||
<div className="flex flex-wrap gap-4">
|
||||
<BrCheckbox name="" label="Casados" checked={formData.family_data.uniao_pais.casados} onClick={() => handleCheckboxClick('family_data.uniao_pais.casados')} />
|
||||
<BrCheckbox name="" label="Separados" checked={formData.family_data.uniao_pais.separados} onClick={() => handleCheckboxClick('family_data.uniao_pais.separados')} />
|
||||
<BrCheckbox name="" label="Separados como uma nova estrutura familiar" checked={formData.family_data.uniao_pais.separados_como_nova_estrutura_familia} onClick={() => handleCheckboxClick('family_data.uniao_pais.separados_como_nova_estrutura_familia')} />
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-4 space-y-2">
|
||||
<label className="text-sm font-medium text-black">Pais</label>
|
||||
<div className="flex flex-wrap gap-4">
|
||||
<BrCheckbox name="" label="Biológico" checked={formData.family_data.pais.biologico} onClick={() => handleCheckboxClick('family_data.pais.biologico')} />
|
||||
<BrCheckbox name="" label="Adotivo" checked={formData.family_data.pais.adotivo} onClick={() => handleCheckboxClick('family_data.pais.adotivo')} />
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-4 grid md:grid-cols-2 gap-4">
|
||||
<BrInput label="Em caso de separação, o estudante vive com quem?" value={formData.family_data.estudante_reside_com_quem} onInput={(e: any) => handleInputChange('family_data.estudante_reside_com_quem', e.target.value)} />
|
||||
<BrInput label="Reação do estudante à situação" value={formData.family_data.reacao_estudante_situacao} onInput={(e: any) => handleInputChange('family_data.reacao_estudante_situacao', e.target.value)} />
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Condições familiares do estudante */}
|
||||
<section className="border-t pt-6 mt-6">
|
||||
<h2 className="text-xl font-semibold mb-4">Condições familiares do estudante</h2>
|
||||
<div className="grid md:grid-cols-3 gap-4">
|
||||
<div>
|
||||
<p className="text-sm font-medium mb-2">Condições de moradia</p>
|
||||
<div className="flex space-x-3">
|
||||
<BrCheckbox name="" label="Taipa" checked={formData.family_conditions.moradia.taipa} onClick={() => handleCheckboxClick('family_conditions.moradia.taipa')} />
|
||||
<BrCheckbox name="" label="Alvenaria" checked={formData.family_conditions.moradia.alvenaria} onClick={() => handleCheckboxClick('family_conditions.moradia.alvenaria')} />
|
||||
<BrCheckbox name="" label="Palafita" checked={formData.family_conditions.moradia.palafita} onClick={() => handleCheckboxClick('family_conditions.moradia.palafita')} />
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-sm font-medium mb-2">Convívio familiar</p>
|
||||
<div className="flex space-x-3">
|
||||
<BrCheckbox name="" label="Excelente" checked={formData.family_conditions.convivio_familiar.excelente} onClick={() => handleCheckboxClick('family_conditions.convivio_familiar.excelente')} />
|
||||
<BrCheckbox name="" label="Bom" checked={formData.family_conditions.convivio_familiar.bom} onClick={() => handleCheckboxClick('family_conditions.convivio_familiar.bom')} />
|
||||
<BrCheckbox name="" label="Problemático" checked={formData.family_conditions.convivio_familiar.problematico} onClick={() => handleCheckboxClick('family_conditions.convivio_familiar.problematico')} />
|
||||
<BrCheckbox name="" label="Precário" checked={formData.family_conditions.convivio_familiar.precario} onClick={() => handleCheckboxClick('family_conditions.convivio_familiar.precario')} />
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-sm font-medium mb-2">Qualidade de comunicação</p>
|
||||
<div className="flex space-x-3">
|
||||
<BrCheckbox name="" label="Excelente" checked={formData.family_conditions.qualidade_comunicacao_com_estudante.execelente} onClick={() => handleCheckboxClick('family_conditions.qualidade_comunicacao_com_estudante.execelente')} />
|
||||
<BrCheckbox name="" label="Boa" checked={formData.family_conditions.qualidade_comunicacao_com_estudante.boa} onClick={() => handleCheckboxClick('family_conditions.qualidade_comunicacao_com_estudante.boa')} />
|
||||
<BrCheckbox name="" label="Ruim" checked={formData.family_conditions.qualidade_comunicacao_com_estudante.ruim} onClick={() => handleCheckboxClick('family_conditions.qualidade_comunicacao_com_estudante.ruim')} />
|
||||
<BrCheckbox name="" label="Péssima" checked={formData.family_conditions.qualidade_comunicacao_com_estudante.pessima} onClick={() => handleCheckboxClick('family_conditions.qualidade_comunicacao_com_estudante.pessima')} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="grid md:grid-cols-2 gap-4 mt-6">
|
||||
<BrInput label="Que medidas disciplinares normalmente são usadas com o estudante" value={formData.family_conditions.medidas_disciplinares_com_estudante} onInput={(e: any) => handleInputChange('family_conditions.medidas_disciplinares_com_estudante', e.target.value)} />
|
||||
<BrInput label="Quem as usa" value={formData.family_conditions.quem_usa_medidas_disciplinares} onInput={(e: any) => handleInputChange('family_conditions.quem_usa_medidas_disciplinares', e.target.value)} />
|
||||
<BrInput label="Quais as reações do estudante frente a essas medidas" value={formData.family_conditions.reacao_estudante_frente_medidas} onInput={(e: any) => handleInputChange('family_conditions.reacao_estudante_frente_medidas', e.target.value)} />
|
||||
<BrInput label="Como reage quando contrariado" value={formData.family_conditions.reacao_contrariado} onInput={(e: any) => handleInputChange('family_conditions.reacao_contrariado', e.target.value)} />
|
||||
</div>
|
||||
<div className="mt-6">
|
||||
<p className="text-sm font-medium mb-2">Condições do ambiente familiar para a aprendizagem escolar</p>
|
||||
<BrInput label="Condição" value={formData.family_conditions.condicao_ambiente_familiar_aprendizagem_escolar} onInput={(e: any) => handleInputChange('family_conditions.condicao_ambiente_familiar_aprendizagem_escolar', e.target.value)} />
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Histórico da Mãe */}
|
||||
<section className="border-t pt-6 mt-6">
|
||||
<h2 className="text-xl font-semibold mb-4">Histórico da Mãe</h2>
|
||||
|
||||
{/* Gestação */}
|
||||
<div className="mb-6">
|
||||
<h3 className="text-lg font-medium mb-3">Gestação</h3>
|
||||
<div className="grid md:grid-cols-3 gap-4">
|
||||
<BrInput label="Transfusão sanguínea na gravidez" value={formData.mother_background.gestacao.transfusao_sanguinea_gravidez} onInput={(e: any) => handleInputChange('mother_background.gestacao.transfusao_sanguinea_gravidez', e.target.value)} />
|
||||
<BrInput label="Quando sentiu movimento da criança" value={formData.mother_background.gestacao.quando_sentiu_movimento_da_crianca} onInput={(e: any) => handleInputChange('mother_background.gestacao.quando_sentiu_movimento_da_crianca', e.target.value)} />
|
||||
<BrInput label="Levou tombo durante a gravidez" value={formData.mother_background.gestacao.levou_tombo_durante_gravidez} onInput={(e: any) => handleInputChange('mother_background.gestacao.levou_tombo_durante_gravidez', e.target.value)} />
|
||||
<BrInput label="Doença na gestação" value={formData.mother_background.gestacao.doenca_na_gestacao} onInput={(e: any) => handleInputChange('mother_background.gestacao.doenca_na_gestacao', e.target.value)} />
|
||||
<BrInput label="Condição de saúde da mãe na gravidez" value={formData.mother_background.gestacao.condicao_saude_da_mae_na_gravidez} onInput={(e: any) => handleInputChange('mother_background.gestacao.condicao_saude_da_mae_na_gravidez', e.target.value)} />
|
||||
<BrInput label="Episódio marcante na gravidez" value={formData.mother_background.gestacao.episodio_marcante_gravidez} onInput={(e: any) => handleInputChange('mother_background.gestacao.episodio_marcante_gravidez', e.target.value)} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Condições de Nascimento */}
|
||||
<div className="mb-6">
|
||||
<h3 className="text-lg font-medium mb-3">Condições de Nascimento</h3>
|
||||
<div className="grid md:grid-cols-4 gap-4">
|
||||
<BrInput label="Nasceu com quantos meses" value={formData.mother_background.condicoes_nascimento.nasceu_quantos_meses} onInput={(e: any) => handleInputChange('mother_background.condicoes_nascimento.nasceu_quantos_meses', e.target.value)} />
|
||||
<BrInput label="Nasceu com quantos quilos" value={formData.mother_background.condicoes_nascimento.nasceu_quantos_quilos} onInput={(e: any) => handleInputChange('mother_background.condicoes_nascimento.nasceu_quantos_quilos', e.target.value)} />
|
||||
<BrInput label="Nasceu com qual comprimento" value={formData.mother_background.condicoes_nascimento.nasceu_com_qual_comprimento} onInput={(e: any) => handleInputChange('mother_background.condicoes_nascimento.nasceu_com_qual_comprimento', e.target.value)} />
|
||||
<BrInput label="Desenvolvimento do parto" value={formData.mother_background.condicoes_nascimento.desenvolvimento_parto} onInput={(e: any) => handleInputChange('mother_background.condicoes_nascimento.desenvolvimento_parto', e.target.value)} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Primeiras Reações */}
|
||||
<div className="mb-6">
|
||||
<h3 className="text-lg font-medium mb-3">Primeiras Reações</h3>
|
||||
<div className="grid md:grid-cols-3 gap-4">
|
||||
<BrInput label="Chorou" value={formData.mother_background.primeiras_reacoes.chorou} onInput={(e: any) => handleInputChange('mother_background.primeiras_reacoes.chorou', e.target.value)} />
|
||||
<BrInput label="Ficou vermelho demais" value={formData.mother_background.primeiras_reacoes.ficou_vermelho_demais} onInput={(e: any) => handleInputChange('mother_background.primeiras_reacoes.ficou_vermelho_demais', e.target.value)} />
|
||||
<BrInput label="Ficou vermelho por quanto tempo" value={formData.mother_background.primeiras_reacoes.ficou_vermelho_por_quanto_tempo} onInput={(e: any) => handleInputChange('mother_background.primeiras_reacoes.ficou_vermelho_por_quanto_tempo', e.target.value)} />
|
||||
<BrInput label="Precisou de oxigênio" value={formData.mother_background.primeiras_reacoes.precisou_de_oxigenio} onInput={(e: any) => handleInputChange('mother_background.primeiras_reacoes.precisou_de_oxigenio', e.target.value)} />
|
||||
<BrInput label="Ficou ictérico" value={formData.mother_background.primeiras_reacoes.ficou_icterico} onInput={(e: any) => handleInputChange('mother_background.primeiras_reacoes.ficou_icterico', e.target.value)} />
|
||||
<BrInput label="Como era quando bebê" value={formData.mother_background.primeiras_reacoes.como_era_quando_bebe} onInput={(e: any) => handleInputChange('mother_background.primeiras_reacoes.como_era_quando_bebe', e.target.value)} />
|
||||
<BrInput label="Qual idade afirmou a cabeça" value={formData.mother_background.primeiras_reacoes.qual_idade_afirmou_cabeca} onInput={(e: any) => handleInputChange('mother_background.primeiras_reacoes.qual_idade_afirmou_cabeca', e.target.value)} />
|
||||
<BrInput label="Qual idade sentou sem apoio" value={formData.mother_background.primeiras_reacoes.qual_idade_sentou_sem_apoio} onInput={(e: any) => handleInputChange('mother_background.primeiras_reacoes.qual_idade_sentou_sem_apoio', e.target.value)} />
|
||||
<BrInput label="Qual idade engatinhou" value={formData.mother_background.primeiras_reacoes.qual_idade_engatinhou} onInput={(e: any) => handleInputChange('mother_background.primeiras_reacoes.qual_idade_engatinhou', e.target.value)} />
|
||||
<BrInput label="Qual idade ficou de pé" value={formData.mother_background.primeiras_reacoes.qual_idade_ficou_de_pe} onInput={(e: any) => handleInputChange('mother_background.primeiras_reacoes.qual_idade_ficou_de_pe', e.target.value)} />
|
||||
<BrInput label="Qual idade andou" value={formData.mother_background.primeiras_reacoes.qual_idade_andou} onInput={(e: any) => handleInputChange('mother_background.primeiras_reacoes.qual_idade_andou', e.target.value)} />
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Linguagem Verbal (3 anos) */}
|
||||
<section className="border-t pt-6 mt-6">
|
||||
<h2 className="text-xl font-semibold mb-4">Linguagem Verbal (3 anos)</h2>
|
||||
<div className="grid md:grid-cols-2 gap-4">
|
||||
<div className="space-y-2">
|
||||
<BrCheckbox name="" label="Balbuciou" checked={formData.verbal_language_three_years.balbuciou} onClick={() => handleCheckboxClick('verbal_language_three_years.balbuciou')} />
|
||||
<BrCheckbox name="" label="Trocou letras" checked={formData.verbal_language_three_years.trocou_letras} onClick={() => handleCheckboxClick('verbal_language_three_years.trocou_letras')} />
|
||||
<BrCheckbox name="" label="Gaguejou" checked={formData.verbal_language_three_years.gaguejou} onClick={() => handleCheckboxClick('verbal_language_three_years.gaguejou')} />
|
||||
</div>
|
||||
<BrInput label="Primeiras expressões" value={formData.verbal_language_three_years.primeiras_expressoes} onInput={(e: any) => handleInputChange('verbal_language_three_years.primeiras_expressoes', e.target.value)} />
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Desenvolvimento */}
|
||||
<section className="border-t pt-6 mt-6">
|
||||
<h2 className="text-xl font-semibold mb-4">Desenvolvimento</h2>
|
||||
|
||||
{/* Saúde */}
|
||||
<div className="mb-6">
|
||||
<h3 className="text-lg font-medium mb-3">Saúde</h3>
|
||||
<div className="grid md:grid-cols-2 gap-4">
|
||||
<BrInput label="Sofreu acidente ou fez cirurgia" value={formData.development.saude.sofreu_acidente_ou_fez_cirurgia} onInput={(e: any) => handleInputChange('development.saude.sofreu_acidente_ou_fez_cirurgia', e.target.value)} />
|
||||
<BrInput label="Possui alergia" value={formData.development.saude.possui_alergia} onInput={(e: any) => handleInputChange('development.saude.possui_alergia', e.target.value)} />
|
||||
<BrInput label="Possui bronquite ou asma" value={formData.development.saude.possui_bronquite_ou_asma} onInput={(e: any) => handleInputChange('development.saude.possui_bronquite_ou_asma', e.target.value)} />
|
||||
<BrInput label="Possui problema de visão ou audição" value={formData.development.saude.possui_problema_visao_audicao} onInput={(e: any) => handleInputChange('development.saude.possui_problema_visao_audicao', e.target.value)} />
|
||||
<BrInput label="Já desmaiou" value={formData.development.saude.ja_desmaiou} onInput={(e: any) => handleInputChange('development.saude.ja_desmaiou', e.target.value)} />
|
||||
<BrInput label="Quando desmaiou" value={formData.development.saude.quando_desmaiou} onInput={(e: any) => handleInputChange('development.saude.quando_desmaiou', e.target.value)} />
|
||||
<BrInput label="Teve ou tem convulsões" value={formData.development.saude.teve_ou_tem_convulsoes} onInput={(e: any) => handleInputChange('development.saude.teve_ou_tem_convulsoes', e.target.value)} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Alimentação */}
|
||||
<div className="mb-6">
|
||||
<h3 className="text-lg font-medium mb-3">Alimentação</h3>
|
||||
<div className="grid md:grid-cols-2 gap-4">
|
||||
<BrInput label="Foi amamentada" value={formData.development.alimentacao.foi_amamentada} onInput={(e: any) => handleInputChange('development.alimentacao.foi_amamentada', e.target.value)} />
|
||||
<BrInput label="Foi amamentada até quando" value={formData.development.alimentacao.foi_amementada_ate_quando} onInput={(e: any) => handleInputChange('development.alimentacao.foi_amementada_ate_quando', e.target.value)} />
|
||||
<BrInput label="Como é sua alimentação" value={formData.development.alimentacao.como_e_sua_alimentacao} onInput={(e: any) => handleInputChange('development.alimentacao.como_e_sua_alimentacao', e.target.value)} />
|
||||
<BrInput label="Foi forçado a se alimentar" value={formData.development.alimentacao.foi_forcado_se_alimentar} onInput={(e: any) => handleInputChange('development.alimentacao.foi_forcado_se_alimentar', e.target.value)} />
|
||||
<BrInput label="Recebe ajuda na alimentação" value={formData.development.alimentacao.recebe_ajuda_na_alimentacao} onInput={(e: any) => handleInputChange('development.alimentacao.recebe_ajuda_na_alimentacao', e.target.value)} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Sono */}
|
||||
<div className="mb-6">
|
||||
<h3 className="text-lg font-medium mb-3">Sono</h3>
|
||||
<div className="grid md:grid-cols-2 gap-4">
|
||||
<div className="space-y-2">
|
||||
<BrCheckbox name="" label="Dorme bem" checked={formData.development.sono.dorme_bem} onClick={() => handleCheckboxClick('development.sono.dorme_bem')} />
|
||||
<BrCheckbox name="" label="Dorme separado dos pais" checked={formData.development.sono.dorme_separado_dos_pais} onClick={() => handleCheckboxClick('development.sono.dorme_separado_dos_pais')} />
|
||||
</div>
|
||||
<BrInput label="Com quem dorme" value={formData.development.sono.com_quem_dorme} onInput={(e: any) => handleInputChange('development.sono.com_quem_dorme', e.target.value)} />
|
||||
</div>
|
||||
<div className="mt-4">
|
||||
<p className="text-sm font-medium mb-2">Tipo de sono</p>
|
||||
<div className="flex flex-wrap gap-4">
|
||||
<BrCheckbox name="" label="Agitado" checked={formData.development.sono.sono.agitado} onClick={() => handleCheckboxClick('development.sono.sono.agitado')} />
|
||||
<BrCheckbox name="" label="Tranquilo" checked={formData.development.sono.sono.tranquilo} onClick={() => handleCheckboxClick('development.sono.sono.tranquilo')} />
|
||||
<BrCheckbox name="" label="Fala dormindo" checked={formData.development.sono.sono.fala_dormindo} onClick={() => handleCheckboxClick('development.sono.sono.fala_dormindo')} />
|
||||
<BrCheckbox name="" label="Sonâmbulo" checked={formData.development.sono.sono.sonambulo} onClick={() => handleCheckboxClick('development.sono.sono.sonambulo')} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Informações Escolares */}
|
||||
<section className="border-t pt-6 mt-6">
|
||||
<h2 className="text-xl font-semibold mb-4">Informações Escolares</h2>
|
||||
<div className="grid md:grid-cols-2 gap-4">
|
||||
<BrInput label="Histórico escolar comum - antecedentes relevantes" value={formData.school_information.historico_escolar_comum_antecedentes_relevantes} onInput={(e: any) => handleInputChange('school_information.historico_escolar_comum_antecedentes_relevantes', e.target.value)} />
|
||||
<BrInput label="Histórico escolar especial - antecedentes relevantes" value={formData.school_information.historico_escolar_especial_antecedentes_relevantes} onInput={(e: any) => handleInputChange('school_information.historico_escolar_especial_antecedentes_relevantes', e.target.value)} />
|
||||
<BrInput label="Deficiência apresentada pelo estudante" value={formData.school_information.deficiencia_apresentada_estudante} onInput={(e: any) => handleInputChange('school_information.deficiencia_apresentada_estudante', e.target.value)} />
|
||||
<BrInput label="Foi retido alguma vez" value={formData.school_information.retido_alguma_vez} onInput={(e: any) => handleInputChange('school_information.retido_alguma_vez', e.target.value)} />
|
||||
<BrInput label="Gosta de ir à escola" value={formData.school_information.gosta_de_ir_escola} onInput={(e: any) => handleInputChange('school_information.gosta_de_ir_escola', e.target.value)} />
|
||||
<BrInput label="É bem aceito pelos amigos" value={formData.school_information.bem_aceito_pelos_amigous} onInput={(e: any) => handleInputChange('school_information.bem_aceito_pelos_amigous', e.target.value)} />
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Sexualidade */}
|
||||
<section className="border-t pt-6 mt-6">
|
||||
<h2 className="text-xl font-semibold mb-4">Sexualidade</h2>
|
||||
<div className="flex flex-wrap gap-4">
|
||||
<BrCheckbox name="" label="Explanação sexual" checked={formData.sexuality.explanacao_sexual} onClick={() => handleCheckboxClick('sexuality.explanacao_sexual')} />
|
||||
<BrCheckbox name="" label="Curiosidade sexual" checked={formData.sexuality.curiosidade_sexual} onClick={() => handleCheckboxClick('sexuality.curiosidade_sexual')} />
|
||||
<BrCheckbox name="" label="Conversa com pais sobre sexualidade" checked={formData.sexuality.conversa_com_pais_sobre_sexualidade} onClick={() => handleCheckboxClick('sexuality.conversa_com_pais_sobre_sexualidade')} />
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Avaliação do Estudante */}
|
||||
<section className="border-t pt-6 mt-6">
|
||||
<h2 className="text-xl font-semibold mb-4">Avaliação do Estudante</h2>
|
||||
<div className="grid md:grid-cols-2 gap-4">
|
||||
<BrInput label="Estudante apresenta outro tipo de deficiência" value={formData.student_assessment.estudante_apresenta_outro_tipo_deficiencia} onInput={(e: any) => handleInputChange('student_assessment.estudante_apresenta_outro_tipo_deficiencia', e.target.value)} />
|
||||
<div className="space-y-2">
|
||||
<BrCheckbox name="" label="Apresenta DA/DF/DI/PC/TGD" checked={formData.student_assessment.apresenta_da_df_di_pc_tgd} onClick={() => handleCheckboxClick('student_assessment.apresenta_da_df_di_pc_tgd')} />
|
||||
</div>
|
||||
<BrInput label="Se sim, data e resultado do diagnóstico" value={formData.student_assessment.se_sim_data_e_resultado_diagnostico} onInput={(e: any) => handleInputChange('student_assessment.se_sim_data_e_resultado_diagnostico', e.target.value)} />
|
||||
<BrInput label="Se não, situação quanto ao diagnóstico - tem outras dificuldades" value={formData.student_assessment.se_não_situacao_quanto_diagnostico_tem_outras_dificuldades} onInput={(e: any) => handleInputChange('student_assessment.se_não_situacao_quanto_diagnostico_tem_outras_dificuldades', e.target.value)} />
|
||||
<BrInput label="Se tem outras dificuldades" value={formData.student_assessment.se_tem_outras_dificuldades} onInput={(e: any) => handleInputChange('student_assessment.se_tem_outras_dificuldades', e.target.value)} />
|
||||
<div className="space-y-2">
|
||||
<BrCheckbox name="" label="Usa medicamentos controlados" checked={formData.student_assessment.usa_medicamentos_controlados} onClick={() => handleCheckboxClick('student_assessment.usa_medicamentos_controlados')} />
|
||||
</div>
|
||||
<BrInput label="Usa quais medicamentos" value={formData.student_assessment.usa_quais_medicamentos} onInput={(e: any) => handleInputChange('student_assessment.usa_quais_medicamentos', e.target.value)} />
|
||||
<div className="space-y-2">
|
||||
<BrCheckbox name="" label="Medicamento interfere na aprendizagem" checked={formData.student_assessment.medicamento_interfere_aprendizagem} onClick={() => handleCheckboxClick('student_assessment.medicamento_interfere_aprendizagem')} />
|
||||
</div>
|
||||
<BrInput label="Se interfere na aprendizagem" value={formData.student_assessment.se_intefere_aprendizagem} onInput={(e: any) => handleInputChange('student_assessment.se_intefere_aprendizagem', e.target.value)} />
|
||||
<div className="space-y-2">
|
||||
<BrCheckbox name="" label="Existem recomendações da saúde" checked={formData.student_assessment.existem_recomendacoes_da_saude} onClick={() => handleCheckboxClick('student_assessment.existem_recomendacoes_da_saude')} />
|
||||
</div>
|
||||
<BrInput label="Se possui recomendações da saúde" value={formData.student_assessment.se_possui_recomendacoes_da_saude} onInput={(e: any) => handleInputChange('student_assessment.se_possui_recomendacoes_da_saude', e.target.value)} />
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Desenvolvimento do Estudante */}
|
||||
<section className="border-t pt-6 mt-6">
|
||||
<h2 className="text-xl font-semibold mb-4">Desenvolvimento do Estudante</h2>
|
||||
|
||||
{/* Função Cognitiva */}
|
||||
<div className="mb-6">
|
||||
<h3 className="text-lg font-medium mb-3">Função Cognitiva</h3>
|
||||
<div className="grid md:grid-cols-2 gap-4">
|
||||
<BrInput label="Percepção" value={formData.student_development.funcao_cognitiva.percepcao} onInput={(e: any) => handleInputChange('student_development.funcao_cognitiva.percepcao', e.target.value)} />
|
||||
<BrInput label="Atenção" value={formData.student_development.funcao_cognitiva.atencao} onInput={(e: any) => handleInputChange('student_development.funcao_cognitiva.atencao', e.target.value)} />
|
||||
<BrInput label="Memória" value={formData.student_development.funcao_cognitiva.memoria} onInput={(e: any) => handleInputChange('student_development.funcao_cognitiva.memoria', e.target.value)} />
|
||||
<BrInput label="Linguagem" value={formData.student_development.funcao_cognitiva.linguagem} onInput={(e: any) => handleInputChange('student_development.funcao_cognitiva.linguagem', e.target.value)} />
|
||||
<BrInput label="Raciocínio lógico" value={formData.student_development.funcao_cognitiva.raciocinio_logico} onInput={(e: any) => handleInputChange('student_development.funcao_cognitiva.raciocinio_logico', e.target.value)} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Função Motora */}
|
||||
<div className="mb-6">
|
||||
<h3 className="text-lg font-medium mb-3">Função Motora</h3>
|
||||
<BrInput label="Desenvolvimento e capacidade motora" value={formData.student_development.funcao_motora.desenvolvimento_e_capacidade_motora} onInput={(e: any) => handleInputChange('student_development.funcao_motora.desenvolvimento_e_capacidade_motora', e.target.value)} />
|
||||
</div>
|
||||
|
||||
{/* Função Pessoal Social */}
|
||||
<div className="mb-6">
|
||||
<h3 className="text-lg font-medium mb-3">Função Pessoal Social</h3>
|
||||
<BrInput label="Área emocional, afetiva e social" value={formData.student_development.funcao_pressoal_social.area_emocional_afetiva_social} onInput={(e: any) => handleInputChange('student_development.funcao_pressoal_social.area_emocional_afetiva_social', e.target.value)} />
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Botões */}
|
||||
<div className="flex justify-center gap-4 mt-8">
|
||||
<button className="bg-red-600 hover:bg-red-700 text-white font-medium py-2 px-4 rounded-full" onClick={() => router.push(`/anamnese?email=${email}&nome=${nome}`)}>
|
||||
Cancelar
|
||||
</button>
|
||||
<button className="bg-green-600 hover:bg-green-700 text-white font-medium py-2 px-4 rounded-full" onClick={handleEdit}>
|
||||
Salvar Alterações
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</AppLayout>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,440 @@
|
||||
// Provenance: jardimdesoftware/edutrace (vuln).
|
||||
// repo: jardimdesoftware/edutrace
|
||||
// commit: c4dc6ddcc5492c77c8a5ad7369c87dea29c001fd
|
||||
// parent: c4dc6ddcc5492c77c8a5ad7369c87dea29c001fd
|
||||
// commit_url: https://github.com/jardimdesoftware/edutrace/commit/ee7ba25fb23ea89cc1b67549cb5e32c8ead92739
|
||||
// cve:
|
||||
// license: Apache-2.0
|
||||
// function: handleInputChange
|
||||
// relpath: front/src/app/editar-anamnese/page.tsx
|
||||
// provenance: agent
|
||||
// mechanism: prototype_pollution
|
||||
|
||||
function AnamnesePage() {
|
||||
const searchParams = useSearchParams();
|
||||
const email = searchParams.get("email");
|
||||
const nome = searchParams.get("nome");
|
||||
|
||||
const { loading } = useAuth();
|
||||
const router = useRouter();
|
||||
|
||||
const [anamnesis, setAnamnesis] = useState<AnamnesisData | null>(null);
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
|
||||
const [formData, setFormData] = useState<AnamnesisData>(initialAnamnesisState);
|
||||
|
||||
useEffect(() => {
|
||||
async function fetchData() {
|
||||
setIsLoading(true);
|
||||
try {
|
||||
const token = decodeToken();
|
||||
if (!token) {
|
||||
router.push('/login');
|
||||
return;
|
||||
}
|
||||
|
||||
const isStudent = token.id_level === ESTUDANTE;
|
||||
|
||||
if (token.id_level === PROFISSIONAL_EDUCACAO || isStudent) {
|
||||
router.push(`/anamnese${email ? `?email=${email}&nome=${nome}` : ''}`);
|
||||
return;
|
||||
}
|
||||
|
||||
const target = isStudent ? token.email : email;
|
||||
|
||||
if (target) {
|
||||
const data = await getAnamneseByEmail(target);
|
||||
setAnamnesis(data);
|
||||
setFormData(data);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Anamnese não encontrada, iniciando modo de criação.", error);
|
||||
setAnamnesis(null);
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
}
|
||||
|
||||
fetchData();
|
||||
}, [email, nome, router]);
|
||||
|
||||
|
||||
const handleInputChange = (name: string, value: string) => {
|
||||
const keys = name.split('.');
|
||||
|
||||
setFormData(prevData => {
|
||||
const newData = JSON.parse(JSON.stringify(prevData));
|
||||
let current = newData;
|
||||
for (let i = 0; i < keys.length - 1; i++) {
|
||||
current = current[keys[i]];
|
||||
}
|
||||
current[keys[keys.length - 1]] = value;
|
||||
return newData;
|
||||
});
|
||||
};
|
||||
|
||||
const handleCheckboxClick = (name: string) => {
|
||||
const keys = name.split('.');
|
||||
|
||||
setFormData(prevData => {
|
||||
// Criar uma cópia profunda para segurança
|
||||
const newData = JSON.parse(JSON.stringify(prevData));
|
||||
|
||||
let currentSection = newData;
|
||||
// Navega até o penúltimo nível do objeto
|
||||
for (let i = 0; i < keys.length - 1; i++) {
|
||||
currentSection = currentSection[keys[i]];
|
||||
}
|
||||
|
||||
const finalKey = keys[keys.length - 1];
|
||||
const currentValue = currentSection[finalKey];
|
||||
|
||||
// Inverte o valor booleano atual
|
||||
currentSection[finalKey] = !currentValue;
|
||||
|
||||
return newData;
|
||||
});
|
||||
};
|
||||
|
||||
const handleEdit = async () => {
|
||||
if (!email) {
|
||||
alert("Email do estudante não encontrado para editar anamnese.");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const dadosAtualizados = { ...formData };
|
||||
await patchAnamnesis(dadosAtualizados, email);
|
||||
alert("Anamnese atualizada com sucesso!");
|
||||
router.push(`/estudantes/visualizar?email=${email}&nome=${nome}`);
|
||||
} catch (error) {
|
||||
console.error("Erro ao atualizar Anamnese: ", error);
|
||||
alert("Falha ao atualizar Anamnese. Verifique o console para mais detalhes.");
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
if (isLoading || loading) {
|
||||
return <h1>Carregando...</h1>; //ADICIONAR COMPONENTE DE LOADING
|
||||
}
|
||||
|
||||
if (anamnesis === null) {
|
||||
return (
|
||||
<AppLayout
|
||||
>
|
||||
<div className="p-6 text-center">
|
||||
<h2 className="text-xl font-bold text-green-700">O estudante ainda não possui uma Anamnese cadastrada</h2>
|
||||
<button className="mt-6 bg-green-600 hover:bg-green-700 text-white font-medium py-2 px-4 rounded-full" onClick={() => router.push(`/estudantes/visualizar?email=${email}&nome=${nome}`)}>
|
||||
Voltar
|
||||
</button>
|
||||
</div>
|
||||
</AppLayout>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
return (
|
||||
<AppLayout
|
||||
>
|
||||
<div className="p-6 space-y-8 w-full">
|
||||
<h1 className="text-3xl font-bold text-gray-800">Editar Anamnese</h1>
|
||||
|
||||
{/* Identificação */}
|
||||
<section>
|
||||
<h2 className="text-xl font-semibold mb-4">Identificação</h2>
|
||||
<div className="grid md:grid-cols-4 gap-4">
|
||||
<BrInput label="Nome da unidade plena" value={formData.identification.nome_unidade_plena} onInput={(e: any) => handleInputChange('identification.nome_unidade_plena', e.target.value)} />
|
||||
<BrInput label="Nome completo" value={formData.identification.nome_completo} onInput={(e: any) => handleInputChange('identification.nome_completo', e.target.value)} />
|
||||
<BrInput label="Data de Nascimento" value={formData.identification.data_de_nascimento} onInput={(e: any) => handleInputChange('identification.data_de_nascimento', e.target.value)} />
|
||||
<BrInput label="Endereço" value={formData.identification.endereco} onInput={(e: any) => handleInputChange('identification.endereco', e.target.value)} />
|
||||
<BrInput label="Bairro" value={formData.identification.bairo} onInput={(e: any) => handleInputChange('identification.bairo', e.target.value)} />
|
||||
<BrInput label="CEP" value={formData.identification.cep} onInput={(e: any) => handleInputChange('identification.cep', e.target.value)} />
|
||||
<BrInput label="Município" value={formData.identification.municipio} onInput={(e: any) => handleInputChange('identification.municipio', e.target.value)} />
|
||||
<BrInput label="Curso" value={formData.identification.curso} onInput={(e: any) => handleInputChange('identification.curso', e.target.value)} />
|
||||
<BrInput label="Série de escolaridade atual" value={formData.identification.serie_de_escolaridade_atual} onInput={(e: any) => handleInputChange('identification.serie_de_escolaridade_atual', e.target.value)} />
|
||||
<BrInput label="Turma" value={formData.identification.turma} onInput={(e: any) => handleInputChange('identification.turma', e.target.value)} />
|
||||
<BrInput label="Idade que iniciou os estudos" value={formData.identification.idade_iniciou_estudos} onInput={(e: any) => handleInputChange('identification.idade_iniciou_estudos', e.target.value)} />
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Dados Familiares */}
|
||||
<section className="border-t pt-6 mt-6">
|
||||
<h2 className="text-xl font-semibold mb-4">Dados familiares</h2>
|
||||
<div className="grid md:grid-cols-4 gap-4">
|
||||
<BrInput label="Nome do pai" value={formData.family_data.nome_pai} onInput={(e: any) => handleInputChange('family_data.nome_pai', e.target.value)} />
|
||||
<BrInput label="Profissão do pai" value={formData.family_data.profissao_pai} onInput={(e: any) => handleInputChange('family_data.profissao_pai', e.target.value)} />
|
||||
<BrInput label="Escolaridade do pai" value={formData.family_data.escolaridade_pai} onInput={(e: any) => handleInputChange('family_data.escolaridade_pai', e.target.value)} />
|
||||
<BrInput label="Idade do pai" value={formData.family_data.idade_pai} onInput={(e: any) => handleInputChange('family_data.idade_pai', e.target.value)} />
|
||||
<BrInput label="Nome da mãe" value={formData.family_data.nome_mae} onInput={(e: any) => handleInputChange('family_data.nome_mae', e.target.value)} />
|
||||
<BrInput label="Profissão da mãe" value={formData.family_data.profissao_mae} onInput={(e: any) => handleInputChange('family_data.profissao_mae', e.target.value)} />
|
||||
<BrInput label="Escolaridade da mãe" value={formData.family_data.escolaridade_mae} onInput={(e: any) => handleInputChange('family_data.escolaridade_mae', e.target.value)} />
|
||||
<BrInput label="Idade da mãe" value={formData.family_data.idade_mae} onInput={(e: any) => handleInputChange('family_data.idade_mae', e.target.value)} />
|
||||
<BrInput label="Outros filhos" value={formData.family_data.outros_filhos} onInput={(e: any) => handleInputChange('family_data.outros_filhos', e.target.value)} />
|
||||
</div>
|
||||
<div className="mt-4 space-y-2">
|
||||
<label className="text-sm font-medium text-black">União dos Pais</label>
|
||||
<div className="flex flex-wrap gap-4">
|
||||
<BrCheckbox name="" label="Casados" checked={formData.family_data.uniao_pais.casados} onClick={() => handleCheckboxClick('family_data.uniao_pais.casados')} />
|
||||
<BrCheckbox name="" label="Separados" checked={formData.family_data.uniao_pais.separados} onClick={() => handleCheckboxClick('family_data.uniao_pais.separados')} />
|
||||
<BrCheckbox name="" label="Separados como uma nova estrutura familiar" checked={formData.family_data.uniao_pais.separados_como_nova_estrutura_familia} onClick={() => handleCheckboxClick('family_data.uniao_pais.separados_como_nova_estrutura_familia')} />
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-4 space-y-2">
|
||||
<label className="text-sm font-medium text-black">Pais</label>
|
||||
<div className="flex flex-wrap gap-4">
|
||||
<BrCheckbox name="" label="Biológico" checked={formData.family_data.pais.biologico} onClick={() => handleCheckboxClick('family_data.pais.biologico')} />
|
||||
<BrCheckbox name="" label="Adotivo" checked={formData.family_data.pais.adotivo} onClick={() => handleCheckboxClick('family_data.pais.adotivo')} />
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-4 grid md:grid-cols-2 gap-4">
|
||||
<BrInput label="Em caso de separação, o estudante vive com quem?" value={formData.family_data.estudante_reside_com_quem} onInput={(e: any) => handleInputChange('family_data.estudante_reside_com_quem', e.target.value)} />
|
||||
<BrInput label="Reação do estudante à situação" value={formData.family_data.reacao_estudante_situacao} onInput={(e: any) => handleInputChange('family_data.reacao_estudante_situacao', e.target.value)} />
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Condições familiares do estudante */}
|
||||
<section className="border-t pt-6 mt-6">
|
||||
<h2 className="text-xl font-semibold mb-4">Condições familiares do estudante</h2>
|
||||
<div className="grid md:grid-cols-3 gap-4">
|
||||
<div>
|
||||
<p className="text-sm font-medium mb-2">Condições de moradia</p>
|
||||
<div className="flex space-x-3">
|
||||
<BrCheckbox name="" label="Taipa" checked={formData.family_conditions.moradia.taipa} onClick={() => handleCheckboxClick('family_conditions.moradia.taipa')} />
|
||||
<BrCheckbox name="" label="Alvenaria" checked={formData.family_conditions.moradia.alvenaria} onClick={() => handleCheckboxClick('family_conditions.moradia.alvenaria')} />
|
||||
<BrCheckbox name="" label="Palafita" checked={formData.family_conditions.moradia.palafita} onClick={() => handleCheckboxClick('family_conditions.moradia.palafita')} />
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-sm font-medium mb-2">Convívio familiar</p>
|
||||
<div className="flex space-x-3">
|
||||
<BrCheckbox name="" label="Excelente" checked={formData.family_conditions.convivio_familiar.excelente} onClick={() => handleCheckboxClick('family_conditions.convivio_familiar.excelente')} />
|
||||
<BrCheckbox name="" label="Bom" checked={formData.family_conditions.convivio_familiar.bom} onClick={() => handleCheckboxClick('family_conditions.convivio_familiar.bom')} />
|
||||
<BrCheckbox name="" label="Problemático" checked={formData.family_conditions.convivio_familiar.problematico} onClick={() => handleCheckboxClick('family_conditions.convivio_familiar.problematico')} />
|
||||
<BrCheckbox name="" label="Precário" checked={formData.family_conditions.convivio_familiar.precario} onClick={() => handleCheckboxClick('family_conditions.convivio_familiar.precario')} />
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-sm font-medium mb-2">Qualidade de comunicação</p>
|
||||
<div className="flex space-x-3">
|
||||
<BrCheckbox name="" label="Excelente" checked={formData.family_conditions.qualidade_comunicacao_com_estudante.execelente} onClick={() => handleCheckboxClick('family_conditions.qualidade_comunicacao_com_estudante.execelente')} />
|
||||
<BrCheckbox name="" label="Boa" checked={formData.family_conditions.qualidade_comunicacao_com_estudante.boa} onClick={() => handleCheckboxClick('family_conditions.qualidade_comunicacao_com_estudante.boa')} />
|
||||
<BrCheckbox name="" label="Ruim" checked={formData.family_conditions.qualidade_comunicacao_com_estudante.ruim} onClick={() => handleCheckboxClick('family_conditions.qualidade_comunicacao_com_estudante.ruim')} />
|
||||
<BrCheckbox name="" label="Péssima" checked={formData.family_conditions.qualidade_comunicacao_com_estudante.pessima} onClick={() => handleCheckboxClick('family_conditions.qualidade_comunicacao_com_estudante.pessima')} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="grid md:grid-cols-2 gap-4 mt-6">
|
||||
<BrInput label="Que medidas disciplinares normalmente são usadas com o estudante" value={formData.family_conditions.medidas_disciplinares_com_estudante} onInput={(e: any) => handleInputChange('family_conditions.medidas_disciplinares_com_estudante', e.target.value)} />
|
||||
<BrInput label="Quem as usa" value={formData.family_conditions.quem_usa_medidas_disciplinares} onInput={(e: any) => handleInputChange('family_conditions.quem_usa_medidas_disciplinares', e.target.value)} />
|
||||
<BrInput label="Quais as reações do estudante frente a essas medidas" value={formData.family_conditions.reacao_estudante_frente_medidas} onInput={(e: any) => handleInputChange('family_conditions.reacao_estudante_frente_medidas', e.target.value)} />
|
||||
<BrInput label="Como reage quando contrariado" value={formData.family_conditions.reacao_contrariado} onInput={(e: any) => handleInputChange('family_conditions.reacao_contrariado', e.target.value)} />
|
||||
</div>
|
||||
<div className="mt-6">
|
||||
<p className="text-sm font-medium mb-2">Condições do ambiente familiar para a aprendizagem escolar</p>
|
||||
<BrInput label="Condição" value={formData.family_conditions.condicao_ambiente_familiar_aprendizagem_escolar} onInput={(e: any) => handleInputChange('family_conditions.condicao_ambiente_familiar_aprendizagem_escolar', e.target.value)} />
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Histórico da Mãe */}
|
||||
<section className="border-t pt-6 mt-6">
|
||||
<h2 className="text-xl font-semibold mb-4">Histórico da Mãe</h2>
|
||||
|
||||
{/* Gestação */}
|
||||
<div className="mb-6">
|
||||
<h3 className="text-lg font-medium mb-3">Gestação</h3>
|
||||
<div className="grid md:grid-cols-3 gap-4">
|
||||
<BrInput label="Transfusão sanguínea na gravidez" value={formData.mother_background.gestacao.transfusao_sanguinea_gravidez} onInput={(e: any) => handleInputChange('mother_background.gestacao.transfusao_sanguinea_gravidez', e.target.value)} />
|
||||
<BrInput label="Quando sentiu movimento da criança" value={formData.mother_background.gestacao.quando_sentiu_movimento_da_crianca} onInput={(e: any) => handleInputChange('mother_background.gestacao.quando_sentiu_movimento_da_crianca', e.target.value)} />
|
||||
<BrInput label="Levou tombo durante a gravidez" value={formData.mother_background.gestacao.levou_tombo_durante_gravidez} onInput={(e: any) => handleInputChange('mother_background.gestacao.levou_tombo_durante_gravidez', e.target.value)} />
|
||||
<BrInput label="Doença na gestação" value={formData.mother_background.gestacao.doenca_na_gestacao} onInput={(e: any) => handleInputChange('mother_background.gestacao.doenca_na_gestacao', e.target.value)} />
|
||||
<BrInput label="Condição de saúde da mãe na gravidez" value={formData.mother_background.gestacao.condicao_saude_da_mae_na_gravidez} onInput={(e: any) => handleInputChange('mother_background.gestacao.condicao_saude_da_mae_na_gravidez', e.target.value)} />
|
||||
<BrInput label="Episódio marcante na gravidez" value={formData.mother_background.gestacao.episodio_marcante_gravidez} onInput={(e: any) => handleInputChange('mother_background.gestacao.episodio_marcante_gravidez', e.target.value)} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Condições de Nascimento */}
|
||||
<div className="mb-6">
|
||||
<h3 className="text-lg font-medium mb-3">Condições de Nascimento</h3>
|
||||
<div className="grid md:grid-cols-4 gap-4">
|
||||
<BrInput label="Nasceu com quantos meses" value={formData.mother_background.condicoes_nascimento.nasceu_quantos_meses} onInput={(e: any) => handleInputChange('mother_background.condicoes_nascimento.nasceu_quantos_meses', e.target.value)} />
|
||||
<BrInput label="Nasceu com quantos quilos" value={formData.mother_background.condicoes_nascimento.nasceu_quantos_quilos} onInput={(e: any) => handleInputChange('mother_background.condicoes_nascimento.nasceu_quantos_quilos', e.target.value)} />
|
||||
<BrInput label="Nasceu com qual comprimento" value={formData.mother_background.condicoes_nascimento.nasceu_com_qual_comprimento} onInput={(e: any) => handleInputChange('mother_background.condicoes_nascimento.nasceu_com_qual_comprimento', e.target.value)} />
|
||||
<BrInput label="Desenvolvimento do parto" value={formData.mother_background.condicoes_nascimento.desenvolvimento_parto} onInput={(e: any) => handleInputChange('mother_background.condicoes_nascimento.desenvolvimento_parto', e.target.value)} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Primeiras Reações */}
|
||||
<div className="mb-6">
|
||||
<h3 className="text-lg font-medium mb-3">Primeiras Reações</h3>
|
||||
<div className="grid md:grid-cols-3 gap-4">
|
||||
<BrInput label="Chorou" value={formData.mother_background.primeiras_reacoes.chorou} onInput={(e: any) => handleInputChange('mother_background.primeiras_reacoes.chorou', e.target.value)} />
|
||||
<BrInput label="Ficou vermelho demais" value={formData.mother_background.primeiras_reacoes.ficou_vermelho_demais} onInput={(e: any) => handleInputChange('mother_background.primeiras_reacoes.ficou_vermelho_demais', e.target.value)} />
|
||||
<BrInput label="Ficou vermelho por quanto tempo" value={formData.mother_background.primeiras_reacoes.ficou_vermelho_por_quanto_tempo} onInput={(e: any) => handleInputChange('mother_background.primeiras_reacoes.ficou_vermelho_por_quanto_tempo', e.target.value)} />
|
||||
<BrInput label="Precisou de oxigênio" value={formData.mother_background.primeiras_reacoes.precisou_de_oxigenio} onInput={(e: any) => handleInputChange('mother_background.primeiras_reacoes.precisou_de_oxigenio', e.target.value)} />
|
||||
<BrInput label="Ficou ictérico" value={formData.mother_background.primeiras_reacoes.ficou_icterico} onInput={(e: any) => handleInputChange('mother_background.primeiras_reacoes.ficou_icterico', e.target.value)} />
|
||||
<BrInput label="Como era quando bebê" value={formData.mother_background.primeiras_reacoes.como_era_quando_bebe} onInput={(e: any) => handleInputChange('mother_background.primeiras_reacoes.como_era_quando_bebe', e.target.value)} />
|
||||
<BrInput label="Qual idade afirmou a cabeça" value={formData.mother_background.primeiras_reacoes.qual_idade_afirmou_cabeca} onInput={(e: any) => handleInputChange('mother_background.primeiras_reacoes.qual_idade_afirmou_cabeca', e.target.value)} />
|
||||
<BrInput label="Qual idade sentou sem apoio" value={formData.mother_background.primeiras_reacoes.qual_idade_sentou_sem_apoio} onInput={(e: any) => handleInputChange('mother_background.primeiras_reacoes.qual_idade_sentou_sem_apoio', e.target.value)} />
|
||||
<BrInput label="Qual idade engatinhou" value={formData.mother_background.primeiras_reacoes.qual_idade_engatinhou} onInput={(e: any) => handleInputChange('mother_background.primeiras_reacoes.qual_idade_engatinhou', e.target.value)} />
|
||||
<BrInput label="Qual idade ficou de pé" value={formData.mother_background.primeiras_reacoes.qual_idade_ficou_de_pe} onInput={(e: any) => handleInputChange('mother_background.primeiras_reacoes.qual_idade_ficou_de_pe', e.target.value)} />
|
||||
<BrInput label="Qual idade andou" value={formData.mother_background.primeiras_reacoes.qual_idade_andou} onInput={(e: any) => handleInputChange('mother_background.primeiras_reacoes.qual_idade_andou', e.target.value)} />
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Linguagem Verbal (3 anos) */}
|
||||
<section className="border-t pt-6 mt-6">
|
||||
<h2 className="text-xl font-semibold mb-4">Linguagem Verbal (3 anos)</h2>
|
||||
<div className="grid md:grid-cols-2 gap-4">
|
||||
<div className="space-y-2">
|
||||
<BrCheckbox name="" label="Balbuciou" checked={formData.verbal_language_three_years.balbuciou} onClick={() => handleCheckboxClick('verbal_language_three_years.balbuciou')} />
|
||||
<BrCheckbox name="" label="Trocou letras" checked={formData.verbal_language_three_years.trocou_letras} onClick={() => handleCheckboxClick('verbal_language_three_years.trocou_letras')} />
|
||||
<BrCheckbox name="" label="Gaguejou" checked={formData.verbal_language_three_years.gaguejou} onClick={() => handleCheckboxClick('verbal_language_three_years.gaguejou')} />
|
||||
</div>
|
||||
<BrInput label="Primeiras expressões" value={formData.verbal_language_three_years.primeiras_expressoes} onInput={(e: any) => handleInputChange('verbal_language_three_years.primeiras_expressoes', e.target.value)} />
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Desenvolvimento */}
|
||||
<section className="border-t pt-6 mt-6">
|
||||
<h2 className="text-xl font-semibold mb-4">Desenvolvimento</h2>
|
||||
|
||||
{/* Saúde */}
|
||||
<div className="mb-6">
|
||||
<h3 className="text-lg font-medium mb-3">Saúde</h3>
|
||||
<div className="grid md:grid-cols-2 gap-4">
|
||||
<BrInput label="Sofreu acidente ou fez cirurgia" value={formData.development.saude.sofreu_acidente_ou_fez_cirurgia} onInput={(e: any) => handleInputChange('development.saude.sofreu_acidente_ou_fez_cirurgia', e.target.value)} />
|
||||
<BrInput label="Possui alergia" value={formData.development.saude.possui_alergia} onInput={(e: any) => handleInputChange('development.saude.possui_alergia', e.target.value)} />
|
||||
<BrInput label="Possui bronquite ou asma" value={formData.development.saude.possui_bronquite_ou_asma} onInput={(e: any) => handleInputChange('development.saude.possui_bronquite_ou_asma', e.target.value)} />
|
||||
<BrInput label="Possui problema de visão ou audição" value={formData.development.saude.possui_problema_visao_audicao} onInput={(e: any) => handleInputChange('development.saude.possui_problema_visao_audicao', e.target.value)} />
|
||||
<BrInput label="Já desmaiou" value={formData.development.saude.ja_desmaiou} onInput={(e: any) => handleInputChange('development.saude.ja_desmaiou', e.target.value)} />
|
||||
<BrInput label="Quando desmaiou" value={formData.development.saude.quando_desmaiou} onInput={(e: any) => handleInputChange('development.saude.quando_desmaiou', e.target.value)} />
|
||||
<BrInput label="Teve ou tem convulsões" value={formData.development.saude.teve_ou_tem_convulsoes} onInput={(e: any) => handleInputChange('development.saude.teve_ou_tem_convulsoes', e.target.value)} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Alimentação */}
|
||||
<div className="mb-6">
|
||||
<h3 className="text-lg font-medium mb-3">Alimentação</h3>
|
||||
<div className="grid md:grid-cols-2 gap-4">
|
||||
<BrInput label="Foi amamentada" value={formData.development.alimentacao.foi_amamentada} onInput={(e: any) => handleInputChange('development.alimentacao.foi_amamentada', e.target.value)} />
|
||||
<BrInput label="Foi amamentada até quando" value={formData.development.alimentacao.foi_amementada_ate_quando} onInput={(e: any) => handleInputChange('development.alimentacao.foi_amementada_ate_quando', e.target.value)} />
|
||||
<BrInput label="Como é sua alimentação" value={formData.development.alimentacao.como_e_sua_alimentacao} onInput={(e: any) => handleInputChange('development.alimentacao.como_e_sua_alimentacao', e.target.value)} />
|
||||
<BrInput label="Foi forçado a se alimentar" value={formData.development.alimentacao.foi_forcado_se_alimentar} onInput={(e: any) => handleInputChange('development.alimentacao.foi_forcado_se_alimentar', e.target.value)} />
|
||||
<BrInput label="Recebe ajuda na alimentação" value={formData.development.alimentacao.recebe_ajuda_na_alimentacao} onInput={(e: any) => handleInputChange('development.alimentacao.recebe_ajuda_na_alimentacao', e.target.value)} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Sono */}
|
||||
<div className="mb-6">
|
||||
<h3 className="text-lg font-medium mb-3">Sono</h3>
|
||||
<div className="grid md:grid-cols-2 gap-4">
|
||||
<div className="space-y-2">
|
||||
<BrCheckbox name="" label="Dorme bem" checked={formData.development.sono.dorme_bem} onClick={() => handleCheckboxClick('development.sono.dorme_bem')} />
|
||||
<BrCheckbox name="" label="Dorme separado dos pais" checked={formData.development.sono.dorme_separado_dos_pais} onClick={() => handleCheckboxClick('development.sono.dorme_separado_dos_pais')} />
|
||||
</div>
|
||||
<BrInput label="Com quem dorme" value={formData.development.sono.com_quem_dorme} onInput={(e: any) => handleInputChange('development.sono.com_quem_dorme', e.target.value)} />
|
||||
</div>
|
||||
<div className="mt-4">
|
||||
<p className="text-sm font-medium mb-2">Tipo de sono</p>
|
||||
<div className="flex flex-wrap gap-4">
|
||||
<BrCheckbox name="" label="Agitado" checked={formData.development.sono.sono.agitado} onClick={() => handleCheckboxClick('development.sono.sono.agitado')} />
|
||||
<BrCheckbox name="" label="Tranquilo" checked={formData.development.sono.sono.tranquilo} onClick={() => handleCheckboxClick('development.sono.sono.tranquilo')} />
|
||||
<BrCheckbox name="" label="Fala dormindo" checked={formData.development.sono.sono.fala_dormindo} onClick={() => handleCheckboxClick('development.sono.sono.fala_dormindo')} />
|
||||
<BrCheckbox name="" label="Sonâmbulo" checked={formData.development.sono.sono.sonambulo} onClick={() => handleCheckboxClick('development.sono.sono.sonambulo')} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Informações Escolares */}
|
||||
<section className="border-t pt-6 mt-6">
|
||||
<h2 className="text-xl font-semibold mb-4">Informações Escolares</h2>
|
||||
<div className="grid md:grid-cols-2 gap-4">
|
||||
<BrInput label="Histórico escolar comum - antecedentes relevantes" value={formData.school_information.historico_escolar_comum_antecedentes_relevantes} onInput={(e: any) => handleInputChange('school_information.historico_escolar_comum_antecedentes_relevantes', e.target.value)} />
|
||||
<BrInput label="Histórico escolar especial - antecedentes relevantes" value={formData.school_information.historico_escolar_especial_antecedentes_relevantes} onInput={(e: any) => handleInputChange('school_information.historico_escolar_especial_antecedentes_relevantes', e.target.value)} />
|
||||
<BrInput label="Deficiência apresentada pelo estudante" value={formData.school_information.deficiencia_apresentada_estudante} onInput={(e: any) => handleInputChange('school_information.deficiencia_apresentada_estudante', e.target.value)} />
|
||||
<BrInput label="Foi retido alguma vez" value={formData.school_information.retido_alguma_vez} onInput={(e: any) => handleInputChange('school_information.retido_alguma_vez', e.target.value)} />
|
||||
<BrInput label="Gosta de ir à escola" value={formData.school_information.gosta_de_ir_escola} onInput={(e: any) => handleInputChange('school_information.gosta_de_ir_escola', e.target.value)} />
|
||||
<BrInput label="É bem aceito pelos amigos" value={formData.school_information.bem_aceito_pelos_amigous} onInput={(e: any) => handleInputChange('school_information.bem_aceito_pelos_amigous', e.target.value)} />
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Sexualidade */}
|
||||
<section className="border-t pt-6 mt-6">
|
||||
<h2 className="text-xl font-semibold mb-4">Sexualidade</h2>
|
||||
<div className="flex flex-wrap gap-4">
|
||||
<BrCheckbox name="" label="Explanação sexual" checked={formData.sexuality.explanacao_sexual} onClick={() => handleCheckboxClick('sexuality.explanacao_sexual')} />
|
||||
<BrCheckbox name="" label="Curiosidade sexual" checked={formData.sexuality.curiosidade_sexual} onClick={() => handleCheckboxClick('sexuality.curiosidade_sexual')} />
|
||||
<BrCheckbox name="" label="Conversa com pais sobre sexualidade" checked={formData.sexuality.conversa_com_pais_sobre_sexualidade} onClick={() => handleCheckboxClick('sexuality.conversa_com_pais_sobre_sexualidade')} />
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Avaliação do Estudante */}
|
||||
<section className="border-t pt-6 mt-6">
|
||||
<h2 className="text-xl font-semibold mb-4">Avaliação do Estudante</h2>
|
||||
<div className="grid md:grid-cols-2 gap-4">
|
||||
<BrInput label="Estudante apresenta outro tipo de deficiência" value={formData.student_assessment.estudante_apresenta_outro_tipo_deficiencia} onInput={(e: any) => handleInputChange('student_assessment.estudante_apresenta_outro_tipo_deficiencia', e.target.value)} />
|
||||
<div className="space-y-2">
|
||||
<BrCheckbox name="" label="Apresenta DA/DF/DI/PC/TGD" checked={formData.student_assessment.apresenta_da_df_di_pc_tgd} onClick={() => handleCheckboxClick('student_assessment.apresenta_da_df_di_pc_tgd')} />
|
||||
</div>
|
||||
<BrInput label="Se sim, data e resultado do diagnóstico" value={formData.student_assessment.se_sim_data_e_resultado_diagnostico} onInput={(e: any) => handleInputChange('student_assessment.se_sim_data_e_resultado_diagnostico', e.target.value)} />
|
||||
<BrInput label="Se não, situação quanto ao diagnóstico - tem outras dificuldades" value={formData.student_assessment.se_não_situacao_quanto_diagnostico_tem_outras_dificuldades} onInput={(e: any) => handleInputChange('student_assessment.se_não_situacao_quanto_diagnostico_tem_outras_dificuldades', e.target.value)} />
|
||||
<BrInput label="Se tem outras dificuldades" value={formData.student_assessment.se_tem_outras_dificuldades} onInput={(e: any) => handleInputChange('student_assessment.se_tem_outras_dificuldades', e.target.value)} />
|
||||
<div className="space-y-2">
|
||||
<BrCheckbox name="" label="Usa medicamentos controlados" checked={formData.student_assessment.usa_medicamentos_controlados} onClick={() => handleCheckboxClick('student_assessment.usa_medicamentos_controlados')} />
|
||||
</div>
|
||||
<BrInput label="Usa quais medicamentos" value={formData.student_assessment.usa_quais_medicamentos} onInput={(e: any) => handleInputChange('student_assessment.usa_quais_medicamentos', e.target.value)} />
|
||||
<div className="space-y-2">
|
||||
<BrCheckbox name="" label="Medicamento interfere na aprendizagem" checked={formData.student_assessment.medicamento_interfere_aprendizagem} onClick={() => handleCheckboxClick('student_assessment.medicamento_interfere_aprendizagem')} />
|
||||
</div>
|
||||
<BrInput label="Se interfere na aprendizagem" value={formData.student_assessment.se_intefere_aprendizagem} onInput={(e: any) => handleInputChange('student_assessment.se_intefere_aprendizagem', e.target.value)} />
|
||||
<div className="space-y-2">
|
||||
<BrCheckbox name="" label="Existem recomendações da saúde" checked={formData.student_assessment.existem_recomendacoes_da_saude} onClick={() => handleCheckboxClick('student_assessment.existem_recomendacoes_da_saude')} />
|
||||
</div>
|
||||
<BrInput label="Se possui recomendações da saúde" value={formData.student_assessment.se_possui_recomendacoes_da_saude} onInput={(e: any) => handleInputChange('student_assessment.se_possui_recomendacoes_da_saude', e.target.value)} />
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Desenvolvimento do Estudante */}
|
||||
<section className="border-t pt-6 mt-6">
|
||||
<h2 className="text-xl font-semibold mb-4">Desenvolvimento do Estudante</h2>
|
||||
|
||||
{/* Função Cognitiva */}
|
||||
<div className="mb-6">
|
||||
<h3 className="text-lg font-medium mb-3">Função Cognitiva</h3>
|
||||
<div className="grid md:grid-cols-2 gap-4">
|
||||
<BrInput label="Percepção" value={formData.student_development.funcao_cognitiva.percepcao} onInput={(e: any) => handleInputChange('student_development.funcao_cognitiva.percepcao', e.target.value)} />
|
||||
<BrInput label="Atenção" value={formData.student_development.funcao_cognitiva.atencao} onInput={(e: any) => handleInputChange('student_development.funcao_cognitiva.atencao', e.target.value)} />
|
||||
<BrInput label="Memória" value={formData.student_development.funcao_cognitiva.memoria} onInput={(e: any) => handleInputChange('student_development.funcao_cognitiva.memoria', e.target.value)} />
|
||||
<BrInput label="Linguagem" value={formData.student_development.funcao_cognitiva.linguagem} onInput={(e: any) => handleInputChange('student_development.funcao_cognitiva.linguagem', e.target.value)} />
|
||||
<BrInput label="Raciocínio lógico" value={formData.student_development.funcao_cognitiva.raciocinio_logico} onInput={(e: any) => handleInputChange('student_development.funcao_cognitiva.raciocinio_logico', e.target.value)} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Função Motora */}
|
||||
<div className="mb-6">
|
||||
<h3 className="text-lg font-medium mb-3">Função Motora</h3>
|
||||
<BrInput label="Desenvolvimento e capacidade motora" value={formData.student_development.funcao_motora.desenvolvimento_e_capacidade_motora} onInput={(e: any) => handleInputChange('student_development.funcao_motora.desenvolvimento_e_capacidade_motora', e.target.value)} />
|
||||
</div>
|
||||
|
||||
{/* Função Pessoal Social */}
|
||||
<div className="mb-6">
|
||||
<h3 className="text-lg font-medium mb-3">Função Pessoal Social</h3>
|
||||
<BrInput label="Área emocional, afetiva e social" value={formData.student_development.funcao_pressoal_social.area_emocional_afetiva_social} onInput={(e: any) => handleInputChange('student_development.funcao_pressoal_social.area_emocional_afetiva_social', e.target.value)} />
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Botões */}
|
||||
<div className="flex justify-center gap-4 mt-8">
|
||||
<button className="bg-red-600 hover:bg-red-700 text-white font-medium py-2 px-4 rounded-full" onClick={() => router.push(`/anamnese?email=${email}&nome=${nome}`)}>
|
||||
Cancelar
|
||||
</button>
|
||||
<button className="bg-green-600 hover:bg-green-700 text-white font-medium py-2 px-4 rounded-full" onClick={handleEdit}>
|
||||
Salvar Alterações
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</AppLayout>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
// Provenance: dayflower/etude-lexical-markdown (fixed).
|
||||
// repo: dayflower/etude-lexical-markdown
|
||||
// commit: c61a8bf78fe20d6ae0eab2e4b8b02004508525ed
|
||||
// parent: 0a2184f59e79a04b1365cd49200026e8f2ffdbd5
|
||||
// commit_url: https://github.com/dayflower/etude-lexical-markdown/commit/c61a8bf78fe20d6ae0eab2e4b8b02004508525ed
|
||||
// cve:
|
||||
// license: MIT
|
||||
// function: deepMergeInto
|
||||
// relpath: src/config/editorConfig.ts
|
||||
// provenance: agent
|
||||
// mechanism: prototype_pollution
|
||||
|
||||
function deepMergeInto(
|
||||
target: Record<string, unknown>,
|
||||
source: Record<string, unknown>,
|
||||
): Record<string, unknown> {
|
||||
for (const key of Object.keys(source)) {
|
||||
if (FORBIDDEN_KEYS.has(key)) continue;
|
||||
const sourceValue = source[key];
|
||||
if (sourceValue === undefined) continue;
|
||||
if (isPlainObject(sourceValue)) {
|
||||
const targetValue = target[key];
|
||||
const nested = isPlainObject(targetValue) ? targetValue : {};
|
||||
target[key] = deepMergeInto(nested, sourceValue);
|
||||
} else {
|
||||
target[key] = sourceValue;
|
||||
}
|
||||
}
|
||||
return target;
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
// Provenance: dayflower/etude-lexical-markdown (vuln).
|
||||
// repo: dayflower/etude-lexical-markdown
|
||||
// commit: 0a2184f59e79a04b1365cd49200026e8f2ffdbd5
|
||||
// parent: 0a2184f59e79a04b1365cd49200026e8f2ffdbd5
|
||||
// commit_url: https://github.com/dayflower/etude-lexical-markdown/commit/c61a8bf78fe20d6ae0eab2e4b8b02004508525ed
|
||||
// cve:
|
||||
// license: MIT
|
||||
// function: deepMergeInto
|
||||
// relpath: src/config/editorConfig.ts
|
||||
// provenance: agent
|
||||
// mechanism: prototype_pollution
|
||||
|
||||
function deepMergeInto(
|
||||
target: Record<string, unknown>,
|
||||
source: Record<string, unknown>,
|
||||
): Record<string, unknown> {
|
||||
for (const key of Object.keys(source)) {
|
||||
const sourceValue = source[key];
|
||||
if (sourceValue === undefined) continue;
|
||||
if (isPlainObject(sourceValue)) {
|
||||
const targetValue = target[key];
|
||||
const nested = isPlainObject(targetValue) ? targetValue : {};
|
||||
target[key] = deepMergeInto(nested, sourceValue);
|
||||
} else {
|
||||
target[key] = sourceValue;
|
||||
}
|
||||
}
|
||||
return target;
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
// Provenance: dayflower/etude-lexical-markdown (fixed).
|
||||
// repo: dayflower/etude-lexical-markdown
|
||||
// commit: db4f54b1ab80ad596de6425e84f90aa781c49999
|
||||
// parent: 1c865815d05b072f4973388c3ac66b6696d9efde
|
||||
// commit_url: https://github.com/dayflower/etude-lexical-markdown/commit/db4f54b1ab80ad596de6425e84f90aa781c49999
|
||||
// cve:
|
||||
// license: MIT
|
||||
// function: deepMergeInto
|
||||
// relpath: src/config/editorConfig.ts
|
||||
// provenance: agent
|
||||
// mechanism: prototype_pollution
|
||||
|
||||
function deepMergeInto(
|
||||
target: Record<string, unknown>,
|
||||
source: Record<string, unknown>,
|
||||
): Record<string, unknown> {
|
||||
for (const key of Object.keys(source)) {
|
||||
if (isForbiddenKey(key)) continue;
|
||||
const sourceValue = source[key];
|
||||
if (sourceValue === undefined) continue;
|
||||
if (isPlainObject(sourceValue)) {
|
||||
const targetValue = target[key];
|
||||
const nested = isPlainObject(targetValue) ? targetValue : {};
|
||||
target[key] = deepMergeInto(nested, sourceValue);
|
||||
} else {
|
||||
target[key] = sourceValue;
|
||||
}
|
||||
}
|
||||
return target;
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
// Provenance: dayflower/etude-lexical-markdown (vuln).
|
||||
// repo: dayflower/etude-lexical-markdown
|
||||
// commit: 1c865815d05b072f4973388c3ac66b6696d9efde
|
||||
// parent: 1c865815d05b072f4973388c3ac66b6696d9efde
|
||||
// commit_url: https://github.com/dayflower/etude-lexical-markdown/commit/db4f54b1ab80ad596de6425e84f90aa781c49999
|
||||
// cve:
|
||||
// license: MIT
|
||||
// function: deepMergeInto
|
||||
// relpath: src/config/editorConfig.ts
|
||||
// provenance: agent
|
||||
// mechanism: prototype_pollution
|
||||
|
||||
function deepMergeInto(
|
||||
target: Record<string, unknown>,
|
||||
source: Record<string, unknown>,
|
||||
): Record<string, unknown> {
|
||||
for (const key of Object.keys(source)) {
|
||||
if (FORBIDDEN_KEYS.has(key)) continue;
|
||||
const sourceValue = source[key];
|
||||
if (sourceValue === undefined) continue;
|
||||
if (isPlainObject(sourceValue)) {
|
||||
const targetValue = target[key];
|
||||
const nested = isPlainObject(targetValue) ? targetValue : {};
|
||||
target[key] = deepMergeInto(nested, sourceValue);
|
||||
} else {
|
||||
target[key] = sourceValue;
|
||||
}
|
||||
}
|
||||
return target;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,31 @@
|
||||
// Provenance: navaneethbv/market-cap (fixed).
|
||||
// repo: navaneethbv/market-cap
|
||||
// commit: 4f8ae9be5519ced5a975f1190e3e4bc43f84e4d6
|
||||
// parent: fec6f024ce72c9c47b61cbac6ce7a35cb2280602
|
||||
// commit_url: https://github.com/navaneethbv/market-cap/commit/4f8ae9be5519ced5a975f1190e3e4bc43f84e4d6
|
||||
// cve:
|
||||
// license: MIT
|
||||
// function: GET
|
||||
// relpath: app/auth/confirm/route.ts
|
||||
// provenance: agent
|
||||
// mechanism: source_reaches_sink
|
||||
|
||||
export async function GET(request: NextRequest) {
|
||||
const { searchParams } = new URL(request.url);
|
||||
const token_hash = searchParams.get("token_hash");
|
||||
const type = searchParams.get("type") as EmailOtpType | null;
|
||||
const nextParam = searchParams.get("next") ?? "/";
|
||||
// Only allow same-origin relative paths to prevent open redirects
|
||||
const next =
|
||||
nextParam.startsWith("/") && !nextParam.startsWith("//") ? nextParam : "/";
|
||||
|
||||
if (token_hash && type) {
|
||||
const supabase = await createClient();
|
||||
const { error } = await supabase.auth.verifyOtp({ type, token_hash });
|
||||
if (!error) {
|
||||
return NextResponse.redirect(new URL(next, request.url));
|
||||
}
|
||||
}
|
||||
|
||||
return NextResponse.redirect(new URL("/login?error=confirm", request.url));
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
// Provenance: navaneethbv/market-cap (vuln).
|
||||
// repo: navaneethbv/market-cap
|
||||
// commit: fec6f024ce72c9c47b61cbac6ce7a35cb2280602
|
||||
// parent: fec6f024ce72c9c47b61cbac6ce7a35cb2280602
|
||||
// commit_url: https://github.com/navaneethbv/market-cap/commit/4f8ae9be5519ced5a975f1190e3e4bc43f84e4d6
|
||||
// cve:
|
||||
// license: MIT
|
||||
// function: GET
|
||||
// relpath: app/auth/confirm/route.ts
|
||||
// provenance: agent
|
||||
// mechanism: source_reaches_sink
|
||||
|
||||
export async function GET(request: NextRequest) {
|
||||
const { searchParams } = new URL(request.url);
|
||||
const token_hash = searchParams.get("token_hash");
|
||||
const type = searchParams.get("type") as EmailOtpType | null;
|
||||
const next = searchParams.get("next") ?? "/";
|
||||
|
||||
if (token_hash && type) {
|
||||
const supabase = await createClient();
|
||||
const { error } = await supabase.auth.verifyOtp({ type, token_hash });
|
||||
if (!error) {
|
||||
return NextResponse.redirect(new URL(next, request.url));
|
||||
}
|
||||
}
|
||||
|
||||
return NextResponse.redirect(new URL("/login?error=confirm", request.url));
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
// Provenance: alexshao3/melodix (fixed).
|
||||
// repo: alexshao3/melodix
|
||||
// commit: 089931ef71ea1e5b7586520baf1a5498e2f05b13
|
||||
// parent: c074fc7413338aefcbea3170ef4d3ba486a8a4b7
|
||||
// commit_url: https://github.com/alexshao3/melodix/commit/089931ef71ea1e5b7586520baf1a5498e2f05b13
|
||||
// cve:
|
||||
// license: MIT
|
||||
// function: PlayerProvider
|
||||
// relpath: apps/miniapp/src/components/PlayerProvider.tsx
|
||||
// provenance: agent
|
||||
// mechanism: permissive_default
|
||||
|
||||
export function PlayerProvider({ children }: { children: React.ReactNode }) {
|
||||
const audioRef = useRef<HTMLAudioElement | null>(null);
|
||||
const [currentTrack, setCurrentTrack] = useState<Track | null>(null);
|
||||
const [queue, setQueue] = useState<Track[]>([]);
|
||||
const [history, setHistory] = useState<Track[]>([]);
|
||||
const [isPlaying, setIsPlaying] = useState(false);
|
||||
const [position, setPosition] = useState(0);
|
||||
const [duration, setDuration] = useState(0);
|
||||
const handleEndedRef = useRef<() => void>(() => {});
|
||||
|
||||
useEffect(() => {
|
||||
const a = new Audio();
|
||||
a.preload = 'metadata';
|
||||
audioRef.current = a;
|
||||
const t = () => setPosition(a.currentTime);
|
||||
const l = () => setDuration(a.duration || 0);
|
||||
const p = () => setIsPlaying(true);
|
||||
const ps = () => setIsPlaying(false);
|
||||
const e = () => handleEndedRef.current?.();
|
||||
a.addEventListener('timeupdate', t);
|
||||
a.addEventListener('loadedmetadata', l);
|
||||
a.addEventListener('play', p);
|
||||
a.addEventListener('pause', ps);
|
||||
a.addEventListener('ended', e);
|
||||
return () => {
|
||||
a.pause();
|
||||
a.removeEventListener('timeupdate', t);
|
||||
a.removeEventListener('loadedmetadata', l);
|
||||
a.removeEventListener('play', p);
|
||||
a.removeEventListener('pause', ps);
|
||||
a.removeEventListener('ended', e);
|
||||
};
|
||||
}, []);
|
||||
|
||||
const playTrack = useCallback((t: Track) => {
|
||||
const a = audioRef.current;
|
||||
if (!a) return;
|
||||
a.src = t.streamUrl ?? t.audioUrl;
|
||||
setCurrentTrack(t);
|
||||
setPosition(0);
|
||||
pushRecentlyPlayed(t);
|
||||
// Best-effort server-side history mirror; `recordPlay` no-ops for guests.
|
||||
void api.recordPlay(t.id);
|
||||
a.play().catch(() => undefined);
|
||||
}, []);
|
||||
|
||||
const play = useCallback(
|
||||
(track: Track, newQueue?: Track[]) => {
|
||||
tgHaptic('light');
|
||||
if (newQueue) {
|
||||
const idx = newQueue.findIndex((t) => t.id === track.id);
|
||||
const upcoming =
|
||||
idx >= 0 ? newQueue.slice(idx + 1) : newQueue.filter((t) => t.id !== track.id);
|
||||
setQueue(upcoming);
|
||||
}
|
||||
if (currentTrack && currentTrack.id !== track.id) {
|
||||
setHistory((h) => [...h.slice(-19), currentTrack]);
|
||||
}
|
||||
playTrack(track);
|
||||
},
|
||||
[currentTrack, playTrack],
|
||||
);
|
||||
|
||||
const toggle = useCallback(() => {
|
||||
const a = audioRef.current;
|
||||
if (!a || !currentTrack) return;
|
||||
tgHaptic('light');
|
||||
if (a.paused) a.play();
|
||||
else a.pause();
|
||||
}, [currentTrack]);
|
||||
|
||||
const next = useCallback(() => {
|
||||
if (queue.length === 0) return;
|
||||
const [head, ...rest] = queue;
|
||||
if (!head) return;
|
||||
if (currentTrack) setHistory((h) => [...h.slice(-19), currentTrack]);
|
||||
setQueue(rest);
|
||||
playTrack(head);
|
||||
}, [queue, currentTrack, playTrack]);
|
||||
|
||||
const prev = useCallback(() => {
|
||||
const a = audioRef.current;
|
||||
if (a && a.currentTime > 3) {
|
||||
a.currentTime = 0;
|
||||
return;
|
||||
}
|
||||
const last = history[history.length - 1];
|
||||
if (!last) {
|
||||
if (a) a.currentTime = 0;
|
||||
return;
|
||||
}
|
||||
setHistory((h) => h.slice(0, -1));
|
||||
if (currentTrack) setQueue((q) => [currentTrack, ...q]);
|
||||
playTrack(last);
|
||||
}, [history, currentTrack, playTrack]);
|
||||
|
||||
useEffect(() => {
|
||||
handleEndedRef.current = () => next();
|
||||
}, [next]);
|
||||
|
||||
const seek = useCallback((s: number) => {
|
||||
const a = audioRef.current;
|
||||
if (!a) return;
|
||||
a.currentTime = s;
|
||||
setPosition(s);
|
||||
}, []);
|
||||
|
||||
const value = useMemo(
|
||||
() => ({ currentTrack, queue, isPlaying, position, duration, play, toggle, next, prev, seek }),
|
||||
[currentTrack, queue, isPlaying, position, duration, play, toggle, next, prev, seek],
|
||||
);
|
||||
|
||||
return <PlayerContext.Provider value={value}>{children}</PlayerContext.Provider>;
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
// Provenance: alexshao3/melodix (vuln).
|
||||
// repo: alexshao3/melodix
|
||||
// commit: c074fc7413338aefcbea3170ef4d3ba486a8a4b7
|
||||
// parent: c074fc7413338aefcbea3170ef4d3ba486a8a4b7
|
||||
// commit_url: https://github.com/alexshao3/melodix/commit/089931ef71ea1e5b7586520baf1a5498e2f05b13
|
||||
// cve:
|
||||
// license: MIT
|
||||
// function: PlayerProvider
|
||||
// relpath: apps/miniapp/src/components/PlayerProvider.tsx
|
||||
// provenance: agent
|
||||
// mechanism: permissive_default
|
||||
|
||||
export function PlayerProvider({ children }: { children: React.ReactNode }) {
|
||||
const audioRef = useRef<HTMLAudioElement | null>(null);
|
||||
const [currentTrack, setCurrentTrack] = useState<Track | null>(null);
|
||||
const [queue, setQueue] = useState<Track[]>([]);
|
||||
const [history, setHistory] = useState<Track[]>([]);
|
||||
const [isPlaying, setIsPlaying] = useState(false);
|
||||
const [position, setPosition] = useState(0);
|
||||
const [duration, setDuration] = useState(0);
|
||||
const handleEndedRef = useRef<() => void>(() => {});
|
||||
|
||||
useEffect(() => {
|
||||
const a = new Audio();
|
||||
a.crossOrigin = 'anonymous';
|
||||
a.preload = 'metadata';
|
||||
audioRef.current = a;
|
||||
const t = () => setPosition(a.currentTime);
|
||||
const l = () => setDuration(a.duration || 0);
|
||||
const p = () => setIsPlaying(true);
|
||||
const ps = () => setIsPlaying(false);
|
||||
const e = () => handleEndedRef.current?.();
|
||||
a.addEventListener('timeupdate', t);
|
||||
a.addEventListener('loadedmetadata', l);
|
||||
a.addEventListener('play', p);
|
||||
a.addEventListener('pause', ps);
|
||||
a.addEventListener('ended', e);
|
||||
return () => {
|
||||
a.pause();
|
||||
a.removeEventListener('timeupdate', t);
|
||||
a.removeEventListener('loadedmetadata', l);
|
||||
a.removeEventListener('play', p);
|
||||
a.removeEventListener('pause', ps);
|
||||
a.removeEventListener('ended', e);
|
||||
};
|
||||
}, []);
|
||||
|
||||
const playTrack = useCallback((t: Track) => {
|
||||
const a = audioRef.current;
|
||||
if (!a) return;
|
||||
a.src = t.streamUrl ?? t.audioUrl;
|
||||
setCurrentTrack(t);
|
||||
setPosition(0);
|
||||
pushRecentlyPlayed(t);
|
||||
// Best-effort server-side history mirror; `recordPlay` no-ops for guests.
|
||||
void api.recordPlay(t.id);
|
||||
a.play().catch(() => undefined);
|
||||
}, []);
|
||||
|
||||
const play = useCallback(
|
||||
(track: Track, newQueue?: Track[]) => {
|
||||
tgHaptic('light');
|
||||
if (newQueue) {
|
||||
const idx = newQueue.findIndex((t) => t.id === track.id);
|
||||
const upcoming =
|
||||
idx >= 0 ? newQueue.slice(idx + 1) : newQueue.filter((t) => t.id !== track.id);
|
||||
setQueue(upcoming);
|
||||
}
|
||||
if (currentTrack && currentTrack.id !== track.id) {
|
||||
setHistory((h) => [...h.slice(-19), currentTrack]);
|
||||
}
|
||||
playTrack(track);
|
||||
},
|
||||
[currentTrack, playTrack],
|
||||
);
|
||||
|
||||
const toggle = useCallback(() => {
|
||||
const a = audioRef.current;
|
||||
if (!a || !currentTrack) return;
|
||||
tgHaptic('light');
|
||||
if (a.paused) a.play();
|
||||
else a.pause();
|
||||
}, [currentTrack]);
|
||||
|
||||
const next = useCallback(() => {
|
||||
if (queue.length === 0) return;
|
||||
const [head, ...rest] = queue;
|
||||
if (!head) return;
|
||||
if (currentTrack) setHistory((h) => [...h.slice(-19), currentTrack]);
|
||||
setQueue(rest);
|
||||
playTrack(head);
|
||||
}, [queue, currentTrack, playTrack]);
|
||||
|
||||
const prev = useCallback(() => {
|
||||
const a = audioRef.current;
|
||||
if (a && a.currentTime > 3) {
|
||||
a.currentTime = 0;
|
||||
return;
|
||||
}
|
||||
const last = history[history.length - 1];
|
||||
if (!last) {
|
||||
if (a) a.currentTime = 0;
|
||||
return;
|
||||
}
|
||||
setHistory((h) => h.slice(0, -1));
|
||||
if (currentTrack) setQueue((q) => [currentTrack, ...q]);
|
||||
playTrack(last);
|
||||
}, [history, currentTrack, playTrack]);
|
||||
|
||||
useEffect(() => {
|
||||
handleEndedRef.current = () => next();
|
||||
}, [next]);
|
||||
|
||||
const seek = useCallback((s: number) => {
|
||||
const a = audioRef.current;
|
||||
if (!a) return;
|
||||
a.currentTime = s;
|
||||
setPosition(s);
|
||||
}, []);
|
||||
|
||||
const value = useMemo(
|
||||
() => ({ currentTrack, queue, isPlaying, position, duration, play, toggle, next, prev, seek }),
|
||||
[currentTrack, queue, isPlaying, position, duration, play, toggle, next, prev, seek],
|
||||
);
|
||||
|
||||
return <PlayerContext.Provider value={value}>{children}</PlayerContext.Provider>;
|
||||
}
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
// Provenance: handielson/Mercado-do-vale-news (fixed).
|
||||
// repo: handielson/Mercado-do-vale-news
|
||||
// commit: 9b5fcf2dae41e56f5f97952266f2d6ba59598598
|
||||
// parent: 70ca282b819ac1d60f4b5e665d224b1043ff1ccc
|
||||
// commit_url: https://github.com/handielson/Mercado-do-vale-news/commit/9b5fcf2dae41e56f5f97952266f2d6ba59598598
|
||||
// cve:
|
||||
// license: MIT
|
||||
// function: fetchMetadata
|
||||
// relpath: services/catalogMetadataService.ts
|
||||
// provenance: agent
|
||||
// mechanism: permissive_default
|
||||
|
||||
async function fetchMetadata(): Promise<MetadataCache | null> {
|
||||
// Deduplicação de requisições concorrentes
|
||||
if (pendingFetch) return pendingFetch;
|
||||
|
||||
pendingFetch = (async () => {
|
||||
try {
|
||||
const controller = new AbortController();
|
||||
const timer = setTimeout(() => controller.abort(), 10000);
|
||||
|
||||
// Bypass completo de cache de CDN e Browser
|
||||
const timestamp = Date.now();
|
||||
const res = await fetch(buildVpsUrl(`/catalog/metadata?_t=${timestamp}`), {
|
||||
signal: controller.signal,
|
||||
headers: { Accept: 'application/json' },
|
||||
cache: 'no-store',
|
||||
});
|
||||
clearTimeout(timer);
|
||||
if (!res.ok) return null;
|
||||
const data = await res.json();
|
||||
return {
|
||||
categories: data.categories || [],
|
||||
brands: data.brands || [],
|
||||
priceRange: data.priceRange || null,
|
||||
timestamp: Date.now(),
|
||||
};
|
||||
} catch {
|
||||
return null;
|
||||
} finally {
|
||||
pendingFetch = null;
|
||||
}
|
||||
})();
|
||||
|
||||
return pendingFetch;
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
// Provenance: handielson/Mercado-do-vale-news (vuln).
|
||||
// repo: handielson/Mercado-do-vale-news
|
||||
// commit: 70ca282b819ac1d60f4b5e665d224b1043ff1ccc
|
||||
// parent: 70ca282b819ac1d60f4b5e665d224b1043ff1ccc
|
||||
// commit_url: https://github.com/handielson/Mercado-do-vale-news/commit/9b5fcf2dae41e56f5f97952266f2d6ba59598598
|
||||
// cve:
|
||||
// license: MIT
|
||||
// function: fetchMetadata
|
||||
// relpath: services/catalogMetadataService.ts
|
||||
// provenance: agent
|
||||
// mechanism: permissive_default
|
||||
|
||||
async function fetchMetadata(): Promise<MetadataCache | null> {
|
||||
// Deduplicação de requisições concorrentes
|
||||
if (pendingFetch) return pendingFetch;
|
||||
|
||||
pendingFetch = (async () => {
|
||||
try {
|
||||
const controller = new AbortController();
|
||||
const timer = setTimeout(() => controller.abort(), 10000);
|
||||
|
||||
// Bypass completo de cache de CDN e Browser
|
||||
const timestamp = Date.now();
|
||||
const res = await fetch(buildVpsUrl(`/catalog/metadata?_t=${timestamp}`), {
|
||||
signal: controller.signal,
|
||||
headers: {
|
||||
Accept: 'application/json',
|
||||
'Cache-Control': 'no-cache, no-store, must-revalidate',
|
||||
'Pragma': 'no-cache'
|
||||
},
|
||||
cache: 'no-store',
|
||||
});
|
||||
clearTimeout(timer);
|
||||
if (!res.ok) return null;
|
||||
const data = await res.json();
|
||||
return {
|
||||
categories: data.categories || [],
|
||||
brands: data.brands || [],
|
||||
priceRange: data.priceRange || null,
|
||||
timestamp: Date.now(),
|
||||
};
|
||||
} catch {
|
||||
return null;
|
||||
} finally {
|
||||
pendingFetch = null;
|
||||
}
|
||||
})();
|
||||
|
||||
return pendingFetch;
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
// Provenance: andrebubniak/money-track (fixed).
|
||||
// repo: andrebubniak/money-track
|
||||
// commit: 4d4a5b063278c8b6697c3faae133d7c39fcd01c0
|
||||
// parent: add96df6d6a6b61506635c23dbacf6c6cfe24dc2
|
||||
// commit_url: https://github.com/andrebubniak/money-track/commit/4d4a5b063278c8b6697c3faae133d7c39fcd01c0
|
||||
// cve:
|
||||
// license: MIT
|
||||
// function: isCategoryIcon
|
||||
// relpath: src/lib/category-icons.ts
|
||||
// provenance: agent
|
||||
// mechanism: prototype_pollution
|
||||
|
||||
export function isCategoryIcon(value: string): value is keyof typeof CATEGORY_ICONS {
|
||||
return Object.hasOwn(CATEGORY_ICONS, value);
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
// Provenance: andrebubniak/money-track (vuln).
|
||||
// repo: andrebubniak/money-track
|
||||
// commit: add96df6d6a6b61506635c23dbacf6c6cfe24dc2
|
||||
// parent: add96df6d6a6b61506635c23dbacf6c6cfe24dc2
|
||||
// commit_url: https://github.com/andrebubniak/money-track/commit/4d4a5b063278c8b6697c3faae133d7c39fcd01c0
|
||||
// cve:
|
||||
// license: MIT
|
||||
// function: isCategoryIcon
|
||||
// relpath: src/lib/category-icons.ts
|
||||
// provenance: agent
|
||||
// mechanism: prototype_pollution
|
||||
|
||||
export function isCategoryIcon(value: string): value is keyof typeof CATEGORY_ICONS {
|
||||
return value in CATEGORY_ICONS;
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
// Provenance: DavideCarvalho/nestjs-filter (fixed).
|
||||
// repo: DavideCarvalho/nestjs-filter
|
||||
// commit: aa0e600d05997ea3d77538ea1c2db427c439f2e8
|
||||
// parent: d899b40d3466f2ffbe9f01c4d49267412401f078
|
||||
// commit_url: https://github.com/DavideCarvalho/nestjs-filter/commit/aa0e600d05997ea3d77538ea1c2db427c439f2e8
|
||||
// cve:
|
||||
// license: MIT
|
||||
// function: normalizeInput
|
||||
// relpath: packages/core/src/input/normalizer.ts
|
||||
// provenance: agent
|
||||
// mechanism: prototype_pollution
|
||||
|
||||
export function normalizeInput(input: unknown, options: NormalizeOptions): Record<string, unknown> {
|
||||
if (input == null || typeof input !== 'object') return {};
|
||||
const norm = pickNormalizer(options.normalizer);
|
||||
const drop = options.dropId === true;
|
||||
const out: Record<string, unknown> = {};
|
||||
for (const [rawKey, value] of Object.entries(input as Record<string, unknown>)) {
|
||||
if (BLOCKED_KEYS.has(rawKey)) continue;
|
||||
let key = norm(rawKey);
|
||||
if (BLOCKED_KEYS.has(key)) continue;
|
||||
if (drop) key = stripId(key);
|
||||
if (key.length === 0) continue;
|
||||
out[key] = value;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
// Provenance: DavideCarvalho/nestjs-filter (vuln).
|
||||
// repo: DavideCarvalho/nestjs-filter
|
||||
// commit: d899b40d3466f2ffbe9f01c4d49267412401f078
|
||||
// parent: d899b40d3466f2ffbe9f01c4d49267412401f078
|
||||
// commit_url: https://github.com/DavideCarvalho/nestjs-filter/commit/aa0e600d05997ea3d77538ea1c2db427c439f2e8
|
||||
// cve:
|
||||
// license: MIT
|
||||
// function: normalizeInput
|
||||
// relpath: packages/core/src/input/normalizer.ts
|
||||
// provenance: agent
|
||||
// mechanism: prototype_pollution
|
||||
|
||||
export function normalizeInput(input: unknown, options: NormalizeOptions): Record<string, unknown> {
|
||||
if (input == null || typeof input !== 'object') return {};
|
||||
const norm = pickNormalizer(options.normalizer);
|
||||
const drop = options.dropId === true;
|
||||
const out: Record<string, unknown> = {};
|
||||
for (const [rawKey, value] of Object.entries(input as Record<string, unknown>)) {
|
||||
let key = norm(rawKey);
|
||||
if (drop) key = stripId(key);
|
||||
if (key.length === 0) continue;
|
||||
out[key] = value;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
// Provenance: Sachin-Salgar/NEW_ERP_FINAL (fixed).
|
||||
// repo: Sachin-Salgar/NEW_ERP_FINAL
|
||||
// commit: 6e9644c81ce3fb356669157182a5ef09a70c4b59
|
||||
// parent: 08976c5d7a07b0663669b875b4507446199f85d7
|
||||
// commit_url: https://github.com/Sachin-Salgar/NEW_ERP_FINAL/commit/6e9644c81ce3fb356669157182a5ef09a70c4b59
|
||||
// cve:
|
||||
// license: Apache-2.0
|
||||
// function: origin
|
||||
// relpath: src/presentation/http/app.ts
|
||||
// provenance: agent
|
||||
// mechanism: permissive_default
|
||||
|
||||
export async function createApplication(config: AppConfig, providedPool?: Pool): Promise<FastifyInstance> {
|
||||
const app = Fastify({
|
||||
logger: createLogger(config),
|
||||
requestIdHeader: 'x-request-id',
|
||||
requestIdLogLabel: 'requestId',
|
||||
ignoreTrailingSlash: true,
|
||||
ajv: {
|
||||
customOptions: {
|
||||
allErrors: true,
|
||||
coerceTypes: true,
|
||||
removeAdditional: false,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const pool = providedPool ?? createDatabasePool(config);
|
||||
const repository = new IdentityAwarePostgresPlatformRepository(pool);
|
||||
const passwordHasher = new BcryptPasswordHasher();
|
||||
const jwtTokenService = new JwtTokenService(config);
|
||||
const authService = new AuthenticationService(repository, passwordHasher, jwtTokenService);
|
||||
const authorizationService = new AuthorizationService(repository);
|
||||
const branchService = new BranchService(repository);
|
||||
const coreEnterpriseService = new CoreEnterpriseService(repository);
|
||||
const locationService = new LocationService(repository);
|
||||
const moduleAccessService = new ModuleAccessService(pool);
|
||||
const registrationService = new UserRegistrationService(repository, passwordHasher);
|
||||
const tenantMembershipService = new TenantMembershipService(repository);
|
||||
|
||||
app.decorate('appConfig', config);
|
||||
app.decorate('authService', authService);
|
||||
app.decorate('authorizationService', authorizationService);
|
||||
app.decorate('branchService', branchService);
|
||||
app.decorate('coreEnterpriseService', coreEnterpriseService);
|
||||
app.decorate('locationService', locationService);
|
||||
app.decorate('moduleAccessService', moduleAccessService);
|
||||
app.decorate('registrationService', registrationService);
|
||||
app.decorate('jwtTokenService', jwtTokenService);
|
||||
app.decorate('tenantMembershipService', tenantMembershipService);
|
||||
|
||||
await app.register(cors, {
|
||||
origin: (origin, callback) => {
|
||||
callback(null, isCorsOriginAllowed(config, origin));
|
||||
},
|
||||
methods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS'],
|
||||
allowedHeaders: ['Content-Type', 'Authorization', 'x-tenant-id'],
|
||||
credentials: true,
|
||||
optionsSuccessStatus: 204,
|
||||
});
|
||||
|
||||
app.setErrorHandler(buildErrorHandler(config));
|
||||
|
||||
await app.register(healthRoutes, { prefix: config.API_PREFIX });
|
||||
await app.register(authRoutes, { prefix: config.API_PREFIX });
|
||||
await app.register(rbacRoutes, { prefix: config.API_PREFIX });
|
||||
await app.register(branchRoutes, { prefix: config.API_PREFIX });
|
||||
await app.register(coreEnterpriseRoutes, { prefix: config.API_PREFIX });
|
||||
await app.register(locationRoutes, { prefix: config.API_PREFIX });
|
||||
|
||||
return app;
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
// Provenance: Sachin-Salgar/NEW_ERP_FINAL (vuln).
|
||||
// repo: Sachin-Salgar/NEW_ERP_FINAL
|
||||
// commit: 08976c5d7a07b0663669b875b4507446199f85d7
|
||||
// parent: 08976c5d7a07b0663669b875b4507446199f85d7
|
||||
// commit_url: https://github.com/Sachin-Salgar/NEW_ERP_FINAL/commit/6e9644c81ce3fb356669157182a5ef09a70c4b59
|
||||
// cve:
|
||||
// license: Apache-2.0
|
||||
// function: origin
|
||||
// relpath: src/presentation/http/app.ts
|
||||
// provenance: agent
|
||||
// mechanism: permissive_default
|
||||
|
||||
export async function createApplication(config: AppConfig, providedPool?: Pool): Promise<FastifyInstance> {
|
||||
const app = Fastify({
|
||||
logger: createLogger(config),
|
||||
requestIdHeader: 'x-request-id',
|
||||
requestIdLogLabel: 'requestId',
|
||||
ignoreTrailingSlash: true,
|
||||
ajv: {
|
||||
customOptions: {
|
||||
allErrors: true,
|
||||
coerceTypes: true,
|
||||
removeAdditional: false,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const pool = providedPool ?? createDatabasePool(config);
|
||||
const repository = new IdentityAwarePostgresPlatformRepository(pool);
|
||||
const passwordHasher = new BcryptPasswordHasher();
|
||||
const jwtTokenService = new JwtTokenService(config);
|
||||
const authService = new AuthenticationService(repository, passwordHasher, jwtTokenService);
|
||||
const authorizationService = new AuthorizationService(repository);
|
||||
const branchService = new BranchService(repository);
|
||||
const coreEnterpriseService = new CoreEnterpriseService(repository);
|
||||
const locationService = new LocationService(repository);
|
||||
const moduleAccessService = new ModuleAccessService(pool);
|
||||
const registrationService = new UserRegistrationService(repository, passwordHasher);
|
||||
const tenantMembershipService = new TenantMembershipService(repository);
|
||||
|
||||
app.decorate('appConfig', config);
|
||||
app.decorate('authService', authService);
|
||||
app.decorate('authorizationService', authorizationService);
|
||||
app.decorate('branchService', branchService);
|
||||
app.decorate('coreEnterpriseService', coreEnterpriseService);
|
||||
app.decorate('locationService', locationService);
|
||||
app.decorate('moduleAccessService', moduleAccessService);
|
||||
app.decorate('registrationService', registrationService);
|
||||
app.decorate('jwtTokenService', jwtTokenService);
|
||||
app.decorate('tenantMembershipService', tenantMembershipService);
|
||||
|
||||
await app.register(cors, {
|
||||
origin: (origin, callback) => {
|
||||
callback(null, isCorsOriginAllowed(config, origin));
|
||||
},
|
||||
methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
|
||||
allowedHeaders: ['Content-Type', 'Authorization', 'x-tenant-id'],
|
||||
credentials: true,
|
||||
optionsSuccessStatus: 204,
|
||||
});
|
||||
|
||||
app.setErrorHandler(buildErrorHandler(config));
|
||||
|
||||
await app.register(healthRoutes, { prefix: config.API_PREFIX });
|
||||
await app.register(authRoutes, { prefix: config.API_PREFIX });
|
||||
await app.register(rbacRoutes, { prefix: config.API_PREFIX });
|
||||
await app.register(branchRoutes, { prefix: config.API_PREFIX });
|
||||
await app.register(coreEnterpriseRoutes, { prefix: config.API_PREFIX });
|
||||
await app.register(locationRoutes, { prefix: config.API_PREFIX });
|
||||
|
||||
return app;
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
// Provenance: Irnhakim/nimestream (fixed).
|
||||
// repo: Irnhakim/nimestream
|
||||
// commit: d17f535bf3012041b056ff3aa991ff6cfa198e43
|
||||
// parent: 0c37bfd9e5292b15b1d7af51f52793d9bdf1cef0
|
||||
// commit_url: https://github.com/Irnhakim/nimestream/commit/d17f535bf3012041b056ff3aa991ff6cfa198e43
|
||||
// cve:
|
||||
// license: MIT
|
||||
// function: GET
|
||||
// relpath: app/api/img/route.js
|
||||
// provenance: agent
|
||||
// mechanism: source_reaches_sink
|
||||
|
||||
export async function GET(request) {
|
||||
const { searchParams } = new URL(request.url);
|
||||
const imageUrl = searchParams.get('url');
|
||||
|
||||
if (!imageUrl) {
|
||||
return new Response('Missing url parameter', { status: 400 });
|
||||
}
|
||||
|
||||
// Only allow proxying images from allowed domains for security
|
||||
const allowed = [
|
||||
'otakudesu.blog', 'otakudesu.cloud', 'otakudesu.ltd',
|
||||
'i3.wp.com', 'i2.wp.com', 'i1.wp.com', 'i0.wp.com',
|
||||
'cdn.otakudesu', 'kusonime.com', 'wp-content',
|
||||
'oploverz.ac', 'oploverz.site', 'backapi.oploverz', 'alqanime.net',
|
||||
'anichin.cafe', 'samehadaku', 'animasu', 'zoronime', 'anoboy', 'nimegami', 'animeindo', 'animekuindo', 'winbu', 'kuramanime', 'animekompi', 'donghub', 'dramabox'
|
||||
];
|
||||
|
||||
let parsedUrl;
|
||||
try {
|
||||
parsedUrl = new URL(imageUrl);
|
||||
} catch (e) {
|
||||
return new Response('Invalid URL', { status: 400 });
|
||||
}
|
||||
|
||||
const hostname = parsedUrl.hostname;
|
||||
const isAllowed = allowed.some(domain =>
|
||||
hostname === domain || hostname.endsWith(`.${domain}`)
|
||||
);
|
||||
if (!isAllowed) {
|
||||
return new Response('Forbidden', { status: 403 });
|
||||
}
|
||||
|
||||
// Determine proper referer
|
||||
let referer = `${BASE_URL}/`;
|
||||
if (imageUrl.includes('kusonime.com')) {
|
||||
referer = 'https://kusonime.com/';
|
||||
} else if (imageUrl.includes('oploverz.ac') || imageUrl.includes('oploverz.site')) {
|
||||
referer = 'https://oploverz.site/';
|
||||
} else if (imageUrl.includes('alqanime.net')) {
|
||||
referer = 'https://alqanime.net/';
|
||||
} else if (imageUrl.includes('anichin.cafe')) {
|
||||
referer = 'https://anichin.cafe/';
|
||||
} else if (imageUrl.includes('samehadaku')) {
|
||||
referer = 'https://samehadaku.vip/';
|
||||
} else if (imageUrl.includes('animasu')) {
|
||||
referer = 'https://animasu.cc/';
|
||||
} else if (imageUrl.includes('kuramanime')) {
|
||||
referer = 'https://kuramanime.net/';
|
||||
}
|
||||
|
||||
try {
|
||||
// Add abort controller to prevent long timeout waits
|
||||
const controller = new AbortController();
|
||||
const timeoutId = setTimeout(() => controller.abort(), 4000); // 4 seconds timeout limit
|
||||
|
||||
const response = await fetch(imageUrl, {
|
||||
headers: {
|
||||
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
|
||||
'Referer': referer,
|
||||
'Accept': 'image/avif,image/webp,image/apng,image/*,*/*;q=0.8',
|
||||
'Accept-Encoding': 'gzip, deflate, br',
|
||||
},
|
||||
signal: controller.signal,
|
||||
cache: 'no-store',
|
||||
});
|
||||
|
||||
clearTimeout(timeoutId);
|
||||
|
||||
if (!response.ok) {
|
||||
return new Response('Failed to fetch source image', { status: response.status });
|
||||
}
|
||||
|
||||
const contentType = response.headers.get('content-type') || 'image/jpeg';
|
||||
const imageBuffer = await response.arrayBuffer();
|
||||
|
||||
return new Response(imageBuffer, {
|
||||
status: 200,
|
||||
headers: {
|
||||
'Content-Type': contentType,
|
||||
'Cache-Control': 'public, max-age=86400, stale-while-revalidate=43200',
|
||||
'Access-Control-Allow-Origin': '*',
|
||||
},
|
||||
});
|
||||
} catch (err) {
|
||||
console.error('Image proxy error:', err.message);
|
||||
return new Response('Error loading image', { status: 500 });
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
// Provenance: Irnhakim/nimestream (vuln).
|
||||
// repo: Irnhakim/nimestream
|
||||
// commit: 0c37bfd9e5292b15b1d7af51f52793d9bdf1cef0
|
||||
// parent: 0c37bfd9e5292b15b1d7af51f52793d9bdf1cef0
|
||||
// commit_url: https://github.com/Irnhakim/nimestream/commit/d17f535bf3012041b056ff3aa991ff6cfa198e43
|
||||
// cve:
|
||||
// license: MIT
|
||||
// function: GET
|
||||
// relpath: app/api/img/route.js
|
||||
// provenance: agent
|
||||
// mechanism: source_reaches_sink
|
||||
|
||||
export async function GET(request) {
|
||||
const { searchParams } = new URL(request.url);
|
||||
const imageUrl = searchParams.get('url');
|
||||
|
||||
if (!imageUrl) {
|
||||
return new Response('Missing url parameter', { status: 400 });
|
||||
}
|
||||
|
||||
// Only allow proxying images from allowed domains for security
|
||||
const allowed = [
|
||||
'otakudesu.blog', 'otakudesu.cloud', 'otakudesu.ltd',
|
||||
'i3.wp.com', 'i2.wp.com', 'i1.wp.com', 'i0.wp.com',
|
||||
'cdn.otakudesu', 'kusonime.com', 'wp-content',
|
||||
'oploverz.ac', 'oploverz.site', 'backapi.oploverz', 'alqanime.net',
|
||||
'anichin.cafe', 'samehadaku', 'animasu', 'zoronime', 'anoboy', 'nimegami', 'animeindo', 'animekuindo', 'winbu', 'kuramanime', 'animekompi', 'donghub', 'dramabox'
|
||||
];
|
||||
const isAllowed = allowed.some(domain => imageUrl.includes(domain));
|
||||
if (!isAllowed) {
|
||||
return new Response('Forbidden', { status: 403 });
|
||||
}
|
||||
|
||||
// Determine proper referer
|
||||
let referer = `${BASE_URL}/`;
|
||||
if (imageUrl.includes('kusonime.com')) {
|
||||
referer = 'https://kusonime.com/';
|
||||
} else if (imageUrl.includes('oploverz.ac') || imageUrl.includes('oploverz.site')) {
|
||||
referer = 'https://oploverz.site/';
|
||||
} else if (imageUrl.includes('alqanime.net')) {
|
||||
referer = 'https://alqanime.net/';
|
||||
} else if (imageUrl.includes('anichin.cafe')) {
|
||||
referer = 'https://anichin.cafe/';
|
||||
} else if (imageUrl.includes('samehadaku')) {
|
||||
referer = 'https://samehadaku.vip/';
|
||||
} else if (imageUrl.includes('animasu')) {
|
||||
referer = 'https://animasu.cc/';
|
||||
} else if (imageUrl.includes('kuramanime')) {
|
||||
referer = 'https://kuramanime.net/';
|
||||
}
|
||||
|
||||
try {
|
||||
// Add abort controller to prevent long timeout waits
|
||||
const controller = new AbortController();
|
||||
const timeoutId = setTimeout(() => controller.abort(), 4000); // 4 seconds timeout limit
|
||||
|
||||
const response = await fetch(imageUrl, {
|
||||
headers: {
|
||||
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
|
||||
'Referer': referer,
|
||||
'Accept': 'image/avif,image/webp,image/apng,image/*,*/*;q=0.8',
|
||||
'Accept-Encoding': 'gzip, deflate, br',
|
||||
},
|
||||
signal: controller.signal,
|
||||
cache: 'no-store',
|
||||
});
|
||||
|
||||
clearTimeout(timeoutId);
|
||||
|
||||
if (!response.ok) {
|
||||
// Fallback redirect to direct URL if fetch failed but URL is reachable in browser
|
||||
return Response.redirect(imageUrl, 302);
|
||||
}
|
||||
|
||||
const contentType = response.headers.get('content-type') || 'image/jpeg';
|
||||
const imageBuffer = await response.arrayBuffer();
|
||||
|
||||
return new Response(imageBuffer, {
|
||||
status: 200,
|
||||
headers: {
|
||||
'Content-Type': contentType,
|
||||
'Cache-Control': 'public, max-age=86400, stale-while-revalidate=43200',
|
||||
'Access-Control-Allow-Origin': '*',
|
||||
},
|
||||
});
|
||||
} catch (err) {
|
||||
console.error('Image proxy error, falling back to direct redirect:', err.message);
|
||||
return Response.redirect(imageUrl, 302);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
# Provenance: HHHHHejia/openniw (fixed).
|
||||
# repo: HHHHHejia/openniw
|
||||
# commit: 0fc94733f6ca3c6b129a0a8e6d7b3acce19d5a10
|
||||
# parent: 4d91ed82fa9a5ec6bf5ef96da1d221fc187700dc
|
||||
# commit_url: https://github.com/HHHHHejia/openniw/commit/0fc94733f6ca3c6b129a0a8e6d7b3acce19d5a10
|
||||
# cve:
|
||||
# license: MIT
|
||||
# function: get_job
|
||||
# relpath: backend/app/routers/jobs.py
|
||||
# provenance: agent
|
||||
# mechanism: identity_from_request_body
|
||||
|
||||
async def get_job(job_id: str, user: dict = Depends(auth.current_user)) -> dict:
|
||||
job = await jobs_service.get(job_id)
|
||||
if job is None:
|
||||
raise HTTPException(404, "Job not found")
|
||||
# Authorization: case-bound jobs are visible only to the case owner;
|
||||
# caseless jobs (free evaluations) are served by the public route only.
|
||||
if job.get("case_id") is None:
|
||||
raise HTTPException(404, "Job not found")
|
||||
await auth.case_owned_by(str(job["case_id"]), user)
|
||||
return {
|
||||
"id": str(job["id"]),
|
||||
"kind": job["kind"],
|
||||
"status": job["status"],
|
||||
"result": job["result"],
|
||||
"error": job["error"],
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
# Provenance: HHHHHejia/openniw (vuln).
|
||||
# repo: HHHHHejia/openniw
|
||||
# commit: 4d91ed82fa9a5ec6bf5ef96da1d221fc187700dc
|
||||
# parent: 4d91ed82fa9a5ec6bf5ef96da1d221fc187700dc
|
||||
# commit_url: https://github.com/HHHHHejia/openniw/commit/0fc94733f6ca3c6b129a0a8e6d7b3acce19d5a10
|
||||
# cve:
|
||||
# license: MIT
|
||||
# function: get_job
|
||||
# relpath: backend/app/routers/jobs.py
|
||||
# provenance: agent
|
||||
# mechanism: identity_from_request_body
|
||||
|
||||
async def get_job(job_id: str, user: dict = Depends(auth.current_user)) -> dict:
|
||||
job = await jobs_service.get(job_id)
|
||||
if job is None:
|
||||
raise HTTPException(404, "Job not found")
|
||||
return {
|
||||
"id": str(job["id"]),
|
||||
"kind": job["kind"],
|
||||
"status": job["status"],
|
||||
"result": job["result"],
|
||||
"error": job["error"],
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
# Provenance: ziyuzuo/openniw (fixed).
|
||||
# repo: ziyuzuo/openniw
|
||||
# commit: b74de31b0a5f37e4e929ba6aa74dbe0f5e6d9a68
|
||||
# parent: 98a0c392ba96cd2c4aa746dd6fc2b183f385225e
|
||||
# commit_url: https://github.com/ziyuzuo/openniw/commit/b74de31b0a5f37e4e929ba6aa74dbe0f5e6d9a68
|
||||
# cve:
|
||||
# license: MIT
|
||||
# function: get_job
|
||||
# relpath: backend/app/routers/jobs.py
|
||||
# provenance: agent
|
||||
# mechanism: identity_from_request_body
|
||||
|
||||
async def get_job(job_id: str, user: dict = Depends(auth.current_user)) -> dict:
|
||||
job = await jobs_service.get(job_id)
|
||||
if job is None:
|
||||
raise HTTPException(404, "Job not found")
|
||||
# Authorization: case-bound jobs are visible only to the case owner;
|
||||
# caseless jobs (free evaluations) are served by the public route only.
|
||||
if job.get("case_id") is None:
|
||||
raise HTTPException(404, "Job not found")
|
||||
await auth.case_owned_by(str(job["case_id"]), user)
|
||||
return {
|
||||
"id": str(job["id"]),
|
||||
"kind": job["kind"],
|
||||
"status": job["status"],
|
||||
"result": job["result"],
|
||||
"error": job["error"],
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
# Provenance: ziyuzuo/openniw (vuln).
|
||||
# repo: ziyuzuo/openniw
|
||||
# commit: 98a0c392ba96cd2c4aa746dd6fc2b183f385225e
|
||||
# parent: 98a0c392ba96cd2c4aa746dd6fc2b183f385225e
|
||||
# commit_url: https://github.com/ziyuzuo/openniw/commit/b74de31b0a5f37e4e929ba6aa74dbe0f5e6d9a68
|
||||
# cve:
|
||||
# license: MIT
|
||||
# function: get_job
|
||||
# relpath: backend/app/routers/jobs.py
|
||||
# provenance: agent
|
||||
# mechanism: identity_from_request_body
|
||||
|
||||
async def get_job(job_id: str, user: dict = Depends(auth.current_user)) -> dict:
|
||||
job = await jobs_service.get(job_id)
|
||||
if job is None:
|
||||
raise HTTPException(404, "Job not found")
|
||||
return {
|
||||
"id": str(job["id"]),
|
||||
"kind": job["kind"],
|
||||
"status": job["status"],
|
||||
"result": job["result"],
|
||||
"error": job["error"],
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
// Provenance: ZUENS2020/overleaf-with-claude (fixed).
|
||||
// repo: ZUENS2020/overleaf-with-claude
|
||||
// commit: 3980b9e5806defb63e45ae2696e6c1899f3a8431
|
||||
// parent: 5a886aa9fb9fe4e2203f3cb1d62c91f4be0525ed
|
||||
// commit_url: https://github.com/ZUENS2020/overleaf-with-claude/commit/3980b9e5806defb63e45ae2696e6c1899f3a8431
|
||||
// cve:
|
||||
// license: AGPL-3.0
|
||||
// function: exportProject
|
||||
// relpath: services/web/app/src/Features/Exports/ExportsController.mjs
|
||||
// provenance: agent
|
||||
// mechanism: identity_from_request_body
|
||||
|
||||
import { expressify } from '@overleaf/promise-utils'
|
||||
import SessionManager from '../Authentication/SessionManager.mjs'
|
||||
import logger from '@overleaf/logger'
|
||||
import OError from '@overleaf/o-error'
|
||||
import settings from '@overleaf/settings'
|
||||
|
||||
async function exportProject(req, res, next) {
|
||||
const { project_id: projectId, brand_variation_id: brandVariationId } =
|
||||
req.params
|
||||
const userId = SessionManager.getLoggedInUserId(req.session)
|
||||
const exportParams = {
|
||||
project_id: projectId,
|
||||
brand_variation_id: brandVariationId,
|
||||
user_id: userId,
|
||||
}
|
||||
|
||||
if (req.body) {
|
||||
if (req.body.firstName) {
|
||||
exportParams.first_name = req.body.firstName.trim()
|
||||
}
|
||||
if (req.body.lastName) {
|
||||
exportParams.last_name = req.body.lastName.trim()
|
||||
}
|
||||
// additional parameters for gallery exports
|
||||
if (req.body.title) {
|
||||
exportParams.title = req.body.title.trim()
|
||||
}
|
||||
if (req.body.description) {
|
||||
exportParams.description = req.body.description.trim()
|
||||
}
|
||||
if (req.body.author) {
|
||||
exportParams.author = req.body.author.trim()
|
||||
}
|
||||
if (req.body.license) {
|
||||
exportParams.license = req.body.license.trim()
|
||||
}
|
||||
if (req.body.showSource != null) {
|
||||
exportParams.show_source = req.body.showSource
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
const exportData = await ExportsHandler.exportProject(exportParams)
|
||||
logger.debug(
|
||||
{
|
||||
userId,
|
||||
projectId,
|
||||
brandVariationId,
|
||||
exportV1Id: exportData.v1_id,
|
||||
},
|
||||
'exported project'
|
||||
)
|
||||
return res.json({
|
||||
export_v1_id: exportData.v1_id,
|
||||
token: exportData.token,
|
||||
message: exportData.message,
|
||||
})
|
||||
} catch (err) {
|
||||
const info = OError.getFullInfo(err)
|
||||
if (info?.forwardResponse) {
|
||||
logger.debug(
|
||||
{ responseError: info.forwardResponse },
|
||||
'forwarding response'
|
||||
)
|
||||
const statusCode = info.forwardResponse.status || 500
|
||||
return res.status(statusCode).json(info.forwardResponse)
|
||||
}
|
||||
throw err
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
// Provenance: ZUENS2020/overleaf-with-claude (vuln).
|
||||
// repo: ZUENS2020/overleaf-with-claude
|
||||
// commit: 5a886aa9fb9fe4e2203f3cb1d62c91f4be0525ed
|
||||
// parent: 5a886aa9fb9fe4e2203f3cb1d62c91f4be0525ed
|
||||
// commit_url: https://github.com/ZUENS2020/overleaf-with-claude/commit/3980b9e5806defb63e45ae2696e6c1899f3a8431
|
||||
// cve:
|
||||
// license: AGPL-3.0
|
||||
// function: exportProject
|
||||
// relpath: services/web/app/src/Features/Exports/ExportsController.mjs
|
||||
// provenance: agent
|
||||
// mechanism: identity_from_request_body
|
||||
|
||||
import { expressify } from '@overleaf/promise-utils'
|
||||
import SessionManager from '../Authentication/SessionManager.mjs'
|
||||
import logger from '@overleaf/logger'
|
||||
import OError from '@overleaf/o-error'
|
||||
|
||||
async function exportProject(req, res, next) {
|
||||
const { project_id: projectId, brand_variation_id: brandVariationId } =
|
||||
req.params
|
||||
const userId = SessionManager.getLoggedInUserId(req.session)
|
||||
const exportParams = {
|
||||
project_id: projectId,
|
||||
brand_variation_id: brandVariationId,
|
||||
user_id: userId,
|
||||
}
|
||||
|
||||
if (req.body) {
|
||||
if (req.body.firstName) {
|
||||
exportParams.first_name = req.body.firstName.trim()
|
||||
}
|
||||
if (req.body.lastName) {
|
||||
exportParams.last_name = req.body.lastName.trim()
|
||||
}
|
||||
// additional parameters for gallery exports
|
||||
if (req.body.title) {
|
||||
exportParams.title = req.body.title.trim()
|
||||
}
|
||||
if (req.body.description) {
|
||||
exportParams.description = req.body.description.trim()
|
||||
}
|
||||
if (req.body.author) {
|
||||
exportParams.author = req.body.author.trim()
|
||||
}
|
||||
if (req.body.license) {
|
||||
exportParams.license = req.body.license.trim()
|
||||
}
|
||||
if (req.body.showSource != null) {
|
||||
exportParams.show_source = req.body.showSource
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
const exportData = await ExportsHandler.exportProject(exportParams)
|
||||
logger.debug(
|
||||
{
|
||||
userId,
|
||||
projectId,
|
||||
brandVariationId,
|
||||
exportV1Id: exportData.v1_id,
|
||||
},
|
||||
'exported project'
|
||||
)
|
||||
return res.json({
|
||||
export_v1_id: exportData.v1_id,
|
||||
message: exportData.message,
|
||||
})
|
||||
} catch (err) {
|
||||
const info = OError.getFullInfo(err)
|
||||
if (info?.forwardResponse) {
|
||||
logger.debug(
|
||||
{ responseError: info.forwardResponse },
|
||||
'forwarding response'
|
||||
)
|
||||
const statusCode = info.forwardResponse.status || 500
|
||||
return res.status(statusCode).json(info.forwardResponse)
|
||||
}
|
||||
throw err
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
// Provenance: dayflower/popmark (fixed).
|
||||
// repo: dayflower/popmark
|
||||
// commit: e5ac407cef37c37178d440541ede301c838640fb
|
||||
// parent: 31d1ac79b4cfa3118597348e79800a6561115149
|
||||
// commit_url: https://github.com/dayflower/popmark/commit/e5ac407cef37c37178d440541ede301c838640fb
|
||||
// cve:
|
||||
// license: MIT
|
||||
// function: deepMergeInto
|
||||
// relpath: src/lexical-markdown/config/editorConfig.ts
|
||||
// provenance: agent
|
||||
// mechanism: prototype_pollution
|
||||
|
||||
function deepMergeInto(
|
||||
target: Record<string, unknown>,
|
||||
source: Record<string, unknown>,
|
||||
): Record<string, unknown> {
|
||||
for (const key of Object.keys(source)) {
|
||||
// popmark patch: guard against prototype pollution (CodeQL).
|
||||
if (key === "__proto__" || key === "constructor" || key === "prototype") {
|
||||
continue;
|
||||
}
|
||||
const sourceValue = source[key];
|
||||
if (sourceValue === undefined) continue;
|
||||
if (isPlainObject(sourceValue)) {
|
||||
const targetValue = target[key];
|
||||
const nested = isPlainObject(targetValue) ? targetValue : {};
|
||||
target[key] = deepMergeInto(nested, sourceValue);
|
||||
} else {
|
||||
target[key] = sourceValue;
|
||||
}
|
||||
}
|
||||
return target;
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
// Provenance: dayflower/popmark (vuln).
|
||||
// repo: dayflower/popmark
|
||||
// commit: 31d1ac79b4cfa3118597348e79800a6561115149
|
||||
// parent: 31d1ac79b4cfa3118597348e79800a6561115149
|
||||
// commit_url: https://github.com/dayflower/popmark/commit/e5ac407cef37c37178d440541ede301c838640fb
|
||||
// cve:
|
||||
// license: MIT
|
||||
// function: deepMergeInto
|
||||
// relpath: src/lexical-markdown/config/editorConfig.ts
|
||||
// provenance: agent
|
||||
// mechanism: prototype_pollution
|
||||
|
||||
function deepMergeInto(
|
||||
target: Record<string, unknown>,
|
||||
source: Record<string, unknown>,
|
||||
): Record<string, unknown> {
|
||||
for (const key of Object.keys(source)) {
|
||||
const sourceValue = source[key];
|
||||
if (sourceValue === undefined) continue;
|
||||
if (isPlainObject(sourceValue)) {
|
||||
const targetValue = target[key];
|
||||
const nested = isPlainObject(targetValue) ? targetValue : {};
|
||||
target[key] = deepMergeInto(nested, sourceValue);
|
||||
} else {
|
||||
target[key] = sourceValue;
|
||||
}
|
||||
}
|
||||
return target;
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
// Provenance: DevilsDev/rag-pipeline-utils (fixed).
|
||||
// repo: DevilsDev/rag-pipeline-utils
|
||||
// commit: 76e5f0a94d6803d0e463d26a61cedb7da90857a7
|
||||
// parent: ba587867118f703632ff2dc63c4feb8ad6793420
|
||||
// commit_url: https://github.com/DevilsDev/rag-pipeline-utils/commit/76e5f0a94d6803d0e463d26a61cedb7da90857a7
|
||||
// cve:
|
||||
// license: MIT
|
||||
// function: handleConfigSet
|
||||
// relpath: src/cli/handlers/config-handler.js
|
||||
// provenance: agent
|
||||
// mechanism: prototype_pollution
|
||||
|
||||
async function handleConfigSet(globalOptions, key, value) {
|
||||
try {
|
||||
const config = JSON.parse(await fs.readFile(globalOptions.config, "utf-8"));
|
||||
|
||||
// Set value using dot notation
|
||||
const keys = key.split(".");
|
||||
const forbidden = new Set(["__proto__", "constructor", "prototype"]);
|
||||
if (keys.some((k) => forbidden.has(k))) {
|
||||
logger.error("Invalid configuration key: contains restricted property");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
let current = config;
|
||||
|
||||
for (let i = 0; i < keys.length - 1; i++) {
|
||||
if (!current[keys[i]]) {
|
||||
current[keys[i]] = {};
|
||||
}
|
||||
current = current[keys[i]];
|
||||
}
|
||||
|
||||
// Parse value
|
||||
let parsedValue;
|
||||
try {
|
||||
parsedValue = JSON.parse(value);
|
||||
} catch (error) {
|
||||
parsedValue = value; // Keep as string
|
||||
}
|
||||
|
||||
current[keys[keys.length - 1]] = parsedValue;
|
||||
|
||||
// Save configuration
|
||||
await fs.writeFile(globalOptions.config, JSON.stringify(config, null, 2));
|
||||
console.log("✅ Configuration updated");
|
||||
} catch (error) {
|
||||
logger.error("❌ Failed to set configuration:", error.message);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
// Provenance: DevilsDev/rag-pipeline-utils (vuln).
|
||||
// repo: DevilsDev/rag-pipeline-utils
|
||||
// commit: ba587867118f703632ff2dc63c4feb8ad6793420
|
||||
// parent: ba587867118f703632ff2dc63c4feb8ad6793420
|
||||
// commit_url: https://github.com/DevilsDev/rag-pipeline-utils/commit/76e5f0a94d6803d0e463d26a61cedb7da90857a7
|
||||
// cve:
|
||||
// license: MIT
|
||||
// function: handleConfigSet
|
||||
// relpath: src/cli/handlers/config-handler.js
|
||||
// provenance: agent
|
||||
// mechanism: prototype_pollution
|
||||
|
||||
async function handleConfigSet(globalOptions, key, value) {
|
||||
try {
|
||||
const config = JSON.parse(await fs.readFile(globalOptions.config, "utf-8"));
|
||||
|
||||
// Set value using dot notation
|
||||
const keys = key.split(".");
|
||||
let current = config;
|
||||
|
||||
for (let i = 0; i < keys.length - 1; i++) {
|
||||
if (!current[keys[i]]) {
|
||||
current[keys[i]] = {};
|
||||
}
|
||||
current = current[keys[i]];
|
||||
}
|
||||
|
||||
// Parse value
|
||||
let parsedValue;
|
||||
try {
|
||||
parsedValue = JSON.parse(value);
|
||||
} catch (error) {
|
||||
parsedValue = value; // Keep as string
|
||||
}
|
||||
|
||||
current[keys[keys.length - 1]] = parsedValue;
|
||||
|
||||
// Save configuration
|
||||
await fs.writeFile(globalOptions.config, JSON.stringify(config, null, 2));
|
||||
console.log("✅ Configuration updated");
|
||||
} catch (error) {
|
||||
logger.error("❌ Failed to set configuration:", error.message);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,977 @@
|
||||
# agent-vfc candidate recipes from agent-trailer security-fix commits (build_recipes.py).
|
||||
# reviewer = "pending" means a human has not yet confirmed the vulnerability and mechanism.
|
||||
|
||||
[[recipe]]
|
||||
name = "academic-based-qoder-app-a79ddb"
|
||||
host = "github"
|
||||
repo = "1173591564/academic-based-qoder"
|
||||
parent = "8170f0377fe64d1ec2e35769d4ce3d0634d97cef"
|
||||
commit = "a79ddb90def54e91f7507cbf6b1548b224d642aa"
|
||||
path = "services/proxy-hub/backend/proxy_hub/app.py"
|
||||
mode = "hunk"
|
||||
language = "python"
|
||||
relpath = "services/proxy-hub/backend/proxy_hub/app.py"
|
||||
license = "MIT"
|
||||
cve = ""
|
||||
year = 2026
|
||||
cwe = "CWE-16"
|
||||
class = "permissive default"
|
||||
mechanism = "permissive_default"
|
||||
provenance = "agent"
|
||||
origin = "github-agent-trailer"
|
||||
project = "academic-based-qoder"
|
||||
trailer = "Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>"
|
||||
reviewer = "pending"
|
||||
evidence = "fix(hub): allow DSH token validation CORS"
|
||||
commit_url = "https://github.com/1173591564/academic-based-qoder/commit/a79ddb90def54e91f7507cbf6b1548b224d642aa"
|
||||
split = "train"
|
||||
|
||||
[[recipe]]
|
||||
name = "anastasios-pw-session-14ec1a"
|
||||
host = "github"
|
||||
repo = "Anas329796/Anastasios"
|
||||
parent = "adb7b0d5d6b81c46d56451c709e7eac9d0dc93fb"
|
||||
commit = "14ec1ac50f9e4e255d875236d30129c6207401d4"
|
||||
path = "extensions/browser/src/browser/pw-session.ts"
|
||||
mode = "hunk"
|
||||
language = "typescript"
|
||||
relpath = "extensions/browser/src/browser/pw-session.ts"
|
||||
license = "MIT"
|
||||
cve = ""
|
||||
year = 2026
|
||||
cwe = "CWE-918"
|
||||
class = "server-side request forgery"
|
||||
mechanism = "source_reaches_sink"
|
||||
provenance = "agent"
|
||||
origin = "github-agent-trailer"
|
||||
project = "Anastasios"
|
||||
trailer = "Co-authored-by: Devin Robison <[email protected]>"
|
||||
reviewer = "pending"
|
||||
evidence = "fix(browser): harden SSRF redirect guard against non-navigation document hops [AI] (#62355)"
|
||||
commit_url = "https://github.com/Anas329796/Anastasios/commit/14ec1ac50f9e4e255d875236d30129c6207401d4"
|
||||
split = "holdout"
|
||||
|
||||
[[recipe]]
|
||||
name = "arsnova-eu-httpcors-9bcba4"
|
||||
host = "github"
|
||||
repo = "kqc-real/arsnova.eu"
|
||||
parent = "2ae60c434f3fb80f91807a2ec485ee1a7ec76bd2"
|
||||
commit = "9bcba4f442aecc6a5e16ef2dc6115177cfc2b6df"
|
||||
path = "apps/backend/src/lib/httpCors.ts"
|
||||
mode = "hunk"
|
||||
language = "typescript"
|
||||
relpath = "apps/backend/src/lib/httpCors.ts"
|
||||
license = "MIT"
|
||||
cve = ""
|
||||
year = 2026
|
||||
cwe = "CWE-16"
|
||||
class = "permissive default"
|
||||
mechanism = "permissive_default"
|
||||
provenance = "agent"
|
||||
origin = "github-agent-trailer"
|
||||
project = "arsnova.eu"
|
||||
trailer = "Co-authored-by: Cursor <[email protected]>"
|
||||
reviewer = "pending"
|
||||
evidence = "fix(security): Produktions-CORS auf Same-Origin begrenzen (#143)"
|
||||
commit_url = "https://github.com/kqc-real/arsnova.eu/commit/9bcba4f442aecc6a5e16ef2dc6115177cfc2b6df"
|
||||
split = "train"
|
||||
|
||||
[[recipe]]
|
||||
name = "astroclaw-pw-session-1553a8"
|
||||
host = "github"
|
||||
repo = "P1R4N351/astroclaw"
|
||||
parent = "d3eed2dc01328f21dd404477bb28e2740fa371a4"
|
||||
commit = "1553a8adf123913cf7f1f1c75be4c4e5cd6c796b"
|
||||
path = "extensions/browser/src/browser/pw-session.ts"
|
||||
mode = "hunk"
|
||||
language = "typescript"
|
||||
relpath = "extensions/browser/src/browser/pw-session.ts"
|
||||
license = "MIT"
|
||||
cve = ""
|
||||
year = 2026
|
||||
cwe = "CWE-918"
|
||||
class = "server-side request forgery"
|
||||
mechanism = "source_reaches_sink"
|
||||
provenance = "agent"
|
||||
origin = "github-agent-trailer"
|
||||
project = "astroclaw"
|
||||
trailer = "Co-authored-by: Devin Robison <[email protected]>"
|
||||
reviewer = "pending"
|
||||
evidence = "fix(browser): harden SSRF redirect guard against non-navigation document hops [AI] (#62355)"
|
||||
commit_url = "https://github.com/P1R4N351/astroclaw/commit/1553a8adf123913cf7f1f1c75be4c4e5cd6c796b"
|
||||
split = "holdout"
|
||||
|
||||
[[recipe]]
|
||||
name = "capgo-app-apptabs-7d73fd"
|
||||
host = "github"
|
||||
repo = "Cap-go/capgo.app"
|
||||
parent = "415ea4e19d7da19a3f8b0cd0bba541d60b902522"
|
||||
commit = "7d73fd21a59eaa3a4e20c6dc0d280e73e47435b7"
|
||||
path = "src/constants/appTabs.ts"
|
||||
mode = "hunk"
|
||||
language = "typescript"
|
||||
relpath = "src/constants/appTabs.ts"
|
||||
license = "AGPL-3.0"
|
||||
cve = ""
|
||||
year = 2026
|
||||
cwe = "CWE-16"
|
||||
class = "permissive default"
|
||||
mechanism = "permissive_default"
|
||||
provenance = "agent"
|
||||
origin = "github-agent-trailer"
|
||||
project = "capgo.app"
|
||||
trailer = "Co-authored-by: Cursor <[email protected]>"
|
||||
reviewer = "pending"
|
||||
evidence = "fix(notifications): harden API CORS and mark console tab as beta (#2623)"
|
||||
commit_url = "https://github.com/Cap-go/capgo.app/commit/7d73fd21a59eaa3a4e20c6dc0d280e73e47435b7"
|
||||
split = "train"
|
||||
|
||||
[[recipe]]
|
||||
name = "capgo-app-hono-4dadd2"
|
||||
host = "github"
|
||||
repo = "Cap-go/capgo.app"
|
||||
parent = "8c0ac7e233946abd8dc26581b871e9fcd0928899"
|
||||
commit = "4dadd2580d02213d227a331eee0232aa59859b59"
|
||||
path = "supabase/functions/_backend/utils/hono.ts"
|
||||
mode = "hunk"
|
||||
language = "typescript"
|
||||
relpath = "supabase/functions/_backend/utils/hono.ts"
|
||||
license = "AGPL-3.0"
|
||||
cve = ""
|
||||
year = 2026
|
||||
cwe = "CWE-16"
|
||||
class = "permissive default"
|
||||
mechanism = "permissive_default"
|
||||
provenance = "agent"
|
||||
origin = "github-agent-trailer"
|
||||
project = "capgo.app"
|
||||
trailer = "Co-authored-by: Cursor <[email protected]>"
|
||||
reviewer = "pending"
|
||||
evidence = "fix(api): CORS for Capacitor localhost WebView (#3105)"
|
||||
commit_url = "https://github.com/Cap-go/capgo.app/commit/4dadd2580d02213d227a331eee0232aa59859b59"
|
||||
split = "holdout"
|
||||
|
||||
[[recipe]]
|
||||
name = "dailyforge-server-ed1470"
|
||||
host = "github"
|
||||
repo = "Annamdevula-Nissi-Grace/Dailyforge"
|
||||
parent = "adc164d6e87ff735a3ea5637a2febfd3217e168a"
|
||||
commit = "ed1470814a108bd725c8b27bd9d86cf95a979a96"
|
||||
path = "backend/src/server.js"
|
||||
mode = "hunk"
|
||||
language = "javascript"
|
||||
relpath = "backend/src/server.js"
|
||||
license = "MIT"
|
||||
cve = ""
|
||||
year = 2026
|
||||
cwe = "CWE-16"
|
||||
class = "permissive default"
|
||||
mechanism = "permissive_default"
|
||||
provenance = "agent"
|
||||
origin = "github-agent-trailer"
|
||||
project = "Dailyforge"
|
||||
trailer = "Co-authored-by: Copilot <[email protected]>"
|
||||
reviewer = "pending"
|
||||
evidence = "Fix: add localhost fallback for CORS origin (#172)"
|
||||
commit_url = "https://github.com/Annamdevula-Nissi-Grace/Dailyforge/commit/ed1470814a108bd725c8b27bd9d86cf95a979a96"
|
||||
split = "train"
|
||||
|
||||
[[recipe]]
|
||||
name = "dnf-plugin-anyrepo-config-26d19a"
|
||||
host = "github"
|
||||
repo = "jfut/dnf-plugin-anyrepo"
|
||||
parent = "33cde479d0db8f45dd89fbdcfb2bc0f1be66bd7a"
|
||||
commit = "26d19aeb8884f244e34ccfdc4f49f07055adc4d0"
|
||||
path = "dnf_plugin_anyrepo/config.py"
|
||||
mode = "hunk"
|
||||
language = "python"
|
||||
relpath = "dnf_plugin_anyrepo/config.py"
|
||||
license = "Apache-2.0"
|
||||
cve = ""
|
||||
year = 2026
|
||||
cwe = "CWE-22"
|
||||
class = "path traversal"
|
||||
mechanism = "path_join_user_input"
|
||||
provenance = "agent"
|
||||
origin = "github-agent-trailer"
|
||||
project = "dnf-plugin-anyrepo"
|
||||
trailer = "Co-authored-by: Codex <[email protected]>"
|
||||
reviewer = "pending"
|
||||
evidence = "fix(config): prevent path traversal in repository names"
|
||||
commit_url = "https://github.com/jfut/dnf-plugin-anyrepo/commit/26d19aeb8884f244e34ccfdc4f49f07055adc4d0"
|
||||
split = "holdout"
|
||||
|
||||
[[recipe]]
|
||||
name = "edutrace-page-ee7ba2"
|
||||
host = "github"
|
||||
repo = "jardimdesoftware/edutrace"
|
||||
parent = "c4dc6ddcc5492c77c8a5ad7369c87dea29c001fd"
|
||||
commit = "ee7ba25fb23ea89cc1b67549cb5e32c8ead92739"
|
||||
path = "front/src/app/editar-anamnese/page.tsx"
|
||||
mode = "hunk"
|
||||
language = "typescript"
|
||||
relpath = "front/src/app/editar-anamnese/page.tsx"
|
||||
license = "Apache-2.0"
|
||||
cve = ""
|
||||
year = 2026
|
||||
cwe = "CWE-1321"
|
||||
class = "prototype pollution"
|
||||
mechanism = "prototype_pollution"
|
||||
provenance = "agent"
|
||||
origin = "github-agent-trailer"
|
||||
project = "edutrace"
|
||||
trailer = "Co-Authored-By: Claude Fable 5 <[email protected]>"
|
||||
reviewer = "pending"
|
||||
evidence = "fix(front): impedir prototype pollution nos handlers de formulário aninhado"
|
||||
commit_url = "https://github.com/jardimdesoftware/edutrace/commit/ee7ba25fb23ea89cc1b67549cb5e32c8ead92739"
|
||||
split = "train"
|
||||
|
||||
[[recipe]]
|
||||
name = "etoj-index-605274"
|
||||
host = "github"
|
||||
repo = "Eternity-Sky/_ETOJ"
|
||||
parent = "b0c020fd9ca0204630fca8a857d6fc1b1497bd5b"
|
||||
commit = "6052743d477eeff62e32553c2790785d3f52c641"
|
||||
path = "api/src/index.ts"
|
||||
mode = "hunk"
|
||||
language = "typescript"
|
||||
relpath = "api/src/index.ts"
|
||||
license = "MIT"
|
||||
cve = ""
|
||||
year = 2026
|
||||
cwe = "CWE-16"
|
||||
class = "permissive default"
|
||||
mechanism = "permissive_default"
|
||||
provenance = "agent"
|
||||
origin = "github-agent-trailer"
|
||||
project = "_ETOJ"
|
||||
trailer = "Generated with [Devin](https://devin.ai)"
|
||||
reviewer = "pending"
|
||||
evidence = "Fix CORS: Add PATCH method to allowed methods"
|
||||
commit_url = "https://github.com/Eternity-Sky/_ETOJ/commit/6052743d477eeff62e32553c2790785d3f52c641"
|
||||
split = "holdout"
|
||||
|
||||
[[recipe]]
|
||||
name = "etude-lexical-markdown-editorconfig-c61a8b"
|
||||
host = "github"
|
||||
repo = "dayflower/etude-lexical-markdown"
|
||||
parent = "0a2184f59e79a04b1365cd49200026e8f2ffdbd5"
|
||||
commit = "c61a8bf78fe20d6ae0eab2e4b8b02004508525ed"
|
||||
path = "src/config/editorConfig.ts"
|
||||
mode = "hunk"
|
||||
language = "typescript"
|
||||
relpath = "src/config/editorConfig.ts"
|
||||
license = "MIT"
|
||||
cve = ""
|
||||
year = 2026
|
||||
cwe = "CWE-1321"
|
||||
class = "prototype pollution"
|
||||
mechanism = "prototype_pollution"
|
||||
provenance = "agent"
|
||||
origin = "github-agent-trailer"
|
||||
project = "etude-lexical-markdown"
|
||||
trailer = "Co-Authored-By: Claude <[email protected]>"
|
||||
reviewer = "pending"
|
||||
evidence = "fix: guard deepMergeInto against prototype pollution"
|
||||
commit_url = "https://github.com/dayflower/etude-lexical-markdown/commit/c61a8bf78fe20d6ae0eab2e4b8b02004508525ed"
|
||||
split = "train"
|
||||
|
||||
[[recipe]]
|
||||
name = "etude-lexical-markdown-editorconfig-db4f54"
|
||||
host = "github"
|
||||
repo = "dayflower/etude-lexical-markdown"
|
||||
parent = "1c865815d05b072f4973388c3ac66b6696d9efde"
|
||||
commit = "db4f54b1ab80ad596de6425e84f90aa781c49999"
|
||||
path = "src/config/editorConfig.ts"
|
||||
mode = "hunk"
|
||||
language = "typescript"
|
||||
relpath = "src/config/editorConfig.ts"
|
||||
license = "MIT"
|
||||
cve = ""
|
||||
year = 2026
|
||||
cwe = "CWE-1321"
|
||||
class = "prototype pollution"
|
||||
mechanism = "prototype_pollution"
|
||||
provenance = "agent"
|
||||
origin = "github-agent-trailer"
|
||||
project = "etude-lexical-markdown"
|
||||
trailer = "Co-Authored-By: Claude <[email protected]>"
|
||||
reviewer = "pending"
|
||||
evidence = "fix: make prototype pollution guard recognizable by CodeQL"
|
||||
commit_url = "https://github.com/dayflower/etude-lexical-markdown/commit/db4f54b1ab80ad596de6425e84f90aa781c49999"
|
||||
split = "holdout"
|
||||
|
||||
[[recipe]]
|
||||
name = "gitim-git-cors-proxy-e4c3a4"
|
||||
host = "github"
|
||||
repo = "CiferaTeam/GitIM"
|
||||
parent = "8afa34d45e119164abec0b76ed77a56f442749a8"
|
||||
commit = "e4c3a4794dbe9fbcce679f7df1ecd2b09b40f9d6"
|
||||
path = "products/gitim/frontend/src/lib/git-cors-proxy.ts"
|
||||
mode = "hunk"
|
||||
language = "typescript"
|
||||
relpath = "products/gitim/frontend/src/lib/git-cors-proxy.ts"
|
||||
license = "Apache-2.0"
|
||||
cve = ""
|
||||
year = 2026
|
||||
cwe = "CWE-16"
|
||||
class = "permissive default"
|
||||
mechanism = "permissive_default"
|
||||
provenance = "agent"
|
||||
origin = "github-agent-trailer"
|
||||
project = "GitIM"
|
||||
trailer = "Co-authored-by: Codex <[email protected]>"
|
||||
reviewer = "pending"
|
||||
evidence = "fix(frontend): use gitim cors proxy by default"
|
||||
commit_url = "https://github.com/CiferaTeam/GitIM/commit/e4c3a4794dbe9fbcce679f7df1ecd2b09b40f9d6"
|
||||
split = "train"
|
||||
|
||||
[[recipe]]
|
||||
name = "lensops-kubernetesmanagement-fe4910"
|
||||
host = "github"
|
||||
repo = "amitknigam84/lensops"
|
||||
parent = "9b87ecc3a44a7fe2a5185cca1fe52441647d5748"
|
||||
commit = "fe49109aedfe21dea4d24d4d9f2fa3f1ecfb6c84"
|
||||
path = "components/KubernetesManagement.tsx"
|
||||
mode = "hunk"
|
||||
language = "typescript"
|
||||
relpath = "components/KubernetesManagement.tsx"
|
||||
license = "MIT"
|
||||
cve = ""
|
||||
year = 2026
|
||||
cwe = "CWE-862"
|
||||
class = "missing authorization"
|
||||
mechanism = "missing_auth_guard"
|
||||
provenance = "agent"
|
||||
origin = "github-agent-trailer"
|
||||
project = "lensops"
|
||||
trailer = "Co-Authored-By: Claude Sonnet 4.6 <[email protected]>"
|
||||
reviewer = "pending"
|
||||
evidence = "Fix missing auth header on namespaces API call"
|
||||
commit_url = "https://github.com/amitknigam84/lensops/commit/fe49109aedfe21dea4d24d4d9f2fa3f1ecfb6c84"
|
||||
split = "holdout"
|
||||
|
||||
[[recipe]]
|
||||
name = "market-cap-route-4f8ae9"
|
||||
host = "github"
|
||||
repo = "navaneethbv/market-cap"
|
||||
parent = "fec6f024ce72c9c47b61cbac6ce7a35cb2280602"
|
||||
commit = "4f8ae9be5519ced5a975f1190e3e4bc43f84e4d6"
|
||||
path = "app/auth/confirm/route.ts"
|
||||
mode = "hunk"
|
||||
language = "typescript"
|
||||
relpath = "app/auth/confirm/route.ts"
|
||||
license = "MIT"
|
||||
cve = ""
|
||||
year = 2026
|
||||
cwe = "CWE-601"
|
||||
class = "open redirect"
|
||||
mechanism = "source_reaches_sink"
|
||||
provenance = "agent"
|
||||
origin = "github-agent-trailer"
|
||||
project = "market-cap"
|
||||
trailer = "Co-Authored-By: Claude Fable 5 <[email protected]>"
|
||||
reviewer = "pending"
|
||||
evidence = "Fix open redirects on the auth next param"
|
||||
commit_url = "https://github.com/navaneethbv/market-cap/commit/4f8ae9be5519ced5a975f1190e3e4bc43f84e4d6"
|
||||
split = "train"
|
||||
|
||||
[[recipe]]
|
||||
name = "melodix-playerprovider-089931"
|
||||
host = "github"
|
||||
repo = "alexshao3/melodix"
|
||||
parent = "c074fc7413338aefcbea3170ef4d3ba486a8a4b7"
|
||||
commit = "089931ef71ea1e5b7586520baf1a5498e2f05b13"
|
||||
path = "apps/miniapp/src/components/PlayerProvider.tsx"
|
||||
mode = "hunk"
|
||||
language = "typescript"
|
||||
relpath = "apps/miniapp/src/components/PlayerProvider.tsx"
|
||||
license = "MIT"
|
||||
cve = ""
|
||||
year = 2026
|
||||
cwe = "CWE-16"
|
||||
class = "permissive default"
|
||||
mechanism = "permissive_default"
|
||||
provenance = "agent"
|
||||
origin = "github-agent-trailer"
|
||||
project = "melodix"
|
||||
trailer = "Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>"
|
||||
reviewer = "pending"
|
||||
evidence = "Merge pull request #17 from alexshao3/devin/1777216143-fix-audio-cors"
|
||||
commit_url = "https://github.com/alexshao3/melodix/commit/089931ef71ea1e5b7586520baf1a5498e2f05b13"
|
||||
split = "holdout"
|
||||
|
||||
[[recipe]]
|
||||
name = "mercado-do-vale-news-catalogmetadataservice-9b5fcf"
|
||||
host = "github"
|
||||
repo = "handielson/Mercado-do-vale-news"
|
||||
parent = "70ca282b819ac1d60f4b5e665d224b1043ff1ccc"
|
||||
commit = "9b5fcf2dae41e56f5f97952266f2d6ba59598598"
|
||||
path = "services/catalogMetadataService.ts"
|
||||
mode = "hunk"
|
||||
language = "typescript"
|
||||
relpath = "services/catalogMetadataService.ts"
|
||||
license = "MIT"
|
||||
cve = ""
|
||||
year = 2026
|
||||
cwe = "CWE-16"
|
||||
class = "permissive default"
|
||||
mechanism = "permissive_default"
|
||||
provenance = "agent"
|
||||
origin = "github-agent-trailer"
|
||||
project = "Mercado-do-vale-news"
|
||||
trailer = "Co-Authored-By: Codex <[email protected]>"
|
||||
reviewer = "pending"
|
||||
evidence = "fix(catalog): avoid metadata cors preflight"
|
||||
commit_url = "https://github.com/handielson/Mercado-do-vale-news/commit/9b5fcf2dae41e56f5f97952266f2d6ba59598598"
|
||||
split = "train"
|
||||
|
||||
[[recipe]]
|
||||
name = "money-track-category-icons-4d4a5b"
|
||||
host = "github"
|
||||
repo = "andrebubniak/money-track"
|
||||
parent = "add96df6d6a6b61506635c23dbacf6c6cfe24dc2"
|
||||
commit = "4d4a5b063278c8b6697c3faae133d7c39fcd01c0"
|
||||
path = "src/lib/category-icons.ts"
|
||||
mode = "hunk"
|
||||
language = "typescript"
|
||||
relpath = "src/lib/category-icons.ts"
|
||||
license = "MIT"
|
||||
cve = ""
|
||||
year = 2026
|
||||
cwe = "CWE-1321"
|
||||
class = "prototype pollution"
|
||||
mechanism = "prototype_pollution"
|
||||
provenance = "agent"
|
||||
origin = "github-agent-trailer"
|
||||
project = "money-track"
|
||||
trailer = "Co-Authored-By: Claude Sonnet 5 <[email protected]>"
|
||||
reviewer = "pending"
|
||||
evidence = "fix(category-icons): use Object.hasOwn to prevent prototype pollution in type guard"
|
||||
commit_url = "https://github.com/andrebubniak/money-track/commit/4d4a5b063278c8b6697c3faae133d7c39fcd01c0"
|
||||
split = "holdout"
|
||||
|
||||
[[recipe]]
|
||||
name = "nestjs-filter-normalizer-aa0e60"
|
||||
host = "github"
|
||||
repo = "DavideCarvalho/nestjs-filter"
|
||||
parent = "d899b40d3466f2ffbe9f01c4d49267412401f078"
|
||||
commit = "aa0e600d05997ea3d77538ea1c2db427c439f2e8"
|
||||
path = "packages/core/src/input/normalizer.ts"
|
||||
mode = "hunk"
|
||||
language = "typescript"
|
||||
relpath = "packages/core/src/input/normalizer.ts"
|
||||
license = "MIT"
|
||||
cve = ""
|
||||
year = 2026
|
||||
cwe = "CWE-1321"
|
||||
class = "prototype pollution"
|
||||
mechanism = "prototype_pollution"
|
||||
provenance = "agent"
|
||||
origin = "github-agent-trailer"
|
||||
project = "nestjs-filter"
|
||||
trailer = "Co-Authored-By: Claude Opus 4.7 <[email protected]>"
|
||||
reviewer = "pending"
|
||||
evidence = "fix(core): add prototype pollution guard to normalizeInput"
|
||||
commit_url = "https://github.com/DavideCarvalho/nestjs-filter/commit/aa0e600d05997ea3d77538ea1c2db427c439f2e8"
|
||||
split = "train"
|
||||
|
||||
[[recipe]]
|
||||
name = "new-erp-final-app-6e9644"
|
||||
host = "github"
|
||||
repo = "Sachin-Salgar/NEW_ERP_FINAL"
|
||||
parent = "08976c5d7a07b0663669b875b4507446199f85d7"
|
||||
commit = "6e9644c81ce3fb356669157182a5ef09a70c4b59"
|
||||
path = "src/presentation/http/app.ts"
|
||||
mode = "hunk"
|
||||
language = "typescript"
|
||||
relpath = "src/presentation/http/app.ts"
|
||||
license = "Apache-2.0"
|
||||
cve = ""
|
||||
year = 2026
|
||||
cwe = "CWE-16"
|
||||
class = "permissive default"
|
||||
mechanism = "permissive_default"
|
||||
provenance = "agent"
|
||||
origin = "github-agent-trailer"
|
||||
project = "NEW_ERP_FINAL"
|
||||
trailer = "Co-authored-by: Copilot <[email protected]>"
|
||||
reviewer = "pending"
|
||||
evidence = "fix: allow patch requests through cors"
|
||||
commit_url = "https://github.com/Sachin-Salgar/NEW_ERP_FINAL/commit/6e9644c81ce3fb356669157182a5ef09a70c4b59"
|
||||
split = "holdout"
|
||||
|
||||
[[recipe]]
|
||||
name = "nimestream-route-d17f53"
|
||||
host = "github"
|
||||
repo = "Irnhakim/nimestream"
|
||||
parent = "0c37bfd9e5292b15b1d7af51f52793d9bdf1cef0"
|
||||
commit = "d17f535bf3012041b056ff3aa991ff6cfa198e43"
|
||||
path = "app/api/img/route.js"
|
||||
mode = "hunk"
|
||||
language = "javascript"
|
||||
relpath = "app/api/img/route.js"
|
||||
license = "MIT"
|
||||
cve = ""
|
||||
year = 2026
|
||||
cwe = "CWE-918"
|
||||
class = "server-side request forgery"
|
||||
mechanism = "source_reaches_sink"
|
||||
provenance = "agent"
|
||||
origin = "github-agent-trailer"
|
||||
project = "nimestream"
|
||||
trailer = "Co-Authored-By: Claude <[email protected]>"
|
||||
reviewer = "pending"
|
||||
evidence = "fix: resolve command injection and SSRF/Open Redirect security issues in multiScraper and image proxy API"
|
||||
commit_url = "https://github.com/Irnhakim/nimestream/commit/d17f535bf3012041b056ff3aa991ff6cfa198e43"
|
||||
split = "train"
|
||||
|
||||
[[recipe]]
|
||||
name = "onlook-helper-57ce1c"
|
||||
host = "github"
|
||||
repo = "zhcndoc/onlook"
|
||||
parent = "cb97e012729eca441e09b1503282cb4bc2f4bcfb"
|
||||
commit = "57ce1ccfacc7e8484cae59013a2b1e34518560e5"
|
||||
path = "apps/web/client/src/server/api/routers/project/helper.ts"
|
||||
mode = "hunk"
|
||||
language = "typescript"
|
||||
relpath = "apps/web/client/src/server/api/routers/project/helper.ts"
|
||||
license = "Apache-2.0"
|
||||
cve = ""
|
||||
year = 2025
|
||||
cwe = "CWE-862"
|
||||
class = "missing authorization"
|
||||
mechanism = "missing_auth_guard"
|
||||
provenance = "agent"
|
||||
origin = "github-agent-trailer"
|
||||
project = "onlook"
|
||||
trailer = "Co-Authored-By: Claude <[email protected]>"
|
||||
reviewer = "pending"
|
||||
evidence = "Fix CVE-2025-63783: Add authorization checks to project mutation APIs (#3062)"
|
||||
commit_url = "https://github.com/zhcndoc/onlook/commit/57ce1ccfacc7e8484cae59013a2b1e34518560e5"
|
||||
split = "holdout"
|
||||
|
||||
[[recipe]]
|
||||
name = "openniw-jobs-0fc947"
|
||||
host = "github"
|
||||
repo = "HHHHHejia/openniw"
|
||||
parent = "4d91ed82fa9a5ec6bf5ef96da1d221fc187700dc"
|
||||
commit = "0fc94733f6ca3c6b129a0a8e6d7b3acce19d5a10"
|
||||
path = "backend/app/routers/jobs.py"
|
||||
mode = "hunk"
|
||||
language = "python"
|
||||
relpath = "backend/app/routers/jobs.py"
|
||||
license = "MIT"
|
||||
cve = ""
|
||||
year = 2026
|
||||
cwe = "CWE-639"
|
||||
class = "insecure direct object reference"
|
||||
mechanism = "identity_from_request_body"
|
||||
provenance = "agent"
|
||||
origin = "github-agent-trailer"
|
||||
project = "openniw"
|
||||
trailer = "Co-Authored-By: Claude Fable 5 <[email protected]>"
|
||||
reviewer = "pending"
|
||||
evidence = "Fix IDOR on job endpoint: case-bound jobs require case ownership"
|
||||
commit_url = "https://github.com/HHHHHejia/openniw/commit/0fc94733f6ca3c6b129a0a8e6d7b3acce19d5a10"
|
||||
split = "train"
|
||||
|
||||
[[recipe]]
|
||||
name = "openniw-jobs-b74de3"
|
||||
host = "github"
|
||||
repo = "ziyuzuo/openniw"
|
||||
parent = "98a0c392ba96cd2c4aa746dd6fc2b183f385225e"
|
||||
commit = "b74de31b0a5f37e4e929ba6aa74dbe0f5e6d9a68"
|
||||
path = "backend/app/routers/jobs.py"
|
||||
mode = "hunk"
|
||||
language = "python"
|
||||
relpath = "backend/app/routers/jobs.py"
|
||||
license = "MIT"
|
||||
cve = ""
|
||||
year = 2026
|
||||
cwe = "CWE-639"
|
||||
class = "insecure direct object reference"
|
||||
mechanism = "identity_from_request_body"
|
||||
provenance = "agent"
|
||||
origin = "github-agent-trailer"
|
||||
project = "openniw"
|
||||
trailer = "Co-Authored-By: Claude Fable 5 <[email protected]>"
|
||||
reviewer = "pending"
|
||||
evidence = "Fix IDOR on job endpoint: case-bound jobs require case ownership"
|
||||
commit_url = "https://github.com/ziyuzuo/openniw/commit/b74de31b0a5f37e4e929ba6aa74dbe0f5e6d9a68"
|
||||
split = "holdout"
|
||||
|
||||
[[recipe]]
|
||||
name = "overleaf-with-claude-exportscontroller-3980b9"
|
||||
host = "github"
|
||||
repo = "ZUENS2020/overleaf-with-claude"
|
||||
parent = "5a886aa9fb9fe4e2203f3cb1d62c91f4be0525ed"
|
||||
commit = "3980b9e5806defb63e45ae2696e6c1899f3a8431"
|
||||
path = "services/web/app/src/Features/Exports/ExportsController.mjs"
|
||||
mode = "hunk"
|
||||
language = "javascript"
|
||||
relpath = "services/web/app/src/Features/Exports/ExportsController.mjs"
|
||||
license = "AGPL-3.0"
|
||||
cve = ""
|
||||
year = 2026
|
||||
cwe = "CWE-639"
|
||||
class = "insecure direct object reference"
|
||||
mechanism = "identity_from_request_body"
|
||||
provenance = "agent"
|
||||
origin = "github-agent-trailer"
|
||||
project = "overleaf-with-claude"
|
||||
trailer = "Co-authored-by: briangough <[email protected]>"
|
||||
reviewer = "pending"
|
||||
evidence = "Fix IDOR in exports by adding token verification (Issue #31637) (#32883)"
|
||||
commit_url = "https://github.com/ZUENS2020/overleaf-with-claude/commit/3980b9e5806defb63e45ae2696e6c1899f3a8431"
|
||||
split = "train"
|
||||
|
||||
[[recipe]]
|
||||
name = "popmark-editorconfig-e5ac40"
|
||||
host = "github"
|
||||
repo = "dayflower/popmark"
|
||||
parent = "31d1ac79b4cfa3118597348e79800a6561115149"
|
||||
commit = "e5ac407cef37c37178d440541ede301c838640fb"
|
||||
path = "src/lexical-markdown/config/editorConfig.ts"
|
||||
mode = "hunk"
|
||||
language = "typescript"
|
||||
relpath = "src/lexical-markdown/config/editorConfig.ts"
|
||||
license = "MIT"
|
||||
cve = ""
|
||||
year = 2026
|
||||
cwe = "CWE-1321"
|
||||
class = "prototype pollution"
|
||||
mechanism = "prototype_pollution"
|
||||
provenance = "agent"
|
||||
origin = "github-agent-trailer"
|
||||
project = "popmark"
|
||||
trailer = "Co-Authored-By: Claude <[email protected]>"
|
||||
reviewer = "pending"
|
||||
evidence = "fix: guard deepMergeInto against prototype pollution"
|
||||
commit_url = "https://github.com/dayflower/popmark/commit/e5ac407cef37c37178d440541ede301c838640fb"
|
||||
split = "holdout"
|
||||
|
||||
[[recipe]]
|
||||
name = "rag-pipeline-utils-config-handler-76e5f0"
|
||||
host = "github"
|
||||
repo = "DevilsDev/rag-pipeline-utils"
|
||||
parent = "ba587867118f703632ff2dc63c4feb8ad6793420"
|
||||
commit = "76e5f0a94d6803d0e463d26a61cedb7da90857a7"
|
||||
path = "src/cli/handlers/config-handler.js"
|
||||
mode = "hunk"
|
||||
language = "javascript"
|
||||
relpath = "src/cli/handlers/config-handler.js"
|
||||
license = "MIT"
|
||||
cve = ""
|
||||
year = 2026
|
||||
cwe = "CWE-1321"
|
||||
class = "prototype pollution"
|
||||
mechanism = "prototype_pollution"
|
||||
provenance = "agent"
|
||||
origin = "github-agent-trailer"
|
||||
project = "rag-pipeline-utils"
|
||||
trailer = "Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>"
|
||||
reviewer = "pending"
|
||||
evidence = "fix(security): prevent prototype pollution in config-handler"
|
||||
commit_url = "https://github.com/DevilsDev/rag-pipeline-utils/commit/76e5f0a94d6803d0e463d26a61cedb7da90857a7"
|
||||
split = "train"
|
||||
|
||||
[[recipe]]
|
||||
name = "registry-proxy-worker-426847"
|
||||
host = "github"
|
||||
repo = "agents-repo/registry-proxy"
|
||||
parent = "6d5937972510cdb5ebca30607b538fdc2e280094"
|
||||
commit = "426847899eb2ee94ae4e5a3aacc50423e36d2dc8"
|
||||
path = "src/worker.js"
|
||||
mode = "hunk"
|
||||
language = "javascript"
|
||||
relpath = "src/worker.js"
|
||||
license = "MIT"
|
||||
cve = ""
|
||||
year = 2026
|
||||
cwe = "CWE-16"
|
||||
class = "permissive default"
|
||||
mechanism = "permissive_default"
|
||||
provenance = "agent"
|
||||
origin = "github-agent-trailer"
|
||||
project = "registry-proxy"
|
||||
trailer = "Co-authored-by: Cursor <[email protected]>"
|
||||
reviewer = "pending"
|
||||
evidence = "fix: handle CORS OPTIONS preflight for catalog fetches (#10)"
|
||||
commit_url = "https://github.com/agents-repo/registry-proxy/commit/426847899eb2ee94ae4e5a3aacc50423e36d2dc8"
|
||||
split = "holdout"
|
||||
|
||||
[[recipe]]
|
||||
name = "rls-alembic-rls-d2b6af"
|
||||
host = "github"
|
||||
repo = "DelfinaCare/rls"
|
||||
parent = "670123485f1c657e9faeb18e633339b6a79e696f"
|
||||
commit = "d2b6af47347fb285b7a3820a7f2d5dded20907ec"
|
||||
path = "rls/alembic_rls.py"
|
||||
mode = "hunk"
|
||||
language = "python"
|
||||
relpath = "rls/alembic_rls.py"
|
||||
license = "MIT"
|
||||
cve = ""
|
||||
year = 2026
|
||||
cwe = "CWE-16"
|
||||
class = "permissive default"
|
||||
mechanism = "permissive_default"
|
||||
provenance = "agent"
|
||||
origin = "github-agent-trailer"
|
||||
project = "rls"
|
||||
trailer = "Co-authored-by: aebrahim <[email protected]>"
|
||||
reviewer = "pending"
|
||||
evidence = "Guard against ENABLE ROW LEVEL SECURITY on tables with no policies (#143)"
|
||||
commit_url = "https://github.com/DelfinaCare/rls/commit/d2b6af47347fb285b7a3820a7f2d5dded20907ec"
|
||||
split = "train"
|
||||
|
||||
[[recipe]]
|
||||
name = "supplieradvisor-mvp-route-387bcf"
|
||||
host = "github"
|
||||
repo = "bigfivefoods/supplieradvisor-mvp"
|
||||
parent = "a7a9bc260d649ea2e582c07435bfd7d93100647b"
|
||||
commit = "387bcf40e984a2ee1832ab7beabf0284c5b627d8"
|
||||
path = "app/api/customers/claims/route.ts"
|
||||
mode = "hunk"
|
||||
language = "typescript"
|
||||
relpath = "app/api/customers/claims/route.ts"
|
||||
license = "MIT"
|
||||
cve = ""
|
||||
year = 2026
|
||||
cwe = "CWE-639"
|
||||
class = "insecure direct object reference"
|
||||
mechanism = "identity_from_request_body"
|
||||
provenance = "agent"
|
||||
origin = "github-agent-trailer"
|
||||
project = "supplieradvisor-mvp"
|
||||
trailer = "Co-authored-by: bigfivefoods <[email protected]>"
|
||||
reviewer = "pending"
|
||||
evidence = "Brief 62: Fix IDOR on customer_claims PATCH/DELETE (#156)"
|
||||
commit_url = "https://github.com/bigfivefoods/supplieradvisor-mvp/commit/387bcf40e984a2ee1832ab7beabf0284c5b627d8"
|
||||
split = "holdout"
|
||||
|
||||
[[recipe]]
|
||||
name = "supplieradvisor-mvp-route-a69e8f"
|
||||
host = "github"
|
||||
repo = "bigfivefoods/supplieradvisor-mvp"
|
||||
parent = "8558538471e4fb10856f8d9a17d2be5ab5c4fb9c"
|
||||
commit = "a69e8f27c0f4d402573d16f0612b51155bbc46e1"
|
||||
path = "app/api/customers/opportunities/route.ts"
|
||||
mode = "hunk"
|
||||
language = "typescript"
|
||||
relpath = "app/api/customers/opportunities/route.ts"
|
||||
license = "MIT"
|
||||
cve = ""
|
||||
year = 2026
|
||||
cwe = "CWE-639"
|
||||
class = "insecure direct object reference"
|
||||
mechanism = "identity_from_request_body"
|
||||
provenance = "agent"
|
||||
origin = "github-agent-trailer"
|
||||
project = "supplieradvisor-mvp"
|
||||
trailer = "Co-authored-by: bigfivefoods <[email protected]>"
|
||||
reviewer = "pending"
|
||||
evidence = "Brief 60: Fix IDOR on opportunities GET/PATCH/DELETE (missing company membership checks) (#148)"
|
||||
commit_url = "https://github.com/bigfivefoods/supplieradvisor-mvp/commit/a69e8f27c0f4d402573d16f0612b51155bbc46e1"
|
||||
split = "train"
|
||||
|
||||
[[recipe]]
|
||||
name = "tools-cli-tools-a96bc0"
|
||||
host = "github"
|
||||
repo = "D-sorganization/Tools"
|
||||
parent = "e735d28b82dd1fbc42c0ae01157b38d1b4c7c864"
|
||||
commit = "a96bc0502a3dcdac303e4f0152508886e5c35c0a"
|
||||
path = "src/shared/python/ai/tools/cli_tools.py"
|
||||
mode = "hunk"
|
||||
language = "python"
|
||||
relpath = "src/shared/python/ai/tools/cli_tools.py"
|
||||
license = "MIT"
|
||||
cve = ""
|
||||
year = 2026
|
||||
cwe = "CWE-78"
|
||||
class = "command injection"
|
||||
mechanism = "source_reaches_sink"
|
||||
provenance = "agent"
|
||||
origin = "github-agent-trailer"
|
||||
project = "Tools"
|
||||
trailer = "Co-authored-by: dieterolson <[email protected]>"
|
||||
reviewer = "pending"
|
||||
evidence = "🛡️ Sentinel: [CRITICAL] Fix command injection in ShellTool (#3307)"
|
||||
commit_url = "https://github.com/D-sorganization/Tools/commit/a96bc0502a3dcdac303e4f0152508886e5c35c0a"
|
||||
split = "holdout"
|
||||
|
||||
[[recipe]]
|
||||
name = "tools-wsgi-e18686"
|
||||
host = "github"
|
||||
repo = "D-sorganization/Tools"
|
||||
parent = "f34c44a0842ac983e2a984fe7fd985be3ccaf747"
|
||||
commit = "e18686aaa174a8a4843c07b4727771c92e0f179e"
|
||||
path = "src/web_applications/unit_converter/wsgi.py"
|
||||
mode = "hunk"
|
||||
language = "python"
|
||||
relpath = "src/web_applications/unit_converter/wsgi.py"
|
||||
license = "MIT"
|
||||
cve = ""
|
||||
year = 2026
|
||||
cwe = "CWE-22"
|
||||
class = "path traversal"
|
||||
mechanism = "path_join_user_input"
|
||||
provenance = "agent"
|
||||
origin = "github-agent-trailer"
|
||||
project = "Tools"
|
||||
trailer = "Co-Authored-By: Claude Sonnet 4.6 <[email protected]>"
|
||||
reviewer = "pending"
|
||||
evidence = "fix(security): validate mesh filenames against path traversal in _download_meshes (#2077) (#2107)"
|
||||
commit_url = "https://github.com/D-sorganization/Tools/commit/e18686aaa174a8a4843c07b4727771c92e0f179e"
|
||||
split = "train"
|
||||
|
||||
[[recipe]]
|
||||
name = "trackly-cli-path-diagnostics-1c1aed"
|
||||
host = "github"
|
||||
repo = "trackly-app/trackly-cli"
|
||||
parent = "8d240ad8d7fc114c8f941ad956a2fdf32391ff60"
|
||||
commit = "1c1aed89b07edb04051830c8f086e02b65e961c6"
|
||||
path = "lib/path-diagnostics.js"
|
||||
mode = "hunk"
|
||||
language = "javascript"
|
||||
relpath = "lib/path-diagnostics.js"
|
||||
license = "MIT"
|
||||
cve = ""
|
||||
year = 2026
|
||||
cwe = "CWE-22"
|
||||
class = "path traversal"
|
||||
mechanism = "path_join_user_input"
|
||||
provenance = "agent"
|
||||
origin = "github-agent-trailer"
|
||||
project = "trackly-cli"
|
||||
trailer = "Co-authored-by: Codex <[email protected]>"
|
||||
reviewer = "pending"
|
||||
evidence = "fix(apply): report blocked path traversal"
|
||||
commit_url = "https://github.com/trackly-app/trackly-cli/commit/1c1aed89b07edb04051830c8f086e02b65e961c6"
|
||||
split = "holdout"
|
||||
|
||||
[[recipe]]
|
||||
name = "upstreamdrift-local-server-c3a078"
|
||||
host = "github"
|
||||
repo = "D-sorganization/UpstreamDrift"
|
||||
parent = "e28d1da5e103d93951ef11b78a6e9b89ac1fa2bc"
|
||||
commit = "c3a0787080489b30e2ed0abfac03b51e45da184b"
|
||||
path = "src/api/local_server.py"
|
||||
mode = "hunk"
|
||||
language = "python"
|
||||
relpath = "src/api/local_server.py"
|
||||
license = "MIT"
|
||||
cve = ""
|
||||
year = 2026
|
||||
cwe = "CWE-22"
|
||||
class = "path traversal"
|
||||
mechanism = "path_join_user_input"
|
||||
provenance = "agent"
|
||||
origin = "github-agent-trailer"
|
||||
project = "UpstreamDrift"
|
||||
trailer = "Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>"
|
||||
reviewer = "pending"
|
||||
evidence = "fix(api): harden local server path traversal (#2805) (#2839)"
|
||||
commit_url = "https://github.com/D-sorganization/UpstreamDrift/commit/c3a0787080489b30e2ed0abfac03b51e45da184b"
|
||||
split = "train"
|
||||
|
||||
[[recipe]]
|
||||
name = "vantalk-firebase-16c3b0"
|
||||
host = "github"
|
||||
repo = "NiSeullent/VanTalk"
|
||||
parent = "7d442bdf537df96c756d47cfc6ce0ccdb3cd8ea7"
|
||||
commit = "16c3b02875b1f51c3cac1dc185e199978a35985c"
|
||||
path = "web/src/firebase.ts"
|
||||
mode = "hunk"
|
||||
language = "typescript"
|
||||
relpath = "web/src/firebase.ts"
|
||||
license = "MIT"
|
||||
cve = ""
|
||||
year = 2026
|
||||
cwe = "CWE-798"
|
||||
class = "hardcoded credentials"
|
||||
mechanism = "secret_in_client"
|
||||
provenance = "agent"
|
||||
origin = "github-agent-trailer"
|
||||
project = "VanTalk"
|
||||
trailer = "Co-authored-by: Cursor <[email protected]>"
|
||||
reviewer = "pending"
|
||||
evidence = "fix(security): load Firebase API key from env, remove hardcoded secret"
|
||||
commit_url = "https://github.com/NiSeullent/VanTalk/commit/16c3b02875b1f51c3cac1dc185e199978a35985c"
|
||||
split = "holdout"
|
||||
|
||||
[[recipe]]
|
||||
name = "waggledance-swarm-ssrf-host-guard-9a4548"
|
||||
host = "github"
|
||||
repo = "Ahkeratmehilaiset/waggledance-swarm"
|
||||
parent = "934b939f1cca5259eaf807db3319eb97b90d8d80"
|
||||
commit = "9a454843aa35332ff2eb3106023eee0c4b5e444b"
|
||||
path = "waggledance/core/v3_13_0/ssrf_host_guard.py"
|
||||
mode = "hunk"
|
||||
language = "python"
|
||||
relpath = "waggledance/core/v3_13_0/ssrf_host_guard.py"
|
||||
license = "Apache-2.0"
|
||||
cve = ""
|
||||
year = 2026
|
||||
cwe = "CWE-918"
|
||||
class = "server-side request forgery"
|
||||
mechanism = "source_reaches_sink"
|
||||
provenance = "agent"
|
||||
origin = "github-agent-trailer"
|
||||
project = "waggledance-swarm"
|
||||
trailer = "Co-authored-by: codex-lead-1 <[email protected]>"
|
||||
reviewer = "pending"
|
||||
evidence = "fix(ssrf): reject bare-string allowed hosts (#1460)"
|
||||
commit_url = "https://github.com/Ahkeratmehilaiset/waggledance-swarm/commit/9a454843aa35332ff2eb3106023eee0c4b5e444b"
|
||||
split = "train"
|
||||
|
||||
[[recipe]]
|
||||
name = "workers-research-utils-209444"
|
||||
host = "github"
|
||||
repo = "G4brym/workers-research"
|
||||
parent = "eab923ad3099c01b002fbd6be7cf994614bbdee4"
|
||||
commit = "209444eb61cc564c2d6b43267256f85fe3e5e30e"
|
||||
path = "src/utils.ts"
|
||||
mode = "hunk"
|
||||
language = "typescript"
|
||||
relpath = "src/utils.ts"
|
||||
license = "MIT"
|
||||
cve = ""
|
||||
year = 2026
|
||||
cwe = "CWE-89"
|
||||
class = "sql injection"
|
||||
mechanism = "source_reaches_sink"
|
||||
provenance = "agent"
|
||||
origin = "github-agent-trailer"
|
||||
project = "workers-research"
|
||||
trailer = "Co-Authored-By: Claude Opus 4.6 <[email protected]>"
|
||||
reviewer = "pending"
|
||||
evidence = "Fix SQL injection in search by using parameterized queries (#41)"
|
||||
commit_url = "https://github.com/G4brym/workers-research/commit/209444eb61cc564c2d6b43267256f85fe3e5e30e"
|
||||
split = "holdout"
|
||||
|
||||
[[recipe]]
|
||||
name = "zoonk-origin-bfbf67"
|
||||
host = "github"
|
||||
repo = "zoonk/zoonk"
|
||||
parent = "2604269350bff51f58572c133b45010cb0976a5a"
|
||||
commit = "bfbf670ccb41d63c407d32c51bd26e626a174f31"
|
||||
path = "packages/utils/src/origin.ts"
|
||||
mode = "hunk"
|
||||
language = "typescript"
|
||||
relpath = "packages/utils/src/origin.ts"
|
||||
license = "MIT"
|
||||
cve = ""
|
||||
year = 2026
|
||||
cwe = "CWE-16"
|
||||
class = "permissive default"
|
||||
mechanism = "permissive_default"
|
||||
provenance = "agent"
|
||||
origin = "github-agent-trailer"
|
||||
project = "zoonk"
|
||||
trailer = "Co-authored-by: Codex <[email protected]>"
|
||||
reviewer = "pending"
|
||||
evidence = "fix(api): allow staging cors from previews (#1559)"
|
||||
commit_url = "https://github.com/zoonk/zoonk/commit/bfbf670ccb41d63c407d32c51bd26e626a174f31"
|
||||
split = "train"
|
||||
@@ -0,0 +1,43 @@
|
||||
// Provenance: agents-repo/registry-proxy (fixed).
|
||||
// repo: agents-repo/registry-proxy
|
||||
// commit: 426847899eb2ee94ae4e5a3aacc50423e36d2dc8
|
||||
// parent: 6d5937972510cdb5ebca30607b538fdc2e280094
|
||||
// commit_url: https://github.com/agents-repo/registry-proxy/commit/426847899eb2ee94ae4e5a3aacc50423e36d2dc8
|
||||
// cve:
|
||||
// license: MIT
|
||||
// function: buildUpstreamRequest
|
||||
// relpath: src/worker.js
|
||||
// provenance: agent
|
||||
// mechanism: permissive_default
|
||||
|
||||
function buildUpstreamRequest(target, env, requestHeaders) {
|
||||
const headers = new Headers();
|
||||
const requestAccept = requestHeaders.get("Accept") || "*/*";
|
||||
headers.set("User-Agent", UPSTREAM_USER_AGENT);
|
||||
|
||||
const ifNoneMatch = requestHeaders.get("If-None-Match");
|
||||
if (ifNoneMatch) {
|
||||
headers.set("If-None-Match", ifNoneMatch);
|
||||
}
|
||||
|
||||
const ifModifiedSince = requestHeaders.get("If-Modified-Since");
|
||||
if (ifModifiedSince) {
|
||||
headers.set("If-Modified-Since", ifModifiedSince);
|
||||
}
|
||||
|
||||
if (env.GITHUB_TOKEN) {
|
||||
headers.set("Accept", "application/vnd.github.raw");
|
||||
headers.set("Authorization", `Bearer ${env.GITHUB_TOKEN}`);
|
||||
return {
|
||||
url: buildContentsApiUrl(target.ref, target.targetPath),
|
||||
headers,
|
||||
};
|
||||
}
|
||||
|
||||
headers.set("Accept", requestAccept);
|
||||
|
||||
return {
|
||||
url: buildUpstreamUrl(target.ref, target.targetPath),
|
||||
headers,
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
// Provenance: agents-repo/registry-proxy (vuln).
|
||||
// repo: agents-repo/registry-proxy
|
||||
// commit: 6d5937972510cdb5ebca30607b538fdc2e280094
|
||||
// parent: 6d5937972510cdb5ebca30607b538fdc2e280094
|
||||
// commit_url: https://github.com/agents-repo/registry-proxy/commit/426847899eb2ee94ae4e5a3aacc50423e36d2dc8
|
||||
// cve:
|
||||
// license: MIT
|
||||
// function: buildUpstreamRequest
|
||||
// relpath: src/worker.js
|
||||
// provenance: agent
|
||||
// mechanism: permissive_default
|
||||
|
||||
function buildUpstreamRequest(target, env, requestHeaders) {
|
||||
const headers = new Headers();
|
||||
const requestAccept = requestHeaders.get("Accept") || "*/*";
|
||||
headers.set("User-Agent", UPSTREAM_USER_AGENT);
|
||||
|
||||
if (env.GITHUB_TOKEN) {
|
||||
headers.set("Accept", "application/vnd.github.raw");
|
||||
headers.set("Authorization", `Bearer ${env.GITHUB_TOKEN}`);
|
||||
return {
|
||||
url: buildContentsApiUrl(target.ref, target.targetPath),
|
||||
headers,
|
||||
};
|
||||
}
|
||||
|
||||
headers.set("Accept", requestAccept);
|
||||
|
||||
return {
|
||||
url: buildUpstreamUrl(target.ref, target.targetPath),
|
||||
headers,
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
// Provenance: bigfivefoods/supplieradvisor-mvp (fixed).
|
||||
// repo: bigfivefoods/supplieradvisor-mvp
|
||||
// commit: 387bcf40e984a2ee1832ab7beabf0284c5b627d8
|
||||
// parent: a7a9bc260d649ea2e582c07435bfd7d93100647b
|
||||
// commit_url: https://github.com/bigfivefoods/supplieradvisor-mvp/commit/387bcf40e984a2ee1832ab7beabf0284c5b627d8
|
||||
// cve:
|
||||
// license: MIT
|
||||
// function: PATCH
|
||||
// relpath: app/api/customers/claims/route.ts
|
||||
// provenance: agent
|
||||
// mechanism: identity_from_request_body
|
||||
|
||||
export async function PATCH(request: NextRequest) {
|
||||
try {
|
||||
const body = await request.json();
|
||||
const claimId = Number(body.id);
|
||||
const companyId = Number(body.companyId);
|
||||
if (!Number.isFinite(claimId) || claimId <= 0) {
|
||||
return NextResponse.json({ error: 'id required' }, { status: 400 });
|
||||
}
|
||||
if (!Number.isFinite(companyId) || companyId <= 0) {
|
||||
return NextResponse.json({ error: 'companyId required' }, { status: 400 });
|
||||
}
|
||||
|
||||
const _gate = await requireCompanyAccess(request, companyId, { legacyPrivyUserId: legacyPrivyFrom(request) });
|
||||
if (!_gate.ok) return _gate.response;
|
||||
|
||||
const supabase = getSupabaseServer();
|
||||
const { data: existing, error: fetchError } = await supabase
|
||||
.from('customer_claims')
|
||||
.select('*')
|
||||
.eq('id', claimId)
|
||||
.eq('profile_id', companyId)
|
||||
.single();
|
||||
if (fetchError || !existing) {
|
||||
return NextResponse.json({ error: 'Claim not found' }, { status: 404 });
|
||||
}
|
||||
|
||||
const fields = [
|
||||
'status',
|
||||
'priority',
|
||||
'title',
|
||||
'description',
|
||||
'amount_claimed',
|
||||
'amount_approved',
|
||||
'resolution_notes',
|
||||
'owner_name',
|
||||
'claim_type',
|
||||
] as const;
|
||||
const updates: Record<string, unknown> = { updated_at: new Date().toISOString() };
|
||||
for (const f of fields) {
|
||||
if (body[f] !== undefined) updates[f] = body[f];
|
||||
}
|
||||
if (['resolved', 'closed', 'approved', 'rejected'].includes(String(body.status))) {
|
||||
updates.resolved_at = new Date().toISOString();
|
||||
}
|
||||
const { data, error } = await supabase
|
||||
.from('customer_claims')
|
||||
.update(updates)
|
||||
.eq('id', claimId)
|
||||
.eq('profile_id', companyId)
|
||||
.select('*')
|
||||
.single();
|
||||
if (error) return NextResponse.json({ error: error.message }, { status: 500 });
|
||||
return NextResponse.json({ success: true, claim: data });
|
||||
} catch (e: unknown) {
|
||||
return NextResponse.json({ error: e instanceof Error ? e.message : 'Error' }, { status: 500 });
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
// Provenance: bigfivefoods/supplieradvisor-mvp (vuln).
|
||||
// repo: bigfivefoods/supplieradvisor-mvp
|
||||
// commit: a7a9bc260d649ea2e582c07435bfd7d93100647b
|
||||
// parent: a7a9bc260d649ea2e582c07435bfd7d93100647b
|
||||
// commit_url: https://github.com/bigfivefoods/supplieradvisor-mvp/commit/387bcf40e984a2ee1832ab7beabf0284c5b627d8
|
||||
// cve:
|
||||
// license: MIT
|
||||
// function: PATCH
|
||||
// relpath: app/api/customers/claims/route.ts
|
||||
// provenance: agent
|
||||
// mechanism: identity_from_request_body
|
||||
|
||||
export async function PATCH(request: NextRequest) {
|
||||
try {
|
||||
const body = await request.json();
|
||||
if (!body.id) return NextResponse.json({ error: 'id required' }, { status: 400 });
|
||||
const fields = [
|
||||
'status',
|
||||
'priority',
|
||||
'title',
|
||||
'description',
|
||||
'amount_claimed',
|
||||
'amount_approved',
|
||||
'resolution_notes',
|
||||
'owner_name',
|
||||
'claim_type',
|
||||
] as const;
|
||||
const updates: Record<string, unknown> = { updated_at: new Date().toISOString() };
|
||||
for (const f of fields) {
|
||||
if (body[f] !== undefined) updates[f] = body[f];
|
||||
}
|
||||
if (['resolved', 'closed', 'approved', 'rejected'].includes(String(body.status))) {
|
||||
updates.resolved_at = new Date().toISOString();
|
||||
}
|
||||
const supabase = getSupabaseServer();
|
||||
const { data, error } = await supabase
|
||||
.from('customer_claims')
|
||||
.update(updates)
|
||||
.eq('id', Number(body.id))
|
||||
.select('*')
|
||||
.single();
|
||||
if (error) return NextResponse.json({ error: error.message }, { status: 500 });
|
||||
return NextResponse.json({ success: true, claim: data });
|
||||
} catch (e: unknown) {
|
||||
return NextResponse.json({ error: e instanceof Error ? e.message : 'Error' }, { status: 500 });
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,157 @@
|
||||
// Provenance: bigfivefoods/supplieradvisor-mvp (fixed).
|
||||
// repo: bigfivefoods/supplieradvisor-mvp
|
||||
// commit: a69e8f27c0f4d402573d16f0612b51155bbc46e1
|
||||
// parent: 8558538471e4fb10856f8d9a17d2be5ab5c4fb9c
|
||||
// commit_url: https://github.com/bigfivefoods/supplieradvisor-mvp/commit/a69e8f27c0f4d402573d16f0612b51155bbc46e1
|
||||
// cve:
|
||||
// license: MIT
|
||||
// function: GET
|
||||
// relpath: app/api/customers/opportunities/route.ts
|
||||
// provenance: agent
|
||||
// mechanism: identity_from_request_body
|
||||
|
||||
export async function GET(request: NextRequest) {
|
||||
try {
|
||||
const companyId = Number(request.nextUrl.searchParams.get('companyId'));
|
||||
const stage = request.nextUrl.searchParams.get('stage');
|
||||
const q = (request.nextUrl.searchParams.get('q') || '').trim().toLowerCase();
|
||||
if (!Number.isFinite(companyId) || companyId <= 0) {
|
||||
return NextResponse.json({ error: 'companyId required' }, { status: 400 });
|
||||
}
|
||||
const _gate = await requireCompanyAccess(request, companyId, { legacyPrivyUserId: legacyPrivyFrom(request) });
|
||||
if (!_gate.ok) return _gate.response;
|
||||
const supabase = getSupabaseServer();
|
||||
const { loadHoldingSubtree, annotateGroupOpportunity } = await import(
|
||||
'@/lib/business/holding-pipeline'
|
||||
);
|
||||
const tree = await loadHoldingSubtree(companyId);
|
||||
let query = supabase
|
||||
.from('opportunities')
|
||||
.select('*')
|
||||
.in('profile_id', tree.ids)
|
||||
.order('updated_at', { ascending: false })
|
||||
.limit(2000);
|
||||
if (stage && stage !== 'all') {
|
||||
query = query.or(`stage.eq.${stage},status.eq.${stage}`);
|
||||
}
|
||||
|
||||
const { data, error } = await query;
|
||||
if (error) {
|
||||
return NextResponse.json({
|
||||
success: true,
|
||||
opportunities: [],
|
||||
warning: error.message,
|
||||
hint: 'Run 20260709_crm_leads_opportunities.sql',
|
||||
});
|
||||
}
|
||||
|
||||
let opportunities: OpportunityListItem[] = (data || []).map((raw) => {
|
||||
const o = raw as Record<string, unknown>;
|
||||
const st = normalizeStage(
|
||||
o.stage as string | null,
|
||||
o.status as string | null
|
||||
);
|
||||
const amount = Number(o.amount ?? o.opportunity_size ?? 0);
|
||||
const probability =
|
||||
o.probability != null ? Number(o.probability) : stageProbability(st);
|
||||
const openDate =
|
||||
toDateOnly(o.open_date as string | null) ||
|
||||
toDateOnly(o.created_at as string | null) ||
|
||||
null;
|
||||
const expectedClose =
|
||||
toDateOnly(o.expected_close_date as string | null) ||
|
||||
toDateOnly(o.estimated_date as string | null) ||
|
||||
null;
|
||||
const actualClose = toDateOnly(o.actual_close_date as string | null);
|
||||
const annotated = annotateGroupOpportunity(
|
||||
{ ...o, stage: st, amount, probability },
|
||||
companyId,
|
||||
tree.names
|
||||
);
|
||||
return {
|
||||
...o,
|
||||
...annotated,
|
||||
name: o.name ?? null,
|
||||
contact_name: o.contact_name ?? null,
|
||||
company_name: o.company_name ?? null,
|
||||
contact_email: o.contact_email ?? null,
|
||||
product_interest: o.product_interest ?? null,
|
||||
stage: st,
|
||||
amount,
|
||||
probability,
|
||||
open_date: openDate,
|
||||
expected_close_date: expectedClose,
|
||||
actual_close_date: actualClose,
|
||||
contact_phone: o.contact_phone || o.contact_number || null,
|
||||
location: o.location || o.opportunity_location || null,
|
||||
description: o.description || o.notes || null,
|
||||
weighted_amount: Math.round((amount * probability) / 100),
|
||||
days_to_expected:
|
||||
openDate && expectedClose
|
||||
? Math.round(
|
||||
(new Date(expectedClose).getTime() -
|
||||
new Date(openDate).getTime()) /
|
||||
(24 * 60 * 60 * 1000)
|
||||
)
|
||||
: null,
|
||||
days_to_close:
|
||||
openDate && actualClose
|
||||
? Math.round(
|
||||
(new Date(actualClose).getTime() -
|
||||
new Date(openDate).getTime()) /
|
||||
(24 * 60 * 60 * 1000)
|
||||
)
|
||||
: null,
|
||||
days_open:
|
||||
openDate && !actualClose
|
||||
? Math.round(
|
||||
(Date.now() - new Date(openDate).getTime()) /
|
||||
(24 * 60 * 60 * 1000)
|
||||
)
|
||||
: openDate && actualClose
|
||||
? Math.round(
|
||||
(new Date(actualClose).getTime() -
|
||||
new Date(openDate).getTime()) /
|
||||
(24 * 60 * 60 * 1000)
|
||||
)
|
||||
: null,
|
||||
};
|
||||
});
|
||||
|
||||
if (q) {
|
||||
opportunities = opportunities.filter((o) => {
|
||||
const hay = [
|
||||
searchHay(o.name),
|
||||
searchHay(o.contact_name),
|
||||
searchHay(o.company_name),
|
||||
searchHay(o.contact_email),
|
||||
searchHay(o.contact_phone),
|
||||
searchHay(o.stage),
|
||||
searchHay(o.product_interest),
|
||||
]
|
||||
.join(' ')
|
||||
.toLowerCase();
|
||||
return hay.includes(q);
|
||||
});
|
||||
}
|
||||
|
||||
const { summarizeGroupPipeline } = await import(
|
||||
'@/lib/business/group-pipeline-view'
|
||||
);
|
||||
const group = summarizeGroupPipeline({
|
||||
viewerCompanyId: companyId,
|
||||
names: tree.names,
|
||||
companyIds: tree.ids,
|
||||
isSubsidiary: tree.isSubsidiary,
|
||||
opportunities,
|
||||
});
|
||||
|
||||
return NextResponse.json({
|
||||
success: true,
|
||||
opportunities,
|
||||
group,
|
||||
});
|
||||
} catch (e: unknown) {
|
||||
return NextResponse.json({ error: e instanceof Error ? e.message : 'Error' }, { status: 500 });
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,155 @@
|
||||
// Provenance: bigfivefoods/supplieradvisor-mvp (vuln).
|
||||
// repo: bigfivefoods/supplieradvisor-mvp
|
||||
// commit: 8558538471e4fb10856f8d9a17d2be5ab5c4fb9c
|
||||
// parent: 8558538471e4fb10856f8d9a17d2be5ab5c4fb9c
|
||||
// commit_url: https://github.com/bigfivefoods/supplieradvisor-mvp/commit/a69e8f27c0f4d402573d16f0612b51155bbc46e1
|
||||
// cve:
|
||||
// license: MIT
|
||||
// function: GET
|
||||
// relpath: app/api/customers/opportunities/route.ts
|
||||
// provenance: agent
|
||||
// mechanism: identity_from_request_body
|
||||
|
||||
export async function GET(request: NextRequest) {
|
||||
try {
|
||||
const companyId = Number(request.nextUrl.searchParams.get('companyId'));
|
||||
const stage = request.nextUrl.searchParams.get('stage');
|
||||
const q = (request.nextUrl.searchParams.get('q') || '').trim().toLowerCase();
|
||||
if (!Number.isFinite(companyId)) {
|
||||
return NextResponse.json({ error: 'companyId required' }, { status: 400 });
|
||||
}
|
||||
const supabase = getSupabaseServer();
|
||||
const { loadHoldingSubtree, annotateGroupOpportunity } = await import(
|
||||
'@/lib/business/holding-pipeline'
|
||||
);
|
||||
const tree = await loadHoldingSubtree(companyId);
|
||||
let query = supabase
|
||||
.from('opportunities')
|
||||
.select('*')
|
||||
.in('profile_id', tree.ids)
|
||||
.order('updated_at', { ascending: false })
|
||||
.limit(2000);
|
||||
if (stage && stage !== 'all') {
|
||||
query = query.or(`stage.eq.${stage},status.eq.${stage}`);
|
||||
}
|
||||
|
||||
const { data, error } = await query;
|
||||
if (error) {
|
||||
return NextResponse.json({
|
||||
success: true,
|
||||
opportunities: [],
|
||||
warning: error.message,
|
||||
hint: 'Run 20260709_crm_leads_opportunities.sql',
|
||||
});
|
||||
}
|
||||
|
||||
let opportunities: OpportunityListItem[] = (data || []).map((raw) => {
|
||||
const o = raw as Record<string, unknown>;
|
||||
const st = normalizeStage(
|
||||
o.stage as string | null,
|
||||
o.status as string | null
|
||||
);
|
||||
const amount = Number(o.amount ?? o.opportunity_size ?? 0);
|
||||
const probability =
|
||||
o.probability != null ? Number(o.probability) : stageProbability(st);
|
||||
const openDate =
|
||||
toDateOnly(o.open_date as string | null) ||
|
||||
toDateOnly(o.created_at as string | null) ||
|
||||
null;
|
||||
const expectedClose =
|
||||
toDateOnly(o.expected_close_date as string | null) ||
|
||||
toDateOnly(o.estimated_date as string | null) ||
|
||||
null;
|
||||
const actualClose = toDateOnly(o.actual_close_date as string | null);
|
||||
const annotated = annotateGroupOpportunity(
|
||||
{ ...o, stage: st, amount, probability },
|
||||
companyId,
|
||||
tree.names
|
||||
);
|
||||
return {
|
||||
...o,
|
||||
...annotated,
|
||||
name: o.name ?? null,
|
||||
contact_name: o.contact_name ?? null,
|
||||
company_name: o.company_name ?? null,
|
||||
contact_email: o.contact_email ?? null,
|
||||
product_interest: o.product_interest ?? null,
|
||||
stage: st,
|
||||
amount,
|
||||
probability,
|
||||
open_date: openDate,
|
||||
expected_close_date: expectedClose,
|
||||
actual_close_date: actualClose,
|
||||
contact_phone: o.contact_phone || o.contact_number || null,
|
||||
location: o.location || o.opportunity_location || null,
|
||||
description: o.description || o.notes || null,
|
||||
weighted_amount: Math.round((amount * probability) / 100),
|
||||
days_to_expected:
|
||||
openDate && expectedClose
|
||||
? Math.round(
|
||||
(new Date(expectedClose).getTime() -
|
||||
new Date(openDate).getTime()) /
|
||||
(24 * 60 * 60 * 1000)
|
||||
)
|
||||
: null,
|
||||
days_to_close:
|
||||
openDate && actualClose
|
||||
? Math.round(
|
||||
(new Date(actualClose).getTime() -
|
||||
new Date(openDate).getTime()) /
|
||||
(24 * 60 * 60 * 1000)
|
||||
)
|
||||
: null,
|
||||
days_open:
|
||||
openDate && !actualClose
|
||||
? Math.round(
|
||||
(Date.now() - new Date(openDate).getTime()) /
|
||||
(24 * 60 * 60 * 1000)
|
||||
)
|
||||
: openDate && actualClose
|
||||
? Math.round(
|
||||
(new Date(actualClose).getTime() -
|
||||
new Date(openDate).getTime()) /
|
||||
(24 * 60 * 60 * 1000)
|
||||
)
|
||||
: null,
|
||||
};
|
||||
});
|
||||
|
||||
if (q) {
|
||||
opportunities = opportunities.filter((o) => {
|
||||
const hay = [
|
||||
searchHay(o.name),
|
||||
searchHay(o.contact_name),
|
||||
searchHay(o.company_name),
|
||||
searchHay(o.contact_email),
|
||||
searchHay(o.contact_phone),
|
||||
searchHay(o.stage),
|
||||
searchHay(o.product_interest),
|
||||
]
|
||||
.join(' ')
|
||||
.toLowerCase();
|
||||
return hay.includes(q);
|
||||
});
|
||||
}
|
||||
|
||||
const { summarizeGroupPipeline } = await import(
|
||||
'@/lib/business/group-pipeline-view'
|
||||
);
|
||||
const group = summarizeGroupPipeline({
|
||||
viewerCompanyId: companyId,
|
||||
names: tree.names,
|
||||
companyIds: tree.ids,
|
||||
isSubsidiary: tree.isSubsidiary,
|
||||
opportunities,
|
||||
});
|
||||
|
||||
return NextResponse.json({
|
||||
success: true,
|
||||
opportunities,
|
||||
group,
|
||||
});
|
||||
} catch (e: unknown) {
|
||||
return NextResponse.json({ error: e instanceof Error ? e.message : 'Error' }, { status: 500 });
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
# Provenance: D-sorganization/Tools (fixed).
|
||||
# repo: D-sorganization/Tools
|
||||
# commit: a96bc0502a3dcdac303e4f0152508886e5c35c0a
|
||||
# parent: e735d28b82dd1fbc42c0ae01157b38d1b4c7c864
|
||||
# commit_url: https://github.com/D-sorganization/Tools/commit/a96bc0502a3dcdac303e4f0152508886e5c35c0a
|
||||
# cve:
|
||||
# license: MIT
|
||||
# function: _is_command_allowed
|
||||
# relpath: src/shared/python/ai/tools/cli_tools.py
|
||||
# provenance: agent
|
||||
# mechanism: source_reaches_sink
|
||||
|
||||
def _is_command_allowed(self, command: str) -> bool:
|
||||
"""Check if a command is allowed.
|
||||
|
||||
Args:
|
||||
command: Command to check.
|
||||
|
||||
Returns:
|
||||
True if allowed, False otherwise.
|
||||
"""
|
||||
# Dangerous commands are never allowed
|
||||
dangerous = ["rm", "sudo", "chmod", "chown", "curl", "wget", "ssh"]
|
||||
|
||||
# Prevent shell injection by blocking command separators/operators
|
||||
shell_operators = ["&&", "||", ";", "|", ">", "<", "$", "`", "\n", "&"]
|
||||
if any(op in command for op in shell_operators):
|
||||
return False
|
||||
|
||||
try:
|
||||
tokens = shlex.split(command)
|
||||
if not tokens:
|
||||
return False
|
||||
|
||||
# Verify the first token is in the allowlist
|
||||
base_cmd = tokens[0]
|
||||
if base_cmd not in self._allowed_commands:
|
||||
return False
|
||||
|
||||
# Verify no token is a dangerous command
|
||||
for token in tokens:
|
||||
if token in dangerous:
|
||||
return False
|
||||
|
||||
try:
|
||||
# Check for absolute/relative paths (e.g., /bin/rm, ./rm)
|
||||
if Path(token).name in dangerous:
|
||||
return False
|
||||
|
||||
# Check for assignments passing executables (e.g., --exec=/bin/rm)
|
||||
if "=" in token:
|
||||
val = token.split("=", 1)[1]
|
||||
if val in dangerous or Path(val).name in dangerous:
|
||||
return False
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
return True
|
||||
except ValueError:
|
||||
# e.g., missing closing quote
|
||||
return False
|
||||
@@ -0,0 +1,48 @@
|
||||
# Provenance: D-sorganization/Tools (vuln).
|
||||
# repo: D-sorganization/Tools
|
||||
# commit: e735d28b82dd1fbc42c0ae01157b38d1b4c7c864
|
||||
# parent: e735d28b82dd1fbc42c0ae01157b38d1b4c7c864
|
||||
# commit_url: https://github.com/D-sorganization/Tools/commit/a96bc0502a3dcdac303e4f0152508886e5c35c0a
|
||||
# cve:
|
||||
# license: MIT
|
||||
# function: _is_command_allowed
|
||||
# relpath: src/shared/python/ai/tools/cli_tools.py
|
||||
# provenance: agent
|
||||
# mechanism: source_reaches_sink
|
||||
|
||||
def _is_command_allowed(self, command: str) -> bool:
|
||||
"""Check if a command is allowed.
|
||||
|
||||
Args:
|
||||
command: Command to check.
|
||||
|
||||
Returns:
|
||||
True if allowed, False otherwise.
|
||||
"""
|
||||
# Dangerous commands are never allowed
|
||||
dangerous = ["rm", "sudo", "chmod", "chown", "curl", "wget", "ssh"]
|
||||
|
||||
# Prevent shell injection by blocking command separators/operators
|
||||
shell_operators = ["&&", "||", ";", "|", ">", "<", "$", "`", "\n", "&"]
|
||||
if any(op in command for op in shell_operators):
|
||||
return False
|
||||
|
||||
try:
|
||||
tokens = shlex.split(command)
|
||||
if not tokens:
|
||||
return False
|
||||
|
||||
# Verify the first token is in the allowlist
|
||||
base_cmd = tokens[0]
|
||||
if base_cmd not in self._allowed_commands:
|
||||
return False
|
||||
|
||||
# Verify no token is a dangerous command
|
||||
for token in tokens:
|
||||
if token in dangerous:
|
||||
return False
|
||||
|
||||
return True
|
||||
except ValueError:
|
||||
# e.g., missing closing quote
|
||||
return False
|
||||
@@ -0,0 +1,48 @@
|
||||
// Provenance: trackly-app/trackly-cli (fixed).
|
||||
// repo: trackly-app/trackly-cli
|
||||
// commit: 1c1aed89b07edb04051830c8f086e02b65e961c6
|
||||
// parent: 8d240ad8d7fc114c8f941ad956a2fdf32391ff60
|
||||
// commit_url: https://github.com/trackly-app/trackly-cli/commit/1c1aed89b07edb04051830c8f086e02b65e961c6
|
||||
// cve:
|
||||
// license: MIT
|
||||
// function: inspectExistingAncestor
|
||||
// relpath: lib/path-diagnostics.js
|
||||
// provenance: agent
|
||||
// mechanism: path_join_user_input
|
||||
|
||||
async function inspectExistingAncestor(exactPath, stat = fs.stat) {
|
||||
let candidate = exactPath;
|
||||
while (true) {
|
||||
try {
|
||||
const stats = await stat(candidate);
|
||||
return {
|
||||
ancestor: candidate,
|
||||
exactPathExists: candidate === exactPath,
|
||||
exactPathType: candidate === exactPath ? (stats.isDirectory() ? 'directory' : 'file') : null,
|
||||
writableDirectory: stats.isDirectory() ? candidate : path.dirname(candidate),
|
||||
inspectionErrorCode: null,
|
||||
};
|
||||
} catch (error) {
|
||||
if (error.code !== 'ENOENT') {
|
||||
return {
|
||||
ancestor: candidate,
|
||||
exactPathExists: null,
|
||||
exactPathType: null,
|
||||
writableDirectory: null,
|
||||
inspectionErrorCode: error.code || 'path_inspection_failed',
|
||||
};
|
||||
}
|
||||
const parent = path.dirname(candidate);
|
||||
if (parent === candidate) {
|
||||
return {
|
||||
ancestor: parent,
|
||||
exactPathExists: false,
|
||||
exactPathType: null,
|
||||
writableDirectory: parent,
|
||||
inspectionErrorCode: null,
|
||||
};
|
||||
}
|
||||
candidate = parent;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
// Provenance: trackly-app/trackly-cli (vuln).
|
||||
// repo: trackly-app/trackly-cli
|
||||
// commit: 8d240ad8d7fc114c8f941ad956a2fdf32391ff60
|
||||
// parent: 8d240ad8d7fc114c8f941ad956a2fdf32391ff60
|
||||
// commit_url: https://github.com/trackly-app/trackly-cli/commit/1c1aed89b07edb04051830c8f086e02b65e961c6
|
||||
// cve:
|
||||
// license: MIT
|
||||
// function: inspectExistingAncestor
|
||||
// relpath: lib/path-diagnostics.js
|
||||
// provenance: agent
|
||||
// mechanism: path_join_user_input
|
||||
|
||||
async function inspectExistingAncestor(exactPath) {
|
||||
let candidate = exactPath;
|
||||
while (true) {
|
||||
try {
|
||||
const stats = await fs.stat(candidate);
|
||||
return {
|
||||
ancestor: candidate,
|
||||
exactPathExists: candidate === exactPath,
|
||||
exactPathType: candidate === exactPath ? (stats.isDirectory() ? 'directory' : 'file') : null,
|
||||
writableDirectory: stats.isDirectory() ? candidate : path.dirname(candidate),
|
||||
};
|
||||
} catch (error) {
|
||||
if (error.code !== 'ENOENT') throw error;
|
||||
const parent = path.dirname(candidate);
|
||||
if (parent === candidate) {
|
||||
return { ancestor: parent, exactPathExists: false, exactPathType: null, writableDirectory: parent };
|
||||
}
|
||||
candidate = parent;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
# Provenance: D-sorganization/UpstreamDrift (fixed).
|
||||
# repo: D-sorganization/UpstreamDrift
|
||||
# commit: c3a0787080489b30e2ed0abfac03b51e45da184b
|
||||
# parent: e28d1da5e103d93951ef11b78a6e9b89ac1fa2bc
|
||||
# commit_url: https://github.com/D-sorganization/UpstreamDrift/commit/c3a0787080489b30e2ed0abfac03b51e45da184b
|
||||
# cve:
|
||||
# license: MIT
|
||||
# function: _find_logo_file
|
||||
# relpath: src/api/local_server.py
|
||||
# provenance: agent
|
||||
# mechanism: path_join_user_input
|
||||
|
||||
def _find_logo_file(logo_name: str) -> Path | None:
|
||||
"""Search for a logo file in known asset directories.
|
||||
|
||||
The caller-supplied ``logo_name`` is joined onto each candidate root via
|
||||
:func:`_safe_join` so that ``..`` traversal, absolute paths, and symlink
|
||||
escape are rejected before touching the filesystem.
|
||||
|
||||
Args:
|
||||
logo_name: Filename of the logo to find.
|
||||
|
||||
Returns:
|
||||
Path to the logo file, or None if not found or rejected as unsafe.
|
||||
"""
|
||||
for root in (
|
||||
Path(__file__).parent.parent.parent / "assets" / "logos",
|
||||
Path(__file__).parent.parent / "launchers" / "assets",
|
||||
):
|
||||
resolved = _safe_join(root, logo_name)
|
||||
if resolved is not None and resolved.exists() and resolved.is_file():
|
||||
return resolved
|
||||
return None
|
||||
@@ -0,0 +1,30 @@
|
||||
# Provenance: D-sorganization/UpstreamDrift (vuln).
|
||||
# repo: D-sorganization/UpstreamDrift
|
||||
# commit: e28d1da5e103d93951ef11b78a6e9b89ac1fa2bc
|
||||
# parent: e28d1da5e103d93951ef11b78a6e9b89ac1fa2bc
|
||||
# commit_url: https://github.com/D-sorganization/UpstreamDrift/commit/c3a0787080489b30e2ed0abfac03b51e45da184b
|
||||
# cve:
|
||||
# license: MIT
|
||||
# function: _find_logo_file
|
||||
# relpath: src/api/local_server.py
|
||||
# provenance: agent
|
||||
# mechanism: path_join_user_input
|
||||
|
||||
def _find_logo_file(logo_name: str) -> Path | None:
|
||||
"""Search for a logo file in known asset directories.
|
||||
|
||||
Args:
|
||||
logo_name: Filename of the logo to find.
|
||||
|
||||
Returns:
|
||||
Path to the logo file, or None if not found.
|
||||
"""
|
||||
logos_dir = Path(__file__).parent.parent.parent / "assets" / "logos"
|
||||
logo_path = logos_dir / logo_name
|
||||
if logo_path.exists() and logo_path.is_file():
|
||||
return logo_path
|
||||
launcher_logos = Path(__file__).parent.parent / "launchers" / "assets"
|
||||
alt_path = launcher_logos / logo_name
|
||||
if alt_path.exists() and alt_path.is_file():
|
||||
return alt_path
|
||||
return None
|
||||
@@ -0,0 +1,28 @@
|
||||
# Provenance: Ahkeratmehilaiset/waggledance-swarm (fixed).
|
||||
# repo: Ahkeratmehilaiset/waggledance-swarm
|
||||
# commit: 9a454843aa35332ff2eb3106023eee0c4b5e444b
|
||||
# parent: 934b939f1cca5259eaf807db3319eb97b90d8d80
|
||||
# commit_url: https://github.com/Ahkeratmehilaiset/waggledance-swarm/commit/9a454843aa35332ff2eb3106023eee0c4b5e444b
|
||||
# cve:
|
||||
# license: Apache-2.0
|
||||
# function: normalize_allowed_hosts
|
||||
# relpath: waggledance/core/v3_13_0/ssrf_host_guard.py
|
||||
# provenance: agent
|
||||
# mechanism: source_reaches_sink
|
||||
|
||||
def normalize_allowed_hosts(raw_hosts: Iterable[str]) -> frozenset[str]:
|
||||
"""Validate and canonicalize an exact-host allowlist."""
|
||||
if (
|
||||
not isinstance(raw_hosts, Iterable)
|
||||
or isinstance(raw_hosts, (str, bytes, Mapping))
|
||||
):
|
||||
raise ValueError("ALLOWLIST_HOSTS_REFUSED")
|
||||
normalized: set[str] = set()
|
||||
for index, host in enumerate(raw_hosts):
|
||||
if not isinstance(host, str) or not host.strip():
|
||||
raise ValueError(f"ALLOWLIST_HOSTS_REFUSED_{index}")
|
||||
clean = normalize_host(host)
|
||||
if "://" in clean or "/" in clean or "?" in clean or "@" in clean:
|
||||
raise ValueError(f"ALLOWLIST_HOSTS_REFUSED_{index}")
|
||||
normalized.add(clean)
|
||||
return frozenset(normalized)
|
||||
@@ -0,0 +1,25 @@
|
||||
# Provenance: Ahkeratmehilaiset/waggledance-swarm (vuln).
|
||||
# repo: Ahkeratmehilaiset/waggledance-swarm
|
||||
# commit: 934b939f1cca5259eaf807db3319eb97b90d8d80
|
||||
# parent: 934b939f1cca5259eaf807db3319eb97b90d8d80
|
||||
# commit_url: https://github.com/Ahkeratmehilaiset/waggledance-swarm/commit/9a454843aa35332ff2eb3106023eee0c4b5e444b
|
||||
# cve:
|
||||
# license: Apache-2.0
|
||||
# function: normalize_allowed_hosts
|
||||
# relpath: waggledance/core/v3_13_0/ssrf_host_guard.py
|
||||
# provenance: agent
|
||||
# mechanism: source_reaches_sink
|
||||
|
||||
def normalize_allowed_hosts(raw_hosts: Sequence[str]) -> frozenset[str]:
|
||||
"""Validate and canonicalize an exact-host allowlist."""
|
||||
if not isinstance(raw_hosts, Sequence) or isinstance(raw_hosts, (str, bytes)):
|
||||
raise ValueError("ALLOWLIST_HOSTS_REFUSED")
|
||||
normalized: set[str] = set()
|
||||
for index, host in enumerate(raw_hosts):
|
||||
if not isinstance(host, str) or not host.strip():
|
||||
raise ValueError(f"ALLOWLIST_HOSTS_REFUSED_{index}")
|
||||
clean = normalize_host(host)
|
||||
if "://" in clean or "/" in clean or "?" in clean or "@" in clean:
|
||||
raise ValueError(f"ALLOWLIST_HOSTS_REFUSED_{index}")
|
||||
normalized.add(clean)
|
||||
return frozenset(normalized)
|
||||
@@ -0,0 +1,162 @@
|
||||
// Provenance: G4brym/workers-research (fixed).
|
||||
// repo: G4brym/workers-research
|
||||
// commit: 209444eb61cc564c2d6b43267256f85fe3e5e30e
|
||||
// parent: eab923ad3099c01b002fbd6be7cf994614bbdee4
|
||||
// commit_url: https://github.com/G4brym/workers-research/commit/209444eb61cc564c2d6b43267256f85fe3e5e30e
|
||||
// cve:
|
||||
// license: MIT
|
||||
// function: formatDuration
|
||||
// relpath: src/utils.ts
|
||||
// provenance: agent
|
||||
// mechanism: source_reaches_sink
|
||||
|
||||
import {
|
||||
createGoogleGenerativeAI,
|
||||
type GoogleGenerativeAIProvider,
|
||||
type GoogleGenerativeAIProviderSettings,
|
||||
} from "@ai-sdk/google";
|
||||
import type { Env } from "./bindings";
|
||||
|
||||
function getGoogleProvider(env: Env): GoogleGenerativeAIProvider {
|
||||
const args: GoogleGenerativeAIProviderSettings = {
|
||||
apiKey: env.GOOGLE_API_KEY,
|
||||
};
|
||||
|
||||
if (env.AI_GATEWAY_ACCOUNT_ID && env.AI_GATEWAY_NAME) {
|
||||
args.baseURL = `https://gateway.ai.cloudflare.com/v1/${env.AI_GATEWAY_ACCOUNT_ID}/${env.AI_GATEWAY_NAME}/google-ai-studio/v1beta`;
|
||||
|
||||
if (env.AI_GATEWAY_API_KEY) {
|
||||
args.headers = {
|
||||
"cf-aig-authorization": `Bearer ${env.AI_GATEWAY_API_KEY}`,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return createGoogleGenerativeAI(args);
|
||||
}
|
||||
|
||||
export function getModel(env: Env) {
|
||||
const google = getGoogleProvider(env);
|
||||
|
||||
return google("gemini-2.0-flash-exp");
|
||||
}
|
||||
|
||||
export function getFallbackModel(env: Env) {
|
||||
const google = getGoogleProvider(env);
|
||||
return google("gemini-2.0-flash");
|
||||
}
|
||||
|
||||
export function getModelThinking(env: Env) {
|
||||
const google = getGoogleProvider(env);
|
||||
|
||||
return google("gemini-2.0-flash-exp");
|
||||
}
|
||||
|
||||
export function timeAgo(date: Date): string {
|
||||
const now = new Date();
|
||||
const seconds = Math.floor((now.getTime() - date.getTime()) / 1000);
|
||||
|
||||
const intervals: [number, string][] = [
|
||||
[60, "minute"],
|
||||
[60, "hour"],
|
||||
[24, "day"],
|
||||
[7, "week"],
|
||||
[4.35, "month"],
|
||||
[12, "year"],
|
||||
];
|
||||
|
||||
let count = seconds;
|
||||
let unit = "second";
|
||||
|
||||
for (const [interval, name] of intervals) {
|
||||
if (count < interval) break;
|
||||
count /= interval;
|
||||
unit = name;
|
||||
}
|
||||
|
||||
count = Math.floor(count);
|
||||
return `${count} ${unit}${count !== 1 ? "s" : ""} ago`;
|
||||
}
|
||||
|
||||
export async function sleep(ms: number): Promise<void> {
|
||||
return new Promise((resolve) => setTimeout(resolve, ms));
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize a domain input for excluded domain matching.
|
||||
* Handles common user input formats:
|
||||
* - Full URLs: "https://reddit.com/foo" → "reddit.com"
|
||||
* - www prefix: "www.reddit.com" → "reddit.com"
|
||||
* - Mixed: "https://www.reddit.com" → "reddit.com"
|
||||
* - Plain domains are returned as-is (lowercased, trimmed)
|
||||
*/
|
||||
export function normalizeDomain(input: string): string {
|
||||
let domain = input.trim().toLowerCase();
|
||||
if (domain.length === 0) return "";
|
||||
|
||||
// If it looks like a URL (has ://), extract the hostname
|
||||
if (domain.includes("://")) {
|
||||
try {
|
||||
domain = new URL(domain).hostname;
|
||||
} catch {
|
||||
// If URL parsing fails, strip the protocol manually
|
||||
domain = domain.replace(/^[a-z]+:\/\//, "").split("/")[0];
|
||||
}
|
||||
} else {
|
||||
// Strip any trailing path from plain domain input
|
||||
domain = domain.split("/")[0];
|
||||
}
|
||||
|
||||
// Strip www. prefix for consistent matching
|
||||
domain = domain.replace(/^www\./, "");
|
||||
|
||||
return domain;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build parameterized search filter conditions for research list queries.
|
||||
* Uses parameterized queries to prevent SQL injection.
|
||||
*/
|
||||
export function buildSearchFilters(
|
||||
q?: string,
|
||||
status?: string,
|
||||
): { conditions: string[]; params: (string | number)[] } {
|
||||
const conditions: string[] = [];
|
||||
const params: (string | number)[] = [];
|
||||
|
||||
if (q?.trim()) {
|
||||
const searchTerm = `%${q.trim()}%`;
|
||||
conditions.push("(title LIKE ? OR query LIKE ?)");
|
||||
params.push(searchTerm, searchTerm);
|
||||
}
|
||||
|
||||
if (status && ["1", "2", "3"].includes(status)) {
|
||||
conditions.push("status = ?");
|
||||
params.push(Number.parseInt(status, 10));
|
||||
}
|
||||
|
||||
return { conditions, params };
|
||||
}
|
||||
|
||||
export function formatDuration(ms: number): string {
|
||||
// Handle negative or zero values
|
||||
if (ms <= 0) {
|
||||
return "0.0 seconds";
|
||||
}
|
||||
|
||||
const seconds = ms / 1000;
|
||||
const minutes = seconds / 60;
|
||||
const hours = minutes / 60;
|
||||
const days = hours / 24;
|
||||
|
||||
// Determine the appropriate unit and format with one decimal place
|
||||
if (days >= 1) {
|
||||
return `${days.toFixed(1)} day${days !== 1 ? "s" : ""}`;
|
||||
} else if (hours >= 1) {
|
||||
return `${hours.toFixed(1)} hour${hours !== 1 ? "s" : ""}`;
|
||||
} else if (minutes >= 1) {
|
||||
return `${minutes.toFixed(1)} minute${minutes !== 1 ? "s" : ""}`;
|
||||
} else {
|
||||
return `${seconds.toFixed(1)} second${seconds !== 1 ? "s" : ""}`;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,137 @@
|
||||
// Provenance: G4brym/workers-research (vuln).
|
||||
// repo: G4brym/workers-research
|
||||
// commit: eab923ad3099c01b002fbd6be7cf994614bbdee4
|
||||
// parent: eab923ad3099c01b002fbd6be7cf994614bbdee4
|
||||
// commit_url: https://github.com/G4brym/workers-research/commit/209444eb61cc564c2d6b43267256f85fe3e5e30e
|
||||
// cve:
|
||||
// license: MIT
|
||||
// function: formatDuration
|
||||
// relpath: src/utils.ts
|
||||
// provenance: agent
|
||||
// mechanism: source_reaches_sink
|
||||
|
||||
import {
|
||||
createGoogleGenerativeAI,
|
||||
type GoogleGenerativeAIProvider,
|
||||
type GoogleGenerativeAIProviderSettings,
|
||||
} from "@ai-sdk/google";
|
||||
import type { Env } from "./bindings";
|
||||
|
||||
function getGoogleProvider(env: Env): GoogleGenerativeAIProvider {
|
||||
const args: GoogleGenerativeAIProviderSettings = {
|
||||
apiKey: env.GOOGLE_API_KEY,
|
||||
};
|
||||
|
||||
if (env.AI_GATEWAY_ACCOUNT_ID && env.AI_GATEWAY_NAME) {
|
||||
args.baseURL = `https://gateway.ai.cloudflare.com/v1/${env.AI_GATEWAY_ACCOUNT_ID}/${env.AI_GATEWAY_NAME}/google-ai-studio/v1beta`;
|
||||
|
||||
if (env.AI_GATEWAY_API_KEY) {
|
||||
args.headers = {
|
||||
"cf-aig-authorization": `Bearer ${env.AI_GATEWAY_API_KEY}`,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return createGoogleGenerativeAI(args);
|
||||
}
|
||||
|
||||
export function getModel(env: Env) {
|
||||
const google = getGoogleProvider(env);
|
||||
|
||||
return google("gemini-2.0-flash-exp");
|
||||
}
|
||||
|
||||
export function getFallbackModel(env: Env) {
|
||||
const google = getGoogleProvider(env);
|
||||
return google("gemini-2.0-flash");
|
||||
}
|
||||
|
||||
export function getModelThinking(env: Env) {
|
||||
const google = getGoogleProvider(env);
|
||||
|
||||
return google("gemini-2.0-flash-exp");
|
||||
}
|
||||
|
||||
export function timeAgo(date: Date): string {
|
||||
const now = new Date();
|
||||
const seconds = Math.floor((now.getTime() - date.getTime()) / 1000);
|
||||
|
||||
const intervals: [number, string][] = [
|
||||
[60, "minute"],
|
||||
[60, "hour"],
|
||||
[24, "day"],
|
||||
[7, "week"],
|
||||
[4.35, "month"],
|
||||
[12, "year"],
|
||||
];
|
||||
|
||||
let count = seconds;
|
||||
let unit = "second";
|
||||
|
||||
for (const [interval, name] of intervals) {
|
||||
if (count < interval) break;
|
||||
count /= interval;
|
||||
unit = name;
|
||||
}
|
||||
|
||||
count = Math.floor(count);
|
||||
return `${count} ${unit}${count !== 1 ? "s" : ""} ago`;
|
||||
}
|
||||
|
||||
export async function sleep(ms: number): Promise<void> {
|
||||
return new Promise((resolve) => setTimeout(resolve, ms));
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize a domain input for excluded domain matching.
|
||||
* Handles common user input formats:
|
||||
* - Full URLs: "https://reddit.com/foo" → "reddit.com"
|
||||
* - www prefix: "www.reddit.com" → "reddit.com"
|
||||
* - Mixed: "https://www.reddit.com" → "reddit.com"
|
||||
* - Plain domains are returned as-is (lowercased, trimmed)
|
||||
*/
|
||||
export function normalizeDomain(input: string): string {
|
||||
let domain = input.trim().toLowerCase();
|
||||
if (domain.length === 0) return "";
|
||||
|
||||
// If it looks like a URL (has ://), extract the hostname
|
||||
if (domain.includes("://")) {
|
||||
try {
|
||||
domain = new URL(domain).hostname;
|
||||
} catch {
|
||||
// If URL parsing fails, strip the protocol manually
|
||||
domain = domain.replace(/^[a-z]+:\/\//, "").split("/")[0];
|
||||
}
|
||||
} else {
|
||||
// Strip any trailing path from plain domain input
|
||||
domain = domain.split("/")[0];
|
||||
}
|
||||
|
||||
// Strip www. prefix for consistent matching
|
||||
domain = domain.replace(/^www\./, "");
|
||||
|
||||
return domain;
|
||||
}
|
||||
|
||||
export function formatDuration(ms: number): string {
|
||||
// Handle negative or zero values
|
||||
if (ms <= 0) {
|
||||
return "0.0 seconds";
|
||||
}
|
||||
|
||||
const seconds = ms / 1000;
|
||||
const minutes = seconds / 60;
|
||||
const hours = minutes / 60;
|
||||
const days = hours / 24;
|
||||
|
||||
// Determine the appropriate unit and format with one decimal place
|
||||
if (days >= 1) {
|
||||
return `${days.toFixed(1)} day${days !== 1 ? "s" : ""}`;
|
||||
} else if (hours >= 1) {
|
||||
return `${hours.toFixed(1)} hour${hours !== 1 ? "s" : ""}`;
|
||||
} else if (minutes >= 1) {
|
||||
return `${minutes.toFixed(1)} minute${minutes !== 1 ? "s" : ""}`;
|
||||
} else {
|
||||
return `${seconds.toFixed(1)} second${seconds !== 1 ? "s" : ""}`;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
// Provenance: zoonk/zoonk (fixed).
|
||||
// repo: zoonk/zoonk
|
||||
// commit: bfbf670ccb41d63c407d32c51bd26e626a174f31
|
||||
// parent: 2604269350bff51f58572c133b45010cb0976a5a
|
||||
// commit_url: https://github.com/zoonk/zoonk/commit/bfbf670ccb41d63c407d32c51bd26e626a174f31
|
||||
// cve:
|
||||
// license: MIT
|
||||
// function: getAllowedHosts
|
||||
// relpath: packages/utils/src/origin.ts
|
||||
// provenance: agent
|
||||
// mechanism: permissive_default
|
||||
|
||||
export function getAllowedHosts(): string[] {
|
||||
return [
|
||||
...ZOONK_DOMAINS.flatMap((domain) => [domain, `*.${domain}`]),
|
||||
...(isLocalhostSupported() ? ["localhost:*"] : []),
|
||||
...(canAcceptVercelPreviewOrigins() ? [ZOONK_VERCEL_PREVIEW_HOST] : []),
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
// Provenance: zoonk/zoonk (vuln).
|
||||
// repo: zoonk/zoonk
|
||||
// commit: 2604269350bff51f58572c133b45010cb0976a5a
|
||||
// parent: 2604269350bff51f58572c133b45010cb0976a5a
|
||||
// commit_url: https://github.com/zoonk/zoonk/commit/bfbf670ccb41d63c407d32c51bd26e626a174f31
|
||||
// cve:
|
||||
// license: MIT
|
||||
// function: getAllowedHosts
|
||||
// relpath: packages/utils/src/origin.ts
|
||||
// provenance: agent
|
||||
// mechanism: permissive_default
|
||||
|
||||
export function getAllowedHosts(): string[] {
|
||||
return [
|
||||
...ZOONK_DOMAINS.flatMap((domain) => [domain, `*.${domain}`]),
|
||||
...(isLocalhostSupported() ? ["localhost:*"] : []),
|
||||
...(getEnvironment() === "production" ? [] : ["*-zoonk.vercel.app"]),
|
||||
];
|
||||
}
|
||||
Reference in New Issue
Block a user