Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

pusher-js

Package Overview
Dependencies
Maintainers
1
Versions
53
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

pusher-js - npm Package Compare versions

Comparing version 7.5.0 to 7.6.0

integration_tests_server/index.js

4

CHANGELOG.md
# Changelog
## 7.6.0
- [ADDED] Introduce and to channel authorization and user authentication in order to allow for changing header and param values after the Pusher object is initialized.
## 7.5.0

@@ -4,0 +8,0 @@

11

package.json
{
"name": "pusher-js",
"version": "7.5.0",
"version": "7.6.0",
"description": "Pusher Channels JavaScript library for browsers, React Native, NodeJS and web workers",

@@ -41,5 +41,5 @@ "main": "dist/node/pusher.js",

"isomorphic-fetch": "^3.0.0",
"jasmine": "^3.99.0",
"jasmine": "^4.5.0",
"jasmine-spec-reporter": "^7.0.0",
"karma": "^6.4.0",
"karma": "^6.4.1",
"karma-browserstack-launcher": "^1.6.0",

@@ -62,3 +62,3 @@ "karma-chrome-launcher": "^3.1.0",

"webpack-cli": "^3.3.12",
"webpack-dev-server": "^3.11.2",
"webpack-dev-server": "^4.11.1",
"webpack-merge": "^5.8.0",

@@ -69,4 +69,5 @@ "xmlhttprequest": "^1.8.0"

"tweetnacl": "^1.0.3",
"@types/node": "^14.14.31"
"@types/node": "^14.14.31",
"@types/express-serve-static-core": "4.17.28"
}
}

@@ -147,6 +147,6 @@ # Pusher Channels Javascript Client

> **⚠️ Important notice**
> **⚠️ Important notice**
>
> React Native support has been **deprecated** and soon will be removed from this repository.
>
> React Native support has been **deprecated** and soon will be removed from this repository.
>
> Please, use our official [React Native SDK](https://github.com/pusher/pusher-websocket-react-native) instead.

@@ -236,2 +236,6 @@

* `paramsProvider` (Function) - When present, this function is called to get additional parameters to be sent when the user authentication endpoint is called. This is equivalent to passing them on the params key, but allows for the parameters to be retrieved dynamically at the time of the request.
* `headersProvider` (Function) - When present, this function is called to get additional headers to be sent when the user authentication endpoint is called. This is equivalent to passing them on the headers key, but allows for the headers to be retrieved dynamically at the time of the request.
* `customHandler` (Function) - When present, this function is called instead of a request being made to the endpoint specified by `userAuthentication.endpoint`.

@@ -257,2 +261,6 @@

* `paramsProvider` (Function) - When present, this function is called to get additional parameters to be sent when the user authentication endpoint is called. This is equivalent to passing them on the params key, but allows for the parameters to be retrieved dynamically at the time of the request.
* `headersProvider` (Function) - When present, this function is called to get additional headers to be sent when the user authentication endpoint is called. This is equivalent to passing them on the headers key, but allows for the headers to be retrieved dynamically at the time of the request.
* `customHandler` (Function) - When present, this function is called instead of a request being made to the endpoint specified by `channelAuthorization.endpoint`.

@@ -259,0 +267,0 @@

@@ -35,3 +35,3 @@ const { merge } = require('webpack-merge');

browsers: browserList,
captureTimeout: 5e3,
captureTimeout: 10e3,
browserNoActivityTimeout: 3e4,

@@ -52,2 +52,1 @@ browserDisconnectTimeout: 3e4,

};

@@ -6,4 +6,4 @@ var base64encode = require('core/base64').default;

exports.API_URL = "http://pusher-js-integration-api.herokuapp.com";
exports.API_EU_URL = "http://pusher-js-integration-api-eu.herokuapp.com";
exports.API_URL = "http://localhost:3000";
exports.API_EU_URL = "http://localhost:3001";

@@ -10,0 +10,0 @@ exports.describe = function(name, body) {

@@ -8,4 +8,4 @@ var base64encode = require('core/base64').default;

exports.API_URL = "http://pusher-js-integration-api.herokuapp.com";
exports.API_EU_URL = "http://pusher-js-integration-api-eu.herokuapp.com";
exports.API_URL = "http://localhost:3000";
exports.API_EU_URL = "http://localhost:3001";

@@ -12,0 +12,0 @@ exports.describe = function(name, body) {

@@ -62,3 +62,3 @@ const TestEnv = require('testenv');

pusher = new Pusher("4d31fbea7080e3b4bf6d", {
pusher = new Pusher("cb7d5e50f5669e5c9ae6", {
authTransport: authTransport,

@@ -65,0 +65,0 @@ authEndpoint: Integration.API_EU_URL + "/auth",

const Pusher = require('pusher_integration');
const Integration = require('integration');
const OneOffTimer = require('core/utils/timers').OneOffTimer;
const Collections = require('core/utils/collections');

@@ -10,18 +9,2 @@ const Runtime = require('runtime').default;

// this is a slightly horrible function that allows easy placement of arbitrary
// delays in jasmine async tests. e.g:
// waitsFor(sleep(3000), "thing to happen", 3500)
function sleep(time) {
var fn = function() {
var val = false;
setTimeout(function(){
val = true;
}, time)
return function() {
return val;
}
}
return fn();
}
function canRunTwoConnections(transport) {

@@ -42,2 +25,6 @@ if (transport !== "sockjs") {

function delay(timeMs) {
return new Promise(resolve => setTimeout(resolve, timeMs));
}
function build(testConfig) {

@@ -72,7 +59,7 @@ var forceTLS = testConfig.forceTLS;

it("should open connections", async function() {
pusher1 = new Pusher("7324d55a5eeb8f554761", {
pusher1 = new Pusher("c49a449b916bb4246729", {
forceTLS: forceTLS,
});
if (canRunTwoConnections(transport)) {
pusher2 = new Pusher("7324d55a5eeb8f554761", {
pusher2 = new Pusher("c49a449b916bb4246729", {
forceTLS: forceTLS,

@@ -407,8 +394,4 @@ });

pusher.send_event(eventName, {}, channelName);
timer = new OneOffTimer(3000, function() {});
await delay(5000);
await waitsFor(function() {
return !timer.isRunning();
}, "timer to finish", 3210);
expect(onEvent).not.toHaveBeenCalled();

@@ -477,8 +460,3 @@ pusher.unsubscribe(channelName);

});
timer = new OneOffTimer(3000, function() {});
await waitsFor(function() {
return !timer.isRunning();
}, "timer to finish", 3210);
await delay(5000);
expect(received).toBe(null);

@@ -527,8 +505,4 @@ });

});
timer = new OneOffTimer(3000, function() {});
await delay(5000);
await waitsFor(function() {
return !timer.isRunning();
}, "timer to finish", 10000);
expect(channel.subscribed).toEqual(false);

@@ -563,8 +537,4 @@ expect(received).toBe(null);

});
timer = new OneOffTimer(3000, function() {});
await delay(10000);
await waitsFor(function() {
return !timer.isRunning();
}, "timer to finish", 10000);
expect(channel.subscribed).toEqual(true);

@@ -637,3 +607,3 @@ expect(received).not.toBe(null);

// actioned by the server, so we just wait a while
await waitsFor(sleep(3000), "unsubscription to finish", 3500)
await delay(5000);

@@ -708,3 +678,3 @@ expect(pusher.channel(channelName)).toBe(undefined);

// actioned by the server, so we just wait a while
await waitsFor(sleep(3000), "unsubscription to finish", 3500)
await delay(5000);
expect(pusher.channel(channelName)).toBe(undefined);

@@ -747,3 +717,3 @@

// actioned by the server, so we just wait a while
await waitsFor(sleep(3000), "unsubscription to finish", 3500)
await delay(5000);

@@ -750,0 +720,0 @@ expect(pusher.channel(channelName)).toBe(undefined);

@@ -40,6 +40,6 @@ const Pusher = require('pusher_integration');

expect(callback).toHaveBeenCalledWith(null, {
"session": "2289545",
"session": 2289545,
"features": ["ws", "sockjs"],
"version": "1.13.0",
"t0": "1355850357911",
"t0": 1355850357911,
"timeline": [

@@ -46,0 +46,0 @@ { t: 0, e: 2 },

@@ -32,2 +32,28 @@ var Runtime = require('runtime').default;

endpoint: "http://example.com/auth",
headers: { "X-Foo": "my-bar" }
};
channelAuthorizer = ChannelAuthorizer(authOptions);
transportAuthorizer = jasmine.createSpy("ajax")
Runtime.getAuthorizers = jasmine.createSpy("getAuthorizers").and.returnValue({
ajax: transportAuthorizer
});
const params = { socketId: '1.23', channelName: 'private-test' };
const callback = function(){};
const query = 'socket_id=1.23&channel_name=private-test';
channelAuthorizer(params, callback);
expect(Runtime.getAuthorizers.calls.count()).toEqual(1);
expect(transportAuthorizer).toHaveBeenCalledWith(
Runtime,
query,
authOptions,
'channel-authorization',
callback);
});
it("should call the specified transport authorizer with params", function(){
const authOptions = {
transport: "ajax",
endpoint: "http://example.com/auth",
params: { foo: "bar" },

@@ -55,3 +81,59 @@ headers: { "X-Foo": "my-bar" }

});
it("should call the specified transport authorizer with paramsProvider", function(){
const authOptions = {
transport: "ajax",
endpoint: "http://example.com/auth",
paramsProvider: () => { return { abc: '123' }; },
headers: { "X-Foo": "my-bar" }
};
channelAuthorizer = ChannelAuthorizer(authOptions);
transportAuthorizer = jasmine.createSpy("ajax")
Runtime.getAuthorizers = jasmine.createSpy("getAuthorizers").and.returnValue({
ajax: transportAuthorizer
});
const params = { socketId: '1.23', channelName: 'private-test' };
const callback = function(){};
const query = 'socket_id=1.23&channel_name=private-test&abc=123';
channelAuthorizer(params, callback);
expect(Runtime.getAuthorizers.calls.count()).toEqual(1);
expect(transportAuthorizer).toHaveBeenCalledWith(
Runtime,
query,
authOptions,
'channel-authorization',
callback);
});
it("should call the specified transport authorizer with params and paramsProvider", function(){
const authOptions = {
transport: "ajax",
endpoint: "http://example.com/auth",
params: { foo: "bar" },
paramsProvider: () => { return { abc: '123' }; },
headers: { "X-Foo": "my-bar" }
};
channelAuthorizer = ChannelAuthorizer(authOptions);
transportAuthorizer = jasmine.createSpy("ajax")
Runtime.getAuthorizers = jasmine.createSpy("getAuthorizers").and.returnValue({
ajax: transportAuthorizer
});
const params = { socketId: '1.23', channelName: 'private-test' };
const callback = function(){};
const query = 'socket_id=1.23&channel_name=private-test&foo=bar&abc=123';
channelAuthorizer(params, callback);
expect(Runtime.getAuthorizers.calls.count()).toEqual(1);
expect(transportAuthorizer).toHaveBeenCalledWith(
Runtime,
query,
authOptions,
'channel-authorization',
callback);
});
});
});

@@ -51,3 +51,79 @@ var Runtime = require('runtime').default;

});
it("should call the specified transport authorizer with params", function(){
const userAuthentication = {
transport: "ajax",
params: { abc: '123' }
};
userAuthenticator = UserAuthenticator(userAuthentication);
transportAuthorizer = jasmine.createSpy("ajax")
Runtime.getAuthorizers = jasmine.createSpy("getAuthorizers").and.returnValue({
ajax: transportAuthorizer
});
const params = { socketId: '1.23' };
const callback = function(){};
const query = 'socket_id=1.23&abc=123';
userAuthenticator(params, callback);
expect(Runtime.getAuthorizers.calls.count()).toEqual(1);
expect(transportAuthorizer).toHaveBeenCalledWith(
Runtime,
query,
userAuthentication,
'user-authentication',
callback);
});
it("should call the specified transport authorizer with paramsProvider", function(){
const userAuthentication = {
transport: "ajax",
paramsProvider: () => { return { abc: '123' }; }
};
userAuthenticator = UserAuthenticator(userAuthentication);
transportAuthorizer = jasmine.createSpy("ajax")
Runtime.getAuthorizers = jasmine.createSpy("getAuthorizers").and.returnValue({
ajax: transportAuthorizer
});
const params = { socketId: '1.23' };
const callback = function(){};
const query = 'socket_id=1.23&abc=123';
userAuthenticator(params, callback);
expect(Runtime.getAuthorizers.calls.count()).toEqual(1);
expect(transportAuthorizer).toHaveBeenCalledWith(
Runtime,
query,
userAuthentication,
'user-authentication',
callback);
});
it("should call the specified transport authorizer with params and paramsProvider", function(){
const userAuthentication = {
transport: "ajax",
params: { abc: '123' },
paramsProvider: () => { return { def: '456' }; }
};
userAuthenticator = UserAuthenticator(userAuthentication);
transportAuthorizer = jasmine.createSpy("ajax")
Runtime.getAuthorizers = jasmine.createSpy("getAuthorizers").and.returnValue({
ajax: transportAuthorizer
});
const params = { socketId: '1.23' };
const callback = function(){};
const query = 'socket_id=1.23&abc=123&def=456';
userAuthenticator(params, callback);
expect(Runtime.getAuthorizers.calls.count()).toEqual(1);
expect(transportAuthorizer).toHaveBeenCalledWith(
Runtime,
query,
userAuthentication,
'user-authentication',
callback);
});
});
});

@@ -201,2 +201,50 @@ var TestEnv = require('testenv');

it('should use channelAuthorization with providers and override deprecated auth options', function() {
let headersProvider = () => { return { abc: '123'} };
let paramsProvider = () => { return { def: '456'} };
let opts = {
authTransport: 'some-auth-transport',
authEndpoint: '/pusher/spec/auth',
auth: {
params: { foo: 'bar' },
headers: { spec: 'header' }
},
channelAuthorization: {
transport: 'some-auth-transport2',
endpoint: '/pusher/spec/auth2',
params: { spec2: 'param2' },
headers: { spec2: 'header2' },
headersProvider,
paramsProvider
}
};
const pusher = {};
let config = Config.getConfig(opts, pusher);
let callback = function(){};
config.channelAuthorizer({
socketId: '1.23',
channelName: 'private-test',
}, callback);
console.log(config);
authOptions = {
transport: 'some-auth-transport2',
endpoint: '/pusher/spec/auth2',
params: { spec2: 'param2' },
headers: { spec2: 'header2' },
headersProvider,
paramsProvider
}
const query = 'socket_id=1.23&channel_name=private-test&spec2=param2&def=456';
expect(transportAuthorizer.calls.count()).toEqual(0);
expect(transportAuthorizer2.calls.count()).toEqual(1);
expect(transportAuthorizer2).toHaveBeenCalledWith(
Runtime,
query,
authOptions,
"channel-authorization",
callback
);
});
it('should use default transport when not provided in channelAuthorization', function() {

@@ -243,3 +291,3 @@ let opts = {

it('should use customerHandler inside channelAuthorization', function() {
it('should use customHandler inside channelAuthorization', function() {
const customHandler = jasmine.createSpy('customHandler');

@@ -292,3 +340,3 @@ let opts = {

params: { foo: 'bar' },
headers: { spec: 'header' }
headers: { spec: 'header' },
}

@@ -308,3 +356,3 @@ };

params: { foo: 'bar' },
headers: { spec: 'header' }
headers: { spec: 'header' },
}

@@ -322,2 +370,42 @@ const query = 'socket_id=1.23&foo=bar';

it('should use userAuthentication options with providers for user authentication', function() {
let headersProvider = () => { return { abc: '123'} };
let paramsProvider = () => { return { def: '456'} };
let opts = {
userAuthentication: {
transport: 'some-auth-transport',
endpoint: '/pusher/spec/auth',
params: { foo: 'bar' },
headers: { spec: 'header' },
headersProvider,
paramsProvider
}
};
const pusher = {};
let config = Config.getConfig(opts, pusher);
let callback = function(){};
config.userAuthenticator({
socketId: '1.23',
}, callback);
authOptions = {
transport: 'some-auth-transport',
endpoint: '/pusher/spec/auth',
params: { foo: 'bar' },
headers: { spec: 'header' },
headersProvider,
paramsProvider
}
const query = 'socket_id=1.23&foo=bar&def=456';
expect(transportAuthorizer.calls.count()).toEqual(1);
expect(transportAuthorizer).toHaveBeenCalledWith(
Runtime,
query,
authOptions,
"user-authentication",
callback
);
});
it('should use default transport when not provided in userAuthentication', function() {

@@ -324,0 +412,0 @@ let opts = {

@@ -16,3 +16,13 @@ var ConnectionManager = require('core/connection/connection_manager').default;

afterAll(() => {
jasmine.clock().uninstall();
try {
jasmine.clock().uninstall();
} catch (e) {
if (e instanceof TypeError) {
// Ignore
// It's a bug in jasmine AFAIK and all other attempts of working
// around it led to other issues
} else {
throw e;
}
}
});

@@ -19,0 +29,0 @@

@@ -166,8 +166,2 @@ var Mocks = require("mocks");

describe("on request end", function() {
beforeEach(function() {
request.start();
});
});
describe("on page unload", function() {

@@ -174,0 +168,0 @@ var unloader;

@@ -228,2 +228,7 @@ const TestEnv = require('testenv');

});
} else {
// Needed so that the describe block isn't empty
it("dummy test", function() {
expect(true).toBe(true);
})
}

@@ -230,0 +235,0 @@ });

var timers = require('core/utils/timers');
describe("timers", function() {
afterEach(() => {
jasmine.clock().uninstall();
});
describe("Timer", function() {

@@ -9,0 +5,0 @@ var callback;

@@ -36,2 +36,30 @@ var ChannelAuthorizer = require('core/auth/channel_authorizer').default;

});
it('should raise a warning if headersProvider is passed', function() {
var headers = { foo: 'bar', n: 42 };
var channelAuthorizer = ChannelAuthorizer({
transport: 'jsonp',
headersProvider: () => headers
})
var document = Mocks.getDocument();
var script = Mocks.getDocumentElement();
var documentElement = Mocks.getDocumentElement();
document.createElement.and.returnValue(script);
document.getElementsByTagName.and.returnValue([]);
document.documentElement = documentElement;
spyOn(Runtime, 'getDocument').and.returnValue(document);
spyOn(Logger, 'warn');
channelAuthorizer({
socketId: '1.23',
channelName: 'chan',
}, function() {})
expect(Logger.warn).toHaveBeenCalledWith(
'To send headers with the channel-authorization request, you must use AJAX, rather than JSONP.'
);
});
});

@@ -38,2 +38,26 @@ var fetchAuth = require('worker/auth/fetch_auth').default;

it('should pass headers from headersProvider in the request', function() {
fetchMock.mock(endpoint, { body: { hello: 'world' } });
var headers = { foo: 'bar', n: 42 };
var channelAuthorizer = ChannelAuthorizer({
transport: 'ajax',
endpoint: endpoint,
headersProvider: () => headers
});
channelAuthorizer({
socketId: '1.23',
channelName: 'chan'
}, function() {});
var lastCall = fetchMock.lastCall(endpoint)[0];
var sentHeaders = lastCall.headers;
expect(sentHeaders.get('Content-Type')).toEqual(
'application/x-www-form-urlencoded'
);
expect(sentHeaders.get('foo')).toEqual('bar');
expect(sentHeaders.get('n')).toEqual('42');
});
it('should pass params in the query string', async function() {

@@ -60,2 +84,24 @@ fetchMock.mock(endpoint, { body: { hello: 'world' } });

it('should pass params from paramsProvider in the query string', async function() {
fetchMock.mock(endpoint, { body: { hello: 'world' } });
var params = { a: 1, b: 2 };
var channelAuthorizer = ChannelAuthorizer({
transport: 'ajax',
endpoint: endpoint,
paramsProvider: () => params
});
channelAuthorizer({
socketId: '1.23',
channelName: 'chan'
}, function() {});
await new Promise(resolve => setTimeout(resolve, 100));
var lastRequest = fetchMock.lastCall(endpoint)[0];
const body = await lastRequest.text()
expect(body).toEqual("socket_id=1.23&channel_name=chan&a=1&b=2");
});
it('should call back with the auth result on success', async function() {

@@ -62,0 +108,0 @@ var data = { foo: 'bar', number: 1 };

@@ -19,10 +19,21 @@ import {

for (var i in authOptions.params) {
for (var key in authOptions.params) {
query +=
'&' +
encodeURIComponent(i) +
encodeURIComponent(key) +
'=' +
encodeURIComponent(authOptions.params[i]);
encodeURIComponent(authOptions.params[key]);
}
if (authOptions.paramsProvider != null) {
let dynamicParams = authOptions.paramsProvider();
for (var key in dynamicParams) {
query +=
'&' +
encodeURIComponent(key) +
'=' +
encodeURIComponent(dynamicParams[key]);
}
}
return query;

@@ -29,0 +40,0 @@ };

@@ -59,2 +59,4 @@ export enum AuthRequestType {

headers?: any;
paramsProvider?: () => any;
headersProvider?: () => any;
customHandler?: AuthHandler;

@@ -75,2 +77,4 @@ }

headers?: any;
paramsProvider?: () => any;
headersProvider?: () => any;
}

@@ -17,10 +17,21 @@ import {

for (var i in authOptions.params) {
for (var key in authOptions.params) {
query +=
'&' +
encodeURIComponent(i) +
encodeURIComponent(key) +
'=' +
encodeURIComponent(authOptions.params[i]);
encodeURIComponent(authOptions.params[key]);
}
if (authOptions.paramsProvider != null) {
let dynamicParams = authOptions.paramsProvider();
for (var key in dynamicParams) {
query +=
'&' +
encodeURIComponent(key) +
'=' +
encodeURIComponent(dynamicParams[key]);
}
}
return query;

@@ -27,0 +38,0 @@ };

@@ -30,2 +30,8 @@ import TimelineSender from 'core/timeline/timeline_sender';

}
if (authOptions.headersProvider != null) {
let dynamicHeaders = authOptions.headersProvider();
for (var headerName in dynamicHeaders) {
xhr.setRequestHeader(headerName, dynamicHeaders[headerName]);
}
}

@@ -32,0 +38,0 @@ xhr.onreadystatechange = function() {

@@ -19,3 +19,6 @@ import Browser from '../browser';

) {
if (authOptions.headers !== undefined) {
if (
authOptions.headers !== undefined ||
authOptions.headersProvider != null
) {
Logger.warn(

@@ -22,0 +25,0 @@ `To send headers with the ${authRequestType.toString()} request, you must use AJAX, rather than JSONP.`

@@ -24,2 +24,9 @@ import AbstractRuntime from 'runtimes/interface';

if (authOptions.headersProvider != null) {
const dynamicHeaders = authOptions.headersProvider();
for (var headerName in dynamicHeaders) {
headers.set(headerName, dynamicHeaders[headerName]);
}
}
var body = query;

@@ -26,0 +33,0 @@ var request = new Request(authOptions.endpoint, {

@@ -35,2 +35,4 @@ export declare enum AuthRequestType {

headers?: any;
paramsProvider?: () => any;
headersProvider?: () => any;
customHandler?: AuthHandler;

@@ -45,2 +47,4 @@ }

headers?: any;
paramsProvider?: () => any;
headersProvider?: () => any;
}

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc