Initial commit
This commit is contained in:
29
LICENSE
29
LICENSE
@@ -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
236
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
|
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.
|
||||||
|
|||||||
Reference in New Issue
Block a user