Skip to content

Instantly share code, notes, and snippets.

@JakobTischler
Created August 11, 2021 09:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JakobTischler/738c8c61f13b525358b949b4d8737f8a to your computer and use it in GitHub Desktop.
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.
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