diff --git a/src/background.js b/src/background.js index 6c1fd0e..8bd3791 100644 --- a/src/background.js +++ b/src/background.js @@ -125,6 +125,10 @@ async function handleVendorGetMessage(message, sender) { return handlePurgeUnlockedEvidenceRecordsMessage(); } + if (message.type === "purge_gvl_reference_data") { + return handlePurgeGvlReferenceDataMessage(); + } + if (message.type === "delete_all_evidence_database") { return handleDeleteAllEvidenceDatabaseMessage(); } @@ -1225,6 +1229,12 @@ async function handlePurgeUnlockedEvidenceRecordsMessage() { return purgeUnlockedEvidenceRecords(db); } +async function handlePurgeGvlReferenceDataMessage() { + const db = await openVendorGetDb(); + + return purgeGvlReferenceData(db); +} + function handleDeleteAllEvidenceDatabaseMessage() { return deleteVendorGetDatabase(); } diff --git a/src/background/db/db-constants.js b/src/background/db/db-constants.js index 12dae18..a2aebec 100644 --- a/src/background/db/db-constants.js +++ b/src/background/db/db-constants.js @@ -33,3 +33,16 @@ const VENDORGET_EVIDENCE_STORE_NAMES = [ VENDORGET_STORE_NAMES.gvlDataCategories, VENDORGET_STORE_NAMES.gvlVendorRelationships ]; + +const VENDORGET_GVL_REFERENCE_STORE_NAMES = [ + VENDORGET_STORE_NAMES.gvlRawEvidence, + VENDORGET_STORE_NAMES.gvlSnapshots, + VENDORGET_STORE_NAMES.gvlSnapshotEvents, + VENDORGET_STORE_NAMES.gvlVendors, + VENDORGET_STORE_NAMES.gvlPurposes, + VENDORGET_STORE_NAMES.gvlSpecialPurposes, + VENDORGET_STORE_NAMES.gvlFeatures, + VENDORGET_STORE_NAMES.gvlSpecialFeatures, + VENDORGET_STORE_NAMES.gvlDataCategories, + VENDORGET_STORE_NAMES.gvlVendorRelationships +]; diff --git a/src/background/db/db-retention.js b/src/background/db/db-retention.js index 6116b42..a561e0f 100644 --- a/src/background/db/db-retention.js +++ b/src/background/db/db-retention.js @@ -89,6 +89,32 @@ async function purgeUnlockedEvidenceRecords(db) { }); } +function purgeGvlReferenceData(db) { + return new Promise((resolve, reject) => { + const clearedStores = {}; + const tx = db.transaction(VENDORGET_GVL_REFERENCE_STORE_NAMES, "readwrite"); + + tx.onerror = () => reject(tx.error); + tx.onabort = () => reject(tx.error); + tx.oncomplete = () => { + resolve({ + success: true, + clearedStores + }); + }; + + for (const storeName of VENDORGET_GVL_REFERENCE_STORE_NAMES) { + const objectStore = tx.objectStore(storeName); + const countRequest = objectStore.count(); + + countRequest.onsuccess = () => { + clearedStores[storeName] = countRequest.result; + objectStore.clear(); + }; + } + }); +} + function buildGvlWorkspaceProtectionIndex(db) { return new Promise((resolve, reject) => { const protectedSnapshotSha256 = new Set(); diff --git a/src/data-maintenance/data-maintenance.css b/src/data-maintenance/data-maintenance.css index 7d6e199..54f738d 100644 --- a/src/data-maintenance/data-maintenance.css +++ b/src/data-maintenance/data-maintenance.css @@ -27,6 +27,7 @@ body { h1, h2, h3, +h4, p { margin: 0; } @@ -47,6 +48,11 @@ h3 { color: #e5edf5; } +h4 { + font-size: 13px; + color: #e5edf5; +} + p { max-width: 760px; font-size: 13px; @@ -87,6 +93,15 @@ p { background: #1f2937; } +.segment-action { + display: grid; + gap: 8px; + padding: 10px; + border: 1px solid #475569; + border-radius: 4px; + background: #172033; +} + .segment-status { width: fit-content; max-width: 100%; @@ -98,6 +113,23 @@ p { background: #172033; } +button { + width: fit-content; + max-width: 100%; + padding: 8px 10px; + border: 1px solid #475569; + border-radius: 4px; + font: inherit; + font-size: 13px; + color: #e5edf5; + background: #1f2937; +} + +button:disabled { + cursor: default; + opacity: 0.65; +} + .danger-panel { border-bottom: 0; } diff --git a/src/data-maintenance/data-maintenance.html b/src/data-maintenance/data-maintenance.html index 48abde7..b0f8182 100644 --- a/src/data-maintenance/data-maintenance.html +++ b/src/data-maintenance/data-maintenance.html @@ -12,44 +12,55 @@ Zurück zum Observe-Dashboard

Datenpflege

- Diese Ansicht bereitet die künftige segmentierte Verwaltung lokaler - VG-Observe-Datenbestände vor. Aktuell werden keine Datenoperationen - ausgeführt. + Lokale Datenbestände verwalten und bereinigen.

-

Geplante Pflegebereiche

+

Datenbereiche

GVL-Referenzdaten

- Referenzdaten der Browser-Datenbank. Enthält Vendorlisten, - Revisionen und zugehörige Referenzbestände. + Vendorlisten, Revisionen und GVL-Referenzbestände.

-

- Noch keine segmentierte Datenpflege implementiert. +

+

GVL-Referenzdaten bereinigen

+

+ Entfernt lokale GVL-Referenzdaten aus der Browser-Datenbank. + Consent-Daten, Request-Beobachtungen und Analyse-Daten bleiben + unberührt. +

+ +
+

+ Bereit.

Consent-Daten

- Dokumentierte Consent-Zustände und zugehörige Ereignisse. + Consent-Zustände und Ereignisse.

- Noch keine segmentierte Datenpflege implementiert. + Noch nicht verfügbar.

Analyse-Daten

- Vorbereitete Arbeits- und Auswertungsdaten zukünftiger - Analysefunktionen. + Analyse- und Arbeitsdaten.

- Noch keine segmentierte Datenpflege implementiert. + Noch nicht verfügbar.

@@ -59,7 +70,7 @@ Reserviert für zukünftige Erweiterungen.

- Noch keine segmentierte Datenpflege implementiert. + Noch nicht verfügbar.

@@ -68,20 +79,17 @@

Gefahrenbereich

- Hier werden später irreversible Verwaltungsaktionen gebündelt. Diese - Aktionen betreffen den lokalen VG-Observe-Datenbestand und erfordern - eine ausdrückliche Sicherheitsbestätigung. + Irreversible Aktionen für den gesamten lokalen Datenbestand.

-

Gesamten lokalen VG-Observe-Datenbestand löschen

-

Noch nicht implementiert.

+

Gesamten lokalen Datenbestand löschen

+

Noch nicht verfügbar.

- Vor einer späteren Umsetzung muss klar angezeigt werden, welche - Datenbereiche betroffen sind. Die Ausführung darf nur nach - ausdrücklicher Sicherheitsabfrage erfolgen. + Erfordert später eine ausdrückliche Sicherheitsbestätigung.

+ diff --git a/src/data-maintenance/data-maintenance.js b/src/data-maintenance/data-maintenance.js new file mode 100644 index 0000000..26fb5f1 --- /dev/null +++ b/src/data-maintenance/data-maintenance.js @@ -0,0 +1,69 @@ +"use strict"; + +const purgeGvlReferenceDataButton = document.getElementById( + "purge-gvl-reference-data-button" +); +const gvlReferenceMaintenanceStatus = document.getElementById( + "gvl-reference-maintenance-status" +); + +document.addEventListener("DOMContentLoaded", () => { + purgeGvlReferenceDataButton?.addEventListener("click", async () => { + await purgeGvlReferenceData(); + }); +}); + +async function purgeGvlReferenceData() { + if (!confirm(buildGvlReferenceDataPurgeConfirmationText())) { + renderGvlReferenceMaintenanceStatus("Abgebrochen."); + return; + } + + purgeGvlReferenceDataButton.disabled = true; + renderGvlReferenceMaintenanceStatus("GVL-Referenzdaten werden bereinigt..."); + + try { + const result = await browser.runtime.sendMessage({ + type: "purge_gvl_reference_data" + }); + + if (!result?.success) { + throw new Error(result?.error ?? "purge_gvl_reference_data_failed"); + } + + renderGvlReferenceMaintenanceStatus( + buildGvlReferenceDataPurgeSuccessMessage(result) + ); + } catch (error) { + renderGvlReferenceMaintenanceStatus( + "GVL-Referenzdaten konnten nicht bereinigt werden." + ); + console.warn("VG-Observe GVL reference data purge failed", error); + } finally { + purgeGvlReferenceDataButton.disabled = false; + } +} + +function buildGvlReferenceDataPurgeConfirmationText() { + return [ + "GVL-Referenzdaten bereinigen?", + "", + "Betroffen: GVL-Referenzdaten der Browser-DB.", + "Nicht betroffen: Consent-Daten, Request-Beobachtungen, Analyse-Daten.", + "", + "Diese Aktion entfernt lokale GVL-Referenzdaten aus der Browser-Datenbank." + ].join("\n"); +} + +function buildGvlReferenceDataPurgeSuccessMessage(result) { + const clearedCount = Object.values(result.clearedStores ?? {}).reduce( + (total, count) => total + Number(count ?? 0), + 0 + ); + + return `GVL-Referenzdaten bereinigt: ${clearedCount} Records entfernt.`; +} + +function renderGvlReferenceMaintenanceStatus(message) { + gvlReferenceMaintenanceStatus.textContent = message; +}