Comparing version 1.1.19 to 1.1.20
{ | ||
"name": "Ably", | ||
"version": "1.1.19", | ||
"version": "1.1.20", | ||
"homepage": "https://www.ably.io/", | ||
@@ -5,0 +5,0 @@ "authors": [ |
/** | ||
* @license Copyright 2019, Ably | ||
* | ||
* Ably JavaScript Library v1.1.19 | ||
* Ably JavaScript Library v1.1.20 | ||
* https://github.com/ably/ably-js | ||
@@ -6,0 +6,0 @@ * |
@@ -5,2 +5,6 @@ # Change Log | ||
## [1.1.20](https://github.com/ably/ably-js/tree/1.1.20) (2019-10-05) | ||
- Fix channel.history with promises bug when using the realtime client | ||
- Auth no way to renew warning: upgrade to error | ||
## [1.1.19](https://github.com/ably/ably-js/tree/1.1.19) (2019-10-03) | ||
@@ -7,0 +11,0 @@ - Fix EventEmitter.once typings https://github.com/ably/ably-js/pull/610 |
@@ -113,3 +113,3 @@ var Auth = (function() { | ||
if(noWayToRenew(options)) { | ||
Logger.logAction(Logger.LOG_MAJOR, 'Auth()', 'library initialized with a token literal without any way to renew the token when it expires (no authUrl, authCallback, or key). See https://help.ably.io/error/40171 for help'); | ||
Logger.logAction(Logger.LOG_ERROR, 'Auth()', 'Warning: library initialized with a token literal without any way to renew the token when it expires (no authUrl, authCallback, or key). See https://help.ably.io/error/40171 for help'); | ||
} | ||
@@ -116,0 +116,0 @@ this._saveTokenOptions(options.defaultTokenParams, options); |
@@ -542,2 +542,5 @@ var RealtimeChannel = (function() { | ||
} else { | ||
if(this.rest.options.promises) { | ||
return Utils.promisify(this, 'history', arguments); | ||
} | ||
callback = noop; | ||
@@ -544,0 +547,0 @@ } |
@@ -24,3 +24,3 @@ Defaults.ENVIRONMENT = ''; | ||
Defaults.version = '1.1.19'; | ||
Defaults.version = '1.1.20'; | ||
Defaults.libstring = Platform.libver + Defaults.version; | ||
@@ -27,0 +27,0 @@ Defaults.apiVersion = '1.1'; |
{ | ||
"name": "ably", | ||
"description": "Realtime client library for Ably.io, the realtime messaging service", | ||
"version": "1.1.19", | ||
"version": "1.1.20", | ||
"main": "./nodejs/index.js", | ||
@@ -6,0 +6,0 @@ "typings": "./browser/static/ably.d.ts", |
@@ -43,5 +43,5 @@ # [Ably](https://www.ably.io) | ||
#### Version: 1.1.19 | ||
#### Version: 1.1.20 | ||
The latest stable version of the Ably Javascript client library is version: 1.1.19 . | ||
The latest stable version of the Ably Javascript client library is version: 1.1.20 . | ||
@@ -48,0 +48,0 @@ For complete API documentation, see the [Ably documentation](https://www.ably.io/documentation). |
"use strict"; | ||
define(['ably', 'shared_helper', 'async'], function(Ably, helper, async) { | ||
var exports = {}, | ||
var currentTime, rest, exports = {}, | ||
_exports = {}, | ||
loadTestData = helper.loadTestData, | ||
testClientId = 'clientId', | ||
utils = helper.Utils, | ||
i = utils.inspect, | ||
displayError = helper.displayError, | ||
closeAndFinish = helper.closeAndFinish, | ||
monitorConnection = helper.monitorConnection, | ||
testOnAllTransports = helper.testOnAllTransports, | ||
BufferUtils = Ably.Realtime.BufferUtils, | ||
Crypto = Ably.Realtime.Crypto, | ||
Message = Ably.Realtime.Message, | ||
displayError = helper.displayError, | ||
testResourcesPath = helper.testResourcesPath, | ||
msgpack = (typeof(window) == 'object') ? Ably.msgpack : require('msgpack-js'), | ||
mixin = helper.Utils.mixin, | ||
utils = helper.Utils, | ||
noop = function() {}, | ||
createPM = Ably.Realtime.ProtocolMessage.fromDeserialized, | ||
mixin = utils.mixin, | ||
closeAndFinish = helper.closeAndFinish, | ||
monitorConnection = helper.monitorConnection, | ||
testOnAllTransports = helper.testOnAllTransports; | ||
simulateDroppedConnection = helper.simulateDroppedConnection, | ||
availableTransports = helper.availableTransports; | ||
exports.setupTmp = function(test) { | ||
exports.setuptmp = function(test) { | ||
test.expect(1); | ||
helper.setupApp(function(err) { | ||
if(err) { | ||
test.ok(false, displayError(err)); | ||
} else { | ||
test.ok(true, 'setup app'); | ||
test.ok(false, helper.displayError(err)); | ||
test.done(); | ||
return; | ||
} | ||
test.done(); | ||
rest = helper.AblyRest(); | ||
rest.time(function(err, time) { | ||
if(err) { | ||
test.ok(false, helper.displayError(err)); | ||
} else { | ||
currentTime = time; | ||
test.ok(true, 'Obtained time via REST'); | ||
} | ||
test.done(); | ||
}); | ||
}); | ||
}; | ||
_exports.init_fallbacks_once_connected_2 = function(test) { | ||
var goodHost = helper.AblyRest().options.realtimeHost; | ||
var realtime = helper.AblyRealtime({ | ||
log: {level: 4}, | ||
httpMaxRetryCount: 3, | ||
restHost: 'a', | ||
fallbackHosts: [goodHost, 'b', 'c'] | ||
function requestSync(realtime, channelName) { | ||
realtime.connection.connectionManager.activeProtocol.transport.send({ | ||
action: 16, | ||
channel: channelName | ||
}); | ||
realtime.connection.once('connected', function() { | ||
var hosts = Ably.Rest.Http._getHosts(realtime); | ||
/* restHost rather than realtimeHost as that's what connectionManager | ||
* knows about; converted to realtimeHost by the websocketTransport */ | ||
test.equal(hosts[0], goodHost, 'Check connected realtime host is the first option'); | ||
closeAndFinish(test, realtime); | ||
}) | ||
} | ||
_exports.init_callbacks_promises = function(test) { | ||
var realtime, | ||
keyStr = helper.getTestApp().keys[0].keyStr, | ||
getOptions = function() { return {key: keyStr, autoConnect: false}; }; | ||
function attachChannels(channels, callback) { | ||
async.map(channels, function(channel, cb) { channel.attach(cb); }, callback); | ||
} | ||
realtime = new Ably.Realtime(getOptions()); | ||
test.ok(!realtime.options.promises, 'Check promises defaults to false'); | ||
function compareMessage(one, two) { | ||
if(one.encoding != two.encoding) return false; | ||
if(typeof(one.data) == 'string' && typeof(two.data) == 'string') { | ||
return one.data == two.data; | ||
} | ||
if(BufferUtils.isBuffer(one.data) && BufferUtils.isBuffer(two.data)) { | ||
return (BufferUtils.bufferCompare(one.data, two.data) === 0); | ||
} | ||
return JSON.stringify(one.data) == JSON.stringify(two.data); | ||
} | ||
realtime = new Ably.Realtime.Promise(getOptions()); | ||
console.log("### with promise constructor ", realtime.options) | ||
test.ok(realtime.options.promises, 'Check promises default to true with promise constructor'); | ||
if(!isBrowser && typeof require == 'function') { | ||
realtime = new require('../../promises').Realtime(getOptions()); | ||
test.ok(realtime.options.promises, 'Check promises default to true with promise require target'); | ||
realtime = new require('../../callbacks').Realtime(getOptions()); | ||
test.ok(!realtime.options.promises, 'Check promises default to false with callback require target'); | ||
function testEachFixture(test, filename, channelName, testsPerFixture, fixtureTest) { | ||
if(!Crypto) { | ||
test.ok(false, 'Encryption not supported'); | ||
test.done(); | ||
return; | ||
} | ||
test.done(); | ||
}; | ||
_exports.auth_token_expires = function(test) { | ||
test.expect(4); | ||
var clientRealtime, | ||
rest = helper.AblyRest(); | ||
rest.auth.requestToken({ ttl: 5000 }, null, function(err, tokenDetails) { | ||
loadTestData(testResourcesPath + filename, function(err, testData) { | ||
if(err) { | ||
test.ok(false, displayError(err)); | ||
test.done(); | ||
test.ok(false, 'Unable to get test assets; err = ' + displayError(err)); | ||
return; | ||
} | ||
clientRealtime = helper.AblyRealtime({ tokenDetails: tokenDetails, queryTime: true, transports: ['xhr_streaming'], log: {level: 4} }); | ||
var realtime = helper.AblyRealtime(); | ||
var key = BufferUtils.base64Decode(testData.key); | ||
var iv = BufferUtils.base64Decode(testData.iv); | ||
var channel = realtime.channels.get(channelName, {cipher: {key: key, iv: iv}}); | ||
clientRealtime.connection.on('failed', function(){ | ||
test.ok(false, 'Failed to connect before token expired'); | ||
closeAndFinish(test, clientRealtime); | ||
}); | ||
clientRealtime.connection.once('connected', function(){ | ||
clientRealtime.connection.off('failed'); | ||
test.ok(true, 'Verify connection connected'); | ||
clientRealtime.connection.once('disconnected', function(stateChange){ | ||
test.ok(true, 'Verify connection disconnected'); | ||
test.equal(stateChange.reason.statusCode, 401, 'Verify correct disconnect statusCode'); | ||
test.equal(stateChange.reason.code, 40142, 'Verify correct disconnect code'); | ||
closeAndFinish(test, clientRealtime); | ||
test.expect(testData.items.length * testsPerFixture); | ||
for(var i = 0; i < testData.items.length; i++) { | ||
var item = testData.items[i]; | ||
/* read messages from test data */ | ||
var testMessage = Message.fromValues(item.encoded); | ||
var encryptedMessage = Message.fromValues(item.encrypted); | ||
/* decode (ie remove any base64 encoding). Will throw when | ||
* it gets to the cipher part of the encoding, so wrap in try/catch */ | ||
try { Message.decode(testMessage); } catch(_) {} | ||
try { Message.decode(encryptedMessage); } catch(_) {} | ||
/* reset channel cipher, to ensure it uses the given iv */ | ||
channel.setOptions({cipher: {key: key, iv: iv}}); | ||
fixtureTest(channel.channelOptions, testMessage, encryptedMessage, item.msgpack); | ||
} | ||
closeAndFinish(test, realtime); | ||
}); | ||
} | ||
var publishIntervalHelper = function(currentMessageNum, channel, dataFn, onPublish){ | ||
return function(currentMessageNum) { | ||
console.log('sending: ' + currentMessageNum); | ||
channel.publish('event0', dataFn(), function() { | ||
console.log('publish callback called'); | ||
onPublish(); | ||
}); | ||
}; | ||
}, | ||
publishAtIntervals = function(numMessages, channel, dataFn, onPublish){ | ||
for(var i = numMessages; i > 0; i--) { | ||
setTimeout(publishIntervalHelper(i, channel, dataFn, onPublish), 2*i); | ||
} | ||
}; | ||
function _multiple_send(test, text, iterations, delay) { | ||
if(!Crypto) { | ||
test.ok(false, 'Encryption not supported'); | ||
test.done(); | ||
return; | ||
} | ||
var realtime = helper.AblyRealtime({ useBinaryProtocol: !text}); | ||
test.expect(iterations + 3); | ||
var channelName = 'multiple_send_' + (text ? 'text_' : 'binary_') + iterations + '_' + delay, | ||
channel = realtime.channels.get(channelName), | ||
messageText = 'Test message (' + channelName + ')'; | ||
Crypto.generateRandomKey(128, function(err, key) { | ||
channel.setOptions({cipher: {key: key}}, function(err) { | ||
if(err) { | ||
test.ok(false, 'Unable to set channel options; err = ' + displayError(err)); | ||
closeAndFinish(test, realtime); | ||
return; | ||
} | ||
test.equal(channel.channelOptions.cipher.algorithm, 'aes'); | ||
test.equal(channel.channelOptions.cipher.keyLength, 128); | ||
function sendAll(sendCb) { | ||
var sent = 0; | ||
var sendOnce = function() { | ||
channel.publish('event0', messageText); | ||
if(++sent == iterations) { | ||
sendCb(null); | ||
return; | ||
} | ||
setTimeout(sendOnce, delay); | ||
}; | ||
sendOnce(); | ||
} | ||
function recvAll(recvCb) { | ||
var received = 0; | ||
channel.subscribe('event0', function(msg) { | ||
test.ok(msg.data == messageText); | ||
if(++received == iterations) | ||
recvCb(null); | ||
}); | ||
} | ||
async.parallel([sendAll, recvAll], function(err) { | ||
if(err) { | ||
test.ok(false, 'Error sending messages; err = ' + displayError(err)); | ||
} | ||
test.ok('Verify all messages received'); | ||
closeAndFinish(test, realtime); | ||
}); | ||
}); | ||
@@ -95,35 +178,146 @@ }); | ||
exports.connectionDetails = function(test) { | ||
test.expect(5); | ||
var realtime = helper.AblyRealtime({log: {level: 4}}), | ||
connectionManager = realtime.connection.connectionManager; | ||
realtime.connection.once('connected', function() { | ||
connectionManager.once('connectiondetails', function(details) { | ||
test.equal(details.connectionStateTtl, 12345, 'Check connectionStateTtl in event'); | ||
test.equal(connectionManager.connectionStateTtl, 12345, 'Check connectionStateTtl set in connectionManager'); | ||
test.equal(details.clientId, 'foo', 'Check clientId in event'); | ||
test.equal(realtime.auth.clientId, 'foo', 'Check clientId set in auth'); | ||
test.equal(realtime.options.maxMessageSize, 98765, 'Check maxMessageSize set'); | ||
closeAndFinish(test, realtime); | ||
function extractClientIds(presenceSet) { | ||
return utils.arrMap(presenceSet, function(presmsg) { | ||
return presmsg.clientId; | ||
}).sort(); | ||
} | ||
function extractMember(presenceSet, clientId) { | ||
return helper.arrFind(presenceSet, function(member) { | ||
return member.clientId === clientId; | ||
}); | ||
} | ||
/***************************************************/ | ||
function extractClientIds(presenceSet) { | ||
return utils.arrMap(presenceSet, function(presmsg) { | ||
return presmsg.clientId; | ||
}).sort(); | ||
} | ||
function extractMember(presenceSet, clientId) { | ||
return helper.arrFind(presenceSet, function(member) { | ||
return member.clientId === clientId; | ||
}); | ||
} | ||
var rest, authToken, authToken2; | ||
var testClientId = 'testclient', testClientId2 = 'testclient2'; | ||
var createListenerChannel = function(channelName, callback) { | ||
var channel, realtime; | ||
try { | ||
realtime = helper.AblyRealtime(); | ||
realtime.connection.on('connected', function() { | ||
console.log("Listener connected"); | ||
channel = realtime.channels.get(channelName); | ||
channel.attach(function(err) { | ||
console.log("Listener attached to channel " + channelName); | ||
callback(err, realtime, channel); | ||
}); | ||
}); | ||
connectionManager.activeProtocol.getTransport().onProtocolMessage(createPM({ | ||
action: 4, | ||
connectionId: 'a', | ||
connectionKey: 'ab', | ||
connectionSerial: -1, | ||
connectionDetails: { | ||
clientId: 'foo', | ||
maxMessageSize: 98765, | ||
connectionStateTtl: 12345 | ||
} catch(err) { | ||
callback(err, realtime); | ||
} | ||
}; | ||
var listenerFor = function(eventName, expectedClientId) { | ||
return function(test, channel, callback) { | ||
var presenceHandler = function(presmsg) { | ||
if(this.event === eventName) { | ||
test.ok(true, 'Presence ' + eventName + ' received'); | ||
if(expectedClientId !== undefined) { | ||
test.equal(presmsg.clientId, expectedClientId, 'Verify correct clientId'); | ||
} | ||
channel.presence.unsubscribe(presenceHandler); | ||
callback(); | ||
} | ||
})); | ||
}; | ||
channel.presence.subscribe(presenceHandler); | ||
}; | ||
}; | ||
var runTestWithEventListener = function(test, channel, eventListener, testRunner) { | ||
try { | ||
createListenerChannel(channel, function(err, listenerRealtime, presenceChannel){ | ||
if(err) { | ||
test.ok(false, displayError(err)); | ||
closeAndFinish(test, listenerRealtime); | ||
return; | ||
} | ||
console.log("presenceChannel:", presenceChannel.name); | ||
async.parallel([ | ||
function(cb) { | ||
eventListener(test, presenceChannel, cb); | ||
}, | ||
testRunner | ||
], function(err, res) { | ||
console.log("in callback, err = ", err); | ||
if(err) { | ||
test.ok(false, displayError(err)); | ||
} | ||
// testRunner might or might not call back with an open realtime | ||
var openConnections = (res[1] && res[1].close) ? | ||
[listenerRealtime, res[1]] : | ||
listenerRealtime; | ||
closeAndFinish(test, openConnections); | ||
}); | ||
}); | ||
} catch(e) { | ||
test.ok(false, 'test failed with exception: ' + e.stack); | ||
test.done(); | ||
} | ||
}; | ||
exports.publishpromise = function(test) { | ||
if(typeof Promise === 'undefined') { | ||
test.done(); | ||
return; | ||
} | ||
test.expect(7); | ||
var realtime = helper.AblyRealtime({promises: true}); | ||
var channel = realtime.channels.get('publishpromise'); | ||
var publishPromise = realtime.connection.once('connected').then(function(connectionStateChange) { | ||
console.log("1") | ||
test.ok(true, 'Check once() returns a promise'); | ||
test.equal(connectionStateChange.current, 'connected', 'Check promise is resolved with a connectionStateChange'); | ||
return channel.attach(); | ||
}).then(function() { | ||
return channel.publish('name', 'data'); | ||
}).then(function() { | ||
console.log("2") | ||
test.ok(true, 'Check publish returns a promise that resolves on publish'); | ||
})['catch'](function(err) { | ||
console.log("2a") | ||
test.ok(false, 'Promise chain failed with error: ' + displayError(err)); | ||
}) | ||
var subscribePromise; | ||
var messagePromise = new Promise(function(msgResolve) { | ||
subscribePromise = channel.subscribe('name', function(msg) { | ||
console.log("3") | ||
test.ok(true, 'Received message'); | ||
msgResolve(); | ||
}).then(function() { | ||
console.log("4") | ||
test.ok(true, 'Check subscribe returns a promise that resolves on attach'); | ||
}); | ||
}) | ||
var channelFailedPromise = realtime.channels.get(':invalid').attach()['catch'](function(err) { | ||
console.log("5") | ||
test.ok(true, 'Check attach returns a promise that is rejected on attach fail'); | ||
test.equal(err.code, 40010, 'Check err passed through correctly'); | ||
}); | ||
monitorConnection(test, realtime); | ||
Promise.all([publishPromise, subscribePromise, messagePromise, channelFailedPromise]).then(function() { | ||
console.log("6") | ||
closeAndFinish(test, realtime); | ||
}); | ||
}; | ||
for(var i=0; i<10; i++) { | ||
exports['test_' + i] = exports.connectionDetails | ||
} | ||
return module.exports = helper.withTimeout(exports); | ||
}); |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Native code
Supply chain riskContains native code (e.g., compiled binaries or shared libraries). Including native code can obscure malicious behavior.
Found 1 instance in 1 package
92449
25
12
4218374
171