fix: harden managed online backup key handling

Require canonical encrypted envelopes and surface typed sanitized keyring corruption states.

Persist crash-durable primary and recovery files, prevalidate removal plans, isolate renderer refresh authority, and cover the real hidden Windows DPAPI and IPC composition.
This commit is contained in:
Sucukdeluxe
2026-08-22 13:28:47 +02:00
parent 39e0dd104e
commit 49fa4518c9
12 changed files with 1626 additions and 505 deletions
+29 -1
View File
@@ -36,6 +36,17 @@ test('encrypts and decrypts fields when secure storage is available', () => {
});
});
test('recognizes only canonical enc:v1 envelopes as encrypted', () => {
withSecretStore(availableSafeStorage(), secretStore => {
const canonical = `enc:v1:${Buffer.from('protected:secret').toString('base64')}`;
assert.equal(secretStore.isEncrypted(canonical), true);
assert.equal(secretStore.isEncrypted('secret'), false);
assert.equal(secretStore.isEncrypted(canonical.replace('enc:v1:', 'enc:v2:')), false);
assert.equal(secretStore.isEncrypted(canonical.replace(/=+$/u, '')), false);
assert.equal(secretStore.isEncrypted(`${canonical}\n`), false);
});
});
test('refuses plaintext storage by default when secure storage is unavailable', () => {
withSecretStore(null, secretStore => {
assert.throws(
@@ -94,7 +105,7 @@ test('throws an identifiable error when decryption fails', () => {
const failure = new Error('decryption failed');
withSecretStore(availableSafeStorage({ decryptString: () => { throw failure; } }), secretStore => {
assert.throws(
() => secretStore.decryptField('enc:v1:invalid'),
() => secretStore.decryptField('enc:v1:aW52YWxpZA=='),
error => error instanceof secretStore.SecretStoreError
&& error.code === 'SECRET_STORE_DECRYPT_FAILED'
&& error.cause === failure
@@ -102,6 +113,23 @@ test('throws an identifiable error when decryption fails', () => {
});
});
test('rejects malformed enc:v1 values instead of treating them as legacy plaintext', () => {
let decryptCalls = 0;
withSecretStore(availableSafeStorage({
decryptString: () => {
decryptCalls++;
return 'unexpected';
}
}), secretStore => {
assert.throws(
() => secretStore.decryptField('enc:v1:YWJjZA'),
error => error instanceof secretStore.SecretStoreError
&& error.code === 'SECRET_STORE_DECRYPT_FAILED'
);
assert.equal(decryptCalls, 0);
});
});
test('keeps legacy plaintext values readable without secure storage', () => {
withSecretStore(null, secretStore => {
assert.equal(secretStore.decryptField('legacy-secret'), 'legacy-secret');