Initial commit

This commit is contained in:
2026-09-04 19:43:24 +02:00
parent 9563db685d
commit 742e5bc6b2
2 changed files with 250 additions and 15 deletions

29
LICENSE
View File

@@ -1,18 +1,21 @@
MIT License MIT License
Copyright (c) 2026 marco.morath Copyright (c) 2026 <Rechteinhaber eintragen>
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and Permission is hereby granted, free of charge, to any person obtaining a copy
associated documentation files (the "Software"), to deal in the Software without restriction, including of this software and associated documentation files (the "Software"), to deal
without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell in the Software without restriction, including without limitation the rights
copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
following conditions: 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 The above copyright notice and this permission notice shall be included in all
portions of the Software. copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
USE OR OTHER DEALINGS IN THE SOFTWARE. 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.

236
README.md
View File

@@ -1,3 +1,235 @@
# thunderbird-paperless-connector # Paperless-ngx für Thunderbird / Betterbird
Addon für Thuderbird oder Betterbird zur Anbindung von Paperless-NGX 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 `</body>` 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.