@nightlybuildgroup/vault 1.5.0 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -181,8 +181,22 @@ nbg-pw items --search git # filtered by search
181
181
  nbg-pw items --folder "Agents" # filtered by folder
182
182
  nbg-pw folders # folder names
183
183
  nbg-pw collections # collection names
184
+ nbg-pw organizations # organization names
184
185
  ```
185
186
 
187
+ Add `--ids` to any of them to print ids alongside names — useful for `config set`
188
+ or scripting. `collections --ids` also shows each collection's org id:
189
+
190
+ ```sh
191
+ $ nbg-pw organizations --ids
192
+ dfff… Acme Inc
193
+ $ nbg-pw collections --ids
194
+ bf2b… Shared (org dfff…)
195
+ ```
196
+
197
+ (You can pass either a **name or an id** to `config set` / `add --collection`, so
198
+ ids are optional — handy mainly when names are ambiguous.)
199
+
186
200
  ### Generating secrets (`generate`)
187
201
 
188
202
  Pure generator — needs no vault session.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nightlybuildgroup/vault",
3
- "version": "1.5.0",
3
+ "version": "1.6.0",
4
4
  "description": "Store Vaultwarden/Bitwarden credentials in the macOS Keychain and read secrets back for local agents.",
5
5
  "type": "module",
6
6
  "bin": {
package/src/cli.js CHANGED
@@ -10,9 +10,10 @@ Commands:
10
10
  delete Delete an item or folder (alias: rm; --permanent skips trash)
11
11
  attach Manage an item's attachments (--file/--list/--get/--delete)
12
12
  list Show an item's field names + types, no values (nbg-pw list "My Visa")
13
- items List item names (--search, --folder, --collection)
14
- folders List folder names
15
- collections List collection names
13
+ items List item names (--search, --folder, --collection; --ids)
14
+ folders List folder names (--ids)
15
+ collections List collection names (--ids shows collection + org ids)
16
+ organizations List organization names (--ids)
16
17
  generate Generate a password or passphrase (bw generate)
17
18
  config Show/set defaults, e.g. the org collection new items share into
18
19
  serve Start a local bw API daemon (unlocked) for fast repeated reads
@@ -55,7 +56,7 @@ export async function runCli(argv, deps = {}) {
55
56
  }
56
57
 
57
58
  async function loadCommands() {
58
- const [setup, get, add, edit, del, attach, list, items, folders, collections, generate, config, status, doctor, serve, reset] =
59
+ const [setup, get, add, edit, del, attach, list, items, folders, collections, organizations, generate, config, status, doctor, serve, reset] =
59
60
  await Promise.all([
60
61
  import('./commands/setup.js'),
61
62
  import('./commands/get.js'),
@@ -67,6 +68,7 @@ async function loadCommands() {
67
68
  import('./commands/items.js'),
68
69
  import('./commands/folders.js'),
69
70
  import('./commands/collections.js'),
71
+ import('./commands/organizations.js'),
70
72
  import('./commands/generate.js'),
71
73
  import('./commands/config.js'),
72
74
  import('./commands/status.js'),
@@ -86,6 +88,7 @@ async function loadCommands() {
86
88
  items: items.default,
87
89
  folders: folders.default,
88
90
  collections: collections.default,
91
+ organizations: organizations.default,
89
92
  generate: generate.default,
90
93
  config: config.default,
91
94
  status: status.default,
@@ -2,13 +2,17 @@ import * as bwModule from '../bw.js';
2
2
  import * as keychainModule from '../keychain.js';
3
3
 
4
4
  export function parseCollectionsArgs(args) {
5
- if (args.length > 0) throw new Error(`unexpected argument: ${args[0]}`);
6
- return {};
5
+ let ids = false;
6
+ for (const a of args) {
7
+ if (a === '--ids') ids = true;
8
+ else throw new Error(`unexpected argument: ${a}`);
9
+ }
10
+ return { ids };
7
11
  }
8
12
 
9
13
  export async function runCollections(args, deps) {
10
14
  const { keychain, bw, out, err } = deps;
11
- parseCollectionsArgs(args);
15
+ const { ids } = parseCollectionsArgs(args);
12
16
 
13
17
  const config = await keychain.readConfig();
14
18
  if (!config) {
@@ -17,11 +21,11 @@ export async function runCollections(args, deps) {
17
21
  }
18
22
 
19
23
  const session = await bw.ensureSession(config);
20
- const collections = await bw.listCollections({ session });
21
- const names = collections
22
- .map((c) => c.name)
23
- .sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase()));
24
- for (const name of names) out(name + '\n');
24
+ const collections = (await bw.listCollections({ session }))
25
+ .sort((a, b) => a.name.toLowerCase().localeCompare(b.name.toLowerCase()));
26
+ for (const c of collections) {
27
+ out(ids ? `${c.id} ${c.name} (org ${c.organizationId})\n` : c.name + '\n');
28
+ }
25
29
  return 0;
26
30
  }
27
31
 
@@ -2,13 +2,17 @@ import * as bwModule from '../bw.js';
2
2
  import * as keychainModule from '../keychain.js';
3
3
 
4
4
  export function parseFoldersArgs(args) {
5
- if (args.length > 0) throw new Error(`unexpected argument: ${args[0]}`);
6
- return {};
5
+ let ids = false;
6
+ for (const a of args) {
7
+ if (a === '--ids') ids = true;
8
+ else throw new Error(`unexpected argument: ${a}`);
9
+ }
10
+ return { ids };
7
11
  }
8
12
 
9
13
  export async function runFolders(args, deps) {
10
14
  const { keychain, bw, out, err } = deps;
11
- parseFoldersArgs(args);
15
+ const { ids } = parseFoldersArgs(args);
12
16
 
13
17
  const config = await keychain.readConfig();
14
18
  if (!config) {
@@ -17,11 +21,11 @@ export async function runFolders(args, deps) {
17
21
  }
18
22
 
19
23
  const session = await bw.ensureSession(config);
20
- const folders = await bw.listFolders({ session });
21
- const names = folders
22
- .map((f) => f.name)
23
- .sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase()));
24
- for (const name of names) out(name + '\n');
24
+ const folders = (await bw.listFolders({ session }))
25
+ .sort((a, b) => a.name.toLowerCase().localeCompare(b.name.toLowerCase()));
26
+ for (const f of folders) {
27
+ out(ids ? `${f.id ?? '-'} ${f.name}\n` : f.name + '\n');
28
+ }
25
29
  return 0;
26
30
  }
27
31
 
@@ -5,6 +5,7 @@ export function parseItemsArgs(args) {
5
5
  let search = null;
6
6
  let folder = null;
7
7
  let collection = null;
8
+ let ids = false;
8
9
  for (let i = 0; i < args.length; i++) {
9
10
  if (args[i] === '--search') {
10
11
  const v = args[++i];
@@ -18,16 +19,18 @@ export function parseItemsArgs(args) {
18
19
  const v = args[++i];
19
20
  if (v === undefined) throw new Error('--collection requires a value');
20
21
  collection = v;
22
+ } else if (args[i] === '--ids') {
23
+ ids = true;
21
24
  } else {
22
25
  throw new Error(`unknown option: ${args[i]}`);
23
26
  }
24
27
  }
25
- return { search, folder, collection };
28
+ return { search, folder, collection, ids };
26
29
  }
27
30
 
28
31
  export async function runItems(args, deps) {
29
32
  const { keychain, bw, out, err } = deps;
30
- const { search, folder, collection } = parseItemsArgs(args);
33
+ const { search, folder, collection, ids } = parseItemsArgs(args);
31
34
 
32
35
  const config = await keychain.readConfig();
33
36
  if (!config) {
@@ -58,11 +61,11 @@ export async function runItems(args, deps) {
58
61
  if (folderId !== undefined) filters.folderId = folderId;
59
62
  if (collectionId !== undefined) filters.collectionId = collectionId;
60
63
 
61
- const items = await bw.listItems(filters);
62
- const names = items
63
- .map((i) => i.name)
64
- .sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase()));
65
- for (const name of names) out(name + '\n');
64
+ const items = (await bw.listItems(filters))
65
+ .sort((a, b) => a.name.toLowerCase().localeCompare(b.name.toLowerCase()));
66
+ for (const i of items) {
67
+ out(ids ? `${i.id} ${i.name}\n` : i.name + '\n');
68
+ }
66
69
  return 0;
67
70
  }
68
71
 
@@ -0,0 +1,39 @@
1
+ import * as bwModule from '../bw.js';
2
+ import * as keychainModule from '../keychain.js';
3
+
4
+ export function parseOrganizationsArgs(args) {
5
+ let ids = false;
6
+ for (const a of args) {
7
+ if (a === '--ids') ids = true;
8
+ else throw new Error(`unexpected argument: ${a}`);
9
+ }
10
+ return { ids };
11
+ }
12
+
13
+ export async function runOrganizations(args, deps) {
14
+ const { keychain, bw, out, err } = deps;
15
+ const { ids } = parseOrganizationsArgs(args);
16
+
17
+ const config = await keychain.readConfig();
18
+ if (!config) {
19
+ err('No stored credentials. Run "nbg-pw setup" first.\n');
20
+ return 1;
21
+ }
22
+
23
+ const session = await bw.ensureSession(config);
24
+ const orgs = (await bw.listOrganizations({ session }))
25
+ .sort((a, b) => a.name.toLowerCase().localeCompare(b.name.toLowerCase()));
26
+ for (const o of orgs) {
27
+ out(ids ? `${o.id} ${o.name}\n` : o.name + '\n');
28
+ }
29
+ return 0;
30
+ }
31
+
32
+ export default async function organizations(args) {
33
+ return runOrganizations(args, {
34
+ keychain: keychainModule,
35
+ bw: bwModule,
36
+ out: (s) => process.stdout.write(s),
37
+ err: (s) => process.stderr.write(s),
38
+ });
39
+ }