d208a2bde2
CI / validate-canonical-controls (push) Successful in 11s
CI / loc-budget (push) Successful in 13s
CI / go-lint (push) Has been skipped
CI / test-go (push) Has been skipped
CI / iace-gt-coverage (push) Has been skipped
CI / detect-changes (push) Successful in 7s
CI / branch-name (push) Has been skipped
CI / guardrail-integrity (push) Has been skipped
CI / secret-scan (push) Has been skipped
CI / dep-audit (push) Has been skipped
CI / sbom-scan (push) Has been skipped
CI / build-sha-integrity (push) Failing after 4s
CI / python-lint (push) Has been skipped
CI / nodejs-build (push) Has been skipped
CI / nodejs-lint (push) Has been skipped
CI / test-python-backend (push) Successful in 30s
CI / test-python-document-crawler (push) Has been skipped
CI / test-python-dsms-gateway (push) Has been skipped
User-Feedback BMW v5: "740 Cookies verschwunden auf 31, Übersicht
verloren". Drei Anpassungen:
Mail-Restrukturierung (_executive_summary.py + _compose.py):
- render_executive_summary(): Top-of-mail TL;DR mit
Compliance-Score (gross + farbig), Top-3-Findings nach
Severity, Cookie-Statistik (deklariert/Browser/Drittland),
Severity-Verteilungs-Chips.
- collapsible(): wrapt jeden Block in <details>/<summary>.
Mailpit + alle modernen Mail-Clients rendern das nativ.
- _compose.py: alle 18+ B-Blöcke + per_doc + per_theme +
legacy_html in Akkordeons. NUR Critical-Findings + Sofort-
massnahmen sind immer offen — Reviewer sieht ~15 Zeilen
Übersicht und klappt selektiv auf.
- Cookie-Inventar (742) hat jetzt eigene Sektion ganz oben
(Akkordeon "🍪 Cookie-Inventar"), Vendor-Karten parallel.
B22 Cross-Domain-Legal-Doc-Detector (cross_domain_doc_check.py):
Real-Beispiel User-Feedback: Elli's AGB liegt auf docs.logpay.de
statt elli.eco. Detektor erkennt SLD-Mismatch:
- HIGH bei agb / widerruf (vertragsrelevant)
- MEDIUM bei dse / nutzungsbedingungen
- INFO bei cookie / impressum (Best-Practice)
Norm: DSGVO Art. 28 (AVV-Pflicht für Hosting) + Art. 13 Abs. 1
lit. e (Empfänger) + § 312i BGB (Cool-URLs).
9/9 Tests grün inkl. Elli/LogPay Pattern.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
60 lines
2.3 KiB
Python
60 lines
2.3 KiB
Python
"""B22 wiring — Cross-Domain-Legal-Doc-Detector."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import html
|
|
import logging
|
|
|
|
from compliance.services.cross_domain_doc_check import check_cross_domain_docs
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
def run_b22(state: dict) -> None:
|
|
new = check_cross_domain_docs(state)
|
|
if not new:
|
|
return
|
|
extras = state.get("extra_findings") or []
|
|
extras.extend(new)
|
|
state["extra_findings"] = extras
|
|
state["cross_domain_doc_html"] = _render(new)
|
|
logger.info("B22 cross-domain: %d finding(s)", len(new))
|
|
|
|
|
|
def _render(findings: list[dict]) -> str:
|
|
cards = []
|
|
for f in findings:
|
|
sev = (f.get("severity") or "").upper()
|
|
color = ("#dc2626" if sev == "HIGH"
|
|
else "#f59e0b" if sev == "MEDIUM" else "#64748b")
|
|
cards.append(
|
|
f"<div style='margin:12px 0;padding:14px;background:#fff;"
|
|
f"border-left:3px solid {color};border-radius:4px;'>"
|
|
f"<div style='font-weight:600;color:{color};font-size:14px;'>"
|
|
f"{sev} · {html.escape(f.get('check_id') or '')}</div>"
|
|
f"<div style='font-size:14px;margin-top:4px;'>"
|
|
f"<strong>{html.escape(f.get('title') or '')}</strong></div>"
|
|
f"<div style='font-size:12px;color:#64748b;margin-top:2px;'>"
|
|
f"{html.escape(f.get('norm') or '')}</div>"
|
|
f"<div style='font-size:12px;color:#475569;margin-top:6px;'>"
|
|
f"<em>{html.escape(f.get('evidence') or '')}</em></div>"
|
|
f"<div style='font-size:13px;margin-top:8px;background:#dcfce7;"
|
|
f"padding:8px 10px;border-radius:4px;'>"
|
|
f"<strong>→ Empfehlung:</strong> "
|
|
f"{html.escape(f.get('recommended_action') or '')}</div>"
|
|
"</div>"
|
|
)
|
|
return (
|
|
"<div style='margin:24px 0;padding:16px;border-left:4px solid #dc2626;"
|
|
"background:#fef2f2;border-radius:4px;'>"
|
|
f"<h2 style='margin:0 0 8px;color:#7f1d1d;font-size:16px;'>"
|
|
f"🌐 Vertragsdoc auf Fremd-Domain ({len(findings)} Fall(e))"
|
|
"</h2>"
|
|
"<p style='margin:0 0 8px;font-size:12px;color:#475569;'>"
|
|
"Vertragsrelevante Dokumente liegen auf einer anderen Second-Level-"
|
|
"Domain als die Site. AVV-Pflicht + URL-Stabilitäts-Risiko."
|
|
"</p>"
|
|
+ "".join(cards) +
|
|
"</div>"
|
|
)
|