Memories
Android-/iOS-Client für Memories. Die Flutter-Oberfläche ruft den gemeinsamen Rust-Dienst
über crates/ffi/memories.h auf; sie implementiert kein separates Speicher- oder
Kryptografieprotokoll.
Modus auswählen
Wählen Sie beim ersten Start, einschließlich des ersten Starts nach einem Upgrade von einer Version ohne gespeicherte Moduspräferenz, wo Sie arbeiten möchten:
| Modus | Speicherort der Daten | Voraussetzungen |
|---|---|---|
| Standalone | Verschlüsselte Bibliothek auf diesem Telefon; funktioniert offline | Eine lokale Bibliothek erstellen oder die vorhandene entsperren |
| Center | Gehosteter Speicher Ihres selbst betriebenen Servers | Server-Origin wie https://center.example.com und ein Mitgliedstoken |
| SaaS | Der gehostete Speicher unter https://memories.ivjn.us |
Ein Mitgliedstoken für diesen Dienst; die URL ist fest vorgegeben |
Der Modus Center der App bezeichnet einen Server mit aktiviertem gehostetem Speicher
(memories-center --data DIR). Er unterscheidet sich von einem reinen Ticket-Autorisierungs-
Center, das signierte Tickets für lokale Geräte verteilt. Center und SaaS verwenden
denselben gehosteten Client; sie unterscheiden sich bei der Endpunktauswahl und dem gespeicherten
Verbindungsprofil. Bei keinem der beiden muss zunächst eine lokale Bibliothek erstellt oder entsperrt werden.
Erste Verbindung
- Wählen Sie einen Modus. Die App merkt sich die Auswahl für den nächsten Start.
- Erstellen oder entsperren Sie für Standalone Ihre Bibliothek. Geben Sie für Center den HTTPS-Origin des Servers ohne API-Pfad ein; behalten Sie für SaaS die feste Dienstadresse bei.
- Geben Sie in beiden gehosteten Modi das vom Dienstbetreiber bereitgestellte Mitgliedstoken ein und wählen Sie Verbinden. Rolle und Berechtigungsumfang des Mitglieds bestimmen, was es tun kann; verwenden Sie für die Arbeit mit Inhalten ein Mitgliedstoken und kein Administrator-Token des Betreibers.
- Öffnen Sie nach dem Verbinden Gehostetes Wissen, um Wissen zu durchsuchen, zu suchen, anzuzeigen, zu bearbeiten oder zu löschen. Sie können auch Anfragen prüfen oder Gekoppelte Geräte öffnen. Serveradresse, aktueller Tresor und gewährter Berechtigungsumfang bleiben sichtbar.
Gehostete Inhalte werden im Ruhezustand mit einem vom Betreiber verwalteten Passwort verschlüsselt, aber der Betreiber kann sie lesen. Die App zeigt Server kann mitlesen an. Zwischen Geräten übertragene versiegelte Geheimnisse haben eine separate Ende-zu-Ende-Schutzgrenze.
Wechseln, trennen und erneut verbinden
Verwenden Sie vor oder nach der Anmeldung Modus wechseln in der Hauptsymbolleiste. Der Dialog kennzeichnet den aktuellen Modus und erläutert die Auswirkungen; wählen Sie zum Wechseln einen anderen Modus oder Abbrechen, um die Sitzung beizubehalten. Schließen Sie zuerst einen geöffneten Editor ab oder verlassen Sie ihn; beim Verlassen eines ungespeicherten Entwurfs wird eine Bestätigung verlangt.
| Aktion | Ergebnis |
|---|---|
| Modus wechseln | Sperrt die lokale Bibliothek, beendet die Freigabe, schließt die aktive gehostete Verbindung und entfernt sichtbare Inhalte; speichert den neuen Modus |
| Zu Standalone zurückkehren | Öffnet den Bildschirm der lokalen Bibliothek erneut im gesperrten Zustand; vorhandene Daten bleiben erhalten |
| Center oder SaaS erneut öffnen | Stellt die gespeicherte Verbindung dieses Modus wieder her, sofern verfügbar |
| Verbindung trennen | Entfernt das gespeicherte Token des aktuellen Profils und schließt dessen Sitzung; die URL und das Profil des anderen Modus bleiben erhalten |
| App in den Hintergrund verschieben | Sperrt den lokalen Zugriff, entfernt gehostete Sitzungen und schließt sensible Seiten und Entwürfe |
| Aus dem Hintergrund zurückkehren | Verwenden Sie auf der gehosteten Seite Gespeicherte Sitzung erneut verbinden oder geben Sie ein Token ein und verbinden Sie sich erneut |
Beim Wechsel werden Bibliotheksdaten weder hochgeladen, kopiert, zusammengeführt noch gelöscht. Das Trennen der Verbindung widerruft das Token auf dem Server nicht. Center und SaaS speichern ihre URL-/Token-Paare in getrennten Einträgen des sicheren Plattformspeichers. Bei einem Upgrade wird die alte gehostete Verbindung nur in den passenden Modus importiert; siehe Konfiguration und Migration.
Verfügbare Funktionen
| Arbeitsablauf | Standalone | Center / SaaS |
|---|---|---|
| Lokale Bibliothek erstellen, sichern und wiederherstellen | Verfügbar | Verwenden Sie den gehosteten Dienst; keine lokale Einrichtung erforderlich |
| Wissen durchsuchen, suchen, anzeigen, bearbeiten und löschen | Nach dem Entsperren verfügbar | Gehostetes Wissen, dessen Aktionen durch den Token-Berechtigungsumfang eingeschränkt sind |
| Wissenskarten erstellen | Lokaler ganzseitiger Editor | Gehosteter ganzseitiger Editor mit den von der gehosteten API akzeptierten Feldern |
| Gehostete Autorisierungsanfragen prüfen | Zu Center oder SaaS wechseln | Registerkarten für offene Anfragen und Verlauf, Bestätigung für Genehmigung/Ablehnung und Aktualisierung |
| Geräte koppeln | Lokaler Genehmigungsablauf für Geräte/Mitglieder | Gehostete Kopplung sowie Steuerelemente für versiegelte Geheimnisse und Geräte, abhängig von den Berechtigungen |
| Relay-Freigabe und Cloud-Verbindungen | Über die Steuerelemente der lokalen Bibliothek verfügbar | Auf der gehosteten Seite nicht angeboten |
Bei der gehosteten Erstellung entfallen Tags, Quelle und Beziehungen; beim Bearbeiten einer vorhandenen gewöhnlichen Karte werden diese Felder unterstützt und andere Metadaten beibehalten. Gewöhnliche Erinnerungen verwenden den Texteditor. Strukturierte Profile, geschützte Karten, Typvorlagen und E2E-Karten können in diesem allgemeinen Editor nur angezeigt werden. Beide Editoren behalten einen Entwurf, wenn das Speichern fehlschlägt; Entwürfe bleiben beim Sperren oder beim Verschieben der App in den Hintergrund nicht erhalten. Siehe Inhaltsbearbeitung und Autorisierung.
Fehlerbehebung bei Verbindungen
Die App validiert Tokens über /v1/session, bevor sie eine Verbindung speichert, auch
bei Konten mit reinem Schreibzugriff. Aktualisieren Sie selbst betriebene Server zusammen mit der App.
Konten mit reinem Lesezugriff können Inhalte ohne Änderungssteuerelemente durchsuchen; Konten mit reinem Schreibzugriff
können Inhalte erstellen, ohne die Bibliothek oder die Typenliste zu laden. Der Server autorisiert jeden
Vorgang erneut. Die Suche schließt private Inhalte, Zugangsdaten und Dateien aus; löschen Sie
die Suchanfrage, um zur Wissensliste zurückzukehren. Abgelaufene/widerrufene Sitzungen, unzureichende
Berechtigungen und nicht verfügbare Server führen zu lokalisierten Fehlermeldungen. Bei einem 401 müssen Sie
die Verbindung trennen und mit einem gültigen Token erneut herstellen.
- Verbindung nicht möglich: Prüfen Sie den vollständigen HTTPS-Origin, Netzwerk, Zertifikat und
Token. Ein selbst betriebenes Center muss gehosteten Speicher aktivieren; ein reiner Ticket-Dienst
kann diesen Bildschirm nicht bereitstellen.
localhostauf einem Telefon bezeichnet das Telefon selbst. - Zugriff verweigert: Prüfen Sie mit dem Dienstbetreiber Tresor, Rolle, Berechtigungsumfang und Ablaufdatum des Tokens. Die Auswahl eines anderen Modus gewährt keinen Zugriff.
- Keine offenen Anfragen: Aktualisieren Sie die Ansicht und prüfen Sie die Zuordnung von Antragsteller/Tresor/Genehmigendem. Die Registerkarte für den Verlauf ist kein vollständiges Server-Auditprotokoll.
- Sitzung nach Wechsel in den Hintergrund geschlossen: Verbinden Sie sich ausdrücklich erneut. Ungespeicherte Entwürfe wurden beim Sperren verworfen und können nicht wiederhergestellt werden.
- Nativer Dienst konnte nicht starten: Verwenden Sie einen Build mit der passenden Rust- Bibliothek. Auch gehostete Modi verwenden FFI und benötigen die native Bibliothek.
Entwicklung
Erstellen Sie zuerst die nativen Bibliotheken mit scripts/build-android.ps1 oder
scripts/build-ios.sh vom Repository-Stammverzeichnis aus. Anforderungen an die Toolchain und Signierungsanweisungen
finden Sie in der README im Stammverzeichnis.
Verwenden Sie Flutter 3.44.2 entsprechend der CI. Führen Sie in diesem Verzeichnis Folgendes aus:
flutter pub get
flutter gen-l10n
dart format --output=none --set-exit-if-changed lib test integration_test
flutter analyze
flutter test
flutter test integration_test/native_smoke_test.dart -d DEVICE_ID
flutter run -d DEVICE_ID
Widget-Tests verwenden ein simuliertes Backend, um das Lebenszyklusverhalten des Sperrbildschirms, Modusauswahl/-wechsel, die Isolation gehosteter Sitzungen, Karten, Lokalisierung und Abläufe mit Geheimnisreferenzen zu prüfen. Zwischenablage-Tests simulieren Flutters Plattformkanal; sie prüfen nicht die Übertragung in eine Betriebssystem-Zwischenablage. Der Integrationstest lädt die echte native Bibliothek und erstellt eine temporäre Datenbank auf dem Gerät. Normale Ausführungen verwenden das plattformspezifische Anwendungsunterstützungsverzeichnis und einen durch Keychain/Keystore geschützten lokalen Faktor. Verwenden Sie bei der Entwicklung Testdaten; die aktuellen Vertrauensgrenzen stehen in SECURITY.md.
Dokumentgeheimnisse und Zwischenablage
Öffnen Sie im Standalone-Modus das Menü einer Erinnerung/Karte und wählen Sie Geheimnis im Dokument schützen, um einen exakten Wert im aktuellen Inhalt durch eine benannte Referenz zu ersetzen. Bestätigen Sie die Warnung zum Verlauf, geben Sie den Referenznamen und das verborgene Geheimnis ein und autorisieren Sie den Vorgang, wenn Sie dazu aufgefordert werden. Der Rust-Dienst speichert die Zugangsdaten und ersetzt den Inhalt in einer einzigen Transaktion.
Wählen Sie bei einem Dokument, einer geschützten Karte oder Zugangsdaten Geheimnis kopieren, um dessen aktuellen Wert nach Bestätigung und Autorisierung zu kopieren. Dokumente zeigen zuerst eine Referenzauswahl an. OTP-Karten kopieren den Seed; ihre separate OTP-Aktion erzeugt einen Einmalcode. Werte werden nicht angezeigt, und verspätete Antworten nach einem Wechsel in den Hintergrund oder nach dem Sperren werden verworfen. Eine abgeschlossene Kopie in der Zwischenablage kann nach dem Sperren bestehen bleiben.
Gewöhnliche Bearbeitungen erhalten die Referenzzuordnungen. Alte Dokumentversionen und vorhandene Sicherungen behalten ihre bisherigen Inhalte. Siehe den Wiki-Leitfaden zu Geheimnissen für Referenzregeln, Aktualisierungen, Kompatibilität und Grenzen der Zwischenablage. Erstellen Sie die native Bibliothek zusammen mit der Flutter-App neu, wenn Sie diese Vorgänge hinzufügen.
Lokalisierung
Verwenden Sie das Sprachsymbol in der App-Leiste, um Englisch, vereinfachtes Chinesisch, Japanisch, Deutsch, Französisch oder die Systemvorgabe auszuwählen. Die Präferenz wird getrennt von der verschlüsselten Bibliothek gespeichert und ist auch im gesperrten Zustand verfügbar. Beim Wechseln der Sprache bleibt die aktuelle Bibliothekssitzung erhalten.
Übersetzungen liegen in lib/l10n/app_*.arb; flutter gen-l10n erzeugt das ignorierte
Verzeichnis lib/l10n/generated/. Material- und Cupertino-Steuerelemente verwenden Flutters
Lokalisierungsdelegaten. Folgen Sie dem Lokalisierungsleitfaden,
wenn Sie Meldungen oder Sprachen hinzufügen.
Sitzung freigeben (Relay-RPC-Host)
Im Standalone-Modus bietet das Überlaufmenü bei entsperrter App im Vordergrund
Sitzung freigeben an.
Die App verbindet sich mit einem Token hoher Entropie mit wss://…/v1/rpc/{room}/a, damit sich eine Desktop-CLI
als Slot b anschließen kann (MEMORIES_DAEMON_RELAY / MEMORIES_DAEMON_ROOM /
MEMORIES_DAEMON_TOKEN). Ein Wechsel in den Hintergrund oder das Sperren beendet die Sitzung. Für das
MVP gibt es auf Mobilgeräten keinen HTTP-/WS-Listener; die native FFI-Sperrliste gilt weiterhin. Siehe
Remote-Daemon.
Biometrisches Entsperren und sensible Aktionen
Verwenden Sie in der entsperrten Standalone-Bibliothek das Überlaufmenü →
Mit Biometrie / Gerätesperre entsperren (standardmäßig deaktiviert; das Aktivieren
erfordert eine Systemprüfung). lib/biometric.dart kapselt local_auth
(BiometricPrompt unter Android mit Geräte-PIN/-Muster/-Passwort als Alternative; Face ID /
Touch ID unter iOS, NSFaceIDUsageDescription in Info.plist). MainActivity
erweitert FlutterFragmentActivity, wie von local_auth vorausgesetzt.
- Das Bibliothekspasswort für das schnelle Entsperren wird mit
AndroidOptions.biometric(resetOnError: false)gespeichert: einem Android-Keystore-AES-Schlüssel mitsetUserAuthenticationRequired(true)undsetInvalidatedByBiometricEnrollment(true). Unter iOS verwendet der Keychain-EintragKeychainAccessibility.passcode. - Durch eine Authentifizierungsprüfung geschützt: Entsperren der Bibliothek, Kopieren/Anzeigen von Zugangsdaten im Klartext, Verwenden geschützter Karten / OTP, Genehmigen von Kopplungs- und Hosted-Center-Anfragen, Versiegeln und erneutes Versiegeln.
- Wenn sich die biometrische Registrierung ändert (
KeyPermanentlyInvalidatedException), informiert die App den Benutzer, prüft erneut mit den Gerätezugangsdaten, verwirft nur die veraltete Kopie für das schnelle Entsperren und erstellt den Schlüssel nach einem einmaligen Entsperren mit Passwort neu. Die Bibliothek wird niemals gelöscht. - Keine Biometrie/Gerätezugangsdaten oder deaktivierter Schalter: der bestehende Passwortablauf.
- Tests simulieren
DeviceAuth/UnlockSecretStore(test/biometric_test.dart).
Inhaltseditor
lib/content_editor.dart wird gemeinsam für neue Erinnerungen, Zugangsdaten und Hosted-
Center-Einträge verwendet: Dateiimport (Titel aus dem Dateinamen), nichtproportionale Schrift für
.env-ähnliche Inhalte (automatisch erkannt oder manuell umgeschaltet) und ein inhaltsorientierter Name, der
aus dem Dateinamen oder der ersten nicht leeren Zeile abgeleitet und erst beim
Speichern abgefragt wird, wenn er noch leer ist. Handschrift (Stift/Radierer/Rückgängig/Leeren, ML Kit Digital
Ink) und OCR (Kamera/Fotos/Datei, ML Kit-Texterkennung) laufen auf dem Gerät; siehe
Handschrift und OCR. Widget-Tests injizieren simulierte ScanServices.
Erinnerungen und Wissenskarten bleiben geöffnet, bis das Speichern erfolgreich ist. Ein fehlgeschlagener Schreibvorgang hält den Entwurf für einen erneuten Versuch verfügbar; das Verlassen mit Änderungen verlangt eine Bestätigung. Entwürfe werden nur im Arbeitsspeicher gehalten und beim Wechsel in den Hintergrund oder beim Sperren wegen Inaktivität weiterhin verworfen. Der Dateiimport fragt vor dem Ersetzen vorhandenen Textes nach. Erinnerungen zeigen ihre Einstellung privat/gewöhnlich vor dem Speichern an, und erneute Versuche für Anhänge überspringen Dateien, die bereits während der aktuellen Bearbeitung gespeichert wurden.
Wissenskarten verwenden einen ganzseitigen Editor mit dauerhaft verfügbarer Speicheraktion, benutzerdefinierten Feldern, Tags, Quellen und Beziehungen. Inhalt bearbeiten öffnet den gemeinsamen Texteditor für Dateiimport, Handschrift und OCR. Bei der gehosteten Erstellung werden nur die von der bestehenden mobilen API akzeptierten Metadaten angeboten.
Autorisierung auf Mobilgeräten
Die Center- und SaaS-Seiten trennen offene Anfragen vom Verlauf. Prüfen Sie Antragsteller, Tresor, Zugriffsumfang, Dauer und die vollständige Begründung, bevor Sie eine Genehmigung oder Ablehnung bestätigen. Für die Genehmigung gilt weiterhin die bestehende Geräteauthentifizierungs- prüfung, und der Antragsteller muss die Berechtigung separat abholen. Bei Fehlern bleibt die Anfrage für einen erneuten Versuch erhalten; ziehen Sie zum Aktualisieren oder verwenden Sie die Aktualisierungsschaltfläche.
Die Center-Anfrage-API liefert keinen vollständigen Entscheidungsverlauf zurück. Die Registerkarte für den Verlauf kombiniert während der aktuellen Verbindung getroffene Entscheidungen mit genehmigten Anfragen, die das Center zurückliefert. Diese lokalen Datensätze werden beim Verlassen der Seite entfernt. Fehlgeschlagene neue Verbindungen werden geschlossen, ohne das gespeicherte Profil zu ersetzen.
Die lokale Mitgliederverwaltung zeigt nur Aktionen an, die gemäß den angezeigten Rollen zulässig sind. Bestätigungen benennen das Mitglied und den alten/neuen Zugriff. Der Rust-Dienst prüft die aktuelle Richtlinie erneut; die Filterung der Oberfläche gewährt keine Befugnisse. Die Owner- Mitgliedschaft kann nicht über gewöhnliche Rollenaktionen geändert werden, und nur Owner sehen die Eigentumsübertragung.
Marke
Logoquelle: assets/brand/logo.svg (+ logo-mono.svg, adaptives
logo-foreground.svg). Symbole und Startbilder wurden mit
rsvg-convert gerendert; verwenden Sie bei Logoänderungen erneut dieselben Größen.