From 742e5bc6b27ba9adc4eb168a542a1f8149f691f3 Mon Sep 17 00:00:00 2001 From: Marco Morath Date: Fri, 4 Sep 2026 19:43:24 +0200 Subject: [PATCH] Initial commit --- LICENSE | 29 ++++--- README.md | 236 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 250 insertions(+), 15 deletions(-) diff --git a/LICENSE b/LICENSE index 68ce501..5b14339 100644 --- a/LICENSE +++ b/LICENSE @@ -1,18 +1,21 @@ MIT License -Copyright (c) 2026 marco.morath +Copyright (c) 2026 -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and -associated documentation files (the "Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the -following conditions: +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: -The above copyright notice and this permission notice shall be included in all copies or substantial -portions of the Software. +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT -LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO -EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -USE OR OTHER DEALINGS IN THE SOFTWARE. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md index b1018e8..463f853 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,235 @@ -# thunderbird-paperless-connector +# Paperless-ngx für Thunderbird / Betterbird -Addon für Thuderbird oder Betterbird zur Anbindung von Paperless-NGX \ No newline at end of file +Legt Anhänge und ganze E-Mails in einem Paperless-ngx-Archiv ab und fügt +Dokumente aus dem Archiv als Anhang oder Freigabelink in Entwürfe ein. + +Schwestererweiterung zur LibreOffice-Fassung; dieselben Erkenntnisse zur +Paperless-Schnittstelle, aber vollständig eigener Code — Thunderbird kennt +WebExtensions, LibreOffice UNO. + +--- + +## Funktionen + +| Ort | Befehl | Wirkung | +|---|---|---| +| Kontextmenü am Anhang | Anhang in Paperless ablegen | ausgewählte Anhänge als Dokument | +| Kontextmenü in der Nachrichtenliste | E-Mail in Paperless ablegen | vollständige Nachricht als `.eml` | +| Schaltfläche im Nachrichtenfenster | dasselbe für die angezeigte Nachricht | | +| Schaltfläche im Verfassenfenster | Aus Paperless einfügen | als Anhang oder als Freigabelink | + +Beim Ablegen stehen dieselben zwei Ziele zur Wahl wie in der +LibreOffice-Fassung: ein **neues Dokument** oder eine **neue Version eines +bestehenden**. Der zweite Fall deckt die Lücke, die Dokumentenverwaltungen +gern offenlassen: + +> Die Rechnung kommt als PDF im Anhang. Später entsteht die bearbeitbare +> Fassung. Beides gehört zusammen — aber das PDF war zuerst da. + +--- + +## Was beim Ablegen passiert + +**Anhänge einzeln wählbar.** Kleine Bilder und Signaturen sind vorab +abgewählt — sie gehören zur Darstellung der Nachricht, nicht zum Inhalt. +Wer sie alle mit archiviert, hat nach einem Jahr hunderte Logos im Bestand. +Die Schwelle liegt bei 8 KB und ist einstellbar. + +**Die ganze Nachricht als `.eml`.** Anhänge bleiben darin enthalten; +Paperless legt sie nicht als eigene Dokumente an, aber die Datei ist +vollständig und lässt sich jederzeit wieder in einem Mailprogramm öffnen. + +**Titel aus dem Betreff.** Präfixe wie `AW:` oder `Fwd:` werden entfernt — +sie tragen im Archiv nichts bei und stören beim Sortieren. + +**Klassifizierung direkt danach.** Sonst trägt ein neues Dokument nur den +Titel, und nachträglich macht man es erfahrungsgemäß nicht mehr. + +--- + +## Einfügen in Entwürfe + +**Als Anhang.** Das Original wird geladen (`?original=true`), nicht die +Archivfassung — bei ZUGFeRD bleibt damit die eingebettete XML erhalten. +Die Version ist wählbar, mit Datum und Format. + +**Als Freigabelink.** Zeitlich begrenzt, ohne Anmeldung abrufbar, auf +Wunsch mit einem Tag am Dokument. Eingefügt werden Name (fett), Adresse +und Gültigkeit: + +``` +Einladung Generalversammlung +https://dms.example.org/share/ZYGwdw… +Link gültig bis 11.09.2026 +``` + +Die Adresse steht sichtbar, nicht nur als Verweisziel — bei einem Link, +der ohne Anmeldung Zugriff gewährt, sollte der Empfänger sehen, wohin er +führt. + +**Der Tag ist abschaltbar.** Ein leeres Tag-Feld bedeutet: keine +Kennzeichnung setzen. Wer es dauerhaft nicht will, leert das Feld in den +Einstellungen. + +> **Einschränkung:** Die Compose-Schnittstelle kennt kein Einfügen an der +> Schreibmarke. Der Nachrichtentext muss vollständig gelesen und +> zurückgeschrieben werden. Der Link landet deshalb am Ende des Textes, +> nicht an der Cursorposition. Bei HTML-Nachrichten wird er vor dem +> schließenden `` eingesetzt. + +Wann was: Der Anhang für alles, was auch in fünf Jahren noch lesbar sein +muss, wenn der Link längst abgelaufen ist. Der Link für große Dateien und +für Empfänger, die ohnehin Zugriff auf das Archiv haben sollen. + +--- + +## Einrichten + +1. Add-ons-Verwaltung → **Paperless-ngx** → Einstellungen +2. Basisadresse eintragen, etwa `https://dms.example.org` — ohne + abschließenden Schrägstrich +3. API-Token eintragen, erzeugt im **Benutzerprofil** von Paperless +4. Speichern — dabei wird das Zugriffsrecht für genau diese Adresse + erbeten und die Verbindung sofort geprüft + +Das Zugriffsrecht steht bewusst **nicht** pauschal im Manifest. Eine +Erweiterung, die von Haus aus jede Adresse erreichen darf, ist eine +unnötig große Angriffsfläche. + +--- + +## Bauen und installieren + +```bash +./build.sh +``` + +Zum Ausprobieren ohne Installation: + +``` +Extras → Entwicklerwerkzeuge → Debuggen von Add-ons +→ Temporäres Add-on laden → manifest.json wählen +``` + +Das ist beim Entwickeln der bessere Weg: Änderungen sind nach einem Klick +auf „Neu laden" wirksam, und die Konsole zeigt Fehler im Klartext. + +Dauerhaft: + +``` +Add-ons-Verwaltung → Zahnrad → Add-on aus Datei installieren +→ paperless-thunderbird-1.0.0.xpi +``` + +--- + +## Bekannte Einschränkung: Zugriff über IP-Adresse + +Der Zugang über `https://` und einen Rechnernamen funktioniert. Der +direkte Weg über eine LAN-Adresse wie `http://192.168.1.5:8000` schlägt +dagegen mit `NetworkError` fehl, auch wenn das Zugriffsrecht erteilt +wurde. + +**Die Ursache ist nicht abschließend geklärt.** Eine Vermutung: Neuere +Gecko-Versionen schränken Anfragen aus erweiterten Kontexten in private +Adressbereiche ein. Falls das zutrifft, lässt es sich von der Erweiterung +aus nicht umgehen. + +Praktisch ist das verschmerzbar — der Weg über den Reverse Proxy ist +ohnehin der bessere, weil er verschlüsselt ist. Wer es untersuchen möchte, +findet in `about:networking` und in der Netzwerkanalyse der +Add-on-Debugansicht Ansatzpunkte. + +## Manifest-Version + +Gebaut nach **Manifest V3** mit den Thunderbird-Besonderheiten: + +- `background.scripts` als Ereignisseite, **kein** Service Worker — + Thunderbird unterstützt keine +- `compose_action` und `message_display_action` neben `action` +- `optional_host_permissions` statt fester Adressen + +Sollte die eingesetzte Version noch MV2 verlangen, sind vier Änderungen +nötig: `manifest_version` auf 2, `optional_host_permissions` nach +`optional_permissions`, `host_permissions` entfällt, und +`background.type: module` bleibt wie es ist. + +--- + +## Sprachen + +Deutsch, Englisch und Französisch über die eingebaute Verwaltung +(`_locales/`). Die Sprache richtet sich nach der Oberfläche von +Thunderbird. Eine weitere Sprache ergänzt man, indem man ein Verzeichnis +mit `messages.json` anlegt — die Schlüssel stehen in +`_locales/de/messages.json`. + +--- + +## Sicherheit + +Ausführlich in [SICHERHEIT.md](SICHERHEIT.md). Die Lage ist entspannter als +bei der LibreOffice-Fassung, weil hier **keine fremden Dokumente geöffnet** +werden — der heikelste Punkt entfällt. Die wichtigsten Maßnahmen: + +- Zugriffsrecht nur für die eingetragene Adresse, zur Laufzeit erbeten +- Nur die fünf tatsächlich benötigten Berechtigungen — `compose.send` war + im ersten Entwurf enthalten, ohne je benutzt zu werden, und ist entfernt +- Nur `http` und `https` als Basisadresse +- Dateinamen aus Anhängen werden bereinigt — sie stammen vom Absender +- Anhangdaten werden erst beim Hochladen geladen, nicht beim Öffnen des + Dialogs +- Freigabelinks und Dokumentnamen werden beim Einfügen HTML-maskiert +- Aufträge zwischen Dialog und Ereignisseite werden nach 30 Minuten + verworfen + +--- + +## Aufbau + +``` +manifest.json +background.js Menüs, Schaltflächen, Vermittlung +lib/ + client.js REST-Client (fetch, FormData) + settings.js Einstellungen, Dateinamen, Hilfsmittel +ui/ + store.html/.js Ablegen: Anhänge oder ganze Nachricht + classify.html/.js Klassifizierung direkt danach + insert.html/.js Einfügen als Anhang oder Link + options.html/.js Verbindung einrichten + gemeinsam.js/.css geteilte Hilfsmittel +_locales/{de,en,fr}/ +icons/ +``` + +Die Dialoge sprechen **nicht** selbst mit Paperless, sondern lassen die +Ereignisseite arbeiten. Dort hängt die zur Laufzeit erteilte Berechtigung; +ein Dialogfenster müsste sie sonst erneut erbitten. + +--- + +## Vor einer Veröffentlichung + +| Datei | Was | +|---|---| +| `manifest.json` | `browser_specific_settings.gecko.id`, `author`, `homepage_url` | +| `LICENSE` | Rechteinhaber | + +Die Kennung sollte einer Domain folgen, die dir gehört. Aktuell steht dort +`paperless@example.org`. + +--- + +## Lizenz + +MIT, siehe [LICENSE](LICENSE). + +## Haftung + +Die Erweiterung schreibt in ein Dokumentenarchiv. Sie wurde gegen eine +Paperless-Instanz entwickelt, aber nicht formal getestet. Die MIT-Lizenz +schließt jede Gewährleistung aus. + +Vor dem ersten produktiven Einsatz: eine Testnachricht ablegen und in +Paperless nachsehen, ob Titel, Datum und Anhänge stimmen.