Show delta token source count, add hint bubble, fix README data paths

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
StyxX65 2026-06-10 14:27:14 +02:00
parent c0e45df440
commit 6a4b0e1706
7 changed files with 16 additions and 7 deletions

View File

@ -15,6 +15,12 @@ Version numbers follow [Semantic Versioning](https://semver.org/spec/v2.0.0.html
- **`update_gdpr.sh`** — standalone CLI/cron equivalent of the GUI update: fetch + fast-forward-only merge with auto-stash of local hotfixes, dependency reinstall only when `requirements.txt` changed, and a `systemctl restart` if a `gdprscanner.service` unit exists (override with `GDPR_SERVICE`). `./update_gdpr.sh --check` reports pending commits without changing anything; safe to run from cron (quiet no-op when already up to date). - **`update_gdpr.sh`** — standalone CLI/cron equivalent of the GUI update: fetch + fast-forward-only merge with auto-stash of local hotfixes, dependency reinstall only when `requirements.txt` changed, and a `systemctl restart` if a `gdprscanner.service` unit exists (override with `GDPR_SERVICE`). `./update_gdpr.sh --check` reports pending commits without changing anything; safe to run from cron (quiet no-op when already up to date).
### Fixed
- **Delta token status hid the source count** — the "Tokens saved" line under the Δ Delta scan toggle always showed the bare translation ("Tokens gemt") because the source count only existed in the JS fallback string, which is ignored whenever the lang key exists. The translations now carry a `{n}` placeholder ("Tokens gemt for {n} kilde(r)") substituted in `checkDeltaStatus()`, and the row gained a "?" hint bubble explaining what the saved change-tokens do and that "Clear tokens" forces the next scan to be a full scan.
- **Stale data-file paths in README** — delta tokens were documented as `~/.gdpr_scanner_delta.json` and the SMTP password/Fernet key as `~/.gdpr_scanner_smtp.json` / `~/.gdpr_scanner_machine_id`; the actual locations have long been `~/.gdprscanner/delta.json`, `~/.gdprscanner/smtp.json`, and `~/.gdprscanner/machine_id`.
--- ---
## [1.7.0] — 2026-06-10 ## [1.7.0] — 2026-06-10

View File

@ -227,7 +227,7 @@ Configure email delivery in **Settings → Email report**. Click **Save** to sto
| SMTP host | e.g. `smtp.office365.com`, `smtp.gmail.com` | | SMTP host | e.g. `smtp.office365.com`, `smtp.gmail.com` |
| Port | `587` for STARTTLS (default), `465` for SMTPS/SSL | | Port | `587` for STARTTLS (default), `465` for SMTPS/SSL |
| Username | SMTP login — usually your sender email address | | Username | SMTP login — usually your sender email address |
| Password | Saved to `~/.gdpr_scanner_smtp.json` (permissions 600). Encrypted at rest using Fernet — key in `~/.gdpr_scanner_machine_id` (chmod 0o600, never share) | | Password | Saved to `~/.gdprscanner/smtp.json` (permissions 600). Encrypted at rest using Fernet — key in `~/.gdprscanner/machine_id` (chmod 0o600, never share) |
| Graph API | When connected to M365, email is sent via `/me/sendMail` (delegated) or `/users/{sender}/sendMail` (app mode) — no SMTP password needed. Requires `Mail.Send` Graph permission with admin consent. | | Graph API | When connected to M365, email is sent via `/me/sendMail` (delegated) or `/users/{sender}/sendMail` (app mode) — no SMTP password needed. Requires `Mail.Send` Graph permission with admin consent. |
| From address | Sender address (defaults to username if blank) | | From address | Sender address (defaults to username if blank) |
| STARTTLS | Enable STARTTLS on port 587 (recommended) | | STARTTLS | Enable STARTTLS on port 587 (recommended) |
@ -273,7 +273,7 @@ Delta scan uses the Microsoft Graph `/delta` API (M365) and the Google Drive **C
1. Run one **full scan** first (Delta checkbox off) — this establishes baseline delta tokens 1. Run one **full scan** first (Delta checkbox off) — this establishes baseline delta tokens
2. Tick **Δ Delta scan** and run again — only items added, modified, or deleted since the previous scan are fetched and CPR-scanned 2. Tick **Δ Delta scan** and run again — only items added, modified, or deleted since the previous scan are fetched and CPR-scanned
3. Delta tokens are saved automatically to `~/.gdpr_scanner_delta.json` after each successful scan 3. Delta tokens are saved automatically to `~/.gdprscanner/delta.json` after each successful scan
4. To force a full rescan, click **Clear tokens** under the checkbox (or delete the file) 4. To force a full rescan, click **Clear tokens** under the checkbox (or delete the file)
Delta tokens are stored **per-source**: Delta tokens are stored **per-source**:

View File

@ -348,8 +348,9 @@
"m365_resuming": "Genoptager — springer allerede skannede elementer over…", "m365_resuming": "Genoptager — springer allerede skannede elementer over…",
"m365_opt_delta": "Delta-scanning", "m365_opt_delta": "Delta-scanning",
"m365_opt_delta_hint": "Kun ændrede elementer (efter første fulde scanning)", "m365_opt_delta_hint": "Kun ændrede elementer (efter første fulde scanning)",
"m365_delta_tokens_saved": "Tokens gemt", "m365_delta_tokens_saved": "Tokens gemt for {n} kilde(r)",
"m365_delta_clear": "Ryd tokens", "m365_delta_clear": "Ryd tokens",
"m365_delta_tokens_hint": "Gemte ændringstokens gør, at delta-scanninger kun henter elementer ændret siden sidste scanning. Ryd tokens tvinger næste scanning til at være en fuld scanning.",
"m365_delta_cleared": "Delta-tokens ryddet — næste scanning bliver fuld scanning.", "m365_delta_cleared": "Delta-tokens ryddet — næste scanning bliver fuld scanning.",
"m365_delta_mode": "Delta-tilstand — henter kun ændrede elementer…", "m365_delta_mode": "Delta-tilstand — henter kun ændrede elementer…",
"m365_smtp_title": "✉ Send rapport", "m365_smtp_title": "✉ Send rapport",

View File

@ -348,8 +348,9 @@
"m365_resuming": "Fortsetzen — bereits gescannte Elemente werden übersprungen…", "m365_resuming": "Fortsetzen — bereits gescannte Elemente werden übersprungen…",
"m365_opt_delta": "Delta-Scan", "m365_opt_delta": "Delta-Scan",
"m365_opt_delta_hint": "Nur geänderte Elemente (nach erstem Vollscan)", "m365_opt_delta_hint": "Nur geänderte Elemente (nach erstem Vollscan)",
"m365_delta_tokens_saved": "Tokens gespeichert", "m365_delta_tokens_saved": "Tokens für {n} Quelle(n) gespeichert",
"m365_delta_clear": "Tokens löschen", "m365_delta_clear": "Tokens löschen",
"m365_delta_tokens_hint": "Gespeicherte Änderungstokens lassen Delta-Scans nur Elemente abrufen, die seit dem letzten Scan geändert wurden. Tokens löschen erzwingt beim nächsten Scan einen Vollscan.",
"m365_delta_cleared": "Delta-Tokens gelöscht — nächster Scan wird ein Vollscan.", "m365_delta_cleared": "Delta-Tokens gelöscht — nächster Scan wird ein Vollscan.",
"m365_delta_mode": "Delta-Modus — nur geänderte Elemente werden abgerufen…", "m365_delta_mode": "Delta-Modus — nur geänderte Elemente werden abgerufen…",
"m365_smtp_title": "✉ Bericht senden", "m365_smtp_title": "✉ Bericht senden",

View File

@ -348,8 +348,9 @@
"m365_resuming": "Resuming — skipping already-scanned items…", "m365_resuming": "Resuming — skipping already-scanned items…",
"m365_opt_delta": "Delta scan", "m365_opt_delta": "Delta scan",
"m365_opt_delta_hint": "Changed items only (after first full scan)", "m365_opt_delta_hint": "Changed items only (after first full scan)",
"m365_delta_tokens_saved": "Tokens saved", "m365_delta_tokens_saved": "Tokens saved for {n} source(s)",
"m365_delta_clear": "Clear tokens", "m365_delta_clear": "Clear tokens",
"m365_delta_tokens_hint": "Saved change-tokens let delta scans fetch only items modified since the last scan. Clear tokens forces the next scan to be a full scan.",
"m365_delta_cleared": "Delta tokens cleared — next scan will be a full scan.", "m365_delta_cleared": "Delta tokens cleared — next scan will be a full scan.",
"m365_delta_mode": "Delta mode — fetching changed items only…", "m365_delta_mode": "Delta mode — fetching changed items only…",
"m365_smtp_title": "✉ Email report", "m365_smtp_title": "✉ Email report",

View File

@ -188,8 +188,7 @@ async function checkDeltaStatus() {
const row = document.getElementById('deltaStatusRow'); const row = document.getElementById('deltaStatusRow');
const txt = document.getElementById('deltaStatusText'); const txt = document.getElementById('deltaStatusText');
if (d.exists) { if (d.exists) {
const src = d.count === 1 ? '1 source' : `${d.count} sources`; txt.textContent = t('m365_delta_tokens_saved', 'Tokens saved for {n} source(s)').replace('{n}', d.count);
txt.textContent = t('m365_delta_tokens_saved', `Tokens saved for ${src}`);
row.style.display = 'flex'; row.style.display = 'flex';
row.style.alignItems = 'center'; row.style.alignItems = 'center';
} else { } else {

View File

@ -110,6 +110,7 @@ document.addEventListener('DOMContentLoaded', applyI18n);
<div id="deltaStatusRow" style="display:none;font-size:10px;padding:3px 0 2px;color:var(--muted)"> <div id="deltaStatusRow" style="display:none;font-size:10px;padding:3px 0 2px;color:var(--muted)">
<span id="deltaStatusText"></span> <span id="deltaStatusText"></span>
<button onclick="clearDeltaTokens()" style="background:none;border:none;color:var(--danger);font-size:10px;cursor:pointer;padding:0 0 0 6px" data-i18n="m365_delta_clear">Clear tokens</button> <button onclick="clearDeltaTokens()" style="background:none;border:none;color:var(--danger);font-size:10px;cursor:pointer;padding:0 0 0 6px" data-i18n="m365_delta_clear">Clear tokens</button>
<span class="hint-wrap"><span class="hint-icon" onclick="toggleHint(this)">?</span><span class="hint-bubble" data-i18n="m365_delta_tokens_hint">Saved change-tokens let delta scans fetch only items modified since the last scan. Clear tokens forces the next scan to be a full scan.</span></span>
</div> </div>
<!-- Photo / biometric scan (#9) --> <!-- Photo / biometric scan (#9) -->