Comparing version 1.1.0 to 1.2.0
@@ -88,19 +88,4 @@ /* | ||
useOldRequestStyle?: boolean | ||
authHandler?: AuthHandler | ||
} | ||
export interface NKeyAuthChallenge { | ||
sig: Buffer; | ||
nkey: string; | ||
} | ||
export interface ChallengeSigner { | ||
(data: Buffer): Buffer | ||
} | ||
export interface AuthHandler { | ||
sign: ChallengeSigner; | ||
id: string | ||
} | ||
export interface SubscribeOptions { | ||
@@ -107,0 +92,0 @@ queue?: string, |
425
lib/nats.js
@@ -1,2 +0,1 @@ | ||
/* eslint-disable no-await-in-loop */ | ||
/* | ||
@@ -28,3 +27,5 @@ * Copyright 2013-2018 The NATS Authors | ||
events = require('events'), | ||
nuid = require('nuid'); | ||
nuid = require('nuid'), | ||
nkeys = require('ts-nkeys'), | ||
fs = require('fs'); | ||
@@ -34,3 +35,3 @@ /** | ||
*/ | ||
var VERSION = '1.1.0', | ||
var VERSION = '1.2.0', | ||
@@ -56,4 +57,2 @@ DEFAULT_PORT = 4222, | ||
// Protocol | ||
//CONTROL_LINE = /^(.*)\r\n/, // TODO: remove / never used | ||
MSG = /^MSG\s+([^\s\r\n]+)\s+([^\s\r\n]+)\s+(([^\s\r\n]+)[^\S\r\n]+)?(\d+)\r\n/i, | ||
@@ -66,2 +65,3 @@ OK = /^\+OK\s*\r\n/i, | ||
SUBRE = /^SUB\s+([^\r\n]+)\r\n/i, | ||
CREDS = /\s*(?:(?:[-]{3,}[^\n]*[-]{3,}\n)(.+)(?:\n\s*[-]{3,}[^\n]*[-]{3,}\n))/i, | ||
@@ -74,3 +74,2 @@ CR_LF = '\r\n', | ||
// Protocol | ||
//PUB = 'PUB', // TODO: remove / never used | ||
SUB = 'SUB', | ||
@@ -85,3 +84,2 @@ UNSUB = 'UNSUB', | ||
// Errors | ||
API_ERR = "API_ERROR", | ||
BAD_AUTHENTICATION = 'BAD_AUTHENTICATION', | ||
@@ -113,8 +111,18 @@ BAD_AUTHENTICATION_MSG = 'User and Token can not both be provided', | ||
SECURE_CONN_REQ_MSG = 'Server requires a secure connection.', | ||
STALE_CONNECTION_ERR = "stale connection", | ||
STALE_CONNECTION_ERR = 'stale connection', | ||
SIGNATURE_REQUIRED = 'SIG_REQ', | ||
SIGNATURE_REQUIRED_MSG = 'Server requires an Nkey signature.', | ||
SIGCB_NOTFUNC = 'SIG_NOT_FUNC', | ||
SIGCB_NOTFUNC_MSG = 'Signature callback is not a function.', | ||
NKEY_OR_JWT_REQ = 'NKEY_OR_JWT_REQ', | ||
NKEY_OR_JWT_REQ_MSG = 'An Nkey or User JWT callback needs to be defined.', | ||
BAD_CREDS = 'BAD_CREDENTIALS', | ||
BAD_CREDS_MSG = 'Bad user credentials', | ||
NO_SEED_IN_CREDS = 'NO_SEED_IN_CREDS', | ||
NO_SEED_IN_CREDS_MSG = 'Can not locate signing key in credentials', | ||
NO_USER_JWT_IN_CREDS = 'NO_USER_JWT_IN_CREDS', | ||
NO_USER_JWT_IN_CREDS_MSG = 'Can not locate user jwt in credentials.', | ||
BAD_OPTIONS = 'BAD_OPTIONS', | ||
BAD_OPTIONS_MSG = 'Options should be an object as second paramater.', | ||
// Pedantic Mode support | ||
//Q_SUB = /^([^\.\*>\s]+|>$|\*)(\.([^\.\*>\s]+|>$|\*))*$/, // TODO: remove / never used | ||
//Q_SUB_NO_WC = /^([^\.\*>\s]+)(\.([^\.\*>\s]+))*$/, // TODO: remove / never used | ||
FLUSH_THRESHOLD = 65536; | ||
@@ -161,3 +169,2 @@ | ||
exports.REQ_TIMEOUT = REQ_TIMEOUT; | ||
exports.API_ERR = API_ERR; | ||
@@ -192,7 +199,20 @@ | ||
* | ||
* @params {Mixed} [opts] | ||
* | ||
* @params {Mixed} [url] - Url, port, or options object | ||
* @params {Object} [opts] - Options | ||
* @api public | ||
*/ | ||
exports.connect = function(opts) { | ||
exports.connect = function(url, opts) { | ||
// If we receive one parameter, parser will | ||
// figure out intent. If we provided opts, then | ||
// first parameter should be url, and second an | ||
// options object. | ||
if (opts !== undefined) { | ||
if ('object' !== typeof opts) { | ||
this.emit('error', new NatsError(BAD_OPTIONS_MSG, BAD_OPTIONS)); | ||
return; | ||
} | ||
opts.url = sanitizeUrl(url); | ||
} else { | ||
opts = url; | ||
} | ||
return new Client(opts); | ||
@@ -253,2 +273,3 @@ }; | ||
if (undefined === opts) { | ||
@@ -259,3 +280,3 @@ options.url = DEFAULT_URI; | ||
} else if ('string' === typeof opts) { | ||
options.url = opts; | ||
options.url = sanitizeUrl(opts); | ||
} else if ('object' === typeof opts) { | ||
@@ -294,4 +315,14 @@ if (opts.port !== undefined) { | ||
this.assignOption(opts, 'useOldRequestStyle'); | ||
this.assignOption(opts, 'authHandler'); | ||
this.assignOption(opts, 'sigCB', 'sig'); | ||
this.assignOption(opts, 'sigcb', 'sig'); | ||
this.assignOption(opts, 'sigCallback', 'sig'); | ||
this.assignOption(opts, 'nkey', 'nkey'); | ||
this.assignOption(opts, 'nkeys', 'nkey'); | ||
this.assignOption(opts, 'userjwt', 'userjwt'); | ||
this.assignOption(opts, 'jwt', 'userjwt'); | ||
this.assignOption(opts, 'JWT', 'userjwt'); | ||
this.assignOption(opts, 'userJWT', 'userjwt'); | ||
this.assignOption(opts, 'usercreds', 'usercreds'); | ||
this.assignOption(opts, 'userCreds', 'usercreds'); | ||
this.assignOption(opts, 'credentials', 'usercreds'); | ||
} | ||
@@ -326,12 +357,12 @@ | ||
}); | ||
// Randomize if needed | ||
if (options.noRandomize !== true) { | ||
shuffle(client.servers); | ||
} | ||
// Randomize if needed | ||
if (options.noRandomize !== true) { | ||
shuffle(client.servers); | ||
} | ||
// if they gave an URL we should add it if different | ||
if(options.url !== undefined && client.servers.indexOf(options.url) === -1) { | ||
//make url first element so it is attempted first | ||
client.servers.unshift(new Server(url.parse(options.url))); | ||
} | ||
// if they gave an URL we should add it if different | ||
if (options.url !== undefined && client.servers.indexOf(options.url) === -1) { | ||
// Make url first element so it is attempted first | ||
client.servers.unshift(new Server(url.parse(options.url))); | ||
} | ||
} else { | ||
@@ -343,4 +374,25 @@ if (undefined === options.url) { | ||
} | ||
// If we are not setup for tls, but were handed a url with a tls:// prefix | ||
// then upgrade to tls. | ||
if (options.tls === false) { | ||
client.servers.forEach(function(server) { | ||
if (server.url.protocol === 'tls' || server.url.protocol === 'tls:') { | ||
options.tls = true; | ||
} | ||
}); | ||
} | ||
}; | ||
function sanitizeUrl(url) { | ||
if ((/^.*:\/\/.*/).exec(url) === null) { | ||
// Does not have a scheme. | ||
url = 'nats://' + url; | ||
} | ||
var u = new URL(url); | ||
if (u.port === '') { | ||
u.port = DEFAULT_PORT; | ||
} | ||
return u.toString(); | ||
} | ||
/** | ||
@@ -361,3 +413,3 @@ * Create a new server. | ||
Server.prototype.toString = function() { | ||
return this.url.href; | ||
return this.url.href; | ||
}; | ||
@@ -404,2 +456,10 @@ | ||
Client.prototype.checkTLSMismatch = function() { | ||
// Switch over to TLS as needed on the fly. | ||
if (this.info.tls_required === true || | ||
(this.options.tls !== false && this.stream.encrypted !== true)) { | ||
if (undefined === this.options.tls) { | ||
this.options.tls = true; | ||
} | ||
} | ||
if (this.info.tls_required === true && | ||
@@ -428,2 +488,106 @@ this.options.tls === false) { | ||
/** | ||
* Load a user jwt from a chained credential file. | ||
* | ||
* @api private | ||
*/ | ||
Client.prototype.loadUserJWT = function() { | ||
var contents = fs.readFileSync(this.options.usercreds); | ||
var m = CREDS.exec(contents); // jwt | ||
if (m === null) { | ||
this.emit('error', new NatsError(NO_USER_JWT_IN_CREDS_MSG, NO_USER_JWT_IN_CREDS)); | ||
this.closeStream(); | ||
return; | ||
} | ||
return m[1]; | ||
}; | ||
/** | ||
* Load a user nkey seed from a chained credential file | ||
* and sign nonce. | ||
* | ||
* @api private | ||
*/ | ||
Client.prototype.loadKeyAndSignNonce = function(nonce) { | ||
var contents = fs.readFileSync(this.options.usercreds); | ||
var re = new RegExp(CREDS, 'g'); | ||
re.exec(contents); // jwt | ||
var m = re.exec(contents); // seed | ||
if (m === null) { | ||
this.emit('error', new NatsError(NO_SEED_IN_CREDS_MSG, NO_SEED_IN_CREDS)); | ||
this.closeStream(); | ||
return; | ||
} | ||
var sk = nkeys.fromSeed(Buffer.from(m[1])); | ||
return sk.sign(nonce); | ||
}; | ||
/** | ||
* Helper that takes a user credentials file and | ||
* generates the proper opts object with proper handlers | ||
* filled in. e.g nats.connect(url, nats.creds("my_creds.ttx") | ||
* | ||
* @params {String} [filepath] | ||
* | ||
* @api public | ||
*/ | ||
exports.creds = function(filepath) { | ||
if (undefined === filepath) { | ||
return undefined; | ||
} | ||
return { | ||
usercreds: filepath | ||
}; | ||
}; | ||
/** | ||
* Check for Nkey mismatch. | ||
* | ||
* @api private | ||
*/ | ||
Client.prototype.checkNkeyMismatch = function() { | ||
if (undefined === this.info.nonce) { | ||
return false; | ||
} | ||
// If this has been specified make sure we can open the file and parse it. | ||
if (this.options.usercreds !== undefined) { | ||
// Treat this as a filename. | ||
// For now we will not capture an error on file not found etc. | ||
var contents = fs.readFileSync(this.options.usercreds); | ||
if (CREDS.exec(contents) === null) { | ||
this.emit('error', new NatsError(BAD_CREDS_MSG, BAD_CREDS)); | ||
this.closeStream(); | ||
return true; | ||
} | ||
// We have a valid file, set up callback handlers. | ||
var client = this; | ||
this.options.sig = function(nonce) { | ||
return client.loadKeyAndSignNonce(nonce); | ||
}; | ||
this.options.userjwt = function() { | ||
return client.loadUserJWT(); | ||
}; | ||
return false; | ||
} | ||
if (undefined === this.options.sig) { | ||
this.emit('error', new NatsError(SIGNATURE_REQUIRED_MSG, SIGNATURE_REQUIRED)); | ||
this.closeStream(); | ||
return true; | ||
} | ||
if (typeof (this.options.sig) !== 'function') { | ||
this.emit('error', new NatsError(SIGCB_NOTFUNC_MSG, SIGCB_NOTFUNC)); | ||
this.closeStream(); | ||
return true; | ||
} | ||
if (undefined === this.options.nkey && undefined === this.options.userjwt) { | ||
this.emit('error', new NatsError(NKEY_OR_JWT_REQ_MSG, NKEY_OR_JWT_REQ)); | ||
this.closeStream(); | ||
return true; | ||
} | ||
return false; | ||
}; | ||
/** | ||
* Callback for first flush/connect. | ||
@@ -560,3 +724,3 @@ * | ||
*/ | ||
Client.prototype.sendConnect = function(challengeResponse) { | ||
Client.prototype.sendConnect = function() { | ||
// Queue the connect command. | ||
@@ -570,2 +734,16 @@ var cs = { | ||
}; | ||
if (this.info.nonce !== undefined && this.options.sig !== undefined) { | ||
var sig = this.options.sig(Buffer.from(this.info.nonce)); | ||
cs.sig = sig.toString('base64'); | ||
} | ||
if (this.options.userjwt !== undefined) { | ||
if (typeof (this.options.userjwt) === 'function') { | ||
cs.jwt = this.options.userjwt(); | ||
} else { | ||
cs.jwt = this.options.userjwt; | ||
} | ||
} | ||
if (this.options.nkey !== undefined) { | ||
cs.nkey = this.options.nkey; | ||
} | ||
if (this.user !== undefined) { | ||
@@ -581,6 +759,4 @@ cs.user = this.user; | ||
} | ||
if(challengeResponse && challengeResponse.nkey && Buffer.isBuffer(challengeResponse.sig)) { | ||
cs.nkey = challengeResponse.nkey; | ||
cs.sig = challengeResponse.sig.toString('base64'); | ||
if (this.options.nkey !== undefined) { | ||
cs.nkey = this.options.nkey; | ||
} | ||
@@ -644,4 +820,5 @@ | ||
this.selectServer(); | ||
// See #45 if we have a stream release the listeners | ||
// otherwise in addition to the leak events will fire fire | ||
// See #45 if we have a stream release the listeners otherwise in addition | ||
// to the leaking of events, the old events will still fire. | ||
if (this.stream) { | ||
@@ -682,3 +859,3 @@ this.stream.removeAllListeners(); | ||
Client.prototype.close = function() { | ||
if(this.pingTimer) { | ||
if (this.pingTimer) { | ||
clearTimeout(this.pingTimer); | ||
@@ -844,23 +1021,2 @@ delete this.pingTimer; | ||
/** | ||
* @api private | ||
*/ | ||
Client.prototype.handlesChallenge = function() { | ||
var ah = this.options.authHandler; | ||
return ah && typeof ah.sign === 'function' && this.info.nonce != undefined; | ||
}; | ||
/** | ||
* @api private | ||
*/ | ||
Client.prototype.handleChallenge = function() { | ||
var ah = this.options.authHandler; | ||
if(ah && this.info.nonce !== undefined) { | ||
var sig = ah.sign(Buffer.from(this.info.nonce)); | ||
return {sig: sig, nkey: ah.id}; | ||
} else { | ||
return undefined; | ||
} | ||
}; | ||
/** | ||
* Process the inbound data queue. | ||
@@ -925,16 +1081,2 @@ * | ||
client.info = JSON.parse(m[1]); | ||
// Check on TLS mismatch. | ||
if (client.checkTLSMismatch() === true) { | ||
return; | ||
} | ||
var challengeResponse; | ||
if(client.handlesChallenge()) { | ||
try { | ||
challengeResponse = this.handleChallenge(); | ||
} catch(ex) { | ||
client.emit('error', new NatsError("client code exception handleChallenge()", API_ERR, ex)); | ||
} | ||
} | ||
// Always try to read the connect_urls from info | ||
@@ -945,5 +1087,12 @@ client.processServerUpdate(); | ||
if (client.infoReceived === false) { | ||
// Check on TLS mismatch. | ||
if (client.checkTLSMismatch() === true) { | ||
return; | ||
} | ||
if (client.checkNkeyMismatch() === true) { | ||
return; | ||
} | ||
// Switch over to TLS as needed. | ||
if (client.options.tls !== false && | ||
client.stream.encrypted !== true) { | ||
if (client.info.tls_required === true) { | ||
var tlsOpts = { | ||
@@ -968,3 +1117,3 @@ socket: client.stream | ||
// Send the connect message and subscriptions immediately | ||
client.sendConnect(challengeResponse); | ||
client.sendConnect(); | ||
client.sendSubscriptions(); | ||
@@ -1074,46 +1223,48 @@ | ||
Client.prototype.processServerUpdate = function() { | ||
var client = this; | ||
if (client.info.connect_urls && client.info.connect_urls.length > 0) { | ||
// parse the infos | ||
var tmp = {}; | ||
client.info.connect_urls.forEach(function(server) { | ||
var u = 'nats://' + server; | ||
var s = new Server(url.parse(u)); | ||
// implicit servers are ones added via the info connect_urls | ||
s.implicit = true; | ||
tmp[s.url.href] = s; | ||
}); | ||
var client = this; | ||
if (client.info.connect_urls && client.info.connect_urls.length > 0) { | ||
// parse the infos | ||
var tmp = {}; | ||
client.info.connect_urls.forEach(function(server) { | ||
var u = 'nats://' + server; | ||
var s = new Server(url.parse(u)); | ||
// implicit servers are ones added via the info connect_urls | ||
s.implicit = true; | ||
tmp[s.url.href] = s; | ||
}); | ||
// remove implicit servers that are no longer reported | ||
var toDelete = []; | ||
client.servers.forEach(function(s, index) { | ||
var u = s.url.href; | ||
if(s.implicit && client.currentServer.url.href !== u && tmp[u] === undefined) { | ||
// server was removed | ||
toDelete.push(index); | ||
} | ||
// remove this entry from reported | ||
delete tmp[u]; | ||
}); | ||
// remove implicit servers that are no longer reported | ||
var toDelete = []; | ||
client.servers.forEach(function(s, index) { | ||
var u = s.url.href; | ||
if (s.implicit && client.currentServer.url.href !== u && tmp[u] === undefined) { | ||
// server was removed | ||
toDelete.push(index); | ||
} | ||
// remove this entry from reported | ||
delete tmp[u]; | ||
}); | ||
// perform the deletion | ||
toDelete.reverse(); | ||
toDelete.forEach(function(index) { | ||
client.servers.splice(index, 1); | ||
}); | ||
// perform the deletion | ||
toDelete.reverse(); | ||
toDelete.forEach(function(index) { | ||
client.servers.splice(index, 1); | ||
}); | ||
// remaining servers are new | ||
var newURLs = []; | ||
for(var k in tmp) { | ||
if(tmp.hasOwnProperty(k)) { | ||
client.servers.push(tmp[k]); | ||
newURLs.push(k); | ||
} | ||
} | ||
// remaining servers are new | ||
var newURLs = []; | ||
for (var k in tmp) { | ||
if (tmp.hasOwnProperty(k)) { | ||
client.servers.push(tmp[k]); | ||
newURLs.push(k); | ||
} | ||
} | ||
if(newURLs.length) { | ||
// new reported servers useful for tests | ||
client.emit('serversDiscovered', newURLs); | ||
if (newURLs.length) { | ||
// new reported servers useful for tests | ||
client.emit('serversDiscovered', newURLs); | ||
// simpler version | ||
client.emit('servers', newURLs); | ||
} | ||
} | ||
} | ||
}; | ||
@@ -1137,2 +1288,3 @@ | ||
} | ||
// Check for auto-unsubscribe | ||
@@ -1164,3 +1316,3 @@ if (sub.max !== undefined) { | ||
sub.callback(msg, this.payload.reply, this.payload.subj, this.payload.sid); | ||
} catch(error) { | ||
} catch (error) { | ||
this.emit('error', error); | ||
@@ -1375,3 +1527,3 @@ } | ||
// the request configuration. Mux requests are always negative numbers | ||
if(sid < 0) { | ||
if (sid < 0) { | ||
this.cancelMuxRequest(sid); | ||
@@ -1424,5 +1576,5 @@ return; | ||
// check the sid is not a mux sid - which is always negative | ||
if(sid < 0) { | ||
if (sid < 0) { | ||
var conf = this.getMuxRequestConfig(sid); | ||
if(conf && conf.timeout) { | ||
if (conf && conf.timeout) { | ||
// clear auto-set timeout | ||
@@ -1436,6 +1588,6 @@ clearTimeout(conf.timeout); | ||
if(sub) { | ||
if (sub) { | ||
sub.expected = expected; | ||
var that = this; | ||
sub.timeout = setTimeout(function () { | ||
sub.timeout = setTimeout(function() { | ||
callback(sid); | ||
@@ -1471,3 +1623,3 @@ // if callback fails unsubscribe will leak | ||
Client.prototype.request = function(subject, opt_msg, opt_options, callback) { | ||
if(this.options.useOldRequestStyle) { | ||
if (this.options.useOldRequestStyle) { | ||
return this.oldRequest(subject, opt_msg, opt_options, callback); | ||
@@ -1489,6 +1641,6 @@ } | ||
if(opt_options.timeout) { | ||
if (opt_options.timeout) { | ||
var client = this; | ||
conf.timeout = setTimeout(function() { | ||
if(conf.callback) { | ||
if (conf.callback) { | ||
conf.callback(new NatsError(REQ_TIMEOUT_MSG_PREFIX + conf.id, REQ_TIMEOUT)); | ||
@@ -1546,3 +1698,3 @@ } | ||
Client.prototype.requestOne = function(subject, opt_msg, opt_options, timeout, callback) { | ||
if(this.options.useOldRequestStyle) { | ||
if (this.options.useOldRequestStyle) { | ||
return this.oldRequestOne(subject, opt_msg, opt_options, timeout, callback); | ||
@@ -1588,3 +1740,3 @@ } | ||
Client.prototype.createResponseMux = function() { | ||
if(!this.respmux) { | ||
if (!this.respmux) { | ||
var client = this; | ||
@@ -1596,12 +1748,13 @@ var inbox = createInbox(); | ||
var conf = client.getMuxRequestConfig(token); | ||
if(conf) { | ||
if(conf.hasOwnProperty('expected')) { | ||
if (conf) { | ||
if (conf.callback) { | ||
conf.callback(msg, reply); | ||
} | ||
if (conf.hasOwnProperty('expected')) { | ||
conf.received++; | ||
if (conf.received >= conf.expected) { | ||
client.cancelMuxRequest(token); | ||
client.emit('unsubscribe', sid, subject); | ||
} | ||
} | ||
if(conf.callback) { | ||
conf.callback(msg, reply); | ||
} | ||
} | ||
@@ -1629,4 +1782,10 @@ }); | ||
var conf = {token: token, callback: callback, inbox: inbox, id: this.respmux.nextID--, received: 0}; | ||
if(expected > 0) { | ||
var conf = { | ||
token: token, | ||
callback: callback, | ||
inbox: inbox, | ||
id: this.respmux.nextID--, | ||
received: 0 | ||
}; | ||
if (expected > 0) { | ||
conf.expected = expected; | ||
@@ -1672,3 +1831,3 @@ } | ||
if (conf) { | ||
if(conf.timeout) { | ||
if (conf.timeout) { | ||
clearTimeout(conf.timeout); | ||
@@ -1675,0 +1834,0 @@ } |
{ | ||
"name": "nats", | ||
"version": "1.1.0", | ||
"version": "1.2.0", | ||
"description": "Node.js client for NATS, a lightweight, high-performance cloud native messaging system", | ||
@@ -37,28 +37,28 @@ "keywords": [ | ||
"cover": "istanbul cover _mocha", | ||
"lint": "if-node-version '>=6' eslint ./lib ./examples/node-pub ./examples/node-sub ./benchmark ./test", | ||
"lint": "if-node-version >=4 eslint ./lib ./examples ./benchmark ./test", | ||
"fmt": "js-beautify -n --config crockford.jscsrc -r lib/* test/*.js test/support/*.js examples/* benchmark/*.js" | ||
}, | ||
"engines": { | ||
"node": ">= 6.0.0" | ||
"node": ">= 4.5.0" | ||
}, | ||
"dependencies": { | ||
"nuid": "^1.0.0" | ||
"nuid": "^1.0.0", | ||
"ts-nkeys": "^1.0.8" | ||
}, | ||
"devDependencies": { | ||
"@types/node": "^10.12.0", | ||
"coveralls": "^2.11.2", | ||
"dependency-check": "2.5.x", | ||
"eslint": "^5.7.0", | ||
"minimist": "^1.2.0", | ||
"coveralls": "^3.0.2", | ||
"dependency-check": "^3.2.1", | ||
"eslint": "^5.10.0", | ||
"if-node-version": "^1.1.1", | ||
"istanbul": "0.4.x", | ||
"istanbul": "^0.4.5", | ||
"js-beautify": "^1.6.12", | ||
"jshint": "^2.9.6", | ||
"jshint-stylish": "2.2.x", | ||
"mocha": "2.5.x", | ||
"mocha": "^5.2.0", | ||
"mocha-lcov-reporter": "1.2.x", | ||
"mocha-multi": "0.9.x", | ||
"should": ">= 9.0.0", | ||
"ts-nkeys": "^1.0.4" | ||
"mocha-multi": "^1.0.1", | ||
"should": ">= 9.0.0" | ||
}, | ||
"typings": "./index.d.ts" | ||
} |
@@ -6,4 +6,4 @@ # NATS - Node.js Client | ||
[](https://www.apache.org/licenses/LICENSE-2.0) | ||
[]() | ||
[]() | ||
[](https://travis-ci.org/nats-io/node-nats) | ||
[](https://coveralls.io/r/nats-io/node-nats?branch=master) | ||
[](https://www.npmjs.com/package/nats) | ||
@@ -151,5 +151,42 @@ [](https://www.npmjs.com/package/nats) | ||
``` | ||
## Authentication | ||
## New Authentication (Nkeys and User Credentials) | ||
See examples for more usage. | ||
```javascript | ||
// Simple connect using credentials file. This loads JWT and signing key | ||
// each time that NATS connects. | ||
var nc = NATS.connect('connect.ngs.global', NATS.creds("./myid.creds"); | ||
// Setting nkey and signing callback directly. | ||
var nc = NATS.connect(url, { | ||
nkey: 'UAH42UG6PV552P5SWLWTBP3H3S5BHAVCO2IEKEXUANJXR75J63RQ5WM6', | ||
sigCB: function(nonce) { | ||
return sk.sign(nonce); | ||
} | ||
}); | ||
// Setting user JWT statically. | ||
var nc = NATS.connect(url, { | ||
userJWT: myJWT, | ||
sigCB: function(nonce) { | ||
return sk.sign(nonce); | ||
} | ||
}); | ||
// Having user JWT be a function that returns the JWT. Can be useful for | ||
// loading a new JWT. | ||
var nc = NATS.connect(url, { | ||
userJWT: function() { | ||
return myJWT; | ||
}, | ||
sigCB: function(nonce) { | ||
return sk.sign(nonce); | ||
} | ||
}); | ||
``` | ||
## Basic Authentication | ||
```javascript | ||
// Connect with username and password in the url | ||
@@ -222,3 +259,3 @@ var nc = NATS.connect("nats://foo:bar@localhost:4222"); | ||
// To prevent payload conversion from a Buffer to a string, set the | ||
// To prevent payload conversion from a Buffer to a string, set the | ||
// preserveBuffers option to true. Message payload return will be a Buffer. | ||
@@ -234,3 +271,3 @@ | ||
// To change the default behaviour specify the max number of connection | ||
// attempts in `maxReconnectAttempts` (set to -1 to retry forever), and the | ||
// attempts in `maxReconnectAttempts` (set to -1 to retry forever), and the | ||
// time in milliseconds between reconnects in `reconnectTimeWait`. | ||
@@ -294,14 +331,10 @@ | ||
| `waitOnFirstConnect` | | `false` | If `true` the server will fall back to a reconnect mode if it fails its first connection attempt. | ||
| `yieldTime` | | | If set, processing will yield at least the specified number of milliseconds to IO callbacks before processing inbound messages | ||
| `yieldTime` | | | If set, processing will yield at least the specified number of milliseconds to IO callbacks before processing inbound messages | ||
## Supported Node Versions | ||
## Supported Node Versions | ||
Support policy for Nodejs versions follows | ||
[Nodejs release support]( https://github.com/nodejs/Release). | ||
We will support and build node-nats on even Nodejs versions that are current | ||
or in maintenance. | ||
Our support policy for Nodejs versions follows [Nodejs release support]( https://github.com/nodejs/Release). | ||
We will support and build node-nats on even-numbered Nodejs versions that are current or in LTS. | ||
@@ -308,0 +341,0 @@ |
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
89731
13
1880
340
2
1
+ Addedts-nkeys@^1.0.8
+ Addedts-nkeys@1.0.16(transitive)
+ Addedtweetnacl@1.0.3(transitive)