diff --git a/src/node_transport.ts b/src/node_transport.ts index a2011c0..a468245 100644 --- a/src/node_transport.ts +++ b/src/node_transport.ts @@ -64,8 +64,9 @@ export class NodeTransport implements Transport { this.socket = await this.dial(hp); const info = await this.peekInfo(); checkOptions(info, options); - const { tls_required: tlsRequired } = info; - if (tlsRequired) { + const { tls_required: tlsRequired, tls_available: tlsAvailable } = info; + const desired = tlsAvailable === true && options.tls !== null; + if (tlsRequired || desired) { this.socket = await this.startTLS(); } //@ts-ignore: this is possibly a TlsSocket diff --git a/test/tls.js b/test/tls.js index 99a9da9..96fb0cd 100644 --- a/test/tls.js +++ b/test/tls.js @@ -251,3 +251,42 @@ test("tls - invalid cert file", tlsInvalidArgPathMacro, { test("tls - invalid ca file", tlsInvalidArgPathMacro, { caFile: resolve(join(dir, "./test/certs/ca.cert")), }, "caFile"); + +test("tls - available connects with or without", async (t) => { + t.plan(4); + const conf = Object.assign({}, { allow_non_tls: true }, tlsConfig); + const ns = await NatsServer.start(conf); + + // test will fail to connect because the certificate is + // not trusted, but the upgrade process was attempted. + try { + await connect({ + servers: `localhost:${ns.port}`, + }); + t.fail("shouldn't have connected"); + } catch (err) { + t.is(err.message, "unable to verify the first certificate"); + } + + // will upgrade to tls as tls is required + const a = connect({ + servers: `localhost:${ns.port}`, + tls: { + caFile: resolve(join(dir, "./test/certs/ca.crt")), + }, + }); + // will NOT upgrade to tls + const b = connect({ + servers: `localhost:${ns.port}`, + tls: null, + }); + const conns = await Promise.all([a, b]); + await conns[0].flush(); + await conns[1].flush(); + + t.is(conns[0].protocol.transport.isEncrypted(), true); + t.is(conns[1].protocol.transport.isEncrypted(), false); + + await ns.stop(); + t.pass(); +});