feat(sync): Storage pane UI for encrypted settings sync (opt-in toggle + restore)

Wires the storage-credential sync (6f7f4196) into the profile Storage pane.

UI (components/profile-modal.html): a "Cross-device sync" card shown only when
storage is unlocked — an opt-in toggle ("Sync these settings to my Nostr account
(encrypted)"), a "Restore from my Nostr account" button, the public-relay /
key-compromise warning copy, and a status line.

Controller (ProfileStorageController):
- toggle on -> storageSyncService.enable() (encrypt + publish), with rollback +
  message if nothing is stored yet; toggle off -> disable() (wipe the note)
- restore -> pull() + re-render the pane so the restored connection shows
- after a successful Save, re-push the synced copy when sync is enabled

Also routes the core's relay READ through the subscription manager (injected
listEvents) instead of pool.list, satisfying lint:pool-access for the new file;
the facade supplies it via nostrClient.getSubscriptionManager().list.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
thePR0M3TH3ANandClaude Opus 4.8 committed 2026-06-21 17:17:35 -04:00
1 parent 6f7f419636
commit 7376ff91e0
5 files changed
+185 -3

No files matched your search

+27
View File
@@ -942,6 +942,33 @@
</button>
</div>
<p id="storageFormStatus" class="text-sm" role="status" aria-live="polite"></p>
<div id="profileStorageSync" class="mt-2 rounded-lg border border-default p-4 space-y-3 hidden">
<div class="space-y-1">
<h4 class="text-sm font-semibold text-text">Cross-device sync</h4>
<p class="text-xs text-muted">
Save an <strong>encrypted</strong> copy of these storage
settings to your Nostr account so you don't have to
re-enter them on other devices.
</p>
</div>
<label class="flex items-start gap-2 text-sm text-muted-strong">
<input id="storageSyncToggle" type="checkbox" class="checkbox mt-0.5" />
<span>Sync these settings to my Nostr account (encrypted)</span>
</label>
<p class="text-xs text-status-warning">
The encrypted copy lives on public relays. It is readable
only with your Nostr key, but anyone who controls your key
could decrypt it — and the relays can see that your account
stores bitvid settings.
</p>
<div class="flex flex-wrap items-center gap-3">
<button id="storageSyncRestoreBtn" type="button" class="btn-ghost focus-ring">
Restore from my Nostr account
</button>
</div>
<p id="storageSyncStatus" class="text-xs" role="status" aria-live="polite"></p>
</div>
</div>
</div>
</section>