Compare commits
7 commits
claude/chr
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a032dd5b13 | ||
|
|
baf13c865f | ||
|
|
1b3ed44e6e | ||
|
|
07a5785580 | ||
|
|
26c01a4fc3 | ||
|
|
19051bbacd | ||
|
|
ea5cd8d623 |
10 changed files with 176 additions and 32 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
dist/
|
||||||
55
CHANGELOG.md
55
CHANGELOG.md
|
|
@ -3,6 +3,61 @@
|
||||||
Format nach [Keep a Changelog](https://keepachangelog.com/de/1.1.0/).
|
Format nach [Keep a Changelog](https://keepachangelog.com/de/1.1.0/).
|
||||||
Die Erweiterungsversion (`manifest.json`) ist unabhängig von der OpenNIT-Serverversion.
|
Die Erweiterungsversion (`manifest.json`) ist unabhängig von der OpenNIT-Serverversion.
|
||||||
|
|
||||||
|
## [Unreleased]
|
||||||
|
|
||||||
|
## [2.5.0] - 2026-07-31
|
||||||
|
|
||||||
|
### Hinzugefügt
|
||||||
|
- **Einträge bearbeiten und löschen:** In der Detailansicht gibt es jetzt „Bearbeiten" und „Löschen".
|
||||||
|
Beim Bearbeiten bleibt das Passwortfeld leer – wer es leer lässt, behält das gespeicherte Passwort;
|
||||||
|
2FA-Secret und Ordner bleiben unangetastet. Für Team-Einträge greift das Schreibrecht des Teams.
|
||||||
|
- **Passwort-Generator einstellbar:** Länge (12–48) und Sonderzeichen lassen sich beim Anlegen wählen –
|
||||||
|
hilfreich bei Seiten, die Sonderzeichen ablehnen.
|
||||||
|
- **2FA-Code wird für den nächsten Schritt bereitgelegt:** Nach dem Ausfüllen eines Eintrags mit 2FA
|
||||||
|
landet beim nächsten 2FA-Feld automatisch ein **frischer** Code in der Zwischenablage – auch dann,
|
||||||
|
wenn die Abfrage erst auf einer Folgeseite kommt (z. B. Microsoft-Anmeldung). Einfügen genügt mit
|
||||||
|
Strg + V; der bisherige Inhalt der Zwischenablage wird dabei überschrieben und der Code nach 30
|
||||||
|
Sekunden wieder entfernt. Abschaltbar unter „Sicherheit → 2FA-Code beim Anmelden bereitlegen".
|
||||||
|
|
||||||
|
### Sicherheit
|
||||||
|
- **Passwort für mehrstufige Logins nicht mehr auf der Festplatte:** Verteilt eine Anmeldung Benutzername
|
||||||
|
und Passwort auf zwei Schritte, wurde das Passwort bisher im lokalen Speicher der Erweiterung abgelegt –
|
||||||
|
und blieb dort liegen, wenn der zweite Schritt nie erreicht wurde. Es wird jetzt nur noch im Arbeits-
|
||||||
|
speicher gehalten, an den jeweiligen Tab gebunden und nach 30 Sekunden bzw. beim Sperren verworfen.
|
||||||
|
- **Warnung bei fremder Domain greift zuverlässiger:** Ein Eintrag für `vpn.firma.de` galt auf `firma.de`
|
||||||
|
fälschlich als passend, sodass die Warnung ausblieb. Zuordnung und Warnung nutzen jetzt dieselbe Regel:
|
||||||
|
nur die hinterlegte Adresse selbst und deren Unteradressen gelten als passend.
|
||||||
|
- **Weniger Berechtigungen:** `scripting` und `activeTab` werden nicht mehr angefordert – beide wurden
|
||||||
|
nicht benötigt.
|
||||||
|
- **Passwort-Generator:** Der Zufall für die Mischreihenfolge wird jetzt getrennt von der Zeichenauswahl
|
||||||
|
gezogen, und die Zeichenwahl ist gleichverteilt.
|
||||||
|
- Notizen werden beim Kopieren wie andere Geheimnisse behandelt und nach 30 Sekunden aus der
|
||||||
|
Zwischenablage entfernt.
|
||||||
|
|
||||||
|
### Geändert
|
||||||
|
- **Benutzername immer sichtbar:** Das Auge zum Ausblenden des Benutzernamens in der Detailansicht ist
|
||||||
|
entfallen – ein Benutzername ist kein Geheimnis. Das Passwort bleibt weiterhin maskiert.
|
||||||
|
- **Vorschläge weichen der Seite:** Sobald in ein Feld getippt wird, verschwindet die Vault-Liste –
|
||||||
|
darunter erscheint typischerweise die Suche der Seite selbst. Bei Feldern, die erkennbar eine eigene
|
||||||
|
Auswahlliste öffnen (etwa Benutzer-Auswahlfelder), erscheinen gar keine Vault-Vorschläge mehr.
|
||||||
|
Ausdrücklich als Anmeldefeld ausgezeichnete Felder sind davon ausgenommen.
|
||||||
|
- **Anmeldung nur noch per SSO:** Das Feld für den manuell erzeugten API-Token samt „Verbindung testen"
|
||||||
|
ist aus den Einstellungen entfernt. Die Verbindung entsteht ausschließlich über „Mit OpenNIT anmelden".
|
||||||
|
Ein aus einer früheren Version übernommener Token wird beim Update aus dem lokalen Speicher gelöscht;
|
||||||
|
wer bisher nur damit verbunden war, meldet sich einmal per SSO an.
|
||||||
|
|
||||||
|
### Behoben
|
||||||
|
- **Restlaufzeit des 2FA-Codes wird wieder korrekt angezeigt:** Der Countdown blieb am Ende eines
|
||||||
|
Zeitfensters stehen und lief mit der Zeit aus dem Takt. Er rechnet nun gegen den tatsächlichen
|
||||||
|
Ablaufzeitpunkt und holt den neuen Code beim Wechsel genau einmal nach. Lässt sich kein neuer Code
|
||||||
|
laden (Tresor gesperrt oder Verbindung weg), zeigt die Anzeige das an, statt auf einem abgelaufenen
|
||||||
|
Wert stehen zu bleiben.
|
||||||
|
- **Neuen Eintrag anlegen funktioniert wieder nach SSO-Anmeldung:** Das Speichern eines im Popup
|
||||||
|
erzeugten Passworts brach bisher mit „Nicht konfiguriert." ab, wenn die Erweiterung über
|
||||||
|
„Mit OpenNIT anmelden" verbunden war – es wurde ausschließlich der manuelle Token akzeptiert.
|
||||||
|
Das Anlegen nutzt nun denselben Zugang wie alle übrigen Aufrufe (inkl. automatischer
|
||||||
|
Token-Erneuerung). Ist der Tresor gesperrt, erscheint die PIN-Abfrage statt einer Fehlermeldung.
|
||||||
|
|
||||||
## [2.4.0] - 2026-07-01
|
## [2.4.0] - 2026-07-01
|
||||||
|
|
||||||
### Hinzugefügt
|
### Hinzugefügt
|
||||||
|
|
|
||||||
14
PRIVACY.md
14
PRIVACY.md
|
|
@ -17,7 +17,7 @@ technisches Client-Werkzeug ohne eigenen Server.
|
||||||
| Datum | Zweck | Speicherort |
|
| Datum | Zweck | Speicherort |
|
||||||
|-------|-------|-------------|
|
|-------|-------|-------------|
|
||||||
| **Server-URL** | Adresse deiner OpenNIT-Instanz | lokal (`chrome.storage.local`) |
|
| **Server-URL** | Adresse deiner OpenNIT-Instanz | lokal (`chrome.storage.local`) |
|
||||||
| **API-Token** | Authentifizierung gegenüber deiner Instanz | lokal (`chrome.storage.local`) |
|
| **Sitzungstoken** | Authentifizierung gegenüber deiner Instanz (per SSO ausgestellt) | lokal (`chrome.storage.local`) |
|
||||||
| **Einstellungen** (PIN-Sperrdauer, Zwischenablage-Option) | Verhalten der Erweiterung | lokal (`chrome.storage.local`) |
|
| **Einstellungen** (PIN-Sperrdauer, Zwischenablage-Option) | Verhalten der Erweiterung | lokal (`chrome.storage.local`) |
|
||||||
| **Entsperr-Status** | Merkt, ob die PIN-Sperre entsperrt ist | Sitzungsspeicher (`chrome.storage.session`, wird beim Schließen des Browsers gelöscht) |
|
| **Entsperr-Status** | Merkt, ob die PIN-Sperre entsperrt ist | Sitzungsspeicher (`chrome.storage.session`, wird beim Schließen des Browsers gelöscht) |
|
||||||
| **Tresor-Einträge** (Titel, Benutzername, URL, Notizen, ob 2FA vorhanden) | Anzeige & Suche | flüchtig im Arbeitsspeicher (max. 5 Min zwischengespeichert) |
|
| **Tresor-Einträge** (Titel, Benutzername, URL, Notizen, ob 2FA vorhanden) | Anzeige & Suche | flüchtig im Arbeitsspeicher (max. 5 Min zwischengespeichert) |
|
||||||
|
|
@ -30,7 +30,7 @@ Die Erweiterung erstellt **keine** Nutzungsprofile und protokolliert **kein** Su
|
||||||
|
|
||||||
- Es werden Daten **ausschließlich** an die von dir eingetragene **OpenNIT-Server-URL** übertragen
|
- Es werden Daten **ausschließlich** an die von dir eingetragene **OpenNIT-Server-URL** übertragen
|
||||||
(verschlüsselt via HTTPS, sofern deine Instanz HTTPS nutzt).
|
(verschlüsselt via HTTPS, sofern deine Instanz HTTPS nutzt).
|
||||||
- Übertragen werden: der API-Token (zur Authentifizierung), die aktuelle Seiten-Adresse (zum Finden
|
- Übertragen werden: der Sitzungstoken (zur Authentifizierung), die aktuelle Seiten-Adresse (zum Finden
|
||||||
passender Einträge), sowie beim Anlegen neuer Einträge die von dir eingegebenen Felder.
|
passender Einträge), sowie beim Anlegen neuer Einträge die von dir eingegebenen Felder.
|
||||||
- Es erfolgt **keine** Übermittlung an Anthropic, Google (außer der Chrome-Sync deines eigenen Browsers,
|
- Es erfolgt **keine** Übermittlung an Anthropic, Google (außer der Chrome-Sync deines eigenen Browsers,
|
||||||
falls du ihn aktiviert hast) oder sonstige Dritte.
|
falls du ihn aktiviert hast) oder sonstige Dritte.
|
||||||
|
|
@ -42,7 +42,7 @@ Siehe [`docs/PERMISSIONS.md`](docs/PERMISSIONS.md). Kurz:
|
||||||
- **Zugriff auf alle Websites** (`host_permissions: <all_urls>`): nötig, um Login-Felder auf beliebigen
|
- **Zugriff auf alle Websites** (`host_permissions: <all_urls>`): nötig, um Login-Felder auf beliebigen
|
||||||
Seiten zu erkennen und auf Wunsch auszufüllen. Es werden **keine** Seiteninhalte gelesen oder
|
Seiten zu erkennen und auf Wunsch auszufüllen. Es werden **keine** Seiteninhalte gelesen oder
|
||||||
übertragen, außer den zum Ausfüllen nötigen Formularfeldern – und diese verlassen den Browser nicht.
|
übertragen, außer den zum Ausfüllen nötigen Formularfeldern – und diese verlassen den Browser nicht.
|
||||||
- **storage**: lokale Speicherung von URL, Token und Einstellungen.
|
- **storage**: lokale Speicherung von URL, Sitzungstoken und Einstellungen.
|
||||||
- **scripting / activeTab**: Einfügen der Zugangsdaten in das aktive Tab-Formular.
|
- **scripting / activeTab**: Einfügen der Zugangsdaten in das aktive Tab-Formular.
|
||||||
- **alarms / offscreen**: automatisches Leeren der Zwischenablage nach dem Kopieren.
|
- **alarms / offscreen**: automatisches Leeren der Zwischenablage nach dem Kopieren.
|
||||||
|
|
||||||
|
|
@ -53,7 +53,7 @@ Zwischenablage entfernt.
|
||||||
|
|
||||||
## 6. Speicherdauer
|
## 6. Speicherdauer
|
||||||
|
|
||||||
- Server-URL, Token und Einstellungen bleiben lokal gespeichert, bis du sie änderst oder die Erweiterung
|
- Server-URL, Sitzungstoken und Einstellungen bleiben lokal gespeichert, bis du sie änderst oder die Erweiterung
|
||||||
entfernst.
|
entfernst.
|
||||||
- Zwischengespeicherte Einträge werden spätestens nach 5 Minuten bzw. beim Sperren verworfen.
|
- Zwischengespeicherte Einträge werden spätestens nach 5 Minuten bzw. beim Sperren verworfen.
|
||||||
- Passwörter/2FA-Codes werden nicht dauerhaft gespeichert.
|
- Passwörter/2FA-Codes werden nicht dauerhaft gespeichert.
|
||||||
|
|
@ -62,7 +62,7 @@ Zwischenablage entfernt.
|
||||||
|
|
||||||
Da die eigentliche Datenverarbeitung in deiner OpenNIT-Instanz stattfindet, richten sich Auskunfts-,
|
Da die eigentliche Datenverarbeitung in deiner OpenNIT-Instanz stattfindet, richten sich Auskunfts-,
|
||||||
Lösch- und Berichtigungsrechte an deren Betreiber. Lokale Daten der Erweiterung entfernst du durch
|
Lösch- und Berichtigungsrechte an deren Betreiber. Lokale Daten der Erweiterung entfernst du durch
|
||||||
Deinstallieren der Erweiterung oder Löschen des Tokens in den Einstellungen.
|
Deinstallieren der Erweiterung oder „Abmelden" in den Einstellungen.
|
||||||
|
|
||||||
## 8. Kontakt
|
## 8. Kontakt
|
||||||
|
|
||||||
|
|
@ -78,7 +78,7 @@ eine erreichbare Kontaktadresse ergänzen.
|
||||||
|
|
||||||
**Controller.** The operator of the OpenNIT instance you connect to. The extension itself has no server.
|
**Controller.** The operator of the OpenNIT instance you connect to. The extension itself has no server.
|
||||||
|
|
||||||
**Data processed.** Server URL, API token and settings (stored locally); unlock state (session storage,
|
**Data processed.** Server URL, session tokens and settings (stored locally); unlock state (session storage,
|
||||||
cleared when the browser closes); vault entry metadata (title, username, URL, notes, whether 2FA exists –
|
cleared when the browser closes); vault entry metadata (title, username, URL, notes, whether 2FA exists –
|
||||||
cached in memory for up to 5 minutes); passwords/2FA codes (fetched **only** at the moment of use, never
|
cached in memory for up to 5 minutes); passwords/2FA codes (fetched **only** at the moment of use, never
|
||||||
stored permanently); the active tab URL (to find matching entries).
|
stored permanently); the active tab URL (to find matching entries).
|
||||||
|
|
@ -96,4 +96,4 @@ browser. See [`docs/PERMISSIONS.md`](docs/PERMISSIONS.md).
|
||||||
within 5 minutes; secrets are never stored persistently.
|
within 5 minutes; secrets are never stored persistently.
|
||||||
|
|
||||||
**Your rights.** Because processing happens in your OpenNIT instance, direct data-subject requests to its
|
**Your rights.** Because processing happens in your OpenNIT instance, direct data-subject requests to its
|
||||||
operator. Remove local extension data by uninstalling the extension or clearing the token.
|
operator. Remove local extension data by uninstalling the extension or signing out in the settings.
|
||||||
|
|
|
||||||
19
README.md
19
README.md
|
|
@ -22,7 +22,10 @@ deiner selbst gehosteten OpenNIT-Instanz und bietet:
|
||||||
- 👁️ **Detailansicht** mit Anzeigen/Kopieren von Zugangsdaten und 2FA-Code mit Countdown
|
- 👁️ **Detailansicht** mit Anzeigen/Kopieren von Zugangsdaten und 2FA-Code mit Countdown
|
||||||
- ➕ **Neue Einträge anlegen** inkl. **Passwort-Generator**
|
- ➕ **Neue Einträge anlegen** inkl. **Passwort-Generator**
|
||||||
- 🔒 **PIN-Sperre** mit demselben PIN wie der Web-Tresor (Dauer frei wählbar, bis „bis Browser schließt")
|
- 🔒 **PIN-Sperre** mit demselben PIN wie der Web-Tresor (Dauer frei wählbar, bis „bis Browser schließt")
|
||||||
|
- ✏️ **Anlegen, Bearbeiten und Löschen** von Einträgen direkt im Popup
|
||||||
- 🧹 **Zwischenablage-Auto-Clear** nach dem Kopieren von Geheimnissen
|
- 🧹 **Zwischenablage-Auto-Clear** nach dem Kopieren von Geheimnissen
|
||||||
|
- 📋 **2FA-Code bereitgelegt:** nach dem Ausfüllen landet beim nächsten 2FA-Feld – auch auf einer
|
||||||
|
Folgeseite – automatisch ein frischer Code in der Zwischenablage (Strg + V genügt)
|
||||||
- 🖼️ **Favicons** der hinterlegten Seiten (serverseitig gecacht – keine externen Aufrufe)
|
- 🖼️ **Favicons** der hinterlegten Seiten (serverseitig gecacht – keine externen Aufrufe)
|
||||||
- 🌙 **Heller & dunkler Modus** (folgt dem System)
|
- 🌙 **Heller & dunkler Modus** (folgt dem System)
|
||||||
|
|
||||||
|
|
@ -37,19 +40,18 @@ Die Erweiterung ist ein reiner **Client** zu deiner OpenNIT-Instanz. Sie enthäl
|
||||||
und **keinen** Remote-Code – alle Skripte sind im Paket enthalten. Kommuniziert wird ausschließlich mit dem
|
und **keinen** Remote-Code – alle Skripte sind im Paket enthalten. Kommuniziert wird ausschließlich mit dem
|
||||||
von dir konfigurierten OpenNIT-Server über dessen REST-API (`/api/vault/extension/...`) per **Bearer-Token**.
|
von dir konfigurierten OpenNIT-Server über dessen REST-API (`/api/vault/extension/...`) per **Bearer-Token**.
|
||||||
|
|
||||||
- Die Anmeldung erfolgt per **SSO** („Mit OpenNIT anmelden"). Die Erweiterung erhält dabei automatisch
|
- Die Anmeldung erfolgt ausschließlich per **SSO** („Mit OpenNIT anmelden"). Die Erweiterung erhält dabei
|
||||||
ein kurzlebiges, rotierendes Zugriffstoken – ein manuelles Erzeugen von Tokens im Web-Tresor entfällt.
|
ein kurzlebiges, rotierendes Zugriffstoken – ein manuelles Erzeugen von Tokens entfällt.
|
||||||
- Passwörter werden **serverseitig** ver-/entschlüsselt; die Erweiterung fordert das Klartext-Passwort
|
- Passwörter werden **serverseitig** ver-/entschlüsselt; die Erweiterung fordert das Klartext-Passwort
|
||||||
eines Eintrags erst **im Moment des Ausfüllens/Kopierens** an – nicht beim Laden der Liste.
|
eines Eintrags erst **im Moment des Ausfüllens/Kopierens** an – nicht beim Laden der Liste.
|
||||||
- Es findet **keine** Ende-zu-Ende-Entschlüsselung im Browser statt; die Erweiterung speichert keine
|
- Es findet **keine** Ende-zu-Ende-Entschlüsselung im Browser statt; die Erweiterung speichert keine
|
||||||
Passwörter dauerhaft (nur Server-URL, Token und Einstellungen in `chrome.storage`).
|
Passwörter dauerhaft (nur Server-URL, Sitzungstoken und Einstellungen in `chrome.storage`).
|
||||||
|
|
||||||
Details: [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md) · Berechtigungen: [`docs/PERMISSIONS.md`](docs/PERMISSIONS.md)
|
Details: [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md) · Berechtigungen: [`docs/PERMISSIONS.md`](docs/PERMISSIONS.md)
|
||||||
|
|
||||||
> **Anmeldung per SSO (Standard):** „Mit OpenNIT anmelden" (OAuth 2.0 + PKCE) – Anmeldung wie an OpenNIT
|
> **Anmeldung per SSO:** „Mit OpenNIT anmelden" (OAuth 2.0 + PKCE) – Anmeldung wie an OpenNIT
|
||||||
> (lokal + 2FA / M365 / Keycloak), automatische Token-Erneuerung mit Rotation. Ein manuell erzeugter Token
|
> (lokal + 2FA / M365 / Keycloak), automatische Token-Erneuerung mit Rotation. Einen manuell eingetragenen
|
||||||
> ist nur noch als „Erweitert"-Fallback in den Erweiterungs-Einstellungen vorgesehen; OpenNIT bietet dafür
|
> API-Token unterstützt die Erweiterung nicht mehr.
|
||||||
> im Frontend keine Token-Erzeugung mehr an. Konzept/Details: [`docs/SSO-PLAN.md`](docs/SSO-PLAN.md).
|
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
|
|
@ -80,9 +82,10 @@ Repository gedacht.
|
||||||
| Einstellung | Beschreibung |
|
| Einstellung | Beschreibung |
|
||||||
|--------------------|--------------|
|
|--------------------|--------------|
|
||||||
| **Server-URL** | Adresse deiner OpenNIT-Instanz, ohne abschließenden Slash (`https://…`). |
|
| **Server-URL** | Adresse deiner OpenNIT-Instanz, ohne abschließenden Slash (`https://…`). |
|
||||||
| **Anmeldung** | Per **SSO** („Mit OpenNIT anmelden"). Ein manueller API-Token ist nur als „Erweitert"-Fallback vorgesehen. |
|
| **Anmeldung** | Ausschließlich per **SSO** („Mit OpenNIT anmelden"). |
|
||||||
| **PIN-Sperre** | Aus / 5 Min / 15 Min / 1 Std / bis der Browser geschlossen wird. Nutzt den **Tresor-PIN**. |
|
| **PIN-Sperre** | Aus / 5 Min / 15 Min / 1 Std / bis der Browser geschlossen wird. Nutzt den **Tresor-PIN**. |
|
||||||
| **Zwischenablage** | Nach 30 s automatisch leeren (Standard: an). |
|
| **Zwischenablage** | Nach 30 s automatisch leeren (Standard: an). |
|
||||||
|
| **2FA bereitlegen** | Frischen 2FA-Code beim nächsten 2FA-Feld in die Zwischenablage legen (Standard: an). |
|
||||||
|
|
||||||
## Build / Paketierung
|
## Build / Paketierung
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ Die Erweiterung ist ein **Manifest-V3-Client** ohne eigenen Server. Sie besteht
|
||||||
└───────────────┘ └──────────┬───────────┘
|
└───────────────┘ └──────────┬───────────┘
|
||||||
│ CLIP_WRITE
|
│ CLIP_WRITE
|
||||||
┌────────▼─────────┐
|
┌────────▼─────────┐
|
||||||
│ offscreen.html │ (Zwischenablage leeren)
|
│ offscreen.html │ (Zwischenablage schreiben/leeren)
|
||||||
└──────────────────┘
|
└──────────────────┘
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
@ -27,8 +27,9 @@ Die Erweiterung ist ein **Manifest-V3-Client** ohne eigenen Server. Sie besteht
|
||||||
| `background.js` | Zentrale Logik: API-Aufrufe, 5-Minuten-Cache, **Lock-Gate**, Favicon-Cache (Data-URLs), Zwischenablage-Timer. Alle Secrets fließen hier durch. |
|
| `background.js` | Zentrale Logik: API-Aufrufe, 5-Minuten-Cache, **Lock-Gate**, Favicon-Cache (Data-URLs), Zwischenablage-Timer. Alle Secrets fließen hier durch. |
|
||||||
| `content.js` | Wird auf jeder Seite ausgeführt. Erkennt Benutzer-/Passwort-/OTP-Felder (inkl. Shadow-DOM, mehrstufige Logins, segmentierte OTP-Felder), zeigt das Vorschlags-Dropdown und füllt Felder framework-kompatibel (React/Vue/Angular). |
|
| `content.js` | Wird auf jeder Seite ausgeführt. Erkennt Benutzer-/Passwort-/OTP-Felder (inkl. Shadow-DOM, mehrstufige Logins, segmentierte OTP-Felder), zeigt das Vorschlags-Dropdown und füllt Felder framework-kompatibel (React/Vue/Angular). |
|
||||||
| `popup.html` / `popup.js` | Toolbar-Popup: Liste, Suche, Detailansicht, Anlegen + Generator, PIN-Schirm. |
|
| `popup.html` / `popup.js` | Toolbar-Popup: Liste, Suche, Detailansicht, Anlegen + Generator, PIN-Schirm. |
|
||||||
| `options.html` / `options.js` | Einstellungen: Server-URL, Token, PIN-Sperrdauer, Zwischenablage. |
|
| `options.html` / `options.js` | Einstellungen: Server-URL, SSO-Anmeldung, PIN-Sperrdauer, Zwischenablage. |
|
||||||
| `offscreen.html` / `offscreen.js` | Minimaldokument, das ausschließlich die Zwischenablage leert (MV3-konform). |
|
| `offscreen.html` / `offscreen.js` | Minimaldokument, das ausschließlich die Zwischenablage beschreibt bzw. leert (MV3-konform). |
|
||||||
|
| `urlmatch.js` | Gemeinsame Zuordnung Eintrag ↔ Seite (`VaultUrl`), geladen in allen drei Kontexten – damit Vorschlagsliste und Sicherheitswarnung dieselbe Regel anwenden. |
|
||||||
|
|
||||||
## Nachrichten (Auszug)
|
## Nachrichten (Auszug)
|
||||||
|
|
||||||
|
|
@ -38,9 +39,12 @@ Die Erweiterung ist ein **Manifest-V3-Client** ohne eigenen Server. Sie besteht
|
||||||
| `GET_LOCK` / `DO_UNLOCK` / `LOCK_NOW` | popup → bg | PIN-Sperre abfragen/entsperren/sperren |
|
| `GET_LOCK` / `DO_UNLOCK` / `LOCK_NOW` | popup → bg | PIN-Sperre abfragen/entsperren/sperren |
|
||||||
| `GET_ENTRIES` / `GET_MATCHING_ENTRIES` | popup/content → bg | Einträge (alle / passend zur URL) |
|
| `GET_ENTRIES` / `GET_MATCHING_ENTRIES` | popup/content → bg | Einträge (alle / passend zur URL) |
|
||||||
| `GET_PASSWORD` / `GET_TOTP` | popup/content → bg | Secret **on demand** |
|
| `GET_PASSWORD` / `GET_TOTP` | popup/content → bg | Secret **on demand** |
|
||||||
|
| `CREATE_ENTRY` / `UPDATE_ENTRY` / `DELETE_ENTRY` | popup → bg | Eintrag anlegen / ändern / löschen |
|
||||||
|
| `SET_PENDING_FILL` / `TAKE_PENDING_FILL` | content → bg | Passwort für den zweiten Login-Schritt hinterlegen bzw. abholen (nur im Speicher, je Tab) |
|
||||||
| `GET_FAVICON` | popup/content → bg | Favicon als Data-URL (serverseitig gecacht) |
|
| `GET_FAVICON` | popup/content → bg | Favicon als Data-URL (serverseitig gecacht) |
|
||||||
| `VAULT_FILL` | popup → content | Aktives Tab-Formular ausfüllen |
|
| `VAULT_FILL` | popup → content | Aktives Tab-Formular ausfüllen |
|
||||||
| `SCHEDULE_CLIP_CLEAR` | popup/content → bg | Zwischenablage-Leerung planen |
|
| `SCHEDULE_CLIP_CLEAR` | popup/content → bg | Zwischenablage-Leerung planen |
|
||||||
|
| `CLIP_WRITE` | content → bg | In die Zwischenablage schreiben, wenn die Seite selbst keinen Zugriff bekommt |
|
||||||
|
|
||||||
## Server-API (in OpenNIT)
|
## Server-API (in OpenNIT)
|
||||||
|
|
||||||
|
|
@ -51,6 +55,8 @@ Alle Endpunkte unter `/api/vault/extension/` mit `Authorization: Bearer <token>`
|
||||||
- `GET /entries/{id}/totp` – aktueller TOTP-Code + Restsekunden
|
- `GET /entries/{id}/totp` – aktueller TOTP-Code + Restsekunden
|
||||||
- `GET /entries/{id}/favicon?fetch=1` – gecachtes Favicon (bei Bedarf serverseitig geholt)
|
- `GET /entries/{id}/favicon?fetch=1` – gecachtes Favicon (bei Bedarf serverseitig geholt)
|
||||||
- `POST /entries` – neuen Eintrag anlegen
|
- `POST /entries` – neuen Eintrag anlegen
|
||||||
|
- `POST /entries/{id}` – Eintrag ändern (leeres Passwortfeld = unverändert)
|
||||||
|
- `POST /entries/{id}/delete` – Eintrag löschen
|
||||||
- `GET /status` – Token gültig? + `pin_enabled` / `pin_lock_secs`
|
- `GET /status` – Token gültig? + `pin_enabled` / `pin_lock_secs`
|
||||||
- `POST /unlock` – Tresor-PIN verifizieren + serverseitiges Entsperr-Fenster für den Token setzen
|
- `POST /unlock` – Tresor-PIN verifizieren + serverseitiges Entsperr-Fenster für den Token setzen
|
||||||
- `POST /lock` – Token sofort wieder sperren (Entsperr-Fenster zurücksetzen)
|
- `POST /lock` – Token sofort wieder sperren (Entsperr-Fenster zurücksetzen)
|
||||||
|
|
@ -74,5 +80,7 @@ Fensterdauer fest; „Bis der Browser geschlossen wird" nutzt ein langes Serverf
|
||||||
|
|
||||||
- **Kein Remote-Code** – alle Skripte im Paket (MV3-CSP-konform, keine Inline-Skripte).
|
- **Kein Remote-Code** – alle Skripte im Paket (MV3-CSP-konform, keine Inline-Skripte).
|
||||||
- **Secrets on demand** – Passwörter/TOTP erst bei Nutzung, nie in der Liste.
|
- **Secrets on demand** – Passwörter/TOTP erst bei Nutzung, nie in der Liste.
|
||||||
- **Kein persistentes Secret** – nur URL, Token, Einstellungen in `chrome.storage`.
|
- **Kein persistentes Secret** – nur URL, Sitzungstoken, Einstellungen in `chrome.storage`. Das Passwort
|
||||||
|
für einen mehrstufigen Login liegt ausschließlich im Speicher des Service Workers (je Tab, 30 s),
|
||||||
|
nie in `chrome.storage`, das auf die Festplatte geschrieben würde.
|
||||||
- **Server-seitige Krypto** – Ver-/Entschlüsselung im OpenNIT-Server, nicht im Browser.
|
- **Server-seitige Krypto** – Ver-/Entschlüsselung im OpenNIT-Server, nicht im Browser.
|
||||||
|
|
|
||||||
|
|
@ -16,15 +16,6 @@ Browser nicht. Es findet kein Tracking und keine Analyse statt.
|
||||||
**Warum:** Das In-Seite-Dropdown mit Vorschlägen und die Felderkennung laufen als Content-Script.
|
**Warum:** Das In-Seite-Dropdown mit Vorschlägen und die Felderkennung laufen als Content-Script.
|
||||||
Notwendig für Autofill und die 2FA-Erkennung (inkl. Shadow-DOM und mehrstufiger Logins).
|
Notwendig für Autofill und die 2FA-Erkennung (inkl. Shadow-DOM und mehrstufiger Logins).
|
||||||
|
|
||||||
## `scripting`
|
|
||||||
|
|
||||||
**Warum:** Werte werden über den nativen Value-Setter gesetzt und Events ausgelöst, damit auch
|
|
||||||
React/Vue/Angular-Formulare die Eingaben übernehmen.
|
|
||||||
|
|
||||||
## `activeTab`
|
|
||||||
|
|
||||||
**Warum:** Zugriff auf den aktiven Tab beim Ausfüllen aus dem Popup („Auf dieser Seite ausfüllen").
|
|
||||||
|
|
||||||
## `storage`
|
## `storage`
|
||||||
|
|
||||||
**Warum:** Lokale Speicherung von Server-URL, Zugriffstoken (per SSO) und Einstellungen; Entsperr-Status in
|
**Warum:** Lokale Speicherung von Server-URL, Zugriffstoken (per SSO) und Einstellungen; Entsperr-Status in
|
||||||
|
|
@ -38,7 +29,8 @@ Einträge-Caches (5 Min).
|
||||||
## `offscreen`
|
## `offscreen`
|
||||||
|
|
||||||
**Warum:** In Manifest V3 hat der Service Worker keinen DOM-Zugriff. Zum programmatischen Leeren der
|
**Warum:** In Manifest V3 hat der Service Worker keinen DOM-Zugriff. Zum programmatischen Leeren der
|
||||||
Zwischenablage wird ein kurzlebiges Offscreen-Dokument (Reason `CLIPBOARD`) genutzt.
|
Zwischenablage wird ein kurzlebiges Offscreen-Dokument (Reason `CLIPBOARD`) genutzt – sowohl zum
|
||||||
|
Bereitlegen eines 2FA-Codes als auch zum anschließenden Leeren.
|
||||||
|
|
||||||
## `identity`
|
## `identity`
|
||||||
|
|
||||||
|
|
@ -48,6 +40,10 @@ OpenNIT-Login-Seite und empfängt die Weiterleitung an `https://<extension-id>.c
|
||||||
|
|
||||||
## Bewusst NICHT angefordert
|
## Bewusst NICHT angefordert
|
||||||
|
|
||||||
|
- **`scripting` / `activeTab`** – nicht nötig: Das Content-Script wird über `content_scripts` geladen,
|
||||||
|
das Ausfüllen aus dem Popup läuft über eine Nachricht an das bereits laufende Script. Der Zugriff auf
|
||||||
|
den aktiven Tab ist bereits durch `host_permissions` abgedeckt.
|
||||||
|
|
||||||
- **`tabs`** – entfällt: Die aktive Tab-Adresse ist bereits über `host_permissions` verfügbar. Dadurch
|
- **`tabs`** – entfällt: Die aktive Tab-Adresse ist bereits über `host_permissions` verfügbar. Dadurch
|
||||||
erscheint **keine** „Browserverlauf lesen"-Warnung.
|
erscheint **keine** „Browserverlauf lesen"-Warnung.
|
||||||
- Keine `cookies`, `history`, `webRequest`, `downloads`, `notifications` o. Ä.
|
- Keine `cookies`, `history`, `webRequest`, `downloads`, `notifications` o. Ä.
|
||||||
|
|
|
||||||
17
extension/LICENSE.txt
Normal file
17
extension/LICENSE.txt
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
OpenNIT Vault – Browser-Erweiterung
|
||||||
|
Copyright (C) 2025 Friederich Loheide
|
||||||
|
|
||||||
|
Dieses Programm ist freie Software: Sie koennen es unter den Bedingungen
|
||||||
|
der GNU Affero General Public License, Version 3, weitergeben und/oder
|
||||||
|
veraendern.
|
||||||
|
|
||||||
|
Die Veroeffentlichung erfolgt in der Hoffnung, dass es nuetzlich ist,
|
||||||
|
jedoch OHNE JEDE GEWAEHRLEISTUNG - sogar ohne die implizite Gewaehr-
|
||||||
|
leistung der Marktreife oder der Eignung fuer einen bestimmten Zweck.
|
||||||
|
Einzelheiten regelt die GNU Affero General Public License.
|
||||||
|
|
||||||
|
Lizenztext: https://www.gnu.org/licenses/agpl-3.0.html
|
||||||
|
Quelltext: https://opennit.de
|
||||||
|
|
||||||
|
Der vollstaendige Lizenztext liegt der OpenNIT-Installation als Datei
|
||||||
|
LICENSE bei und kann ueber die oben genannte Adresse bezogen werden.
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
"name": "OpenNIT Vault",
|
"name": "OpenNIT Vault",
|
||||||
"version": "2.4.1",
|
"version": "2.4.1",
|
||||||
"description": "OpenNIT Vault – Passwort-Manager mit Autofill für Benutzer-, Passwort- und 2FA-Felder direkt im Browser.",
|
"description": "OpenNIT Vault – Passwort-Manager mit Autofill für Benutzer-, Passwort- und 2FA-Felder direkt im Browser.",
|
||||||
|
"homepage_url": "https://opennit.de",
|
||||||
"permissions": [
|
"permissions": [
|
||||||
"storage",
|
"storage",
|
||||||
"activeTab",
|
"activeTab",
|
||||||
|
|
|
||||||
63
extension/urlmatch.js
Normal file
63
extension/urlmatch.js
Normal file
|
|
@ -0,0 +1,63 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Gemeinsame Zuordnung Eintrag ↔ Seite.
|
||||||
|
*
|
||||||
|
* Wird in allen drei Kontexten geladen (Service Worker via importScripts,
|
||||||
|
* Popup via <script>, Seiten via content_scripts) – damit Vorschlagsliste und
|
||||||
|
* Sicherheitswarnung dieselbe Regel anwenden.
|
||||||
|
*
|
||||||
|
* Regel: Ein Eintrag passt zu einer Seite, wenn deren Host dem hinterlegten Host
|
||||||
|
* entspricht oder eine Subdomain davon ist. Die Gegenrichtung gilt bewusst nicht –
|
||||||
|
* ein Eintrag für `vpn.firma.de` passt nicht zu `firma.de`.
|
||||||
|
*/
|
||||||
|
var VaultUrl = (function () {
|
||||||
|
/**
|
||||||
|
* Host einer Adresse in vergleichbarer Form (klein, ohne `www.`).
|
||||||
|
* @param {string} raw Adresse mit oder ohne Schema
|
||||||
|
* @return {string} Host oder '' wenn nicht bestimmbar
|
||||||
|
*/
|
||||||
|
function host(raw) {
|
||||||
|
const s = String(raw || '').trim();
|
||||||
|
if (!s) return '';
|
||||||
|
try {
|
||||||
|
return new URL(s.includes('://') ? s : 'https://' + s).hostname.replace(/^www\./, '').toLowerCase();
|
||||||
|
} catch {
|
||||||
|
return s.replace(/^www\./, '').toLowerCase();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Hinterlegte Adressen eines Eintrags (mehrzeilig) als Liste. */
|
||||||
|
function list(entryUrls) {
|
||||||
|
if (Array.isArray(entryUrls)) return entryUrls.map(u => String(u || '').trim()).filter(Boolean);
|
||||||
|
return String(entryUrls || '').split('\n').map(u => u.trim()).filter(Boolean);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Passt einer der hinterlegten Hosts zur Seite?
|
||||||
|
* @param {string|string[]} entryUrls Adressen des Eintrags
|
||||||
|
* @param {string} pageUrl Adresse der Seite
|
||||||
|
* @return {boolean}
|
||||||
|
*/
|
||||||
|
function matches(entryUrls, pageUrl) {
|
||||||
|
const pageHost = host(pageUrl);
|
||||||
|
if (!pageHost) return false;
|
||||||
|
return list(entryUrls).some(raw => {
|
||||||
|
let eh = host(raw);
|
||||||
|
if (eh.startsWith('*.')) eh = eh.slice(2);
|
||||||
|
if (!eh) return false;
|
||||||
|
return pageHost === eh || pageHost.endsWith('.' + eh);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Wie `matches`, wertet einen Eintrag ohne hinterlegte Adresse aber als passend. */
|
||||||
|
function matchesOrUnset(entryUrls, pageUrl) {
|
||||||
|
if (!list(entryUrls).length) return true;
|
||||||
|
return matches(entryUrls, pageUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
return { host, list, matches, matchesOrUnset };
|
||||||
|
})();
|
||||||
|
|
||||||
|
// Im Service Worker steht `self` zur Verfügung, im Popup/Content-Script `window`.
|
||||||
|
if (typeof self !== 'undefined') self.VaultUrl = VaultUrl;
|
||||||
|
|
@ -45,7 +45,7 @@ SICHERHEIT & DATENSCHUTZ
|
||||||
• Passwörter werden erst im Moment der Nutzung abgerufen und nicht dauerhaft gespeichert
|
• Passwörter werden erst im Moment der Nutzung abgerufen und nicht dauerhaft gespeichert
|
||||||
|
|
||||||
EINRICHTUNG
|
EINRICHTUNG
|
||||||
Server-URL eintragen, im OpenNIT-Tresor einen API-Token erzeugen und einfügen – fertig.
|
Server-URL eintragen, auf „Mit OpenNIT anmelden" klicken und den Zugriff bestätigen – fertig.
|
||||||
|
|
||||||
OpenNIT Vault benötigt eine laufende OpenNIT-Instanz.
|
OpenNIT Vault benötigt eine laufende OpenNIT-Instanz.
|
||||||
```
|
```
|
||||||
|
|
@ -71,7 +71,7 @@ SECURITY & PRIVACY
|
||||||
• Passwords are fetched only at the moment of use and never stored permanently
|
• Passwords are fetched only at the moment of use and never stored permanently
|
||||||
|
|
||||||
SETUP
|
SETUP
|
||||||
Enter your server URL, generate an API token in the OpenNIT vault, paste it — done.
|
Enter your server URL, click "Sign in with OpenNIT" and approve access — done.
|
||||||
|
|
||||||
OpenNIT Vault requires a running OpenNIT instance.
|
OpenNIT Vault requires a running OpenNIT instance.
|
||||||
```
|
```
|
||||||
|
|
@ -93,7 +93,7 @@ Deutsch (primär), Englisch
|
||||||
|
|
||||||
## Datenschutz-Angaben (Data usage im Dashboard)
|
## Datenschutz-Angaben (Data usage im Dashboard)
|
||||||
|
|
||||||
- Erhobene Datentypen: **Authentifizierungsinformationen** (API-Token), **Website-Inhalte** nur für
|
- Erhobene Datentypen: **Authentifizierungsinformationen** (Sitzungstoken), **Website-Inhalte** nur für
|
||||||
Autofill (verlassen den Browser nicht).
|
Autofill (verlassen den Browser nicht).
|
||||||
- Nicht verkauft/weitergegeben. Nicht für Werbung/Bonität genutzt.
|
- Nicht verkauft/weitergegeben. Nicht für Werbung/Bonität genutzt.
|
||||||
- Verschlüsselte Übertragung (HTTPS).
|
- Verschlüsselte Übertragung (HTTPS).
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue