pusher-js 7.0.6 → 7.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +18 -0
- package/README.md +27 -87
- package/dist/node/pusher.js +325 -73
- package/dist/node/pusher.js.map +1 -1
- package/dist/react-native/pusher.js +2 -2
- package/dist/react-native/pusher.js.map +1 -1
- package/dist/web/pusher-with-encryption.js +330 -78
- package/dist/web/pusher-with-encryption.js.map +1 -1
- package/dist/web/pusher-with-encryption.min.js +2 -2
- package/dist/web/pusher-with-encryption.min.js.map +1 -1
- package/dist/web/pusher.js +330 -78
- package/dist/web/pusher.js.map +1 -1
- package/dist/web/pusher.min.js +2 -2
- package/dist/web/pusher.min.js.map +1 -1
- package/dist/worker/pusher-with-encryption.worker.js +314 -69
- package/dist/worker/pusher-with-encryption.worker.js.map +1 -1
- package/dist/worker/pusher-with-encryption.worker.min.js +2 -2
- package/dist/worker/pusher-with-encryption.worker.min.js.map +1 -1
- package/dist/worker/pusher.worker.js +314 -69
- package/dist/worker/pusher.worker.js.map +1 -1
- package/dist/worker/pusher.worker.min.js +2 -2
- package/dist/worker/pusher.worker.min.js.map +1 -1
- package/index.d.ts +8 -3
- package/package.json +2 -2
- package/spec/config/karma/config.worker.js +3 -0
- package/spec/config/karma/integration.js +4 -2
- package/spec/javascripts/helpers/mocks.js +41 -8
- package/spec/javascripts/helpers/worker/mock-dom-dependencies.js +1 -0
- package/spec/javascripts/integration/core/cluster_config_spec.js +8 -0
- package/spec/javascripts/integration/core/timeout_configuration_spec.js +1 -0
- package/spec/javascripts/integration/index.worker.js +12 -1
- package/spec/javascripts/unit/core/channels/channel_spec.js +25 -0
- package/spec/javascripts/unit/core/channels/encrypted_channel_spec.js +64 -66
- package/spec/javascripts/unit/core/channels/presence_channel_spec.js +51 -41
- package/spec/javascripts/unit/core/channels/private_channel_spec.js +8 -46
- package/spec/javascripts/unit/core/config_spec.js +307 -7
- package/spec/javascripts/unit/core/connection/connection_manager_spec.js +1 -0
- package/spec/javascripts/unit/core/http/http_socket_spec.js +1 -0
- package/spec/javascripts/unit/core/logger_spec.js +21 -20
- package/spec/javascripts/unit/core/pusher_spec.js +67 -39
- package/spec/javascripts/unit/core/pusher_with_encryption_spec.js +2 -0
- package/spec/javascripts/unit/core/strategies/cached_strategy_spec.js +1 -0
- package/spec/javascripts/unit/core/strategies/delayed_strategy_spec.js +1 -0
- package/spec/javascripts/unit/core/strategies/sequential_strategy_spec.js +1 -0
- package/spec/javascripts/unit/core/strategies/transport_strategy_spec.js +1 -0
- package/spec/javascripts/unit/core/transports/assistant_to_the_transport_manager_spec.js +1 -0
- package/spec/javascripts/unit/core/user_spec.js +295 -0
- package/spec/javascripts/unit/core/utils/periodic_timer_spec.js +4 -1
- package/spec/javascripts/unit/core/utils/timers_spec.js +6 -0
- package/spec/javascripts/unit/core/utils/url_store_spec.js +1 -1
- package/spec/javascripts/unit/core_with_runtime/auth/channel_authorizer_spec.js +55 -0
- package/spec/javascripts/unit/core_with_runtime/auth/deprecated_channel_authorizer_spec.js +48 -0
- package/spec/javascripts/unit/core_with_runtime/auth/user_authorizer_spec.js +52 -0
- package/spec/javascripts/unit/core_with_runtime/readme.md +5 -0
- package/spec/javascripts/unit/index.node.js +3 -0
- package/spec/javascripts/unit/index.web.js +3 -0
- package/spec/javascripts/unit/index.worker.js +3 -0
- package/spec/javascripts/unit/web/pusher_authorizer_spec.js +15 -16
- package/spec/javascripts/unit/web/transports/hosts_and_ports_spec.js +1 -0
- package/spec/javascripts/unit/worker/channel_authorizer_spec.js +110 -0
- package/src/core/auth/auth_transports.ts +8 -1
- package/src/core/auth/channel_authorizer.ts +53 -0
- package/src/core/auth/deprecated_channel_authorizer.ts +58 -0
- package/src/core/auth/options.ts +52 -17
- package/src/core/auth/user_authenticator.ts +51 -0
- package/src/core/channels/channel.ts +17 -3
- package/src/core/channels/channels.ts +4 -0
- package/src/core/channels/encrypted_channel.ts +26 -20
- package/src/core/channels/presence_channel.ts +5 -2
- package/src/core/channels/private_channel.ts +9 -4
- package/src/core/config.ts +76 -11
- package/src/core/defaults.ts +15 -0
- package/src/core/errors.ts +9 -0
- package/src/core/options.ts +18 -5
- package/src/core/pusher.ts +9 -1
- package/src/core/user.ts +143 -0
- package/src/core/utils/factory.ts +1 -10
- package/src/core/utils/url_store.ts +4 -1
- package/src/runtimes/isomorphic/auth/xhr_auth.ts +32 -19
- package/src/runtimes/web/auth/jsonp_auth.ts +13 -7
- package/src/runtimes/worker/auth/fetch_auth.ts +17 -12
- package/types/src/core/auth/auth_transports.d.ts +2 -1
- package/types/src/core/auth/channel_authorizer.d.ts +3 -0
- package/types/src/core/auth/deprecated_channel_authorizer.d.ts +18 -0
- package/types/src/core/auth/options.d.ts +34 -15
- package/types/src/core/auth/user_authenticator.d.ts +3 -0
- package/types/src/core/channels/channel.d.ts +4 -2
- package/types/src/core/channels/encrypted_channel.d.ts +2 -2
- package/types/src/core/channels/private_channel.d.ts +2 -2
- package/types/src/core/config.d.ts +4 -6
- package/types/src/core/defaults.d.ts +3 -0
- package/types/src/core/errors.d.ts +3 -0
- package/types/src/core/options.d.ts +6 -3
- package/types/src/core/pusher.d.ts +3 -0
- package/types/src/core/user.d.ts +15 -0
- package/types/src/core/utils/factory.d.ts +0 -2
- package/types/src/runtimes/isomorphic/auth/xhr_auth.d.ts +1 -1
- package/worker/with-encryption/index.js +1 -1
- package/spec/javascripts/unit/core/pusher_authorizer_spec.js +0 -160
- package/spec/javascripts/unit/worker/pusher_authorizer_spec.js +0 -111
- package/src/core/auth/pusher_authorizer.ts +0 -64
- package/types/index.d.ts +0 -15
- package/types/src/core/auth/pusher_authorizer.d.ts +0 -13
- package/types/src/core/index.d.ts +0 -6
- package/types/src/runtimes/react-native/tweetnacl-dummy.d.ts +0 -5
- package/types/src/runtimes/react-native/tweetnacl-util-dummy.d.ts +0 -7
package/src/core/config.ts
CHANGED
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
import { Options } from './options';
|
|
2
2
|
import Defaults from './defaults';
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
ChannelAuthorizationHandler,
|
|
5
|
+
UserAuthenticationHandler,
|
|
6
|
+
AuthOptions
|
|
7
|
+
} from './auth/options';
|
|
8
|
+
import UserAuthenticator from './auth/user_authenticator';
|
|
9
|
+
import ChannelAuthorizer from './auth/channel_authorizer';
|
|
10
|
+
import { ChannelAuthorizerProxy } from './auth/deprecated_channel_authorizer';
|
|
4
11
|
import Runtime from 'runtime';
|
|
5
12
|
import * as nacl from 'tweetnacl';
|
|
6
13
|
import Logger from './logger';
|
|
@@ -17,8 +24,6 @@ export interface Config {
|
|
|
17
24
|
// these are all 'required' config parameters, it's not necessary for the user
|
|
18
25
|
// to set them, but they have configured defaults.
|
|
19
26
|
activityTimeout: number;
|
|
20
|
-
authEndpoint: string;
|
|
21
|
-
authTransport: AuthTransport;
|
|
22
27
|
enableStats: boolean;
|
|
23
28
|
httpHost: string;
|
|
24
29
|
httpPath: string;
|
|
@@ -32,12 +37,12 @@ export interface Config {
|
|
|
32
37
|
wsPath: string;
|
|
33
38
|
wsPort: number;
|
|
34
39
|
wssPort: number;
|
|
40
|
+
userAuthenticator: UserAuthenticationHandler;
|
|
41
|
+
channelAuthorizer: ChannelAuthorizationHandler;
|
|
35
42
|
|
|
36
43
|
// these are all optional parameters or overrrides. The customer can set these
|
|
37
44
|
// but it's not strictly necessary
|
|
38
45
|
forceTLS?: boolean;
|
|
39
|
-
auth?: AuthOptions;
|
|
40
|
-
authorizer?: AuthorizerGenerator;
|
|
41
46
|
cluster?: string;
|
|
42
47
|
disabledTransports?: Transport[];
|
|
43
48
|
enabledTransports?: Transport[];
|
|
@@ -46,11 +51,10 @@ export interface Config {
|
|
|
46
51
|
timelineParams?: any;
|
|
47
52
|
}
|
|
48
53
|
|
|
49
|
-
|
|
54
|
+
// getConfig mainly sets the defaults for the options that are not provided
|
|
55
|
+
export function getConfig(opts: Options, pusher): Config {
|
|
50
56
|
let config: Config = {
|
|
51
57
|
activityTimeout: opts.activityTimeout || Defaults.activityTimeout,
|
|
52
|
-
authEndpoint: opts.authEndpoint || Defaults.authEndpoint,
|
|
53
|
-
authTransport: opts.authTransport || Defaults.authTransport,
|
|
54
58
|
cluster: opts.cluster || Defaults.cluster,
|
|
55
59
|
httpPath: opts.httpPath || Defaults.httpPath,
|
|
56
60
|
httpPort: opts.httpPort || Defaults.httpPort,
|
|
@@ -65,11 +69,12 @@ export function getConfig(opts: Options): Config {
|
|
|
65
69
|
enableStats: getEnableStatsConfig(opts),
|
|
66
70
|
httpHost: getHttpHost(opts),
|
|
67
71
|
useTLS: shouldUseTLS(opts),
|
|
68
|
-
wsHost: getWebsocketHost(opts)
|
|
72
|
+
wsHost: getWebsocketHost(opts),
|
|
73
|
+
|
|
74
|
+
userAuthenticator: buildUserAuthenticator(opts),
|
|
75
|
+
channelAuthorizer: buildChannelAuthorizer(opts, pusher)
|
|
69
76
|
};
|
|
70
77
|
|
|
71
|
-
if ('auth' in opts) config.auth = opts.auth;
|
|
72
|
-
if ('authorizer' in opts) config.authorizer = opts.authorizer;
|
|
73
78
|
if ('disabledTransports' in opts)
|
|
74
79
|
config.disabledTransports = opts.disabledTransports;
|
|
75
80
|
if ('enabledTransports' in opts)
|
|
@@ -129,3 +134,63 @@ function getEnableStatsConfig(opts: Options): boolean {
|
|
|
129
134
|
}
|
|
130
135
|
return false;
|
|
131
136
|
}
|
|
137
|
+
|
|
138
|
+
function buildUserAuthenticator(opts: Options): UserAuthenticationHandler {
|
|
139
|
+
const userAuthentication = {
|
|
140
|
+
...Defaults.userAuthentication,
|
|
141
|
+
...opts.userAuthentication
|
|
142
|
+
};
|
|
143
|
+
if (
|
|
144
|
+
'customHandler' in userAuthentication &&
|
|
145
|
+
userAuthentication['customHandler'] != null
|
|
146
|
+
) {
|
|
147
|
+
return userAuthentication['customHandler'];
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
return UserAuthenticator(userAuthentication);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
function buildChannelAuth(
|
|
154
|
+
opts: Options,
|
|
155
|
+
pusher
|
|
156
|
+
): AuthOptions<ChannelAuthorizationHandler> {
|
|
157
|
+
let channelAuthorization: AuthOptions<ChannelAuthorizationHandler>;
|
|
158
|
+
if ('channelAuthorization' in opts) {
|
|
159
|
+
channelAuthorization = {
|
|
160
|
+
...Defaults.channelAuthorization,
|
|
161
|
+
...opts.channelAuthorization
|
|
162
|
+
};
|
|
163
|
+
} else {
|
|
164
|
+
channelAuthorization = {
|
|
165
|
+
transport: opts.authTransport || Defaults.authTransport,
|
|
166
|
+
endpoint: opts.authEndpoint || Defaults.authEndpoint
|
|
167
|
+
};
|
|
168
|
+
if ('auth' in opts) {
|
|
169
|
+
if ('params' in opts.auth) channelAuthorization.params = opts.auth.params;
|
|
170
|
+
if ('headers' in opts.auth)
|
|
171
|
+
channelAuthorization.headers = opts.auth.headers;
|
|
172
|
+
}
|
|
173
|
+
if ('authorizer' in opts)
|
|
174
|
+
channelAuthorization.customHandler = ChannelAuthorizerProxy(
|
|
175
|
+
pusher,
|
|
176
|
+
channelAuthorization,
|
|
177
|
+
opts.authorizer
|
|
178
|
+
);
|
|
179
|
+
}
|
|
180
|
+
return channelAuthorization;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
function buildChannelAuthorizer(
|
|
184
|
+
opts: Options,
|
|
185
|
+
pusher
|
|
186
|
+
): ChannelAuthorizationHandler {
|
|
187
|
+
const channelAuthorization = buildChannelAuth(opts, pusher);
|
|
188
|
+
if (
|
|
189
|
+
'customHandler' in channelAuthorization &&
|
|
190
|
+
channelAuthorization['customHandler'] != null
|
|
191
|
+
) {
|
|
192
|
+
return channelAuthorization['customHandler'];
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
return ChannelAuthorizer(channelAuthorization);
|
|
196
|
+
}
|
package/src/core/defaults.ts
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AuthOptions,
|
|
3
|
+
ChannelAuthorizationHandler,
|
|
4
|
+
UserAuthenticationHandler
|
|
5
|
+
} from './auth/options';
|
|
1
6
|
import { AuthTransport } from './config';
|
|
2
7
|
|
|
3
8
|
export interface DefaultConfig {
|
|
@@ -17,6 +22,8 @@ export interface DefaultConfig {
|
|
|
17
22
|
pongTimeout: number;
|
|
18
23
|
unavailableTimeout: number;
|
|
19
24
|
cluster: string;
|
|
25
|
+
userAuthentication: AuthOptions<UserAuthenticationHandler>;
|
|
26
|
+
channelAuthorization: AuthOptions<ChannelAuthorizationHandler>;
|
|
20
27
|
|
|
21
28
|
cdn_http?: string;
|
|
22
29
|
cdn_https?: string;
|
|
@@ -44,6 +51,14 @@ var Defaults: DefaultConfig = {
|
|
|
44
51
|
pongTimeout: 30000,
|
|
45
52
|
unavailableTimeout: 10000,
|
|
46
53
|
cluster: 'mt1',
|
|
54
|
+
userAuthentication: {
|
|
55
|
+
endpoint: '/pusher/user-auth',
|
|
56
|
+
transport: 'ajax'
|
|
57
|
+
},
|
|
58
|
+
channelAuthorization: {
|
|
59
|
+
endpoint: '/pusher/auth',
|
|
60
|
+
transport: 'ajax'
|
|
61
|
+
},
|
|
47
62
|
|
|
48
63
|
// CDN configuration
|
|
49
64
|
cdn_http: CDN_HTTP,
|
package/src/core/errors.ts
CHANGED
|
@@ -7,6 +7,15 @@ export class BadEventName extends Error {
|
|
|
7
7
|
Object.setPrototypeOf(this, new.target.prototype);
|
|
8
8
|
}
|
|
9
9
|
}
|
|
10
|
+
|
|
11
|
+
export class BadChannelName extends Error {
|
|
12
|
+
constructor(msg?: string) {
|
|
13
|
+
super(msg);
|
|
14
|
+
|
|
15
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
10
19
|
export class RequestTimedOut extends Error {
|
|
11
20
|
constructor(msg?: string) {
|
|
12
21
|
super(msg);
|
package/src/core/options.ts
CHANGED
|
@@ -1,14 +1,27 @@
|
|
|
1
1
|
import ConnectionManager from './connection/connection_manager';
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
AuthOptions,
|
|
4
|
+
ChannelAuthorizationHandler,
|
|
5
|
+
UserAuthenticationHandler
|
|
6
|
+
} from './auth/options';
|
|
7
|
+
import {
|
|
8
|
+
ChannelAuthorizerGenerator,
|
|
9
|
+
DeprecatedAuthOptions
|
|
10
|
+
} from './auth/deprecated_channel_authorizer';
|
|
3
11
|
import { AuthTransport, Transport } from './config';
|
|
4
12
|
import * as nacl from 'tweetnacl';
|
|
5
13
|
|
|
6
14
|
export interface Options {
|
|
7
15
|
activityTimeout?: number;
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
16
|
+
|
|
17
|
+
auth?: DeprecatedAuthOptions; // DEPRECATED use channelAuthorization instead
|
|
18
|
+
authEndpoint?: string; // DEPRECATED use channelAuthorization instead
|
|
19
|
+
authTransport?: AuthTransport; // DEPRECATED use channelAuthorization instead
|
|
20
|
+
authorizer?: ChannelAuthorizerGenerator; // DEPRECATED use channelAuthorization instead
|
|
21
|
+
|
|
22
|
+
channelAuthorization?: AuthOptions<ChannelAuthorizationHandler>;
|
|
23
|
+
userAuthentication?: AuthOptions<UserAuthenticationHandler>;
|
|
24
|
+
|
|
12
25
|
cluster?: string;
|
|
13
26
|
enableStats?: boolean;
|
|
14
27
|
disableStats?: boolean;
|
package/src/core/pusher.ts
CHANGED
|
@@ -20,6 +20,7 @@ import UrlStore from 'core/utils/url_store';
|
|
|
20
20
|
import { Options } from './options';
|
|
21
21
|
import { Config, getConfig } from './config';
|
|
22
22
|
import StrategyOptions from './strategies/strategy_options';
|
|
23
|
+
import UserFacade from './user';
|
|
23
24
|
|
|
24
25
|
export default class Pusher {
|
|
25
26
|
/* STATIC PROPERTIES */
|
|
@@ -60,6 +61,7 @@ export default class Pusher {
|
|
|
60
61
|
timelineSender: TimelineSender;
|
|
61
62
|
connection: ConnectionManager;
|
|
62
63
|
timelineSenderTimer: PeriodicTimer;
|
|
64
|
+
user: UserFacade;
|
|
63
65
|
|
|
64
66
|
constructor(app_key: string, options?: Options) {
|
|
65
67
|
checkAppKey(app_key);
|
|
@@ -77,7 +79,7 @@ export default class Pusher {
|
|
|
77
79
|
}
|
|
78
80
|
|
|
79
81
|
this.key = app_key;
|
|
80
|
-
this.config = getConfig(options);
|
|
82
|
+
this.config = getConfig(options, this);
|
|
81
83
|
|
|
82
84
|
this.channels = Factory.createChannels();
|
|
83
85
|
this.global_emitter = new EventsDispatcher();
|
|
@@ -145,6 +147,8 @@ export default class Pusher {
|
|
|
145
147
|
Pusher.instances.push(this);
|
|
146
148
|
this.timeline.info({ instances: Pusher.instances.length });
|
|
147
149
|
|
|
150
|
+
this.user = new UserFacade(this);
|
|
151
|
+
|
|
148
152
|
if (Pusher.isReady) {
|
|
149
153
|
this.connect();
|
|
150
154
|
}
|
|
@@ -247,6 +251,10 @@ export default class Pusher {
|
|
|
247
251
|
shouldUseTLS(): boolean {
|
|
248
252
|
return this.config.useTLS;
|
|
249
253
|
}
|
|
254
|
+
|
|
255
|
+
signin() {
|
|
256
|
+
this.user.signin();
|
|
257
|
+
}
|
|
250
258
|
}
|
|
251
259
|
|
|
252
260
|
function checkAppKey(key) {
|
package/src/core/user.ts
ADDED
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import Pusher from './pusher';
|
|
2
|
+
import Logger from './logger';
|
|
3
|
+
import {
|
|
4
|
+
UserAuthenticationData,
|
|
5
|
+
UserAuthenticationCallback
|
|
6
|
+
} from './auth/options';
|
|
7
|
+
import Channel from './channels/channel';
|
|
8
|
+
import EventsDispatcher from './events/dispatcher';
|
|
9
|
+
|
|
10
|
+
export default class UserFacade extends EventsDispatcher {
|
|
11
|
+
pusher: Pusher;
|
|
12
|
+
signin_requested: boolean = false;
|
|
13
|
+
user_data: any = null;
|
|
14
|
+
serverToUserChannel: Channel = null;
|
|
15
|
+
|
|
16
|
+
public constructor(pusher: Pusher) {
|
|
17
|
+
super(function(eventName, data) {
|
|
18
|
+
Logger.debug('No callbacks on user for ' + eventName);
|
|
19
|
+
});
|
|
20
|
+
this.pusher = pusher;
|
|
21
|
+
this.pusher.connection.bind('connected', () => {
|
|
22
|
+
this._signin();
|
|
23
|
+
});
|
|
24
|
+
this.pusher.connection.bind('connecting', () => {
|
|
25
|
+
this._disconnect();
|
|
26
|
+
});
|
|
27
|
+
this.pusher.connection.bind('disconnected', () => {
|
|
28
|
+
this._disconnect();
|
|
29
|
+
});
|
|
30
|
+
this.pusher.connection.bind('message', event => {
|
|
31
|
+
var eventName = event.event;
|
|
32
|
+
if (eventName === 'pusher:signin_success') {
|
|
33
|
+
this._onSigninSuccess(event.data);
|
|
34
|
+
}
|
|
35
|
+
if (
|
|
36
|
+
this.serverToUserChannel &&
|
|
37
|
+
this.serverToUserChannel.name === event.channel
|
|
38
|
+
) {
|
|
39
|
+
this.serverToUserChannel.handleEvent(event);
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
public signin() {
|
|
45
|
+
if (this.signin_requested) {
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
this.signin_requested = true;
|
|
50
|
+
this._signin();
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
private _signin() {
|
|
54
|
+
if (!this.signin_requested) {
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
if (this.pusher.connection.state !== 'connected') {
|
|
59
|
+
// Signin will be attempted when the connection is connected
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const onAuthorize: UserAuthenticationCallback = (
|
|
64
|
+
err,
|
|
65
|
+
authData: UserAuthenticationData
|
|
66
|
+
) => {
|
|
67
|
+
if (err) {
|
|
68
|
+
Logger.warn(`Error during signin: ${err}`);
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
this.pusher.send_event('pusher:signin', {
|
|
73
|
+
auth: authData.auth,
|
|
74
|
+
user_data: authData.user_data
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
// Later when we get pusher:singin_success event, the user will be marked as signed in
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
this.pusher.config.userAuthenticator(
|
|
81
|
+
{
|
|
82
|
+
socketId: this.pusher.connection.socket_id
|
|
83
|
+
},
|
|
84
|
+
onAuthorize
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
private _onSigninSuccess(data: any) {
|
|
89
|
+
try {
|
|
90
|
+
this.user_data = JSON.parse(data.user_data);
|
|
91
|
+
} catch (e) {
|
|
92
|
+
Logger.error(`Failed parsing user data after signin: ${data.user_data}`);
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
if (typeof this.user_data.id !== 'string' || this.user_data.id === '') {
|
|
97
|
+
Logger.error(
|
|
98
|
+
`user_data doesn't contain an id. user_data: ${this.user_data}`
|
|
99
|
+
);
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
this._subscribeChannels();
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
private _subscribeChannels() {
|
|
107
|
+
const ensure_subscribed = channel => {
|
|
108
|
+
if (channel.subscriptionPending && channel.subscriptionCancelled) {
|
|
109
|
+
channel.reinstateSubscription();
|
|
110
|
+
} else if (
|
|
111
|
+
!channel.subscriptionPending &&
|
|
112
|
+
this.pusher.connection.state === 'connected'
|
|
113
|
+
) {
|
|
114
|
+
channel.subscribe();
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
this.serverToUserChannel = new Channel(
|
|
119
|
+
`#server-to-user-${this.user_data.id}`,
|
|
120
|
+
this.pusher
|
|
121
|
+
);
|
|
122
|
+
this.serverToUserChannel.bind_global((eventName, data) => {
|
|
123
|
+
if (
|
|
124
|
+
eventName.indexOf('pusher_internal:') === 0 ||
|
|
125
|
+
eventName.indexOf('pusher:') === 0
|
|
126
|
+
) {
|
|
127
|
+
// ignore internal events
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
this.emit(eventName, data);
|
|
131
|
+
});
|
|
132
|
+
ensure_subscribed(this.serverToUserChannel);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
private _disconnect() {
|
|
136
|
+
this.user_data = null;
|
|
137
|
+
if (this.serverToUserChannel) {
|
|
138
|
+
this.serverToUserChannel.unbind_all();
|
|
139
|
+
this.serverToUserChannel.disconnect();
|
|
140
|
+
this.serverToUserChannel = null;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
@@ -6,8 +6,7 @@ import Handshake from '../connection/handshake';
|
|
|
6
6
|
import TransportConnection from '../transports/transport_connection';
|
|
7
7
|
import SocketHooks from '../http/socket_hooks';
|
|
8
8
|
import HTTPSocket from '../http/http_socket';
|
|
9
|
-
|
|
10
|
-
import PusherAuthorizer from '../auth/pusher_authorizer';
|
|
9
|
+
|
|
11
10
|
import Timeline from '../timeline/timeline';
|
|
12
11
|
import {
|
|
13
12
|
default as TimelineSender,
|
|
@@ -61,14 +60,6 @@ var Factory = {
|
|
|
61
60
|
return new TimelineSender(timeline, options);
|
|
62
61
|
},
|
|
63
62
|
|
|
64
|
-
createAuthorizer(channel: Channel, options: AuthorizerOptions): Authorizer {
|
|
65
|
-
if (options.authorizer) {
|
|
66
|
-
return options.authorizer(channel, options);
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
return new PusherAuthorizer(channel, options);
|
|
70
|
-
},
|
|
71
|
-
|
|
72
63
|
createHandshake(
|
|
73
64
|
transport: TransportConnection,
|
|
74
65
|
callback: (HandshakePayload) => void
|
|
@@ -6,7 +6,10 @@ const urlStore = {
|
|
|
6
6
|
baseUrl: 'https://pusher.com',
|
|
7
7
|
urls: {
|
|
8
8
|
authenticationEndpoint: {
|
|
9
|
-
path: '/docs/authenticating_users'
|
|
9
|
+
path: '/docs/channels/server_api/authenticating_users'
|
|
10
|
+
},
|
|
11
|
+
authorizationEndpoint: {
|
|
12
|
+
path: '/docs/channels/server_api/authorizing-users/'
|
|
10
13
|
},
|
|
11
14
|
javascriptQuickStart: {
|
|
12
15
|
path: '/docs/javascript_quick_start'
|
|
@@ -5,24 +5,27 @@ import Runtime from 'runtime';
|
|
|
5
5
|
import { AuthTransport } from 'core/auth/auth_transports';
|
|
6
6
|
import AbstractRuntime from 'runtimes/interface';
|
|
7
7
|
import UrlStore from 'core/utils/url_store';
|
|
8
|
-
import {
|
|
8
|
+
import {
|
|
9
|
+
AuthRequestType,
|
|
10
|
+
AuthTransportCallback,
|
|
11
|
+
InternalAuthOptions
|
|
12
|
+
} from 'core/auth/options';
|
|
9
13
|
import { HTTPAuthError } from 'core/errors';
|
|
10
14
|
|
|
11
|
-
|
|
15
|
+
const ajax: AuthTransport = function(
|
|
12
16
|
context: AbstractRuntime,
|
|
13
|
-
|
|
14
|
-
|
|
17
|
+
query: string,
|
|
18
|
+
authOptions: InternalAuthOptions,
|
|
19
|
+
authRequestType: AuthRequestType,
|
|
20
|
+
callback: AuthTransportCallback
|
|
15
21
|
) {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
xhr = Runtime.createXHR();
|
|
20
|
-
xhr.open('POST', self.options.authEndpoint, true);
|
|
22
|
+
const xhr = Runtime.createXHR();
|
|
23
|
+
xhr.open('POST', authOptions.endpoint, true);
|
|
21
24
|
|
|
22
25
|
// add request headers
|
|
23
26
|
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
|
|
24
|
-
for (var headerName in
|
|
25
|
-
xhr.setRequestHeader(headerName,
|
|
27
|
+
for (var headerName in authOptions.headers) {
|
|
28
|
+
xhr.setRequestHeader(headerName, authOptions.headers[headerName]);
|
|
26
29
|
}
|
|
27
30
|
|
|
28
31
|
xhr.onreadystatechange = function() {
|
|
@@ -38,10 +41,11 @@ var ajax: AuthTransport = function(
|
|
|
38
41
|
callback(
|
|
39
42
|
new HTTPAuthError(
|
|
40
43
|
200,
|
|
41
|
-
|
|
44
|
+
`JSON returned from ${authRequestType.toString()} endpoint was invalid, yet status code was 200. Data was: ${
|
|
42
45
|
xhr.responseText
|
|
46
|
+
}`
|
|
43
47
|
),
|
|
44
|
-
|
|
48
|
+
null
|
|
45
49
|
);
|
|
46
50
|
}
|
|
47
51
|
|
|
@@ -50,21 +54,30 @@ var ajax: AuthTransport = function(
|
|
|
50
54
|
callback(null, data);
|
|
51
55
|
}
|
|
52
56
|
} else {
|
|
53
|
-
|
|
57
|
+
let suffix = '';
|
|
58
|
+
switch (authRequestType) {
|
|
59
|
+
case AuthRequestType.UserAuthentication:
|
|
60
|
+
suffix = UrlStore.buildLogSuffix('authenticationEndpoint');
|
|
61
|
+
break;
|
|
62
|
+
case AuthRequestType.ChannelAuthorization:
|
|
63
|
+
suffix = `Clients must be authenticated to join private or presence channels. ${UrlStore.buildLogSuffix(
|
|
64
|
+
'authorizationEndpoint'
|
|
65
|
+
)}`;
|
|
66
|
+
break;
|
|
67
|
+
}
|
|
54
68
|
callback(
|
|
55
69
|
new HTTPAuthError(
|
|
56
70
|
xhr.status,
|
|
57
|
-
|
|
58
|
-
`received status: ${xhr.status} from ${
|
|
59
|
-
`Clients must be authenticated to join private or presence channels. ${suffix}`
|
|
71
|
+
`Unable to retrieve auth string from ${authRequestType.toString()} endpoint - ` +
|
|
72
|
+
`received status: ${xhr.status} from ${authOptions.endpoint}. ${suffix}`
|
|
60
73
|
),
|
|
61
|
-
|
|
74
|
+
null
|
|
62
75
|
);
|
|
63
76
|
}
|
|
64
77
|
}
|
|
65
78
|
};
|
|
66
79
|
|
|
67
|
-
xhr.send(
|
|
80
|
+
xhr.send(query);
|
|
68
81
|
return xhr;
|
|
69
82
|
};
|
|
70
83
|
|
|
@@ -3,16 +3,22 @@ import Logger from 'core/logger';
|
|
|
3
3
|
import JSONPRequest from '../dom/jsonp_request';
|
|
4
4
|
import { ScriptReceivers } from '../dom/script_receiver_factory';
|
|
5
5
|
import { AuthTransport } from 'core/auth/auth_transports';
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
AuthRequestType,
|
|
8
|
+
AuthTransportCallback,
|
|
9
|
+
InternalAuthOptions
|
|
10
|
+
} from 'core/auth/options';
|
|
7
11
|
|
|
8
12
|
var jsonp: AuthTransport = function(
|
|
9
13
|
context: Browser,
|
|
10
|
-
|
|
11
|
-
|
|
14
|
+
query: string,
|
|
15
|
+
authOptions: InternalAuthOptions,
|
|
16
|
+
authRequestType: AuthRequestType,
|
|
17
|
+
callback: AuthTransportCallback
|
|
12
18
|
) {
|
|
13
|
-
if (
|
|
19
|
+
if (authOptions.headers !== undefined) {
|
|
14
20
|
Logger.warn(
|
|
15
|
-
|
|
21
|
+
`To send headers with the ${authRequestType.toString()} request, you must use AJAX, rather than JSONP.`
|
|
16
22
|
);
|
|
17
23
|
}
|
|
18
24
|
|
|
@@ -28,11 +34,11 @@ var jsonp: AuthTransport = function(
|
|
|
28
34
|
|
|
29
35
|
var callback_name = "Pusher.auth_callbacks['" + callbackName + "']";
|
|
30
36
|
script.src =
|
|
31
|
-
|
|
37
|
+
authOptions.endpoint +
|
|
32
38
|
'?callback=' +
|
|
33
39
|
encodeURIComponent(callback_name) +
|
|
34
40
|
'&' +
|
|
35
|
-
|
|
41
|
+
query;
|
|
36
42
|
|
|
37
43
|
var head =
|
|
38
44
|
document.getElementsByTagName('head')[0] || document.documentElement;
|
|
@@ -1,22 +1,28 @@
|
|
|
1
1
|
import AbstractRuntime from 'runtimes/interface';
|
|
2
2
|
import { AuthTransport } from 'core/auth/auth_transports';
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
AuthRequestType,
|
|
5
|
+
AuthTransportCallback,
|
|
6
|
+
InternalAuthOptions
|
|
7
|
+
} from 'core/auth/options';
|
|
4
8
|
import { HTTPAuthError } from 'core/errors';
|
|
5
9
|
|
|
6
10
|
var fetchAuth: AuthTransport = function(
|
|
7
11
|
context: AbstractRuntime,
|
|
8
|
-
|
|
9
|
-
|
|
12
|
+
query: string,
|
|
13
|
+
authOptions: InternalAuthOptions,
|
|
14
|
+
authRequestType: AuthRequestType,
|
|
15
|
+
callback: AuthTransportCallback
|
|
10
16
|
) {
|
|
11
17
|
var headers = new Headers();
|
|
12
18
|
headers.set('Content-Type', 'application/x-www-form-urlencoded');
|
|
13
19
|
|
|
14
|
-
for (var headerName in
|
|
15
|
-
headers.set(headerName,
|
|
20
|
+
for (var headerName in authOptions.headers) {
|
|
21
|
+
headers.set(headerName, authOptions.headers[headerName]);
|
|
16
22
|
}
|
|
17
23
|
|
|
18
|
-
var body =
|
|
19
|
-
var request = new Request(
|
|
24
|
+
var body = query;
|
|
25
|
+
var request = new Request(authOptions.endpoint, {
|
|
20
26
|
headers,
|
|
21
27
|
body,
|
|
22
28
|
credentials: 'same-origin',
|
|
@@ -33,24 +39,23 @@ var fetchAuth: AuthTransport = function(
|
|
|
33
39
|
}
|
|
34
40
|
throw new HTTPAuthError(
|
|
35
41
|
200,
|
|
36
|
-
`Could not get
|
|
42
|
+
`Could not get ${authRequestType.toString()} info from your auth endpoint, status: ${status}`
|
|
37
43
|
);
|
|
38
44
|
})
|
|
39
45
|
.then(data => {
|
|
40
|
-
let parsedData
|
|
46
|
+
let parsedData;
|
|
41
47
|
try {
|
|
42
48
|
parsedData = JSON.parse(data);
|
|
43
49
|
} catch (e) {
|
|
44
50
|
throw new HTTPAuthError(
|
|
45
51
|
200,
|
|
46
|
-
|
|
47
|
-
data
|
|
52
|
+
`JSON returned from ${authRequestType.toString()} endpoint was invalid, yet status code was 200. Data was: ${data}`
|
|
48
53
|
);
|
|
49
54
|
}
|
|
50
55
|
callback(null, parsedData);
|
|
51
56
|
})
|
|
52
57
|
.catch(err => {
|
|
53
|
-
callback(err,
|
|
58
|
+
callback(err, null);
|
|
54
59
|
});
|
|
55
60
|
};
|
|
56
61
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import AbstractRuntime from '../../runtimes/interface';
|
|
2
|
+
import { AuthRequestType, InternalAuthOptions } from './options';
|
|
2
3
|
interface AuthTransport {
|
|
3
|
-
(context: AbstractRuntime,
|
|
4
|
+
(context: AbstractRuntime, query: string, authOptions: InternalAuthOptions, authRequestType: AuthRequestType, callback: Function): void;
|
|
4
5
|
}
|
|
5
6
|
interface AuthTransports {
|
|
6
7
|
[index: string]: AuthTransport;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import Channel from '../channels/channel';
|
|
2
|
+
import { ChannelAuthorizationCallback, ChannelAuthorizationHandler, InternalAuthOptions } from './options';
|
|
3
|
+
export interface DeprecatedChannelAuthorizer {
|
|
4
|
+
authorize(socketId: string, callback: ChannelAuthorizationCallback): void;
|
|
5
|
+
}
|
|
6
|
+
export interface ChannelAuthorizerGenerator {
|
|
7
|
+
(channel: Channel, options: DeprecatedAuthorizerOptions): DeprecatedChannelAuthorizer;
|
|
8
|
+
}
|
|
9
|
+
export interface DeprecatedAuthOptions {
|
|
10
|
+
params?: any;
|
|
11
|
+
headers?: any;
|
|
12
|
+
}
|
|
13
|
+
export interface DeprecatedAuthorizerOptions {
|
|
14
|
+
authTransport: 'ajax' | 'jsonp';
|
|
15
|
+
authEndpoint: string;
|
|
16
|
+
auth?: DeprecatedAuthOptions;
|
|
17
|
+
}
|
|
18
|
+
export declare const ChannelAuthorizerProxy: (pusher: any, authOptions: InternalAuthOptions, channelAuthorizerGenerator: ChannelAuthorizerGenerator) => ChannelAuthorizationHandler;
|