Summary
Per-object / per-type sync exclusion is now enforced on the built-in server sync path (fixed in #43), but the gist-sync plugin export path is not filtered: it uploads excluded objects — entity JSON and their secret material — to the user's GitHub gist anyway.
Mechanism
#43 added an excluded_ids: Option<Vec<String>> parameter to the backup_export Tauri command; the server-sync push() in src/services/sync.ts now passes the resolved excluded-id set so excluded entities and their secrets are stripped before encryption.
The plugin runtime calls the same command without that argument:
// src/plugins/runtime.ts:811 (exportState)
const blob: number[] = await invoke("backup_export", {
encKey: encKeyBytes,
accountId: "gist-sync",
deviceId,
// no excludedIds → Option defaults to None → strip_excluded is a no-op
});
Because excluded_ids is Option, an absent argument deserializes to None, so strip_excluded early-returns and the blob contains every object — including ones the user marked cloud-off. For a user relying on the gist-sync plugin, an excluded Host/Identity/SSH Key (and its password / private key) still leaves the device.
Expected
Excluding an object should keep it off every sync destination, not just the built-in server. Either:
- pass
getExcludedObjectIds() (from src/services/sync.ts) into the plugin's exportState → backup_export invoke, so the same filter applies; or
- if plugin sync is intentionally exempt, make that explicit in the UI (e.g. a note on the exclusion toggle that third-party sync plugins are not covered), so the
cloud-off badge doesn't over-promise.
Notes
Summary
Per-object / per-type sync exclusion is now enforced on the built-in server sync path (fixed in #43), but the gist-sync plugin export path is not filtered: it uploads excluded objects — entity JSON and their secret material — to the user's GitHub gist anyway.
Mechanism
#43 added an
excluded_ids: Option<Vec<String>>parameter to thebackup_exportTauri command; the server-syncpush()insrc/services/sync.tsnow passes the resolved excluded-id set so excluded entities and their secrets are stripped before encryption.The plugin runtime calls the same command without that argument:
Because
excluded_idsisOption, an absent argument deserializes toNone, sostrip_excludedearly-returns and the blob contains every object — including ones the user markedcloud-off. For a user relying on the gist-sync plugin, an excluded Host/Identity/SSH Key (and its password / private key) still leaves the device.Expected
Excluding an object should keep it off every sync destination, not just the built-in server. Either:
getExcludedObjectIds()(fromsrc/services/sync.ts) into the plugin'sexportState→backup_exportinvoke, so the same filter applies; orcloud-offbadge doesn't over-promise.Notes
getExcludedObjectIds()(src/services/sync.ts) and the Ruststrip_excludedinsidebackup_export— the plugin path just needs to supply the id set.