mirror of
https://github.com/PR0M3TH3AN/bitvid.git
synced 2026-10-27 07:52:24 +00:00
fix(storage): let a Blossom-only (keyless) account sync across devices
importAccountRecord hard-required encryptedMasterKey, but a Blossom-only account is keyless (no encrypted payloads) and legitimately has none — so its synced record failed to import. Require the envelope ONLY when the record carries an encrypted connection that actually needs it to unlock. Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
1 parent
ef2e48912d
commit
51072e4871
2 files changed
+55
-1
No files matched your search
@@ -735,7 +735,21 @@ export class StorageService {
|
||||
if (!pubkey) {
|
||||
throw new Error("Pubkey required to import storage account record.");
|
||||
}
|
||||
if (!record || typeof record !== "object" || !record.encryptedMasterKey) {
|
||||
if (!record || typeof record !== "object") {
|
||||
throw new Error("Invalid storage account record.");
|
||||
}
|
||||
// A Blossom-only account is keyless (no encrypted payloads), so it legitimately
|
||||
// has no encryptedMasterKey. Require the envelope ONLY when the record actually
|
||||
// carries an encrypted connection that would need it to unlock — otherwise a
|
||||
// Blossom-only account can't sync across devices.
|
||||
const connections =
|
||||
record.connections && typeof record.connections === "object"
|
||||
? record.connections
|
||||
: {};
|
||||
const hasEncryptedConnection = Object.values(connections).some(
|
||||
(conn) => conn && conn.encrypted != null,
|
||||
);
|
||||
if (hasEncryptedConnection && !record.encryptedMasterKey) {
|
||||
throw new Error("Invalid storage account record.");
|
||||
}
|
||||
const toSave = { ...record, pubkey };
|
||||
|
||||
@@ -240,4 +240,44 @@ describe("saving multiple providers does not clash", () => {
|
||||
await storageService.importAccountRecord(pubkey, record);
|
||||
assert.equal(fired, null, "off() detached the observer");
|
||||
});
|
||||
|
||||
test("a Blossom-only (keyless) account syncs without an encryptedMasterKey", async () => {
|
||||
// Blossom connections are keyless (encrypted: null), so a Blossom-only account
|
||||
// legitimately has no encryptedMasterKey. Importing it must still work.
|
||||
const record = {
|
||||
pubkey,
|
||||
connections: {
|
||||
blossom: {
|
||||
id: "blossom",
|
||||
provider: "blossom",
|
||||
meta: { provider: "blossom", servers: ["https://blossom.band"] },
|
||||
encrypted: null,
|
||||
},
|
||||
},
|
||||
};
|
||||
await storageService.importAccountRecord(pubkey, record); // must not throw
|
||||
const conns = await storageService.listConnections(pubkey);
|
||||
assert.deepEqual(conns.map((c) => c.id), ["blossom"]);
|
||||
assert.deepEqual(conns[0].meta.servers, ["https://blossom.band"]);
|
||||
});
|
||||
|
||||
test("an encrypted (R2/S3) connection still requires the master-key envelope", async () => {
|
||||
// A record carrying an encrypted payload can't be unlocked without the
|
||||
// envelope — importing it without one must still be rejected.
|
||||
const record = {
|
||||
pubkey,
|
||||
connections: {
|
||||
default: {
|
||||
id: "default",
|
||||
provider: "cloudflare_r2",
|
||||
meta: { provider: "cloudflare_r2" },
|
||||
encrypted: { cipher: "deadbeef", iv: "00" },
|
||||
},
|
||||
},
|
||||
};
|
||||
await assert.rejects(
|
||||
() => storageService.importAccountRecord(pubkey, record),
|
||||
/Invalid storage account record/,
|
||||
);
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user