Add cloud sync UI (settings, status bar, workspace creation)
Details
Implement the full Cloud Sync UI layer connecting to the existing
Rust FFI CloudSyncService backend. This adds:
- CloudSyncSettingsViewModel: manages auth, passphrase setup/unlock,
mnemonic recovery, sync status, quota, and device list. Follows the
ConnectionsViewModel pattern as a composed property on SettingsViewModel.
- CloudSyncSettingsSection view: UserControl with visibility-driven
state sections (auth form, passphrase setup, passphrase entry,
recovery form, sync dashboard with status/quota/devices).
- Settings panel integration: new "Cloud Sync" expander between
Connections and Security sections, with xmlns:views namespace.
- Status bar cloud sync indicator: StorageStatePillViewModel now checks
for PrivStackCloud sync tier before file-sync/P2P logic. Shows
"Syncing (N)" with pending count, "Synced" when caught up, or
"Cloud (Paused)" when authenticated but not syncing. Includes a
5-second DispatcherTimer poll while cloud sync is active.
- Workspace creation cloud sync option: WorkspaceSwitcherViewModel gains
SelectedSyncTier and IsCloudSyncAvailable properties plus
SelectCloudSync command. The overlay shows a "PrivStack Cloud" button
(E2E encrypted) alongside Google Drive/iCloud/Custom options.
ConfirmStorageLocation registers the workspace with cloud if selected.
- Unit tests: 18 tests for CloudSyncSettingsViewModel covering auth,
passphrase validation, mnemonic, sync start/stop, quota, and devices.
5 tests for StorageStatePill cloud status model behavior.
Version bumped to 1.27.0 (minor: new feature).
Add Emergency Kit recovery feature (Rust 1.9.0, Desktop 1.26.0)
Details
BIP39 12-word mnemonic-based master password recovery system that allows
users to regain access to their encrypted data without a full data wipe.
Rust core:
- privstack-crypto: RecoveryBlob type with create/open/reencrypt functions
that encrypt the master key with a mnemonic-derived key
- privstack-vault: setup_recovery(), has_recovery(), and
reset_password_with_recovery() methods on Vault and VaultManager, with
full re-encryption of all vault blobs on password reset
- privstack-ffi: Three new FFI functions (setup_recovery, has_recovery,
reset_with_recovery) with error codes RecoveryNotConfigured=34 and
InvalidRecoveryMnemonic=35, including entity_store and blob_store
re-encryption
C# desktop:
- Native bindings: P/Invoke declarations, IAuthService interface methods,
and PrivStackService implementations for all three recovery operations
- EmergencyKitPdfService: QuestPDF-based A4 PDF generator with numbered
word grid, security warnings, and recovery instructions
- Setup wizard: New EmergencyKit step after Password for new installs,
displaying recovery words and requiring PDF download before proceeding
- Recovery flow: Two-step RecoveryViewModel (enter 12 words, set new
password) with RecoveryView, wired into UnlockViewModel and App.axaml.cs
navigation. Unlock screen shows conditional recovery link when configured
- Settings: Emergency Kit section in Security expander showing status
indicator, generate/regenerate button, word display, and PDF download
Add per-entity encryption, DekRegistry, and S3 key persistence (1.8.0)
Details
Cloud sync engine now encrypts/decrypts batches per-entity using a
thread-safe DekRegistry (Arc<RwLock<HashMap<String, DerivedKey>>>).
The sync engine groups outbox events by entity_id and encrypts each
group with the entity's DEK via ChaCha20-Poly1305. Per-entity cursor
tracking replaces the single cursor_position.
FFI auth.rs now persists passphrase-encrypted and mnemonic-encrypted
private keys to S3 during setup_passphrase, and retrieves them during
enter_passphrase and recover_from_mnemonic. This uses workspace-scoped
STS credentials obtained from the API's list_workspaces endpoint.
Added recovery_key_s3_key() helper to compaction.rs for the mnemonic
backup storage path. PrivStackHandle gains cloud_dek_registry and
cloud_active_workspace fields for FFI state management.
Implement IShareableBehavior in 5 plugins for cloud sync sharing
Details
Adds IShareableBehavior capability to Tasks (1.8.0), Notes (1.37.0), Journal (1.4.0), Snippets (1.4.0), and RSS (1.6.0) plugins. Each plugin declares its shareable entity types, provides entity title/type resolution for the share dialog, and registers the capability in OnInitializeAsync. Calendar, Files, and Contacts are excluded from sharing per the cloud sync implementation plan (Calendar has no shareable entities, Files has complex blob handling deferred to Phase 8, Contacts deferred for privacy concerns).
Add IShareableBehavior capability interface to SDK (1.26.0)
Details
New capability interface for plugins that support per-entity sharing via PrivStack Cloud. Declares ShareableEntityTypes, IsExcludedFromSharing (default false), GetEntityTitle, and GetEntityType. Follows established capability registration pattern (Host.Capabilities.Register in OnInitializeAsync). SDK version bumped to 1.26.0 for new public API surface.
Get notified about new releases