No description
  • JavaScript 44.1%
  • HTML 28.3%
  • CSS 20%
  • PHP 6.3%
  • Shell 0.7%
  • Other 0.6%
Find a file
2026-05-07 18:16:21 +02:00
assets feat: verbessere Formatierung und Struktur der mail_diagnose.php für bessere Lesbarkeit und Benutzerfreundlichkeit 2026-05-07 16:32:54 +02:00
docker feat: ändere Dienstnamen in docker-compose.yml von ${APP_NAME} zu capturebarrierefreiheit 2026-05-07 18:16:21 +02:00
.gitignore feat: Enhance project structure and add Docker support 2026-05-07 16:03:18 +02:00
CodeRecap.md feat: aktualisiere CodeRecap.md mit neuen Abschnitten zur Tastaturzugänglichkeit und E-Mail-Template-Engine; überarbeite README.md für bessere Struktur und Klarheit 2026-05-07 17:55:59 +02:00
index.html feat: Enhance project structure and add Docker support 2026-05-07 16:03:18 +02:00
LICENSE Remove copyright notice from LICENSE 2025-10-20 23:21:33 +02:00
README.md feat: aktualisiere CodeRecap.md mit neuen Abschnitten zur Tastaturzugänglichkeit und E-Mail-Template-Engine; überarbeite README.md für bessere Struktur und Klarheit 2026-05-07 17:55:59 +02:00

Capture Barrierefrei

Eine barrierefreie Bot-Erkennungs- und Formularvalidierungslösung mit integrierter Formularerkennung und E-Mail-Versand-System.

Version License WCAG

Repository: git.nerdtech.info/L_cke_text/captureBarrierefrei

Inhaltsverzeichnis

Einführung

Capture Barrierefrei ist eine Alternative zu herkömmlichen CAPTCHA-Systemen, die barrierefrei gestaltet wurde. Das Projekt bietet ein Grundgerüst für eine agnostische Lösung zum Schutz von Webformularen vor Spam-Bots und automatisierten Angriffen, während es gleichzeitig die Zugänglichkeit für alle Nutzer, einschließlich solcher mit Beeinträchtigungen, gewährleistet.

Projektübersicht

Die Lösung besteht aus zwei Hauptmodulen:

  1. CaptureBarriereFrei: Erkennt automatisierte Bot-Zugriffe durch Verhaltensanalyse
  2. MailSender: Verarbeitet Formularübermittlungen und E-Mail-Versand mit Templateunterstützung

Beide Module sind so konzipiert, dass sie den Prinzipien der Barrierefreiheit entsprechen und mit Screenreadern sowie anderen assistiven Technologien kompatibel sind.

Architektur

Dateistruktur

├── assets/
│   ├── js/
│   │   ├── captureBarriereFrei/    # Bot-Erkennungs-Modul
│   │   │   ├── index.js            # Einstiegspunkt, exposes window.CaptureBarriereFrei
│   │   │   ├── core.js             # Kernfunktionalität
│   │   │   ├── botDetection.js     # Bot-Erkennungslogik
│   │   │   ├── formProtection.js   # Formularschutz
│   │   │   ├── formValidation.js   # Validierungsfunktionen
│   │   │   ├── ui.js               # UI-Komponenten + injizierte Styles (Dark/Light)
│   │   │   ├── utils.js            # Hilfsfunktionen
│   │   │   └── logger.js           # Logging-Funktionalität
│   │   └── mailSender/             # E-Mail-Versand-Modul
│   │       ├── index.js            # Einstiegspunkt, exposes window.MailSender
│   │       ├── core/               # Kernfunktionalität
│   │       └── utils/              # Hilfsfunktionen
│   ├── config/
│   │   ├── config.js               # Zentrale Konfiguration (window.FormularKonfiguration)
│   │   └── betreff-routing.json    # Subject-Dropdown + per-Subject Empfänger-Routing
│   ├── css/
│   │   ├── style.css               # Design System (Dark/Light, Akkordeon, Theme-Toggle)
│   │   └── form-styles.css         # Portables Basis-Stylesheet (nicht anfassen)
│   ├── php/
│   │   ├── send_mail.php           # Backend-Handler für POST-Anfragen
│   │   └── mail_diagnose.php       # Debug-Helper (nicht für Produktion)
│   └── templates/
│       ├── contact.html            # Benachrichtigungs-Mail an Seitenbetreiber
│       └── confirmation.html       # Bestätigungs-Mail an Nutzer
└── index.html                      # Showcase mit Akkordeon-Anleitung und Theme-Toggle
docker/
├── Dockerfile                      # php:8.2-apache + msmtp (Build-Kontext: Repo-Root)
├── docker-compose.yml              # Traefik-Labels, HTTPS, Security-Headers
├── entrypoint.sh                   # Schreibt /etc/msmtprc zur Laufzeit
└── .env.example                    # SMTP-Vorlage (nie committen)

Sicherheitskonzept

Das Sicherheitskonzept basiert auf einem mehrstufigen Ansatz — kein einzelner Mechanismus, sondern eine Kombination aus:

  • Verhaltensanalyse Mausbewegungen, Tastatureingaben, Scrollverhalten
  • Honeypot-Felder für Menschen unsichtbare Fallen, die Bots typischerweise befüllen
  • Zeitanalyse zu schnelles Ausfüllen deutet auf Automatisierung hin
  • Punkte-basiertes Scoring erst ab Score ≥ 40 wird der Submit freigegeben
  • Human-Verification-Checkbox faktisch Pflicht, da der Score ohne sie max. 32 erreicht
  • Server-seitige Empfänger-Whitelist verhindert, dass direkter POST-Zugriff beliebige Empfänger einschleust

Technischer Deep-Dive zu Score-Berechnung, Ladeablauf, Submit-Pfad und Template-Engine: → CodeRecap.md

Barrierefreiheit

Capture Barrierefrei wurde mit Fokus auf Zugänglichkeit entwickelt (WCAG 2.1 AA):

  1. Tastaturzugänglichkeit: Alle Funktionen sind vollständig per Tastatur bedienbar — inkl. der CAPTCHA-Checkbox (Tab → Space)
  2. Screenreader-Unterstützung: ARIA-Attribute und semantisches HTML
  3. Skip-Links: <a href="#main-content" class="skip-link"> + <main tabindex="-1"> (WCAG 2.4.1)
  4. Farben und Kontraste: Ausreichende Kontrastverhältnisse im Dark- und Light-Mode
  5. Fehlerfeedback: Klare, zugängliche Fehlermeldungen mit aria-describedby
  6. Fokus-Management: JS-gestützte Fokusindikatoren (.cbf-focused) und logische Tab-Reihenfolge; kein e.preventDefault() blockiert natives Tastaturverhalten
  7. Theme-neutral: Sowohl Dark- als auch Light-Mode erfüllen die Kontrastanforderungen

Pflichtattribute die nicht entfernt werden dürfen:

  • <select name="betreff"> braucht aria-required="true" und aria-invalid="false"
  • Jedes Eingabefeld braucht ein <label> und ein aria-describedby-Fehlerelement

Installationsanleitung

  1. Dateien kopieren — folgende Ordner und Dateien ins Zielprojekt übernehmen (Struktur beibehalten):

    assets/js/captureBarriereFrei/
    assets/js/mailSender/
    assets/config/config.js
    assets/config/betreff-routing.json
    assets/css/form-styles.css
    assets/php/send_mail.php
    assets/templates/contact.html
    assets/templates/confirmation.html
    

    Nicht kopieren: assets/php/mail_diagnose.php, assets/templates/helper.js, index.html (Showcase)

  2. Skripte einbinden — Reihenfolge in <body> einhalten (Module vor Config):

    <!-- Module zuerst (laden asynchron) -->
    <script type="module" src="assets/js/captureBarriereFrei/index.js"></script>
    <script type="module" src="assets/js/mailSender/index.js"></script>
    
    <!-- Konfiguration zuletzt (nutzt window.CaptureBarriereFrei + window.MailSender) -->
    <script src="assets/config/config.js"></script>
    <script>
      document.addEventListener('DOMContentLoaded', function () {
        window.FormularKonfiguration.initialisiere();
      });
    </script>
    
  3. Formular vorbereiten:

    <form id="kontaktFormular" method="post" class="protected" data-template="kontakt">
      <!-- Formularfelder -->
    </form>
    

    class="protected" aktiviert den automatischen Bot-Schutz. data-template gibt an, welche Template-Konfiguration aus config.js verwendet wird. Der <select name="betreff"> wird dynamisch aus betreff-routing.json befüllt — keine <option>-Elemente manuell eintragen.

  4. PHP-Backend einrichten: Sicherstellen, dass send_mail.php auf dem Server PHP mail() oder SMTP nutzen kann. Mit mail_diagnose.php lässt sich die Serverkonfiguration prüfen (danach vom Server entfernen).

  5. Theme-Switch (optional): Das <html>-Element trägt immer entweder data-theme="dark" oder data-theme="light" — nie keines von beidem. Das aktive Theme wird in localStorage unter cbf-theme gespeichert. Ohne gespeicherten Wert folgt der Switch der Systempräferenz (prefers-color-scheme).

    FOUC-Prevention im <head> (vor dem ersten <style>):

    <script>
      (function () {
        var stored = localStorage.getItem('cbf-theme');
        var prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
        var theme = stored || (prefersDark ? 'dark' : 'light');
        document.documentElement.setAttribute('data-theme', theme);
      })();
    </script>
    

    Alle CSS Custom Properties in style.css sowie die per ensureStyles() injizierten Checkbox-Styles in ui.js reagieren auf dieses Attribut.

Konfiguration

Die Hauptkonfiguration erfolgt in assets/config/config.js:

window.FormularKonfiguration = {
    empfaenger: 'ihre-email@domain.de',
    betreff: 'Neue Nachricht vom Kontaktformular',
    endpoint: 'assets/php/send_mail.php',
    thresholdScore: 40,          // Bot-Score-Schwellenwert (Standard: 40)
    DEBUGGING: false,            // true = verbose console logging
    // ...weitere Einstellungen für Templates, Dateiuploads etc.
};

Das Subject-Dropdown und das Empfänger-Routing werden in assets/config/betreff-routing.json gepflegt:

[
  { "wert": "anfrage", "bezeichnung": "Allgemeine Anfrage", "empfaenger": "info@domain.de" },
  { "wert": "support", "bezeichnung": "Support",            "empfaenger": "support@domain.de" }
]

E-Mail-Zustellbarkeit

Damit Kontaktanfragen sicher ankommen und nicht im Spam landen, sind ein paar einfache Einstellungen auf dem Mailserver und in der Domain notwendig. Das klingt technischer als es ist die meisten Hoster bieten dafür fertige Assistenten im Control Panel an.

Domain-Einstellungen (empfohlen)

Maßnahme Was es tut Priorität
SPF-Record Erlaubt deinem Server, E-Mails für deine Domain zu senden verhindert Spoofing Hoch
DKIM-Signatur Digitale Unterschrift, die beweist, dass die Mail wirklich von dir kommt Hoch
DMARC-Record Gibt Mailservern an, wie mit Mails umzugehen ist, die SPF/DKIM nicht bestehen Mittel

Beispiel-DNS-Einträge (Werte bei deinem Hoster anpassen):

# SPF  erlaube deinem Mailserver (IP oder Hostname anpassen)
TXT  @  "v=spf1 mx a include:dein-mailserver.de ~all"

# DMARC  optionale Benachrichtigungs-Mail anpassen
TXT  _dmarc  "v=DMARC1; p=quarantine; rua=mailto:dmarc@deinedomain.de"

Den DKIM-Key generiert dein Mailserver (z. B. Postfix + OpenDKIM) der öffentliche Schlüssel kommt dann als TXT-Record in die DNS-Zone.

Absenderadresse (SMTP_FROM)

Die Absenderadresse in docker/.env sollte auf derselben Domain liegen wie die Website:

# Gut  Domain stimmt überein, SPF/DKIM greifen
SMTP_FROM=kontakt@deinedomain.de

# Problematisch  fremde Domain, hohe Spam-Wahrscheinlichkeit
SMTP_FROM=irgendwas@gmail.com

Hinweis für Empfänger: Wenn du Kontaktanfragen auf eine persönliche Adresse weiterleitest, füge die Absenderadresse (SMTP_FROM) zum Adressbuch deines Mailprogramms hinzu. Viele Spam-Filter lernen daraus und stufen künftige Mails korrekt ein.

Warum landen Mails trotzdem im Spam?

Häufige Ursachen und Lösungen:

  1. Kein SPF/DKIM → DNS-Records wie oben beschrieben einrichten
  2. From-Header ≠ AbsenderdomainSMTP_FROM und Mailserver-Domain angleichen
  3. Shared-Hosting-IP auf Sperrliste → IP-Reputation bei MXToolbox prüfen; ggf. dedizierten Mailserver nutzen
  4. Kein Reverse-DNS (PTR-Record) → Beim Hoster einen PTR-Record für die Server-IP einrichten lassen
  5. Neue Domain / neue IP → E-Mail-Verkehr langsam aufbauen ("Warm-up"), nicht sofort viele Mails senden

Schnelltest nach dem Deployment

mail_diagnose.php ist durch ein Secret-Token geschützt und funktioniert auf Shared Hosting und Docker gleichermaßen keine Serverkonfiguration nötig.

Einmalig: Token setzen

Öffne assets/php/mail_diagnose.php und ersetze BITTE_AENDERN durch einen eigenen zufälligen String:

# Zufälliges Token generieren (Linux/macOS)
openssl rand -hex 16
// assets/php/mail_diagnose.php  Zeile ~13
define('DIAGNOSE_TOKEN', 'dein-generiertes-token-hier');

Aufruf im Browser:

https://deinedomain.de/assets/php/mail_diagnose.php?token=dein-generiertes-token-hier

Docker (alternativ direkt im Container):

docker exec -it <container-name> curl "localhost/assets/php/mail_diagnose.php?token=dein-token"

Nach der Diagnose: Token zurücksetzen (BITTE_AENDERN) oder Datei vom Server entfernen.

Nutzungsbeispiele

Einfache Implementierung:

<form id="kontaktFormular" class="protected" data-template="kontakt">
  <div class="form-group">
    <label for="name">Name</label>
    <input type="text" id="name" name="name" required aria-describedby="name-error">
    <span id="name-error" class="error-message" aria-live="polite"></span>
  </div>
  <div class="form-group">
    <label for="email">E-Mail</label>
    <input type="email" id="email" name="email" required aria-describedby="email-error">
    <span id="email-error" class="error-message" aria-live="polite"></span>
  </div>
  <div class="form-group">
    <label for="nachricht">Nachricht</label>
    <textarea id="nachricht" name="nachricht" required aria-describedby="nachricht-error"></textarea>
    <span id="nachricht-error" class="error-message" aria-live="polite"></span>
  </div>
  <button type="submit">Absenden</button>
</form>

Benutzerdefinierte Konfiguration:

const captureConfig = {
  formSelectors: '#meinFormular',
  minTimeToFill: 5000,    // 5 Sekunden
  thresholdScore: 50      // Höherer Schwellenwert für mehr Sicherheit
};

const mailConfig = {
  recipient: 'team@domain.de',
  subject: 'Kontaktanfrage Website',
  endpoint: 'mein-handler.php'
};

const captureInstance = new CaptureBarriereFrei(captureConfig);
const mailSender = new MailSender(mailConfig);

Dev-Server starten (Pflicht — file:// bricht fetch() für JSON/Templates/PHP):

# Python (im Projektordner)
python3 -m http.server 8080

# Dann im Browser öffnen:
# http://localhost:8080

Showcase

index.html ist die interaktive Demo-Seite des Projekts. Sie zeigt alle Features live im Browser — kein Build-Schritt nötig.

Was die Showcase-Seite enthält:

  • Live-Kontaktformular mit aktivem Bot-Schutz, Human-Verification-Checkbox und barrierefreier Validierung
  • Feature-Cards (12 Stück, 6 davon hinter „Mehr anzeigen"): Überblick über alle Kernfunktionen
  • Dark/Light-Mode-Toggle mit FOUC-Prevention und localStorage-Persistenz
  • Responsive Burger-Navigation (Breakpoint 768 px) mit Full-Screen-Overlay, Focus-Trap und Escape-Key-Unterstützung
  • Akkordeon-Anleitung mit Schritt-für-Schritt-Installationshinweisen
  • DSGVO-Abschnitt mit Erläuterungen zu Art. 25 (Privacy by Design) und Art. 32 (TLS/HTTPS)

Showcase lokal starten:

# Im Projektordner
python3 -m http.server 8080
# → http://localhost:8080

file:// ist nicht ausreichend — fetch() für JSON-Routing und HTML-Templates erfordert HTTP.

Docker-Deployment

Das docker/-Verzeichnis enthält alles für den produktiven Betrieb hinter einem Traefik-Reverse-Proxy mit automatischem Let's-Encrypt-Zertifikat.

docker/
├── Dockerfile          ← php:8.2-apache + msmtp (Build-Kontext: Repo-Root)
├── docker-compose.yml  ← Traefik-Labels, HTTPS, Security-Headers (alle Domains/Namen via ENV)
├── entrypoint.sh       ← Schreibt /etc/msmtprc zur Laufzeit
└── .env.example        ← Vorlage für alle Variablen (nie committen)

Einmaliges Setup:

# 1. .env aus der Vorlage anlegen und Werte eintragen
cp docker/.env.example docker/.env
# Pflichtfelder in docker/.env:
#   APP_NAME       Container-Name + Traefik-Bezeichner  (z. B. myapp)
#   APP_DOMAIN     Öffentliche Domain                   (z. B. example.com)
#   SMTP_HOST      Mailserver-Hostname
#   SMTP_PORT      587 (STARTTLS) oder 465 (SSL)
#   SMTP_FROM      Absenderadresse
#   SMTP_USER      SMTP-Benutzername
#   SMTP_PASSWORD  SMTP-Passwort

# 2. Container bauen und starten (vom Repo-Root aus)
docker compose -f docker/docker-compose.yml up -d --build

Einmaliges Setup:

# 1. .env aus der Vorlage anlegen und Werte eintragen
cp docker/.env.example docker/.env
# → SMTP_HOST, SMTP_PORT, SMTP_FROM, SMTP_USER, SMTP_PASSWORD setzen

# 2. Container bauen und starten (vom Repo-Root aus)
docker compose -f docker/docker-compose.yml up -d --build

Sicherheitshinweise:

  • docker/.env ist in .gitignore eingetragen und landet niemals im Repository.
  • entrypoint.sh schreibt /etc/msmtprc erst beim Containerstart aus den ENV-Variablen — keine Credentials im Image-Layer.
  • Das Dockerfile entfernt docker/, README.md, AGENTS.md und .gitignore aus dem Web-Root, sodass nur die Anwendungsdateien unter /var/www/html/ erreichbar sind.

Voraussetzungen auf dem Host:

  • Docker + Docker Compose v2
  • Laufender Traefik-Container im externen Netzwerk traefik-public mit konfiguriertem letsencrypt-Certresolver
  • DNS-Eintrag für allyform.jpboehm.de zeigt auf den Host

TODO und Überlegungen

  • Umgebungsvariablen / .env-Support für Serverkonfiguration
  • PHP-Payload in Base64 zur Verschleierung sensibler Daten
  • Dynamische, nichtlineare Score-Berechnung (Jitter, Interaktionsdichte):
    function scoreMausbewegung(bewegungen) {
      if (bewegungen === 0)  return 0;
      if (bewegungen < 5)   return 2;
      if (bewegungen < 15)  return 6;
      return 10;
    }
    
  • Erweiterte Verhaltensanalyse: Tipp-Rhythmus, Pause-Muster, Scroll-Jitter

Lizenz

Dieses Projekt steht unter der MIT-Lizenz. Siehe LICENSE für Details.