Skip to content

Commit 00a68d5

Browse files
Copilotaviadhahami
andcommitted
Merge origin/master into copilot/update-readme-content
Resolve README.md conflict in bastion host section by keeping the modernized destructured SocksProxyAgent import with axios-style agent config. Incorporate master's new Custom SSL/TLS Configuration section, pass_request_options example updates, requestOptions forwarding tests, and version bump to 0.10.10. Co-authored-by: aviadhahami <7353632+aviadhahami@users.noreply.github.com>
1 parent ccc8ec0 commit 00a68d5

4 files changed

Lines changed: 191 additions & 7 deletions

File tree

README.md

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,42 @@ const vault = require('node-vault')({
232232
});
233233
```
234234

235+
## Custom SSL/TLS Configuration
236+
237+
If you encounter SSL errors after upgrading to Node 18+ (e.g., `EPROTO` errors related to
238+
`unsafe legacy renegotiation disabled`), you can pass SSL/TLS options via `requestOptions`
239+
or `rpDefaults` when initializing the client:
240+
241+
```javascript
242+
const vault = require('node-vault')({
243+
apiVersion: 'v1',
244+
endpoint: 'https://vault.example.com:8200',
245+
token: 'MY_TOKEN',
246+
requestOptions: {
247+
agentOptions: {
248+
securityOptions: 'SSL_OP_LEGACY_SERVER_CONNECT',
249+
},
250+
},
251+
});
252+
```
253+
254+
The `requestOptions` object is passed through to the underlying HTTP library
255+
([postman-request](https://www.npmjs.com/package/postman-request)) for every request. You can
256+
use it to configure any supported request option, including `agentOptions`, custom `headers`,
257+
or a custom `agent`.
258+
259+
You can also pass request options per-call to any method:
260+
261+
```javascript
262+
vault.read('secret/hello', {
263+
agentOptions: {
264+
securityOptions: 'SSL_OP_LEGACY_SERVER_CONNECT',
265+
},
266+
});
267+
```
268+
269+
See [example/pass_request_options.js](example/pass_request_options.js) for more examples.
270+
235271
[![Backers](https://opencollective.com/node-vault/tiers/backers.svg?avatarHeight=80&width=600)](https://opencollective.com/node-vault/contribute)
236272

237273
[examples]: https://github.com/nodevault/node-vault/tree/master/example

example/pass_request_options.js

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,32 @@
22

33
process.env.DEBUG = 'node-vault'; // switch on debug mode
44

5-
const vault = require('./../src/index')();
5+
// Pass request options at initialization time.
6+
// These options are forwarded to postman-request for every request.
7+
const vault = require('./../src/index')({
8+
requestOptions: {
9+
agentOptions: {
10+
cert: '<path-to-cert>',
11+
key: '<path-to-key>',
12+
passphrase: '<your-passphrase>',
13+
securityOptions: 'SSL_OP_NO_SSLv3',
14+
},
15+
},
16+
});
617

7-
const options = {
18+
// You can also pass (or override) request options per-call.
19+
const perCallOptions = {
820
headers: {
921
'X-HELLO': 'world',
1022
},
1123
agentOptions: {
12-
cert: 'mycert',
13-
key: 'mykey',
14-
passphrase: 'password',
24+
cert: '<path-to-cert>',
25+
key: '<path-to-key>',
26+
passphrase: '<your-passphrase>',
1527
securityOptions: 'SSL_OP_NO_SSLv3',
1628
},
1729
};
1830

19-
vault.help('sys/policy', options)
31+
vault.help('sys/policy', perCallOptions)
2032
.then(() => vault.help('sys/mounts'))
2133
.catch((err) => console.error(err.message));

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "node-vault",
3-
"version": "0.10.9",
3+
"version": "0.10.10",
44
"description": "Javascript client for HashiCorp's Vault",
55
"main": "./src/index.js",
66
"scripts": {

test/unit.js

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,142 @@ describe('node-vault', () => {
295295
});
296296
});
297297

298+
describe('config.requestOptions forwarding', () => {
299+
let requestWithOpts = null;
300+
let vaultWithOpts = null;
301+
302+
const agentOpts = {
303+
securityOptions: 'SSL_OP_LEGACY_SERVER_CONNECT',
304+
};
305+
306+
function getURIWithOpts(path) {
307+
return [vaultWithOpts.endpoint, vaultWithOpts.apiVersion, path].join('/');
308+
}
309+
310+
function assertRequestWithOpts(thisRequest, params, done) {
311+
return () => {
312+
thisRequest.should.have.calledOnce();
313+
thisRequest.calledWithMatch(params).should.be.ok();
314+
return done();
315+
};
316+
}
317+
318+
beforeEach(() => {
319+
requestWithOpts = sinon.stub();
320+
const resp = sinon.stub();
321+
resp.statusCode = 200;
322+
323+
requestWithOpts.returns({
324+
then(fn) {
325+
return fn(resp);
326+
},
327+
catch(fn) {
328+
return fn();
329+
},
330+
});
331+
332+
vaultWithOpts = index({
333+
endpoint: 'http://localhost:8200',
334+
token: '123',
335+
'request-promise': {
336+
defaults: () => requestWithOpts,
337+
},
338+
requestOptions: {
339+
agentOptions: agentOpts,
340+
},
341+
});
342+
});
343+
344+
it('should forward agentOptions from config.requestOptions in help()', (done) => {
345+
const path = 'sys/policy';
346+
const params = {
347+
method: 'GET',
348+
uri: `${getURIWithOpts(path)}?help=1`,
349+
agentOptions: agentOpts,
350+
};
351+
vaultWithOpts.help(path)
352+
.then(assertRequestWithOpts(requestWithOpts, params, done))
353+
.catch(done);
354+
});
355+
356+
it('should forward agentOptions from config.requestOptions in read()', (done) => {
357+
const path = 'secret/hello';
358+
const params = {
359+
method: 'GET',
360+
uri: getURIWithOpts(path),
361+
agentOptions: agentOpts,
362+
};
363+
vaultWithOpts.read(path)
364+
.then(assertRequestWithOpts(requestWithOpts, params, done))
365+
.catch(done);
366+
});
367+
368+
it('should forward agentOptions from config.requestOptions in write()', (done) => {
369+
const path = 'secret/hello';
370+
const params = {
371+
method: 'POST',
372+
uri: getURIWithOpts(path),
373+
agentOptions: agentOpts,
374+
};
375+
vaultWithOpts.write(path, { value: 'world' })
376+
.then(assertRequestWithOpts(requestWithOpts, params, done))
377+
.catch(done);
378+
});
379+
380+
it('should forward agentOptions from config.requestOptions in delete()', (done) => {
381+
const path = 'secret/hello';
382+
const params = {
383+
method: 'DELETE',
384+
uri: getURIWithOpts(path),
385+
agentOptions: agentOpts,
386+
};
387+
vaultWithOpts.delete(path)
388+
.then(assertRequestWithOpts(requestWithOpts, params, done))
389+
.catch(done);
390+
});
391+
392+
it('should forward agentOptions from config.requestOptions in list()', (done) => {
393+
const path = 'secret/hello';
394+
const params = {
395+
method: 'LIST',
396+
uri: getURIWithOpts(path),
397+
agentOptions: agentOpts,
398+
};
399+
vaultWithOpts.list(path)
400+
.then(assertRequestWithOpts(requestWithOpts, params, done))
401+
.catch(done);
402+
});
403+
404+
it('should forward agentOptions from config.requestOptions in generated functions', (done) => {
405+
const name = 'myTestFunction';
406+
vaultWithOpts.generateFunction(name, {
407+
method: 'GET',
408+
path: '/myroute',
409+
});
410+
const params = {
411+
agentOptions: agentOpts,
412+
};
413+
vaultWithOpts[name]()
414+
.then(assertRequestWithOpts(requestWithOpts, params, done))
415+
.catch(done);
416+
});
417+
418+
it('should allow per-call requestOptions to override config.requestOptions', (done) => {
419+
const path = 'secret/hello';
420+
const overrideOpts = {
421+
securityOptions: 'SSL_OP_NO_SSLv3',
422+
};
423+
const params = {
424+
method: 'GET',
425+
uri: getURIWithOpts(path),
426+
agentOptions: overrideOpts,
427+
};
428+
vaultWithOpts.read(path, { agentOptions: overrideOpts })
429+
.then(assertRequestWithOpts(requestWithOpts, params, done))
430+
.catch(done);
431+
});
432+
});
433+
298434
describe('unwrap(options)', () => {
299435
it('should return original response', (done) => {
300436
const path = 'sys/wrapping/unwrap';

0 commit comments

Comments
 (0)