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.
Files changed (106) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/README.md +27 -87
  3. package/dist/node/pusher.js +325 -73
  4. package/dist/node/pusher.js.map +1 -1
  5. package/dist/react-native/pusher.js +2 -2
  6. package/dist/react-native/pusher.js.map +1 -1
  7. package/dist/web/pusher-with-encryption.js +330 -78
  8. package/dist/web/pusher-with-encryption.js.map +1 -1
  9. package/dist/web/pusher-with-encryption.min.js +2 -2
  10. package/dist/web/pusher-with-encryption.min.js.map +1 -1
  11. package/dist/web/pusher.js +330 -78
  12. package/dist/web/pusher.js.map +1 -1
  13. package/dist/web/pusher.min.js +2 -2
  14. package/dist/web/pusher.min.js.map +1 -1
  15. package/dist/worker/pusher-with-encryption.worker.js +314 -69
  16. package/dist/worker/pusher-with-encryption.worker.js.map +1 -1
  17. package/dist/worker/pusher-with-encryption.worker.min.js +2 -2
  18. package/dist/worker/pusher-with-encryption.worker.min.js.map +1 -1
  19. package/dist/worker/pusher.worker.js +314 -69
  20. package/dist/worker/pusher.worker.js.map +1 -1
  21. package/dist/worker/pusher.worker.min.js +2 -2
  22. package/dist/worker/pusher.worker.min.js.map +1 -1
  23. package/index.d.ts +8 -3
  24. package/package.json +2 -2
  25. package/spec/config/karma/config.worker.js +3 -0
  26. package/spec/config/karma/integration.js +4 -2
  27. package/spec/javascripts/helpers/mocks.js +41 -8
  28. package/spec/javascripts/helpers/worker/mock-dom-dependencies.js +1 -0
  29. package/spec/javascripts/integration/core/cluster_config_spec.js +8 -0
  30. package/spec/javascripts/integration/core/timeout_configuration_spec.js +1 -0
  31. package/spec/javascripts/integration/index.worker.js +12 -1
  32. package/spec/javascripts/unit/core/channels/channel_spec.js +25 -0
  33. package/spec/javascripts/unit/core/channels/encrypted_channel_spec.js +64 -66
  34. package/spec/javascripts/unit/core/channels/presence_channel_spec.js +51 -41
  35. package/spec/javascripts/unit/core/channels/private_channel_spec.js +8 -46
  36. package/spec/javascripts/unit/core/config_spec.js +307 -7
  37. package/spec/javascripts/unit/core/connection/connection_manager_spec.js +1 -0
  38. package/spec/javascripts/unit/core/http/http_socket_spec.js +1 -0
  39. package/spec/javascripts/unit/core/logger_spec.js +21 -20
  40. package/spec/javascripts/unit/core/pusher_spec.js +67 -39
  41. package/spec/javascripts/unit/core/pusher_with_encryption_spec.js +2 -0
  42. package/spec/javascripts/unit/core/strategies/cached_strategy_spec.js +1 -0
  43. package/spec/javascripts/unit/core/strategies/delayed_strategy_spec.js +1 -0
  44. package/spec/javascripts/unit/core/strategies/sequential_strategy_spec.js +1 -0
  45. package/spec/javascripts/unit/core/strategies/transport_strategy_spec.js +1 -0
  46. package/spec/javascripts/unit/core/transports/assistant_to_the_transport_manager_spec.js +1 -0
  47. package/spec/javascripts/unit/core/user_spec.js +295 -0
  48. package/spec/javascripts/unit/core/utils/periodic_timer_spec.js +4 -1
  49. package/spec/javascripts/unit/core/utils/timers_spec.js +6 -0
  50. package/spec/javascripts/unit/core/utils/url_store_spec.js +1 -1
  51. package/spec/javascripts/unit/core_with_runtime/auth/channel_authorizer_spec.js +55 -0
  52. package/spec/javascripts/unit/core_with_runtime/auth/deprecated_channel_authorizer_spec.js +48 -0
  53. package/spec/javascripts/unit/core_with_runtime/auth/user_authorizer_spec.js +52 -0
  54. package/spec/javascripts/unit/core_with_runtime/readme.md +5 -0
  55. package/spec/javascripts/unit/index.node.js +3 -0
  56. package/spec/javascripts/unit/index.web.js +3 -0
  57. package/spec/javascripts/unit/index.worker.js +3 -0
  58. package/spec/javascripts/unit/web/pusher_authorizer_spec.js +15 -16
  59. package/spec/javascripts/unit/web/transports/hosts_and_ports_spec.js +1 -0
  60. package/spec/javascripts/unit/worker/channel_authorizer_spec.js +110 -0
  61. package/src/core/auth/auth_transports.ts +8 -1
  62. package/src/core/auth/channel_authorizer.ts +53 -0
  63. package/src/core/auth/deprecated_channel_authorizer.ts +58 -0
  64. package/src/core/auth/options.ts +52 -17
  65. package/src/core/auth/user_authenticator.ts +51 -0
  66. package/src/core/channels/channel.ts +17 -3
  67. package/src/core/channels/channels.ts +4 -0
  68. package/src/core/channels/encrypted_channel.ts +26 -20
  69. package/src/core/channels/presence_channel.ts +5 -2
  70. package/src/core/channels/private_channel.ts +9 -4
  71. package/src/core/config.ts +76 -11
  72. package/src/core/defaults.ts +15 -0
  73. package/src/core/errors.ts +9 -0
  74. package/src/core/options.ts +18 -5
  75. package/src/core/pusher.ts +9 -1
  76. package/src/core/user.ts +143 -0
  77. package/src/core/utils/factory.ts +1 -10
  78. package/src/core/utils/url_store.ts +4 -1
  79. package/src/runtimes/isomorphic/auth/xhr_auth.ts +32 -19
  80. package/src/runtimes/web/auth/jsonp_auth.ts +13 -7
  81. package/src/runtimes/worker/auth/fetch_auth.ts +17 -12
  82. package/types/src/core/auth/auth_transports.d.ts +2 -1
  83. package/types/src/core/auth/channel_authorizer.d.ts +3 -0
  84. package/types/src/core/auth/deprecated_channel_authorizer.d.ts +18 -0
  85. package/types/src/core/auth/options.d.ts +34 -15
  86. package/types/src/core/auth/user_authenticator.d.ts +3 -0
  87. package/types/src/core/channels/channel.d.ts +4 -2
  88. package/types/src/core/channels/encrypted_channel.d.ts +2 -2
  89. package/types/src/core/channels/private_channel.d.ts +2 -2
  90. package/types/src/core/config.d.ts +4 -6
  91. package/types/src/core/defaults.d.ts +3 -0
  92. package/types/src/core/errors.d.ts +3 -0
  93. package/types/src/core/options.d.ts +6 -3
  94. package/types/src/core/pusher.d.ts +3 -0
  95. package/types/src/core/user.d.ts +15 -0
  96. package/types/src/core/utils/factory.d.ts +0 -2
  97. package/types/src/runtimes/isomorphic/auth/xhr_auth.d.ts +1 -1
  98. package/worker/with-encryption/index.js +1 -1
  99. package/spec/javascripts/unit/core/pusher_authorizer_spec.js +0 -160
  100. package/spec/javascripts/unit/worker/pusher_authorizer_spec.js +0 -111
  101. package/src/core/auth/pusher_authorizer.ts +0 -64
  102. package/types/index.d.ts +0 -15
  103. package/types/src/core/auth/pusher_authorizer.d.ts +0 -13
  104. package/types/src/core/index.d.ts +0 -6
  105. package/types/src/runtimes/react-native/tweetnacl-dummy.d.ts +0 -5
  106. package/types/src/runtimes/react-native/tweetnacl-util-dummy.d.ts +0 -7
@@ -1,6 +1,13 @@
1
1
  import { Options } from './options';
2
2
  import Defaults from './defaults';
3
- import { AuthOptions, AuthorizerGenerator } from './auth/options';
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
- export function getConfig(opts: Options): Config {
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
+ }
@@ -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,
@@ -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);
@@ -1,14 +1,27 @@
1
1
  import ConnectionManager from './connection/connection_manager';
2
- import { AuthOptions, AuthorizerGenerator } from './auth/options';
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
- auth?: AuthOptions;
9
- authEndpoint?: string;
10
- authTransport?: AuthTransport;
11
- authorizer?: AuthorizerGenerator;
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;
@@ -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) {
@@ -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
- import { AuthorizerOptions, Authorizer } from '../auth/options';
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 { AuthorizerCallback } from 'core/auth/options';
8
+ import {
9
+ AuthRequestType,
10
+ AuthTransportCallback,
11
+ InternalAuthOptions
12
+ } from 'core/auth/options';
9
13
  import { HTTPAuthError } from 'core/errors';
10
14
 
11
- var ajax: AuthTransport = function(
15
+ const ajax: AuthTransport = function(
12
16
  context: AbstractRuntime,
13
- socketId: string,
14
- callback: AuthorizerCallback
17
+ query: string,
18
+ authOptions: InternalAuthOptions,
19
+ authRequestType: AuthRequestType,
20
+ callback: AuthTransportCallback
15
21
  ) {
16
- var self = this,
17
- xhr;
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 this.authOptions.headers) {
25
- xhr.setRequestHeader(headerName, this.authOptions.headers[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
- 'JSON returned from auth endpoint was invalid, yet status code was 200. Data was: ' +
44
+ `JSON returned from ${authRequestType.toString()} endpoint was invalid, yet status code was 200. Data was: ${
42
45
  xhr.responseText
46
+ }`
43
47
  ),
44
- { auth: '' }
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
- var suffix = UrlStore.buildLogSuffix('authenticationEndpoint');
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
- 'Unable to retrieve auth string from auth endpoint - ' +
58
- `received status: ${xhr.status} from ${self.options.authEndpoint}. ` +
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
- { auth: '' }
74
+ null
62
75
  );
63
76
  }
64
77
  }
65
78
  };
66
79
 
67
- xhr.send(this.composeQuery(socketId));
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 { AuthorizerCallback } from 'core/auth/options';
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
- socketId: string,
11
- callback: AuthorizerCallback
14
+ query: string,
15
+ authOptions: InternalAuthOptions,
16
+ authRequestType: AuthRequestType,
17
+ callback: AuthTransportCallback
12
18
  ) {
13
- if (this.authOptions.headers !== undefined) {
19
+ if (authOptions.headers !== undefined) {
14
20
  Logger.warn(
15
- 'To send headers with the auth request, you must use AJAX, rather than JSONP.'
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
- this.options.authEndpoint +
37
+ authOptions.endpoint +
32
38
  '?callback=' +
33
39
  encodeURIComponent(callback_name) +
34
40
  '&' +
35
- this.composeQuery(socketId);
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 { AuthorizerCallback, AuthData } from 'core/auth/options';
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
- socketId: string,
9
- callback: AuthorizerCallback
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 this.authOptions.headers) {
15
- headers.set(headerName, this.authOptions.headers[headerName]);
20
+ for (var headerName in authOptions.headers) {
21
+ headers.set(headerName, authOptions.headers[headerName]);
16
22
  }
17
23
 
18
- var body = this.composeQuery(socketId);
19
- var request = new Request(this.options.authEndpoint, {
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 auth info from your auth endpoint, status: ${status}`
42
+ `Could not get ${authRequestType.toString()} info from your auth endpoint, status: ${status}`
37
43
  );
38
44
  })
39
45
  .then(data => {
40
- let parsedData: AuthData;
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
- 'JSON returned from auth endpoint was invalid, yet status code was 200. Data was: ' +
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, { auth: '' });
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, socketId: string, callback: Function): void;
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,3 @@
1
+ import { InternalAuthOptions, ChannelAuthorizationHandler } from './options';
2
+ declare const ChannelAuthorizer: (authOptions: InternalAuthOptions) => ChannelAuthorizationHandler;
3
+ export default ChannelAuthorizer;
@@ -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;