From d92dd3b5fce36b6a07e0d5a4ff8a8170f1af061b Mon Sep 17 00:00:00 2001 From: Benjamin Admin Date: Sat, 13 Jun 2026 16:38:38 +0200 Subject: [PATCH] feat(banner): Consent-Historie/Widerruf live erkennen (Borlabs-Stil, #62) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit consent_history.detect_consent_history: erkennt CMP-Anbieter (Borlabs/ Usercentrics/OneTrust/Cookiebot/…) aus Storage+Cookies, versionierten Consent (historie-fähig) + dauerhaftes Widerruf-/Einstellungs-Widget. consent_scanner ruft es in Phase A; scan_matrix_summary surft summary.consent_history; browser_cross_finding: positiver Befund wenn vorhanden, sonst Best-Practice-LOW („Nutzer sehen, wann sie welcher Version zugestimmt haben"); BrowserBehaviorView zeigt es im Engine-Detail. Tests: 7 (classify/versioned) + 2 Cross-Finding. Co-Authored-By: Claude Opus 4.7 --- .../agent/_components/BrowserBehaviorView.tsx | 14 ++- .../services/browser_cross_finding.py | 32 +++++++ .../tests/test_browser_cross_finding.py | 24 ++++- consent-tester/services/consent_history.py | 95 +++++++++++++++++++ consent-tester/services/consent_scanner.py | 10 ++ .../services/scan_matrix_summary.py | 2 + consent-tester/tests/test_consent_history.py | 35 +++++++ 7 files changed, 208 insertions(+), 4 deletions(-) create mode 100644 consent-tester/services/consent_history.py create mode 100644 consent-tester/tests/test_consent_history.py diff --git a/admin-compliance/app/sdk/agent/_components/BrowserBehaviorView.tsx b/admin-compliance/app/sdk/agent/_components/BrowserBehaviorView.tsx index cc08b510..fc2ff860 100644 --- a/admin-compliance/app/sdk/agent/_components/BrowserBehaviorView.tsx +++ b/admin-compliance/app/sdk/agent/_components/BrowserBehaviorView.tsx @@ -14,11 +14,15 @@ import React, { useEffect, useState } from 'react' type Finding = { text: string; severity: string; legal_ref?: string; service?: string } type Surface = { has_impressum_link?: boolean; has_dse_link?: boolean; banner_text_issues?: number } type Violations = { before_consent?: number; after_reject?: number; banner_text?: number } +type ConsentHistory = { + provider?: string; history_capable?: boolean; withdraw_ui?: boolean + versioned_consent?: boolean; stored?: boolean +} type Summary = { cookies_before_consent?: number; cookies_after_reject?: number reject_respected?: boolean; banner_detected?: boolean; banner_provider?: string banner_screenshot_b64?: string; surface?: Surface; banner_findings?: Finding[] - violations?: Violations + violations?: Violations; consent_history?: ConsentHistory } type Row = { profile_id: string; label: string; engine?: string; is_mobile?: boolean @@ -227,6 +231,14 @@ export function BrowserBehaviorView({ snapshotId }: { snapshotId: string }) { ) : (
Kein Banner-Screenshot erfasst.
)} + {selRow.summary?.consent_history && ( +
+ Einwilligungs-Historie:{' '} + {selRow.summary.consent_history.provider || 'kein bekanntes CMP erkannt'} + {selRow.summary.consent_history.history_capable ? ' · versioniert (nachvollziehbar)' : ''} + {selRow.summary.consent_history.withdraw_ui ? ' · Widerruf-Widget vorhanden' : ' · kein Widerruf-Widget erkannt'} +
+ )} {(selRow.summary?.banner_findings?.length ?? 0) > 0 ? (