fix: bind removal plans to full key identity
Require both the current record ID and decrypted full key to match a prepared removal plan before deleting local state. Invalidate mismatched plans before returning KEYRING_REMOVE_PLAN_INVALID so a replacement with the same canonical ID cannot be deleted and the stale plan cannot be reused. Cover normal, idempotent, rebased, duplicate-ID, and same-ID replacement removal behavior while preserving the replacement generation.
This commit is contained in:
@@ -507,10 +507,15 @@ function createOnlineBackupKeyring({
|
||||
const state = await readState();
|
||||
const blockingIssue = firstBlockingIssue(state);
|
||||
if (blockingIssue) throw issueError(blockingIssue);
|
||||
if (!state.entries.some(current => current.id === plan.id)) {
|
||||
const currentEntry = state.entries.find(current => current.id === plan.id);
|
||||
if (!currentEntry) {
|
||||
removalPlans.delete(plan);
|
||||
return false;
|
||||
}
|
||||
if (currentEntry.key !== plan.key) {
|
||||
removalPlans.delete(plan);
|
||||
throw issueError(KEYRING_ERROR_CODES.plan);
|
||||
}
|
||||
await writeEntries(
|
||||
state.entries.filter(current => current.id !== plan.id),
|
||||
nextGeneration(state.generation)
|
||||
|
||||
Reference in New Issue
Block a user