Compare commits
2 Commits
bc82e33bf2
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ee24caf8b7 | ||
|
|
7a7815feca |
48
VERIFY.md
Normal file
48
VERIFY.md
Normal file
@@ -0,0 +1,48 @@
|
||||
# Verifizierungs-Checkliste
|
||||
|
||||
Nach Thunderbird-Updates, Plugin-Änderungen oder Deployments diese Punkte prüfen.
|
||||
|
||||
## Vorlagen — Sync & Anzeige
|
||||
- [ ] Pull überschreibt lokale Vorlagen nicht (Merge statt Replace) — importierte Vorlagen dürfen nach Sync nicht verschwinden
|
||||
- [ ] Vorlagen mit Leerzeichen im Titel werden korrekt erstellt, gesynct und angezeigt (kein Duplikat)
|
||||
- [ ] Scope-Badge (Persönlich/Abteilung/Alle) zeigt den richtigen Wert — Abteilungsvorlagen dürfen nicht als "Privat" erscheinen
|
||||
- [ ] Scope-Badge umschalten funktioniert (Warnung bei Downgrade, altes File wird gelöscht, neues wird gepusht)
|
||||
- [ ] Sync-Dots sind grün nach Pull (nicht grau/unknown) — Hashes müssen korrekt geschrieben werden
|
||||
- [ ] Background SHA-Check alle 5s läuft, voller Pull nur bei Änderung
|
||||
- [ ] UI refreshed automatisch wenn Background-Sync neue Templates pullt
|
||||
|
||||
## Signaturen
|
||||
- [ ] Signaturen-Tab lädt beim Öffnen automatisch die erste Identität + deren Signatur
|
||||
- [ ] Kein "Bitte wählen" Placeholder im Identity-Dropdown
|
||||
- [ ] Signatur-Sync-Status ist grün beim Öffnen (nicht grau)
|
||||
- [ ] `attachSignature: false` wird gesetzt — alte Datei-basierte Signaturen werden deaktiviert
|
||||
- [ ] Footer (Banner) lädt korrekt als eingebettete data-URI, nicht als Datei-Referenz
|
||||
- [ ] Signatur-Quelle "= andere E-Mail" funktioniert (Kopie von anderer Identität)
|
||||
|
||||
## Settings / Verbindung
|
||||
- [ ] E-Mail ist ein Dropdown mit TB-Identitäten (kein Freitext)
|
||||
- [ ] Token-Feld hat Show/Hide Toggle
|
||||
- [ ] `defaults.local.json` wird beim ersten Start geladen (wenn in XPI vorhanden)
|
||||
- [ ] Ohne `defaults.local.json` funktioniert Plugin normal (manuell konfigurieren)
|
||||
- [ ] Auto-Detection via `_config/abteilungen.json` erkennt Abteilung + E-Mail
|
||||
- [ ] Abteilungsname wird im Scope-Badge und Editor-Dropdown angezeigt (nicht generisch "Abteilung")
|
||||
|
||||
## Popup (Compose-Fenster)
|
||||
- [ ] Vorlagen-Popup öffnet, zeigt alle Vorlagen
|
||||
- [ ] Template-Insertion funktioniert (HTML wird korrekt eingefügt)
|
||||
- [ ] Prefix-Dropdown ("Textbaustein voranstellen") funktioniert
|
||||
|
||||
## UX-Elemente
|
||||
- [ ] Toast-Benachrichtigungen erscheinen bei Sync/Push/Pull/Fehler
|
||||
- [ ] Spinner bei Sync-Operationen sichtbar
|
||||
- [ ] Custom Delete-Modal statt browser confirm()
|
||||
- [ ] Offline-Banner erscheint bei fehlender Verbindung
|
||||
- [ ] Collapsible-Sections sind visuell klickbar (Hintergrund + Hover)
|
||||
- [ ] Template-Name Inline-Validierung (leer + Duplikat)
|
||||
- [ ] Checkbox-Klick auf Template-Name toggelt Checkbox
|
||||
|
||||
## API / Gitea
|
||||
- [ ] `toFilename()` behält Leerzeichen und Groß-/Kleinschreibung
|
||||
- [ ] `_benutzer/`, `_config/` werden aus Department-Liste gefiltert
|
||||
- [ ] Persönliche Vorlagen syncen in `_benutzer/{email}/`
|
||||
- [ ] `checkRemoteShas()` inkludiert persönlichen Ordner
|
||||
@@ -544,7 +544,8 @@ class SyncManager {
|
||||
|
||||
await browser.identities.update(identity.id, {
|
||||
signature: fullSig,
|
||||
signatureIsPlainText: false
|
||||
signatureIsPlainText: false,
|
||||
attachSignature: false
|
||||
});
|
||||
updated++;
|
||||
}
|
||||
@@ -561,7 +562,8 @@ class SyncManager {
|
||||
const fullSig = SyncManager.combineSignature(srcHeader, footer);
|
||||
await browser.identities.update(id, {
|
||||
signature: fullSig,
|
||||
signatureIsPlainText: false
|
||||
signatureIsPlainText: false,
|
||||
attachSignature: false
|
||||
});
|
||||
loadedHeaders[email] = srcHeader;
|
||||
updated++;
|
||||
@@ -784,6 +786,19 @@ async function updateSyncHashes() {
|
||||
for (const t of templates) {
|
||||
data.tpl[t.id] = simpleHashBg(t.content || '');
|
||||
}
|
||||
|
||||
// Also update signature hashes from Thunderbird identities
|
||||
try {
|
||||
const accounts = await browser.accounts.list();
|
||||
data.sig = data.sig || {};
|
||||
for (const account of accounts) {
|
||||
const identities = await browser.identities.list(account.id);
|
||||
for (const identity of identities) {
|
||||
data.sig[identity.email.toLowerCase()] = simpleHashBg(identity.signature || '');
|
||||
}
|
||||
}
|
||||
} catch (_) {}
|
||||
|
||||
await browser.storage.local.set({ [HASH_STORAGE_KEY_BG]: data });
|
||||
}
|
||||
|
||||
|
||||
Binary file not shown.
@@ -1193,10 +1193,25 @@ document.getElementById('sig-save-button').addEventListener('click', async () =>
|
||||
|
||||
await browser.identities.update(identityId, {
|
||||
signature: fullSignature,
|
||||
signatureIsPlainText: false
|
||||
signatureIsPlainText: false,
|
||||
attachSignature: false
|
||||
});
|
||||
|
||||
if (identity) identity.signature = fullSignature;
|
||||
|
||||
// Update all identities that reference this email as source
|
||||
for (const otherId of allIdentities) {
|
||||
const otherSource = sourceMap[otherId.email.toLowerCase()] || 'own';
|
||||
if (otherSource === `=${identity.email.toLowerCase()}`) {
|
||||
await browser.identities.update(otherId.id, {
|
||||
signature: fullSignature,
|
||||
signatureIsPlainText: false,
|
||||
attachSignature: false
|
||||
});
|
||||
otherId.signature = fullSignature;
|
||||
}
|
||||
}
|
||||
|
||||
updateSigSyncIndicator();
|
||||
|
||||
// Auto-push to server
|
||||
@@ -1674,17 +1689,30 @@ window.addEventListener('load', async () => {
|
||||
loadSyncConfig();
|
||||
await loadIdentities();
|
||||
|
||||
// Always init sig hashes from current identities
|
||||
if (allIdentities.length > 0) {
|
||||
for (const id of allIdentities) {
|
||||
sigSyncedHashes[id.email.toLowerCase()] = simpleHash(id.signature || '');
|
||||
}
|
||||
saveSyncHashes();
|
||||
}
|
||||
updateSigSyncIndicator();
|
||||
|
||||
checkForServerUpdates();
|
||||
setInterval(checkForServerUpdates, 30000);
|
||||
|
||||
// Auto-refresh UI when background sync updates hashes (fires after templates + hashes are both written)
|
||||
// Auto-refresh UI when background sync updates storage
|
||||
let refreshing = false;
|
||||
browser.storage.onChanged.addListener(async (changes, area) => {
|
||||
if (area !== 'local') return;
|
||||
if (changes[HASH_STORAGE_KEY]) {
|
||||
if (area !== 'local' || refreshing) return;
|
||||
if (changes[HASH_STORAGE_KEY] || changes[TEMPLATE_STORAGE_KEY]) {
|
||||
refreshing = true;
|
||||
await loadSyncHashes();
|
||||
const templates = await getTemplates();
|
||||
renderTemplates(templates);
|
||||
updateTplSyncIndicator();
|
||||
updateSigSyncIndicator();
|
||||
refreshing = false;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user