Created
August 11, 2021 09:00
-
-
Save JakobTischler/738c8c61f13b525358b949b4d8737f8a to your computer and use it in GitHub Desktop.
In the Bitwarden Web Vault, goes through each folder, checks if it's empty, and deletes it if so. To be pasted and executed in the browser console.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var sleep = (ms = 1000) => { | |
return new Promise((resolve) => setTimeout(resolve, ms)); | |
}; | |
async function deleteEmptyFolders(startIndex = 0) { | |
const config = { | |
sleepBetweenFolder: 250, | |
sleepAfterLinkClick: 100, | |
sleepAfterEditClick: 500, | |
sleepAfterDeleteClick: 1200, | |
sleepAfterDeleteConfirmClick: 1500, | |
}; | |
let reCall = false; | |
const folders = document.querySelectorAll( | |
'.vault-filters .card-body > ul.card-ul:nth-of-type(3) li.ng-star-inserted' | |
); | |
if (!folders) { | |
console.error(`"folders" couldn't be found`); | |
return; | |
} | |
for (let i = startIndex; i < folders.length; i++) { | |
const folder = folders[i]; | |
// 1. Click folder link | |
const link = folder.querySelector('.d-flex > a.text-break'); | |
if (!link) { | |
console.error(`${i}: "link" couldn't be found`); | |
return; | |
} | |
link.click(); | |
await sleep(config.sleepAfterLinkClick); | |
// 2. Check for "no items" | |
if (!document.querySelector('.col-6 > app-vault-ciphers > .no-items')) { | |
console.log(`${i}: folder has items → ignore`); | |
await sleep(config.sleepBetweenFolder); | |
continue; | |
} | |
// 3. Click folder edit button | |
const editButton = folder.querySelector('a[title="Edit Folder"]'); | |
if (!editButton) { | |
console.error(`${i}: "editButton" couldn't be found`); | |
return; | |
} | |
editButton.click(); | |
await sleep(config.sleepAfterEditClick); | |
// 4. Click delete button | |
const deleteButton = document.querySelector('app-modal button[title="Delete"]'); | |
if (!deleteButton) { | |
console.error(`${i}: "deleteButton" couldn't be found`); | |
return; | |
} | |
deleteButton.click(); | |
await sleep(config.sleepAfterDeleteClick); | |
// 5. Click confirm button | |
const confirmButton = document.querySelector('.swal2-popup.swal2-modal button.swal2-confirm'); | |
if (!confirmButton) { | |
console.error(`${i}: "confirmButton" couldn't be found`); | |
return; | |
} | |
confirmButton.click(); | |
console.log(`${i}: folder deleted`); | |
await sleep(config.sleepAfterDeleteConfirmClick); | |
// 6. Re-call function to use updated nodeList, start at current index | |
reCall = true; | |
startIndex = i; | |
break; | |
} | |
if (reCall) { | |
deleteEmptyFolders(startIndex); | |
} else { | |
console.log('—'.repeat(41)); | |
console.log(' DELETION COMPLETE'); | |
console.log('—'.repeat(41)); | |
} | |
} | |
deleteEmptyFolders(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment