Skip to content

Instantly share code, notes, and snippets.

@0xquad
Created March 7, 2024 18:53
Show Gist options
  • Save 0xquad/89077b1245425f17f4476336b0701ef4 to your computer and use it in GitHub Desktop.
Save 0xquad/89077b1245425f17f4476336b0701ef4 to your computer and use it in GitHub Desktop.
/*
** A script to move many items from a collection to another in Bitwarden/Vaultwarden.
**
** As of 2024-03 Bitwarden still haven't implemented any feature to move a lot of items
** from one collection to another. Refs:
** - https://community.bitwarden.com/t/how-to-move-lot-of-items-into-an-existing-collection/53798/8
** - https://github.com/dani-garcia/vaultwarden/discussions/2705
**
** This script offers a semi-manual/automated way of doing that.
**
** 1. Login to the web interface of Bitwarden/Vaultwarden and paste the following in the web console.
** 2. Gather the necessary info:
** - the organization ID
** - the collection IDs (to filter/find items, to remove them from, to add them to)
** - the authorization Bearer token (JWT)
** 3. Adjust the script and replace the info with yours
** 4. Open the web console and paste your adjusted script and run it
**
** WARNINGS: No error checks; backup your vault first if you can
** HINTS: collRemove can be empty ([]) if you need to simply reassign items without unassigning
**/
(() => {
const token = 'eYJ0...my-auth-token-here';
const orgId = 'f05f21be-d37e-40aa-aef7-8c0789c445d0'; // your organization ID
const collFilter = ['c099c9fc-a505-486f-97bf-041910c383fd', 'd3246e9f-e3a3-4a1f-9d0e-ed07c02a7f99']; // find items in any of these collections
const collRemove = ['c099c9fc-a505-486f-97bf-041910c383fd', 'd3246e9f-e3a3-4a1f-9d0e-ed07c02a7f99']; // unassign from these collections
const collAdd = '405038fd-d237-48d3-81e4-954b7977e8f5'; // assign to this collection instead
fetch(`/api/ciphers/organization-details?organizationId=${orgId}`, {headers: {authorization: `Bearer ${token}`}}).then(resp => {
resp.json().then(data => {
let count = 0;
data.Data.filter(item => item.CollectionIds.filter(c => collFilter.includes(c)).length > 0).forEach(item => {
const payload = {collectionIds: [...item.CollectionIds.filter(c => !collRemove.includes(c)), collAdd]};
//console.log(`PUT ${item.Id}/collections-admin ${JSON.stringify(payload)}`); count++; return; // dry run
const opts = {method: 'PUT', body: JSON.stringify(payload), headers: {authorization: `Bearer ${token}`}};
fetch(`/api/ciphers/${item.Id}/collections-admin`, opts).then(resp => {
if (resp.ok) {
console.log(`Successfully reassigned item ${item.Id} to collections: ${JSON.stringify(payload)}`);
count++;
}
});
});
console.log(`Reassigned a total of ${count} items`);
});
});
})()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment