node-vault-client 2.0.1 → 2.1.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 +293 -5
- package/package.json +14 -6
- package/src/Lease.js +16 -5
- package/src/MountResolver.js +220 -0
- package/src/VaultApiClient.js +27 -10
- package/src/VaultClient.js +334 -29
- package/src/VaultNodeConfig.js +52 -6
- package/src/auth/VaultAppRoleAuth.js +10 -10
- package/src/auth/VaultBaseAuth.js +6 -2
- package/src/auth/VaultIAMAuth.js +12 -17
- package/src/auth/VaultKubernetesAuth.js +7 -0
- package/src/auth/VaultTokenAuth.js +1 -1
- package/src/errors.js +32 -2
- package/src/kvTransform.js +90 -0
package/README.md
CHANGED
|
@@ -47,14 +47,16 @@ vaultClient.read('secret/tst').then(lease => {
|
|
|
47
47
|
|
|
48
48
|
```javascript
|
|
49
49
|
const vaultClient = VaultClient.boot('main', {
|
|
50
|
-
api: {
|
|
50
|
+
api: {
|
|
51
|
+
url: 'https://vault.example.com:8200/',
|
|
52
|
+
namespace: 'some_namespace', // Optional. X-Vault-Namespace header (canonical location; auth.config.namespace is honored as a legacy fallback)
|
|
53
|
+
},
|
|
51
54
|
auth: {
|
|
52
55
|
type: 'iam',
|
|
53
56
|
mount: 'aws', // Optional. Vault AWS auth mount point ("aws" by default)
|
|
54
57
|
config: {
|
|
55
58
|
role: 'my_iam_role',
|
|
56
59
|
iam_server_id_header_value: 'https://vault.example.com:8200/', // Optional. X-Vault-AWS-IAM-Server-ID header
|
|
57
|
-
namespace: 'some_namespace', // Optional. X-Vault-Namespace header
|
|
58
60
|
region: 'eu-central-1', // Optional. AWS STS region (see below)
|
|
59
61
|
credentials: { // Optional. Resolved from the AWS provider chain when omitted
|
|
60
62
|
accessKeyId: process.env.AWS_ACCESS_KEY_ID,
|
|
@@ -136,6 +138,14 @@ const vaultClient = VaultClient.boot('main', {
|
|
|
136
138
|
* [.read(path)](#VaultClient+read) ⇒ <code>Promise.<Lease></code>
|
|
137
139
|
* [.list(path)](#VaultClient+list) ⇒ <code>Promise.<Lease></code>
|
|
138
140
|
* [.write(path, data)](#VaultClient+write) ⇒ <code>Promise.<Object></code>
|
|
141
|
+
* [.delete(path)](#VaultClient+delete) ⇒ <code>Promise.<Object></code>
|
|
142
|
+
* [.update(path, data)](#VaultClient+update) ⇒ <code>Promise.<Object></code>
|
|
143
|
+
* [.request(method, path, [data])](#VaultClient+request) ⇒ <code>Promise.<Object></code>
|
|
144
|
+
* [.deleteVersions(path, versions)](#VaultClient+deleteVersions) ⇒ <code>Promise.<Object></code>
|
|
145
|
+
* [.undeleteVersions(path, versions)](#VaultClient+undeleteVersions) ⇒ <code>Promise.<Object></code>
|
|
146
|
+
* [.destroyVersions(path, versions)](#VaultClient+destroyVersions) ⇒ <code>Promise.<Object></code>
|
|
147
|
+
* [.readMetadata(path)](#VaultClient+readMetadata) ⇒ <code>Promise.<Object></code>
|
|
148
|
+
* [.deleteMetadata(path)](#VaultClient+deleteMetadata) ⇒ <code>Promise.<Object></code>
|
|
139
149
|
* [.close()](#VaultClient+close)
|
|
140
150
|
* _static_
|
|
141
151
|
* [.boot(name, [options])](#VaultClient.boot) ⇒ <code>VaultClient</code>
|
|
@@ -143,6 +153,11 @@ const vaultClient = VaultClient.boot('main', {
|
|
|
143
153
|
* [.clear([name])](#VaultClient.clear)
|
|
144
154
|
* [Lease](#Lease)
|
|
145
155
|
|
|
156
|
+
**Return contract**: [`read()`](#VaultClient+read) and [`list()`](#VaultClient+list) resolve to a
|
|
157
|
+
[`Lease`](#Lease) — use its accessors to extract the secret data. Every other data-plane method
|
|
158
|
+
(`write`, `delete`, `update`, `request` and the KV v2 helpers) resolves to the raw parsed Vault
|
|
159
|
+
response body, which may be empty/undefined for `204 No Content` responses.
|
|
160
|
+
|
|
146
161
|
<a name="new_VaultClient_new"></a>
|
|
147
162
|
|
|
148
163
|
#### new VaultClient(options)
|
|
@@ -156,12 +171,15 @@ Client constructor function.
|
|
|
156
171
|
| options.api.url | <code>String</code> | | the url of the vault server |
|
|
157
172
|
| [options.api.apiVersion] | <code>String</code> | `v1` | |
|
|
158
173
|
| [options.api.requestOptions] | <code>Object</code> | | extra options merged into every HTTP request (see [Custom transport](#custom-transport-proxy--self-signed-tls)) |
|
|
174
|
+
| [options.api.namespace] | <code>String</code> | | Optional. Vault namespace, sent as the `X-Vault-Namespace` header on **every** request — login, token lookup/renewal, and all secret operations — for every auth type. This is the canonical location; `auth.config.namespace` is still honored for backward compatibility. |
|
|
175
|
+
| [options.api.kv.autoDetect] | <code>boolean</code> | `false` | auto-detect the KV version of each mount on first use (see [KV v2 & generic backends](#kv-v2--generic-backends)) |
|
|
176
|
+
| [options.api.engines] | <code>Object</code> | `{}` | static mount-to-version map, e.g. `{ secret: 2, legacy: 1 }` (see [KV v2 & generic backends](#kv-v2--generic-backends)) |
|
|
159
177
|
| options.auth | <code>Object</code> | | |
|
|
160
178
|
| options.auth.type | <code>String</code> | | |
|
|
161
179
|
| [options.auth.mount] | <code>String</code> | | Vault auth backend mount point; default varies per method (e.g. "aws" for iam, "approle", "token", "kubernetes") |
|
|
162
180
|
| options.auth.config | <code>Object</code> | | auth configuration variables |
|
|
163
|
-
| [options.auth.config.namespace] | <code>String</code> | | Optional. Vault namespace
|
|
164
|
-
| options.logger | <code>Object</code>
|
|
181
|
+
| [options.auth.config.namespace] | <code>String</code> | | Optional. Legacy location for the Vault namespace (see `api.namespace`). Sent as the `X-Vault-Namespace` header on **every** request for every auth type. |
|
|
182
|
+
| [options.logger] | <code>Object</code> \| <code>false</code> | | Logger that supports "error", "info", "warn", "trace", "debug" methods. Uses `console` by default. Pass `false` to disable logging. |
|
|
165
183
|
|
|
166
184
|
##### Custom transport (proxy / self-signed TLS)
|
|
167
185
|
|
|
@@ -196,6 +214,8 @@ env var with no code change. Only disable verification
|
|
|
196
214
|
(`new Agent({ connect: { rejectUnauthorized: false } })`) in throwaway/dev setups — it removes
|
|
197
215
|
MITM protection.
|
|
198
216
|
|
|
217
|
+
<a name="VaultClient+fillNodeConfig"></a>
|
|
218
|
+
|
|
199
219
|
#### vaultClient.fillNodeConfig() ⇒ <code>Promise</code>
|
|
200
220
|
Populates Vault's values to NPM "config" module
|
|
201
221
|
|
|
@@ -236,9 +256,131 @@ Resolves to the raw parsed Vault response body, which may be empty/undefined for
|
|
|
236
256
|
|
|
237
257
|
| Param | Type | Description |
|
|
238
258
|
| --- | --- | --- |
|
|
239
|
-
| path |
|
|
259
|
+
| path | <code>string</code> | path used to write data |
|
|
240
260
|
| data | <code>object</code> | data to write |
|
|
241
261
|
|
|
262
|
+
<a name="VaultClient+delete"></a>
|
|
263
|
+
|
|
264
|
+
#### vaultClient.delete(path) ⇒ <code>Promise.<Object></code>
|
|
265
|
+
Deletes a secret
|
|
266
|
+
|
|
267
|
+
On KV v2 mounts this sends `DELETE` to the `data/` path, soft-deleting the latest version.
|
|
268
|
+
On KV v1 / non-KV mounts this sends `DELETE` to the raw path. Resolves to the raw parsed
|
|
269
|
+
Vault response body, which may be empty/undefined for `204 No Content` responses.
|
|
270
|
+
|
|
271
|
+
**Kind**: instance method of [<code>VaultClient</code>](#VaultClient)
|
|
272
|
+
|
|
273
|
+
| Param | Type | Description |
|
|
274
|
+
| --- | --- | --- |
|
|
275
|
+
| path | <code>string</code> | path to the secret |
|
|
276
|
+
|
|
277
|
+
<a name="VaultClient+update"></a>
|
|
278
|
+
|
|
279
|
+
#### vaultClient.update(path, data) ⇒ <code>Promise.<Object></code>
|
|
280
|
+
Updates (merge-patches) a KV v2 secret
|
|
281
|
+
|
|
282
|
+
Sends `PATCH` with `Content-Type: application/merge-patch+json`, merging `data` into the
|
|
283
|
+
existing secret without overwriting keys that are not listed. KV v2 merge-patch operation —
|
|
284
|
+
KV v1 mounts do not support `PATCH` and Vault returns `405` there. Resolves to the raw
|
|
285
|
+
parsed Vault response body.
|
|
286
|
+
|
|
287
|
+
**Kind**: instance method of [<code>VaultClient</code>](#VaultClient)
|
|
288
|
+
|
|
289
|
+
| Param | Type | Description |
|
|
290
|
+
| --- | --- | --- |
|
|
291
|
+
| path | <code>string</code> | path to the secret |
|
|
292
|
+
| data | <code>object</code> | keys to merge into the existing secret |
|
|
293
|
+
|
|
294
|
+
<a name="VaultClient+request"></a>
|
|
295
|
+
|
|
296
|
+
#### vaultClient.request(method, path, [data]) ⇒ <code>Promise.<Object></code>
|
|
297
|
+
Raw request — escape hatch for any Vault backend
|
|
298
|
+
|
|
299
|
+
Sends the literal API path with no KV path rewriting and no response unwrapping, and
|
|
300
|
+
resolves to the parsed response body. Use it for non-KV backends (e.g. Transit) or when you
|
|
301
|
+
have already constructed the complete Vault API path.
|
|
302
|
+
|
|
303
|
+
**Kind**: instance method of [<code>VaultClient</code>](#VaultClient)
|
|
304
|
+
|
|
305
|
+
| Param | Type | Description |
|
|
306
|
+
| --- | --- | --- |
|
|
307
|
+
| method | <code>string</code> | HTTP method (e.g. `GET`, `POST`) |
|
|
308
|
+
| path | <code>string</code> | literal API path, sent as-is |
|
|
309
|
+
| [data] | <code>object</code> | request body |
|
|
310
|
+
|
|
311
|
+
<a name="VaultClient+deleteVersions"></a>
|
|
312
|
+
|
|
313
|
+
#### vaultClient.deleteVersions(path, versions) ⇒ <code>Promise.<Object></code>
|
|
314
|
+
Soft-deletes specific versions of a KV v2 secret
|
|
315
|
+
|
|
316
|
+
KV v2 only — rejects with `UnsupportedOperationError` on non-v2 mounts. Resolves to the raw
|
|
317
|
+
parsed Vault response body.
|
|
318
|
+
|
|
319
|
+
**Kind**: instance method of [<code>VaultClient</code>](#VaultClient)
|
|
320
|
+
|
|
321
|
+
| Param | Type | Description |
|
|
322
|
+
| --- | --- | --- |
|
|
323
|
+
| path | <code>string</code> | path to the secret |
|
|
324
|
+
| versions | <code>Array.<number></code> | version numbers to soft-delete |
|
|
325
|
+
|
|
326
|
+
<a name="VaultClient+undeleteVersions"></a>
|
|
327
|
+
|
|
328
|
+
#### vaultClient.undeleteVersions(path, versions) ⇒ <code>Promise.<Object></code>
|
|
329
|
+
Undeletes (restores) soft-deleted versions of a KV v2 secret
|
|
330
|
+
|
|
331
|
+
KV v2 only — rejects with `UnsupportedOperationError` on non-v2 mounts. Resolves to the raw
|
|
332
|
+
parsed Vault response body.
|
|
333
|
+
|
|
334
|
+
**Kind**: instance method of [<code>VaultClient</code>](#VaultClient)
|
|
335
|
+
|
|
336
|
+
| Param | Type | Description |
|
|
337
|
+
| --- | --- | --- |
|
|
338
|
+
| path | <code>string</code> | path to the secret |
|
|
339
|
+
| versions | <code>Array.<number></code> | version numbers to restore |
|
|
340
|
+
|
|
341
|
+
<a name="VaultClient+destroyVersions"></a>
|
|
342
|
+
|
|
343
|
+
#### vaultClient.destroyVersions(path, versions) ⇒ <code>Promise.<Object></code>
|
|
344
|
+
Permanently destroys specific versions of a KV v2 secret
|
|
345
|
+
|
|
346
|
+
The destroyed version data cannot be recovered. KV v2 only — rejects with
|
|
347
|
+
`UnsupportedOperationError` on non-v2 mounts. Resolves to the raw parsed Vault response body.
|
|
348
|
+
|
|
349
|
+
**Kind**: instance method of [<code>VaultClient</code>](#VaultClient)
|
|
350
|
+
|
|
351
|
+
| Param | Type | Description |
|
|
352
|
+
| --- | --- | --- |
|
|
353
|
+
| path | <code>string</code> | path to the secret |
|
|
354
|
+
| versions | <code>Array.<number></code> | version numbers to destroy |
|
|
355
|
+
|
|
356
|
+
<a name="VaultClient+readMetadata"></a>
|
|
357
|
+
|
|
358
|
+
#### vaultClient.readMetadata(path) ⇒ <code>Promise.<Object></code>
|
|
359
|
+
Reads KV v2 metadata for a secret
|
|
360
|
+
|
|
361
|
+
Resolves to the metadata document (`current_version`, the `versions` map, timestamps, etc.).
|
|
362
|
+
KV v2 only — rejects with `UnsupportedOperationError` on non-v2 mounts.
|
|
363
|
+
|
|
364
|
+
**Kind**: instance method of [<code>VaultClient</code>](#VaultClient)
|
|
365
|
+
|
|
366
|
+
| Param | Type | Description |
|
|
367
|
+
| --- | --- | --- |
|
|
368
|
+
| path | <code>string</code> | path to the secret |
|
|
369
|
+
|
|
370
|
+
<a name="VaultClient+deleteMetadata"></a>
|
|
371
|
+
|
|
372
|
+
#### vaultClient.deleteMetadata(path) ⇒ <code>Promise.<Object></code>
|
|
373
|
+
Deletes all metadata and version history for a KV v2 secret (permanent)
|
|
374
|
+
|
|
375
|
+
KV v2 only — rejects with `UnsupportedOperationError` on non-v2 mounts. Resolves to the raw
|
|
376
|
+
parsed Vault response body, which may be empty/undefined for `204 No Content` responses.
|
|
377
|
+
|
|
378
|
+
**Kind**: instance method of [<code>VaultClient</code>](#VaultClient)
|
|
379
|
+
|
|
380
|
+
| Param | Type | Description |
|
|
381
|
+
| --- | --- | --- |
|
|
382
|
+
| path | <code>string</code> | path to the secret |
|
|
383
|
+
|
|
242
384
|
<a name="VaultClient+close"></a>
|
|
243
385
|
|
|
244
386
|
#### vaultClient.close()
|
|
@@ -315,6 +457,152 @@ If no name passed all named instances will be cleared.
|
|
|
315
457
|
| --- | --- | --- |
|
|
316
458
|
| [name] | <code>String</code> | Vault instance name, all instances will be cleared if no name were passed |
|
|
317
459
|
|
|
460
|
+
## KV v2 & generic backends
|
|
461
|
+
|
|
462
|
+
### Overview
|
|
463
|
+
|
|
464
|
+
By default the client behaves exactly as before (KV v1 / raw passthrough). To enable transparent
|
|
465
|
+
KV v2 support set `api.kv.autoDetect: true` **or** supply a static `api.engines` map. Either
|
|
466
|
+
option activates path-rewriting and response-unwrapping; callers do not need to know the engine
|
|
467
|
+
version.
|
|
468
|
+
|
|
469
|
+
### Configuration options
|
|
470
|
+
|
|
471
|
+
| Option | Type | Default | Description |
|
|
472
|
+
|---|---|---|---|
|
|
473
|
+
| `api.kv.autoDetect` | `boolean` | `false` | Auto-detect the KV version of each mount on first use via `GET sys/internal/ui/mounts/<path>`. |
|
|
474
|
+
| `api.engines` | `Object` | `{}` | Static mount-to-version map, e.g. `{ secret: 2, legacy: 1 }`. Overrides detection; use this when the token lacks permission on `sys/internal/ui/mounts`. |
|
|
475
|
+
|
|
476
|
+
Both options can be combined: `engines` acts as an override — matching mounts skip detection
|
|
477
|
+
while unmatched mounts are auto-detected (when `autoDetect: true`).
|
|
478
|
+
|
|
479
|
+
### Auto-detect example
|
|
480
|
+
|
|
481
|
+
```javascript
|
|
482
|
+
const client = VaultClient.boot('main', {
|
|
483
|
+
api: {
|
|
484
|
+
url: 'https://vault.example.com:8200/',
|
|
485
|
+
kv: { autoDetect: true },
|
|
486
|
+
},
|
|
487
|
+
auth: { type: 'token', config: { token: '...' } },
|
|
488
|
+
});
|
|
489
|
+
|
|
490
|
+
// Works transparently on both KV v1 and KV v2 mounts
|
|
491
|
+
const lease = await client.read('secret/my-app/config');
|
|
492
|
+
console.log(lease.getData()); // the secret object
|
|
493
|
+
console.log(lease.getMetadata()); // KV v2 version metadata (undefined on v1)
|
|
494
|
+
```
|
|
495
|
+
|
|
496
|
+
### Static engines override example
|
|
497
|
+
|
|
498
|
+
```javascript
|
|
499
|
+
const client = VaultClient.boot('main', {
|
|
500
|
+
api: {
|
|
501
|
+
url: 'https://vault.example.com:8200/',
|
|
502
|
+
engines: { secret: 2, legacy: 1 },
|
|
503
|
+
},
|
|
504
|
+
auth: { type: 'token', config: { token: '...' } },
|
|
505
|
+
});
|
|
506
|
+
```
|
|
507
|
+
|
|
508
|
+
### KV v2-specific methods
|
|
509
|
+
|
|
510
|
+
These methods require a KV v2 mount and throw `UnsupportedOperationError` on v1 / non-KV mounts.
|
|
511
|
+
|
|
512
|
+
```javascript
|
|
513
|
+
// Soft-delete specific versions
|
|
514
|
+
await client.deleteVersions('secret/foo', [1, 2]);
|
|
515
|
+
|
|
516
|
+
// Restore soft-deleted versions
|
|
517
|
+
await client.undeleteVersions('secret/foo', [1]);
|
|
518
|
+
|
|
519
|
+
// Permanently destroy versions
|
|
520
|
+
await client.destroyVersions('secret/foo', [1, 2]);
|
|
521
|
+
|
|
522
|
+
// Read version metadata (current_version, versions map, etc.)
|
|
523
|
+
const meta = await client.readMetadata('secret/foo');
|
|
524
|
+
|
|
525
|
+
// Delete all metadata and version history (permanent)
|
|
526
|
+
await client.deleteMetadata('secret/foo');
|
|
527
|
+
```
|
|
528
|
+
|
|
529
|
+
### update() — merge-patch
|
|
530
|
+
|
|
531
|
+
```javascript
|
|
532
|
+
// PATCH a subset of keys without overwriting others (KV v2)
|
|
533
|
+
await client.update('secret/foo', { password: 'new-value' });
|
|
534
|
+
// Sends PATCH secret/data/foo with Content-Type: application/merge-patch+json
|
|
535
|
+
```
|
|
536
|
+
|
|
537
|
+
### delete()
|
|
538
|
+
|
|
539
|
+
```javascript
|
|
540
|
+
// Soft-delete the latest version on KV v2; DELETE on v1/passthrough
|
|
541
|
+
await client.delete('secret/foo');
|
|
542
|
+
```
|
|
543
|
+
|
|
544
|
+
### request() — raw escape hatch
|
|
545
|
+
|
|
546
|
+
For any Vault backend that does not benefit from KV path rewriting use `request()`. It sends the
|
|
547
|
+
literal path with no rewriting or response normalisation and returns the parsed body directly.
|
|
548
|
+
|
|
549
|
+
```javascript
|
|
550
|
+
// Encrypt with Transit engine — path must not be rewritten
|
|
551
|
+
const result = await client.request('POST', 'transit/encrypt/my-key', {
|
|
552
|
+
plaintext: Buffer.from('hello').toString('base64'),
|
|
553
|
+
});
|
|
554
|
+
console.log(result.data.ciphertext);
|
|
555
|
+
```
|
|
556
|
+
|
|
557
|
+
### Lease.getMetadata()
|
|
558
|
+
|
|
559
|
+
`getMetadata()` is additive — existing code is unaffected.
|
|
560
|
+
|
|
561
|
+
```javascript
|
|
562
|
+
const lease = await client.read('secret/my-app/db');
|
|
563
|
+
lease.getData(); // the secret values
|
|
564
|
+
lease.getMetadata(); // { version, created_time, deletion_time, destroyed, custom_metadata }
|
|
565
|
+
// undefined on KV v1 / passthrough mounts
|
|
566
|
+
```
|
|
567
|
+
|
|
568
|
+
### Path requirements when autoDetect / engines are active
|
|
569
|
+
|
|
570
|
+
When `autoDetect: true` or `api.engines` is set, the client rewrites logical paths to the
|
|
571
|
+
correct KV v2 API paths automatically (e.g. `secret/foo` → `secret/data/foo` for reads).
|
|
572
|
+
**Callers must pass logical paths — do not include the internal KV v2 segments** (`data/`,
|
|
573
|
+
`metadata/`, `delete/`, `undelete/`, `destroy/`) in the path argument:
|
|
574
|
+
|
|
575
|
+
```javascript
|
|
576
|
+
// Correct — logical path only
|
|
577
|
+
await client.read('secret/my-app/config');
|
|
578
|
+
|
|
579
|
+
// Wrong — double-rewrite: 'secret/data/foo' becomes 'secret/data/data/foo' on the wire
|
|
580
|
+
await client.read('secret/data/foo');
|
|
581
|
+
```
|
|
582
|
+
|
|
583
|
+
If you need to send a fully-literal Vault API path (e.g. when working with non-KV backends or
|
|
584
|
+
when you have already constructed the complete path), use `request()` which bypasses all path
|
|
585
|
+
rewriting:
|
|
586
|
+
|
|
587
|
+
```javascript
|
|
588
|
+
// Literal path, no rewriting
|
|
589
|
+
await client.request('GET', 'secret/data/foo');
|
|
590
|
+
```
|
|
591
|
+
|
|
592
|
+
### Mount detection caching
|
|
593
|
+
|
|
594
|
+
- Each canonical mount is detected at most once per `VaultClient` instance.
|
|
595
|
+
- Concurrent first-touch requests for the same mount share a single in-flight detection promise.
|
|
596
|
+
- The detection endpoint used is `GET sys/internal/ui/mounts/<path>` (readable by any authenticated token).
|
|
597
|
+
- When the token lacks permission on that endpoint, set `api.engines` to skip detection.
|
|
598
|
+
|
|
599
|
+
### Error classes
|
|
600
|
+
|
|
601
|
+
| Class | When thrown |
|
|
602
|
+
|---|---|
|
|
603
|
+
| `UnsupportedOperationError` | A v2-only method (`deleteVersions`, `undeleteVersions`, `destroyVersions`, `readMetadata`, `deleteMetadata`) is called against a non-v2 mount. |
|
|
604
|
+
| `VaultError` | Mount detection fails (e.g. permission denied) and no `api.engines` override was provided. |
|
|
605
|
+
|
|
318
606
|
## Contributing
|
|
319
607
|
|
|
320
608
|
Contributions are welcome! Please read the [contributing guide](CONTRIBUTING.md) to get started,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "node-vault-client",
|
|
3
|
-
"version": "2.0
|
|
3
|
+
"version": "2.1.0",
|
|
4
4
|
"description": "A Vault Client implemented in pure javascript for HashiCorp Vault. It supports variety of Auth Backends and performs lease renewal for issued auth token.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"url": "git+https://github.com/namecheap/node-vault-client.git"
|
|
@@ -15,9 +15,10 @@
|
|
|
15
15
|
"scripts": {
|
|
16
16
|
"test": "mocha --exit \"test/**/*.test.mjs\"",
|
|
17
17
|
"test:unit": "mocha \"test/*.test.mjs\"",
|
|
18
|
-
"test:e2e": "mocha --exit \"test/e2e
|
|
18
|
+
"test:e2e": "mocha --exit \"test/e2e/e2e.test.mjs\"",
|
|
19
|
+
"test:e2e:kv2": "mocha --exit \"test/e2e/e2e.kv2.test.mjs\"",
|
|
19
20
|
"coverage": "c8 npm run test:unit",
|
|
20
|
-
"lint": "eslint src/",
|
|
21
|
+
"lint": "eslint src/ test/",
|
|
21
22
|
"version": "git add -A ."
|
|
22
23
|
},
|
|
23
24
|
"c8": {
|
|
@@ -29,14 +30,18 @@
|
|
|
29
30
|
"html",
|
|
30
31
|
"lcov"
|
|
31
32
|
],
|
|
32
|
-
"all": true
|
|
33
|
+
"all": true,
|
|
34
|
+
"check-coverage": true,
|
|
35
|
+
"statements": 97,
|
|
36
|
+
"branches": 93,
|
|
37
|
+
"functions": 100,
|
|
38
|
+
"lines": 97
|
|
33
39
|
},
|
|
34
40
|
"author": "Namecheap <opensource@namecheap.com>",
|
|
35
41
|
"license": "Apache-2.0",
|
|
36
42
|
"dependencies": {
|
|
37
43
|
"@aws-sdk/credential-providers": "^3.382.0",
|
|
38
44
|
"aws4": "^1.8.0",
|
|
39
|
-
"lodash": "^4.17.21",
|
|
40
45
|
"long-timeout": "^0.1.1"
|
|
41
46
|
},
|
|
42
47
|
"peerDependencies": {
|
|
@@ -45,7 +50,9 @@
|
|
|
45
50
|
"overrides": {
|
|
46
51
|
"serialize-javascript": "^7.0.5",
|
|
47
52
|
"glob": "^13.0.0",
|
|
48
|
-
"diff": "^8.0.3"
|
|
53
|
+
"diff": "^8.0.3",
|
|
54
|
+
"brace-expansion": "^5.0.8",
|
|
55
|
+
"js-yaml": "^4.3.0"
|
|
49
56
|
},
|
|
50
57
|
"devDependencies": {
|
|
51
58
|
"@eslint/js": "^9.0.0",
|
|
@@ -54,6 +61,7 @@
|
|
|
54
61
|
"deep-freeze": "^0.0.1",
|
|
55
62
|
"eslint": "^9.39.4",
|
|
56
63
|
"globals": "^17.6.0",
|
|
64
|
+
"lodash": "^4.17.21",
|
|
57
65
|
"mocha": "^11.7.6",
|
|
58
66
|
"sinon": "^22.0.0",
|
|
59
67
|
"sinon-chai": "^4.0.0"
|
package/src/Lease.js
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const _ = require('lodash');
|
|
4
|
-
|
|
5
3
|
class Lease {
|
|
6
4
|
constructor(
|
|
7
5
|
requestId,
|
|
8
6
|
leaseId,
|
|
9
7
|
leaseDuration,
|
|
10
8
|
renewable,
|
|
11
|
-
data
|
|
9
|
+
data,
|
|
10
|
+
metadata
|
|
12
11
|
) {
|
|
13
12
|
this.__requestId = requestId;
|
|
14
13
|
this.__leaseId = leaseId;
|
|
15
14
|
this.__leaseDuration = leaseDuration;
|
|
16
15
|
this.__renewable = renewable;
|
|
17
16
|
this.__data = data === undefined ? {} : data;
|
|
17
|
+
this.__metadata = metadata;
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
static fromResponse(response) {
|
|
@@ -23,7 +23,8 @@ class Lease {
|
|
|
23
23
|
response.lease_id,
|
|
24
24
|
response.lease_duration,
|
|
25
25
|
response.renewable,
|
|
26
|
-
response.data
|
|
26
|
+
response.data,
|
|
27
|
+
response.metadata
|
|
27
28
|
);
|
|
28
29
|
}
|
|
29
30
|
|
|
@@ -43,7 +44,7 @@ class Lease {
|
|
|
43
44
|
* @returns {Object}
|
|
44
45
|
*/
|
|
45
46
|
getData() {
|
|
46
|
-
return
|
|
47
|
+
return structuredClone(this.__data);
|
|
47
48
|
}
|
|
48
49
|
|
|
49
50
|
/**
|
|
@@ -52,6 +53,16 @@ class Lease {
|
|
|
52
53
|
isRenewable() {
|
|
53
54
|
return this.__renewable;
|
|
54
55
|
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* KV v2 version metadata object (created_time, version, etc.).
|
|
59
|
+
* Returns undefined for KV v1 / non-KV leases.
|
|
60
|
+
*
|
|
61
|
+
* @returns {Object|undefined}
|
|
62
|
+
*/
|
|
63
|
+
getMetadata() {
|
|
64
|
+
return this.__metadata;
|
|
65
|
+
}
|
|
55
66
|
}
|
|
56
67
|
|
|
57
68
|
module.exports = Lease;
|