fix: sync code not transferring identity when encryption enabled
_getAllData() was reading raw storage which contains encrypted blobs
when at-rest encryption is enabled. The sync code export would send
{ _ssLocalEncrypted: true, data: <blob> } instead of actual identity
data. The importing browser couldn't use these blobs.
Fixed _getAllData() to use Storage._readSecure() which decrypts
transparently. Fixed _applyData() to use Storage._writeSecure()
so imported data gets encrypted on the receiving end.
Also: hide the Auto-Sync Folder section entirely in browsers that
don't support File System Access API (Firefox, Brave, Safari)
instead of showing a broken-looking error message.
https://claude.ai/code/session_01SWSwDfMVij53bCTNSCLMwn
This commit is contained in:
+26
-10
@@ -791,25 +791,41 @@ const SilentSendSync = {
|
|||||||
// ----------------------------------------------------------------
|
// ----------------------------------------------------------------
|
||||||
|
|
||||||
async _getAllData() {
|
async _getAllData() {
|
||||||
const result = await api.storage.local.get(null);
|
// Use dynamic import to avoid circular dependency
|
||||||
|
const StorageModule = (await import('./storage.js')).default;
|
||||||
|
const identity = await StorageModule._readSecure('ss_identity');
|
||||||
|
const mappings = await StorageModule._readSecure('ss_mappings');
|
||||||
|
const settings = await StorageModule._readSecure('ss_settings');
|
||||||
|
const result = await api.storage.local.get('ss_lastModified');
|
||||||
return {
|
return {
|
||||||
version: '1',
|
version: '1',
|
||||||
lastModified: result.ss_lastModified || Date.now(),
|
lastModified: result.ss_lastModified || Date.now(),
|
||||||
identity: result.ss_identity || {},
|
identity: identity || {},
|
||||||
mappings: result.ss_mappings || [],
|
mappings: mappings || [],
|
||||||
settings: result.ss_settings || {},
|
settings: settings || {},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
async _applyData(data, source = 'unknown') {
|
async _applyData(data, source = 'unknown') {
|
||||||
const toSet = {
|
const StorageModule = (await import('./storage.js')).default;
|
||||||
|
|
||||||
|
// Write through Storage module so data gets encrypted if at-rest
|
||||||
|
// encryption is enabled
|
||||||
|
if (data.identity !== undefined) {
|
||||||
|
await StorageModule._writeSecure('ss_identity', data.identity);
|
||||||
|
}
|
||||||
|
if (data.mappings !== undefined) {
|
||||||
|
await StorageModule._writeSecure('ss_mappings', data.mappings);
|
||||||
|
}
|
||||||
|
if (data.settings !== undefined) {
|
||||||
|
await StorageModule._writeSecure('ss_settings', data.settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Metadata stays plaintext
|
||||||
|
await api.storage.local.set({
|
||||||
ss_lastModified: data.lastModified,
|
ss_lastModified: data.lastModified,
|
||||||
ss_sync_notification: { source, time: Date.now() },
|
ss_sync_notification: { source, time: Date.now() },
|
||||||
};
|
});
|
||||||
if (data.identity !== undefined) toSet.ss_identity = data.identity;
|
|
||||||
if (data.mappings !== undefined) toSet.ss_mappings = data.mappings;
|
|
||||||
if (data.settings !== undefined) toSet.ss_settings = data.settings;
|
|
||||||
await api.storage.local.set(toSet);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
async _getSyncChunkKeys() {
|
async _getSyncChunkKeys() {
|
||||||
|
|||||||
@@ -238,7 +238,7 @@
|
|||||||
<div id="syncStatus" style="margin-top:8px;font-size:12px;min-height:16px"></div>
|
<div id="syncStatus" style="margin-top:8px;font-size:12px;min-height:16px"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="margin-top:20px;padding-top:16px;border-top:1px solid #e5e7eb">
|
<div id="fileSyncSection" style="margin-top:20px;padding-top:16px;border-top:1px solid #e5e7eb">
|
||||||
<h3 style="font-size:13px;font-weight:600;margin:0 0 4px">Auto-Sync Folder — fully automatic, no copy-paste</h3>
|
<h3 style="font-size:13px;font-weight:600;margin:0 0 4px">Auto-Sync Folder — fully automatic, no copy-paste</h3>
|
||||||
<p class="section-desc" style="margin-bottom:8px">
|
<p class="section-desc" style="margin-bottom:8px">
|
||||||
Pick the same folder in each browser once. Changes are written to
|
Pick the same folder in each browser once. Changes are written to
|
||||||
|
|||||||
@@ -721,6 +721,13 @@ let syncDirHandle = null;
|
|||||||
const SYNC_FILE_NAME = 'silent-send-sync.json';
|
const SYNC_FILE_NAME = 'silent-send-sync.json';
|
||||||
|
|
||||||
async function initFileSync() {
|
async function initFileSync() {
|
||||||
|
// Hide the entire section if File System Access API isn't supported
|
||||||
|
if (!window.showDirectoryPicker) {
|
||||||
|
const section = $('#fileSyncSection');
|
||||||
|
if (section) section.style.display = 'none';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
syncDirHandle = await SilentSendSync.loadSyncDirHandle();
|
syncDirHandle = await SilentSendSync.loadSyncDirHandle();
|
||||||
updateFileSyncUI();
|
updateFileSyncUI();
|
||||||
if (syncDirHandle) {
|
if (syncDirHandle) {
|
||||||
|
|||||||
Reference in New Issue
Block a user