Transfer von GitLab

This commit is contained in:
Florian Otto
2026-04-13 23:59:49 +02:00
parent 8f3f5fd1cf
commit c4651e518d
33 changed files with 1504 additions and 1 deletions
+27
View File
@@ -0,0 +1,27 @@
# Node.js / Standard-Entwicklungsdateien
node_modules/
dist/
build/
.env
# Editor-Dateien
*.log
*.swp
*.swo
*.tmp
.idea/
.vscode/
.DS_Store
# Browser-Erweiterung spezifisch
.sass-cache/
.cache/
#*.zip
# Betriebssystem-Cache
Thumbs.db
ehthumbs.db
Desktop.ini
# Andere temporäre Dateien
*.bak
+21
View File
@@ -0,0 +1,21 @@
# 📋 Changelog
Format:
- **[Version]** - Datum
- Kategorie: Beschreibung
---
## [0.0.1] - 2025-04-28
### Hinzugefügt
- Erstveröffentlichung von CookieKop (Beta-Version).
- Screenshot-Funktion zum Erfassen von Webseiten mit Cookie-Verstößen.
- Automatische E-Mail-Erstellung an Datenschutzbehörden.
- Auswahl des Bundeslandes in den Optionen.
- Lokale Speicherung aller Daten ohne Serververbindung.
- Optionaler Projektbanner in E-Mails.
### Geplant
- Erstellung einer PDF-Meldung.
- Teilen von anonymisierten Statistiken (nur mit aktiver Zustimmung).
+16
View File
@@ -0,0 +1,16 @@
Creative Commons Lizenzvertrag
CookieKop (c) 2025 1337gut und Mitwirkende
Dieses Werk ist lizenziert unter der Creative Commons Namensnennung - Nicht-kommerziell - Weitergabe unter gleichen Bedingungen 4.0 International Lizenz (CC BY-NC-SA 4.0).
Du darfst:
- Teilen — das Material in jedwedem Format oder Medium vervielfältigen und weiterverbreiten
- Bearbeiten — das Material remixen, verändern und darauf aufbauen
Unter den folgenden Bedingungen:
- Namensnennung — Du musst angemessene Urheber- und Rechteangaben machen.
- Nicht kommerziell — Du darfst das Material nicht für kommerzielle Zwecke nutzen.
- Weitergabe unter gleichen Bedingungen — Wenn du das Material veränderst, musst du deine Beiträge unter derselben Lizenz verbreiten.
Lizenzdetails: https://creativecommons.org/licenses/by-nc-sa/4.0/deed.de
+116 -1
View File
@@ -1,2 +1,117 @@
# Cookiekop
# CookieKop
![Logo](icons/logo_alt.png)
CookieKop ist ein datenschutzfreundliches Open-Source-Plugin, um Webseiten mit rechtswidrigen Cookie-Bannern schnell und unkompliziert zu melden.
## 🔹 Funktionen
- 📸 Screenshot erstellen: Speichere Screenshots von Webseiten mit problematischen Cookie-Bannern.
- 📧 E-Mail-Vorbereitung: Erzeuge eine fertige E-Mail an die zuständige Datenschutzbehörde deines Bundeslandes.
- 🛡️ Projektbanner (optional): Automatischer Hinweis auf CookieKop am Ende der E-Mail.
- 🔒 Datenschutzfreundlich: Alle Daten werden ausschließlich lokal gespeichert. Keine externe Serverkommunikation, kein Tracking.
- 🏛️ Bundeslandauswahl: CookieKop findet automatisch die richtige Behörde für dein Bundesland.
## 🚧 Geplante Funktionen
- 📝 Erstellung einer PDF-Datei mit allen Meldungsdaten (aktuell deaktiviert).
- 📈 Teilen von anonymisierten Statistiken (nur mit aktiver Zustimmung, aktuell deaktiviert).
## ❌ Bekannte Fehler
- 🦊 Plugin läuft noch nicht in Firefox (Unterstützung ist hier herzlich willkommen!)
## 📦 Installation lokal
### Für Chromium-basierte Browser (Chrome, Edge, Brave, Vivaldi)
1. ZIP herunterladen
- Entweder eine Release-ZIP von GitLab herunterladen (zum Beispiel `cookiekop_v0.0.1_chromium.zip`),
- oder eine aktuelle ZIP selbst erstellen (siehe Abschnitt "ZIP selbst erstellen").
2. ZIP entpacken
- Entpacke die ZIP-Datei in einen beliebigen Ordner auf deinem Computer.
3. Erweiterungen-Seite öffnen
- Gehe zu: `chrome://extensions/`
- Entwicklermodus oben rechts aktivieren.
4. Entpackte Erweiterung laden
- Klicke auf "Entpackte Erweiterung laden".
- Wähle den entpackten CookieKop-Ordner aus.
### Für Mozilla Firefox
1. ZIP herunterladen
- Entweder eine Release-ZIP von GitLab herunterladen (zum Beispiel `cookiekop_v0.0.1_firefox.zip`),
- oder eine aktuelle ZIP selbst erstellen (siehe Abschnitt "ZIP selbst erstellen").
2. ZIP entpacken
- Entpacke die ZIP-Datei in einen beliebigen Ordner auf deinem Computer.
3. Erweiterung temporär laden
- Öffne Firefox und gehe zu: `about:debugging#/runtime/this-firefox`
- Klicke auf "Temporäres Add-on laden".
- Wähle die `manifest.json` Datei im entpackten CookieKop-Ordner aus.
Hinweis: In Firefox bleibt die Erweiterung nur bis zum nächsten Browserneustart aktiv.
## 📦 ZIP selbst erstellen (optional)
Wenn du keine fertige ZIP-Datei verwenden möchtest, kannst du die ZIP-Dateien auch selbst erstellen.
1. Terminal oder Konsole öffnen (Git Bash, macOS Terminal, Linux Terminal).
2. In den Projektordner wechseln:
```bash
cd /pfad/zum/cookiekop/
```
3. Master-Skript ausführen:
```bash
./build_all_zips.sh
```
Das Skript erstellt automatisch:
- `cookiekop_vX.Y.Z_chromium.zip`
- `cookiekop_vX.Y.Z_firefox.zip`
Die ZIP-Dateien befinden sich anschließend im Projektordner und können wie oben beschrieben installiert werden.
## 📜 Lizenz
Dieses Projekt steht unter der Creative Commons BY-NC-SA 4.0 Lizenz.
- Namensnennung erforderlich ("CookieKop by 1337gut und Mitwirkende").
- Keine kommerzielle Nutzung erlaubt.
- Veränderungen und Weiterentwicklungen müssen unter gleicher Lizenz veröffentlicht werden.
Der vollständige Lizenztext liegt unter `/LICENSE`.
## 📣 Haftungsausschluss
Es wurde größtmögliche Sorgfalt auf die Entwicklung und rechtliche Konformität gelegt.
Dennoch erfolgt die Nutzung auf eigene Verantwortung.
Es wird keine Haftung für eventuelle Schäden, Fehlfunktionen oder rechtliche Folgen übernommen.
## 🙌 Mitmachen
CookieKop ist ein Community-Projekt.
Fehler gefunden? Ideen für neue Features?
Erstelle gerne Issues oder Merge Requests auf GitLab!
### 💬 Feedback und Fehler melden
Dein Feedback hilft uns, CookieKop noch besser zu machen!
Wenn du einen Fehler gefunden hast oder eine Idee zur Verbesserung hast,
erstelle bitte ein [neues Issue mit unserem Feedback-Formular](https://gitlab.com/1337gut/cookiekop/-/issues/new?issue[template]=Feedback).
Vielen Dank für deine Unterstützung! 🚀
## 📢 Hinweis
CookieKop befindet sich derzeit in der Beta-Phase (Version 0.0.1).
Funktionen wie die PDF-Erstellung und das Teilen von Statistiken sind geplant, aber aktuell deaktiviert.
## Disclaimer: KI-Nutzung
Dieses Plugin wurde unter Mitwirkung von ChatGPT erstellt, da meine Programmierkenntnisse nicht ausreichen, um das alleine zu schaffen.
+3
View File
@@ -0,0 +1,3 @@
chrome.runtime.onInstalled.addListener(() => {
console.log("CookieKop wurde erfolgreich installiert.");
});
+74
View File
@@ -0,0 +1,74 @@
# Datenschutzbehörden Deutschland (Stand: 2025)
# Quelle: Offizielle Webseiten der Landesdatenschutzbehörden und BfDI (Bundesbeauftragter für den Datenschutz und die Informationsfreiheit)
Baden-Württemberg
E-Mail: poststelle@lfdi.bwl.de
Website: https://www.baden-wuerttemberg.datenschutz.de/
Bayern (Landesamt für Datenschutzaufsicht - Unternehmen/Private)
E-Mail: poststelle@lda.bayern.de
Website: https://www.lda.bayern.de/
Bayern (Landesbeauftragter für den Datenschutz - öffentliche Stellen)
E-Mail: poststelle@datenschutz-bayern.de
Website: https://www.datenschutz-bayern.de/
Berlin
E-Mail: mailbox@datenschutz-berlin.de
Website: https://www.datenschutz-berlin.de/
Brandenburg
E-Mail: poststelle@lda.brandenburg.de
Website: https://www.lda.brandenburg.de/
Bremen
E-Mail: office@datenschutz.bremen.de
Website: https://www.datenschutz.bremen.de/
Hamburg
E-Mail: mailbox@datenschutz.hamburg.de
Website: https://www.datenschutz-hamburg.de/
Hessen
E-Mail: poststelle@datenschutz.hessen.de
Website: https://datenschutz.hessen.de/
Mecklenburg-Vorpommern
E-Mail: info@datenschutz-mv.de
Website: https://www.datenschutz-mv.de/
Niedersachsen
E-Mail: poststelle@lfd.niedersachsen.de
Website: https://lfd.niedersachsen.de/
Nordrhein-Westfalen
E-Mail: poststelle@ldi.nrw.de
Website: https://www.ldi.nrw.de/
Rheinland-Pfalz
E-Mail: poststelle@datenschutz.rlp.de
Website: https://www.datenschutz.rlp.de/
Saarland
E-Mail: poststelle@datenschutz.saarland.de
Website: https://datenschutz.saarland.de/
Sachsen
E-Mail: saechsdsb@slt.sachsen.de
Website: https://www.saechsdsb.de/
Sachsen-Anhalt
E-Mail: poststelle@lfd.sachsen-anhalt.de
Website: https://datenschutz.sachsen-anhalt.de/
Schleswig-Holstein (ULD)
E-Mail: mail@datenschutzzentrum.de
Website: https://www.datenschutzzentrum.de/
Thüringen
E-Mail: poststelle@datenschutz.thueringen.de
Website: https://www.datenschutz.thueringen.de/
Bund (BfDI - Telekommunikation, Post, Bundesbehörden)
E-Mail: poststelle@bfdi.bund.de
Website: https://www.bfdi.bund.de/
+95
View File
@@ -0,0 +1,95 @@
#!/bin/bash
# Exit bei Fehler
set -e
# --- Prüfen, ob "zip" installiert ist ---
if ! command -v zip &> /dev/null
then
echo "❌ Fehler: 'zip' ist nicht installiert."
echo "Bitte installiere 'zip', z.B. unter Ubuntu: sudo apt install zip"
exit 1
fi
# Versionsnummer aus manifest.json auslesen
VERSION=$(grep '"version"' manifest.json | head -n 1 | sed -E 's/.*"([0-9]+\.[0-9]+\.[0-9]+)".*/\1/')
echo "Gefundene Version: $VERSION"
# Variablen
CHROMIUM_ZIPNAME="cookiekop_v${VERSION}_chromium.zip"
FIREFOX_ZIPNAME="cookiekop_v${VERSION}_firefox.zip"
# Temp-Ordner vorbereiten
TEMPDIR_CHROMIUM="temp_cookiekop_chromium"
TEMPDIR_FIREFOX="temp_cookiekop_firefox"
rm -f $CHROMIUM_ZIPNAME $FIREFOX_ZIPNAME
rm -rf $TEMPDIR_CHROMIUM $TEMPDIR_FIREFOX
mkdir -p $TEMPDIR_CHROMIUM
mkdir -p $TEMPDIR_FIREFOX
# --- Chromium Build ---
cp manifest.json popup.html popup.js options.html options.js background.js README.md LICENSE "$TEMPDIR_CHROMIUM/"
cp -r util "$TEMPDIR_CHROMIUM/"
cp -r data "$TEMPDIR_CHROMIUM/"
cp -r styles "$TEMPDIR_CHROMIUM/"
cp -r icons "$TEMPDIR_CHROMIUM/"
cp -r libs "$TEMPDIR_CHROMIUM/"
cd $TEMPDIR_CHROMIUM
zip -r ../$CHROMIUM_ZIPNAME *
cd ..
# --- Firefox Build ---
cp popup.html popup.js options.html options.js background.js README.md LICENSE "$TEMPDIR_FIREFOX/"
cp -r util "$TEMPDIR_FIREFOX/"
cp -r data "$TEMPDIR_FIREFOX/"
cp -r styles "$TEMPDIR_FIREFOX/"
cp -r icons "$TEMPDIR_FIREFOX/"
cp -r libs "$TEMPDIR_FIREFOX/"
# Temporäres Firefox-spezifisches manifest.json erstellen
cat << EOF > $TEMPDIR_FIREFOX/manifest.json
{
"manifest_version": 2,
"name": "CookieKop",
"version": "${VERSION}",
"description": "Melde rechtswidrige Cookie-Banner schnell und einfach.",
"background": {
"scripts": ["background.js"],
"persistent": false
},
"browser_action": {
"default_popup": "popup.html",
"default_icon": "icons/icon48.png"
},
"permissions": [
"storage",
"activeTab",
"tabs",
"downloads"
],
"options_ui": {
"page": "options.html",
"open_in_tab": true
},
"icons": {
"48": "icons/icon48.png",
"128": "icons/icon128.png"
}
}
EOF
# ZIP-Datei für Firefox erstellen
cd $TEMPDIR_FIREFOX
zip -r ../$FIREFOX_ZIPNAME *
cd ..
# Temp-Ordner löschen
rm -rf $TEMPDIR_CHROMIUM $TEMPDIR_FIREFOX
# Erfolgsmeldung
echo "✅ Erfolgreich erstellt:"
echo "$CHROMIUM_ZIPNAME"
echo "$FIREFOX_ZIPNAME"
+29
View File
@@ -0,0 +1,29 @@
#!/bin/bash
# Setze Variablen
ZIPNAME="cookiekop_chromium.zip"
TEMPDIR="temp_cookiekop_chromium"
# Alte ZIP löschen
rm -f $ZIPNAME
# Temp-Ordner erstellen
mkdir -p $TEMPDIR
# Wichtige Dateien kopieren
cp manifest.json popup.html popup.js options.html options.js background.js README.md LICENSE $TEMPDIR/
cp -r util $TEMPDIR/
cp -r data $TEMPDIR/
cp -r styles $TEMPDIR/
cp -r icons $TEMPDIR/
cp -r libs $TEMPDIR/
# In Temp-Ordner wechseln und zippen
cd $TEMPDIR
zip -r ../$ZIPNAME *
cd ..
# Temp-Ordner löschen
rm -rf $TEMPDIR
echo "Chromium-ZIP erfolgreich erstellt: $ZIPNAME"
+29
View File
@@ -0,0 +1,29 @@
#!/bin/bash
# Setze Variablen
ZIPNAME="cookiekop_firefox.zip"
TEMPDIR="temp_cookiekop"
# Alte ZIP löschen
rm -f $ZIPNAME
# Temp-Ordner erstellen
mkdir -p $TEMPDIR
# Wichtige Dateien kopieren
cp manifest.json popup.html popup.js options.html options.js background.js README.md LICENSE $TEMPDIR/
cp -r util $TEMPDIR/
cp -r data $TEMPDIR/
cp -r styles $TEMPDIR/
cp -r icons $TEMPDIR/
cp -r libs $TEMPDIR/
# In Temp-Ordner wechseln und zippen
cd $TEMPDIR
zip -r ../$ZIPNAME *
cd ..
# Temp-Ordner löschen
rm -rf $TEMPDIR
echo "Firefox-ZIP erfolgreich erstellt: $ZIPNAME"
Binary file not shown.
Binary file not shown.
+104
View File
@@ -0,0 +1,104 @@
[
{
"bundesland": "Baden-Württemberg",
"behoerde": "Der Landesbeauftragte für den Datenschutz und die Informationsfreiheit",
"email": "poststelle@lfdi.bwl.de",
"website": "https://www.baden-wuerttemberg.datenschutz.de/"
},
{
"bundesland": "Bayern",
"behoerde": "Bayerisches Landesamt für Datenschutzaufsicht",
"email": "poststelle@lda.bayern.de",
"website": "https://www.lda.bayern.de/"
},
{
"bundesland": "Berlin",
"behoerde": "Berliner Beauftragte für Datenschutz und Informationsfreiheit",
"email": "mailbox@datenschutz-berlin.de",
"website": "https://www.datenschutz-berlin.de/"
},
{
"bundesland": "Brandenburg",
"behoerde": "Die Landesbeauftragte für den Datenschutz und für das Recht auf Akteneinsicht Brandenburg",
"email": "poststelle@lda.brandenburg.de",
"website": "https://www.lda.brandenburg.de/"
},
{
"bundesland": "Bremen",
"behoerde": "Der Landesbeauftragte für Datenschutz und Informationsfreiheit",
"email": "office@datenschutz.bremen.de",
"website": "https://www.datenschutz.bremen.de/"
},
{
"bundesland": "Hamburg",
"behoerde": "Der Hamburgische Beauftragte für Datenschutz und Informationsfreiheit",
"email": "mailbox@datenschutz.hamburg.de",
"website": "https://www.datenschutz-hamburg.de/"
},
{
"bundesland": "Hessen",
"behoerde": "Hess. Beauftragter für Datenschutz und Informationsfreiheit",
"email": "poststelle@datenschutz.hessen.de",
"website": "https://datenschutz.hessen.de/"
},
{
"bundesland": "Mecklenburg-Vorpommern",
"behoerde": "Der Landesbeauftragte für Datenschutz und Informationsfreiheit Mecklenburg-Vorpommern",
"email": "info@datenschutz-mv.de",
"website": "https://www.datenschutz-mv.de/"
},
{
"bundesland": "Niedersachsen",
"behoerde": "Der Landesbeauftragte für den Datenschutz Niedersachsen",
"email": "poststelle@lfd.niedersachsen.de",
"website": "https://lfd.niedersachsen.de/"
},
{
"bundesland": "Nordrhein-Westfalen",
"behoerde": "Landesbeauftragte für Datenschutz und Informationsfreiheit in NRW",
"email": "poststelle@ldi.nrw.de",
"website": "https://www.ldi.nrw.de/"
},
{
"bundesland": "Rheinland-Pfalz",
"behoerde": "Der Landesbeauftragte für den Datenschutz und die Informationsfreiheit Rheinland-Pfalz",
"email": "poststelle@datenschutz.rlp.de",
"website": "https://www.datenschutz.rlp.de/"
},
{
"bundesland": "Saarland",
"behoerde": "Die Landesbeauftragte für Datenschutz und Informationsfreiheit",
"email": "poststelle@datenschutz.saarland.de",
"website": "https://datenschutz.saarland.de/"
},
{
"bundesland": "Sachsen",
"behoerde": "Sächsische Datenschutz- und Transparenzbeauftragte",
"email": "saechsdsb@slt.sachsen.de",
"website": "https://www.saechsdsb.de/"
},
{
"bundesland": "Sachsen-Anhalt",
"behoerde": "Landesbeauftragte für den Datenschutz",
"email": "poststelle@lfd.sachsen-anhalt.de",
"website": "https://datenschutz.sachsen-anhalt.de/"
},
{
"bundesland": "Schleswig-Holstein (ULD)",
"behoerde": "Unabhängiges Landeszentrum für Datenschutz Schleswig-Holstein",
"email": "mail@datenschutzzentrum.de",
"website": "https://www.datenschutzzentrum.de/"
},
{
"bundesland": "Thüringen",
"behoerde": "Thüringer Landesbeauftragter für den Datenschutz und die Informationsfreiheit",
"email": "poststelle@datenschutz.thueringen.de",
"website": "https://www.datenschutz.thueringen.de/"
},
{
"bundesland": "Bund",
"behoerde": "BfDI - Bundesbeauftragter für den Datenschutz und die Informationsfreiheit",
"email": "poststelle@bfdi.bund.de",
"website": "https://www.bfdi.bund.de/"
}
]
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

+398
View File
File diff suppressed because one or more lines are too long
+34
View File
@@ -0,0 +1,34 @@
{
"manifest_version": 3,
"name": "CookieKop",
"description": "Melde Webseiten mit rechtswidrigen Cookie-Bannern schnell, einfach und datenschutzfreundlich.",
"version": "0.0.1",
"permissions": [
"storage",
"activeTab",
"downloads",
"scripting"
],
"host_permissions": [
"<all_urls>"
],
"action": {
"default_popup": "popup.html",
"default_icon": {
"16": "icons/icon16.png",
"32": "icons/icon32.png",
"48": "icons/icon48.png",
"128": "icons/icon128.png"
}
},
"background": {
"service_worker": "background.js"
},
"options_page": "options.html",
"icons": {
"16": "icons/icon16.png",
"32": "icons/icon32.png",
"48": "icons/icon48.png",
"128": "icons/icon128.png"
}
}
+53
View File
@@ -0,0 +1,53 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<title>Einstellungen CookieKop</title>
<script src="util/constants.js"></script>
<script src="options.js" defer></script>
<link rel="stylesheet" href="styles/options.css">
</head>
<body>
<header>
<h1>Einstellungen</h1>
</header>
<section>
<label for="state-selector">Bundesland auswählen:</label>
<select id="state-selector">
<option value="">-- Bitte auswählen --</option>
<option value="Baden-Württemberg">Baden-Württemberg</option>
<option value="Bayern">Bayern</option>
<option value="Berlin">Berlin</option>
<option value="Brandenburg">Brandenburg</option>
<option value="Bremen">Bremen</option>
<option value="Hamburg">Hamburg</option>
<option value="Hessen">Hessen</option>
<option value="Mecklenburg-Vorpommern">Mecklenburg-Vorpommern</option>
<option value="Niedersachsen">Niedersachsen</option>
<option value="Nordrhein-Westfalen">Nordrhein-Westfalen</option>
<option value="Rheinland-Pfalz">Rheinland-Pfalz</option>
<option value="Saarland">Saarland</option>
<option value="Sachsen">Sachsen</option>
<option value="Sachsen-Anhalt">Sachsen-Anhalt</option>
<option value="Schleswig-Holstein">Schleswig-Holstein</option>
<option value="Thüringen">Thüringen</option>
<option value="Bund">Bund</option>
</select>
<!--<label for="pdf-path">Standard-Pfad für PDF-Dateien:</label>
<input type="text" id="pdf-path" placeholder="cookiekop/pdfs/">
<label for="screenshot-path">Standard-Pfad für Screenshots:</label>
<input type="text" id="screenshot-path" placeholder="cookiekop/screenshots/">
-->
<label><input type="checkbox" id="show-banner"> Projektbanner in E-Mail/PDF anzeigen</label>
<!-- Auszug nur für Statistikbereich -->
<label><input type="checkbox" id="share-stats" disabled> Anonymisierte Statistik teilen (geplant)</label>
<small>Diese Funktion wird in einer zukünftigen Version verfügbar sein.</small>
<button id="save-options">Einstellungen speichern</button>
</section>
</body>
</html>
+30
View File
@@ -0,0 +1,30 @@
// options.js
document.addEventListener("DOMContentLoaded", async () => {
const options = await loadOptions();
document.getElementById("state-selector").value = options.state || "";
document.getElementById("pdf-path").value = options.pdfPath || "cookiekop/pdfs/";
document.getElementById("screenshot-path").value = options.screenshotPath || "cookiekop/screenshots/";
document.getElementById("show-banner").checked = options.showBanner ?? true;
document.getElementById("share-stats").checked = options.shareStats ?? false;
document.getElementById("save-options").addEventListener("click", saveOptions);
});
// Optionen speichern
async function saveOptions() {
const options = {
state: document.getElementById("state-selector").value,
showBanner: document.getElementById("show-banner").checked
// pdfPath und screenshotPath werden NICHT mehr gespeichert!
};
await chrome.storage.local.set({ options });
alert("Einstellungen gespeichert!");
}
// Optionen laden
async function loadOptions() {
const result = await chrome.storage.local.get('options');
return result.options || {};
}
+43
View File
@@ -0,0 +1,43 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<title>Meldung erstellen CookieKop</title>
<script src="libs/jspdf.umd.min.js"></script>
<script src="util/constants.js"></script>
<script src="util/storage.js"></script>
<script src="popup.js" defer></script> <!-- WICHTIG: defer! -->
<link rel="stylesheet" href="styles/popup.css">
</head>
<body>
<header>
<h1 id="project-name"></h1>
</header>
<section>
<label>Aktuelle URL:</label>
<input type="text" id="current-url" readonly>
<label>Verstoß auswählen:</label>
<div id="violations"></div>
<label>Zusätzliche Hinweise:</label>
<textarea id="custom-note" rows="3" placeholder="Optionale Ergänzungen"></textarea>
<div class="actions">
<button id="screenshot-btn">Screenshot erstellen</button>
<!-- PDF-Button ausgegraut und Hinweis eingebaut -->
<button id="create-pdf-btn" disabled title="PDF-Funktion wird bald verfügbar sein.">PDF erstellen (geplant)</button>
<button id="create-email-btn">E-Mail vorbereiten</button>
<button id="open-options-btn">Einstellungen öffnen</button>
</div>
</section>
<footer>
<small id="project-banner"></small>
</footer>
</body>
</html>
+135
View File
@@ -0,0 +1,135 @@
// popup.js
document.addEventListener("DOMContentLoaded", async () => {
document.getElementById("project-name").innerText = PROJECT_NAME;
const options = await loadOptions();
const bannerElement = document.getElementById("project-banner");
if (bannerElement && (options.showBanner ?? SHOW_BANNER_DEFAULT)) {
bannerElement.innerText = `Erstellt mit ${PROJECT_NAME} deinem datenschutzfreundlichen Helfer gegen unerlaubte Cookie-Banner.`;
}
const [tab] = await chrome.tabs.query({ active: true, currentWindow: true });
document.getElementById("current-url").value = tab.url;
const violationsDiv = document.getElementById("violations");
VIOLATION_TYPES.forEach(type => {
const label = document.createElement("label");
label.innerHTML = `<input type="checkbox" value="${type}"> ${type}`;
violationsDiv.appendChild(label);
});
document.getElementById("screenshot-btn").addEventListener("click", createScreenshot);
// PDF-Funktion aktuell deaktiviert:
// document.getElementById("create-pdf-btn").addEventListener("click", preparePDF);
document.getElementById("create-email-btn").addEventListener("click", prepareEmail);
document.getElementById("open-options-btn").addEventListener("click", openOptions);
});
// Optionen laden
async function loadOptions() {
const result = await chrome.storage.local.get('options');
return result.options || {};
}
// Screenshot erstellen und speichern
async function createScreenshot() {
try {
const [tab] = await chrome.tabs.query({ active: true, currentWindow: true });
const imageUri = await chrome.tabs.captureVisibleTab(tab.windowId, { format: "png" });
const url = new URL(tab.url);
const domain = url.hostname.replace('www.', '');
const now = new Date();
const timestamp = now.getFullYear().toString()
+ String(now.getMonth() + 1).padStart(2, '0')
+ String(now.getDate()).padStart(2, '0')
+ String(now.getHours()).padStart(2, '0')
+ String(now.getMinutes()).padStart(2, '0');
const filename = `${timestamp}_${domain}.png`;
const response = await fetch(imageUri);
const blob = await response.blob();
const blobUrl = URL.createObjectURL(blob);
await chrome.downloads.download({
url: blobUrl,
filename: `cookiekop/screenshots/${filename}`, // Vorschlagpfad
saveAs: true
});
// Kein alert mehr notwendig!
} catch (error) {
console.error("Fehler beim Screenshot:", error);
alert("Screenshot konnte nicht gespeichert werden.");
}
}
// (PDF erstellen Funktion bleibt auskommentiert später aktivieren)
// E-Mail vorbereiten
async function prepareEmail() {
const url = document.getElementById("current-url").value;
const violations = Array.from(document.querySelectorAll('#violations input:checked')).map(input => input.value);
const note = document.getElementById("custom-note").value;
const options = await loadOptions();
let body = `Sehr geehrte Damen und Herren,\n\n`;
body += `ich möchte folgende Verstöße gegen die DSGVO im Zusammenhang mit dem Cookie-Banner melden:\n\n`;
violations.forEach(v => {
body += `- ${v}\n`;
});
body += `\nURL: ${url}\n`;
if (note) {
body += `\nZusätzliche Hinweise: ${note}\n`;
}
if (options.showBanner ?? true) {
body += `\n\nErstellt mit CookieKop https://gitlab.com/1337gut/cookiekop`;
}
body += `\n\nMit freundlichen Grüßen\n\n`;
const subject = encodeURIComponent("Meldung eines Cookie-Banner-Verstoßes");
const bodyEncoded = encodeURIComponent(body);
let recipient = "poststelle@lda.bayern.de"; // Fallback
if (options?.state) {
try {
const response = await fetch('data/datenschutzbehoerden.json');
const authorities = await response.json();
const found = authorities.find(entry => entry.bundesland === options.state);
if (found && found.email) {
recipient = found.email;
}
} catch (error) {
console.error("Fehler beim Laden der Behördenliste:", error);
}
}
const mailtoLink = `mailto:${recipient}?subject=${subject}&body=${bodyEncoded}`;
try {
await chrome.tabs.create({ url: mailtoLink });
} catch (error) {
console.error("Fehler beim Öffnen von mailto:", error);
fallbackCopyEmailText(body);
}
}
// Fallback: E-Mail-Text in Zwischenablage kopieren
function fallbackCopyEmailText(text) {
navigator.clipboard.writeText(text).then(() => {
alert("E-Mail-Text wurde kopiert. Bitte öffne dein E-Mail-Programm und füge ihn ein (Strg+V).");
}).catch(err => {
console.error("Kopieren fehlgeschlagen:", err);
alert("Fehler beim Kopieren des E-Mail-Texts.");
});
}
// Optionen-Seite öffnen
function openOptions() {
chrome.runtime.openOptionsPage();
}
+29
View File
@@ -0,0 +1,29 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<title>Statistik CookieKop</title>
<script src="util/constants.js"></script>
<script src="statistics.js" defer></script>
<link rel="stylesheet" href="styles/statistics.css">
</head>
<body>
<header>
<h1>Deine Statistik</h1>
</header>
<section>
<div id="stats">
<p>Gesendete Meldungen: <span id="report-count">0</span></p>
</div>
<div id="share-option">
<button id="share-stats-btn">Statistik anonym teilen</button>
</div>
</section>
<footer>
<small>CookieKop Datenschutzfreundlich</small>
</footer>
</body>
</html>
+32
View File
@@ -0,0 +1,32 @@
// statistics.js
document.addEventListener("DOMContentLoaded", async () => {
const count = await loadFromStorage('reportCount') || 0;
document.getElementById("report-count").innerText = count;
document.getElementById("share-stats-btn").addEventListener("click", shareStats);
});
// Statistik anonym teilen
async function shareStats() {
const options = await loadFromStorage('options');
if (!options?.shareStats) {
alert("Das Teilen von Statistiken ist deaktiviert.");
return;
}
const count = await loadFromStorage('reportCount') || 0;
const payload = {
reports: count,
browser: navigator.userAgent,
timestamp: new Date().toISOString()
};
try {
// Dummy Upload (kann später erweitert werden)
alert("Statistik erfolgreich (lokal simuliert) geteilt.");
} catch (error) {
console.error("Fehler beim Teilen der Statistik:", error);
alert("Fehler beim Senden der Statistik.");
}
}
+33
View File
@@ -0,0 +1,33 @@
/* styles/options.css */
body {
font-family: sans-serif;
padding: 10px;
width: 300px;
}
header h1 {
font-size: 20px;
margin-bottom: 10px;
}
label {
display: block;
margin-top: 10px;
font-weight: bold;
}
input[type="text"],
select {
width: 100%;
box-sizing: border-box;
margin-top: 5px;
}
button {
margin-top: 15px;
padding: 8px;
font-size: 14px;
cursor: pointer;
}
+49
View File
@@ -0,0 +1,49 @@
/* styles/popup.css */
body {
font-family: sans-serif;
padding: 10px;
width: 300px;
}
header h1 {
font-size: 20px;
margin-bottom: 10px;
}
label {
display: block;
margin-top: 10px;
font-weight: bold;
}
input[type="text"],
textarea {
width: 100%;
box-sizing: border-box;
margin-top: 5px;
}
.actions {
margin-top: 15px;
display: flex;
flex-direction: column;
gap: 5px;
}
button {
padding: 8px;
font-size: 14px;
cursor: pointer;
}
footer {
margin-top: 15px;
font-size: 10px;
text-align: center;
color: #666;
}
#project-banner {
display: none;
}
+35
View File
@@ -0,0 +1,35 @@
/* styles/statistics.css */
body {
font-family: sans-serif;
padding: 10px;
width: 300px;
}
header h1 {
font-size: 20px;
margin-bottom: 10px;
}
#stats p {
font-size: 16px;
margin: 10px 0;
}
#share-option {
margin-top: 20px;
}
button {
padding: 8px;
font-size: 14px;
cursor: pointer;
}
footer {
margin-top: 15px;
font-size: 10px;
text-align: center;
color: #666;
}
+23
View File
@@ -0,0 +1,23 @@
// constants.js
// Projektname und zentrale Konfigurationen
const PROJECT_NAME = "CookieKop";
// Standardwert: Soll der Banner angezeigt werden?
const SHOW_BANNER_DEFAULT = true;
// Standardwert: Soll die Statistik anonymisiert geteilt werden?
const SHARE_STATS_DEFAULT = false;
// (Platzhalter) URL für anonymen Statistik-Upload
const STATS_UPLOAD_URL = "https://your-stats-endpoint.example.com/upload"; // aktuell deaktiviert
// Verfügbare Cookie-Verstoßtypen
const VIOLATION_TYPES = [
"Kein 'Ablehnen'-Button sichtbar",
"Voreingestellte Zustimmung (Checkboxen vorausgefüllt)",
"Intransparente Sprache",
"Keine echte Auswahlmöglichkeit",
"Tracking startet vor Einwilligung",
"Andere (bitte in Kommentar beschreiben)"
];
+46
View File
@@ -0,0 +1,46 @@
// util/pdf.js
async function generatePDF(url, violations, note, screenshotDataUrl) {
const { jsPDF } = window.jspdf;
const doc = new jsPDF();
let y = 10;
doc.setFontSize(16);
doc.text("Cookie-Banner Verstoßmeldung", 10, y);
y += 10;
doc.setFontSize(12);
doc.text(`Datum: ${new Date().toLocaleString()}`, 10, y);
y += 10;
doc.text(`URL:`, 10, y);
doc.text(url, 30, y);
y += 10;
doc.text("Verstöße:", 10, y);
violations.forEach(v => {
y += 7;
doc.text(`- ${v}`, 15, y);
});
y += 10;
doc.text("Zusätzliche Hinweise:", 10, y);
y += 7;
const splitNote = doc.splitTextToSize(note || "Keine Angabe", 180);
doc.text(splitNote, 10, y);
y += splitNote.length * 7;
if (screenshotDataUrl) {
y += 10;
doc.text("Screenshot:", 10, y);
y += 5;
try {
doc.addImage(screenshotDataUrl, 'PNG', 10, y, 180, 100);
} catch (error) {
console.error("Fehler beim Einfügen des Screenshots ins PDF:", error);
}
}
doc.save('cookiekop_meldung.pdf');
}
+25
View File
@@ -0,0 +1,25 @@
// util/screenshot.js
// Macht einen Screenshot vom aktiven Tab und speichert ihn lokal
async function takeScreenshotAndStore() {
try {
const [tab] = await chrome.tabs.query({ active: true, currentWindow: true });
const imageUri = await chrome.tabs.captureVisibleTab(tab.windowId, { format: "png" });
await saveToStorage('screenshot', imageUri);
return imageUri;
} catch (error) {
console.error("Fehler beim Screenshot erstellen:", error);
throw error;
}
}
// Lädt den Screenshot aus dem Storage
async function loadScreenshot() {
return await loadFromStorage('screenshot');
}
// Löscht gespeicherten Screenshot
async function clearScreenshot() {
await removeFromStorage('screenshot');
}
+25
View File
@@ -0,0 +1,25 @@
// util/storage.js
// Speichert beliebige Daten in chrome.storage.local
async function saveToStorage(key, value) {
const data = {};
data[key] = value;
return chrome.storage.local.set(data);
}
// Holt Daten aus chrome.storage.local
async function loadFromStorage(key) {
const result = await chrome.storage.local.get(key);
return result[key];
}
// Löscht einen bestimmten Schlüssel aus dem Storage
async function removeFromStorage(key) {
return chrome.storage.local.remove(key);
}
// Löscht ALLE gespeicherten Daten (zurücksetzen)
async function clearStorage() {
return chrome.storage.local.clear();
}